From 1d02eb1e8b59a5d8e51753f3adc8cc88d270ff28 Mon Sep 17 00:00:00 2001 From: Jian Lu Date: Mon, 20 Jan 2025 22:22:24 +0800 Subject: [PATCH] feat: adjust dir and support event array --- .../ActionsSetting/Action.tsx | 79 +++++ .../ActionsSetting/Actions.tsx | 54 ++++ .../DynamicComponent.tsx | 0 .../LinkageRuleAction.tsx | 0 .../ValueDynamicComponent.tsx | 0 .../Variables.tsx | 0 .../action-hooks.ts | 0 .../bindLinkageRulesToFiled.ts | 0 .../components/EnableLinkage.tsx | 0 .../components/LinkageHeader.style.ts | 0 .../components/LinkageHeader.tsx | 281 ++++++++++++++++++ .../compute-rules.ts | 0 .../context.ts | 0 .../forEachLinkageRule.ts | 0 .../index.tsx | 41 ++- .../{LinkageRules => ActionsSetting}/type.ts | 0 .../useActionValues.ts | 0 .../useValues.ts | 0 .../{ => EventsSetting}/EventSelect.tsx | 21 +- .../components/EnableLinkage.tsx | 44 +++ .../components/LinkageHeader.style.ts | 12 + .../components/LinkageHeader.tsx | 42 +-- .../EventSettingItem/EventsSetting/index.tsx | 139 +++++++++ .../{filter => Filter2}/DynamicComponent.tsx | 0 .../Filter.Action.Designer.tsx | 0 .../{filter => Filter2}/Filter.tsx | 1 - .../{filter => Filter2}/FilterAction.tsx | 0 .../{filter => Filter2}/FilterGroup.tsx | 0 .../{filter => Filter2}/FilterItem.tsx | 0 .../{filter => Filter2}/FilterItems.tsx | 0 .../{filter => Filter2}/SaveDefaultValue.tsx | 0 .../{filter => Filter2}/context.ts | 0 .../{filter => Filter2}/index.en-US.md | 0 .../{filter => Filter2}/index.md | 0 .../{filter => Filter2}/index.ts | 0 .../useFilterActionProps.ts | 0 .../{filter => Filter2}/useOperators.ts | 0 .../{filter => Filter2}/useValues.ts | 0 .../LinkageRules/LinkageRuleActionGroup.tsx | 84 ------ .../EventSettingItem/{ => _}/ActionsInput.tsx | 2 +- .../{ => _}/ConditionInput.tsx | 0 .../EventSettingItem/{ => _}/EventSetting.tsx | 37 ++- .../src/event-flow/EventSettingItem/index.tsx | 46 ++- .../schema-settings/LinkageRules/index.tsx | 1 + 44 files changed, 728 insertions(+), 156 deletions(-) create mode 100644 packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/Action.tsx create mode 100644 packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/Actions.tsx rename packages/core/client/src/event-flow/EventSettingItem/{LinkageRules => ActionsSetting}/DynamicComponent.tsx (100%) rename packages/core/client/src/event-flow/EventSettingItem/{LinkageRules => ActionsSetting}/LinkageRuleAction.tsx (100%) rename packages/core/client/src/event-flow/EventSettingItem/{LinkageRules => ActionsSetting}/ValueDynamicComponent.tsx (100%) rename packages/core/client/src/event-flow/EventSettingItem/{LinkageRules => ActionsSetting}/Variables.tsx (100%) rename packages/core/client/src/event-flow/EventSettingItem/{LinkageRules => ActionsSetting}/action-hooks.ts (100%) rename packages/core/client/src/event-flow/EventSettingItem/{LinkageRules => ActionsSetting}/bindLinkageRulesToFiled.ts (100%) rename packages/core/client/src/event-flow/EventSettingItem/{LinkageRules => ActionsSetting}/components/EnableLinkage.tsx (100%) rename packages/core/client/src/event-flow/EventSettingItem/{LinkageRules => ActionsSetting}/components/LinkageHeader.style.ts (100%) create mode 100644 packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/components/LinkageHeader.tsx rename packages/core/client/src/event-flow/EventSettingItem/{LinkageRules => ActionsSetting}/compute-rules.ts (100%) rename packages/core/client/src/event-flow/EventSettingItem/{LinkageRules => ActionsSetting}/context.ts (100%) rename packages/core/client/src/event-flow/EventSettingItem/{LinkageRules => ActionsSetting}/forEachLinkageRule.ts (100%) rename packages/core/client/src/event-flow/EventSettingItem/{LinkageRules => ActionsSetting}/index.tsx (86%) rename packages/core/client/src/event-flow/EventSettingItem/{LinkageRules => ActionsSetting}/type.ts (100%) rename packages/core/client/src/event-flow/EventSettingItem/{LinkageRules => ActionsSetting}/useActionValues.ts (100%) rename packages/core/client/src/event-flow/EventSettingItem/{LinkageRules => ActionsSetting}/useValues.ts (100%) rename packages/core/client/src/event-flow/EventSettingItem/{ => EventsSetting}/EventSelect.tsx (63%) create mode 100644 packages/core/client/src/event-flow/EventSettingItem/EventsSetting/components/EnableLinkage.tsx create mode 100644 packages/core/client/src/event-flow/EventSettingItem/EventsSetting/components/LinkageHeader.style.ts rename packages/core/client/src/event-flow/EventSettingItem/{LinkageRules => EventsSetting}/components/LinkageHeader.tsx (92%) create mode 100644 packages/core/client/src/event-flow/EventSettingItem/EventsSetting/index.tsx rename packages/core/client/src/event-flow/EventSettingItem/{filter => Filter2}/DynamicComponent.tsx (100%) rename packages/core/client/src/event-flow/EventSettingItem/{filter => Filter2}/Filter.Action.Designer.tsx (100%) rename packages/core/client/src/event-flow/EventSettingItem/{filter => Filter2}/Filter.tsx (99%) rename packages/core/client/src/event-flow/EventSettingItem/{filter => Filter2}/FilterAction.tsx (100%) rename packages/core/client/src/event-flow/EventSettingItem/{filter => Filter2}/FilterGroup.tsx (100%) rename packages/core/client/src/event-flow/EventSettingItem/{filter => Filter2}/FilterItem.tsx (100%) rename packages/core/client/src/event-flow/EventSettingItem/{filter => Filter2}/FilterItems.tsx (100%) rename packages/core/client/src/event-flow/EventSettingItem/{filter => Filter2}/SaveDefaultValue.tsx (100%) rename packages/core/client/src/event-flow/EventSettingItem/{filter => Filter2}/context.ts (100%) rename packages/core/client/src/event-flow/EventSettingItem/{filter => Filter2}/index.en-US.md (100%) rename packages/core/client/src/event-flow/EventSettingItem/{filter => Filter2}/index.md (100%) rename packages/core/client/src/event-flow/EventSettingItem/{filter => Filter2}/index.ts (100%) rename packages/core/client/src/event-flow/EventSettingItem/{filter => Filter2}/useFilterActionProps.ts (100%) rename packages/core/client/src/event-flow/EventSettingItem/{filter => Filter2}/useOperators.ts (100%) rename packages/core/client/src/event-flow/EventSettingItem/{filter => Filter2}/useValues.ts (100%) delete mode 100644 packages/core/client/src/event-flow/EventSettingItem/LinkageRules/LinkageRuleActionGroup.tsx rename packages/core/client/src/event-flow/EventSettingItem/{ => _}/ActionsInput.tsx (97%) rename packages/core/client/src/event-flow/EventSettingItem/{ => _}/ConditionInput.tsx (100%) rename packages/core/client/src/event-flow/EventSettingItem/{ => _}/EventSetting.tsx (76%) diff --git a/packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/Action.tsx b/packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/Action.tsx new file mode 100644 index 0000000000..818a330dc4 --- /dev/null +++ b/packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/Action.tsx @@ -0,0 +1,79 @@ +/** + * 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 { ArrayField as ArrayFieldModel, VoidField } from '@formily/core'; +import { ArrayField, ObjectField, observer, useField } from '@formily/react'; +import { Space, TreeSelect } from 'antd'; +import React, { useCallback, useMemo } from 'react'; +import { useTranslation } from 'react-i18next'; +import { withDynamicSchemaProps } from '../../../hoc/withDynamicSchemaProps'; +import { + FormButtonLinkageRuleAction, + FormFieldLinkageRuleAction, + FormStyleLinkageRuleAction, +} from './LinkageRuleAction'; +import { RemoveActionContext } from './context'; +import { useControllableValue } from 'ahooks'; + +const ActionSelect = (props) => { + const { t } = useTranslation(); + const { definitions, className } = props; + const [state, setState] = useControllableValue(props, { + defaultValue: undefined, + }); + let treeData = definitions?.map((module) => ({ + value: module.name, + title: module.title + ' - ' + module.uid, + selectable: false, + children: + module?.events?.map((event) => ({ + value: module.name + '.' + event.name, + title: event.title, + })) || [], + })); + treeData = treeData?.filter((item) => item.children.length > 0); + + return ( + { + setState(value); + }} + treeData={treeData} + className={className} + /> + ); +}; + +export const Action = observer( + (props: any): any => { + const { linkageOptions, category, elementType } = props; + const field = useField(); + const type = category === 'default' ? elementType : category; + const componentMap: { + [key: string]: any; + } = { + button: FormButtonLinkageRuleAction, + field: FormFieldLinkageRuleAction, + style: FormStyleLinkageRuleAction, + }; + return field?.value?.map((item, index) => { + return ( + field.remove(index)}> + + + ); + }); + }, + { displayName: 'LinkageRuleActions' }, +); diff --git a/packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/Actions.tsx b/packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/Actions.tsx new file mode 100644 index 0000000000..ebe25d1607 --- /dev/null +++ b/packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/Actions.tsx @@ -0,0 +1,54 @@ +/** + * 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 { ArrayField as ArrayFieldModel, VoidField } from '@formily/core'; +import { ArrayField, ObjectField, observer, useField } from '@formily/react'; +import { Space } from 'antd'; +import React, { useCallback, useMemo } from 'react'; +import { useTranslation } from 'react-i18next'; +import { withDynamicSchemaProps } from '../../../hoc/withDynamicSchemaProps'; +import { Action } from './Action'; + +interface LinkageRuleActionGroupProps { + type: 'button' | 'field' | 'style'; + linkageOptions: any; + collectionName: string; +} + +export const Actions = withDynamicSchemaProps( + (props: LinkageRuleActionGroupProps) => { + const { t } = useTranslation(); + const field = useField(); + const { category, elementType, linkageOptions, collectionName } = props; + + const components = useMemo( + () => [Action, { category, elementType, linkageOptions, collectionName }], + [collectionName, linkageOptions, category, elementType], + ); + const spaceStyle = useMemo(() => ({ marginTop: 8, marginBottom: 8 }), []); + const style = useMemo(() => ({ marginLeft: 10 }), []); + const onClick = useCallback(() => { + const f = field.query('.actions').take() as ArrayFieldModel; + const items = f.value || []; + items.push({}); + f.value = items; + f.initialValue = items; + }, [field]); + + return ( + + ); + }, + { displayName: 'Actions' }, +); diff --git a/packages/core/client/src/event-flow/EventSettingItem/LinkageRules/DynamicComponent.tsx b/packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/DynamicComponent.tsx similarity index 100% rename from packages/core/client/src/event-flow/EventSettingItem/LinkageRules/DynamicComponent.tsx rename to packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/DynamicComponent.tsx diff --git a/packages/core/client/src/event-flow/EventSettingItem/LinkageRules/LinkageRuleAction.tsx b/packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/LinkageRuleAction.tsx similarity index 100% rename from packages/core/client/src/event-flow/EventSettingItem/LinkageRules/LinkageRuleAction.tsx rename to packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/LinkageRuleAction.tsx diff --git a/packages/core/client/src/event-flow/EventSettingItem/LinkageRules/ValueDynamicComponent.tsx b/packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/ValueDynamicComponent.tsx similarity index 100% rename from packages/core/client/src/event-flow/EventSettingItem/LinkageRules/ValueDynamicComponent.tsx rename to packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/ValueDynamicComponent.tsx diff --git a/packages/core/client/src/event-flow/EventSettingItem/LinkageRules/Variables.tsx b/packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/Variables.tsx similarity index 100% rename from packages/core/client/src/event-flow/EventSettingItem/LinkageRules/Variables.tsx rename to packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/Variables.tsx diff --git a/packages/core/client/src/event-flow/EventSettingItem/LinkageRules/action-hooks.ts b/packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/action-hooks.ts similarity index 100% rename from packages/core/client/src/event-flow/EventSettingItem/LinkageRules/action-hooks.ts rename to packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/action-hooks.ts diff --git a/packages/core/client/src/event-flow/EventSettingItem/LinkageRules/bindLinkageRulesToFiled.ts b/packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/bindLinkageRulesToFiled.ts similarity index 100% rename from packages/core/client/src/event-flow/EventSettingItem/LinkageRules/bindLinkageRulesToFiled.ts rename to packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/bindLinkageRulesToFiled.ts diff --git a/packages/core/client/src/event-flow/EventSettingItem/LinkageRules/components/EnableLinkage.tsx b/packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/components/EnableLinkage.tsx similarity index 100% rename from packages/core/client/src/event-flow/EventSettingItem/LinkageRules/components/EnableLinkage.tsx rename to packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/components/EnableLinkage.tsx diff --git a/packages/core/client/src/event-flow/EventSettingItem/LinkageRules/components/LinkageHeader.style.ts b/packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/components/LinkageHeader.style.ts similarity index 100% rename from packages/core/client/src/event-flow/EventSettingItem/LinkageRules/components/LinkageHeader.style.ts rename to packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/components/LinkageHeader.style.ts diff --git a/packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/components/LinkageHeader.tsx b/packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/components/LinkageHeader.tsx new file mode 100644 index 0000000000..ea576a4118 --- /dev/null +++ b/packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/components/LinkageHeader.tsx @@ -0,0 +1,281 @@ +/** + * 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 { CopyOutlined } from '@ant-design/icons'; +import { ArrayBase } from '@formily/antd-v5'; +import { ArrayField } from '@formily/core'; +import { ISchema, RecursionField, observer, useField, useFieldSchema } from '@formily/react'; +import { toArr } from '@formily/shared'; +import { Badge, Card, Collapse, CollapsePanelProps, CollapseProps, Empty, Input } from 'antd'; +import { cloneDeep } from 'lodash'; +import React, { Fragment, useEffect, useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import { useToken } from '../../../../style'; +import { arrayCollapseItemStyle } from './LinkageHeader.style'; + +const LinkageRulesTitle = (props) => { + const array = ArrayBase.useArray(); + const index = ArrayBase.useIndex(props.index); + const { t } = useTranslation(); + const value = array?.field?.value[index]; + return
动作 {index + 1}
; + // return ( + // { + // ev.stopPropagation(); + // array.field.value.splice(index, 1, { ...value, title: ev.target.value }); + // }} + // onBlur={(ev) => { + // ev.stopPropagation(); + // array.field.value.splice(index, 1, { ...value, title: ev.target.value }); + // }} + // autoSize + // style={{ width: '70%', border: 'none' }} + // onClick={(e) => { + // e.stopPropagation(); + // }} + // /> + // ); +}; + +export interface IArrayCollapseProps extends CollapseProps { + defaultOpenPanelCount?: number; +} +type ComposedArrayCollapse = React.FC> & { + CollapsePanel?: React.FC>; +}; + +const isAdditionComponent = (schema: ISchema) => { + return schema['x-component']?.indexOf?.('Addition') > -1; +}; + +const isIndexComponent = (schema: ISchema) => { + return schema['x-component']?.indexOf?.('Index') > -1; +}; + +const isRemoveComponent = (schema: ISchema) => { + return schema['x-component']?.indexOf?.('Remove') > -1; +}; + +const isMoveUpComponent = (schema: ISchema) => { + return schema['x-component']?.indexOf?.('MoveUp') > -1; +}; + +const isMoveDownComponent = (schema: ISchema) => { + return schema['x-component']?.indexOf?.('MoveDown') > -1; +}; +const isCopyComponent = (schema: ISchema) => { + return schema['x-component']?.indexOf?.('Copy') > -1; +}; +const isOperationComponent = (schema: ISchema) => { + return ( + isAdditionComponent(schema) || + isRemoveComponent(schema) || + isMoveDownComponent(schema) || + isMoveUpComponent(schema) || + isCopyComponent(schema) + ); +}; + +const range = (count: number) => Array.from({ length: count }).map((_, i) => i); + +const takeDefaultActiveKeys = (dataSourceLength: number, defaultOpenPanelCount: number) => { + if (dataSourceLength < defaultOpenPanelCount) return range(dataSourceLength); + return range(defaultOpenPanelCount); +}; + +const insertActiveKeys = (activeKeys: number[], index: number) => { + if (activeKeys.length <= index) return activeKeys.concat(index); + return activeKeys.reduce((buf, key) => { + if (key < index) return buf.concat(key); + if (key === index) return buf.concat([key, key + 1]); + return buf.concat(key + 1); + }, []); +}; + +export const ArrayCollapse: ComposedArrayCollapse = observer( + (props: IArrayCollapseProps) => { + const field = useField(); + const dataSource = Array.isArray(field.value) ? field.value : []; + const [activeKeys, setActiveKeys] = useState( + takeDefaultActiveKeys(dataSource.length, props.defaultOpenPanelCount), + ); + const schema = useFieldSchema(); + useEffect(() => { + if (!field.modified && dataSource.length) { + setActiveKeys(takeDefaultActiveKeys(dataSource.length, props.defaultOpenPanelCount)); + } + }, [dataSource.length, field]); + if (!schema) throw new Error('can not found schema object'); + + const renderAddition = () => { + return schema.reduceProperties((addition, schema, key) => { + if (isAdditionComponent(schema)) { + return ; + } + return addition; + }, null); + }; + const renderEmpty = () => { + if (dataSource.length) return; + return ( + + + + ); + }; + + const renderItems = () => { + if (!dataSource || dataSource.length === 0) { + return null; + } + return ( + setActiveKeys(toArr(keys).map(Number))} + className={props.className} + style={arrayCollapseItemStyle} + > + {dataSource.map((item, index) => { + const items = Array.isArray(schema.items) ? schema.items[index] || schema.items[0] : schema.items; + + const panelProps = field.query(`${field.address}.${index}`).get('componentProps'); + const props: CollapsePanelProps = items['x-component-props']; + const header = () => { + const header = `${panelProps?.header || props.header || field.title}`; + const path = field.address.concat(index); + const errors = field.form.queryFeedbacks({ + type: 'error', + address: `${path}.**`, + }); + return ( + field.value?.[index]}> + { + if (!isIndexComponent(schema)) return false; + return true; + }} + onlyRenderProperties + /> + {errors.length ? ( + + {header} + + ) : ( + + )} + + ); + }; + + const extra = ( + + { + if (!isOperationComponent(schema)) return false; + return true; + }} + onlyRenderProperties + /> + {panelProps?.extra} + + ); + + const content = ( + { + if (isIndexComponent(schema)) return false; + if (isOperationComponent(schema)) return false; + return true; + }} + /> + ); + return ( + + + {content} + + + ); + })} + + ); + }; + return ( + { + setActiveKeys(insertActiveKeys(activeKeys, index)); + }} + > + {/* {renderEmpty()} */} + {renderItems()} + {renderAddition()} + + ); + }, + { displayName: 'ArrayCollapse' }, +); + +const CollapsePanel: React.FC> = ({ children }) => { + return {children}; +}; + +CollapsePanel.displayName = 'CollapsePanel'; + +ArrayCollapse.defaultProps = { + defaultOpenPanelCount: 5, +}; +ArrayCollapse.displayName = 'ArrayCollapse'; +ArrayCollapse.CollapsePanel = CollapsePanel; + +ArrayBase.mixin(ArrayCollapse); + +export default ArrayCollapse; + +//@ts-ignore +ArrayCollapse.Copy = React.forwardRef((props: any, ref) => { + const { token } = useToken(); + const self = useField(); + const array = ArrayBase.useArray(); + const index = ArrayBase.useIndex(props.index); + if (!array) return null; + if (array.field?.pattern !== 'editable') return null; + return ( + { + if (self?.disabled) return; + e.stopPropagation(); + if (array.props?.disabled) return; + const value = cloneDeep(array?.field?.value[index]); + array.field.push(value); + if (props.onClick) { + props.onClick(e); + } + }} + /> + ); +}); +(ArrayCollapse as any).Copy.displayName = 'ArrayCollapse.Copy'; diff --git a/packages/core/client/src/event-flow/EventSettingItem/LinkageRules/compute-rules.ts b/packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/compute-rules.ts similarity index 100% rename from packages/core/client/src/event-flow/EventSettingItem/LinkageRules/compute-rules.ts rename to packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/compute-rules.ts diff --git a/packages/core/client/src/event-flow/EventSettingItem/LinkageRules/context.ts b/packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/context.ts similarity index 100% rename from packages/core/client/src/event-flow/EventSettingItem/LinkageRules/context.ts rename to packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/context.ts diff --git a/packages/core/client/src/event-flow/EventSettingItem/LinkageRules/forEachLinkageRule.ts b/packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/forEachLinkageRule.ts similarity index 100% rename from packages/core/client/src/event-flow/EventSettingItem/LinkageRules/forEachLinkageRule.ts rename to packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/forEachLinkageRule.ts diff --git a/packages/core/client/src/event-flow/EventSettingItem/LinkageRules/index.tsx b/packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/index.tsx similarity index 86% rename from packages/core/client/src/event-flow/EventSettingItem/LinkageRules/index.tsx rename to packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/index.tsx index a2d3c2af6f..29e84dc9d5 100644 --- a/packages/core/client/src/event-flow/EventSettingItem/LinkageRules/index.tsx +++ b/packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/index.tsx @@ -20,19 +20,18 @@ import { SubFormProvider } from '../../../schema-component/antd/association-fiel import { DynamicComponentProps } from '../../../schema-component/antd/filter/DynamicComponent'; import { FilterContext } from '../../../schema-component/antd/filter/context'; import { VariableInput, getShouldChange } from '../../../schema-settings/VariableInput/VariableInput'; -import { LinkageRuleActionGroup } from './LinkageRuleActionGroup'; +import { Actions } from './Actions'; import { EnableLinkage } from './components/EnableLinkage'; import { ArrayCollapse } from './components/LinkageHeader'; import { FormProvider, createSchemaField } from '@formily/react'; -import { Filter } from '../filter'; +import { Filter } from '../Filter2'; export interface Props { dynamicComponent: any; } -export const FormLinkageRules = withDynamicSchemaProps( +export const ActionsSetting = withDynamicSchemaProps( observer((props: Props) => { - console.log('FormLinkageRules22', props); const fieldSchema = useFieldSchema(); const { options, defaultValues, collectionName, form, variables, localVariables, record, dynamicComponent } = useProps(props); // 新版 UISchema(1.0 之后)中已经废弃了 useProps,这里之所以继续保留是为了兼容旧版的 UISchema @@ -70,7 +69,7 @@ export const FormLinkageRules = withDynamicSchemaProps( wrapperCol: 16, }, properties: { - conditions: { + conditionsTitle: { 'x-component': 'h4', 'x-content': '{{ t("Condition") }}', }, @@ -106,13 +105,13 @@ export const FormLinkageRules = withDynamicSchemaProps( }, }, }, - actions: { + actionsTitle: { 'x-component': 'h4', - 'x-content': '{{ t("Properties") }}', + 'x-content': '{{ t("动作") }}', }, - action: { + actions: { type: 'void', - 'x-component': (_props) => , + 'x-component': (_props) => , }, }, }, @@ -173,18 +172,18 @@ export const FormLinkageRules = withDynamicSchemaProps( return ( // 这里使用 SubFormProvider 包裹,是为了让子表格的联动规则中 “当前对象” 的配置显示正确 - - - - - - - - - - - + // + + + + + + + + + + // ); }), - { displayName: 'FormLinkageRules' }, + { displayName: 'ActionsSetting' }, ); diff --git a/packages/core/client/src/event-flow/EventSettingItem/LinkageRules/type.ts b/packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/type.ts similarity index 100% rename from packages/core/client/src/event-flow/EventSettingItem/LinkageRules/type.ts rename to packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/type.ts diff --git a/packages/core/client/src/event-flow/EventSettingItem/LinkageRules/useActionValues.ts b/packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/useActionValues.ts similarity index 100% rename from packages/core/client/src/event-flow/EventSettingItem/LinkageRules/useActionValues.ts rename to packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/useActionValues.ts diff --git a/packages/core/client/src/event-flow/EventSettingItem/LinkageRules/useValues.ts b/packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/useValues.ts similarity index 100% rename from packages/core/client/src/event-flow/EventSettingItem/LinkageRules/useValues.ts rename to packages/core/client/src/event-flow/EventSettingItem/ActionsSetting/useValues.ts diff --git a/packages/core/client/src/event-flow/EventSettingItem/EventSelect.tsx b/packages/core/client/src/event-flow/EventSettingItem/EventsSetting/EventSelect.tsx similarity index 63% rename from packages/core/client/src/event-flow/EventSettingItem/EventSelect.tsx rename to packages/core/client/src/event-flow/EventSettingItem/EventsSetting/EventSelect.tsx index 4843d74265..24e719607f 100644 --- a/packages/core/client/src/event-flow/EventSettingItem/EventSelect.tsx +++ b/packages/core/client/src/event-flow/EventSettingItem/EventsSetting/EventSelect.tsx @@ -10,24 +10,30 @@ import React from 'react'; import { useControllableValue } from 'ahooks'; import { Card, Space, TreeSelect } from 'antd'; -import { EventDefinition } from '../types'; +import { EventDefinition } from '../../types'; -export default function EventSelect(props: { modules: EventDefinition[]; value: any; onChange: (v: any) => void }) { - const { modules, onChange } = props; - const [state, setState] = useControllableValue>(props, { +export default function EventSelect(props: { + definitions: EventDefinition[]; + value: any; + onChange: (v: any) => void; + className?: string; +}) { + const { definitions, className } = props; + const [state, setState] = useControllableValue(props, { defaultValue: undefined, }); - let treeData = modules?.map((module) => ({ + let treeData = definitions?.map((module) => ({ value: module.name, - title: module.title, + title: module.title + ' - ' + module.uid, + selectable: false, children: module?.events?.map((event) => ({ value: module.name + '.' + event.name, title: event.title, })) || [], })); - treeData = treeData.filter((item) => item.children.length > 0); + treeData = treeData?.filter((item) => item.children.length > 0); return ( ); } diff --git a/packages/core/client/src/event-flow/EventSettingItem/EventsSetting/components/EnableLinkage.tsx b/packages/core/client/src/event-flow/EventSettingItem/EventsSetting/components/EnableLinkage.tsx new file mode 100644 index 0000000000..6915d094be --- /dev/null +++ b/packages/core/client/src/event-flow/EventSettingItem/EventsSetting/components/EnableLinkage.tsx @@ -0,0 +1,44 @@ +/** + * 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 { ArrayBase } from '@formily/antd-v5'; +import { Switch } from 'antd'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; + +export const EnableLinkage = React.forwardRef((props: any, ref) => { + const array = ArrayBase.useArray(); + const index = ArrayBase.useIndex(props.index); + const { t } = useTranslation(); + + return ( + { + e.stopPropagation(); + array.field.value.splice(index, 1, { ...array?.field?.value[index], disabled: !checked }); + }} + onClick={(checked, e) => { + e.stopPropagation(); + }} + /> + ); +}); +EnableLinkage.displayName = 'EnableLinkage'; diff --git a/packages/core/client/src/event-flow/EventSettingItem/EventsSetting/components/LinkageHeader.style.ts b/packages/core/client/src/event-flow/EventSettingItem/EventsSetting/components/LinkageHeader.style.ts new file mode 100644 index 0000000000..2b4e0122cf --- /dev/null +++ b/packages/core/client/src/event-flow/EventSettingItem/EventsSetting/components/LinkageHeader.style.ts @@ -0,0 +1,12 @@ +/** + * 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. + */ + +export const arrayCollapseItemStyle = { + marginBottom: 10, +}; diff --git a/packages/core/client/src/event-flow/EventSettingItem/LinkageRules/components/LinkageHeader.tsx b/packages/core/client/src/event-flow/EventSettingItem/EventsSetting/components/LinkageHeader.tsx similarity index 92% rename from packages/core/client/src/event-flow/EventSettingItem/LinkageRules/components/LinkageHeader.tsx rename to packages/core/client/src/event-flow/EventSettingItem/EventsSetting/components/LinkageHeader.tsx index 760ed5ad8b..9eccb04742 100644 --- a/packages/core/client/src/event-flow/EventSettingItem/LinkageRules/components/LinkageHeader.tsx +++ b/packages/core/client/src/event-flow/EventSettingItem/EventsSetting/components/LinkageHeader.tsx @@ -24,25 +24,26 @@ const LinkageRulesTitle = (props) => { const index = ArrayBase.useIndex(props.index); const { t } = useTranslation(); const value = array?.field?.value[index]; - return ( - { - ev.stopPropagation(); - array.field.value.splice(index, 1, { ...value, title: ev.target.value }); - }} - onBlur={(ev) => { - ev.stopPropagation(); - array.field.value.splice(index, 1, { ...value, title: ev.target.value }); - }} - autoSize - style={{ width: '70%', border: 'none' }} - onClick={(e) => { - e.stopPropagation(); - }} - /> - ); + return
{`事件 ${index + 1}`}
; + // return ( + // { + // ev.stopPropagation(); + // array.field.value.splice(index, 1, { ...value, title: ev.target.value }); + // }} + // onBlur={(ev) => { + // ev.stopPropagation(); + // array.field.value.splice(index, 1, { ...value, title: ev.target.value }); + // }} + // autoSize + // style={{ width: '70%', border: 'none' }} + // onClick={(e) => { + // e.stopPropagation(); + // }} + // /> + // ); }; export interface IArrayCollapseProps extends CollapseProps { @@ -133,6 +134,9 @@ export const ArrayCollapse: ComposedArrayCollapse = observer( }; const renderItems = () => { + if (!dataSource || dataSource.length === 0) { + return null; + } return ( { + const components = useMemo(() => ({ ArrayCollapse, ActionsSetting, EventSelect }), []); + const { definitions } = useProps(props); + + const schema = useMemo( + () => ({ + type: 'object', + properties: { + events: { + type: 'array', + // default: defaultValues, + 'x-component': 'ArrayCollapse', + 'x-decorator': 'FormItem', + 'x-component-props': { + accordion: true, + }, + items: { + type: 'object', + 'x-component': 'ArrayCollapse.CollapsePanel', + 'x-component-props': { + // extra: , + }, + properties: { + layout: { + type: 'void', + 'x-component': 'FormLayout', + 'x-component-props': { + labelStyle: { + marginTop: '4px', + }, + labelCol: 8, + wrapperCol: 16, + }, + properties: { + eventTitle: { + 'x-component': 'h4', + 'x-content': '{{ t("触发事件") }}', + }, + event: { + 'x-component': EventSelect, + 'x-component-props': { + definitions, + className: css` + margin-bottom: 12px; + `, + }, + }, + actionTitle: { + 'x-component': 'h4', + 'x-content': '{{ t("执行动作") }}', + }, + actions: { + type: 'void', + 'x-component': ActionsSetting, + 'x-component-props': { + ...props, + }, + }, + }, + }, + remove: { + type: 'void', + 'x-component': 'ArrayCollapse.Remove', + }, + // moveUp: { + // type: 'void', + // 'x-component': 'ArrayCollapse.MoveUp', + // }, + // moveDown: { + // type: 'void', + // 'x-component': 'ArrayCollapse.MoveDown', + // }, + // copy: { + // type: 'void', + // 'x-component': 'ArrayCollapse.Copy', + // }, + }, + }, + properties: { + add: { + type: 'void', + title: '{{ t("Add events") }}', + 'x-component': 'ArrayCollapse.Addition', + 'x-reactions': { + dependencies: ['rules'], + fulfill: { + state: { + // disabled: '{{$deps[0].length >= 3}}', + }, + }, + }, + }, + }, + }, + }, + }), + [], + ); + + return ; + // return ( + // // 这里使用 SubFormProvider 包裹,是为了让子表格的联动规则中 “当前对象” 的配置显示正确 + // // + // + // + // + // + // + // + // + // + // + // // + // ); + }), + { displayName: 'Evets' }, +); diff --git a/packages/core/client/src/event-flow/EventSettingItem/filter/DynamicComponent.tsx b/packages/core/client/src/event-flow/EventSettingItem/Filter2/DynamicComponent.tsx similarity index 100% rename from packages/core/client/src/event-flow/EventSettingItem/filter/DynamicComponent.tsx rename to packages/core/client/src/event-flow/EventSettingItem/Filter2/DynamicComponent.tsx diff --git a/packages/core/client/src/event-flow/EventSettingItem/filter/Filter.Action.Designer.tsx b/packages/core/client/src/event-flow/EventSettingItem/Filter2/Filter.Action.Designer.tsx similarity index 100% rename from packages/core/client/src/event-flow/EventSettingItem/filter/Filter.Action.Designer.tsx rename to packages/core/client/src/event-flow/EventSettingItem/Filter2/Filter.Action.Designer.tsx diff --git a/packages/core/client/src/event-flow/EventSettingItem/filter/Filter.tsx b/packages/core/client/src/event-flow/EventSettingItem/Filter2/Filter.tsx similarity index 99% rename from packages/core/client/src/event-flow/EventSettingItem/filter/Filter.tsx rename to packages/core/client/src/event-flow/EventSettingItem/Filter2/Filter.tsx index 67eb047062..033e857398 100644 --- a/packages/core/client/src/event-flow/EventSettingItem/filter/Filter.tsx +++ b/packages/core/client/src/event-flow/EventSettingItem/Filter2/Filter.tsx @@ -54,7 +54,6 @@ export const Filter: any = withDynamicSchemaProps( }, [fieldSchema.defaultValue]); return (
- 1111 { - const { linkageOptions, category, elementType } = props; - const field = useField(); - const type = category === 'default' ? elementType : category; - const componentMap: { - [key in LinkageRuleActionGroupProps['type']]: any; - } = { - button: FormButtonLinkageRuleAction, - field: FormFieldLinkageRuleAction, - style: FormStyleLinkageRuleAction, - }; - return field?.value?.map((item, index) => { - return ( - field.remove(index)}> - - - ); - }); - }, - { displayName: 'LinkageRuleActions' }, -); - -export interface LinkageRuleActionGroupProps { - type: 'button' | 'field' | 'style'; - linkageOptions: any; - collectionName: string; -} - -export const LinkageRuleActionGroup = withDynamicSchemaProps( - (props: LinkageRuleActionGroupProps) => { - const { t } = useTranslation(); - const field = useField(); - const logic = 'actions'; - - // 新版 UISchema(1.0 之后)中已经废弃了 useProps,这里之所以继续保留是为了兼容旧版的 UISchema - const { category, elementType, linkageOptions, collectionName } = useProps(props); - const style = useMemo(() => ({ marginLeft: 10 }), []); - const components = useMemo( - () => [LinkageRuleActions, { category, elementType, linkageOptions, collectionName }], - [collectionName, linkageOptions, category, elementType], - ); - const spaceStyle = useMemo(() => ({ marginTop: 8, marginBottom: 8 }), []); - const onClick = useCallback(() => { - const f = field.query('.actions').take() as ArrayFieldModel; - const items = f.value || []; - items.push({}); - f.value = items; - f.initialValue = items; - }, [field]); - - return ( - - ); - }, - { displayName: 'LinkageRuleActionGroup' }, -); diff --git a/packages/core/client/src/event-flow/EventSettingItem/ActionsInput.tsx b/packages/core/client/src/event-flow/EventSettingItem/_/ActionsInput.tsx similarity index 97% rename from packages/core/client/src/event-flow/EventSettingItem/ActionsInput.tsx rename to packages/core/client/src/event-flow/EventSettingItem/_/ActionsInput.tsx index 45ed6b5ff0..a9fddc2b43 100644 --- a/packages/core/client/src/event-flow/EventSettingItem/ActionsInput.tsx +++ b/packages/core/client/src/event-flow/EventSettingItem/_/ActionsInput.tsx @@ -11,7 +11,7 @@ import React from 'react'; import { useControllableValue } from 'ahooks'; import { Card, Space, Button, Tag, Tooltip, Select, TreeSelect } from 'antd'; import { CloseOutlined, PlusOutlined, SettingFilled } from '@ant-design/icons'; -import { EventDefinition } from '../types'; +import { EventDefinition } from '../../types'; export default function ActionsInput(props: { modules: EventDefinition[]; value: any; onChange: (v: any) => void }) { const { modules } = props; diff --git a/packages/core/client/src/event-flow/EventSettingItem/ConditionInput.tsx b/packages/core/client/src/event-flow/EventSettingItem/_/ConditionInput.tsx similarity index 100% rename from packages/core/client/src/event-flow/EventSettingItem/ConditionInput.tsx rename to packages/core/client/src/event-flow/EventSettingItem/_/ConditionInput.tsx diff --git a/packages/core/client/src/event-flow/EventSettingItem/EventSetting.tsx b/packages/core/client/src/event-flow/EventSettingItem/_/EventSetting.tsx similarity index 76% rename from packages/core/client/src/event-flow/EventSettingItem/EventSetting.tsx rename to packages/core/client/src/event-flow/EventSettingItem/_/EventSetting.tsx index 9e94593ab3..76ff36e9a6 100644 --- a/packages/core/client/src/event-flow/EventSettingItem/EventSetting.tsx +++ b/packages/core/client/src/event-flow/EventSettingItem/_/EventSetting.tsx @@ -1,11 +1,11 @@ -/** - * 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. - */ +// /** +// * 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 React, { useMemo } from 'react'; import { useControllableValue } from 'ahooks'; @@ -14,10 +14,11 @@ import EventSelect from './EventSelect'; import ConditionInput from './ConditionInput'; import ActionsInput from './ActionsInput'; import { CloseOutlined, PlusOutlined } from '@ant-design/icons'; -import { EventSetting } from '../types'; +import { EventSetting } from '../../types'; import { FormLinkageRules } from './LinkageRules'; import { createForm } from '@formily/core'; -import options from './options.json'; +import options from '../options.json'; +import { onFormValuesChange, onFormInit } from '@formily/core'; const EventCard = (props) => { const { modules, onDelete } = props; @@ -33,6 +34,11 @@ const EventCard = (props) => { () => createForm({ initialValues: { rules: [] }, + effects() { + onFormValuesChange((form) => { + console.log('onFormValuesChange', JSON.parse(JSON.stringify(form.values))); + }); + }, }), [], ); @@ -53,7 +59,7 @@ const EventCard = (props) => { setState({ ...state, actions: v })} /> */} { localVariables={[]} options={options} variables={{}} - value={{ rules: [] }} - record={{ - __collectionName: 't_aierml1wni1', + // value={{ rules: [] }} + // record={{ + // __collectionName: 't_aierml1wni1', + // }} + onChange={(v) => { + console.log('onChange', v); }} /> diff --git a/packages/core/client/src/event-flow/EventSettingItem/index.tsx b/packages/core/client/src/event-flow/EventSettingItem/index.tsx index a890e856ba..ecdacd0ecc 100644 --- a/packages/core/client/src/event-flow/EventSettingItem/index.tsx +++ b/packages/core/client/src/event-flow/EventSettingItem/index.tsx @@ -14,14 +14,22 @@ import { useApp, usePlugin, useSchemaSettings, + useLinkageCollectionFilterOptions, + useFormBlockContext, + useVariables, + useLocalVariables, + useFormBlockType, + useRecord, } from '@nocobase/client'; import React from 'react'; import { ISchema, useField } from '@formily/react'; -import EventSettings from './EventSetting'; import { SchemaSettingsKey, useEvent } from '..'; import { useFieldSchema } from '@formily/react'; +import { useLinkageCollectionFieldOptions } from './ActionsSetting/action-hooks'; +import { EventsSetting } from './EventsSetting'; -export const EventSettingItem = () => { +// packages/core/client/src/schema-settings/SchemaSettings.tsx +export const EventSettingItem = (props) => { // const field = useField(); const filed = useField(); const schema = useFieldSchema(); @@ -31,10 +39,20 @@ export const EventSettingItem = () => { const { dn } = useDesignable(); const fieldSchema = useFieldSchema(); console.log('definitions', definitions); + const { readPretty, Component, afterSubmit } = props; + const collectionName = 't_aierml1wni1'; + const options = useLinkageCollectionFilterOptions(collectionName); + const linkageOptions = useLinkageCollectionFieldOptions(collectionName, readPretty); + const { form } = useFormBlockContext(); + const variables = useVariables(); + const localVariables = useLocalVariables(); + const { type: formBlockType } = useFormBlockType(); + const record = useRecord(); + return ( { title: '事件配置', properties: { events: { - type: 'array', - default: fieldSchema?.[SchemaSettingsKey] || [], - 'x-decorator': 'FormItem', - 'x-component': 'EventSettings', - 'x-component-props': { - modules: definitions, + 'x-component': EventsSetting, + 'x-use-component-props': () => { + return { + definitions, + options, + defaultValues: undefined, + linkageOptions, + category: 'default', + elementType: 'field', + collectionName, + form, + variables, + localVariables, + record, + formBlockType, + }; }, }, }, diff --git a/packages/core/client/src/schema-settings/LinkageRules/index.tsx b/packages/core/client/src/schema-settings/LinkageRules/index.tsx index c5b97bfb27..113b396adc 100644 --- a/packages/core/client/src/schema-settings/LinkageRules/index.tsx +++ b/packages/core/client/src/schema-settings/LinkageRules/index.tsx @@ -30,6 +30,7 @@ export interface Props { export const FormLinkageRules = withDynamicSchemaProps( observer((props: Props) => { + console.log('FormLinkageRules', props); const fieldSchema = useFieldSchema(); const { options, defaultValues, collectionName, form, variables, localVariables, record, dynamicComponent } = useProps(props); // 新版 UISchema(1.0 之后)中已经废弃了 useProps,这里之所以继续保留是为了兼容旧版的 UISchema