From 761e7152a228388f528282f0438df7a78ae67371 Mon Sep 17 00:00:00 2001 From: Ramesh Mane <101566080+rameshmane7218@users.noreply.github.com> Date: Fri, 22 Dec 2023 02:03:16 +0530 Subject: [PATCH 01/21] feat: hook and dropdown menu for user sort management --- .../nc-gui/components/account/UserList.vue | 39 ++++- .../nc-gui/components/account/UserMenu.vue | 89 ++++++++++++ packages/nc-gui/composables/useUserSorts.ts | 133 ++++++++++++++++++ packages/nc-gui/lang/en.json | 4 +- packages/nc-gui/lib/types.ts | 6 + 5 files changed, 263 insertions(+), 8 deletions(-) create mode 100644 packages/nc-gui/components/account/UserMenu.vue create mode 100644 packages/nc-gui/composables/useUserSorts.ts diff --git a/packages/nc-gui/components/account/UserList.vue b/packages/nc-gui/components/account/UserList.vue index c5d5293651..a516ffc5a8 100644 --- a/packages/nc-gui/components/account/UserList.vue +++ b/packages/nc-gui/components/account/UserList.vue @@ -2,7 +2,16 @@ import { OrgUserRoles } from 'nocodb-sdk' import type { OrgUserReqType, RequestParams, UserType } from 'nocodb-sdk' import type { User } from '#imports' -import { extractSdkResponseErrorMsg, iconMap, useApi, useCopy, useDashboard, useDebounceFn, useNuxtApp } from '#imports' +import { + extractSdkResponseErrorMsg, + iconMap, + useApi, + useCopy, + useDashboard, + useDebounceFn, + useNuxtApp, + useUserSorts, +} from '#imports' const { api, isLoading } = useApi() @@ -19,8 +28,14 @@ const { user: loggedInUser } = useGlobal() const { copy } = useCopy() +const { sorts, sortDirection, loadSorts, saveOrUpdate, handleGetSortsData } = useUserSorts() + const users = ref([]) +const sortedUsers = computed(() => { + return handleGetSortsData(users.value, sorts.value) as UserType[] +}) + const currentPage = ref(1) const currentLimit = ref(10) @@ -64,6 +79,7 @@ const loadUsers = useDebounceFn(async (page = currentPage.value, limit = current onMounted(() => { loadUsers() + loadSorts() }) const updateRole = async (userId: string, roles: string) => { @@ -176,10 +192,21 @@ const openDeleteModal = (user: UserType) => {
-
- {{ $t('labels.email') }} +
+ + {{ $t('labels.email') }} + + +
+
+ + {{ $t('objects.role') }} + +
-
{{ $t('objects.role') }}
{{ $t('labels.action') }}
@@ -193,7 +220,7 @@ const openDeleteModal = (user: UserType) => {
{
diff --git a/packages/nc-gui/components/account/UserMenu.vue b/packages/nc-gui/components/account/UserMenu.vue new file mode 100644 index 0000000000..af99ebc0e6 --- /dev/null +++ b/packages/nc-gui/components/account/UserMenu.vue @@ -0,0 +1,89 @@ + + + + + diff --git a/packages/nc-gui/composables/useUserSorts.ts b/packages/nc-gui/composables/useUserSorts.ts new file mode 100644 index 0000000000..15ccccd3e1 --- /dev/null +++ b/packages/nc-gui/composables/useUserSorts.ts @@ -0,0 +1,133 @@ +import rfdc from 'rfdc' +import type { UsersSortType } from '~/lib' +import { useGlobal } from '#imports' + +/** + * Hook for managing user sorts and sort configurations. + * @returns An object containing reactive values and functions related to user sorts. + */ +export function useUserSorts() { + const clone = rfdc() + + const { user } = useGlobal() + + const sorts = ref([]) + + // Key for storing user sort configurations in local storage + const userSortConfigKey = 'userSortConfig' + + // Default user ID if no user found (fallback) + const defaultUserId = 'default' + + /** + * Computed property that returns a record of sort directions based on the current sort configurations. + * @type {ComputedRef>} + */ + const sortDirection: ComputedRef> = computed(() => { + return sorts.value.reduce((acc, curr) => { + acc = { ...acc, [curr.field]: curr.direction } + return acc + }, {} as Record) + }) + + /** + * Loads user sort configurations from local storage based on the current user ID. + */ + function loadSorts(): void { + try { + // Retrieve sort configuration from local storage + const storedConfig = localStorage.getItem(userSortConfigKey) + + const sortConfig = storedConfig ? JSON.parse(storedConfig) : {} + sorts.value = sortConfig + + // Load user-specific sort configurations or default configurations + sorts.value = user.value?.id ? sortConfig[user.value.id] || [] : sortConfig[defaultUserId] || [] + } catch (error) { + console.error('Error while retrieving sort configuration from local storage:', error) + // Set sorts to an empty array in case of an error + sorts.value = [] + } + } + + /** + * Saves or updates a user sort configuration and updates local storage. + * @param {UsersSortType} newSortConfig - The new sort configuration to save or update. + */ + function saveOrUpdate(newSortConfig: UsersSortType): void { + try { + const fieldIndex = sorts.value.findIndex((sort) => sort.field === newSortConfig.field) + if (newSortConfig.direction) { + if (fieldIndex !== -1) { + // Update the direction if the field exists + sorts.value = [ + ...clone(sorts.value).map((sort) => { + if (sort.field === newSortConfig.field) { + sort.direction = newSortConfig.direction + } + return sort + }), + ] + } else { + // Add a new sort configuration if the field does not exist + sorts.value = [...clone(sorts.value), newSortConfig] + } + } else { + if (fieldIndex !== -1) { + // Remove the sort configuration if the field exists and direction is not present + sorts.value = [...clone(sorts.value).filter((sort) => sort.field !== newSortConfig.field)] + } + } + + // Update local storage with the new sort configurations + const storedConfig = localStorage.getItem(userSortConfigKey) + const sortConfig = storedConfig ? JSON.parse(storedConfig) : {} + + if (user.value?.id) { + // Save or delete user-specific sort configurations + if (sorts.value.length) { + sortConfig[user.value.id] = sorts.value + } else { + delete sortConfig[user.value.id] + } + } else { + // Save or delete default user sort configurations + sortConfig[defaultUserId] = sorts.value + } + + localStorage.setItem(userSortConfigKey, JSON.stringify(sortConfig)) + } catch (error) { + console.error('Error while retrieving sort configuration from local storage:', error) + } + } + + /** + * Sorts and returns a deep copy of an array of objects based on the provided sort configurations. + * + * @param data - The array of objects to be sorted. + * @param sortsConfig - The array of sort configurations. + * @returns A new array containing sorted objects. + * @template T - The type of objects in the input array. + */ + function handleGetSortsData>(data: T[], sortsConfig: UsersSortType[] = sorts.value): T[] { + const sortedData = clone(data).sort((a, b) => { + let sortCondition = 0 + + for (const { field, direction } of sortsConfig) { + if (a[field]) continue + + if (direction === 'asc') { + sortCondition = sortCondition || a[field]?.localeCompare(b[field]) + } else if (direction === 'desc') { + sortCondition = sortCondition || b[field]?.localeCompare(a[field]) + } + } + + return sortCondition + }) + + return sortedData + } + + return { sorts, sortDirection, loadSorts, saveOrUpdate, handleGetSortsData } +} diff --git a/packages/nc-gui/lang/en.json b/packages/nc-gui/lang/en.json index b2875c9f0e..ae26001223 100644 --- a/packages/nc-gui/lang/en.json +++ b/packages/nc-gui/lang/en.json @@ -189,7 +189,8 @@ "shift": "Shift", "enter": "Enter", "seconds": "Seconds", - "paste": "Paste" + "paste": "Paste", + "resetSort": "Reset Sort" }, "objects": { "workspace": "Workspace", @@ -1212,7 +1213,6 @@ "thankYou": "Thank you!", "submittedFormData": "You have successfully submitted the form data.", "editingSystemKeyNotSupported": "Editing system key not supported" - }, "error": { "nameRequired": "Name Required", diff --git a/packages/nc-gui/lib/types.ts b/packages/nc-gui/lib/types.ts index 7643f681ce..0cde7912e3 100644 --- a/packages/nc-gui/lib/types.ts +++ b/packages/nc-gui/lib/types.ts @@ -176,6 +176,11 @@ interface SidebarTableNode extends TableType { isViewsLoading?: boolean } +interface UsersSortType { + field: string + direction?: 'asc' | 'desc' +} + export type { User, ProjectMetaInfo, @@ -201,4 +206,5 @@ export type { ViewPageType, NcButtonSize, SidebarTableNode, + UsersSortType, } From b4bc820be2cbd232c3f8d65a3f440bb56aade2ce Mon Sep 17 00:00:00 2001 From: Ramesh Mane <101566080+rameshmane7218@users.noreply.github.com> Date: Fri, 22 Dec 2023 02:18:14 +0530 Subject: [PATCH 02/21] fix: array for continue issue - user sort management --- packages/nc-gui/composables/useUserSorts.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nc-gui/composables/useUserSorts.ts b/packages/nc-gui/composables/useUserSorts.ts index 15ccccd3e1..2faa0e05aa 100644 --- a/packages/nc-gui/composables/useUserSorts.ts +++ b/packages/nc-gui/composables/useUserSorts.ts @@ -114,7 +114,7 @@ export function useUserSorts() { let sortCondition = 0 for (const { field, direction } of sortsConfig) { - if (a[field]) continue + if (!a[field]) continue if (direction === 'asc') { sortCondition = sortCondition || a[field]?.localeCompare(b[field]) From a87b8c9bd3d27da2c8c75b12a410b592f121c88e Mon Sep 17 00:00:00 2001 From: Ramesh Mane <101566080+rameshmane7218@users.noreply.github.com> Date: Fri, 22 Dec 2023 10:47:52 +0530 Subject: [PATCH 03/21] fix: update handleGetSortsData for single level of user sort --- packages/nc-gui/composables/useUserSorts.ts | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/nc-gui/composables/useUserSorts.ts b/packages/nc-gui/composables/useUserSorts.ts index 2faa0e05aa..9fe603d4ca 100644 --- a/packages/nc-gui/composables/useUserSorts.ts +++ b/packages/nc-gui/composables/useUserSorts.ts @@ -61,16 +61,18 @@ export function useUserSorts() { if (fieldIndex !== -1) { // Update the direction if the field exists sorts.value = [ - ...clone(sorts.value).map((sort) => { - if (sort.field === newSortConfig.field) { - sort.direction = newSortConfig.direction - } - return sort - }), + ...clone(sorts.value) + .map((sort) => { + if (sort.field === newSortConfig.field) { + sort.direction = newSortConfig.direction + } + return sort + }) + .filter((sort) => sort.field !== newSortConfig.field), // For now it is only single level of sorting so remove another sort field ] } else { - // Add a new sort configuration if the field does not exist - sorts.value = [...clone(sorts.value), newSortConfig] + // Add a new sort configuration + sorts.value = [newSortConfig] } } else { if (fieldIndex !== -1) { From fcbb1123e9e8b15d6bd41416500774f13073a9fe Mon Sep 17 00:00:00 2001 From: Ramesh Mane <101566080+rameshmane7218@users.noreply.github.com> Date: Mon, 25 Dec 2023 12:02:01 +0530 Subject: [PATCH 04/21] fix: sort user by roles --- .../nc-gui/components/account/UserList.vue | 2 +- .../components/project/AccessSettings.vue | 12 ++++- packages/nc-gui/composables/useUserSorts.ts | 52 ++++++++++++++++--- 3 files changed, 56 insertions(+), 10 deletions(-) diff --git a/packages/nc-gui/components/account/UserList.vue b/packages/nc-gui/components/account/UserList.vue index a516ffc5a8..57c756a348 100644 --- a/packages/nc-gui/components/account/UserList.vue +++ b/packages/nc-gui/components/account/UserList.vue @@ -28,7 +28,7 @@ const { user: loggedInUser } = useGlobal() const { copy } = useCopy() -const { sorts, sortDirection, loadSorts, saveOrUpdate, handleGetSortsData } = useUserSorts() +const { sorts, sortDirection, loadSorts, saveOrUpdate, handleGetSortsData } = useUserSorts('Org') const users = ref([]) diff --git a/packages/nc-gui/components/project/AccessSettings.vue b/packages/nc-gui/components/project/AccessSettings.vue index 3bed047889..d5f4b4c718 100644 --- a/packages/nc-gui/components/project/AccessSettings.vue +++ b/packages/nc-gui/components/project/AccessSettings.vue @@ -9,7 +9,7 @@ import { } from 'nocodb-sdk' import type { WorkspaceUserRoles } from 'nocodb-sdk' import InfiniteLoading from 'v3-infinite-loading' -import { isEeUI, storeToRefs } from '#imports' +import { isEeUI, storeToRefs, useUserSorts } from '#imports' const basesStore = useBases() const { getProjectUsers, createProjectUser, updateProjectUser, removeProjectUser } = basesStore @@ -17,6 +17,8 @@ const { activeProjectId } = storeToRefs(basesStore) const { orgRoles, baseRoles } = useRoles() +const { sorts, sortDirection, loadSorts, saveOrUpdate, handleGetSortsData } = useUserSorts('Project') + const isSuper = computed(() => orgRoles.value?.[OrgUserRoles.SUPER_ADMIN]) interface Collaborators { @@ -36,6 +38,11 @@ const isLoading = ref(false) const isSearching = ref(false) const accessibleRoles = ref<(typeof ProjectRoles)[keyof typeof ProjectRoles][]>([]) +const sortedCollaborators = computed(() => { + console.log('collaborator', sorts.value, collaborators.value) + return handleGetSortsData([...collaborators.value], sorts.value) +}) + const loadCollaborators = async () => { try { currentPage.value += 1 @@ -150,6 +157,7 @@ onMounted(async () => { } else if (currentRoleIndex !== -1) { accessibleRoles.value = OrderedProjectRoles.slice(currentRoleIndex + 1) } + loadSorts() } catch (e: any) { message.error(await extractSdkResponseErrorMsg(e)) } finally { @@ -192,7 +200,7 @@ onMounted(async () => {
diff --git a/packages/nc-gui/composables/useUserSorts.ts b/packages/nc-gui/composables/useUserSorts.ts index 9fe603d4ca..a7410ebe1d 100644 --- a/packages/nc-gui/composables/useUserSorts.ts +++ b/packages/nc-gui/composables/useUserSorts.ts @@ -1,12 +1,13 @@ import rfdc from 'rfdc' import type { UsersSortType } from '~/lib' import { useGlobal } from '#imports' +import { extractRolesObj, ProjectRoles, OrgUserRoles, WorkspaceUserRoles } from 'nocodb-sdk' /** * Hook for managing user sorts and sort configurations. * @returns An object containing reactive values and functions related to user sorts. */ -export function useUserSorts() { +export function useUserSorts(roleType: 'Workspace' | 'Org' | 'Project') { const clone = rfdc() const { user } = useGlobal() @@ -68,7 +69,7 @@ export function useUserSorts() { } return sort }) - .filter((sort) => sort.field !== newSortConfig.field), // For now it is only single level of sorting so remove another sort field + .filter((sort) => sort.field === newSortConfig.field), // For now it is only single level of sorting so remove another sort field ] } else { // Add a new sort configuration @@ -112,16 +113,53 @@ export function useUserSorts() { * @template T - The type of objects in the input array. */ function handleGetSortsData>(data: T[], sortsConfig: UsersSortType[] = sorts.value): T[] { - const sortedData = clone(data).sort((a, b) => { + let userRoleOrder: string[] = [] + if (roleType === 'Workspace') { + userRoleOrder = Object.values(WorkspaceUserRoles) + } else if (roleType === 'Org') { + userRoleOrder = Object.values(OrgUserRoles) + } else if (roleType === 'Project') { + userRoleOrder = Object.values(ProjectRoles) + } + data = clone(data) + // let superUserIndex = data.findIndex((user) => user?.roles?.includes('super')) + // let superUser = superUserIndex !== -1 ? data.splice(superUserIndex, 1) : null + // console.log('super', superUser) + const sortedData = data.sort((a, b) => { let sortCondition = 0 for (const { field, direction } of sortsConfig) { if (!a[field]) continue - if (direction === 'asc') { - sortCondition = sortCondition || a[field]?.localeCompare(b[field]) - } else if (direction === 'desc') { - sortCondition = sortCondition || b[field]?.localeCompare(a[field]) + if (field === 'roles') { + for (const role of userRoleOrder) { + const indexA = a?.roles?.split(',')?.indexOf(role) ?? -1 + const indexB = b?.roles?.split(',')?.indexOf(role) ?? -1 + + // if (indexA === -1) { + // sortCondition = sortCondition || direction === 'asc' ? 1 : -1 // Role A is missing, so it should come last + // break + // } + + // if (indexB === -1) { + // sortCondition = sortCondition || direction === 'asc' ? -1 : 1 // Role B is missing, so it should come last + // break + // } + + if (direction === 'asc') { + sortCondition = sortCondition || indexA - indexB + break + } else if (direction === 'desc') { + sortCondition = sortCondition || indexB - indexA + break + } + } + } else { + if (direction === 'asc') { + sortCondition = sortCondition || a[field]?.localeCompare(b[field]) + } else if (direction === 'desc') { + sortCondition = sortCondition || b[field]?.localeCompare(a[field]) + } } } From 114da7e2c00477437280f4c8da03cb1cdaeb1ca8 Mon Sep 17 00:00:00 2001 From: Ramesh Mane <101566080+rameshmane7218@users.noreply.github.com> Date: Wed, 27 Dec 2023 09:13:58 +0530 Subject: [PATCH 05/21] fix: user roles sort issue --- .../nc-gui/components/account/UserList.vue | 11 ++ .../components/project/AccessSettings.vue | 21 +++- packages/nc-gui/composables/useUserSorts.ts | 112 +++++++----------- packages/nc-gui/lib/types.ts | 2 +- 4 files changed, 72 insertions(+), 74 deletions(-) diff --git a/packages/nc-gui/components/account/UserList.vue b/packages/nc-gui/components/account/UserList.vue index 57c756a348..ddb661451c 100644 --- a/packages/nc-gui/components/account/UserList.vue +++ b/packages/nc-gui/components/account/UserList.vue @@ -12,6 +12,7 @@ import { useNuxtApp, useUserSorts, } from '#imports' +import rfdc from 'rfdc' const { api, isLoading } = useApi() @@ -33,6 +34,7 @@ const { sorts, sortDirection, loadSorts, saveOrUpdate, handleGetSortsData } = us const users = ref([]) const sortedUsers = computed(() => { + console.log('users', users.value) return handleGetSortsData(users.value, sorts.value) as UserType[] }) @@ -54,6 +56,8 @@ const pagination = reactive({ position: ['bottomCenter'], }) +const clone = rfdc() + const loadUsers = useDebounceFn(async (page = currentPage.value, limit = currentLimit.value) => { currentPage.value = page try { @@ -89,6 +93,13 @@ const updateRole = async (userId: string, roles: string) => { } as OrgUserReqType) message.success(t('msg.success.roleUpdated')) + users.value = clone(users.value).map((user) => { + if (user.id === userId) { + user['roles'] = roles + } + return user + }) + $e('a:org-user:role-updated', { role: roles }) } catch (e: any) { message.error(await extractSdkResponseErrorMsg(e)) diff --git a/packages/nc-gui/components/project/AccessSettings.vue b/packages/nc-gui/components/project/AccessSettings.vue index d5f4b4c718..a1a7f96539 100644 --- a/packages/nc-gui/components/project/AccessSettings.vue +++ b/packages/nc-gui/components/project/AccessSettings.vue @@ -39,8 +39,7 @@ const isSearching = ref(false) const accessibleRoles = ref<(typeof ProjectRoles)[keyof typeof ProjectRoles][]>([]) const sortedCollaborators = computed(() => { - console.log('collaborator', sorts.value, collaborators.value) - return handleGetSortsData([...collaborators.value], sorts.value) + return handleGetSortsData(collaborators.value, sorts.value) }) const loadCollaborators = async () => { @@ -91,6 +90,10 @@ const loadListData = async ($state: any) => { $state.loaded() } +const updateCollaboratorLocalState = ()=>{ + +} + const updateCollaborator = async (collab: any, roles: ProjectRoles) => { try { if ( @@ -193,9 +196,19 @@ onMounted(async () => {
-
{{ $t('objects.users') }}
+
+ + {{ $t('objects.users') }} + + +
{{ $t('title.dateJoined') }}
-
{{ $t('general.access') }}
+
+ + {{ $t('general.access') }} + + +
diff --git a/packages/nc-gui/composables/useUserSorts.ts b/packages/nc-gui/composables/useUserSorts.ts index a7410ebe1d..9287b8199b 100644 --- a/packages/nc-gui/composables/useUserSorts.ts +++ b/packages/nc-gui/composables/useUserSorts.ts @@ -12,7 +12,7 @@ export function useUserSorts(roleType: 'Workspace' | 'Org' | 'Project') { const { user } = useGlobal() - const sorts = ref([]) + const sorts = ref({}) // Key for storing user sort configurations in local storage const userSortConfigKey = 'userSortConfig' @@ -25,10 +25,10 @@ export function useUserSorts(roleType: 'Workspace' | 'Org' | 'Project') { * @type {ComputedRef>} */ const sortDirection: ComputedRef> = computed(() => { - return sorts.value.reduce((acc, curr) => { - acc = { ...acc, [curr.field]: curr.direction } - return acc - }, {} as Record) + if (sorts.value.field) { + return { [sorts.value.field]: sorts.value.direction } as Record + } + return {} as Record }) /** @@ -43,11 +43,11 @@ export function useUserSorts(roleType: 'Workspace' | 'Org' | 'Project') { sorts.value = sortConfig // Load user-specific sort configurations or default configurations - sorts.value = user.value?.id ? sortConfig[user.value.id] || [] : sortConfig[defaultUserId] || [] + sorts.value = user.value?.id ? sortConfig[user.value.id] || {} : sortConfig[defaultUserId] || {} } catch (error) { console.error('Error while retrieving sort configuration from local storage:', error) - // Set sorts to an empty array in case of an error - sorts.value = [] + // Set sorts to an empty obj in case of an error + sorts.value = {} } } @@ -57,29 +57,10 @@ export function useUserSorts(roleType: 'Workspace' | 'Org' | 'Project') { */ function saveOrUpdate(newSortConfig: UsersSortType): void { try { - const fieldIndex = sorts.value.findIndex((sort) => sort.field === newSortConfig.field) - if (newSortConfig.direction) { - if (fieldIndex !== -1) { - // Update the direction if the field exists - sorts.value = [ - ...clone(sorts.value) - .map((sort) => { - if (sort.field === newSortConfig.field) { - sort.direction = newSortConfig.direction - } - return sort - }) - .filter((sort) => sort.field === newSortConfig.field), // For now it is only single level of sorting so remove another sort field - ] - } else { - // Add a new sort configuration - sorts.value = [newSortConfig] - } + if (newSortConfig.field && newSortConfig.direction) { + sorts.value = { ...newSortConfig } } else { - if (fieldIndex !== -1) { - // Remove the sort configuration if the field exists and direction is not present - sorts.value = [...clone(sorts.value).filter((sort) => sort.field !== newSortConfig.field)] - } + sorts.value = {} } // Update local storage with the new sort configurations @@ -88,7 +69,7 @@ export function useUserSorts(roleType: 'Workspace' | 'Org' | 'Project') { if (user.value?.id) { // Save or delete user-specific sort configurations - if (sorts.value.length) { + if (sorts.value.field) { sortConfig[user.value.id] = sorts.value } else { delete sortConfig[user.value.id] @@ -108,11 +89,11 @@ export function useUserSorts(roleType: 'Workspace' | 'Org' | 'Project') { * Sorts and returns a deep copy of an array of objects based on the provided sort configurations. * * @param data - The array of objects to be sorted. - * @param sortsConfig - The array of sort configurations. + * @param sortsConfig - The object of sort configurations. * @returns A new array containing sorted objects. * @template T - The type of objects in the input array. */ - function handleGetSortsData>(data: T[], sortsConfig: UsersSortType[] = sorts.value): T[] { + function handleGetSortsData>(data: T[], sortsConfig: UsersSortType = sorts.value): T[] { let userRoleOrder: string[] = [] if (roleType === 'Workspace') { userRoleOrder = Object.values(WorkspaceUserRoles) @@ -121,51 +102,44 @@ export function useUserSorts(roleType: 'Workspace' | 'Org' | 'Project') { } else if (roleType === 'Project') { userRoleOrder = Object.values(ProjectRoles) } + data = clone(data) - // let superUserIndex = data.findIndex((user) => user?.roles?.includes('super')) - // let superUser = superUserIndex !== -1 ? data.splice(superUserIndex, 1) : null + + let superUserIndex = data.findIndex((user) => user?.roles?.includes('super')) + let superUser = superUserIndex !== -1 ? data.splice(superUserIndex, 1) : null // console.log('super', superUser) - const sortedData = data.sort((a, b) => { - let sortCondition = 0 - - for (const { field, direction } of sortsConfig) { - if (!a[field]) continue - - if (field === 'roles') { - for (const role of userRoleOrder) { - const indexA = a?.roles?.split(',')?.indexOf(role) ?? -1 - const indexB = b?.roles?.split(',')?.indexOf(role) ?? -1 - - // if (indexA === -1) { - // sortCondition = sortCondition || direction === 'asc' ? 1 : -1 // Role A is missing, so it should come last - // break - // } - - // if (indexB === -1) { - // sortCondition = sortCondition || direction === 'asc' ? -1 : 1 // Role B is missing, so it should come last - // break - // } - - if (direction === 'asc') { - sortCondition = sortCondition || indexA - indexB - break - } else if (direction === 'desc') { - sortCondition = sortCondition || indexB - indexA - break - } + let sortedData = data.sort((a, b) => { + switch (sortsConfig.field) { + case 'roles': { + const roleA = a?.roles?.split(',')[0] + const roleB = b?.roles?.split(',')[0] + + if (sortsConfig.direction === 'asc') { + return userRoleOrder.indexOf(roleA) - userRoleOrder.indexOf(roleB) + } else if (sortsConfig.direction === 'desc') { + return userRoleOrder.indexOf(roleB) - userRoleOrder.indexOf(roleA) } - } else { - if (direction === 'asc') { - sortCondition = sortCondition || a[field]?.localeCompare(b[field]) - } else if (direction === 'desc') { - sortCondition = sortCondition || b[field]?.localeCompare(a[field]) + } + case 'email': { + if (sortsConfig.direction === 'asc') { + return a[sortsConfig.field]?.localeCompare(b[sortsConfig.field]) + } else if (sortsConfig.direction === 'desc') { + return b[sortsConfig.field]?.localeCompare(a[sortsConfig.field]) } } } - return sortCondition + return 0 }) + if (superUser && superUser.length) { + if (sortsConfig.direction === 'desc') { + sortedData = [...sortedData, superUser[0]] + } else { + sortedData = [superUser[0], ...sortedData] + } + } + return sortedData } diff --git a/packages/nc-gui/lib/types.ts b/packages/nc-gui/lib/types.ts index 0cde7912e3..be506296ab 100644 --- a/packages/nc-gui/lib/types.ts +++ b/packages/nc-gui/lib/types.ts @@ -177,7 +177,7 @@ interface SidebarTableNode extends TableType { } interface UsersSortType { - field: string + field?: 'email' | 'roles' direction?: 'asc' | 'desc' } From 6020999f85b17acc2fcf989427a36c441f08e82b Mon Sep 17 00:00:00 2001 From: Ramesh Mane <101566080+rameshmane7218@users.noreply.github.com> Date: Thu, 28 Dec 2023 20:51:09 +0530 Subject: [PATCH 06/21] fix: lint erros --- packages/nc-gui/components/account/UserList.vue | 8 ++++---- packages/nc-gui/components/account/UserMenu.vue | 2 +- .../components/project/AccessSettings.vue | 8 ++------ packages/nc-gui/composables/useUserSorts.ts | 17 ++++++++--------- 4 files changed, 15 insertions(+), 20 deletions(-) diff --git a/packages/nc-gui/components/account/UserList.vue b/packages/nc-gui/components/account/UserList.vue index ddb661451c..2730d0fd56 100644 --- a/packages/nc-gui/components/account/UserList.vue +++ b/packages/nc-gui/components/account/UserList.vue @@ -1,6 +1,7 @@