Skip to content

Commit

Permalink
refactor: code splitting of the table component (nocobase#121)
Browse files Browse the repository at this point in the history
* refactor: 表格拆分模块化

* refactor: 表格拆分模块化

* refactor: code splitting of the table component (nocobase#120)

* missing TableIndex

* refactor: 表格拆分模块化

* code format

Co-authored-by: chenos <[email protected]>
  • Loading branch information
semmywong and chenos authored Dec 2, 2021
1 parent 1072e03 commit 12f58ef
Show file tree
Hide file tree
Showing 54 changed files with 2,886 additions and 2,848 deletions.
2 changes: 1 addition & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"singleQuote": true,
"trailingComma": "all",
"printWidth": 80,
"printWidth": 120,
"overrides": [
{
"files": ".prettierrc",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import { LockOutlined } from '@ant-design/icons';
import cls from 'classnames';
import { uid } from '@formily/shared';
import { Resource } from '../../../resource';
import { TableRowContext, useTable } from '../../../schemas/table';
import { TableRowContext } from '../../../schemas/table';
import { useTable } from '../../../schemas/table';
import { useRequest } from 'ahooks';
import { VisibleContext } from '../../../context';
import { connect, ISchema, observer, useField } from '@formily/react';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import { LockOutlined } from '@ant-design/icons';
import cls from 'classnames';
import { uid, isValid } from '@formily/shared';
import { Resource } from '../../../resource';
import { TableRowContext, useTable } from '../../../schemas/table';
import { TableRowContext } from '../../../schemas/table';
import { useTable } from '../../../schemas/table';
import { useRequest } from 'ahooks';
import { VisibleContext } from '../../../context';
import { connect, observer, useForm } from '@formily/react';
Expand Down
7 changes: 2 additions & 5 deletions packages/client/src/components/schema-renderer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,8 @@ import { Menu } from '../../schemas/menu';
import { Password } from '../../schemas/password';
import { Radio } from '../../schemas/radio';
import { Select } from '../../schemas/select';
import {
CollectionFieldContext,
Table,
TableRowContext,
} from '../../schemas/table';
import { Table } from '../../schemas/table';
import { CollectionFieldContext, TableRowContext } from '../../schemas/table';
import { Tabs } from '../../schemas/tabs';
import { TimePicker } from '../../schemas/time-picker';
import { Upload } from '../../schemas/upload';
Expand Down
40 changes: 40 additions & 0 deletions packages/client/src/schemas/table/Actions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React from 'react';
import { Space } from 'antd';
import { RecursionField } from '@formily/react';
import { useDesignable } from '..';
import { Droppable, SortableItem } from '../../components/Sortable';
import { getSchemaPath } from '../../components/schema-renderer';

export const Actions = (props: any) => {
const { align = 'left' } = props;
const { schema, designable } = useDesignable();
return (
<Droppable
id={`${schema.name}-${align}`}
className={`action-bar-align-${align}`}
data={{ align, path: getSchemaPath(schema) }}
>
<Space>
{schema.mapProperties((s) => {
const currentAlign = s['x-align'] || 'left';
if (currentAlign !== align) {
return null;
}
return (
<SortableItem
id={s.name}
data={{
align,
draggable: true,
title: s.title,
path: getSchemaPath(s),
}}
>
<RecursionField name={s.name} schema={s} />
</SortableItem>
);
})}
</Space>
</Droppable>
);
};
76 changes: 76 additions & 0 deletions packages/client/src/schemas/table/AddActionButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import React, { useState } from 'react';
import { Dropdown, Menu, Button } from 'antd';
import { SettingOutlined } from '@ant-design/icons';
import { useTranslation } from 'react-i18next';
import { Schema } from '@formily/react';
import { useDesignable, ISchema } from '..';
import { useDisplayedMapContext, useClient } from '../../constate';
import SwitchMenuItem from '../../components/SwitchMenuItem';
import { getSchemaPath } from '../../components/schema-renderer';
import { generateActionSchema } from './utils';

export const AddActionButton = () => {
const { t } = useTranslation();
const [visible, setVisible] = useState(false);
const displayed = useDisplayedMapContext();
const { appendChild, remove } = useDesignable();
const { schema, designable } = useDesignable();
const { createSchema, removeSchema, updateSchema } = useClient();

if (!designable || !schema['x-designable-bar']) {
return null;
}
return (
<Dropdown
trigger={['hover']}
visible={visible}
onVisibleChange={setVisible}
overlay={
<Menu>
<Menu.ItemGroup title={t('Enable actions')}>
{[
{ title: t('Filter'), name: 'filter' },
{ title: t('Export'), name: 'export' },
{ title: t('Add new'), name: 'create' },
{ title: t('Delete'), name: 'destroy' },
].map((item) => (
<SwitchMenuItem
key={item.name}
checked={displayed.has(item.name)}
title={item.title}
onChange={async (checked) => {
if (!checked) {
const s = displayed.get(item.name) as Schema;
const path = getSchemaPath(s);
displayed.remove(item.name);
const removed = remove(path);
await removeSchema(removed);
} else {
const s = generateActionSchema(item.name);
const data = appendChild(s);
await createSchema(data);
}
}}
/>
))}
</Menu.ItemGroup>
<Menu.Divider />
<Menu.SubMenu disabled title={t('Customize')}>
<Menu.Item style={{ minWidth: 120 }}>{t('Function')}</Menu.Item>
<Menu.Item>{t('Popup form')}</Menu.Item>
<Menu.Item>{t('Flexible popup')}</Menu.Item>
</Menu.SubMenu>
</Menu>
}
>
<Button
className={'designable-btn designable-btn-dash'}
style={{ marginLeft: 8 }}
type={'dashed'}
icon={<SettingOutlined />}
>
{t('Configure actions')}
</Button>
</Dropdown>
);
};
232 changes: 232 additions & 0 deletions packages/client/src/schemas/table/AddColumn.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
import React, { useState } from 'react';
import { Dropdown, Menu, Button } from 'antd';
import { SettingOutlined } from '@ant-design/icons';
import { useTranslation } from 'react-i18next';
import { uid } from '@formily/shared';
import { FormDialog, FormLayout } from '@formily/antd';
import { useDesignable, createCollectionField, ISchema } from '..';
import { useCollectionContext, useCollectionsContext, useDisplayedMapContext, useClient } from '../../constate';
import { useTable } from './hooks/useTable';
import SwitchMenuItem from '../../components/SwitchMenuItem';
import { isAssociation, options } from '../database-field/interfaces';
import { getSchemaPath, SchemaField } from '../../components/schema-renderer';

export function AddColumn() {
const { t } = useTranslation();
const [visible, setVisible] = useState(false);
const { appendChild, remove } = useDesignable();
const { loadCollections } = useCollectionsContext();
const { collection, fields, refresh } = useCollectionContext();
const displayed = useDisplayedMapContext();
const { service } = useTable();
const { createSchema, removeSchema, updateSchema } = useClient();
return (
<Dropdown
trigger={['hover']}
visible={visible}
onVisibleChange={setVisible}
overlay={
<Menu>
<Menu.ItemGroup className={'display-fields'} title={t('Display fields')}>
{fields.map((field) => (
<SwitchMenuItem
title={field?.uiSchema?.title}
checked={displayed.has(field.name)}
onChange={async (checked) => {
if (checked) {
console.log('SwitchMenuItem.field.name', field.dataType, service.params[0]);
const columnSchema: ISchema = {
type: 'void',
'x-component': 'Table.Column',
'x-component-props': {
fieldName: field.name,
},
'x-designable-bar': 'Table.Column.DesignableBar',
};
if (field.interface === 'linkTo') {
columnSchema.properties = {
options: {
type: 'void',
'x-decorator': 'Form',
'x-component': 'Select.Options.Drawer',
'x-component-props': {
useOkAction: '{{ Select.useOkAction }}',
},
title: "{{t('Select record')}}",
properties: {
table: {
type: 'array',
'x-designable-bar': 'Table.DesignableBar',
'x-decorator': 'BlockItem',
'x-decorator-props': {
draggable: false,
},
'x-component': 'Table',
default: [],
'x-component-props': {
rowKey: 'id',
useRowSelection: '{{ Select.useRowSelection }}',
useSelectedRowKeys: '{{ Select.useSelectedRowKeys }}',
onSelect: '{{ Select.useSelect() }}',
collectionName: field.target,
// dragSort: true,
// showIndex: true,
refreshRequestOnChange: true,
pagination: {
pageSize: 10,
},
},
properties: {
[uid()]: {
type: 'void',
'x-component': 'Table.ActionBar',
'x-designable-bar': 'Table.ActionBar.DesignableBar',
properties: {
[uid()]: {
type: 'void',
title: "{{t('Filter')}}",
'x-decorator': 'AddNew.Displayed',
'x-decorator-props': {
displayName: 'filter',
},
'x-align': 'left',
'x-component': 'Table.Filter',
'x-designable-bar': 'Table.Filter.DesignableBar',
'x-component-props': {
fieldNames: [],
},
},
},
},
},
},
},
},
option: {
type: 'void',
'x-component': 'Select.OptionTag',
properties: {
[uid()]: {
type: 'void',
title: "{{t('View record')}}",
'x-component': 'Action.Drawer',
'x-component-props': {
bodyStyle: {
background: '#f0f2f5',
},
},
properties: {
[uid()]: {
type: 'void',
'x-component': 'Tabs',
'x-designable-bar': 'Tabs.DesignableBar',
properties: {
[uid()]: {
type: 'void',
title: "{{t('Details')}}",
'x-designable-bar': 'Tabs.TabPane.DesignableBar',
'x-component': 'Tabs.TabPane',
'x-component-props': {},
properties: {
[uid()]: {
type: 'void',
'x-component': 'Grid',
'x-component-props': {
addNewComponent: 'AddNew.PaneItem',
},
},
},
},
},
},
},
},
},
},
};
}
const data = appendChild(columnSchema);
await createSchema(data);
if (isAssociation(field)) {
const defaultAppends = service.params[0]?.defaultAppends || [];
defaultAppends.push(field.name);
await service.run({
...service.params[0],
defaultAppends,
});
}
} else {
const s: any = displayed.get(field.name);
const p = getSchemaPath(s);
const removed = remove(p);
await removeSchema(removed);
displayed.remove(field.name);
if (isAssociation(field)) {
const defaultAppends = service.params[0]?.defaultAppends || [];
const index = defaultAppends.indexOf(field.name);
if (index > -1) {
defaultAppends.splice(index, 1);
}
await service.run({
...service.params[0],
defaultAppends,
});
}
}
// service.refresh();
}}
/>
))}
</Menu.ItemGroup>
<Menu.Divider />
<Menu.SubMenu disabled popupClassName={'add-new-fields-popup'} title={t('Add field')}>
{options.map((option) => (
<Menu.ItemGroup title={option.label}>
{option.children.map((item) => (
<Menu.Item
style={{ minWidth: 150 }}
key={item.name}
onClick={async () => {
setVisible(false);
const values = await FormDialog(t('Add field'), () => {
return (
<FormLayout layout={'vertical'}>
<SchemaField scope={{ loadCollections }} schema={item} />
</FormLayout>
);
}).open({
initialValues: {
interface: item.name,
...item.default,
key: uid(),
name: `f_${uid()}`,
},
});
await createCollectionField(collection?.name, values);
const data = appendChild({
type: 'void',
'x-component': 'Table.Column',
'x-component-props': {
fieldName: values.name,
},
'x-designable-bar': 'Table.Column.DesignableBar',
});
await createSchema(data);
await refresh();
}}
>
{item.title}
</Menu.Item>
))}
</Menu.ItemGroup>
))}
</Menu.SubMenu>
</Menu>
}
>
<Button type={'dashed'} className={'designable-btn designable-btn-dash'} icon={<SettingOutlined />}>
{t('Configure fields')}
</Button>
</Dropdown>
);
}
Loading

0 comments on commit 12f58ef

Please sign in to comment.