Browse Source

feat: user field record type

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

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

@ -44,16 +44,18 @@ const loadCollaborators = async () => {
totalCollaborators.value = totalRows totalCollaborators.value = totalRows
collaborators.value = [ collaborators.value = [
...users.map((user: any) => ({ ...users
...user, .filter((u: any) => !u?.deleted)
base_roles: user.roles, .map((user: any) => ({
roles: extractRolesObj(user.main_roles)?.[OrgUserRoles.SUPER_ADMIN] ...user,
? OrgUserRoles.SUPER_ADMIN base_roles: user.roles,
: user.roles ?? roles: extractRolesObj(user.main_roles)?.[OrgUserRoles.SUPER_ADMIN]
(user.workspace_roles ? OrgUserRoles.SUPER_ADMIN
? WorkspaceRolesToProjectRoles[user.workspace_roles as WorkspaceUserRoles] ?? ProjectRoles.NO_ACCESS : user.roles ??
: ProjectRoles.NO_ACCESS), (user.workspace_roles
})), ? WorkspaceRolesToProjectRoles[user.workspace_roles as WorkspaceUserRoles] ?? ProjectRoles.NO_ACCESS
: ProjectRoles.NO_ACCESS),
})),
] ]
} catch (e: any) { } catch (e: any) {
message.error(await extractSdkResponseErrorMsg(e)) 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 dayjs from 'dayjs'
import type { Ref } from 'vue' import type { Ref } from 'vue'
import type { MaybeRef } from '@vueuse/core' 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 { RelationTypes, UITypes, dateFormats, isDateMonthFormat, isSystemColumn, isVirtualCol, timeFormats } from 'nocodb-sdk'
import { parse } from 'papaparse' import { parse } from 'papaparse'
import type { Cell } from './cellRange' import type { Cell } from './cellRange'
@ -115,7 +115,7 @@ export function useMultiSelect(
if (columnObj.uidt === UITypes.User) { if (columnObj.uidt === UITypes.User) {
if (textToCopy && Array.isArray(textToCopy)) { if (textToCopy && Array.isArray(textToCopy)) {
textToCopy = textToCopy textToCopy = textToCopy
.map((user: { id: string; email: string; display_name: string }) => { .map((user: UserFieldRecordType) => {
return user.email return user.email
}) })
.join(', ') .join(', ')

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

@ -2763,6 +2763,13 @@ export interface NotificationUpdateType {
is_read?: boolean; is_read?: boolean;
} }
export interface UserFieldRecordType {
id: string;
display_name?: string;
email: string;
deleted?: boolean;
}
import type { import type {
AxiosInstance, AxiosInstance,
AxiosRequestConfig, 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 * @tags Auth
* @name TokenRefresh * @name TokenRefresh
@ -3351,7 +3358,7 @@ export class Api<
* @request POST:/api/v1/auth/token/refresh * @request POST:/api/v1/auth/token/refresh
* @response `200` `{ * @response `200` `{
\** \**
* New access token for user * New JWT auth token for user
* @example 96751db2d53fb834382b682268874a2ea9ee610e4d904e688d1513f11d3c30d62d36d9e05dec0d63 * @example 96751db2d53fb834382b682268874a2ea9ee610e4d904e688d1513f11d3c30d62d36d9e05dec0d63
*\ *\
token?: string, token?: string,
@ -3367,7 +3374,7 @@ export class Api<
this.request< this.request<
{ {
/** /**
* New access token for user * New JWT auth token for user
* @example 96751db2d53fb834382b682268874a2ea9ee610e4d904e688d1513f11d3c30d62d36d9e05dec0d63 * @example 96751db2d53fb834382b682268874a2ea9ee610e4d904e688d1513f11d3c30d62d36d9e05dec0d63
*/ */
token?: string; 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() return dayjs()
.utc() .utc()
.format(this.isMySQL() ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD HH:mm:ssZ'); .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" "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": { "responses": {

Loading…
Cancel
Save