feat(client): block schema template manager
This commit is contained in:
parent
c183b98bfb
commit
dd79cb05bf
@ -1,7 +1,9 @@
|
|||||||
import { Field } from '@formily/core';
|
import { Field } from '@formily/core';
|
||||||
import { useField } from '@formily/react';
|
import { useField } from '@formily/react';
|
||||||
import { useRequest } from 'ahooks';
|
import { useRequest } from 'ahooks';
|
||||||
|
import template from 'lodash/template';
|
||||||
import React, { createContext, useContext } from 'react';
|
import React, { createContext, useContext } from 'react';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
import { TableFieldResource, useAPIClient, useRecord } from '../';
|
import { TableFieldResource, useAPIClient, useRecord } from '../';
|
||||||
import { CollectionProvider, useCollection, useCollectionManager } from '../collection-manager';
|
import { CollectionProvider, useCollection, useCollectionManager } from '../collection-manager';
|
||||||
import { useRecordIndex } from '../record-provider';
|
import { useRecordIndex } from '../record-provider';
|
||||||
@ -175,3 +177,11 @@ export const useParamsFromRecord = () => {
|
|||||||
filterByTk: filterByTk,
|
filterByTk: filterByTk,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const RecordLink = (props) => {
|
||||||
|
const field = useField();
|
||||||
|
const record = useRecord();
|
||||||
|
const { title, to, ...others } = props;
|
||||||
|
const compiled = template(to || '');
|
||||||
|
return <Link {...others} to={compiled({ record: record || {} })}>{field.title}</Link>;
|
||||||
|
};
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { SchemaComponentOptions } from '../schema-component/core/SchemaComponentOptions';
|
import { SchemaComponentOptions } from '../schema-component/core/SchemaComponentOptions';
|
||||||
import { useParamsFromRecord, useSourceIdFromParentRecord, useSourceIdFromRecord } from './BlockProvider';
|
import { RecordLink, useParamsFromRecord, useSourceIdFromParentRecord, useSourceIdFromRecord } from './BlockProvider';
|
||||||
import { CalendarBlockProvider, useCalendarBlockProps } from './CalendarBlockProvider';
|
import { CalendarBlockProvider, useCalendarBlockProps } from './CalendarBlockProvider';
|
||||||
import { FormBlockProvider, useFormBlockProps } from './FormBlockProvider';
|
import { FormBlockProvider, useFormBlockProps } from './FormBlockProvider';
|
||||||
import * as bp from './hooks';
|
import * as bp from './hooks';
|
||||||
@ -18,6 +18,7 @@ export const BlockSchemaComponentProvider: React.FC = (props) => {
|
|||||||
TableSelectorProvider,
|
TableSelectorProvider,
|
||||||
FormBlockProvider,
|
FormBlockProvider,
|
||||||
KanbanBlockProvider,
|
KanbanBlockProvider,
|
||||||
|
RecordLink,
|
||||||
}}
|
}}
|
||||||
scope={{
|
scope={{
|
||||||
...bp,
|
...bp,
|
||||||
|
@ -6,7 +6,7 @@ export const RecordIndexContext = createContext(null);
|
|||||||
export const RecordProvider: React.FC<{ record: any }> = (props) => {
|
export const RecordProvider: React.FC<{ record: any }> = (props) => {
|
||||||
const { record, children } = props;
|
const { record, children } = props;
|
||||||
const __parent = useContext(RecordContext);
|
const __parent = useContext(RecordContext);
|
||||||
return <RecordContext.Provider value={{...record, __parent}}>{children}</RecordContext.Provider>;
|
return <RecordContext.Provider value={{ ...record, __parent }}>{children}</RecordContext.Provider>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const RecordIndexProvider: React.FC<{ index: any }> = (props) => {
|
export const RecordIndexProvider: React.FC<{ index: any }> = (props) => {
|
||||||
|
@ -365,7 +365,7 @@ export const ViewActionInitializer = (props) => {
|
|||||||
properties: {
|
properties: {
|
||||||
tab1: {
|
tab1: {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
title: '详情',
|
title: '{{t("Details")}}',
|
||||||
'x-component': 'Tabs.TabPane',
|
'x-component': 'Tabs.TabPane',
|
||||||
'x-designer': 'Tabs.Designer',
|
'x-designer': 'Tabs.Designer',
|
||||||
'x-component-props': {},
|
'x-component-props': {},
|
||||||
@ -407,11 +407,28 @@ export const UpdateActionInitializer = (props) => {
|
|||||||
className: 'nb-action-popup',
|
className: 'nb-action-popup',
|
||||||
},
|
},
|
||||||
properties: {
|
properties: {
|
||||||
grid: {
|
tabs: {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
'x-component': 'Grid',
|
'x-component': 'Tabs',
|
||||||
'x-initializer': 'RecordFormBlockInitializers',
|
'x-component-props': {},
|
||||||
properties: {},
|
'x-initializer': 'TabPaneInitializers',
|
||||||
|
properties: {
|
||||||
|
tab1: {
|
||||||
|
type: 'void',
|
||||||
|
title: '{{t("Edit")}}',
|
||||||
|
'x-component': 'Tabs.TabPane',
|
||||||
|
'x-designer': 'Tabs.Designer',
|
||||||
|
'x-component-props': {},
|
||||||
|
properties: {
|
||||||
|
grid: {
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid',
|
||||||
|
'x-initializer': 'RecordBlockInitializers',
|
||||||
|
properties: {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1,55 +1,20 @@
|
|||||||
import { Card, PageHeader as AntdPageHeader, Table } from 'antd';
|
import { PageHeader as AntdPageHeader } from 'antd';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Link } from 'react-router-dom';
|
import { CollectionManagerProvider } from '../collection-manager';
|
||||||
import { useCompile, useRequest } from '..';
|
import { SchemaComponent } from '../schema-component';
|
||||||
|
import { uiSchemaTemplatesCollection } from './collections/uiSchemaTemplates';
|
||||||
|
import { uiSchemaTemplatesSchema } from './schemas/uiSchemaTemplates';
|
||||||
|
|
||||||
export const BlockTemplatePage = () => {
|
export const BlockTemplatePage = () => {
|
||||||
const { data, loading } = useRequest({
|
|
||||||
resource: 'uiSchemaTemplates',
|
|
||||||
action: 'list',
|
|
||||||
params: {
|
|
||||||
appends: ['collection'],
|
|
||||||
sort: ['-createdAt'],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const compile = useCompile();
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<AntdPageHeader ghost={false} title={t('Block templates')} />
|
<AntdPageHeader ghost={false} title={t('Block templates')} />
|
||||||
<div style={{ margin: 24 }}>
|
<div style={{ margin: 24 }}>
|
||||||
<Card bordered={false}>
|
<CollectionManagerProvider collections={[uiSchemaTemplatesCollection]}>
|
||||||
<Table
|
<SchemaComponent schema={uiSchemaTemplatesSchema} />
|
||||||
rowSelection={{
|
</CollectionManagerProvider>
|
||||||
type: 'checkbox',
|
|
||||||
}}
|
|
||||||
columns={[
|
|
||||||
{
|
|
||||||
dataIndex: 'name',
|
|
||||||
title: t('Template name'),
|
|
||||||
render: (value) => <>{value || '未命名'}</>,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
dataIndex: ['collection', 'title'],
|
|
||||||
title: t('Collection display name'),
|
|
||||||
render: (value) => compile(value),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
dataIndex: 'componentName',
|
|
||||||
title: t('Block type'),
|
|
||||||
render: (value) => value,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
dataIndex: 'actions',
|
|
||||||
title: t('Actions'),
|
|
||||||
render: (_, record) => <Link to={`/admin/block-templates/${record.key}`}>查看</Link>,
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
loading={loading}
|
|
||||||
dataSource={data?.data}
|
|
||||||
/>
|
|
||||||
</Card>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
import { CollectionOptions } from '../../collection-manager';
|
||||||
|
|
||||||
|
export const uiSchemaTemplatesCollection: CollectionOptions = {
|
||||||
|
name: 'uiSchemaTemplates',
|
||||||
|
filterTargetKey: 'key',
|
||||||
|
targetKey: 'key',
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
type: 'integer',
|
||||||
|
name: 'name',
|
||||||
|
interface: 'input',
|
||||||
|
uiSchema: {
|
||||||
|
title: '{{ t("Template name") }}',
|
||||||
|
type: 'number',
|
||||||
|
'x-component': 'Input',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
@ -1,49 +1,26 @@
|
|||||||
import { ISchema } from '@formily/react';
|
import { ISchema } from '@formily/react';
|
||||||
import { CollectionOptions } from '../../collection-manager';
|
import { uid } from '@formily/shared';
|
||||||
|
|
||||||
const collection: CollectionOptions = {
|
|
||||||
name: 'uiSchemaTemplates',
|
|
||||||
filterTargetKey: 'name',
|
|
||||||
targetKey: 'name',
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
type: 'integer',
|
|
||||||
name: 'name',
|
|
||||||
interface: 'input',
|
|
||||||
uiSchema: {
|
|
||||||
title: '{{ t("Template name") }}',
|
|
||||||
type: 'number',
|
|
||||||
'x-component': 'Input',
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
export const uiSchemaTemplatesSchema: ISchema = {
|
export const uiSchemaTemplatesSchema: ISchema = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
block1: {
|
[uid()]: {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
'x-collection': 'collections',
|
'x-decorator': 'TableBlockProvider',
|
||||||
'x-decorator': 'ResourceActionProvider',
|
|
||||||
'x-decorator-props': {
|
'x-decorator-props': {
|
||||||
collection,
|
collection: 'uiSchemaTemplates',
|
||||||
request: {
|
resource: 'uiSchemaTemplates',
|
||||||
resource: 'uiSchemaTemplates',
|
action: 'list',
|
||||||
action: 'list',
|
params: {
|
||||||
params: {
|
pageSize: 20,
|
||||||
pageSize: 50,
|
appends: ['collection'],
|
||||||
filter: {},
|
sort: ['-createdAt'],
|
||||||
// sort: ['sort'],
|
|
||||||
appends: [],
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
rowKey: 'key',
|
||||||
|
showIndex: true,
|
||||||
|
dragSort: false,
|
||||||
},
|
},
|
||||||
// 'x-component': 'CollectionProvider',
|
'x-component': 'CardItem',
|
||||||
// 'x-component-props': {
|
|
||||||
// collection,
|
|
||||||
// },
|
|
||||||
properties: {
|
properties: {
|
||||||
actions: {
|
actions: {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
@ -54,97 +31,177 @@ export const uiSchemaTemplatesSchema: ISchema = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
properties: {
|
properties: {
|
||||||
delete: {
|
destroy: {
|
||||||
type: 'void',
|
|
||||||
title: '{{ t("Delete") }}',
|
title: '{{ t("Delete") }}',
|
||||||
|
'x-action': 'destroy',
|
||||||
'x-component': 'Action',
|
'x-component': 'Action',
|
||||||
|
'x-designer': 'Action.Designer',
|
||||||
'x-component-props': {
|
'x-component-props': {
|
||||||
useAction: '{{ cm.useBulkDestroyActionAndRefreshCM }}',
|
icon: 'DeleteOutlined',
|
||||||
confirm: {
|
confirm: {
|
||||||
title: "{{t('Delete record')}}",
|
title: "{{t('Delete record')}}",
|
||||||
content: "{{t('Are you sure you want to delete it?')}}",
|
content: "{{t('Are you sure you want to delete it?')}}",
|
||||||
},
|
},
|
||||||
},
|
useProps: '{{ useBulkDestroyActionProps }}',
|
||||||
},
|
|
||||||
create: {
|
|
||||||
type: 'void',
|
|
||||||
title: '{{ t("Add block template") }}',
|
|
||||||
'x-component': 'Action',
|
|
||||||
'x-component-props': {
|
|
||||||
type: 'primary',
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
table: {
|
[uid()]: {
|
||||||
type: 'void',
|
type: 'array',
|
||||||
'x-uid': 'input',
|
'x-component': 'TableV2',
|
||||||
'x-component': 'Table.Void',
|
|
||||||
'x-component-props': {
|
'x-component-props': {
|
||||||
rowKey: 'name',
|
|
||||||
rowSelection: {
|
rowSelection: {
|
||||||
type: 'checkbox',
|
type: 'checkbox',
|
||||||
},
|
},
|
||||||
useDataSource: '{{ cm.useDataSourceFromRAC }}',
|
useProps: '{{ useTableBlockProps }}',
|
||||||
},
|
},
|
||||||
properties: {
|
properties: {
|
||||||
column1: {
|
actions: {
|
||||||
type: 'void',
|
|
||||||
'x-decorator': 'Table.Column.Decorator',
|
|
||||||
'x-component': 'Table.Column',
|
|
||||||
properties: {
|
|
||||||
title: {
|
|
||||||
'x-component': 'CollectionField',
|
|
||||||
'x-read-pretty': true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
column2: {
|
|
||||||
type: 'void',
|
|
||||||
'x-decorator': 'Table.Column.Decorator',
|
|
||||||
'x-component': 'Table.Column',
|
|
||||||
properties: {
|
|
||||||
name: {
|
|
||||||
type: 'string',
|
|
||||||
'x-component': 'CollectionField',
|
|
||||||
'x-read-pretty': true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
column3: {
|
|
||||||
type: 'void',
|
type: 'void',
|
||||||
title: '{{ t("Actions") }}',
|
title: '{{ t("Actions") }}',
|
||||||
'x-component': 'Table.Column',
|
'x-component': 'TableV2.Column',
|
||||||
properties: {
|
properties: {
|
||||||
actions: {
|
actions: {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
|
'x-decorator': 'DndContext',
|
||||||
'x-component': 'Space',
|
'x-component': 'Space',
|
||||||
'x-component-props': {
|
'x-component-props': {
|
||||||
split: '|',
|
split: '|',
|
||||||
},
|
},
|
||||||
properties: {
|
properties: {
|
||||||
view: {
|
view: {
|
||||||
type: 'void',
|
title: '{{ t("View") }}',
|
||||||
title: '{{ t("Configure fields") }}',
|
'x-action': 'view',
|
||||||
'x-component': 'Action.Link',
|
'x-component': 'RecordLink',
|
||||||
'x-component-props': {},
|
'x-component-props': {
|
||||||
|
to: '/admin/block-templates/${record.key}',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
delete: {
|
edit: {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
title: '{{ t("Delete") }}',
|
title: '{{ t("Edit") }}',
|
||||||
|
'x-action': 'update',
|
||||||
'x-component': 'Action.Link',
|
'x-component': 'Action.Link',
|
||||||
'x-component-props': {
|
'x-component-props': {
|
||||||
|
openMode: 'drawer',
|
||||||
|
icon: 'EditOutlined',
|
||||||
|
},
|
||||||
|
properties: {
|
||||||
|
drawer: {
|
||||||
|
type: 'void',
|
||||||
|
title: '{{ t("Edit record") }}',
|
||||||
|
'x-component': 'Action.Container',
|
||||||
|
'x-component-props': {
|
||||||
|
className: 'nb-action-popup',
|
||||||
|
},
|
||||||
|
properties: {
|
||||||
|
form: {
|
||||||
|
type: 'void',
|
||||||
|
'x-decorator': 'FormBlockProvider',
|
||||||
|
'x-decorator-props': {
|
||||||
|
resource: 'uiSchemaTemplates',
|
||||||
|
collection: 'uiSchemaTemplates',
|
||||||
|
action: 'get',
|
||||||
|
useParams: '{{ useParamsFromRecord }}',
|
||||||
|
},
|
||||||
|
'x-component': 'CardItem',
|
||||||
|
properties: {
|
||||||
|
[uid()]: {
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'FormV2',
|
||||||
|
'x-component-props': {
|
||||||
|
useProps: '{{ useFormBlockProps }}',
|
||||||
|
},
|
||||||
|
properties: {
|
||||||
|
name: {
|
||||||
|
type: 'string',
|
||||||
|
'x-component': 'CollectionField',
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-collection-field': 'uiSchemaTemplates.name',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'ActionBar',
|
||||||
|
'x-component-props': {
|
||||||
|
layout: 'one-column',
|
||||||
|
style: {
|
||||||
|
marginTop: 24,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
properties: {
|
||||||
|
submit: {
|
||||||
|
title: 'Submit',
|
||||||
|
'x-action': 'submit',
|
||||||
|
'x-component': 'Action',
|
||||||
|
'x-component-props': {
|
||||||
|
type: 'primary',
|
||||||
|
htmlType: 'submit',
|
||||||
|
useProps: '{{ useUpdateActionProps }}',
|
||||||
|
},
|
||||||
|
type: 'void',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
destroy: {
|
||||||
|
title: '{{ t("Delete") }}',
|
||||||
|
'x-action': 'destroy',
|
||||||
|
'x-component': 'Action.Link',
|
||||||
|
'x-component-props': {
|
||||||
|
icon: 'DeleteOutlined',
|
||||||
confirm: {
|
confirm: {
|
||||||
title: "{{t('Delete record')}}",
|
title: "{{t('Delete record')}}",
|
||||||
content: "{{t('Are you sure you want to delete it?')}}",
|
content: "{{t('Are you sure you want to delete it?')}}",
|
||||||
},
|
},
|
||||||
useAction: '{{ cm.useDestroyActionAndRefreshCM }}',
|
useProps: '{{ useDestroyActionProps }}',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
column1: {
|
||||||
|
type: 'void',
|
||||||
|
'x-decorator': 'TableV2.Column.Decorator',
|
||||||
|
'x-component': 'TableV2.Column',
|
||||||
|
properties: {
|
||||||
|
name: {
|
||||||
|
type: 'string',
|
||||||
|
'x-collection-field': 'uiSchemaTemplates.name',
|
||||||
|
'x-component': 'CollectionField',
|
||||||
|
'x-read-pretty': true,
|
||||||
|
'x-component-props': {
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
column2: {
|
||||||
|
type: 'void',
|
||||||
|
title: '{{t("Collection display name")}}',
|
||||||
|
'x-decorator': 'TableV2.Column.Decorator',
|
||||||
|
'x-component': 'TableV2.Column',
|
||||||
|
properties: {
|
||||||
|
'collection.title': {
|
||||||
|
type: 'string',
|
||||||
|
'x-collection-field': 'uiSchemaTemplates.collection',
|
||||||
|
'x-component': 'Input',
|
||||||
|
'x-read-pretty': true,
|
||||||
|
'x-component-props': {
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user