diff options
Diffstat (limited to 'apps/workflowengine/src/components/Checks/RequestUserGroup.vue')
-rw-r--r-- | apps/workflowengine/src/components/Checks/RequestUserGroup.vue | 118 |
1 files changed, 81 insertions, 37 deletions
diff --git a/apps/workflowengine/src/components/Checks/RequestUserGroup.vue b/apps/workflowengine/src/components/Checks/RequestUserGroup.vue index ba55d88c81c..f9606b7ca26 100644 --- a/apps/workflowengine/src/components/Checks/RequestUserGroup.vue +++ b/apps/workflowengine/src/components/Checks/RequestUserGroup.vue @@ -1,44 +1,31 @@ <!-- - - @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net> - - - - @author Julius Härtl <jus@bitgrid.net> - - - - @license GNU AGPL version 3 or any later version - - - - This program is free software: you can redistribute it and/or modify - - it under the terms of the GNU Affero General Public License as - - published by the Free Software Foundation, either version 3 of the - - License, or (at your option) any later version. - - - - This program is distributed in the hope that it will be useful, - - but WITHOUT ANY WARRANTY; without even the implied warranty of - - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU Affero General Public License for more details. - - - - You should have received a copy of the GNU Affero General Public License - - along with this program. If not, see <http://www.gnu.org/licenses/>. - - - --> - + - SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors + - SPDX-License-Identifier: AGPL-3.0-or-later +--> <template> <div> - <NcMultiselect :value="currentValue" + <NcSelect :aria-label-combobox="t('workflowengine', 'Select groups')" + :aria-label-listbox="t('workflowengine', 'Groups')" + :clearable="false" :loading="status.isLoading && groups.length === 0" + :placeholder="t('workflowengine', 'Type to search for group …')" :options="groups" - :multiple="false" + :model-value="currentValue" label="displayname" - track-by="id" - @search-change="searchAsync" - @input="(value) => $emit('input', value.id)" /> + @search="searchAsync" + @input="update" /> </div> </template> <script> -import NcMultiselect from '@nextcloud/vue/dist/Components/NcMultiselect' -import axios from '@nextcloud/axios' +import { translate as t } from '@nextcloud/l10n' import { generateOcsUrl } from '@nextcloud/router' +import axios from '@nextcloud/axios' +import NcSelect from '@nextcloud/vue/components/NcSelect' + const groups = [] +const wantedGroups = [] const status = { isLoading: false, } @@ -46,10 +33,10 @@ const status = { export default { name: 'RequestUserGroup', components: { - NcMultiselect, + NcSelect, }, props: { - value: { + modelValue: { type: String, default: '', }, @@ -58,28 +45,52 @@ export default { default: () => { return {} }, }, }, + emits: ['update:model-value'], data() { return { groups, status, + wantedGroups, + newValue: '', } }, computed: { - currentValue() { - return this.groups.find(group => group.id === this.value) || null + currentValue: { + get() { + return this.groups.find(group => group.id === this.newValue) || null + }, + set(value) { + this.newValue = value + }, + }, + }, + watch: { + modelValue() { + this.updateInternalValue() }, }, async mounted() { + // If empty, load first chunk of groups if (this.groups.length === 0) { await this.searchAsync('') } - if (this.currentValue === null) { - await this.searchAsync(this.value) + // If a current group is set but not in our list of groups then search for that group + if (this.currentValue === null && this.newValue) { + await this.searchAsync(this.newValue) } }, methods: { + t, + searchAsync(searchQuery) { if (this.status.isLoading) { + if (searchQuery) { + // The first 20 groups are loaded up front (indicated by an + // empty searchQuery parameter), afterwards we may load + // groups that have not been fetched yet, but are used + // in existing rules. + this.enqueueWantedGroup(searchQuery) + } return } @@ -92,21 +103,54 @@ export default { }) }) this.status.isLoading = false + this.findGroupByQueue() }, (error) => { console.error('Error while loading group list', error.response) }) }, + async updateInternalValue() { + if (!this.newValue) { + await this.searchAsync(this.modelValue) + } + this.newValue = this.modelValue + }, addGroup(group) { const index = this.groups.findIndex((item) => item.id === group.id) if (index === -1) { this.groups.push(group) } }, + hasGroup(group) { + const index = this.groups.findIndex((item) => item.id === group) + return index > -1 + }, + update(value) { + this.newValue = value.id + this.$emit('update:model-value', this.newValue) + }, + enqueueWantedGroup(expectedGroupId) { + const index = this.wantedGroups.findIndex((groupId) => groupId === expectedGroupId) + if (index === -1) { + this.wantedGroups.push(expectedGroupId) + } + }, + async findGroupByQueue() { + let nextQuery + do { + nextQuery = this.wantedGroups.shift() + if (this.hasGroup(nextQuery)) { + nextQuery = undefined + } + } while (!nextQuery && this.wantedGroups.length > 0) + if (nextQuery) { + await this.searchAsync(nextQuery) + } + }, }, } </script> <style scoped> - .multiselect { - width: 100%; - } +.v-select { + width: 100%; +} </style> |