From 73c2efd4c10677bff8aba12597d818885f790a65 Mon Sep 17 00:00:00 2001 From: Katherine Date: Fri, 6 Dec 2024 18:23:37 +0800 Subject: [PATCH] feat: support configuring text, icon, and type for add and select buttons in sub-table (#5778) * feat: support configuring text, icon, and type for sub-table buttons * refactor: action style improve * fix: bug * fix: bug * fix: bug --- lerna.json | 4 +- .../antd/action/Action.Designer.tsx | 7 +- .../src/schema-component/antd/action/hooks.ts | 2 +- .../association-field/InternalSubTable.tsx | 9 ++ .../antd/association-field/SubTable.tsx | 112 +++++++++++------- .../antd/association-field/index.ts | 4 +- .../antd/association-field/schema.ts | 51 ++++++++ 7 files changed, 138 insertions(+), 51 deletions(-) diff --git a/lerna.json b/lerna.json index 8da11d6b4d..ed40e6af8d 100644 --- a/lerna.json +++ b/lerna.json @@ -2,9 +2,7 @@ "version": "1.5.0-beta.2", "npmClient": "yarn", "useWorkspaces": true, - "npmClientArgs": [ - "--ignore-engines" - ], + "npmClientArgs": ["--ignore-engines"], "command": { "version": { "forcePublish": true, diff --git a/packages/core/client/src/schema-component/antd/action/Action.Designer.tsx b/packages/core/client/src/schema-component/antd/action/Action.Designer.tsx index a92be9ecfc..af8f27f27b 100644 --- a/packages/core/client/src/schema-component/antd/action/Action.Designer.tsx +++ b/packages/core/client/src/schema-component/antd/action/Action.Designer.tsx @@ -69,7 +69,6 @@ export function ButtonEditor(props) { title: t('Button title'), default: fieldSchema.title, 'x-component-props': {}, - // description: `原字段标题:${collectionField?.uiSchema?.title}`, }, icon: { 'x-decorator': 'FormItem', @@ -78,7 +77,6 @@ export function ButtonEditor(props) { default: fieldSchema?.['x-component-props']?.icon, 'x-component-props': {}, 'x-visible': !isLink, - // description: `原字段标题:${collectionField?.uiSchema?.title}`, }, iconColor: { title: t('Color'), @@ -718,7 +716,7 @@ export const actionSettingsItems: SchemaSettingOptions['items'] = [ 'duplicate', 'customize:create', ].includes(fieldSchema['x-action'] || ''); - return !isPopupAction; + return !isPopupAction && !fieldSchema?.['x-action-settings'].disableSecondConFirm; }, }, { @@ -945,11 +943,12 @@ export const ActionDesigner = (props) => { buttonEditorProps, linkageRulesProps, schemaSettings = 'ActionSettings', + enableDrag = true, ...restProps } = props; const app = useApp(); const fieldSchema = useFieldSchema(); - const isDraggable = fieldSchema?.parent['x-component'] !== 'CollectionField'; + const isDraggable = fieldSchema?.parent['x-component'] !== 'CollectionField' && enableDrag; const settingsName = `ActionSettings:${fieldSchema['x-action']}`; const defaultActionSettings = schemaSettings || 'ActionSettings'; const hasAction = app.schemaSettingsManager.has(settingsName); diff --git a/packages/core/client/src/schema-component/antd/action/hooks.ts b/packages/core/client/src/schema-component/antd/action/hooks.ts index e337b38f20..dcbfea5f98 100644 --- a/packages/core/client/src/schema-component/antd/action/hooks.ts +++ b/packages/core/client/src/schema-component/antd/action/hooks.ts @@ -59,5 +59,5 @@ export const useLinkageAction = () => { const fieldSchema = useFieldSchema(); const isRecordAction = useIsDetailBlock(); const isAction = ['Action.Link', 'Action'].includes(fieldSchema['x-component']); - return isAction && isRecordAction; + return isAction && isRecordAction && fieldSchema['x-action']; }; diff --git a/packages/core/client/src/schema-component/antd/association-field/InternalSubTable.tsx b/packages/core/client/src/schema-component/antd/association-field/InternalSubTable.tsx index 9a0aa71830..98616dcbc3 100644 --- a/packages/core/client/src/schema-component/antd/association-field/InternalSubTable.tsx +++ b/packages/core/client/src/schema-component/antd/association-field/InternalSubTable.tsx @@ -24,6 +24,9 @@ export const InternalSubTable = observer( const fieldSchema = useFieldSchema(); const insert = useInsertSchema('SubTable'); const insertSelector = useInsertSchema('Selector'); + const insertSelect = useInsertSchema('SubTable.SelectAction'); + const insertAddNewAction = useInsertSchema('SubTable.AddNewAction'); + const { options } = useAssociationFieldContext(); const { actionName } = useACLActionParamsContext(); useEffect(() => { @@ -33,8 +36,14 @@ export const InternalSubTable = observer( useEffect(() => { if (field.componentProps?.allowSelectExistingRecord) { insertSelector(schema.Selector); + insertSelect(schema.SelectAction); } }, [field.componentProps?.allowSelectExistingRecord]); + useEffect(() => { + if (field.componentProps?.allowAddnew !== false) { + insertAddNewAction(schema.AddNewAction); + } + }, [field.componentProps?.allowAddnew]); const option = useSchemaOptionsContext(); const components = { ...option.components, diff --git a/packages/core/client/src/schema-component/antd/association-field/SubTable.tsx b/packages/core/client/src/schema-component/antd/association-field/SubTable.tsx index 2f2fa5f0c6..e5caebaf68 100644 --- a/packages/core/client/src/schema-component/antd/association-field/SubTable.tsx +++ b/packages/core/client/src/schema-component/antd/association-field/SubTable.tsx @@ -13,9 +13,9 @@ import { exchangeArrayState } from '@formily/core/esm/shared/internals'; import { observer, RecursionField, useFieldSchema } from '@formily/react'; import { action } from '@formily/reactive'; import { isArr } from '@formily/shared'; -import { Button } from 'antd'; import React, { useContext, useEffect, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; +import { Space } from 'antd'; import { FormProvider, RecordPickerContext, @@ -31,12 +31,13 @@ import { CollectionRecordProvider, useCollection, useCollectionRecord } from '.. import { markRecordAsNew } from '../../../data-source/collection-record/isNewRecord'; import { FlagProvider } from '../../../flag-provider'; import { useCompile } from '../../hooks'; -import { ActionContextProvider } from '../action'; +import { ActionContextProvider, ActionDesigner, Action } from '../action'; import { useSubTableSpecialCase } from '../form-item/hooks/useSpecialCase'; import { Table } from '../table-v2/Table'; import { SubFormProvider, useAssociationFieldContext, useFieldNames } from './hooks'; import { useTableSelectorProps } from './InternalPicker'; import { getLabelFormatValue, useLabelUiSchema } from './util'; +import { GeneralSchemaDesigner } from '../../../schema-settings'; const subTableContainer = css` .ant-table-footer { @@ -79,16 +80,27 @@ const tableClassName = css` `; const addNewButtonClassName = css` - display: block; - border-radius: 0px; - border-right: 1px solid rgba(0, 0, 0, 0.06); + .ant-btn { + // display: block; + // border-radius: 0px; + // border-right: 1px solid rgba(0, 0, 0, 0.06); + } `; const selectButtonClassName = css` - display: block; - border-radius: 0px; + .ant-btn { + // display: block; + // border-radius: 0px; + } `; +export const AddNewAction = (props) => { + return
{props.children}
; +}; +export const SelectAction = (props) => { + return
{props.children}
; +}; + export const SubTable: any = observer( (props: any) => { const { openSize } = props; @@ -195,6 +207,25 @@ export const SubTable: any = observer( hideOnSinglePage: false, }; }, [field.value?.length, pageSize, currentPage]); + + const useSubTableAddNewProps = () => { + const { field } = useAssociationFieldContext(); + return { + onClick() { + field.value = field.value || []; + field.value.push(markRecordAsNew({})); + // 计算总页数,并跳转到最后一页 + const totalPages = Math.ceil(field.value.length / (field.componentProps?.pageSize || 10)); + setTimeout(() => { + setCurrentPage(totalPages); + }); + return field.onInput(field.value); + }, + }; + }; + const handleSelect = () => { + setVisibleSelector(true); + }; return (
@@ -223,43 +254,40 @@ export const SubTable: any = observer( } pagination={paginationConfig} rowSelection={{ type: 'none', hideSelectAll: true }} - footer={() => - field.editable && ( - <> - {allowAddnew !== false && ( - - )} - {allowSelectExistingRecord && ( - - )} - - ) - } isSubTable={true} /> + {field.editable && ( + + + {allowAddnew !== false && ( + { + return s['x-component'] === 'AssociationField.SubTable.AddNewAction'; + }} + /> + )} + {allowSelectExistingRecord && ( + { + return s['x-component'] === 'AssociationField.SubTable.SelectAction'; + }} + /> + )} + + + )} diff --git a/packages/core/client/src/schema-component/antd/association-field/index.ts b/packages/core/client/src/schema-component/antd/association-field/index.ts index 61ba03f687..7efe5e47ba 100644 --- a/packages/core/client/src/schema-component/antd/association-field/index.ts +++ b/packages/core/client/src/schema-component/antd/association-field/index.ts @@ -14,7 +14,7 @@ import { FileSelector } from './FileManager'; import { InternalPicker } from './InternalPicker'; import { Nester } from './Nester'; import { ReadPretty } from './ReadPretty'; -import { SubTable } from './SubTable'; +import { SubTable, AddNewAction, SelectAction } from './SubTable'; export { AssociationFieldMode, @@ -32,5 +32,7 @@ AssociationField.Viewer = Action.Container; AssociationField.InternalSelect = InternalPicker; AssociationField.ReadPretty = ReadPretty; AssociationField.FileSelector = FileSelector; +AssociationField.SubTable.AddNewAction = AddNewAction; +AssociationField.SubTable.SelectAction = SelectAction; export { useAssociationFieldContext } from './hooks'; diff --git a/packages/core/client/src/schema-component/antd/association-field/schema.ts b/packages/core/client/src/schema-component/antd/association-field/schema.ts index 1e15444679..fd7e23ae2c 100644 --- a/packages/core/client/src/schema-component/antd/association-field/schema.ts +++ b/packages/core/client/src/schema-component/antd/association-field/schema.ts @@ -140,4 +140,55 @@ export default { }, properties: {}, }, + AddNewAction: { + type: 'void', + 'x-component': 'AssociationField.SubTable.AddNewAction', + properties: { + 'add-new': { + type: 'void', + title: '{{ t("Add new") }}', + 'x-component': 'Action', + 'x-designer': 'Action.Designer', + 'x-action': null, + 'x-designer-props': { + enableDrag: false, + }, + 'x-action-settings': { + removable: false, + disableSecondConFirm: true, + }, + 'x-use-component-props': 'useSubTableAddNewProps', + 'x-component-props': { + type: 'default', + onClick: '{{handleAddNew}}', + size: 'small', + }, + }, + }, + }, + SelectAction: { + type: 'void', + 'x-component': 'AssociationField.SubTable.SelectAction', + properties: { + select: { + type: 'void', + title: '{{ t("Select") }}', + 'x-component': 'Action', + 'x-action': null, + 'x-designer': 'Action.Designer', + 'x-designer-props': { + enableDrag: false, + }, + 'x-action-settings': { + removable: false, + disableSecondConFirm: true, + }, + 'x-component-props': { + type: 'default', + onClick: '{{handleSelect}}', + size: 'small', + }, + }, + }, + }, };