fix(plugin-workflow): fix form event parse variables (#3106)

This commit is contained in:
Junyi 2023-11-28 20:58:15 +08:00 committed by GitHub
parent d2d885b2a6
commit bd6fbcd319
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 90 additions and 130 deletions

View File

@ -4,7 +4,7 @@ import { App, message } from 'antd';
import _, { cloneDeep } from 'lodash';
import get from 'lodash/get';
import omit from 'lodash/omit';
import { ChangeEvent, useContext, useEffect } from 'react';
import { ChangeEvent, useCallback, useContext, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router-dom';
import { useReactToPrint } from 'react-to-print';
@ -97,85 +97,109 @@ export function getFormValues({
return form.values;
}
export function useCollectValuesToSubmit() {
const form = useForm();
const filterByTk = useFilterByTk();
const { field, resource } = useBlockRequestContext();
const { fields, getField, getTreeParentField, name } = useCollection();
const fieldNames = fields.map((field) => field.name);
const { fieldSchema } = useActionContext();
const { getActiveFieldsName } = useFormActiveFields() || {};
const variables = useVariables();
const localVariables = useLocalVariables({ currentForm: form });
const actionSchema = useFieldSchema();
const currentRecord = useRecord();
return useCallback(async () => {
const { assignedValues: originalAssignedValues = {}, overwriteValues } = actionSchema?.['x-action-settings'] ?? {};
const values = getFormValues({
filterByTk,
field,
form,
fieldNames,
getField,
resource,
actionFields: getActiveFieldsName?.('form') || [],
});
const assignedValues = {};
const waitList = Object.keys(originalAssignedValues).map(async (key) => {
const value = originalAssignedValues[key];
const collectionField = getField(key);
if (process.env.NODE_ENV !== 'production') {
if (!collectionField) {
throw new Error(`useCreateActionProps: field "${key}" not found in collection "${name}"`);
}
}
if (isVariable(value)) {
const result = await variables?.parseVariable(value, localVariables);
if (result) {
assignedValues[key] = transformVariableValue(result, { targetCollectionField: collectionField });
}
} else if (value != null && value !== '') {
assignedValues[key] = value;
}
});
await Promise.all(waitList);
// const values = omitBy(formValues, (value) => isEqual(JSON.stringify(value), '[{}]'));
const addChild = fieldSchema?.['x-component-props']?.addChild;
if (addChild) {
const treeParentField = getTreeParentField();
values[treeParentField?.name ?? 'parent'] = omit(currentRecord?.__parent, ['children']);
values[treeParentField?.foreignKey ?? 'parentId'] = currentRecord?.__parent?.id;
}
return {
...values,
...overwriteValues,
...assignedValues,
};
}, [
actionSchema,
currentRecord?.__parent,
field,
fieldNames,
fieldSchema,
filterByTk,
form,
getActiveFieldsName,
getField,
getTreeParentField,
localVariables,
name,
resource,
variables,
]);
}
export const useCreateActionProps = () => {
const form = useForm();
const { field, resource, __parent } = useBlockRequestContext();
const { setVisible, fieldSchema } = useActionContext();
const { setVisible } = useActionContext();
const navigate = useNavigate();
const actionSchema = useFieldSchema();
const actionField = useField();
const { fields, getField, getTreeParentField, name } = useCollection();
const compile = useCompile();
const filterByTk = useFilterByTk();
const currentRecord = useRecord();
const { modal } = App.useApp();
const variables = useVariables();
const localVariables = useLocalVariables({ currentForm: form });
const { getActiveFieldsName } = useFormActiveFields() || {};
const { t } = useTranslation();
const collectValues = useCollectValuesToSubmit();
const action = actionField.componentProps.saveMode || 'create';
const filterKeys = actionField.componentProps.filterKeys?.checked || [];
return {
async onClick() {
const fieldNames = fields.map((field) => field.name);
const {
assignedValues: originalAssignedValues = {},
onSuccess,
overwriteValues,
skipValidator,
triggerWorkflows,
} = actionSchema?.['x-action-settings'] ?? {};
const addChild = fieldSchema?.['x-component-props']?.addChild;
const assignedValues = {};
const waitList = Object.keys(originalAssignedValues).map(async (key) => {
const value = originalAssignedValues[key];
const collectionField = getField(key);
if (process.env.NODE_ENV !== 'production') {
if (!collectionField) {
throw new Error(`useCreateActionProps: field "${key}" not found in collection "${name}"`);
}
}
if (isVariable(value)) {
const result = await variables?.parseVariable(value, localVariables);
if (result) {
assignedValues[key] = transformVariableValue(result, { targetCollectionField: collectionField });
}
} else if (value != null && value !== '') {
assignedValues[key] = value;
}
});
await Promise.all(waitList);
const { onSuccess, skipValidator, triggerWorkflows } = actionSchema?.['x-action-settings'] ?? {};
if (!skipValidator) {
await form.submit();
}
const values = getFormValues({
filterByTk,
field,
form,
fieldNames,
getField,
resource,
actionFields: getActiveFieldsName?.('form') || [],
});
// const values = omitBy(formValues, (value) => isEqual(JSON.stringify(value), '[{}]'));
if (addChild) {
const treeParentField = getTreeParentField();
values[treeParentField?.name ?? 'parent'] = omit(currentRecord?.__parent, ['children']);
values[treeParentField?.foreignKey ?? 'parentId'] = currentRecord?.__parent?.id;
}
const values = await collectValues();
actionField.data = field.data || {};
actionField.data.loading = true;
try {
const data = await resource[action]({
values: {
...values,
...overwriteValues,
...assignedValues,
},
values,
filterKeys: filterKeys,
// TODO(refactor): should change to inject by plugin
triggerWorkflows: triggerWorkflows?.length

View File

@ -4,14 +4,10 @@ import {
useAPIClient,
useActionContext,
useBlockRequestContext,
useCollection,
useCollectValuesToSubmit,
useCollectionDataSource,
useCollectionManager,
useCompile,
useCurrentUserContext,
useFilterByTk,
useFormActiveFields,
useRecord,
} from '@nocobase/client';
import { isURL, parse } from '@nocobase/utils/client';
import { App, message } from 'antd';
@ -104,92 +100,32 @@ export default {
useActionTriggerable: true,
};
function getFormValues({
filterByTk,
form,
getField,
actionFields,
}: {
filterByTk;
form;
getField;
actionFields: any[];
}) {
if (filterByTk) {
if (actionFields) {
const keys = Object.keys(form.values).filter((key) => {
const f = getField(key);
return !actionFields.includes(key) && ['hasOne', 'hasMany', 'belongsTo', 'belongsToMany'].includes(f?.type);
});
return omit({ ...form.values }, keys);
}
}
return form.values;
}
export function useTriggerWorkflowsActionProps() {
const api = useAPIClient();
const form = useForm();
const { field, resource, __parent } = useBlockRequestContext();
const { setVisible, fieldSchema } = useActionContext();
const { field, __parent } = useBlockRequestContext();
const { setVisible } = useActionContext();
const navigate = useNavigate();
const actionSchema = useFieldSchema();
const actionField = useField();
const { fields, getField, getTreeParentField } = useCollection();
const compile = useCompile();
const filterByTk = useFilterByTk();
const currentRecord = useRecord();
const currentUserContext = useCurrentUserContext();
const { modal } = App.useApp();
const { getActiveFieldsName } = useFormActiveFields() || {};
const collectValues = useCollectValuesToSubmit();
const currentUser = currentUserContext?.data?.data;
const filterKeys = actionField.componentProps.filterKeys || [];
return {
async onClick() {
const {
assignedValues: originalAssignedValues = {},
onSuccess,
overwriteValues,
skipValidator,
triggerWorkflows,
} = actionSchema?.['x-action-settings'] ?? {};
const addChild = fieldSchema?.['x-component-props']?.addChild;
const assignedValues = parse(originalAssignedValues)({
// @deprecated
currentTime: new Date(),
// @deprecated
currentRecord,
// @deprecated
currentUser,
$user: currentUser,
$nRecord: currentRecord,
$nForm: form.values,
$nDate: {
now: new Date(),
},
});
const { onSuccess, skipValidator, triggerWorkflows } = actionSchema?.['x-action-settings'] ?? {};
if (!skipValidator) {
await form.submit();
}
const values = getFormValues({ filterByTk, form, getField, actionFields: getActiveFieldsName?.('form') || [] });
// const values = omitBy(formValues, (value) => isEqual(JSON.stringify(value), '[{}]'));
if (addChild) {
const treeParentField = getTreeParentField();
values[treeParentField?.name ?? 'parent'] = currentRecord;
values[treeParentField?.foreignKey ?? 'parentId'] = currentRecord.id;
}
const values = await collectValues();
actionField.data = field.data || {};
actionField.data.loading = true;
try {
const data = await api.resource('workflows').trigger({
values: {
...values,
...overwriteValues,
...assignedValues,
},
values,
filterKeys: filterKeys,
// TODO(refactor): should change to inject by plugin
triggerWorkflows: triggerWorkflows?.length