mirror of
https://github.com/nextcloud/server.git
synced 2026-05-28 04:32:30 -04:00
Merge pull request #53248 from nextcloud/backport/52776/stable31
[stable31] fix(accounts): enhance UX for groups assignment
This commit is contained in:
commit
1c96d26e74
9 changed files with 63 additions and 36 deletions
|
|
@ -42,7 +42,7 @@
|
|||
<NcAppNavigationList class="account-management__group-list"
|
||||
aria-describedby="group-list-desc"
|
||||
data-cy-users-settings-navigation-groups="custom">
|
||||
<GroupListItem v-for="group in userGroups"
|
||||
<GroupListItem v-for="group in filteredGroups"
|
||||
:id="group.id"
|
||||
ref="groupListItems"
|
||||
:key="group.id"
|
||||
|
|
@ -96,7 +96,11 @@ const selectedGroup = computed(() => route.params?.selectedGroup)
|
|||
/** Current active group - URL decoded */
|
||||
const selectedGroupDecoded = computed(() => selectedGroup.value ? decodeURIComponent(selectedGroup.value) : null)
|
||||
/** All available groups */
|
||||
const groups = computed(() => store.getters.getSortedGroups)
|
||||
const groups = computed(() => {
|
||||
return isAdminOrDelegatedAdmin.value
|
||||
? store.getters.getSortedGroups
|
||||
: store.getters.getSubAdminGroups
|
||||
})
|
||||
/** User groups */
|
||||
const { userGroups } = useFormatGroups(groups)
|
||||
/** Server settings for current user */
|
||||
|
|
@ -119,6 +123,14 @@ const loadingGroups = ref(false)
|
|||
const offset = ref(0)
|
||||
/** Search query for groups */
|
||||
const groupsSearchQuery = ref('')
|
||||
const filteredGroups = computed(() => {
|
||||
if (isAdminOrDelegatedAdmin.value) {
|
||||
return userGroups.value
|
||||
}
|
||||
|
||||
const substring = groupsSearchQuery.value.toLowerCase()
|
||||
return userGroups.value.filter(group => group.id.toLowerCase().search(substring) !== -1 || group.title.toLowerCase().search(substring) !== -1)
|
||||
})
|
||||
|
||||
const groupListItems = ref([])
|
||||
const lastGroupListItem = computed(() => {
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@
|
|||
:input-label="t('settings', 'Admin of the following groups')"
|
||||
:placeholder="t('settings', 'Set account as admin for …')"
|
||||
:disabled="loading.groups || loading.all"
|
||||
:options="subAdminsGroups"
|
||||
:options="availableGroups"
|
||||
:close-on-select="false"
|
||||
:multiple="true"
|
||||
label="name"
|
||||
|
|
@ -179,7 +179,6 @@ export default {
|
|||
|
||||
data() {
|
||||
return {
|
||||
availableGroups: [],
|
||||
possibleManagers: [],
|
||||
// TRANSLATORS This string describes a manager in the context of an organization
|
||||
managerInputLabel: t('settings', 'Manager'),
|
||||
|
|
@ -210,9 +209,12 @@ export default {
|
|||
return this.$store.getters.getPasswordPolicyMinLength
|
||||
},
|
||||
|
||||
subAdminsGroups() {
|
||||
// data provided php side
|
||||
return this.availableGroups.filter(group => group.id !== 'admin' && group.id !== '__nc_internal_recent' && group.id !== 'disabled')
|
||||
availableGroups() {
|
||||
const groups = (this.settings.isAdmin || this.settings.isDelegatedAdmin)
|
||||
? this.$store.getters.getSortedGroups
|
||||
: this.$store.getters.getSubAdminGroups
|
||||
|
||||
return groups.filter(group => group.id !== '__nc_internal_recent' && group.id !== 'disabled')
|
||||
},
|
||||
|
||||
languages() {
|
||||
|
|
@ -236,13 +238,6 @@ export default {
|
|||
},
|
||||
|
||||
mounted() {
|
||||
// admins also can assign the system groups
|
||||
if (this.isAdmin || this.isDelegatedAdmin) {
|
||||
this.availableGroups = this.$store.getters.getSortedGroups.filter(group => group.id !== '__nc_internal_recent' && group.id !== 'disabled')
|
||||
} else {
|
||||
this.availableGroups = [...this.$store.getters.getSubAdminGroups]
|
||||
}
|
||||
|
||||
this.$refs.username?.focus?.()
|
||||
},
|
||||
|
||||
|
|
@ -281,7 +276,7 @@ export default {
|
|||
},
|
||||
|
||||
async searchGroups(query, toggleLoading) {
|
||||
if (!this.isAdmin && !this.isDelegatedAdmin) {
|
||||
if (!this.settings.isAdmin && !this.settings.isDelegatedAdmin) {
|
||||
// managers cannot search for groups
|
||||
return
|
||||
}
|
||||
|
|
@ -297,7 +292,10 @@ export default {
|
|||
limit: 25,
|
||||
})
|
||||
const groups = await this.promise
|
||||
this.availableGroups = groups
|
||||
// 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 })
|
||||
}
|
||||
|
|
@ -315,7 +313,6 @@ export default {
|
|||
this.loading.groups = true
|
||||
try {
|
||||
await this.$store.dispatch('addGroup', gid)
|
||||
this.availableGroups.push({ id: gid, name: gid })
|
||||
this.newUser.groups.push({ id: gid, name: gid })
|
||||
} catch (error) {
|
||||
logger.error(t('settings', 'Failed to create group'), { error })
|
||||
|
|
|
|||
|
|
@ -410,6 +410,18 @@ export default {
|
|||
return encodeURIComponent(this.user.id + this.rand)
|
||||
},
|
||||
|
||||
availableGroups() {
|
||||
const groups = (this.settings.isAdmin || this.settings.isDelegatedAdmin)
|
||||
? this.$store.getters.getSortedGroups
|
||||
: this.$store.getters.getSubAdminGroups
|
||||
|
||||
return groups.filter(group => group.id !== '__nc_internal_recent' && group.id !== 'disabled')
|
||||
},
|
||||
|
||||
availableSubAdminGroups() {
|
||||
return this.availableGroups.filter(group => group.id !== 'admin')
|
||||
},
|
||||
|
||||
userGroupsLabels() {
|
||||
return this.userGroups
|
||||
.map(group => group.name ?? group.id)
|
||||
|
|
@ -559,7 +571,11 @@ export default {
|
|||
this.loading.groupsDetails = true
|
||||
try {
|
||||
const groups = await loadUserGroups({ userId: this.user.id })
|
||||
this.availableGroups = this.availableGroups.map(availableGroup => groups.find(group => group.id === availableGroup.id) ?? availableGroup)
|
||||
// Populate store from server request
|
||||
for (const group of groups) {
|
||||
this.$store.commit('addGroup', group)
|
||||
}
|
||||
this.selectedGroups = this.selectedGroups.map(selectedGroup => groups.find(group => group.id === selectedGroup.id) ?? selectedGroup)
|
||||
} catch (error) {
|
||||
logger.error(t('settings', 'Failed to load groups with details'), { error })
|
||||
}
|
||||
|
|
@ -572,7 +588,11 @@ export default {
|
|||
this.loading.subAdminGroupsDetails = true
|
||||
try {
|
||||
const groups = await loadUserSubAdminGroups({ userId: this.user.id })
|
||||
this.availableSubAdminGroups = this.availableSubAdminGroups.map(availableGroup => groups.find(group => group.id === availableGroup.id) ?? availableGroup)
|
||||
// Populate store from server request
|
||||
for (const group of groups) {
|
||||
this.$store.commit('addGroup', group)
|
||||
}
|
||||
this.selectedSubAdminGroups = this.selectedSubAdminGroups.map(selectedGroup => groups.find(group => group.id === selectedGroup.id) ?? selectedGroup)
|
||||
} catch (error) {
|
||||
logger.error(t('settings', 'Failed to load subadmin groups with details'), { error })
|
||||
}
|
||||
|
|
@ -595,8 +615,10 @@ export default {
|
|||
limit: 25,
|
||||
})
|
||||
const groups = await this.promise
|
||||
this.availableGroups = groups
|
||||
this.availableSubAdminGroups = groups.filter(group => group.id !== 'admin')
|
||||
// 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 })
|
||||
}
|
||||
|
|
@ -753,8 +775,6 @@ export default {
|
|||
this.loading.groups = true
|
||||
try {
|
||||
await this.$store.dispatch('addGroup', gid)
|
||||
this.availableGroups.push({ id: gid, name: gid })
|
||||
this.availableSubAdminGroups.push({ id: gid, name: gid })
|
||||
const userid = this.user.id
|
||||
await this.$store.dispatch('addUserGroup', { userid, gid })
|
||||
this.userGroups.push({ id: gid, name: gid })
|
||||
|
|
|
|||
|
|
@ -17,14 +17,12 @@ function formatGroupMenu(group?: IGroup) {
|
|||
return null
|
||||
}
|
||||
|
||||
const item = {
|
||||
return {
|
||||
id: group.id,
|
||||
title: group.name,
|
||||
usercount: group.usercount,
|
||||
count: Math.max(0, group.usercount - group.disabled),
|
||||
usercount: group.usercount ?? 0,
|
||||
count: Math.max(0, (group.usercount ?? 0) - (group.disabled ?? 0)),
|
||||
}
|
||||
|
||||
return item
|
||||
}
|
||||
|
||||
export const useFormatGroups = (groups: Ref<IGroup[]>|ComputedRef<IGroup[]>) => {
|
||||
|
|
|
|||
|
|
@ -43,8 +43,8 @@ export default {
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
availableGroups: this.user.groups.map(id => ({ id, name: id })),
|
||||
availableSubAdminGroups: this.user.subadmin.map(id => ({ id, name: id })),
|
||||
selectedGroups: this.user.groups.map(id => ({ id, name: id })),
|
||||
selectedSubAdminGroups: this.user.subadmin.map(id => ({ id, name: id })),
|
||||
userGroups: this.user.groups.map(id => ({ id, name: id })),
|
||||
userSubAdminGroups: this.user.subadmin.map(id => ({ id, name: id })),
|
||||
}
|
||||
|
|
|
|||
4
dist/settings-users-3239.js
vendored
4
dist/settings-users-3239.js
vendored
File diff suppressed because one or more lines are too long
2
dist/settings-users-3239.js.map
vendored
2
dist/settings-users-3239.js.map
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue