mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-09 23:49:27 +08:00
feat: support param value input
This commit is contained in:
parent
f959a1aa34
commit
70a1f6b05d
@ -11,7 +11,7 @@ import { useEvent } from '../../event-flow';
|
|||||||
import { useCollection } from '../../data-source/collection/CollectionProvider';
|
import { useCollection } from '../../data-source/collection/CollectionProvider';
|
||||||
|
|
||||||
export function useFormEvents({ form }) {
|
export function useFormEvents({ form }) {
|
||||||
const { define, emit } = useEvent();
|
const { define, emit, removeDefinition } = useEvent();
|
||||||
const collection = useCollection();
|
const collection = useCollection();
|
||||||
const fields = collection?.fields || [];
|
const fields = collection?.fields || [];
|
||||||
const fieldsMap = fields.reduce((acc, field) => {
|
const fieldsMap = fields.reduce((acc, field) => {
|
||||||
@ -122,5 +122,7 @@ export function useFormEvents({ form }) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// TODO remove define
|
||||||
|
|
||||||
define(inter);
|
define(inter);
|
||||||
}
|
}
|
||||||
|
@ -39,8 +39,13 @@ export class EventFlowPlugin extends Plugin {
|
|||||||
// this.app.addProviders()
|
// this.app.addProviders()
|
||||||
// this.app.router.add()
|
// this.app.router.add()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static isEqual(a: EventDefinition, b: EventDefinition) {
|
||||||
|
return a.name === b.name && a.uid === b.uid;
|
||||||
|
}
|
||||||
|
|
||||||
// 定义事件
|
// 定义事件
|
||||||
define(definition: EventDefinition[] | EventDefinition) {
|
define(definition: EventDefinition | EventDefinition[]) {
|
||||||
if (!definition) {
|
if (!definition) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -51,6 +56,17 @@ export class EventFlowPlugin extends Plugin {
|
|||||||
}
|
}
|
||||||
this.definitions = uniqBy(this.definitions, (item) => item.name + item.uid);
|
this.definitions = uniqBy(this.definitions, (item) => item.name + item.uid);
|
||||||
}
|
}
|
||||||
|
// 移除定义事件
|
||||||
|
removeDefinition(definition: EventDefinition | EventDefinition[]) {
|
||||||
|
if (!definition) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Array.isArray(definition)) {
|
||||||
|
this.definitions = this.definitions.filter((item) => !definition.some((d) => EventFlowPlugin.isEqual(item, d)));
|
||||||
|
} else {
|
||||||
|
this.definitions = this.definitions.filter((item) => !EventFlowPlugin.isEqual(item, definition));
|
||||||
|
}
|
||||||
|
}
|
||||||
// 运行时注册事件
|
// 运行时注册事件
|
||||||
register(events: EventSetting[]) {
|
register(events: EventSetting[]) {
|
||||||
console.log('todo register', events);
|
console.log('todo register', events);
|
||||||
|
@ -12,7 +12,7 @@ import { Button, Input, Space } from 'antd';
|
|||||||
import React, { useCallback } from 'react';
|
import React, { useCallback } from 'react';
|
||||||
import { ArrayField as ArrayFieldModel } from '@formily/core';
|
import { ArrayField as ArrayFieldModel } from '@formily/core';
|
||||||
import { CloseCircleOutlined } from '@ant-design/icons';
|
import { CloseCircleOutlined } from '@ant-design/icons';
|
||||||
import { ActionParamSelect } from './ActionParamSelect';
|
import { ActionParamSelect } from '../components/ActionParamSelect';
|
||||||
import { VariableInput, getShouldChange } from '../../../schema-settings';
|
import { VariableInput, getShouldChange } from '../../../schema-settings';
|
||||||
import { CollectionField } from '../../../data-source/collection-field';
|
import { CollectionField } from '../../../data-source/collection-field';
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ import { ArrayBase } from '@formily/antd-v5';
|
|||||||
import { useActionOptions } from './hooks/useActionOptions';
|
import { useActionOptions } from './hooks/useActionOptions';
|
||||||
import { CloseCircleOutlined } from '@ant-design/icons';
|
import { CloseCircleOutlined } from '@ant-design/icons';
|
||||||
import { ActionParamsField } from './ActionParams';
|
import { ActionParamsField } from './ActionParams';
|
||||||
import { ActionSelect } from './ActionSelect';
|
import { ActionSelect } from '../components/ActionSelect';
|
||||||
|
|
||||||
interface LinkageRuleActionGroupProps {
|
interface LinkageRuleActionGroupProps {
|
||||||
type: 'button' | 'field' | 'style';
|
type: 'button' | 'field' | 'style';
|
||||||
|
@ -1,104 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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 { useDataSourceManager } from '../../../../data-source/data-source';
|
|
||||||
import { useEvent } from '../../../hooks/useEvent';
|
|
||||||
import { EventParam, EventSetting, EventDefinition } from '../../../types';
|
|
||||||
|
|
||||||
const useCurrentEventParams: (event?: EventSetting['event']) => {
|
|
||||||
[key: string]: EventParam;
|
|
||||||
} = (event) => {
|
|
||||||
const { definitions } = useEvent();
|
|
||||||
const definition = definitions?.find((d) => d.name === event?.definition && d.uid === event.uid);
|
|
||||||
const eventParams = definition?.events?.find((e) => e.name === event?.event)?.params;
|
|
||||||
return eventParams;
|
|
||||||
};
|
|
||||||
|
|
||||||
const useStateDefine = ({ definitions }: { definitions: EventDefinition[] }) => {
|
|
||||||
const stateDefine = definitions.filter((item) => item.uid && item.states);
|
|
||||||
const stateDefineOptions = {};
|
|
||||||
stateDefine.forEach((definition) => {
|
|
||||||
stateDefineOptions[definition.uid] = {
|
|
||||||
name: definition.uid,
|
|
||||||
title: `${definition.title}-${definition.uid}`,
|
|
||||||
type: 'object',
|
|
||||||
properties: definition.states,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
return { stateDefineOptions };
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useFilterOptions = (recordValues: EventSetting) => {
|
|
||||||
const selectedEvent: EventSetting['event'] = recordValues?.['event'];
|
|
||||||
const currentEventParamsDefine = useCurrentEventParams(selectedEvent);
|
|
||||||
const { definitions } = useEvent();
|
|
||||||
const { stateDefineOptions } = useStateDefine({ definitions });
|
|
||||||
|
|
||||||
const options: EventParam[] = [
|
|
||||||
{
|
|
||||||
name: '_eventParams',
|
|
||||||
title: '事件参数',
|
|
||||||
type: 'object',
|
|
||||||
properties: currentEventParamsDefine,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '_state',
|
|
||||||
title: '组件数据',
|
|
||||||
type: 'object',
|
|
||||||
properties: stateDefineOptions,
|
|
||||||
},
|
|
||||||
// {
|
|
||||||
// name: '_system',
|
|
||||||
// title: '系统参数',
|
|
||||||
// type: 'object',
|
|
||||||
// properties: {},
|
|
||||||
// },
|
|
||||||
];
|
|
||||||
const dm = useDataSourceManager();
|
|
||||||
|
|
||||||
const getOption = (opt: EventParam) => {
|
|
||||||
if (opt.type === 'object' && opt.properties) {
|
|
||||||
return {
|
|
||||||
name: opt.name,
|
|
||||||
title: opt.title,
|
|
||||||
children: Object.keys(opt.properties).map((key) =>
|
|
||||||
getOption({
|
|
||||||
...opt.properties[key],
|
|
||||||
name: key,
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (opt.type === 'array' && opt.items) {
|
|
||||||
//TODO: 处理数组
|
|
||||||
return {
|
|
||||||
name: opt.name,
|
|
||||||
title: opt.title,
|
|
||||||
children: [],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const fieldInterface = dm?.collectionFieldInterfaceManager.getFieldInterface(opt?.interface || opt.type);
|
|
||||||
const { nested, children, operators } = fieldInterface?.filterable || {};
|
|
||||||
const res = {
|
|
||||||
name: opt.name,
|
|
||||||
type: opt.type,
|
|
||||||
// target: opt.target,
|
|
||||||
title: opt?.uiSchema?.title || opt.title || opt.name,
|
|
||||||
schema: opt?.uiSchema,
|
|
||||||
interface: opt.interface,
|
|
||||||
operators:
|
|
||||||
operators?.filter?.((operator) => {
|
|
||||||
return !operator?.visible || operator.visible(opt);
|
|
||||||
}) || [],
|
|
||||||
};
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
return options.map((opt) => getOption(opt));
|
|
||||||
};
|
|
@ -25,17 +25,17 @@ import { FormProvider, createSchemaField } from '@formily/react';
|
|||||||
import { ArrayCollapse } from '../components/LinkageHeader';
|
import { ArrayCollapse } from '../components/LinkageHeader';
|
||||||
import { Filter } from '../Filter';
|
import { Filter } from '../Filter';
|
||||||
import { ArrayBase, Select, DatePicker, Editable, Input, ArrayItems, FormItem } from '@formily/antd-v5';
|
import { ArrayBase, Select, DatePicker, Editable, Input, ArrayItems, FormItem } from '@formily/antd-v5';
|
||||||
import { useFilterOptions } from './hooks/useFilterOptions';
|
import { useFilterOptions } from '../hooks/useFilterOptions';
|
||||||
import { EventDefinition, EventSetting } from '../../types';
|
import { EventDefinition, EventSetting } from '../../types';
|
||||||
import { useVariableOptions } from './hooks/useVariableOptions';
|
import { useVariableOptions } from '../hooks/useVariableOptions';
|
||||||
import { uniqBy } from 'lodash';
|
import { uniqBy } from 'lodash';
|
||||||
import { AddBtn, DeleteBtn } from './AddBtn';
|
import { AddBtn, DeleteBtn } from './AddBtn';
|
||||||
import { ActionSelect } from './ActionSelect';
|
import { ActionSelect } from '../components/ActionSelect';
|
||||||
import { ActionParamSelect } from './ActionParamSelect';
|
import { ActionParamSelect } from '../components/ActionParamSelect';
|
||||||
import { Space } from 'antd';
|
import { Space } from 'antd';
|
||||||
import { useFormBlockContext } from '../../../block-provider';
|
import { useFormBlockContext } from '../../../block-provider';
|
||||||
import ConditionSelect from './ConditionSelect';
|
import ConditionSelect from '../components/ConditionSelect';
|
||||||
import { actionsSchema } from './schemas/actions';
|
import { actionsSchema } from '../schemas/actions';
|
||||||
|
|
||||||
const SchemaField = createSchemaField({
|
const SchemaField = createSchemaField({
|
||||||
components: {
|
components: {
|
||||||
@ -71,12 +71,10 @@ export const ActionsSetting = withDynamicSchemaProps(
|
|||||||
const array = ArrayBase.useArray();
|
const array = ArrayBase.useArray();
|
||||||
const recordValues = ArrayBase.useRecord();
|
const recordValues = ArrayBase.useRecord();
|
||||||
const index = ArrayBase.useIndex();
|
const index = ArrayBase.useIndex();
|
||||||
const { definitions, options, defaultValues, collectionName, variables, localVariables, record, dynamicComponent } =
|
const { options, defaultValues, collectionName, variables, localVariables, record, dynamicComponent } = props;
|
||||||
props;
|
|
||||||
const { getAllCollectionsInheritChain } = useCollectionManager_deprecated();
|
const { getAllCollectionsInheritChain } = useCollectionManager_deprecated();
|
||||||
const parentRecordData = useCollectionParentRecordData();
|
const parentRecordData = useCollectionParentRecordData();
|
||||||
const { form } = useFormBlockContext();
|
const { form } = useFormBlockContext();
|
||||||
const filterOptions = useFilterOptions(recordValues);
|
|
||||||
const variableOptions = useVariableOptions();
|
const variableOptions = useVariableOptions();
|
||||||
console.log('variableOptions', variableOptions);
|
console.log('variableOptions', variableOptions);
|
||||||
const components = useMemo(
|
const components = useMemo(
|
||||||
@ -131,6 +129,14 @@ export const ActionsSetting = withDynamicSchemaProps(
|
|||||||
},
|
},
|
||||||
condition: {
|
condition: {
|
||||||
'x-component': 'ConditionSelect',
|
'x-component': 'ConditionSelect',
|
||||||
|
'x-reactions': {
|
||||||
|
dependencies: ['...event'],
|
||||||
|
fulfill: {
|
||||||
|
state: {
|
||||||
|
'componentProps.options3': '{{$deps[0]}}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
actionsTitle: {
|
actionsTitle: {
|
||||||
'x-component': 'h4',
|
'x-component': 'h4',
|
||||||
@ -173,7 +179,6 @@ export const ActionsSetting = withDynamicSchemaProps(
|
|||||||
props,
|
props,
|
||||||
record,
|
record,
|
||||||
variables,
|
variables,
|
||||||
filterOptions,
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
const value = useMemo(
|
const value = useMemo(
|
||||||
|
@ -22,5 +22,6 @@ export function ActionParamSelect(props: { action: EventActionSetting }) {
|
|||||||
value: params[key]?.name || key,
|
value: params[key]?.name || key,
|
||||||
...params[key],
|
...params[key],
|
||||||
}));
|
}));
|
||||||
|
console.log('ActionParamSelect', props);
|
||||||
return <Select options={options} {...rest} style={{ minWidth: 150 }}></Select>;
|
return <Select options={options} {...rest} style={{ minWidth: 150 }}></Select>;
|
||||||
}
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
/**
|
||||||
|
* 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 { Input, Select } from 'antd';
|
||||||
|
import { EventActionSetting } from '../../types';
|
||||||
|
import { useEvent } from '../../hooks/useEvent';
|
||||||
|
import React, { useCallback } from 'react';
|
||||||
|
import { VariableInput } from '../../../schema-settings/VariableInput';
|
||||||
|
import { getShouldChange } from '../../../schema-settings/VariableInput';
|
||||||
|
import { CollectionField } from '../../../data-source/collection-field';
|
||||||
|
import { withDynamicSchemaProps } from '../../../hoc/withDynamicSchemaProps';
|
||||||
|
import { SchemaComponent } from '../../../schema-component';
|
||||||
|
|
||||||
|
export const ActionParamValueInput = (props) => {
|
||||||
|
const renderSchemaComponent = useCallback(({ value, onChange }): React.JSX.Element => {
|
||||||
|
return <Input value={value} onChange={onChange} style={{ minWidth: 100 }} />;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// const renderSchemaComponent = useCallback(({ value, onChange }): React.JSX.Element => {
|
||||||
|
// console.log('renderSchemaComponent', value, onChange);
|
||||||
|
// return <CollectionField value={value} onChange={onChange} />;
|
||||||
|
// }, []);
|
||||||
|
|
||||||
|
console.log('ActionParamValueInput props', props);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<VariableInput
|
||||||
|
{...props}
|
||||||
|
// form={form}
|
||||||
|
// record={record}
|
||||||
|
shouldChange={getShouldChange({
|
||||||
|
// collectionField,
|
||||||
|
// variables,
|
||||||
|
// localVariables,
|
||||||
|
// getAllCollectionsInheritChain,
|
||||||
|
})}
|
||||||
|
renderSchemaComponent={renderSchemaComponent}
|
||||||
|
// returnScope={(scope) => {
|
||||||
|
// return uniqBy([...scope, ...variableOptions], 'key');
|
||||||
|
// }}
|
||||||
|
style={{ minWidth: 200 }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
@ -10,7 +10,7 @@
|
|||||||
import { observer } from '@formily/react';
|
import { observer } from '@formily/react';
|
||||||
import { Cascader } from 'antd';
|
import { Cascader } from 'antd';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useActionOptions } from './hooks/useActionOptions';
|
import { useActionOptions } from '../hooks/useActionOptions';
|
||||||
import { EventActionSetting } from '../../types';
|
import { EventActionSetting } from '../../types';
|
||||||
|
|
||||||
export const ActionSelect = observer((props: any) => {
|
export const ActionSelect = observer((props: any) => {
|
@ -7,29 +7,35 @@
|
|||||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import { Filter, useFilterOptions } from '../Filter';
|
import { Filter } from '../Filter';
|
||||||
|
import { useFilterOptions } from '../hooks/useFilterOptions';
|
||||||
import { ArrayBase } from '@formily/antd-v5';
|
import { ArrayBase } from '@formily/antd-v5';
|
||||||
import { css } from '@emotion/css';
|
import { css } from '@emotion/css';
|
||||||
import { getShouldChange } from '../../../schema-settings/VariableInput';
|
import { getShouldChange } from '../../../schema-settings/VariableInput';
|
||||||
import { DynamicComponentProps } from '../../../schema-component/antd/filter/DynamicComponent';
|
import { DynamicComponentProps } from '../../../schema-component/antd/filter/DynamicComponent';
|
||||||
import { VariableInput } from '../../../schema-settings/VariableInput';
|
import { VariableInput } from '../../../schema-settings/VariableInput';
|
||||||
import { uniqBy } from 'lodash';
|
import { uniqBy } from 'lodash';
|
||||||
import { useVariableOptions } from './hooks/useVariableOptions';
|
import { useVariableOptions } from '../hooks/useVariableOptions';
|
||||||
|
import { EventSetting } from '../../types';
|
||||||
|
import { useField } from '@formily/react';
|
||||||
|
import { ObjectField } from '@formily/core';
|
||||||
|
import { useUpdateEffect } from 'ahooks';
|
||||||
|
|
||||||
export default function ConditionSelect(props: any) {
|
export default function ConditionSelect(props: { event?: EventSetting['event']; onChange?: any }) {
|
||||||
const recordValues = ArrayBase.useRecord();
|
const filterOptions = useFilterOptions(props.event);
|
||||||
const filterOptions = useFilterOptions(recordValues);
|
|
||||||
const variableOptions = useVariableOptions();
|
const variableOptions = useVariableOptions();
|
||||||
console.log('filterOptions', filterOptions, props);
|
console.log('filterOptions', filterOptions, props);
|
||||||
|
const field = useField<ObjectField>();
|
||||||
|
useUpdateEffect(() => {
|
||||||
|
// 当 event 变化时,清空 condition
|
||||||
|
// TODO: 条件判定进行清空
|
||||||
|
field.value = {};
|
||||||
|
}, [JSON.stringify(props.event)]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Filter
|
<Filter
|
||||||
className={css`
|
options={filterOptions}
|
||||||
position: relative;
|
|
||||||
width: 100%;
|
|
||||||
margin-left: 10px;
|
|
||||||
`}
|
|
||||||
dynamicComponent={(props: DynamicComponentProps) => {
|
dynamicComponent={(props: DynamicComponentProps) => {
|
||||||
const { collectionField } = props;
|
const { collectionField } = props;
|
||||||
return (
|
return (
|
@ -1,44 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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 (
|
|
||||||
<Switch
|
|
||||||
{...props}
|
|
||||||
checkedChildren={t('On')}
|
|
||||||
unCheckedChildren={t('Off')}
|
|
||||||
checked={!array?.field?.value[index].disabled}
|
|
||||||
size={'small'}
|
|
||||||
style={{
|
|
||||||
transition: 'all 0.25s ease-in-out',
|
|
||||||
color: 'rgba(0, 0, 0, 0.8)',
|
|
||||||
fontSize: 16,
|
|
||||||
marginLeft: 6,
|
|
||||||
marginBottom: 3,
|
|
||||||
}}
|
|
||||||
onChange={(checked, e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
array.field.value.splice(index, 1, { ...array?.field?.value[index], disabled: !checked });
|
|
||||||
}}
|
|
||||||
onClick={(checked, e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
EnableLinkage.displayName = 'EnableLinkage';
|
|
@ -7,7 +7,7 @@
|
|||||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { useEvent } from '../../../hooks/useEvent';
|
import { useEvent } from '../../hooks/useEvent';
|
||||||
|
|
||||||
export function useActionOptions() {
|
export function useActionOptions() {
|
||||||
const { definitions } = useEvent();
|
const { definitions } = useEvent();
|
@ -7,7 +7,7 @@
|
|||||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { useEvent } from '../../../hooks/useEvent';
|
import { useEvent } from '../../hooks/useEvent';
|
||||||
|
|
||||||
export function useActionOptions() {
|
export function useActionOptions() {
|
||||||
const { definitions } = useEvent();
|
const { definitions } = useEvent();
|
@ -7,6 +7,97 @@
|
|||||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export const useFilterOptions = () => {
|
import { useDataSourceManager } from '../../../data-source/data-source';
|
||||||
return { filterOptions: [] };
|
import { useEvent } from '../../hooks/useEvent';
|
||||||
|
import { EventParam, EventSetting, EventDefinition } from '../../types';
|
||||||
|
|
||||||
|
const useCurrentEventParams: (event?: EventSetting['event']) => {
|
||||||
|
[key: string]: EventParam;
|
||||||
|
} = (event) => {
|
||||||
|
const { definitions } = useEvent();
|
||||||
|
const definition = definitions?.find((d) => d.name === event?.definition && d.uid === event.uid);
|
||||||
|
const eventParams = definition?.events?.find((e) => e.name === event?.event)?.params;
|
||||||
|
return eventParams;
|
||||||
|
};
|
||||||
|
|
||||||
|
const useStateDefine = ({ definitions }: { definitions: EventDefinition[] }) => {
|
||||||
|
const stateDefine = definitions.filter((item) => item.uid && item.states);
|
||||||
|
const stateDefineOptions = {};
|
||||||
|
stateDefine.forEach((definition) => {
|
||||||
|
stateDefineOptions[definition.uid] = {
|
||||||
|
name: definition.uid,
|
||||||
|
title: `${definition.title}-${definition.uid}`,
|
||||||
|
type: 'object',
|
||||||
|
properties: definition.states,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return { stateDefineOptions };
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useFilterOptions = (event?: EventSetting['event']) => {
|
||||||
|
const currentEventParamsDefine = useCurrentEventParams(event);
|
||||||
|
const { definitions } = useEvent();
|
||||||
|
const { stateDefineOptions } = useStateDefine({ definitions });
|
||||||
|
|
||||||
|
const options: EventParam[] = [
|
||||||
|
{
|
||||||
|
name: '_eventParams',
|
||||||
|
title: '事件参数',
|
||||||
|
type: 'object',
|
||||||
|
properties: currentEventParamsDefine,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '_state',
|
||||||
|
title: '组件数据',
|
||||||
|
type: 'object',
|
||||||
|
properties: stateDefineOptions,
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// name: '_system',
|
||||||
|
// title: '系统参数',
|
||||||
|
// type: 'object',
|
||||||
|
// properties: {},
|
||||||
|
// },
|
||||||
|
];
|
||||||
|
const dm = useDataSourceManager();
|
||||||
|
|
||||||
|
const getOption = (opt: EventParam) => {
|
||||||
|
if (opt.type === 'object' && opt.properties) {
|
||||||
|
return {
|
||||||
|
name: opt.name,
|
||||||
|
title: opt.title,
|
||||||
|
children: Object.keys(opt.properties).map((key) =>
|
||||||
|
getOption({
|
||||||
|
...opt.properties[key],
|
||||||
|
name: key,
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (opt.type === 'array' && opt.items) {
|
||||||
|
//TODO: 处理数组
|
||||||
|
return {
|
||||||
|
name: opt.name,
|
||||||
|
title: opt.title,
|
||||||
|
children: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const fieldInterface = dm?.collectionFieldInterfaceManager.getFieldInterface(opt?.interface || opt.type);
|
||||||
|
const { nested, children, operators } = fieldInterface?.filterable || {};
|
||||||
|
const res = {
|
||||||
|
name: opt.name,
|
||||||
|
type: opt.type,
|
||||||
|
// target: opt.target,
|
||||||
|
title: opt?.uiSchema?.title || opt.title || opt.name,
|
||||||
|
schema: opt?.uiSchema,
|
||||||
|
interface: opt.interface,
|
||||||
|
operators:
|
||||||
|
operators?.filter?.((operator) => {
|
||||||
|
return !operator?.visible || operator.visible(opt);
|
||||||
|
}) || [],
|
||||||
|
};
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
return options.map((opt) => getOption(opt));
|
||||||
};
|
};
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
|
|
||||||
import { useCompile } from '@nocobase/client';
|
import { useCompile } from '@nocobase/client';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { useEvent } from '../../../hooks/useEvent';
|
import { useEvent } from '../../hooks/useEvent';
|
||||||
import { EventParam } from '../../../types';
|
import { EventParam } from '../../types';
|
||||||
|
|
||||||
export const useVariableOptions = () => {
|
export const useVariableOptions = () => {
|
||||||
const { definitions } = useEvent();
|
const { definitions } = useEvent();
|
@ -20,8 +20,9 @@ import {
|
|||||||
useLocalVariables,
|
useLocalVariables,
|
||||||
useFormBlockType,
|
useFormBlockType,
|
||||||
useRecord,
|
useRecord,
|
||||||
|
Filter,
|
||||||
} from '@nocobase/client';
|
} from '@nocobase/client';
|
||||||
import React, { useMemo } from 'react';
|
import React, { useEffect, useMemo } from 'react';
|
||||||
import { ISchema, useField } from '@formily/react';
|
import { ISchema, useField } from '@formily/react';
|
||||||
import { SchemaSettingsKey, useEvent } from '..';
|
import { SchemaSettingsKey, useEvent } from '..';
|
||||||
import { useFieldSchema } from '@formily/react';
|
import { useFieldSchema } from '@formily/react';
|
||||||
@ -30,8 +31,13 @@ import { ActionsSetting } from './ActionsSetting';
|
|||||||
import EventSelect from './EventSelect';
|
import EventSelect from './EventSelect';
|
||||||
import { ArrayCollapse } from './components/LinkageHeader';
|
import { ArrayCollapse } from './components/LinkageHeader';
|
||||||
import { css } from '@emotion/css';
|
import { css } from '@emotion/css';
|
||||||
import { useFilterOptions } from './hooks/useFilterOptions';
|
|
||||||
import { FormItem, FormLayout } from '@formily/antd-v5';
|
import { FormItem, FormLayout } from '@formily/antd-v5';
|
||||||
|
import { rulesSchema } from './schemas/rules';
|
||||||
|
import { ActionSelect } from './components/ActionSelect';
|
||||||
|
import { ActionParamSelect } from './components/ActionParamSelect';
|
||||||
|
import ConditionSelect from './components/ConditionSelect';
|
||||||
|
import { Space } from 'antd';
|
||||||
|
import { ActionParamValueInput } from './components/ActionParamValueInput';
|
||||||
|
|
||||||
// packages/core/client/src/schema-settings/SchemaSettings.tsx
|
// packages/core/client/src/schema-settings/SchemaSettings.tsx
|
||||||
export const EventSettingItem = (props) => {
|
export const EventSettingItem = (props) => {
|
||||||
@ -51,13 +57,29 @@ export const EventSettingItem = (props) => {
|
|||||||
const variables = useVariables();
|
const variables = useVariables();
|
||||||
const localVariables = useLocalVariables();
|
const localVariables = useLocalVariables();
|
||||||
const { type: formBlockType } = useFormBlockType();
|
const { type: formBlockType } = useFormBlockType();
|
||||||
const record = useRecord();
|
|
||||||
return (
|
return (
|
||||||
<SchemaSettingsModalItem
|
<SchemaSettingsModalItem
|
||||||
title={'Event Setting'}
|
title={'Event Setting'}
|
||||||
components={{ ArrayCollapse, ActionsSetting, EventSelect, FormLayout }}
|
components={{
|
||||||
initialValues={{}}
|
ArrayCollapse,
|
||||||
scope={{}}
|
// ActionsSetting,
|
||||||
|
EventSelect,
|
||||||
|
// FormLayout,
|
||||||
|
// Filter,
|
||||||
|
Space,
|
||||||
|
ActionParamSelect,
|
||||||
|
ActionSelect,
|
||||||
|
ConditionSelect,
|
||||||
|
ActionParamValueInput,
|
||||||
|
}}
|
||||||
|
initialValues={{ events: schema[SchemaSettingsKey] }}
|
||||||
|
scope={{
|
||||||
|
emptyParams: (field, target) => {
|
||||||
|
const params = field.query('.params').take(1);
|
||||||
|
params.value = [];
|
||||||
|
},
|
||||||
|
}}
|
||||||
width={1000}
|
width={1000}
|
||||||
schema={
|
schema={
|
||||||
{
|
{
|
||||||
@ -78,59 +100,42 @@ export const EventSettingItem = (props) => {
|
|||||||
items: {
|
items: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
'x-component': 'ArrayCollapse.CollapsePanel',
|
'x-component': 'ArrayCollapse.CollapsePanel',
|
||||||
'x-component-props': {
|
|
||||||
// extra: <EnableLinkage />,
|
|
||||||
},
|
|
||||||
properties: {
|
properties: {
|
||||||
layout: {
|
eventTitle: {
|
||||||
type: 'void',
|
'x-component': 'h4',
|
||||||
'x-component': 'FormLayout',
|
'x-content': '{{ t("触发事件") }}',
|
||||||
|
},
|
||||||
|
event: {
|
||||||
|
'x-component': EventSelect,
|
||||||
'x-component-props': {
|
'x-component-props': {
|
||||||
labelStyle: {
|
definitions,
|
||||||
marginTop: '4px',
|
className: css`
|
||||||
},
|
margin-bottom: 12px;
|
||||||
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-use-component-props': () => {
|
|
||||||
return {
|
|
||||||
definitions,
|
|
||||||
options,
|
|
||||||
linkageOptions,
|
|
||||||
category: 'default',
|
|
||||||
elementType: 'field',
|
|
||||||
collectionName,
|
|
||||||
// form,
|
|
||||||
variables,
|
|
||||||
localVariables,
|
|
||||||
record,
|
|
||||||
formBlockType,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
actionTitle: {
|
||||||
|
'x-component': 'h4',
|
||||||
|
'x-content': '{{ t("执行规则") }}',
|
||||||
|
},
|
||||||
|
actionsBlock: rulesSchema,
|
||||||
|
// actionsBlock: {
|
||||||
|
// type: 'void',
|
||||||
|
// 'x-component': ActionsSetting,
|
||||||
|
// 'x-use-component-props': () => {
|
||||||
|
// return {
|
||||||
|
// options,
|
||||||
|
// linkageOptions,
|
||||||
|
// category: 'default',
|
||||||
|
// elementType: 'field',
|
||||||
|
// collectionName,
|
||||||
|
// // form,
|
||||||
|
// variables,
|
||||||
|
// localVariables,
|
||||||
|
// formBlockType,
|
||||||
|
// };
|
||||||
|
// },
|
||||||
|
// },
|
||||||
remove: {
|
remove: {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
'x-component': 'ArrayCollapse.Remove',
|
'x-component': 'ArrayCollapse.Remove',
|
||||||
@ -140,7 +145,7 @@ export const EventSettingItem = (props) => {
|
|||||||
properties: {
|
properties: {
|
||||||
add: {
|
add: {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
title: '{{ t("Add events") }}',
|
title: '{{ t("添加事件") }}',
|
||||||
'x-component': 'ArrayCollapse.Addition',
|
'x-component': 'ArrayCollapse.Addition',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -150,15 +155,15 @@ export const EventSettingItem = (props) => {
|
|||||||
}
|
}
|
||||||
onSubmit={({ events }) => {
|
onSubmit={({ events }) => {
|
||||||
console.log('todo onSubmit', JSON.parse(JSON.stringify(events)));
|
console.log('todo onSubmit', JSON.parse(JSON.stringify(events)));
|
||||||
// fieldSchema[SchemaSettingsKey] = events;
|
fieldSchema[SchemaSettingsKey] = events;
|
||||||
// dn.emit('patch', {
|
dn.emit('patch', {
|
||||||
// schema: {
|
schema: {
|
||||||
// 'x-uid': fieldSchema['x-uid'],
|
'x-uid': fieldSchema['x-uid'],
|
||||||
// [SchemaSettingsKey]: events,
|
[SchemaSettingsKey]: events,
|
||||||
// },
|
},
|
||||||
// });
|
});
|
||||||
// register(events);
|
// register(events);
|
||||||
// dn.refresh();
|
dn.refresh();
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { ActionParamValueInput } from '../components/ActionParamValueInput';
|
||||||
|
|
||||||
const actionParamsSchema = {
|
const actionParamsSchema = {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
properties: {
|
properties: {
|
||||||
@ -22,7 +24,7 @@ const actionParamsSchema = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
properties: {
|
properties: {
|
||||||
key: {
|
name: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
'x-component': 'ActionParamSelect',
|
'x-component': 'ActionParamSelect',
|
||||||
'x-reactions': {
|
'x-reactions': {
|
||||||
@ -36,7 +38,21 @@ const actionParamsSchema = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
value: { type: 'string', 'x-component': 'Input' },
|
value: {
|
||||||
|
type: 'string',
|
||||||
|
'x-component': 'ActionParamValueInput',
|
||||||
|
'x-reactions': {
|
||||||
|
dependencies: ['...action', '.name'],
|
||||||
|
fulfill: {
|
||||||
|
schema: {
|
||||||
|
'x-component-props': {
|
||||||
|
action: '{{$deps[0]}}',
|
||||||
|
paramName: '{{$deps[1]}}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
removeBtn: {
|
removeBtn: {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
'x-component': 'ArrayItems.Remove',
|
'x-component': 'ArrayItems.Remove',
|
||||||
@ -62,6 +78,11 @@ export const actionsSchema = {
|
|||||||
actions: {
|
actions: {
|
||||||
type: 'array',
|
type: 'array',
|
||||||
'x-component': 'ArrayItems',
|
'x-component': 'ArrayItems',
|
||||||
|
'x-component-props': {
|
||||||
|
style: {
|
||||||
|
marginLeft: 12,
|
||||||
|
},
|
||||||
|
},
|
||||||
items: {
|
items: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
'x-component': 'Space',
|
'x-component': 'Space',
|
@ -0,0 +1,81 @@
|
|||||||
|
/**
|
||||||
|
* 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 { css } from '@emotion/css';
|
||||||
|
import { actionsSchema } from './actions';
|
||||||
|
|
||||||
|
export const rulesSchema = {
|
||||||
|
type: 'void',
|
||||||
|
properties: {
|
||||||
|
rules: {
|
||||||
|
type: 'array',
|
||||||
|
'x-component': 'ArrayCollapse',
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-component-props': {
|
||||||
|
accordion: true,
|
||||||
|
titleRender: (item: any, index: number) => {
|
||||||
|
return `规则 ${index + 1}`;
|
||||||
|
},
|
||||||
|
showEmpty: false,
|
||||||
|
},
|
||||||
|
items: {
|
||||||
|
type: 'object',
|
||||||
|
'x-component': 'ArrayCollapse.CollapsePanel',
|
||||||
|
properties: {
|
||||||
|
conditionsTitle: {
|
||||||
|
'x-component': 'h4',
|
||||||
|
'x-content': '{{ t("Condition") }}',
|
||||||
|
},
|
||||||
|
condition: {
|
||||||
|
'x-component': 'ConditionSelect',
|
||||||
|
'x-component-props': {
|
||||||
|
className: css`
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
margin-left: 12px;
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
'x-reactions': {
|
||||||
|
dependencies: ['...event'],
|
||||||
|
fulfill: {
|
||||||
|
state: {
|
||||||
|
'componentProps.event': '{{$deps[0]}}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
actionsTitle: {
|
||||||
|
'x-component': 'h4',
|
||||||
|
'x-content': '{{ t("动作") }}',
|
||||||
|
},
|
||||||
|
actionsBlock: actionsSchema,
|
||||||
|
remove: {
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'ArrayCollapse.Remove',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
properties: {
|
||||||
|
add: {
|
||||||
|
type: 'void',
|
||||||
|
title: '{{ t("添加规则") }}',
|
||||||
|
'x-component': 'ArrayCollapse.Addition',
|
||||||
|
// 'x-reactions': {
|
||||||
|
// dependencies: ['rules'],
|
||||||
|
// fulfill: {
|
||||||
|
// state: {
|
||||||
|
// disabled: '{{$deps[0].length >= 3}}',
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
@ -43,6 +43,8 @@ export const useEvent = () => {
|
|||||||
definitions: eventFlowPlugin?.definitions,
|
definitions: eventFlowPlugin?.definitions,
|
||||||
// 定义事件
|
// 定义事件
|
||||||
define,
|
define,
|
||||||
|
// 移除事件
|
||||||
|
removeDefinition: eventFlowPlugin?.removeDefinition,
|
||||||
// 运行时事件注册
|
// 运行时事件注册
|
||||||
register,
|
register,
|
||||||
// 触发事件
|
// 触发事件
|
||||||
|
Loading…
x
Reference in New Issue
Block a user