feat(client): improve code
This commit is contained in:
parent
0ee81dc221
commit
8b4d59ee97
@ -4,7 +4,7 @@ import { uid } from '@formily/shared';
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { PluginManager } from '../plugin-manager';
|
import { PluginManager } from '../plugin-manager';
|
||||||
import { ActionContext, SchemaComponent, useActionContext } from '../schema-component';
|
import { ActionContext, SchemaComponent, useActionContext } from '../schema-component';
|
||||||
import { RoleTable } from './RolePermissionManager';
|
import * as components from './Configuration';
|
||||||
|
|
||||||
const useCloseAction = () => {
|
const useCloseAction = () => {
|
||||||
const { setVisible } = useActionContext();
|
const { setVisible } = useActionContext();
|
||||||
@ -47,7 +47,7 @@ export const ACLShortcut = () => {
|
|||||||
setVisible(true);
|
setVisible(true);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<SchemaComponent components={{ RoleTable }} scope={{ useCloseAction }} schema={schema} />
|
<SchemaComponent components={components} scope={{ useCloseAction }} schema={schema} />
|
||||||
</ActionContext.Provider>
|
</ActionContext.Provider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
25
packages/client/src/acl/Configuration/MenuConfigure.tsx
Normal file
25
packages/client/src/acl/Configuration/MenuConfigure.tsx
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { Table } from 'antd';
|
||||||
|
import React from 'react';
|
||||||
|
import { useRoute } from '../../route-switch';
|
||||||
|
|
||||||
|
export const MenuConfigure = () => {
|
||||||
|
const route = useRoute();
|
||||||
|
console.log(route);
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Table
|
||||||
|
columns={[
|
||||||
|
{
|
||||||
|
dataIndex: 'title',
|
||||||
|
title: '菜单项',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'accessible',
|
||||||
|
title: '允许访问',
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
dataSource={[]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
37
packages/client/src/acl/Configuration/RoleConfigure.tsx
Normal file
37
packages/client/src/acl/Configuration/RoleConfigure.tsx
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import { FormLayout } from '@formily/antd';
|
||||||
|
import React from 'react';
|
||||||
|
import { SchemaComponent } from '../../schema-component';
|
||||||
|
|
||||||
|
export const RoleConfigure = () => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<FormLayout layout={'vertical'}>
|
||||||
|
<SchemaComponent
|
||||||
|
schema={{
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
allowConfigure: {
|
||||||
|
title: '配置权限',
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-component': 'Checkbox',
|
||||||
|
'x-content': '允许配置系统,包括界面配置、数据表配置、权限配置、系统配置等全部配置项',
|
||||||
|
},
|
||||||
|
strategy: {
|
||||||
|
title: '通用数据操作权限',
|
||||||
|
description: '所有数据表都默认使用通用数据操作权限;同时,可以针对每个数据表单独配置权限。',
|
||||||
|
'x-component': 'StrategyActions',
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
},
|
||||||
|
allowNewMenu: {
|
||||||
|
title: '新增菜单项默认访问权限',
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-component': 'Checkbox',
|
||||||
|
'x-content': '新增菜单项默认允许访问',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</FormLayout>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
11
packages/client/src/acl/Configuration/RoleTable.tsx
Normal file
11
packages/client/src/acl/Configuration/RoleTable.tsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { SchemaComponent } from '../../schema-component';
|
||||||
|
import { roleSchema } from './schemas/roles';
|
||||||
|
|
||||||
|
export const RoleTable = () => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<SchemaComponent schema={roleSchema} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
@ -0,0 +1,55 @@
|
|||||||
|
import { FormItem, FormLayout } from '@formily/antd';
|
||||||
|
import { Checkbox, Select, Table } from 'antd';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
export const RolesResourcesActions = () => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<FormLayout layout={'vertical'}>
|
||||||
|
<FormItem label={'操作权限'}>
|
||||||
|
<Table
|
||||||
|
size={'small'}
|
||||||
|
pagination={false}
|
||||||
|
columns={[
|
||||||
|
{
|
||||||
|
dataIndex: 'displayName',
|
||||||
|
title: '操作',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'type',
|
||||||
|
title: '类型',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'enable',
|
||||||
|
title: '允许操作',
|
||||||
|
render: () => <Checkbox />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'scope',
|
||||||
|
title: '可操作的数据范围',
|
||||||
|
render: () => <Select size={'small'} />,
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
dataSource={[
|
||||||
|
{
|
||||||
|
displayName: '添加',
|
||||||
|
type: 'new-data',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: '导入',
|
||||||
|
type: 'new-data',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: '查看',
|
||||||
|
type: 'old-data',
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label={'字段权限'}>
|
||||||
|
<Table />
|
||||||
|
</FormItem>
|
||||||
|
</FormLayout>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
47
packages/client/src/acl/Configuration/StrategyActions.tsx
Normal file
47
packages/client/src/acl/Configuration/StrategyActions.tsx
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import { Checkbox, Select, Table } from 'antd';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
export const StrategyActions = () => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Table
|
||||||
|
size={'small'}
|
||||||
|
pagination={false}
|
||||||
|
columns={[
|
||||||
|
{
|
||||||
|
dataIndex: 'displayName',
|
||||||
|
title: '操作',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'type',
|
||||||
|
title: '类型',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'enable',
|
||||||
|
title: '允许操作',
|
||||||
|
render: () => <Checkbox />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: 'scope',
|
||||||
|
title: '可操作的数据范围',
|
||||||
|
render: () => <Select size={'small'}/>,
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
dataSource={[
|
||||||
|
{
|
||||||
|
displayName: '添加',
|
||||||
|
type: 'new-data',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: '导入',
|
||||||
|
type: 'new-data',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: '查看',
|
||||||
|
type: 'old-data',
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
6
packages/client/src/acl/Configuration/index.tsx
Normal file
6
packages/client/src/acl/Configuration/index.tsx
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export * from './MenuConfigure';
|
||||||
|
export * from './RoleConfigure';
|
||||||
|
export * from './RolesResourcesActions';
|
||||||
|
export * from './RoleTable';
|
||||||
|
export * from './StrategyActions';
|
||||||
|
|
175
packages/client/src/acl/Configuration/schemas/roleCollections.ts
Normal file
175
packages/client/src/acl/Configuration/schemas/roleCollections.ts
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
import { ISchema } from '@formily/react';
|
||||||
|
|
||||||
|
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 roleCollectionsSchema: ISchema = {
|
||||||
|
type: 'void',
|
||||||
|
'x-decorator': 'ResourceActionProvider',
|
||||||
|
'x-decorator-props': {
|
||||||
|
association: {
|
||||||
|
sourceKey: 'name',
|
||||||
|
targetKey: 'name',
|
||||||
|
},
|
||||||
|
resourceName: 'roles.collections',
|
||||||
|
request: {
|
||||||
|
resource: 'roles.collections',
|
||||||
|
action: 'list',
|
||||||
|
params: {
|
||||||
|
pageSize: 5,
|
||||||
|
filter: {},
|
||||||
|
sort: ['sort'],
|
||||||
|
appends: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-component': 'CollectionProvider',
|
||||||
|
'x-component-props': {
|
||||||
|
collection,
|
||||||
|
},
|
||||||
|
properties: {
|
||||||
|
table1: {
|
||||||
|
type: 'void',
|
||||||
|
'x-uid': 'input',
|
||||||
|
'x-component': 'VoidTable',
|
||||||
|
'x-component-props': {
|
||||||
|
rowKey: 'name',
|
||||||
|
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: {
|
||||||
|
configure: {
|
||||||
|
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: {
|
||||||
|
usingActionsConfig: {
|
||||||
|
'x-component': 'Radio.Group',
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
enum: [
|
||||||
|
{ value: false, label: '使用通用权限:只能查看、添加、修改数据' },
|
||||||
|
{ value: true, label: '单独配置权限' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
'x-component': 'RolesResourcesActions',
|
||||||
|
'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: '{{ useUpdateAction }}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
288
packages/client/src/acl/Configuration/schemas/roles.ts
Normal file
288
packages/client/src/acl/Configuration/schemas/roles.ts
Normal file
@ -0,0 +1,288 @@
|
|||||||
|
import { ISchema } from '@formily/react';
|
||||||
|
import { roleCollectionsSchema } from './roleCollections';
|
||||||
|
|
||||||
|
const collection = {
|
||||||
|
name: 'roles',
|
||||||
|
filterTargetKey: 'name',
|
||||||
|
targetKey: '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,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
export const roleSchema: ISchema = {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
block1: {
|
||||||
|
type: 'void',
|
||||||
|
'x-decorator': 'ResourceActionProvider',
|
||||||
|
'x-decorator-props': {
|
||||||
|
collection: {
|
||||||
|
targetKey: 'name',
|
||||||
|
},
|
||||||
|
resourceName: 'roles',
|
||||||
|
request: {
|
||||||
|
resource: 'roles',
|
||||||
|
action: 'list',
|
||||||
|
params: {
|
||||||
|
pageSize: 5,
|
||||||
|
filter: {},
|
||||||
|
sort: ['createdAt'],
|
||||||
|
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: {
|
||||||
|
tabs1: {
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Tabs',
|
||||||
|
'x-component-props': {},
|
||||||
|
properties: {
|
||||||
|
tab1: {
|
||||||
|
type: 'void',
|
||||||
|
title: '系统全局配置',
|
||||||
|
'x-component': 'Tabs.TabPane',
|
||||||
|
'x-component-props': {},
|
||||||
|
properties: {
|
||||||
|
role: {
|
||||||
|
'x-component': 'RoleConfigure',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
tab2: {
|
||||||
|
type: 'void',
|
||||||
|
title: '数据权限',
|
||||||
|
'x-component': 'Tabs.TabPane',
|
||||||
|
'x-component-props': {},
|
||||||
|
properties: {
|
||||||
|
roleCollectionsSchema,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
tab3: {
|
||||||
|
type: 'void',
|
||||||
|
title: '菜单访问权限',
|
||||||
|
'x-component': 'Tabs.TabPane',
|
||||||
|
'x-component-props': {},
|
||||||
|
properties: {
|
||||||
|
menu: {
|
||||||
|
'x-component': 'MenuConfigure',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
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 }}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
@ -7,11 +7,12 @@ import {
|
|||||||
ResourceActionProvider,
|
ResourceActionProvider,
|
||||||
useDataSourceFromRAC
|
useDataSourceFromRAC
|
||||||
} from './';
|
} from './';
|
||||||
|
import * as hooks from './action-hooks';
|
||||||
|
|
||||||
export const CollectionManagerSchemaComponentProvider: React.FC = (props) => {
|
export const CollectionManagerSchemaComponentProvider: React.FC = (props) => {
|
||||||
return (
|
return (
|
||||||
<SchemaComponentOptions
|
<SchemaComponentOptions
|
||||||
scope={{ useDataSourceFromRAC }}
|
scope={{ ...hooks, useDataSourceFromRAC }}
|
||||||
components={{ CollectionField, CollectionFieldProvider, CollectionProvider, ResourceActionProvider }}
|
components={{ CollectionField, CollectionFieldProvider, CollectionProvider, ResourceActionProvider }}
|
||||||
>
|
>
|
||||||
{props.children}
|
{props.children}
|
||||||
|
@ -1,81 +1,12 @@
|
|||||||
import { useForm } from '@formily/react';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useResourceActionContext, useResourceContext } from '..';
|
import { SchemaComponent } from '../../schema-component';
|
||||||
import { useRequest } from '../../api-client';
|
|
||||||
import { useRecord } from '../../record-provider';
|
|
||||||
import { SchemaComponent, useActionContext } from '../../schema-component';
|
|
||||||
import { collectionSchema } from './schemas/collections';
|
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 = () => {
|
export const ConfigurationTable = () => {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<SchemaComponent
|
<SchemaComponent
|
||||||
schema={collectionSchema}
|
schema={collectionSchema}
|
||||||
scope={{ useCancelAction, useCreateAction, useUpdateAction, useDestroyAction, useValues }}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
69
packages/client/src/collection-manager/action-hooks.ts
Normal file
69
packages/client/src/collection-manager/action-hooks.ts
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
import { useForm } from '@formily/react';
|
||||||
|
import { useRequest } from '../api-client';
|
||||||
|
import { useRecord } from '../record-provider';
|
||||||
|
import { useActionContext } from '../schema-component';
|
||||||
|
import { useResourceActionContext, useResourceContext } from './ResourceActionProvider';
|
||||||
|
|
||||||
|
export const useCancelAction = () => {
|
||||||
|
const form = useForm();
|
||||||
|
const ctx = useActionContext();
|
||||||
|
return {
|
||||||
|
async run() {
|
||||||
|
ctx.setVisible(false);
|
||||||
|
form.reset();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export 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();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export 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();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useDestroyAction = () => {
|
||||||
|
const { refresh } = useResourceActionContext();
|
||||||
|
const { resource, targetKey } = useResourceContext();
|
||||||
|
const { [targetKey]: filterByTk } = useRecord();
|
||||||
|
return {
|
||||||
|
async run() {
|
||||||
|
await resource.destroy({ filterByTk });
|
||||||
|
refresh();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useValues = (options) => {
|
||||||
|
const record = useRecord();
|
||||||
|
return useRequest(() => Promise.resolve({ data: record }), {
|
||||||
|
...options,
|
||||||
|
refreshDeps: [record],
|
||||||
|
});
|
||||||
|
};
|
@ -7,7 +7,7 @@ export const ActionBar = () => {
|
|||||||
const fieldSchema = useFieldSchema();
|
const fieldSchema = useFieldSchema();
|
||||||
const ActionInitializer = useComponent(fieldSchema['x-action-initializer']);
|
const ActionInitializer = useComponent(fieldSchema['x-action-initializer']);
|
||||||
return (
|
return (
|
||||||
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
|
<div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 16 }}>
|
||||||
<div style={{ display: 'flex', justifyContent: 'space-between', width: '100%' }}>
|
<div style={{ display: 'flex', justifyContent: 'space-between', width: '100%' }}>
|
||||||
<Space>
|
<Space>
|
||||||
{fieldSchema.mapProperties((schema, key) => {
|
{fieldSchema.mapProperties((schema, key) => {
|
||||||
|
@ -6,6 +6,7 @@ export default {
|
|||||||
sortable: 'sort',
|
sortable: 'sort',
|
||||||
autoGenId: false,
|
autoGenId: false,
|
||||||
model: 'CollectionModel',
|
model: 'CollectionModel',
|
||||||
|
repository: 'CollectionRepository',
|
||||||
timestamps: false,
|
timestamps: false,
|
||||||
filterTargetKey: 'name',
|
filterTargetKey: 'name',
|
||||||
fields: [
|
fields: [
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { Plugin } from '@nocobase/server';
|
import { Plugin } from '@nocobase/server';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
import { CollectionRepository } from '.';
|
||||||
import {
|
import {
|
||||||
afterCreateForReverseField,
|
afterCreateForReverseField,
|
||||||
beforeCreateForChildrenCollection,
|
beforeCreateForChildrenCollection,
|
||||||
@ -15,6 +16,10 @@ export class CollectionManagerPlugin extends Plugin {
|
|||||||
FieldModel,
|
FieldModel,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.app.db.registerRepositories({
|
||||||
|
CollectionRepository,
|
||||||
|
});
|
||||||
|
|
||||||
// 要在 beforeInitOptions 之前处理
|
// 要在 beforeInitOptions 之前处理
|
||||||
this.app.db.on('fields.beforeCreate', beforeCreateForReverseField(this.app.db));
|
this.app.db.on('fields.beforeCreate', beforeCreateForReverseField(this.app.db));
|
||||||
this.app.db.on('fields.beforeCreate', beforeCreateForChildrenCollection(this.app.db));
|
this.app.db.on('fields.beforeCreate', beforeCreateForChildrenCollection(this.app.db));
|
||||||
@ -41,6 +46,10 @@ export class CollectionManagerPlugin extends Plugin {
|
|||||||
await model.migrate({ transaction });
|
await model.migrate({ transaction });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.app.on('beforeStart', async () => {
|
||||||
|
await this.app.db.getRepository<CollectionRepository>('collections').load();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async load() {
|
async load() {
|
||||||
|
@ -7,7 +7,7 @@ interface LoadOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class CollectionRepository extends Repository {
|
export class CollectionRepository extends Repository {
|
||||||
async load(options?: LoadOptions) {
|
async load(options: LoadOptions = {}) {
|
||||||
const { filter, skipExist } = options;
|
const { filter, skipExist } = options;
|
||||||
const instances = (await this.find({ filter })) as CollectionModel[];
|
const instances = (await this.find({ filter })) as CollectionModel[];
|
||||||
for (const instance of instances) {
|
for (const instance of instances) {
|
||||||
|
Loading…
Reference in New Issue
Block a user