chore: after success configure (#5374)

* chore: after success configure

* fix: bug

* refactor: locale

* fix: bulk edit

* fix: customize request

* refactor: public form not suport after success configiration
This commit is contained in:
Katherine 2024-10-11 10:11:39 +08:00 committed by GitHub
parent a09e27fff9
commit f7ff74d5f3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 189 additions and 105 deletions

View File

@ -224,7 +224,7 @@ export const useCreateActionProps = () => {
return {
async onClick() {
const { onSuccess, skipValidator, triggerWorkflows } = actionSchema?.['x-action-settings'] ?? {};
const { manualClose, redirecting, redirectTo, successMessage, actionAfterSuccess } = onSuccess || {};
if (!skipValidator) {
await form.submit();
}
@ -242,46 +242,49 @@ export const useCreateActionProps = () => {
: undefined,
updateAssociationValues,
});
if (actionAfterSuccess === 'previous' || (!actionAfterSuccess && redirecting !== true)) {
setVisible?.(false);
}
setSubmitted?.(true);
setFormValueChanged?.(false);
actionField.data.loading = false;
actionField.data.data = data;
// __parent?.service?.refresh?.();
if (!onSuccess?.successMessage) {
if (!successMessage) {
message.success(t('Saved successfully'));
await resetFormCorrectly(form);
if (onSuccess?.redirecting && onSuccess?.redirectTo) {
if (isURL(onSuccess.redirectTo)) {
window.location.href = onSuccess.redirectTo;
if (((redirecting && !actionAfterSuccess) || actionAfterSuccess === 'redirect') && redirectTo) {
if (isURL(redirectTo)) {
window.location.href = redirectTo;
} else {
navigate(onSuccess.redirectTo);
navigate(redirectTo);
}
}
return;
}
if (onSuccess?.manualClose) {
if (manualClose) {
modal.success({
title: compile(onSuccess?.successMessage),
title: compile(successMessage),
onOk: async () => {
await resetFormCorrectly(form);
if (onSuccess?.redirecting && onSuccess?.redirectTo) {
if (isURL(onSuccess.redirectTo)) {
window.location.href = onSuccess.redirectTo;
if (((redirecting && !actionAfterSuccess) || actionAfterSuccess === 'redirect') && redirectTo) {
if (isURL(redirectTo)) {
window.location.href = redirectTo;
} else {
navigate(onSuccess.redirectTo);
navigate(redirectTo);
}
}
},
});
} else {
message.success(compile(onSuccess?.successMessage));
message.success(compile(successMessage));
await resetFormCorrectly(form);
if (onSuccess?.redirecting && onSuccess?.redirectTo) {
if (isURL(onSuccess.redirectTo)) {
window.location.href = onSuccess.redirectTo;
if (((redirecting && !actionAfterSuccess) || actionAfterSuccess === 'redirect') && redirectTo) {
if (isURL(redirectTo)) {
window.location.href = redirectTo;
} else {
navigate(onSuccess.redirectTo);
navigate(redirectTo);
}
}
}
@ -319,7 +322,7 @@ export const useAssociationCreateActionProps = () => {
triggerWorkflows,
} = actionSchema?.['x-action-settings'] ?? {};
const addChild = fieldSchema?.['x-component-props']?.addChild;
const { successMessage } = onSuccess || {};
const assignedValues = {};
const waitList = Object.keys(originalAssignedValues).map(async (key) => {
const value = originalAssignedValues[key];
@ -379,10 +382,10 @@ export const useAssociationCreateActionProps = () => {
__parent?.service?.refresh?.();
setVisible?.(false);
setSubmitted?.(true);
if (!onSuccess?.successMessage) {
if (!successMessage) {
return;
}
message.success(compile(onSuccess?.successMessage));
message.success(compile(successMessage));
} catch (error) {
actionField.data.data = null;
actionField.data.loading = false;
@ -568,6 +571,7 @@ export const useCustomizeUpdateActionProps = () => {
const variables = useVariables();
const localVariables = useLocalVariables({ currentForm: form });
const { name, getField } = useCollection_deprecated();
const { setVisible } = useActionContext();
return {
async onClick(e?, callBack?) {
@ -577,7 +581,7 @@ export const useCustomizeUpdateActionProps = () => {
skipValidator,
triggerWorkflows,
} = actionSchema?.['x-action-settings'] ?? {};
const { manualClose, redirecting, redirectTo, successMessage, actionAfterSuccess } = onSuccess || {};
const assignedValues = {};
const waitList = Object.keys(originalAssignedValues).map(async (key) => {
const value = originalAssignedValues[key];
@ -611,6 +615,9 @@ export const useCustomizeUpdateActionProps = () => {
? triggerWorkflows.map((row) => [row.workflowKey, row.context].filter(Boolean).join('!')).join(',')
: undefined,
});
if (actionAfterSuccess === 'previous' || (!actionAfterSuccess && redirecting !== true)) {
setVisible?.(false);
}
// service?.refresh?.();
if (callBack) {
callBack?.();
@ -618,29 +625,29 @@ export const useCustomizeUpdateActionProps = () => {
if (!(resource instanceof TableFieldResource)) {
__parent?.service?.refresh?.();
}
if (!onSuccess?.successMessage) {
if (!successMessage) {
return;
}
if (onSuccess?.manualClose) {
if (manualClose) {
modal.success({
title: compile(onSuccess?.successMessage),
title: compile(successMessage),
onOk: async () => {
if (onSuccess?.redirecting && onSuccess?.redirectTo) {
if (isURL(onSuccess.redirectTo)) {
window.location.href = onSuccess.redirectTo;
if (((redirecting && !actionAfterSuccess) || actionAfterSuccess === 'redirect') && redirectTo) {
if (isURL(redirectTo)) {
window.location.href = redirectTo;
} else {
navigate(onSuccess.redirectTo);
navigate(redirectTo);
}
}
},
});
} else {
message.success(compile(onSuccess?.successMessage));
if (onSuccess?.redirecting && onSuccess?.redirectTo) {
if (isURL(onSuccess.redirectTo)) {
window.location.href = onSuccess.redirectTo;
message.success(compile(successMessage));
if (((redirecting && !actionAfterSuccess) || actionAfterSuccess === 'redirect') && redirectTo) {
if (isURL(redirectTo)) {
window.location.href = redirectTo;
} else {
navigate(onSuccess.redirectTo);
navigate(redirectTo);
}
}
}
@ -665,6 +672,7 @@ export const useCustomizeBulkUpdateActionProps = () => {
const record = useRecord();
const { name, getField } = useCollection_deprecated();
const localVariables = useLocalVariables();
const { setVisible } = useActionContext();
return {
async onClick() {
@ -673,6 +681,7 @@ export const useCustomizeBulkUpdateActionProps = () => {
onSuccess,
updateMode,
} = actionSchema?.['x-action-settings'] ?? {};
const { manualClose, redirecting, redirectTo, successMessage, actionAfterSuccess } = onSuccess || {};
actionField.data = field.data || {};
actionField.data.loading = true;
@ -697,7 +706,9 @@ export const useCustomizeBulkUpdateActionProps = () => {
}
});
await Promise.all(waitList);
if (actionAfterSuccess === 'previous' || (!actionAfterSuccess && redirecting !== true)) {
setVisible?.(false);
}
modal.confirm({
title: t('Bulk update'),
content: updateMode === 'selected' ? t('Update selected data?') : t('Update all data?'),
@ -730,29 +741,29 @@ export const useCustomizeBulkUpdateActionProps = () => {
if (!(resource instanceof TableFieldResource)) {
__parent?.service?.refresh?.();
}
if (!onSuccess?.successMessage) {
if (!successMessage) {
return;
}
if (onSuccess?.manualClose) {
if (manualClose) {
modal.success({
title: compile(onSuccess?.successMessage),
title: compile(successMessage),
onOk: async () => {
if (onSuccess?.redirecting && onSuccess?.redirectTo) {
if (isURL(onSuccess.redirectTo)) {
window.location.href = onSuccess.redirectTo;
if (((redirecting && !actionAfterSuccess) || actionAfterSuccess === 'redirect') && redirectTo) {
if (isURL(redirectTo)) {
window.location.href = redirectTo;
} else {
navigate(onSuccess.redirectTo);
navigate(redirectTo);
}
}
},
});
} else {
message.success(compile(onSuccess?.successMessage));
if (onSuccess?.redirecting && onSuccess?.redirectTo) {
if (isURL(onSuccess.redirectTo)) {
window.location.href = onSuccess.redirectTo;
message.success(compile(successMessage));
if (((redirecting && !actionAfterSuccess) || actionAfterSuccess === 'redirect') && redirectTo) {
if (isURL(redirectTo)) {
window.location.href = redirectTo;
} else {
navigate(onSuccess.redirectTo);
navigate(redirectTo);
}
}
}
@ -778,6 +789,7 @@ export const useCustomizeRequestActionProps = () => {
const currentUserContext = useCurrentUserContext();
const currentUser = currentUserContext?.data?.data;
const actionField = useField();
const { t } = useTranslation();
const { setVisible } = useActionContext();
const { modal } = App.useApp();
const { getActiveFieldsName } = useFormActiveFields() || {};
@ -785,6 +797,7 @@ export const useCustomizeRequestActionProps = () => {
return {
async onClick() {
const { skipValidator, onSuccess, requestSettings } = actionSchema?.['x-action-settings'] ?? {};
const { manualClose, redirecting, redirectTo, successMessage, actionAfterSuccess } = onSuccess || {};
const xAction = actionSchema?.['x-action'];
if (!requestSettings['url']) {
return;
@ -829,26 +842,36 @@ export const useCustomizeRequestActionProps = () => {
}
service?.refresh?.();
if (xAction === 'customize:form:request') {
if (actionAfterSuccess === 'previous' || (!actionAfterSuccess && redirecting !== true)) {
setVisible?.(false);
}
if (!onSuccess?.successMessage) {
return;
}
if (onSuccess?.manualClose) {
modal.success({
title: compile(onSuccess?.successMessage),
onOk: async () => {
if (onSuccess?.redirecting && onSuccess?.redirectTo) {
if (isURL(onSuccess.redirectTo)) {
window.location.href = onSuccess.redirectTo;
if (!successMessage) {
message.success(t('Saved successfully'));
await resetFormCorrectly(form);
if (((redirecting && !actionAfterSuccess) || actionAfterSuccess === 'redirect') && redirectTo) {
if (isURL(redirectTo)) {
window.location.href = redirectTo;
} else {
navigate(onSuccess.redirectTo);
navigate(redirectTo);
}
}
}
if (manualClose) {
modal.success({
title: compile(successMessage),
onOk: async () => {
if (((redirecting && !actionAfterSuccess) || actionAfterSuccess === 'redirect') && redirectTo) {
if (isURL(redirectTo)) {
window.location.href = redirectTo;
} else {
navigate(redirectTo);
}
}
},
});
} else {
message.success(compile(onSuccess?.successMessage));
message.success(compile(successMessage));
}
} finally {
actionField.data.loading = false;
@ -883,7 +906,7 @@ export const useUpdateActionProps = () => {
skipValidator,
triggerWorkflows,
} = actionSchema?.['x-action-settings'] ?? {};
const { manualClose, redirecting, redirectTo, successMessage, actionAfterSuccess } = onSuccess || {};
const assignedValues = {};
const waitList = Object.keys(originalAssignedValues).map(async (key) => {
const value = originalAssignedValues[key];
@ -941,32 +964,39 @@ export const useUpdateActionProps = () => {
if (callBack) {
callBack?.();
}
if (actionAfterSuccess === 'previous' || (!actionAfterSuccess && redirecting !== true)) {
setVisible?.(false);
}
setFormValueChanged?.(false);
if (!onSuccess?.successMessage) {
if (!successMessage) {
return;
}
if (onSuccess?.manualClose) {
if (manualClose) {
modal.success({
title: compile(onSuccess?.successMessage),
title: compile(successMessage),
onOk: async () => {
await form.reset();
if (onSuccess?.redirecting && onSuccess?.redirectTo) {
if (isURL(onSuccess.redirectTo)) {
window.location.href = onSuccess.redirectTo;
if (((redirecting && !actionAfterSuccess) || actionAfterSuccess === 'redirect') && redirectTo) {
if (isURL(redirectTo)) {
window.location.href = redirectTo;
} else {
navigate(onSuccess.redirectTo);
navigate(redirectTo);
}
}
},
});
} else {
message.success(compile(onSuccess?.successMessage));
if (onSuccess?.redirecting && onSuccess?.redirectTo) {
if (isURL(onSuccess.redirectTo)) {
window.location.href = onSuccess.redirectTo;
message.success(compile(successMessage));
if (
((redirecting && !actionAfterSuccess) ||
actionAfterSuccess === 'redirect' ||
actionAfterSuccess === 'redirect') &&
redirectTo
) {
if (isURL(redirectTo)) {
window.location.href = redirectTo;
} else {
navigate(onSuccess.redirectTo);
navigate(redirectTo);
}
}
}

View File

@ -640,7 +640,7 @@
"Current time": "Current time",
"System variables": "System variables",
"Date variables": "Date variables",
"Popup close method": "Popup close method",
"Message popup close method": "Message popup close method",
"Automatic close": "Automatic close",
"Manually close": "Manually close",
"After successful update": "After successful update",

View File

@ -656,7 +656,7 @@
"Parent record": "上级记录",
"Current time": "当前时间",
"Now": "现在",
"Popup close method": "弹窗关闭方式",
"Message popup close method": "消息弹窗关闭方式",
"Automatic close": "自动关闭",
"Manually close": "手动关闭",
"After successful update": "更新成功后",
@ -1001,5 +1001,8 @@
"Ellipsis overflow content": "省略超出长度的内容",
"Picker": "选择器",
"Quarter":"季度",
"Switching the picker, the value and default value will be cleared":"切换选择器时,字段的值和默认值将会被清空"
"Switching the picker, the value and default value will be cleared":"切换选择器时,字段的值和默认值将会被清空",
"Stay on the current popup or page":"停留在当前弹窗或页面",
"Return to the previous popup or page":"返回上一层弹窗或页面",
"Action after successful submission":"提交成功后动作"
}

View File

@ -181,6 +181,10 @@ export const createSubmitActionSettings = new SchemaSettings({
{
name: 'afterSuccessfulSubmission',
Component: AfterSuccess,
useVisible() {
const { type } = useDataBlockProps() || ({} as any);
return type !== 'publicForm';
},
},
{
name: 'refreshDataBlockRequest',

View File

@ -251,18 +251,26 @@ export function SkipValidation() {
/>
);
}
export function AfterSuccess() {
const { dn } = useDesignable();
const { t } = useTranslation();
const fieldSchema = useFieldSchema();
const { onSuccess } = fieldSchema?.['x-action-settings'] || {};
return (
<SchemaSettingsModalItem
title={t('After successful submission')}
initialValues={
fieldSchema?.['x-action-settings']?.['onSuccess'] || {
onSuccess
? {
actionAfterSuccess: onSuccess?.redirecting ? 'redirect' : 'previous',
...onSuccess,
}
: {
manualClose: false,
redirecting: false,
successMessage: '{{t("Saved successfully")}}',
actionAfterSuccess: 'previous',
}
}
schema={
@ -277,7 +285,7 @@ export function AfterSuccess() {
'x-component-props': {},
},
manualClose: {
title: t('Popup close method'),
title: t('Message popup close method'),
enum: [
{ label: t('Automatic close'), value: false },
{ label: t('Manually close'), value: true },
@ -288,6 +296,7 @@ export function AfterSuccess() {
},
redirecting: {
title: t('Then'),
'x-hidden': true,
enum: [
{ label: t('Stay on current page'), value: false },
{ label: t('Redirect to'), value: true },
@ -304,6 +313,25 @@ export function AfterSuccess() {
},
},
},
actionAfterSuccess: {
title: t('Action after successful submission'),
enum: [
{ label: t('Stay on the current popup or page'), value: 'stay' },
{ label: t('Return to the previous popup or page'), value: 'previous' },
{ label: t('Redirect to'), value: 'redirect' },
],
'x-decorator': 'FormItem',
'x-component': 'Radio.Group',
'x-component-props': {},
'x-reactions': {
target: 'redirectTo',
fulfill: {
state: {
visible: "{{$self.value==='redirect'}}",
},
},
},
},
redirectTo: {
title: t('Link'),
'x-decorator': 'FormItem',

View File

@ -7,7 +7,7 @@
* For more information, please refer to: https://www.nocobase.com/agreement.
*/
import { SchemaExpressionScopeContext, useField, useForm } from '@formily/react';
import { SchemaExpressionScopeContext, useField, useForm, useFieldSchema } from '@formily/react';
import {
SchemaInitializerItemType,
TableFieldResource,
@ -93,9 +93,12 @@ export const useCustomizeBulkEditActionProps = () => {
const selectedRecordKeys =
tableBlockContext.field?.data?.selectedRowKeys ?? expressionScope?.selectedRecordKeys ?? {};
const { setVisible, fieldSchema: actionSchema, setSubmitted } = actionContext;
const fieldSchema = useFieldSchema();
return {
async onClick() {
const { onSuccess, skipValidator, updateMode } = actionSchema?.['x-action-settings'] ?? {};
const { updateMode } = actionSchema?.['x-action-settings'] ?? {};
const { onSuccess, skipValidator, triggerWorkflows } = fieldSchema?.['x-action-settings'] ?? {};
const { manualClose, redirecting, redirectTo, successMessage, actionAfterSuccess } = onSuccess || {};
const { filter } = __parent.service.params?.[0] ?? {};
if (!skipValidator) {
@ -125,28 +128,36 @@ export const useCustomizeBulkEditActionProps = () => {
if (!(resource instanceof TableFieldResource)) {
__parent?.__parent?.service?.refresh?.();
}
// __parent?.service?.refresh?.();
if (actionAfterSuccess === 'previous' || (!actionAfterSuccess && redirecting !== true)) {
setVisible?.(false);
}
setSubmitted(true);
if (!onSuccess?.successMessage) {
if (!successMessage) {
if (((redirecting && !actionAfterSuccess) || actionAfterSuccess === 'redirect') && redirectTo) {
if (isURL(redirectTo)) {
window.location.href = redirectTo;
} else {
navigate(redirectTo);
}
}
return;
}
if (onSuccess?.manualClose) {
if (manualClose) {
modal.success({
title: compile(onSuccess?.successMessage),
title: compile(successMessage),
onOk: async () => {
await form.reset();
if (onSuccess?.redirecting && onSuccess?.redirectTo) {
if (isURL(onSuccess.redirectTo)) {
window.location.href = onSuccess.redirectTo;
if (((redirecting && !actionAfterSuccess) || actionAfterSuccess === 'redirect') && redirectTo) {
if (isURL(redirectTo)) {
window.location.href = redirectTo;
} else {
navigate(onSuccess.redirectTo);
navigate(redirectTo);
}
}
},
});
} else {
message.success(compile(onSuccess?.successMessage));
message.success(compile(successMessage));
}
} finally {
actionField.data.loading = false;

View File

@ -36,6 +36,7 @@ export const useCustomizeRequestActionProps = () => {
return {
async onClick(e?, callBack?) {
const { skipValidator, onSuccess } = actionSchema?.['x-action-settings'] ?? {};
const { manualClose, redirecting, redirectTo, successMessage, actionAfterSuccess } = onSuccess || {};
const xAction = actionSchema?.['x-action'];
if (skipValidator !== true && xAction === 'customize:form:request') {
await form.submit();
@ -74,32 +75,39 @@ export const useCustomizeRequestActionProps = () => {
if (callBack) {
callBack?.();
}
if (xAction === 'customize:form:request') {
if (actionAfterSuccess === 'previous' || (!actionAfterSuccess && redirecting !== true)) {
setVisible?.(false);
}
if (!onSuccess?.successMessage) {
if (!successMessage) {
if (((redirecting && !actionAfterSuccess) || actionAfterSuccess === 'redirect') && redirectTo) {
if (isURL(redirectTo)) {
window.location.href = redirectTo;
} else {
navigate(redirectTo);
}
}
return;
}
if (onSuccess?.manualClose) {
if (manualClose) {
modal.success({
title: compile(onSuccess?.successMessage),
title: compile(successMessage),
onOk: async () => {
if (onSuccess?.redirecting && onSuccess?.redirectTo) {
if (isURL(onSuccess.redirectTo)) {
window.location.href = onSuccess.redirectTo;
if (((redirecting && !actionAfterSuccess) || actionAfterSuccess === 'redirect') && redirectTo) {
if (isURL(redirectTo)) {
window.location.href = redirectTo;
} else {
navigate(onSuccess.redirectTo);
navigate(redirectTo);
}
}
},
});
} else {
message.success(compile(onSuccess?.successMessage));
if (onSuccess?.redirecting && onSuccess?.redirectTo) {
if (isURL(onSuccess.redirectTo)) {
window.location.href = onSuccess.redirectTo;
message.success(compile(successMessage));
if (((redirecting && !actionAfterSuccess) || actionAfterSuccess === 'redirect') && redirectTo) {
if (isURL(redirectTo)) {
window.location.href = redirectTo;
} else {
navigate(onSuccess.redirectTo);
navigate(redirectTo);
}
}
}