refactor: refactor calendar demo

This commit is contained in:
Semmy 2022-02-26 13:46:29 +08:00
parent f06a4497f0
commit f6e5a900d1
10 changed files with 605 additions and 237 deletions

View File

@ -9,11 +9,9 @@ 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 { ActionInitializer } from './ActionInitializer';
import { CalendarContext, ToolbarContext } from './context'; import { CalendarContext, ToolbarContext } from './context';
import { Event } from './Event'; import { Event } from './Event';
import { Filter } from './Filter'; import { Filter } from './Filter';
import { FooterActionInitializer } from './FooterActionInitializer';
import { Nav } from './Nav'; import { Nav } from './Nav';
import './style.less'; import './style.less';
import { Title } from './Title'; import { Title } from './Title';
@ -120,11 +118,13 @@ export const Calendar: any = observer((props: any) => {
<AsyncDataProvider value={result}> <AsyncDataProvider value={result}>
<CalendarContext.Provider value={{ field, props, record }}> <CalendarContext.Provider value={{ field, props, record }}>
<div {...props} style={{ height: 700 }}> <div {...props} style={{ height: 700 }}>
<ActionContext.Provider value={{ visible, setVisible }}> {eventSchema && (
<RecordProvider record={record}> <ActionContext.Provider value={{ visible, setVisible }}>
<SchemaComponent memoized name={eventSchema.name} schema={eventSchema as any} /> <RecordProvider record={record}>
</RecordProvider> <SchemaComponent memoized name={eventSchema.name} schema={eventSchema as any} />
</ActionContext.Provider> </RecordProvider>
</ActionContext.Provider>
)}
<BigCalendar <BigCalendar
popup popup
selectable selectable
@ -171,10 +171,6 @@ export const Calendar: any = observer((props: any) => {
); );
}); });
Calendar.ActionInitializer = ActionInitializer;
Calendar.FooterActionInitializer = FooterActionInitializer;
Calendar.ActionBar = ActionBar; Calendar.ActionBar = ActionBar;
Calendar.Event = Event; Calendar.Event = Event;

View File

@ -2,9 +2,9 @@ import { observer, useFieldSchema } from '@formily/react';
import { Switch } from 'antd'; import { Switch } from 'antd';
import React from 'react'; import React from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useCollection } from '../../../collection-manager'; import { useCollection } from '../../../../collection-manager';
import { SchemaInitializer } from '../../../schema-initializer'; import { SchemaInitializer } from '../../../../schema-initializer';
import { useDesignable } from '../../hooks'; import { useDesignable } from '../../../hooks';
export const ActionInitializer = observer((props: any) => { export const ActionInitializer = observer((props: any) => {
const { name: collectName } = useCollection(); const { name: collectName } = useCollection();

View File

@ -2,9 +2,9 @@ import { observer, useFieldSchema } from '@formily/react';
import { Switch } from 'antd'; import { Switch } from 'antd';
import React from 'react'; import React from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useCollection } from '../../../collection-manager'; import { useCollection } from '../../../../collection-manager';
import { SchemaInitializer } from '../../../schema-initializer'; import { SchemaInitializer } from '../../../../schema-initializer';
import { useDesignable } from '../../hooks'; import { useDesignable } from '../../../hooks';
export const FooterActionInitializer = observer((props: any) => { export const FooterActionInitializer = observer((props: any) => {
const { name: collectName } = useCollection(); const { name: collectName } = useCollection();

View File

@ -2,21 +2,14 @@
* title: Calendar * title: Calendar
*/ */
import { useField, useFieldSchema, useForm } from '@formily/react';
import { observable } from '@formily/reactive'; import { observable } from '@formily/reactive';
import { uid } from '@formily/shared';
import { import {
AntdSchemaComponentProvider, AntdSchemaComponentProvider,
CalendarContext,
CollectionProvider,
SchemaComponent, SchemaComponent,
SchemaComponentProvider, SchemaComponentProvider,
SchemaInitializerProvider, SchemaInitializerProvider,
useActionContext,
useAsyncData,
useRequest,
} from '@nocobase/client'; } from '@nocobase/client';
import React, { useContext, useEffect } from 'react'; import React from 'react';
import defaultValues from './defaultValues'; import defaultValues from './defaultValues';
const dataSource = observable(defaultValues); const dataSource = observable(defaultValues);
@ -31,7 +24,6 @@ const schema = {
toolBar: { toolBar: {
type: 'void', type: 'void',
'x-component': 'Calendar.ActionBar', 'x-component': 'Calendar.ActionBar',
'x-action-initializer': 'Calendar.ActionInitializer',
properties: { properties: {
today: { today: {
type: 'void', type: 'void',
@ -61,222 +53,19 @@ const schema = {
'x-action': 'calendar:viewSelect', 'x-action': 'calendar:viewSelect',
'x-align': 'right', 'x-align': 'right',
}, },
// filter: {
// type: 'void',
// title: '过滤',
// 'x-align': 'right',
// 'x-component': 'Calendar.Filter',
// 'x-action': 'calendar:filter',
// },
},
},
event: {
type: 'void',
name: 'event',
'x-component': 'Calendar.Event',
properties: {
modal: {
'x-component': 'Action.Drawer',
'x-decorator': 'Form',
'x-decorator-props': {
useValues: '{{ useValues }}',
},
type: 'void',
title: 'Drawer Title',
properties: {
grid: {
type: 'void',
'x-component': 'Grid',
'x-item-initializer': 'FormItemInitializer',
'x-item-initializer-props': {
readPretty: true,
},
},
footer: {
'x-component': 'Action.Drawer.Footer',
type: 'void',
properties: {
[uid()]: {
title: 'submit',
'x-component': 'ActionBar',
'x-action-initializer': 'Calendar.FooterActionInitializer',
},
},
},
},
},
}, },
}, },
}, },
}; };
const useSaveAction = () => {
const { setVisible } = useActionContext();
const { refresh: dataRefresh, data } = useAsyncData();
const form = useForm();
const fieldSchema = useFieldSchema();
const field = useField();
return {
async run() {
setVisible(false);
console.log(form.values, fieldSchema, field, data);
dataSource.push({ ...form.values, start: new Date(form.values.start), end: new Date(form.values.end) });
schema['x-component-props']['dataSource'] = dataSource;
dataRefresh();
form.reset();
},
};
};
const useCloseAction = () => {
const { setVisible } = useActionContext();
return {
async run() {
setVisible(false);
},
};
};
const useRemoveAction = () => {
const { refresh: dataRefresh, data } = useAsyncData();
const { record } = useContext(CalendarContext);
const { setVisible } = useActionContext();
return {
async run() {
setVisible(false);
for (let i = 0, iLen = dataSource.length; i < iLen; i++) {
const element = dataSource[i];
if (element.id === record.id) {
dataSource.splice(i, 1);
break;
}
}
schema['x-component-props']['dataSource'] = dataSource;
dataRefresh();
},
};
};
const useEditAction = () => {
const { refresh: dataRefresh, data } = useAsyncData();
const { record } = useContext(CalendarContext);
const { setVisible } = useActionContext();
return {
async run() {
console.log(record);
},
};
};
const useUpdateAction = () => {
const form = useForm();
const { setVisible } = useActionContext();
const { refresh: dataRefresh, data } = useAsyncData();
return {
async run() {
setVisible(false);
console.log(form.values);
const record = form.values;
for (let i = 0, iLen = dataSource.length; i < iLen; i++) {
const element = dataSource[i];
if (element.id === record.id) {
dataSource[i] = { ...record };
break;
}
}
schema['x-component-props']['dataSource'] = dataSource;
form.reset();
},
};
};
const useValues = (options) => {
const { visible } = useActionContext();
const { record } = useContext(CalendarContext);
const result = useRequest(
() =>
Promise.resolve({
data: {
...record,
},
}),
{ ...options, manual: true },
);
useEffect(() => {
if (visible) {
result.run();
}
}, [visible]);
return result;
};
const collection = {
name: 'tests',
fields: [
{
type: 'string',
name: 'id',
interface: 'input',
uiSchema: {
type: 'string',
'x-component': 'Input',
},
},
{
type: 'string',
name: 'title',
interface: 'input',
uiSchema: {
type: 'string',
'x-component': 'Input',
},
},
{
type: 'string',
name: 'start',
interface: 'datetime',
uiSchema: {
type: 'string',
'x-component': 'DatePicker',
'x-component-props': {
dateFormat: 'YYYY-MM-DD',
},
},
},
{
type: 'string',
name: 'end',
interface: 'datetime',
uiSchema: {
type: 'string',
'x-component': 'DatePicker',
'x-component-props': {
dateFormat: 'YYYY-MM-DD',
},
},
},
],
};
export default () => { export default () => {
return ( return (
<CollectionProvider collection={collection}> <SchemaComponentProvider>
<SchemaComponentProvider <SchemaInitializerProvider>
scope={{ <AntdSchemaComponentProvider>
useSaveAction, <SchemaComponent schema={schema} />
useCloseAction, </AntdSchemaComponentProvider>
useEditAction, </SchemaInitializerProvider>
useUpdateAction, </SchemaComponentProvider>
useValues,
useRemoveAction,
}}
>
<SchemaInitializerProvider>
<AntdSchemaComponentProvider>
<SchemaComponent schema={schema} />
</AntdSchemaComponentProvider>
</SchemaInitializerProvider>
</SchemaComponentProvider>
</CollectionProvider>
); );
}; };

View File

@ -0,0 +1,139 @@
/**
* title: Calendar
*/
import { observer, RecursionField } from '@formily/react';
import { observable } from '@formily/reactive';
import { uid } from '@formily/shared';
import { AntdSchemaComponentProvider, SchemaComponent, SchemaComponentProvider, useRecord } from '@nocobase/client';
import React from 'react';
import defaultValues from './defaultValues';
const dataSource = observable(defaultValues);
const DetailCalendar = observer((props) => {
const record = useRecord();
debugger;
const detailSchema = {
type: 'void',
properties: {
id: {
type: 'string',
title: 'ID',
'x-component': 'Input',
'x-decorator': 'FormItem',
'x-read-pretty': true,
default: record.id,
},
title: {
type: 'string',
title: '标题',
'x-component': 'Input',
'x-decorator': 'FormItem',
'x-read-pretty': true,
default: record.title,
},
start: {
type: 'string',
title: '开始时间',
'x-component': 'DatePicker',
'x-decorator': 'FormItem',
'x-read-pretty': true,
default: record.start,
},
end: {
type: 'string',
title: '结束时间',
'x-component': 'DatePicker',
'x-decorator': 'FormItem',
'x-read-pretty': true,
default: record.end,
},
},
};
return <RecursionField schema={detailSchema as any} name="DetailCalendar" onlyRenderProperties />;
});
const schema = {
type: 'void',
name: 'calendar1',
'x-component': 'Calendar',
'x-component-props': {
dataSource: dataSource,
},
properties: {
toolBar: {
type: 'void',
'x-component': 'Calendar.ActionBar',
properties: {
today: {
type: 'void',
title: '今天',
'x-component': 'Calendar.Today',
'x-action': 'calendar:today',
'x-align': 'left',
},
nav: {
type: 'void',
title: '翻页',
'x-component': 'Calendar.Nav',
'x-action': 'calendar:nav',
'x-align': 'left',
},
title: {
type: 'void',
title: '标题',
'x-component': 'Calendar.Title',
'x-action': 'calendar:title',
'x-align': 'left',
},
viewSelect: {
type: 'void',
title: '视图切换',
'x-component': 'Calendar.ViewSelect',
'x-action': 'calendar:viewSelect',
'x-align': 'right',
},
},
},
event: {
type: 'void',
name: 'event',
'x-component': 'Calendar.Event',
properties: {
modal: {
'x-component': 'Action.Drawer',
'x-decorator': 'Form',
type: 'void',
title: 'Calendar Detail',
properties: {
grid: {
type: 'void',
'x-component': 'DetailCalendar',
},
footer: {
'x-component': 'Action.Drawer.Footer',
type: 'void',
properties: {
[uid()]: {
title: 'submit',
'x-component': 'ActionBar',
},
},
},
},
},
},
},
},
};
export default () => {
return (
<SchemaComponentProvider components={{ DetailCalendar }}>
<AntdSchemaComponentProvider>
<SchemaComponent schema={schema as any} />
</AntdSchemaComponentProvider>
</SchemaComponentProvider>
);
};

View File

@ -0,0 +1,157 @@
/**
* title: Calendar
*/
import { observable } from '@formily/reactive';
import { uid } from '@formily/shared';
import {
AntdSchemaComponentProvider,
CollectionField,
CollectionProvider,
SchemaComponent,
SchemaComponentProvider,
SchemaInitializerProvider,
} from '@nocobase/client';
import React from 'react';
import defaultValues from './defaultValues';
const dataSource = observable(defaultValues);
const schema = {
type: 'void',
name: 'calendar1',
'x-component': 'Calendar',
'x-component-props': {
dataSource: dataSource,
},
properties: {
toolBar: {
type: 'void',
'x-component': 'Calendar.ActionBar',
properties: {
today: {
type: 'void',
title: '今天',
'x-component': 'Calendar.Today',
'x-action': 'calendar:today',
'x-align': 'left',
},
nav: {
type: 'void',
title: '翻页',
'x-component': 'Calendar.Nav',
'x-action': 'calendar:nav',
'x-align': 'left',
},
title: {
type: 'void',
title: '标题',
'x-component': 'Calendar.Title',
'x-action': 'calendar:title',
'x-align': 'left',
},
viewSelect: {
type: 'void',
title: '视图切换',
'x-component': 'Calendar.ViewSelect',
'x-action': 'calendar:viewSelect',
'x-align': 'right',
},
},
},
event: {
type: 'void',
name: 'event',
'x-component': 'Calendar.Event',
properties: {
modal: {
'x-component': 'Action.Drawer',
'x-decorator': 'Form',
type: 'void',
title: 'Drawer Title',
properties: {
grid: {
type: 'void',
'x-component': 'Grid',
'x-initializer': 'GridFormItemInitializers',
},
footer: {
'x-component': 'Action.Drawer.Footer',
type: 'void',
properties: {
[uid()]: {
title: 'submit',
'x-component': 'ActionBar',
},
},
},
},
},
},
},
},
};
const collection = {
name: 'tests',
fields: [
{
type: 'string',
name: 'id',
interface: 'input',
uiSchema: {
type: 'string',
title: 'id',
'x-component': 'Input',
},
},
{
type: 'string',
name: 'title',
interface: 'input',
uiSchema: {
type: 'string',
title: '标题',
'x-component': 'Input',
},
},
{
type: 'string',
name: 'start',
interface: 'datetime',
uiSchema: {
type: 'string',
title: '开始时间',
'x-component': 'DatePicker',
'x-component-props': {
dateFormat: 'YYYY-MM-DD',
},
},
},
{
type: 'string',
name: 'end',
interface: 'datetime',
uiSchema: {
type: 'string',
title: '结束时间',
'x-component': 'DatePicker',
'x-component-props': {
dateFormat: 'YYYY-MM-DD',
},
},
},
],
};
export default () => {
return (
<CollectionProvider collection={collection}>
<SchemaComponentProvider designable={true} components={{ CollectionField }}>
<SchemaInitializerProvider>
<AntdSchemaComponentProvider>
<SchemaComponent schema={schema} />
</AntdSchemaComponentProvider>
</SchemaInitializerProvider>
</SchemaComponentProvider>
</CollectionProvider>
);
};

View File

@ -0,0 +1,276 @@
/**
* title: Calendar
*/
import { useField, useFieldSchema, useForm } from '@formily/react';
import { observable } from '@formily/reactive';
import { uid } from '@formily/shared';
import {
AntdSchemaComponentProvider,
CalendarContext,
CollectionProvider,
SchemaComponent,
SchemaComponentProvider,
SchemaInitializerProvider,
useActionContext,
useAsyncData,
useRequest,
} from '@nocobase/client';
import React, { useContext, useEffect } from 'react';
import defaultValues from './defaultValues';
const dataSource = observable(defaultValues);
const schema = {
type: 'void',
name: 'calendar1',
'x-component': 'Calendar',
'x-component-props': {
dataSource: dataSource,
},
properties: {
toolBar: {
type: 'void',
'x-component': 'Calendar.ActionBar',
properties: {
today: {
type: 'void',
title: '今天',
'x-component': 'Calendar.Today',
'x-action': 'calendar:today',
'x-align': 'left',
},
nav: {
type: 'void',
title: '翻页',
'x-component': 'Calendar.Nav',
'x-action': 'calendar:nav',
'x-align': 'left',
},
title: {
type: 'void',
title: '标题',
'x-component': 'Calendar.Title',
'x-action': 'calendar:title',
'x-align': 'left',
},
viewSelect: {
type: 'void',
title: '视图切换',
'x-component': 'Calendar.ViewSelect',
'x-action': 'calendar:viewSelect',
'x-align': 'right',
},
// filter: {
// type: 'void',
// title: '过滤',
// 'x-align': 'right',
// 'x-component': 'Calendar.Filter',
// 'x-action': 'calendar:filter',
// },
},
},
event: {
type: 'void',
name: 'event',
'x-component': 'Calendar.Event',
properties: {
modal: {
'x-component': 'Action.Drawer',
'x-decorator': 'Form',
'x-decorator-props': {
useValues: '{{ useValues }}',
},
type: 'void',
title: 'Drawer Title',
properties: {
grid: {
type: 'void',
'x-component': 'Grid',
},
footer: {
'x-component': 'Action.Drawer.Footer',
type: 'void',
properties: {
[uid()]: {
title: 'submit',
'x-component': 'ActionBar',
},
},
},
},
},
},
},
},
};
const useSaveAction = () => {
const { setVisible } = useActionContext();
const { refresh: dataRefresh, data } = useAsyncData();
const form = useForm();
const fieldSchema = useFieldSchema();
const field = useField();
return {
async run() {
setVisible(false);
console.log(form.values, fieldSchema, field, data);
dataSource.push({ ...form.values, start: new Date(form.values.start), end: new Date(form.values.end) });
schema['x-component-props']['dataSource'] = dataSource;
dataRefresh();
form.reset();
},
};
};
const useCloseAction = () => {
const { setVisible } = useActionContext();
return {
async run() {
setVisible(false);
},
};
};
const useRemoveAction = () => {
const { refresh: dataRefresh, data } = useAsyncData();
const { record } = useContext(CalendarContext);
const { setVisible } = useActionContext();
return {
async run() {
setVisible(false);
for (let i = 0, iLen = dataSource.length; i < iLen; i++) {
const element = dataSource[i];
if (element.id === record.id) {
dataSource.splice(i, 1);
break;
}
}
schema['x-component-props']['dataSource'] = dataSource;
dataRefresh();
},
};
};
const useEditAction = () => {
const { refresh: dataRefresh, data } = useAsyncData();
const { record } = useContext(CalendarContext);
const { setVisible } = useActionContext();
return {
async run() {
console.log(record);
},
};
};
const useUpdateAction = () => {
const form = useForm();
const { setVisible } = useActionContext();
const { refresh: dataRefresh, data } = useAsyncData();
return {
async run() {
setVisible(false);
console.log(form.values);
const record = form.values;
for (let i = 0, iLen = dataSource.length; i < iLen; i++) {
const element = dataSource[i];
if (element.id === record.id) {
dataSource[i] = { ...record };
break;
}
}
schema['x-component-props']['dataSource'] = dataSource;
form.reset();
},
};
};
const useValues = (options) => {
const { visible } = useActionContext();
const { record } = useContext(CalendarContext);
const result = useRequest(
() =>
Promise.resolve({
data: {
...record,
},
}),
{ ...options, manual: true },
);
useEffect(() => {
if (visible) {
result.run();
}
}, [visible]);
return result;
};
const collection = {
name: 'tests',
fields: [
{
type: 'string',
name: 'id',
interface: 'input',
uiSchema: {
type: 'string',
'x-component': 'Input',
},
},
{
type: 'string',
name: 'title',
interface: 'input',
uiSchema: {
type: 'string',
'x-component': 'Input',
},
},
{
type: 'string',
name: 'start',
interface: 'datetime',
uiSchema: {
type: 'string',
'x-component': 'DatePicker',
'x-component-props': {
dateFormat: 'YYYY-MM-DD',
},
},
},
{
type: 'string',
name: 'end',
interface: 'datetime',
uiSchema: {
type: 'string',
'x-component': 'DatePicker',
'x-component-props': {
dateFormat: 'YYYY-MM-DD',
},
},
},
],
};
export default () => {
return (
<CollectionProvider collection={collection}>
<SchemaComponentProvider
scope={{
useSaveAction,
useCloseAction,
useEditAction,
useUpdateAction,
useValues,
useRemoveAction,
}}
>
<SchemaInitializerProvider>
<AntdSchemaComponentProvider>
<SchemaComponent schema={schema} />
</AntdSchemaComponentProvider>
</SchemaInitializerProvider>
</SchemaComponentProvider>
</CollectionProvider>
);
};

View File

@ -11,6 +11,14 @@ group:
### Calendar ### Calendar
#### Sync Data #### general calendar
<code src="./demos/demo1.tsx" /> <code src="./demos/demo1.tsx" />
#### view calendar detail
<code src="./demos/demo2.tsx" />
#### view calendar detail used initializer
<code src="./demos/demo3.tsx" />

View File

@ -121,9 +121,11 @@ const useColProperties = () => {
}; };
export const Grid: any = observer((props) => { export const Grid: any = observer((props) => {
debugger;
const field = useField(); const field = useField();
const fieldSchema = useFieldSchema(); const fieldSchema = useFieldSchema();
const { render } = useSchemaInitializer(fieldSchema['x-initializer']); const { render } = useSchemaInitializer(fieldSchema['x-initializer']);
debugger;
const addr = field.address.toString(); const addr = field.address.toString();
const rows = useRowProperties(); const rows = useRowProperties();
return ( return (

View File

@ -29,6 +29,7 @@ export const useSchemaInitializer = (name: string) => {
} }
if (isPlainObj(initializer)) { if (isPlainObj(initializer)) {
debugger;
return { return {
exists: true, exists: true,
render: (props?: any) => { render: (props?: any) => {