Replace dropdowns with autocomplete, for "find principals by perm"

This commit is contained in:
Lance Edgar 2023-10-18 17:35:14 -05:00
parent f86cc83996
commit 659f5a8fe1
3 changed files with 173 additions and 47 deletions

View file

@ -16,31 +16,52 @@
<div>
${h.form(request.current_route_url(), method='GET', **{'@submit': 'formSubmitting = true'})}
<div style="margin-left: 10rem; max-width: 50%;">
${h.hidden('permission_group', **{':value': 'selectedGroup'})}
<b-field label="Permission Group" horizontal>
<b-select name="permission_group"
v-model="selectedGroup"
@input="selectGroup">
<option v-for="groupkey in sortedGroups"
:key="groupkey"
:value="groupkey">
{{ permissionGroups[groupkey].label }}
</option>
</b-select>
<b-autocomplete v-if="!selectedGroup"
ref="permissionGroupAutocomplete"
v-model="permissionGroupTerm"
:data="permissionGroupChoices"
field="groupkey"
:custom-formatter="filtr => filtr.label"
open-on-focus
keep-first
icon-pack="fas"
clearable
clear-on-select
@select="permissionGroupSelect">
</b-autocomplete>
<b-button v-if="selectedGroup"
@click="permissionGroupReset()">
{{ permissionGroups[selectedGroup].label }}
</b-button>
</b-field>
${h.hidden('permission', **{':value': 'selectedPermission'})}
<b-field label="Permission" horizontal>
<b-select name="permission"
v-model="selectedPermission">
<option v-for="perm in groupPermissions"
:key="perm.permkey"
:value="perm.permkey">
{{ perm.label }}
</option>
</b-select>
<b-autocomplete v-if="!selectedPermission"
ref="permissionAutocomplete"
v-model="permissionTerm"
:data="permissionChoices"
field="permkey"
:custom-formatter="filtr => filtr.label"
open-on-focus
keep-first
icon-pack="fas"
clearable
clear-on-select
@select="permissionSelect">
</b-autocomplete>
<b-button v-if="selectedPermission"
@click="permissionReset()">
{{ selectedPermissionLabel }}
</b-button>
</b-field>
<div class="buttons">
<b-field horizontal>
<div class="buttons" style="margin-top: 1rem;">
<once-button tag="a"
href="${request.current_route_url(_query=None)}"
text="Reset Form">
@ -53,7 +74,9 @@
{{ formSubmitting ? "Working, please wait..." : "Find ${model_title_plural}" }}
</b-button>
</div>
</b-field>
</div>
${h.end_form()}
% if principals is not None:
@ -91,24 +114,114 @@
data() {
return {
groupPermissions: ${json.dumps(buefy_perms.get(selected_group, {}).get('permissions', []))|n},
permissionGroupTerm: '',
permissionTerm: '',
selectedGroup: ${json.dumps(selected_group)|n},
% if selected_permission:
selectedPermission: ${json.dumps(selected_permission)|n},
% elif selected_group in buefy_perms:
selectedPermission: ${json.dumps(buefy_perms[selected_group]['permissions'][0]['permkey'])|n},
% else:
selectedPermission: null,
% endif
selectedPermissionLabel: ${json.dumps(selected_permission_label or '')|n},
formSubmitting: false,
}
},
computed: {
permissionGroupChoices() {
// collect all groups
let choices = []
for (let groupkey of this.sortedGroups) {
choices.push(this.permissionGroups[groupkey])
}
// parse list of search terms
let terms = []
for (let term of this.permissionGroupTerm.toLowerCase().split(' ')) {
term = term.trim()
if (term) {
terms.push(term)
}
}
// filter groups by search terms
choices = choices.filter(option => {
let label = option.label.toLowerCase()
for (let term of terms) {
if (label.indexOf(term) < 0) {
return false
}
}
return true
})
return choices
},
permissionChoices() {
// collect all permissions for current group
let choices = this.groupPermissions
// parse list of search terms
let terms = []
for (let term of this.permissionTerm.toLowerCase().split(' ')) {
term = term.trim()
if (term) {
terms.push(term)
}
}
// filter permissions by search terms
choices = choices.filter(option => {
let label = option.label.toLowerCase()
for (let term of terms) {
if (label.indexOf(term) < 0) {
return false
}
}
return true
})
return choices
},
},
methods: {
selectGroup(groupkey) {
permissionGroupSelect(option) {
this.selectedPermission = null
this.selectedPermissionLabel = null
if (option) {
this.selectedGroup = option.groupkey
this.groupPermissions = this.permissionGroups[option.groupkey].permissions
this.$nextTick(() => {
this.$refs.permissionAutocomplete.focus()
})
}
},
// re-populate Permission dropdown, auto-select first option
this.groupPermissions = this.permissionGroups[groupkey].permissions
this.selectedPermission = this.groupPermissions[0].permkey
permissionGroupReset() {
this.selectedGroup = null
this.selectedPermission = null
this.selectedPermissionLabel = ''
this.$nextTick(() => {
this.$refs.permissionGroupAutocomplete.focus()
})
},
permissionSelect(option) {
if (option) {
this.selectedPermission = option.permkey
this.selectedPermissionLabel = option.label
}
},
permissionReset() {
this.selectedPermission = null
this.selectedPermissionLabel = null
this.permissionTerm = ''
this.$nextTick(() => {
this.$refs.permissionAutocomplete.focus()
})
},
}
})

View file

@ -3,8 +3,8 @@
<%def name="context_menu_items()">
${parent.context_menu_items()}
% if request.has_perm('{}.find_by_perm'.format(permission_prefix)):
<li>${h.link_to("Find {} with Permission X".format(model_title_plural), url('{}.find_by_perm'.format(route_prefix)))}</li>
% if master.has_perm('find_by_perm'):
<li>${h.link_to(f"Find {model_title_plural} by Permission", url(f'{route_prefix}.find_by_perm'))}</li>
% endif
</%def>

View file

@ -77,7 +77,20 @@ class PrincipalMasterView(MasterView):
perms = self.get_buefy_perms_data(sorted_perms)
context['buefy_perms'] = perms
context['buefy_sorted_groups'] = list(perms)
context['selected_group'] = permission_group or 'common'
if permission_group and permission_group not in perms:
permission_group = None
if permission:
if permission_group:
group = dict([(p['permkey'], p) for p in perms[permission_group]['permissions']])
if permission in group:
context['selected_permission_label'] = group[permission]['label']
else:
permission = None
else:
permission = None
context['selected_group'] = permission_group
context['selected_permission'] = permission
return self.render_to_response('find_by_perm', context)