chore: migrate audit logs plugin
This commit is contained in:
		
							parent
							
								
									83f01305cb
								
							
						
					
					
						commit
						ac1e9abf77
					
				
							
								
								
									
										2
									
								
								packages/plugins/@hera/plugin-audit-logs/.npmignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								packages/plugins/@hera/plugin-audit-logs/.npmignore
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,2 @@
 | 
			
		||||
/node_modules
 | 
			
		||||
/src
 | 
			
		||||
							
								
								
									
										1
									
								
								packages/plugins/@hera/plugin-audit-logs/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								packages/plugins/@hera/plugin-audit-logs/README.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
# @hera/plugin-audit-logs
 | 
			
		||||
							
								
								
									
										2
									
								
								packages/plugins/@hera/plugin-audit-logs/client.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								packages/plugins/@hera/plugin-audit-logs/client.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,2 @@
 | 
			
		||||
export * from './dist/client';
 | 
			
		||||
export { default } from './dist/client';
 | 
			
		||||
							
								
								
									
										1
									
								
								packages/plugins/@hera/plugin-audit-logs/client.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								packages/plugins/@hera/plugin-audit-logs/client.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
module.exports = require('./dist/client/index.js');
 | 
			
		||||
							
								
								
									
										24
									
								
								packages/plugins/@hera/plugin-audit-logs/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								packages/plugins/@hera/plugin-audit-logs/package.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,24 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@hera/plugin-audit-logs",
 | 
			
		||||
  "displayName": "Audit logs",
 | 
			
		||||
  "displayName.zh-CN": "审计日志",
 | 
			
		||||
  "description": "Audit logs.",
 | 
			
		||||
  "description.zh-CN": "审计日志。",
 | 
			
		||||
  "version": "1.0.0",
 | 
			
		||||
  "main": "dist/server/index.js",
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@ant-design/icons": "5.x",
 | 
			
		||||
    "@formily/antd-v5": "1.x",
 | 
			
		||||
    "@formily/react": "2.x",
 | 
			
		||||
    "@formily/shared": "2.x",
 | 
			
		||||
    "react": "^18.2.0",
 | 
			
		||||
    "react-i18next": "^11.15.1"
 | 
			
		||||
  },
 | 
			
		||||
  "peerDependencies": {
 | 
			
		||||
    "@nocobase/client": "0.x",
 | 
			
		||||
    "@nocobase/database": "0.x",
 | 
			
		||||
    "@nocobase/server": "0.x",
 | 
			
		||||
    "@nocobase/test": "0.x"
 | 
			
		||||
  },
 | 
			
		||||
  "dependencies": {}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										2
									
								
								packages/plugins/@hera/plugin-audit-logs/server.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								packages/plugins/@hera/plugin-audit-logs/server.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,2 @@
 | 
			
		||||
export * from './dist/server';
 | 
			
		||||
export { default } from './dist/server';
 | 
			
		||||
							
								
								
									
										1
									
								
								packages/plugins/@hera/plugin-audit-logs/server.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								packages/plugins/@hera/plugin-audit-logs/server.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
module.exports = require('./dist/server/index.js');
 | 
			
		||||
@ -0,0 +1,37 @@
 | 
			
		||||
import { TableOutlined } from '@ant-design/icons';
 | 
			
		||||
import { ISchema } from '@formily/react';
 | 
			
		||||
import {
 | 
			
		||||
  createTableBlockSchema,
 | 
			
		||||
  SchemaInitializerItem,
 | 
			
		||||
  useSchemaInitializer,
 | 
			
		||||
  useSchemaInitializerItem,
 | 
			
		||||
} from '@nocobase/client';
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { useTranslation } from 'react-i18next';
 | 
			
		||||
 | 
			
		||||
export const AuditLogsBlockInitializer = () => {
 | 
			
		||||
  const { insert } = useSchemaInitializer();
 | 
			
		||||
  const { t } = useTranslation();
 | 
			
		||||
  const itemConfig = useSchemaInitializerItem();
 | 
			
		||||
 | 
			
		||||
  const schema = createTableBlockSchema({
 | 
			
		||||
    collection: 'auditLogs',
 | 
			
		||||
    rowKey: 'id',
 | 
			
		||||
    tableActionInitializers: 'auditLogsTable:configureActions',
 | 
			
		||||
    tableColumnInitializers: 'auditLogsTable:configureColumns',
 | 
			
		||||
    tableActionColumnInitializers: 'auditLogsTable:configureItemActions',
 | 
			
		||||
    tableBlockProvider: 'AuditLogsBlockProvider',
 | 
			
		||||
    disableTemplate: true,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <SchemaInitializerItem
 | 
			
		||||
      icon={<TableOutlined />}
 | 
			
		||||
      onClick={() => {
 | 
			
		||||
        insert(schema as ISchema);
 | 
			
		||||
      }}
 | 
			
		||||
      title={t('Audit Logs')}
 | 
			
		||||
      {...itemConfig}
 | 
			
		||||
    />
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
@ -0,0 +1,17 @@
 | 
			
		||||
import { ExtendCollectionsProvider, TableBlockProvider } from '@nocobase/client';
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { useAuditChangesCollection, useAuditLogsCollection, useCollectionsCollection } from './collections';
 | 
			
		||||
 | 
			
		||||
export const AuditLogsBlockProvider: React.FC = ({ children, ...restProps }) => {
 | 
			
		||||
  const auditChangesCollection = useAuditChangesCollection();
 | 
			
		||||
  const auditLogsCollection = useAuditLogsCollection();
 | 
			
		||||
  const collectionsCollection = useCollectionsCollection();
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <ExtendCollectionsProvider collections={[auditLogsCollection, auditChangesCollection, collectionsCollection]}>
 | 
			
		||||
      <TableBlockProvider name="audit-logs" {...restProps}>
 | 
			
		||||
        {children}
 | 
			
		||||
      </TableBlockProvider>
 | 
			
		||||
    </ExtendCollectionsProvider>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
@ -0,0 +1,27 @@
 | 
			
		||||
import { SchemaComponentOptions } from '@nocobase/client';
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { AuditLogsBlockInitializer } from './AuditLogsBlockInitializer';
 | 
			
		||||
import { AuditLogsBlockProvider } from './AuditLogsBlockProvider';
 | 
			
		||||
import { AuditLogsField } from './components/AuditLogsField';
 | 
			
		||||
import { AuditLogsValue } from './components/AuditLogsValue';
 | 
			
		||||
import { AuditLogsViewActionInitializer } from './components/AuditLogsViewActionInitializer';
 | 
			
		||||
import { AuditLogs } from './deplicated/AuditLogs';
 | 
			
		||||
import { AuditLogsTableActionColumnInitializer } from './initializers/AuditLogsTableActionColumnInitializer';
 | 
			
		||||
 | 
			
		||||
export const AuditLogsProvider = (props: any) => {
 | 
			
		||||
  return (
 | 
			
		||||
    <SchemaComponentOptions
 | 
			
		||||
      components={{
 | 
			
		||||
        AuditLogs,
 | 
			
		||||
        AuditLogsBlockProvider,
 | 
			
		||||
        AuditLogsBlockInitializer,
 | 
			
		||||
        AuditLogsValue,
 | 
			
		||||
        AuditLogsField,
 | 
			
		||||
        AuditLogsViewActionInitializer,
 | 
			
		||||
        AuditLogsTableActionColumnInitializer,
 | 
			
		||||
      }}
 | 
			
		||||
    >
 | 
			
		||||
      {props.children}
 | 
			
		||||
    </SchemaComponentOptions>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
@ -0,0 +1,166 @@
 | 
			
		||||
import { useAuditLogsTranslation } from './locale';
 | 
			
		||||
 | 
			
		||||
export const useAuditLogsCollection = () => {
 | 
			
		||||
  return {
 | 
			
		||||
    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,
 | 
			
		||||
            ellipsis: true,
 | 
			
		||||
          },
 | 
			
		||||
          'x-read-pretty': true,
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        name: 'type',
 | 
			
		||||
        type: 'string',
 | 
			
		||||
        interface: 'select',
 | 
			
		||||
        uiSchema: {
 | 
			
		||||
          type: 'string',
 | 
			
		||||
          title: '{{t("Action type")}}',
 | 
			
		||||
          'x-component': 'Select',
 | 
			
		||||
          'x-component-props': { ellipsis: true },
 | 
			
		||||
          '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' },
 | 
			
		||||
          ],
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        name: 'recordId',
 | 
			
		||||
        type: 'string',
 | 
			
		||||
        interface: 'input',
 | 
			
		||||
        uiSchema: {
 | 
			
		||||
          title: '{{t("Record ID")}}',
 | 
			
		||||
          type: 'string',
 | 
			
		||||
          'x-component': 'Input',
 | 
			
		||||
          'x-component-props': { ellipsis: true },
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        collectionName: 'auditLogs',
 | 
			
		||||
        name: 'collection',
 | 
			
		||||
        type: 'belongsTo',
 | 
			
		||||
        interface: 'm2o',
 | 
			
		||||
        target: 'collections',
 | 
			
		||||
        targetKey: 'name',
 | 
			
		||||
        sourceKey: 'id',
 | 
			
		||||
        foreignKey: 'collectionName',
 | 
			
		||||
        uiSchema: {
 | 
			
		||||
          type: 'object',
 | 
			
		||||
          title: '{{t("Collection")}}',
 | 
			
		||||
          'x-component': 'AssociationField',
 | 
			
		||||
          'x-component-props': { fieldNames: { value: 'name', label: 'title' }, ellipsis: true },
 | 
			
		||||
          'x-read-pretty': true,
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        name: 'user',
 | 
			
		||||
        collectionName: 'auditLogs',
 | 
			
		||||
        type: 'belongsTo',
 | 
			
		||||
        interface: 'createdBy',
 | 
			
		||||
        targetKey: 'id',
 | 
			
		||||
        foreignKey: 'createdById',
 | 
			
		||||
        target: 'users',
 | 
			
		||||
        uiSchema: {
 | 
			
		||||
          type: 'object',
 | 
			
		||||
          title: '{{t("User")}}',
 | 
			
		||||
          'x-component': 'AssociationField',
 | 
			
		||||
          'x-component-props': { fieldNames: { value: 'id', label: 'nickname' }, ellipsis: true },
 | 
			
		||||
          'x-read-pretty': true,
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        name: 'changes',
 | 
			
		||||
        collectionName: 'auditLogs',
 | 
			
		||||
        type: 'hasMany',
 | 
			
		||||
        interface: 'subTable',
 | 
			
		||||
        target: 'auditChanges',
 | 
			
		||||
        foreignKey: 'auditLogId',
 | 
			
		||||
        targetKey: 'id',
 | 
			
		||||
        uiSchema: {
 | 
			
		||||
          type: 'object',
 | 
			
		||||
          title: '{{t("Details of changes", { ns: "audit-logs" })}}',
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
    ],
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const useAuditChangesCollection = () => {
 | 
			
		||||
  return {
 | 
			
		||||
    name: 'auditChanges',
 | 
			
		||||
    title: '{{t("Audit Changes")}}',
 | 
			
		||||
    fields: [
 | 
			
		||||
      {
 | 
			
		||||
        name: 'field',
 | 
			
		||||
        type: 'json',
 | 
			
		||||
        interface: 'input',
 | 
			
		||||
        uiSchema: {
 | 
			
		||||
          title: '{{t("Field")}}',
 | 
			
		||||
          'x-component': 'AuditLogsField',
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        type: 'json',
 | 
			
		||||
        name: 'before',
 | 
			
		||||
        interface: 'input',
 | 
			
		||||
        uiSchema: {
 | 
			
		||||
          title: '{{t("Before change")}}',
 | 
			
		||||
          'x-component': 'AuditLogsValue',
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        type: 'json',
 | 
			
		||||
        name: 'after',
 | 
			
		||||
        interface: 'input',
 | 
			
		||||
        uiSchema: {
 | 
			
		||||
          title: '{{t("After change")}}',
 | 
			
		||||
          'x-component': 'AuditLogsValue',
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
    ],
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const useCollectionsCollection = () => {
 | 
			
		||||
  return {
 | 
			
		||||
    name: 'collections',
 | 
			
		||||
    title: '{{t("Collections")}}',
 | 
			
		||||
    fields: [
 | 
			
		||||
      {
 | 
			
		||||
        name: 'name',
 | 
			
		||||
        type: 'string',
 | 
			
		||||
        interface: 'input',
 | 
			
		||||
        uiSchema: {
 | 
			
		||||
          title: '{{t("Collection name")}}',
 | 
			
		||||
          type: 'string',
 | 
			
		||||
          'x-component': 'Input',
 | 
			
		||||
          'x-component-props': { ellipsis: true },
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        name: 'title',
 | 
			
		||||
        type: 'string',
 | 
			
		||||
        interface: 'input',
 | 
			
		||||
        uiSchema: {
 | 
			
		||||
          title: '{{t("Collection display name")}}',
 | 
			
		||||
          type: 'string',
 | 
			
		||||
          'x-component': 'Input',
 | 
			
		||||
          'x-component-props': { ellipsis: true },
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
    ],
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
@ -0,0 +1,19 @@
 | 
			
		||||
import { EllipsisWithTooltip, useCompile } from '@nocobase/client';
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { observer, useField } from '@formily/react';
 | 
			
		||||
 | 
			
		||||
export const AuditLogsField = observer(
 | 
			
		||||
  () => {
 | 
			
		||||
    const field = useField<any>();
 | 
			
		||||
    const compile = useCompile();
 | 
			
		||||
    if (!field.value) {
 | 
			
		||||
      return null;
 | 
			
		||||
    }
 | 
			
		||||
    return (
 | 
			
		||||
      <EllipsisWithTooltip ellipsis>
 | 
			
		||||
        {field.value?.uiSchema?.title ? compile(field.value?.uiSchema?.title) : field.value.name}
 | 
			
		||||
      </EllipsisWithTooltip>
 | 
			
		||||
    );
 | 
			
		||||
  },
 | 
			
		||||
  { displayName: 'AuditLogsField' },
 | 
			
		||||
);
 | 
			
		||||
@ -0,0 +1,26 @@
 | 
			
		||||
import { EllipsisWithTooltip, FormProvider, SchemaComponent, useRecord } from '@nocobase/client';
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { observer, useField } from '@formily/react';
 | 
			
		||||
 | 
			
		||||
export const AuditLogsValue = observer(
 | 
			
		||||
  () => {
 | 
			
		||||
    const field = useField<any>();
 | 
			
		||||
    const record = useRecord();
 | 
			
		||||
    if (record.field?.uiSchema) {
 | 
			
		||||
      return (
 | 
			
		||||
        <FormProvider>
 | 
			
		||||
          <SchemaComponent
 | 
			
		||||
            schema={{
 | 
			
		||||
              name: record.field.name,
 | 
			
		||||
              ...record.field?.uiSchema,
 | 
			
		||||
              default: field.value,
 | 
			
		||||
              'x-read-pretty': true,
 | 
			
		||||
            }}
 | 
			
		||||
          />
 | 
			
		||||
        </FormProvider>
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
    return <EllipsisWithTooltip ellipsis>{field.value ? JSON.stringify(field.value) : null}</EllipsisWithTooltip>;
 | 
			
		||||
  },
 | 
			
		||||
  { displayName: 'AuditLogsValue' },
 | 
			
		||||
);
 | 
			
		||||
@ -0,0 +1,343 @@
 | 
			
		||||
import { ActionInitializer } from '@nocobase/client';
 | 
			
		||||
import React from 'react';
 | 
			
		||||
 | 
			
		||||
export const AuditLogsViewActionInitializer = () => {
 | 
			
		||||
  const schema = {
 | 
			
		||||
    type: 'void',
 | 
			
		||||
    title: '{{ t("View") }}',
 | 
			
		||||
    'x-action': 'view',
 | 
			
		||||
    // 'x-designer': 'Action.Designer',
 | 
			
		||||
    'x-toolbar': 'ActionSchemaToolbar',
 | 
			
		||||
    'x-settings': 'actionSettings:view',
 | 
			
		||||
    'x-component': 'Action',
 | 
			
		||||
    'x-component-props': {
 | 
			
		||||
      openMode: 'drawer',
 | 
			
		||||
    },
 | 
			
		||||
    properties: {
 | 
			
		||||
      drawer: {
 | 
			
		||||
        type: 'void',
 | 
			
		||||
        title: '{{ t("View record") }}',
 | 
			
		||||
        'x-component': 'Action.Container',
 | 
			
		||||
        'x-component-props': {
 | 
			
		||||
          className: 'nb-action-popup',
 | 
			
		||||
        },
 | 
			
		||||
        properties: {
 | 
			
		||||
          tabs: {
 | 
			
		||||
            type: 'void',
 | 
			
		||||
            'x-component': 'Tabs',
 | 
			
		||||
            'x-component-props': {},
 | 
			
		||||
            properties: {
 | 
			
		||||
              tab1: {
 | 
			
		||||
                type: 'void',
 | 
			
		||||
                title: '{{t("Details")}}',
 | 
			
		||||
                'x-component': 'Tabs.TabPane',
 | 
			
		||||
                'x-designer': 'Tabs.Designer',
 | 
			
		||||
                'x-component-props': {},
 | 
			
		||||
                properties: {
 | 
			
		||||
                  grid: {
 | 
			
		||||
                    type: 'void',
 | 
			
		||||
                    'x-component': 'Grid',
 | 
			
		||||
                    properties: {
 | 
			
		||||
                      '7ypqrxaqysp': {
 | 
			
		||||
                        type: 'void',
 | 
			
		||||
                        'x-component': 'Grid.Row',
 | 
			
		||||
                        properties: {
 | 
			
		||||
                          '1fc2l8dwe7m': {
 | 
			
		||||
                            type: 'void',
 | 
			
		||||
                            'x-component': 'Grid.Col',
 | 
			
		||||
                            properties: {
 | 
			
		||||
                              '5ley6xifrsb': {
 | 
			
		||||
                                type: 'void',
 | 
			
		||||
                                'x-acl-action': 'auditLogs:get',
 | 
			
		||||
                                'x-decorator': 'FormBlockProvider',
 | 
			
		||||
                                'x-decorator-props': {
 | 
			
		||||
                                  resource: 'auditLogs',
 | 
			
		||||
                                  collection: 'auditLogs',
 | 
			
		||||
                                  readPretty: true,
 | 
			
		||||
                                  action: 'get',
 | 
			
		||||
                                  params: {
 | 
			
		||||
                                    appends: ['collection', 'user', 'changes'],
 | 
			
		||||
                                  },
 | 
			
		||||
                                  useParams: '{{ useParamsFromRecord }}',
 | 
			
		||||
                                  useSourceId: '{{ useSourceIdFromParentRecord }}',
 | 
			
		||||
                                },
 | 
			
		||||
                                'x-component': 'CardItem',
 | 
			
		||||
                                properties: {
 | 
			
		||||
                                  bv710pbf9w6: {
 | 
			
		||||
                                    type: 'void',
 | 
			
		||||
                                    'x-component': 'FormV2',
 | 
			
		||||
                                    'x-read-pretty': true,
 | 
			
		||||
                                    'x-component-props': {
 | 
			
		||||
                                      useProps: '{{ useFormBlockProps }}',
 | 
			
		||||
                                    },
 | 
			
		||||
                                    properties: {
 | 
			
		||||
                                      grid: {
 | 
			
		||||
                                        type: 'void',
 | 
			
		||||
                                        'x-component': 'Grid',
 | 
			
		||||
                                        properties: {
 | 
			
		||||
                                          g4c24abnbd9: {
 | 
			
		||||
                                            type: 'void',
 | 
			
		||||
                                            'x-component': 'Grid.Row',
 | 
			
		||||
                                            properties: {
 | 
			
		||||
                                              fkt9dj5lu1k: {
 | 
			
		||||
                                                type: 'void',
 | 
			
		||||
                                                'x-component': 'Grid.Col',
 | 
			
		||||
                                                properties: {
 | 
			
		||||
                                                  createdAt: {
 | 
			
		||||
                                                    type: 'string',
 | 
			
		||||
                                                    'x-component': 'CollectionField',
 | 
			
		||||
                                                    'x-decorator': 'FormItem',
 | 
			
		||||
                                                    'x-collection-field': 'auditLogs.createdAt',
 | 
			
		||||
                                                    'x-component-props': {},
 | 
			
		||||
                                                    'x-read-pretty': true,
 | 
			
		||||
                                                  },
 | 
			
		||||
                                                },
 | 
			
		||||
                                              },
 | 
			
		||||
                                            },
 | 
			
		||||
                                          },
 | 
			
		||||
                                          l267bkv423v: {
 | 
			
		||||
                                            type: 'void',
 | 
			
		||||
                                            'x-component': 'Grid.Row',
 | 
			
		||||
                                            properties: {
 | 
			
		||||
                                              tehaepm5xqy: {
 | 
			
		||||
                                                type: 'void',
 | 
			
		||||
                                                'x-component': 'Grid.Col',
 | 
			
		||||
                                                properties: {
 | 
			
		||||
                                                  type: {
 | 
			
		||||
                                                    type: 'string',
 | 
			
		||||
                                                    'x-component': 'CollectionField',
 | 
			
		||||
                                                    'x-decorator': 'FormItem',
 | 
			
		||||
                                                    'x-collection-field': 'auditLogs.type',
 | 
			
		||||
                                                    'x-component-props': {},
 | 
			
		||||
                                                    'x-read-pretty': true,
 | 
			
		||||
                                                  },
 | 
			
		||||
                                                },
 | 
			
		||||
                                              },
 | 
			
		||||
                                            },
 | 
			
		||||
                                          },
 | 
			
		||||
                                          zhmn2tkzdh2: {
 | 
			
		||||
                                            type: 'void',
 | 
			
		||||
                                            'x-component': 'Grid.Row',
 | 
			
		||||
                                            properties: {
 | 
			
		||||
                                              yuwyej17i64: {
 | 
			
		||||
                                                type: 'void',
 | 
			
		||||
                                                'x-component': 'Grid.Col',
 | 
			
		||||
                                                properties: {
 | 
			
		||||
                                                  recordId: {
 | 
			
		||||
                                                    type: 'string',
 | 
			
		||||
                                                    'x-component': 'CollectionField',
 | 
			
		||||
                                                    'x-decorator': 'FormItem',
 | 
			
		||||
                                                    'x-collection-field': 'auditLogs.recordId',
 | 
			
		||||
                                                    'x-component-props': {},
 | 
			
		||||
                                                  },
 | 
			
		||||
                                                },
 | 
			
		||||
                                              },
 | 
			
		||||
                                            },
 | 
			
		||||
                                          },
 | 
			
		||||
                                          '6q933ic06mj': {
 | 
			
		||||
                                            type: 'void',
 | 
			
		||||
                                            'x-component': 'Grid.Row',
 | 
			
		||||
                                            properties: {
 | 
			
		||||
                                              nwtbkqd99zl2: {
 | 
			
		||||
                                                type: 'void',
 | 
			
		||||
                                                'x-component': 'Grid.Col',
 | 
			
		||||
                                                properties: {
 | 
			
		||||
                                                  'collection.title': {
 | 
			
		||||
                                                    type: 'string',
 | 
			
		||||
                                                    'x-component': 'CollectionField',
 | 
			
		||||
                                                    'x-decorator': 'FormItem',
 | 
			
		||||
                                                    'x-collection-field': 'auditLogs.collection.title',
 | 
			
		||||
                                                    'x-component-props': {},
 | 
			
		||||
                                                  },
 | 
			
		||||
                                                },
 | 
			
		||||
                                              },
 | 
			
		||||
                                              nwtbkqd99zl1: {
 | 
			
		||||
                                                type: 'void',
 | 
			
		||||
                                                'x-component': 'Grid.Col',
 | 
			
		||||
                                                properties: {
 | 
			
		||||
                                                  'collection.name': {
 | 
			
		||||
                                                    type: 'string',
 | 
			
		||||
                                                    'x-component': 'CollectionField',
 | 
			
		||||
                                                    'x-decorator': 'FormItem',
 | 
			
		||||
                                                    'x-collection-field': 'auditLogs.collection.name',
 | 
			
		||||
                                                    'x-component-props': {},
 | 
			
		||||
                                                  },
 | 
			
		||||
                                                },
 | 
			
		||||
                                              },
 | 
			
		||||
                                            },
 | 
			
		||||
                                          },
 | 
			
		||||
                                          xd4kzulndqk: {
 | 
			
		||||
                                            type: 'void',
 | 
			
		||||
                                            'x-component': 'Grid.Row',
 | 
			
		||||
                                            properties: {
 | 
			
		||||
                                              k3sd72n83zd: {
 | 
			
		||||
                                                type: 'void',
 | 
			
		||||
                                                'x-component': 'Grid.Col',
 | 
			
		||||
                                                properties: {
 | 
			
		||||
                                                  user: {
 | 
			
		||||
                                                    type: 'string',
 | 
			
		||||
                                                    'x-component': 'CollectionField',
 | 
			
		||||
                                                    'x-decorator': 'FormItem',
 | 
			
		||||
                                                    'x-collection-field': 'auditLogs.user',
 | 
			
		||||
                                                    'x-component-props': {},
 | 
			
		||||
                                                    'x-read-pretty': true,
 | 
			
		||||
                                                    properties: {
 | 
			
		||||
                                                      viewer: {
 | 
			
		||||
                                                        type: 'void',
 | 
			
		||||
                                                        title: '{{ t("View record") }}',
 | 
			
		||||
                                                        'x-component': 'RecordPicker.Viewer',
 | 
			
		||||
                                                        'x-component-props': {
 | 
			
		||||
                                                          className: 'nb-action-popup',
 | 
			
		||||
                                                        },
 | 
			
		||||
                                                        properties: {
 | 
			
		||||
                                                          tabs: {
 | 
			
		||||
                                                            type: 'void',
 | 
			
		||||
                                                            'x-component': 'Tabs',
 | 
			
		||||
                                                            'x-component-props': {},
 | 
			
		||||
                                                            'x-initializer': 'TabPaneInitializers',
 | 
			
		||||
                                                            properties: {
 | 
			
		||||
                                                              tab1: {
 | 
			
		||||
                                                                type: 'void',
 | 
			
		||||
                                                                title: '{{t("Details")}}',
 | 
			
		||||
                                                                'x-component': 'Tabs.TabPane',
 | 
			
		||||
                                                                'x-designer': 'Tabs.Designer',
 | 
			
		||||
                                                                'x-component-props': {},
 | 
			
		||||
                                                                properties: {
 | 
			
		||||
                                                                  grid: {
 | 
			
		||||
                                                                    type: 'void',
 | 
			
		||||
                                                                    'x-component': 'Grid',
 | 
			
		||||
                                                                    'x-initializer': 'popup:common:addBlock',
 | 
			
		||||
                                                                  },
 | 
			
		||||
                                                                },
 | 
			
		||||
                                                              },
 | 
			
		||||
                                                            },
 | 
			
		||||
                                                          },
 | 
			
		||||
                                                        },
 | 
			
		||||
                                                      },
 | 
			
		||||
                                                    },
 | 
			
		||||
                                                  },
 | 
			
		||||
                                                },
 | 
			
		||||
                                              },
 | 
			
		||||
                                            },
 | 
			
		||||
                                          },
 | 
			
		||||
                                          '3lghgclbtcg': {
 | 
			
		||||
                                            type: 'void',
 | 
			
		||||
                                            'x-component': 'Grid.Row',
 | 
			
		||||
                                            properties: {
 | 
			
		||||
                                              '8l1v1auwlx0': {
 | 
			
		||||
                                                type: 'void',
 | 
			
		||||
                                                'x-component': 'Grid.Col',
 | 
			
		||||
                                                properties: {
 | 
			
		||||
                                                  changes: {
 | 
			
		||||
                                                    type: 'void',
 | 
			
		||||
                                                    'x-component': 'TableField',
 | 
			
		||||
                                                    'x-decorator': 'FormItem',
 | 
			
		||||
                                                    'x-collection-field': 'auditLogs.changes',
 | 
			
		||||
                                                    'x-component-props': {},
 | 
			
		||||
                                                    properties: {
 | 
			
		||||
                                                      block: {
 | 
			
		||||
                                                        type: 'void',
 | 
			
		||||
                                                        'x-decorator': 'TableFieldProvider',
 | 
			
		||||
                                                        'x-acl-action': 'auditChanges:list',
 | 
			
		||||
                                                        'x-decorator-props': {
 | 
			
		||||
                                                          collection: 'auditChanges',
 | 
			
		||||
                                                          association: 'auditLogs.changes',
 | 
			
		||||
                                                          resource: 'auditLogs.changes',
 | 
			
		||||
                                                          action: 'list',
 | 
			
		||||
                                                          params: {
 | 
			
		||||
                                                            paginate: false,
 | 
			
		||||
                                                          },
 | 
			
		||||
                                                          showIndex: true,
 | 
			
		||||
                                                          dragSort: false,
 | 
			
		||||
                                                        },
 | 
			
		||||
                                                        properties: {
 | 
			
		||||
                                                          actions: {
 | 
			
		||||
                                                            type: 'void',
 | 
			
		||||
                                                            'x-component': 'TableField.ActionBar',
 | 
			
		||||
                                                            'x-component-props': {},
 | 
			
		||||
                                                          },
 | 
			
		||||
                                                          changes: {
 | 
			
		||||
                                                            type: 'array',
 | 
			
		||||
                                                            'x-component': 'TableV2',
 | 
			
		||||
                                                            'x-component-props': {
 | 
			
		||||
                                                              rowSelection: false,
 | 
			
		||||
                                                              useProps: '{{ useTableFieldProps }}',
 | 
			
		||||
                                                            },
 | 
			
		||||
                                                            properties: {
 | 
			
		||||
                                                              '5uvv96u9ict': {
 | 
			
		||||
                                                                type: 'void',
 | 
			
		||||
                                                                'x-decorator': 'TableV2.Column.Decorator',
 | 
			
		||||
                                                                'x-component': 'TableV2.Column',
 | 
			
		||||
                                                                properties: {
 | 
			
		||||
                                                                  field: {
 | 
			
		||||
                                                                    'x-collection-field': 'auditChanges.field',
 | 
			
		||||
                                                                    'x-component': 'CollectionField',
 | 
			
		||||
                                                                    'x-read-pretty': true,
 | 
			
		||||
                                                                    'x-component-props': {
 | 
			
		||||
                                                                      ellipsis: true,
 | 
			
		||||
                                                                    },
 | 
			
		||||
                                                                  },
 | 
			
		||||
                                                                },
 | 
			
		||||
                                                              },
 | 
			
		||||
                                                              h7a4tgt11gd: {
 | 
			
		||||
                                                                type: 'void',
 | 
			
		||||
                                                                'x-decorator': 'TableV2.Column.Decorator',
 | 
			
		||||
                                                                'x-component': 'TableV2.Column',
 | 
			
		||||
                                                                properties: {
 | 
			
		||||
                                                                  before: {
 | 
			
		||||
                                                                    'x-collection-field': 'auditChanges.before',
 | 
			
		||||
                                                                    'x-component': 'CollectionField',
 | 
			
		||||
                                                                    'x-read-pretty': true,
 | 
			
		||||
                                                                    'x-component-props': {
 | 
			
		||||
                                                                      ellipsis: true,
 | 
			
		||||
                                                                    },
 | 
			
		||||
                                                                  },
 | 
			
		||||
                                                                },
 | 
			
		||||
                                                              },
 | 
			
		||||
                                                              m275z8rglzx: {
 | 
			
		||||
                                                                type: 'void',
 | 
			
		||||
                                                                'x-decorator': 'TableV2.Column.Decorator',
 | 
			
		||||
                                                                'x-component': 'TableV2.Column',
 | 
			
		||||
                                                                properties: {
 | 
			
		||||
                                                                  after: {
 | 
			
		||||
                                                                    'x-collection-field': 'auditChanges.after',
 | 
			
		||||
                                                                    'x-component': 'CollectionField',
 | 
			
		||||
                                                                    'x-read-pretty': true,
 | 
			
		||||
                                                                    'x-component-props': {
 | 
			
		||||
                                                                      ellipsis: true,
 | 
			
		||||
                                                                    },
 | 
			
		||||
                                                                  },
 | 
			
		||||
                                                                },
 | 
			
		||||
                                                              },
 | 
			
		||||
                                                            },
 | 
			
		||||
                                                          },
 | 
			
		||||
                                                        },
 | 
			
		||||
                                                      },
 | 
			
		||||
                                                    },
 | 
			
		||||
                                                  },
 | 
			
		||||
                                                },
 | 
			
		||||
                                              },
 | 
			
		||||
                                            },
 | 
			
		||||
                                          },
 | 
			
		||||
                                        },
 | 
			
		||||
                                      },
 | 
			
		||||
                                    },
 | 
			
		||||
                                  },
 | 
			
		||||
                                },
 | 
			
		||||
                              },
 | 
			
		||||
                            },
 | 
			
		||||
                          },
 | 
			
		||||
                        },
 | 
			
		||||
                      },
 | 
			
		||||
                    },
 | 
			
		||||
                  },
 | 
			
		||||
                },
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
          },
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
  };
 | 
			
		||||
  return <ActionInitializer schema={schema} />;
 | 
			
		||||
};
 | 
			
		||||
@ -0,0 +1,513 @@
 | 
			
		||||
import { ArrayTable } from '@formily/antd-v5';
 | 
			
		||||
import { observer, useField } from '@formily/react';
 | 
			
		||||
import {
 | 
			
		||||
  ExtendCollectionsProvider,
 | 
			
		||||
  FormProvider,
 | 
			
		||||
  SchemaComponent,
 | 
			
		||||
  TableBlockProvider,
 | 
			
		||||
  useCollection_deprecated,
 | 
			
		||||
  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<any>();
 | 
			
		||||
    return <div>{field?.value?.nickname || field.value?.id}</div>;
 | 
			
		||||
  },
 | 
			
		||||
  { displayName: 'Username' },
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const Collection = observer(
 | 
			
		||||
  () => {
 | 
			
		||||
    const field = useField<any>();
 | 
			
		||||
    const { title, name } = field.value || {};
 | 
			
		||||
    const compile = useCompile();
 | 
			
		||||
    return <div>{title ? compile(title) : name}</div>;
 | 
			
		||||
  },
 | 
			
		||||
  { displayName: 'Collection' },
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const Field = observer(
 | 
			
		||||
  () => {
 | 
			
		||||
    const field = useField<any>();
 | 
			
		||||
    const compile = useCompile();
 | 
			
		||||
    if (!field.value) {
 | 
			
		||||
      return null;
 | 
			
		||||
    }
 | 
			
		||||
    return <div>{field.value?.uiSchema?.title ? compile(field.value?.uiSchema?.title) : field.value.name}</div>;
 | 
			
		||||
  },
 | 
			
		||||
  { displayName: 'Field' },
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const Value = observer(
 | 
			
		||||
  () => {
 | 
			
		||||
    const field = useField<any>();
 | 
			
		||||
    const record = ArrayTable.useRecord();
 | 
			
		||||
    if (record.field?.uiSchema) {
 | 
			
		||||
      return (
 | 
			
		||||
        <FormProvider>
 | 
			
		||||
          <SchemaComponent
 | 
			
		||||
            schema={{
 | 
			
		||||
              name: record.field.name,
 | 
			
		||||
              ...record.field?.uiSchema,
 | 
			
		||||
              default: field.value,
 | 
			
		||||
              'x-read-pretty': true,
 | 
			
		||||
            }}
 | 
			
		||||
          />
 | 
			
		||||
        </FormProvider>
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
    return <div>{field.value ? JSON.stringify(field.value) : null}</div>;
 | 
			
		||||
  },
 | 
			
		||||
  { displayName: 'Value' },
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const IsAssociationBlock = createContext(null);
 | 
			
		||||
IsAssociationBlock.displayName = 'IsAssociationBlock';
 | 
			
		||||
 | 
			
		||||
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 (
 | 
			
		||||
    <SchemaComponent
 | 
			
		||||
      memoized
 | 
			
		||||
      components={{ ArrayTable, Username, Collection, Field, Value }}
 | 
			
		||||
      schema={{
 | 
			
		||||
        type: 'void',
 | 
			
		||||
        name: 'lfm4trkw8j3',
 | 
			
		||||
        'x-component': 'div',
 | 
			
		||||
        properties: {
 | 
			
		||||
          actions: {
 | 
			
		||||
            type: 'void',
 | 
			
		||||
            'x-component': 'ActionBar',
 | 
			
		||||
            'x-component-props': {
 | 
			
		||||
              style: {
 | 
			
		||||
                marginBottom: 16,
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
            properties: {
 | 
			
		||||
              filter: {
 | 
			
		||||
                type: 'void',
 | 
			
		||||
                title: '{{ t("Filter") }}',
 | 
			
		||||
                'x-action': 'filter',
 | 
			
		||||
                // 'x-designer': 'Filter.Action.Designer',
 | 
			
		||||
                'x-component': 'Filter.Action',
 | 
			
		||||
                'x-component-props': {
 | 
			
		||||
                  icon: 'FilterOutlined',
 | 
			
		||||
                  useProps: '{{ useFilterActionProps }}',
 | 
			
		||||
                },
 | 
			
		||||
                'x-align': 'left',
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
          },
 | 
			
		||||
          y84dlntcaup: {
 | 
			
		||||
            type: 'array',
 | 
			
		||||
            'x-component': 'TableV2',
 | 
			
		||||
            'x-component-props': {
 | 
			
		||||
              rowKey: 'id',
 | 
			
		||||
              rowSelection: {
 | 
			
		||||
                type: 'checkbox',
 | 
			
		||||
              },
 | 
			
		||||
              useProps: '{{ useTableBlockProps }}',
 | 
			
		||||
            },
 | 
			
		||||
            properties: {
 | 
			
		||||
              actions: {
 | 
			
		||||
                type: 'void',
 | 
			
		||||
                title: '{{ t("Actions") }}',
 | 
			
		||||
                'x-action-column': 'actions',
 | 
			
		||||
                'x-decorator': 'TableV2.Column.ActionBar',
 | 
			
		||||
                'x-component': 'TableV2.Column',
 | 
			
		||||
                'x-designer': 'TableV2.ActionColumnDesigner',
 | 
			
		||||
                'x-initializer': 'table:configureItemActions',
 | 
			
		||||
                properties: {
 | 
			
		||||
                  actions: {
 | 
			
		||||
                    type: 'void',
 | 
			
		||||
                    'x-decorator': 'DndContext',
 | 
			
		||||
                    'x-component': 'Space',
 | 
			
		||||
                    'x-component-props': {
 | 
			
		||||
                      split: '|',
 | 
			
		||||
                    },
 | 
			
		||||
                    properties: {
 | 
			
		||||
                      o80rypwmeeg: {
 | 
			
		||||
                        type: 'void',
 | 
			
		||||
                        title: '{{ t("View") }}',
 | 
			
		||||
                        // 'x-designer': 'Action.Designer',
 | 
			
		||||
                        'x-toolbar': 'ActionSchemaToolbar',
 | 
			
		||||
                        'x-settings': 'actionSettings:view',
 | 
			
		||||
                        'x-component': 'Action.Link',
 | 
			
		||||
                        'x-component-props': {
 | 
			
		||||
                          openMode: 'drawer',
 | 
			
		||||
                        },
 | 
			
		||||
                        properties: {
 | 
			
		||||
                          drawer: {
 | 
			
		||||
                            type: 'void',
 | 
			
		||||
                            title: '{{ t("View record") }}',
 | 
			
		||||
                            'x-component': 'Action.Container',
 | 
			
		||||
                            'x-component-props': {
 | 
			
		||||
                              className: 'nb-action-popup',
 | 
			
		||||
                            },
 | 
			
		||||
                            properties: {
 | 
			
		||||
                              grid: {
 | 
			
		||||
                                type: 'void',
 | 
			
		||||
                                'x-component': 'Grid',
 | 
			
		||||
                                properties: {
 | 
			
		||||
                                  tdlav8o9o17: {
 | 
			
		||||
                                    type: 'void',
 | 
			
		||||
                                    'x-component': 'Grid.Row',
 | 
			
		||||
                                    properties: {
 | 
			
		||||
                                      '7bsnaf47i6g': {
 | 
			
		||||
                                        type: 'void',
 | 
			
		||||
                                        'x-component': 'Grid.Col',
 | 
			
		||||
                                        properties: {
 | 
			
		||||
                                          '6s2qbihe3tu': {
 | 
			
		||||
                                            type: 'void',
 | 
			
		||||
                                            'x-acl-action': 'auditLogs:get',
 | 
			
		||||
                                            'x-decorator': 'FormBlockProvider',
 | 
			
		||||
                                            'x-decorator-props': {
 | 
			
		||||
                                              resource: 'auditLogs',
 | 
			
		||||
                                              collection: 'auditLogs',
 | 
			
		||||
                                              readPretty: true,
 | 
			
		||||
                                              action: 'get',
 | 
			
		||||
                                              params: {
 | 
			
		||||
                                                appends: ['collection', 'user', 'changes'],
 | 
			
		||||
                                              },
 | 
			
		||||
                                              useParams: '{{ useParamsFromRecord }}',
 | 
			
		||||
                                              useSourceId: '{{ useSourceIdFromParentRecord }}',
 | 
			
		||||
                                            },
 | 
			
		||||
                                            'x-component': 'CardItem',
 | 
			
		||||
                                            properties: {
 | 
			
		||||
                                              mevpuonrda0: {
 | 
			
		||||
                                                type: 'void',
 | 
			
		||||
                                                'x-component': 'FormV2',
 | 
			
		||||
                                                'x-read-pretty': true,
 | 
			
		||||
                                                'x-component-props': {
 | 
			
		||||
                                                  useProps: '{{ useFormBlockProps }}',
 | 
			
		||||
                                                },
 | 
			
		||||
                                                properties: {
 | 
			
		||||
                                                  grid: {
 | 
			
		||||
                                                    type: 'void',
 | 
			
		||||
                                                    'x-component': 'Grid',
 | 
			
		||||
                                                    properties: {
 | 
			
		||||
                                                      row1: {
 | 
			
		||||
                                                        type: 'void',
 | 
			
		||||
                                                        'x-component': 'Grid.Row',
 | 
			
		||||
                                                        properties: {
 | 
			
		||||
                                                          col11: {
 | 
			
		||||
                                                            type: 'void',
 | 
			
		||||
                                                            'x-component': 'Grid.Col',
 | 
			
		||||
                                                            properties: {
 | 
			
		||||
                                                              collection: {
 | 
			
		||||
                                                                type: 'string',
 | 
			
		||||
                                                                title: '{{t("Collection display name")}}',
 | 
			
		||||
                                                                'x-component': 'Collection',
 | 
			
		||||
                                                                'x-decorator': 'FormItem',
 | 
			
		||||
                                                                'x-read-pretty': true,
 | 
			
		||||
                                                              },
 | 
			
		||||
                                                            },
 | 
			
		||||
                                                          },
 | 
			
		||||
                                                        },
 | 
			
		||||
                                                      },
 | 
			
		||||
                                                      row2: {
 | 
			
		||||
                                                        type: 'void',
 | 
			
		||||
                                                        'x-component': 'Grid.Row',
 | 
			
		||||
                                                        properties: {
 | 
			
		||||
                                                          col21: {
 | 
			
		||||
                                                            type: 'void',
 | 
			
		||||
                                                            'x-component': 'Grid.Col',
 | 
			
		||||
                                                            properties: {
 | 
			
		||||
                                                              type: {
 | 
			
		||||
                                                                type: 'string',
 | 
			
		||||
                                                                'x-component': 'CollectionField',
 | 
			
		||||
                                                                'x-decorator': 'FormItem',
 | 
			
		||||
                                                                'x-read-pretty': true,
 | 
			
		||||
                                                              },
 | 
			
		||||
                                                            },
 | 
			
		||||
                                                          },
 | 
			
		||||
                                                        },
 | 
			
		||||
                                                      },
 | 
			
		||||
                                                      row3: {
 | 
			
		||||
                                                        type: 'void',
 | 
			
		||||
                                                        'x-component': 'Grid.Row',
 | 
			
		||||
                                                        properties: {
 | 
			
		||||
                                                          col31: {
 | 
			
		||||
                                                            type: 'void',
 | 
			
		||||
                                                            'x-component': 'Grid.Col',
 | 
			
		||||
                                                            properties: {
 | 
			
		||||
                                                              createdAt: {
 | 
			
		||||
                                                                type: 'string',
 | 
			
		||||
                                                                'x-component': 'CollectionField',
 | 
			
		||||
                                                                'x-decorator': 'FormItem',
 | 
			
		||||
                                                                'x-read-pretty': true,
 | 
			
		||||
                                                              },
 | 
			
		||||
                                                            },
 | 
			
		||||
                                                          },
 | 
			
		||||
                                                        },
 | 
			
		||||
                                                      },
 | 
			
		||||
                                                      row4: {
 | 
			
		||||
                                                        type: 'void',
 | 
			
		||||
                                                        'x-component': 'Grid.Row',
 | 
			
		||||
                                                        properties: {
 | 
			
		||||
                                                          col41: {
 | 
			
		||||
                                                            type: 'void',
 | 
			
		||||
                                                            'x-component': 'Grid.Col',
 | 
			
		||||
                                                            properties: {
 | 
			
		||||
                                                              user: {
 | 
			
		||||
                                                                type: 'string',
 | 
			
		||||
                                                                title: '{{t("User")}}',
 | 
			
		||||
                                                                'x-component': 'Username',
 | 
			
		||||
                                                                'x-decorator': 'FormItem',
 | 
			
		||||
                                                                'x-read-pretty': true,
 | 
			
		||||
                                                              },
 | 
			
		||||
                                                            },
 | 
			
		||||
                                                          },
 | 
			
		||||
                                                        },
 | 
			
		||||
                                                      },
 | 
			
		||||
                                                      row5: {
 | 
			
		||||
                                                        type: 'void',
 | 
			
		||||
                                                        'x-component': 'Grid.Row',
 | 
			
		||||
                                                        properties: {
 | 
			
		||||
                                                          col51: {
 | 
			
		||||
                                                            type: 'void',
 | 
			
		||||
                                                            'x-component': 'Grid.Col',
 | 
			
		||||
                                                            properties: {
 | 
			
		||||
                                                              changes: {
 | 
			
		||||
                                                                type: 'array',
 | 
			
		||||
                                                                title: '{{t("Field value changes")}}',
 | 
			
		||||
                                                                'x-decorator': 'FormItem',
 | 
			
		||||
                                                                'x-component': 'ArrayTable',
 | 
			
		||||
                                                                'x-component-props': {
 | 
			
		||||
                                                                  pagination: { pageSize: 10 },
 | 
			
		||||
                                                                  scroll: { x: '100%' },
 | 
			
		||||
                                                                },
 | 
			
		||||
                                                                items: {
 | 
			
		||||
                                                                  type: 'object',
 | 
			
		||||
                                                                  properties: {
 | 
			
		||||
                                                                    column3: {
 | 
			
		||||
                                                                      type: 'void',
 | 
			
		||||
                                                                      'x-component': 'ArrayTable.Column',
 | 
			
		||||
                                                                      'x-component-props': {
 | 
			
		||||
                                                                        width: 200,
 | 
			
		||||
                                                                        title: '{{t("Field")}}',
 | 
			
		||||
                                                                      },
 | 
			
		||||
                                                                      properties: {
 | 
			
		||||
                                                                        field: {
 | 
			
		||||
                                                                          type: 'string',
 | 
			
		||||
                                                                          //'x-decorator': 'Editable',
 | 
			
		||||
                                                                          'x-component': 'Field',
 | 
			
		||||
                                                                        },
 | 
			
		||||
                                                                      },
 | 
			
		||||
                                                                    },
 | 
			
		||||
                                                                    column4: {
 | 
			
		||||
                                                                      type: 'void',
 | 
			
		||||
                                                                      'x-component': 'ArrayTable.Column',
 | 
			
		||||
                                                                      'x-component-props': {
 | 
			
		||||
                                                                        width: 200,
 | 
			
		||||
                                                                        title: '{{t("Before change")}}',
 | 
			
		||||
                                                                      },
 | 
			
		||||
                                                                      properties: {
 | 
			
		||||
                                                                        before: {
 | 
			
		||||
                                                                          type: 'string',
 | 
			
		||||
                                                                          'x-decorator': 'FormItem',
 | 
			
		||||
                                                                          'x-component': 'Value',
 | 
			
		||||
                                                                        },
 | 
			
		||||
                                                                      },
 | 
			
		||||
                                                                    },
 | 
			
		||||
                                                                    column5: {
 | 
			
		||||
                                                                      type: 'void',
 | 
			
		||||
                                                                      'x-component': 'ArrayTable.Column',
 | 
			
		||||
                                                                      'x-component-props': {
 | 
			
		||||
                                                                        width: 200,
 | 
			
		||||
                                                                        title: '{{t("After change")}}',
 | 
			
		||||
                                                                      },
 | 
			
		||||
                                                                      properties: {
 | 
			
		||||
                                                                        after: {
 | 
			
		||||
                                                                          type: 'string',
 | 
			
		||||
                                                                          'x-decorator': 'FormItem',
 | 
			
		||||
                                                                          'x-component': 'Value',
 | 
			
		||||
                                                                        },
 | 
			
		||||
                                                                      },
 | 
			
		||||
                                                                    },
 | 
			
		||||
                                                                  },
 | 
			
		||||
                                                                },
 | 
			
		||||
                                                              },
 | 
			
		||||
                                                            },
 | 
			
		||||
                                                          },
 | 
			
		||||
                                                        },
 | 
			
		||||
                                                      },
 | 
			
		||||
                                                    },
 | 
			
		||||
                                                  },
 | 
			
		||||
                                                },
 | 
			
		||||
                                              },
 | 
			
		||||
                                            },
 | 
			
		||||
                                          },
 | 
			
		||||
                                        },
 | 
			
		||||
                                      },
 | 
			
		||||
                                    },
 | 
			
		||||
                                  },
 | 
			
		||||
                                },
 | 
			
		||||
                              },
 | 
			
		||||
                            },
 | 
			
		||||
                          },
 | 
			
		||||
                        },
 | 
			
		||||
                      },
 | 
			
		||||
                    },
 | 
			
		||||
                  },
 | 
			
		||||
                },
 | 
			
		||||
              },
 | 
			
		||||
              column1: {
 | 
			
		||||
                type: 'void',
 | 
			
		||||
                'x-decorator': 'TableV2.Column.Decorator',
 | 
			
		||||
                'x-component': 'TableV2.Column',
 | 
			
		||||
                properties: {
 | 
			
		||||
                  createdAt: {
 | 
			
		||||
                    'x-component': 'CollectionField',
 | 
			
		||||
                    'x-read-pretty': true,
 | 
			
		||||
                  },
 | 
			
		||||
                },
 | 
			
		||||
              },
 | 
			
		||||
              column2: {
 | 
			
		||||
                type: 'void',
 | 
			
		||||
                'x-decorator': 'TableV2.Column.Decorator',
 | 
			
		||||
                'x-component': 'TableV2.Column',
 | 
			
		||||
                properties: {
 | 
			
		||||
                  type: {
 | 
			
		||||
                    'x-component': 'CollectionField',
 | 
			
		||||
                    'x-read-pretty': true,
 | 
			
		||||
                  },
 | 
			
		||||
                },
 | 
			
		||||
              },
 | 
			
		||||
              column3: {
 | 
			
		||||
                type: 'void',
 | 
			
		||||
                'x-component': 'TableV2.Column',
 | 
			
		||||
                title: '{{t("Collection display name")}}',
 | 
			
		||||
                properties: {
 | 
			
		||||
                  collection: {
 | 
			
		||||
                    'x-component': 'Collection',
 | 
			
		||||
                    'x-read-pretty': true,
 | 
			
		||||
                  },
 | 
			
		||||
                },
 | 
			
		||||
              },
 | 
			
		||||
              ...ext,
 | 
			
		||||
              column4: {
 | 
			
		||||
                type: 'void',
 | 
			
		||||
                'x-component': 'TableV2.Column',
 | 
			
		||||
                title: '{{t("User")}}',
 | 
			
		||||
                properties: {
 | 
			
		||||
                  user: {
 | 
			
		||||
                    'x-component': 'Username',
 | 
			
		||||
                    'x-read-pretty': true,
 | 
			
		||||
                  },
 | 
			
		||||
                },
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
          },
 | 
			
		||||
        },
 | 
			
		||||
      }}
 | 
			
		||||
    />
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
AuditLogs.Decorator = observer(
 | 
			
		||||
  (props: any) => {
 | 
			
		||||
    const parent = useCollection_deprecated();
 | 
			
		||||
    const record = useRecord();
 | 
			
		||||
    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,
 | 
			
		||||
        sort: '-createdAt',
 | 
			
		||||
      },
 | 
			
		||||
      rowKey: 'id',
 | 
			
		||||
      showIndex: true,
 | 
			
		||||
      dragSort: false,
 | 
			
		||||
    };
 | 
			
		||||
    return (
 | 
			
		||||
      <IsAssociationBlock.Provider value={!!parent.name}>
 | 
			
		||||
        <ExtendCollectionsProvider collections={[collection]}>
 | 
			
		||||
          <TableBlockProvider {...defaults}>{props.children}</TableBlockProvider>
 | 
			
		||||
        </ExtendCollectionsProvider>
 | 
			
		||||
      </IsAssociationBlock.Provider>
 | 
			
		||||
    );
 | 
			
		||||
  },
 | 
			
		||||
  { displayName: 'AuditLogs.Decorator' },
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
AuditLogs.Designer = AuditLogsDesigner;
 | 
			
		||||
@ -0,0 +1,77 @@
 | 
			
		||||
import { useField, useFieldSchema } from '@formily/react';
 | 
			
		||||
import {
 | 
			
		||||
  GeneralSchemaDesigner,
 | 
			
		||||
  SchemaSettingsDataScope,
 | 
			
		||||
  SchemaSettingsDivider,
 | 
			
		||||
  SchemaSettingsRemove,
 | 
			
		||||
  SchemaSettingsSelectItem,
 | 
			
		||||
  useCollection_deprecated,
 | 
			
		||||
  useDesignable,
 | 
			
		||||
  useFormBlockContext,
 | 
			
		||||
  useTableBlockContext,
 | 
			
		||||
} from '@nocobase/client';
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { useTranslation } from 'react-i18next';
 | 
			
		||||
 | 
			
		||||
export const AuditLogsDesigner = () => {
 | 
			
		||||
  const { name, title } = useCollection_deprecated();
 | 
			
		||||
  const field = useField();
 | 
			
		||||
  const fieldSchema = useFieldSchema();
 | 
			
		||||
  const { form } = useFormBlockContext();
 | 
			
		||||
  const { service } = useTableBlockContext();
 | 
			
		||||
  const { t } = useTranslation();
 | 
			
		||||
  const { dn } = useDesignable();
 | 
			
		||||
  return (
 | 
			
		||||
    <GeneralSchemaDesigner title={title || name}>
 | 
			
		||||
      <SchemaSettingsDataScope
 | 
			
		||||
        collectionName={name}
 | 
			
		||||
        defaultFilter={fieldSchema?.['x-decorator-props']?.params?.filter || {}}
 | 
			
		||||
        form={form}
 | 
			
		||||
        onSubmit={({ filter }) => {
 | 
			
		||||
          const params = field.decoratorProps.params || {};
 | 
			
		||||
          params.filter = 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'],
 | 
			
		||||
              'x-decorator-props': fieldSchema['x-decorator-props'],
 | 
			
		||||
            },
 | 
			
		||||
          });
 | 
			
		||||
        }}
 | 
			
		||||
      />
 | 
			
		||||
      <SchemaSettingsSelectItem
 | 
			
		||||
        title={t('Records per page')}
 | 
			
		||||
        value={field.decoratorProps?.params?.pageSize || 20}
 | 
			
		||||
        options={[
 | 
			
		||||
          { label: '10', value: 10 },
 | 
			
		||||
          { label: '20', value: 20 },
 | 
			
		||||
          { label: '50', value: 50 },
 | 
			
		||||
          { label: '100', value: 100 },
 | 
			
		||||
          { label: '200', value: 200 },
 | 
			
		||||
        ]}
 | 
			
		||||
        onChange={(pageSize) => {
 | 
			
		||||
          const params = field.decoratorProps.params || {};
 | 
			
		||||
          params.pageSize = 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'],
 | 
			
		||||
              'x-decorator-props': fieldSchema['x-decorator-props'],
 | 
			
		||||
            },
 | 
			
		||||
          });
 | 
			
		||||
        }}
 | 
			
		||||
      />
 | 
			
		||||
      <SchemaSettingsDivider />
 | 
			
		||||
      <SchemaSettingsRemove
 | 
			
		||||
        removeParentsIfNoChildren
 | 
			
		||||
        breakRemoveOn={{
 | 
			
		||||
          'x-component': 'Grid',
 | 
			
		||||
        }}
 | 
			
		||||
      />
 | 
			
		||||
    </GeneralSchemaDesigner>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										39
									
								
								packages/plugins/@hera/plugin-audit-logs/src/client/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								packages/plugins/@hera/plugin-audit-logs/src/client/index.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,39 @@
 | 
			
		||||
import { Plugin, SchemaInitializerItemType } from '@nocobase/client';
 | 
			
		||||
import { AuditLogsProvider } from './AuditLogsProvider';
 | 
			
		||||
import {
 | 
			
		||||
  auditLogsTableActionColumnInitializers,
 | 
			
		||||
  auditLogsTableActionColumnInitializers_deprecated,
 | 
			
		||||
} from './initializers/AuditLogsTableActionColumnInitializers';
 | 
			
		||||
import {
 | 
			
		||||
  auditLogsTableActionInitializers,
 | 
			
		||||
  auditLogsTableActionInitializers_deprecated,
 | 
			
		||||
} from './initializers/AuditLogsTableActionInitializers';
 | 
			
		||||
import {
 | 
			
		||||
  auditLogsTableColumnInitializers,
 | 
			
		||||
  auditLogsTableColumnInitializers_deprecated,
 | 
			
		||||
} from './initializers/AuditLogsTableColumnInitializers';
 | 
			
		||||
export * from './AuditLogsBlockInitializer';
 | 
			
		||||
export * from './AuditLogsProvider';
 | 
			
		||||
 | 
			
		||||
export class AuditLogsPlugin extends Plugin {
 | 
			
		||||
  async load() {
 | 
			
		||||
    this.app.use(AuditLogsProvider);
 | 
			
		||||
    this.app.schemaInitializerManager.add(auditLogsTableActionInitializers_deprecated);
 | 
			
		||||
    this.app.schemaInitializerManager.add(auditLogsTableActionInitializers);
 | 
			
		||||
    this.app.schemaInitializerManager.add(auditLogsTableActionColumnInitializers_deprecated);
 | 
			
		||||
    this.app.schemaInitializerManager.add(auditLogsTableActionColumnInitializers);
 | 
			
		||||
    this.app.schemaInitializerManager.add(auditLogsTableColumnInitializers_deprecated);
 | 
			
		||||
    this.app.schemaInitializerManager.add(auditLogsTableColumnInitializers);
 | 
			
		||||
 | 
			
		||||
    const blockInitializers = this.app.schemaInitializerManager.get('page:addBlock');
 | 
			
		||||
    const recordBlockInitializers = this.app.schemaInitializerManager.get('popup:common:addBlock');
 | 
			
		||||
    const auditLogs: Omit<SchemaInitializerItemType, 'name'> = {
 | 
			
		||||
      title: '{{t("Audit logs")}}',
 | 
			
		||||
      Component: 'AuditLogsBlockInitializer',
 | 
			
		||||
    };
 | 
			
		||||
    blockInitializers.add('otherBlocks.auditLogs', auditLogs);
 | 
			
		||||
    recordBlockInitializers.add('otherBlocks.auditLogs', auditLogs);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default AuditLogsPlugin;
 | 
			
		||||
@ -0,0 +1,27 @@
 | 
			
		||||
import { InitializerWithSwitch, useSchemaInitializerItem } from '@nocobase/client';
 | 
			
		||||
import React from 'react';
 | 
			
		||||
 | 
			
		||||
export const AuditLogsTableActionColumnInitializer = () => {
 | 
			
		||||
  const schema = {
 | 
			
		||||
    type: 'void',
 | 
			
		||||
    title: '{{ t("Actions") }}',
 | 
			
		||||
    'x-decorator': 'TableV2.Column.ActionBar',
 | 
			
		||||
    'x-component': 'TableV2.Column',
 | 
			
		||||
    'x-designer': 'TableV2.ActionColumnDesigner',
 | 
			
		||||
    'x-initializer': 'auditLogsTable:configureItemActions',
 | 
			
		||||
    'x-action-column': 'actions',
 | 
			
		||||
    properties: {
 | 
			
		||||
      actions: {
 | 
			
		||||
        type: 'void',
 | 
			
		||||
        'x-decorator': 'DndContext',
 | 
			
		||||
        'x-component': 'Space',
 | 
			
		||||
        'x-component-props': {
 | 
			
		||||
          split: '|',
 | 
			
		||||
        },
 | 
			
		||||
        properties: {},
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
  };
 | 
			
		||||
  const itemConfig = useSchemaInitializerItem();
 | 
			
		||||
  return <InitializerWithSwitch {...itemConfig} schema={schema} item={itemConfig} type={'x-action-column'} />;
 | 
			
		||||
};
 | 
			
		||||
@ -0,0 +1,141 @@
 | 
			
		||||
import { MenuOutlined } from '@ant-design/icons';
 | 
			
		||||
import { useFieldSchema } from '@formily/react';
 | 
			
		||||
import {
 | 
			
		||||
  CompatibleSchemaInitializer,
 | 
			
		||||
  createDesignable,
 | 
			
		||||
  Resizable,
 | 
			
		||||
  useAPIClient,
 | 
			
		||||
  useDesignable,
 | 
			
		||||
} from '@nocobase/client';
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { useTranslation } from 'react-i18next';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @deprecated
 | 
			
		||||
 */
 | 
			
		||||
export const auditLogsTableActionColumnInitializers_deprecated = new CompatibleSchemaInitializer({
 | 
			
		||||
  name: 'AuditLogsTableActionColumnInitializers',
 | 
			
		||||
  insertPosition: 'beforeEnd',
 | 
			
		||||
  Component: (props: any) => <MenuOutlined {...props} style={{ cursor: 'pointer' }} />,
 | 
			
		||||
  useInsert() {
 | 
			
		||||
    const fieldSchema = useFieldSchema();
 | 
			
		||||
    const api = useAPIClient();
 | 
			
		||||
    const { refresh } = useDesignable();
 | 
			
		||||
    const { t } = useTranslation();
 | 
			
		||||
 | 
			
		||||
    return (schema) => {
 | 
			
		||||
      const spaceSchema = fieldSchema.reduceProperties((buf, schema) => {
 | 
			
		||||
        if (schema['x-component'] === 'Space') {
 | 
			
		||||
          return schema;
 | 
			
		||||
        }
 | 
			
		||||
        return buf;
 | 
			
		||||
      }, null);
 | 
			
		||||
      if (!spaceSchema) {
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      const dn = createDesignable({
 | 
			
		||||
        t,
 | 
			
		||||
        api,
 | 
			
		||||
        refresh,
 | 
			
		||||
        current: spaceSchema,
 | 
			
		||||
      });
 | 
			
		||||
      dn.loadAPIClientEvents();
 | 
			
		||||
      dn.insertBeforeEnd(schema);
 | 
			
		||||
    };
 | 
			
		||||
  },
 | 
			
		||||
  items: [
 | 
			
		||||
    {
 | 
			
		||||
      name: 'enableActions',
 | 
			
		||||
      type: 'itemGroup',
 | 
			
		||||
      title: '{{t("Enable actions")}}',
 | 
			
		||||
      children: [
 | 
			
		||||
        {
 | 
			
		||||
          name: 'view',
 | 
			
		||||
          type: 'item',
 | 
			
		||||
          title: '{{t("View")}}',
 | 
			
		||||
          Component: 'AuditLogsViewActionInitializer',
 | 
			
		||||
          schema: {
 | 
			
		||||
            'x-component': 'Action.Link',
 | 
			
		||||
            'x-action': 'view',
 | 
			
		||||
            'x-decorator': 'ACLActionProvider',
 | 
			
		||||
          },
 | 
			
		||||
        },
 | 
			
		||||
      ],
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      name: 'divider',
 | 
			
		||||
      type: 'divider',
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      name: 'columnWidth',
 | 
			
		||||
      type: 'item',
 | 
			
		||||
      title: '{{t("Column width")}}',
 | 
			
		||||
      Component: Resizable,
 | 
			
		||||
    },
 | 
			
		||||
  ],
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export const auditLogsTableActionColumnInitializers = new CompatibleSchemaInitializer(
 | 
			
		||||
  {
 | 
			
		||||
    name: 'auditLogsTable:configureItemActions',
 | 
			
		||||
    insertPosition: 'beforeEnd',
 | 
			
		||||
    Component: (props: any) => <MenuOutlined {...props} style={{ cursor: 'pointer' }} />,
 | 
			
		||||
    useInsert() {
 | 
			
		||||
      const fieldSchema = useFieldSchema();
 | 
			
		||||
      const api = useAPIClient();
 | 
			
		||||
      const { refresh } = useDesignable();
 | 
			
		||||
      const { t } = useTranslation();
 | 
			
		||||
 | 
			
		||||
      return (schema) => {
 | 
			
		||||
        const spaceSchema = fieldSchema.reduceProperties((buf, schema) => {
 | 
			
		||||
          if (schema['x-component'] === 'Space') {
 | 
			
		||||
            return schema;
 | 
			
		||||
          }
 | 
			
		||||
          return buf;
 | 
			
		||||
        }, null);
 | 
			
		||||
        if (!spaceSchema) {
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
        const dn = createDesignable({
 | 
			
		||||
          t,
 | 
			
		||||
          api,
 | 
			
		||||
          refresh,
 | 
			
		||||
          current: spaceSchema,
 | 
			
		||||
        });
 | 
			
		||||
        dn.loadAPIClientEvents();
 | 
			
		||||
        dn.insertBeforeEnd(schema);
 | 
			
		||||
      };
 | 
			
		||||
    },
 | 
			
		||||
    items: [
 | 
			
		||||
      {
 | 
			
		||||
        name: 'enableActions',
 | 
			
		||||
        type: 'itemGroup',
 | 
			
		||||
        title: '{{t("Enable actions")}}',
 | 
			
		||||
        children: [
 | 
			
		||||
          {
 | 
			
		||||
            name: 'view',
 | 
			
		||||
            type: 'item',
 | 
			
		||||
            title: '{{t("View")}}',
 | 
			
		||||
            Component: 'AuditLogsViewActionInitializer',
 | 
			
		||||
            schema: {
 | 
			
		||||
              'x-component': 'Action.Link',
 | 
			
		||||
              'x-action': 'view',
 | 
			
		||||
              'x-decorator': 'ACLActionProvider',
 | 
			
		||||
            },
 | 
			
		||||
          },
 | 
			
		||||
        ],
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        name: 'divider',
 | 
			
		||||
        type: 'divider',
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        name: 'columnWidth',
 | 
			
		||||
        type: 'item',
 | 
			
		||||
        title: '{{t("Column width")}}',
 | 
			
		||||
        Component: Resizable,
 | 
			
		||||
      },
 | 
			
		||||
    ],
 | 
			
		||||
  },
 | 
			
		||||
  auditLogsTableActionColumnInitializers_deprecated,
 | 
			
		||||
);
 | 
			
		||||
@ -0,0 +1,76 @@
 | 
			
		||||
import { CompatibleSchemaInitializer } from '@nocobase/client';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @deprecated
 | 
			
		||||
 * 操作记录表格操作配置
 | 
			
		||||
 */
 | 
			
		||||
export const auditLogsTableActionInitializers_deprecated = new CompatibleSchemaInitializer({
 | 
			
		||||
  name: 'AuditLogsTableActionInitializers',
 | 
			
		||||
  title: "{{t('Configure actions')}}",
 | 
			
		||||
  icon: 'SettingOutlined',
 | 
			
		||||
  style: {
 | 
			
		||||
    marginLeft: 8,
 | 
			
		||||
  },
 | 
			
		||||
  items: [
 | 
			
		||||
    {
 | 
			
		||||
      type: 'itemGroup',
 | 
			
		||||
      title: "{{t('Enable actions')}}",
 | 
			
		||||
      name: 'enableActions',
 | 
			
		||||
      children: [
 | 
			
		||||
        {
 | 
			
		||||
          name: 'filter',
 | 
			
		||||
          title: "{{t('Filter')}}",
 | 
			
		||||
          Component: 'FilterActionInitializer',
 | 
			
		||||
          schema: {
 | 
			
		||||
            'x-align': 'left',
 | 
			
		||||
          },
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          name: 'refresh',
 | 
			
		||||
          title: "{{t('Refresh')}}",
 | 
			
		||||
          Component: 'RefreshActionInitializer',
 | 
			
		||||
          schema: {
 | 
			
		||||
            'x-align': 'right',
 | 
			
		||||
          },
 | 
			
		||||
        },
 | 
			
		||||
      ],
 | 
			
		||||
    },
 | 
			
		||||
  ],
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export const auditLogsTableActionInitializers = new CompatibleSchemaInitializer(
 | 
			
		||||
  {
 | 
			
		||||
    name: 'auditLogsTable:configureActions',
 | 
			
		||||
    title: "{{t('Configure actions')}}",
 | 
			
		||||
    icon: 'SettingOutlined',
 | 
			
		||||
    style: {
 | 
			
		||||
      marginLeft: 8,
 | 
			
		||||
    },
 | 
			
		||||
    items: [
 | 
			
		||||
      {
 | 
			
		||||
        type: 'itemGroup',
 | 
			
		||||
        title: "{{t('Enable actions')}}",
 | 
			
		||||
        name: 'enableActions',
 | 
			
		||||
        children: [
 | 
			
		||||
          {
 | 
			
		||||
            name: 'filter',
 | 
			
		||||
            title: "{{t('Filter')}}",
 | 
			
		||||
            Component: 'FilterActionInitializer',
 | 
			
		||||
            schema: {
 | 
			
		||||
              'x-align': 'left',
 | 
			
		||||
            },
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            name: 'refresh',
 | 
			
		||||
            title: "{{t('Refresh')}}",
 | 
			
		||||
            Component: 'RefreshActionInitializer',
 | 
			
		||||
            schema: {
 | 
			
		||||
              'x-align': 'right',
 | 
			
		||||
            },
 | 
			
		||||
          },
 | 
			
		||||
        ],
 | 
			
		||||
      },
 | 
			
		||||
    ],
 | 
			
		||||
  },
 | 
			
		||||
  auditLogsTableActionInitializers_deprecated,
 | 
			
		||||
);
 | 
			
		||||
@ -0,0 +1,139 @@
 | 
			
		||||
import {
 | 
			
		||||
  CompatibleSchemaInitializer,
 | 
			
		||||
  SchemaInitializerChildren,
 | 
			
		||||
  useAssociatedTableColumnInitializerFields,
 | 
			
		||||
  useCompile,
 | 
			
		||||
  useInheritsTableColumnInitializerFields,
 | 
			
		||||
  useTableColumnInitializerFields,
 | 
			
		||||
} from '@nocobase/client';
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { useTranslation } from 'react-i18next';
 | 
			
		||||
 | 
			
		||||
// 表格列配置
 | 
			
		||||
const ParentCollectionFields = () => {
 | 
			
		||||
  const inheritFields = useInheritsTableColumnInitializerFields();
 | 
			
		||||
  const { t } = useTranslation();
 | 
			
		||||
  const compile = useCompile();
 | 
			
		||||
  if (!inheritFields?.length) return null;
 | 
			
		||||
  const res = [];
 | 
			
		||||
  inheritFields.forEach((inherit) => {
 | 
			
		||||
    Object.values(inherit)[0].length &&
 | 
			
		||||
      res.push({
 | 
			
		||||
        type: 'itemGroup',
 | 
			
		||||
        divider: true,
 | 
			
		||||
        title: t(`Parent collection fields`) + '(' + compile(`${Object.keys(inherit)[0]}`) + ')',
 | 
			
		||||
        children: Object.values(inherit)[0].filter((v: any) => !v?.field?.isForeignKey),
 | 
			
		||||
      });
 | 
			
		||||
  });
 | 
			
		||||
  return <SchemaInitializerChildren>{res}</SchemaInitializerChildren>;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const AssociatedFields = () => {
 | 
			
		||||
  const associatedFields = useAssociatedTableColumnInitializerFields();
 | 
			
		||||
  const { t } = useTranslation();
 | 
			
		||||
 | 
			
		||||
  if (!associatedFields?.length) return null;
 | 
			
		||||
  const schema: any = [
 | 
			
		||||
    {
 | 
			
		||||
      type: 'itemGroup',
 | 
			
		||||
      divider: true,
 | 
			
		||||
      title: t('Display association fields'),
 | 
			
		||||
      children: associatedFields,
 | 
			
		||||
    },
 | 
			
		||||
  ];
 | 
			
		||||
  return <SchemaInitializerChildren>{schema}</SchemaInitializerChildren>;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @deprecated
 | 
			
		||||
 */
 | 
			
		||||
export const auditLogsTableColumnInitializers_deprecated = new CompatibleSchemaInitializer({
 | 
			
		||||
  name: 'AuditLogsTableColumnInitializers',
 | 
			
		||||
  insertPosition: 'beforeEnd',
 | 
			
		||||
  icon: 'SettingOutlined',
 | 
			
		||||
  title: '{{t("Configure columns")}}',
 | 
			
		||||
  wrap(s) {
 | 
			
		||||
    if (s['x-action-column']) {
 | 
			
		||||
      return s;
 | 
			
		||||
    }
 | 
			
		||||
    return {
 | 
			
		||||
      type: 'void',
 | 
			
		||||
      'x-decorator': 'TableV2.Column.Decorator',
 | 
			
		||||
      'x-designer': 'TableV2.Column.Designer',
 | 
			
		||||
      'x-component': 'TableV2.Column',
 | 
			
		||||
      properties: {
 | 
			
		||||
        [s.name]: {
 | 
			
		||||
          ...s,
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
    };
 | 
			
		||||
  },
 | 
			
		||||
  items: [
 | 
			
		||||
    {
 | 
			
		||||
      name: 'displayFields',
 | 
			
		||||
      type: 'itemGroup',
 | 
			
		||||
      title: '{{t("Display fields")}}',
 | 
			
		||||
      useChildren: useTableColumnInitializerFields,
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      name: 'parentCollectionFields',
 | 
			
		||||
      Component: ParentCollectionFields,
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      name: 'associationFields',
 | 
			
		||||
      Component: AssociatedFields,
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      name: 'actionColumn',
 | 
			
		||||
      title: '{{t("Action column")}}',
 | 
			
		||||
      Component: 'AuditLogsTableActionColumnInitializer',
 | 
			
		||||
    },
 | 
			
		||||
  ],
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export const auditLogsTableColumnInitializers = new CompatibleSchemaInitializer(
 | 
			
		||||
  {
 | 
			
		||||
    name: 'auditLogsTable:configureColumns',
 | 
			
		||||
    insertPosition: 'beforeEnd',
 | 
			
		||||
    icon: 'SettingOutlined',
 | 
			
		||||
    title: '{{t("Configure columns")}}',
 | 
			
		||||
    wrap(s) {
 | 
			
		||||
      if (s['x-action-column']) {
 | 
			
		||||
        return s;
 | 
			
		||||
      }
 | 
			
		||||
      return {
 | 
			
		||||
        type: 'void',
 | 
			
		||||
        'x-decorator': 'TableV2.Column.Decorator',
 | 
			
		||||
        'x-designer': 'TableV2.Column.Designer',
 | 
			
		||||
        'x-component': 'TableV2.Column',
 | 
			
		||||
        properties: {
 | 
			
		||||
          [s.name]: {
 | 
			
		||||
            ...s,
 | 
			
		||||
          },
 | 
			
		||||
        },
 | 
			
		||||
      };
 | 
			
		||||
    },
 | 
			
		||||
    items: [
 | 
			
		||||
      {
 | 
			
		||||
        name: 'displayFields',
 | 
			
		||||
        type: 'itemGroup',
 | 
			
		||||
        title: '{{t("Display fields")}}',
 | 
			
		||||
        useChildren: useTableColumnInitializerFields,
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        name: 'parentCollectionFields',
 | 
			
		||||
        Component: ParentCollectionFields,
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        name: 'associationFields',
 | 
			
		||||
        Component: AssociatedFields,
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        name: 'actionColumn',
 | 
			
		||||
        title: '{{t("Action column")}}',
 | 
			
		||||
        Component: 'AuditLogsTableActionColumnInitializer',
 | 
			
		||||
      },
 | 
			
		||||
    ],
 | 
			
		||||
  },
 | 
			
		||||
  auditLogsTableColumnInitializers_deprecated,
 | 
			
		||||
);
 | 
			
		||||
@ -0,0 +1,14 @@
 | 
			
		||||
import { i18n, tval as nTval } from '@nocobase/client';
 | 
			
		||||
import { useTranslation } from 'react-i18next';
 | 
			
		||||
 | 
			
		||||
export const NAMESPACE = 'audit-logs';
 | 
			
		||||
 | 
			
		||||
export function lang(key: string) {
 | 
			
		||||
  return i18n.t(key, { ns: NAMESPACE });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function useAuditLogsTranslation() {
 | 
			
		||||
  return useTranslation(NAMESPACE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const tval = (key: string) => nTval(key, { ns: NAMESPACE });
 | 
			
		||||
							
								
								
									
										303
									
								
								packages/plugins/@hera/plugin-audit-logs/src/client/utils.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										303
									
								
								packages/plugins/@hera/plugin-audit-logs/src/client/utils.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,303 @@
 | 
			
		||||
import { uid } from '@formily/shared';
 | 
			
		||||
 | 
			
		||||
export const createSchema = () => {
 | 
			
		||||
  const filterSchema = {
 | 
			
		||||
    'x-component': 'Action',
 | 
			
		||||
    'x-component-props': {
 | 
			
		||||
      popover: true,
 | 
			
		||||
    },
 | 
			
		||||
    type: 'void',
 | 
			
		||||
    title: '{{t("Filter")}}',
 | 
			
		||||
    properties: {
 | 
			
		||||
      popover: {
 | 
			
		||||
        type: 'void',
 | 
			
		||||
        'x-decorator': 'Form',
 | 
			
		||||
        'x-decorator-props': {},
 | 
			
		||||
        'x-component': 'Action.Popover',
 | 
			
		||||
        'x-component-props': {
 | 
			
		||||
          trigger: 'click',
 | 
			
		||||
          placement: 'bottomLeft',
 | 
			
		||||
        },
 | 
			
		||||
        properties: {
 | 
			
		||||
          filter: {
 | 
			
		||||
            type: 'object',
 | 
			
		||||
            default: {
 | 
			
		||||
              $and: [{}],
 | 
			
		||||
            },
 | 
			
		||||
            'x-component': 'Filter',
 | 
			
		||||
            'x-component-props': {
 | 
			
		||||
              useDataSource: '{{cm.useFilterDataSource}}',
 | 
			
		||||
            },
 | 
			
		||||
          },
 | 
			
		||||
          footer: {
 | 
			
		||||
            type: 'void',
 | 
			
		||||
            'x-component': 'Action.Popover.Footer',
 | 
			
		||||
            properties: {
 | 
			
		||||
              actions: {
 | 
			
		||||
                type: 'void',
 | 
			
		||||
                'x-component': 'ActionBar',
 | 
			
		||||
                properties: {
 | 
			
		||||
                  saveDefault: {
 | 
			
		||||
                    type: 'void',
 | 
			
		||||
                    'x-component': 'Filter.SaveDefaultValue',
 | 
			
		||||
                    'x-component-props': {},
 | 
			
		||||
                  },
 | 
			
		||||
                  cancel: {
 | 
			
		||||
                    type: 'void',
 | 
			
		||||
                    title: '{{t("Cancel")}}',
 | 
			
		||||
                    'x-component': 'Action',
 | 
			
		||||
                    'x-component-props': {
 | 
			
		||||
                      useAction: '{{cm.useCancelFilterAction}}',
 | 
			
		||||
                    },
 | 
			
		||||
                  },
 | 
			
		||||
                  submit: {
 | 
			
		||||
                    type: 'void',
 | 
			
		||||
                    title: '{{t("Submit")}}',
 | 
			
		||||
                    'x-component': 'Action',
 | 
			
		||||
                    'x-component-props': {
 | 
			
		||||
                      type: 'primary',
 | 
			
		||||
                      useAction: '{{cm.useFilterAction}}',
 | 
			
		||||
                    },
 | 
			
		||||
                  },
 | 
			
		||||
                },
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
          },
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
  };
 | 
			
		||||
  const schema = {
 | 
			
		||||
    type: 'void',
 | 
			
		||||
    name: 'actionLog',
 | 
			
		||||
    'x-decorator': 'ResourceActionProvider',
 | 
			
		||||
    'x-decorator-props': {
 | 
			
		||||
      collection: 'action_logs',
 | 
			
		||||
      dragSort: false,
 | 
			
		||||
      request: {
 | 
			
		||||
        resource: 'action_logs',
 | 
			
		||||
        action: 'list',
 | 
			
		||||
        params: {
 | 
			
		||||
          pageSize: 20,
 | 
			
		||||
          filter: {},
 | 
			
		||||
          appends: [],
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
    'x-designer': 'ActionLog.Designer',
 | 
			
		||||
    'x-component': 'CardItem',
 | 
			
		||||
    properties: {
 | 
			
		||||
      actions: {
 | 
			
		||||
        type: 'void',
 | 
			
		||||
        'x-component': 'ActionBar',
 | 
			
		||||
        'x-component-props': {
 | 
			
		||||
          layout: 'one-column',
 | 
			
		||||
          style: {
 | 
			
		||||
            marginBottom: 16,
 | 
			
		||||
          },
 | 
			
		||||
        },
 | 
			
		||||
        properties: {
 | 
			
		||||
          [uid()]: { ...filterSchema },
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
      table: {
 | 
			
		||||
        type: 'void',
 | 
			
		||||
        'x-component': 'Table.Void',
 | 
			
		||||
        'x-component-props': {
 | 
			
		||||
          rowKey: 'id',
 | 
			
		||||
          useDataSource: '{{cm.useDataSourceFromRAC}}',
 | 
			
		||||
        },
 | 
			
		||||
        properties: {
 | 
			
		||||
          column1: {
 | 
			
		||||
            type: 'void',
 | 
			
		||||
            title: "{{t('Created at')}}",
 | 
			
		||||
            'x-component': 'Table.Column',
 | 
			
		||||
            properties: {
 | 
			
		||||
              created_at: {
 | 
			
		||||
                type: 'string',
 | 
			
		||||
                'x-component': 'DatePicker',
 | 
			
		||||
                'x-read-pretty': true,
 | 
			
		||||
                'x-component-props': {
 | 
			
		||||
                  format: 'YYYY-MM-DD HH:mm:ss',
 | 
			
		||||
                },
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
          },
 | 
			
		||||
          column2: {
 | 
			
		||||
            type: 'void',
 | 
			
		||||
            title: "{{t('Created by')}}",
 | 
			
		||||
            'x-component': 'Table.Column',
 | 
			
		||||
            properties: {
 | 
			
		||||
              'user.nickname': {
 | 
			
		||||
                type: 'string',
 | 
			
		||||
                'x-component': 'Input',
 | 
			
		||||
                'x-read-pretty': true,
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
          },
 | 
			
		||||
          column3: {
 | 
			
		||||
            type: 'void',
 | 
			
		||||
            title: "{{t('Collection display name')}}",
 | 
			
		||||
            'x-component': 'Table.Column',
 | 
			
		||||
            properties: {
 | 
			
		||||
              'collection.title': {
 | 
			
		||||
                type: 'string',
 | 
			
		||||
                'x-component': 'Input',
 | 
			
		||||
                'x-read-pretty': true,
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
          },
 | 
			
		||||
          column4: {
 | 
			
		||||
            type: 'void',
 | 
			
		||||
            title: "{{t('Action type')}}",
 | 
			
		||||
            'x-component': 'Table.Column',
 | 
			
		||||
            properties: {
 | 
			
		||||
              type: {
 | 
			
		||||
                type: 'string',
 | 
			
		||||
                'x-component': 'Select',
 | 
			
		||||
                'x-read-pretty': true,
 | 
			
		||||
                enum: [
 | 
			
		||||
                  { label: "{{ t('Add new') }}", value: 'create', color: 'green' },
 | 
			
		||||
                  { label: "{{ t('Update') }}", value: 'update', color: 'blue' },
 | 
			
		||||
                  { label: "{{ t('Delete') }}", value: 'destroy', color: 'red' },
 | 
			
		||||
                ],
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
          },
 | 
			
		||||
          [uid()]: {
 | 
			
		||||
            type: 'void',
 | 
			
		||||
            title: "{{t('Actions')}}",
 | 
			
		||||
            'x-component': 'Table.Column',
 | 
			
		||||
            'x-component-props': {
 | 
			
		||||
              width: 60,
 | 
			
		||||
              align: 'center',
 | 
			
		||||
            },
 | 
			
		||||
            properties: {
 | 
			
		||||
              [uid()]: {
 | 
			
		||||
                title: '{{ t("View") }}',
 | 
			
		||||
                type: 'void',
 | 
			
		||||
                'x-action': 'view',
 | 
			
		||||
                'x-component': 'Action.Link',
 | 
			
		||||
                'x-component-props': {
 | 
			
		||||
                  openMode: 'drawer',
 | 
			
		||||
                },
 | 
			
		||||
                properties: {
 | 
			
		||||
                  drawer: {
 | 
			
		||||
                    type: 'void',
 | 
			
		||||
                    'x-component': 'Action.Container',
 | 
			
		||||
                    'x-component-props': {
 | 
			
		||||
                      className: 'nb-action-popup',
 | 
			
		||||
                    },
 | 
			
		||||
                    title: '{{ t("View record") }}',
 | 
			
		||||
                    properties: {
 | 
			
		||||
                      created_at: {
 | 
			
		||||
                        type: 'string',
 | 
			
		||||
                        title: "{{t('Created at')}}",
 | 
			
		||||
                        'x-decorator': 'FormItem',
 | 
			
		||||
                        'x-component': 'DatePicker',
 | 
			
		||||
                        'x-read-pretty': true,
 | 
			
		||||
                        'x-component-props': {
 | 
			
		||||
                          format: 'YYYY-MM-DD HH:mm:ss',
 | 
			
		||||
                        },
 | 
			
		||||
                      },
 | 
			
		||||
                      'user.nickname': {
 | 
			
		||||
                        type: 'string',
 | 
			
		||||
                        title: "{{t('Created by')}}",
 | 
			
		||||
                        'x-decorator': 'FormItem',
 | 
			
		||||
                        'x-component': 'Input',
 | 
			
		||||
                        'x-read-pretty': true,
 | 
			
		||||
                      },
 | 
			
		||||
                      'collection.title': {
 | 
			
		||||
                        type: 'string',
 | 
			
		||||
                        title: "{{t('Collection display name')}}",
 | 
			
		||||
                        'x-decorator': 'FormItem',
 | 
			
		||||
                        'x-component': 'Input',
 | 
			
		||||
                        'x-read-pretty': true,
 | 
			
		||||
                      },
 | 
			
		||||
                      type: {
 | 
			
		||||
                        type: 'string',
 | 
			
		||||
                        title: "{{t('Action type')}}",
 | 
			
		||||
                        'x-decorator': 'FormItem',
 | 
			
		||||
                        'x-component': 'Select',
 | 
			
		||||
                        'x-read-pretty': true,
 | 
			
		||||
                        enum: [
 | 
			
		||||
                          {
 | 
			
		||||
                            label: "{{t('Insert')}}",
 | 
			
		||||
                            value: 'create',
 | 
			
		||||
                            color: 'green',
 | 
			
		||||
                          },
 | 
			
		||||
                          {
 | 
			
		||||
                            label: "{{t('Update')}}",
 | 
			
		||||
                            value: 'update',
 | 
			
		||||
                            color: 'blue',
 | 
			
		||||
                          },
 | 
			
		||||
                          {
 | 
			
		||||
                            label: "{{t('Delete')}}",
 | 
			
		||||
                            value: 'destroy',
 | 
			
		||||
                            color: 'red',
 | 
			
		||||
                          },
 | 
			
		||||
                        ],
 | 
			
		||||
                      },
 | 
			
		||||
                      changes: {
 | 
			
		||||
                        type: 'array',
 | 
			
		||||
                        title: "{{t('Data changes')}}",
 | 
			
		||||
                        'x-decorator': 'FormItem',
 | 
			
		||||
                        'x-component': 'Table.Array',
 | 
			
		||||
                        'x-component-props': {
 | 
			
		||||
                          pagination: false,
 | 
			
		||||
                          showIndex: true,
 | 
			
		||||
                        },
 | 
			
		||||
                        items: {
 | 
			
		||||
                          type: 'object',
 | 
			
		||||
                          properties: {
 | 
			
		||||
                            column1: {
 | 
			
		||||
                              type: 'void',
 | 
			
		||||
                              'x-component': 'Table.Column',
 | 
			
		||||
                              'x-component-props': { title: "{{t('Field display name')}}" },
 | 
			
		||||
                              properties: {
 | 
			
		||||
                                field: {
 | 
			
		||||
                                  type: 'string',
 | 
			
		||||
                                  'x-decorator': 'FormilyFormItem',
 | 
			
		||||
                                  'x-component': 'ActionLog.Field',
 | 
			
		||||
                                },
 | 
			
		||||
                              },
 | 
			
		||||
                            },
 | 
			
		||||
                            column2: {
 | 
			
		||||
                              type: 'void',
 | 
			
		||||
                              'x-component': 'Table.Column',
 | 
			
		||||
                              'x-component-props': { title: "{{ t('Before change') }}" },
 | 
			
		||||
                              properties: {
 | 
			
		||||
                                before: {
 | 
			
		||||
                                  type: 'string',
 | 
			
		||||
                                  'x-decorator': 'FormilyFormItem',
 | 
			
		||||
                                  'x-component': 'ActionLog.FieldValue',
 | 
			
		||||
                                },
 | 
			
		||||
                              },
 | 
			
		||||
                            },
 | 
			
		||||
                            column3: {
 | 
			
		||||
                              type: 'void',
 | 
			
		||||
                              'x-component': 'Table.Column',
 | 
			
		||||
                              'x-component-props': { title: "{{ t('After change') }}" },
 | 
			
		||||
                              properties: {
 | 
			
		||||
                                after: {
 | 
			
		||||
                                  type: 'string',
 | 
			
		||||
                                  'x-decorator': 'FormilyFormItem',
 | 
			
		||||
                                  'x-component': 'ActionLog.FieldValue',
 | 
			
		||||
                                },
 | 
			
		||||
                              },
 | 
			
		||||
                            },
 | 
			
		||||
                          },
 | 
			
		||||
                        },
 | 
			
		||||
                      },
 | 
			
		||||
                    },
 | 
			
		||||
                  },
 | 
			
		||||
                },
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
          },
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
  };
 | 
			
		||||
  return schema;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										2
									
								
								packages/plugins/@hera/plugin-audit-logs/src/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								packages/plugins/@hera/plugin-audit-logs/src/index.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,2 @@
 | 
			
		||||
export * from './server';
 | 
			
		||||
export { default } from './server';
 | 
			
		||||
@ -0,0 +1,4 @@
 | 
			
		||||
{
 | 
			
		||||
  "Details of changes": "Details of changes",
 | 
			
		||||
  "Create record": "Create record"
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,4 @@
 | 
			
		||||
{
 | 
			
		||||
  "Details of changes": "变更详情",
 | 
			
		||||
  "Create record": "创建数据"
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,117 @@
 | 
			
		||||
import Database from '@nocobase/database';
 | 
			
		||||
import { createMockServer, MockServer } from '@nocobase/test';
 | 
			
		||||
 | 
			
		||||
describe('hook', () => {
 | 
			
		||||
  let api: MockServer;
 | 
			
		||||
  let db: Database;
 | 
			
		||||
 | 
			
		||||
  beforeEach(async () => {
 | 
			
		||||
    api = await createMockServer({
 | 
			
		||||
      plugins: ['audit-logs'],
 | 
			
		||||
    });
 | 
			
		||||
    db = api.db;
 | 
			
		||||
    db.collection({
 | 
			
		||||
      name: 'posts',
 | 
			
		||||
      logging: true,
 | 
			
		||||
      fields: [
 | 
			
		||||
        {
 | 
			
		||||
          type: 'string',
 | 
			
		||||
          name: 'title',
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          type: 'string',
 | 
			
		||||
          name: 'status',
 | 
			
		||||
          defaultValue: 'draft',
 | 
			
		||||
        },
 | 
			
		||||
      ],
 | 
			
		||||
    });
 | 
			
		||||
    db.collection({
 | 
			
		||||
      name: 'users',
 | 
			
		||||
      logging: false,
 | 
			
		||||
      fields: [
 | 
			
		||||
        { type: 'string', name: 'nickname' },
 | 
			
		||||
        { type: 'string', name: 'token' },
 | 
			
		||||
      ],
 | 
			
		||||
    });
 | 
			
		||||
    await db.sync();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  afterEach(async () => {
 | 
			
		||||
    await api.destroy();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('model', async () => {
 | 
			
		||||
    const Post = db.getCollection('posts').model;
 | 
			
		||||
    const post = await Post.create({ title: 't1' });
 | 
			
		||||
    await post.update({ title: 't2' });
 | 
			
		||||
    await post.destroy();
 | 
			
		||||
    const auditLogs = await db.getCollection('auditLogs').repository.find({
 | 
			
		||||
      appends: ['changes'],
 | 
			
		||||
    });
 | 
			
		||||
    expect(auditLogs.length).toBe(3);
 | 
			
		||||
 | 
			
		||||
    const titleChange = (changes) => {
 | 
			
		||||
      return changes.find((item) => item.field.name === 'title');
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    expect(titleChange(auditLogs[0].changes).before).toBeNull();
 | 
			
		||||
    expect(titleChange(auditLogs[0].changes).after).toBe('t1');
 | 
			
		||||
 | 
			
		||||
    expect(titleChange(auditLogs[1].changes).before).toBe('t1');
 | 
			
		||||
    expect(titleChange(auditLogs[1].changes).after).toBe('t2');
 | 
			
		||||
 | 
			
		||||
    expect(titleChange(auditLogs[2].changes).before).toBe('t2');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('repository', async () => {
 | 
			
		||||
    const Post = db.getCollection('posts');
 | 
			
		||||
    const User = db.getCollection('users').model;
 | 
			
		||||
    const user = await User.create({ nickname: 'a', token: 'token1' });
 | 
			
		||||
    const post = await Post.repository.create({
 | 
			
		||||
      values: { title: 't1' },
 | 
			
		||||
      context: {
 | 
			
		||||
        state: {
 | 
			
		||||
          currentUser: user,
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
    });
 | 
			
		||||
    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: {
 | 
			
		||||
            name: 'title',
 | 
			
		||||
            type: 'string',
 | 
			
		||||
          },
 | 
			
		||||
          before: null,
 | 
			
		||||
          after: 't1',
 | 
			
		||||
        },
 | 
			
		||||
      ],
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // 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);
 | 
			
		||||
  // });
 | 
			
		||||
});
 | 
			
		||||
@ -0,0 +1,34 @@
 | 
			
		||||
import { defineCollection } from '@nocobase/database';
 | 
			
		||||
 | 
			
		||||
export default defineCollection({
 | 
			
		||||
  dumpRules: {
 | 
			
		||||
    group: 'log',
 | 
			
		||||
  },
 | 
			
		||||
  name: 'auditChanges',
 | 
			
		||||
  title: '变动值',
 | 
			
		||||
  createdBy: false,
 | 
			
		||||
  updatedBy: false,
 | 
			
		||||
  createdAt: false,
 | 
			
		||||
  updatedAt: false,
 | 
			
		||||
  shared: true,
 | 
			
		||||
  fields: [
 | 
			
		||||
    {
 | 
			
		||||
      type: 'json',
 | 
			
		||||
      name: 'field',
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      type: 'json',
 | 
			
		||||
      name: 'before',
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      type: 'json',
 | 
			
		||||
      name: 'after',
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      type: 'belongsTo',
 | 
			
		||||
      name: 'log',
 | 
			
		||||
      target: 'auditLogs',
 | 
			
		||||
      foreignKey: 'auditLogId',
 | 
			
		||||
    },
 | 
			
		||||
  ],
 | 
			
		||||
});
 | 
			
		||||
@ -0,0 +1,51 @@
 | 
			
		||||
import { defineCollection } from '@nocobase/database';
 | 
			
		||||
 | 
			
		||||
export default defineCollection({
 | 
			
		||||
  dumpRules: {
 | 
			
		||||
    group: 'log',
 | 
			
		||||
  },
 | 
			
		||||
  name: 'auditLogs',
 | 
			
		||||
  createdBy: false,
 | 
			
		||||
  updatedBy: false,
 | 
			
		||||
  updatedAt: false,
 | 
			
		||||
  shared: true,
 | 
			
		||||
  fields: [
 | 
			
		||||
    {
 | 
			
		||||
      type: 'date',
 | 
			
		||||
      name: 'createdAt',
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      type: 'string',
 | 
			
		||||
      name: 'type',
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      type: 'string',
 | 
			
		||||
      name: 'recordId',
 | 
			
		||||
      index: true,
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      type: 'string',
 | 
			
		||||
      name: 'collectionName',
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      type: 'belongsTo',
 | 
			
		||||
      name: 'collection',
 | 
			
		||||
      target: 'collections',
 | 
			
		||||
      targetKey: 'name',
 | 
			
		||||
      sourceKey: 'id',
 | 
			
		||||
      foreignKey: 'collectionName',
 | 
			
		||||
      constraints: false,
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      type: 'hasMany',
 | 
			
		||||
      name: 'changes',
 | 
			
		||||
      target: 'auditChanges',
 | 
			
		||||
      foreignKey: 'auditLogId',
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      type: 'belongsTo',
 | 
			
		||||
      name: 'user',
 | 
			
		||||
      target: 'users',
 | 
			
		||||
    },
 | 
			
		||||
  ],
 | 
			
		||||
});
 | 
			
		||||
@ -0,0 +1,3 @@
 | 
			
		||||
export const LOG_TYPE_CREATE = 'create';
 | 
			
		||||
export const LOG_TYPE_UPDATE = 'update';
 | 
			
		||||
export const LOG_TYPE_DESTROY = 'destroy';
 | 
			
		||||
@ -0,0 +1,45 @@
 | 
			
		||||
import { LOG_TYPE_CREATE } from '../constants';
 | 
			
		||||
 | 
			
		||||
export async function afterCreate(model, options) {
 | 
			
		||||
  if (options.logging === false) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  const { collection } = model.constructor;
 | 
			
		||||
  if (!collection || !collection.options.logging) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  const transaction = options.transaction;
 | 
			
		||||
  const AuditLog = model.constructor.database.getCollection('auditLogs');
 | 
			
		||||
  const currentUserId = options?.context?.state?.currentUser?.id;
 | 
			
		||||
  try {
 | 
			
		||||
    const changes = [];
 | 
			
		||||
    const changed = model.changed();
 | 
			
		||||
    if (changed) {
 | 
			
		||||
      changed.forEach((key: string) => {
 | 
			
		||||
        const field = collection.findField((field) => {
 | 
			
		||||
          return field.name === key || field.options.field === key;
 | 
			
		||||
        });
 | 
			
		||||
        if (field && !field.options.hidden) {
 | 
			
		||||
          changes.push({
 | 
			
		||||
            field: field.options,
 | 
			
		||||
            after: model.get(key),
 | 
			
		||||
          });
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
    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) {
 | 
			
		||||
    // console.error(error);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,43 @@
 | 
			
		||||
import { LOG_TYPE_DESTROY } from '../constants';
 | 
			
		||||
 | 
			
		||||
export async function afterDestroy(model, options) {
 | 
			
		||||
  const { collection } = model.constructor;
 | 
			
		||||
  if (!collection || !collection.options.logging) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  const transaction = options.transaction;
 | 
			
		||||
  const AuditLog = model.constructor.database.getCollection('auditLogs');
 | 
			
		||||
  const currentUserId = options?.context?.state?.currentUser?.id;
 | 
			
		||||
  try {
 | 
			
		||||
    const changes = [];
 | 
			
		||||
    Object.keys(model.get()).forEach((key: string) => {
 | 
			
		||||
      const field = collection.findField((field) => {
 | 
			
		||||
        return field.name === key || field.options.field === key;
 | 
			
		||||
      });
 | 
			
		||||
      if (field) {
 | 
			
		||||
        changes.push({
 | 
			
		||||
          field: field.options,
 | 
			
		||||
          before: model.get(key),
 | 
			
		||||
        });
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
    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();
 | 
			
		||||
    // }
 | 
			
		||||
  } catch (error) {
 | 
			
		||||
    // if (!options.transaction) {
 | 
			
		||||
    //   await transaction.rollback();
 | 
			
		||||
    // }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,52 @@
 | 
			
		||||
import { LOG_TYPE_UPDATE } from '../constants';
 | 
			
		||||
 | 
			
		||||
export async function afterUpdate(model, options) {
 | 
			
		||||
  const { collection } = model.constructor;
 | 
			
		||||
  if (!collection || !collection.options.logging) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  const changed = model.changed();
 | 
			
		||||
  if (!changed) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  const transaction = options.transaction;
 | 
			
		||||
  const AuditLog = model.constructor.database.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) {
 | 
			
		||||
      changes.push({
 | 
			
		||||
        field: field.options,
 | 
			
		||||
        after: model.get(key),
 | 
			
		||||
        before: model.previous(key),
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
  if (!changes.length) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  try {
 | 
			
		||||
    await AuditLog.repository.create({
 | 
			
		||||
      values: {
 | 
			
		||||
        type: LOG_TYPE_UPDATE,
 | 
			
		||||
        collectionName: model.constructor.name,
 | 
			
		||||
        recordId: model.get(model.constructor.primaryKeyAttribute),
 | 
			
		||||
        createdAt: model.get('updatedAt'),
 | 
			
		||||
        userId: currentUserId,
 | 
			
		||||
        changes,
 | 
			
		||||
      },
 | 
			
		||||
      transaction,
 | 
			
		||||
      hooks: false,
 | 
			
		||||
    });
 | 
			
		||||
    // if (!options.transaction) {
 | 
			
		||||
    //   await transaction.commit();
 | 
			
		||||
    // }
 | 
			
		||||
  } catch (error) {
 | 
			
		||||
    // if (!options.transaction) {
 | 
			
		||||
    //   await transaction.rollback();
 | 
			
		||||
    // }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,3 @@
 | 
			
		||||
export * from './after-create';
 | 
			
		||||
export * from './after-update';
 | 
			
		||||
export * from './after-destroy';
 | 
			
		||||
							
								
								
									
										23
									
								
								packages/plugins/@hera/plugin-audit-logs/src/server/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								packages/plugins/@hera/plugin-audit-logs/src/server/index.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,23 @@
 | 
			
		||||
import { Plugin } from '@nocobase/server';
 | 
			
		||||
import path from 'path';
 | 
			
		||||
import { afterCreate, afterDestroy, afterUpdate } from './hooks';
 | 
			
		||||
 | 
			
		||||
export default class PluginActionLogs extends Plugin {
 | 
			
		||||
  async beforeLoad() {
 | 
			
		||||
    this.db.on('afterCreate', afterCreate);
 | 
			
		||||
    this.db.on('afterUpdate', afterUpdate);
 | 
			
		||||
    this.db.on('afterDestroy', afterDestroy);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async load() {
 | 
			
		||||
    await this.importCollections(path.resolve(__dirname, 'collections'));
 | 
			
		||||
 | 
			
		||||
    this.db.addMigrations({
 | 
			
		||||
      namespace: 'audit-logs',
 | 
			
		||||
      directory: path.resolve(__dirname, './migrations'),
 | 
			
		||||
      context: {
 | 
			
		||||
        plugin: this,
 | 
			
		||||
      },
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user