diff --git a/packages/app/client/src/pages/index.tsx b/packages/app/client/src/pages/index.tsx index c5b8fc4f4..35da6966f 100644 --- a/packages/app/client/src/pages/index.tsx +++ b/packages/app/client/src/pages/index.tsx @@ -35,6 +35,7 @@ import { WorkflowRouteProvider, WorkflowShortcut } from '@nocobase/client'; +import { AuditLogsProvider } from '@nocobase/plugin-audit-logs/client'; import { notification } from 'antd'; import 'antd/dist/antd.css'; import React from 'react'; @@ -104,6 +105,7 @@ const providers = [ }, }, ], + AuditLogsProvider, BlockSchemaComponentProvider, AntdSchemaComponentProvider, ACLProvider, diff --git a/packages/app/client/tsconfig.json b/packages/app/client/tsconfig.json index 6d42f8cb4..f8870894d 100644 --- a/packages/app/client/tsconfig.json +++ b/packages/app/client/tsconfig.json @@ -11,6 +11,8 @@ "baseUrl": "./", "strict": true, "paths": { + "@nocobase/plugin-*/client": ["../../plugins/*/src/client"], + "@nocobase/*": ["../../core/*/src/"], "@/*": ["src/*"], "@@/*": ["src/.umi/*"] }, diff --git a/packages/app/server/src/config/plugins.ts b/packages/app/server/src/config/plugins.ts index 597f808f0..3966758d1 100644 --- a/packages/app/server/src/config/plugins.ts +++ b/packages/app/server/src/config/plugins.ts @@ -12,4 +12,5 @@ export default [ '@nocobase/plugin-china-region', '@nocobase/plugin-workflow', '@nocobase/plugin-client', + '@nocobase/plugin-audit-logs', ] as PluginsConfigurations; diff --git a/packages/core/client/src/action-logs/ActionLog.tsx b/packages/core/client/src/action-logs/ActionLog.tsx deleted file mode 100644 index e46bfb484..000000000 --- a/packages/core/client/src/action-logs/ActionLog.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import { Field } from '@formily/core'; -import { observer, RecursionField, useField, useFieldSchema } from '@formily/react'; -import React from 'react'; -import { useCollection } from '..'; -import { SchemaComponent } from '../schema-component'; -import { ActionLogDesigner } from './ActionLog.Designer'; -import { createSchema } from './utils'; - -export const ActionLog = () => { - const schema = createSchema(); - return ; -}; - -ActionLog.Designer = ActionLogDesigner; - -ActionLog.Field = observer((props: any) => { - const { value } = props; - return
{value?.uiSchema?.title || value?.name}
; -}); - -ActionLog.FieldValue = observer((props: any) => { - const field = useField(); - const fieldSchema = useFieldSchema(); - const { getField } = useCollection(); - const collectionField = getField(fieldSchema.name); - - if (!collectionField.uiSchema) { - if (!field.value) { - return
; - } - if (typeof field.value === 'boolean') { - return
{field.value ? 'true' : 'false'}
; - } - if (typeof field.value === 'string' || typeof field.value === 'number') { - return
{field.value}
; - } - return
{JSON.stringify(field.value, null, 2)}
; - } - - return ( - - ); -}); diff --git a/packages/core/client/src/action-logs/ActionLogBlockInitializer.tsx b/packages/core/client/src/action-logs/ActionLogBlockInitializer.tsx deleted file mode 100644 index d593293b0..000000000 --- a/packages/core/client/src/action-logs/ActionLogBlockInitializer.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { TableOutlined } from '@ant-design/icons'; -import React from 'react'; -import { useTranslation } from 'react-i18next'; -import { SchemaInitializer } from '../schema-initializer'; - -export const ActionLogBlockInitializer = (props) => { - const { insert } = props; - const { t } = useTranslation(); - return ( - } - onClick={({ item }) => { - insert({ type: 'void', 'x-component': 'ActionLog', 'x-component-props': {} }); - }} - items={[ - { - type: 'item', - name: 'ActionLog', - title: t('Action Logs'), - }, - ]} - /> - ); -}; diff --git a/packages/core/client/src/action-logs/ActionLogProvider.tsx b/packages/core/client/src/action-logs/ActionLogProvider.tsx deleted file mode 100644 index 7ba24a051..000000000 --- a/packages/core/client/src/action-logs/ActionLogProvider.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import React, { useContext } from 'react'; -import { SchemaInitializerContext, SchemaInitializerProvider } from '../schema-initializer'; - -const actionLogsItemGroup = { - type: 'itemGroup', - title: '{{t("Others")}}', - children: [ - { - type: 'item', - title: '{{t("Action logs")}}', - component: 'ActionLogBlockInitializer', - }, - ], -}; - -export const ActionLogProvider = (props: any) => { - const initializes = useContext(SchemaInitializerContext); - initializes.BlockInitializers.items.push({ ...actionLogsItemGroup }); - return {props.children}; -}; diff --git a/packages/core/client/src/action-logs/demos/demo1.tsx b/packages/core/client/src/action-logs/demos/demo1.tsx deleted file mode 100644 index 45e45fdce..000000000 --- a/packages/core/client/src/action-logs/demos/demo1.tsx +++ /dev/null @@ -1,88 +0,0 @@ -import { ISchema } from '@formily/react'; -import { - ActionLog, - ActionLogProvider, - AntdSchemaComponentProvider, - APIClient, - APIClientProvider, - CollectionManagerProvider, - SchemaComponent, - SchemaComponentProvider, - SchemaInitializerProvider, -} from '@nocobase/client'; -import MockAdapter from 'axios-mock-adapter'; -import React from 'react'; -import { mockData } from './mockData'; - -const apiClient = new APIClient(); - -const mock = new MockAdapter(apiClient.axios); - -mock.onGet('/action_logs:list').reply(200, mockData); - -const schema = { - type: 'void', - name: 'ActionLog', - 'x-component': 'ActionLog', -}; - -const collections = [ - { - name: 'action_logs', - fields: [ - { - type: 'integer', - name: 'id', - interface: 'input', - uiSchema: { - title: 'ID', - type: 'number', - 'x-component': 'InputNumber', - required: true, - description: 'description1', - } as ISchema, - }, - { - type: 'string', - name: 'created_at', - interface: 'createdAt', - uiSchema: { - title: 'Created At', - type: 'number', - 'x-component': 'DatePicker', - required: true, - description: 'Date Picker', - } as ISchema, - }, - { - type: 'string', - name: 'collection_name', - interface: 'input', - uiSchema: { - title: 'collection name', - type: 'number', - 'x-component': 'Input', - description: 'collection name', - } as ISchema, - }, - ], - }, -]; - -export default () => { - return ( - - - - - - - - - - - - - - ); -}; diff --git a/packages/core/client/src/action-logs/demos/mockData.ts b/packages/core/client/src/action-logs/demos/mockData.ts deleted file mode 100644 index a116d0676..000000000 --- a/packages/core/client/src/action-logs/demos/mockData.ts +++ /dev/null @@ -1,285 +0,0 @@ -export const mockData = { - data: [ - { - id: 41, - created_at: '2022-03-04T09:14:45.173Z', - collection_name: 'users', - type: 'create', - index: 7, - user_id: 1, - user: { - id: 1, - nickname: 'Super Admin', - email: 'admin@nocobase.com', - appLang: null, - token: '6287df8c3f623ba2cb12', - reset_token: null, - sort: 1, - created_at: '2022-02-17T05:31:09.172Z', - updated_at: '2022-02-17T05:31:32.031Z', - }, - collection: { - name: 'users', - logging: true, - title: '{{t("Users")}}', - privilege: 'undelete', - sortable: 'sort', - options: { createdBy: false, updatedBy: false }, - sort: 2, - created_at: '2021-09-02T15:07:56.914Z', - updated_at: '2021-09-15T00:59:20.676Z', - ui_schema_key: null, - }, - }, - { - id: 40, - created_at: '2022-03-04T09:14:25.133Z', - collection_name: 'users', - type: 'create', - index: 5, - user_id: 1, - user: { - id: 1, - nickname: 'Super Admin', - email: 'admin@nocobase.com', - appLang: null, - token: '6287df8c3f623ba2cb12', - reset_token: null, - sort: 1, - created_at: '2022-02-17T05:31:09.172Z', - updated_at: '2022-02-17T05:31:32.031Z', - }, - collection: { - name: 'users', - logging: true, - title: '{{t("Users")}}', - privilege: 'undelete', - sortable: 'sort', - options: { createdBy: false, updatedBy: false }, - sort: 2, - created_at: '2021-09-02T15:07:56.914Z', - updated_at: '2021-09-15T00:59:20.676Z', - ui_schema_key: null, - }, - }, - { - id: 39, - created_at: '2022-03-04T09:13:36.399Z', - collection_name: 'users', - type: 'create', - index: 2, - user_id: 1, - user: { - id: 1, - nickname: 'Super Admin', - email: 'admin@nocobase.com', - appLang: null, - token: '6287df8c3f623ba2cb12', - reset_token: null, - sort: 1, - created_at: '2022-02-17T05:31:09.172Z', - updated_at: '2022-02-17T05:31:32.031Z', - }, - collection: { - name: 'users', - logging: true, - title: '{{t("Users")}}', - privilege: 'undelete', - sortable: 'sort', - options: { createdBy: false, updatedBy: false }, - sort: 2, - created_at: '2021-09-02T15:07:56.914Z', - updated_at: '2021-09-15T00:59:20.676Z', - ui_schema_key: null, - }, - }, - { - id: 38, - created_at: '2022-03-02T09:16:07.590Z', - collection_name: 't_2uhu4szs1kq', - type: 'update', - index: 3, - user_id: 1, - user: { - id: 1, - nickname: 'Super Admin', - email: 'admin@nocobase.com', - appLang: null, - token: '6287df8c3f623ba2cb12', - reset_token: null, - sort: 1, - created_at: '2022-02-17T05:31:09.172Z', - updated_at: '2022-02-17T05:31:32.031Z', - }, - collection: { - name: 't_2uhu4szs1kq', - logging: true, - title: '任务', - privilege: null, - sortable: 'sort', - options: {}, - sort: 3, - created_at: '2021-09-03T08:17:30.495Z', - updated_at: '2021-09-18T04:15:42.572Z', - ui_schema_key: null, - }, - }, - { - id: 37, - created_at: '2022-03-02T09:16:06.611Z', - collection_name: 't_2uhu4szs1kq', - type: 'update', - index: 3, - user_id: null, - user: null, - collection: { - name: 't_2uhu4szs1kq', - logging: true, - title: '任务', - privilege: null, - sortable: 'sort', - options: {}, - sort: 3, - created_at: '2021-09-03T08:17:30.495Z', - updated_at: '2021-09-18T04:15:42.572Z', - ui_schema_key: null, - }, - }, - { - id: 36, - created_at: '2022-03-02T09:16:06.526Z', - collection_name: 't_2uhu4szs1kq', - type: 'update', - index: 3, - user_id: 1, - user: { - id: 1, - nickname: 'Super Admin', - email: 'admin@nocobase.com', - appLang: null, - token: '6287df8c3f623ba2cb12', - reset_token: null, - sort: 1, - created_at: '2022-02-17T05:31:09.172Z', - updated_at: '2022-02-17T05:31:32.031Z', - }, - collection: { - name: 't_2uhu4szs1kq', - logging: true, - title: '任务', - privilege: null, - sortable: 'sort', - options: {}, - sort: 3, - created_at: '2021-09-03T08:17:30.495Z', - updated_at: '2021-09-18T04:15:42.572Z', - ui_schema_key: null, - }, - }, - { - id: 35, - created_at: '2022-03-02T09:16:05.930Z', - collection_name: 't_2uhu4szs1kq', - type: 'update', - index: 3, - user_id: null, - user: null, - collection: { - name: 't_2uhu4szs1kq', - logging: true, - title: '任务', - privilege: null, - sortable: 'sort', - options: {}, - sort: 3, - created_at: '2021-09-03T08:17:30.495Z', - updated_at: '2021-09-18T04:15:42.572Z', - ui_schema_key: null, - }, - }, - { - id: 34, - created_at: '2022-03-02T09:16:05.842Z', - collection_name: 't_2uhu4szs1kq', - type: 'update', - index: 3, - user_id: 1, - user: { - id: 1, - nickname: 'Super Admin', - email: 'admin@nocobase.com', - appLang: null, - token: '6287df8c3f623ba2cb12', - reset_token: null, - sort: 1, - created_at: '2022-02-17T05:31:09.172Z', - updated_at: '2022-02-17T05:31:32.031Z', - }, - collection: { - name: 't_2uhu4szs1kq', - logging: true, - title: '任务', - privilege: null, - sortable: 'sort', - options: {}, - sort: 3, - created_at: '2021-09-03T08:17:30.495Z', - updated_at: '2021-09-18T04:15:42.572Z', - ui_schema_key: null, - }, - }, - { - id: 33, - created_at: '2022-03-02T09:16:04.209Z', - collection_name: 't_2uhu4szs1kq', - type: 'update', - index: 3, - user_id: 1, - user: { - id: 1, - nickname: 'Super Admin', - email: 'admin@nocobase.com', - appLang: null, - token: '6287df8c3f623ba2cb12', - reset_token: null, - sort: 1, - created_at: '2022-02-17T05:31:09.172Z', - updated_at: '2022-02-17T05:31:32.031Z', - }, - collection: { - name: 't_2uhu4szs1kq', - logging: true, - title: '任务', - privilege: null, - sortable: 'sort', - options: {}, - sort: 3, - created_at: '2021-09-03T08:17:30.495Z', - updated_at: '2021-09-18T04:15:42.572Z', - ui_schema_key: null, - }, - }, - { - id: 32, - created_at: '2022-03-02T09:16:02.289Z', - collection_name: 't_2uhu4szs1kq', - type: 'update', - index: 5, - user_id: null, - user: null, - collection: { - name: 't_2uhu4szs1kq', - logging: true, - title: '任务', - privilege: null, - sortable: 'sort', - options: {}, - sort: 3, - created_at: '2021-09-03T08:17:30.495Z', - updated_at: '2021-09-18T04:15:42.572Z', - ui_schema_key: null, - }, - }, - ], - meta: { count: 41, page: 1, per_page: 10 }, -}; diff --git a/packages/core/client/src/action-logs/index.md b/packages/core/client/src/action-logs/index.md deleted file mode 100644 index 04938463e..000000000 --- a/packages/core/client/src/action-logs/index.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -nav: - path: /client -group: - path: /client ---- - -# ActionLogs - -## Examples - - diff --git a/packages/core/client/src/action-logs/index.ts b/packages/core/client/src/action-logs/index.ts deleted file mode 100644 index f5fe65168..000000000 --- a/packages/core/client/src/action-logs/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './ActionLog'; -export * from './ActionLogBlockInitializer'; -export * from './ActionLogProvider'; diff --git a/packages/core/client/src/collection-manager/Configuration/ConfigurationTable.tsx b/packages/core/client/src/collection-manager/Configuration/ConfigurationTable.tsx index a801a8d73..076bb3118 100644 --- a/packages/core/client/src/collection-manager/Configuration/ConfigurationTable.tsx +++ b/packages/core/client/src/collection-manager/Configuration/ConfigurationTable.tsx @@ -1,12 +1,10 @@ -import { Field } from '@formily/core'; -import { useFieldSchema, useForm } from '@formily/react'; +import { useForm } from '@formily/react'; import { action } from '@formily/reactive'; import { uid } from '@formily/shared'; import React, { useContext, useEffect, useState } from 'react'; import { useRequest } from '../../api-client'; import { useRecord } from '../../record-provider'; import { SchemaComponent, useActionContext, useCompile } from '../../schema-component'; -import { useCollection } from '../hooks'; import { useCollectionManager } from '../hooks/useCollectionManager'; import { DataSourceContext } from '../sub-table'; import { AddSubFieldAction } from './AddSubFieldAction'; @@ -33,6 +31,7 @@ const useCollectionValues = (options) => { createdBy: true, updatedBy: true, sortable: true, + logging: true, fields: [ { name: 'id', diff --git a/packages/core/client/src/collection-manager/index.tsx b/packages/core/client/src/collection-manager/index.tsx index e5689827d..437328ddc 100644 --- a/packages/core/client/src/collection-manager/index.tsx +++ b/packages/core/client/src/collection-manager/index.tsx @@ -1,3 +1,4 @@ +export { useCollectionFilterOptions, useSortFields } from './action-hooks'; export * from './CollectionField'; export * from './CollectionFieldProvider'; export * from './CollectionManagerProvider'; diff --git a/packages/core/client/src/index.tsx b/packages/core/client/src/index.tsx index 4a95666ab..b43c12fcc 100644 --- a/packages/core/client/src/index.tsx +++ b/packages/core/client/src/index.tsx @@ -1,7 +1,6 @@ import './global.less'; export * from './acl'; -export * from './action-logs'; export * from './antd-config-provider'; export * from './api-client'; export * from './application'; diff --git a/packages/core/client/src/locale/en_US.ts b/packages/core/client/src/locale/en_US.ts index 392c5bc0f..d499a950e 100644 --- a/packages/core/client/src/locale/en_US.ts +++ b/packages/core/client/src/locale/en_US.ts @@ -526,5 +526,10 @@ export default { "Invalid JSON format": "Invalid JSON format", "After successful request": "After successful request", "Add exported field": "Add exported field", - "Exported table header name": "Exported table header name" + "Exported table header name": "Exported table header name", + "Audit logs": "Audit logs", + "Record ID": "Record ID", + "User": "User", + "Field": "Field", + "Field value changes": "Field value changes", } diff --git a/packages/core/client/src/locale/zh_CN.ts b/packages/core/client/src/locale/zh_CN.ts index ffc83d8ff..f24a511de 100644 --- a/packages/core/client/src/locale/zh_CN.ts +++ b/packages/core/client/src/locale/zh_CN.ts @@ -576,5 +576,10 @@ export default { 'Request body': '请求体(JSON格式)', 'Request success': '请求成功', 'Invalid JSON format': '非法JSON格式', - 'After successful request': '请求成功之后' + 'After successful request': '请求成功之后', + "Audit logs": "操作记录", + "Record ID": "数据 ID", + "User": "用户", + "Field": "字段", + "Field value changes": "变更记录", } diff --git a/packages/core/client/src/schema-initializer/buttons/BlockInitializers.tsx b/packages/core/client/src/schema-initializer/buttons/BlockInitializers.tsx index b7f0571b5..c7f3b0b46 100644 --- a/packages/core/client/src/schema-initializer/buttons/BlockInitializers.tsx +++ b/packages/core/client/src/schema-initializer/buttons/BlockInitializers.tsx @@ -164,6 +164,12 @@ export const BlockInitializers = { title: '{{t("Markdown")}}', component: 'MarkdownBlockInitializer', }, + { + key: 'auditLogs', + type: 'item', + title: '{{t("Audit logs")}}', + component: 'AuditLogsBlockInitializer', + }, ], }, ], diff --git a/packages/core/client/src/schema-initializer/buttons/CreateFormBlockInitializers.tsx b/packages/core/client/src/schema-initializer/buttons/CreateFormBlockInitializers.tsx index 725ea2392..12acb733e 100644 --- a/packages/core/client/src/schema-initializer/buttons/CreateFormBlockInitializers.tsx +++ b/packages/core/client/src/schema-initializer/buttons/CreateFormBlockInitializers.tsx @@ -27,7 +27,7 @@ export const CreateFormBlockInitializers = (props: any) => { }, { type: 'itemGroup', - title: '{{t("Media")}}', + title: '{{t("Other blocks")}}', children: [ { type: 'item', diff --git a/packages/core/client/src/schema-initializer/buttons/RecordBlockInitializers.tsx b/packages/core/client/src/schema-initializer/buttons/RecordBlockInitializers.tsx index c6cd218f2..b61067611 100644 --- a/packages/core/client/src/schema-initializer/buttons/RecordBlockInitializers.tsx +++ b/packages/core/client/src/schema-initializer/buttons/RecordBlockInitializers.tsx @@ -54,7 +54,7 @@ export const RecordBlockInitializers = (props: any) => { }, { type: 'itemGroup', - title: '{{t("Media")}}', + title: '{{t("Other blocks")}}', children: [ { key: 'markdown', @@ -62,6 +62,12 @@ export const RecordBlockInitializers = (props: any) => { title: '{{t("Markdown")}}', component: 'MarkdownBlockInitializer', }, + { + key: 'auditLogs', + type: 'item', + title: '{{t("Audit logs")}}', + component: 'AuditLogsBlockInitializer', + }, ], }, ]} diff --git a/packages/core/client/src/schema-initializer/buttons/RecordFormBlockInitializers.tsx b/packages/core/client/src/schema-initializer/buttons/RecordFormBlockInitializers.tsx index 81486a080..8abcae900 100644 --- a/packages/core/client/src/schema-initializer/buttons/RecordFormBlockInitializers.tsx +++ b/packages/core/client/src/schema-initializer/buttons/RecordFormBlockInitializers.tsx @@ -24,7 +24,7 @@ export const RecordFormBlockInitializers = (props: any) => { }, { type: 'itemGroup', - title: '{{t("Media")}}', + title: '{{t("Other blocks")}}', children: [ { type: 'item', diff --git a/packages/core/client/src/schema-initializer/buttons/TableSelectorInitializers.tsx b/packages/core/client/src/schema-initializer/buttons/TableSelectorInitializers.tsx index 87078630f..c6a931758 100644 --- a/packages/core/client/src/schema-initializer/buttons/TableSelectorInitializers.tsx +++ b/packages/core/client/src/schema-initializer/buttons/TableSelectorInitializers.tsx @@ -25,7 +25,7 @@ export const TableSelectorInitializers = (props: any) => { }, { type: 'itemGroup', - title: t('Media'), + title: t('Other blocks'), children: [ { type: 'item', diff --git a/packages/core/devtools/umiConfig.js b/packages/core/devtools/umiConfig.js index ff08758eb..6c7e64ecc 100644 --- a/packages/core/devtools/umiConfig.js +++ b/packages/core/devtools/umiConfig.js @@ -1,6 +1,7 @@ const { existsSync } = require('fs'); const { resolve } = require('path'); const packageJson = require('./package.json'); +const fs = require('fs'); console.log('VERSION: ', packageJson.version); @@ -44,16 +45,21 @@ function getUmiConfig() { } function resolveNocobasePackagesAlias(config) { - const clientSrc = resolve(process.cwd(), './packages/core/client/src'); - const utilsSrc = resolve(process.cwd(), './packages/core/utils/src'); - const sdkSrc = resolve(process.cwd(), './packages/core/sdk/src'); - if (existsSync(clientSrc)) { - config.module.rules.get('ts-in-node_modules').include.add(clientSrc); - config.resolve.alias.set('@nocobase/client', clientSrc); - config.module.rules.get('ts-in-node_modules').include.add(utilsSrc); - config.resolve.alias.set('@nocobase/utils', utilsSrc); - config.module.rules.get('ts-in-node_modules').include.add(sdkSrc); - config.resolve.alias.set('@nocobase/sdk', sdkSrc); + const cores = fs.readdirSync(resolve(process.cwd(), './packages/core')); + for (const package of cores) { + const packageSrc = resolve(process.cwd(), './packages/core/', package, 'src'); + if (existsSync(packageSrc)) { + config.module.rules.get('ts-in-node_modules').include.add(packageSrc); + config.resolve.alias.set(`@nocobase/${package}`, packageSrc); + } + } + const plugins = fs.readdirSync(resolve(process.cwd(), './packages/plugins')); + for (const package of plugins) { + const packageSrc = resolve(process.cwd(), './packages/plugins/', package, 'src'); + if (existsSync(packageSrc)) { + config.module.rules.get('ts-in-node_modules').include.add(packageSrc); + config.resolve.alias.set(`@nocobase/plugin-${package}`, packageSrc); + } } } diff --git a/packages/plugins/action-logs/.npmignore b/packages/plugins/audit-logs/.npmignore similarity index 100% rename from packages/plugins/action-logs/.npmignore rename to packages/plugins/audit-logs/.npmignore diff --git a/packages/plugins/audit-logs/client.d.ts b/packages/plugins/audit-logs/client.d.ts new file mode 100755 index 000000000..d472744e5 --- /dev/null +++ b/packages/plugins/audit-logs/client.d.ts @@ -0,0 +1,2 @@ +// @ts-nocheck +export * from './lib/client'; diff --git a/packages/plugins/audit-logs/client.js b/packages/plugins/audit-logs/client.js new file mode 100755 index 000000000..5effcafee --- /dev/null +++ b/packages/plugins/audit-logs/client.js @@ -0,0 +1,12 @@ +var _useExportClient = require("./lib/client"); + +Object.keys(_useExportClient).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (key in exports && exports[key] === _useExportClient[key]) return; + Object.defineProperty(exports, key, { + enumerable: true, + get: function get() { + return _useExportClient[key]; + } + }); +}); diff --git a/packages/plugins/action-logs/package.json b/packages/plugins/audit-logs/package.json similarity index 57% rename from packages/plugins/action-logs/package.json rename to packages/plugins/audit-logs/package.json index 6b89f4994..a3cbdb412 100644 --- a/packages/plugins/action-logs/package.json +++ b/packages/plugins/audit-logs/package.json @@ -1,8 +1,8 @@ { - "name": "@nocobase/plugin-action-logs", + "name": "@nocobase/plugin-audit-logs", "version": "0.7.0-alpha.83", - "main": "./lib/index.js", - "types": "./lib/index.d.ts", + "main": "./lib/server/index.js", + "types": "./lib/server/index.d.ts", "license": "Apache-2.0", "licenses": [ { @@ -10,6 +10,10 @@ "url": "http://www.apache.org/licenses/LICENSE-2.0" } ], + "dependencies": { + "@nocobase/client": "0.7.0-alpha.83", + "@nocobase/server": "0.7.0-alpha.83" + }, "devDependencies": { "@nocobase/test": "0.7.0-alpha.83" }, diff --git a/packages/plugins/audit-logs/server.d.ts b/packages/plugins/audit-logs/server.d.ts new file mode 100755 index 000000000..d8ed31d87 --- /dev/null +++ b/packages/plugins/audit-logs/server.d.ts @@ -0,0 +1,2 @@ +// @ts-nocheck +export * from './lib/server'; diff --git a/packages/plugins/audit-logs/server.js b/packages/plugins/audit-logs/server.js new file mode 100755 index 000000000..c93247d51 --- /dev/null +++ b/packages/plugins/audit-logs/server.js @@ -0,0 +1,12 @@ +var _useExportServer = require("./lib/server"); + +Object.keys(_useExportServer).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (key in exports && exports[key] === _useExportServer[key]) return; + Object.defineProperty(exports, key, { + enumerable: true, + get: function get() { + return _useExportServer[key]; + } + }); +}); diff --git a/packages/plugins/audit-logs/src/client/AuditLogs.tsx b/packages/plugins/audit-logs/src/client/AuditLogs.tsx new file mode 100644 index 000000000..24f9a210f --- /dev/null +++ b/packages/plugins/audit-logs/src/client/AuditLogs.tsx @@ -0,0 +1,493 @@ +import { ArrayTable } from '@formily/antd'; +import { observer, useField } from '@formily/react'; +import { + CollectionManagerContext, + CollectionManagerProvider, + FormProvider, + SchemaComponent, + TableBlockProvider, + useCollection, + useCompile, useRecord +} from '@nocobase/client'; +import React, { createContext, useContext } from 'react'; +import { AuditLogsDesigner } from './AuditLogsDesigner'; + +const collection = { + name: 'auditLogs', + title: '{{t("Audit logs")}}', + fields: [ + { + name: 'createdAt', + type: 'date', + interface: 'createdAt', + uiSchema: { + type: 'datetime', + title: '{{t("Created at")}}', + 'x-component': 'DatePicker', + 'x-component-props': { + showTime: true, + }, + 'x-read-pretty': true, + }, + }, + { + name: 'type', + type: 'string', + interface: 'select', + uiSchema: { + type: 'string', + title: '{{t("Action type")}}', + 'x-component': 'Select', + 'x-read-pretty': true, + enum: [ + { label: '{{t("Create record")}}', value: 'create', color: 'lime' }, + { label: '{{t("Update record")}}', value: 'update', color: 'gold' }, + { label: '{{t("Delete record")}}', value: 'destroy', color: 'magenta' }, + ], + }, + }, + ], +}; + +const Username = observer(() => { + const field = useField(); + return
{field?.value?.nickname || field.value?.id}
; +}); + +const Collection = observer(() => { + const field = useField(); + const { title, name } = field.value || {}; + const compile = useCompile(); + return
{title ? compile(title) : name}
; +}); + +const Field = observer(() => { + const field = useField(); + const compile = useCompile(); + if (!field.value) { + return null; + } + return
{field.value?.uiSchema?.title ? compile(field.value?.uiSchema?.title) : field.value.name}
; +}); + +const Value = observer(() => { + const field = useField(); + const record = ArrayTable.useRecord(); + if (record.field?.uiSchema) { + return ( + + + + ); + } + return
{field.value ? JSON.stringify(field.value) : null}
; +}); + +const IsAssociationBlock = createContext(null); + +export const AuditLogs: any = () => { + const isAssoc = useContext(IsAssociationBlock); + const ext = {}; + if (!isAssoc) { + ext['column31'] = { + type: 'void', + 'x-component': 'TableV2.Column', + title: '{{t("Record ID")}}', + properties: { + recordId: { + 'x-component': 'Input', + 'x-read-pretty': true, + }, + }, + } + } + return ( + + ); +}; + +AuditLogs.Decorator = observer((props: any) => { + const parent = useCollection(); + const record = useRecord(); + const { interfaces } = useContext(CollectionManagerContext); + let filter = props?.params?.filter; + if (parent.name) { + const filterByTk = record?.[parent.filterTargetKey || 'id']; + if (filter) { + filter = { + $and: [filter, { + collectionName: parent.name, + recordId: filterByTk, + }], + }; + } else { + filter = { + collectionName: parent.name, + recordId: filterByTk, + }; + } + } + const defaults = { + collection: 'auditLogs', + resource: 'auditLogs', + action: 'list', + params: { + pageSize: 20, + appends: ['collection', 'user'], + ...props.params, + filter, + }, + rowKey: 'id', + showIndex: true, + dragSort: false, + }; + return ( + + + {props.children} + + + ); +}); + +AuditLogs.Designer = AuditLogsDesigner; diff --git a/packages/plugins/audit-logs/src/client/AuditLogsBlockInitializer.tsx b/packages/plugins/audit-logs/src/client/AuditLogsBlockInitializer.tsx new file mode 100644 index 000000000..45bb683cb --- /dev/null +++ b/packages/plugins/audit-logs/src/client/AuditLogsBlockInitializer.tsx @@ -0,0 +1,33 @@ +import { TableOutlined } from '@ant-design/icons'; +import { SchemaInitializer } from '@nocobase/client'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; + +export const AuditLogsBlockInitializer = (props) => { + const { insert } = props; + const { t } = useTranslation(); + return ( + } + onClick={() => { + insert({ + type: 'void', + 'x-designer': 'AuditLogs.Designer', + 'x-decorator': 'AuditLogs.Decorator', + 'x-decorator-props': { + params: {}, + }, + 'x-component': 'CardItem', + properties: { + auditLogs: { + type: 'void', + 'x-component': 'AuditLogs', + }, + }, + }); + }} + title={t('Audit Logs')} + /> + ); +}; diff --git a/packages/core/client/src/action-logs/ActionLog.Designer.tsx b/packages/plugins/audit-logs/src/client/AuditLogsDesigner.tsx similarity index 57% rename from packages/core/client/src/action-logs/ActionLog.Designer.tsx rename to packages/plugins/audit-logs/src/client/AuditLogsDesigner.tsx index 9770a2c77..05a9411b3 100644 --- a/packages/core/client/src/action-logs/ActionLog.Designer.tsx +++ b/packages/plugins/audit-logs/src/client/AuditLogsDesigner.tsx @@ -1,46 +1,44 @@ import { ISchema, useField, useFieldSchema } from '@formily/react'; +import { GeneralSchemaDesigner, SchemaSettings, useCollection, useCollectionFilterOptions, useDesignable, useSortFields, useTableBlockContext } from '@nocobase/client'; import React from 'react'; import { useTranslation } from 'react-i18next'; -import { useCollection, useResourceActionContext } from '../collection-manager'; -import { useCollectionFilterOptions } from '../collection-manager/action-hooks'; -import { useDesignable } from '../schema-component/hooks'; -import { GeneralSchemaDesigner, SchemaSettings } from '../schema-settings'; -export const ActionLogDesigner = () => { - const { name, title } = useCollection(); +export const AuditLogsDesigner = () => { + const { name, title, sortable } = useCollection(); const field = useField(); const fieldSchema = useFieldSchema(); const dataSource = useCollectionFilterOptions(name); - const ctx = useResourceActionContext(); + const sortFields = useSortFields(name); + const { service } = useTableBlockContext(); const { t } = useTranslation(); const { dn } = useDesignable(); - const defaultFilter = fieldSchema?.['x-decorator-props']?.request?.params?.filter || {}; - + const defaultFilter = fieldSchema?.['x-decorator-props']?.params?.filter || {}; + const defaultSort = fieldSchema?.['x-decorator-props']?.params?.sort || []; return ( { - const params = field.decoratorProps.request.params || {}; + const params = field.decoratorProps.params || {}; params.filter = filter; - field.decoratorProps.request.params = params; - fieldSchema['x-decorator-props']['request']['params'] = params; - ctx.run({ ...ctx.params?.[0], filter }); + field.decoratorProps.params = params; + fieldSchema['x-decorator-props']['params'] = params; + service.run({ ...service.params?.[0], filter, page: 1 }); dn.emit('patch', { schema: { ['x-uid']: fieldSchema['x-uid'], @@ -49,10 +47,9 @@ export const ActionLogDesigner = () => { }); }} /> - { { label: '200', value: 200 }, ]} onChange={(pageSize) => { - const params = field.decoratorProps.request.params || {}; + const params = field.decoratorProps.params || {}; params.pageSize = pageSize; - field.decoratorProps.request.params = params; - fieldSchema['x-decorator-props']['request']['params'] = params; - ctx.run({ ...ctx.params?.[0], pageSize }); + field.decoratorProps.params = params; + fieldSchema['x-decorator-props']['params'] = params; + service.run({ ...service.params?.[0], pageSize, page: 1 }); dn.emit('patch', { schema: { ['x-uid']: fieldSchema['x-uid'], diff --git a/packages/plugins/audit-logs/src/client/AuditLogsProvider.tsx b/packages/plugins/audit-logs/src/client/AuditLogsProvider.tsx new file mode 100644 index 000000000..9c0fad0ca --- /dev/null +++ b/packages/plugins/audit-logs/src/client/AuditLogsProvider.tsx @@ -0,0 +1,12 @@ +import { SchemaComponentOptions } from '@nocobase/client'; +import React from 'react'; +import { AuditLogs } from './AuditLogs'; +import { AuditLogsBlockInitializer } from './AuditLogsBlockInitializer'; + +export const AuditLogsProvider = (props: any) => { + return ( + + {props.children} + + ); +}; diff --git a/packages/plugins/audit-logs/src/client/index.ts b/packages/plugins/audit-logs/src/client/index.ts new file mode 100644 index 000000000..42cefcafa --- /dev/null +++ b/packages/plugins/audit-logs/src/client/index.ts @@ -0,0 +1,3 @@ +export * from './AuditLogsBlockInitializer'; +export * from './AuditLogsProvider'; + diff --git a/packages/core/client/src/action-logs/utils.ts b/packages/plugins/audit-logs/src/client/utils.ts similarity index 100% rename from packages/core/client/src/action-logs/utils.ts rename to packages/plugins/audit-logs/src/client/utils.ts diff --git a/packages/plugins/action-logs/src/index.ts b/packages/plugins/audit-logs/src/index.ts similarity index 100% rename from packages/plugins/action-logs/src/index.ts rename to packages/plugins/audit-logs/src/index.ts diff --git a/packages/plugins/action-logs/src/__tests__/hook.test.ts b/packages/plugins/audit-logs/src/server/__tests__/hook.test.ts similarity index 65% rename from packages/plugins/action-logs/src/__tests__/hook.test.ts rename to packages/plugins/audit-logs/src/server/__tests__/hook.test.ts index ff9375cf1..b9d27882a 100644 --- a/packages/plugins/action-logs/src/__tests__/hook.test.ts +++ b/packages/plugins/audit-logs/src/server/__tests__/hook.test.ts @@ -1,6 +1,6 @@ import Database from '@nocobase/database'; import { mockServer, MockServer } from '@nocobase/test'; -import logPlugin from '../server'; +import logPlugin from '../'; describe('hook', () => { let api: MockServer; @@ -47,8 +47,8 @@ describe('hook', () => { const post = await Post.create({ title: 't1' }); await post.update({ title: 't2' }); await post.destroy(); - const ActionLog = db.getCollection('action_logs').model; - const count = await ActionLog.count(); + const AuditLog = db.getCollection('auditLogs').model; + const count = await AuditLog.count(); expect(count).toBe(3); }); @@ -56,7 +56,7 @@ describe('hook', () => { const Post = db.getCollection('posts'); const User = db.getCollection('users').model; const user = await User.create({ nickname: 'a', token: 'token1' }); - await Post.repository.create({ + const post = await Post.repository.create({ values: { title: 't1' }, context: { state: { @@ -64,14 +64,15 @@ describe('hook', () => { }, }, }); - const ActionLog = db.getCollection('action_logs'); - const log = await ActionLog.repository.findOne({ + const AuditLog = db.getCollection('auditLogs'); + const log = await AuditLog.repository.findOne({ appends: ['changes'], }); expect(log.toJSON()).toMatchObject({ collectionName: 'posts', type: 'create', userId: 1, + recordId: `${post.get('id')}`, changes: [ { field: { @@ -85,21 +86,21 @@ describe('hook', () => { }); }); - it.skip('resource', async () => { - const agent = api.agent(); - agent.set('Authorization', `Bearer token1`); - const response = await agent.resource('posts').create({ - values: { title: 't1' }, - }); - await agent.resource('posts').update({ - resourceIndex: response.body.data.id, - values: { title: 't2' }, - }); - await agent.resource('posts').destroy({ - resourceIndex: response.body.data.id, - }); - const ActionLog = db.getCollection('action_logs').model; - const count = await ActionLog.count(); - expect(count).toBe(3); - }); + // it.skip('resource', async () => { + // const agent = api.agent(); + // agent.set('Authorization', `Bearer token1`); + // const response = await agent.resource('posts').create({ + // values: { title: 't1' }, + // }); + // await agent.resource('posts').update({ + // resourceIndex: response.body.data.id, + // values: { title: 't2' }, + // }); + // await agent.resource('posts').destroy({ + // resourceIndex: response.body.data.id, + // }); + // const ActionLog = db.getCollection('action_logs').model; + // const count = await ActionLog.count(); + // expect(count).toBe(3); + // }); }); diff --git a/packages/plugins/action-logs/src/collections/action_changes.ts b/packages/plugins/audit-logs/src/server/collections/auditChanges.ts similarity index 64% rename from packages/plugins/action-logs/src/collections/action_changes.ts rename to packages/plugins/audit-logs/src/server/collections/auditChanges.ts index 24f230033..cae4c356f 100644 --- a/packages/plugins/action-logs/src/collections/action_changes.ts +++ b/packages/plugins/audit-logs/src/server/collections/auditChanges.ts @@ -1,19 +1,13 @@ -import { CollectionOptions } from '@nocobase/database'; +import { defineCollection } from '@nocobase/database'; -export default { - name: 'action_changes', +export default defineCollection({ + name: 'auditChanges', title: '变动值', createdBy: false, updatedBy: false, createdAt: false, updatedAt: false, fields: [ - { - type: 'belongsTo', - name: 'log', - target: 'action_logs', - foreignKey: 'actionLogId', - }, { type: 'json', name: 'field', @@ -26,5 +20,11 @@ export default { type: 'json', name: 'after', }, + { + type: 'belongsTo', + name: 'log', + target: 'auditLogs', + foreignKey: 'auditLogId', + }, ], -} as CollectionOptions; +}); diff --git a/packages/plugins/action-logs/src/collections/action_logs.ts b/packages/plugins/audit-logs/src/server/collections/auditLogs.ts similarity index 65% rename from packages/plugins/action-logs/src/collections/action_logs.ts rename to packages/plugins/audit-logs/src/server/collections/auditLogs.ts index f67bfd699..7c72c5fc1 100644 --- a/packages/plugins/action-logs/src/collections/action_logs.ts +++ b/packages/plugins/audit-logs/src/server/collections/auditLogs.ts @@ -1,8 +1,7 @@ -import { CollectionOptions } from '@nocobase/database'; +import { defineCollection } from '@nocobase/database'; -export default { - name: 'action_logs', - title: '操作记录', +export default defineCollection({ + name: 'auditLogs', createdBy: false, updatedBy: false, updatedAt: false, @@ -12,9 +11,12 @@ export default { name: 'createdAt', }, { - type: 'belongsTo', - name: 'user', - target: 'users', + type: 'string', + name: 'type', + }, + { + type: 'string', + name: 'recordId', }, { type: 'string', @@ -25,22 +27,20 @@ export default { name: 'collection', target: 'collections', targetKey: 'name', - sourceKey: 'collectionName', + sourceKey: 'id', + foreignKey: 'collectionName', constraints: false, }, - { - type: 'string', - name: 'type', - }, - { - type: 'integer', - name: 'index', - }, { type: 'hasMany', name: 'changes', - target: 'action_changes', - foreignKey: 'actionLogId', + target: 'auditChanges', + foreignKey: 'auditLogId', + }, + { + type: 'belongsTo', + name: 'user', + target: 'users', }, ], -} as CollectionOptions; +}); diff --git a/packages/plugins/action-logs/src/constants.ts b/packages/plugins/audit-logs/src/server/constants.ts similarity index 100% rename from packages/plugins/action-logs/src/constants.ts rename to packages/plugins/audit-logs/src/server/constants.ts diff --git a/packages/plugins/action-logs/src/hooks/after-create.ts b/packages/plugins/audit-logs/src/server/hooks/after-create.ts similarity index 59% rename from packages/plugins/action-logs/src/hooks/after-create.ts rename to packages/plugins/audit-logs/src/server/hooks/after-create.ts index 75644e904..e2df66f75 100644 --- a/packages/plugins/action-logs/src/hooks/after-create.ts +++ b/packages/plugins/audit-logs/src/server/hooks/after-create.ts @@ -1,4 +1,4 @@ -import Database, { updateAssociations } from '@nocobase/database'; +import Database from '@nocobase/database'; import { LOG_TYPE_CREATE } from '../constants'; export async function afterCreate(model, options) { @@ -8,22 +8,9 @@ export async function afterCreate(model, options) { return; } const transaction = options.transaction; - const ActionLog = db.getCollection('action_logs'); + const AuditLog = db.getCollection('auditLogs'); const currentUserId = options?.context?.state?.currentUser?.id; try { - const log = await ActionLog.model.create( - { - type: LOG_TYPE_CREATE, - collectionName: model.constructor.name, - index: model.get(model.constructor.primaryKeyAttribute), - createdAt: model.get('createdAt'), - userId: currentUserId, - }, - { - transaction, - hooks: false, - }, - ); const changes = []; const changed = model.changed(); if (changed) { @@ -31,21 +18,25 @@ export async function afterCreate(model, options) { const field = collection.findField((field) => { return field.name === key || field.options.field === key; }); - if (field && !field.options.hidden && field.options.type !== 'formula') { + if (field && !field.options.hidden) { changes.push({ field: field.options, after: model.get(key), }); } }); - await updateAssociations(log, { changes }, { transaction }); } - // if (!options.transaction) { - // await transaction.commit(); - // } - } catch (error) { - // if (!options.transaction) { - // await transaction.rollback(); - // } - } + await AuditLog.repository.create({ + values: { + type: LOG_TYPE_CREATE, + collectionName: model.constructor.name, + recordId: model.get(model.constructor.primaryKeyAttribute), + createdAt: model.get('createdAt'), + userId: currentUserId, + changes, + }, + transaction, + hooks: false, + }); + } catch (error) {} } diff --git a/packages/plugins/action-logs/src/hooks/after-destroy.ts b/packages/plugins/audit-logs/src/server/hooks/after-destroy.ts similarity index 73% rename from packages/plugins/action-logs/src/hooks/after-destroy.ts rename to packages/plugins/audit-logs/src/server/hooks/after-destroy.ts index 2a3fc0384..03e1d7e6a 100644 --- a/packages/plugins/action-logs/src/hooks/after-destroy.ts +++ b/packages/plugins/audit-logs/src/server/hooks/after-destroy.ts @@ -1,4 +1,4 @@ -import Database, { updateAssociations } from '@nocobase/database'; +import Database from '@nocobase/database'; import { LOG_TYPE_DESTROY } from '../constants'; export async function afterDestroy(model, options) { @@ -8,21 +8,9 @@ export async function afterDestroy(model, options) { return; } const transaction = options.transaction; - const ActionLog = db.getCollection('action_logs'); + const AuditLog = db.getCollection('auditLogs'); const currentUserId = options?.context?.state?.currentUser?.id; try { - const log = await ActionLog.model.create( - { - type: LOG_TYPE_DESTROY, - collectionName: model.constructor.name, - index: model.get(model.constructor.primaryKeyAttribute), - userId: currentUserId, - }, - { - transaction, - hooks: false, - }, - ); const changes = []; Object.keys(model.get()).forEach((key: string) => { const field = collection.findField((field) => { @@ -35,7 +23,17 @@ export async function afterDestroy(model, options) { }); } }); - await updateAssociations(log, { changes }, { transaction }); + await AuditLog.repository.create({ + values: { + type: LOG_TYPE_DESTROY, + collectionName: model.constructor.name, + recordId: model.get(model.constructor.primaryKeyAttribute), + userId: currentUserId, + changes, + }, + transaction, + hooks: false, + }); // if (!options.transaction) { // await transaction.commit(); // } diff --git a/packages/plugins/action-logs/src/hooks/after-update.ts b/packages/plugins/audit-logs/src/server/hooks/after-update.ts similarity index 72% rename from packages/plugins/action-logs/src/hooks/after-update.ts rename to packages/plugins/audit-logs/src/server/hooks/after-update.ts index 879e94649..a687f996a 100644 --- a/packages/plugins/action-logs/src/hooks/after-update.ts +++ b/packages/plugins/audit-logs/src/server/hooks/after-update.ts @@ -1,4 +1,4 @@ -import Database, { updateAssociations } from '@nocobase/database'; +import Database from '@nocobase/database'; import { LOG_TYPE_UPDATE } from '../constants'; export async function afterUpdate(model, options) { @@ -12,14 +12,14 @@ export async function afterUpdate(model, options) { return; } const transaction = options.transaction; - const ActionLog = db.getCollection('action_logs'); + const AuditLog = db.getCollection('auditLogs'); const currentUserId = options?.context?.state?.currentUser?.id; const changes = []; changed.forEach((key: string) => { const field = collection.findField((field) => { return field.name === key || field.options.field === key; }); - if (field && !field.options.hidden && field.options.type !== 'formula') { + if (field && !field.options.hidden) { changes.push({ field: field.options, after: model.get(key), @@ -31,20 +31,18 @@ export async function afterUpdate(model, options) { return; } try { - const log = await ActionLog.model.create( - { + await AuditLog.repository.create({ + values: { type: LOG_TYPE_UPDATE, collectionName: model.constructor.name, - index: model.get(model.constructor.primaryKeyAttribute), + recordId: model.get(model.constructor.primaryKeyAttribute), createdAt: model.get('updatedAt'), userId: currentUserId, + changes, }, - { - transaction, - hooks: false, - }, - ); - await updateAssociations(log, { changes }, { transaction }); + transaction, + hooks: false, + }); // if (!options.transaction) { // await transaction.commit(); // } diff --git a/packages/plugins/action-logs/src/hooks/index.ts b/packages/plugins/audit-logs/src/server/hooks/index.ts similarity index 100% rename from packages/plugins/action-logs/src/hooks/index.ts rename to packages/plugins/audit-logs/src/server/hooks/index.ts diff --git a/packages/plugins/action-logs/src/server.ts b/packages/plugins/audit-logs/src/server/index.ts similarity index 88% rename from packages/plugins/action-logs/src/server.ts rename to packages/plugins/audit-logs/src/server/index.ts index 3df4a5984..da304f973 100644 --- a/packages/plugins/action-logs/src/server.ts +++ b/packages/plugins/audit-logs/src/server/index.ts @@ -1,6 +1,6 @@ -import path from 'path'; -import { afterCreate, afterUpdate, afterDestroy } from './hooks'; import { Plugin } from '@nocobase/server'; +import path from 'path'; +import { afterCreate, afterDestroy, afterUpdate } from './hooks'; export default class PluginActionLogs extends Plugin { async beforeLoad() { diff --git a/packages/plugins/collection-manager/src/models/field.ts b/packages/plugins/collection-manager/src/models/field.ts index 5c9a81347..f602b35e9 100644 --- a/packages/plugins/collection-manager/src/models/field.ts +++ b/packages/plugins/collection-manager/src/models/field.ts @@ -22,7 +22,16 @@ export class FieldModel extends MagicAttributeModel { if (skipExist && collection.hasField(name)) { return collection.getField(name); } - return collection.setField(name, this.get()); + const options = this.get(); + if (options.uiSchemaUid) { + const UISchema = this.db.getModel('uiSchemas'); + const uiSchema = await UISchema.findByPk(options.uiSchemaUid, { + transaction: loadOptions.transaction, + }); + return collection.setField(name, { ...options, uiSchema }); + } else { + return collection.setField(name, options); + } } async migrate(options?: SyncOptions & Transactionable) { diff --git a/packages/plugins/collection-manager/src/plugin.ts b/packages/plugins/collection-manager/src/plugin.ts index 36a0e0d05..212c4a6da 100644 --- a/packages/plugins/collection-manager/src/plugin.ts +++ b/packages/plugins/collection-manager/src/plugin.ts @@ -8,7 +8,7 @@ import { afterCreateForReverseField, beforeCreateForChildrenCollection, beforeCreateForReverseField, - beforeInitOptions, + beforeInitOptions } from './hooks'; import { CollectionModel, FieldModel } from './models'; @@ -86,6 +86,12 @@ export class CollectionManagerPlugin extends Plugin { } }); + this.app.db.on('fields.afterCreateWithAssociations', async (model, { context, transaction }) => { + if (context) { + await model.load({ transaction }); + } + }); + this.app.db.on('fields.afterCreateWithAssociations', async (model, { context, transaction }) => { if (!context) { return; diff --git a/packages/plugins/users/src/collections/users.ts b/packages/plugins/users/src/collections/users.ts index 3a38e805e..8d6fc7408 100644 --- a/packages/plugins/users/src/collections/users.ts +++ b/packages/plugins/users/src/collections/users.ts @@ -7,6 +7,7 @@ export default { model: 'UserModel', createdBy: true, updatedBy: true, + logging: true, fields: [ { name: 'id',