diff --git a/packages/core/client/src/modules/blocks/data-blocks/details-multi/detailsWithPaginationSettings.tsx b/packages/core/client/src/modules/blocks/data-blocks/details-multi/detailsWithPaginationSettings.tsx index 6fad304307..f310ec6154 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/details-multi/detailsWithPaginationSettings.tsx +++ b/packages/core/client/src/modules/blocks/data-blocks/details-multi/detailsWithPaginationSettings.tsx @@ -2,6 +2,7 @@ import { ArrayItems } from '@formily/antd-v5'; import { ISchema, useField, useFieldSchema } from '@formily/react'; import { useTranslation } from 'react-i18next'; import { SchemaSettings } from '../../../../application/schema-settings/SchemaSettings'; +import { SchemaSettingsItemType } from '../../../../application/schema-settings/types'; import { useFormBlockContext } from '../../../../block-provider'; import { useDetailsBlockContext } from '../../../../block-provider/DetailsBlockProvider'; import { useCollection_deprecated, useSortFields } from '../../../../collection-manager'; @@ -9,7 +10,6 @@ import { removeNullCondition, useDesignable } from '../../../../schema-component import { SchemaSettingsBlockTitleItem, SchemaSettingsTemplate } from '../../../../schema-settings'; import { SchemaSettingsDataScope } from '../../../../schema-settings/SchemaSettingsDataScope'; import { setDataLoadingModeSettingsItem } from './setDataLoadingModeSettingsItem'; -import { SchemaSettingsItemType } from '../../../../application/schema-settings/types'; const commonItems: SchemaSettingsItemType[] = [ { @@ -29,6 +29,7 @@ const commonItems: SchemaSettingsItemType[] = [ collectionName: name, defaultFilter: fieldSchema?.['x-decorator-props']?.params?.filter || {}, form, + noRecord: true, onSubmit: ({ filter }) => { filter = removeNullCondition(filter); const params = field.decoratorProps.params || {}; diff --git a/packages/core/client/src/modules/blocks/data-blocks/form/FormBlockInitializer.tsx b/packages/core/client/src/modules/blocks/data-blocks/form/FormBlockInitializer.tsx index f3f5caf866..0dd98c7328 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/form/FormBlockInitializer.tsx +++ b/packages/core/client/src/modules/blocks/data-blocks/form/FormBlockInitializer.tsx @@ -51,19 +51,23 @@ export const FormBlockInitializer = ({ }, [createBlockSchema, createFormBlock], ); + const doTemplateWrap = useCallback( + (templateSchema, options) => { + if (customizeTemplateWrap) { + return customizeTemplateWrap(templateSchema, options); + } + + return templateWrap(templateSchema, options); + }, + [customizeTemplateWrap, templateWrap], + ); return ( } componentType={componentType} - templateWrap={(templateSchema, options) => { - if (customizeTemplateWrap) { - return customizeTemplateWrap(templateSchema, options); - } - - return templateWrap(templateSchema, options); - }} + templateWrap={doTemplateWrap} onCreateBlockSchema={onCreateFormBlockSchema} filter={filterCollections} onlyCurrentDataSource={onlyCurrentDataSource} @@ -80,28 +84,34 @@ export const useCreateFormBlock = () => { const itemConfig = useSchemaInitializerItem(); const { isCusomeizeCreate: isCustomizeCreate } = itemConfig; - const createFormBlock = ({ item }) => { - insert( - createCreateFormBlockUISchema({ - collectionName: item.collectionName || item.name, - dataSource: item.dataSource, - isCusomeizeCreate: isCustomizeCreate, - }), - ); - }; + const createFormBlock = useCallback( + ({ item }) => { + insert( + createCreateFormBlockUISchema({ + collectionName: item.collectionName || item.name, + dataSource: item.dataSource, + isCusomeizeCreate: isCustomizeCreate, + }), + ); + }, + [insert, isCustomizeCreate], + ); - const templateWrap = (templateSchema, { item }) => { - const schema = createCreateFormBlockUISchema({ - isCusomeizeCreate: isCustomizeCreate, - dataSource: item.dataSource, - templateSchema: templateSchema, - collectionName: item.name, - }); - if (item.template && item.mode === 'reference') { - schema['x-template-key'] = item.template.key; - } - return schema; - }; + const templateWrap = useCallback( + (templateSchema, { item }) => { + const schema = createCreateFormBlockUISchema({ + isCusomeizeCreate: isCustomizeCreate, + dataSource: item.dataSource, + templateSchema: templateSchema, + collectionName: item.name, + }); + if (item.template && item.mode === 'reference') { + schema['x-template-key'] = item.template.key; + } + return schema; + }, + [isCustomizeCreate], + ); return { createFormBlock, diff --git a/packages/core/client/src/modules/blocks/data-blocks/form/createFormBlockSettings.tsx b/packages/core/client/src/modules/blocks/data-blocks/form/createFormBlockSettings.tsx index c93d350873..f06ec43b9f 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/form/createFormBlockSettings.tsx +++ b/packages/core/client/src/modules/blocks/data-blocks/form/createFormBlockSettings.tsx @@ -9,74 +9,6 @@ import { SchemaSettingsLinkageRules, } from '../../../../schema-settings'; -// TODO: 0.20 版之后可以删除 -export const creationFormBlockSettings = new SchemaSettings({ - name: 'blockSettings:creationForm', - items: [ - { - name: 'title', - Component: SchemaSettingsBlockTitleItem, - }, - { - name: 'linkageRules', - Component: SchemaSettingsLinkageRules, - useComponentProps() { - const { name } = useCollection_deprecated(); - return { - collectionName: name, - }; - }, - }, - { - name: 'dataTemplates', - Component: SchemaSettingsDataTemplates, - useVisible() { - const { action } = useFormBlockContext(); - return !action; - }, - useComponentProps() { - const { name } = useCollection_deprecated(); - return { - collectionName: name, - }; - }, - }, - { - name: 'divider', - type: 'divider', - }, - { - name: 'formItemTemplate', - Component: SchemaSettingsFormItemTemplate, - useComponentProps() { - const { name } = useCollection_deprecated(); - const fieldSchema = useFieldSchema(); - const defaultResource = - fieldSchema?.['x-decorator-props']?.resource || fieldSchema?.['x-decorator-props']?.association; - return { - componentName: 'FormItem', - collectionName: name, - resourceName: defaultResource, - }; - }, - }, - { - name: 'divider2', - type: 'divider', - }, - { - name: 'remove', - type: 'remove', - componentProps: { - removeParentsIfNoChildren: true, - breakRemoveOn: { - 'x-component': 'Grid', - }, - }, - }, - ], -}); - export const createFormBlockSettings = new SchemaSettings({ name: 'blockSettings:createForm', items: [ diff --git a/packages/core/client/src/modules/variable/__e2e__/basic.test.ts b/packages/core/client/src/modules/variable/__e2e__/basic.test.ts new file mode 100644 index 0000000000..eadfcbc29b --- /dev/null +++ b/packages/core/client/src/modules/variable/__e2e__/basic.test.ts @@ -0,0 +1,19 @@ +import { expect, test } from '@nocobase/test/e2e'; +import { tableViewLinkageRulesVariables } from './templates'; + +test.describe('variables', () => { + test('linkage rules of table view action', async ({ page, mockPage }) => { + await mockPage(tableViewLinkageRulesVariables).goto(); + + // 1. 打开联动规则设置弹窗,并显示变量列表 + await page.getByLabel('action-Action.Link-View-view-').hover(); + await page.getByLabel('designer-schema-settings-Action.Link-actionSettings:view-users').hover(); + await page.getByRole('menuitem', { name: 'Linkage rules' }).click(); + await page.getByLabel('variable-button').click(); + + // 2. 断言应该显示的变量 + ['Constant', 'Current user', 'Current role', 'Date variables', 'Current record'].forEach(async (name) => { + await expect(page.getByRole('menuitemcheckbox', { name })).toBeVisible(); + }); + }); +}); diff --git a/packages/core/client/src/modules/variable/__e2e__/templates.ts b/packages/core/client/src/modules/variable/__e2e__/templates.ts new file mode 100644 index 0000000000..d343828d3f --- /dev/null +++ b/packages/core/client/src/modules/variable/__e2e__/templates.ts @@ -0,0 +1,229 @@ +export const tableViewLinkageRulesVariables = { + pageSchema: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Page', + properties: { + g1wycipht9k: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid', + 'x-initializer': 'page:addBlock', + properties: { + '7i8pwd4xhj5': { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Row', + 'x-app-version': '0.21.0-alpha.8', + properties: { + pblvpmq357i: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Col', + 'x-app-version': '0.21.0-alpha.8', + properties: { + dwwc54m8ky1: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-decorator': 'TableBlockProvider', + 'x-acl-action': 'users:list', + 'x-use-decorator-props': 'useTableBlockDecoratorProps', + 'x-decorator-props': { + collection: 'users', + dataSource: 'main', + action: 'list', + params: { + pageSize: 20, + }, + rowKey: 'id', + showIndex: true, + dragSort: false, + }, + 'x-toolbar': 'BlockSchemaToolbar', + 'x-settings': 'blockSettings:table', + 'x-component': 'CardItem', + 'x-filter-targets': [], + 'x-app-version': '0.21.0-alpha.8', + properties: { + actions: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-initializer': 'table:configureActions', + 'x-component': 'ActionBar', + 'x-component-props': { + style: { + marginBottom: 'var(--nb-spacing)', + }, + }, + 'x-app-version': '0.21.0-alpha.8', + 'x-uid': 'dwfejl3y35l', + 'x-async': false, + 'x-index': 1, + }, + b0gp5kve5cy: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'array', + 'x-initializer': 'table:configureColumns', + 'x-component': 'TableV2', + 'x-use-component-props': 'useTableBlockProps', + 'x-component-props': { + rowKey: 'id', + rowSelection: { + type: 'checkbox', + }, + }, + 'x-app-version': '0.21.0-alpha.8', + properties: { + actions: { + _isJSONSchemaObject: true, + version: '2.0', + 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', + 'x-app-version': '0.21.0-alpha.8', + properties: { + tf980vw8dg7: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-decorator': 'DndContext', + 'x-component': 'Space', + 'x-component-props': { + split: '|', + }, + 'x-app-version': '0.21.0-alpha.8', + properties: { + dmpqsodnxr6: { + 'x-uid': 'vivhb5goy37', + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + title: '{{ t("View") }}', + 'x-action': 'view', + 'x-toolbar': 'ActionSchemaToolbar', + 'x-settings': 'actionSettings:view', + 'x-component': 'Action.Link', + 'x-component-props': { + openMode: 'drawer', + }, + 'x-decorator': 'ACLActionProvider', + 'x-designer-props': { + linkageAction: true, + }, + 'x-linkage-rules': [ + { + condition: { + $and: [{}], + }, + actions: [], + }, + ], + properties: { + drawer: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + title: '{{ t("View record") }}', + 'x-component': 'Action.Container', + 'x-component-props': { + className: 'nb-action-popup', + }, + properties: { + tabs: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Tabs', + 'x-component-props': {}, + 'x-initializer': 'popup:addTab', + properties: { + tab1: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + title: '{{t("Details")}}', + 'x-component': 'Tabs.TabPane', + 'x-designer': 'Tabs.Designer', + 'x-component-props': {}, + properties: { + grid: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid', + 'x-initializer': 'popup:common:addBlock', + 'x-uid': '8mxgjwcq1lu', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': '9fbdmfbk67y', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'dn6hvykic0s', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'czk4w54afwy', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': '3hbqk34vlxs', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'fptg47gw3v0', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'r6rocjxtxwr', + 'x-async': false, + 'x-index': 2, + }, + }, + 'x-uid': 'gy0al0nl08m', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': '2vkcx6nt5y0', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': '2zeeh485ev6', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'ckrzeha5h5t', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'qnwmpeqykgx', + 'x-async': true, + 'x-index': 1, + }, +}; diff --git a/packages/core/client/src/schema-component/antd/action/Action.tsx b/packages/core/client/src/schema-component/antd/action/Action.tsx index 1a728330a2..428cf1d23c 100644 --- a/packages/core/client/src/schema-component/antd/action/Action.tsx +++ b/packages/core/client/src/schema-component/antd/action/Action.tsx @@ -9,10 +9,16 @@ import { StablePopover, useActionContext } from '../..'; import { useDesignable } from '../../'; import { useACLActionParamsContext } from '../../../acl'; import { withDynamicSchemaProps } from '../../../application/hoc/withDynamicSchemaProps'; -import { useCollectionParentRecordData, useDataBlockRequest } from '../../../data-source'; +import { + useCollection, + useCollectionParentRecordData, + useCollectionRecordData, + useDataBlockRequest, +} from '../../../data-source'; import { Icon } from '../../../icon'; import { TreeRecordProvider } from '../../../modules/blocks/data-blocks/table/TreeRecordProvider'; -import { RecordProvider, useRecord } from '../../../record-provider'; +import { DeclareVariable } from '../../../modules/variable/DeclareVariable'; +import { RecordProvider } from '../../../record-provider'; import { useLocalVariables, useVariables } from '../../../variables'; import { SortableItem } from '../../common'; import { useCompile, useComponent, useDesigner } from '../../hooks'; @@ -63,8 +69,9 @@ export const Action: ComposedAction = withDynamicSchemaProps( const fieldSchema = useFieldSchema(); const compile = useCompile(); const form = useForm(); - const record = useRecord(); + const recordData = useCollectionRecordData(); const parentRecordData = useCollectionParentRecordData(); + const collection = useCollection(); const designerProps = fieldSchema['x-designer-props']; const openMode = fieldSchema?.['x-component-props']?.['openMode']; const openSize = fieldSchema?.['x-component-props']?.['openSize']; @@ -76,7 +83,7 @@ export const Action: ComposedAction = withDynamicSchemaProps( const tarComponent = useComponent(component) || component; const { modal } = App.useApp(); const variables = useVariables(); - const localVariables = useLocalVariables({ currentForm: { values: record } as any }); + const localVariables = useLocalVariables({ currentForm: { values: recordData } as any }); const { getAriaLabel } = useGetAriaLabelOfAction(title); const service = useDataBlockRequest(); @@ -196,7 +203,14 @@ export const Action: ComposedAction = withDynamicSchemaProps( > {popover && } {!popover && renderButton()} - {!popover && props.children} + + {!popover && props.children} + {element} ); @@ -206,7 +220,7 @@ export const Action: ComposedAction = withDynamicSchemaProps( return wrapSSR( // fix https://nocobase.height.app/T-3966 - {result} + {result} , ); } diff --git a/packages/core/client/src/schema-component/antd/grid-card/GridCard.Item.tsx b/packages/core/client/src/schema-component/antd/grid-card/GridCard.Item.tsx index a1bc407375..4e9ce7d2f5 100644 --- a/packages/core/client/src/schema-component/antd/grid-card/GridCard.Item.tsx +++ b/packages/core/client/src/schema-component/antd/grid-card/GridCard.Item.tsx @@ -3,11 +3,8 @@ import { ObjectField } from '@formily/core'; import { useField } from '@formily/react'; import { Card } from 'antd'; import React from 'react'; -import { useTranslation } from 'react-i18next'; import { withDynamicSchemaProps } from '../../../application/hoc/withDynamicSchemaProps'; import { useCollectionParentRecordData } from '../../../data-source/collection-record/CollectionRecordProvider'; -import { useCollection } from '../../../data-source/collection/CollectionProvider'; -import { DeclareVariable } from '../../../modules/variable/DeclareVariable'; import { RecordProvider } from '../../../record-provider'; const itemCss = css` @@ -32,22 +29,13 @@ const gridCardCss = css` export const GridCardItem = withDynamicSchemaProps( (props) => { - const { t } = useTranslation(); - const collection = useCollection(); const field = useField(); const parentRecordData = useCollectionParentRecordData(); return (
- - {props.children} - + {props.children}
diff --git a/packages/core/client/src/schema-component/antd/list/List.Item.tsx b/packages/core/client/src/schema-component/antd/list/List.Item.tsx index 22b496afdd..c82f85844d 100644 --- a/packages/core/client/src/schema-component/antd/list/List.Item.tsx +++ b/packages/core/client/src/schema-component/antd/list/List.Item.tsx @@ -5,16 +5,11 @@ import classnames from 'classnames'; import React from 'react'; import { useDesignable } from '../../hooks'; -import { useTranslation } from 'react-i18next'; import { withDynamicSchemaProps } from '../../../application/hoc/withDynamicSchemaProps'; import { useCollectionParentRecordData } from '../../../data-source/collection-record/CollectionRecordProvider'; -import { useCollection } from '../../../data-source/collection/CollectionProvider'; -import { DeclareVariable } from '../../../modules/variable/DeclareVariable'; import { RecordProvider } from '../../../record-provider'; export const ListItem = withDynamicSchemaProps((props) => { - const { t } = useTranslation(); - const collection = useCollection(); const field = useField(); const { designable } = useDesignable(); const parentRecordData = useCollectionParentRecordData(); @@ -31,14 +26,7 @@ export const ListItem = withDynamicSchemaProps((props) => { ])} > - - {props.children} - + {props.children} ); diff --git a/packages/core/client/src/schema-component/antd/table-v2/Table.tsx b/packages/core/client/src/schema-component/antd/table-v2/Table.tsx index 6c1665ed09..a444a39a79 100644 --- a/packages/core/client/src/schema-component/antd/table-v2/Table.tsx +++ b/packages/core/client/src/schema-component/antd/table-v2/Table.tsx @@ -28,7 +28,6 @@ import { import { useACLFieldWhitelist } from '../../../acl/ACLProvider'; import { withDynamicSchemaProps } from '../../../application/hoc/withDynamicSchemaProps'; import { isNewRecord } from '../../../data-source/collection-record/isNewRecord'; -import { DeclareVariable } from '../../../modules/variable/DeclareVariable'; import { useToken } from '../__builtins__'; import { SubFormProvider } from '../association-field/hooks'; import { ColumnFieldProvider } from './components/ColumnFieldProvider'; @@ -57,7 +56,6 @@ export const useColumnsDeepMemoized = (columns: any[]) => { }; const useTableColumns = (props: { showDel?: boolean; isSubTable?: boolean }) => { - const { t } = useTranslation(); const { token } = useToken(); const field = useArrayField(props); const schema = useFieldSchema(); @@ -108,24 +106,17 @@ const useTableColumns = (props: { showDel?: boolean; isSubTable?: boolean }) => const index = field.value?.indexOf(record); const basePath = field.address.concat(record.__index || index); return ( - - - - - - - - - - - - - + + + + + + + + + + + ); }, } as TableColumnProps; @@ -133,15 +124,7 @@ const useTableColumns = (props: { showDel?: boolean; isSubTable?: boolean }) => // 这里不能把 columnsSchema 作为依赖,因为其每次都会变化,这里使用 hasChangedColumns 作为依赖 // eslint-disable-next-line react-hooks/exhaustive-deps }), - [ - hasChangedColumns, - schema, - field, - parentRecordData, - schemaInWhitelist, - token.paddingContentVerticalLG, - token.marginSM, - ], + [columnsSchema, field.value, field.address, collection, parentRecordData, schemaToolbarBigger], ); const tableColumns = useMemo(() => { diff --git a/packages/core/client/src/schema-initializer/items/DataBlockInitializer.tsx b/packages/core/client/src/schema-initializer/items/DataBlockInitializer.tsx index 96e988cbb1..6f5db5cc25 100644 --- a/packages/core/client/src/schema-initializer/items/DataBlockInitializer.tsx +++ b/packages/core/client/src/schema-initializer/items/DataBlockInitializer.tsx @@ -280,14 +280,11 @@ export interface DataBlockInitializerProps { /** 如果只有一项数据表时,不显示 children 列表 */ hideChildrenIfSingleCollection?: boolean; items?: ReturnType[]; - /** - * 是否是点击弹窗中的 Others 选项进入的 - */ - fromOthersInPopup?: boolean; /** * 隐藏弹窗中的 Other records 选项 */ hideOtherRecordsInPopup?: boolean; + onClick?: (args: any) => void; } export const DataBlockInitializer = (props: DataBlockInitializerProps) => { @@ -305,14 +302,20 @@ export const DataBlockInitializer = (props: DataBlockInitializerProps) => { hideChildrenIfSingleCollection, filterDataSource, items: itemsFromProps, - fromOthersInPopup, hideOtherRecordsInPopup, + onClick: propsOnClick, } = props; const { insert, setVisible } = useSchemaInitializer(); const compile = useCompile(); const { getTemplateSchemaByMode } = useSchemaTemplateManager(); const onClick = useCallback( - async ({ item }) => { + async (options) => { + const { item, fromOthersInPopup } = options; + + if (propsOnClick) { + return propsOnClick(options); + } + if (item.template) { const s = await getTemplateSchemaByMode(item); templateWrap ? insert(templateWrap(s, { item, fromOthersInPopup })) : insert(s); @@ -323,7 +326,7 @@ export const DataBlockInitializer = (props: DataBlockInitializerProps) => { } setVisible(false); }, - [fromOthersInPopup, getTemplateSchemaByMode, insert, onCreateBlockSchema, setVisible, templateWrap], + [getTemplateSchemaByMode, insert, onCreateBlockSchema, propsOnClick, setVisible, templateWrap], ); const items = itemsFromProps || @@ -336,6 +339,7 @@ export const DataBlockInitializer = (props: DataBlockInitializerProps) => { showAssociationFields, dataBlockInitializerProps: props, hideOtherRecordsInPopup, + onClick, }); const getMenuItems = useGetSchemaInitializerMenuItems(onClick); const childItems = useMemo(() => { diff --git a/packages/core/client/src/schema-initializer/items/RecordAssociationFormBlockInitializer.tsx b/packages/core/client/src/schema-initializer/items/RecordAssociationFormBlockInitializer.tsx index a64df1e7fc..e435b883f1 100644 --- a/packages/core/client/src/schema-initializer/items/RecordAssociationFormBlockInitializer.tsx +++ b/packages/core/client/src/schema-initializer/items/RecordAssociationFormBlockInitializer.tsx @@ -79,10 +79,9 @@ export function useCreateAssociationFormBlock() { const templateWrap = useCallback( (templateSchema, { item }) => { - const field = item.associationField; - const collection = getCollection(field.target); - - if (item.template.componentName === 'FormItem') { + if (item.template.componentName === 'FormItem' && item.associationField) { + const field = item.associationField; + const collection = getCollection(field.target); const blockSchema = createCreateFormBlockUISchema({ dataSource: collection.dataSource, association: `${field.collectionName}.${field.name}`, diff --git a/packages/core/client/src/schema-initializer/utils.ts b/packages/core/client/src/schema-initializer/utils.ts index 34e6a713de..b276df65ca 100644 --- a/packages/core/client/src/schema-initializer/utils.ts +++ b/packages/core/client/src/schema-initializer/utils.ts @@ -13,13 +13,13 @@ import { useDataSourceKey, useFormBlockContext, } from '../'; +import { useFormActiveFields } from '../block-provider/hooks/useFormActiveFields'; import { FieldOptions, useCollectionManager_deprecated, useCollection_deprecated } from '../collection-manager'; import { Collection, CollectionFieldOptions } from '../data-source/collection/Collection'; import { useDataSourceManager } from '../data-source/data-source/DataSourceManagerProvider'; import { isAssocField } from '../filter-provider/utils'; import { useActionContext, useCompile, useDesignable } from '../schema-component'; import { useSchemaTemplateManager } from '../schema-templates'; -import { useFormActiveFields } from '../block-provider/hooks/useFormActiveFields'; export const itemsMerge = (items1) => { return items1; }; @@ -842,6 +842,7 @@ export const useCollectionDataSourceItems = ({ filterDataSource, dataBlockInitializerProps, hideOtherRecordsInPopup, + onClick, }: { componentName; filter?: (options: { collection?: Collection; associationField?: CollectionFieldOptions }) => boolean; @@ -853,6 +854,7 @@ export const useCollectionDataSourceItems = ({ * 隐藏弹窗中的 Other records 选项 */ hideOtherRecordsInPopup?: boolean; + onClick?: (options: any) => void; }) => { const { t } = useTranslation(); const dm = useDataSourceManager(); @@ -956,11 +958,13 @@ export const useCollectionDataSourceItems = ({ onlyCurrentDataSource: false, hideChildrenIfSingleCollection: false, onCreateBlockSchema: dataBlockInitializerProps.onCreateBlockSchema, - fromOthersInPopup: true, componentType: componentTypeMap[componentName] || componentName, filter({ collection: c, associationField }) { return true; }, + onClick(options) { + onClick({ ...options, fromOthersInPopup: true }); + }, }, }; @@ -1008,6 +1012,7 @@ export const useCollectionDataSourceItems = ({ dataBlockInitializerProps, hideOtherRecordsInPopup, noAssociationMenu, + onClick, t, ]); } @@ -1608,7 +1613,6 @@ function useAssociationFields({ }; }); }, [ - cm, collection.fields, compile, componentName, diff --git a/packages/core/client/src/schema-settings/SchemaSettings.tsx b/packages/core/client/src/schema-settings/SchemaSettings.tsx index 2016f8c947..f5429074d2 100644 --- a/packages/core/client/src/schema-settings/SchemaSettings.tsx +++ b/packages/core/client/src/schema-settings/SchemaSettings.tsx @@ -65,7 +65,6 @@ import { useGlobalTheme, useLinkageCollectionFilterOptions, useRecord, - useSchemaSettingsItem, useSortFields, } from '..'; import { @@ -947,6 +946,8 @@ export interface SchemaSettingsModalItemProps { asyncGetInitialValues?: () => Promise; eventKey?: string; hide?: boolean; + /** 上下文中不需要当前记录 */ + noRecord?: boolean; } export const SchemaSettingsModalItem: FC = (props) => { const { @@ -959,6 +960,7 @@ export const SchemaSettingsModalItem: FC = (props) asyncGetInitialValues, initialValues, width = 'fit-content', + noRecord = false, ...others } = props; const options = useContext(SchemaOptionsContext); @@ -1000,7 +1002,7 @@ export const SchemaSettingsModalItem: FC = (props) value={popupRecordVariable.value} collection={popupRecordVariable.collection} > - + = function DataScopeConfigure(props) { const { t } = useTranslation(); @@ -76,6 +76,7 @@ export const SchemaSettingsDataScope: FC = function DataScopeCon initialValues={{ filter: props.defaultFilter }} schema={getSchema as () => ISchema} onSubmit={props.onSubmit} + noRecord={props.noRecord} /> ); }; diff --git a/packages/core/client/src/schema-settings/SchemaSettingsPlugin.ts b/packages/core/client/src/schema-settings/SchemaSettingsPlugin.ts index 64335af437..46ddbd60c0 100644 --- a/packages/core/client/src/schema-settings/SchemaSettingsPlugin.ts +++ b/packages/core/client/src/schema-settings/SchemaSettingsPlugin.ts @@ -23,10 +23,7 @@ import { detailsBlockSettings, singleDataDetailsBlockSettings, } from '../modules/blocks/data-blocks/details-single/detailsBlockSettings'; -import { - createFormBlockSettings, - creationFormBlockSettings, -} from '../modules/blocks/data-blocks/form/createFormBlockSettings'; +import { createFormBlockSettings } from '../modules/blocks/data-blocks/form/createFormBlockSettings'; import { editFormBlockSettings } from '../modules/blocks/data-blocks/form/editFormBlockSettings'; import { fieldSettingsFormItem } from '../modules/blocks/data-blocks/form/fieldSettingsFormItem'; import { gridCardBlockSettings } from '../modules/blocks/data-blocks/grid-card/gridCardBlockSettings'; @@ -43,6 +40,7 @@ import { cascadeSelectComponentFieldSettings } from '../modules/fields/component import { datePickerComponentFieldSettings } from '../modules/fields/component/DatePicker/datePickerComponentFieldSettings'; import { fileManagerComponentFieldSettings } from '../modules/fields/component/FileManager/fileManagerComponentFieldSettings'; import { uploadAttachmentComponentFieldSettings } from '../modules/fields/component/FileManager/uploadAttachmentComponentFieldSettings'; +import { inputNumberComponentFieldSettings } from '../modules/fields/component/InputNumber/inputNumberComponentFieldSettings'; import { subformComponentFieldSettings } from '../modules/fields/component/Nester/subformComponentFieldSettings'; import { recordPickerComponentFieldSettings } from '../modules/fields/component/Picker/recordPickerComponentFieldSettings'; import { subformPopoverComponentFieldSettings } from '../modules/fields/component/PopoverNester/subformPopoverComponentFieldSettings'; @@ -50,13 +48,11 @@ import { selectComponentFieldSettings } from '../modules/fields/component/Select import { subTablePopoverComponentFieldSettings } from '../modules/fields/component/SubTable/subTablePopoverComponentFieldSettings'; import { tagComponentFieldSettings } from '../modules/fields/component/Tag/tagComponentFieldSettings'; import { unixTimestampComponentFieldSettings } from '../modules/fields/component/UnixTimestamp/unixTimestampComponentFieldSettings'; -import { inputNumberComponentFieldSettings } from '../modules/fields/component/InputNumber/inputNumberComponentFieldSettings'; export class SchemaSettingsPlugin extends Plugin { async load() { // block settings this.schemaSettingsManager.add(tableBlockSettings); - this.schemaSettingsManager.add(creationFormBlockSettings); this.schemaSettingsManager.add(createFormBlockSettings); this.schemaSettingsManager.add(editFormBlockSettings); this.schemaSettingsManager.add(filterFormBlockSettings); diff --git a/packages/core/client/src/schema-settings/VariableInput/hooks/useRecordVariable.ts b/packages/core/client/src/schema-settings/VariableInput/hooks/useRecordVariable.ts index 5078217f7f..4192cc62cd 100644 --- a/packages/core/client/src/schema-settings/VariableInput/hooks/useRecordVariable.ts +++ b/packages/core/client/src/schema-settings/VariableInput/hooks/useRecordVariable.ts @@ -1,9 +1,10 @@ import { Schema } from '@formily/json-schema'; import _ from 'lodash'; import { useTranslation } from 'react-i18next'; -import { CollectionFieldOptions_deprecated } from '../../../collection-manager'; -import { useBaseVariable } from './useBaseVariable'; import { useFormBlockContext } from '../../../block-provider/FormBlockProvider'; +import { CollectionFieldOptions_deprecated } from '../../../collection-manager'; +import { useCollection, useCollectionRecordData } from '../../../data-source'; +import { useBaseVariable } from './useBaseVariable'; interface Props { collectionField?: CollectionFieldOptions_deprecated; @@ -45,13 +46,16 @@ export const useRecordVariable = (props: Props) => { */ export const useCurrentRecordVariable = (props: Props = {}) => { const { t } = useTranslation(); + const collection = useCollection(); + const recordData = useCollectionRecordData(); const { formRecord, collectionName } = useFormBlockContext(); + const realCollectionName = formRecord?.data ? collectionName : collection?.name; const currentRecordSettings = useBaseVariable({ collectionField: props.collectionField, uiSchema: props.schema, name: '$nRecord', title: t('Current record'), - collectionName: collectionName, + collectionName: realCollectionName, noDisabled: props.noDisabled, targetFieldSchema: props.targetFieldSchema, }); @@ -60,10 +64,10 @@ export const useCurrentRecordVariable = (props: Props = {}) => { /** 变量配置 */ currentRecordSettings, /** 变量值 */ - currentRecordCtx: formRecord?.data, + currentRecordCtx: formRecord?.data || recordData, /** 用于判断是否需要显示配置项 */ - shouldDisplayCurrentRecord: !formRecord?.isNew && !_.isEmpty(formRecord?.data), + shouldDisplayCurrentRecord: !_.isEmpty(_.omit(recordData, ['__collectionName', '__parent'])) || !!formRecord?.data, /** 当前记录对应的 collection name */ - collectionName, + collectionName: realCollectionName, }; }; diff --git a/packages/core/client/src/schema-settings/types.ts b/packages/core/client/src/schema-settings/types.ts index 6a4857fe18..32a366352c 100644 --- a/packages/core/client/src/schema-settings/types.ts +++ b/packages/core/client/src/schema-settings/types.ts @@ -29,4 +29,6 @@ export interface DataScopeProps { * 当前表单区块中的表单实例 */ form: Form; + /** 上下文中不需要当前记录 */ + noRecord?: boolean; } diff --git a/packages/plugins/@nocobase/plugin-calendar/src/locale/index.ts b/packages/plugins/@nocobase/plugin-calendar/src/locale/index.ts index 863344e28b..42a6600b83 100644 --- a/packages/plugins/@nocobase/plugin-calendar/src/locale/index.ts +++ b/packages/plugins/@nocobase/plugin-calendar/src/locale/index.ts @@ -12,5 +12,7 @@ export function generateNTemplate(key: string) { } export function useTranslation() { - return useT(NAMESPACE); + return useT([NAMESPACE, 'client'], { + nsMode: 'fallback', + }); } diff --git a/packages/plugins/@nocobase/plugin-kanban/src/client/locale/index.ts b/packages/plugins/@nocobase/plugin-kanban/src/client/locale/index.ts index 016d63abe0..b3d73c6802 100644 --- a/packages/plugins/@nocobase/plugin-kanban/src/client/locale/index.ts +++ b/packages/plugins/@nocobase/plugin-kanban/src/client/locale/index.ts @@ -15,7 +15,7 @@ export function generateNTemplate(key: string) { } export function useKanbanTranslation() { - return useTranslation(NAMESPACE, { + return useTranslation([NAMESPACE, 'client'], { nsMode: 'fallback', }); } diff --git a/packages/plugins/@nocobase/plugin-map/src/client/locale/index.ts b/packages/plugins/@nocobase/plugin-map/src/client/locale/index.ts index 4021248411..08ab5a2ad0 100644 --- a/packages/plugins/@nocobase/plugin-map/src/client/locale/index.ts +++ b/packages/plugins/@nocobase/plugin-map/src/client/locale/index.ts @@ -15,7 +15,7 @@ export function generateNTemplate(key: string) { } export function useMapTranslation() { - return useTranslation(NAMESPACE, { + return useTranslation([NAMESPACE, 'client'], { nsMode: 'fallback', }); }