refactor: audit logs block (#1517)
* refactor: audit-log * refactor: audit-log fix view action * refactor: audit-log view fix * refactor(audit-log): collection field fix * refactor: audit-log view field fix * refactor(audit-log): support fixedBlock * refactor(audit-log): i18n fix * refactor(audit-log): fixedTable and drag issue * refactor(audit-log): remove template support * refactor(audit-log): drag fix * refactor(audit-log): disableTemplate & DndContext --------- Co-authored-by: anuoua <anuoua@gmail.com>
This commit is contained in:
		
							parent
							
								
									e913af7f32
								
							
						
					
					
						commit
						07ec115904
					
				@ -20,7 +20,7 @@ export const CollectionManagerProvider: React.FC<CollectionManagerOptions> = (pr
 | 
			
		||||
        service,
 | 
			
		||||
        interfaces: { ...defaultInterfaces, ...ctx.interfaces, ...interfaces },
 | 
			
		||||
        templates: { ...defaultTemplates, ...templates },
 | 
			
		||||
        collections,
 | 
			
		||||
        collections: [...ctx.collections, ...collections],
 | 
			
		||||
        refreshCM,
 | 
			
		||||
      }}
 | 
			
		||||
    >
 | 
			
		||||
@ -38,7 +38,7 @@ export const RemoteCollectionManagerProvider = (props: any) => {
 | 
			
		||||
    action: 'list',
 | 
			
		||||
    params: {
 | 
			
		||||
      paginate: false,
 | 
			
		||||
      appends: ['fields', 'fields.uiSchema','category'],
 | 
			
		||||
      appends: ['fields', 'fields.uiSchema', 'category'],
 | 
			
		||||
      filter: {
 | 
			
		||||
        // inherit: false,
 | 
			
		||||
      },
 | 
			
		||||
@ -75,13 +75,13 @@ export const RemoteCollectionManagerProvider = (props: any) => {
 | 
			
		||||
 | 
			
		||||
export const CollectionCategroriesProvider = (props) => {
 | 
			
		||||
  const api = useAPIClient();
 | 
			
		||||
  const options={
 | 
			
		||||
  const options = {
 | 
			
		||||
    url: 'collectionCategories:list',
 | 
			
		||||
    params: {
 | 
			
		||||
      paginate: false,
 | 
			
		||||
      sort:['sort']
 | 
			
		||||
      sort: ['sort'],
 | 
			
		||||
    },
 | 
			
		||||
  }
 | 
			
		||||
  };
 | 
			
		||||
  const result = useRequest(options);
 | 
			
		||||
  if (result.loading) {
 | 
			
		||||
    return <Spin />;
 | 
			
		||||
@ -91,11 +91,11 @@ export const CollectionCategroriesProvider = (props) => {
 | 
			
		||||
      value={{
 | 
			
		||||
        ...result,
 | 
			
		||||
        data: result?.data?.data,
 | 
			
		||||
        refresh:async ()=>{
 | 
			
		||||
        refresh: async () => {
 | 
			
		||||
          const { data } = await api.request(options);
 | 
			
		||||
          result.mutate(data);
 | 
			
		||||
          return data?.data || [];
 | 
			
		||||
        }
 | 
			
		||||
        },
 | 
			
		||||
      }}
 | 
			
		||||
    >
 | 
			
		||||
      {props.children}
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@ import cls from 'classnames';
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { useCollection } from '../../../collection-manager';
 | 
			
		||||
import { useSchemaInitializer } from '../../../schema-initializer';
 | 
			
		||||
import { SortableItem } from '../../common';
 | 
			
		||||
import { DndContext, SortableItem } from '../../common';
 | 
			
		||||
import { useDesigner } from '../../hooks';
 | 
			
		||||
import { AssociationFilterInitializer } from './AssociationFilter.Initializer';
 | 
			
		||||
import { AssociationFilterItem } from './AssociationFilter.Item';
 | 
			
		||||
@ -17,59 +17,61 @@ export const AssociationFilter = (props) => {
 | 
			
		||||
  const { exists, render } = useSchemaInitializer(filedSchema['x-initializer']);
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <SortableItem
 | 
			
		||||
      className={cls(
 | 
			
		||||
        'nb-block-item',
 | 
			
		||||
        props.className,
 | 
			
		||||
        css`
 | 
			
		||||
          position: relative;
 | 
			
		||||
          &:hover {
 | 
			
		||||
            > .general-schema-designer {
 | 
			
		||||
              display: block;
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
          &.nb-form-item:hover {
 | 
			
		||||
            > .general-schema-designer {
 | 
			
		||||
              background: rgba(241, 139, 98, 0.06) !important;
 | 
			
		||||
              border: 0 !important;
 | 
			
		||||
              top: -5px !important;
 | 
			
		||||
              bottom: -5px !important;
 | 
			
		||||
              left: -5px !important;
 | 
			
		||||
              right: -5px !important;
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
          > .general-schema-designer {
 | 
			
		||||
            position: absolute;
 | 
			
		||||
            z-index: 999;
 | 
			
		||||
            top: 0;
 | 
			
		||||
            bottom: 0;
 | 
			
		||||
            left: 0;
 | 
			
		||||
            right: 0;
 | 
			
		||||
            display: none;
 | 
			
		||||
            border: 2px solid rgba(241, 139, 98, 0.3);
 | 
			
		||||
            pointer-events: none;
 | 
			
		||||
            > .general-schema-designer-icons {
 | 
			
		||||
              position: absolute;
 | 
			
		||||
              right: 2px;
 | 
			
		||||
              top: 2px;
 | 
			
		||||
              line-height: 16px;
 | 
			
		||||
              pointer-events: all;
 | 
			
		||||
              .ant-space-item {
 | 
			
		||||
                background-color: #f18b62;
 | 
			
		||||
                color: #fff;
 | 
			
		||||
                line-height: 16px;
 | 
			
		||||
                width: 16px;
 | 
			
		||||
                padding-left: 1px;
 | 
			
		||||
    <DndContext>
 | 
			
		||||
      <SortableItem
 | 
			
		||||
        className={cls(
 | 
			
		||||
          'nb-block-item',
 | 
			
		||||
          props.className,
 | 
			
		||||
          css`
 | 
			
		||||
            position: relative;
 | 
			
		||||
            &:hover {
 | 
			
		||||
              > .general-schema-designer {
 | 
			
		||||
                display: block;
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        `,
 | 
			
		||||
      )}
 | 
			
		||||
    >
 | 
			
		||||
      <Designer />
 | 
			
		||||
      {props.children}
 | 
			
		||||
      {render()}
 | 
			
		||||
    </SortableItem>
 | 
			
		||||
            &.nb-form-item:hover {
 | 
			
		||||
              > .general-schema-designer {
 | 
			
		||||
                background: rgba(241, 139, 98, 0.06) !important;
 | 
			
		||||
                border: 0 !important;
 | 
			
		||||
                top: -5px !important;
 | 
			
		||||
                bottom: -5px !important;
 | 
			
		||||
                left: -5px !important;
 | 
			
		||||
                right: -5px !important;
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
            > .general-schema-designer {
 | 
			
		||||
              position: absolute;
 | 
			
		||||
              z-index: 999;
 | 
			
		||||
              top: 0;
 | 
			
		||||
              bottom: 0;
 | 
			
		||||
              left: 0;
 | 
			
		||||
              right: 0;
 | 
			
		||||
              display: none;
 | 
			
		||||
              border: 2px solid rgba(241, 139, 98, 0.3);
 | 
			
		||||
              pointer-events: none;
 | 
			
		||||
              > .general-schema-designer-icons {
 | 
			
		||||
                position: absolute;
 | 
			
		||||
                right: 2px;
 | 
			
		||||
                top: 2px;
 | 
			
		||||
                line-height: 16px;
 | 
			
		||||
                pointer-events: all;
 | 
			
		||||
                .ant-space-item {
 | 
			
		||||
                  background-color: #f18b62;
 | 
			
		||||
                  color: #fff;
 | 
			
		||||
                  line-height: 16px;
 | 
			
		||||
                  width: 16px;
 | 
			
		||||
                  padding-left: 1px;
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          `,
 | 
			
		||||
        )}
 | 
			
		||||
      >
 | 
			
		||||
        <Designer />
 | 
			
		||||
        {props.children}
 | 
			
		||||
        {render()}
 | 
			
		||||
      </SortableItem>
 | 
			
		||||
    </DndContext>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -6,6 +6,7 @@ import { useTranslation } from 'react-i18next';
 | 
			
		||||
import { useDesignable } from '../../hooks';
 | 
			
		||||
import { useRecord } from '../../../record-provider';
 | 
			
		||||
import { useBlockTemplateContext } from '../../../schema-templates/BlockTemplate';
 | 
			
		||||
import { uid } from '@formily/shared';
 | 
			
		||||
 | 
			
		||||
const FixedBlockContext = React.createContext({
 | 
			
		||||
  setFixedSchema: (schema: Schema) => {},
 | 
			
		||||
 | 
			
		||||
@ -23,6 +23,7 @@ export const TableBlockDesigner = () => {
 | 
			
		||||
  const defaultFilter = fieldSchema?.['x-decorator-props']?.params?.filter || {};
 | 
			
		||||
  const defaultSort = fieldSchema?.['x-decorator-props']?.params?.sort || [];
 | 
			
		||||
  const defaultResource = fieldSchema?.['x-decorator-props']?.resource;
 | 
			
		||||
  const supportTemplate = !fieldSchema?.['x-decorator-props']?.disableTemplate;
 | 
			
		||||
  const sort = defaultSort?.map((item: string) => {
 | 
			
		||||
    return item.startsWith('-')
 | 
			
		||||
      ? {
 | 
			
		||||
@ -211,8 +212,10 @@ export const TableBlockDesigner = () => {
 | 
			
		||||
          });
 | 
			
		||||
        }}
 | 
			
		||||
      />
 | 
			
		||||
      <SchemaSettings.Divider />
 | 
			
		||||
      <SchemaSettings.Template componentName={'Table'} collectionName={name} resourceName={defaultResource} />
 | 
			
		||||
      {supportTemplate && <SchemaSettings.Divider />}
 | 
			
		||||
      {supportTemplate && (
 | 
			
		||||
        <SchemaSettings.Template componentName={'Table'} collectionName={name} resourceName={defaultResource} />
 | 
			
		||||
      )}
 | 
			
		||||
      <SchemaSettings.Divider />
 | 
			
		||||
      <SchemaSettings.Remove
 | 
			
		||||
        removeParentsIfNoChildren
 | 
			
		||||
 | 
			
		||||
@ -10,7 +10,7 @@ import {
 | 
			
		||||
  SchemaInitializerButtonProps,
 | 
			
		||||
  SchemaInitializerItemComponent,
 | 
			
		||||
  SchemaInitializerItemOptions,
 | 
			
		||||
  SchemaInitializerItemProps
 | 
			
		||||
  SchemaInitializerItemProps,
 | 
			
		||||
} from './types';
 | 
			
		||||
 | 
			
		||||
const defaultWrap = (s: ISchema) => s;
 | 
			
		||||
 | 
			
		||||
@ -6,7 +6,7 @@ import { SchemaInitializer, SchemaSettings } from '../..';
 | 
			
		||||
import { useAPIClient } from '../../api-client';
 | 
			
		||||
import { createDesignable, useDesignable } from '../../schema-component';
 | 
			
		||||
 | 
			
		||||
const Resizable = (props) => {
 | 
			
		||||
export const Resizable = (props) => {
 | 
			
		||||
  const { t } = useTranslation();
 | 
			
		||||
  const { dn } = useDesignable();
 | 
			
		||||
  const fieldSchema = useFieldSchema();
 | 
			
		||||
 | 
			
		||||
@ -2,5 +2,13 @@ export * from './SchemaInitializer';
 | 
			
		||||
export * from './SchemaInitializerProvider';
 | 
			
		||||
export * from './types';
 | 
			
		||||
export * from './items';
 | 
			
		||||
export { gridRowColWrap, useRecordCollectionDataSourceItems } from './utils';
 | 
			
		||||
export {
 | 
			
		||||
  gridRowColWrap,
 | 
			
		||||
  useRecordCollectionDataSourceItems,
 | 
			
		||||
  createTableBlockSchema,
 | 
			
		||||
  useAssociatedTableColumnInitializerFields,
 | 
			
		||||
  useInheritsTableColumnInitializerFields,
 | 
			
		||||
  useTableColumnInitializerFields,
 | 
			
		||||
  itemsMerge,
 | 
			
		||||
} from './utils';
 | 
			
		||||
export * from './buttons';
 | 
			
		||||
 | 
			
		||||
@ -815,10 +815,20 @@ export const createReadPrettyFormBlockSchema = (options) => {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const createTableBlockSchema = (options) => {
 | 
			
		||||
  const { collection, resource, rowKey, ...others } = options;
 | 
			
		||||
  const {
 | 
			
		||||
    collection,
 | 
			
		||||
    resource,
 | 
			
		||||
    rowKey,
 | 
			
		||||
    tableActionInitializers,
 | 
			
		||||
    tableColumnInitializers,
 | 
			
		||||
    tableActionColumnInitializers,
 | 
			
		||||
    tableBlockProvider,
 | 
			
		||||
    disableTemplate,
 | 
			
		||||
    ...others
 | 
			
		||||
  } = options;
 | 
			
		||||
  const schema: ISchema = {
 | 
			
		||||
    type: 'void',
 | 
			
		||||
    'x-decorator': 'TableBlockProvider',
 | 
			
		||||
    'x-decorator': tableBlockProvider ?? 'TableBlockProvider',
 | 
			
		||||
    'x-acl-action': `${resource || collection}:list`,
 | 
			
		||||
    'x-decorator-props': {
 | 
			
		||||
      collection,
 | 
			
		||||
@ -830,6 +840,7 @@ export const createTableBlockSchema = (options) => {
 | 
			
		||||
      rowKey,
 | 
			
		||||
      showIndex: true,
 | 
			
		||||
      dragSort: false,
 | 
			
		||||
      disableTemplate: disableTemplate ?? false,
 | 
			
		||||
      ...others,
 | 
			
		||||
    },
 | 
			
		||||
    'x-designer': 'TableBlockDesigner',
 | 
			
		||||
@ -837,7 +848,7 @@ export const createTableBlockSchema = (options) => {
 | 
			
		||||
    properties: {
 | 
			
		||||
      actions: {
 | 
			
		||||
        type: 'void',
 | 
			
		||||
        'x-initializer': 'TableActionInitializers',
 | 
			
		||||
        'x-initializer': tableActionInitializers ?? 'TableActionInitializers',
 | 
			
		||||
        'x-component': 'ActionBar',
 | 
			
		||||
        'x-component-props': {
 | 
			
		||||
          style: {
 | 
			
		||||
@ -848,7 +859,7 @@ export const createTableBlockSchema = (options) => {
 | 
			
		||||
      },
 | 
			
		||||
      [uid()]: {
 | 
			
		||||
        type: 'array',
 | 
			
		||||
        'x-initializer': 'TableColumnInitializers',
 | 
			
		||||
        'x-initializer': tableColumnInitializers ?? 'TableColumnInitializers',
 | 
			
		||||
        'x-component': 'TableV2',
 | 
			
		||||
        'x-component-props': {
 | 
			
		||||
          rowKey: 'id',
 | 
			
		||||
@ -865,7 +876,7 @@ export const createTableBlockSchema = (options) => {
 | 
			
		||||
            'x-decorator': 'TableV2.Column.ActionBar',
 | 
			
		||||
            'x-component': 'TableV2.Column',
 | 
			
		||||
            'x-designer': 'TableV2.ActionColumnDesigner',
 | 
			
		||||
            'x-initializer': 'TableActionColumnInitializers',
 | 
			
		||||
            'x-initializer': tableActionColumnInitializers ?? 'TableActionColumnInitializers',
 | 
			
		||||
            properties: {
 | 
			
		||||
              actions: {
 | 
			
		||||
                type: 'void',
 | 
			
		||||
 | 
			
		||||
@ -1,31 +1,29 @@
 | 
			
		||||
import { TableOutlined } from '@ant-design/icons';
 | 
			
		||||
import { SchemaInitializer } from '@nocobase/client';
 | 
			
		||||
import { ISchema } from '@formily/react';
 | 
			
		||||
import { createTableBlockSchema, SchemaInitializer } from '@nocobase/client';
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { useTranslation } from 'react-i18next';
 | 
			
		||||
 | 
			
		||||
export const AuditLogsBlockInitializer = (props) => {
 | 
			
		||||
  const { insert } = props;
 | 
			
		||||
  const { t } = useTranslation();
 | 
			
		||||
 | 
			
		||||
  const schema = createTableBlockSchema({
 | 
			
		||||
    collection: 'auditLogs',
 | 
			
		||||
    rowKey: 'id',
 | 
			
		||||
    tableActionInitializers: 'AuditLogsTableActionInitializers',
 | 
			
		||||
    tableColumnInitializers: 'AuditLogsTableColumnInitializers',
 | 
			
		||||
    tableActionColumnInitializers: 'AuditLogsTableActionColumnInitializers',
 | 
			
		||||
    tableBlockProvider: 'AuditLogsBlockProvider',
 | 
			
		||||
    disableTemplate: true,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <SchemaInitializer.Item
 | 
			
		||||
      {...props}
 | 
			
		||||
      icon={<TableOutlined />}
 | 
			
		||||
      onClick={() => {
 | 
			
		||||
        insert({
 | 
			
		||||
          type: 'void',
 | 
			
		||||
          'x-designer': 'AuditLogs.Designer',
 | 
			
		||||
          'x-decorator': 'AuditLogs.Decorator',
 | 
			
		||||
          'x-decorator-props': {
 | 
			
		||||
            params: {},
 | 
			
		||||
          },
 | 
			
		||||
          'x-component': 'CardItem',
 | 
			
		||||
          properties: {
 | 
			
		||||
            auditLogs: {
 | 
			
		||||
              type: 'void',
 | 
			
		||||
              'x-component': 'AuditLogs',
 | 
			
		||||
            },
 | 
			
		||||
          },
 | 
			
		||||
        });
 | 
			
		||||
        insert(schema as ISchema);
 | 
			
		||||
      }}
 | 
			
		||||
      title={t('Audit Logs')}
 | 
			
		||||
    />
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,33 @@
 | 
			
		||||
import {
 | 
			
		||||
  CollectionManagerProvider,
 | 
			
		||||
  SchemaInitializerContext,
 | 
			
		||||
  SchemaInitializerProvider,
 | 
			
		||||
  TableBlockProvider,
 | 
			
		||||
} from '@nocobase/client';
 | 
			
		||||
import React, { useContext } from 'react';
 | 
			
		||||
import { useAuditChangesCollection, useAuditLogsCollection, useCollectionsCollection } from './collections';
 | 
			
		||||
import { AuditLogsTableActionColumnInitializers } from './initializers/AuditLogsTableActionColumnInitializers';
 | 
			
		||||
import { AuditLogsTableActionInitializers } from './initializers/AuditLogsTableActionInitializers';
 | 
			
		||||
import { AuditLogsTableColumnInitializers } from './initializers/AuditLogsTableColumnInitializers';
 | 
			
		||||
 | 
			
		||||
export const AuditLogsBlockProvider: React.FC = ({ children, ...restProps }) => {
 | 
			
		||||
  const initializers = useContext(SchemaInitializerContext);
 | 
			
		||||
  const auditChangesCollection = useAuditChangesCollection();
 | 
			
		||||
  const auditLogsCollection = useAuditLogsCollection();
 | 
			
		||||
  const collectionsCollection = useCollectionsCollection();
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <SchemaInitializerProvider
 | 
			
		||||
      initializers={{
 | 
			
		||||
        ...initializers,
 | 
			
		||||
        AuditLogsTableActionInitializers,
 | 
			
		||||
        AuditLogsTableActionColumnInitializers,
 | 
			
		||||
        AuditLogsTableColumnInitializers,
 | 
			
		||||
      }}
 | 
			
		||||
    >
 | 
			
		||||
      <CollectionManagerProvider collections={[auditLogsCollection, auditChangesCollection, collectionsCollection]}>
 | 
			
		||||
        <TableBlockProvider {...restProps}>{children}</TableBlockProvider>
 | 
			
		||||
      </CollectionManagerProvider>
 | 
			
		||||
    </SchemaInitializerProvider>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
@ -1,11 +1,26 @@
 | 
			
		||||
import { SchemaComponentOptions } from '@nocobase/client';
 | 
			
		||||
import { SchemaComponentOptions, SchemaInitializerContext, SchemaInitializerProvider } from '@nocobase/client';
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { AuditLogs } from './AuditLogs';
 | 
			
		||||
import { AuditLogsBlockInitializer } from './AuditLogsBlockInitializer';
 | 
			
		||||
import { AuditLogsValue } from './components/AuditLogsValue';
 | 
			
		||||
import { AuditLogsField } from './components/AuditLogsField';
 | 
			
		||||
import { AuditLogsBlockProvider } from './AuditLogsBlockProvider';
 | 
			
		||||
import { AuditLogsTableActionColumnInitializer } from './initializers/AuditLogsTableActionColumnInitializer';
 | 
			
		||||
import { AuditLogs } from './deplicated/AuditLogs';
 | 
			
		||||
import { AuditLogsViewActionInitializer } from './components/AuditLogsViewActionInitializer';
 | 
			
		||||
 | 
			
		||||
export const AuditLogsProvider = (props: any) => {
 | 
			
		||||
  return (
 | 
			
		||||
    <SchemaComponentOptions components={{ AuditLogs, AuditLogsBlockInitializer }}>
 | 
			
		||||
    <SchemaComponentOptions
 | 
			
		||||
      components={{
 | 
			
		||||
        AuditLogs,
 | 
			
		||||
        AuditLogsBlockProvider,
 | 
			
		||||
        AuditLogsBlockInitializer,
 | 
			
		||||
        AuditLogsValue,
 | 
			
		||||
        AuditLogsField,
 | 
			
		||||
        AuditLogsViewActionInitializer,
 | 
			
		||||
        AuditLogsTableActionColumnInitializer,
 | 
			
		||||
      }}
 | 
			
		||||
    >
 | 
			
		||||
      {props.children}
 | 
			
		||||
    </SchemaComponentOptions>
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										166
									
								
								packages/plugins/audit-logs/src/client/collections.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								packages/plugins/audit-logs/src/client/collections.tsx
									
									
									
									
									
										Normal file
									
								
							@ -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': 'RecordPicker',
 | 
			
		||||
          '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': 'RecordPicker',
 | 
			
		||||
          '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,12 @@
 | 
			
		||||
import { 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 <div>{field.value?.uiSchema?.title ? compile(field.value?.uiSchema?.title) : field.value.name}</div>;
 | 
			
		||||
});
 | 
			
		||||
@ -0,0 +1,23 @@
 | 
			
		||||
import { 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 <div>{field.value ? JSON.stringify(field.value) : null}</div>;
 | 
			
		||||
});
 | 
			
		||||
@ -0,0 +1,340 @@
 | 
			
		||||
import { ActionInitializer } from '@nocobase/client';
 | 
			
		||||
import React from 'react';
 | 
			
		||||
 | 
			
		||||
export const AuditLogsViewActionInitializer = (props) => {
 | 
			
		||||
  const schema = {
 | 
			
		||||
    type: 'void',
 | 
			
		||||
    title: '{{ t("View") }}',
 | 
			
		||||
    'x-action': 'view',
 | 
			
		||||
    'x-designer': 'Action.Designer',
 | 
			
		||||
    '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',
 | 
			
		||||
                                  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': 'RecordBlockInitializers',
 | 
			
		||||
                                                                  },
 | 
			
		||||
                                                                },
 | 
			
		||||
                                                              },
 | 
			
		||||
                                                            },
 | 
			
		||||
                                                          },
 | 
			
		||||
                                                        },
 | 
			
		||||
                                                      },
 | 
			
		||||
                                                    },
 | 
			
		||||
                                                  },
 | 
			
		||||
                                                },
 | 
			
		||||
                                              },
 | 
			
		||||
                                            },
 | 
			
		||||
                                          },
 | 
			
		||||
                                          '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: {
 | 
			
		||||
                                                                type: 'checkbox',
 | 
			
		||||
                                                              },
 | 
			
		||||
                                                              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 {...props} schema={schema} />;
 | 
			
		||||
};
 | 
			
		||||
@ -7,7 +7,8 @@ import {
 | 
			
		||||
  SchemaComponent,
 | 
			
		||||
  TableBlockProvider,
 | 
			
		||||
  useCollection,
 | 
			
		||||
  useCompile, useRecord
 | 
			
		||||
  useCompile,
 | 
			
		||||
  useRecord,
 | 
			
		||||
} from '@nocobase/client';
 | 
			
		||||
import React, { createContext, useContext } from 'react';
 | 
			
		||||
import { AuditLogsDesigner } from './AuditLogsDesigner';
 | 
			
		||||
@ -106,7 +107,7 @@ export const AuditLogs: any = () => {
 | 
			
		||||
          'x-read-pretty': true,
 | 
			
		||||
        },
 | 
			
		||||
      },
 | 
			
		||||
    }
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
  return (
 | 
			
		||||
    <SchemaComponent
 | 
			
		||||
@ -454,10 +455,13 @@ AuditLogs.Decorator = observer((props: any) => {
 | 
			
		||||
    const filterByTk = record?.[parent.filterTargetKey || 'id'];
 | 
			
		||||
    if (filter) {
 | 
			
		||||
      filter = {
 | 
			
		||||
        $and: [filter, {
 | 
			
		||||
          collectionName: parent.name,
 | 
			
		||||
          recordId: `${filterByTk}`,
 | 
			
		||||
        }],
 | 
			
		||||
        $and: [
 | 
			
		||||
          filter,
 | 
			
		||||
          {
 | 
			
		||||
            collectionName: parent.name,
 | 
			
		||||
            recordId: `${filterByTk}`,
 | 
			
		||||
          },
 | 
			
		||||
        ],
 | 
			
		||||
      };
 | 
			
		||||
    } else {
 | 
			
		||||
      filter = {
 | 
			
		||||
@ -1,5 +1,13 @@
 | 
			
		||||
import { ISchema, useField, useFieldSchema } from '@formily/react';
 | 
			
		||||
import { GeneralSchemaDesigner, SchemaSettings, useCollection, useCollectionFilterOptions, useDesignable, useSortFields, useTableBlockContext } from '@nocobase/client';
 | 
			
		||||
import {
 | 
			
		||||
  GeneralSchemaDesigner,
 | 
			
		||||
  SchemaSettings,
 | 
			
		||||
  useCollection,
 | 
			
		||||
  useCollectionFilterOptions,
 | 
			
		||||
  useDesignable,
 | 
			
		||||
  useSortFields,
 | 
			
		||||
  useTableBlockContext,
 | 
			
		||||
} from '@nocobase/client';
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { useTranslation } from 'react-i18next';
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,26 @@
 | 
			
		||||
import { InitializerWithSwitch } from '@nocobase/client';
 | 
			
		||||
import React from 'react';
 | 
			
		||||
 | 
			
		||||
export const AuditLogsTableActionColumnInitializer = (props) => {
 | 
			
		||||
  const schema = {
 | 
			
		||||
    type: 'void',
 | 
			
		||||
    title: '{{ t("Actions") }}',
 | 
			
		||||
    'x-decorator': 'TableV2.Column.ActionBar',
 | 
			
		||||
    'x-component': 'TableV2.Column',
 | 
			
		||||
    'x-designer': 'TableV2.ActionColumnDesigner',
 | 
			
		||||
    'x-initializer': 'AuditLogsTableActionColumnInitializers',
 | 
			
		||||
    'x-action-column': 'actions',
 | 
			
		||||
    properties: {
 | 
			
		||||
      actions: {
 | 
			
		||||
        type: 'void',
 | 
			
		||||
        'x-decorator': 'DndContext',
 | 
			
		||||
        'x-component': 'Space',
 | 
			
		||||
        'x-component-props': {
 | 
			
		||||
          split: '|',
 | 
			
		||||
        },
 | 
			
		||||
        properties: {},
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
  };
 | 
			
		||||
  return <InitializerWithSwitch {...props} schema={schema} type={'x-action-column'} />;
 | 
			
		||||
};
 | 
			
		||||
@ -0,0 +1,63 @@
 | 
			
		||||
import { MenuOutlined } from '@ant-design/icons';
 | 
			
		||||
import { useFieldSchema } from '@formily/react';
 | 
			
		||||
import { createDesignable, Resizable, SchemaInitializer, useAPIClient, useDesignable } from '@nocobase/client';
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { useTranslation } from 'react-i18next';
 | 
			
		||||
 | 
			
		||||
export const AuditLogsTableActionColumnInitializers = (props: any) => {
 | 
			
		||||
  const fieldSchema = useFieldSchema();
 | 
			
		||||
  const api = useAPIClient();
 | 
			
		||||
  const { refresh } = useDesignable();
 | 
			
		||||
  const { t } = useTranslation();
 | 
			
		||||
  return (
 | 
			
		||||
    <SchemaInitializer.Button
 | 
			
		||||
      insertPosition={'beforeEnd'}
 | 
			
		||||
      insert={(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={[
 | 
			
		||||
        {
 | 
			
		||||
          type: 'itemGroup',
 | 
			
		||||
          title: t('Enable actions'),
 | 
			
		||||
          children: [
 | 
			
		||||
            {
 | 
			
		||||
              type: 'item',
 | 
			
		||||
              title: t('View'),
 | 
			
		||||
              component: 'AuditLogsViewActionInitializer',
 | 
			
		||||
              schema: {
 | 
			
		||||
                'x-component': 'Action.Link',
 | 
			
		||||
                'x-action': 'view',
 | 
			
		||||
                'x-decorator': 'ACLActionProvider',
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
          ],
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          type: 'divider',
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          type: 'item',
 | 
			
		||||
          title: t('Column width'),
 | 
			
		||||
          component: Resizable,
 | 
			
		||||
        },
 | 
			
		||||
      ]}
 | 
			
		||||
      component={<MenuOutlined style={{ cursor: 'pointer' }} />}
 | 
			
		||||
    />
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
@ -0,0 +1,51 @@
 | 
			
		||||
import { Schema } from '@formily/react';
 | 
			
		||||
 | 
			
		||||
// 操作记录表格操作配置
 | 
			
		||||
export const AuditLogsTableActionInitializers = {
 | 
			
		||||
  title: "{{t('Configure actions')}}",
 | 
			
		||||
  icon: 'SettingOutlined',
 | 
			
		||||
  style: {
 | 
			
		||||
    marginLeft: 8,
 | 
			
		||||
  },
 | 
			
		||||
  items: [
 | 
			
		||||
    {
 | 
			
		||||
      type: 'itemGroup',
 | 
			
		||||
      title: "{{t('Enable actions')}}",
 | 
			
		||||
      children: [
 | 
			
		||||
        {
 | 
			
		||||
          type: 'item',
 | 
			
		||||
          title: "{{t('Filter')}}",
 | 
			
		||||
          component: 'FilterActionInitializer',
 | 
			
		||||
          schema: {
 | 
			
		||||
            'x-align': 'left',
 | 
			
		||||
          },
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          type: 'item',
 | 
			
		||||
          title: "{{t('Refresh')}}",
 | 
			
		||||
          component: 'RefreshActionInitializer',
 | 
			
		||||
          schema: {
 | 
			
		||||
            'x-align': 'right',
 | 
			
		||||
          },
 | 
			
		||||
        },
 | 
			
		||||
      ],
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      type: 'divider',
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      type: 'item',
 | 
			
		||||
      title: "{{t('Association fields filter')}}",
 | 
			
		||||
      component: 'ActionBarAssociationFilterAction',
 | 
			
		||||
      schema: {
 | 
			
		||||
        'x-align': 'left',
 | 
			
		||||
      },
 | 
			
		||||
      find: (schema: Schema) => {
 | 
			
		||||
        const resultSchema = Object.entries(schema.parent.properties).find(
 | 
			
		||||
          ([, value]) => value['x-component'] === 'AssociationFilter',
 | 
			
		||||
        )?.[1];
 | 
			
		||||
        return resultSchema;
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
  ],
 | 
			
		||||
};
 | 
			
		||||
@ -0,0 +1,88 @@
 | 
			
		||||
import {
 | 
			
		||||
  itemsMerge,
 | 
			
		||||
  SchemaInitializer,
 | 
			
		||||
  useAssociatedTableColumnInitializerFields,
 | 
			
		||||
  useCompile,
 | 
			
		||||
  useInheritsTableColumnInitializerFields,
 | 
			
		||||
  useTableColumnInitializerFields,
 | 
			
		||||
} from '@nocobase/client';
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { useTranslation } from 'react-i18next';
 | 
			
		||||
 | 
			
		||||
// 表格列配置
 | 
			
		||||
export const AuditLogsTableColumnInitializers = (props: any) => {
 | 
			
		||||
  const { items = [] } = props;
 | 
			
		||||
  const { t } = useTranslation();
 | 
			
		||||
  const associatedFields = useAssociatedTableColumnInitializerFields();
 | 
			
		||||
  const inheritFields = useInheritsTableColumnInitializerFields();
 | 
			
		||||
  const compile = useCompile();
 | 
			
		||||
  const fieldItems: any[] = [
 | 
			
		||||
    {
 | 
			
		||||
      type: 'itemGroup',
 | 
			
		||||
      title: t('Display fields'),
 | 
			
		||||
      children: useTableColumnInitializerFields(),
 | 
			
		||||
    },
 | 
			
		||||
  ];
 | 
			
		||||
  if (inheritFields?.length > 0) {
 | 
			
		||||
    inheritFields.forEach((inherit) => {
 | 
			
		||||
      Object.values(inherit)[0].length &&
 | 
			
		||||
        fieldItems.push(
 | 
			
		||||
          {
 | 
			
		||||
            type: 'divider',
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            type: 'itemGroup',
 | 
			
		||||
            title: t(`Parent collection fields`) + '(' + compile(`${Object.keys(inherit)[0]}`) + ')',
 | 
			
		||||
            children: Object.values(inherit)[0],
 | 
			
		||||
          },
 | 
			
		||||
        );
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
  if (associatedFields?.length > 0) {
 | 
			
		||||
    fieldItems.push(
 | 
			
		||||
      {
 | 
			
		||||
        type: 'divider',
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        type: 'itemGroup',
 | 
			
		||||
        title: t('Display association fields'),
 | 
			
		||||
        children: associatedFields,
 | 
			
		||||
      },
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
  fieldItems.push(
 | 
			
		||||
    {
 | 
			
		||||
      type: 'divider',
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      type: 'item',
 | 
			
		||||
      title: t('Action column'),
 | 
			
		||||
      component: 'AuditLogsTableActionColumnInitializer',
 | 
			
		||||
    },
 | 
			
		||||
  );
 | 
			
		||||
  return (
 | 
			
		||||
    <SchemaInitializer.Button
 | 
			
		||||
      insertPosition={'beforeEnd'}
 | 
			
		||||
      icon={'SettingOutlined'}
 | 
			
		||||
      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={itemsMerge(fieldItems, items)}
 | 
			
		||||
    >
 | 
			
		||||
      {t('Configure columns')}
 | 
			
		||||
    </SchemaInitializer.Button>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										3
									
								
								packages/plugins/audit-logs/src/client/locale/en-US.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								packages/plugins/audit-logs/src/client/locale/en-US.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,3 @@
 | 
			
		||||
export default {
 | 
			
		||||
  'Details of changes': 'Details of changes',
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										12
									
								
								packages/plugins/audit-logs/src/client/locale/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								packages/plugins/audit-logs/src/client/locale/index.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,12 @@
 | 
			
		||||
import { i18n } 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);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1
									
								
								packages/plugins/audit-logs/src/client/locale/ja-JP.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								packages/plugins/audit-logs/src/client/locale/ja-JP.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
export default {};
 | 
			
		||||
							
								
								
									
										1
									
								
								packages/plugins/audit-logs/src/client/locale/ru-RU.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								packages/plugins/audit-logs/src/client/locale/ru-RU.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
export default {};
 | 
			
		||||
							
								
								
									
										1
									
								
								packages/plugins/audit-logs/src/client/locale/tr-TR.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								packages/plugins/audit-logs/src/client/locale/tr-TR.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
export default {};
 | 
			
		||||
							
								
								
									
										3
									
								
								packages/plugins/audit-logs/src/client/locale/zh-CN.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								packages/plugins/audit-logs/src/client/locale/zh-CN.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,3 @@
 | 
			
		||||
export default {
 | 
			
		||||
  'Details of changes': '变更详情',
 | 
			
		||||
};
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user