feat: improve code
This commit is contained in:
parent
f8c3c6a19b
commit
0314faeae9
@ -162,6 +162,7 @@ export const SchemaField = createSchemaField({
|
|||||||
loadData: loadChinaRegionData,
|
loadData: loadChinaRegionData,
|
||||||
loadDataSource: loadChinaRegionDataSource,
|
loadDataSource: loadChinaRegionDataSource,
|
||||||
},
|
},
|
||||||
|
Select,
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
Card,
|
Card,
|
||||||
|
39
packages/client/src/demos/RequestProvider.tsx
Normal file
39
packages/client/src/demos/RequestProvider.tsx
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import { useRequest } from 'ahooks';
|
||||||
|
import { Spin } from 'antd';
|
||||||
|
import React, { useMemo } from 'react';
|
||||||
|
import { MemoryRouter as Router } from 'react-router-dom';
|
||||||
|
import {
|
||||||
|
createRouteSwitch,
|
||||||
|
RouteRedirectProps,
|
||||||
|
AdminLayout,
|
||||||
|
AuthLayout,
|
||||||
|
RouteSchemaRenderer,
|
||||||
|
} from '../';
|
||||||
|
import { UseRequestProvider } from 'ahooks';
|
||||||
|
import { extend } from 'umi-request';
|
||||||
|
|
||||||
|
const request = extend({
|
||||||
|
prefix: process.env.API_URL,
|
||||||
|
timeout: 30000,
|
||||||
|
});
|
||||||
|
|
||||||
|
request.use(async (ctx, next) => {
|
||||||
|
const { headers } = ctx.req.options as any;
|
||||||
|
const token = localStorage.getItem('NOCOBASE_TOKEN');
|
||||||
|
if (token) {
|
||||||
|
headers['Authorization'] = `Bearer ${token}`;
|
||||||
|
}
|
||||||
|
await next();
|
||||||
|
});
|
||||||
|
|
||||||
|
export const RequestProvider = (props) => {
|
||||||
|
return (
|
||||||
|
<UseRequestProvider
|
||||||
|
value={{
|
||||||
|
requestMethod: (service) => request(service),
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{props.children}
|
||||||
|
</UseRequestProvider>
|
||||||
|
);
|
||||||
|
};
|
@ -124,16 +124,7 @@ function generateCardItemSchema(component) {
|
|||||||
'x-designable-bar': 'Table.DesignableBar',
|
'x-designable-bar': 'Table.DesignableBar',
|
||||||
'x-decorator': 'CardItem',
|
'x-decorator': 'CardItem',
|
||||||
'x-component': 'Table',
|
'x-component': 'Table',
|
||||||
default: [
|
default: [],
|
||||||
// { key: uid(), field1: uid(), field2: uid() },
|
|
||||||
// { key: uid(), field1: uid(), field2: uid() },
|
|
||||||
// { key: uid(), field1: uid(), field2: uid() },
|
|
||||||
// { key: uid(), field1: uid(), field2: uid() },
|
|
||||||
// { key: uid(), field1: uid(), field2: uid() },
|
|
||||||
// { key: uid(), field1: uid(), field2: uid() },
|
|
||||||
// { key: uid(), field1: uid(), field2: uid() },
|
|
||||||
// { key: uid(), field1: uid(), field2: uid() },
|
|
||||||
],
|
|
||||||
'x-component-props': {
|
'x-component-props': {
|
||||||
rowKey: 'id',
|
rowKey: 'id',
|
||||||
dragSort: true,
|
dragSort: true,
|
||||||
@ -178,7 +169,7 @@ function generateCardItemSchema(component) {
|
|||||||
icon: 'DeleteOutlined',
|
icon: 'DeleteOutlined',
|
||||||
confirm: {
|
confirm: {
|
||||||
title: '删除数据',
|
title: '删除数据',
|
||||||
content: '删除后无法恢复,确定要删除吗?'
|
content: '删除后无法恢复,确定要删除吗?',
|
||||||
},
|
},
|
||||||
useAction: '{{ Table.useTableDestroyAction }}',
|
useAction: '{{ Table.useTableDestroyAction }}',
|
||||||
},
|
},
|
||||||
@ -1407,6 +1398,110 @@ AddNew.FormItem = observer((props: any) => {
|
|||||||
fieldName: field.name,
|
fieldName: field.name,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
if (field.interface === 'linkTo') {
|
||||||
|
data.properties = {
|
||||||
|
options: {
|
||||||
|
type: 'void',
|
||||||
|
'x-decorator': 'Form',
|
||||||
|
'x-component': 'Select.Options.Drawer',
|
||||||
|
'x-component-props': {
|
||||||
|
useOkAction: '{{ Select.useOkAction }}',
|
||||||
|
},
|
||||||
|
title: '关联数据',
|
||||||
|
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',
|
||||||
|
defaultSelectedRowKeys: '{{ 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: '筛选',
|
||||||
|
'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: '查看数据',
|
||||||
|
'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: '详情',
|
||||||
|
'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',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
if (isGridBlock(schema)) {
|
if (isGridBlock(schema)) {
|
||||||
path.pop();
|
path.pop();
|
||||||
path.pop();
|
path.pop();
|
||||||
|
@ -28,6 +28,7 @@ import cls from 'classnames';
|
|||||||
import { Droppable, SortableItem } from '../../components/Sortable';
|
import { Droppable, SortableItem } from '../../components/Sortable';
|
||||||
import { useDndContext } from '@dnd-kit/core';
|
import { useDndContext } from '@dnd-kit/core';
|
||||||
import { getSchemaPath } from '../../components/schema-renderer';
|
import { getSchemaPath } from '../../components/schema-renderer';
|
||||||
|
import { BlockSchemaContext } from '../../context';
|
||||||
|
|
||||||
const DraggableBlock = (props) => {
|
const DraggableBlock = (props) => {
|
||||||
const { className, children, ...others } = props;
|
const { className, children, ...others } = props;
|
||||||
@ -62,8 +63,13 @@ const Block = (props) => {
|
|||||||
export const BlockItem: any = observer((props: any) => {
|
export const BlockItem: any = observer((props: any) => {
|
||||||
const { draggable = true } = props;
|
const { draggable = true } = props;
|
||||||
const ctx = useDndContext();
|
const ctx = useDndContext();
|
||||||
return React.createElement(
|
const { schema } = useDesignable();
|
||||||
|
return (
|
||||||
|
<BlockSchemaContext.Provider value={schema}>
|
||||||
|
{React.createElement(
|
||||||
draggable && ctx.activators?.length > 0 ? DraggableBlock : Block,
|
draggable && ctx.activators?.length > 0 ? DraggableBlock : Block,
|
||||||
props,
|
props,
|
||||||
|
)}
|
||||||
|
</BlockSchemaContext.Provider>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -24,12 +24,10 @@ import { BlockSchemaContext } from '../../context';
|
|||||||
export const CardItem: any = connect((props) => {
|
export const CardItem: any = connect((props) => {
|
||||||
const { schema } = useDesignable();
|
const { schema } = useDesignable();
|
||||||
return (
|
return (
|
||||||
<BlockSchemaContext.Provider value={schema}>
|
|
||||||
<BlockItem className={'nb-card-item'}>
|
<BlockItem className={'nb-card-item'}>
|
||||||
<Card bordered={false} {...props}>
|
<Card bordered={false} {...props}>
|
||||||
{props.children}
|
{props.children}
|
||||||
</Card>
|
</Card>
|
||||||
</BlockItem>
|
</BlockItem>
|
||||||
</BlockSchemaContext.Provider>
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -11,7 +11,13 @@ import {
|
|||||||
useForm,
|
useForm,
|
||||||
RecursionField,
|
RecursionField,
|
||||||
} from '@formily/react';
|
} from '@formily/react';
|
||||||
import { useSchemaPath, SchemaField, useDesignable, removeSchema, ISchema } from '../';
|
import {
|
||||||
|
useSchemaPath,
|
||||||
|
SchemaField,
|
||||||
|
useDesignable,
|
||||||
|
removeSchema,
|
||||||
|
ISchema,
|
||||||
|
} from '../';
|
||||||
import get from 'lodash/get';
|
import get from 'lodash/get';
|
||||||
import { Button, Dropdown, Menu, message, Space } from 'antd';
|
import { Button, Dropdown, Menu, message, Space } from 'antd';
|
||||||
import { MenuOutlined, DragOutlined } from '@ant-design/icons';
|
import { MenuOutlined, DragOutlined } from '@ant-design/icons';
|
||||||
@ -38,6 +44,7 @@ import {
|
|||||||
import { useResource as useGeneralResource } from '../../hooks/useResource';
|
import { useResource as useGeneralResource } from '../../hooks/useResource';
|
||||||
import { Resource } from '../../resource';
|
import { Resource } from '../../resource';
|
||||||
import { BaseResult } from '@ahooksjs/use-request/lib/types';
|
import { BaseResult } from '@ahooksjs/use-request/lib/types';
|
||||||
|
import { CollectionFieldContext } from '../table';
|
||||||
|
|
||||||
export interface DescriptionsContextProps {
|
export interface DescriptionsContextProps {
|
||||||
resource?: Resource;
|
resource?: Resource;
|
||||||
@ -87,15 +94,11 @@ const FormMain = (props: any) => {
|
|||||||
'x-decorator': 'Form.__Decorator',
|
'x-decorator': 'Form.__Decorator',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
const content = (
|
const content = (
|
||||||
<FormProvider form={form}>
|
<FormProvider form={form}>
|
||||||
{schema['x-decorator'] === 'Form' ? (
|
{schema['x-decorator'] === 'Form' ? (
|
||||||
<SchemaField
|
<SchemaField components={options.components} scope={scope} schema={s} />
|
||||||
components={options.components}
|
|
||||||
scope={scope}
|
|
||||||
schema={s}
|
|
||||||
/>
|
|
||||||
) : (
|
) : (
|
||||||
<FormLayout layout={'vertical'} {...others}>
|
<FormLayout layout={'vertical'} {...others}>
|
||||||
<SchemaField
|
<SchemaField
|
||||||
@ -180,7 +183,9 @@ Form.Field = observer((props: any) => {
|
|||||||
const required = schema['required'] || collectionField?.uiSchema?.required;
|
const required = schema['required'] || collectionField?.uiSchema?.required;
|
||||||
const description =
|
const description =
|
||||||
schema['description'] || collectionField?.uiSchema?.description;
|
schema['description'] || collectionField?.uiSchema?.description;
|
||||||
|
console.log('schema.properties', schema.properties)
|
||||||
return (
|
return (
|
||||||
|
<CollectionFieldContext.Provider value={collectionField}>
|
||||||
<RecursionField
|
<RecursionField
|
||||||
name={randomName}
|
name={randomName}
|
||||||
schema={
|
schema={
|
||||||
@ -194,11 +199,15 @@ Form.Field = observer((props: any) => {
|
|||||||
required,
|
required,
|
||||||
description,
|
description,
|
||||||
'x-decorator': 'FormilyFormItem',
|
'x-decorator': 'FormilyFormItem',
|
||||||
|
properties: {
|
||||||
|
...schema.properties,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
} as ISchema)
|
} as ISchema)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
</CollectionFieldContext.Provider>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
206
packages/client/src/schemas/select/demos/demo1.tsx
Normal file
206
packages/client/src/schemas/select/demos/demo1.tsx
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { ISchema, SchemaRenderer } from '../../';
|
||||||
|
import { useSelect, useOptionTagValues } from '../';
|
||||||
|
import { uid } from '@formily/shared';
|
||||||
|
import { RequestProvider } from '@nocobase/client/src/demos/RequestProvider';
|
||||||
|
import { CollectionsProvider } from '@nocobase/client/src/constate';
|
||||||
|
|
||||||
|
console.log({ useSelect });
|
||||||
|
|
||||||
|
const dataSource = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
title: '标题1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
title: '标题2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
title: '标题3',
|
||||||
|
},
|
||||||
|
] as any[];
|
||||||
|
|
||||||
|
function useValues() {
|
||||||
|
return {
|
||||||
|
table: dataSource,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const schema: ISchema = {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
input: {
|
||||||
|
interface: 'select',
|
||||||
|
type: 'string',
|
||||||
|
title: `编辑模式`,
|
||||||
|
enum: dataSource,
|
||||||
|
default: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
title: '标题1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
title: '标题2',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-component': 'Select.Drawer',
|
||||||
|
'x-component-props': {
|
||||||
|
placeholder: 'please enter',
|
||||||
|
mode: 'tags',
|
||||||
|
fieldNames: {
|
||||||
|
label: 'title',
|
||||||
|
value: 'id',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-reactions': {
|
||||||
|
target: 'read',
|
||||||
|
fulfill: {
|
||||||
|
state: {
|
||||||
|
value: '{{$self.value}}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
properties: {
|
||||||
|
options: {
|
||||||
|
type: 'void',
|
||||||
|
'x-decorator': 'Form',
|
||||||
|
'x-component': 'Select.Options.Drawer',
|
||||||
|
title: '关联数据',
|
||||||
|
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',
|
||||||
|
collectionName: 'users',
|
||||||
|
// 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: '筛选',
|
||||||
|
'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: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
read: {
|
||||||
|
interface: 'select',
|
||||||
|
type: 'string',
|
||||||
|
title: `阅读模式`,
|
||||||
|
enum: dataSource,
|
||||||
|
default: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
title: '标题1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
title: '标题2',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'x-read-pretty': true,
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-component': 'Select.Drawer',
|
||||||
|
'x-component-props': {
|
||||||
|
placeholder: 'please enter',
|
||||||
|
mode: 'tags',
|
||||||
|
fieldNames: {
|
||||||
|
label: 'title',
|
||||||
|
value: 'id',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
properties: {
|
||||||
|
option: {
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Select.OptionTag',
|
||||||
|
properties: {
|
||||||
|
[uid()]: {
|
||||||
|
type: 'void',
|
||||||
|
title: '查看数据',
|
||||||
|
'x-component': 'Action.Drawer',
|
||||||
|
'x-component-props': {
|
||||||
|
bodyStyle: {
|
||||||
|
background: '#f0f2f5',
|
||||||
|
// paddingTop: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
properties: {
|
||||||
|
[uid()]: {
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Tabs',
|
||||||
|
'x-designable-bar': 'Tabs.DesignableBar',
|
||||||
|
properties: {
|
||||||
|
[uid()]: {
|
||||||
|
type: 'void',
|
||||||
|
title: '详情',
|
||||||
|
'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',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
return (
|
||||||
|
<RequestProvider>
|
||||||
|
<CollectionsProvider>
|
||||||
|
<SchemaRenderer
|
||||||
|
scope={{ useSelect, useValues, useOptionTagValues }}
|
||||||
|
schema={schema}
|
||||||
|
/>
|
||||||
|
</CollectionsProvider>
|
||||||
|
</RequestProvider>
|
||||||
|
);
|
||||||
|
};
|
@ -383,192 +383,7 @@ export default () => {
|
|||||||
|
|
||||||
## Select.Drawer
|
## Select.Drawer
|
||||||
|
|
||||||
```tsx
|
<code src="./demos/demo1.tsx"/>
|
||||||
import React from 'react';
|
|
||||||
import { SchemaRenderer } from '../';
|
|
||||||
import { useSelect, useOptionTagValues } from './';
|
|
||||||
|
|
||||||
console.log({ useSelect })
|
|
||||||
|
|
||||||
const dataSource = [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
title: '标题1',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
title: '标题2',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
title: '标题3',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
function useValues() {
|
|
||||||
return {
|
|
||||||
table: dataSource,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const schema = {
|
|
||||||
type: 'object',
|
|
||||||
properties: {
|
|
||||||
input: {
|
|
||||||
interface: 'select',
|
|
||||||
type: 'string',
|
|
||||||
title: `编辑模式`,
|
|
||||||
enum: dataSource,
|
|
||||||
default: [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
title: '标题1',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
title: '标题2',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'x-decorator': 'FormItem',
|
|
||||||
'x-component': 'Select.Drawer',
|
|
||||||
'x-component-props': {
|
|
||||||
placeholder: 'please enter',
|
|
||||||
mode: 'tags',
|
|
||||||
fieldNames: {
|
|
||||||
label: 'title',
|
|
||||||
value: 'id',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'x-reactions': {
|
|
||||||
target: 'read',
|
|
||||||
fulfill: {
|
|
||||||
state: {
|
|
||||||
value: '{{$self.value}}',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
properties: {
|
|
||||||
options: {
|
|
||||||
type: 'void',
|
|
||||||
'x-component': 'Select.Options',
|
|
||||||
properties: {
|
|
||||||
form: {
|
|
||||||
type: 'void',
|
|
||||||
'x-component': 'Form',
|
|
||||||
'x-component-props': {
|
|
||||||
useValues: '{{ useValues }}',
|
|
||||||
},
|
|
||||||
properties: {
|
|
||||||
table: {
|
|
||||||
type: 'array',
|
|
||||||
'x-component': 'Table',
|
|
||||||
properties: {
|
|
||||||
actionbar: {
|
|
||||||
type: 'void',
|
|
||||||
'x-component': 'Table.ActionBar',
|
|
||||||
'x-component-props': {
|
|
||||||
align: 'bottom',
|
|
||||||
},
|
|
||||||
properties: {
|
|
||||||
action: {
|
|
||||||
type: 'void',
|
|
||||||
'x-component': 'Action',
|
|
||||||
'x-component-props': {
|
|
||||||
useAction: '{{ useSelect }}',
|
|
||||||
},
|
|
||||||
title: '确定',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
column1: {
|
|
||||||
type: 'void',
|
|
||||||
title: '标题',
|
|
||||||
'x-component': 'Table.Column',
|
|
||||||
'x-component-props': {
|
|
||||||
// title: 'z1',
|
|
||||||
},
|
|
||||||
// 'x-designable-bar': 'Table.Column.DesignableBar',
|
|
||||||
properties: {
|
|
||||||
title: {
|
|
||||||
type: 'string',
|
|
||||||
required: true,
|
|
||||||
'x-read-pretty': true,
|
|
||||||
'x-decorator-props': {
|
|
||||||
feedbackLayout: 'popover',
|
|
||||||
},
|
|
||||||
'x-decorator': 'FormItem',
|
|
||||||
'x-component': 'Input',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
read: {
|
|
||||||
interface: 'select',
|
|
||||||
type: 'string',
|
|
||||||
title: `阅读模式`,
|
|
||||||
enum: dataSource,
|
|
||||||
default: [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
title: '标题1',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
title: '标题2',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'x-read-pretty': true,
|
|
||||||
'x-decorator': 'FormItem',
|
|
||||||
'x-component': 'Select.Drawer',
|
|
||||||
'x-component-props': {
|
|
||||||
placeholder: 'please enter',
|
|
||||||
mode: 'tags',
|
|
||||||
fieldNames: {
|
|
||||||
label: 'title',
|
|
||||||
value: 'id',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
properties: {
|
|
||||||
option: {
|
|
||||||
type: 'void',
|
|
||||||
'x-component': 'Select.OptionTag',
|
|
||||||
properties: {
|
|
||||||
form: {
|
|
||||||
type: 'void',
|
|
||||||
'x-component': 'Form',
|
|
||||||
'x-component-props': {
|
|
||||||
useValues: '{{ useOptionTagValues }}',
|
|
||||||
},
|
|
||||||
properties: {
|
|
||||||
title: {
|
|
||||||
type: 'string',
|
|
||||||
title: '标题',
|
|
||||||
'x-read-pretty': true,
|
|
||||||
'x-decorator': 'FormItem',
|
|
||||||
'x-component': 'Input',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export default () => {
|
|
||||||
return (
|
|
||||||
<SchemaRenderer scope={{ useSelect, useValues, useOptionTagValues }} schema={schema} />
|
|
||||||
);
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
## Schema API
|
## Schema API
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import {
|
import {
|
||||||
connect,
|
connect,
|
||||||
mapReadPretty,
|
mapReadPretty,
|
||||||
@ -7,6 +7,7 @@ import {
|
|||||||
observer,
|
observer,
|
||||||
RecursionField,
|
RecursionField,
|
||||||
useFieldSchema,
|
useFieldSchema,
|
||||||
|
Schema,
|
||||||
} from '@formily/react';
|
} from '@formily/react';
|
||||||
import { Drawer, Select as AntdSelect, Tag } from 'antd';
|
import { Drawer, Select as AntdSelect, Tag } from 'antd';
|
||||||
import { PreviewText } from '@formily/antd';
|
import { PreviewText } from '@formily/antd';
|
||||||
@ -19,6 +20,14 @@ import { createContext } from 'react';
|
|||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
import { isEmpty } from 'lodash';
|
import { isEmpty } from 'lodash';
|
||||||
import { Field, isArrayField, isField } from '@formily/core';
|
import { Field, isArrayField, isField } from '@formily/core';
|
||||||
|
import { Action } from '../action';
|
||||||
|
import { BlockSchemaContext, VisibleContext } from '../../context';
|
||||||
|
import { SchemaRenderer } from '../../components/schema-renderer';
|
||||||
|
import { uid } from '@formily/shared';
|
||||||
|
import { CollectionFieldContext } from '../table';
|
||||||
|
import { CollectionProvider, useCollectionContext } from '../../constate';
|
||||||
|
import { Resource } from '../../resource';
|
||||||
|
import { useRequest } from 'ahooks';
|
||||||
|
|
||||||
export const Select: any = connect(
|
export const Select: any = connect(
|
||||||
(props) => {
|
(props) => {
|
||||||
@ -227,22 +236,48 @@ Select.Object = connect(
|
|||||||
|
|
||||||
const OptionTagContext = createContext(null);
|
const OptionTagContext = createContext(null);
|
||||||
|
|
||||||
const SelectContext = createContext<any>({});
|
const SelectedRowKeysContext = createContext([]);
|
||||||
|
|
||||||
|
Select.useOkAction = () => {
|
||||||
|
const { props } = useContext(SelectContext);
|
||||||
|
const [selectedRows] = useContext(SelectedRowKeysContext);
|
||||||
|
return {
|
||||||
|
async run() {
|
||||||
|
props.onChange(selectedRows);
|
||||||
|
console.log('selectedRows', selectedRows);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
Select.useSelect = () => {
|
||||||
|
const [, setSelectedRows] = useContext(SelectedRowKeysContext);
|
||||||
|
return (keys, rows) => {
|
||||||
|
setSelectedRows(rows);
|
||||||
|
console.log('Select.onSelect', keys, rows);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
Select.useSelectedRowKeys = () => {
|
||||||
|
const [selectedRows] = useContext(SelectedRowKeysContext);
|
||||||
|
return selectedRows?.map((row) => row.id) || [];
|
||||||
|
};
|
||||||
|
|
||||||
|
const SelectContext = createContext(null);
|
||||||
|
|
||||||
Select.Drawer = connect(
|
Select.Drawer = connect(
|
||||||
(props) => {
|
(props) => {
|
||||||
const field = useField();
|
const field = useField<Field>();
|
||||||
const {
|
const {
|
||||||
value,
|
value,
|
||||||
onChange,
|
onChange,
|
||||||
fieldNames = {
|
fieldNames = {
|
||||||
label: 'label',
|
label: 'id',
|
||||||
value: 'value',
|
value: 'id',
|
||||||
},
|
},
|
||||||
...others
|
...others
|
||||||
} = props;
|
} = props;
|
||||||
const [visible, setVisible] = useState(false);
|
const [visible, setVisible] = useState(false);
|
||||||
const schema = useFieldSchema();
|
const { schema } = useDesignable();
|
||||||
const options = field?.['dataSource'] || props.options || [];
|
const options = field?.['dataSource'] || props.options || [];
|
||||||
|
|
||||||
let optionValue = undefined;
|
let optionValue = undefined;
|
||||||
@ -289,13 +324,13 @@ Select.Drawer = connect(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// const selectedKeys = toArr(optionValue).map((item) => item.value);
|
||||||
const selectedKeys = toArr(optionValue).map((item) => item.value);
|
const [selectedRows, setSelectedRows] = useState(toArr(field.value));
|
||||||
|
console.log({ optionValue, value });
|
||||||
console.log({ selectedKeys });
|
const collectionField = useContext(CollectionFieldContext);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<SelectContext.Provider value={{ field, schema, props }}>
|
||||||
|
<VisibleContext.Provider value={[visible, setVisible]}>
|
||||||
<AntdSelect
|
<AntdSelect
|
||||||
{...others}
|
{...others}
|
||||||
labelInValue
|
labelInValue
|
||||||
@ -317,32 +352,21 @@ Select.Drawer = connect(
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
></AntdSelect>
|
></AntdSelect>
|
||||||
<Drawer
|
<SelectedRowKeysContext.Provider
|
||||||
width={'50%'}
|
value={[selectedRows, setSelectedRows]}
|
||||||
visible={visible}
|
|
||||||
onClose={() => setVisible(false)}
|
|
||||||
destroyOnClose
|
|
||||||
>
|
|
||||||
{/* <SelectedRowKeysContext.Provider value={selectedKeys}> */}
|
|
||||||
<SelectContext.Provider
|
|
||||||
value={{
|
|
||||||
onChange(selectValue) {
|
|
||||||
onFieldChange(selectValue);
|
|
||||||
setVisible(false);
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
|
<CollectionProvider collectionName={collectionField?.target}>
|
||||||
<RecursionField
|
<RecursionField
|
||||||
onlyRenderProperties
|
onlyRenderProperties
|
||||||
schema={schema}
|
schema={schema}
|
||||||
filterProperties={(s) => {
|
filterProperties={(s) => {
|
||||||
return s['x-component'] === 'Select.Options';
|
return s['x-component'] === 'Select.Options.Drawer';
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
</CollectionProvider>
|
||||||
|
</SelectedRowKeysContext.Provider>
|
||||||
|
</VisibleContext.Provider>
|
||||||
</SelectContext.Provider>
|
</SelectContext.Provider>
|
||||||
{/* </SelectedRowKeysContext.Provider> */}
|
|
||||||
</Drawer>
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
mapProps(
|
mapProps(
|
||||||
@ -365,41 +389,98 @@ Select.Drawer = connect(
|
|||||||
),
|
),
|
||||||
mapReadPretty(
|
mapReadPretty(
|
||||||
observer((props: any) => {
|
observer((props: any) => {
|
||||||
|
const collectionField = useContext(CollectionFieldContext);
|
||||||
const field = useField<Formily.Core.Models.Field>();
|
const field = useField<Formily.Core.Models.Field>();
|
||||||
const { fieldNames = { label: 'label' }, ...others } = props;
|
const { fieldNames = { label: 'id' }, ...others } = props;
|
||||||
const value = field.value || field.initialValue;
|
const value = field.value || field.initialValue;
|
||||||
const schema = useFieldSchema();
|
const { schema } = useDesignable();
|
||||||
console.log({ fieldNames, field, value });
|
console.log({ fieldNames, field, value });
|
||||||
if (!value) {
|
if (!value) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const values = toArr(value);
|
const values = toArr(value);
|
||||||
|
const s = schema.reduceProperties((buf, current) => {
|
||||||
|
if (current['x-component'] === 'Select.OptionTag') {
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
}, null);
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
<BlockSchemaContext.Provider value={schema}>
|
||||||
|
<CollectionProvider collectionName={collectionField?.target}>
|
||||||
{values.map((data, index) => {
|
{values.map((data, index) => {
|
||||||
return (
|
return (
|
||||||
<OptionTagContext.Provider value={{ index, data, fieldNames }}>
|
<OptionTagContext.Provider
|
||||||
{data[fieldNames.label]}
|
value={{ index, data, fieldNames }}
|
||||||
{/* <RecursionField
|
>
|
||||||
schema={schema}
|
{s ? (
|
||||||
onlyRenderProperties
|
<RecursionField name={s.name} schema={s} />
|
||||||
filterProperties={(s) => {
|
) : (
|
||||||
return s['x-component'] === 'Select.OptionTag';
|
data[fieldNames.label]
|
||||||
}}
|
)}
|
||||||
/> */}
|
|
||||||
</OptionTagContext.Provider>
|
</OptionTagContext.Provider>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
</CollectionProvider>
|
||||||
|
</BlockSchemaContext.Provider>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Select.Drawer.useResource = ({ onSuccess }) => {
|
||||||
|
const { collection } = useCollectionContext();
|
||||||
|
const ctx = useContext(OptionTagContext);
|
||||||
|
const resource = Resource.make({
|
||||||
|
resourceName: collection?.name,
|
||||||
|
resourceKey: ctx.data.id,
|
||||||
|
});
|
||||||
|
console.log('OptionTagContext', ctx.data.id)
|
||||||
|
const { schema } = useDesignable();
|
||||||
|
const fieldFields = (schema: Schema) => {
|
||||||
|
const names = [];
|
||||||
|
schema.reduceProperties((buf, current) => {
|
||||||
|
if (current['x-component'] === 'Form.Field') {
|
||||||
|
const fieldName = current['x-component-props']?.['fieldName'];
|
||||||
|
if (fieldName) {
|
||||||
|
buf.push(fieldName);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const fieldNames = fieldFields(current);
|
||||||
|
buf.push(...fieldNames);
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
}, names);
|
||||||
|
return names;
|
||||||
|
};
|
||||||
|
const [visible] = useContext(VisibleContext);
|
||||||
|
const service = useRequest(
|
||||||
|
(params?: any) => {
|
||||||
|
console.log('Table.useResource', params);
|
||||||
|
return resource.get({ ...params, appends: fieldFields(schema) });
|
||||||
|
},
|
||||||
|
{
|
||||||
|
formatResult: (result) => result?.data,
|
||||||
|
onSuccess,
|
||||||
|
manual: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
useEffect(() => {
|
||||||
|
if (visible) {
|
||||||
|
service.run();
|
||||||
|
}
|
||||||
|
}, [visible]);
|
||||||
|
return { resource, service, initialValues: service.data, ...service };
|
||||||
|
}
|
||||||
|
|
||||||
Select.Options = observer((props) => {
|
Select.Options = observer((props) => {
|
||||||
return <>{props.children}</>;
|
return <>{props.children}</>;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Select.Options.Drawer = Action.Drawer;
|
||||||
|
|
||||||
export function useSelect() {
|
export function useSelect() {
|
||||||
const { onChange } = useContext(SelectContext);
|
const { onChange } = useContext(SelectContext);
|
||||||
return {
|
return {
|
||||||
@ -418,12 +499,10 @@ Select.OptionTag = observer((props) => {
|
|||||||
const [visible, setVisible] = useState(false);
|
const [visible, setVisible] = useState(false);
|
||||||
const { data, fieldNames } = useContext(OptionTagContext);
|
const { data, fieldNames } = useContext(OptionTagContext);
|
||||||
return (
|
return (
|
||||||
<>
|
<VisibleContext.Provider value={[visible, setVisible]}>
|
||||||
<Tag onClick={() => setVisible(true)}>{data[fieldNames.label]}</Tag>
|
<Tag onClick={() => setVisible(true)}>{data[fieldNames.label]}</Tag>
|
||||||
<Drawer width={'50%'} visible={visible} onClose={() => setVisible(false)}>
|
|
||||||
{props.children}
|
{props.children}
|
||||||
</Drawer>
|
</VisibleContext.Provider>
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -3,39 +3,29 @@ import { range } from 'lodash';
|
|||||||
import { ISchema } from '@formily/react';
|
import { ISchema } from '@formily/react';
|
||||||
import { SchemaRenderer } from '../..';
|
import { SchemaRenderer } from '../..';
|
||||||
import { uid } from '@formily/shared';
|
import { uid } from '@formily/shared';
|
||||||
|
import {
|
||||||
|
CollectionsProvider,
|
||||||
|
DesignableSwitchProvider,
|
||||||
|
} from '@nocobase/client/src/constate';
|
||||||
|
import { RequestProvider } from '@nocobase/client/src/demos/RequestProvider';
|
||||||
|
|
||||||
const loadDataSource = (params?: any): Promise<any> => {
|
const schema = {
|
||||||
const { page, pageSize = 50 } = params || {};
|
name: 'table1',
|
||||||
console.log({ pageSize });
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
resolve({
|
|
||||||
list: range(50 || pageSize).map(() => {
|
|
||||||
return { id: uid(), title: uid() };
|
|
||||||
}),
|
|
||||||
total: 50,
|
|
||||||
});
|
|
||||||
}, 1000);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const schema: ISchema = {
|
|
||||||
type: 'array',
|
type: 'array',
|
||||||
name: 'arr',
|
'x-designable-bar': 'Table.DesignableBar',
|
||||||
|
'x-decorator': 'CardItem',
|
||||||
'x-component': 'Table',
|
'x-component': 'Table',
|
||||||
|
default: [],
|
||||||
'x-component-props': {
|
'x-component-props': {
|
||||||
|
collectionName: 'users',
|
||||||
|
rowKey: 'id',
|
||||||
dragSort: true,
|
dragSort: true,
|
||||||
showIndex: true,
|
showIndex: true,
|
||||||
refreshRequestOnChange: false,
|
refreshRequestOnChange: true,
|
||||||
clientSidePagination: true,
|
|
||||||
dataRequest: '{{ loadDataSource }}',
|
|
||||||
pagination: {
|
pagination: {
|
||||||
pageSize: 2,
|
pageSize: 10,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// default: range(50).map(() => {
|
|
||||||
// return { id: uid(), title: uid() };
|
|
||||||
// }),
|
|
||||||
properties: {
|
properties: {
|
||||||
[uid()]: {
|
[uid()]: {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
@ -44,6 +34,12 @@ const schema: ISchema = {
|
|||||||
properties: {
|
properties: {
|
||||||
[uid()]: {
|
[uid()]: {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
|
title: '筛选',
|
||||||
|
'x-decorator': 'AddNew.Displayed',
|
||||||
|
'x-decorator-props': {
|
||||||
|
displayName: 'filter',
|
||||||
|
},
|
||||||
|
'x-align': 'left',
|
||||||
'x-component': 'Table.Filter',
|
'x-component': 'Table.Filter',
|
||||||
'x-designable-bar': 'Table.Filter.DesignableBar',
|
'x-designable-bar': 'Table.Filter.DesignableBar',
|
||||||
'x-component-props': {
|
'x-component-props': {
|
||||||
@ -53,15 +49,44 @@ const schema: ISchema = {
|
|||||||
[uid()]: {
|
[uid()]: {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
name: 'action1',
|
name: 'action1',
|
||||||
title: '添加',
|
title: '删除',
|
||||||
|
'x-align': 'right',
|
||||||
|
'x-decorator': 'AddNew.Displayed',
|
||||||
|
'x-decorator-props': {
|
||||||
|
displayName: 'destroy',
|
||||||
|
},
|
||||||
'x-component': 'Action',
|
'x-component': 'Action',
|
||||||
'x-designable-bar': 'Table.Action.DesignableBar',
|
'x-designable-bar': 'Table.Action.DesignableBar',
|
||||||
|
'x-component-props': {
|
||||||
|
icon: 'DeleteOutlined',
|
||||||
|
confirm: {
|
||||||
|
title: '删除数据',
|
||||||
|
content: '删除后无法恢复,确定要删除吗?',
|
||||||
|
},
|
||||||
|
useAction: '{{ Table.useTableDestroyAction }}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[uid()]: {
|
||||||
|
type: 'void',
|
||||||
|
name: 'action1',
|
||||||
|
title: '添加',
|
||||||
|
'x-align': 'right',
|
||||||
|
'x-decorator': 'AddNew.Displayed',
|
||||||
|
'x-decorator-props': {
|
||||||
|
displayName: 'create',
|
||||||
|
},
|
||||||
|
'x-component': 'Action',
|
||||||
|
'x-component-props': {
|
||||||
|
icon: 'PlusOutlined',
|
||||||
|
type: 'primary',
|
||||||
|
},
|
||||||
|
'x-designable-bar': 'Table.Action.DesignableBar',
|
||||||
properties: {
|
properties: {
|
||||||
modal: {
|
modal: {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
title: '添加数据',
|
title: '添加数据',
|
||||||
'x-decorator': 'Form',
|
'x-decorator': 'Form',
|
||||||
'x-component': 'Action.Modal',
|
'x-component': 'Action.Drawer',
|
||||||
'x-component-props': {
|
'x-component-props': {
|
||||||
useOkAction: '{{ Table.useTableCreateAction }}',
|
useOkAction: '{{ Table.useTableCreateAction }}',
|
||||||
},
|
},
|
||||||
@ -77,76 +102,55 @@ const schema: ISchema = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
[uid()]: {
|
[uid()]: {
|
||||||
type: 'void',
|
|
||||||
name: 'action1',
|
|
||||||
title: '删除',
|
|
||||||
'x-component': 'Action',
|
|
||||||
'x-designable-bar': 'Table.Action.DesignableBar',
|
|
||||||
'x-component-props': {
|
|
||||||
useAction: '{{ Table.useTableDestroyAction }}',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
column2: {
|
|
||||||
type: 'void',
|
type: 'void',
|
||||||
title: '操作',
|
title: '操作',
|
||||||
'x-component': 'Table.Column',
|
'x-component': 'Table.Column',
|
||||||
'x-component-props': {
|
'x-component-props': {},
|
||||||
className: 'nb-table-operation',
|
'x-designable-bar': 'Table.Operation.DesignableBar',
|
||||||
},
|
|
||||||
properties: {
|
|
||||||
action1: {
|
|
||||||
type: 'void',
|
|
||||||
name: 'dropdown1',
|
|
||||||
'x-component': 'Action.Dropdown',
|
|
||||||
'x-designable-bar': 'Action.DesignableBar',
|
|
||||||
'x-component-props': {
|
|
||||||
buttonProps: {
|
|
||||||
icon: 'EllipsisOutlined',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
properties: {
|
properties: {
|
||||||
[uid()]: {
|
[uid()]: {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
title: '操作 1',
|
'x-component': 'Action.Group',
|
||||||
'x-component': 'Menu.Action',
|
|
||||||
'x-component-props': {
|
'x-component-props': {
|
||||||
style: {
|
type: 'link',
|
||||||
minWidth: 150,
|
|
||||||
},
|
|
||||||
disabled: true,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
properties: {
|
||||||
[uid()]: {
|
[uid()]: {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
name: 'action1',
|
name: 'action1',
|
||||||
title: '查看',
|
title: '查看',
|
||||||
'x-component': 'Menu.Action',
|
'x-component': 'Action',
|
||||||
|
'x-component-props': {
|
||||||
|
type: 'link',
|
||||||
|
},
|
||||||
'x-designable-bar': 'Table.Action.DesignableBar',
|
'x-designable-bar': 'Table.Action.DesignableBar',
|
||||||
|
'x-action-type': 'view',
|
||||||
properties: {
|
properties: {
|
||||||
[uid()]: {
|
[uid()]: {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
title: '查看',
|
title: '查看数据',
|
||||||
'x-component': 'Action.Modal',
|
'x-component': 'Action.Drawer',
|
||||||
'x-component-props': {
|
'x-component-props': {
|
||||||
bodyStyle: {
|
bodyStyle: {
|
||||||
background: '#f0f2f5',
|
background: '#f0f2f5',
|
||||||
paddingTop: 0,
|
// paddingTop: 0,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
properties: {
|
properties: {
|
||||||
[uid()]: {
|
[uid()]: {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
'x-component': 'Tabs',
|
'x-component': 'Tabs',
|
||||||
|
'x-designable-bar': 'Tabs.DesignableBar',
|
||||||
properties: {
|
properties: {
|
||||||
[uid()]: {
|
[uid()]: {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
|
title: '详情',
|
||||||
|
'x-designable-bar': 'Tabs.TabPane.DesignableBar',
|
||||||
'x-component': 'Tabs.TabPane',
|
'x-component': 'Tabs.TabPane',
|
||||||
'x-component-props': {
|
'x-component-props': {},
|
||||||
tab: 'Tab1',
|
|
||||||
},
|
|
||||||
properties: {
|
properties: {
|
||||||
[uid()]: {
|
[uid()]: {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
@ -166,17 +170,22 @@ const schema: ISchema = {
|
|||||||
[uid()]: {
|
[uid()]: {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
title: '编辑',
|
title: '编辑',
|
||||||
'x-component': 'Menu.Action',
|
'x-component': 'Action',
|
||||||
|
'x-component-props': {
|
||||||
|
type: 'link',
|
||||||
|
},
|
||||||
'x-designable-bar': 'Table.Action.DesignableBar',
|
'x-designable-bar': 'Table.Action.DesignableBar',
|
||||||
|
'x-action-type': 'update',
|
||||||
properties: {
|
properties: {
|
||||||
[uid()]: {
|
[uid()]: {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
title: '编辑数据',
|
title: '编辑数据',
|
||||||
'x-decorator': 'Form',
|
'x-decorator': 'Form',
|
||||||
'x-decorator-props': {
|
'x-decorator-props': {
|
||||||
|
useResource: '{{ Table.useResource }}',
|
||||||
useValues: '{{ Table.useTableRowRecord }}',
|
useValues: '{{ Table.useTableRowRecord }}',
|
||||||
},
|
},
|
||||||
'x-component': 'Action.Modal',
|
'x-component': 'Action.Drawer',
|
||||||
'x-component-props': {
|
'x-component-props': {
|
||||||
useOkAction: '{{ Table.useTableUpdateAction }}',
|
useOkAction: '{{ Table.useTableUpdateAction }}',
|
||||||
},
|
},
|
||||||
@ -187,75 +196,39 @@ const schema: ISchema = {
|
|||||||
'x-component-props': {
|
'x-component-props': {
|
||||||
addNewComponent: 'AddNew.FormItem',
|
addNewComponent: 'AddNew.FormItem',
|
||||||
},
|
},
|
||||||
properties: {
|
|
||||||
[uid()]: {
|
|
||||||
type: 'void',
|
|
||||||
'x-component': 'Grid.Row',
|
|
||||||
properties: {
|
|
||||||
[uid()]: {
|
|
||||||
type: 'void',
|
|
||||||
'x-component': 'Grid.Col',
|
|
||||||
properties: {
|
|
||||||
title: {
|
|
||||||
title: '标题',
|
|
||||||
type: 'string',
|
|
||||||
'x-component': 'Input',
|
|
||||||
'x-decorator': 'FormItem',
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
// [uid()]: {
|
||||||
|
// type: 'void',
|
||||||
|
// title: '删除',
|
||||||
|
// 'x-component': 'Action',
|
||||||
|
// 'x-designable-bar': 'Table.Action.DesignableBar',
|
||||||
|
// 'x-action-type': 'destroy',
|
||||||
|
// 'x-component-props': {
|
||||||
|
// type: 'link',
|
||||||
|
// useAction: '{{ Table.useTableDestroyAction }}',
|
||||||
|
// },
|
||||||
|
// },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
|
||||||
[uid()]: {
|
|
||||||
type: 'void',
|
|
||||||
title: '删除',
|
|
||||||
'x-component': 'Menu.Action',
|
|
||||||
'x-component-props': {
|
|
||||||
useAction: '{{ Table.useTableDestroyAction }}',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
column0: {
|
|
||||||
type: 'void',
|
|
||||||
title: 'ID',
|
|
||||||
'x-component': 'Table.Column',
|
|
||||||
'x-designable-bar': 'Table.Column.DesignableBar',
|
|
||||||
properties: {
|
|
||||||
id: {
|
|
||||||
type: 'string',
|
|
||||||
'x-component': 'Input',
|
|
||||||
'x-read-pretty': true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
column1: {
|
|
||||||
type: 'void',
|
|
||||||
title: 'Title',
|
|
||||||
'x-component': 'Table.Column',
|
|
||||||
properties: {
|
|
||||||
title: {
|
|
||||||
type: 'string',
|
|
||||||
'x-component': 'Input',
|
|
||||||
'x-read-pretty': true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<SchemaRenderer scope={{ loadDataSource }} schema={schema} />
|
<RequestProvider>
|
||||||
|
<DesignableSwitchProvider>
|
||||||
|
<CollectionsProvider>
|
||||||
|
<SchemaRenderer schema={schema} />
|
||||||
|
</CollectionsProvider>
|
||||||
|
</DesignableSwitchProvider>
|
||||||
|
</RequestProvider>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -40,7 +40,11 @@ import {
|
|||||||
SchemaField,
|
SchemaField,
|
||||||
SchemaRenderer,
|
SchemaRenderer,
|
||||||
} from '../../components/schema-renderer';
|
} from '../../components/schema-renderer';
|
||||||
import { interfaces, isAssociation, options } from '../database-field/interfaces';
|
import {
|
||||||
|
interfaces,
|
||||||
|
isAssociation,
|
||||||
|
options,
|
||||||
|
} from '../database-field/interfaces';
|
||||||
import { DraggableBlockContext } from '../../components/drag-and-drop';
|
import { DraggableBlockContext } from '../../components/drag-and-drop';
|
||||||
import AddNew from '../add-new';
|
import AddNew from '../add-new';
|
||||||
import { isGridRowOrCol } from '../grid';
|
import { isGridRowOrCol } from '../grid';
|
||||||
@ -94,7 +98,7 @@ export interface ITableRowContext {
|
|||||||
|
|
||||||
const TableContext = createContext<ITableContext>({} as any);
|
const TableContext = createContext<ITableContext>({} as any);
|
||||||
export const TableRowContext = createContext<ITableRowContext>(null);
|
export const TableRowContext = createContext<ITableRowContext>(null);
|
||||||
const CollectionFieldContext = createContext(null);
|
export const CollectionFieldContext = createContext(null);
|
||||||
|
|
||||||
export const useTable = () => {
|
export const useTable = () => {
|
||||||
return useContext(TableContext);
|
return useContext(TableContext);
|
||||||
@ -417,20 +421,133 @@ function AddColumn() {
|
|||||||
checked={displayed.has(field.name)}
|
checked={displayed.has(field.name)}
|
||||||
onChange={async (checked) => {
|
onChange={async (checked) => {
|
||||||
if (checked) {
|
if (checked) {
|
||||||
console.log('SwitchMenuItem.field.name', field.dataType, service.params[0])
|
console.log(
|
||||||
const data = appendChild({
|
'SwitchMenuItem.field.name',
|
||||||
|
field.dataType,
|
||||||
|
service.params[0],
|
||||||
|
);
|
||||||
|
const columnSchema: ISchema = {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
'x-component': 'Table.Column',
|
'x-component': 'Table.Column',
|
||||||
'x-component-props': {
|
'x-component-props': {
|
||||||
fieldName: field.name,
|
fieldName: field.name,
|
||||||
},
|
},
|
||||||
'x-designable-bar': 'Table.Column.DesignableBar',
|
'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: '关联数据',
|
||||||
|
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',
|
||||||
|
defaultSelectedRowKeys: '{{ 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: '筛选',
|
||||||
|
'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: '查看数据',
|
||||||
|
'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: '详情',
|
||||||
|
'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);
|
await createSchema(data);
|
||||||
if (isAssociation(field)) {
|
if (isAssociation(field)) {
|
||||||
const defaultAppends = service.params[0]?.defaultAppends || [];
|
const defaultAppends =
|
||||||
|
service.params[0]?.defaultAppends || [];
|
||||||
defaultAppends.push(field.name);
|
defaultAppends.push(field.name);
|
||||||
await service.run({...service.params[0], defaultAppends});
|
await service.run({
|
||||||
|
...service.params[0],
|
||||||
|
defaultAppends,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const s: any = displayed.get(field.name);
|
const s: any = displayed.get(field.name);
|
||||||
@ -439,12 +556,16 @@ function AddColumn() {
|
|||||||
await removeSchema(removed);
|
await removeSchema(removed);
|
||||||
displayed.remove(field.name);
|
displayed.remove(field.name);
|
||||||
if (isAssociation(field)) {
|
if (isAssociation(field)) {
|
||||||
const defaultAppends = service.params[0]?.defaultAppends || [];
|
const defaultAppends =
|
||||||
|
service.params[0]?.defaultAppends || [];
|
||||||
const index = defaultAppends.indexOf(field.name);
|
const index = defaultAppends.indexOf(field.name);
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
defaultAppends.splice(index, 1);
|
defaultAppends.splice(index, 1);
|
||||||
}
|
}
|
||||||
await service.run({...service.params[0], defaultAppends});
|
await service.run({
|
||||||
|
...service.params[0],
|
||||||
|
defaultAppends,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// service.refresh();
|
// service.refresh();
|
||||||
@ -535,7 +656,7 @@ const TableMain = () => {
|
|||||||
setSelectedRowKeys,
|
setSelectedRowKeys,
|
||||||
service,
|
service,
|
||||||
field,
|
field,
|
||||||
props: { rowKey, dragSort, showIndex },
|
props: { rowKey, dragSort, showIndex, onSelect },
|
||||||
refresh,
|
refresh,
|
||||||
} = useTable();
|
} = useTable();
|
||||||
const columns = useTableColumns();
|
const columns = useTableColumns();
|
||||||
@ -624,8 +745,9 @@ const TableMain = () => {
|
|||||||
rowSelection={{
|
rowSelection={{
|
||||||
type: 'checkbox',
|
type: 'checkbox',
|
||||||
selectedRowKeys,
|
selectedRowKeys,
|
||||||
onChange: (rowKeys) => {
|
onChange: (rowKeys, rows) => {
|
||||||
setSelectedRowKeys(rowKeys);
|
setSelectedRowKeys(rowKeys);
|
||||||
|
onSelect && onSelect(rowKeys, rows);
|
||||||
},
|
},
|
||||||
renderCell: (checked, record, _, originNode) => {
|
renderCell: (checked, record, _, originNode) => {
|
||||||
const index = findIndex(
|
const index = findIndex(
|
||||||
@ -697,12 +819,15 @@ const TableProvider = (props: any) => {
|
|||||||
rowKey = 'id',
|
rowKey = 'id',
|
||||||
dataRequest,
|
dataRequest,
|
||||||
useResource = useGeneralResource,
|
useResource = useGeneralResource,
|
||||||
|
defaultSelectedRowKeys,
|
||||||
...others
|
...others
|
||||||
} = props;
|
} = props;
|
||||||
const { schema } = useDesignable();
|
const { schema } = useDesignable();
|
||||||
const field = useField<Formily.Core.Models.ArrayField>();
|
const field = useField<Formily.Core.Models.ArrayField>();
|
||||||
const [pagination, setPagination] = usePagination();
|
const [pagination, setPagination] = usePagination();
|
||||||
const [selectedRowKeys, setSelectedRowKeys] = useState<any>([]);
|
const [selectedRowKeys, setSelectedRowKeys] = useState<any>(
|
||||||
|
defaultSelectedRowKeys || [],
|
||||||
|
);
|
||||||
const [, refresh] = useState(uid());
|
const [, refresh] = useState(uid());
|
||||||
const { resource } = useResource();
|
const { resource } = useResource();
|
||||||
const { sortableField } = useCollectionContext();
|
const { sortableField } = useCollectionContext();
|
||||||
@ -1859,6 +1984,9 @@ Table.Cell = observer((props: any) => {
|
|||||||
feedbackLayout: 'popover',
|
feedbackLayout: 'popover',
|
||||||
},
|
},
|
||||||
'x-decorator': 'FormilyFormItem',
|
'x-decorator': 'FormilyFormItem',
|
||||||
|
properties: {
|
||||||
|
...schema?.properties,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user