feat: improve approval (#820)
Co-authored-by: bai.zixv <bai.zixv@foxmail.com> Reviewed-on: daoyoucloud/tachybase#820
This commit is contained in:
parent
a30a214ac0
commit
e9c4ade676
@ -4,7 +4,7 @@ import { APPROVAL_ACTION_STATUS } from '../../../constants';
|
||||
import { ApprovalActionConfigComponent } from './VC.ApprovalActionConfig';
|
||||
|
||||
export const ApproverActionConfigInitializer = new SchemaInitializer({
|
||||
name: 'ApprovalProcessAddActionButton',
|
||||
name: 'ApproverActionConfigInitializer',
|
||||
title: '{{t("Configure actions")}}',
|
||||
items: [
|
||||
{
|
||||
|
@ -10,7 +10,7 @@ import { ApproverAddBlockComponent } from './VC.ApproverAddBlock';
|
||||
import { ApproverAddBlockKit } from './VC.ApproverAddBlockKit';
|
||||
|
||||
export const ApproverAddBlockInitializer = new SchemaInitializer({
|
||||
name: 'ApprovalProcessAddBlockButton',
|
||||
name: 'ApproverAddBlockInitializer',
|
||||
wrap: gridRowColWrap,
|
||||
title: "{{t('Add block')}}",
|
||||
items: [
|
||||
|
@ -9,7 +9,7 @@ import { flatSchemaArray } from '../../../constants';
|
||||
export const ApproverAddBlockKit = () => {
|
||||
const itemConfig = useSchemaInitializerItem();
|
||||
const formSchema = createFormBlockSchema({
|
||||
actionInitializers: 'ApprovalProcessAddActionButton',
|
||||
actionInitializers: 'ApproverActionConfigInitializer',
|
||||
actions: {
|
||||
approve: {
|
||||
type: 'void',
|
||||
|
@ -54,7 +54,7 @@ export const ApproverBlock = ({ value: srcID, onChange }) => {
|
||||
name: id,
|
||||
'x-uid': id,
|
||||
'x-component': 'Grid',
|
||||
'x-initializer': 'ApprovalProcessAddBlockButton',
|
||||
'x-initializer': 'ApproverAddBlockInitializer',
|
||||
properties: {},
|
||||
};
|
||||
|
||||
|
@ -10,11 +10,8 @@ export default class PluginKitApprovalTrigger extends Plugin {
|
||||
async load() {
|
||||
const workflowPlugin = this.app.pm.get(PluginWorkflow);
|
||||
workflowPlugin.registerTrigger('approval', ApprovalTrigger);
|
||||
// workflowPlugin.registerInstruction('approval', ApprovalInstruction);
|
||||
|
||||
this.app.schemaInitializerManager.add(LauncherActionConfigInitializer);
|
||||
this.app.schemaInitializerManager.add(LauncherAddBlockButtonIntializer);
|
||||
// this.app.schemaInitializerManager.add(ApproverActionConfigInitializer);
|
||||
// this.app.schemaInitializerManager.add(ApproverAddBlockInitializer);
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ import { SchemaInitializerItem, useSchemaInitializer, useSchemaInitializerItem }
|
||||
import { uid } from '@nocobase/utils/client';
|
||||
import React from 'react';
|
||||
import { NAMESPACE } from '../../locale';
|
||||
import { PathNameMap_ApprovalBlock } from './map';
|
||||
|
||||
// 创建区块-审批(发起/待办)
|
||||
export const ApprovalBlockComponent = () => {
|
||||
@ -54,7 +53,7 @@ export const ApprovalBlockComponent = () => {
|
||||
name: id,
|
||||
'x-uid': id,
|
||||
'x-component': 'CardItem',
|
||||
'x-decorator': PathNameMap_ApprovalBlock.Decorator,
|
||||
'x-decorator': 'ApprovalBlock.Decorator',
|
||||
'x-decorator-props': {
|
||||
collection: item.collection,
|
||||
action: 'listCentralized',
|
||||
|
@ -1,5 +1,3 @@
|
||||
// import { PathNameMap_ApprovalBlock } from '../map';
|
||||
import { ApprovalBlock } from '../map';
|
||||
import { NAMESPACE } from '../../../locale';
|
||||
import { css } from '@nocobase/client';
|
||||
|
||||
@ -66,7 +64,6 @@ export const SchemaApprovalBlockLaunch = {
|
||||
title: '{{t("Actions")}}',
|
||||
properties: {
|
||||
action: {
|
||||
// 'x-component': PathNameMap_ApprovalBlock.ViewActionLaunch,
|
||||
'x-component': 'ApprovalBlock.ViewActionLaunch',
|
||||
},
|
||||
},
|
||||
|
@ -24,7 +24,6 @@ import { ActionBarProvider } from './Pd.ActionBar';
|
||||
import { WithdrawActionProvider } from './Pd.WithdrawAction';
|
||||
import { SchemaComponentContextProvider } from '../common/Pd.SchemaComponent';
|
||||
import { ApplyActionStatusProvider } from './Pd.ApplyActionStatus';
|
||||
import { ApprovalCommon } from '../../approval-common/map';
|
||||
import { FlowContextProvider } from '../common/Pd.FlowContext';
|
||||
|
||||
export const ViewActionLaunchContent = () => {
|
||||
@ -136,7 +135,7 @@ export const ViewActionLaunchContent = () => {
|
||||
process: {
|
||||
type: 'void',
|
||||
'x-decorator': 'CardItem',
|
||||
'x-component': ApprovalCommon.PathNameMap.ViewComponent.ApprovalProcess,
|
||||
'x-component': 'ApprovalCommon.ViewComponent.ApprovalProcess',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -1,31 +0,0 @@
|
||||
import { ViewActionTodos } from './todos/VC.ViewActionTodos';
|
||||
import { ApprovalBlockComponent } from './VC.ApprovalBlock';
|
||||
import { ApprovalBlockTodos } from './todos/VC.ApprovalBlockTodos';
|
||||
import { ViewActionLaunch } from './launch/VC.ViewActionLaunch';
|
||||
import { ApprovalBlockDecorator } from './Dt.ApprovalBlock';
|
||||
|
||||
import { ApprovalBlockLaunch } from './launch/VC.ApprovalBlockLaunch';
|
||||
|
||||
// 区块-审批
|
||||
export const ApprovalBlock = () => null;
|
||||
|
||||
export const PathNameMap_ApprovalBlock = {
|
||||
Decorator: 'ApprovalBlock.Decorator',
|
||||
BlockInitializer: 'ApprovalBlock.BlockInitializer',
|
||||
Launch: 'ApprovalBlock.Launch',
|
||||
Todos: 'ApprovalBlock.Todos',
|
||||
ViewActionLaunch: 'ApprovalBlock.ViewActionLaunch',
|
||||
ViewActionTodos: 'ApprovalBlock.ViewActionTodos',
|
||||
};
|
||||
|
||||
ApprovalBlock.Decorator = ApprovalBlockDecorator;
|
||||
|
||||
ApprovalBlock.BlockInitializer = ApprovalBlockComponent;
|
||||
|
||||
ApprovalBlock.Launch = ApprovalBlockLaunch;
|
||||
|
||||
ApprovalBlock.Todos = ApprovalBlockTodos;
|
||||
|
||||
ApprovalBlock.ViewActionLaunch = ViewActionLaunch;
|
||||
|
||||
ApprovalBlock.ViewActionTodos = ViewActionTodos;
|
@ -5,7 +5,6 @@ import {
|
||||
FormBlockContext,
|
||||
FormV2,
|
||||
RecordProvider,
|
||||
SchemaComponent,
|
||||
useAPIClient,
|
||||
useAssociationNames,
|
||||
useCurrentUserContext,
|
||||
@ -23,36 +22,40 @@ export function ApprovalFormBlockDecorator(props) {
|
||||
const omitApproval = _.omit(approvalExecutions, ['approval', 'job', 'node', 'snapshot']);
|
||||
const { execution, workflow } = useFlowContext();
|
||||
const fieldSchema = useFieldSchema();
|
||||
|
||||
const field = useField();
|
||||
const ref = useRef(null);
|
||||
const formBlockRef = useRef(null);
|
||||
const { getAssociationAppends } = useAssociationNames();
|
||||
const { appends, updateAssociationValues } = getAssociationAppends();
|
||||
const { data } = useCurrentUserContext();
|
||||
const { findComponent } = useDesignable();
|
||||
const component = findComponent(field.component?.[0]) || Fragment;
|
||||
const ContainerFormComp = findComponent(field.component?.[0]) || Fragment;
|
||||
|
||||
const form = useMemo(() => {
|
||||
return createForm({
|
||||
initialValues: omitApproval,
|
||||
pattern:
|
||||
!workflow.enabled || execution.status || job.status || omitApproval.status == null
|
||||
!workflow?.enabled || execution?.status || job?.status || omitApproval?.status == null
|
||||
? 'disabled'
|
||||
: omitApproval.status || data.data?.id !== omitApproval.userId
|
||||
? 'readPretty'
|
||||
: 'editable',
|
||||
});
|
||||
}, [data.data?.id, omitApproval.status, workflow.enabled]);
|
||||
}, [data.data?.id, omitApproval?.status, workflow?.enabled]);
|
||||
|
||||
const params = useMemo(() => ({ appends: appends, ...props.params }), [appends, props.params]);
|
||||
const result = useMemo(() => ({ loading: false, data: { data: omitApproval } }), [omitApproval]);
|
||||
const collectionApi = useAPIClient().resource(props.collection);
|
||||
const blockRequestContext = useContext(BlockRequestContext_deprecated);
|
||||
const request = useMemo(
|
||||
|
||||
const formValue = useMemo(
|
||||
() => ({
|
||||
params: params,
|
||||
form: form,
|
||||
field: field,
|
||||
service: result,
|
||||
updateAssociationValues: updateAssociationValues,
|
||||
formBlockRef: ref,
|
||||
formBlockRef: formBlockRef,
|
||||
}),
|
||||
[field, form, params, result, updateAssociationValues],
|
||||
);
|
||||
@ -76,13 +79,13 @@ export function ApprovalFormBlockDecorator(props) {
|
||||
__parent: blockRequestContext,
|
||||
}}
|
||||
>
|
||||
<FormBlockContext.Provider value={request}>
|
||||
<SchemaComponent component={component} {...field.componentProps}>
|
||||
<FormBlockContext.Provider value={formValue}>
|
||||
<ContainerFormComp {...field.componentProps}>
|
||||
<FormV2.Templates key={1} style={{ marginBottom: 18 }} form={form} />
|
||||
<div key={2} ref={ref}>
|
||||
<div key={2} ref={formBlockRef}>
|
||||
<RecursionField schema={fieldSchema} onlyRenderProperties={true} />
|
||||
</div>
|
||||
</SchemaComponent>
|
||||
</ContainerFormComp>
|
||||
</FormBlockContext.Provider>
|
||||
</BlockRequestContext_deprecated.Provider>
|
||||
</FormActiveFieldsProvider>
|
||||
|
@ -13,11 +13,11 @@ export function useContextApprovalAction() {
|
||||
}
|
||||
|
||||
export function ApprovalActionProvider({ children, ...props }) {
|
||||
const context = useContextApprovalExecutions();
|
||||
const { status } = useContextApprovalExecutions();
|
||||
|
||||
if (context && context.status !== props.status) {
|
||||
return null;
|
||||
if (!status || status === props.status) {
|
||||
return <ContextApprovalAction.Provider value={props}>{children}</ContextApprovalAction.Provider>;
|
||||
}
|
||||
|
||||
return <ContextApprovalAction.Provider value={props}>{children}</ContextApprovalAction.Provider>;
|
||||
return null;
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
// @ts-nocheck
|
||||
import {
|
||||
RemoteSchemaComponent,
|
||||
SchemaComponent,
|
||||
@ -11,26 +10,26 @@ import { DetailsBlockProvider, ExecutionContextProvider } from '@nocobase/plugin
|
||||
import { Result, Spin } from 'antd';
|
||||
import _ from 'lodash';
|
||||
import React, { useContext } from 'react';
|
||||
import { FormBlockProvider } from '../../../common/Pd.FormBlock';
|
||||
import { NAMESPACE, useTranslation } from '../../../locale';
|
||||
import { ApprovalContext } from '../../approval-common/Pd.ApprovalData';
|
||||
import { ContextWithActionEnabled } from '../../approval-common/Pd.WithActionEnabled';
|
||||
import { ContextApprovalExecution } from '../common/Pd.ApprovalExecution';
|
||||
import { ContextApprovalExecutions } from './Pd.ApprovalExecutions';
|
||||
import { NAMESPACE, useTranslation } from '../../../locale';
|
||||
import { FormBlockProvider } from '../../../common/Pd.FormBlock';
|
||||
import { ApprovalContext } from '../../approval-common/Pd.ApprovalData';
|
||||
import { ApprovalCommon } from '../../approval-common/map';
|
||||
import { SchemaComponentContextProvider } from '../common/Pd.SchemaComponent';
|
||||
import { useApprovalDetailBlockProps } from './hooks/useApprovalDetailBlockProps';
|
||||
import { useApprovalFormBlockProps } from './hooks/useApprovalFormBlockProps';
|
||||
import { useSubmit } from './hooks/useSubmit';
|
||||
import { ApprovalFormBlockDecorator } from './Dt.ApprovalFormBlock';
|
||||
import { ActionBarProvider } from './Pd.ActionBarProvider';
|
||||
import { ApprovalActionProvider } from './Pd.ApprovalAction';
|
||||
import { ContextApprovalExecutions } from './Pd.ApprovalExecutions';
|
||||
import { useApprovalDetailBlockProps } from './hooks/useApprovalDetailBlockProps';
|
||||
import { useApprovalFormBlockProps } from './hooks/useApprovalFormBlockProps';
|
||||
import { useSubmit } from './hooks/useSubmit';
|
||||
|
||||
// 审批-待办-查看: 内容
|
||||
export const ViewActionTodosContent = () => {
|
||||
const { id } = useRecord();
|
||||
const { t } = useTranslation();
|
||||
const { actionEnabled } = useContext(ContextWithActionEnabled);
|
||||
const { loading, data } = useRequest(
|
||||
const { loading, data: data }: any = useRequest(
|
||||
{
|
||||
resource: 'approvalRecords',
|
||||
action: 'get',
|
||||
@ -68,15 +67,19 @@ export const ViewActionTodosContent = () => {
|
||||
},
|
||||
{ refreshDeps: [id] },
|
||||
);
|
||||
|
||||
if (loading) return <Spin />;
|
||||
if (!(data != null && data.data))
|
||||
|
||||
if (data == null || !data.data) {
|
||||
return <Result status="error" title={t('Submission may be withdrawn, please try refresh the list.')} />;
|
||||
}
|
||||
|
||||
const items = data.data;
|
||||
const { approvalExecution, node, approval, workflow } = items;
|
||||
const { approvalExecution, node, approval, workflow, execution } = items;
|
||||
const { nodes } = workflow;
|
||||
const omitWorkflow = _.omit(workflow, ['nodes']);
|
||||
const { execution } = items;
|
||||
// return null;
|
||||
node?.config.applyDetail;
|
||||
|
||||
return (
|
||||
<ExecutionContextProvider workflow={omitWorkflow} nodes={nodes} execution={execution}>
|
||||
<ApprovalContext.Provider value={approval}>
|
||||
@ -84,9 +87,9 @@ export const ViewActionTodosContent = () => {
|
||||
<ContextApprovalExecutions.Provider value={data.data}>
|
||||
<SchemaComponent
|
||||
components={{
|
||||
SchemaComponentProvider: SchemaComponentProvider,
|
||||
RemoteSchemaComponent: RemoteSchemaComponent,
|
||||
SchemaComponentContextProvider: SchemaComponentContextProvider,
|
||||
SchemaComponentProvider,
|
||||
RemoteSchemaComponent,
|
||||
SchemaComponentContextProvider,
|
||||
FormBlockProvider,
|
||||
ActionBarProvider,
|
||||
ApprovalActionProvider,
|
||||
@ -113,7 +116,9 @@ export const ViewActionTodosContent = () => {
|
||||
detail: {
|
||||
type: 'void',
|
||||
'x-decorator': 'SchemaComponentContextProvider',
|
||||
'x-decorator-props': { designable: false },
|
||||
'x-decorator-props': {
|
||||
designable: false,
|
||||
},
|
||||
'x-component': 'RemoteSchemaComponent',
|
||||
'x-component-props': {
|
||||
uid: node?.config.applyDetail,
|
||||
@ -134,7 +139,7 @@ export const ViewActionTodosContent = () => {
|
||||
history: {
|
||||
type: 'void',
|
||||
'x-decorator': 'CardItem',
|
||||
'x-component': ApprovalCommon.ViewComponent.ApprovalProcess,
|
||||
'x-component': 'ApprovalCommon.ViewComponent.ApprovalProcess',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -1,12 +1,15 @@
|
||||
import { Plugin } from '@nocobase/client';
|
||||
import { ApprovalCommon } from './map';
|
||||
import { ApprovalDataProvider } from './Pd.ApprovalData';
|
||||
import { ApprovalProcess } from './VC.ApprovalProcess';
|
||||
|
||||
export default class PluginKitApprovalCommon extends Plugin {
|
||||
async afterAdd() {}
|
||||
async beforeLoad() {}
|
||||
async load() {
|
||||
this.app.addComponents({
|
||||
ApprovalCommon,
|
||||
// ApprovalCommon,
|
||||
'ApprovalCommon.Provider.ApprovalDataProvider': ApprovalDataProvider,
|
||||
'ApprovalCommon.ViewComponent.ApprovalProcess': ApprovalProcess,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,26 +0,0 @@
|
||||
import { ApprovalDataProvider } from './Pd.ApprovalData';
|
||||
import { ApprovalProcess } from './VC.ApprovalProcess';
|
||||
|
||||
// 通用,审批
|
||||
export const ApprovalCommon = () => null;
|
||||
|
||||
ApprovalCommon.PathNameMap = {
|
||||
Provider: {
|
||||
ApprovalDataProvider: 'ApprovalCommon.Provider.ApprovalDataProvider',
|
||||
},
|
||||
ViewComponent: {
|
||||
ApprovalProcess: 'ApprovalCommon.ViewComponent.ApprovalProcess',
|
||||
},
|
||||
};
|
||||
|
||||
ApprovalCommon.Decorator = null;
|
||||
|
||||
ApprovalCommon.Provider = {
|
||||
ApprovalDataProvider,
|
||||
};
|
||||
|
||||
ApprovalCommon.BlockInitializer = null;
|
||||
|
||||
ApprovalCommon.ViewComponent = {
|
||||
ApprovalProcess,
|
||||
};
|
@ -2,7 +2,6 @@ import { AuditOutlined } from '@ant-design/icons';
|
||||
import { SchemaInitializerItem, useSchemaInitializer, useSchemaInitializerItem } from '@nocobase/client';
|
||||
import { uid } from '@nocobase/utils/client';
|
||||
import React from 'react';
|
||||
import { ApprovalRecordBlock } from './map';
|
||||
|
||||
// 初始化器,创建区块-相关审批
|
||||
export function RecordApprovalsInitializer() {
|
||||
@ -18,13 +17,13 @@ export function RecordApprovalsInitializer() {
|
||||
type: 'void',
|
||||
name: id,
|
||||
'x-uid': id,
|
||||
'x-decorator': ApprovalRecordBlock.PathNameMap.Decorator,
|
||||
'x-decorator': 'ApprovalRecordBlock.Decorator',
|
||||
'x-component': 'CardItem',
|
||||
'x-designer': 'List.Designer',
|
||||
properties: {
|
||||
block: {
|
||||
type: 'void',
|
||||
'x-component': ApprovalRecordBlock.PathNameMap.ViewComponent,
|
||||
'x-component': 'ApprovalRecordBlock.ViewComponent',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { NAMESPACE } from '../../locale';
|
||||
import { ApprovalCommon } from '../approval-common/map';
|
||||
|
||||
export const SchemaRecordApprovals = {
|
||||
type: 'void',
|
||||
@ -86,9 +85,8 @@ export const SchemaRecordApprovals = {
|
||||
},
|
||||
processRow: {
|
||||
type: 'void',
|
||||
// 'x-decorator': 'ApprovalBlock.ApprovalDataProvider',
|
||||
'x-decorator': ApprovalCommon.PathNameMap.Provider.ApprovalDataProvider,
|
||||
'x-component': ApprovalCommon.PathNameMap.ViewComponent.ApprovalProcess,
|
||||
'x-decorator': 'ApprovalCommon.Provider.ApprovalDataProvider',
|
||||
'x-component': 'ApprovalCommon.ViewComponent.ApprovalProcess',
|
||||
'x-component-props': {
|
||||
actionEnabled: true,
|
||||
},
|
||||
|
@ -1,44 +0,0 @@
|
||||
import { RecordApprovalsDecorator } from './Dt.RecordApprovals';
|
||||
import { RecordApprovalsInitializer } from './Iz.RecordApprovals';
|
||||
import { RecordApprovals } from './VC.RecordApprovals';
|
||||
|
||||
// 区块-相关审批
|
||||
export const ApprovalRecordBlock = () => null;
|
||||
|
||||
// Think: 这里其实可以从框架层面定义, 现在是取名字,
|
||||
// 可以改为, name和component的对象.让开发体验更友好.
|
||||
// 目前只是适应框架现在的定义,这样处理
|
||||
// 名称映射,声明而不是生成,提供ts较好的路径提示信息,便于修改,以及避免遍历计算带来的性能损耗
|
||||
ApprovalRecordBlock.PathNameMap = {
|
||||
Decorator: 'ApprovalRecordBlock.Decorator',
|
||||
BlockInitializer: 'ApprovalRecordBlock.BlockInitializer',
|
||||
ViewComponent: 'ApprovalRecordBlock.ViewComponent',
|
||||
};
|
||||
|
||||
ApprovalRecordBlock.Decorator = RecordApprovalsDecorator;
|
||||
|
||||
ApprovalRecordBlock.BlockInitializer = RecordApprovalsInitializer;
|
||||
|
||||
ApprovalRecordBlock.ViewComponent = RecordApprovals;
|
||||
|
||||
// ApprovalRecordBlock.PathNameMap = getPathNameMap(ApprovalRecordBlock);
|
||||
// 改为如下形式, 需要改addComponent的机制, 以及加载组件的机制
|
||||
// 以下代码为 demo
|
||||
// export const ApprovalRecordBlock1 = {
|
||||
// Decorator: {
|
||||
// name: 'ApprovalRecordBlock.Decorator',
|
||||
// component: RecordApprovalsDecorator,
|
||||
// },
|
||||
// Provider: {
|
||||
// name: '',
|
||||
// component: null,
|
||||
// },
|
||||
// BlockInitializer: {
|
||||
// name: 'ApprovalRecordBlock.BlockInitializer',
|
||||
// component: RecordApprovalsInitializer,
|
||||
// },
|
||||
// ViewComponent: {
|
||||
// name: 'ApprovalRecordBlock.ViewComponent',
|
||||
// component: RecordApprovals,
|
||||
// },
|
||||
// };
|
@ -2,7 +2,7 @@ import { defineCollection } from '@nocobase/database';
|
||||
|
||||
export default defineCollection({
|
||||
namespace: 'workflow.approvalExecutions',
|
||||
duplicator: 'required',
|
||||
dumpRules: 'required',
|
||||
name: 'approvalExecutions',
|
||||
fields: [
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { defineCollection } from '@nocobase/database';
|
||||
export default defineCollection({
|
||||
namespace: 'workflow.approvalRecords',
|
||||
duplicator: 'required',
|
||||
dumpRules: 'required',
|
||||
name: 'approvalRecords',
|
||||
fields: [
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { defineCollection } from '@nocobase/database';
|
||||
export default defineCollection({
|
||||
namespace: 'workflow.approvals',
|
||||
duplicator: 'required',
|
||||
dumpRules: 'required',
|
||||
name: 'approvals',
|
||||
createdBy: true,
|
||||
updatedBy: true,
|
||||
|
Loading…
Reference in New Issue
Block a user