Browse Source

Merge pull request #7342 from nocodb/nc-oss/3ad21a14

User Management sort bug fixes and user field UI/UX
pull/7347/head
Raju Udava 8 months ago committed by GitHub
parent
commit
18d0a76dbd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      packages/nc-gui/components/cell/User.vue
  2. 7
      packages/nc-gui/components/project/AccessSettings.vue
  3. 3
      packages/nc-gui/components/virtual-cell/Formula.vue
  4. 35
      packages/nc-gui/components/workspace/CollaboratorsList.vue
  5. 8
      packages/nc-gui/composables/useUserSorts.ts
  6. 8
      packages/nocodb-sdk/src/lib/enums.ts

8
packages/nc-gui/components/cell/User.vue

@ -326,7 +326,7 @@ const filterOption = (input: string, option: any) => {
:class="`nc-select-option-${column.title}-${op.email}`" :class="`nc-select-option-${column.title}-${op.email}`"
@click.stop @click.stop
> >
<a-tag class="rounded-tag" color="'#ccc'"> <a-tag class="rounded-tag !pl-0" color="'#ccc'">
<span <span
:style="{ :style="{
'color': tinycolor.isReadable('#ccc' || '#ccc', '#fff', { level: 'AA', size: 'large' }) 'color': tinycolor.isReadable('#ccc' || '#ccc', '#fff', { level: 'AA', size: 'large' })
@ -334,9 +334,13 @@ const filterOption = (input: string, option: any) => {
: tinycolor.mostReadable('#ccc' || '#ccc', ['#0b1d05', '#fff']).toHex8String(), : tinycolor.mostReadable('#ccc' || '#ccc', ['#0b1d05', '#fff']).toHex8String(),
'font-size': '13px', 'font-size': '13px',
}" }"
class="flex items-center gap-2"
:class="{ 'text-sm': isKanban }" :class="{ 'text-sm': isKanban }"
> >
{{ op.display_name?.length ? op.display_name : op.email }} <GeneralUserIcon size="medium" :email="op.email" />
<span>
{{ op.display_name?.length ? op.display_name : op.email }}
</span>
</span> </span>
</a-tag> </a-tag>
</a-select-option> </a-select-option>

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

@ -10,6 +10,7 @@ import {
} from 'nocodb-sdk' } from 'nocodb-sdk'
import type { Roles, WorkspaceUserRoles } from 'nocodb-sdk' import type { Roles, WorkspaceUserRoles } from 'nocodb-sdk'
import { isEeUI, storeToRefs, useUserSorts } from '#imports' import { isEeUI, storeToRefs, useUserSorts } from '#imports'
import type { User } from '#imports'
const basesStore = useBases() const basesStore = useBases()
const { getBaseUsers, createProjectUser, updateProjectUser, removeProjectUser } = basesStore const { getBaseUsers, createProjectUser, updateProjectUser, removeProjectUser } = basesStore
@ -85,7 +86,7 @@ const updateCollaborator = async (collab: any, roles: ProjectRoles) => {
WorkspaceRolesToProjectRoles[currentCollaborator.workspace_roles as WorkspaceUserRoles] === roles && WorkspaceRolesToProjectRoles[currentCollaborator.workspace_roles as WorkspaceUserRoles] === roles &&
isEeUI) isEeUI)
) { ) {
await removeProjectUser(activeProjectId.value!, collab) await removeProjectUser(activeProjectId.value!, currentCollaborator as unknown as User)
if ( if (
currentCollaborator.workspace_roles && currentCollaborator.workspace_roles &&
WorkspaceRolesToProjectRoles[currentCollaborator.workspace_roles as WorkspaceUserRoles] === roles && WorkspaceRolesToProjectRoles[currentCollaborator.workspace_roles as WorkspaceUserRoles] === roles &&
@ -97,11 +98,11 @@ const updateCollaborator = async (collab: any, roles: ProjectRoles) => {
} }
} else if (currentCollaborator.base_roles) { } else if (currentCollaborator.base_roles) {
currentCollaborator.roles = roles currentCollaborator.roles = roles
await updateProjectUser(activeProjectId.value!, collab) await updateProjectUser(activeProjectId.value!, currentCollaborator as unknown as User)
} else { } else {
currentCollaborator.roles = roles currentCollaborator.roles = roles
currentCollaborator.base_roles = roles currentCollaborator.base_roles = roles
await createProjectUser(activeProjectId.value!, collab) await createProjectUser(activeProjectId.value!, currentCollaborator as unknown as User)
} }
} catch (e: any) { } catch (e: any) {
message.error(await extractSdkResponseErrorMsg(e)) message.error(await extractSdkResponseErrorMsg(e))

3
packages/nc-gui/components/virtual-cell/Formula.vue

@ -11,7 +11,6 @@ import {
renderValue, renderValue,
replaceUrlsWithLink, replaceUrlsWithLink,
useBase, useBase,
useGlobal,
} from '#imports' } from '#imports'
// todo: column type doesn't have required property `error` - throws in typecheck // todo: column type doesn't have required property `error` - throws in typecheck
@ -23,8 +22,6 @@ const isExpandedFormOpen = inject(IsExpandedFormOpenInj, ref(false))!
const { isPg } = useBase() const { isPg } = useBase()
const { showNull } = useGlobal()
const result = computed(() => const result = computed(() =>
isPg(column.value.source_id) ? renderValue(handleTZ(cellValue?.value)) : renderValue(cellValue?.value), isPg(column.value.source_id) ? renderValue(handleTZ(cellValue?.value)) : renderValue(cellValue?.value),
) )

35
packages/nc-gui/components/workspace/CollaboratorsList.vue

@ -1,6 +1,6 @@
<script lang="ts" setup> <script lang="ts" setup>
import { OrderedWorkspaceRoles, WorkspaceUserRoles, parseStringDateTime, timeAgo } from 'nocodb-sdk' import { OrderedWorkspaceRoles, WorkspaceUserRoles, parseStringDateTime, timeAgo } from 'nocodb-sdk'
import { storeToRefs, useWorkspace } from '#imports' import { storeToRefs, useUserSorts, useWorkspace } from '#imports'
const { workspaceRoles, loadRoles } = useRoles() const { workspaceRoles, loadRoles } = useRoles()
@ -9,6 +9,9 @@ const workspaceStore = useWorkspace()
const { removeCollaborator, updateCollaborator: _updateCollaborator } = workspaceStore const { removeCollaborator, updateCollaborator: _updateCollaborator } = workspaceStore
const { collaborators } = storeToRefs(workspaceStore) const { collaborators } = storeToRefs(workspaceStore)
const { sorts, sortDirection, loadSorts, saveOrUpdate, handleGetSortedData } = useUserSorts('Workspace')
const userSearchText = ref('') const userSearchText = ref('')
const filterCollaborators = computed(() => { const filterCollaborators = computed(() => {
@ -19,11 +22,20 @@ const filterCollaborators = computed(() => {
return collaborators.value.filter((collab) => collab.email!.includes(userSearchText.value)) return collaborators.value.filter((collab) => collab.email!.includes(userSearchText.value))
}) })
const sortedCollaborators = computed(() => {
return handleGetSortedData(filterCollaborators.value, sorts.value)
})
const updateCollaborator = async (collab: any, roles: WorkspaceUserRoles) => { const updateCollaborator = async (collab: any, roles: WorkspaceUserRoles) => {
collab.roles = roles
try { try {
await _updateCollaborator(collab.id, collab.roles) await _updateCollaborator(collab.id, roles)
message.success('Successfully updated user role') message.success('Successfully updated user role')
collaborators.value?.forEach((collaborator) => {
if (collaborator.id === collab.id) {
collaborator.roles = roles
}
})
} catch (e: any) { } catch (e: any) {
message.error(await extractSdkResponseErrorMsg(e)) message.error(await extractSdkResponseErrorMsg(e))
} }
@ -39,6 +51,7 @@ const accessibleRoles = computed<WorkspaceUserRoles[]>(() => {
onMounted(async () => { onMounted(async () => {
await loadRoles() await loadRoles()
loadSorts()
}) })
</script> </script>
@ -59,15 +72,25 @@ 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"> <div class="flex flex-row bg-gray-50 min-h-12 items-center">
<div class="text-gray-700 users-email-grid w-3/8 ml-10 mr-3">{{ $t('objects.users') }}</div> <div class="text-gray-700 users-email-grid w-3/8 ml-10 mr-3 flex items-center space-x-2">
<div class="text-gray-700 user-access-grid w-2/8 mr-3">{{ $t('general.access') }}</div> <span>
{{ $t('objects.users') }}
</span>
<LazyAccountUserMenu :direction="sortDirection.email" field="email" :handle-user-sort="saveOrUpdate" />
</div>
<div class="text-gray-700 user-access-grid w-2/8 mr-3 flex items-center space-x-2">
<span>
{{ $t('general.access') }}
</span>
<LazyAccountUserMenu :direction="sortDirection.roles" field="roles" :handle-user-sort="saveOrUpdate" />
</div>
<div class="text-gray-700 date-joined-grid w-2/8 mr-3">{{ $t('title.dateJoined') }}</div> <div class="text-gray-700 date-joined-grid w-2/8 mr-3">{{ $t('title.dateJoined') }}</div>
<div class="text-gray-700 user-access-grid w-1/8">Actions</div> <div class="text-gray-700 user-access-grid w-1/8">Actions</div>
</div> </div>
<div class="flex flex-col nc-scrollbar-md"> <div class="flex flex-col nc-scrollbar-md">
<div <div
v-for="(collab, i) of filterCollaborators" v-for="(collab, i) of sortedCollaborators"
:key="i" :key="i"
class="flex flex-row border-b-1 py-1 min-h-14 items-center justify-around last" class="flex flex-row border-b-1 py-1 min-h-14 items-center justify-around last"
> >

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

@ -1,5 +1,5 @@
import rfdc from 'rfdc' import rfdc from 'rfdc'
import { OrgUserRoles, ProjectRoles, WorkspaceUserRoles } from 'nocodb-sdk' import { OrderedOrgRoles, OrderedProjectRoles, OrderedWorkspaceRoles } from 'nocodb-sdk'
import type { UsersSortType } from '~/lib' import type { UsersSortType } from '~/lib'
import { useGlobal } from '#imports' import { useGlobal } from '#imports'
@ -105,11 +105,11 @@ export function useUserSorts(roleType: 'Workspace' | 'Org' | 'Project') {
function handleGetSortedData<T extends Record<string, any>>(data: T[], sortsConfig: UsersSortType = sorts.value): T[] { function handleGetSortedData<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(OrderedWorkspaceRoles)
} else if (roleType === 'Org') { } else if (roleType === 'Org') {
userRoleOrder = Object.values(OrgUserRoles) userRoleOrder = Object.values(OrderedOrgRoles)
} else if (roleType === 'Project') { } else if (roleType === 'Project') {
userRoleOrder = Object.values(ProjectRoles) userRoleOrder = Object.values(OrderedProjectRoles)
} }
data = clone(data) data = clone(data)

8
packages/nocodb-sdk/src/lib/enums.ts

@ -243,8 +243,12 @@ export const OrderedWorkspaceRoles = [
WorkspaceUserRoles.EDITOR, WorkspaceUserRoles.EDITOR,
WorkspaceUserRoles.COMMENTER, WorkspaceUserRoles.COMMENTER,
WorkspaceUserRoles.VIEWER, WorkspaceUserRoles.VIEWER,
// placeholder for no access ];
null,
export const OrderedOrgRoles = [
OrgUserRoles.SUPER_ADMIN,
OrgUserRoles.CREATOR,
OrgUserRoles.VIEWER,
]; ];
export const OrderedProjectRoles = [ export const OrderedProjectRoles = [

Loading…
Cancel
Save