aboutsummaryrefslogtreecommitdiffstats
path: root/apps/workflowengine/src/components/Checks/RequestUserGroup.vue
diff options
context:
space:
mode:
Diffstat (limited to 'apps/workflowengine/src/components/Checks/RequestUserGroup.vue')
-rw-r--r--apps/workflowengine/src/components/Checks/RequestUserGroup.vue156
1 files changed, 156 insertions, 0 deletions
diff --git a/apps/workflowengine/src/components/Checks/RequestUserGroup.vue b/apps/workflowengine/src/components/Checks/RequestUserGroup.vue
new file mode 100644
index 00000000000..f9606b7ca26
--- /dev/null
+++ b/apps/workflowengine/src/components/Checks/RequestUserGroup.vue
@@ -0,0 +1,156 @@
+<!--
+ - SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
+ - SPDX-License-Identifier: AGPL-3.0-or-later
+-->
+<template>
+ <div>
+ <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"
+ :model-value="currentValue"
+ label="displayname"
+ @search="searchAsync"
+ @input="update" />
+ </div>
+</template>
+
+<script>
+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,
+}
+
+export default {
+ name: 'RequestUserGroup',
+ components: {
+ NcSelect,
+ },
+ props: {
+ modelValue: {
+ type: String,
+ default: '',
+ },
+ check: {
+ type: Object,
+ default: () => { return {} },
+ },
+ },
+ emits: ['update:model-value'],
+ data() {
+ return {
+ groups,
+ status,
+ wantedGroups,
+ newValue: '',
+ }
+ },
+ computed: {
+ 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 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
+ }
+
+ this.status.isLoading = true
+ return axios.get(generateOcsUrl('cloud/groups/details?limit=20&search={searchQuery}', { searchQuery })).then((response) => {
+ response.data.ocs.data.groups.forEach((group) => {
+ this.addGroup({
+ id: group.id,
+ displayname: group.displayname,
+ })
+ })
+ 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>
+.v-select {
+ width: 100%;
+}
+</style>