150 lines
4.2 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 React, { useContext, useEffect } from 'react';
import { App, Card, Tooltip } from 'antd';
import { onFieldChange } from '@formily/core';
import { useField, useForm, useFormEffects } from '@formily/react';
import {
SchemaComponent,
SchemaComponentContext,
useActionContext,
useApp,
usePlugin,
useRecord,
useResourceActionContext,
useResourceContext,
} from '@nocobase/client';
import { ExecutionLink } from './ExecutionLink';
import { ExecutionResourceProvider } from './ExecutionResourceProvider';
import { WorkflowLink } from './WorkflowLink';
import OpenDrawer from './components/OpenDrawer';
import { workflowSchema } from './schemas/workflows';
import { ExecutionStatusSelect, ExecutionStatusColumn } from './components/ExecutionStatus';
import WorkflowPlugin, { RadioWithTooltip } from '.';
import { useRefreshActionProps } from './hooks/useRefreshActionProps';
import { useTranslation } from 'react-i18next';
function SyncOptionSelect(props) {
const field = useField<any>();
const record = useRecord();
const workflowPlugin = usePlugin(WorkflowPlugin);
useFormEffects((form) => {
onFieldChange('type', (f: any) => {
let disabled = record.id || !f.value;
if (f.value) {
const trigger = workflowPlugin.triggers.get(f.value);
if (trigger.sync != null) {
disabled = true;
field.setValue(trigger.sync);
} else {
field.setInitialValue(false);
}
}
field.setPattern(disabled ? 'disabled' : 'editable');
});
});
useEffect(() => {
if (record.id) {
field.setPattern('disabled');
const trigger = workflowPlugin.triggers.get(record.type);
if (trigger.sync != null) {
field.setValue(trigger.sync);
} else {
field.setInitialValue(false);
}
}
}, [record.id, field, workflowPlugin.triggers]);
return <RadioWithTooltip {...props} />;
}
function useWorkflowSyncReaction(field) {
const app = useApp();
field.visible = Boolean(usePlugin('multi-app-share-collection') || app.name !== 'main');
}
function useSyncAction() {
const { message } = App.useApp();
const { t } = useTranslation();
const { resource } = useResourceContext();
return {
async run() {
await resource.sync();
message.success(t('Operation succeeded'));
},
};
}
function useRevisionAction() {
const { message } = App.useApp();
const { t } = useTranslation();
const { refresh } = useResourceActionContext();
const { resource, targetKey } = useResourceContext();
const { setVisible } = useActionContext();
const { [targetKey]: filterByTk } = useRecord();
const form = useForm();
const field = useField();
return {
async run() {
try {
await form.submit();
field.data = field.data || {};
field.data.loading = true;
await resource.revision({ filterByTk, values: form.values });
message.success(t('Operation succeeded'));
refresh();
setVisible(false);
} catch (error) {
console.error(error);
} finally {
if (field.data) {
field.data.loading = false;
}
}
},
};
}
export function WorkflowPane() {
const ctx = useContext(SchemaComponentContext);
const { useTriggersOptions } = usePlugin(WorkflowPlugin);
return (
<Card bordered={false}>
<SchemaComponentContext.Provider value={{ ...ctx, designable: false }}>
<SchemaComponent
schema={workflowSchema}
components={{
WorkflowLink,
ExecutionResourceProvider,
ExecutionLink,
OpenDrawer,
ExecutionStatusSelect,
SyncOptionSelect,
ExecutionStatusColumn,
Tooltip,
}}
scope={{
useTriggersOptions,
useWorkflowSyncReaction,
useSyncAction,
useRefreshActionProps,
useRevisionAction,
}}
/>
</SchemaComponentContext.Provider>
</Card>
);
}