mirror of
https://gitee.com/nocobase/nocobase.git
synced 2024-11-30 19:28:34 +08:00
feat(client): improve the collection manager module
This commit is contained in:
parent
451f706b46
commit
fc1a65a2fb
@ -5,6 +5,7 @@ import {
|
||||
AntdSchemaComponentProvider,
|
||||
APIClientProvider,
|
||||
AuthLayout,
|
||||
CollectionManagerProvider,
|
||||
CollectionManagerShortcut,
|
||||
compose,
|
||||
DesignableSwitch,
|
||||
@ -40,6 +41,7 @@ const providers = [
|
||||
{ components: { ACLShortcut, DesignableSwitch, CollectionManagerShortcut, SystemSettingsShortcut } },
|
||||
],
|
||||
[SchemaComponentProvider, { components: { Link, NavLink } }],
|
||||
CollectionManagerProvider,
|
||||
AntdSchemaComponentProvider,
|
||||
[DocumentTitleProvider, { addonAfter: 'NocoBase' }],
|
||||
[RouteSwitchProvider, { components: { AuthLayout, AdminLayout, RouteSchemaComponent, SigninPage, SignupPage } }],
|
||||
|
@ -3,6 +3,7 @@ import { Result } from 'ahooks/lib/useRequest/src/types';
|
||||
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
|
||||
|
||||
export interface ActionParams {
|
||||
filterByTk?: any;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@ import {
|
||||
AntdSchemaComponentProvider,
|
||||
APIClientProvider,
|
||||
AuthLayout,
|
||||
CollectionManagerProvider,
|
||||
CollectionManagerShortcut,
|
||||
compose,
|
||||
DesignableSwitch,
|
||||
@ -39,6 +40,7 @@ const providers = [
|
||||
{ components: { ACLShortcut, DesignableSwitch, CollectionManagerShortcut, SystemSettingsShortcut } },
|
||||
],
|
||||
[SchemaComponentProvider, { components: { Link, NavLink } }],
|
||||
CollectionManagerProvider,
|
||||
AntdSchemaComponentProvider,
|
||||
[DocumentTitleProvider, { addonAfter: 'NocoBase' }],
|
||||
[RouteSwitchProvider, { components: { AuthLayout, AdminLayout, RouteSchemaComponent, SigninPage, SignupPage } }],
|
||||
|
@ -26,6 +26,8 @@ const InternalField: React.FC = (props) => {
|
||||
setFieldProps('description', uiSchema.description);
|
||||
setFieldProps('initialValue', uiSchema.default);
|
||||
setRequired();
|
||||
// @ts-ignore
|
||||
field.dataSource = uiSchema.enum;
|
||||
field.component = [component, uiSchema['x-component-props']];
|
||||
}, [uiSchema.title, uiSchema.description, uiSchema.required]);
|
||||
return React.createElement(component, props);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { CollectionContext } from './context';
|
||||
import { useCollectionManager } from './hooks';
|
||||
import { CollectionOptions } from './types';
|
||||
import { CollectionContext } from './context';
|
||||
|
||||
export const CollectionProvider: React.FC<{ name?: string; collection: CollectionOptions }> = (props) => {
|
||||
const { name, collection, children } = props;
|
||||
|
@ -1,146 +0,0 @@
|
||||
import { Button, Divider, Drawer, Space, Table, Typography } from 'antd';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
export const ConfigurationTable = () => {
|
||||
return (
|
||||
<div>
|
||||
<Space style={{ justifyContent: 'flex-end', width: '100%', marginBottom: 16 }}>
|
||||
<Button key="destroy">删除</Button>
|
||||
<Button type={'primary'} key="create">
|
||||
添加
|
||||
</Button>
|
||||
</Space>
|
||||
<Table
|
||||
rowSelection={{
|
||||
type: 'checkbox',
|
||||
}}
|
||||
columns={[
|
||||
{
|
||||
title: '数据表名称',
|
||||
dataIndex: 'title',
|
||||
key: 'title',
|
||||
},
|
||||
{
|
||||
title: '数据表标识',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'actions',
|
||||
key: 'actions',
|
||||
render: () => (
|
||||
<Space split={<Divider type="vertical" />}>
|
||||
<ConfigureFields />
|
||||
<Typography.Link>Edit</Typography.Link>
|
||||
<Typography.Link>Delete</Typography.Link>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
]}
|
||||
dataSource={[
|
||||
{
|
||||
name: 'users',
|
||||
title: '用户',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const ConfigureFields = () => {
|
||||
const [visible, setVisible] = useState(false);
|
||||
return (
|
||||
<>
|
||||
<Typography.Link onClick={() => setVisible(true)}>Configure</Typography.Link>
|
||||
<Drawer width={800} title={'字段配置'} visible={visible} destroyOnClose onClose={() => setVisible(false)}>
|
||||
<CollectionFieldList />
|
||||
</Drawer>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const CollectionFieldList = () => {
|
||||
return (
|
||||
<div>
|
||||
<Space style={{ justifyContent: 'flex-end', width: '100%', marginBottom: 16 }}>
|
||||
<Button key="destroy">删除</Button>
|
||||
<Button type={'primary'} key="create">
|
||||
添加
|
||||
</Button>
|
||||
</Space>
|
||||
<Table
|
||||
rowSelection={{
|
||||
type: 'checkbox',
|
||||
}}
|
||||
columns={[
|
||||
{
|
||||
title: '字段名称',
|
||||
dataIndex: 'title',
|
||||
key: 'title',
|
||||
},
|
||||
{
|
||||
title: '字段标识',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'actions',
|
||||
key: 'actions',
|
||||
render: () => (
|
||||
<Space split={<Divider type="vertical" />}>
|
||||
<CollectionFieldEdit />
|
||||
<Typography.Link>Delete</Typography.Link>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
]}
|
||||
dataSource={[
|
||||
{
|
||||
name: 'title',
|
||||
title: '标题',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const CollectionFieldEdit = () => {
|
||||
const [visible, setVisible] = useState(false);
|
||||
return (
|
||||
<>
|
||||
<Typography.Link onClick={() => setVisible(true)}>Edit</Typography.Link>
|
||||
<Drawer
|
||||
width={800}
|
||||
title={'字段配置'}
|
||||
visible={visible}
|
||||
destroyOnClose
|
||||
onClose={() => setVisible(false)}
|
||||
footer={
|
||||
<Space style={{ justifyContent: 'flex-end', width: '100%' }}>
|
||||
<Button
|
||||
onClick={() => {
|
||||
setVisible(false);
|
||||
}}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
type={'primary'}
|
||||
onClick={() => {
|
||||
setVisible(false);
|
||||
}}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</Space>
|
||||
}
|
||||
>
|
||||
CollectionFieldEdit
|
||||
</Drawer>
|
||||
</>
|
||||
);
|
||||
};
|
@ -0,0 +1,82 @@
|
||||
import { useForm } from '@formily/react';
|
||||
import React from 'react';
|
||||
import { useResourceActionContext, useResourceContext } from '..';
|
||||
import { useRequest } from '../../api-client';
|
||||
import { useRecord } from '../../record-provider';
|
||||
import { SchemaComponent, useActionContext } from '../../schema-component';
|
||||
import { collectionSchema } from './schemas/collections';
|
||||
|
||||
const useCancelAction = () => {
|
||||
const form = useForm();
|
||||
const ctx = useActionContext();
|
||||
return {
|
||||
async run() {
|
||||
ctx.setVisible(false);
|
||||
form.reset();
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const useCreateAction = () => {
|
||||
const form = useForm();
|
||||
const ctx = useActionContext();
|
||||
const { refresh } = useResourceActionContext();
|
||||
const { resource } = useResourceContext();
|
||||
return {
|
||||
async run() {
|
||||
await form.submit();
|
||||
await resource.create({ values: form.values });
|
||||
ctx.setVisible(false);
|
||||
await form.reset();
|
||||
refresh();
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const useUpdateAction = () => {
|
||||
const form = useForm();
|
||||
const ctx = useActionContext();
|
||||
const { refresh } = useResourceActionContext();
|
||||
const { resource, targetKey } = useResourceContext();
|
||||
const { [targetKey]: filterByTk } = useRecord();
|
||||
return {
|
||||
async run() {
|
||||
await form.submit();
|
||||
await resource.update({ filterByTk, values: form.values });
|
||||
ctx.setVisible(false);
|
||||
await form.reset();
|
||||
refresh();
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const useDestroyAction = () => {
|
||||
const { refresh } = useResourceActionContext();
|
||||
const { resource, targetKey } = useResourceContext();
|
||||
const { [targetKey]: filterByTk } = useRecord();
|
||||
return {
|
||||
async run() {
|
||||
await resource.destroy({ filterByTk });
|
||||
refresh();
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const useValues = (options) => {
|
||||
const record = useRecord();
|
||||
return useRequest(() => Promise.resolve({ data: record }), {
|
||||
...options,
|
||||
refreshDeps: [record],
|
||||
});
|
||||
};
|
||||
|
||||
export const ConfigurationTable = () => {
|
||||
return (
|
||||
<div>
|
||||
<SchemaComponent
|
||||
schema={collectionSchema}
|
||||
scope={{ useCancelAction, useCreateAction, useUpdateAction, useDestroyAction, useValues }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
@ -0,0 +1 @@
|
||||
export * from './ConfigurationTable';
|
@ -0,0 +1,249 @@
|
||||
import { ISchema } from '@formily/react';
|
||||
|
||||
const collection = {
|
||||
name: 'fields',
|
||||
fields: [
|
||||
{
|
||||
type: 'string',
|
||||
name: 'type',
|
||||
interface: 'input',
|
||||
uiSchema: {
|
||||
title: '存储类型',
|
||||
type: 'string',
|
||||
'x-component': 'Select',
|
||||
enum: [
|
||||
{
|
||||
label: 'String',
|
||||
value: 'string',
|
||||
},
|
||||
],
|
||||
required: true,
|
||||
} as ISchema,
|
||||
},
|
||||
{
|
||||
type: 'string',
|
||||
name: 'title',
|
||||
interface: 'input',
|
||||
uiSchema: {
|
||||
title: '字段名称',
|
||||
type: 'string',
|
||||
'x-component': 'Input',
|
||||
required: true,
|
||||
} as ISchema,
|
||||
},
|
||||
{
|
||||
type: 'string',
|
||||
name: 'name',
|
||||
interface: 'input',
|
||||
uiSchema: {
|
||||
title: '字段标识',
|
||||
type: 'string',
|
||||
'x-component': 'Input',
|
||||
description: '使用英文',
|
||||
} as ISchema,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const collectionFieldSchema: ISchema = {
|
||||
type: 'void',
|
||||
'x-collection-field': 'collections.fields',
|
||||
'x-decorator': 'ResourceActionProvider',
|
||||
'x-decorator-props': {
|
||||
association: {
|
||||
sourceKey: 'name',
|
||||
targetKey: 'name',
|
||||
},
|
||||
request: {
|
||||
resource: 'collections.fields',
|
||||
action: 'list',
|
||||
params: {
|
||||
pageSize: 5,
|
||||
filter: {},
|
||||
sort: ['sort'],
|
||||
appends: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
'x-component': 'CollectionProvider',
|
||||
'x-component-props': {
|
||||
collection,
|
||||
},
|
||||
properties: {
|
||||
actions: {
|
||||
type: 'void',
|
||||
'x-component': 'ActionBar',
|
||||
properties: {
|
||||
delete: {
|
||||
type: 'void',
|
||||
title: '删除',
|
||||
'x-component': 'Action',
|
||||
},
|
||||
create: {
|
||||
type: 'void',
|
||||
title: '创建',
|
||||
'x-component': 'Action',
|
||||
'x-component-props': {
|
||||
type: 'primary',
|
||||
},
|
||||
properties: {
|
||||
drawer: {
|
||||
type: 'void',
|
||||
'x-component': 'Action.Drawer',
|
||||
'x-decorator': 'Form',
|
||||
title: 'Drawer Title',
|
||||
properties: {
|
||||
type: {
|
||||
'x-component': 'CollectionField',
|
||||
'x-decorator': 'FormItem',
|
||||
},
|
||||
title: {
|
||||
'x-component': 'CollectionField',
|
||||
'x-decorator': 'FormItem',
|
||||
},
|
||||
name: {
|
||||
'x-component': 'CollectionField',
|
||||
'x-decorator': 'FormItem',
|
||||
},
|
||||
footer: {
|
||||
type: 'void',
|
||||
'x-component': 'Action.Drawer.Footer',
|
||||
properties: {
|
||||
action1: {
|
||||
title: 'Cancel',
|
||||
'x-component': 'Action',
|
||||
'x-component-props': {
|
||||
useAction: '{{ useCancelAction }}',
|
||||
},
|
||||
},
|
||||
action2: {
|
||||
title: 'Submit',
|
||||
'x-component': 'Action',
|
||||
'x-component-props': {
|
||||
type: 'primary',
|
||||
useAction: '{{ useCreateAction }}',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
table1: {
|
||||
type: 'void',
|
||||
'x-uid': 'input',
|
||||
'x-component': 'VoidTable',
|
||||
'x-component-props': {
|
||||
rowKey: 'id',
|
||||
rowSelection: {
|
||||
type: 'checkbox',
|
||||
},
|
||||
useDataSource: '{{ useDataSourceFromRAC }}',
|
||||
},
|
||||
properties: {
|
||||
column1: {
|
||||
type: 'void',
|
||||
'x-decorator': 'TableColumnDecorator',
|
||||
'x-component': 'VoidTable.Column',
|
||||
properties: {
|
||||
title: {
|
||||
type: 'number',
|
||||
'x-component': 'CollectionField',
|
||||
'x-read-pretty': true,
|
||||
},
|
||||
},
|
||||
},
|
||||
column2: {
|
||||
type: 'void',
|
||||
'x-decorator': 'TableColumnDecorator',
|
||||
'x-component': 'VoidTable.Column',
|
||||
properties: {
|
||||
name: {
|
||||
type: 'string',
|
||||
'x-component': 'CollectionField',
|
||||
'x-read-pretty': true,
|
||||
},
|
||||
},
|
||||
},
|
||||
column3: {
|
||||
type: 'void',
|
||||
title: 'Actions',
|
||||
'x-component': 'VoidTable.Column',
|
||||
properties: {
|
||||
actions: {
|
||||
type: 'void',
|
||||
'x-component': 'Space',
|
||||
'x-component-props': {
|
||||
split: '|',
|
||||
},
|
||||
properties: {
|
||||
update: {
|
||||
type: 'void',
|
||||
title: '编辑',
|
||||
'x-component': 'Action.Link',
|
||||
'x-component-props': {
|
||||
type: 'primary',
|
||||
},
|
||||
properties: {
|
||||
drawer: {
|
||||
type: 'void',
|
||||
'x-component': 'Action.Drawer',
|
||||
'x-decorator': 'Form',
|
||||
'x-decorator-props': {
|
||||
useValues: '{{ useValues }}',
|
||||
},
|
||||
title: 'Drawer Title',
|
||||
properties: {
|
||||
title: {
|
||||
'x-component': 'CollectionField',
|
||||
'x-decorator': 'FormItem',
|
||||
},
|
||||
name: {
|
||||
'x-component': 'CollectionField',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-disabled': true,
|
||||
},
|
||||
footer: {
|
||||
type: 'void',
|
||||
'x-component': 'Action.Drawer.Footer',
|
||||
properties: {
|
||||
action1: {
|
||||
title: 'Cancel',
|
||||
'x-component': 'Action',
|
||||
'x-component-props': {
|
||||
useAction: '{{ useCancelAction }}',
|
||||
},
|
||||
},
|
||||
action2: {
|
||||
title: 'Submit',
|
||||
'x-component': 'Action',
|
||||
'x-component-props': {
|
||||
type: 'primary',
|
||||
useAction: '{{ useUpdateAction }}',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
delete: {
|
||||
type: 'void',
|
||||
title: '删除',
|
||||
'x-component': 'Action.Link',
|
||||
'x-component-props': {
|
||||
useAction: '{{ useDestroyAction }}',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
@ -0,0 +1,259 @@
|
||||
import { ISchema } from '@formily/react';
|
||||
import { collectionFieldSchema } from './collectionFields';
|
||||
|
||||
const collection = {
|
||||
name: 'collections',
|
||||
filterTargetKey: 'name',
|
||||
fields: [
|
||||
{
|
||||
type: 'integer',
|
||||
name: 'title',
|
||||
interface: 'input',
|
||||
uiSchema: {
|
||||
title: '数据表名称',
|
||||
type: 'number',
|
||||
'x-component': 'Input',
|
||||
required: true,
|
||||
} as ISchema,
|
||||
},
|
||||
{
|
||||
type: 'string',
|
||||
name: 'name',
|
||||
interface: 'input',
|
||||
uiSchema: {
|
||||
title: '数据表标识',
|
||||
type: 'string',
|
||||
'x-component': 'Input',
|
||||
description: '使用英文',
|
||||
} as ISchema,
|
||||
},
|
||||
{
|
||||
type: 'hasMany',
|
||||
name: 'fields',
|
||||
target: 'fields',
|
||||
collectionName: 'collections',
|
||||
sourceKey: 'name',
|
||||
targetKey: 'name',
|
||||
uiSchema: {},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const collectionSchema: ISchema = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
block1: {
|
||||
type: 'void',
|
||||
'x-collection': 'collections',
|
||||
'x-decorator': 'ResourceActionProvider',
|
||||
'x-decorator-props': {
|
||||
collection: {
|
||||
targetKey: 'name',
|
||||
},
|
||||
request: {
|
||||
resource: 'collections',
|
||||
action: 'list',
|
||||
params: {
|
||||
pageSize: 5,
|
||||
filter: {},
|
||||
sort: ['sort'],
|
||||
appends: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
'x-component': 'CollectionProvider',
|
||||
'x-component-props': {
|
||||
collection,
|
||||
},
|
||||
properties: {
|
||||
actions: {
|
||||
type: 'void',
|
||||
'x-component': 'ActionBar',
|
||||
properties: {
|
||||
delete: {
|
||||
type: 'void',
|
||||
title: '删除',
|
||||
'x-component': 'Action',
|
||||
},
|
||||
create: {
|
||||
type: 'void',
|
||||
title: '创建',
|
||||
'x-component': 'Action',
|
||||
'x-component-props': {
|
||||
type: 'primary',
|
||||
},
|
||||
properties: {
|
||||
drawer: {
|
||||
type: 'void',
|
||||
'x-component': 'Action.Drawer',
|
||||
'x-decorator': 'Form',
|
||||
title: 'Drawer Title',
|
||||
properties: {
|
||||
title: {
|
||||
'x-component': 'CollectionField',
|
||||
'x-decorator': 'FormItem',
|
||||
},
|
||||
name: {
|
||||
'x-component': 'CollectionField',
|
||||
'x-decorator': 'FormItem',
|
||||
},
|
||||
footer: {
|
||||
type: 'void',
|
||||
'x-component': 'Action.Drawer.Footer',
|
||||
properties: {
|
||||
action1: {
|
||||
title: 'Cancel',
|
||||
'x-component': 'Action',
|
||||
'x-component-props': {
|
||||
useAction: '{{ useCancelAction }}',
|
||||
},
|
||||
},
|
||||
action2: {
|
||||
title: 'Submit',
|
||||
'x-component': 'Action',
|
||||
'x-component-props': {
|
||||
type: 'primary',
|
||||
useAction: '{{ useCreateAction }}',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
table1: {
|
||||
type: 'void',
|
||||
'x-uid': 'input',
|
||||
'x-component': 'VoidTable',
|
||||
'x-component-props': {
|
||||
rowKey: 'id',
|
||||
rowSelection: {
|
||||
type: 'checkbox',
|
||||
},
|
||||
useDataSource: '{{ useDataSourceFromRAC }}',
|
||||
},
|
||||
properties: {
|
||||
column1: {
|
||||
type: 'void',
|
||||
'x-decorator': 'TableColumnDecorator',
|
||||
'x-component': 'VoidTable.Column',
|
||||
properties: {
|
||||
title: {
|
||||
type: 'number',
|
||||
'x-component': 'CollectionField',
|
||||
'x-read-pretty': true,
|
||||
},
|
||||
},
|
||||
},
|
||||
column2: {
|
||||
type: 'void',
|
||||
'x-decorator': 'TableColumnDecorator',
|
||||
'x-component': 'VoidTable.Column',
|
||||
properties: {
|
||||
name: {
|
||||
type: 'string',
|
||||
'x-component': 'CollectionField',
|
||||
'x-read-pretty': true,
|
||||
},
|
||||
},
|
||||
},
|
||||
column3: {
|
||||
type: 'void',
|
||||
title: 'Actions',
|
||||
'x-component': 'VoidTable.Column',
|
||||
properties: {
|
||||
actions: {
|
||||
type: 'void',
|
||||
'x-component': 'Space',
|
||||
'x-component-props': {
|
||||
split: '|',
|
||||
},
|
||||
properties: {
|
||||
view: {
|
||||
type: 'void',
|
||||
title: '配置字段',
|
||||
'x-component': 'Action.Link',
|
||||
'x-component-props': {},
|
||||
properties: {
|
||||
drawer: {
|
||||
type: 'void',
|
||||
'x-component': 'Action.Drawer',
|
||||
title: 'Drawer Title',
|
||||
properties: {
|
||||
collectionFieldSchema,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
update: {
|
||||
type: 'void',
|
||||
title: '编辑',
|
||||
'x-component': 'Action.Link',
|
||||
'x-component-props': {
|
||||
type: 'primary',
|
||||
},
|
||||
properties: {
|
||||
drawer: {
|
||||
type: 'void',
|
||||
'x-component': 'Action.Drawer',
|
||||
'x-decorator': 'Form',
|
||||
'x-decorator-props': {
|
||||
useValues: '{{ useValues }}',
|
||||
},
|
||||
title: 'Drawer Title',
|
||||
properties: {
|
||||
title: {
|
||||
'x-component': 'CollectionField',
|
||||
'x-decorator': 'FormItem',
|
||||
},
|
||||
name: {
|
||||
'x-component': 'CollectionField',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-disabled': true,
|
||||
},
|
||||
footer: {
|
||||
type: 'void',
|
||||
'x-component': 'Action.Drawer.Footer',
|
||||
properties: {
|
||||
action1: {
|
||||
title: 'Cancel',
|
||||
'x-component': 'Action',
|
||||
'x-component-props': {
|
||||
useAction: '{{ useCancelAction }}',
|
||||
},
|
||||
},
|
||||
action2: {
|
||||
title: 'Submit',
|
||||
'x-component': 'Action',
|
||||
'x-component-props': {
|
||||
type: 'primary',
|
||||
useAction: '{{ useUpdateAction }}',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
delete: {
|
||||
type: 'void',
|
||||
title: '删除',
|
||||
'x-component': 'Action.Link',
|
||||
'x-component-props': {
|
||||
useAction: '{{ useDestroyAction }}',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
@ -1,22 +1,59 @@
|
||||
import { Result } from 'ahooks/lib/useRequest/src/types';
|
||||
import React, { createContext, useContext, useEffect } from 'react';
|
||||
import { useRequest } from '../api-client';
|
||||
import { useRecord } from '..';
|
||||
import { useAPIClient, useRequest } from '../api-client';
|
||||
|
||||
export const ResourceActionContext = createContext<Result<any, any>>(null);
|
||||
|
||||
interface ResourceActionProviderProps {
|
||||
type?: 'association' | 'collection';
|
||||
request?: any;
|
||||
uid?: string;
|
||||
}
|
||||
|
||||
export const ResourceActionProvider: React.FC<ResourceActionProviderProps> = (props) => {
|
||||
const { request, uid } = props;
|
||||
console.log(request);
|
||||
const ResourceContext = createContext<any>(null);
|
||||
|
||||
const CollectionResourceActionProvider = (props) => {
|
||||
const { collection, request, uid } = props;
|
||||
const api = useAPIClient();
|
||||
const service = useRequest(request, {
|
||||
uid,
|
||||
refreshDeps: [request],
|
||||
});
|
||||
return <ResourceActionContext.Provider value={service}>{props.children}</ResourceActionContext.Provider>;
|
||||
const resource = api.resource(request.resource);
|
||||
return (
|
||||
<ResourceContext.Provider value={{ type: 'collection', resource, collection }}>
|
||||
<ResourceActionContext.Provider value={service}>{props.children}</ResourceActionContext.Provider>
|
||||
</ResourceContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
const AssociationResourceActionProvider = (props) => {
|
||||
const { association, request, uid } = props;
|
||||
const api = useAPIClient();
|
||||
const record = useRecord();
|
||||
const resourceOf = record[association.sourceKey];
|
||||
const service = useRequest(
|
||||
{ resourceOf, ...request },
|
||||
{
|
||||
uid,
|
||||
refreshDeps: [request, resourceOf],
|
||||
},
|
||||
);
|
||||
const resource = api.resource(request.resource, resourceOf);
|
||||
return (
|
||||
<ResourceContext.Provider value={{ type: 'association', resource, association }}>
|
||||
<ResourceActionContext.Provider value={service}>{props.children}</ResourceActionContext.Provider>
|
||||
</ResourceContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const ResourceActionProvider: React.FC<ResourceActionProviderProps> = (props) => {
|
||||
const { request } = props;
|
||||
if (request?.resource?.includes('.')) {
|
||||
return <AssociationResourceActionProvider {...props} />;
|
||||
}
|
||||
return <CollectionResourceActionProvider {...props} />;
|
||||
};
|
||||
|
||||
export const useResourceActionContext = () => {
|
||||
@ -32,3 +69,8 @@ export const useDataSourceFromRAC = (options: any) => {
|
||||
}, [service.loading]);
|
||||
return service;
|
||||
};
|
||||
|
||||
export const useResourceContext = () => {
|
||||
const { type, resource, collection, association } = useContext(ResourceContext);
|
||||
return { type, resource, collection, association, targetKey: association?.targetKey || collection?.targetKey };
|
||||
};
|
||||
|
@ -1,3 +1,4 @@
|
||||
export * from './useCollection';
|
||||
export * from './useCollectionField';
|
||||
export * from './useCollectionManager';
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { useContext } from 'react';
|
||||
import { SchemaKey } from '@formily/react';
|
||||
import { CollectionFieldOptions } from '../types';
|
||||
import { CollectionContext } from '../context';
|
||||
import { useContext } from 'react';
|
||||
import { useAPIClient } from '../../api-client';
|
||||
import { CollectionContext } from '../context';
|
||||
import { CollectionFieldOptions } from '../types';
|
||||
|
||||
export const useCollection = () => {
|
||||
const collection = useContext(CollectionContext);
|
||||
|
@ -1,15 +1,17 @@
|
||||
import { useContext } from 'react';
|
||||
import { CollectionFieldContext } from '../context';
|
||||
import { useRecord } from '../../record-provider';
|
||||
import { useCollection } from './useCollection';
|
||||
import { useAPIClient } from '../../api-client';
|
||||
import { useRecord } from '../../record-provider';
|
||||
import { CollectionFieldContext } from '../context';
|
||||
import { useCollection } from './useCollection';
|
||||
|
||||
export const useCollectionField = () => {
|
||||
const collection = useCollection();
|
||||
const record = useRecord();
|
||||
const api = useAPIClient();
|
||||
const ctx = useContext(CollectionFieldContext);
|
||||
const resource = api?.resource(`${collection?.name || ctx?.collectinName}.${ctx.name}`, record[ctx.sourceKey]);
|
||||
const resourceName = `${ctx?.collectinName || collection?.name}.${ctx.name}`;
|
||||
const resource = api?.resource(resourceName, record[ctx.sourceKey]);
|
||||
console.log({ resourceName });
|
||||
return {
|
||||
...ctx,
|
||||
resource,
|
||||
|
@ -7,6 +7,7 @@ export interface CollectionManagerOptions {
|
||||
|
||||
export interface CollectionOptions {
|
||||
name?: string;
|
||||
filterTargetKey?: string;
|
||||
fields?: any[];
|
||||
}
|
||||
|
||||
@ -18,6 +19,7 @@ export interface ICollectionProviderProps {
|
||||
export interface CollectionFieldOptions {
|
||||
name?: any;
|
||||
collectinName?: string;
|
||||
targetKey?: string;
|
||||
sourceKey?: string; // association field
|
||||
uiSchema?: ISchema;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user