feat: improve code

This commit is contained in:
chenos 2022-02-18 02:05:42 +08:00
parent b656f69565
commit acf459d5df
18 changed files with 450 additions and 551 deletions

View File

@ -32,8 +32,10 @@ const getSchema = (schema: IField, useAction): ISchema => {
'x-component': 'CollectionField', 'x-component': 'CollectionField',
'x-decorator': 'FormItem', 'x-decorator': 'FormItem',
}, },
title: { 'uiSchema.title': {
'x-component': 'CollectionField', type: 'number',
title: '字段名称',
'x-component': 'Input',
'x-decorator': 'FormItem', 'x-decorator': 'FormItem',
}, },
name: { name: {

View File

@ -72,7 +72,7 @@ export const collectionFieldSchema: ISchema = {
pageSize: 5, pageSize: 5,
filter: {}, filter: {},
sort: ['sort'], sort: ['sort'],
appends: [], appends: ['uiSchema'],
}, },
}, },
}, },
@ -114,12 +114,12 @@ export const collectionFieldSchema: ISchema = {
properties: { properties: {
column1: { column1: {
type: 'void', type: 'void',
'x-decorator': 'TableColumnDecorator', title: '字段名称',
'x-component': 'VoidTable.Column', 'x-component': 'VoidTable.Column',
properties: { properties: {
title: { 'uiSchema.title': {
type: 'number', type: 'number',
'x-component': 'CollectionField', 'x-component': 'Input',
'x-read-pretty': true, 'x-read-pretty': true,
}, },
}, },

View File

@ -1,5 +1,6 @@
import { Result } from 'ahooks/lib/useRequest/src/types'; import { Result } from 'ahooks/lib/useRequest/src/types';
import React, { createContext, useContext, useEffect } from 'react'; import React, { createContext, useContext, useEffect } from 'react';
import { useCollectionManager } from '.';
import { CollectionProvider, useRecord } from '..'; import { CollectionProvider, useRecord } from '..';
import { useAPIClient, useRequest } from '../api-client'; import { useAPIClient, useRequest } from '../api-client';
@ -14,13 +15,17 @@ interface ResourceActionProviderProps {
const ResourceContext = createContext<any>(null); const ResourceContext = createContext<any>(null);
const CollectionResourceActionProvider = (props) => { const CollectionResourceActionProvider = (props) => {
const { collection, request, uid } = props; let { collection, request, uid } = props;
const { get } = useCollectionManager();
const api = useAPIClient(); const api = useAPIClient();
const service = useRequest(request, { const service = useRequest(request, { uid });
uid,
// refreshDeps: [request],
});
const resource = api.resource(request.resource); const resource = api.resource(request.resource);
if (typeof collection === 'string') {
collection = get(collection);
}
if (!collection) {
return null;
}
return ( return (
<ResourceContext.Provider value={{ type: 'collection', resource, collection }}> <ResourceContext.Provider value={{ type: 'collection', resource, collection }}>
<ResourceActionContext.Provider value={service}> <ResourceActionContext.Provider value={service}>
@ -31,18 +36,19 @@ const CollectionResourceActionProvider = (props) => {
}; };
const AssociationResourceActionProvider = (props) => { const AssociationResourceActionProvider = (props) => {
const { collection, association, request, uid } = props; let { collection, association, request, uid } = props;
const { get } = useCollectionManager();
const api = useAPIClient(); const api = useAPIClient();
const record = useRecord(); const record = useRecord();
const resourceOf = record[association.sourceKey]; const resourceOf = record[association.sourceKey];
const service = useRequest( const service = useRequest({ resourceOf, ...request }, { uid });
{ resourceOf, ...request },
{
uid,
// refreshDeps: [request, resourceOf],
},
);
const resource = api.resource(request.resource, resourceOf); const resource = api.resource(request.resource, resourceOf);
if (typeof collection === 'string') {
collection = get(collection);
}
if (!collection) {
return null;
}
return ( return (
<ResourceContext.Provider value={{ type: 'association', resource, association }}> <ResourceContext.Provider value={{ type: 'association', resource, association }}>
<ResourceActionContext.Provider value={service}> <ResourceActionContext.Provider value={service}>

View File

@ -32,6 +32,18 @@ export const useCreateAction = () => {
}; };
}; };
export const useCreateActionWithoutRefresh = () => {
const form = useForm();
const { resource } = useResourceContext();
return {
async run() {
await form.submit();
await resource.create({ values: form.values });
await form.reset();
},
};
};
export const useUpdateAction = () => { export const useUpdateAction = () => {
const form = useForm(); const form = useForm();
const ctx = useActionContext(); const ctx = useActionContext();

View File

@ -22,7 +22,7 @@ export const ActionDrawer: ComposedActionDrawer = observer((props) => {
{createPortal( {createPortal(
<Drawer <Drawer
width={'50%'} width={'50%'}
title={schema.title} title={field.title}
{...others} {...others}
destroyOnClose destroyOnClose
visible={visible} visible={visible}

View File

@ -1,10 +1,10 @@
import { FormLayout } from '@formily/antd'; import { FormLayout } from '@formily/antd';
import { createForm } from '@formily/core'; import { createForm } from '@formily/core';
import { FieldContext, FormContext, observer, useField, useFieldSchema } from '@formily/react'; import { FieldContext, FormContext, observer, RecursionField, useField, useFieldSchema } from '@formily/react';
import { Options, Result } from 'ahooks/lib/useRequest/src/types'; import { Options, Result } from 'ahooks/lib/useRequest/src/types';
import { Spin } from 'antd'; import { Spin } from 'antd';
import React, { useMemo } from 'react'; import React, { useMemo } from 'react';
import { useAttach } from '../..'; import { useAttach, useComponent } from '../..';
import { useRequest } from '../../../api-client'; import { useRequest } from '../../../api-client';
type Opts = Options<any, any> & { uid?: string }; type Opts = Options<any, any> & { uid?: string };
@ -18,13 +18,39 @@ export type FormUseValues = (opts?: Opts, props?: FormProps) => Result<any, any>
const FormComponent: React.FC<FormProps> = (props) => { const FormComponent: React.FC<FormProps> = (props) => {
const { form, children, ...others } = props; const { form, children, ...others } = props;
const field = useField(); const field = useField();
const fieldSchema = useFieldSchema();
// TODO: component 里 useField 会与当前 field 存在偏差 // TODO: component 里 useField 会与当前 field 存在偏差
const f = useAttach(form.createVoidField({ ...field.props, basePath: '' })); const f = useAttach(form.createVoidField({ ...field.props, basePath: '' }));
return ( return (
<FieldContext.Provider value={undefined}> <FieldContext.Provider value={undefined}>
<FormContext.Provider value={form}> <FormContext.Provider value={form}>
<FormLayout layout={'vertical'} {...others}> <FormLayout layout={'vertical'} {...others}>
<FieldContext.Provider value={f}>{children}</FieldContext.Provider> <RecursionField basePath={f.address} schema={fieldSchema} onlyRenderProperties />
</FormLayout>
</FormContext.Provider>
</FieldContext.Provider>
);
};
const Def = (props: any) => props.children;
const FormDecorator: React.FC<FormProps> = (props) => {
const { form, children, ...others } = props;
const field = useField();
const fieldSchema = useFieldSchema();
// TODO: component 里 useField 会与当前 field 存在偏差
const f = useAttach(form.createVoidField({ ...field.props, basePath: '' }));
const Component = useComponent(fieldSchema['x-component'], Def);
return (
<FieldContext.Provider value={undefined}>
<FormContext.Provider value={form}>
<FormLayout layout={'vertical'} {...others}>
<FieldContext.Provider value={f}>
<Component {...field.componentProps}>
<RecursionField basePath={f.address} schema={fieldSchema} onlyRenderProperties />
</Component>
</FieldContext.Provider>
{/* <FieldContext.Provider value={f}>{children}</FieldContext.Provider> */}
</FormLayout> </FormLayout>
</FormContext.Provider> </FormContext.Provider>
</FieldContext.Provider> </FieldContext.Provider>
@ -63,7 +89,11 @@ export const Form: React.FC<FormProps> = observer((props) => {
); );
return ( return (
<Spin spinning={loading}> <Spin spinning={loading}>
<FormComponent form={form} {...others} /> {fieldSchema['x-decorator'] === 'Form' ? (
<FormDecorator form={form} {...others} />
) : (
<FormComponent form={form} {...others} />
)}
</Spin> </Spin>
); );
}); });

View File

@ -2,13 +2,13 @@ import { SchemaOptionsContext } from '@formily/react';
import { get } from 'lodash'; import { get } from 'lodash';
import { useContext } from 'react'; import { useContext } from 'react';
export const useComponent = (component: any) => { export const useComponent = (component: any, defaults?: any) => {
if (!component) { if (!component) {
return null; return defaults;
} }
if (typeof component !== 'string') { if (typeof component !== 'string') {
return component; return component;
} }
const { components } = useContext(SchemaOptionsContext); const { components } = useContext(SchemaOptionsContext);
return get(components, component); return get(components, component) || defaults;
}; };

View File

@ -0,0 +1,75 @@
import { FormOutlined } from '@ant-design/icons';
import { ISchema } from '@formily/react';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { SchemaInitializer } from '../..';
import { useCollectionManager } from '../../../collection-manager';
const createSchema = (collectionName) => {
const schema: ISchema = {
type: 'void',
'x-collection': 'collections',
'x-decorator': 'ResourceActionProvider',
'x-decorator-props': {
collection: collectionName,
request: {
resource: collectionName,
action: 'get',
params: {},
},
},
'x-component': 'CardItem',
properties: {
form: {
type: 'void',
'x-decorator': 'Form',
'x-decorator-props': {},
properties: {
grid: {
type: 'void',
'x-component': 'Grid',
'x-item-initializer': 'FormItemInitializer',
properties: {},
},
actions: {
type: 'void',
'x-component': 'ActionBar',
'x-action-initializer': 'FormActionInitializer',
properties: {},
},
},
},
},
};
return schema;
};
const itemWrap = SchemaInitializer.itemWrap;
export const FormBlock = itemWrap((props) => {
const { insert } = props;
const { collections } = useCollectionManager();
const { t } = useTranslation();
return (
<SchemaInitializer.Item
{...props}
icon={<FormOutlined />}
onClick={({ item }) => {
insert(createSchema(item.name));
}}
items={[
{
type: 'itemGroup',
title: t('Select data source'),
children: collections?.map((item) => {
return {
type: 'item',
name: item.name,
title: item.title,
};
}),
},
]}
/>
);
});

View File

@ -1,260 +0,0 @@
import { TableOutlined } from '@ant-design/icons';
import { ISchema } from '@formily/react';
import { clone } from '@formily/shared';
import React from 'react';
import { SchemaInitializer } from '../../';
import { CollectionOptions, useCollectionManager } from '../../../collection-manager';
const collection: CollectionOptions = {
name: 'collections',
filterTargetKey: 'name',
targetKey: 'name',
fields: [
{
type: 'integer',
name: 'title',
interface: 'input',
uiSchema: {
title: '数据表名称',
type: 'number',
'x-component': 'Input',
required: true,
},
},
{
type: 'string',
name: 'name',
interface: 'input',
uiSchema: {
title: '数据表标识',
type: 'string',
'x-component': 'Input',
description: '使用英文',
},
},
{
type: 'hasMany',
name: 'fields',
target: 'fields',
collectionName: 'collections',
sourceKey: 'name',
targetKey: 'name',
uiSchema: {},
},
],
};
export const collectionSchema: ISchema = {
type: 'void',
'x-collection': 'collections',
'x-component': 'CardItem',
'x-decorator': 'ResourceActionProvider',
'x-decorator-props': {
collection,
request: {
resource: 'collections',
action: 'list',
params: {
pageSize: 5,
filter: {},
sort: ['sort'],
appends: [],
},
},
},
properties: {
actions: {
type: 'void',
'x-component': 'ActionBar',
'x-action-initializer': 'AddActionButton',
properties: {
delete: {
type: 'void',
title: '删除',
'x-component': 'Action',
},
create: {
type: 'void',
title: '创建',
'x-component': 'Action',
'x-component-props': {
type: 'primary',
},
properties: {
drawer: {
type: 'void',
'x-component': 'Action.Drawer',
'x-decorator': 'Form',
title: 'Drawer Title',
properties: {
title: {
'x-component': 'CollectionField',
'x-decorator': 'FormItem',
},
name: {
'x-component': 'CollectionField',
'x-decorator': 'FormItem',
},
footer: {
type: 'void',
'x-component': 'Action.Drawer.Footer',
properties: {
action1: {
title: 'Cancel',
'x-component': 'Action',
'x-component-props': {
useAction: '{{ useCancelAction }}',
},
},
action2: {
title: 'Submit',
'x-component': 'Action',
'x-component-props': {
type: 'primary',
useAction: '{{ useCreateAction }}',
},
},
},
},
},
},
},
},
},
},
table1: {
type: 'void',
'x-component': 'VoidTable',
'x-component-props': {
rowKey: 'id',
rowSelection: {
type: 'checkbox',
},
useDataSource: '{{ useDataSourceFromRAC }}',
},
'x-column-initializer': 'AddTableColumn',
properties: {
column3: {
type: 'void',
title: 'Actions',
'x-component': 'VoidTable.Column',
properties: {
actions: {
type: 'void',
'x-component': 'Space',
'x-component-props': {
split: '|',
},
properties: {
view: {
type: 'void',
title: '配置字段',
'x-component': 'Action.Link',
'x-component-props': {},
properties: {
drawer: {
type: 'void',
'x-component': 'Action.Drawer',
title: 'Drawer Title',
properties: {},
},
},
},
update: {
type: 'void',
title: '编辑',
'x-component': 'Action.Link',
'x-component-props': {
type: 'primary',
},
properties: {
drawer: {
type: 'void',
'x-component': 'Action.Drawer',
'x-decorator': 'Form',
'x-decorator-props': {
useValues: '{{ useValues }}',
},
title: 'Drawer Title',
properties: {
title: {
'x-component': 'CollectionField',
'x-decorator': 'FormItem',
},
name: {
'x-component': 'CollectionField',
'x-decorator': 'FormItem',
'x-disabled': true,
},
footer: {
type: 'void',
'x-component': 'Action.Drawer.Footer',
properties: {
action1: {
title: 'Cancel',
'x-component': 'Action',
'x-component-props': {
useAction: '{{ useCancelAction }}',
},
},
action2: {
title: 'Submit',
'x-component': 'Action',
'x-component-props': {
type: 'primary',
useAction: '{{ useUpdateAction }}',
},
},
},
},
},
},
},
},
delete: {
type: 'void',
title: '删除',
'x-component': 'Action.Link',
'x-component-props': {
useAction: '{{ useDestroyAction }}',
},
},
},
},
},
},
},
},
},
};
const itemWrap = SchemaInitializer.itemWrap;
export const FormBlockInitializerItem = itemWrap((props) => {
const { insert } = props;
const { collections } = useCollectionManager();
return (
<SchemaInitializer.Item
icon={<TableOutlined />}
onClick={() => {
insert(clone(collectionSchema));
}}
items={[
{
type: 'itemGroup',
title: 'select a data source',
children: collections?.map((item) => {
return {
type: 'item',
name: item.name,
title: item.title,
};
}),
},
]}
>
Form
</SchemaInitializer.Item>
);
});

View File

@ -0,0 +1,99 @@
import { TableOutlined } from '@ant-design/icons';
import { ISchema } from '@formily/react';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { SchemaInitializer } from '../..';
import { useCollectionManager } from '../../../collection-manager';
const createSchema = (collectionName) => {
const schema: ISchema = {
type: 'void',
'x-collection': 'collections',
'x-decorator': 'ResourceActionProvider',
'x-decorator-props': {
collection: collectionName,
request: {
resource: collectionName,
action: 'list',
params: {
perPage: 20,
pageSize: 20,
filter: {},
// sort: ['sort'],
appends: [],
},
},
},
'x-component': 'CardItem',
properties: {
actions: {
type: 'void',
'x-component': 'ActionBar',
'x-action-initializer': 'TableActionInitializer',
properties: {},
},
table1: {
type: 'void',
'x-component': 'VoidTable',
'x-component-props': {
rowKey: 'id',
rowSelection: {
type: 'checkbox',
},
useDataSource: '{{ useDataSourceFromRAC }}',
},
'x-column-initializer': 'TableColumnInitializer',
properties: {
actions: {
type: 'void',
title: 'Actions',
'x-decorator': 'TableColumnActionBar',
'x-component': 'VoidTable.Column',
'x-action-initializer': 'TableColumnActionInitializer',
properties: {
actions: {
type: 'void',
'x-component': 'Space',
'x-component-props': {
split: '|',
},
properties: {},
},
},
},
},
},
},
};
return schema;
};
const itemWrap = SchemaInitializer.itemWrap;
export const TableBlock = itemWrap((props) => {
const { insert } = props;
const { collections } = useCollectionManager();
const { t } = useTranslation();
return (
<SchemaInitializer.Item
{...props}
icon={<TableOutlined />}
onClick={({ item }) => {
insert(createSchema(item.name));
}}
items={[
{
type: 'itemGroup',
title: t('Select data source'),
children: collections?.map((item) => {
return {
type: 'item',
name: item.name,
title: item.title,
};
}),
},
]}
/>
);
});

View File

@ -1,135 +0,0 @@
import { TableOutlined } from '@ant-design/icons';
import { ISchema } from '@formily/react';
import { clone } from '@formily/shared';
import React from 'react';
import { SchemaInitializer } from '../..';
import { CollectionOptions, useCollectionManager } from '../../../collection-manager';
const collection: CollectionOptions = {
name: 'collections',
filterTargetKey: 'name',
targetKey: 'name',
fields: [
{
type: 'integer',
name: 'title',
interface: 'input',
uiSchema: {
title: '数据表名称',
type: 'number',
required: true,
'x-component': 'Input',
},
},
{
type: 'string',
name: 'name',
interface: 'input',
uiSchema: {
title: '数据表标识',
type: 'string',
description: '使用英文',
'x-component': 'Input',
},
},
{
type: 'hasMany',
name: 'fields',
target: 'fields',
collectionName: 'collections',
sourceKey: 'name',
targetKey: 'name',
uiSchema: {},
},
],
};
export const collectionSchema: ISchema = {
type: 'void',
'x-collection': 'collections',
'x-component': 'CardItem',
'x-decorator': 'ResourceActionProvider',
'x-decorator-props': {
collection,
request: {
resource: 'collections',
action: 'list',
params: {
pageSize: 5,
filter: {},
sort: ['sort'],
appends: [],
},
},
},
properties: {
actions: {
type: 'void',
'x-component': 'ActionBar',
'x-action-initializer': 'TableActionInitializer',
properties: {},
},
table1: {
type: 'void',
'x-component': 'VoidTable',
'x-component-props': {
rowKey: 'id',
rowSelection: {
type: 'checkbox',
},
useDataSource: '{{ useDataSourceFromRAC }}',
},
'x-column-initializer': 'TableColumnInitializer',
properties: {
actions: {
type: 'void',
title: 'Actions',
'x-decorator': 'TableColumnActionBar',
'x-component': 'VoidTable.Column',
'x-action-initializer': 'TableColumnActionInitializer',
properties: {
actions: {
type: 'void',
'x-component': 'Space',
'x-component-props': {
split: '|',
},
properties: {},
},
},
},
},
},
},
};
const itemWrap = SchemaInitializer.itemWrap;
export const TableBlockInitializerItem = itemWrap((props) => {
const { insert } = props;
const { collections } = useCollectionManager();
return (
<SchemaInitializer.Item
icon={<TableOutlined />}
onClick={() => {
insert(clone(collectionSchema));
}}
items={[
{
type: 'itemGroup',
title: 'select a data source',
children: collections?.map((item) => {
return {
type: 'item',
name: item.name,
title: item.title,
};
}),
},
]}
>
Table
</SchemaInitializer.Item>
);
});

View File

@ -1,10 +1,10 @@
import { FormOutlined } from '@ant-design/icons';
import { ISchema, observer } from '@formily/react'; import { ISchema, observer } from '@formily/react';
import { uid } from '@formily/shared'; import { uid } from '@formily/shared';
import React from 'react'; import React from 'react';
import { useTranslation } from 'react-i18next';
import { SchemaInitializer } from '../..'; import { SchemaInitializer } from '../..';
import { FormBlockInitializerItem } from './FormBlockInitializerItem'; import { FormBlock } from './FormBlock';
import { TableBlockInitializerItem } from './TableBlockInitializerItem'; import { TableBlock } from './TableBlock';
const gridRowColWrap = (schema: ISchema) => { const gridRowColWrap = (schema: ISchema) => {
return { return {
@ -22,99 +22,8 @@ const gridRowColWrap = (schema: ISchema) => {
}; };
}; };
const itemWrap = SchemaInitializer.itemWrap;
const TestInitializerItem = itemWrap((props) => {
const { insert } = props;
return (
<SchemaInitializer.Item
icon={<FormOutlined />}
onClick={() => {
insert({
type: 'void',
name: uid(),
'x-decorator': 'CardItem',
'x-component': 'Grid',
'x-uid': uid(),
properties: {
row1: {
type: 'void',
'x-component': 'Grid.Row',
'x-uid': uid(),
properties: {
col11: {
type: 'void',
'x-component': 'Grid.Col',
properties: {
block1: {
type: 'void',
title: '1',
'x-decorator': 'BlockItem',
'x-component': 'Block',
},
block2: {
type: 'void',
title: '2',
'x-decorator': 'BlockItem',
'x-component': 'Block',
},
},
},
col12: {
type: 'void',
'x-component': 'Grid.Col',
properties: {
block3: {
type: 'void',
title: '3',
'x-decorator': 'BlockItem',
'x-component': 'Block',
},
},
},
},
},
row2: {
type: 'void',
'x-component': 'Grid.Row',
'x-uid': uid(),
properties: {
col21: {
type: 'void',
'x-component': 'Grid.Col',
properties: {
block4: {
type: 'void',
title: '4',
'x-decorator': 'BlockItem',
'x-component': 'Block',
},
},
},
col22: {
type: 'void',
'x-component': 'Grid.Col',
properties: {
block5: {
type: 'void',
title: '5',
'x-decorator': 'BlockItem',
'x-component': 'Block',
},
},
},
},
},
},
});
}}
>
Test
</SchemaInitializer.Item>
);
});
export const BlockInitializer = observer((props: any) => { export const BlockInitializer = observer((props: any) => {
const { t } = useTranslation();
return ( return (
<SchemaInitializer.Button <SchemaInitializer.Button
wrap={gridRowColWrap} wrap={gridRowColWrap}
@ -122,23 +31,23 @@ export const BlockInitializer = observer((props: any) => {
items={[ items={[
{ {
type: 'itemGroup', type: 'itemGroup',
title: 'Data blocks', title: t('Data blocks'),
children: [ children: [
{ {
type: 'item', type: 'item',
title: 'Table', title: t('Table'),
component: TableBlockInitializerItem, component: TableBlock,
}, },
{ {
type: 'item', type: 'item',
title: 'Form', title: t('Form'),
component: FormBlockInitializerItem, component: FormBlock,
}, },
], ],
}, },
]} ]}
> >
Add block {t('Add block')}
</SchemaInitializer.Button> </SchemaInitializer.Button>
); );
}); });

View File

@ -0,0 +1,83 @@
import { observer, useFieldSchema } from '@formily/react';
import { Switch } from 'antd';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { SchemaInitializer } from '../..';
import { useDesignable } from '../../../schema-component';
const useCurrentActionSchema = (action: string) => {
const fieldSchema = useFieldSchema();
const { remove } = useDesignable();
const schema = fieldSchema.reduceProperties((buf, s) => {
if (s['x-action'] === action) {
return s;
}
return buf;
});
return {
schema,
exists: !!schema,
remove() {
schema && remove(schema);
},
};
};
const InitializeAction = SchemaInitializer.itemWrap((props) => {
const { item, insert } = props;
const { exists, remove } = useCurrentActionSchema(item.schema['x-action']);
return (
<SchemaInitializer.Item
onClick={() => {
if (exists) {
return remove();
}
insert({
type: 'void',
'x-component': 'Action',
...item.schema,
});
}}
>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
{item.title}
<Switch style={{ marginLeft: 20 }} size={'small'} checked={exists} />
</div>
</SchemaInitializer.Item>
);
});
export const FormActionInitializer = observer((props: any) => {
const { t } = useTranslation();
return (
<SchemaInitializer.Button
insertPosition={'beforeEnd'}
style={{ marginLeft: 8 }}
items={[
{
type: 'itemGroup',
title: t('Enable actions'),
children: [
{
type: 'item',
title: t('Submit'),
component: InitializeAction,
schema: {
title: '{{ t("Submit") }}',
'x-action': 'submit',
'x-align': 'left',
'x-component': 'Action',
'x-component-props': {
type: 'primary',
useAction: '{{ useCreateActionWithoutRefresh }}',
},
},
},
],
},
]}
>
{t('Configure actions')}
</SchemaInitializer.Button>
);
});

View File

@ -3,37 +3,24 @@ import { uid } from '@formily/shared';
import { Switch } from 'antd'; import { Switch } from 'antd';
import React from 'react'; import React from 'react';
import { SchemaInitializer, SchemaInitializerItemOptions } from '../..'; import { SchemaInitializer, SchemaInitializerItemOptions } from '../..';
import { useCollection } from '../../../collection-manager';
import { useDesignable } from '../../../schema-component'; import { useDesignable } from '../../../schema-component';
const useFormItemInitializerFields = () => { const useFormItemInitializerFields = () => {
return [ const { name, fields } = useCollection();
{ return fields?.map((field) => {
return {
type: 'item', type: 'item',
title: 'Name', title: field?.uiSchema?.title || field.name,
component: InitializeFormItem, component: InitializeFormItem,
schema: { schema: {
name: 'name', name: field.name,
type: 'string', 'x-component': 'CollectionField',
title: 'Name',
'x-component': 'Input',
'x-decorator': 'FormItem', 'x-decorator': 'FormItem',
'x-collection-field': 'posts.name', 'x-collection-field': `${name}.${field.name}`,
}, },
}, } as SchemaInitializerItemOptions;
{ });
type: 'item',
title: 'Title',
component: InitializeFormItem,
schema: {
name: 'title',
type: 'string',
title: 'Title',
'x-component': 'Input',
'x-decorator': 'FormItem',
'x-collection-field': 'posts.title',
},
},
] as SchemaInitializerItemOptions[];
}; };
const gridRowColWrap = (schema: ISchema) => { const gridRowColWrap = (schema: ISchema) => {

View File

@ -73,8 +73,50 @@ export const TableActionInitializer = observer((props: any) => {
title: t('Add new'), title: t('Add new'),
component: InitializeAction, component: InitializeAction,
schema: { schema: {
type: 'void',
title: '{{ t("Add new") }}', title: '{{ t("Add new") }}',
'x-action': 'create', 'x-action': 'create',
'x-component': 'Action',
'x-component-props': {
type: 'primary',
},
properties: {
drawer: {
type: 'void',
title: '{{ t("Add new record") }}',
'x-component': 'Action.Drawer',
'x-decorator': 'Form',
properties: {
grid: {
type: 'void',
'x-component': 'Grid',
'x-item-initializer': 'FormItemInitializer',
properties: {},
},
footer: {
type: 'void',
'x-component': 'Action.Drawer.Footer',
properties: {
action1: {
title: '{{ t("Cancel") }}',
'x-component': 'Action',
'x-component-props': {
useAction: '{{ useCancelAction }}',
},
},
action2: {
title: '{{ t("Submit") }}',
'x-component': 'Action',
'x-component-props': {
type: 'primary',
useAction: '{{ useCreateAction }}',
},
},
},
},
},
},
},
}, },
}, },
{ {

View File

@ -31,6 +31,30 @@ const useCurrentActionSchema = (action: string) => {
}; };
}; };
const InitializeViewAction = SchemaInitializer.itemWrap((props) => {
const { item, insert } = props;
const { exists, remove } = useCurrentActionSchema(item.schema['x-action']);
return (
<SchemaInitializer.Item
onClick={() => {
console.log('InitializeAction', insert);
if (exists) {
return remove();
}
insert({
type: 'void',
'x-component': 'Action.Link',
...item.schema,
});
}}
>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
{item.title} <Switch style={{ marginLeft: 20 }} size={'small'} checked={exists} />
</div>
</SchemaInitializer.Item>
);
});
const InitializeAction = SchemaInitializer.itemWrap((props) => { const InitializeAction = SchemaInitializer.itemWrap((props) => {
const { item, insert } = props; const { item, insert } = props;
const { exists, remove } = useCurrentActionSchema(item.schema['x-action']); const { exists, remove } = useCurrentActionSchema(item.schema['x-action']);
@ -89,7 +113,7 @@ export const TableColumnActionInitializer = observer((props: any) => {
{ {
type: 'item', type: 'item',
title: t('View'), title: t('View'),
component: InitializeAction, component: InitializeViewAction,
schema: { schema: {
title: '{{ t("View") }}', title: '{{ t("View") }}',
type: 'void', type: 'void',
@ -101,7 +125,31 @@ export const TableColumnActionInitializer = observer((props: any) => {
type: 'void', type: 'void',
'x-component': 'Action.Drawer', 'x-component': 'Action.Drawer',
title: '{{ t("View record") }}', title: '{{ t("View record") }}',
properties: {}, properties: {
tabs: {
type: 'void',
'x-component': 'Tabs',
'x-component-props': {},
properties: {
tab1: {
type: 'void',
title: '详情',
'x-component': 'Tabs.TabPane',
'x-component-props': {},
properties: {
grid: {
type: 'void',
'x-decorator': 'Form',
'x-component': 'Grid',
'x-read-pretty': true,
'x-item-initializer': 'RecordBlockInitializer',
properties: {},
},
},
},
},
},
},
}, },
}, },
}, },
@ -124,7 +172,7 @@ export const TableColumnActionInitializer = observer((props: any) => {
properties: {}, properties: {},
}, },
}, },
} },
}, },
{ {
type: 'item', type: 'item',

View File

@ -8,11 +8,11 @@ import { useCollection, useDesignable } from '../../..';
const useTableColumnInitializerFields = () => { const useTableColumnInitializerFields = () => {
const { name, fields } = useCollection(); const { name, fields } = useCollection();
return fields return fields
.filter((field) => field?.uiSchema?.title) // .filter((field) => field?.uiSchema?.title)
.map((field) => { .map((field) => {
return { return {
type: 'item', type: 'item',
title: field?.uiSchema?.title, title: field?.uiSchema?.title || field.name,
schema: { schema: {
name: field.name, name: field.name,
'x-collection-field': `${name}.${field.name}`, 'x-collection-field': `${name}.${field.name}`,

View File

@ -1,5 +1,6 @@
export * from './BlockInitializer'; export * from './BlockInitializer';
export * from './DetailsActionInitializer'; export * from './DetailsActionInitializer';
export * from './FormActionInitializer';
export * from './FormItemInitializer'; export * from './FormItemInitializer';
export * from './RecordBlockInitializer'; export * from './RecordBlockInitializer';
export * from './TableActionInitializer'; export * from './TableActionInitializer';