Browse Source

fix: user roles sort issue

feat/user-management-sort
Ramesh Mane 9 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,
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<UserType[]>([])
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))

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 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 () => {
<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-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 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 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 sorts = ref<UsersSortType[]>([])
const sorts = ref<UsersSortType>({})
// 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<Record<string, UsersSortType['direction']>>}
*/
const sortDirection: ComputedRef<Record<string, UsersSortType['direction']>> = computed(() => {
return sorts.value.reduce((acc, curr) => {
acc = { ...acc, [curr.field]: curr.direction }
return acc
}, {} as Record<string, UsersSortType['direction']>)
if (sorts.value.field) {
return { [sorts.value.field]: sorts.value.direction } 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
// 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<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[] = []
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
}

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

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

Loading…
Cancel
Save