From 019a42b0ed518dd3a52adb0138fa1636fb6b60f7 Mon Sep 17 00:00:00 2001 From: wjh Date: Wed, 5 Jun 2024 14:39:54 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AD=90=E8=A1=A8=E6=A0=BC=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E5=BF=AB=E9=80=9F=E6=B7=BB=E5=8A=A0=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=20(#1122)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: sealday Reviewed-on: https://git.daoyoucloud.com/daoyoucloud/tachybase/pulls/1122 Reviewed-by: sealday Co-authored-by: wjh Co-committed-by: wjh --- packages/core/client/src/locale/en_US.json | 3 +- packages/core/client/src/locale/zh-CN.json | 3 +- .../subTablePopoverComponentFieldSettings.tsx | 186 +++++++++++- .../antd/association-field/SubTable.tsx | 23 +- .../SubTabs/InternamTabs.tsx | 265 ++++++++++++++++++ .../antd/association-field/SubTabs/hook.tsx | 58 ++++ .../antd/form-item/FormItem.Settings.tsx | 172 ++++++++++++ .../schema-component/antd/table-v2/Table.tsx | 3 +- 8 files changed, 703 insertions(+), 10 deletions(-) create mode 100644 packages/core/client/src/schema-component/antd/association-field/SubTabs/InternamTabs.tsx create mode 100644 packages/core/client/src/schema-component/antd/association-field/SubTabs/hook.tsx diff --git a/packages/core/client/src/locale/en_US.json b/packages/core/client/src/locale/en_US.json index feebd7327..cd7a9dfcd 100644 --- a/packages/core/client/src/locale/en_US.json +++ b/packages/core/client/src/locale/en_US.json @@ -830,5 +830,6 @@ "Designer properties": "Designer properties", "Load": "Load", "Dump": "Dump", - "Chang on Parent":"Chang on Parent" + "Chang on Parent":"Chang on Parent", + "Please enter search content":"Please enter search content" } diff --git a/packages/core/client/src/locale/zh-CN.json b/packages/core/client/src/locale/zh-CN.json index 978208a7b..e5e88f5fe 100644 --- a/packages/core/client/src/locale/zh-CN.json +++ b/packages/core/client/src/locale/zh-CN.json @@ -933,5 +933,6 @@ "Dump": "存储", "Sorry, the page you visited does not exist.": "对不起,您访问的页面不存在。", "Back Home": "回到主页", - "Chang on Parent": "选择父级" + "Chang on Parent": "选择父级", + "Please enter search content":"请输入查询内容" } diff --git a/packages/core/client/src/modules/fields/component/SubTable/subTablePopoverComponentFieldSettings.tsx b/packages/core/client/src/modules/fields/component/SubTable/subTablePopoverComponentFieldSettings.tsx index 4a83540cc..edf1e5330 100644 --- a/packages/core/client/src/modules/fields/component/SubTable/subTablePopoverComponentFieldSettings.tsx +++ b/packages/core/client/src/modules/fields/component/SubTable/subTablePopoverComponentFieldSettings.tsx @@ -1,3 +1,4 @@ +import { useCollectionManager } from '@tachybase/client'; import { ArrayItems } from '@tachybase/components'; import { Field, ISchema, useField, useFieldSchema } from '@tachybase/schema'; @@ -6,7 +7,7 @@ import { useTranslation } from 'react-i18next'; import { SchemaSettings } from '../../../../application/schema-settings/SchemaSettings'; import { useCollectionManager_deprecated, useSortFields } from '../../../../collection-manager'; import { useFieldComponentName } from '../../../../common/useFieldComponentName'; -import { useDesignable, useFieldModeOptions, useIsAddNewForm } from '../../../../schema-component'; +import { useCompile, useDesignable, useFieldModeOptions, useIsAddNewForm } from '../../../../schema-component'; import { isSubMode } from '../../../../schema-component/antd/association-field/util'; import { useIsAssociationField, useIsFieldReadPretty } from '../../../../schema-component/antd/form-item'; @@ -242,7 +243,188 @@ export const allowAddNewData = { }, }; +export const isQuickAddTabs = { + name: 'isquickaddtabs', + type: 'switch', + useVisible() { + const readPretty = useIsFieldReadPretty(); + const isAssociationField = useIsAssociationField(); + return !readPretty && isAssociationField; + }, + + useComponentProps() { + const { t } = useTranslation(); + const field = useField(); + const fieldSchema = useFieldSchema(); + const { dn, refresh } = useDesignable(); + return { + title: t('Is Quick Add Tabs'), + checked: fieldSchema['x-component-props']?.isQuickAdd || false, + onChange(value) { + const schema = { + ['x-uid']: fieldSchema['x-uid'], + }; + field.componentProps['isQuickAdd'] = value; + fieldSchema['x-component-props'] = fieldSchema['x-component-props'] || {}; + fieldSchema['x-component-props']['isQuickAdd'] = value; + schema['x-component-props'] = fieldSchema['x-component-props']; + dn.emit('patch', { + schema, + }); + refresh(); + }, + }; + }, +}; + +export const setQuickAddTabs = { + name: 'setquickaddtabs', + type: 'select', + useComponentProps() { + const { t } = useTranslation(); + const field = useField(); + const compile = useCompile(); + const fieldSchema = useFieldSchema(); + const cm = useCollectionManager(); + const options = cm.getCollection(fieldSchema['x-collection-field']); + const defVal = fieldSchema['x-component-props']['quickAddField'] || 'none'; + const { dn } = useDesignable(); + const isAddNewForm = useIsAddNewForm(); + const fieldTabsOptions = options.fields + .map((item) => { + if (item.interface === 'm2o' || item.interface === 'select') { + return { + ...item, + label: compile(item.uiSchema?.title), + value: item.name, + }; + } + }) + .filter(Boolean); + fieldTabsOptions.unshift({ + label: 'none', + value: 'none', + }); + return { + title: t('Set Quick Add Tabs'), + options: fieldTabsOptions, + value: defVal, + onChange(mode) { + const schema = { + ['x-uid']: fieldSchema['x-uid'], + }; + fieldSchema['x-component-props'] = fieldSchema['x-component-props'] || {}; + fieldSchema['x-component-props']['quickAddField'] = { + fieldInterface: fieldTabsOptions.find((item) => item.value === mode)['interface'] || 'none', + value: mode, + }; + schema['x-component-props'] = fieldSchema['x-component-props']; + field.componentProps = field.componentProps || {}; + field.componentProps['quickAddField'] = fieldSchema['x-component-props']['quickAddField']; + + // 子表单状态不允许设置默认值 + if (isSubMode(fieldSchema) && isAddNewForm) { + // @ts-ignore + schema.default = null; + fieldSchema.default = null; + field.setInitialValue(null); + field.setValue(null); + } + + void dn.emit('patch', { + schema, + }); + dn.refresh(); + }, + }; + }, + useVisible() { + const fieldSchema = useFieldSchema(); + return fieldSchema['x-component-props']['isQuickAdd']; + }, +}; + +export const setQuickAddParentTabs = { + name: 'setquickaddparenttabs', + type: 'select', + useComponentProps() { + const { t } = useTranslation(); + const field = useField(); + const compile = useCompile(); + const fieldSchema = useFieldSchema(); + const cm = useCollectionManager(); + const { value: quickField } = fieldSchema['x-component-props']?.['quickAddField'] || {}; + const options = cm.getCollectionFields(`${fieldSchema['x-collection-field']}.${quickField}`); + const { dn } = useDesignable(); + const isAddNewForm = useIsAddNewForm(); + const fieldTabsOptions = options + .map((item) => { + if (item.interface === 'm2o') + return { + ...item, + label: compile(item.uiSchema.title), + value: item.name, + }; + }) + .filter(Boolean); + fieldTabsOptions.unshift({ + label: t('none'), + value: 'none', + }); + const defValue = fieldSchema['x-component-props']?.['quickAddParentCollection']?.value || 'none'; + return { + title: t('Set Quick Add Parent Tabs'), + options: fieldTabsOptions, + value: defValue, + onChange(mode) { + const schema = { + ['x-uid']: fieldSchema['x-uid'], + }; + fieldSchema['x-component-props'] = fieldSchema['x-component-props'] || {}; + fieldSchema['x-component-props']['quickAddParentCollection'] = { + collectionField: `${fieldSchema['x-collection-field']}.${quickField}.${mode}`, + value: mode, + }; + schema['x-component-props'] = fieldSchema['x-component-props']; + field.componentProps = field.componentProps || {}; + field.componentProps['quickAddParentCollection'] = { + collectionField: `${fieldSchema['x-collection-field']}.${quickField}.${mode}`, + value: mode, + }; + // 子表单状态不允许设置默认值 + if (isSubMode(fieldSchema) && isAddNewForm) { + // @ts-ignore + schema.default = null; + fieldSchema.default = null; + field.setInitialValue(null); + field.setValue(null); + } + void dn.emit('patch', { + schema, + }); + dn.refresh(); + }, + }; + }, + useVisible() { + const fieldSchema = useFieldSchema(); + return ( + fieldSchema['x-component-props']['isQuickAdd'] && + fieldSchema['x-component-props']['quickAddField'] && + fieldSchema['x-component-props']['quickAddField'] !== 'none' + ); + }, +}; + export const subTablePopoverComponentFieldSettings = new SchemaSettings({ name: 'fieldSettings:component:SubTable', - items: [fieldComponent, allowAddNewData, allowSelectExistingRecord, setDefaultSortingRules], + items: [ + fieldComponent, + allowAddNewData, + allowSelectExistingRecord, + setDefaultSortingRules, + isQuickAddTabs, + setQuickAddTabs, + setQuickAddParentTabs, + ], }); 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 baa629542..46b54c5c3 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 @@ -1,4 +1,4 @@ -import React, { useContext, useMemo, useState } from 'react'; +import React, { useContext, useEffect, useMemo, useState } from 'react'; import { action, ArrayField, @@ -7,11 +7,13 @@ import { observer, RecursionField, useFieldSchema, + useForm, } from '@tachybase/schema'; -import { Button } from 'antd'; +import { useAsyncEffect } from 'ahooks'; +import { Button, Tabs } from 'antd'; import { createStyles } from 'antd-style'; -import { unionBy, uniqBy } from 'lodash'; +import { set, unionBy, uniqBy } from 'lodash'; import { useTranslation } from 'react-i18next'; import { @@ -21,11 +23,12 @@ import { SchemaComponentOptions, useActionContext, } from '../..'; +import { useAPIClient, useRequest } from '../../../api-client'; import { useCreateActionProps } from '../../../block-provider/hooks'; import { FormActiveFieldsProvider } from '../../../block-provider/hooks/useFormActiveFields'; import { TableSelectorParamsProvider } from '../../../block-provider/TableSelectorProvider'; import { CollectionProvider_deprecated } from '../../../collection-manager'; -import { CollectionRecordProvider, useCollectionRecord } from '../../../data-source'; +import { CollectionRecordProvider, useCollectionManager, useCollectionRecord } from '../../../data-source'; import { markRecordAsNew } from '../../../data-source/collection-record/isNewRecord'; import { FlagProvider } from '../../../flag-provider'; import { useCompile } from '../../hooks'; @@ -33,6 +36,7 @@ import { ActionContextProvider } from '../action'; import { Table } from '../table-v2/Table'; import { useAssociationFieldContext, useFieldNames } from './hooks'; import { useTableSelectorProps } from './InternalPicker'; +import { InternalTabs } from './SubTabs/InternamTabs'; import { getLabelFormatValue, useLabelUiSchema } from './util'; const useStyles = createStyles(({ css }) => { @@ -106,7 +110,7 @@ export const SubTable: any = observer( const compile = useCompile(); const labelUiSchema = useLabelUiSchema(collectionField, fieldNames?.label || 'label'); const recordV2 = useCollectionRecord(); - + const [fieldValue, setFieldValue] = useState([]); const move = (fromIndex: number, toIndex: number) => { if (toIndex === undefined) return; if (!isArr(field.value)) return; @@ -122,6 +126,7 @@ export const SubTable: any = observer( return field.onInput(field.value); }); }; + field.move = move; const options = useMemo(() => { @@ -172,11 +177,17 @@ export const SubTable: any = observer( const filter = list.length ? { $and: [{ [`${targetKey}.$ne`]: list }] } : {}; return filter; }; + const tabsProps = { + ...props, + fieldValue, + setFieldValue, + }; return (
+ @@ -198,6 +210,7 @@ export const SubTable: any = observer( onClick={() => { field.value = field.value || []; field.value.push(markRecordAsNew({})); + setFieldValue([...field.value]); }} > {t('Add new')} diff --git a/packages/core/client/src/schema-component/antd/association-field/SubTabs/InternamTabs.tsx b/packages/core/client/src/schema-component/antd/association-field/SubTabs/InternamTabs.tsx new file mode 100644 index 000000000..9f4e85b7b --- /dev/null +++ b/packages/core/client/src/schema-component/antd/association-field/SubTabs/InternamTabs.tsx @@ -0,0 +1,265 @@ +import React, { useEffect, useState } from 'react'; +import { ArrayField, observer, onFieldChange, Schema, useFieldSchema, useFormEffects } from '@tachybase/schema'; + +import { CheckOutlined, CheckSquareOutlined, SearchOutlined } from '@ant-design/icons'; +import { useAsyncEffect, useDeepCompareEffect } from 'ahooks'; +import { Badge, Button, Input, Space, Tabs } from 'antd'; +import flat from 'flat'; +import { useTranslation } from 'react-i18next'; + +import { useAPIClient } from '../../../../api-client'; +import { useCollectionManager } from '../../../../data-source'; +import { markRecordAsNew } from '../../../../data-source/collection-record/isNewRecord'; +import { useAssociationFieldContext } from '../hooks'; +import { useFieldServiceFilter } from './hook'; + +export const InternalTabs = observer((props) => { + const { fieldValue, setFieldValue } = props as any; + const fieldSchema = useFieldSchema(); + const cm = useCollectionManager(); + const api = useAPIClient(); + const isQuickAdd = fieldSchema['parent']['x-component-props']['isQuickAdd']; + const { value: quickAddField, fieldInterface } = fieldSchema['parent']['x-component-props']?.['quickAddField'] || {}; + const quickAddParentField = fieldSchema['parent']['x-component-props']['quickAddParentCollection']; + const [options, setOptions] = useState([]); + const [defOptions, setDefOptions] = useState([]); + const { field, options: collectionField } = useAssociationFieldContext(); + const { t } = useTranslation(); + const [changeForm, setChangeForm] = useState(); + + const tableSchema = fieldSchema.reduceProperties((buf, schema) => { + const found = schema.reduceProperties( + (buf, schema) => { + if (schema.name === quickAddField) { + return schema; + } + return buf; + }, + new Schema({ name: 'not-found' }), + ); + if (found.name === quickAddField) { + return found; + } + return buf; + }, new Schema({})); + const tabparams = tableSchema['x-component-props']?.['service']?.['params']; + const [fieldServiceFilter, setFieldServiceFilter] = useFieldServiceFilter(tabparams?.filter); + const formFilter = flat(tabparams?.filter || {}); + const formFieldFilter = Object.values(formFilter) + ?.map((item) => { + const field = item as String; + const match = field.match(/^{{\$nForm\.(.*?)\./); + if (match) return match[1]; + }) + .filter(Boolean); + useAsyncEffect(async () => { + const itemParams = {}; + const optionsItem = []; + if (tabparams?.filter && !fieldServiceFilter) return; + if ((quickAddField || quickAddField !== 'none' || !isQuickAdd) && fieldSchema.properties) { + const params = { pageSize: 99999, filter: JSON.stringify(fieldServiceFilter) }; + if (quickAddParentField && quickAddParentField?.value !== 'none') { + params['appends'] = [quickAddParentField.value]; + const collection = cm.getCollection(quickAddParentField.collectionField); + const parentItem = await api.request({ + url: collection.name + ':list', + params: { pageSize: 9999 }, + }); + itemParams['parentTitleField'] = collection.titleField; + itemParams['parentOptions'] = parentItem?.data?.data; + } + + if (tableSchema && fieldInterface === 'm2o') { + itemParams['service'] = tableSchema['x-component-props'].service; + itemParams['collectionName'] = cm.getCollection(tableSchema['x-collection-field']).name; + const childrenItem = await api.request({ + url: itemParams['collectionName'] + ':list', + params, + }); + itemParams['childrenTitleField'] = cm.getCollection(itemParams['collectionName']).titleField; + itemParams['childrenOptions'] = childrenItem?.data?.data; + + if (itemParams['parentOptions']?.length && itemParams['childrenOptions']?.length) { + itemParams['parentOptions'].forEach((parentItem) => { + const items = itemParams['childrenOptions'] + .map((item) => { + if (item[quickAddParentField?.value]?.id === parentItem.id) { + return { + ...item, + label: item[itemParams['childrenTitleField']], + keys: item.id, + value: item.id, + checked: false, + }; + } + }) + .filter(Boolean); + if (!items.length) return; + optionsItem.push({ + ...parentItem, + value: parentItem?.id, + label: parentItem[itemParams['parentTitleField']], + key: parentItem.id, + childrenItems: items, + }); + }); + } else if ( + itemParams['childrenOptions']?.length && + (!quickAddParentField || quickAddParentField?.value === 'none') + ) { + itemParams['childrenOptions'].forEach((item) => { + optionsItem.push({ + ...item, + label: item[itemParams['childrenTitleField']], + value: item?.id, + key: item?.id, + checked: false, + }); + }); + } + setOptions(optionsItem); + setDefOptions(optionsItem); + } else if (tableSchema) { + const fieldItem = cm.getCollectionField(tableSchema['x-collection-field']); + if (!fieldItem?.uiSchema || !fieldItem?.uiSchema.enum) return; + fieldItem.uiSchema.enum.forEach((item) => { + optionsItem.push(item); + }); + setOptions(optionsItem); + setDefOptions(optionsItem); + } + } + }, [fieldServiceFilter, fieldSchema, changeForm]); + + useDeepCompareEffect(() => { + if (!defOptions.length) return; + const fieldTabs = field.value; + if (quickAddParentField && quickAddParentField?.value !== 'none') { + const filterParantOptions = tabsParantFilterOptions(defOptions, fieldTabs, quickAddField); + const filterOptions = tabsParantFilterOptions(options, fieldTabs, quickAddField); + setDefOptions(filterParantOptions); + setOptions(filterOptions); + } else { + const filterDefOptions = tabsFilterOptions(options, fieldTabs, quickAddField); + setDefOptions(filterDefOptions); + const filterOptions = tabsFilterOptions(options, fieldTabs, quickAddField); + setOptions(filterOptions); + } + }, [quickAddField, fieldValue]); + + useFormEffects(() => { + onFieldChange(formFieldFilter, (field) => { + setChangeForm(field); + }); + }); + const onSelect = (value) => { + if (quickAddParentField && quickAddParentField.value !== 'none') { + const filterOption = defOptions + .map((item) => { + const filterItem = item?.childrenItems?.filter((childrenItem) => childrenItem?.label?.includes(value)); + if (item?.label?.includes(value) || filterItem.length) { + return { + ...item, + childrenItems: filterItem.length ? filterItem : item.childrenItems, + }; + } + }) + .filter(Boolean); + setOptions(filterOption); + } else { + const filterOption = defOptions.filter((item) => item?.label?.includes(value)); + setOptions(filterOption); + } + }; + + const onChange = (item) => { + field.value = field.value || []; + const addItem = {}; + addItem[quickAddField] = item; + field.value.push(markRecordAsNew(addItem)); + setFieldValue([...field.value]); + }; + + return isQuickAdd && quickAddField && quickAddField !== 'none' ? ( +
+ } + onChange={(e) => { + onSelect(e.target.value); + }} + /> + + {quickAddParentField && quickAddParentField?.value !== 'none' ? ( + <> + {options.length ? ( + ({ + ...item, + children: ( + + {item?.childrenItems?.map((childrenitem, index) => ( + + ))} + + ), + }))} + style={{ height: '30vh', overflow: 'auto', padding: '10px' }} + > + ) : null} + + ) : ( + + {options.map((item, index) => ( + + ))} + + )} +
+ ) : null; +}); + +const tabsParantFilterOptions = (options, fieldTabs, arrayField) => { + const filterOptions = options?.map((oItem) => { + const filterItem = oItem.childrenItems.map((childrenItem) => { + const fieldTabsValue = fieldTabs.find((item) => item[arrayField]?.value === childrenItem.value); + return { + ...childrenItem, + checked: fieldTabsValue ? true : false, + }; + }); + return { + ...oItem, + childrenItems: filterItem, + }; + }); + return filterOptions; +}; + +const tabsFilterOptions = (optitons, filterTabs, arrayField) => { + const filterOptions = optitons.map((item) => { + const filterValue = filterTabs.find((filterTabsItem) => filterTabsItem[arrayField]?.value === item.value); + return { + ...item, + checked: filterValue ? true : false, + }; + }); + return filterOptions; +}; diff --git a/packages/core/client/src/schema-component/antd/association-field/SubTabs/hook.tsx b/packages/core/client/src/schema-component/antd/association-field/SubTabs/hook.tsx new file mode 100644 index 000000000..715fcf275 --- /dev/null +++ b/packages/core/client/src/schema-component/antd/association-field/SubTabs/hook.tsx @@ -0,0 +1,58 @@ +import { useEffect, useState } from 'react'; +import { DEBOUNCE_WAIT, isVariable, mergeFilter, useParseDataScopeFilter } from '@tachybase/client'; +import { reaction } from '@tachybase/schema'; +import { flatten, getValuesByPath } from '@tachybase/utils/client'; + +import _ from 'lodash'; + +import { getPath } from '../../../../variables/utils/getPath'; +import { getVariableName } from '../../../../variables/utils/getVariableName'; + +export const useFieldServiceFilter = (filter, originalFilter?) => { + const [fieldServiceFilter, setFieldServiceFilter] = useState(null); + const { parseFilter, findVariable } = useParseDataScopeFilter(); + + useEffect(() => { + const filterFromSchema = filter; + + const _run = async () => { + const result = await parseFilter(mergeFilter([filterFromSchema || originalFilter])); + setFieldServiceFilter(result); + }; + const run = _.debounce(_run, DEBOUNCE_WAIT); + + _run(); + + const dispose = reaction(() => { + // 这一步主要是为了使 reaction 能够收集到依赖 + const flat = flatten(filterFromSchema, { + breakOn({ key }) { + return key.startsWith('$') && key !== '$and' && key !== '$or'; + }, + transformValue(value) { + if (!isVariable(value)) { + return value; + } + const variableName = getVariableName(value); + const variable = findVariable(variableName); + + if (process.env.NODE_ENV !== 'production' && !variable) { + throw new Error(`useServiceOptions: can not find variable ${variableName}`); + } + + const result = getValuesByPath( + { + [variableName]: variable?.ctx || {}, + }, + getPath(value), + ); + return result; + }, + }); + return flat; + }, run); + + return dispose; + }, [filter, findVariable, originalFilter, parseFilter]); + return [fieldServiceFilter, setFieldServiceFilter]; +}; diff --git a/packages/core/client/src/schema-component/antd/form-item/FormItem.Settings.tsx b/packages/core/client/src/schema-component/antd/form-item/FormItem.Settings.tsx index d2a5bd79a..6f4fcb2bb 100644 --- a/packages/core/client/src/schema-component/antd/form-item/FormItem.Settings.tsx +++ b/packages/core/client/src/schema-component/antd/form-item/FormItem.Settings.tsx @@ -13,6 +13,7 @@ import { useCollectionField_deprecated, useCollectionManager_deprecated, } from '../../../collection-manager'; +import { useCollection, useCollectionManager } from '../../../data-source'; import { useRecord } from '../../../record-provider'; import { useColumnSchema } from '../../../schema-component/antd/table-v2/Table.Column.Decorator'; import { generalSettingsItems } from '../../../schema-items/GeneralSettings'; @@ -305,6 +306,177 @@ export const formItemSettings = new SchemaSettings({ return form && !isFormReadPretty && validateSchema; }, }, + { + name: 'isquickaddtabs', + type: 'switch', + useVisible() { + const readPretty = useIsFieldReadPretty(); + const isAssociationField = useIsAssociationField(); + const fieldMode = useFieldMode(); + return !readPretty && isAssociationField && ['SubTable'].includes(fieldMode); + }, + + useComponentProps() { + const { t } = useTranslation(); + const field = useField(); + const fieldSchema = useFieldSchema(); + const { dn, refresh } = useDesignable(); + return { + title: t('Is Quick Add Tabs'), + checked: fieldSchema['x-component-props']?.isQuickAdd || false, + onChange(value) { + const schema = { + ['x-uid']: fieldSchema['x-uid'], + }; + field.componentProps['isQuickAdd'] = value; + fieldSchema['x-component-props'] = fieldSchema['x-component-props'] || {}; + fieldSchema['x-component-props']['isQuickAdd'] = value; + schema['x-component-props'] = fieldSchema['x-component-props']; + dn.emit('patch', { + schema, + }); + refresh(); + }, + }; + }, + }, + { + name: 'setquickaddtabs', + type: 'select', + useComponentProps() { + const { t } = useTranslation(); + const field = useField(); + const compile = useCompile(); + const fieldSchema = useFieldSchema(); + const cm = useCollectionManager(); + const options = cm.getCollection(fieldSchema['x-collection-field']); + const defVal = fieldSchema['x-component-props']['quickAddField'] || 'none'; + const { dn } = useDesignable(); + const isAddNewForm = useIsAddNewForm(); + const fieldTabsOptions = options.fields + .map((item) => { + if (item.interface === 'm2o' || item.interface === 'select') { + return { + ...item, + label: compile(item.uiSchema?.title), + value: item.name, + }; + } + }) + .filter(Boolean); + fieldTabsOptions.unshift({ + label: 'none', + value: 'none', + }); + return { + title: t('Set Quick Add Tabs'), + options: fieldTabsOptions, + value: defVal, + onChange(mode) { + const schema = { + ['x-uid']: fieldSchema['x-uid'], + }; + fieldSchema['x-component-props'] = fieldSchema['x-component-props'] || {}; + fieldSchema['x-component-props']['quickAddField'] = { + fieldInterface: fieldTabsOptions.find((item) => item.value === mode)['interface'] || 'none', + value: mode, + }; + schema['x-component-props'] = fieldSchema['x-component-props']; + field.componentProps = field.componentProps || {}; + field.componentProps['quickAddField'] = fieldSchema['x-component-props']['quickAddField']; + + // 子表单状态不允许设置默认值 + if (isSubMode(fieldSchema) && isAddNewForm) { + // @ts-ignore + schema.default = null; + fieldSchema.default = null; + field.setInitialValue(null); + field.setValue(null); + } + + void dn.emit('patch', { + schema, + }); + dn.refresh(); + }, + }; + }, + useVisible() { + const fieldSchema = useFieldSchema(); + return fieldSchema['x-component-props']['isQuickAdd']; + }, + }, + { + name: 'setquickaddparenttabs', + type: 'select', + useComponentProps() { + const { t } = useTranslation(); + const field = useField(); + const compile = useCompile(); + const fieldSchema = useFieldSchema(); + const cm = useCollectionManager(); + const { value: quickField } = fieldSchema['x-component-props']?.['quickAddField'] || {}; + const options = cm.getCollectionFields(`${fieldSchema['x-collection-field']}.${quickField}`); + const { dn } = useDesignable(); + const isAddNewForm = useIsAddNewForm(); + const fieldTabsOptions = options + .map((item) => { + if (item.interface === 'm2o') + return { + ...item, + label: compile(item.uiSchema.title), + value: item.name, + }; + }) + .filter(Boolean); + fieldTabsOptions.unshift({ + label: t('none'), + value: 'none', + }); + const defValue = fieldSchema['x-component-props']?.['quickAddParentCollection']?.value || 'none'; + return { + title: t('Set Quick Add Parent Tabs'), + options: fieldTabsOptions, + value: defValue, + onChange(mode) { + const schema = { + ['x-uid']: fieldSchema['x-uid'], + }; + fieldSchema['x-component-props'] = fieldSchema['x-component-props'] || {}; + fieldSchema['x-component-props']['quickAddParentCollection'] = { + collectionField: `${fieldSchema['x-collection-field']}.${quickField}.${mode}`, + value: mode, + }; + schema['x-component-props'] = fieldSchema['x-component-props']; + field.componentProps = field.componentProps || {}; + field.componentProps['quickAddParentCollection'] = { + collectionField: `${fieldSchema['x-collection-field']}.${quickField}.${mode}`, + value: mode, + }; + // 子表单状态不允许设置默认值 + if (isSubMode(fieldSchema) && isAddNewForm) { + // @ts-ignore + schema.default = null; + fieldSchema.default = null; + field.setInitialValue(null); + field.setValue(null); + } + void dn.emit('patch', { + schema, + }); + dn.refresh(); + }, + }; + }, + useVisible() { + const fieldSchema = useFieldSchema(); + return ( + fieldSchema['x-component-props']['isQuickAdd'] && + fieldSchema['x-component-props']['quickAddField'] && + fieldSchema['x-component-props']['quickAddField'] !== 'none' + ); + }, + }, { name: 'defaultValue', Component: SchemaSettingsDefaultValue, 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 2e19418db..b7bc0930b 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 @@ -46,7 +46,7 @@ const useArrayField = (props) => { return (props.field || field) as ArrayField; }; -const useTableColumns = (props: { showDel?: boolean; isSubTable?: boolean }) => { +const useTableColumns = (props: { showDel?: boolean; isSubTable?: boolean; setFieldValue?: any }) => { const { t } = useTranslation(); const { styles } = useStyles(); const field = useArrayField(props); @@ -162,6 +162,7 @@ const useTableColumns = (props: { showDel?: boolean; isSubTable?: boolean }) => }); field.value.splice(index, 1); field.initialValue?.splice(index, 1); + props.setFieldValue([...field.value]); return field.onInput(field.value); }); }}