Browse Source

feat: user field record type

Signed-off-by: mertmit <mertmit99@gmail.com>
pull/7202/head
mertmit 7 months ago
parent
commit
5ee7a195b7
  1. 53
      packages/nc-gui/components/cell/User.vue
  2. 22
      packages/nc-gui/components/project/AccessSettings.vue
  3. 4
      packages/nc-gui/composables/useMultiSelect/index.ts
  4. 13
      packages/nocodb-sdk/src/lib/Api.ts
  5. 2
      packages/nocodb/src/meta/meta.service.ts
  6. 21
      packages/nocodb/src/schema/swagger.json

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

@ -2,6 +2,7 @@
import { onUnmounted } from '@vue/runtime-core'
import tinycolor from 'tinycolor2'
import type { Select as AntSelect } from 'ant-design-vue'
import type { UserFieldRecordType } from 'nocodb-sdk'
import {
ActiveCellInj,
CellClickHookInj,
@ -25,7 +26,7 @@ import {
import MdiCloseCircle from '~icons/mdi/close-circle'
interface Props {
modelValue?: { id: string; email: string; display_name: string }[] | string | null
modelValue?: UserFieldRecordType[] | string | null
rowIndex?: number
location?: 'cell' | 'filter'
forceMulti?: boolean
@ -75,14 +76,15 @@ const searchVal = ref<string | null>()
const { isUIAllowed } = useRoles()
const options = computed<{ id: string; email: string; display_name: string }[]>(() => {
const collaborators: { id: string; email: string; display_name: string }[] = []
const options = computed<UserFieldRecordType[]>(() => {
const collaborators: UserFieldRecordType[] = []
collaborators.push(
...(baseUsers.value?.map((user: any) => ({
id: user.id,
email: user.email,
display_name: user.display_name,
deleted: user.deleted,
})) || []),
)
return collaborators
@ -309,28 +311,29 @@ const filterOption = (input: string, option: any) => {
<template #suffixIcon>
<GeneralIcon icon="arrowDown" class="text-gray-700 nc-select-expand-btn" />
</template>
<a-select-option
v-for="op of options"
:key="op.id || op.email"
:value="op.id"
:data-testid="`select-option-${column.title}-${location === 'filter' ? 'filter' : rowIndex}`"
:class="`nc-select-option-${column.title}-${op.email}`"
@click.stop
>
<a-tag class="rounded-tag" color="'#ccc'">
<span
:style="{
'color': tinycolor.isReadable('#ccc' || '#ccc', '#fff', { level: 'AA', size: 'large' })
? '#fff'
: tinycolor.mostReadable('#ccc' || '#ccc', ['#0b1d05', '#fff']).toHex8String(),
'font-size': '13px',
}"
:class="{ 'text-sm': isKanban }"
>
{{ op.display_name?.length ? op.display_name : op.email }}
</span>
</a-tag>
</a-select-option>
<template v-for="op of options" :key="op.id || op.email">
<a-select-option
v-if="!op.deleted"
:value="op.id"
:data-testid="`select-option-${column.title}-${location === 'filter' ? 'filter' : rowIndex}`"
:class="`nc-select-option-${column.title}-${op.email}`"
@click.stop
>
<a-tag class="rounded-tag" color="'#ccc'">
<span
:style="{
'color': tinycolor.isReadable('#ccc' || '#ccc', '#fff', { level: 'AA', size: 'large' })
? '#fff'
: tinycolor.mostReadable('#ccc' || '#ccc', ['#0b1d05', '#fff']).toHex8String(),
'font-size': '13px',
}"
:class="{ 'text-sm': isKanban }"
>
{{ op.display_name?.length ? op.display_name : op.email }}
</span>
</a-tag>
</a-select-option>
</template>
<template #tagRender="{ label, value: val, onClose }">
<a-tag

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

@ -44,16 +44,18 @@ const loadCollaborators = async () => {
totalCollaborators.value = totalRows
collaborators.value = [
...users.map((user: any) => ({
...user,
base_roles: user.roles,
roles: extractRolesObj(user.main_roles)?.[OrgUserRoles.SUPER_ADMIN]
? OrgUserRoles.SUPER_ADMIN
: user.roles ??
(user.workspace_roles
? WorkspaceRolesToProjectRoles[user.workspace_roles as WorkspaceUserRoles] ?? ProjectRoles.NO_ACCESS
: ProjectRoles.NO_ACCESS),
})),
...users
.filter((u: any) => !u?.deleted)
.map((user: any) => ({
...user,
base_roles: user.roles,
roles: extractRolesObj(user.main_roles)?.[OrgUserRoles.SUPER_ADMIN]
? OrgUserRoles.SUPER_ADMIN
: user.roles ??
(user.workspace_roles
? WorkspaceRolesToProjectRoles[user.workspace_roles as WorkspaceUserRoles] ?? ProjectRoles.NO_ACCESS
: ProjectRoles.NO_ACCESS),
})),
]
} catch (e: any) {
message.error(await extractSdkResponseErrorMsg(e))

4
packages/nc-gui/composables/useMultiSelect/index.ts

@ -2,7 +2,7 @@ import { computed } from 'vue'
import dayjs from 'dayjs'
import type { Ref } from 'vue'
import type { MaybeRef } from '@vueuse/core'
import type { ColumnType, LinkToAnotherRecordType, TableType } from 'nocodb-sdk'
import type { ColumnType, LinkToAnotherRecordType, TableType, UserFieldRecordType } from 'nocodb-sdk'
import { RelationTypes, UITypes, dateFormats, isDateMonthFormat, isSystemColumn, isVirtualCol, timeFormats } from 'nocodb-sdk'
import { parse } from 'papaparse'
import type { Cell } from './cellRange'
@ -115,7 +115,7 @@ export function useMultiSelect(
if (columnObj.uidt === UITypes.User) {
if (textToCopy && Array.isArray(textToCopy)) {
textToCopy = textToCopy
.map((user: { id: string; email: string; display_name: string }) => {
.map((user: UserFieldRecordType) => {
return user.email
})
.join(', ')

13
packages/nocodb-sdk/src/lib/Api.ts

@ -2763,6 +2763,13 @@ export interface NotificationUpdateType {
is_read?: boolean;
}
export interface UserFieldRecordType {
id: string;
display_name?: string;
email: string;
deleted?: boolean;
}
import type {
AxiosInstance,
AxiosRequestConfig,
@ -3343,7 +3350,7 @@ export class Api<
}),
/**
* @description Regenerate user refresh token
* @description Creates a new refresh token and JWT auth token for the user. The refresh token is sent as a cookie, while the JWT auth token is included in the response body.
*
* @tags Auth
* @name TokenRefresh
@ -3351,7 +3358,7 @@ export class Api<
* @request POST:/api/v1/auth/token/refresh
* @response `200` `{
\**
* New access token for user
* New JWT auth token for user
* @example 96751db2d53fb834382b682268874a2ea9ee610e4d904e688d1513f11d3c30d62d36d9e05dec0d63
*\
token?: string,
@ -3367,7 +3374,7 @@ export class Api<
this.request<
{
/**
* New access token for user
* New JWT auth token for user
* @example 96751db2d53fb834382b682268874a2ea9ee610e4d904e688d1513f11d3c30d62d36d9e05dec0d63
*/
token?: string;

2
packages/nocodb/src/meta/meta.service.ts

@ -912,7 +912,7 @@ export class MetaService {
);
}
private now(): any {
public now(): any {
return dayjs()
.utc()
.format(this.isMySQL() ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD HH:mm:ssZ');

21
packages/nocodb/src/schema/swagger.json

@ -23864,6 +23864,27 @@
"type": "boolean"
}
}
},
"UserFieldRecord": {
"type": "object",
"properties": {
"id": {
"type": "string",
"required": true
},
"display_name": {
"type": "string",
"required": false
},
"email": {
"type": "string",
"required": true
},
"deleted": {
"type": "boolean",
"required": false
}
}
}
},
"responses": {

Loading…
Cancel
Save