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 { useTranslation } from 'react-i18next';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { useAPIClient } from '../../api-client';
|
||||
import { useCollection } from '../../collection-manager';
|
||||
import { useRecord } from '../../record-provider';
|
||||
import { useActionContext, useCompile } from '../../schema-component';
|
||||
@ -54,6 +55,50 @@ const filterValue = (value) => {
|
||||
return obj;
|
||||
};
|
||||
|
||||
function getFormValues(filterByTk, field, form, fieldNames, getField, resource) {
|
||||
let values = {};
|
||||
for (const key in form.values) {
|
||||
if (fieldNames.includes(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') {
|
||||
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];
|
||||
}
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
export const useCreateActionProps = () => {
|
||||
const form = useForm();
|
||||
const { field, resource, __parent } = useBlockRequestContext();
|
||||
@ -64,6 +109,7 @@ export const useCreateActionProps = () => {
|
||||
const actionField = useField();
|
||||
const { fields, getField } = useCollection();
|
||||
const compile = useCompile();
|
||||
const filterByTk = useFilterByTk();
|
||||
return {
|
||||
async onClick() {
|
||||
const fieldNames = fields.map((field) => field.name);
|
||||
@ -72,37 +118,7 @@ export const useCreateActionProps = () => {
|
||||
if (!skipValidator) {
|
||||
await form.submit();
|
||||
}
|
||||
let values = {};
|
||||
for (const key in form.values) {
|
||||
if (fieldNames.includes(key)) {
|
||||
const items = form.values[key];
|
||||
const collectionField = getField(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];
|
||||
}
|
||||
}
|
||||
const values = getFormValues(filterByTk, field, form, fieldNames, getField, resource);
|
||||
actionField.data = field.data || {};
|
||||
actionField.data.loading = true;
|
||||
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 = () => {
|
||||
const form = useForm();
|
||||
const filterByTk = useFilterByTk();
|
||||
@ -204,44 +278,7 @@ export const useUpdateActionProps = () => {
|
||||
await form.submit();
|
||||
}
|
||||
const fieldNames = fields.map((field) => field.name);
|
||||
let values = {};
|
||||
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];
|
||||
}
|
||||
}
|
||||
const values = getFormValues(filterByTk, field, form, fieldNames, getField, resource);
|
||||
actionField.data = field.data || {};
|
||||
actionField.data.loading = true;
|
||||
await resource.update({
|
||||
|
@ -301,5 +301,15 @@ export default {
|
||||
'After successful save': 'After successful save',
|
||||
'Button background color': 'Button background color',
|
||||
'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.': '点击当前自定义按钮时,当前数据以下字段将按照以下表单保存。',
|
||||
'Button background color': '按钮颜色',
|
||||
'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 { useActionContext, useCompile, useDesignable } from '../..';
|
||||
import { GeneralSchemaDesigner, SchemaSettings } from '../../../schema-settings';
|
||||
import { requestSettingsSchema } from './utils';
|
||||
|
||||
const MenuGroup = (props) => {
|
||||
const fieldSchema = useFieldSchema();
|
||||
@ -15,8 +16,18 @@ const MenuGroup = (props) => {
|
||||
'customize:popup': t('Popup'),
|
||||
'customize:update': t('Update 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 <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) && (
|
||||
<SchemaSettings.SwitchItem
|
||||
title={t('Skip required validation')}
|
||||
@ -218,6 +246,8 @@ export const ActionDesigner = (props) => {
|
||||
{
|
||||
'customize:save': t('After successful save'),
|
||||
'customize:update': t('After successful update'),
|
||||
'customize:table:request': t('After successful request'),
|
||||
'customize:form:request': t('After successful request'),
|
||||
}[actionType]
|
||||
}
|
||||
initialValues={fieldSchema?.['x-action-settings']?.['onSuccess']}
|
||||
@ -227,6 +257,8 @@ export const ActionDesigner = (props) => {
|
||||
title: {
|
||||
'customize:save': t('After successful save'),
|
||||
'customize:update': t('After successful update'),
|
||||
'customize:table:request': t('After successful request'),
|
||||
'customize:form:request': t('After successful request'),
|
||||
}[actionType],
|
||||
properties: {
|
||||
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,
|
||||
SchemaInitializerItemComponent,
|
||||
SchemaInitializerItemOptions,
|
||||
SchemaInitializerItemProps
|
||||
SchemaInitializerItemProps,
|
||||
} from './types';
|
||||
|
||||
const defaultWrap = (s: ISchema) => s;
|
||||
@ -129,7 +129,7 @@ SchemaInitializer.Button = observer((props: SchemaInitializerButtonProps) => {
|
||||
...style,
|
||||
}}
|
||||
{...others}
|
||||
icon={<Icon type={icon as string}/>}
|
||||
icon={<Icon type={icon as string} />}
|
||||
>
|
||||
{compile(props.children || props.title)}
|
||||
</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 { cloneDeep } from 'lodash';
|
||||
import React, { createContext, useContext, useMemo, useState } from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
ActionContext,
|
||||
@ -19,7 +20,7 @@ import {
|
||||
useActionContext,
|
||||
useAPIClient,
|
||||
useCollection,
|
||||
useCompile
|
||||
useCompile,
|
||||
} from '..';
|
||||
import { useSchemaTemplateManager } from '../schema-templates';
|
||||
import { useBlockTemplateContext } from '../schema-templates/BlockTemplate';
|
||||
@ -466,7 +467,7 @@ SchemaSettings.PopupItem = (props) => {
|
||||
};
|
||||
|
||||
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 [schemaUid, setSchemaUid] = useState<string>(props.uid);
|
||||
const { t } = useTranslation();
|
||||
@ -487,13 +488,14 @@ SchemaSettings.ActionModalItem = React.memo((props: any) => {
|
||||
setVisible(false);
|
||||
};
|
||||
|
||||
const submitHandler = () => {
|
||||
const submitHandler = async () => {
|
||||
await form.submit();
|
||||
onSubmit?.(cloneDeep(form.values));
|
||||
setVisible(false);
|
||||
};
|
||||
|
||||
const openAssignedFieldValueHandler = async () => {
|
||||
if (!schemaUid && initialSchema['x-uid']) {
|
||||
if (!schemaUid && initialSchema?.['x-uid']) {
|
||||
fieldSchema['x-action-settings'].schemaUid = initialSchema['x-uid'];
|
||||
dn.emit('patch', { schema: fieldSchema });
|
||||
await api.resource('uiSchemas').insert({ values: initialSchema });
|
||||
@ -509,31 +511,40 @@ SchemaSettings.ActionModalItem = React.memo((props: any) => {
|
||||
<SchemaSettings.Item {...others} onClick={openAssignedFieldValueHandler}>
|
||||
{props.children || props.title}
|
||||
</SchemaSettings.Item>
|
||||
|
||||
<Modal
|
||||
width={'50%'}
|
||||
title={compile(title)}
|
||||
{...others}
|
||||
destroyOnClose
|
||||
visible={visible}
|
||||
onCancel={cancelHandler}
|
||||
footer={
|
||||
<Space>
|
||||
<Button onClick={cancelHandler}>{t('Cancel')}</Button>
|
||||
<Button type="primary" onClick={submitHandler}>
|
||||
{t('Submit')}
|
||||
</Button>
|
||||
</Space>
|
||||
}
|
||||
>
|
||||
<FormProvider form={form}>
|
||||
<FormLayout layout={'vertical'}>
|
||||
{modalTip && <Alert message={modalTip} />}
|
||||
{modalTip && <br />}
|
||||
{visible && <RemoteSchemaComponent noForm uid={schemaUid} />}
|
||||
</FormLayout>
|
||||
</FormProvider>
|
||||
</Modal>
|
||||
{createPortal(
|
||||
<div
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
}}
|
||||
>
|
||||
<Modal
|
||||
width={'50%'}
|
||||
title={compile(title)}
|
||||
{...others}
|
||||
destroyOnClose
|
||||
visible={visible}
|
||||
onCancel={cancelHandler}
|
||||
footer={
|
||||
<Space>
|
||||
<Button onClick={cancelHandler}>{t('Cancel')}</Button>
|
||||
<Button type="primary" onClick={submitHandler}>
|
||||
{t('Submit')}
|
||||
</Button>
|
||||
</Space>
|
||||
}
|
||||
>
|
||||
<FormProvider form={form}>
|
||||
<FormLayout layout={'vertical'}>
|
||||
{modalTip && <Alert message={modalTip} />}
|
||||
{modalTip && <br />}
|
||||
{visible && schemaUid && <RemoteSchemaComponent noForm components={components} uid={schemaUid} />}
|
||||
{visible && schema && <SchemaComponent components={components} schema={schema} />}
|
||||
</FormLayout>
|
||||
</FormProvider>
|
||||
</Modal>
|
||||
</div>,
|
||||
document.body,
|
||||
)}
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user