feat: collection configuration interface
This commit is contained in:
parent
2924418800
commit
7ed5054c41
@ -25,25 +25,12 @@ const schema: ISchema = {
|
|||||||
[uid()]: {
|
[uid()]: {
|
||||||
'x-component': 'Action.Drawer',
|
'x-component': 'Action.Drawer',
|
||||||
type: 'void',
|
type: 'void',
|
||||||
title: 'Drawer Title',
|
title: '角色配置',
|
||||||
properties: {
|
properties: {
|
||||||
hello1: {
|
hello1: {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
'x-component': 'RoleTable',
|
'x-component': 'RoleTable',
|
||||||
},
|
},
|
||||||
// footer1: {
|
|
||||||
// 'x-component': 'Action.Drawer.Footer',
|
|
||||||
// type: 'void',
|
|
||||||
// properties: {
|
|
||||||
// close1: {
|
|
||||||
// title: 'Close',
|
|
||||||
// 'x-component': 'Action',
|
|
||||||
// 'x-component-props': {
|
|
||||||
// useAction: '{{ useCloseAction }}',
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -215,7 +215,7 @@ export const ResourceActionsForm = () => {
|
|||||||
title: '可操作的数据范围',
|
title: '可操作的数据范围',
|
||||||
dataIndex: 'scope',
|
dataIndex: 'scope',
|
||||||
key: 'scope',
|
key: 'scope',
|
||||||
render: () => <ScopeRecordPicker />
|
render: () => <ScopeRecordPicker />,
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
dataSource={[
|
dataSource={[
|
||||||
|
@ -4,6 +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 { SchemaComponent, useActionVisible, VisibleContext } from '../schema-component';
|
import { SchemaComponent, useActionVisible, VisibleContext } from '../schema-component';
|
||||||
|
import { ConfigurationTable } from './Configuration';
|
||||||
|
|
||||||
const useCloseAction = () => {
|
const useCloseAction = () => {
|
||||||
const { setVisible } = useActionVisible();
|
const { setVisible } = useActionVisible();
|
||||||
@ -24,24 +25,10 @@ const schema: ISchema = {
|
|||||||
[uid()]: {
|
[uid()]: {
|
||||||
'x-component': 'Action.Drawer',
|
'x-component': 'Action.Drawer',
|
||||||
type: 'void',
|
type: 'void',
|
||||||
title: 'Drawer Title',
|
title: '数据表配置',
|
||||||
properties: {
|
properties: {
|
||||||
hello1: {
|
configuration: {
|
||||||
'x-content': 'Hello',
|
'x-component': 'ConfigurationTable',
|
||||||
title: 'T1',
|
|
||||||
},
|
|
||||||
footer1: {
|
|
||||||
'x-component': 'Action.Drawer.Footer',
|
|
||||||
type: 'void',
|
|
||||||
properties: {
|
|
||||||
close1: {
|
|
||||||
title: 'Close',
|
|
||||||
'x-component': 'Action',
|
|
||||||
'x-component-props': {
|
|
||||||
useAction: '{{ useCloseAction }}',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -59,7 +46,7 @@ export const CollectionManagerShortcut = () => {
|
|||||||
setVisible(true);
|
setVisible(true);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<SchemaComponent scope={{ useCloseAction }} schema={schema} />
|
<SchemaComponent scope={{ useCloseAction }} schema={schema} components={{ ConfigurationTable }} />
|
||||||
</VisibleContext.Provider>
|
</VisibleContext.Provider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
146
packages/client/src/collection-manager/Configuration.tsx
Normal file
146
packages/client/src/collection-manager/Configuration.tsx
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
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>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
50
packages/client/src/i18n/i18n.ts
Normal file
50
packages/client/src/i18n/i18n.ts
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
import i18next from 'i18next';
|
||||||
|
import moment from 'moment';
|
||||||
|
import { initReactI18next } from 'react-i18next';
|
||||||
|
|
||||||
|
const zhCN = require('../locale/zh_CN');
|
||||||
|
const enUS = require('../locale/en_US');
|
||||||
|
const log = require('debug')('i18next');
|
||||||
|
|
||||||
|
export const i18n = i18next.createInstance();
|
||||||
|
|
||||||
|
i18n.use(initReactI18next).init({
|
||||||
|
lng: localStorage.getItem('locale') || 'en-US',
|
||||||
|
debug: false,
|
||||||
|
defaultNS: 'client',
|
||||||
|
// parseMissingKeyHandler: (key) => {
|
||||||
|
// console.log('parseMissingKeyHandler', `'${key}': '${key}',`);
|
||||||
|
// return key;
|
||||||
|
// },
|
||||||
|
// ns: ['client'],
|
||||||
|
resources: {
|
||||||
|
'en-US': {
|
||||||
|
client: {
|
||||||
|
...enUS,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'zh-CN': {
|
||||||
|
client: {
|
||||||
|
...zhCN,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const momentLngs = {
|
||||||
|
'en-US': 'en',
|
||||||
|
'zh-CN': 'zh-cn',
|
||||||
|
};
|
||||||
|
|
||||||
|
function setMomentLng(language) {
|
||||||
|
const lng = momentLngs[language || 'en-US'] || 'en';
|
||||||
|
log(lng);
|
||||||
|
moment.locale(lng);
|
||||||
|
}
|
||||||
|
|
||||||
|
setMomentLng(localStorage.getItem('locale'));
|
||||||
|
|
||||||
|
i18n.on('languageChanged', (lng) => {
|
||||||
|
localStorage.setItem('locale', lng);
|
||||||
|
setMomentLng(lng);
|
||||||
|
});
|
@ -1,54 +1 @@
|
|||||||
import i18next from 'i18next';
|
export * from './i18n';
|
||||||
import { initReactI18next } from 'react-i18next';
|
|
||||||
import moment from 'moment';
|
|
||||||
|
|
||||||
const zhCN = require('../locale/zh_CN');
|
|
||||||
const enUS = require('../locale/en_US');
|
|
||||||
const log = require('debug')('i18next');
|
|
||||||
|
|
||||||
export const i18n = i18next.createInstance();
|
|
||||||
|
|
||||||
i18n.use(initReactI18next).init({
|
|
||||||
lng: localStorage.getItem('locale') || 'en-US',
|
|
||||||
debug: false,
|
|
||||||
defaultNS: 'client',
|
|
||||||
// parseMissingKeyHandler: (key) => {
|
|
||||||
// console.log('parseMissingKeyHandler', `'${key}': '${key}',`);
|
|
||||||
// return key;
|
|
||||||
// },
|
|
||||||
// ns: ['client'],
|
|
||||||
resources: {
|
|
||||||
'en-US': {
|
|
||||||
client: {
|
|
||||||
...enUS,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'zh-CN': {
|
|
||||||
client: {
|
|
||||||
...zhCN,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const momentLngs = {
|
|
||||||
'en-US': 'en',
|
|
||||||
'zh-CN': 'zh-cn',
|
|
||||||
};
|
|
||||||
|
|
||||||
function setMomentLng(language) {
|
|
||||||
const lng = momentLngs[language || 'en-US'] || 'en';
|
|
||||||
log(lng);
|
|
||||||
moment.locale(lng);
|
|
||||||
}
|
|
||||||
|
|
||||||
setMomentLng(localStorage.getItem('locale'));
|
|
||||||
|
|
||||||
i18n.on('languageChanged', (lng) => {
|
|
||||||
localStorage.setItem('locale', lng);
|
|
||||||
setMomentLng(lng);
|
|
||||||
});
|
|
||||||
|
|
||||||
// export const t = i18n.t;
|
|
||||||
|
|
||||||
export default i18n;
|
|
||||||
|
@ -9,6 +9,12 @@ export const ActionDrawer: ComposedActionDrawer = observer((props) => {
|
|||||||
const [visible, setVisible] = useContext(VisibleContext);
|
const [visible, setVisible] = useContext(VisibleContext);
|
||||||
const schema = useFieldSchema();
|
const schema = useFieldSchema();
|
||||||
const field = useField();
|
const field = useField();
|
||||||
|
const footerSchema = schema.reduceProperties((buf, s) => {
|
||||||
|
if (s['x-component'] === 'Action.Drawer.Footer') {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
});
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{createPortal(
|
{createPortal(
|
||||||
@ -20,6 +26,7 @@ export const ActionDrawer: ComposedActionDrawer = observer((props) => {
|
|||||||
visible={visible}
|
visible={visible}
|
||||||
onClose={() => setVisible(false)}
|
onClose={() => setVisible(false)}
|
||||||
footer={
|
footer={
|
||||||
|
footerSchema && (
|
||||||
<RecursionField
|
<RecursionField
|
||||||
basePath={field.address}
|
basePath={field.address}
|
||||||
schema={schema}
|
schema={schema}
|
||||||
@ -28,6 +35,7 @@ export const ActionDrawer: ComposedActionDrawer = observer((props) => {
|
|||||||
return s['x-component'] === 'Action.Drawer.Footer';
|
return s['x-component'] === 'Action.Drawer.Footer';
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<RecursionField
|
<RecursionField
|
||||||
|
Loading…
Reference in New Issue
Block a user