feat: 审批编辑

Reviewed-on: daoyoucloud/tachybase#1242
Reviewed-by: sealday <zhanglin@daoyoucloud.com>
Co-authored-by: bai.zixv <bai.zixv@foxmail.com>
Co-committed-by: bai.zixv <bai.zixv@foxmail.com>
This commit is contained in:
bai.zixv 2024-06-28 14:38:40 +08:00 committed by sealday
parent e772d9ad2b
commit e10e627d1c
6 changed files with 100 additions and 22 deletions

View File

@ -10,3 +10,4 @@ export * from './fieldSettingsFormItem';
export * from './formActionInitializers'; export * from './formActionInitializers';
export * from './formItemInitializers'; export * from './formItemInitializers';
export * from './updateFormActionInitializers'; export * from './updateFormActionInitializers';
export * from './createEditFormBlockUISchema';

View File

@ -17,11 +17,8 @@ import { ApprovalFormBlockProvider } from './VC.ApprovalFormBlockProvider';
export const ApproverBlock = ({ value: srcID, onChange }) => { export const ApproverBlock = ({ value: srcID, onChange }) => {
const apiClient = useAPIClient(); const apiClient = useAPIClient();
// const workflowPlugin = usePlugin(PluginWorkflow);
const { values, setValuesIn } = useForm(); const { values, setValuesIn } = useForm();
const { setFormValueChanged } = useContext(ContextApproverConfig) as any; const { setFormValueChanged } = useContext(ContextApproverConfig) as any;
// const current = useNodeContext();
// const nodes = useAvailableUpstreams(current);
const onChangeFunc = useCallback( const onChangeFunc = useCallback(
(data) => { (data) => {
const flatSet = flatSchemaArray( const flatSet = flatSchemaArray(
@ -42,7 +39,7 @@ export const ApproverBlock = ({ value: srcID, onChange }) => {
[setFormValueChanged, setValuesIn, values.actions], [setFormValueChanged, setValuesIn, values.actions],
); );
const { data, loading } = useRequest(async () => { const { data: schemaData, loading } = useRequest(async () => {
if (srcID) { if (srcID) {
const { data: serviceData } = await apiClient.request({ url: `uiSchemas:getJsonSchema/${srcID}` }); const { data: serviceData } = await apiClient.request({ url: `uiSchemas:getJsonSchema/${srcID}` });
if (serviceData?.data?.['x-uid'] === srcID) { if (serviceData?.data?.['x-uid'] === srcID) {
@ -88,7 +85,7 @@ export const ApproverBlock = ({ value: srcID, onChange }) => {
SimpleDesigner, SimpleDesigner,
}} }}
// @ts-ignore // @ts-ignore
schema={data} schema={schemaData}
onChange={onChangeFunc} onChange={onChangeFunc}
/> />
</ContextApproverBlock.Provider> </ContextApproverBlock.Provider>

View File

@ -2,16 +2,19 @@ import React, { useContext, useState } from 'react';
import { import {
createStyles, createStyles,
ExtendCollectionsProvider, ExtendCollectionsProvider,
parseCollectionName,
RecordProvider, RecordProvider,
SchemaComponent, SchemaComponent,
SchemaComponentContext, SchemaComponentContext,
} from '@tachybase/client'; } from '@tachybase/client';
import { useForm } from '@tachybase/schema';
import { uid } from '@tachybase/utils/client'; import { uid } from '@tachybase/utils/client';
import { useFlowContext } from '../../../../../FlowContext'; import { useFlowContext } from '../../../../../FlowContext';
import { CollectionApprovalTodos } from '../../../common/Cn.ApprovalTodos'; import { CollectionApprovalTodos } from '../../../common/Cn.ApprovalTodos';
import { NAMESPACE } from '../../../locale'; import { NAMESPACE } from '../../../locale';
import { ApproverBlock } from './VC.ApproverBlock'; import { SchemaAddBlock } from '../../trigger/launcher-interface/SchemaAddBlock.component';
import { ApproverBlock } from './ApproverBlock.view';
const useStyles = createStyles(({ css }) => { const useStyles = createStyles(({ css }) => {
return { return {
@ -30,6 +33,8 @@ export const ApproverInterfaceComponent = () => {
const { workflow } = useFlowContext(); const { workflow } = useFlowContext();
const { styles } = useStyles(); const { styles } = useStyles();
const commentFields = CollectionApprovalTodos.fields.filter((field) => field.name === 'comment'); const commentFields = CollectionApprovalTodos.fields.filter((field) => field.name === 'comment');
const schema = getSchema({ styles });
return ( return (
<ExtendCollectionsProvider <ExtendCollectionsProvider
collections={[ collections={[
@ -48,25 +53,32 @@ export const ApproverInterfaceComponent = () => {
> >
<RecordProvider record={{}} parent={false}> <RecordProvider record={{}} parent={false}>
<SchemaComponent <SchemaComponent
components={{ SchemaContent: ApproverBlock }} components={{
schema={{ ApproverBlock,
name: 'drawer', SchemaAddBlock,
type: 'void',
title: `{{t("Approver's interface", { ns: "${NAMESPACE}" })}}`,
'x-component': 'Action.Drawer',
'x-component-props': {
className: styles.container,
},
properties: {
applyDetail: {
type: 'string',
'x-component': 'SchemaContent',
},
},
}} }}
schema={schema}
/> />
</RecordProvider> </RecordProvider>
</SchemaComponentContext.Provider> </SchemaComponentContext.Provider>
</ExtendCollectionsProvider> </ExtendCollectionsProvider>
); );
}; };
function getSchema({ styles }) {
return {
name: 'drawer',
type: 'void',
title: `{{t("Approver's interface", { ns: "${NAMESPACE}" })}}`,
'x-component': 'Action.Drawer',
'x-component-props': {
className: styles.container,
},
properties: {
applyDetail: {
type: 'string',
'x-component': 'ApproverBlock',
},
},
};
}

View File

@ -0,0 +1,45 @@
import React from 'react';
import {
createEditFormBlockUISchema,
createFormBlockSchema,
parseCollectionName,
SchemaInitializerItem,
useRecordCollectionDataSourceItems,
useSchemaInitializer,
useSchemaInitializerItem,
useSchemaTemplateManager,
} from '@tachybase/client';
import { useForm } from '@tachybase/schema';
import { APPROVAL_STATUS, flatSchemaArray } from '../../../constants';
export const EditableForm = () => {
const { insert } = useSchemaInitializer();
const { getTemplateSchemaByMode } = useSchemaTemplateManager();
const { values } = useForm();
const [dataSource, collectionName] = parseCollectionName(values.collection);
const itemConfig = useSchemaInitializerItem();
const items = useRecordCollectionDataSourceItems('FormItem');
const onClick = async ({ item }) => {
const template = item.template ? await getTemplateSchemaByMode(item) : null;
const formSchema = createEditFormBlockUISchema({
dataSource: dataSource,
collectionName: collectionName,
templateSchema: template,
});
const [key] = Object.keys(formSchema.properties);
const [targetSchema] = flatSchemaArray(
formSchema.properties[key],
(property) => property['x-component'] === 'ActionBar',
);
targetSchema['x-decorator'] = 'ActionBarProvider';
targetSchema['x-component-props'].style = { marginTop: '1.5em', flexWrap: 'wrap' };
insert(formSchema);
};
return <SchemaInitializerItem {...itemConfig} onClick={onClick} items={items} />;
};

View File

@ -5,6 +5,7 @@ import { useAvailableUpstreams, useNodeContext } from '../../../../../nodes';
import { PluginWorkflow } from '../../../../../Plugin'; import { PluginWorkflow } from '../../../../../Plugin';
import { useTrigger } from '../../../../../triggers'; import { useTrigger } from '../../../../../triggers';
import { NAMESPACE } from '../../../locale'; import { NAMESPACE } from '../../../locale';
import { EditableForm } from './EditableForm.schema';
import { ApproverAddBlockComponent } from './VC.ApproverAddBlock'; import { ApproverAddBlockComponent } from './VC.ApproverAddBlock';
import { ApproverAddBlockKit } from './VC.ApproverAddBlockKit'; import { ApproverAddBlockKit } from './VC.ApproverAddBlockKit';
@ -32,6 +33,19 @@ export const ApproverAddBlockInitializer = new SchemaInitializer({
}, },
], ],
}, },
{
name: 'forms',
type: 'itemGroup',
title: '{{t("Form")}}',
children: [
{
name: 'form',
type: 'item',
title: `{{t("Apply form", { ns: "${NAMESPACE}" })}}`,
Component: EditableForm,
},
],
},
{ {
type: 'itemGroup', type: 'itemGroup',
name: 'dataBlocks', name: 'dataBlocks',

View File

@ -4,6 +4,7 @@ import { ArrayItems } from '@tachybase/components';
import { uid } from '@tachybase/utils/client'; import { uid } from '@tachybase/utils/client';
import { RadioWithTooltip } from '../../../../components'; import { RadioWithTooltip } from '../../../../components';
import { useWorkflowAnyExecuted } from '../../../../hooks';
import { Instruction } from '../../../../nodes'; import { Instruction } from '../../../../nodes';
import { APPROVAL_ACTION_STATUS } from '../../constants'; import { APPROVAL_ACTION_STATUS } from '../../constants';
import { NAMESPACE } from '../../locale'; import { NAMESPACE } from '../../locale';
@ -12,7 +13,7 @@ import { AssigneesSelect } from './approval-config/VC.AssigneesSelect';
import { ContentTooltip } from './approval-config/VC.ContentTooltip'; import { ContentTooltip } from './approval-config/VC.ContentTooltip';
import { NegotiationConfig } from './approval-config/VC.NegotiationConfig'; import { NegotiationConfig } from './approval-config/VC.NegotiationConfig';
import { SchemaConfigButtonApprover } from './approval-config/VC.SchemaConfigButtonApprover'; import { SchemaConfigButtonApprover } from './approval-config/VC.SchemaConfigButtonApprover';
import { ApproverInterfaceComponent } from './approver-interface/VC.ApproverInterface'; import { ApproverInterfaceComponent } from './approver-interface/ApproverInterface.schema';
import { isApprovalReturnFunc } from './utils'; import { isApprovalReturnFunc } from './utils';
import { ApprovalInstructionNode } from './VC.ApprovalInstructionNode'; import { ApprovalInstructionNode } from './VC.ApprovalInstructionNode';
@ -41,6 +42,13 @@ export class ApprovalInstruction extends Instruction {
]; ];
// 审批节点表单设置 // 审批节点表单设置
fieldset = { fieldset = {
collection: {
type: 'string',
title: '{{t("Collection")}}',
'x-decorator': 'FormItem',
'x-component': 'DataSourceCollectionCascader',
// 'x-disabled': '{{ useWorkflowAnyExecuted() }}',
},
branchMode: { branchMode: {
type: 'boolean', type: 'boolean',
title: `{{t("Pass mode", { ns: "${NAMESPACE}" })}}`, title: `{{t("Pass mode", { ns: "${NAMESPACE}" })}}`,
@ -175,6 +183,7 @@ export class ApprovalInstruction extends Instruction {
}, },
}; };
// 审批节点组件 // 审批节点组件
scope = { useWorkflowAnyExecuted };
Component = ApprovalInstructionNode; Component = ApprovalInstructionNode;
components = { components = {
ArrayItems, ArrayItems,