Katherine 6fef3d7bed
feat: support variables on the left side of linkage rule conditions (#6609)
* feat: support linkage rules setting for association block action

* chore: linkage rule

* fix: bug

* fix: bug

* refactor: linkage rule

* refactor: code imporve

* fix: bug

* fix: bug

* fix: bug

* fix: bug

* refactor: code imporve

* fix: test

* fix: test

* fix: test

* test: e2e test

* fix: bug

* fix: bug

* fix: test

* fix: e2e test

* fix: bug

* chore: support legacy leftVar in linkage rules

* fix: bug

* fix: bug

* fix: bug

* fix: bug

* fix: bug

* fix: bug

* fix: bug

* fix: create submit linkage rule

* fix: action panel

* refactor: code improve

* fix: bug

* fix: test

* fix: test

* fix: code improve

* fix: e2e test

* fix: bug

* refactor: refresh & expend action support linkage rule

* refactor: code improve

* fix: test

* fix: bug

* fix: bug

* fix: e2e test

* fix: e2e test

* fix: e2e test

* fix: test

* refactor: code improve

* fix: e2e test

* fix: bug

* fix: e2e test

* fix: e2e test

* fix: test

* fix: e2e test

* fix: e2e test

* fix: bug
2025-04-16 15:52:51 +08:00

247 lines
6.1 KiB
TypeScript

/**
* This file is part of the NocoBase (R) project.
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
* Authors: NocoBase Team.
*
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
* For more information, please refer to: https://www.nocobase.com/agreement.
*/
import { useFieldSchema } from '@formily/react';
import {
ActionDesigner,
SchemaInitializerOpenModeSchemaItems,
SchemaSettings,
SchemaSettingsDivider,
SchemaSettingsRemove,
SchemaSettingsSelectItem,
useDesignable,
useOpenModeContext,
useSchemaToolbar,
SecondConFirm,
AfterSuccess,
RefreshDataBlockRequest,
SchemaSettingsLinkageRules,
useDataBlockProps,
} from '@nocobase/client';
import { ModalProps } from 'antd';
import React from 'react';
import { useTranslation } from 'react-i18next';
function UpdateMode() {
const { dn } = useDesignable();
const { t } = useTranslation();
const fieldSchema = useFieldSchema();
return (
<SchemaSettingsSelectItem
title={t('Data will be updated')}
options={[
{ label: t('Selected'), value: 'selected' },
{ label: t('Entire collection', { ns: 'action-bulk-edit' }), value: 'all' },
]}
value={fieldSchema?.['x-action-settings']?.['updateMode']}
onChange={(value) => {
fieldSchema['x-action-settings']['updateMode'] = value;
dn.emit('patch', {
schema: {
'x-uid': fieldSchema['x-uid'],
'x-action-settings': fieldSchema['x-action-settings'],
},
});
dn.refresh();
}}
/>
);
}
function RemoveButton(
props: {
onConfirmOk?: ModalProps['onOk'];
} = {},
) {
const { t } = useTranslation();
const fieldSchema = useFieldSchema();
const isDeletable = fieldSchema?.parent['x-component'] === 'CollectionField';
return (
!isDeletable && (
<>
<SchemaSettingsDivider />
<SchemaSettingsRemove
removeParentsIfNoChildren
breakRemoveOn={(s) => {
return s['x-component'] === 'Space' || s['x-component'].endsWith('ActionBar');
}}
confirm={{
title: t('Delete action'),
onOk: props.onConfirmOk,
}}
/>
</>
)
);
}
/**
* @deprecated
* 之所以还保留,仅是为了兼容旧版 schema
*/
export const deprecatedBulkEditActionSettings = new SchemaSettings({
name: 'ActionSettings:customize:bulkEdit',
items: [
{
name: 'editButton',
Component: ActionDesigner.ButtonEditor,
useComponentProps() {
const { buttonEditorProps } = useSchemaToolbar();
return buttonEditorProps;
},
},
{
name: 'linkageRules',
Component: SchemaSettingsLinkageRules,
useComponentProps() {
const { linkageRulesProps } = useSchemaToolbar();
return {
...linkageRulesProps,
};
},
},
{
name: 'openMode',
Component: SchemaInitializerOpenModeSchemaItems,
useComponentProps() {
const fieldSchema = useFieldSchema();
const isPopupAction = ['create', 'update', 'view', 'customize:popup', 'duplicate', 'customize:create'].includes(
fieldSchema['x-action'] || '',
);
return {
openMode: isPopupAction,
openSize: isPopupAction,
};
},
},
{
name: 'updateMode',
Component: UpdateMode,
},
{
name: 'remove',
sort: 100,
Component: RemoveButton as any,
useComponentProps() {
const { removeButtonProps } = useSchemaToolbar();
return removeButtonProps;
},
},
],
});
export const bulkEditActionSettings = new SchemaSettings({
name: 'actionSettings:bulkEdit',
items: [
{
name: 'editButton',
Component: ActionDesigner.ButtonEditor,
useComponentProps() {
const { buttonEditorProps } = useSchemaToolbar();
return buttonEditorProps;
},
},
{
name: 'linkageRules',
Component: SchemaSettingsLinkageRules,
useComponentProps() {
const { linkageRulesProps } = useSchemaToolbar();
return {
...linkageRulesProps,
};
},
},
{
name: 'openMode',
Component: SchemaInitializerOpenModeSchemaItems,
useComponentProps() {
const { hideOpenMode } = useOpenModeContext();
const fieldSchema = useFieldSchema();
const isPopupAction = ['create', 'update', 'view', 'customize:popup', 'duplicate', 'customize:create'].includes(
fieldSchema['x-action'] || '',
);
return {
openMode: isPopupAction && !hideOpenMode,
openSize: isPopupAction && !hideOpenMode,
};
},
},
{
name: 'updateMode',
Component: UpdateMode,
},
{
name: 'remove',
sort: 100,
Component: RemoveButton as any,
useComponentProps() {
const { removeButtonProps } = useSchemaToolbar();
return removeButtonProps;
},
},
],
});
/**
* 批量编辑表单的submit 按钮
*/
export const bulkEditFormSubmitActionSettings = new SchemaSettings({
name: 'actionSettings:bulkEditSubmit',
items: [
{
name: 'editButton',
Component: ActionDesigner.ButtonEditor,
useComponentProps() {
const { buttonEditorProps } = useSchemaToolbar();
return buttonEditorProps;
},
},
{
name: 'secondConfirmation',
Component: SecondConFirm,
},
{
name: 'afterSuccessfulSubmission',
Component: AfterSuccess,
},
{
name: 'linkageRules',
Component: SchemaSettingsLinkageRules,
useComponentProps() {
const { linkageRulesProps } = useSchemaToolbar();
return {
...linkageRulesProps,
};
},
},
{
name: 'refreshDataBlockRequest',
Component: RefreshDataBlockRequest,
useComponentProps() {
return {
isPopupAction: true,
};
},
},
{
name: 'remove',
sort: 100,
Component: RemoveButton as any,
useComponentProps() {
const { removeButtonProps } = useSchemaToolbar();
return removeButtonProps;
},
},
],
});