feat: improve schema initializer
This commit is contained in:
parent
590ca267b2
commit
ac4c8f031d
@ -8,13 +8,14 @@ export const ResourceActionContext = createContext<Result<any, any> & { state?:
|
||||
|
||||
interface ResourceActionProviderProps {
|
||||
type?: 'association' | 'collection';
|
||||
collection?: any;
|
||||
request?: any;
|
||||
uid?: string;
|
||||
}
|
||||
|
||||
const ResourceContext = createContext<any>(null);
|
||||
|
||||
const InternalCollectionResourceActionProvider = (props) => {
|
||||
const CollectionResourceActionProvider = (props) => {
|
||||
let { collection, request, uid } = props;
|
||||
const api = useAPIClient();
|
||||
const service = useRequest(
|
||||
@ -22,7 +23,7 @@ const InternalCollectionResourceActionProvider = (props) => {
|
||||
...request,
|
||||
params: {
|
||||
...request?.params,
|
||||
appends: collection.fields.filter(field => field.target).map((field) => field.name),
|
||||
appends: collection.fields.filter((field) => field.target).map((field) => field.name),
|
||||
},
|
||||
},
|
||||
{ uid },
|
||||
@ -37,32 +38,26 @@ const InternalCollectionResourceActionProvider = (props) => {
|
||||
);
|
||||
};
|
||||
|
||||
const CollectionResourceActionProvider = (props) => {
|
||||
let { collection, request, uid } = props;
|
||||
const { getCollection } = useCollectionManager();
|
||||
if (typeof collection === 'string') {
|
||||
collection = getCollection(collection);
|
||||
}
|
||||
if (!collection) {
|
||||
return null;
|
||||
}
|
||||
return <InternalCollectionResourceActionProvider {...props} collection={collection} />;
|
||||
};
|
||||
|
||||
const AssociationResourceActionProvider = (props) => {
|
||||
let { collection, association, request, uid } = props;
|
||||
const { get } = useCollectionManager();
|
||||
const api = useAPIClient();
|
||||
const record = useRecord();
|
||||
const resourceOf = record[association.sourceKey];
|
||||
const service = useRequest({ resourceOf, ...request }, { uid });
|
||||
const service = useRequest(
|
||||
{
|
||||
resourceOf,
|
||||
...request,
|
||||
params: {
|
||||
...request?.params,
|
||||
appends: [
|
||||
...collection?.fields?.filter?.((field) => field.target).map((field) => field.name),
|
||||
...request?.params?.appends,
|
||||
],
|
||||
},
|
||||
},
|
||||
{ uid },
|
||||
);
|
||||
const resource = api.resource(request.resource, resourceOf);
|
||||
if (typeof collection === 'string') {
|
||||
collection = get(collection);
|
||||
}
|
||||
if (!collection) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<ResourceContext.Provider value={{ type: 'association', resource, association }}>
|
||||
<ResourceActionContext.Provider value={service}>
|
||||
@ -73,11 +68,18 @@ const AssociationResourceActionProvider = (props) => {
|
||||
};
|
||||
|
||||
export const ResourceActionProvider: React.FC<ResourceActionProviderProps> = (props) => {
|
||||
const { request } = props;
|
||||
if (request?.resource?.includes('.')) {
|
||||
return <AssociationResourceActionProvider {...props} />;
|
||||
let { collection, request } = props;
|
||||
const { getCollection } = useCollectionManager();
|
||||
if (typeof collection === 'string') {
|
||||
collection = getCollection(collection);
|
||||
}
|
||||
return <CollectionResourceActionProvider {...props} />;
|
||||
if (!collection) {
|
||||
return null;
|
||||
}
|
||||
if (request?.resource?.includes('.')) {
|
||||
return <AssociationResourceActionProvider {...props} collection={collection} />;
|
||||
}
|
||||
return <CollectionResourceActionProvider {...props} collection={collection} />;
|
||||
};
|
||||
|
||||
export const useResourceActionContext = () => {
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { css } from '@emotion/css';
|
||||
import { observer, RecursionField, useField, useFieldSchema } from '@formily/react';
|
||||
import { Drawer } from 'antd';
|
||||
import classNames from 'classnames';
|
||||
import React from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { useActionContext } from './hooks';
|
||||
@ -27,6 +28,13 @@ export const ActionDrawer: ComposedActionDrawer = observer((props) => {
|
||||
destroyOnClose
|
||||
visible={visible}
|
||||
onClose={() => setVisible(false)}
|
||||
className={classNames(others.className, css`
|
||||
&.nb-action-popup {
|
||||
.ant-drawer-content {
|
||||
background: #f0f2f5;
|
||||
}
|
||||
}
|
||||
`)}
|
||||
footer={
|
||||
footerSchema && (
|
||||
<div
|
||||
|
@ -114,45 +114,28 @@ export const LinkToFieldInitializer = (props) => {
|
||||
properties: {
|
||||
drawer1: {
|
||||
'x-component': 'Action.Drawer',
|
||||
'x-component-props': {
|
||||
},
|
||||
type: 'void',
|
||||
title: 'Drawer Title',
|
||||
properties: {
|
||||
details: {
|
||||
tabs: {
|
||||
type: 'void',
|
||||
'x-collection': 'collections',
|
||||
'x-decorator': 'ResourceActionProvider',
|
||||
'x-decorator-props': {
|
||||
collection: item.field.target,
|
||||
request: {
|
||||
resource: item.field.target,
|
||||
action: 'get',
|
||||
params: {},
|
||||
},
|
||||
},
|
||||
'x-designer': 'Form.Designer',
|
||||
'x-component': 'CardItem',
|
||||
'x-component': 'Tabs',
|
||||
'x-component-props': {},
|
||||
'x-initializer': 'TabPaneInitializers',
|
||||
properties: {
|
||||
form: {
|
||||
tab1: {
|
||||
type: 'void',
|
||||
'x-decorator': 'Form',
|
||||
'x-decorator-props': {},
|
||||
title: '详情',
|
||||
'x-component': 'Tabs.TabPane',
|
||||
'x-designer': 'Tabs.Designer',
|
||||
'x-component-props': {},
|
||||
properties: {
|
||||
actions: {
|
||||
type: 'void',
|
||||
'x-initializer': 'FormActionInitializers',
|
||||
'x-component': 'ActionBar',
|
||||
'x-component-props': {
|
||||
layout: 'one-column',
|
||||
style: {
|
||||
marginBottom: 16,
|
||||
},
|
||||
},
|
||||
properties: {},
|
||||
},
|
||||
grid: {
|
||||
type: 'void',
|
||||
'x-component': 'Grid',
|
||||
'x-initializer': 'GridFormItemInitializers',
|
||||
'x-initializer': 'RecordBlockInitializers',
|
||||
properties: {},
|
||||
},
|
||||
},
|
||||
|
@ -3,12 +3,11 @@ import { ISchema } from '@formily/react';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { SchemaInitializer } from '../..';
|
||||
import { useCollectionManager } from '../../../collection-manager';
|
||||
import { useCollection } from '../../../collection-manager';
|
||||
|
||||
const createSchema = (collectionName) => {
|
||||
const schema: ISchema = {
|
||||
type: 'void',
|
||||
'x-collection': 'collections',
|
||||
'x-decorator': 'ResourceActionProvider',
|
||||
'x-decorator-props': {
|
||||
collection: collectionName,
|
||||
@ -53,14 +52,14 @@ const createSchema = (collectionName) => {
|
||||
|
||||
export const RecordFormBlockInitializer = (props) => {
|
||||
const { insert } = props;
|
||||
const { collections } = useCollectionManager();
|
||||
const { name } = useCollection();
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<SchemaInitializer.Item
|
||||
{...props}
|
||||
icon={<FormOutlined />}
|
||||
onClick={({ item }) => {
|
||||
insert(createSchema(item.name));
|
||||
insert(createSchema(name));
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
@ -4,46 +4,78 @@ import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { SchemaInitializer } from '../..';
|
||||
import { useCollectionManager } from '../../../collection-manager';
|
||||
import { useRecord } from '../../../record-provider';
|
||||
|
||||
const createSchema = (collectionName) => {
|
||||
const createSchema = (field, record) => {
|
||||
const resourceOf = record[field.sourceKey || 'id'];
|
||||
const schema: ISchema = {
|
||||
type: 'void',
|
||||
'x-collection': 'collections',
|
||||
'x-decorator': 'ResourceActionProvider',
|
||||
'x-decorator-props': {
|
||||
collection: collectionName,
|
||||
collection: field.target,
|
||||
association: {
|
||||
name: field.name,
|
||||
targetKey: field.targetKey,
|
||||
sourceKey: field.sourceKey,
|
||||
},
|
||||
request: {
|
||||
resource: collectionName,
|
||||
action: 'get',
|
||||
params: {},
|
||||
resource: `${field.collectionName}.${field.name}`,
|
||||
// resourceOf,
|
||||
action: 'list',
|
||||
params: {
|
||||
pageSize: 20,
|
||||
filter: {},
|
||||
// sort: ['sort'],
|
||||
appends: [],
|
||||
},
|
||||
},
|
||||
'x-designer': 'Form.Designer',
|
||||
},
|
||||
'x-designer': 'Table.Void.Designer',
|
||||
'x-component': 'CardItem',
|
||||
properties: {
|
||||
form: {
|
||||
type: 'void',
|
||||
'x-decorator': 'Form',
|
||||
'x-decorator-props': {},
|
||||
properties: {
|
||||
grid: {
|
||||
type: 'void',
|
||||
'x-component': 'Grid',
|
||||
'x-initializer': 'GridFormItemInitializers',
|
||||
properties: {},
|
||||
},
|
||||
actions: {
|
||||
type: 'void',
|
||||
'x-initializer': 'FormActionInitializers',
|
||||
'x-initializer': 'TableActionInitializers',
|
||||
'x-component': 'ActionBar',
|
||||
'x-component-props': {
|
||||
layout: 'one-column',
|
||||
style: {
|
||||
marginTop: 24,
|
||||
marginBottom: 16,
|
||||
},
|
||||
},
|
||||
properties: {},
|
||||
},
|
||||
table: {
|
||||
type: 'void',
|
||||
'x-component': 'Table.Void',
|
||||
'x-component-props': {
|
||||
rowKey: 'id',
|
||||
rowSelection: {
|
||||
type: 'checkbox',
|
||||
},
|
||||
useDataSource: '{{ cm.useDataSourceFromRAC }}',
|
||||
},
|
||||
'x-initializer': 'TableColumnInitializers',
|
||||
properties: {
|
||||
actions: {
|
||||
type: 'void',
|
||||
title: '{{ t("Actions") }}',
|
||||
'x-decorator': 'Table.Column.ActionBar',
|
||||
'x-component': 'Table.Column',
|
||||
'x-designer': 'Table.RowActionDesigner',
|
||||
'x-initializer': 'TableRecordActionInitializers',
|
||||
properties: {
|
||||
actions: {
|
||||
type: 'void',
|
||||
'x-decorator': 'DndContext',
|
||||
'x-component': 'Space',
|
||||
'x-component-props': {
|
||||
split: '|',
|
||||
},
|
||||
properties: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -55,12 +87,13 @@ export const RecordRelationBlockInitializer = (props) => {
|
||||
const { insert } = props;
|
||||
const { collections } = useCollectionManager();
|
||||
const { t } = useTranslation();
|
||||
const record = useRecord();
|
||||
return (
|
||||
<SchemaInitializer.Item
|
||||
{...props}
|
||||
icon={<FormOutlined />}
|
||||
onClick={({ item }) => {
|
||||
insert(createSchema(item.name));
|
||||
insert(createSchema(item.field, record));
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
@ -1,10 +1,34 @@
|
||||
import { useFieldSchema } from '@formily/react';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { SchemaInitializer, useCollection } from '../..';
|
||||
import { useAPIClient } from '../../api-client';
|
||||
import { useDesignable } from '../../schema-component';
|
||||
import { gridRowColWrap } from './utils';
|
||||
|
||||
const useRelationFields = () => {
|
||||
const { fields } = useCollection();
|
||||
return fields.filter(field => field.interface === 'linkTo').map((field) => {
|
||||
return {
|
||||
type: 'item',
|
||||
field,
|
||||
title: field?.uiSchema?.title || field.name,
|
||||
component: 'RecordRelationBlockInitializer',
|
||||
};
|
||||
}) as any;
|
||||
};
|
||||
|
||||
// 当前行记录所在面板的添加区块
|
||||
export const RecordBlockInitializers = {
|
||||
wrap: gridRowColWrap,
|
||||
title: "{{t('Add block')}}",
|
||||
items: [
|
||||
export const RecordBlockInitializers = (props: any) => {
|
||||
const fieldSchema = useFieldSchema();
|
||||
const api = useAPIClient();
|
||||
const { refresh } = useDesignable();
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<SchemaInitializer.Button
|
||||
wrap={gridRowColWrap}
|
||||
title={t('Add block')}
|
||||
items={[
|
||||
{
|
||||
type: 'itemGroup',
|
||||
title: 'Data blocks',
|
||||
@ -24,13 +48,7 @@ export const RecordBlockInitializers = {
|
||||
{
|
||||
type: 'itemGroup',
|
||||
title: '关系数据区块',
|
||||
children: [
|
||||
{
|
||||
type: 'item',
|
||||
title: '关系数据',
|
||||
component: 'RecordRelationBlockInitializer',
|
||||
},
|
||||
],
|
||||
children: useRelationFields(),
|
||||
},
|
||||
{
|
||||
type: 'itemGroup',
|
||||
@ -43,5 +61,7 @@ export const RecordBlockInitializers = {
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
]}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
@ -63,6 +63,9 @@ export const TableRecordActionInitializers = (props: any) => {
|
||||
drawer: {
|
||||
type: 'void',
|
||||
'x-component': 'Action.Drawer',
|
||||
'x-component-props': {
|
||||
className: 'nb-action-popup',
|
||||
},
|
||||
title: '{{ t("View record") }}',
|
||||
properties: {
|
||||
tabs: {
|
||||
|
Loading…
Reference in New Issue
Block a user