import { InfoOutlined } from '@ant-design/icons'; import { createForm } from '@formily/core'; import { ISchema, useForm } from '@formily/react'; import { ActionContextProvider, SchemaComponent, SchemaInitializerItemOptions, css, cx, useAPIClient, useActionContext, useCompile, useResourceActionContext, } from '@nocobase/client'; import { Registry } from '@nocobase/utils/client'; import { Alert, Button, Input, Tag, message } from 'antd'; import React, { useEffect, useMemo, useState } from 'react'; import { useFlowContext } from '../FlowContext'; import { DrawerDescription } from '../components/DrawerDescription'; import { NAMESPACE, lang } from '../locale'; import useStyles from '../style'; import { VariableOptions } from '../variable'; import collection from './collection'; import formTrigger from './form'; import schedule from './schedule/'; function useUpdateConfigAction() { const form = useForm(); const api = useAPIClient(); const { workflow } = useFlowContext() ?? {}; const ctx = useActionContext(); const { refresh } = useResourceActionContext(); return { async run() { if (workflow.executed) { message.error(lang('Trigger in executed workflow cannot be modified')); return; } await form.submit(); await api.resource('workflows').update?.({ filterByTk: workflow.id, values: { config: form.values, }, }); ctx.setVisible(false); refresh(); }, }; } export interface Trigger { title: string; type: string; description?: string; // group: string; useVariables?(config: any, options?): VariableOptions; fieldset: { [key: string]: ISchema }; view?: ISchema; scope?: { [key: string]: any }; components?: { [key: string]: any }; useInitializers?(config): SchemaInitializerItemOptions | null; initializers?: any; } export const triggers = new Registry(); triggers.register(formTrigger.type, formTrigger); triggers.register(collection.type, collection); triggers.register(schedule.type, schedule); function TriggerExecution() { const compile = useCompile(); const { workflow, execution } = useFlowContext(); const { styles } = useStyles(); if (!execution) { return null; } const trigger = triggers.get(workflow.type); return ( , shape: 'circle', size: 'small', className: styles.nodeJobButtonClass, type: 'primary', }, properties: { [execution.id]: { type: 'void', 'x-decorator': 'Form', 'x-decorator-props': { initialValue: execution, }, 'x-component': 'Action.Modal', title: (
{compile(trigger.title)} {workflow.title} #{execution.id}
), properties: { createdAt: { type: 'string', title: `{{t("Triggered at", { ns: "${NAMESPACE}" })}}`, 'x-decorator': 'FormItem', 'x-component': 'DatePicker', 'x-component-props': { showTime: true, }, 'x-read-pretty': true, }, context: { type: 'object', title: `{{t("Trigger variables", { ns: "${NAMESPACE}" })}}`, 'x-decorator': 'FormItem', 'x-component': 'Input.JSON', 'x-component-props': { className: css` padding: 1em; background-color: #eee; `, }, 'x-read-pretty': true, }, }, }, }, }} /> ); } export const TriggerConfig = () => { const api = useAPIClient(); const compile = useCompile(); const { workflow, refresh } = useFlowContext(); const [editingTitle, setEditingTitle] = useState(''); const [editingConfig, setEditingConfig] = useState(false); const { styles } = useStyles(); let typeTitle = ''; useEffect(() => { if (workflow) { setEditingTitle(workflow.title ?? typeTitle); } }, [workflow]); const form = useMemo( () => createForm({ initialValues: workflow?.config, values: workflow?.config, disabled: workflow?.executed, }), [workflow], ); if (!workflow || !workflow.type) { return null; } const { title, type, executed } = workflow; const trigger = triggers.get(type); const { fieldset, scope, components } = trigger; typeTitle = trigger.title; const detailText = executed ? '{{t("View")}}' : '{{t("Configure")}}'; const titleText = lang('Trigger'); async function onChangeTitle(next) { const t = next || typeTitle; setEditingTitle(t); if (t === title) { return; } await api.resource('workflows').update?.({ filterByTk: workflow.id, values: { title: t, }, }); refresh(); } function onOpenDrawer(ev) { if (ev.target === ev.currentTarget) { setEditingConfig(true); return; } const whiteSet = new Set(['workflow-node-meta', 'workflow-node-config-button', 'ant-input-disabled']); for (let el = ev.target; el && el !== ev.currentTarget; el = el.parentNode) { if ((Array.from(el.classList ?? []) as string[]).some((name: string) => whiteSet.has(name))) { setEditingConfig(true); ev.stopPropagation(); return; } } } return (
{titleText}
setEditingTitle(ev.target.value)} onBlur={(ev) => onChangeTitle(ev.target.value)} autoSize />
); }; export function useTrigger() { const { workflow } = useFlowContext(); return triggers.get(workflow.type); }