Browse Source

fix: user roles sort issue

pull/7276/head
Ramesh Mane 11 months ago
parent
commit
114da7e2c0
  1. 11
      packages/nc-gui/components/account/UserList.vue
  2. 21
      packages/nc-gui/components/project/AccessSettings.vue
  3. 112
      packages/nc-gui/composables/useUserSorts.ts
  4. 2
      packages/nc-gui/lib/types.ts

11
packages/nc-gui/components/account/UserList.vue

@ -12,6 +12,7 @@ import {
useNuxtApp, useNuxtApp,
useUserSorts, useUserSorts,
} from '#imports' } from '#imports'
import rfdc from 'rfdc'
const { api, isLoading } = useApi() const { api, isLoading } = useApi()
@ -33,6 +34,7 @@ const { sorts, sortDirection, loadSorts, saveOrUpdate, handleGetSortsData } = us
const users = ref<UserType[]>([]) const users = ref<UserType[]>([])
const sortedUsers = computed(() => { const sortedUsers = computed(() => {
console.log('users', users.value)
return handleGetSortsData(users.value, sorts.value) as UserType[] return handleGetSortsData(users.value, sorts.value) as UserType[]
}) })
@ -54,6 +56,8 @@ const pagination = reactive({
position: ['bottomCenter'], position: ['bottomCenter'],
}) })
const clone = rfdc()
const loadUsers = useDebounceFn(async (page = currentPage.value, limit = currentLimit.value) => { const loadUsers = useDebounceFn(async (page = currentPage.value, limit = currentLimit.value) => {
currentPage.value = page currentPage.value = page
try { try {
@ -89,6 +93,13 @@ const updateRole = async (userId: string, roles: string) => {
} as OrgUserReqType) } as OrgUserReqType)
message.success(t('msg.success.roleUpdated')) 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 }) $e('a:org-user:role-updated', { role: roles })
} catch (e: any) { } catch (e: any) {
message.error(await extractSdkResponseErrorMsg(e)) message.error(await extractSdkResponseErrorMsg(e))

21
packages/nc-gui/components/project/AccessSettings.vue

@ -39,8 +39,7 @@ const isSearching = ref(false)
const accessibleRoles = ref<(typeof ProjectRoles)[keyof typeof ProjectRoles][]>([]) const accessibleRoles = ref<(typeof ProjectRoles)[keyof typeof ProjectRoles][]>([])
const sortedCollaborators = computed(() => { 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 () => { const loadCollaborators = async () => {
@ -91,6 +90,10 @@ const loadListData = async ($state: any) => {
$state.loaded() $state.loaded()
} }
const updateCollaboratorLocalState = ()=>{
}
const updateCollaborator = async (collab: any, roles: ProjectRoles) => { const updateCollaborator = async (collab: any, roles: ProjectRoles) => {
try { try {
if ( if (
@ -193,9 +196,19 @@ onMounted(async () => {
<div v-else class="nc-collaborators-list mt-6 h-full"> <div v-else class="nc-collaborators-list mt-6 h-full">
<div class="flex flex-col rounded-lg overflow-hidden border-1 max-w-350 max-h-[calc(100%-8rem)]"> <div class="flex flex-col rounded-lg overflow-hidden border-1 max-w-350 max-h-[calc(100%-8rem)]">
<div class="flex flex-row bg-gray-50 min-h-12 items-center border-b-1"> <div class="flex flex-row bg-gray-50 min-h-12 items-center border-b-1">
<div class="text-gray-700 users-email-grid">{{ $t('objects.users') }}</div> <div class="text-gray-700 users-email-grid flex items-center space-x-2">
<span>
{{ $t('objects.users') }}
</span>
<LazyAccountUserMenu :direction="sortDirection['email']" field="email" :handle-user-sort="saveOrUpdate" />
</div>
<div class="text-gray-700 date-joined-grid">{{ $t('title.dateJoined') }}</div> <div class="text-gray-700 date-joined-grid">{{ $t('title.dateJoined') }}</div>
<div class="text-gray-700 user-access-grid">{{ $t('general.access') }}</div> <div class="text-gray-700 user-access-grid flex items-center space-x-2">
<span>
{{ $t('general.access') }}
</span>
<LazyAccountUserMenu :direction="sortDirection['roles']" field="roles" :handle-user-sort="saveOrUpdate" />
</div>
</div> </div>
<div class="flex flex-col nc-scrollbar-md"> <div class="flex flex-col nc-scrollbar-md">

112
packages/nc-gui/composables/useUserSorts.ts

@ -12,7 +12,7 @@ export function useUserSorts(roleType: 'Workspace' | 'Org' | 'Project') {
const { user } = useGlobal() const { user } = useGlobal()
const sorts = ref<UsersSortType[]>([]) const sorts = ref<UsersSortType>({})
// Key for storing user sort configurations in local storage // Key for storing user sort configurations in local storage
const userSortConfigKey = 'userSortConfig' const userSortConfigKey = 'userSortConfig'
@ -25,10 +25,10 @@ export function useUserSorts(roleType: 'Workspace' | 'Org' | 'Project') {
* @type {ComputedRef<Record<string, UsersSortType['direction']>>} * @type {ComputedRef<Record<string, UsersSortType['direction']>>}
*/ */
const sortDirection: ComputedRef<Record<string, UsersSortType['direction']>> = computed(() => { const sortDirection: ComputedRef<Record<string, UsersSortType['direction']>> = computed(() => {
return sorts.value.reduce((acc, curr) => { if (sorts.value.field) {
acc = { ...acc, [curr.field]: curr.direction } return { [sorts.value.field]: sorts.value.direction } as Record<string, UsersSortType['direction']>
return acc }
}, {} as Record<string, UsersSortType['direction']>) return {} as Record<string, UsersSortType['direction']>
}) })
/** /**
@ -43,11 +43,11 @@ export function useUserSorts(roleType: 'Workspace' | 'Org' | 'Project') {
sorts.value = sortConfig sorts.value = sortConfig
// Load user-specific sort configurations or default configurations // 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) { } catch (error) {
console.error('Error while retrieving sort configuration from local storage:', error) console.error('Error while retrieving sort configuration from local storage:', error)
// Set sorts to an empty array in case of an error // Set sorts to an empty obj in case of an error
sorts.value = [] sorts.value = {}
} }
} }
@ -57,29 +57,10 @@ export function useUserSorts(roleType: 'Workspace' | 'Org' | 'Project') {
*/ */
function saveOrUpdate(newSortConfig: UsersSortType): void { function saveOrUpdate(newSortConfig: UsersSortType): void {
try { try {
const fieldIndex = sorts.value.findIndex((sort) => sort.field === newSortConfig.field) if (newSortConfig.field && newSortConfig.direction) {
if (newSortConfig.direction) { sorts.value = { ...newSortConfig }
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]
}
} else { } else {
if (fieldIndex !== -1) { sorts.value = {}
// 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 // Update local storage with the new sort configurations
@ -88,7 +69,7 @@ export function useUserSorts(roleType: 'Workspace' | 'Org' | 'Project') {
if (user.value?.id) { if (user.value?.id) {
// Save or delete user-specific sort configurations // Save or delete user-specific sort configurations
if (sorts.value.length) { if (sorts.value.field) {
sortConfig[user.value.id] = sorts.value sortConfig[user.value.id] = sorts.value
} else { } else {
delete sortConfig[user.value.id] 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. * 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 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. * @returns A new array containing sorted objects.
* @template T - The type of objects in the input array. * @template T - The type of objects in the input array.
*/ */
function handleGetSortsData<T extends Record<string, any>>(data: T[], sortsConfig: UsersSortType[] = sorts.value): T[] { function handleGetSortsData<T extends Record<string, any>>(data: T[], sortsConfig: UsersSortType = sorts.value): T[] {
let userRoleOrder: string[] = [] let userRoleOrder: string[] = []
if (roleType === 'Workspace') { if (roleType === 'Workspace') {
userRoleOrder = Object.values(WorkspaceUserRoles) userRoleOrder = Object.values(WorkspaceUserRoles)
@ -121,51 +102,44 @@ export function useUserSorts(roleType: 'Workspace' | 'Org' | 'Project') {
} else if (roleType === 'Project') { } else if (roleType === 'Project') {
userRoleOrder = Object.values(ProjectRoles) userRoleOrder = Object.values(ProjectRoles)
} }
data = clone(data) 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) // console.log('super', superUser)
const sortedData = data.sort((a, b) => { let sortedData = data.sort((a, b) => {
let sortCondition = 0 switch (sortsConfig.field) {
case 'roles': {
for (const { field, direction } of sortsConfig) { const roleA = a?.roles?.split(',')[0]
if (!a[field]) continue const roleB = b?.roles?.split(',')[0]
if (field === 'roles') { if (sortsConfig.direction === 'asc') {
for (const role of userRoleOrder) { return userRoleOrder.indexOf(roleA) - userRoleOrder.indexOf(roleB)
const indexA = a?.roles?.split(',')?.indexOf(role) ?? -1 } else if (sortsConfig.direction === 'desc') {
const indexB = b?.roles?.split(',')?.indexOf(role) ?? -1 return userRoleOrder.indexOf(roleB) - userRoleOrder.indexOf(roleA)
// 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') { case 'email': {
sortCondition = sortCondition || a[field]?.localeCompare(b[field]) if (sortsConfig.direction === 'asc') {
} else if (direction === 'desc') { return a[sortsConfig.field]?.localeCompare(b[sortsConfig.field])
sortCondition = sortCondition || b[field]?.localeCompare(a[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 return sortedData
} }

2
packages/nc-gui/lib/types.ts

@ -177,7 +177,7 @@ interface SidebarTableNode extends TableType {
} }
interface UsersSortType { interface UsersSortType {
field: string field?: 'email' | 'roles'
direction?: 'asc' | 'desc' direction?: 'asc' | 'desc'
} }

Loading…
Cancel
Save