mirror of
https://gitee.com/nocobase/nocobase.git
synced 2024-11-30 19:28:34 +08:00
feat: improve code
This commit is contained in:
parent
b656f69565
commit
acf459d5df
@ -32,8 +32,10 @@ const getSchema = (schema: IField, useAction): ISchema => {
|
||||
'x-component': 'CollectionField',
|
||||
'x-decorator': 'FormItem',
|
||||
},
|
||||
title: {
|
||||
'x-component': 'CollectionField',
|
||||
'uiSchema.title': {
|
||||
type: 'number',
|
||||
title: '字段名称',
|
||||
'x-component': 'Input',
|
||||
'x-decorator': 'FormItem',
|
||||
},
|
||||
name: {
|
||||
|
@ -72,7 +72,7 @@ export const collectionFieldSchema: ISchema = {
|
||||
pageSize: 5,
|
||||
filter: {},
|
||||
sort: ['sort'],
|
||||
appends: [],
|
||||
appends: ['uiSchema'],
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -114,12 +114,12 @@ export const collectionFieldSchema: ISchema = {
|
||||
properties: {
|
||||
column1: {
|
||||
type: 'void',
|
||||
'x-decorator': 'TableColumnDecorator',
|
||||
title: '字段名称',
|
||||
'x-component': 'VoidTable.Column',
|
||||
properties: {
|
||||
title: {
|
||||
'uiSchema.title': {
|
||||
type: 'number',
|
||||
'x-component': 'CollectionField',
|
||||
'x-component': 'Input',
|
||||
'x-read-pretty': true,
|
||||
},
|
||||
},
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Result } from 'ahooks/lib/useRequest/src/types';
|
||||
import React, { createContext, useContext, useEffect } from 'react';
|
||||
import { useCollectionManager } from '.';
|
||||
import { CollectionProvider, useRecord } from '..';
|
||||
import { useAPIClient, useRequest } from '../api-client';
|
||||
|
||||
@ -14,13 +15,17 @@ interface ResourceActionProviderProps {
|
||||
const ResourceContext = createContext<any>(null);
|
||||
|
||||
const CollectionResourceActionProvider = (props) => {
|
||||
const { collection, request, uid } = props;
|
||||
let { collection, request, uid } = props;
|
||||
const { get } = useCollectionManager();
|
||||
const api = useAPIClient();
|
||||
const service = useRequest(request, {
|
||||
uid,
|
||||
// refreshDeps: [request],
|
||||
});
|
||||
const service = useRequest(request, { uid });
|
||||
const resource = api.resource(request.resource);
|
||||
if (typeof collection === 'string') {
|
||||
collection = get(collection);
|
||||
}
|
||||
if (!collection) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<ResourceContext.Provider value={{ type: 'collection', resource, collection }}>
|
||||
<ResourceActionContext.Provider value={service}>
|
||||
@ -31,18 +36,19 @@ const CollectionResourceActionProvider = (props) => {
|
||||
};
|
||||
|
||||
const AssociationResourceActionProvider = (props) => {
|
||||
const { collection, association, request, uid } = props;
|
||||
let { collection, association, request, uid } = props;
|
||||
const { get } = useCollectionManager();
|
||||
const api = useAPIClient();
|
||||
const record = useRecord();
|
||||
const resourceOf = record[association.sourceKey];
|
||||
const service = useRequest(
|
||||
{ resourceOf, ...request },
|
||||
{
|
||||
uid,
|
||||
// refreshDeps: [request, resourceOf],
|
||||
},
|
||||
);
|
||||
const service = useRequest({ resourceOf, ...request }, { uid });
|
||||
const resource = api.resource(request.resource, resourceOf);
|
||||
if (typeof collection === 'string') {
|
||||
collection = get(collection);
|
||||
}
|
||||
if (!collection) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<ResourceContext.Provider value={{ type: 'association', resource, association }}>
|
||||
<ResourceActionContext.Provider value={service}>
|
||||
|
@ -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 = () => {
|
||||
const form = useForm();
|
||||
const ctx = useActionContext();
|
||||
|
@ -22,7 +22,7 @@ export const ActionDrawer: ComposedActionDrawer = observer((props) => {
|
||||
{createPortal(
|
||||
<Drawer
|
||||
width={'50%'}
|
||||
title={schema.title}
|
||||
title={field.title}
|
||||
{...others}
|
||||
destroyOnClose
|
||||
visible={visible}
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { FormLayout } from '@formily/antd';
|
||||
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 { Spin } from 'antd';
|
||||
import React, { useMemo } from 'react';
|
||||
import { useAttach } from '../..';
|
||||
import { useAttach, useComponent } from '../..';
|
||||
import { useRequest } from '../../../api-client';
|
||||
|
||||
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 { form, children, ...others } = props;
|
||||
const field = useField();
|
||||
const fieldSchema = useFieldSchema();
|
||||
// TODO: component 里 useField 会与当前 field 存在偏差
|
||||
const f = useAttach(form.createVoidField({ ...field.props, basePath: '' }));
|
||||
return (
|
||||
<FieldContext.Provider value={undefined}>
|
||||
<FormContext.Provider value={form}>
|
||||
<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>
|
||||
</FormContext.Provider>
|
||||
</FieldContext.Provider>
|
||||
@ -63,7 +89,11 @@ export const Form: React.FC<FormProps> = observer((props) => {
|
||||
);
|
||||
return (
|
||||
<Spin spinning={loading}>
|
||||
<FormComponent form={form} {...others} />
|
||||
{fieldSchema['x-decorator'] === 'Form' ? (
|
||||
<FormDecorator form={form} {...others} />
|
||||
) : (
|
||||
<FormComponent form={form} {...others} />
|
||||
)}
|
||||
</Spin>
|
||||
);
|
||||
});
|
||||
|
@ -2,13 +2,13 @@ import { SchemaOptionsContext } from '@formily/react';
|
||||
import { get } from 'lodash';
|
||||
import { useContext } from 'react';
|
||||
|
||||
export const useComponent = (component: any) => {
|
||||
export const useComponent = (component: any, defaults?: any) => {
|
||||
if (!component) {
|
||||
return null;
|
||||
return defaults;
|
||||
}
|
||||
if (typeof component !== 'string') {
|
||||
return component;
|
||||
}
|
||||
const { components } = useContext(SchemaOptionsContext);
|
||||
return get(components, component);
|
||||
return get(components, component) || defaults;
|
||||
};
|
||||
|
@ -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,
|
||||
};
|
||||
}),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
);
|
||||
});
|
@ -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>
|
||||
);
|
||||
});
|
@ -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,
|
||||
};
|
||||
}),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
);
|
||||
});
|
@ -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>
|
||||
);
|
||||
});
|
@ -1,10 +1,10 @@
|
||||
import { FormOutlined } from '@ant-design/icons';
|
||||
import { ISchema, observer } from '@formily/react';
|
||||
import { uid } from '@formily/shared';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { SchemaInitializer } from '../..';
|
||||
import { FormBlockInitializerItem } from './FormBlockInitializerItem';
|
||||
import { TableBlockInitializerItem } from './TableBlockInitializerItem';
|
||||
import { FormBlock } from './FormBlock';
|
||||
import { TableBlock } from './TableBlock';
|
||||
|
||||
const gridRowColWrap = (schema: ISchema) => {
|
||||
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) => {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<SchemaInitializer.Button
|
||||
wrap={gridRowColWrap}
|
||||
@ -122,23 +31,23 @@ export const BlockInitializer = observer((props: any) => {
|
||||
items={[
|
||||
{
|
||||
type: 'itemGroup',
|
||||
title: 'Data blocks',
|
||||
title: t('Data blocks'),
|
||||
children: [
|
||||
{
|
||||
type: 'item',
|
||||
title: 'Table',
|
||||
component: TableBlockInitializerItem,
|
||||
title: t('Table'),
|
||||
component: TableBlock,
|
||||
},
|
||||
{
|
||||
type: 'item',
|
||||
title: 'Form',
|
||||
component: FormBlockInitializerItem,
|
||||
title: t('Form'),
|
||||
component: FormBlock,
|
||||
},
|
||||
],
|
||||
},
|
||||
]}
|
||||
>
|
||||
Add block
|
||||
{t('Add block')}
|
||||
</SchemaInitializer.Button>
|
||||
);
|
||||
});
|
||||
|
@ -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>
|
||||
);
|
||||
});
|
@ -3,37 +3,24 @@ import { uid } from '@formily/shared';
|
||||
import { Switch } from 'antd';
|
||||
import React from 'react';
|
||||
import { SchemaInitializer, SchemaInitializerItemOptions } from '../..';
|
||||
import { useCollection } from '../../../collection-manager';
|
||||
import { useDesignable } from '../../../schema-component';
|
||||
|
||||
const useFormItemInitializerFields = () => {
|
||||
return [
|
||||
{
|
||||
const { name, fields } = useCollection();
|
||||
return fields?.map((field) => {
|
||||
return {
|
||||
type: 'item',
|
||||
title: 'Name',
|
||||
title: field?.uiSchema?.title || field.name,
|
||||
component: InitializeFormItem,
|
||||
schema: {
|
||||
name: 'name',
|
||||
type: 'string',
|
||||
title: 'Name',
|
||||
'x-component': 'Input',
|
||||
name: field.name,
|
||||
'x-component': 'CollectionField',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-collection-field': 'posts.name',
|
||||
'x-collection-field': `${name}.${field.name}`,
|
||||
},
|
||||
},
|
||||
{
|
||||
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[];
|
||||
} as SchemaInitializerItemOptions;
|
||||
});
|
||||
};
|
||||
|
||||
const gridRowColWrap = (schema: ISchema) => {
|
||||
|
@ -73,8 +73,50 @@ export const TableActionInitializer = observer((props: any) => {
|
||||
title: t('Add new'),
|
||||
component: InitializeAction,
|
||||
schema: {
|
||||
type: 'void',
|
||||
title: '{{ t("Add new") }}',
|
||||
'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 }}',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -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 { item, insert } = props;
|
||||
const { exists, remove } = useCurrentActionSchema(item.schema['x-action']);
|
||||
@ -89,7 +113,7 @@ export const TableColumnActionInitializer = observer((props: any) => {
|
||||
{
|
||||
type: 'item',
|
||||
title: t('View'),
|
||||
component: InitializeAction,
|
||||
component: InitializeViewAction,
|
||||
schema: {
|
||||
title: '{{ t("View") }}',
|
||||
type: 'void',
|
||||
@ -101,7 +125,31 @@ export const TableColumnActionInitializer = observer((props: any) => {
|
||||
type: 'void',
|
||||
'x-component': 'Action.Drawer',
|
||||
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: {},
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'item',
|
||||
|
@ -8,11 +8,11 @@ import { useCollection, useDesignable } from '../../..';
|
||||
const useTableColumnInitializerFields = () => {
|
||||
const { name, fields } = useCollection();
|
||||
return fields
|
||||
.filter((field) => field?.uiSchema?.title)
|
||||
// .filter((field) => field?.uiSchema?.title)
|
||||
.map((field) => {
|
||||
return {
|
||||
type: 'item',
|
||||
title: field?.uiSchema?.title,
|
||||
title: field?.uiSchema?.title || field.name,
|
||||
schema: {
|
||||
name: field.name,
|
||||
'x-collection-field': `${name}.${field.name}`,
|
||||
|
@ -1,5 +1,6 @@
|
||||
export * from './BlockInitializer';
|
||||
export * from './DetailsActionInitializer';
|
||||
export * from './FormActionInitializer';
|
||||
export * from './FormItemInitializer';
|
||||
export * from './RecordBlockInitializer';
|
||||
export * from './TableActionInitializer';
|
||||
|
Loading…
Reference in New Issue
Block a user