feat: support tab dump and load (#915)

Reviewed-on: daoyoucloud/tachybase#915
This commit is contained in:
sealday 2024-05-06 21:44:44 +08:00
parent a6c26367b3
commit b562ab8b28

View File

@ -1,16 +1,66 @@
import { useForm } from '@tachybase/schema'; import { ISchema, useField, useFieldSchema, useForm } from '@tachybase/schema';
import React, { useMemo } from 'react'; import React, { useMemo } from 'react';
import { SchemaComponent, useActionContext, useDesignable, useRecord } from '../..'; import { SchemaComponent, useAPIClient, useActionContext, useDesignable, useProps, useRecord } from '../..';
import { SchemaInitializer } from '../../application/schema-initializer/SchemaInitializer'; import { SchemaInitializer } from '../../application/schema-initializer/SchemaInitializer';
import { useGetAriaLabelOfSchemaInitializer } from '../hooks/useGetAriaLabelOfSchemaInitializer'; import { useGetAriaLabelOfSchemaInitializer } from '../hooks/useGetAriaLabelOfSchemaInitializer';
import { message } from 'antd';
import { saveAs } from 'file-saver';
export const TabPaneInitializers = (props?: any) => { export const TabPaneInitializers = (props?: any) => {
const { designable, insertBeforeEnd } = useDesignable(); const { designable, insertBeforeEnd } = useDesignable();
const fieldSchema = useFieldSchema();
const { isCreate, isBulkEdit, options } = props; const { isCreate, isBulkEdit, options } = props;
const { gridInitializer } = options; const { gridInitializer } = options;
const { getAriaLabel } = useGetAriaLabelOfSchemaInitializer(); const { getAriaLabel } = useGetAriaLabelOfSchemaInitializer();
const record = useRecord(); const record = useRecord();
const useDumpAction = () => {
const api = useAPIClient();
return {
async run() {
const deleteUid = (s: ISchema) => {
delete s['name'];
delete s['x-uid'];
Object.keys(s.properties || {}).forEach((key) => {
deleteUid(s.properties[key]);
});
};
const { data } = await api.request({
url: `/uiSchemas:getJsonSchema/${fieldSchema['x-uid']}?includeAsyncNode=true`,
});
const s = data?.data || {};
deleteUid(s);
const blob = new Blob([JSON.stringify(s, null, 2)], { type: 'application/json' });
saveAs(blob, fieldSchema['x-uid'] + '.schema.json');
message.success('Save successful!');
},
};
};
const useLoadAction = () => {
const api = useAPIClient();
const form = useForm();
const actionField = useField();
const ctx = useActionContext();
return {
async run() {
actionField.data ??= {};
actionField.data.loading = true;
const { file } = form.values;
const { data } = await api.request({
url: file.url,
baseURL: '/',
});
const s = data ?? {};
Object.values(s.properties).forEach((s) => {
insertBeforeEnd(s as ISchema);
});
actionField.data.loading = false;
ctx.setVisible(false);
},
};
};
const useSubmitAction = () => { const useSubmitAction = () => {
const form = useForm(); const form = useForm();
const ctx = useActionContext(); const ctx = useActionContext();
@ -53,64 +103,158 @@ export const TabPaneInitializers = (props?: any) => {
return { return {
type: 'void', type: 'void',
properties: { properties: {
action1: { fixStyle: {
type: 'void', type: 'void',
'x-component': 'Action', 'x-component': 'div',
'x-component-props': { 'x-component-props': {
icon: 'PlusOutlined',
style: { style: {
borderColor: 'var(--colorSettings)', display: 'flex',
color: 'var(--colorSettings)',
}, },
type: 'dashed',
'aria-label': getAriaLabel(),
}, },
title: '{{t("Add tab")}}',
properties: { properties: {
drawer1: { action2: {
'x-decorator': 'Form',
'x-component': 'Action.Modal',
'x-component-props': {
width: 520,
},
type: 'void', type: 'void',
title: '{{t("Add tab")}}', 'x-component': 'Action',
'x-component-props': {
icon: 'SaveOutlined',
style: {
borderColor: 'var(--colorSettings)',
color: 'var(--colorSettings)',
marginRight: 'var(--nb-spacing)',
},
type: 'dashed',
useAction: useDumpAction,
'aria-label': getAriaLabel(),
},
title: '{{t("Dump")}}',
},
action3: {
type: 'void',
'x-component': 'Action',
'x-component-props': {
icon: 'UploadOutlined',
style: {
borderColor: 'var(--colorSettings)',
color: 'var(--colorSettings)',
marginRight: 'var(--nb-spacing)',
},
type: 'dashed',
'aria-label': getAriaLabel(),
},
title: '{{t("Load")}}',
properties: { properties: {
title: { drawer1: {
title: '{{t("Tab name")}}', 'x-decorator': 'Form',
required: true, 'x-component': 'Action.Modal',
'x-component': 'Input', 'x-component-props': {
'x-decorator': 'FormItem', width: 520,
}, },
icon: {
title: '{{t("Icon")}}',
'x-component': 'IconPicker',
'x-decorator': 'FormItem',
},
footer: {
'x-component': 'Action.Modal.Footer',
type: 'void', type: 'void',
title: '{{t("Load")}}',
properties: { properties: {
cancel: { file: {
title: '{{t("Cancel")}}', type: 'object',
'x-component': 'Action', title: '{{ t("File") }}',
required: true,
'x-decorator': 'FormItem',
'x-component': 'Upload.Attachment',
'x-component-props': { 'x-component-props': {
useAction: () => { action: 'attachments:create',
const ctx = useActionContext(); multiple: false,
return { },
async run() { },
ctx.setVisible(false); footer: {
'x-component': 'Action.Modal.Footer',
type: 'void',
properties: {
cancel: {
title: '{{t("Cancel")}}',
'x-component': 'Action',
'x-component-props': {
useAction: () => {
const ctx = useActionContext();
return {
async run() {
ctx.setVisible(false);
},
};
}, },
}; },
},
submit: {
title: '{{t("Submit")}}',
'x-component': 'Action',
'x-component-props': {
type: 'primary',
useAction: useLoadAction,
},
}, },
}, },
}, },
submit: { },
title: '{{t("Submit")}}', },
'x-component': 'Action', },
'x-component-props': { },
type: 'primary', action1: {
useAction: useSubmitAction, type: 'void',
'x-component': 'Action',
'x-component-props': {
icon: 'PlusOutlined',
style: {
borderColor: 'var(--colorSettings)',
color: 'var(--colorSettings)',
},
type: 'dashed',
'aria-label': getAriaLabel(),
},
title: '{{t("Add tab")}}',
properties: {
drawer1: {
'x-decorator': 'Form',
'x-component': 'Action.Modal',
'x-component-props': {
width: 520,
},
type: 'void',
title: '{{t("Add tab")}}',
properties: {
title: {
title: '{{t("Tab name")}}',
required: true,
'x-component': 'Input',
'x-decorator': 'FormItem',
},
icon: {
title: '{{t("Icon")}}',
'x-component': 'IconPicker',
'x-decorator': 'FormItem',
},
footer: {
'x-component': 'Action.Modal.Footer',
type: 'void',
properties: {
cancel: {
title: '{{t("Cancel")}}',
'x-component': 'Action',
'x-component-props': {
useAction: () => {
const ctx = useActionContext();
return {
async run() {
ctx.setVisible(false);
},
};
},
},
},
submit: {
title: '{{t("Submit")}}',
'x-component': 'Action',
'x-component-props': {
type: 'primary',
useAction: useSubmitAction,
},
},
}, },
}, },
}, },