From 838ccacf84cc278730da51074e58aa541ed2e61f Mon Sep 17 00:00:00 2001 From: Ramesh Mane <101566080+rameshmane7218@users.noreply.github.com> Date: Tue, 2 Jan 2024 08:15:23 +0000 Subject: [PATCH 01/23] feat: hook and dropdown menu for user sort management --- .../nc-gui/components/account/UserList.vue | 8 +- .../nc-gui/components/account/UserMenu.vue | 14 +- packages/nc-gui/composables/useUserSorts.ts | 140 ++++++------------ packages/nc-gui/lang/en.json | 3 +- packages/nc-gui/lib/types.ts | 2 +- 5 files changed, 67 insertions(+), 100 deletions(-) diff --git a/packages/nc-gui/components/account/UserList.vue b/packages/nc-gui/components/account/UserList.vue index b73f89c4d8..7ed471e203 100644 --- a/packages/nc-gui/components/account/UserList.vue +++ b/packages/nc-gui/components/account/UserList.vue @@ -28,12 +28,12 @@ const { user: loggedInUser } = useGlobal() const { copy } = useCopy() -const { sorts, sortDirection, loadSorts, saveOrUpdate, handleGetSortedData } = useUserSorts('Org') +const { sorts, sortDirection, loadSorts, saveOrUpdate, handleGetSortsData } = useUserSorts() const users = ref([]) const sortedUsers = computed(() => { - return handleGetSortedData(users.value, sorts.value) as UserType[] + return handleGetSortsData(users.value, sorts.value) as UserType[] }) const currentPage = ref(1) @@ -205,13 +205,13 @@ const openDeleteModal = (user: UserType) => { {{ $t('labels.email') }} - +
{{ $t('objects.role') }} - +
{{ $t('labels.action') }} diff --git a/packages/nc-gui/components/account/UserMenu.vue b/packages/nc-gui/components/account/UserMenu.vue index f125eeae3b..af99ebc0e6 100644 --- a/packages/nc-gui/components/account/UserMenu.vue +++ b/packages/nc-gui/components/account/UserMenu.vue @@ -10,9 +10,9 @@ const { field, direction, handleUserSort } = defineProps<{ const isOpen = ref(false) -const sortUserBy = (direction?: UsersSortType['direction']) => { +const sortUserBy = async (direction?: UsersSortType['direction']) => { handleUserSort({ - field, + field: field, direction, }) isOpen.value = false @@ -57,6 +57,16 @@ const sortUserBy = (direction?: UsersSortType['direction']) => { {{ $t('general.sortDesc') }}
+ + + + +
+ + + {{ $t('general.resetSort') }} +
+
diff --git a/packages/nc-gui/composables/useUserSorts.ts b/packages/nc-gui/composables/useUserSorts.ts index 4644bd86ac..15ccccd3e1 100644 --- a/packages/nc-gui/composables/useUserSorts.ts +++ b/packages/nc-gui/composables/useUserSorts.ts @@ -1,20 +1,17 @@ import rfdc from 'rfdc' -import { OrgUserRoles, ProjectRoles, WorkspaceUserRoles } from 'nocodb-sdk' import type { UsersSortType } from '~/lib' import { useGlobal } from '#imports' /** * Hook for managing user sorts and sort configurations. - * - * @param {string} roleType - The type of role for which user sorts are managed ('Workspace', 'Org', or 'Project'). - * @returns {object} An object containing reactive values and functions related to user sorts. + * @returns An object containing reactive values and functions related to user sorts. */ -export function useUserSorts(roleType: 'Workspace' | 'Org' | 'Project') { +export function useUserSorts() { const clone = rfdc() const { user } = useGlobal() - const sorts = ref({}) + const sorts = ref([]) // Key for storing user sort configurations in local storage const userSortConfigKey = 'userSortConfig' @@ -27,10 +24,10 @@ export function useUserSorts(roleType: 'Workspace' | 'Org' | 'Project') { * @type {ComputedRef>} */ const sortDirection: ComputedRef> = computed(() => { - if (sorts.value.field) { - return { [sorts.value.field]: sorts.value.direction } as Record - } - return {} as Record + return sorts.value.reduce((acc, curr) => { + acc = { ...acc, [curr.field]: curr.direction } + return acc + }, {} as Record) }) /** @@ -41,22 +38,15 @@ export function useUserSorts(roleType: 'Workspace' | 'Org' | 'Project') { // Retrieve sort configuration from local storage const storedConfig = localStorage.getItem(userSortConfigKey) - const sortConfig = storedConfig ? JSON.parse(storedConfig) : ({} as Record) + const sortConfig = storedConfig ? JSON.parse(storedConfig) : {} + sorts.value = sortConfig - if (sortConfig && isValidSortConfig(sortConfig)) { - // Load user-specific sort configurations or default configurations - sorts.value = user.value?.id ? sortConfig[user.value.id] || {} : sortConfig[defaultUserId] || {} - } else { - throw new Error('Invalid sort config stored in local storage') - } + // Load user-specific sort configurations or default configurations + sorts.value = user.value?.id ? sortConfig[user.value.id] || [] : sortConfig[defaultUserId] || [] } catch (error) { - console.error(error) - - // remove sortConfig from localStorage in case of error - localStorage.removeItem(userSortConfigKey) - - // Set sorts to an empty obj in case of an error - sorts.value = {} + console.error('Error while retrieving sort configuration from local storage:', error) + // Set sorts to an empty array in case of an error + sorts.value = [] } } @@ -66,10 +56,27 @@ export function useUserSorts(roleType: 'Workspace' | 'Org' | 'Project') { */ function saveOrUpdate(newSortConfig: UsersSortType): void { try { - if (newSortConfig.field && newSortConfig.direction) { - sorts.value = { ...newSortConfig } + 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 { - sorts.value = {} + 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 @@ -78,7 +85,7 @@ export function useUserSorts(roleType: 'Workspace' | 'Org' | 'Project') { if (user.value?.id) { // Save or delete user-specific sort configurations - if (sorts.value.field) { + if (sorts.value.length) { sortConfig[user.value.id] = sorts.value } else { delete sortConfig[user.value.id] @@ -90,7 +97,7 @@ export function useUserSorts(roleType: 'Workspace' | 'Org' | 'Project') { localStorage.setItem(userSortConfigKey, JSON.stringify(sortConfig)) } catch (error) { - console.error('Error while saving sort configuration into local storage:', error) + console.error('Error while retrieving sort configuration from local storage:', error) } } @@ -98,80 +105,29 @@ 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 object of sort configurations. + * @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 handleGetSortedData>(data: T[], sortsConfig: UsersSortType = sorts.value): T[] { - 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) + function handleGetSortsData>(data: T[], sortsConfig: UsersSortType[] = sorts.value): T[] { + const sortedData = clone(data).sort((a, b) => { + let sortCondition = 0 - const superUserIndex = data.findIndex((user) => user?.roles?.includes('super')) - const superUser = sortsConfig.field === 'roles' && superUserIndex !== -1 ? data.splice(superUserIndex, 1) : null + for (const { field, direction } of sortsConfig) { + if (a[field]) continue - 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 { - return userRoleOrder.indexOf(roleB) - userRoleOrder.indexOf(roleA) - } - } - case 'email': { - if (sortsConfig.direction === 'asc') { - return a[sortsConfig.field]?.localeCompare(b[sortsConfig.field]) - } else { - return b[sortsConfig.field]?.localeCompare(a[sortsConfig.field]) - } + if (direction === 'asc') { + sortCondition = sortCondition || a[field]?.localeCompare(b[field]) + } else if (direction === 'desc') { + sortCondition = sortCondition || b[field]?.localeCompare(a[field]) } } - return 0 + return sortCondition }) - if (superUser && superUser.length) { - if (sortsConfig.direction === 'desc') { - sortedData = [...sortedData, superUser[0]] - } else { - sortedData = [superUser[0], ...sortedData] - } - } - return sortedData } - /** - * Checks if the provided sort configuration has the expected structure. - * @param sortConfig - The sort configuration to validate. - * @param expectedStructure - The expected structure for the sort configuration. - * Defaults to { field: 'email', direction: 'asc' }. - * @returns `true` if the sort configuration is valid, otherwise `false`. - */ - function isValidSortConfig( - sortConfig: Record, - expectedStructure: UsersSortType = { field: 'email', direction: 'asc' }, - ): boolean { - // Check if the sortConfig has the expected keys - for (const key in sortConfig) { - const isValidConfig = Object.keys(sortConfig[key]).every((key) => - Object.prototype.hasOwnProperty.call(expectedStructure, key), - ) - if (!isValidConfig) return false - } - return true - } - - return { sorts, sortDirection, loadSorts, saveOrUpdate, handleGetSortedData } + return { sorts, sortDirection, loadSorts, saveOrUpdate, handleGetSortsData } } diff --git a/packages/nc-gui/lang/en.json b/packages/nc-gui/lang/en.json index bd37f1b56e..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", diff --git a/packages/nc-gui/lib/types.ts b/packages/nc-gui/lib/types.ts index eb653eb374..c246011cf3 100644 --- a/packages/nc-gui/lib/types.ts +++ b/packages/nc-gui/lib/types.ts @@ -178,7 +178,7 @@ interface SidebarTableNode extends TableType { } interface UsersSortType { - field?: 'email' | 'roles' + field: string direction?: 'asc' | 'desc' } From 06a8dec6e8bc8461d6b5bea018a81c0293a8b822 Mon Sep 17 00:00:00 2001 From: Ramesh Mane <101566080+rameshmane7218@users.noreply.github.com> Date: Tue, 2 Jan 2024 08:15:23 +0000 Subject: [PATCH 02/23] 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 42ccab07b9a0226184f1da998f4d3378e3672726 Mon Sep 17 00:00:00 2001 From: Ramesh Mane <101566080+rameshmane7218@users.noreply.github.com> Date: Tue, 2 Jan 2024 08:15:23 +0000 Subject: [PATCH 03/23] 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 4407567596e2823fd25dac9d5a6283fe9e52a9d5 Mon Sep 17 00:00:00 2001 From: Ramesh Mane <101566080+rameshmane7218@users.noreply.github.com> Date: Tue, 2 Jan 2024 08:15:23 +0000 Subject: [PATCH 04/23] 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, 51 insertions(+), 15 deletions(-) diff --git a/packages/nc-gui/components/account/UserList.vue b/packages/nc-gui/components/account/UserList.vue index 7ed471e203..6ed9a7a3ab 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 006c4e80f3..c0540a4111 100644 --- a/packages/nc-gui/components/project/AccessSettings.vue +++ b/packages/nc-gui/components/project/AccessSettings.vue @@ -8,7 +8,8 @@ import { parseStringDateTime, timeAgo, } from 'nocodb-sdk' -import type { Roles, WorkspaceUserRoles } from 'nocodb-sdk' +import type { WorkspaceUserRoles } from 'nocodb-sdk' +import InfiniteLoading from 'v3-infinite-loading' import { isEeUI, storeToRefs, useUserSorts } from '#imports' const basesStore = useBases() @@ -17,7 +18,7 @@ const { activeProjectId } = storeToRefs(basesStore) const { orgRoles, baseRoles } = useRoles() -const { sorts, sortDirection, loadSorts, saveOrUpdate, handleGetSortedData } = useUserSorts('Project') +const { sorts, sortDirection, loadSorts, saveOrUpdate, handleGetSortsData } = useUserSorts('Project') const isSuper = computed(() => orgRoles.value?.[OrgUserRoles.SUPER_ADMIN]) @@ -38,12 +39,9 @@ const isLoading = ref(false) const isSearching = ref(false) const accessibleRoles = ref<(typeof ProjectRoles)[keyof typeof ProjectRoles][]>([]) -const filteredCollaborators = computed(() => - collaborators.value.filter((collab) => collab.email.toLowerCase().includes(userSearchText.value.toLowerCase())), -) - const sortedCollaborators = computed(() => { - return handleGetSortedData(filteredCollaborators.value, sorts.value) + console.log('collaborator', sorts.value, collaborators.value) + return handleGetSortsData([...collaborators.value], sorts.value) }) const loadCollaborators = 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 dc44350739a4eb79b60d107e22f7754c189d8338 Mon Sep 17 00:00:00 2001 From: Ramesh Mane <101566080+rameshmane7218@users.noreply.github.com> Date: Tue, 2 Jan 2024 08:15:23 +0000 Subject: [PATCH 05/23] fix: user roles sort issue --- .../nc-gui/components/account/UserList.vue | 9 +- .../components/project/AccessSettings.vue | 32 ++++- packages/nc-gui/composables/useUserSorts.ts | 112 +++++++----------- packages/nc-gui/lib/types.ts | 2 +- 4 files changed, 77 insertions(+), 78 deletions(-) diff --git a/packages/nc-gui/components/account/UserList.vue b/packages/nc-gui/components/account/UserList.vue index 6ed9a7a3ab..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,10 +93,11 @@ const updateRole = async (userId: string, roles: string) => { } as OrgUserReqType) message.success(t('msg.success.roleUpdated')) - users.value.forEach((user) => { + users.value = clone(users.value).map((user) => { if (user.id === userId) { - user.roles = roles + user['roles'] = roles } + return user }) $e('a:org-user:role-updated', { role: roles }) diff --git a/packages/nc-gui/components/project/AccessSettings.vue b/packages/nc-gui/components/project/AccessSettings.vue index c0540a4111..8600475d55 100644 --- a/packages/nc-gui/components/project/AccessSettings.vue +++ b/packages/nc-gui/components/project/AccessSettings.vue @@ -40,8 +40,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 () => { @@ -72,6 +71,28 @@ const loadCollaborators = async () => { } } +const loadListData = async ($state: any) => { + const prevUsersCount = collaborators.value?.length || 0 + if (collaborators.value?.length === totalCollaborators.value) { + $state.complete() + return + } + $state.loading() + // const oldPagesCount = currentPage.value || 0 + + await loadCollaborators() + + if (prevUsersCount === collaborators.value?.length) { + $state.complete() + return + } + $state.loaded() +} + +const updateCollaboratorLocalState = ()=>{ + +} + const updateCollaborator = async (collab: any, roles: ProjectRoles) => { const currentCollaborator = collaborators.value.find((coll) => coll.id === collab.id)! @@ -159,16 +180,15 @@ onMounted(async () => { {{ $t('objects.users') }} - + - +
{{ $t('title.dateJoined') }}
{{ $t('general.access') }} - +
-
{{ $t('title.dateJoined') }}
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 c246011cf3..eb653eb374 100644 --- a/packages/nc-gui/lib/types.ts +++ b/packages/nc-gui/lib/types.ts @@ -178,7 +178,7 @@ interface SidebarTableNode extends TableType { } interface UsersSortType { - field: string + field?: 'email' | 'roles' direction?: 'asc' | 'desc' } From 2af64adc009f98e68e030639fd99f7a800474fb4 Mon Sep 17 00:00:00 2001 From: Ramesh Mane <101566080+rameshmane7218@users.noreply.github.com> Date: Tue, 2 Jan 2024 08:15:23 +0000 Subject: [PATCH 06/23] 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 @@