aboutsummaryrefslogtreecommitdiffstats
path: root/apps/settings/src/components/Users/NewUserDialog.vue
diff options
context:
space:
mode:
Diffstat (limited to 'apps/settings/src/components/Users/NewUserDialog.vue')
-rw-r--r--apps/settings/src/components/Users/NewUserDialog.vue116
1 files changed, 72 insertions, 44 deletions
diff --git a/apps/settings/src/components/Users/NewUserDialog.vue b/apps/settings/src/components/Users/NewUserDialog.vue
index 26e4afbd924..ef401b565fa 100644
--- a/apps/settings/src/components/Users/NewUserDialog.vue
+++ b/apps/settings/src/components/Users/NewUserDialog.vue
@@ -61,32 +61,36 @@
:required="newUser.password === '' || settings.newUserRequireEmail" />
<div class="dialog__item">
<NcSelect class="dialog__select"
+ data-test="groups"
:input-label="!settings.isAdmin && !settings.isDelegatedAdmin ? t('settings', 'Member of the following groups (required)') : t('settings', 'Member of the following groups')"
:placeholder="t('settings', 'Set account groups')"
:disabled="loading.groups || loading.all"
- :options="canAddGroups"
+ :options="availableGroups"
:value="newUser.groups"
label="name"
:close-on-select="false"
:multiple="true"
- :taggable="true"
+ :taggable="settings.isAdmin || settings.isDelegatedAdmin"
:required="!settings.isAdmin && !settings.isDelegatedAdmin"
- @input="handleGroupInput"
- @option:created="createGroup" />
+ :create-option="(value) => ({ id: value, name: value, isCreating: true })"
+ @search="searchGroups"
+ @option:created="createGroup"
+ @option:selected="options => addGroup(options.at(-1))" />
<!-- If user is not admin, they are a subadmin.
Subadmins can't create users outside their groups
Therefore, empty select is forbidden -->
</div>
- <div v-if="subAdminsGroups.length > 0"
- class="dialog__item">
+ <div class="dialog__item">
<NcSelect v-model="newUser.subAdminsGroups"
class="dialog__select"
:input-label="t('settings', 'Admin of the following groups')"
:placeholder="t('settings', 'Set account as admin for …')"
- :options="subAdminsGroups"
+ :disabled="loading.groups || loading.all"
+ :options="availableGroups"
:close-on-select="false"
:multiple="true"
- label="name" />
+ label="name"
+ @search="searchGroups" />
</div>
<div class="dialog__item">
<NcSelect v-model="newUser.quota"
@@ -136,11 +140,14 @@
<script>
import { formatFileSize, parseFileSize } from '@nextcloud/files'
-import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
-import NcDialog from '@nextcloud/vue/dist/Components/NcDialog.js'
-import NcPasswordField from '@nextcloud/vue/dist/Components/NcPasswordField.js'
-import NcSelect from '@nextcloud/vue/dist/Components/NcSelect.js'
-import NcTextField from '@nextcloud/vue/dist/Components/NcTextField.js'
+import NcButton from '@nextcloud/vue/components/NcButton'
+import NcDialog from '@nextcloud/vue/components/NcDialog'
+import NcPasswordField from '@nextcloud/vue/components/NcPasswordField'
+import NcSelect from '@nextcloud/vue/components/NcSelect'
+import NcTextField from '@nextcloud/vue/components/NcTextField'
+
+import { searchGroups } from '../../service/groups.ts'
+import logger from '../../logger.ts'
export default {
name: 'NewUserDialog',
@@ -177,6 +184,8 @@ export default {
managerInputLabel: t('settings', 'Manager'),
// TRANSLATORS This string describes a manager in the context of an organization
managerLabel: t('settings', 'Set line manager'),
+ // Cancelable promise for search groups request
+ promise: null,
}
},
@@ -200,27 +209,12 @@ export default {
return this.$store.getters.getPasswordPolicyMinLength
},
- groups() {
- // data provided php side + remove the recent and disabled groups
- return this.$store.getters.getGroups
- .filter(group => group.id !== '__nc_internal_recent' && group.id !== 'disabled')
- .sort((a, b) => a.name.localeCompare(b.name))
- },
-
- subAdminsGroups() {
- // data provided php side
- return this.$store.getters.getSubadminGroups
- },
+ availableGroups() {
+ const groups = (this.settings.isAdmin || this.settings.isDelegatedAdmin)
+ ? this.$store.getters.getSortedGroups
+ : this.$store.getters.getSubAdminGroups
- canAddGroups() {
- // disabled if no permission to add new users to group
- return this.groups.map(group => {
- // clone object because we don't want
- // to edit the original groups
- group = Object.assign({}, group)
- group.$isDisabled = group.canAdd === false
- return group
- })
+ return groups.filter(group => group.id !== '__nc_internal_recent' && group.id !== 'disabled')
},
languages() {
@@ -281,13 +275,32 @@ export default {
}
},
- handleGroupInput(groups) {
- /**
- * Filter out groups with no id to prevent duplicate selected options
- *
- * Created groups are added programmatically by `createGroup()`
- */
- this.newUser.groups = groups.filter(group => Boolean(group.id))
+ async searchGroups(query, toggleLoading) {
+ if (!this.settings.isAdmin && !this.settings.isDelegatedAdmin) {
+ // managers cannot search for groups
+ return
+ }
+
+ if (this.promise) {
+ this.promise.cancel()
+ }
+ toggleLoading(true)
+ try {
+ this.promise = searchGroups({
+ search: query,
+ offset: 0,
+ limit: 25,
+ })
+ const groups = await this.promise
+ // Populate store from server request
+ for (const group of groups) {
+ this.$store.commit('addGroup', group)
+ }
+ } catch (error) {
+ logger.error(t('settings', 'Failed to search groups'), { error })
+ }
+ this.promise = null
+ toggleLoading(false)
},
/**
@@ -300,11 +313,26 @@ export default {
this.loading.groups = true
try {
await this.$store.dispatch('addGroup', gid)
- this.newUser.groups.push(this.groups.find(group => group.id === gid))
- this.loading.groups = false
+ this.newUser.groups.push({ id: gid, name: gid })
} catch (error) {
- this.loading.groups = false
+ logger.error(t('settings', 'Failed to create group'), { error })
+ }
+ this.loading.groups = false
+ },
+
+ /**
+ * Add user to group
+ *
+ * @param {object} group Group object
+ */
+ async addGroup(group) {
+ if (group.isCreating) {
+ return
+ }
+ if (group.canAdd === false) {
+ return
}
+ this.newUser.groups.push(group)
},
/**
@@ -318,7 +346,7 @@ export default {
const validQuota = OC.Util.computerFileSize(quota)
if (validQuota !== null && validQuota >= 0) {
// unify format output
- quota = formatFileSize(parseFileSize(quota))
+ quota = formatFileSize(parseFileSize(quota, true))
this.newUser.quota = { id: quota, label: quota }
return this.newUser.quota
}