From 30d5b0281140653192ba01fcbd11b0e367af96a0 Mon Sep 17 00:00:00 2001 From: Ferdinand Thiessen Date: Fri, 8 Mar 2024 15:04:16 +0100 Subject: [PATCH] feat(settings): Split account management into navigation and content The should ease the maintenance of it due to reduced complexity. Signed-off-by: Ferdinand Thiessen --- apps/settings/src/components/UserList.vue | 34 +- .../components/Users/UserSettingsDialog.vue | 31 +- .../src/composables/useGroupsNavigation.ts | 52 +++ .../src/main-apps-users-management.ts | 7 +- apps/settings/src/store/index.js | 26 +- apps/settings/src/views/UserManagement.vue | 296 +----------------- .../src/views/UserManagementNavigation.vue | 221 ++++++++++++- apps/settings/src/views/user-types.d.ts | 14 + cypress/e2e/settings/users_columns.cy.ts | 6 +- 9 files changed, 355 insertions(+), 332 deletions(-) create mode 100644 apps/settings/src/composables/useGroupsNavigation.ts create mode 100644 apps/settings/src/views/user-types.d.ts diff --git a/apps/settings/src/components/UserList.vue b/apps/settings/src/components/UserList.vue index 5672788bafe..3ddb617dda5 100644 --- a/apps/settings/src/components/UserList.vue +++ b/apps/settings/src/components/UserList.vue @@ -36,8 +36,7 @@ - + @@ -78,16 +77,16 @@ - - diff --git a/apps/settings/src/composables/useGroupsNavigation.ts b/apps/settings/src/composables/useGroupsNavigation.ts new file mode 100644 index 00000000000..835664fbdc1 --- /dev/null +++ b/apps/settings/src/composables/useGroupsNavigation.ts @@ -0,0 +1,52 @@ +import type { ComputedRef, Ref } from 'vue' +import type { IGroup } from '../views/user-types' + +import { computed } from 'vue' + +/** + * Format a group to a menu entry + * + * @param group the group + */ +function formatGroupMenu(group?: IGroup) { + if (typeof group === 'undefined') { + return null + } + + const item = { + id: group.id, + title: group.name, + usercount: group.usercount, + count: Math.max(0, group.usercount - group.disabled), + } + + return item +} + +export const useFormatGroups = (groups: Ref|ComputedRef) => { + /** + * All non-disabled non-admin groups + */ + const userGroups = computed(() => { + const formatted = groups.value + // filter out disabled and admin + .filter(group => group.id !== 'disabled' && group.id !== 'admin') + // format group + .map(group => formatGroupMenu(group)) + // remove invalid + .filter(group => group !== null) + return formatted as NonNullable>[] + }) + + /** + * The admin group if found otherwise null + */ + const adminGroup = computed(() => formatGroupMenu(groups.value.find(group => group.id === 'admin'))) + + /** + * The group of disabled users + */ + const disabledGroup = computed(() => formatGroupMenu(groups.value.find(group => group.id === 'disabled'))) + + return { adminGroup, disabledGroup, userGroups } +} diff --git a/apps/settings/src/main-apps-users-management.ts b/apps/settings/src/main-apps-users-management.ts index 37d7e9ba821..08f94695355 100644 --- a/apps/settings/src/main-apps-users-management.ts +++ b/apps/settings/src/main-apps-users-management.ts @@ -29,12 +29,13 @@ import { translate as t, translatePlural as n } from '@nextcloud/l10n' import SettingsApp from './views/SettingsApp.vue' import router from './router/index.ts' -import store from './store/index.js' +import { useStore } from './store/index.js' import { getRequestToken } from '@nextcloud/auth' import { PiniaVuePlugin, createPinia } from 'pinia' Vue.use(VTooltip, { defaultHtml: false }) +const store = useStore() sync(store, router) // CSP config for webpack dynamic chunk loading @@ -44,10 +45,6 @@ __webpack_nonce__ = btoa(getRequestToken() ?? '') // bind to window Vue.prototype.t = t Vue.prototype.n = n -Vue.prototype.OC = window.OC -Vue.prototype.OCA = window.OCA -// @ts-expect-error This is a private property we use -Vue.prototype.oc_userconfig = window.oc_userconfig Vue.use(PiniaVuePlugin) const pinia = createPinia() diff --git a/apps/settings/src/store/index.js b/apps/settings/src/store/index.js index 7f477d3882d..809673ec575 100644 --- a/apps/settings/src/store/index.js +++ b/apps/settings/src/store/index.js @@ -45,14 +45,20 @@ const mutations = { }, } -export default new Store({ - modules: { - users, - apps, - settings, - oc, - }, - strict: debug, +let store = null - mutations, -}) +export const useStore = () => { + if (store === null) { + store = new Store({ + modules: { + users, + apps, + settings, + oc, + }, + strict: debug, + mutations, + }) + } + return store +} diff --git a/apps/settings/src/views/UserManagement.vue b/apps/settings/src/views/UserManagement.vue index d25071e63ed..64c5c826560 100644 --- a/apps/settings/src/views/UserManagement.vue +++ b/apps/settings/src/views/UserManagement.vue @@ -21,192 +21,31 @@ --> diff --git a/apps/settings/src/views/UserManagementNavigation.vue b/apps/settings/src/views/UserManagementNavigation.vue index a32313f8edf..4959040a1bf 100644 --- a/apps/settings/src/views/UserManagementNavigation.vue +++ b/apps/settings/src/views/UserManagementNavigation.vue @@ -1,5 +1,222 @@ - + + diff --git a/apps/settings/src/views/user-types.d.ts b/apps/settings/src/views/user-types.d.ts new file mode 100644 index 00000000000..790a9c5b1ae --- /dev/null +++ b/apps/settings/src/views/user-types.d.ts @@ -0,0 +1,14 @@ +export interface IGroup { + id: string + name: string + + /** + * Overall user count + */ + usercount: number + + /** + * Number of disabled users + */ + disabled: number +} diff --git a/cypress/e2e/settings/users_columns.cy.ts b/cypress/e2e/settings/users_columns.cy.ts index 363e0628508..5f2a293b824 100644 --- a/cypress/e2e/settings/users_columns.cy.ts +++ b/cypress/e2e/settings/users_columns.cy.ts @@ -34,7 +34,7 @@ describe('Settings: Show and hide columns', function() { beforeEach(function() { // open the settings dialog - cy.get('.app-navigation-entry__settings').contains('Account management settings').click() + cy.contains('button', 'Account management settings').click() // reset all visibility toggles cy.get('.modal-container #settings-section_visibility-settings input[type="checkbox"]').uncheck({ force: true }) @@ -57,7 +57,7 @@ describe('Settings: Show and hide columns', function() { }) // open the settings dialog - cy.get('.app-navigation-entry__settings').contains('Account management settings').click() + cy.contains('button', 'Account management settings').click() cy.contains('.modal-container', 'Account management settings').within(() => { // enable the language toggle @@ -88,7 +88,7 @@ describe('Settings: Show and hide columns', function() { }) // open the settings dialog - cy.get('.app-navigation-entry__settings').contains('Account management settings').click() + cy.contains('button', 'Account management settings').click() cy.contains('.modal-container', 'Account management settings').within(() => { // disable the last login toggle