fix: add tool to make user account from profile view

This commit is contained in:
Lance Edgar 2024-07-04 21:32:46 -05:00
parent ddec77c37f
commit 58be7e9d5b
2 changed files with 167 additions and 17 deletions

View file

@ -1635,28 +1635,30 @@
<br /> <br />
<div id="users-accordion"> <div id="users-accordion">
<b-collapse class="panel" <${b}-collapse v-for="user in users"
v-for="user in users" :key="user.uuid"
:key="user.uuid"> class="panel">
<div slot="trigger" <div slot="trigger"
slot-scope="props"
class="panel-heading" class="panel-heading"
role="button"> role="button">
<b-icon pack="fas"
icon="caret-right">
</b-icon>
<strong>{{ user.username }}</strong> <strong>{{ user.username }}</strong>
</div> </div>
<div class="panel-block"> <div class="panel-block">
<div style="display: flex; justify-content: space-between; width: 100%;"> <div style="display: flex; justify-content: space-between; width: 100%;">
<div> <div style="flex-grow: 1;">
<div class="field-wrapper id"> <b-field horizontal label="Username">
<div class="field-row">
<label>Username</label>
<div class="field">
{{ user.username }} {{ user.username }}
</div> </b-field>
</div> <b-field horizontal label="Active">
</div> {{ user.active ? "Yes" : "No" }}
</b-field>
</div> </div>
<div> <div>
@ -1669,13 +1671,66 @@
</div> </div>
</div> </div>
</b-collapse> </${b}-collapse>
</div> </div>
</div> </div>
<div v-if="!users.length"> <div v-if="!users.length"
style="display: flex; justify-content: space-between;">
<p>{{ person.display_name }} does not have a user account.</p> <p>{{ person.display_name }} does not have a user account.</p>
% if request.has_perm('users.create'):
<b-button type="primary"
icon-pack="fas"
icon-left="plus"
@click="createUserInit()">
Create User
</b-button>
<${b}-modal has-modal-card
% if request.use_oruga:
v-model:active="createUserShowDialog"
% else:
:active.sync="createUserShowDialog"
% endif
>
<div class="modal-card">
<header class="modal-card-head">
<p class="modal-card-title">Create User</p>
</header>
<section class="modal-card-body">
<b-field label="Person">
<span>{{ person.display_name }}</span>
</b-field>
<b-field label="Username">
<b-input v-model="createUserUsername"
ref="username" />
</b-field>
<b-field label="Active">
<b-checkbox v-model="createUserActive" />
</b-field>
</section>
<footer class="modal-card-foot">
<b-button @click="createUserShowDialog = false">
Cancel
</b-button>
<b-button type="is-primary"
@click="createUserSave()"
:disabled="createUserSaveDisabled"
icon-pack="fas"
icon-left="save">
{{ createUserSaving ? "Working, please wait..." : "Save" }}
</b-button>
</footer>
</div> </div>
</${b}-modal>
% endif
</div>
% if request.use_oruga: % if request.use_oruga:
<o-loading v-model:active="refreshingTab" :full-page="false"></o-loading> <o-loading v-model:active="refreshingTab" :full-page="false"></o-loading>
% else: % else:
@ -2730,6 +2785,13 @@
let UserTabData = { let UserTabData = {
refreshTabURL: '${url('people.profile_tab_user', uuid=person.uuid)}', refreshTabURL: '${url('people.profile_tab_user', uuid=person.uuid)}',
users: [], users: [],
% if request.has_perm('users.create'):
createUserShowDialog: false,
createUserUsername: null,
createUserActive: false,
createUserSaving: false,
% endif
} }
let UserTab = { let UserTab = {
@ -2738,12 +2800,62 @@
props: { props: {
person: Object, person: Object,
}, },
computed: {},
computed: {
% if request.has_perm('users.create'):
createUserSaveDisabled() {
if (this.createUserSaving) {
return true
}
if (!this.createUserUsername) {
return true
}
return false
},
% endif
},
methods: { methods: {
refreshTabSuccess(response) { refreshTabSuccess(response) {
this.users = response.data.users this.users = response.data.users
this.createUserSuggestedUsername = response.data.suggested_username
}, },
% if request.has_perm('users.create'):
createUserInit() {
this.createUserUsername = this.createUserSuggestedUsername
this.createUserActive = true
this.createUserShowDialog = true
this.$nextTick(() => {
this.$refs.username.focus()
})
},
createUserSave() {
this.createUserSaving = true
let url = '${master.get_action_url('profile_make_user', instance)}'
let params = {
username: this.createUserUsername,
active: this.createUserActive,
}
this.simplePOST(url, params, response => {
this.$emit('profile-changed', response.data)
this.createUserSaving = false
this.createUserShowDialog = false
this.refreshTab()
}, response => {
this.createUserSaving = false
})
},
% endif
}, },
} }

View file

@ -1280,11 +1280,40 @@ class PersonView(MasterView):
""" """
Fetch user tab data for profile view. Fetch user tab data for profile view.
""" """
app = self.get_rattail_app()
auth = app.get_auth_handler()
person = self.get_instance() person = self.get_instance()
return { context = {
'users': self.get_context_users(person), 'users': self.get_context_users(person),
} }
if not context['users']:
context['suggested_username'] = auth.generate_unique_username(self.Session(),
person=person)
return context
def profile_make_user(self):
"""
Create a new user account, presumably from the profile view.
"""
app = self.get_rattail_app()
model = self.model
auth = app.get_auth_handler()
person = self.get_instance()
if person.users:
return {'error': f"This person already has {len(person.users)} user accounts."}
data = self.request.json_body
user = auth.make_user(session=self.Session(),
person=person,
username=data['username'],
active=data['active'])
self.Session.flush()
return self.profile_changed_response(person)
def profile_revisions_grid(self, person): def profile_revisions_grid(self, person):
route_prefix = self.get_route_prefix() route_prefix = self.get_route_prefix()
factory = self.get_grid_factory() factory = self.get_grid_factory()
@ -1787,6 +1816,15 @@ class PersonView(MasterView):
route_name=f'{route_prefix}.profile_tab_user', route_name=f'{route_prefix}.profile_tab_user',
renderer='json') renderer='json')
# profile - make user
config.add_route(f'{route_prefix}.profile_make_user',
f'{instance_url_prefix}/make-user',
request_method='POST')
config.add_view(cls, attr='profile_make_user',
route_name=f'{route_prefix}.profile_make_user',
permission='users.create',
renderer='json')
# profile - revisions data # profile - revisions data
config.add_tailbone_permission('people_profile', config.add_tailbone_permission('people_profile',
'people_profile.view_versions', 'people_profile.view_versions',