feat: custom request (#439)
* feat: custom api request * fix: fix review problem * fix: add after request successful tip * fix: add after request successful tip * fix: add filterByTk * fix: add validate * fix: update locale * fix: update locale * fix: update locale * fix: update locale * fix: update locale
This commit is contained in:
parent
373c2b9a2d
commit
9f6e6f22a6
@ -2,6 +2,7 @@ import { useField, useFieldSchema, useForm } from '@formily/react';
|
|||||||
import { message, Modal } from 'antd';
|
import { message, Modal } from 'antd';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
|
import { useAPIClient } from '../../api-client';
|
||||||
import { useCollection } from '../../collection-manager';
|
import { useCollection } from '../../collection-manager';
|
||||||
import { useRecord } from '../../record-provider';
|
import { useRecord } from '../../record-provider';
|
||||||
import { useActionContext, useCompile } from '../../schema-component';
|
import { useActionContext, useCompile } from '../../schema-component';
|
||||||
@ -54,29 +55,21 @@ const filterValue = (value) => {
|
|||||||
return obj;
|
return obj;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useCreateActionProps = () => {
|
function getFormValues(filterByTk, field, form, fieldNames, getField, resource) {
|
||||||
const form = useForm();
|
|
||||||
const { field, resource, __parent } = useBlockRequestContext();
|
|
||||||
const { visible, setVisible } = useActionContext();
|
|
||||||
const history = useHistory();
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const actionSchema = useFieldSchema();
|
|
||||||
const actionField = useField();
|
|
||||||
const { fields, getField } = useCollection();
|
|
||||||
const compile = useCompile();
|
|
||||||
return {
|
|
||||||
async onClick() {
|
|
||||||
const fieldNames = fields.map((field) => field.name);
|
|
||||||
const { assignedValues, onSuccess, overwriteValues, skipValidator } = actionSchema?.['x-action-settings'] ?? {};
|
|
||||||
|
|
||||||
if (!skipValidator) {
|
|
||||||
await form.submit();
|
|
||||||
}
|
|
||||||
let values = {};
|
let values = {};
|
||||||
for (const key in form.values) {
|
for (const key in form.values) {
|
||||||
if (fieldNames.includes(key)) {
|
if (fieldNames.includes(key)) {
|
||||||
const items = form.values[key];
|
|
||||||
const collectionField = getField(key);
|
const collectionField = getField(key);
|
||||||
|
if (filterByTk) {
|
||||||
|
if (collectionField.interface === 'subTable') {
|
||||||
|
values[key] = form.values[key];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (field.added && !field.added.has(key)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const items = form.values[key];
|
||||||
if (collectionField.interface === 'linkTo') {
|
if (collectionField.interface === 'linkTo') {
|
||||||
const targetKey = collectionField.targetKey || 'id';
|
const targetKey = collectionField.targetKey || 'id';
|
||||||
if (resource instanceof TableFieldResource) {
|
if (resource instanceof TableFieldResource) {
|
||||||
@ -103,6 +96,29 @@ export const useCreateActionProps = () => {
|
|||||||
values[key] = form.values[key];
|
values[key] = form.values[key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useCreateActionProps = () => {
|
||||||
|
const form = useForm();
|
||||||
|
const { field, resource, __parent } = useBlockRequestContext();
|
||||||
|
const { visible, setVisible } = useActionContext();
|
||||||
|
const history = useHistory();
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const actionSchema = useFieldSchema();
|
||||||
|
const actionField = useField();
|
||||||
|
const { fields, getField } = useCollection();
|
||||||
|
const compile = useCompile();
|
||||||
|
const filterByTk = useFilterByTk();
|
||||||
|
return {
|
||||||
|
async onClick() {
|
||||||
|
const fieldNames = fields.map((field) => field.name);
|
||||||
|
const { assignedValues, onSuccess, overwriteValues, skipValidator } = actionSchema?.['x-action-settings'] ?? {};
|
||||||
|
|
||||||
|
if (!skipValidator) {
|
||||||
|
await form.submit();
|
||||||
|
}
|
||||||
|
const values = getFormValues(filterByTk, field, form, fieldNames, getField, resource);
|
||||||
actionField.data = field.data || {};
|
actionField.data = field.data || {};
|
||||||
actionField.data.loading = true;
|
actionField.data.loading = true;
|
||||||
await resource.create({
|
await resource.create({
|
||||||
@ -186,6 +202,64 @@ export const useCustomizeUpdateActionProps = () => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useCustomizeRequestActionProps = () => {
|
||||||
|
const apiClient = useAPIClient();
|
||||||
|
const history = useHistory();
|
||||||
|
const filterByTk = useFilterByTk();
|
||||||
|
const actionSchema = useFieldSchema();
|
||||||
|
const compile = useCompile();
|
||||||
|
const form = useForm();
|
||||||
|
const { fields, getField } = useCollection();
|
||||||
|
const { field, resource } = useBlockRequestContext();
|
||||||
|
return {
|
||||||
|
async onClick() {
|
||||||
|
const { skipValidator, onSuccess, requestSettings } = actionSchema?.['x-action-settings'] ?? {};
|
||||||
|
if (!requestSettings['url']) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (skipValidator === false) {
|
||||||
|
await form.submit();
|
||||||
|
}
|
||||||
|
|
||||||
|
const headers = requestSettings['headers'] ? JSON.parse(requestSettings['headers']) : {};
|
||||||
|
const params = requestSettings['params'] ? JSON.parse(requestSettings['params']) : {};
|
||||||
|
const data = requestSettings['data'] ? JSON.parse(requestSettings['data']) : {};
|
||||||
|
const methods = ['POST', 'PUT', 'PATCH'];
|
||||||
|
if (actionSchema['x-action'] === 'customize:form:request' && methods.includes(requestSettings['method'])) {
|
||||||
|
const fieldNames = fields.map((field) => field.name);
|
||||||
|
const values = getFormValues(filterByTk, field, form, fieldNames, getField, resource);
|
||||||
|
Object.assign(data, values);
|
||||||
|
}
|
||||||
|
await apiClient.request({
|
||||||
|
...requestSettings,
|
||||||
|
headers,
|
||||||
|
params,
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
|
||||||
|
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;
|
||||||
|
} else {
|
||||||
|
history.push(onSuccess.redirectTo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
message.success(compile(onSuccess?.successMessage));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
export const useUpdateActionProps = () => {
|
export const useUpdateActionProps = () => {
|
||||||
const form = useForm();
|
const form = useForm();
|
||||||
const filterByTk = useFilterByTk();
|
const filterByTk = useFilterByTk();
|
||||||
@ -204,44 +278,7 @@ export const useUpdateActionProps = () => {
|
|||||||
await form.submit();
|
await form.submit();
|
||||||
}
|
}
|
||||||
const fieldNames = fields.map((field) => field.name);
|
const fieldNames = fields.map((field) => field.name);
|
||||||
let values = {};
|
const values = getFormValues(filterByTk, field, form, fieldNames, getField, resource);
|
||||||
for (const key in form.values) {
|
|
||||||
if (fieldNames.includes(key)) {
|
|
||||||
const collectionField = getField(key);
|
|
||||||
if (collectionField.interface === 'subTable') {
|
|
||||||
values[key] = form.values[key];
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (field.added && !field.added.has(key)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const items = form.values[key];
|
|
||||||
if (collectionField.interface === 'linkTo') {
|
|
||||||
const targetKey = collectionField.targetKey || 'id';
|
|
||||||
if (resource instanceof TableFieldResource) {
|
|
||||||
if (Array.isArray(items)) {
|
|
||||||
values[key] = filterValue(items);
|
|
||||||
} else if (items && typeof items === 'object') {
|
|
||||||
values[key] = filterValue(items);
|
|
||||||
} else {
|
|
||||||
values[key] = items;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (Array.isArray(items)) {
|
|
||||||
values[key] = items.map((item) => item[targetKey]);
|
|
||||||
} else if (items && typeof items === 'object') {
|
|
||||||
values[key] = items[targetKey];
|
|
||||||
} else {
|
|
||||||
values[key] = items;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
values[key] = form.values[key];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
values[key] = form.values[key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
actionField.data = field.data || {};
|
actionField.data = field.data || {};
|
||||||
actionField.data.loading = true;
|
actionField.data.loading = true;
|
||||||
await resource.update({
|
await resource.update({
|
||||||
|
@ -301,5 +301,15 @@ export default {
|
|||||||
'After successful save': 'After successful save',
|
'After successful save': 'After successful save',
|
||||||
'Button background color': 'Button background color',
|
'Button background color': 'Button background color',
|
||||||
'Highlight': 'Highlight',
|
'Highlight': 'Highlight',
|
||||||
'Danger red': 'Danger red'
|
'Danger red': 'Danger red',
|
||||||
|
'Custom request': 'Custom request',
|
||||||
|
'Request settings': 'Request settings',
|
||||||
|
'Request URL': 'Request URL',
|
||||||
|
'Request method': 'Request method',
|
||||||
|
'Request query parameters': 'Request query parameters(JSON)',
|
||||||
|
'Request headers': 'Request headers(JSON)',
|
||||||
|
'Request body': 'Request body(JSON)',
|
||||||
|
'Request success': 'Request success',
|
||||||
|
'Invalid JSON format': 'Invalid JSON format',
|
||||||
|
'After successful request': 'After successful request'
|
||||||
}
|
}
|
||||||
|
@ -536,5 +536,15 @@ export default {
|
|||||||
'After clicking the custom button, the following fields of the current record will be saved according to the following form.': '点击当前自定义按钮时,当前数据以下字段将按照以下表单保存。',
|
'After clicking the custom button, the following fields of the current record will be saved according to the following form.': '点击当前自定义按钮时,当前数据以下字段将按照以下表单保存。',
|
||||||
'Button background color': '按钮颜色',
|
'Button background color': '按钮颜色',
|
||||||
'Highlight': '高亮',
|
'Highlight': '高亮',
|
||||||
'Danger red': '红色'
|
'Danger red': '红色',
|
||||||
|
'Custom request': '自定义请求',
|
||||||
|
'Request settings': '请求设置',
|
||||||
|
'Request URL': '请求地址',
|
||||||
|
'Request method': '请求方法',
|
||||||
|
'Request query parameters': '请求查询参数(JSON格式)',
|
||||||
|
'Request headers': '请求头参数(JSON格式)',
|
||||||
|
'Request body': '请求体(JSON格式)',
|
||||||
|
'Request success': '请求成功',
|
||||||
|
'Invalid JSON format': '非法JSON格式',
|
||||||
|
'After successful request': '请求成功之后'
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import React, { useEffect, useState } from 'react';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useActionContext, useCompile, useDesignable } from '../..';
|
import { useActionContext, useCompile, useDesignable } from '../..';
|
||||||
import { GeneralSchemaDesigner, SchemaSettings } from '../../../schema-settings';
|
import { GeneralSchemaDesigner, SchemaSettings } from '../../../schema-settings';
|
||||||
|
import { requestSettingsSchema } from './utils';
|
||||||
|
|
||||||
const MenuGroup = (props) => {
|
const MenuGroup = (props) => {
|
||||||
const fieldSchema = useFieldSchema();
|
const fieldSchema = useFieldSchema();
|
||||||
@ -15,8 +16,18 @@ const MenuGroup = (props) => {
|
|||||||
'customize:popup': t('Popup'),
|
'customize:popup': t('Popup'),
|
||||||
'customize:update': t('Update record'),
|
'customize:update': t('Update record'),
|
||||||
'customize:save': t('Save record'),
|
'customize:save': t('Save record'),
|
||||||
|
'customize:table:request': t('Custom request'),
|
||||||
|
'customize:form:request': t('Custom request'),
|
||||||
};
|
};
|
||||||
if (!['customize:popup', 'customize:update', 'customize:save'].includes(actionType)) {
|
if (
|
||||||
|
![
|
||||||
|
'customize:popup',
|
||||||
|
'customize:update',
|
||||||
|
'customize:save',
|
||||||
|
'customize:table:request',
|
||||||
|
'customize:form:request',
|
||||||
|
].includes(actionType)
|
||||||
|
) {
|
||||||
return <>{props.children}</>;
|
return <>{props.children}</>;
|
||||||
}
|
}
|
||||||
return <Menu.ItemGroup title={`${t('Customize')} > ${actionTitles[actionType]}`}>{props.children}</Menu.ItemGroup>;
|
return <Menu.ItemGroup title={`${t('Customize')} > ${actionTitles[actionType]}`}>{props.children}</Menu.ItemGroup>;
|
||||||
@ -162,6 +173,23 @@ export const ActionDesigner = (props) => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
{isValid(fieldSchema?.['x-action-settings']?.requestSettings) && (
|
||||||
|
<SchemaSettings.ActionModalItem
|
||||||
|
title={t('Request settings')}
|
||||||
|
schema={requestSettingsSchema}
|
||||||
|
initialValues={fieldSchema?.['x-action-settings']?.requestSettings}
|
||||||
|
onSubmit={(requestSettings) => {
|
||||||
|
fieldSchema['x-action-settings']['requestSettings'] = requestSettings;
|
||||||
|
dn.emit('patch', {
|
||||||
|
schema: {
|
||||||
|
['x-uid']: fieldSchema['x-uid'],
|
||||||
|
'x-action-settings': fieldSchema['x-action-settings'],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
dn.refresh();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
{isValid(fieldSchema?.['x-action-settings']?.skipValidator) && (
|
{isValid(fieldSchema?.['x-action-settings']?.skipValidator) && (
|
||||||
<SchemaSettings.SwitchItem
|
<SchemaSettings.SwitchItem
|
||||||
title={t('Skip required validation')}
|
title={t('Skip required validation')}
|
||||||
@ -218,6 +246,8 @@ export const ActionDesigner = (props) => {
|
|||||||
{
|
{
|
||||||
'customize:save': t('After successful save'),
|
'customize:save': t('After successful save'),
|
||||||
'customize:update': t('After successful update'),
|
'customize:update': t('After successful update'),
|
||||||
|
'customize:table:request': t('After successful request'),
|
||||||
|
'customize:form:request': t('After successful request'),
|
||||||
}[actionType]
|
}[actionType]
|
||||||
}
|
}
|
||||||
initialValues={fieldSchema?.['x-action-settings']?.['onSuccess']}
|
initialValues={fieldSchema?.['x-action-settings']?.['onSuccess']}
|
||||||
@ -227,6 +257,8 @@ export const ActionDesigner = (props) => {
|
|||||||
title: {
|
title: {
|
||||||
'customize:save': t('After successful save'),
|
'customize:save': t('After successful save'),
|
||||||
'customize:update': t('After successful update'),
|
'customize:update': t('After successful update'),
|
||||||
|
'customize:table:request': t('After successful request'),
|
||||||
|
'customize:form:request': t('After successful request'),
|
||||||
}[actionType],
|
}[actionType],
|
||||||
properties: {
|
properties: {
|
||||||
successMessage: {
|
successMessage: {
|
||||||
|
@ -0,0 +1,68 @@
|
|||||||
|
import type { ISchema } from '@formily/react';
|
||||||
|
|
||||||
|
const validateJSON = {
|
||||||
|
validator: `{{(value, rule)=> {
|
||||||
|
if (!value) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const val = JSON.parse(value);
|
||||||
|
if(!isNaN(val)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} catch(error) {
|
||||||
|
console.error(error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}}}`,
|
||||||
|
message: '{{t("Invalid JSON format")}}',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const requestSettingsSchema: ISchema = {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
url: {
|
||||||
|
type: 'string',
|
||||||
|
title: '{{t("Request URL")}}',
|
||||||
|
required: true,
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-component': 'Input',
|
||||||
|
},
|
||||||
|
method: {
|
||||||
|
type: 'string',
|
||||||
|
title: '{{t("Request method")}}',
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-component': 'Select',
|
||||||
|
default: 'POST',
|
||||||
|
enum: [
|
||||||
|
{ label: 'POST', value: 'POST' },
|
||||||
|
{ label: 'GET', value: 'GET' },
|
||||||
|
{ label: 'PUT', value: 'PUT' },
|
||||||
|
{ label: 'PATCH', value: 'PATCH' },
|
||||||
|
{ label: 'DELETE', value: 'DELETE' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
headers: {
|
||||||
|
type: 'string',
|
||||||
|
title: '{{t("Request headers")}}',
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-component': 'Input.TextArea',
|
||||||
|
'x-validator': validateJSON,
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
type: 'string',
|
||||||
|
title: '{{t("Request query parameters")}}',
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-component': 'Input.TextArea',
|
||||||
|
'x-validator': validateJSON,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
type: 'string',
|
||||||
|
title: '{{t("Request body")}}',
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-component': 'Input.TextArea',
|
||||||
|
'x-validator': validateJSON,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
@ -9,7 +9,7 @@ import {
|
|||||||
SchemaInitializerButtonProps,
|
SchemaInitializerButtonProps,
|
||||||
SchemaInitializerItemComponent,
|
SchemaInitializerItemComponent,
|
||||||
SchemaInitializerItemOptions,
|
SchemaInitializerItemOptions,
|
||||||
SchemaInitializerItemProps
|
SchemaInitializerItemProps,
|
||||||
} from './types';
|
} from './types';
|
||||||
|
|
||||||
const defaultWrap = (s: ISchema) => s;
|
const defaultWrap = (s: ISchema) => s;
|
||||||
@ -129,7 +129,7 @@ SchemaInitializer.Button = observer((props: SchemaInitializerButtonProps) => {
|
|||||||
...style,
|
...style,
|
||||||
}}
|
}}
|
||||||
{...others}
|
{...others}
|
||||||
icon={<Icon type={icon as string}/>}
|
icon={<Icon type={icon as string} />}
|
||||||
>
|
>
|
||||||
{compile(props.children || props.title)}
|
{compile(props.children || props.title)}
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -101,6 +101,28 @@ export const FormActionInitializers = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: 'item',
|
||||||
|
title: '{{t("Custom request")}}',
|
||||||
|
component: 'CustomizeActionInitializer',
|
||||||
|
schema: {
|
||||||
|
title: '{{ t("Custom request") }}',
|
||||||
|
'x-component': 'Action',
|
||||||
|
'x-action': 'customize:form:request',
|
||||||
|
'x-designer': 'Action.Designer',
|
||||||
|
'x-action-settings': {
|
||||||
|
requestSettings: {},
|
||||||
|
onSuccess: {
|
||||||
|
manualClose: false,
|
||||||
|
redirecting: false,
|
||||||
|
successMessage: '{{t("Request success")}}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-component-props': {
|
||||||
|
useProps: '{{ useCustomizeRequestActionProps }}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -208,6 +230,28 @@ export const CreateFormActionInitializers = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: 'item',
|
||||||
|
title: '{{t("Custom request")}}',
|
||||||
|
component: 'CustomizeActionInitializer',
|
||||||
|
schema: {
|
||||||
|
title: '{{ t("Custom request") }}',
|
||||||
|
'x-component': 'Action',
|
||||||
|
'x-action': 'customize:form:request',
|
||||||
|
'x-designer': 'Action.Designer',
|
||||||
|
'x-action-settings': {
|
||||||
|
requestSettings: {},
|
||||||
|
onSuccess: {
|
||||||
|
manualClose: false,
|
||||||
|
redirecting: false,
|
||||||
|
successMessage: '{{t("Request success")}}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-component-props': {
|
||||||
|
useProps: '{{ useCustomizeRequestActionProps }}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -315,6 +359,28 @@ export const UpdateFormActionInitializers = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: 'item',
|
||||||
|
title: '{{t("Custom request")}}',
|
||||||
|
component: 'CustomizeActionInitializer',
|
||||||
|
schema: {
|
||||||
|
title: '{{ t("Custom request") }}',
|
||||||
|
'x-component': 'Action',
|
||||||
|
'x-action': 'customize:form:request',
|
||||||
|
'x-designer': 'Action.Designer',
|
||||||
|
'x-action-settings': {
|
||||||
|
requestSettings: {},
|
||||||
|
onSuccess: {
|
||||||
|
manualClose: false,
|
||||||
|
redirecting: false,
|
||||||
|
successMessage: '{{t("Request success")}}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-component-props': {
|
||||||
|
useProps: '{{ useCustomizeRequestActionProps }}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -113,6 +113,28 @@ export const ReadPrettyFormActionInitializers = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: 'item',
|
||||||
|
title: '{{t("Custom request")}}',
|
||||||
|
component: 'CustomizeActionInitializer',
|
||||||
|
schema: {
|
||||||
|
title: '{{ t("Custom request") }}',
|
||||||
|
'x-component': 'Action',
|
||||||
|
'x-action': 'customize:form:request',
|
||||||
|
'x-designer': 'Action.Designer',
|
||||||
|
'x-action-settings': {
|
||||||
|
requestSettings: {},
|
||||||
|
onSuccess: {
|
||||||
|
manualClose: false,
|
||||||
|
redirecting: false,
|
||||||
|
successMessage: '{{t("Request success")}}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-component-props': {
|
||||||
|
useProps: '{{ useCustomizeRequestActionProps }}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -149,6 +149,28 @@ export const TableActionColumnInitializers = (props: any) => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: 'item',
|
||||||
|
title: '{{t("Custom request")}}',
|
||||||
|
component: 'CustomizeActionInitializer',
|
||||||
|
schema: {
|
||||||
|
title: '{{ t("Custom request") }}',
|
||||||
|
'x-component': 'Action.Link',
|
||||||
|
'x-action': 'customize:table:request',
|
||||||
|
'x-designer': 'Action.Designer',
|
||||||
|
'x-action-settings': {
|
||||||
|
requestSettings: {},
|
||||||
|
onSuccess: {
|
||||||
|
manualClose: false,
|
||||||
|
redirecting: false,
|
||||||
|
successMessage: '{{t("Request success")}}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-component-props': {
|
||||||
|
useProps: '{{ useCustomizeRequestActionProps }}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
|
@ -7,6 +7,7 @@ import { Alert, Button, Dropdown, Menu, MenuItemProps, Modal, Select, Space, Swi
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { cloneDeep } from 'lodash';
|
import { cloneDeep } from 'lodash';
|
||||||
import React, { createContext, useContext, useMemo, useState } from 'react';
|
import React, { createContext, useContext, useMemo, useState } from 'react';
|
||||||
|
import { createPortal } from 'react-dom';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import {
|
import {
|
||||||
ActionContext,
|
ActionContext,
|
||||||
@ -19,7 +20,7 @@ import {
|
|||||||
useActionContext,
|
useActionContext,
|
||||||
useAPIClient,
|
useAPIClient,
|
||||||
useCollection,
|
useCollection,
|
||||||
useCompile
|
useCompile,
|
||||||
} from '..';
|
} from '..';
|
||||||
import { useSchemaTemplateManager } from '../schema-templates';
|
import { useSchemaTemplateManager } from '../schema-templates';
|
||||||
import { useBlockTemplateContext } from '../schema-templates/BlockTemplate';
|
import { useBlockTemplateContext } from '../schema-templates/BlockTemplate';
|
||||||
@ -466,7 +467,7 @@ SchemaSettings.PopupItem = (props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
SchemaSettings.ActionModalItem = React.memo((props: any) => {
|
SchemaSettings.ActionModalItem = React.memo((props: any) => {
|
||||||
const { title, onSubmit, initialValues, initialSchema, modalTip, ...others } = props;
|
const { title, onSubmit, initialValues, initialSchema, schema, modalTip, components, ...others } = props;
|
||||||
const [visible, setVisible] = useState(false);
|
const [visible, setVisible] = useState(false);
|
||||||
const [schemaUid, setSchemaUid] = useState<string>(props.uid);
|
const [schemaUid, setSchemaUid] = useState<string>(props.uid);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@ -487,13 +488,14 @@ SchemaSettings.ActionModalItem = React.memo((props: any) => {
|
|||||||
setVisible(false);
|
setVisible(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const submitHandler = () => {
|
const submitHandler = async () => {
|
||||||
|
await form.submit();
|
||||||
onSubmit?.(cloneDeep(form.values));
|
onSubmit?.(cloneDeep(form.values));
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const openAssignedFieldValueHandler = async () => {
|
const openAssignedFieldValueHandler = async () => {
|
||||||
if (!schemaUid && initialSchema['x-uid']) {
|
if (!schemaUid && initialSchema?.['x-uid']) {
|
||||||
fieldSchema['x-action-settings'].schemaUid = initialSchema['x-uid'];
|
fieldSchema['x-action-settings'].schemaUid = initialSchema['x-uid'];
|
||||||
dn.emit('patch', { schema: fieldSchema });
|
dn.emit('patch', { schema: fieldSchema });
|
||||||
await api.resource('uiSchemas').insert({ values: initialSchema });
|
await api.resource('uiSchemas').insert({ values: initialSchema });
|
||||||
@ -509,7 +511,12 @@ SchemaSettings.ActionModalItem = React.memo((props: any) => {
|
|||||||
<SchemaSettings.Item {...others} onClick={openAssignedFieldValueHandler}>
|
<SchemaSettings.Item {...others} onClick={openAssignedFieldValueHandler}>
|
||||||
{props.children || props.title}
|
{props.children || props.title}
|
||||||
</SchemaSettings.Item>
|
</SchemaSettings.Item>
|
||||||
|
{createPortal(
|
||||||
|
<div
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Modal
|
<Modal
|
||||||
width={'50%'}
|
width={'50%'}
|
||||||
title={compile(title)}
|
title={compile(title)}
|
||||||
@ -530,10 +537,14 @@ SchemaSettings.ActionModalItem = React.memo((props: any) => {
|
|||||||
<FormLayout layout={'vertical'}>
|
<FormLayout layout={'vertical'}>
|
||||||
{modalTip && <Alert message={modalTip} />}
|
{modalTip && <Alert message={modalTip} />}
|
||||||
{modalTip && <br />}
|
{modalTip && <br />}
|
||||||
{visible && <RemoteSchemaComponent noForm uid={schemaUid} />}
|
{visible && schemaUid && <RemoteSchemaComponent noForm components={components} uid={schemaUid} />}
|
||||||
|
{visible && schema && <SchemaComponent components={components} schema={schema} />}
|
||||||
</FormLayout>
|
</FormLayout>
|
||||||
</FormProvider>
|
</FormProvider>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
</div>,
|
||||||
|
document.body,
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user