Merge branch 'next' into develop

This commit is contained in:
nocobase[bot] 2024-12-06 10:24:01 +00:00
commit 3c7138fff9
7 changed files with 138 additions and 51 deletions

View File

@ -2,9 +2,7 @@
"version": "1.6.0-alpha.2", "version": "1.6.0-alpha.2",
"npmClient": "yarn", "npmClient": "yarn",
"useWorkspaces": true, "useWorkspaces": true,
"npmClientArgs": [ "npmClientArgs": ["--ignore-engines"],
"--ignore-engines"
],
"command": { "command": {
"version": { "version": {
"forcePublish": true, "forcePublish": true,

View File

@ -69,7 +69,6 @@ export function ButtonEditor(props) {
title: t('Button title'), title: t('Button title'),
default: fieldSchema.title, default: fieldSchema.title,
'x-component-props': {}, 'x-component-props': {},
// description: `原字段标题:${collectionField?.uiSchema?.title}`,
}, },
icon: { icon: {
'x-decorator': 'FormItem', 'x-decorator': 'FormItem',
@ -78,7 +77,6 @@ export function ButtonEditor(props) {
default: fieldSchema?.['x-component-props']?.icon, default: fieldSchema?.['x-component-props']?.icon,
'x-component-props': {}, 'x-component-props': {},
'x-visible': !isLink, 'x-visible': !isLink,
// description: `原字段标题:${collectionField?.uiSchema?.title}`,
}, },
iconColor: { iconColor: {
title: t('Color'), title: t('Color'),
@ -730,7 +728,7 @@ export const actionSettingsItems: SchemaSettingOptions['items'] = [
'duplicate', 'duplicate',
'customize:create', 'customize:create',
].includes(fieldSchema['x-action'] || ''); ].includes(fieldSchema['x-action'] || '');
return !isPopupAction; return !isPopupAction && !fieldSchema?.['x-action-settings'].disableSecondConFirm;
}, },
}, },
{ {
@ -957,11 +955,12 @@ export const ActionDesigner = (props) => {
buttonEditorProps, buttonEditorProps,
linkageRulesProps, linkageRulesProps,
schemaSettings = 'ActionSettings', schemaSettings = 'ActionSettings',
enableDrag = true,
...restProps ...restProps
} = props; } = props;
const app = useApp(); const app = useApp();
const fieldSchema = useFieldSchema(); 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 settingsName = `ActionSettings:${fieldSchema['x-action']}`;
const defaultActionSettings = schemaSettings || 'ActionSettings'; const defaultActionSettings = schemaSettings || 'ActionSettings';
const hasAction = app.schemaSettingsManager.has(settingsName); const hasAction = app.schemaSettingsManager.has(settingsName);

View File

@ -63,5 +63,5 @@ export const useLinkageAction = () => {
const fieldSchema = useFieldSchema(); const fieldSchema = useFieldSchema();
const isRecordAction = useIsDetailBlock(); const isRecordAction = useIsDetailBlock();
const isAction = ['Action.Link', 'Action'].includes(fieldSchema['x-component']); const isAction = ['Action.Link', 'Action'].includes(fieldSchema['x-component']);
return isAction && isRecordAction; return isAction && isRecordAction && fieldSchema['x-action'];
}; };

View File

@ -25,6 +25,9 @@ export const InternalSubTable = observer(
const fieldSchema = useFieldSchema(); const fieldSchema = useFieldSchema();
const insert = useInsertSchema('SubTable'); const insert = useInsertSchema('SubTable');
const insertSelector = useInsertSchema('Selector'); const insertSelector = useInsertSchema('Selector');
const insertSelect = useInsertSchema('SubTable.SelectAction');
const insertAddNewAction = useInsertSchema('SubTable.AddNewAction');
const { options } = useAssociationFieldContext(); const { options } = useAssociationFieldContext();
const { actionName } = useACLActionParamsContext(); const { actionName } = useACLActionParamsContext();
useEffect(() => { useEffect(() => {
@ -34,8 +37,14 @@ export const InternalSubTable = observer(
useEffect(() => { useEffect(() => {
if (field.componentProps?.allowSelectExistingRecord) { if (field.componentProps?.allowSelectExistingRecord) {
insertSelector(schema.Selector); insertSelector(schema.Selector);
insertSelect(schema.SelectAction);
} }
}, [field.componentProps?.allowSelectExistingRecord]); }, [field.componentProps?.allowSelectExistingRecord]);
useEffect(() => {
if (field.componentProps?.allowAddnew !== false) {
insertAddNewAction(schema.AddNewAction);
}
}, [field.componentProps?.allowAddnew]);
const option = useSchemaOptionsContext(); const option = useSchemaOptionsContext();
const components = { const components = {
...option.components, ...option.components,

View File

@ -13,9 +13,9 @@ import { exchangeArrayState } from '@formily/core/esm/shared/internals';
import { observer, useFieldSchema } from '@formily/react'; import { observer, useFieldSchema } from '@formily/react';
import { action } from '@formily/reactive'; import { action } from '@formily/reactive';
import { isArr } from '@formily/shared'; import { isArr } from '@formily/shared';
import { Button } from 'antd';
import React, { useContext, useEffect, useMemo, useState } from 'react'; import React, { useContext, useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { Space } from 'antd';
import { import {
FormProvider, FormProvider,
RecordPickerContext, RecordPickerContext,
@ -32,12 +32,13 @@ import { markRecordAsNew } from '../../../data-source/collection-record/isNewRec
import { FlagProvider } from '../../../flag-provider'; import { FlagProvider } from '../../../flag-provider';
import { NocoBaseRecursionField } from '../../../formily/NocoBaseRecursionField'; import { NocoBaseRecursionField } from '../../../formily/NocoBaseRecursionField';
import { useCompile } from '../../hooks'; import { useCompile } from '../../hooks';
import { ActionContextProvider } from '../action'; import { ActionContextProvider, ActionDesigner, Action } from '../action';
import { useSubTableSpecialCase } from '../form-item/hooks/useSpecialCase'; import { useSubTableSpecialCase } from '../form-item/hooks/useSpecialCase';
import { SubFormProvider, useAssociationFieldContext, useFieldNames } from './hooks'; import { SubFormProvider, useAssociationFieldContext, useFieldNames } from './hooks';
import { useTableSelectorProps } from './InternalPicker'; import { useTableSelectorProps } from './InternalPicker';
import { Table } from './Table'; import { Table } from './Table';
import { getLabelFormatValue, useLabelUiSchema } from './util'; import { getLabelFormatValue, useLabelUiSchema } from './util';
import { GeneralSchemaDesigner } from '../../../schema-settings';
const subTableContainer = css` const subTableContainer = css`
.ant-table-footer { .ant-table-footer {
@ -80,16 +81,27 @@ const tableClassName = css`
`; `;
const addNewButtonClassName = css` const addNewButtonClassName = css`
display: block; .ant-btn {
border-radius: 0px; // display: block;
border-right: 1px solid rgba(0, 0, 0, 0.06); // border-radius: 0px;
// border-right: 1px solid rgba(0, 0, 0, 0.06);
}
`; `;
const selectButtonClassName = css` const selectButtonClassName = css`
display: block; .ant-btn {
border-radius: 0px; // display: block;
// border-radius: 0px;
}
`; `;
export const AddNewAction = (props) => {
return <div className={addNewButtonClassName}>{props.children}</div>;
};
export const SelectAction = (props) => {
return <div className={selectButtonClassName}>{props.children}</div>;
};
export const SubTable: any = observer( export const SubTable: any = observer(
(props: any) => { (props: any) => {
const { openSize } = props; const { openSize } = props;
@ -196,6 +208,25 @@ export const SubTable: any = observer(
hideOnSinglePage: false, hideOnSinglePage: false,
}; };
}, [field.value?.length, pageSize, currentPage]); }, [field.value?.length, pageSize, currentPage]);
const useSubTableAddNewProps = () => {
const { field } = useAssociationFieldContext<ArrayField>();
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 ( return (
<div className={subTableContainer}> <div className={subTableContainer}>
<FlagProvider isInSubTable> <FlagProvider isInSubTable>
@ -224,43 +255,40 @@ export const SubTable: any = observer(
} }
pagination={paginationConfig} pagination={paginationConfig}
rowSelection={{ type: 'none', hideSelectAll: true }} rowSelection={{ type: 'none', hideSelectAll: true }}
footer={() =>
field.editable && (
<>
{allowAddnew !== false && (
<Button
type={'text'}
block
className={addNewButtonClassName}
onClick={() => {
field.value = field.value || [];
field.value.push(markRecordAsNew({}));
// 计算总页数,并跳转到最后一页
const totalPages = Math.ceil(field.value.length / (field.componentProps?.pageSize || 10));
setCurrentPage(totalPages);
return field.onInput(field.value);
}}
>
{t('Add new')}
</Button>
)}
{allowSelectExistingRecord && (
<Button
type={'text'}
block
className={selectButtonClassName}
onClick={() => {
setVisibleSelector(true);
}}
>
{t('Select')}
</Button>
)}
</>
)
}
isSubTable={true} isSubTable={true}
/> />
{field.editable && (
<SchemaComponentOptions scope={{ useSubTableAddNewProps, handleSelect }}>
<Space
style={{
marginTop: '10px',
position: field.value?.length ? 'absolute' : 'relative',
bottom: '0',
}}
>
{allowAddnew !== false && (
<RecursionField
onlyRenderProperties
basePath={field.address}
schema={fieldSchema.parent}
filterProperties={(s) => {
return s['x-component'] === 'AssociationField.SubTable.AddNewAction';
}}
/>
)}
{allowSelectExistingRecord && (
<RecursionField
onlyRenderProperties
basePath={field.address}
schema={fieldSchema.parent}
filterProperties={(s) => {
return s['x-component'] === 'AssociationField.SubTable.SelectAction';
}}
/>
)}
</Space>
</SchemaComponentOptions>
)}
</SubFormProvider> </SubFormProvider>
</FormActiveFieldsProvider> </FormActiveFieldsProvider>
</CollectionRecordProvider> </CollectionRecordProvider>

View File

@ -14,7 +14,7 @@ import { FileSelector } from './FileManager';
import { InternalPicker } from './InternalPicker'; import { InternalPicker } from './InternalPicker';
import { Nester } from './Nester'; import { Nester } from './Nester';
import { ReadPretty } from './ReadPretty'; import { ReadPretty } from './ReadPretty';
import { SubTable } from './SubTable'; import { SubTable, AddNewAction, SelectAction } from './SubTable';
export { export {
AssociationFieldMode, AssociationFieldMode,
@ -32,5 +32,7 @@ AssociationField.Viewer = Action.Container;
AssociationField.InternalSelect = InternalPicker; AssociationField.InternalSelect = InternalPicker;
AssociationField.ReadPretty = ReadPretty; AssociationField.ReadPretty = ReadPretty;
AssociationField.FileSelector = FileSelector; AssociationField.FileSelector = FileSelector;
AssociationField.SubTable.AddNewAction = AddNewAction;
AssociationField.SubTable.SelectAction = SelectAction;
export { useAssociationFieldContext } from './hooks'; export { useAssociationFieldContext } from './hooks';

View File

@ -140,4 +140,55 @@ export default {
}, },
properties: {}, 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',
},
},
},
},
}; };