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 7 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}`"
@click.stop
>
<a-tag class="rounded-tag" color="'#ccc'">
<a-tag class="rounded-tag !pl-0" color="'#ccc'">
<span
:style="{
'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(),
'font-size': '13px',
}"
class="flex items-center gap-2"
: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>
</a-tag>
</a-select-option>

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

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

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

@ -11,7 +11,6 @@ import {
renderValue,
replaceUrlsWithLink,
useBase,
useGlobal,
} from '#imports'
// 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 { showNull } = useGlobal()
const result = computed(() =>
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>
import { OrderedWorkspaceRoles, WorkspaceUserRoles, parseStringDateTime, timeAgo } from 'nocodb-sdk'
import { storeToRefs, useWorkspace } from '#imports'
import { storeToRefs, useUserSorts, useWorkspace } from '#imports'
const { workspaceRoles, loadRoles } = useRoles()
@ -9,6 +9,9 @@ const workspaceStore = useWorkspace()
const { removeCollaborator, updateCollaborator: _updateCollaborator } = workspaceStore
const { collaborators } = storeToRefs(workspaceStore)
const { sorts, sortDirection, loadSorts, saveOrUpdate, handleGetSortedData } = useUserSorts('Workspace')
const userSearchText = ref('')
const filterCollaborators = computed(() => {
@ -19,11 +22,20 @@ const filterCollaborators = computed(() => {
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) => {
collab.roles = roles
try {
await _updateCollaborator(collab.id, collab.roles)
await _updateCollaborator(collab.id, roles)
message.success('Successfully updated user role')
collaborators.value?.forEach((collaborator) => {
if (collaborator.id === collab.id) {
collaborator.roles = roles
}
})
} catch (e: any) {
message.error(await extractSdkResponseErrorMsg(e))
}
@ -39,6 +51,7 @@ const accessibleRoles = computed<WorkspaceUserRoles[]>(() => {
onMounted(async () => {
await loadRoles()
loadSorts()
})
</script>
@ -59,15 +72,25 @@ 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">
<div class="text-gray-700 users-email-grid w-3/8 ml-10 mr-3">{{ $t('objects.users') }}</div>
<div class="text-gray-700 user-access-grid w-2/8 mr-3">{{ $t('general.access') }}</div>
<div class="text-gray-700 users-email-grid w-3/8 ml-10 mr-3 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 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 user-access-grid w-1/8">Actions</div>
</div>
<div class="flex flex-col nc-scrollbar-md">
<div
v-for="(collab, i) of filterCollaborators"
v-for="(collab, i) of sortedCollaborators"
:key="i"
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 { OrgUserRoles, ProjectRoles, WorkspaceUserRoles } from 'nocodb-sdk'
import { OrderedOrgRoles, OrderedProjectRoles, OrderedWorkspaceRoles } from 'nocodb-sdk'
import type { UsersSortType } from '~/lib'
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[] {
let userRoleOrder: string[] = []
if (roleType === 'Workspace') {
userRoleOrder = Object.values(WorkspaceUserRoles)
userRoleOrder = Object.values(OrderedWorkspaceRoles)
} else if (roleType === 'Org') {
userRoleOrder = Object.values(OrgUserRoles)
userRoleOrder = Object.values(OrderedOrgRoles)
} else if (roleType === 'Project') {
userRoleOrder = Object.values(ProjectRoles)
userRoleOrder = Object.values(OrderedProjectRoles)
}
data = clone(data)

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

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

Loading…
Cancel
Save