0e7cb9e5cf
* refactor(plugin-workflow): split manual and dynamic calculation into plugins * refactor(plugin-workflow): move loop to plugin * refactor(plugin-workflow): move parallel to plugin * fix(plugin-dynamic-calculation): fix package title * fix(plugin-workflow): fix plugin name * refactor(plugin-workflow): move delay to plugin * refactor(plugin-workflow): simplify exporting names * refactor(plugin-workflow): move aggregate to plugin * refactor(plugin-workflow): move sql to plugin * refactor(plugin-workflow): move reqeust to plugin * refactor(plugin-workflow): move form trigger to plugin * refactor(plugin-workflow): move locale to plugins * fix(plugin-workflow): fix test cases * fix(plugin-workflow-request): package name typo * fix(plugin-workflow): remove clean db from testkit * fix(plugin-workflow-sql): skip independent case * fix(plugin-workflow-sql): skip independent case * fix(plugin-workflow-delay): fix test cases * test(plugin-workflow-delay): fix test cases * test(plugin-workflow-delay): fix test cases * test(plugin-workflow-delay): fix test cases * test(plugin-workflow-delay): fix test cases * fix(plugin-workflow): fix migration version matching * test(plugin-workflow): fix test case * refactor(plugin-workflow): correct exporting of testkit * fix(plugin-workflow): fix testkit and require module * refactor(plugin-workflow): add workflow-test package for testing * test(plugin-workflow): test weird case * fix(plugin-workflow-test): remove workflow dependency to avoid cycling * fix(plugin-workflow): fix migration version * fix(plugin-workflow): fix migration and packages * fix(plugin-workflow): fix package dependencies * fix(preset): fix builtin list in preset * fix(plugin-workflow): add package entry file * fix(plugin-workflow): fix migrations * refactor(plugin-workflow): remove require * fix(plugin-workflow): fix locale namespace * fix(plugin-workflow): fix merged errors * fix(plugin-workflow): fix import cycling references * refactor(plugin-workflow): change instruction and triggers to classes in client * fix(plugin-workflow): fix migration version
126 lines
3.8 KiB
TypeScript
126 lines
3.8 KiB
TypeScript
import React, { useCallback, useMemo } from 'react';
|
|
import { Button, Dropdown, MenuProps } from 'antd';
|
|
import { PlusOutlined } from '@ant-design/icons';
|
|
|
|
import { css, useAPIClient, useCompile, usePlugin } from '@nocobase/client';
|
|
|
|
import WorkflowPlugin from '.';
|
|
import { useFlowContext } from './FlowContext';
|
|
import { NAMESPACE } from './locale';
|
|
import { Instruction } from './nodes';
|
|
import useStyles from './style';
|
|
|
|
interface AddButtonProps {
|
|
upstream;
|
|
branchIndex?: number | null;
|
|
[key: string]: any;
|
|
}
|
|
|
|
export function AddButton(props: AddButtonProps) {
|
|
const { upstream, branchIndex = null } = props;
|
|
const { instructions } = usePlugin(WorkflowPlugin);
|
|
const compile = useCompile();
|
|
const api = useAPIClient();
|
|
const { workflow, refresh } = useFlowContext() ?? {};
|
|
const instructionList = Array.from(instructions.getValues()) as Instruction[];
|
|
const { styles } = useStyles();
|
|
|
|
const groups = useMemo(() => {
|
|
return [
|
|
{ key: 'control', label: `{{t("Control", { ns: "${NAMESPACE}" })}}` },
|
|
{ key: 'collection', label: `{{t("Collection operations", { ns: "${NAMESPACE}" })}}` },
|
|
{ key: 'manual', label: `{{t("Manual", { ns: "${NAMESPACE}" })}}` },
|
|
{ key: 'extended', label: `{{t("Extended types", { ns: "${NAMESPACE}" })}}` },
|
|
]
|
|
.filter((group) => instructionList.filter((item) => item.group === group.key).length)
|
|
.map((group) => {
|
|
const groupInstructions = instructionList.filter(
|
|
(item) =>
|
|
item.group === group.key &&
|
|
(item.isAvailable ? item.isAvailable({ workflow, upstream, branchIndex }) : true),
|
|
);
|
|
|
|
return {
|
|
...group,
|
|
type: 'group',
|
|
children: groupInstructions.map((item) => ({
|
|
role: 'button',
|
|
'aria-label': item.type,
|
|
key: item.type,
|
|
label: item.title,
|
|
type: item.options ? 'subMenu' : null,
|
|
children: item.options
|
|
? item.options.map((option) => ({
|
|
role: 'button',
|
|
'aria-label': option.key,
|
|
key: option.key,
|
|
label: option.label,
|
|
}))
|
|
: null,
|
|
})),
|
|
};
|
|
});
|
|
}, [branchIndex, instructionList, upstream, workflow]);
|
|
const resource = useMemo(() => {
|
|
if (!workflow) {
|
|
return null;
|
|
}
|
|
return api.resource('workflows.nodes', workflow.id);
|
|
}, [workflow?.id]);
|
|
const onCreate = useCallback(
|
|
async ({ keyPath }) => {
|
|
const type = keyPath.pop();
|
|
const config = {};
|
|
const [optionKey] = keyPath;
|
|
const instruction = instructions.get(type);
|
|
if (optionKey) {
|
|
const { value } = instruction.options?.find((item) => item.key === optionKey) ?? {};
|
|
Object.assign(config, typeof value === 'function' ? value() : value);
|
|
}
|
|
|
|
if (resource) {
|
|
await resource.create({
|
|
values: {
|
|
type,
|
|
upstreamId: upstream?.id ?? null,
|
|
branchIndex,
|
|
title: compile(instruction.title),
|
|
config,
|
|
},
|
|
});
|
|
refresh();
|
|
}
|
|
},
|
|
[branchIndex, resource?.create, upstream?.id],
|
|
);
|
|
|
|
const menu = useMemo<MenuProps>(() => {
|
|
return {
|
|
onClick: onCreate,
|
|
items: compile(groups),
|
|
};
|
|
}, [groups, onCreate]);
|
|
|
|
if (!workflow) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<div className={styles.addButtonClass}>
|
|
<Dropdown
|
|
trigger={['click']}
|
|
menu={menu}
|
|
disabled={workflow.executed}
|
|
overlayClassName={css`
|
|
.ant-dropdown-menu-root {
|
|
max-height: 30em;
|
|
overflow-y: auto;
|
|
}
|
|
`}
|
|
>
|
|
<Button aria-label={props['aria-label'] || 'add-button'} shape="circle" icon={<PlusOutlined />} />
|
|
</Dropdown>
|
|
</div>
|
|
);
|
|
}
|