feat: table and calendar schema settings

This commit is contained in:
chenos 2022-03-06 12:06:50 +08:00
parent b05cfe4b02
commit f9018cabda
10 changed files with 244 additions and 12 deletions

View File

@ -4,7 +4,9 @@ import { useCollectionManager } from '.';
import { CollectionProvider, useRecord } from '..'; import { CollectionProvider, useRecord } from '..';
import { useAPIClient, useRequest } from '../api-client'; import { useAPIClient, useRequest } from '../api-client';
export const ResourceActionContext = createContext<Result<any, any> & { state?: any; setState?: any }>(null); export const ResourceActionContext = createContext<
Result<any, any> & { state?: any; setState?: any; defaultRequest?: any }
>(null);
interface ResourceActionProviderProps { interface ResourceActionProviderProps {
type?: 'association' | 'collection'; type?: 'association' | 'collection';
@ -38,7 +40,7 @@ const CollectionResourceActionProvider = (props) => {
const resource = api.resource(request.resource); const resource = api.resource(request.resource);
return ( return (
<ResourceContext.Provider value={{ type: 'collection', resource, collection }}> <ResourceContext.Provider value={{ type: 'collection', resource, collection }}>
<ResourceActionContext.Provider value={service}> <ResourceActionContext.Provider value={{ ...service, defaultRequest: request }}>
<CollectionProvider collection={collection}>{props.children}</CollectionProvider> <CollectionProvider collection={collection}>{props.children}</CollectionProvider>
</ResourceActionContext.Provider> </ResourceActionContext.Provider>
</ResourceContext.Provider> </ResourceContext.Provider>
@ -67,7 +69,7 @@ const AssociationResourceActionProvider = (props) => {
const resource = api.resource(request.resource, resourceOf); const resource = api.resource(request.resource, resourceOf);
return ( return (
<ResourceContext.Provider value={{ type: 'association', resource, association }}> <ResourceContext.Provider value={{ type: 'association', resource, association }}>
<ResourceActionContext.Provider value={service}> <ResourceActionContext.Provider value={{ ...service, defaultRequest: request }}>
<CollectionProvider collection={collection}>{props.children}</CollectionProvider> <CollectionProvider collection={collection}>{props.children}</CollectionProvider>
</ResourceActionContext.Provider> </ResourceActionContext.Provider>
</ResourceContext.Provider> </ResourceContext.Provider>

View File

@ -85,13 +85,15 @@ export const useFilterDataSource = (options) => {
}; };
export const useFilterAction = () => { export const useFilterAction = () => {
const { run, params } = useResourceActionContext(); const { run, params, defaultRequest } = useResourceActionContext();
const form = useForm(); const form = useForm();
const ctx = useActionContext(); const ctx = useActionContext();
const [first, ...others] = params; const [first, ...others] = params;
return { return {
async run() { async run() {
run({ ...first, filter: form.values.filter }, ...others); const prevFilter = defaultRequest?.params?.filter;
const filter = prevFilter ? { $and: [prevFilter, form.values.filter] } : form.values.filter;
run({ ...first, filter }, ...others);
ctx.setVisible(false); ctx.setVisible(false);
}, },
}; };

View File

@ -57,9 +57,7 @@ export const ActionDesigner = () => {
dn.emit('patch', { dn.emit('patch', {
schema: { schema: {
'x-uid': fieldSchema['x-uid'], 'x-uid': fieldSchema['x-uid'],
'x-component-props': { 'x-component-props': fieldSchema['x-component-props'],
openMode: value,
},
}, },
}); });
dn.refresh(); dn.refresh();

View File

@ -0,0 +1,139 @@
import { ISchema, useField, useFieldSchema } from '@formily/react';
import React from 'react';
import { useCompile, useDesignable } from '../..';
import { useCollection, useResourceActionContext } from '../../../collection-manager';
import { useCollectionFilterOptions } from '../../../collection-manager/action-hooks';
import { GeneralSchemaDesigner, SchemaSettings } from '../../../schema-settings';
export const CalendarDesigner = () => {
const field = useField();
const fieldSchema = useFieldSchema();
const { name, title, fields } = useCollection();
const dataSource = useCollectionFilterOptions(name);
const ctx = useResourceActionContext();
const { dn } = useDesignable();
const compile = useCompile();
const defaultFilter = fieldSchema?.['x-decorator-props']?.request?.params?.filter || {};
const options = fields?.map((field) => {
return {
value: field.name,
label: compile(field?.uiSchema?.title),
};
});
const calendarSchema = fieldSchema.properties.calendar;
const fieldNames = calendarSchema?.['x-component-props']?.['fieldNames'] || {};
return (
<GeneralSchemaDesigner title={title || name}>
<SchemaSettings.SelectItem
title={'标题字段'}
value={fieldNames.title}
options={options}
onChange={(title) => {
field.query(field.address.concat('calendar')).take((f) => {
f.componentProps.fieldNames = {
...f.componentProps.fieldNames,
title,
};
calendarSchema['x-component-props']['fieldNames'] = f.componentProps.fieldNames;
dn.emit('patch', {
schema: {
['x-uid']: calendarSchema['x-uid'],
'x-component-props': calendarSchema['x-component-props'],
},
});
dn.refresh();
ctx.refresh();
});
}}
/>
<SchemaSettings.SelectItem
title={'开始日期字段'}
value={fieldNames.start}
options={options}
onChange={(start) => {
field.query(field.address.concat('calendar')).take((f) => {
f.componentProps.fieldNames = {
...f.componentProps.fieldNames,
start,
};
calendarSchema['x-component-props']['fieldNames'] = f.componentProps.fieldNames;
dn.emit('patch', {
schema: {
['x-uid']: calendarSchema['x-uid'],
'x-component-props': calendarSchema['x-component-props'],
},
});
dn.refresh();
ctx.refresh();
});
}}
/>
<SchemaSettings.SelectItem
title={'结束日期字段'}
value={fieldNames.end}
options={options}
onChange={(end) => {
field.query(field.address.concat('calendar')).take((f) => {
f.componentProps.fieldNames = {
...f.componentProps.fieldNames,
end,
};
calendarSchema['x-component-props']['fieldNames'] = f.componentProps.fieldNames;
dn.emit('patch', {
schema: {
['x-uid']: calendarSchema['x-uid'],
'x-component-props': calendarSchema['x-component-props'],
},
});
dn.refresh();
ctx.refresh();
});
}}
/>
<SchemaSettings.ModalItem
title={'设置数据范围'}
schema={
{
type: 'object',
title: '设置数据范围',
properties: {
filter: {
default: defaultFilter,
title: '数据范围',
enum: dataSource,
'x-component': 'Filter',
'x-component-props': {},
},
},
} as ISchema
}
initialValues={
{
// title: field.title,
// icon: field.componentProps.icon,
}
}
onSubmit={({ filter }) => {
const params = field.decoratorProps.request.params || {};
params.filter = filter;
field.decoratorProps.request.params = params;
fieldSchema['x-decorator-props']['request']['params'] = params;
ctx.run({ filter });
dn.emit('patch', {
schema: {
['x-uid']: fieldSchema['x-uid'],
'x-decorator-props': field.decoratorProps,
},
});
}}
/>
<SchemaSettings.Divider />
<SchemaSettings.Remove
removeParentsIfNoChildren
breakRemoveOn={{
'x-component': 'Grid',
}}
/>
</GeneralSchemaDesigner>
);
};

View File

@ -9,6 +9,7 @@ import { SchemaComponent } from '../..';
import { AsyncDataProvider, RecordProvider, useRequest } from '../../../'; import { AsyncDataProvider, RecordProvider, useRequest } from '../../../';
import { i18n } from '../../../i18n'; import { i18n } from '../../../i18n';
import { ActionBar, ActionContext } from '../action'; import { ActionBar, ActionContext } from '../action';
import { CalendarDesigner } from './Calendar.Designer';
import { CalendarContext, ToolbarContext } from './context'; import { CalendarContext, ToolbarContext } from './context';
import { Event } from './Event'; import { Event } from './Event';
import { Nav } from './Nav'; import { Nav } from './Nav';
@ -101,6 +102,7 @@ export const Calendar: any = observer((props: any) => {
refreshDeps: [props.dataSource], refreshDeps: [props.dataSource],
onSuccess(data) { onSuccess(data) {
const events = toEvents(data?.data, fieldNames); const events = toEvents(data?.data, fieldNames);
console.log('events', events, data);
setDataSource(events); setDataSource(events);
}, },
}, },
@ -112,6 +114,7 @@ export const Calendar: any = observer((props: any) => {
} }
return buf; return buf;
}, null); }, null);
console.log('field', field);
return ( return (
<AsyncDataProvider value={result}> <AsyncDataProvider value={result}>
<CalendarContext.Provider value={{ field, props, record }}> <CalendarContext.Provider value={{ field, props, record }}>
@ -180,3 +183,5 @@ Calendar.Today = Today;
Calendar.Nav = Nav; Calendar.Nav = Nav;
Calendar.ViewSelect = ViewSelect; Calendar.ViewSelect = ViewSelect;
Calendar.Designer = CalendarDesigner;

View File

@ -0,0 +1,17 @@
import React from 'react';
import { useCollection } from '../../../collection-manager';
import { GeneralSchemaDesigner, SchemaSettings } from '../../../schema-settings';
export const TableDesigner = () => {
const { name, title } = useCollection();
return (
<GeneralSchemaDesigner title={title || name}>
<SchemaSettings.Remove
removeParentsIfNoChildren
breakRemoveOn={{
'x-component': 'Grid',
}}
/>
</GeneralSchemaDesigner>
);
};

View File

@ -1,11 +1,76 @@
import { ISchema, useField, useFieldSchema } from '@formily/react';
import React from 'react'; import React from 'react';
import { useCollection } from '../../../collection-manager'; import { useCollection, useResourceActionContext } from '../../../collection-manager';
import { useCollectionFilterOptions } from '../../../collection-manager/action-hooks';
import { GeneralSchemaDesigner, SchemaSettings } from '../../../schema-settings'; import { GeneralSchemaDesigner, SchemaSettings } from '../../../schema-settings';
import { useDesignable } from '../../hooks';
export const TableVoidDesigner = () => { export const TableVoidDesigner = () => {
const { name, title } = useCollection(); const { name, title } = useCollection();
const field = useField();
const fieldSchema = useFieldSchema();
const dataSource = useCollectionFilterOptions(name);
const ctx = useResourceActionContext();
const { dn } = useDesignable();
const defaultFilter = fieldSchema?.['x-decorator-props']?.request?.params?.filter || {};
return ( return (
<GeneralSchemaDesigner title={title || name}> <GeneralSchemaDesigner title={title || name}>
<SchemaSettings.ModalItem
title={'设置数据范围'}
schema={
{
type: 'object',
title: '设置数据范围',
properties: {
filter: {
default: defaultFilter,
title: '数据范围',
enum: dataSource,
'x-component': 'Filter',
'x-component-props': {},
},
},
} as ISchema
}
onSubmit={({ filter }) => {
const params = field.decoratorProps.request.params || {};
params.filter = filter;
field.decoratorProps.request.params = params;
fieldSchema['x-decorator-props']['request']['params'] = params;
ctx.run({ ...ctx.params?.[0], filter });
dn.emit('patch', {
schema: {
['x-uid']: fieldSchema['x-uid'],
'x-decorator-props': fieldSchema['x-decorator-props'],
},
});
}}
/>
<SchemaSettings.SelectItem
title={'每页显示'}
value={field.decoratorProps.request.params?.pageSize || 20}
options={[
{ label: '10', value: 10 },
{ label: '20', value: 20 },
{ label: '50', value: 50 },
{ label: '100', value: 100 },
{ label: '200', value: 200 },
]}
onChange={(pageSize) => {
const params = field.decoratorProps.request.params || {};
params.pageSize = pageSize;
field.decoratorProps.request.params = params;
fieldSchema['x-decorator-props']['request']['params'] = params;
ctx.run({ ...ctx.params?.[0], pageSize });
dn.emit('patch', {
schema: {
['x-uid']: fieldSchema['x-uid'],
'x-decorator-props': fieldSchema['x-decorator-props'],
},
});
}}
/>
<SchemaSettings.Divider />
<SchemaSettings.Remove <SchemaSettings.Remove
removeParentsIfNoChildren removeParentsIfNoChildren
breakRemoveOn={{ breakRemoveOn={{

View File

@ -3,6 +3,7 @@ import { TableColumn } from './Table.Column';
import { TableColumnActionBar } from './Table.Column.ActionBar'; import { TableColumnActionBar } from './Table.Column.ActionBar';
import { TableColumnDecorator } from './Table.Column.Decorator'; import { TableColumnDecorator } from './Table.Column.Decorator';
import { TableColumnDeigner } from './Table.Column.Deigner'; import { TableColumnDeigner } from './Table.Column.Deigner';
import { TableDesigner } from './Table.Designer';
import { TableRowActionDesigner } from './Table.RowActionDesigner'; import { TableRowActionDesigner } from './Table.RowActionDesigner';
import { TableRowSelection } from './Table.RowSelection'; import { TableRowSelection } from './Table.RowSelection';
import { TableVoid } from './Table.Void'; import { TableVoid } from './Table.Void';
@ -21,3 +22,4 @@ Table.Column.Decorator = TableColumnDecorator;
Table.Column.Deigner = TableColumnDeigner; Table.Column.Deigner = TableColumnDeigner;
Table.RowActionDesigner = TableRowActionDesigner; Table.RowActionDesigner = TableRowActionDesigner;
Table.Designer = TableDesigner;

View File

@ -20,7 +20,7 @@ const createSchema = (collectionName, { title, start, end }) => {
params: {}, params: {},
}, },
}, },
'x-designer': 'Form.Designer', 'x-designer': 'Calendar.Designer',
'x-component': 'CardItem', 'x-component': 'CardItem',
properties: { properties: {
calendar: { calendar: {

View File

@ -142,8 +142,10 @@ SchemaSettings.SelectItem = (props) => {
const { title, options, value, onChange, ...others } = props; const { title, options, value, onChange, ...others } = props;
return ( return (
<SchemaSettings.Item {...others}> <SchemaSettings.Item {...others}>
{title} <div style={{ alignItems: 'center', display: 'flex', justifyContent: 'space-between' }}>
<Select bordered={false} defaultValue={value} onChange={onChange} options={options} style={{ minWidth: 100 }} /> {title}
<Select bordered={false} defaultValue={value} onChange={onChange} options={options} style={{ minWidth: 100 }} />
</div>
</SchemaSettings.Item> </SchemaSettings.Item>
); );
}; };