fix: 审批, 自动刷新机制和撤回后更改子表格关联字段 (#1260)
Reviewed-on: daoyoucloud/tachybase#1260 Co-authored-by: bai.zixv <bai.zixv@foxmail.com> Co-committed-by: bai.zixv <bai.zixv@foxmail.com>
This commit is contained in:
parent
a15f5aedf0
commit
ef2e2c9beb
@ -0,0 +1,19 @@
|
|||||||
|
import { useActionContext, useAPIClient, useTableBlockContext } from '@tachybase/client';
|
||||||
|
|
||||||
|
// NOTE: 用于处理关闭弹窗, 和刷新外边显示的表格
|
||||||
|
export function useHandleRefresh(delay = 500) {
|
||||||
|
const { service } = useTableBlockContext();
|
||||||
|
const { setVisible, setSubmitted } = useActionContext() as any;
|
||||||
|
|
||||||
|
const refreshTable = () => {
|
||||||
|
setVisible(false);
|
||||||
|
setSubmitted?.(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
service.refresh();
|
||||||
|
}, delay);
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
refreshTable,
|
||||||
|
};
|
||||||
|
}
|
@ -22,11 +22,24 @@ export const ViewActionLaunch = ({ popoverComponent = 'Action.Drawer', popoverCo
|
|||||||
drawer: {
|
drawer: {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
'x-component': popoverComponent,
|
'x-component': popoverComponent,
|
||||||
'x-component-props': { className: 'nb-action-popup', ...popoverComponentProps },
|
'x-component-props': {
|
||||||
|
className: 'nb-action-popup',
|
||||||
|
...popoverComponentProps,
|
||||||
|
},
|
||||||
properties: {
|
properties: {
|
||||||
content: Object.assign({ type: 'void' }, record.approvalId ? {} : { 'x-decorator': 'RecordDecorator' }, {
|
content: Object.assign(
|
||||||
'x-component': 'ViewActionContent',
|
{
|
||||||
}),
|
type: 'void',
|
||||||
|
},
|
||||||
|
record.approvalId
|
||||||
|
? {}
|
||||||
|
: {
|
||||||
|
'x-decorator': 'RecordDecorator',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'x-component': 'ViewActionContent',
|
||||||
|
},
|
||||||
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -58,8 +58,6 @@ export const ViewActionLaunchContent = () => {
|
|||||||
) as any;
|
) as any;
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const approvalData = data?.data;
|
const approvalData = data?.data;
|
||||||
const { approval, execution, ...approvalValue } = approvalData || {};
|
|
||||||
const { workflow } = approval || {};
|
|
||||||
|
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return <Spin />;
|
return <Spin />;
|
||||||
@ -69,6 +67,9 @@ export const ViewActionLaunchContent = () => {
|
|||||||
return <Result status="error" title="Loading failed" />;
|
return <Result status="error" title="Loading failed" />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { approval, execution, ...approvalValue } = approvalData || {};
|
||||||
|
const { workflow } = approval || {};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FlowContextProvider
|
<FlowContextProvider
|
||||||
value={{
|
value={{
|
||||||
|
@ -1,27 +1,30 @@
|
|||||||
import { useActionContext, useAPIClient } from '@tachybase/client';
|
import { useAPIClient } from '@tachybase/client';
|
||||||
import { useField } from '@tachybase/schema';
|
import { useField } from '@tachybase/schema';
|
||||||
|
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
import { useApproval } from '../../../approval-common/ApprovalData.provider';
|
import { useApproval } from '../../../approval-common/ApprovalData.provider';
|
||||||
|
import { useHandleRefresh } from '../../common/useHandleRefresh';
|
||||||
|
|
||||||
export function useDestroyAction() {
|
export function useDestroyAction() {
|
||||||
|
const { refreshTable } = useHandleRefresh();
|
||||||
|
|
||||||
const field = useField();
|
const field = useField();
|
||||||
const { setVisible, setSubmitted } = useActionContext() as any;
|
|
||||||
const approval = useApproval();
|
const approval = useApproval();
|
||||||
const apiClient = useAPIClient();
|
const apiClient = useAPIClient();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
async run() {
|
async run() {
|
||||||
try {
|
try {
|
||||||
|
console.log('%c Line:16 🍓 run', 'font-size:18px;color:#6ec1c2;background:#93c0a4');
|
||||||
|
|
||||||
_.set(field, ['data', 'loading'], true);
|
_.set(field, ['data', 'loading'], true);
|
||||||
|
|
||||||
await apiClient.resource('approvals').destroy({
|
await apiClient.resource('approvals').destroy({
|
||||||
filterByTk: approval.id,
|
filterByTk: approval.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
setSubmitted(true);
|
refreshTable();
|
||||||
setVisible(false);
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
_.set(field, ['data', 'loading'], false);
|
_.set(field, ['data', 'loading'], false);
|
||||||
}
|
}
|
||||||
|
@ -1,40 +1,43 @@
|
|||||||
import { useActionContext, useAPIClient } from '@tachybase/client';
|
import { useAPIClient } from '@tachybase/client';
|
||||||
import { useField, useForm } from '@tachybase/schema';
|
import { useField, useForm } from '@tachybase/schema';
|
||||||
|
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
import { useFlowContext } from '../../../../../../FlowContext';
|
import { useFlowContext } from '../../../../../../FlowContext';
|
||||||
import { useApproval } from '../../../approval-common/ApprovalData.provider';
|
import { useApproval } from '../../../approval-common/ApprovalData.provider';
|
||||||
|
import { useHandleRefresh } from '../../common/useHandleRefresh';
|
||||||
import { useContextApprovalStatus } from '../Pd.ApplyActionStatus';
|
import { useContextApprovalStatus } from '../Pd.ApplyActionStatus';
|
||||||
|
|
||||||
export function useSubmit() {
|
export function useSubmit() {
|
||||||
const from = useForm();
|
const { refreshTable } = useHandleRefresh();
|
||||||
|
const apiClient = useAPIClient();
|
||||||
|
|
||||||
|
const form = useForm();
|
||||||
const field = useField();
|
const field = useField();
|
||||||
const { setVisible, setSubmitted } = useActionContext() as any;
|
|
||||||
const { id } = useApproval();
|
const { id } = useApproval();
|
||||||
const { workflow } = useFlowContext();
|
const { workflow } = useFlowContext();
|
||||||
const contextApprovalStatus = useContextApprovalStatus();
|
const contextApprovalStatus = useContextApprovalStatus();
|
||||||
const apiClient = useAPIClient();
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
async run() {
|
async run() {
|
||||||
try {
|
try {
|
||||||
from.submit();
|
form.submit();
|
||||||
|
|
||||||
_.set(field, ['data', 'loading'], true);
|
_.set(field, ['data', 'loading'], true);
|
||||||
|
|
||||||
apiClient.resource('approvals').update({
|
apiClient.resource('approvals').update({
|
||||||
filterByTk: id,
|
filterByTk: id,
|
||||||
values: {
|
values: {
|
||||||
collectionName: workflow.config.collection,
|
collectionName: workflow.config.collection,
|
||||||
data: from.values,
|
data: form.values,
|
||||||
status: contextApprovalStatus,
|
status: contextApprovalStatus,
|
||||||
|
schemaFormId: workflow.config.applyForm,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
setSubmitted(true);
|
|
||||||
setVisible(false);
|
form.reset();
|
||||||
from.reset();
|
|
||||||
_.set(field, ['data', 'loading'], false);
|
_.set(field, ['data', 'loading'], false);
|
||||||
|
refreshTable();
|
||||||
} catch (m) {
|
} catch (m) {
|
||||||
_.set(field, ['data', 'loading'], false);
|
_.set(field, ['data', 'loading'], false);
|
||||||
}
|
}
|
||||||
|
@ -1,30 +1,33 @@
|
|||||||
import { useActionContext, useAPIClient } from '@tachybase/client';
|
import { useActionContext, useAPIClient, useTableBlockContext } from '@tachybase/client';
|
||||||
import { useField } from '@tachybase/schema';
|
import { useField } from '@tachybase/schema';
|
||||||
|
|
||||||
import { useApproval } from '../../../approval-common/ApprovalData.provider';
|
import { useApproval } from '../../../approval-common/ApprovalData.provider';
|
||||||
|
import { useHandleRefresh } from '../../common/useHandleRefresh';
|
||||||
|
|
||||||
// 撤回
|
// 撤回
|
||||||
export function useWithdrawAction() {
|
export function useWithdrawAction() {
|
||||||
|
const { refreshTable } = useHandleRefresh(100);
|
||||||
|
|
||||||
const field = useField();
|
const field = useField();
|
||||||
const { setVisible, setSubmitted } = useActionContext() as any;
|
|
||||||
const approval = useApproval();
|
const approval = useApproval();
|
||||||
const api = useAPIClient();
|
const api = useAPIClient();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
async run() {
|
async run() {
|
||||||
try {
|
try {
|
||||||
field.data = field.data ?? {};
|
field.data = field.data ?? {};
|
||||||
|
|
||||||
field.data.loading = true;
|
field.data.loading = true;
|
||||||
|
|
||||||
await api.resource('approvals').withdraw({
|
await api.resource('approvals').withdraw({
|
||||||
filterByTk: approval.id,
|
filterByTk: approval.id,
|
||||||
});
|
});
|
||||||
|
// setSubmitted(true);
|
||||||
setVisible(false);
|
|
||||||
|
|
||||||
setSubmitted(true);
|
|
||||||
|
|
||||||
field.data.loading = false;
|
field.data.loading = false;
|
||||||
|
refreshTable();
|
||||||
} catch (v) {
|
} catch (v) {
|
||||||
|
console.log('%c Line:33 🌽 v', 'font-size:18px;color:#33a5ff;background:#fca650', v);
|
||||||
if (field.data) {
|
if (field.data) {
|
||||||
field.data.loading = false;
|
field.data.loading = false;
|
||||||
}
|
}
|
||||||
|
@ -1,36 +1,39 @@
|
|||||||
import { useActionContext, useAPIClient, useRefreshActionProps } from '@tachybase/client';
|
import { useAPIClient } from '@tachybase/client';
|
||||||
import { useField, useForm } from '@tachybase/schema';
|
import { useField, useForm } from '@tachybase/schema';
|
||||||
|
|
||||||
|
import { useHandleRefresh } from '../../common/useHandleRefresh';
|
||||||
import { useContextApprovalAction } from '../Pd.ApprovalAction';
|
import { useContextApprovalAction } from '../Pd.ApprovalAction';
|
||||||
import { useContextApprovalExecutions } from '../Pd.ApprovalExecutions';
|
import { useContextApprovalExecutions } from '../Pd.ApprovalExecutions';
|
||||||
|
|
||||||
export function useSubmit() {
|
export function useSubmit() {
|
||||||
|
const { refreshTable } = useHandleRefresh();
|
||||||
|
|
||||||
const field = useField();
|
const field = useField();
|
||||||
const api = useAPIClient();
|
const api = useAPIClient();
|
||||||
const form = useForm();
|
const form = useForm();
|
||||||
const approvalExecutions = useContextApprovalExecutions();
|
const approvalExecutions = useContextApprovalExecutions();
|
||||||
const { status } = useContextApprovalAction();
|
const { status } = useContextApprovalAction();
|
||||||
const { setVisible, setSubmitted } = useActionContext() as any;
|
|
||||||
// TODO: 自动更新外层block, 提升交互体验
|
|
||||||
// const { onClick: refreshAction } = useRefreshActionProps();
|
|
||||||
return {
|
return {
|
||||||
run: async () => {
|
run: async () => {
|
||||||
try {
|
try {
|
||||||
if (form.values.status) {
|
if (form.values.status) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await form.submit();
|
await form.submit();
|
||||||
field.data = field.data ?? {};
|
field.data = field.data ?? {};
|
||||||
field.data.loading = true;
|
field.data.loading = true;
|
||||||
setVisible(false);
|
|
||||||
await api.resource('approvalRecords').submit({
|
await api.resource('approvalRecords').submit({
|
||||||
filterByTk: approvalExecutions.id,
|
filterByTk: approvalExecutions.id,
|
||||||
values: { ...form.values, status },
|
values: { ...form.values, status },
|
||||||
});
|
});
|
||||||
|
|
||||||
field.data.loading = false;
|
field.data.loading = false;
|
||||||
await form.reset();
|
await form.reset();
|
||||||
// refreshAction?.();
|
|
||||||
setSubmitted?.(true);
|
refreshTable();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
field.data && (field.data.loading = false);
|
field.data && (field.data.loading = false);
|
||||||
|
@ -4,6 +4,7 @@ import { parseCollectionName } from '@tachybase/data-source-manager';
|
|||||||
import { EXECUTION_STATUS, JOB_STATUS, PluginWorkflow } from '../..';
|
import { EXECUTION_STATUS, JOB_STATUS, PluginWorkflow } from '../..';
|
||||||
import { APPROVAL_ACTION_STATUS, APPROVAL_STATUS } from './constants';
|
import { APPROVAL_ACTION_STATUS, APPROVAL_STATUS } from './constants';
|
||||||
import { getSummary } from './tools';
|
import { getSummary } from './tools';
|
||||||
|
import { getAssociationName, jsonParse } from './utils';
|
||||||
|
|
||||||
const workflows = {
|
const workflows = {
|
||||||
async listApprovalFlows(context, next) {
|
async listApprovalFlows(context, next) {
|
||||||
@ -71,13 +72,27 @@ const approvals = {
|
|||||||
return actions.create(context, next);
|
return actions.create(context, next);
|
||||||
},
|
},
|
||||||
async update(context, next) {
|
async update(context, next) {
|
||||||
const { collectionName, data, status } = context.action.params.values ?? {};
|
const { collectionName, data, status, schemaFormId } = context.action.params.values ?? {};
|
||||||
|
|
||||||
const [dataSourceName, cName] = parseCollectionName(collectionName);
|
const [dataSourceName, cName] = parseCollectionName(collectionName);
|
||||||
const dataSource = context.app.dataSourceManager.dataSources.get(dataSourceName);
|
const dataSource = context.app.dataSourceManager.dataSources.get(dataSourceName);
|
||||||
const collection = dataSource.collectionManager.getCollection(cName);
|
const collection = dataSource.collectionManager.getCollection(cName);
|
||||||
|
|
||||||
|
/** 以下为,处理子表单子表格等关联字段的更新逻辑 */
|
||||||
|
const schemaOfForm = await context.db.getRepository('uiSchemas').getJsonSchema(schemaFormId);
|
||||||
|
const itemsOfSchema = await jsonParse(`**["x-component-props".mode]`, schemaOfForm);
|
||||||
|
const fieldAssociationName = itemsOfSchema
|
||||||
|
.filter((item) => {
|
||||||
|
return ['Nester', 'SubTable', 'PopoverNester'].includes(item?.['x-component-props']?.mode);
|
||||||
|
})
|
||||||
|
.map((item) => getAssociationName(item['x-collection-field']));
|
||||||
|
const updateAssociationValues = [...new Set(fieldAssociationName)];
|
||||||
|
/** 以上为,处理子表单子表格等关联字段的更新逻辑 */
|
||||||
|
|
||||||
const [target] = await collection.repository.update({
|
const [target] = await collection.repository.update({
|
||||||
filterByTk: data[collection.filterTargetKey],
|
filterByTk: data[collection.filterTargetKey],
|
||||||
values: data,
|
values: data,
|
||||||
|
updateAssociationValues,
|
||||||
});
|
});
|
||||||
context.action.mergeParams({
|
context.action.mergeParams({
|
||||||
values: {
|
values: {
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
import jsonata from 'jsonata';
|
||||||
|
|
||||||
|
export function getAssociationName(str) {
|
||||||
|
const lastIndex = str.lastIndexOf('.');
|
||||||
|
if (lastIndex !== -1) {
|
||||||
|
return str.substring(lastIndex + 1);
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function jsonParse(expression, scope) {
|
||||||
|
const result = jsonata(expression).evaluate(scope);
|
||||||
|
return result;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user