refactor code
This commit is contained in:
parent
1007324b09
commit
27b61bd571
@ -19,6 +19,8 @@
|
||||
"gitHead": "f0b335ac30f29f25c95d7d137655fa64d8d67f1e",
|
||||
"dependencies": {
|
||||
"@antv/g2plot": "^2.3.27",
|
||||
"@dnd-kit/core": "^3.1.1",
|
||||
"@dnd-kit/sortable": "^4.0.0",
|
||||
"@formily/antd": "^2.0.0-beta.72",
|
||||
"@formily/core": "^2.0.0-beta.72",
|
||||
"@formily/react": "^2.0.0-beta.72",
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { SchemaRenderer } from '../../';
|
||||
import React from 'react';
|
||||
import { FormItem } from '@formily/antd';
|
||||
import { useCollectionContext } from '../../schemas';
|
||||
import { action } from '@formily/reactive';
|
||||
import { useCollectionsContext } from '../../constate/Collections';
|
||||
|
||||
const useAsyncDataSource = (service: any) => (field: any) => {
|
||||
field.loading = true;
|
||||
@ -15,10 +15,10 @@ const useAsyncDataSource = (service: any) => (field: any) => {
|
||||
};
|
||||
|
||||
export default () => {
|
||||
const { data, loading } = useCollectionContext();
|
||||
const { collections = [], loading } = useCollectionsContext();
|
||||
|
||||
const loadCollections = async (field: any) => {
|
||||
return data.map((item: any) => ({
|
||||
return collections.map((item: any) => ({
|
||||
label: item.title,
|
||||
value: item.name,
|
||||
}));
|
||||
|
@ -17,26 +17,24 @@ import {
|
||||
useHistory,
|
||||
Redirect,
|
||||
} from 'react-router-dom';
|
||||
import {
|
||||
CollectionContextProvider,
|
||||
PageTitleContextProvider,
|
||||
SchemaRenderer,
|
||||
SwithDesignableContextProvider,
|
||||
usePageTitleContext,
|
||||
useSwithDesignableContext,
|
||||
} from '../../schemas';
|
||||
import { SchemaRenderer } from '../../schemas';
|
||||
import { useRequest } from 'ahooks';
|
||||
import './style.less';
|
||||
|
||||
import { uid } from '@formily/shared';
|
||||
import { ISchema, Schema } from '@formily/react';
|
||||
import Database from './datatable';
|
||||
import { HighlightOutlined } from '@ant-design/icons';
|
||||
import { useCookieState } from 'ahooks';
|
||||
import cls from 'classnames';
|
||||
import {
|
||||
DesignableSwitchProvider,
|
||||
useDesignableSwitchContext,
|
||||
PageTitleProvider,
|
||||
usePageTitleContext,
|
||||
CollectionsProvider,
|
||||
} from '../../constate';
|
||||
|
||||
function DesignableToggle() {
|
||||
const { designable, setDesignable } = useSwithDesignableContext();
|
||||
const { designable, setDesignable } = useDesignableSwitchContext();
|
||||
return (
|
||||
<Button
|
||||
className={cls('nb-designable-toggle', { active: designable })}
|
||||
@ -78,7 +76,7 @@ function LayoutWithMenu(props: LayoutWithMenuProps) {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<Layout.Header style={{ display: 'flex' }}>
|
||||
@ -147,11 +145,11 @@ export function AdminLayout({ route }: any) {
|
||||
}
|
||||
return [...items, ...findProperties(current)];
|
||||
}, []);
|
||||
}
|
||||
};
|
||||
const current = findProperties(new Schema(data)).shift();
|
||||
const defaultSelectedKeys = [current?.name];
|
||||
let parent = current?.parent;
|
||||
while(parent) {
|
||||
while (parent) {
|
||||
if (parent['x-component'] === 'Menu') {
|
||||
break;
|
||||
}
|
||||
@ -162,14 +160,17 @@ export function AdminLayout({ route }: any) {
|
||||
console.log('current?.title', current, current?.title, defaultSelectedKeys);
|
||||
|
||||
return (
|
||||
<SwithDesignableContextProvider>
|
||||
<CollectionContextProvider>
|
||||
{/* @ts-ignore */}
|
||||
<PageTitleContextProvider defaultPageTitle={current?.title}>
|
||||
<LayoutWithMenu defaultSelectedKeys={defaultSelectedKeys} current={current} schema={data} />
|
||||
</PageTitleContextProvider>
|
||||
</CollectionContextProvider>
|
||||
</SwithDesignableContextProvider>
|
||||
<DesignableSwitchProvider>
|
||||
<CollectionsProvider>
|
||||
<PageTitleProvider defaultPageTitle={current?.title}>
|
||||
<LayoutWithMenu
|
||||
defaultSelectedKeys={defaultSelectedKeys}
|
||||
current={current}
|
||||
schema={data}
|
||||
/>
|
||||
</PageTitleProvider>
|
||||
</CollectionsProvider>
|
||||
</DesignableSwitchProvider>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ import { DragAndDrop } from '../../schemas/drag-and-drop';
|
||||
import { TreeSelect } from '../../schemas/tree-select';
|
||||
import { Page } from '../../schemas/page';
|
||||
import { Chart } from '../../schemas/chart';
|
||||
import { useCollectionContext, useSwithDesignableContext } from '../../schemas';
|
||||
import { useDesignableSwitchContext } from '../../constate/DesignableSwitch';
|
||||
|
||||
export const BlockContext = createContext({ dragRef: null });
|
||||
|
||||
@ -193,7 +193,7 @@ export function useSchemaComponent(component: string) {
|
||||
}
|
||||
|
||||
export function useDesignable(path?: any) {
|
||||
const { designable } = useSwithDesignableContext();
|
||||
let { designable = true } = useDesignableSwitchContext();
|
||||
const { schema = new Schema({}), refresh } = useContext(DesignableContext);
|
||||
const schemaPath = path || useSchemaPath();
|
||||
const fieldSchema = useFieldSchema();
|
||||
@ -453,7 +453,7 @@ export interface SchemaRendererProps {
|
||||
}
|
||||
|
||||
export const SchemaRenderer = (props: SchemaRendererProps) => {
|
||||
const { designable } = useSwithDesignableContext();
|
||||
const { designable = true } = useDesignableSwitchContext();
|
||||
const [, refresh] = useState(uid());
|
||||
const form = useMemo(() => props.form || createForm(), []);
|
||||
const schema = useMemo(() => {
|
||||
|
44
packages/client/src/constate/Collections.ts
Normal file
44
packages/client/src/constate/Collections.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import { useRequest } from 'ahooks';
|
||||
import constate from 'constate';
|
||||
|
||||
const [CollectionsProvider, useCollectionsContext] = constate(() => {
|
||||
const result = useRequest('collections:findAll', {
|
||||
formatResult: (result) => result?.data,
|
||||
});
|
||||
return { ...result, collections: result.data || [] };
|
||||
});
|
||||
|
||||
export { CollectionsProvider, useCollectionsContext };
|
||||
|
||||
export interface CollectionProviderProps {
|
||||
collectionName?: string;
|
||||
}
|
||||
|
||||
const [CollectionProvider, useCollectionContext] = constate(
|
||||
(props: CollectionProviderProps) => {
|
||||
const { collectionName } = props;
|
||||
const { data = [], loading, refresh } = useCollectionsContext();
|
||||
let collection: any;
|
||||
let fields = [];
|
||||
if (collectionName) {
|
||||
collection = data.find((item) => item.name === collectionName);
|
||||
}
|
||||
if (collection) {
|
||||
fields = collection?.fields || [];
|
||||
}
|
||||
return {
|
||||
collection,
|
||||
fields,
|
||||
loading,
|
||||
refresh,
|
||||
getField(name: string) {
|
||||
if (!name) {
|
||||
return null;
|
||||
}
|
||||
return fields.find((item) => item.name === name);
|
||||
},
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
export { CollectionProvider, useCollectionContext };
|
15
packages/client/src/constate/DesignableSwitch.ts
Normal file
15
packages/client/src/constate/DesignableSwitch.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { useCookieState } from "ahooks";
|
||||
import constate from 'constate';
|
||||
|
||||
const [DesignableSwitchProvider, useDesignableSwitchContext] = constate(() => {
|
||||
const [active, setActive] = useCookieState('useCookieDesignable');
|
||||
|
||||
return {
|
||||
designable: active === 'true',
|
||||
setDesignable(value) {
|
||||
setActive(value ? 'true' : 'false');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export { DesignableSwitchProvider, useDesignableSwitchContext };
|
9
packages/client/src/constate/DisplayedMap.ts
Normal file
9
packages/client/src/constate/DisplayedMap.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { useMap } from 'ahooks';
|
||||
import constate from 'constate';
|
||||
|
||||
const [DisplayedMapProvider, useDisplayedMapContext] = constate(() => {
|
||||
const [map, { set, remove, get }] = useMap([]);
|
||||
return { map, set, remove, get, has: (key: any) => !!get(key) };
|
||||
});
|
||||
|
||||
export { DisplayedMapProvider, useDisplayedMapContext };
|
12
packages/client/src/constate/PageTitle.ts
Normal file
12
packages/client/src/constate/PageTitle.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import constate from 'constate';
|
||||
import { useState } from 'react';
|
||||
|
||||
export interface PageTitleProviderProps {
|
||||
defaultPageTitle?: string;
|
||||
}
|
||||
|
||||
const [PageTitleProvider, usePageTitleContext] = constate(({ defaultPageTitle }: PageTitleProviderProps) => {
|
||||
return useState(defaultPageTitle);
|
||||
});
|
||||
|
||||
export { PageTitleProvider, usePageTitleContext };
|
4
packages/client/src/constate/index.tsx
Normal file
4
packages/client/src/constate/index.tsx
Normal file
@ -0,0 +1,4 @@
|
||||
export * from './Collections';
|
||||
export * from './DesignableSwitch';
|
||||
export * from './DisplayedMap';
|
||||
export * from './PageTitle';
|
3
packages/client/src/context.ts
Normal file
3
packages/client/src/context.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import { createContext } from "react";
|
||||
|
||||
export const VisibleContext = createContext<any>(null);
|
@ -21,7 +21,7 @@ export interface ListOptions {
|
||||
|
||||
export class Resource {
|
||||
|
||||
protected options: ResourceOptions;
|
||||
public options: ResourceOptions;
|
||||
|
||||
constructor(options: string | ResourceOptions) {
|
||||
if (typeof options === 'string') {
|
||||
@ -45,6 +45,15 @@ export class Resource {
|
||||
return request(`${resourceName}:get/${resourceKey}`);
|
||||
}
|
||||
|
||||
create(values: any) {
|
||||
const { resourceName } = this.options;
|
||||
const url = `${resourceName}:create`;
|
||||
return request(url, {
|
||||
method: 'post',
|
||||
data: values,
|
||||
});
|
||||
}
|
||||
|
||||
save(values: any, options: SaveOptions = {}) {
|
||||
const resourceKey = options.resourceKey || this.options.resourceKey;
|
||||
const { resourceName } = this.options;
|
||||
@ -66,7 +75,7 @@ export class Resource {
|
||||
});
|
||||
}
|
||||
|
||||
static make(options: string | Resource | ResourceOptions) {
|
||||
static make(options: null | string | Resource | ResourceOptions): Resource | null {
|
||||
if (typeof options === 'string') {
|
||||
return new Resource({ resourceName: options });
|
||||
}
|
||||
@ -76,6 +85,7 @@ export class Resource {
|
||||
if (typeof options === 'object' && options.resourceName) {
|
||||
return new Resource(options);
|
||||
}
|
||||
throw 'resource 参数错误';
|
||||
console.warn('resource 初始化参数错误');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -281,7 +281,7 @@ const schema = {
|
||||
item1: {
|
||||
type: 'void',
|
||||
title: `操作1`,
|
||||
'x-designable-bar': 'Menu.DesignableBar',
|
||||
'x-designable-bar': 'Action.DesignableBar',
|
||||
'x-component': 'Menu.Action',
|
||||
properties: {
|
||||
modal1: {
|
||||
@ -291,7 +291,17 @@ const schema = {
|
||||
properties: {
|
||||
input: {
|
||||
type: 'string',
|
||||
title: '输入框',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Input',
|
||||
'x-designable-bar': 'Input.DesignableBar',
|
||||
},
|
||||
grid: {
|
||||
type: 'void',
|
||||
'x-component': 'Grid',
|
||||
'x-component-props': {
|
||||
addNewComponent: 'AddNew.FormItem',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -13,7 +13,7 @@ import {
|
||||
} from '@formily/react';
|
||||
import { Button, Dropdown, Menu, Popover, Space, Drawer, Modal } from 'antd';
|
||||
import { Link, useHistory, LinkProps } from 'react-router-dom';
|
||||
import { useDesignable, VisibleContext, useDefaultAction, useVisible } from '..';
|
||||
import { useDesignable, useDefaultAction } from '..';
|
||||
import './style.less';
|
||||
import { uid } from '@formily/shared';
|
||||
import cls from 'classnames';
|
||||
@ -21,18 +21,18 @@ import { MenuOutlined } from '@ant-design/icons';
|
||||
import { FormLayout } from '@formily/antd';
|
||||
import IconPicker from '../../components/icon-picker';
|
||||
import { useSchemaComponent } from '../../components/schema-renderer';
|
||||
import { VisibleContext } from '../../context';
|
||||
|
||||
export const Action: any = observer((props: any) => {
|
||||
const { useAction = useDefaultAction, icon, ...others } = props;
|
||||
const { run } = useAction();
|
||||
const field = useField();
|
||||
const { schema, DesignableBar } = useDesignable();
|
||||
const { visible, setVisible } = useVisible(field.address.entire);
|
||||
const [visible, setVisible] = useState(false);
|
||||
const child = Object.values(schema.properties || {}).shift();
|
||||
const isDropdownOrPopover =
|
||||
child &&
|
||||
['Action.Dropdown', 'Action.Popover'].includes(child['x-component']);
|
||||
// console.log({ DesignableBar, schema });
|
||||
return (
|
||||
<VisibleContext.Provider value={[visible, setVisible]}>
|
||||
{!isDropdownOrPopover && (
|
||||
@ -75,7 +75,6 @@ Action.Modal = observer((props: any) => {
|
||||
} = props;
|
||||
const { schema } = useDesignable();
|
||||
const [visible, setVisible] = useContext(VisibleContext);
|
||||
console.log('VisibleContext', visible);
|
||||
const form = useForm();
|
||||
const { run: runOk } = useOkAction();
|
||||
const { run: runCancel } = useCancelAction();
|
||||
@ -190,8 +189,13 @@ Action.Drawer = observer((props: any) => {
|
||||
Action.Dropdown = observer((props: any) => {
|
||||
const { buttonProps = {}, ...others } = props;
|
||||
const { schema } = useDesignable();
|
||||
const componentProps = schema.parent['x-component-props'] || {};
|
||||
const icon = buttonProps.icon || componentProps['icon'];
|
||||
let componentProps = {...buttonProps};
|
||||
let title = schema.title;
|
||||
if (schema.parent['x-component'] === 'Action') {
|
||||
title = schema.parent.title;
|
||||
componentProps = {...buttonProps, ...(schema.parent['x-component-props'] || {})}
|
||||
}
|
||||
const icon = componentProps['icon'];
|
||||
return (
|
||||
<Dropdown
|
||||
trigger={['click']}
|
||||
@ -207,7 +211,7 @@ Action.Dropdown = observer((props: any) => {
|
||||
{...componentProps}
|
||||
icon={<IconPicker type={icon} />}
|
||||
>
|
||||
{schema.title || schema.parent.title}
|
||||
{title}
|
||||
</Button>
|
||||
</Dropdown>
|
||||
);
|
||||
|
@ -52,23 +52,23 @@ import {
|
||||
createOrUpdateCollection,
|
||||
createSchema,
|
||||
removeSchema,
|
||||
request,
|
||||
useCollectionContext,
|
||||
useDesignable,
|
||||
useSchemaPath,
|
||||
} from '../';
|
||||
import { uid } from '@formily/shared';
|
||||
import { useRequest } from 'ahooks';
|
||||
import { getSchemaPath, SchemaField } from '../../components/schema-renderer';
|
||||
import { useResourceContext } from '../';
|
||||
import { cloneDeep } from 'lodash';
|
||||
import { options } from '../database-field/interfaces';
|
||||
import { useDisplayFieldsContext } from '../form';
|
||||
|
||||
import './style.less';
|
||||
import IconPicker from '../../components/icon-picker';
|
||||
import { barChartConfig, columnChartConfig } from './chart';
|
||||
import { isGridRowOrCol } from '../grid';
|
||||
import {
|
||||
useCollectionContext,
|
||||
useCollectionsContext,
|
||||
useDisplayedMapContext,
|
||||
} from '../../constate';
|
||||
|
||||
const generateGridBlock = (schema: ISchema) => {
|
||||
const name = schema.name || uid();
|
||||
@ -136,6 +136,10 @@ function generateCardItemSchema(component) {
|
||||
rowKey: 'id',
|
||||
dragSort: true,
|
||||
showIndex: true,
|
||||
refreshRequestOnChange: true,
|
||||
pagination: {
|
||||
pageSize: 10,
|
||||
},
|
||||
},
|
||||
properties: {
|
||||
[uid()]: {
|
||||
@ -192,20 +196,7 @@ function generateCardItemSchema(component) {
|
||||
},
|
||||
[uid()]: {
|
||||
type: 'void',
|
||||
'x-component': 'Table.ActionBar',
|
||||
'x-component-props': {
|
||||
align: 'bottom',
|
||||
},
|
||||
properties: {
|
||||
[uid()]: {
|
||||
type: 'void',
|
||||
'x-component': 'Table.Pagination',
|
||||
'x-component-props': {},
|
||||
},
|
||||
},
|
||||
},
|
||||
[uid()]: {
|
||||
type: 'void',
|
||||
title: '操作',
|
||||
'x-component': 'Table.Column',
|
||||
'x-component-props': {
|
||||
className: 'nb-table-operation',
|
||||
@ -286,7 +277,7 @@ function generateCardItemSchema(component) {
|
||||
title: '编辑数据',
|
||||
'x-decorator': 'Form',
|
||||
'x-decorator-props': {
|
||||
useValues: '{{ Table.useTableRow }}',
|
||||
useValues: '{{ Table.useTableRowRecord }}',
|
||||
},
|
||||
'x-component': 'Action.Modal',
|
||||
'x-component-props': {
|
||||
@ -406,15 +397,7 @@ AddNew.CardItem = observer((props: any) => {
|
||||
const { ghost, defaultAction } = props;
|
||||
const { schema, insertBefore, insertAfter, appendChild } = useDesignable();
|
||||
const path = useSchemaPath();
|
||||
// const {
|
||||
// data: collections = [],
|
||||
// loading,
|
||||
// run,
|
||||
// } = useRequest('collections:findAll', {
|
||||
// formatResult: (result) => result?.data,
|
||||
// });
|
||||
const { data: collections = [], loading, refresh } = useCollectionContext();
|
||||
console.log({ collections });
|
||||
const { collections = [], loading, refresh } = useCollectionsContext();
|
||||
return (
|
||||
<Dropdown
|
||||
trigger={['click']}
|
||||
@ -424,12 +407,11 @@ AddNew.CardItem = observer((props: any) => {
|
||||
onVisibleChange={(visible) => {
|
||||
console.log('onVisibleChange', visible);
|
||||
}}
|
||||
placement={'bottomCenter'}
|
||||
overlay={
|
||||
<Menu
|
||||
onClick={async (info) => {
|
||||
let data: ISchema;
|
||||
let resourceName = null;
|
||||
let collectionName = null;
|
||||
if (['addNewTable', 'addNewForm'].includes(info.key)) {
|
||||
const values = await FormDialog(`新建数据表`, () => {
|
||||
return (
|
||||
@ -448,12 +430,12 @@ AddNew.CardItem = observer((props: any) => {
|
||||
data = generateCardItemSchema(
|
||||
info.key === 'addNewTable' ? 'Table' : 'Form',
|
||||
);
|
||||
resourceName = values.name;
|
||||
collectionName = values.name;
|
||||
} else if (info.key.startsWith('collection.')) {
|
||||
const keys = info.key.split('.');
|
||||
const component = keys.pop();
|
||||
const tableName = keys.pop();
|
||||
resourceName = tableName;
|
||||
collectionName = tableName;
|
||||
data = generateCardItemSchema(component);
|
||||
console.log('info.keyPath', component, tableName);
|
||||
} else {
|
||||
@ -463,9 +445,10 @@ AddNew.CardItem = observer((props: any) => {
|
||||
if (schema['key']) {
|
||||
data['key'] = uid();
|
||||
}
|
||||
if (resourceName) {
|
||||
if (collectionName) {
|
||||
data['x-component-props'] = data['x-component-props'] || {};
|
||||
data['x-component-props']['resourceName'] = resourceName;
|
||||
data['x-component-props']['resource'] = collectionName;
|
||||
data['x-component-props']['collectionName'] = collectionName;
|
||||
}
|
||||
if (isGridBlock(schema)) {
|
||||
path.pop();
|
||||
@ -511,7 +494,7 @@ AddNew.CardItem = observer((props: any) => {
|
||||
title={view.title}
|
||||
>
|
||||
<Menu.ItemGroup key={`${view.key}-select`} title={'所属数据表'}>
|
||||
{collections.map((item) => (
|
||||
{collections?.map((item) => (
|
||||
<Menu.Item
|
||||
style={{ minWidth: 150 }}
|
||||
key={`collection.${item.name}.${view.key}`}
|
||||
@ -586,76 +569,9 @@ AddNew.CardItem = observer((props: any) => {
|
||||
{ghost ? (
|
||||
<PlusOutlined />
|
||||
) : (
|
||||
<Button block type={'dashed'} icon={<PlusOutlined />}></Button>
|
||||
)}
|
||||
</Dropdown>
|
||||
);
|
||||
});
|
||||
|
||||
AddNew.BlockItem = observer((props: any) => {
|
||||
const { ghost, defaultAction } = props;
|
||||
const { schema, insertBefore, insertAfter } = useDesignable();
|
||||
const path = useSchemaPath();
|
||||
return (
|
||||
<Dropdown
|
||||
overlayStyle={{
|
||||
minWidth: 200,
|
||||
}}
|
||||
placement={'bottomCenter'}
|
||||
overlay={
|
||||
<Menu>
|
||||
<Menu.SubMenu title={'新建表格'}>
|
||||
<Menu.ItemGroup title={'选择数据表'}>
|
||||
<Menu.Item>数据表1</Menu.Item>
|
||||
</Menu.ItemGroup>
|
||||
<Menu.Divider></Menu.Divider>
|
||||
<Menu.Item>新增数据表</Menu.Item>
|
||||
</Menu.SubMenu>
|
||||
<Menu.SubMenu title={'新建表单'}>
|
||||
<Menu.ItemGroup title={'选择数据表'}>
|
||||
<Menu.Item>数据表1</Menu.Item>
|
||||
</Menu.ItemGroup>
|
||||
<Menu.Divider></Menu.Divider>
|
||||
<Menu.Item>新增数据表</Menu.Item>
|
||||
</Menu.SubMenu>
|
||||
<Menu.Item
|
||||
onClick={async () => {
|
||||
let data: ISchema = {
|
||||
type: 'void',
|
||||
title: uid(),
|
||||
'x-designable-bar': 'BlockItem.DesignableBar',
|
||||
'x-decorator': 'CardItem',
|
||||
'x-component': 'Markdown.Void',
|
||||
};
|
||||
if (schema['key']) {
|
||||
data['key'] = uid();
|
||||
}
|
||||
console.log('isGridBlock(schema)', isGridBlock(schema));
|
||||
if (isGridBlock(schema)) {
|
||||
path.pop();
|
||||
path.pop();
|
||||
data = generateGridBlock(data);
|
||||
}
|
||||
if (data) {
|
||||
let s;
|
||||
if (defaultAction === 'insertAfter') {
|
||||
s = insertAfter(data, [...path]);
|
||||
} else {
|
||||
s = insertBefore(data, [...path]);
|
||||
}
|
||||
await createSchema(s);
|
||||
}
|
||||
}}
|
||||
>
|
||||
新建 Markdown
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
}
|
||||
>
|
||||
{ghost ? (
|
||||
<PlusOutlined />
|
||||
) : (
|
||||
<Button block type={'dashed'} icon={<PlusOutlined />}></Button>
|
||||
<Button type={'dashed'} icon={<PlusOutlined />}>
|
||||
新增区块
|
||||
</Button>
|
||||
)}
|
||||
</Dropdown>
|
||||
);
|
||||
@ -692,15 +608,9 @@ AddNew.FormItem = observer((props: any) => {
|
||||
const { schema, insertBefore, insertAfter, appendChild, deepRemove } =
|
||||
useDesignable();
|
||||
const path = useSchemaPath();
|
||||
const { resource = {}, refresh } = useResourceContext();
|
||||
const { collection, fields, refresh } = useCollectionContext();
|
||||
const [visible, setVisible] = useState(false);
|
||||
const {
|
||||
displayFields,
|
||||
hasDisplayField,
|
||||
getDisplayField,
|
||||
removeDisplayField,
|
||||
} = useDisplayFieldsContext();
|
||||
console.log({ displayFields });
|
||||
const displayed = useDisplayedMapContext();
|
||||
return (
|
||||
<Dropdown
|
||||
trigger={['click']}
|
||||
@ -709,18 +619,17 @@ AddNew.FormItem = observer((props: any) => {
|
||||
overlayStyle={{
|
||||
minWidth: 200,
|
||||
}}
|
||||
placement={'bottomCenter'}
|
||||
overlay={
|
||||
<Menu>
|
||||
<Menu.ItemGroup className={'display-fields'} title={`要展示的字段`}>
|
||||
{resource?.fields?.map((field) => (
|
||||
{fields?.map((field) => (
|
||||
<Menu.Item key={field.key}>
|
||||
<SwitchField
|
||||
field={field}
|
||||
checked={hasDisplayField(field.name)}
|
||||
checked={displayed.has(field.name)}
|
||||
onChange={async (checked) => {
|
||||
if (!checked) {
|
||||
const s: any = getDisplayField(field.name);
|
||||
const s: any = displayed.get(field.name);
|
||||
const p = getSchemaPath(s);
|
||||
const removed = deepRemove(p);
|
||||
if (!removed) {
|
||||
@ -728,7 +637,7 @@ AddNew.FormItem = observer((props: any) => {
|
||||
return;
|
||||
}
|
||||
const last = removed.pop();
|
||||
removeDisplayField(field.name);
|
||||
displayed.remove(field.name);
|
||||
if (isGridRowOrCol(last)) {
|
||||
await removeSchema(last);
|
||||
}
|
||||
@ -797,7 +706,7 @@ AddNew.FormItem = observer((props: any) => {
|
||||
name: `f_${uid()}`,
|
||||
},
|
||||
});
|
||||
await createCollectionField(resource.name, values);
|
||||
await createCollectionField(collection?.name, values);
|
||||
await refresh();
|
||||
let data: ISchema = cloneDeep(values.uiSchema);
|
||||
data['name'] = values.name;
|
||||
@ -834,7 +743,6 @@ AddNew.FormItem = observer((props: any) => {
|
||||
<Menu.Item
|
||||
onClick={async () => {
|
||||
let data: ISchema = {
|
||||
key: uid(),
|
||||
type: 'void',
|
||||
default: '这是一段演示文字,**支持使用 Markdown 语法**',
|
||||
'x-designable-bar': 'Markdown.Void.DesignableBar',
|
||||
@ -842,6 +750,9 @@ AddNew.FormItem = observer((props: any) => {
|
||||
'x-read-pretty': true,
|
||||
'x-component': 'Markdown.Void',
|
||||
};
|
||||
if (schema['key']) {
|
||||
data['key'] = uid();
|
||||
}
|
||||
if (isGridBlock(schema)) {
|
||||
path.pop();
|
||||
path.pop();
|
||||
@ -858,6 +769,7 @@ AddNew.FormItem = observer((props: any) => {
|
||||
} else {
|
||||
s = insertBefore(data, [...path]);
|
||||
}
|
||||
console.log('ISchema', schema, data, path);
|
||||
await createSchema(s);
|
||||
}
|
||||
setVisible(false);
|
||||
@ -871,7 +783,9 @@ AddNew.FormItem = observer((props: any) => {
|
||||
{ghost ? (
|
||||
<PlusOutlined />
|
||||
) : (
|
||||
<Button block type={'dashed'} icon={<PlusOutlined />}></Button>
|
||||
<Button type={'dashed'} icon={<PlusOutlined />}>
|
||||
配置字段
|
||||
</Button>
|
||||
)}
|
||||
</Dropdown>
|
||||
);
|
||||
@ -881,10 +795,8 @@ AddNew.PaneItem = observer((props: any) => {
|
||||
const { ghost, defaultAction } = props;
|
||||
const { schema, insertBefore, insertAfter, appendChild } = useDesignable();
|
||||
const path = useSchemaPath();
|
||||
const { resource = {}, refresh } = useResourceContext();
|
||||
const [visible, setVisible] = useState(false);
|
||||
const { displayFields } = useDisplayFieldsContext();
|
||||
console.log({ displayFields });
|
||||
|
||||
return (
|
||||
<Dropdown
|
||||
trigger={['click']}
|
||||
@ -893,7 +805,7 @@ AddNew.PaneItem = observer((props: any) => {
|
||||
overlayStyle={{
|
||||
minWidth: 200,
|
||||
}}
|
||||
placement={'bottomCenter'}
|
||||
// placement={'bottomCenter'}
|
||||
overlay={
|
||||
<Menu>
|
||||
<Menu.ItemGroup title={'数据区块'}>
|
||||
@ -907,7 +819,7 @@ AddNew.PaneItem = observer((props: any) => {
|
||||
'x-component': 'Form',
|
||||
'x-read-pretty': true,
|
||||
'x-component-props': {
|
||||
useValues: '{{ Table.useTableRow }}',
|
||||
useValues: '{{ Table.useTableRowRecord }}',
|
||||
},
|
||||
'x-designable-bar': 'Form.DesignableBar',
|
||||
properties: {
|
||||
@ -953,7 +865,7 @@ AddNew.PaneItem = observer((props: any) => {
|
||||
'x-decorator': 'CardItem',
|
||||
'x-component': 'Form',
|
||||
'x-component-props': {
|
||||
useValues: '{{ Table.useTableRow }}',
|
||||
useValues: '{{ Table.useTableRowRecord }}',
|
||||
showDefaultButtons: true,
|
||||
},
|
||||
'x-designable-bar': 'Form.DesignableBar',
|
||||
@ -1045,7 +957,9 @@ AddNew.PaneItem = observer((props: any) => {
|
||||
{ghost ? (
|
||||
<PlusOutlined />
|
||||
) : (
|
||||
<Button block type={'dashed'} icon={<PlusOutlined />}></Button>
|
||||
<Button block type={'dashed'} icon={<PlusOutlined />}>
|
||||
新增区块
|
||||
</Button>
|
||||
)}
|
||||
</Dropdown>
|
||||
);
|
||||
|
@ -39,11 +39,8 @@ import Modal from 'antd/lib/modal/Modal';
|
||||
import { clone, cloneDeep, get } from 'lodash';
|
||||
import { useEffect } from 'react';
|
||||
import { useRequest } from 'ahooks';
|
||||
import {
|
||||
createOrUpdateCollection,
|
||||
deleteCollection,
|
||||
useCollectionContext,
|
||||
} from '..';
|
||||
import { createOrUpdateCollection, deleteCollection } from '..';
|
||||
import { useCollectionsContext } from '../../constate/Collections';
|
||||
|
||||
export const DatabaseCollection = observer((props) => {
|
||||
const field = useField<Formily.Core.Models.ArrayField>();
|
||||
@ -53,21 +50,12 @@ export const DatabaseCollection = observer((props) => {
|
||||
const [activeIndex, setActiveIndex] = useState(0);
|
||||
const form = useForm();
|
||||
const [newValue, setNewValue] = useState('');
|
||||
const { loading, refresh, data } = useCollectionContext();
|
||||
const { loading, refresh, collections = [] } = useCollectionsContext();
|
||||
|
||||
useEffect(() => {
|
||||
field.setValue(data);
|
||||
console.log('onSuccess', data);
|
||||
}, [data]);
|
||||
|
||||
// const { run, loading } = useRequest('collections:findAll', {
|
||||
// formatResult: (result) => result?.data,
|
||||
// onSuccess(data) {
|
||||
// // field.setValue(data);
|
||||
// // console.log('onSuccess', data);
|
||||
// },
|
||||
// manual: true,
|
||||
// });
|
||||
field.setValue(collections);
|
||||
console.log('onSuccess', collections);
|
||||
}, [collections]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
@ -17,7 +17,6 @@ import {
|
||||
SchemaField,
|
||||
useDesignable,
|
||||
removeSchema,
|
||||
useCollectionContext,
|
||||
} from '../';
|
||||
import get from 'lodash/get';
|
||||
import { Button, Dropdown, Menu, Space } from 'antd';
|
||||
|
@ -17,7 +17,6 @@ import {
|
||||
SchemaField,
|
||||
useDesignable,
|
||||
removeSchema,
|
||||
useCollectionContext,
|
||||
updateSchema,
|
||||
} from '../';
|
||||
import get from 'lodash/get';
|
||||
@ -33,7 +32,8 @@ import constate from 'constate';
|
||||
import { useEffect } from 'react';
|
||||
import { uid } from '@formily/shared';
|
||||
import { getSchemaPath } from '../../components/schema-renderer';
|
||||
import { FormFieldUIDContext, useDisplayFieldsContext } from '.';
|
||||
import { RandomNameContext } from '.';
|
||||
import { useDisplayedMapContext } from '../../constate';
|
||||
|
||||
export const FieldDesignableBar = observer((props) => {
|
||||
const field = useField();
|
||||
@ -41,8 +41,8 @@ export const FieldDesignableBar = observer((props) => {
|
||||
const { designable, schema, deepRemove } = useDesignable();
|
||||
const [visible, setVisible] = useState(false);
|
||||
const { dragRef } = useContext(DraggableBlockContext);
|
||||
const fieldUid = useContext(FormFieldUIDContext);
|
||||
const { removeDisplayField } = useDisplayFieldsContext();
|
||||
const randomName = useContext(RandomNameContext);
|
||||
const displayed = useDisplayedMapContext();
|
||||
const fieldName = schema['x-component-props']?.['fieldName'];
|
||||
if (!designable) {
|
||||
return null;
|
||||
@ -71,13 +71,13 @@ export const FieldDesignableBar = observer((props) => {
|
||||
onClick={async () => {
|
||||
const title = uid();
|
||||
field
|
||||
.query(field.address.concat(fieldUid, fieldName))
|
||||
.query(field.address.concat(randomName, fieldName))
|
||||
.take((f) => {
|
||||
f.title = title;
|
||||
});
|
||||
console.log(
|
||||
'fieldfieldfieldfieldfield',
|
||||
field.address.concat(fieldUid, fieldName).entire,
|
||||
field.address.concat(randomName, fieldName).entire,
|
||||
schema,
|
||||
);
|
||||
schema['title'] = title;
|
||||
@ -98,7 +98,7 @@ export const FieldDesignableBar = observer((props) => {
|
||||
schema['x-component-props']?.['fieldName'];
|
||||
console.log({ schema, removed, fieldName });
|
||||
const last = removed.pop();
|
||||
removeDisplayField(fieldName);
|
||||
displayed.remove(fieldName);
|
||||
if (isGridRowOrCol(last)) {
|
||||
await removeSchema(last);
|
||||
}
|
||||
|
@ -12,15 +12,7 @@ import {
|
||||
useForm,
|
||||
RecursionField,
|
||||
} from '@formily/react';
|
||||
import {
|
||||
useSchemaPath,
|
||||
SchemaField,
|
||||
useDesignable,
|
||||
removeSchema,
|
||||
useCollectionContext,
|
||||
useResourceContext,
|
||||
ResourceContextProvider,
|
||||
} from '../';
|
||||
import { useSchemaPath, SchemaField, useDesignable, removeSchema } from '../';
|
||||
import get from 'lodash/get';
|
||||
import { Button, Dropdown, Menu, message, Space } from 'antd';
|
||||
import { MenuOutlined, DragOutlined } from '@ant-design/icons';
|
||||
@ -39,48 +31,30 @@ import { FieldDesignableBar } from './Field.DesignableBar';
|
||||
import { createContext } from 'react';
|
||||
import { BlockItem } from '../block-item';
|
||||
import { Resource } from '../../resource';
|
||||
import { useMap } from 'ahooks';
|
||||
|
||||
const [DisplayFieldsContextProvider, useDisplayFieldsContext] = constate(() => {
|
||||
const [displayFields, { set, remove, get }] = useMap([]);
|
||||
|
||||
return {
|
||||
displayFields,
|
||||
hasDisplayField(fieldName) {
|
||||
return !!get(fieldName);
|
||||
},
|
||||
addDisplayField(fieldName, schema) {
|
||||
set(fieldName, schema);
|
||||
},
|
||||
getDisplayField(fieldName) {
|
||||
return get(fieldName);
|
||||
},
|
||||
removeDisplayField(fieldName) {
|
||||
remove(fieldName);
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
export { DisplayFieldsContextProvider, useDisplayFieldsContext };
|
||||
import {
|
||||
CollectionProvider,
|
||||
useCollectionContext,
|
||||
DisplayedMapProvider,
|
||||
useDisplayedMapContext,
|
||||
} from '../../constate';
|
||||
|
||||
export const Form: any = observer((props: any) => {
|
||||
const {
|
||||
useValues = () => ({}),
|
||||
showDefaultButtons = false,
|
||||
resourceName,
|
||||
...others
|
||||
} = props;
|
||||
const { schema } = useDesignable();
|
||||
const initialValues = useValues();
|
||||
const form = useMemo(() => {
|
||||
console.log('Form.useMemo', initialValues);
|
||||
return createForm({
|
||||
initialValues,
|
||||
return createForm({
|
||||
initialValues,
|
||||
readPretty: schema['x-read-pretty'],
|
||||
});
|
||||
}, []);
|
||||
const path = useSchemaPath();
|
||||
const scope = useContext(SchemaExpressionScopeContext);
|
||||
const { collection } = useCollectionContext();
|
||||
const content = (
|
||||
<FormProvider form={form}>
|
||||
{schema['x-decorator'] === 'Form' ? (
|
||||
@ -115,7 +89,7 @@ export const Form: any = observer((props: any) => {
|
||||
onClick={async () => {
|
||||
const values = await form.submit();
|
||||
console.log({ values });
|
||||
await Resource.make(resourceName).save(values);
|
||||
await Resource.make(props.resource).save(values);
|
||||
message.success('保存成功');
|
||||
await form.reset();
|
||||
}}
|
||||
@ -134,49 +108,47 @@ export const Form: any = observer((props: any) => {
|
||||
)}
|
||||
</FormProvider>
|
||||
);
|
||||
return resourceName ? (
|
||||
// @ts-ignore
|
||||
<ResourceContextProvider resourceName={resourceName}>
|
||||
<DisplayFieldsContextProvider>{content}</DisplayFieldsContextProvider>
|
||||
</ResourceContextProvider>
|
||||
) : (
|
||||
<DisplayFieldsContextProvider>{content}</DisplayFieldsContextProvider>
|
||||
return (
|
||||
<CollectionProvider
|
||||
collectionName={props.collectionName || collection?.name}
|
||||
>
|
||||
<DisplayedMapProvider>{content}</DisplayedMapProvider>
|
||||
</CollectionProvider>
|
||||
);
|
||||
});
|
||||
|
||||
export const FormFieldUIDContext = createContext(null);
|
||||
export const RandomNameContext = createContext(null);
|
||||
|
||||
Form.Field = observer((props: any) => {
|
||||
const { fieldName } = props;
|
||||
const { schema } = useDesignable();
|
||||
const path = getSchemaPath(schema);
|
||||
console.log('getSchemaPath', path);
|
||||
const { addDisplayField } = useDisplayFieldsContext();
|
||||
const { resource = {} } = useResourceContext();
|
||||
const { getField } = useCollectionContext();
|
||||
const displayed = useDisplayedMapContext();
|
||||
useEffect(() => {
|
||||
if (fieldName) {
|
||||
addDisplayField && addDisplayField(fieldName, schema);
|
||||
displayed.set(fieldName, schema);
|
||||
}
|
||||
}, [fieldName, schema]);
|
||||
if (!fieldName) {
|
||||
return null;
|
||||
}
|
||||
const field = resource?.fields?.find((item) => item.name === fieldName);
|
||||
if (!field) {
|
||||
const collectionField = getField(fieldName);
|
||||
if (!collectionField) {
|
||||
return null;
|
||||
}
|
||||
const name = useContext(FormFieldUIDContext);
|
||||
const title = schema['title'] || field.uiSchema['title'];
|
||||
const randomName = useContext(RandomNameContext);
|
||||
const title = schema['title'] || collectionField?.uiSchema?.title;
|
||||
return (
|
||||
<RecursionField
|
||||
name={name}
|
||||
name={randomName}
|
||||
schema={
|
||||
new Schema({
|
||||
'x-path': path,
|
||||
type: 'void',
|
||||
properties: {
|
||||
[field.name]: {
|
||||
...field.uiSchema,
|
||||
[collectionField.name]: {
|
||||
...collectionField.uiSchema,
|
||||
title,
|
||||
'x-decorator': 'FormilyFormItem',
|
||||
},
|
||||
@ -188,11 +160,10 @@ Form.Field = observer((props: any) => {
|
||||
});
|
||||
|
||||
Form.Field.Item = observer((props) => {
|
||||
const name = uid();
|
||||
return (
|
||||
<FormFieldUIDContext.Provider value={name}>
|
||||
<RandomNameContext.Provider value={uid()}>
|
||||
<BlockItem>{props.children}</BlockItem>
|
||||
</FormFieldUIDContext.Provider>
|
||||
</RandomNameContext.Provider>
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -10,51 +10,6 @@ import { useCookieState, useRequest } from 'ahooks';
|
||||
|
||||
export * from '../components/schema-renderer';
|
||||
|
||||
export function mapReadPretty(component: any, readPrettyProps?: any) {
|
||||
return function (target) {
|
||||
return observer(
|
||||
(props) => {
|
||||
const field = useField();
|
||||
// if (!isVoidField(field) && field?.pattern === 'readPretty') {
|
||||
if (field?.pattern === 'readPretty') {
|
||||
return React.createElement(component, {
|
||||
...readPrettyProps,
|
||||
...props,
|
||||
});
|
||||
}
|
||||
return React.createElement(target, props);
|
||||
},
|
||||
{
|
||||
forwardRef: true,
|
||||
},
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export const VisibleContext = createContext(null);
|
||||
|
||||
export function useVisible(name, defaultValue = false) {
|
||||
const [visible, setVisible] = useState(defaultValue);
|
||||
return { visible, setVisible };
|
||||
// const [visible, setVisible] = useCookieState(`${name}-visible`, {
|
||||
// defaultValue: defaultValue ? 'true' : null,
|
||||
// });
|
||||
// return {
|
||||
// visible: visible === 'true' ? true : false,
|
||||
// setVisible: (value) => {
|
||||
// setVisible(value ? 'true' : null);
|
||||
// },
|
||||
// }
|
||||
}
|
||||
|
||||
export const DesignableBarContext = createContext(null);
|
||||
|
||||
const [PageTitleContextProvider, usePageTitleContext] = constate(({ defaultPageTitle }) => {
|
||||
return useState(defaultPageTitle);
|
||||
});
|
||||
|
||||
export { PageTitleContextProvider, usePageTitleContext };
|
||||
|
||||
export function useDefaultAction() {
|
||||
return {
|
||||
async run() {},
|
||||
@ -93,6 +48,9 @@ export async function deleteCollection(name) {
|
||||
}
|
||||
|
||||
export async function createSchema(schema: ISchema) {
|
||||
if (!schema) {
|
||||
return;
|
||||
}
|
||||
if (!schema['key']) {
|
||||
return;
|
||||
}
|
||||
@ -125,36 +83,3 @@ export async function removeSchema(schema: ISchema) {
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const [CollectionContextProvider, useCollectionContext] = constate(() => {
|
||||
return useRequest('collections:findAll', {
|
||||
formatResult: (result) => result?.data,
|
||||
});
|
||||
});
|
||||
|
||||
export { CollectionContextProvider, useCollectionContext };
|
||||
|
||||
const [SwithDesignableContextProvider, useSwithDesignableContext] = constate(() => {
|
||||
const [active, setActive] = useCookieState('useCookieDesignable');
|
||||
|
||||
return {
|
||||
designable: active === 'true',
|
||||
setDesignable(value) {
|
||||
setActive(value ? 'true' : 'false');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export { SwithDesignableContextProvider, useSwithDesignableContext };
|
||||
|
||||
const [ResourceContextProvider, useResourceContext] = constate(
|
||||
({ resourceName }) => {
|
||||
// const schema = useFieldSchema();
|
||||
const { data: collections = [], loading, refresh } = useCollectionContext();
|
||||
const resource = collections.find((item) => item.name === resourceName);
|
||||
console.log({ resource });
|
||||
return { resource, refresh };
|
||||
},
|
||||
);
|
||||
|
||||
export { ResourceContextProvider, useResourceContext };
|
||||
|
@ -46,7 +46,7 @@ Input.URL = connect(AntdInput, mapReadPretty(Display.URL))
|
||||
Input.DesignableBar = observer((props) => {
|
||||
const field = useField();
|
||||
const fieldSchema = useFieldSchema();
|
||||
const { root, currentSchema, schema, refresh, deepRemove } = useDesignable();
|
||||
const { root, currentSchema, schema, refresh, deepRemove, remove } = useDesignable();
|
||||
const [visible, setVisible] = useState(false);
|
||||
const { dragRef } = useContext(DraggableBlockContext);
|
||||
return (
|
||||
@ -71,6 +71,10 @@ Input.DesignableBar = observer((props) => {
|
||||
<Menu.Item
|
||||
key={'update'}
|
||||
onClick={() => {
|
||||
const title = uid();
|
||||
schema['title'] = title;
|
||||
field.title = title;
|
||||
refresh();
|
||||
console.log({ root, currentSchema, schema, fieldSchema }, getSchemaPath(fieldSchema));
|
||||
}}
|
||||
>
|
||||
@ -80,12 +84,13 @@ Input.DesignableBar = observer((props) => {
|
||||
<Menu.Item
|
||||
key={'delete'}
|
||||
onClick={async () => {
|
||||
const removed = deepRemove();
|
||||
// console.log({ removed })
|
||||
const last = removed.pop();
|
||||
if (isGridRowOrCol(last)) {
|
||||
await removeSchema(last);
|
||||
}
|
||||
remove();
|
||||
// const removed = deepRemove();
|
||||
// // console.log({ removed })
|
||||
// const last = removed.pop();
|
||||
// if (isGridRowOrCol(last)) {
|
||||
// await removeSchema(last);
|
||||
// }
|
||||
}}
|
||||
>
|
||||
删除当前区块
|
||||
|
@ -50,24 +50,16 @@ import {
|
||||
DragOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import { IconPicker } from '../../components/icon-picker';
|
||||
import {
|
||||
createSchema,
|
||||
removeSchema,
|
||||
updateSchema,
|
||||
useDefaultAction,
|
||||
useVisible,
|
||||
VisibleContext,
|
||||
} from '..';
|
||||
import { createSchema, removeSchema, updateSchema, useDefaultAction } from '..';
|
||||
import { useMount } from 'ahooks';
|
||||
import './style.less';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { findPropertyByPath, getSchemaPath, useSchemaPath } from '../../';
|
||||
import { request } from '../';
|
||||
import { generateDefaultSchema } from './defaultSchemas';
|
||||
import _, { cloneDeep, get, isNull } from 'lodash';
|
||||
import { FormDialog, FormItem, FormLayout, Input } from '@formily/antd';
|
||||
import deepmerge from 'deepmerge';
|
||||
import { onFieldChange } from '@formily/core';
|
||||
import { VisibleContext } from '../../context';
|
||||
|
||||
export const MenuModeContext = createContext(null);
|
||||
|
||||
@ -101,11 +93,19 @@ const SideMenu = (props: any) => {
|
||||
};
|
||||
|
||||
export const Menu: any = observer((props: any) => {
|
||||
const { mode, onSelect, sideMenuRef, defaultSelectedKeys = [], ...others } = props;
|
||||
const {
|
||||
mode,
|
||||
onSelect,
|
||||
sideMenuRef,
|
||||
defaultSelectedKeys = [],
|
||||
...others
|
||||
} = props;
|
||||
const { designable, schema } = useDesignable();
|
||||
const fieldSchema = useFieldSchema();
|
||||
console.log('Menu.schema', schema, fieldSchema);
|
||||
const [selectedKey, setSelectedKey] = useState(defaultSelectedKeys[0]||null);
|
||||
const [selectedKey, setSelectedKey] = useState(
|
||||
defaultSelectedKeys[0] || null,
|
||||
);
|
||||
const ref = useRef();
|
||||
const path = useSchemaPath();
|
||||
const child = schema.properties && schema.properties[selectedKey];
|
||||
@ -170,7 +170,7 @@ export const Menu: any = observer((props: any) => {
|
||||
onSelect &&
|
||||
onSelect({ ...info, keyPath, schema: selectedSchema });
|
||||
}}
|
||||
defaultSelectedKeys={defaultSelectedKeys||[]}
|
||||
defaultSelectedKeys={defaultSelectedKeys || []}
|
||||
selectedKey={selectedKey}
|
||||
sideMenuRef={sideMenuRef}
|
||||
/>
|
||||
@ -237,7 +237,7 @@ Menu.Action = observer((props: any) => {
|
||||
const { icon, useAction = useDefaultAction, ...others } = props;
|
||||
const { schema, DesignableBar } = useDesignable();
|
||||
const field = useField();
|
||||
const { visible, setVisible } = useVisible(field.address.entire);
|
||||
const [visible, setVisible] = useState(false);
|
||||
const { run } = useAction();
|
||||
return (
|
||||
<VisibleContext.Provider value={[visible, setVisible]}>
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { PageHeader as AntdPageHeader } from 'antd';
|
||||
import { observer } from '@formily/react';
|
||||
import { usePageTitleContext } from '..';
|
||||
import { usePageTitleContext } from '../../constate/PageTitle';
|
||||
|
||||
export const Page = observer((props) => {
|
||||
const { children, ...others } = props;
|
||||
|
@ -1,43 +0,0 @@
|
||||
import React, { useState } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { useField, observer, RecursionField, Schema } from '@formily/react';
|
||||
import { Dropdown, Menu } from 'antd';
|
||||
import {
|
||||
MenuOutlined,
|
||||
ArrowUpOutlined,
|
||||
ArrowDownOutlined,
|
||||
DeleteOutlined,
|
||||
} from '@ant-design/icons';
|
||||
|
||||
export const ColumnDesignableBar = (props) => {
|
||||
const [active, setActive] = useState(false);
|
||||
return (
|
||||
<>
|
||||
<Menu.Item
|
||||
onClick={() => {
|
||||
setActive(false);
|
||||
}}
|
||||
icon={<ArrowUpOutlined />}
|
||||
>
|
||||
在上方插入区块
|
||||
</Menu.Item>
|
||||
<Menu.Item
|
||||
onClick={() => {
|
||||
setActive(false);
|
||||
}}
|
||||
icon={<ArrowDownOutlined />}
|
||||
>
|
||||
在下方插入区块
|
||||
</Menu.Item>
|
||||
<Menu.Divider />
|
||||
<Menu.Item
|
||||
onClick={() => {
|
||||
setActive(false);
|
||||
}}
|
||||
icon={<DeleteOutlined />}
|
||||
>
|
||||
删除区块
|
||||
</Menu.Item>
|
||||
</>
|
||||
);
|
||||
};
|
@ -1,43 +0,0 @@
|
||||
import React, { useState } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { useField, observer, RecursionField, Schema } from '@formily/react';
|
||||
import { Dropdown, Menu } from 'antd';
|
||||
import {
|
||||
MenuOutlined,
|
||||
ArrowUpOutlined,
|
||||
ArrowDownOutlined,
|
||||
DeleteOutlined,
|
||||
} from '@ant-design/icons';
|
||||
|
||||
export const DesignableBar = (props) => {
|
||||
const [active, setActive] = useState(false);
|
||||
return (
|
||||
<>
|
||||
<Menu.Item
|
||||
onClick={() => {
|
||||
setActive(false);
|
||||
}}
|
||||
icon={<ArrowUpOutlined />}
|
||||
>
|
||||
在上方插入区块
|
||||
</Menu.Item>
|
||||
<Menu.Item
|
||||
onClick={() => {
|
||||
setActive(false);
|
||||
}}
|
||||
icon={<ArrowDownOutlined />}
|
||||
>
|
||||
在下方插入区块
|
||||
</Menu.Item>
|
||||
<Menu.Divider />
|
||||
<Menu.Item
|
||||
onClick={() => {
|
||||
setActive(false);
|
||||
}}
|
||||
icon={<DeleteOutlined />}
|
||||
>
|
||||
删除区块
|
||||
</Menu.Item>
|
||||
</>
|
||||
);
|
||||
};
|
@ -1,386 +0,0 @@
|
||||
import React from 'react';
|
||||
import { SchemaRenderer } from '../..';
|
||||
import { Table, useTableCreateAction } from '../';
|
||||
import { uid } from '@formily/shared';
|
||||
import { createForm } from '@formily/core';
|
||||
import { ISchema, observer } from '@formily/react';
|
||||
|
||||
function useAction() {
|
||||
return {
|
||||
async run() {
|
||||
alert('自定义');
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const schema: ISchema = {
|
||||
name: `table_${uid()}`,
|
||||
type: 'array',
|
||||
'x-component': 'Table',
|
||||
default: [
|
||||
{ key: uid(), field1: uid(), field2: uid() },
|
||||
{ key: uid(), field1: uid(), field2: uid() },
|
||||
{ key: uid(), field1: uid(), field2: uid() },
|
||||
{ key: uid(), field1: uid(), field2: uid() },
|
||||
{ key: uid(), field1: uid(), field2: uid() },
|
||||
{ key: uid(), field1: uid(), field2: uid() },
|
||||
{ key: uid(), field1: uid(), field2: uid() },
|
||||
{ key: uid(), field1: uid(), field2: uid() },
|
||||
{ key: uid(), field1: uid(), field2: uid() },
|
||||
{ key: uid(), field1: uid(), field2: uid() },
|
||||
{ key: uid(), field1: uid(), field2: uid() },
|
||||
{ key: uid(), field1: uid(), field2: uid() },
|
||||
],
|
||||
'x-component-props': {
|
||||
rowKey: 'key',
|
||||
dragSort: 'sort',
|
||||
showIndex: true,
|
||||
defaultFilter: {},
|
||||
defaultSort: [],
|
||||
pagination: {
|
||||
defaultPageSize: 50,
|
||||
},
|
||||
},
|
||||
properties: {
|
||||
[`action_bar_${uid()}`]: {
|
||||
type: 'void',
|
||||
'x-component': 'Table.ActionBar',
|
||||
'x-designable-bar': 'Table.ActionBar.DesignableBar',
|
||||
properties: {
|
||||
action1: {
|
||||
type: 'void',
|
||||
title: '筛选',
|
||||
'x-component': 'Action',
|
||||
'x-designable-bar': 'Table.Filter.DesignableBar',
|
||||
properties: {
|
||||
popover1: {
|
||||
type: 'void',
|
||||
title: '弹窗标题',
|
||||
'x-decorator': 'Form',
|
||||
'x-component': 'Action.Popover',
|
||||
'x-component-props': {},
|
||||
properties: {
|
||||
filter: {
|
||||
name: 'filter',
|
||||
type: 'object',
|
||||
'x-component': 'Filter',
|
||||
properties: {
|
||||
column1: {
|
||||
type: 'void',
|
||||
title: '字段1',
|
||||
'x-component': 'Filter.Column',
|
||||
'x-component-props': {
|
||||
operations: [
|
||||
{ label: '等于', value: 'eq' },
|
||||
{ label: '不等于', value: 'ne' },
|
||||
],
|
||||
},
|
||||
properties: {
|
||||
field1: {
|
||||
type: 'string',
|
||||
'x-component': 'Input',
|
||||
},
|
||||
},
|
||||
},
|
||||
column2: {
|
||||
type: 'void',
|
||||
title: '字段2',
|
||||
'x-component': 'Filter.Column',
|
||||
'x-component-props': {
|
||||
operations: [
|
||||
{ label: '大于', value: 'gt' },
|
||||
{ label: '小于', value: 'lt' },
|
||||
{ label: '非空', value: 'notNull', noValue: true },
|
||||
],
|
||||
},
|
||||
properties: {
|
||||
field1: {
|
||||
type: 'number',
|
||||
'x-component': 'InputNumber',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
action2: {
|
||||
type: 'void',
|
||||
name: 'action1',
|
||||
title: '新增',
|
||||
'x-component': 'Action',
|
||||
'x-designable-bar': 'Table.Action.DesignableBar',
|
||||
properties: {
|
||||
drawer1: {
|
||||
type: 'void',
|
||||
title: '抽屉标题',
|
||||
'x-decorator': 'Form',
|
||||
'x-component': 'Action.Modal',
|
||||
'x-component-props': {
|
||||
useOkAction: '{{ Table.useTableCreateAction }}',
|
||||
},
|
||||
properties: {
|
||||
field1: {
|
||||
type: 'string',
|
||||
title: '字段1',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Input',
|
||||
},
|
||||
field2: {
|
||||
type: 'string',
|
||||
title: '字段2',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Input',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
action3: {
|
||||
type: 'void',
|
||||
name: 'action1',
|
||||
title: '删除',
|
||||
'x-designable-bar': 'Table.Action.SimpleDesignableBar',
|
||||
'x-component': 'Action',
|
||||
'x-component-props': {
|
||||
useAction: '{{ Table.useTableDestroyAction }}',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
[`a_${uid()}`]: {
|
||||
type: 'void',
|
||||
'x-component': 'Table.ActionBar',
|
||||
'x-component-props': {
|
||||
align: 'bottom',
|
||||
},
|
||||
properties: {
|
||||
pagination: {
|
||||
type: 'void',
|
||||
title: '新增',
|
||||
'x-component': 'Table.Addition',
|
||||
'x-component-props': {},
|
||||
},
|
||||
},
|
||||
},
|
||||
// [`column_${uid()}`]: {
|
||||
// type: 'void',
|
||||
// title: '排序',
|
||||
// 'x-component': 'Table.Column',
|
||||
// properties: {
|
||||
// sort: {
|
||||
// type: 'void',
|
||||
// 'x-component': 'Table.SortHandle',
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// [`column_${uid()}`]: {
|
||||
// type: 'void',
|
||||
// title: '序号',
|
||||
// 'x-component': 'Table.Column',
|
||||
// properties: {
|
||||
// index: {
|
||||
// type: 'void',
|
||||
// 'x-component': 'Table.Index',
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
[`column_${uid()}`]: {
|
||||
type: 'void',
|
||||
'x-component': 'Table.Column',
|
||||
'x-component-props': {
|
||||
className: 'nb-table-operation',
|
||||
},
|
||||
properties: {
|
||||
[uid()]: {
|
||||
type: 'void',
|
||||
'x-component': 'Action.Dropdown',
|
||||
'x-component-props': {
|
||||
buttonProps: {
|
||||
icon: 'EllipsisOutlined',
|
||||
},
|
||||
},
|
||||
properties: {
|
||||
[uid()]: {
|
||||
type: 'void',
|
||||
title: '操作 1',
|
||||
'x-component': 'Menu.Action',
|
||||
'x-component-props': {
|
||||
useAction,
|
||||
style: {
|
||||
minWidth: 150,
|
||||
},
|
||||
disabled: true,
|
||||
},
|
||||
},
|
||||
[uid()]: {
|
||||
type: 'void',
|
||||
title: '操作 2',
|
||||
'x-component': 'Menu.Action',
|
||||
'x-default-action': true,
|
||||
'x-component-props': {
|
||||
useAction,
|
||||
},
|
||||
},
|
||||
[uid()]: {
|
||||
type: 'void',
|
||||
name: 'action1',
|
||||
title: '查看',
|
||||
'x-component': 'Menu.Action',
|
||||
'x-designable-bar': 'Table.Action.DesignableBar',
|
||||
properties: {
|
||||
drawer1: {
|
||||
type: 'void',
|
||||
title: '查看',
|
||||
'x-component': 'Action.Modal',
|
||||
'x-component-props': {},
|
||||
properties: {
|
||||
[uid()]: {
|
||||
type: 'void',
|
||||
'x-component': 'Tabs',
|
||||
properties: {
|
||||
tab1: {
|
||||
type: 'void',
|
||||
'x-component': 'Tabs.TabPane',
|
||||
'x-component-props': {
|
||||
tab: 'Tab1',
|
||||
},
|
||||
properties: {
|
||||
aaa: {
|
||||
type: 'string',
|
||||
title: 'AAA',
|
||||
'x-decorator': 'FormItem',
|
||||
required: true,
|
||||
'x-component': 'Input',
|
||||
},
|
||||
},
|
||||
},
|
||||
tab2: {
|
||||
type: 'void',
|
||||
'x-component': 'Tabs.TabPane',
|
||||
'x-component-props': {
|
||||
tab: 'Tab2',
|
||||
},
|
||||
properties: {
|
||||
bbb: {
|
||||
type: 'string',
|
||||
title: 'BBB',
|
||||
'x-decorator': 'FormItem',
|
||||
required: true,
|
||||
'x-component': 'Input',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
[uid()]: {
|
||||
type: 'void',
|
||||
name: 'action1',
|
||||
title: '修改',
|
||||
'x-component': 'Menu.Action',
|
||||
'x-designable-bar': 'Table.Action.DesignableBar',
|
||||
properties: {
|
||||
drawer1: {
|
||||
type: 'void',
|
||||
title: '编辑表单',
|
||||
'x-decorator': 'Form',
|
||||
'x-decorator-props': {
|
||||
useValues: '{{ Table.useTableRow }}',
|
||||
},
|
||||
'x-component': 'Action.Modal',
|
||||
'x-component-props': {
|
||||
useOkAction: '{{ Table.useTableUpdateAction }}',
|
||||
},
|
||||
properties: {
|
||||
field1: {
|
||||
type: 'string',
|
||||
title: '字段1',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Input',
|
||||
},
|
||||
field2: {
|
||||
type: 'string',
|
||||
title: '字段2',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Input',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
[uid()]: {
|
||||
type: 'void',
|
||||
title: '删除',
|
||||
'x-component': 'Menu.Action',
|
||||
'x-component-props': {
|
||||
useAction: '{{ Table.useTableDestroyAction }}',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
[`column_${uid()}`]: {
|
||||
type: 'void',
|
||||
title: '字段1',
|
||||
'x-component': 'Table.Column',
|
||||
'x-component-props': {
|
||||
// title: 'z1',
|
||||
},
|
||||
'x-designable-bar': 'Table.Column.DesignableBar',
|
||||
properties: {
|
||||
field1: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
'x-read-pretty': true,
|
||||
'x-decorator-props': {
|
||||
feedbackLayout: 'popover',
|
||||
},
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Input',
|
||||
},
|
||||
},
|
||||
},
|
||||
[`column_${uid()}`]: {
|
||||
type: 'void',
|
||||
title: '字段2',
|
||||
'x-component': 'Table.Column',
|
||||
'x-designable-bar': 'Table.Column.DesignableBar',
|
||||
properties: {
|
||||
field2: {
|
||||
type: 'string',
|
||||
// title: '字段2',
|
||||
required: true,
|
||||
'x-read-pretty': true,
|
||||
'x-decorator-props': {
|
||||
feedbackLayout: 'popover',
|
||||
},
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Input',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const form = createForm({
|
||||
// designable: true,
|
||||
});
|
||||
|
||||
export default observer(() => {
|
||||
return (
|
||||
<div>
|
||||
<SchemaRenderer
|
||||
scope={{ Table, useTableCreateAction }}
|
||||
form={form}
|
||||
schema={schema}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
});
|
261
packages/client/src/schemas/table/demos/demo3.tsx
Normal file
261
packages/client/src/schemas/table/demos/demo3.tsx
Normal file
@ -0,0 +1,261 @@
|
||||
import React from 'react';
|
||||
import { range } from 'lodash';
|
||||
import { ISchema } from '@formily/react';
|
||||
import { SchemaRenderer } from '../..';
|
||||
import { uid } from '@formily/shared';
|
||||
|
||||
const loadDataSource = (params?: any): Promise<any> => {
|
||||
const { page, pageSize = 50 } = params || {};
|
||||
console.log({ pageSize });
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
resolve({
|
||||
list: range(50 || pageSize).map(() => {
|
||||
return { id: uid(), title: uid() };
|
||||
}),
|
||||
total: 50,
|
||||
});
|
||||
}, 1000);
|
||||
});
|
||||
};
|
||||
|
||||
const schema: ISchema = {
|
||||
type: 'array',
|
||||
name: 'arr',
|
||||
'x-component': 'Table',
|
||||
'x-component-props': {
|
||||
dragSort: true,
|
||||
showIndex: true,
|
||||
refreshRequestOnChange: false,
|
||||
clientSidePagination: true,
|
||||
dataRequest: '{{ loadDataSource }}',
|
||||
pagination: {
|
||||
pageSize: 2,
|
||||
},
|
||||
},
|
||||
// default: range(50).map(() => {
|
||||
// return { id: uid(), title: uid() };
|
||||
// }),
|
||||
properties: {
|
||||
[uid()]: {
|
||||
type: 'void',
|
||||
'x-component': 'Table.ActionBar',
|
||||
'x-designable-bar': 'Table.ActionBar.DesignableBar',
|
||||
properties: {
|
||||
[uid()]: {
|
||||
type: 'void',
|
||||
'x-component': 'Table.Filter',
|
||||
'x-designable-bar': 'Table.Filter.DesignableBar',
|
||||
'x-component-props': {
|
||||
fieldNames: [],
|
||||
},
|
||||
},
|
||||
[uid()]: {
|
||||
type: 'void',
|
||||
name: 'action1',
|
||||
title: '新增',
|
||||
'x-component': 'Action',
|
||||
'x-designable-bar': 'Table.Action.DesignableBar',
|
||||
properties: {
|
||||
modal: {
|
||||
type: 'void',
|
||||
title: '新增数据',
|
||||
'x-decorator': 'Form',
|
||||
'x-component': 'Action.Modal',
|
||||
'x-component-props': {
|
||||
useOkAction: '{{ Table.useTableCreateAction }}',
|
||||
},
|
||||
properties: {
|
||||
[uid()]: {
|
||||
type: 'void',
|
||||
'x-component': 'Grid',
|
||||
'x-component-props': {
|
||||
addNewComponent: 'AddNew.FormItem',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
[uid()]: {
|
||||
type: 'void',
|
||||
name: 'action1',
|
||||
title: '删除',
|
||||
'x-component': 'Action',
|
||||
'x-designable-bar': 'Table.Action.DesignableBar',
|
||||
'x-component-props': {
|
||||
useAction: '{{ Table.useTableDestroyAction }}',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
column2: {
|
||||
type: 'void',
|
||||
title: '操作',
|
||||
'x-component': 'Table.Column',
|
||||
'x-component-props': {
|
||||
className: 'nb-table-operation',
|
||||
},
|
||||
properties: {
|
||||
action1: {
|
||||
type: 'void',
|
||||
name: 'dropdown1',
|
||||
'x-component': 'Action.Dropdown',
|
||||
'x-designable-bar': 'Action.DesignableBar',
|
||||
'x-component-props': {
|
||||
buttonProps: {
|
||||
icon: 'EllipsisOutlined',
|
||||
},
|
||||
},
|
||||
properties: {
|
||||
[uid()]: {
|
||||
type: 'void',
|
||||
title: '操作 1',
|
||||
'x-component': 'Menu.Action',
|
||||
'x-component-props': {
|
||||
style: {
|
||||
minWidth: 150,
|
||||
},
|
||||
disabled: true,
|
||||
},
|
||||
},
|
||||
[uid()]: {
|
||||
type: 'void',
|
||||
name: 'action1',
|
||||
title: '查看',
|
||||
'x-component': 'Menu.Action',
|
||||
'x-designable-bar': 'Table.Action.DesignableBar',
|
||||
properties: {
|
||||
[uid()]: {
|
||||
type: 'void',
|
||||
title: '查看',
|
||||
'x-component': 'Action.Modal',
|
||||
'x-component-props': {
|
||||
bodyStyle: {
|
||||
background: '#f0f2f5',
|
||||
paddingTop: 0,
|
||||
},
|
||||
},
|
||||
properties: {
|
||||
[uid()]: {
|
||||
type: 'void',
|
||||
'x-component': 'Tabs',
|
||||
properties: {
|
||||
[uid()]: {
|
||||
type: 'void',
|
||||
'x-component': 'Tabs.TabPane',
|
||||
'x-component-props': {
|
||||
tab: 'Tab1',
|
||||
},
|
||||
properties: {
|
||||
[uid()]: {
|
||||
type: 'void',
|
||||
'x-component': 'Grid',
|
||||
'x-component-props': {
|
||||
addNewComponent: 'AddNew.PaneItem',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
[uid()]: {
|
||||
type: 'void',
|
||||
title: '编辑',
|
||||
'x-component': 'Menu.Action',
|
||||
'x-designable-bar': 'Table.Action.DesignableBar',
|
||||
properties: {
|
||||
[uid()]: {
|
||||
type: 'void',
|
||||
title: '编辑数据',
|
||||
'x-decorator': 'Form',
|
||||
'x-decorator-props': {
|
||||
useValues: '{{ Table.useTableRowRecord }}',
|
||||
},
|
||||
'x-component': 'Action.Modal',
|
||||
'x-component-props': {
|
||||
useOkAction: '{{ Table.useTableUpdateAction }}',
|
||||
},
|
||||
properties: {
|
||||
[uid()]: {
|
||||
type: 'void',
|
||||
'x-component': 'Grid',
|
||||
'x-component-props': {
|
||||
addNewComponent: 'AddNew.FormItem',
|
||||
},
|
||||
properties: {
|
||||
[uid()]: {
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Row',
|
||||
properties: {
|
||||
[uid()]: {
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Col',
|
||||
properties: {
|
||||
title: {
|
||||
title: '标题',
|
||||
type: 'string',
|
||||
'x-component': 'Input',
|
||||
'x-decorator': 'FormItem',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
[uid()]: {
|
||||
type: 'void',
|
||||
title: '删除',
|
||||
'x-component': 'Menu.Action',
|
||||
'x-component-props': {
|
||||
useAction: '{{ Table.useTableDestroyAction }}',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
column0: {
|
||||
type: 'void',
|
||||
title: 'ID',
|
||||
'x-component': 'Table.Column',
|
||||
'x-designable-bar': 'Table.Column.DesignableBar',
|
||||
properties: {
|
||||
id: {
|
||||
type: 'string',
|
||||
'x-component': 'Input',
|
||||
'x-read-pretty': true,
|
||||
},
|
||||
},
|
||||
},
|
||||
column1: {
|
||||
type: 'void',
|
||||
title: 'Title',
|
||||
'x-component': 'Table.Column',
|
||||
properties: {
|
||||
title: {
|
||||
type: 'string',
|
||||
'x-component': 'Input',
|
||||
'x-read-pretty': true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default () => {
|
||||
return (
|
||||
<div>
|
||||
<SchemaRenderer scope={{ loadDataSource }} schema={schema} />
|
||||
</div>
|
||||
);
|
||||
};
|
@ -60,4 +60,15 @@ group:
|
||||
|
||||
## Examples
|
||||
|
||||
<code src="./demos/demo1.tsx"/>
|
||||
<code src="./demos/demo3.tsx"/>
|
||||
|
||||
## API
|
||||
|
||||
表格的几个重要概念
|
||||
|
||||
- collection 当前表格的数据表配置信息(主要是字段)
|
||||
- resource 当前资源,用于处理 create、update、list、destroy
|
||||
- service 当前表格的 resource.list 实例
|
||||
- field 当前表格的 ArrayField 对象
|
||||
- schema 当前表格的 json schema
|
||||
- props 当前表格的参数
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -71,8 +71,8 @@
|
||||
|
||||
th.nb-table-operation,
|
||||
td.nb-table-operation {
|
||||
width: 24px;
|
||||
text-align: center;
|
||||
width: 50px;
|
||||
text-align: center !important;
|
||||
padding: 0 !important;
|
||||
&::before {
|
||||
display: none;
|
||||
|
31
yarn.lock
31
yarn.lock
@ -1755,6 +1755,37 @@
|
||||
resolved "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.4.0.tgz#c3c5ae543c897caa9c2a68630bed355be5f9990f"
|
||||
integrity sha512-JZButFdZ1+/xAfpguQHoabIXkcqRRKpMrWKBkpEZZyxfY9C1DpADFB8PEqGSTeFr135SaTRfKqGKx5xSCLI7ZQ==
|
||||
|
||||
"@dnd-kit/accessibility@^3.0.0":
|
||||
version "3.0.0"
|
||||
resolved "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.0.0.tgz#b56e3750414fd907b7d6972b3116aa8f96d07fde"
|
||||
integrity sha512-QwaQ1IJHQHMMuAGOOYHQSx7h7vMZPfO97aDts8t5N/MY7n2QTDSnW+kF7uRQ1tVBkr6vJ+BqHWG5dlgGvwVjow==
|
||||
dependencies:
|
||||
tslib "^2.0.0"
|
||||
|
||||
"@dnd-kit/core@^3.1.1":
|
||||
version "3.1.1"
|
||||
resolved "https://registry.npmjs.org/@dnd-kit/core/-/core-3.1.1.tgz#c5ad6665931f5a51e74226220e58ac7514f3faf0"
|
||||
integrity sha512-18YY5+1lTqJbGSg6JBSa/fjAOTUYAysFrQ5Ti8oppEPHFacQbC+owM51y2z2KN0LkDHBfGZKw2sFT7++ttwfpA==
|
||||
dependencies:
|
||||
"@dnd-kit/accessibility" "^3.0.0"
|
||||
"@dnd-kit/utilities" "^2.0.0"
|
||||
tslib "^2.0.0"
|
||||
|
||||
"@dnd-kit/sortable@^4.0.0":
|
||||
version "4.0.0"
|
||||
resolved "https://registry.npmjs.org/@dnd-kit/sortable/-/sortable-4.0.0.tgz#81dd2b014a16527cf89602dc40060d9ee4dad352"
|
||||
integrity sha512-teYVFy6mQG/u6F6CaGxAkzPfiNJvguFzWfJ/zonYQRxfANHX6QJ6GziMG9KON/Ae9Q2ODJP8vib+guWJrDXeGg==
|
||||
dependencies:
|
||||
"@dnd-kit/utilities" "^2.0.0"
|
||||
tslib "^2.0.0"
|
||||
|
||||
"@dnd-kit/utilities@^2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmjs.org/@dnd-kit/utilities/-/utilities-2.0.0.tgz#a8462dff65c6f606ecbe95273c7e263b14a1ab97"
|
||||
integrity sha512-bjs49yMNzMM+BYRsBUhTqhTk6HEvhuY3leFt6Em6NaYGgygaMbtGbbXof/UXBv7rqyyi0OkmBBnrCCcxqS2t/g==
|
||||
dependencies:
|
||||
tslib "^2.0.0"
|
||||
|
||||
"@eslint/eslintrc@^0.4.2":
|
||||
version "0.4.2"
|
||||
resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz#f63d0ef06f5c0c57d76c4ab5f63d3835c51b0179"
|
||||
|
Loading…
Reference in New Issue
Block a user