feat: improve code
This commit is contained in:
parent
257488ebad
commit
de2b7cab75
@ -22,6 +22,7 @@ export function AdminLayout(props: any) {
|
||||
const [schema, setSchema] = useState({});
|
||||
const onSelect = ({ item }) => {
|
||||
const schema = item.props.schema;
|
||||
console.log('onSelect', schema);
|
||||
setSchema(schema);
|
||||
setTitle(schema.title);
|
||||
history.push(`/admin/${schema['x-uid']}`);
|
||||
@ -30,7 +31,7 @@ export function AdminLayout(props: any) {
|
||||
const result = useSystemSettings();
|
||||
return (
|
||||
<Layout>
|
||||
<Layout.Header style={{ position: 'relative', paddingLeft: 0 }}>
|
||||
<Layout.Header style={{ height: 46, lineHeight: '46px', position: 'relative', paddingLeft: 0 }}>
|
||||
<div style={{ display: 'flex' }}>
|
||||
<div style={{ display: 'inline-flex', color: '#fff', padding: '0 24px' }}>{result?.data?.data?.title}</div>
|
||||
<RemoteSchemaComponent
|
||||
@ -74,7 +75,7 @@ export function AdminLayout(props: any) {
|
||||
</Layout.Header>
|
||||
<Layout>
|
||||
<Layout.Sider style={{ display: 'none' }} theme={'light'} ref={sideMenuRef}></Layout.Sider>
|
||||
<Layout.Content>
|
||||
<Layout.Content style={{ minHeight: 'calc(100vh - 46px)' }}>
|
||||
<RemoteSchemaComponent onlyRenderProperties uid={match.params.name} />
|
||||
</Layout.Content>
|
||||
</Layout>
|
||||
|
@ -0,0 +1,14 @@
|
||||
import { useField } from '@formily/react';
|
||||
import React from 'react';
|
||||
import { GeneralSchemaDesigner, SchemaSettings } from '../../../';
|
||||
|
||||
export const MenuDesigner = () => {
|
||||
const field = useField();
|
||||
return (
|
||||
<GeneralSchemaDesigner>
|
||||
<SchemaSettings.Item>编辑</SchemaSettings.Item>
|
||||
<SchemaSettings.Divider />
|
||||
<SchemaSettings.Remove />
|
||||
</GeneralSchemaDesigner>
|
||||
);
|
||||
};
|
@ -1,13 +1,121 @@
|
||||
import { DesktopOutlined } from '@ant-design/icons';
|
||||
import { observer, RecursionField, Schema, SchemaExpressionScopeContext, useFieldSchema } from '@formily/react';
|
||||
import { css } from '@emotion/css';
|
||||
import {
|
||||
observer,
|
||||
RecursionField,
|
||||
Schema,
|
||||
SchemaExpressionScopeContext,
|
||||
useField,
|
||||
useFieldSchema
|
||||
} from '@formily/react';
|
||||
import { Menu as AntdMenu } from 'antd';
|
||||
import React, { createContext, useContext, useEffect, useState } from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { createDesignable, DndContext, SortableItem, useComponent, useDesignable, useDesigner } from '../..';
|
||||
import { Icon, useAPIClient } from '../../../';
|
||||
import { MenuDesigner } from './Menu.Designer';
|
||||
import { findKeysByUid, findMenuItem } from './util';
|
||||
|
||||
const subMenuDesignerCss = css`
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
margin-left: -24px;
|
||||
margin-right: -34px;
|
||||
padding: 0 34px 0 24px;
|
||||
width: calc(100% + 58px);
|
||||
&:hover {
|
||||
> .general-schema-designer {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
&.nb-action-link {
|
||||
> .general-schema-designer {
|
||||
top: -10px;
|
||||
bottom: -10px;
|
||||
left: -10px;
|
||||
right: -10px;
|
||||
}
|
||||
}
|
||||
> .general-schema-designer {
|
||||
position: absolute;
|
||||
z-index: 999;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
display: none;
|
||||
background: rgba(241, 139, 98, 0.06);
|
||||
border: 0;
|
||||
pointer-events: none;
|
||||
> .general-schema-designer-icons {
|
||||
position: absolute;
|
||||
right: 2px;
|
||||
top: 2px;
|
||||
line-height: 16px;
|
||||
pointer-events: all;
|
||||
.ant-space-item {
|
||||
background-color: #f18b62;
|
||||
color: #fff;
|
||||
line-height: 16px;
|
||||
width: 16px;
|
||||
padding-left: 1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const designerCss = css`
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
margin-left: -20px;
|
||||
margin-right: -20px;
|
||||
padding: 0 20px;
|
||||
width: calc(100% + 40px);
|
||||
&:hover {
|
||||
> .general-schema-designer {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
&.nb-action-link {
|
||||
> .general-schema-designer {
|
||||
top: -10px;
|
||||
bottom: -10px;
|
||||
left: -10px;
|
||||
right: -10px;
|
||||
}
|
||||
}
|
||||
> .general-schema-designer {
|
||||
position: absolute;
|
||||
z-index: 999;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
display: none;
|
||||
background: rgba(241, 139, 98, 0.06);
|
||||
border: 0;
|
||||
pointer-events: none;
|
||||
> .general-schema-designer-icons {
|
||||
position: absolute;
|
||||
right: 2px;
|
||||
top: 2px;
|
||||
line-height: 16px;
|
||||
pointer-events: all;
|
||||
.ant-space-item {
|
||||
background-color: #f18b62;
|
||||
color: #fff;
|
||||
line-height: 16px;
|
||||
width: 16px;
|
||||
padding-left: 1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
type ComposedMenu = React.FC<any> & {
|
||||
Item?: React.FC<any>;
|
||||
URL?: React.FC<any>;
|
||||
SubMenu?: React.FC<any>;
|
||||
Designer?: React.FC<any>;
|
||||
};
|
||||
|
||||
const MenuModeContext = createContext(null);
|
||||
@ -22,6 +130,8 @@ const useSideMenuRef = () => {
|
||||
return scope[scopeKey];
|
||||
};
|
||||
|
||||
const MenuItemDesignerContext = createContext(null);
|
||||
|
||||
export const Menu: ComposedMenu = observer((props) => {
|
||||
let {
|
||||
onSelect,
|
||||
@ -32,7 +142,11 @@ export const Menu: ComposedMenu = observer((props) => {
|
||||
defaultOpenKeys: dOpenKeys,
|
||||
...others
|
||||
} = props;
|
||||
const Designer = useDesigner();
|
||||
const schema = useFieldSchema();
|
||||
const { refresh } = useDesignable();
|
||||
const api = useAPIClient();
|
||||
const Initializer = useComponent(schema['x-initializer']);
|
||||
const sideMenuRef = useSideMenuRef();
|
||||
const [defaultSelectedKeys, setDefaultSelectedKeys] = useState(() => {
|
||||
if (dSelectedKeys) {
|
||||
@ -70,98 +184,190 @@ export const Menu: ComposedMenu = observer((props) => {
|
||||
if (!sideMenuElement) {
|
||||
return;
|
||||
}
|
||||
sideMenuElement.style.display = sideMenuSchema?.properties ? 'block' : 'none';
|
||||
}, [sideMenuSchema?.properties, sideMenuRef]);
|
||||
sideMenuElement.style.display = sideMenuSchema?.['x-component'] === 'Menu.SubMenu' ? 'block' : 'none';
|
||||
}, [sideMenuSchema?.name, sideMenuRef]);
|
||||
return (
|
||||
<MenuModeContext.Provider value={mode}>
|
||||
<AntdMenu
|
||||
{...others}
|
||||
onSelect={(info: any) => {
|
||||
const s = schema.properties[info.key];
|
||||
if (mode === 'mix') {
|
||||
setSideMenuSchema(s);
|
||||
if (!s?.properties) {
|
||||
onSelect && onSelect(info);
|
||||
} else {
|
||||
const menuItemSchema = findMenuItem(s);
|
||||
if (!menuItemSchema) {
|
||||
return;
|
||||
<DndContext>
|
||||
<MenuItemDesignerContext.Provider value={Designer}>
|
||||
<MenuModeContext.Provider value={mode}>
|
||||
<AntdMenu
|
||||
{...others}
|
||||
style={{
|
||||
width: mode === 'mix' ? '100%' : undefined,
|
||||
}}
|
||||
className={css`
|
||||
.ant-menu-item:hover {
|
||||
> .ant-menu-title-content > div {
|
||||
.general-schema-designer {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO
|
||||
setLoading(true);
|
||||
const keys = findKeysByUid(schema, menuItemSchema['x-uid']);
|
||||
setDefaultSelectedKeys(keys);
|
||||
setTimeout(() => {
|
||||
setLoading(false);
|
||||
}, 100);
|
||||
onSelect &&
|
||||
onSelect({
|
||||
key: menuItemSchema.name,
|
||||
item: {
|
||||
props: {
|
||||
schema: menuItemSchema,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
} else {
|
||||
onSelect && onSelect(info);
|
||||
}
|
||||
}}
|
||||
mode={mode === 'mix' ? 'horizontal' : mode}
|
||||
defaultOpenKeys={defaultOpenKeys}
|
||||
defaultSelectedKeys={defaultSelectedKeys}
|
||||
>
|
||||
<RecursionField schema={schema} onlyRenderProperties />
|
||||
</AntdMenu>
|
||||
{loading
|
||||
? null
|
||||
: mode === 'mix' &&
|
||||
sideMenuSchema?.properties &&
|
||||
sideMenuRef?.current?.firstChild &&
|
||||
createPortal(
|
||||
<MenuModeContext.Provider value={'inline'}>
|
||||
<AntdMenu
|
||||
mode={'inline'}
|
||||
defaultOpenKeys={defaultOpenKeys}
|
||||
defaultSelectedKeys={defaultSelectedKeys}
|
||||
onSelect={(info) => {
|
||||
`}
|
||||
onSelect={(info: any) => {
|
||||
const s = schema.properties[info.key];
|
||||
if (mode === 'mix') {
|
||||
setSideMenuSchema(s);
|
||||
if (s['x-component'] !== 'Menu.SubMenu') {
|
||||
onSelect && onSelect(info);
|
||||
}}
|
||||
>
|
||||
<RecursionField schema={sideMenuSchema} onlyRenderProperties />
|
||||
</AntdMenu>
|
||||
</MenuModeContext.Provider>,
|
||||
sideMenuRef.current.firstChild,
|
||||
)}
|
||||
</MenuModeContext.Provider>
|
||||
} else {
|
||||
const menuItemSchema = findMenuItem(s);
|
||||
if (!menuItemSchema) {
|
||||
return;
|
||||
}
|
||||
// TODO
|
||||
setLoading(true);
|
||||
const keys = findKeysByUid(schema, menuItemSchema['x-uid']);
|
||||
setDefaultSelectedKeys(keys);
|
||||
setTimeout(() => {
|
||||
setLoading(false);
|
||||
}, 100);
|
||||
onSelect &&
|
||||
onSelect({
|
||||
key: menuItemSchema.name,
|
||||
item: {
|
||||
props: {
|
||||
schema: menuItemSchema,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
} else {
|
||||
onSelect && onSelect(info);
|
||||
}
|
||||
}}
|
||||
mode={mode === 'mix' ? 'horizontal' : mode}
|
||||
defaultOpenKeys={defaultOpenKeys}
|
||||
defaultSelectedKeys={defaultSelectedKeys}
|
||||
>
|
||||
<RecursionField schema={schema} onlyRenderProperties />
|
||||
{Initializer && <Initializer style={{ background: 'none', marginTop: 7, marginLeft: 8 }} />}
|
||||
</AntdMenu>
|
||||
{loading
|
||||
? null
|
||||
: mode === 'mix' &&
|
||||
sideMenuSchema?.['x-component'] === 'Menu.SubMenu' &&
|
||||
sideMenuRef?.current?.firstChild &&
|
||||
createPortal(
|
||||
<MenuModeContext.Provider value={'inline'}>
|
||||
<AntdMenu
|
||||
mode={'inline'}
|
||||
defaultOpenKeys={defaultOpenKeys}
|
||||
defaultSelectedKeys={defaultSelectedKeys}
|
||||
onSelect={(info) => {
|
||||
onSelect && onSelect(info);
|
||||
}}
|
||||
className={css`
|
||||
.ant-menu-item {
|
||||
> .ant-menu-title-content {
|
||||
margin-left: -24px;
|
||||
margin-right: -16px;
|
||||
padding: 0 16px 0 24px;
|
||||
> div {
|
||||
> .general-schema-designer {
|
||||
right: 6px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.ant-menu-submenu-title {
|
||||
.ant-menu-title-content {
|
||||
margin-left: -24px;
|
||||
margin-right: -34px;
|
||||
padding: 0 34px 0 24px;
|
||||
> div {
|
||||
> .general-schema-designer {
|
||||
right: 6px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`}
|
||||
>
|
||||
<RecursionField schema={sideMenuSchema} onlyRenderProperties />
|
||||
{Initializer && (
|
||||
<Initializer
|
||||
style={{ margin: 8 }}
|
||||
insert={(s) => {
|
||||
console.log('createDesignable', s);
|
||||
const dn = createDesignable({
|
||||
api,
|
||||
refresh,
|
||||
current: sideMenuSchema,
|
||||
});
|
||||
dn.loadAPIClientEvents();
|
||||
dn.insertAdjacent('beforeEnd', s);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</AntdMenu>
|
||||
</MenuModeContext.Provider>,
|
||||
sideMenuRef.current.firstChild,
|
||||
)}
|
||||
</MenuModeContext.Provider>
|
||||
</MenuItemDesignerContext.Provider>
|
||||
</DndContext>
|
||||
);
|
||||
});
|
||||
|
||||
Menu.Item = observer((props) => {
|
||||
const { icon, ...others } = props;
|
||||
const schema = useFieldSchema();
|
||||
const Designer = useContext(MenuItemDesignerContext);
|
||||
return (
|
||||
<AntdMenu.Item {...props} icon={<DesktopOutlined />} key={schema.name} eventKey={schema.name} schema={schema}>
|
||||
{schema.title}
|
||||
<AntdMenu.Item {...others} key={schema.name} eventKey={schema.name} schema={schema}>
|
||||
<SortableItem className={designerCss}>
|
||||
<Icon type={icon} style={{ marginRight: 5 }} />
|
||||
{schema.title}
|
||||
<Designer />
|
||||
</SortableItem>
|
||||
</AntdMenu.Item>
|
||||
);
|
||||
});
|
||||
|
||||
Menu.URL = observer((props) => {
|
||||
const { icon, ...others } = props;
|
||||
const schema = useFieldSchema();
|
||||
const field = useField();
|
||||
const Designer = useContext(MenuItemDesignerContext);
|
||||
return (
|
||||
<AntdMenu.Item {...others} key={schema.name} eventKey={schema.name} schema={schema} onClick={() => {
|
||||
window.open(props.href, '_blank');
|
||||
}}>
|
||||
<SortableItem className={designerCss}>
|
||||
<Icon style={{ marginRight: 5 }} type={icon} />
|
||||
{schema.title}
|
||||
<Designer />
|
||||
</SortableItem>
|
||||
</AntdMenu.Item>
|
||||
);
|
||||
});
|
||||
|
||||
Menu.SubMenu = observer((props) => {
|
||||
const { icon, ...others } = props;
|
||||
const schema = useFieldSchema();
|
||||
const field = useField();
|
||||
const mode = useContext(MenuModeContext);
|
||||
const Designer = useContext(MenuItemDesignerContext);
|
||||
if (mode === 'mix') {
|
||||
return <Menu.Item {...props} />;
|
||||
}
|
||||
return (
|
||||
<AntdMenu.SubMenu
|
||||
{...props}
|
||||
icon={<DesktopOutlined />}
|
||||
title={schema.title}
|
||||
{...others}
|
||||
key={schema.name}
|
||||
eventKey={schema.name}
|
||||
title={
|
||||
<SortableItem className={subMenuDesignerCss}>
|
||||
<Icon style={{ marginRight: 5 }} type={icon} />
|
||||
{field.title}
|
||||
<Designer />
|
||||
</SortableItem>
|
||||
}
|
||||
>
|
||||
<RecursionField schema={schema} onlyRenderProperties />
|
||||
</AntdMenu.SubMenu>
|
||||
);
|
||||
});
|
||||
|
||||
Menu.Designer = MenuDesigner;
|
||||
|
@ -0,0 +1,204 @@
|
||||
import { FormDialog, FormLayout } from '@formily/antd';
|
||||
import { observer, SchemaOptionsContext } from '@formily/react';
|
||||
import React, { useContext } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { SchemaComponent, SchemaComponentOptions } from '../../..';
|
||||
import { SchemaInitializer } from '../../../../schema-initializer';
|
||||
|
||||
export const MenuItemInitializer = observer((props: any) => {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<SchemaInitializer.Button
|
||||
insertPosition={'beforeEnd'}
|
||||
insert={props.insert}
|
||||
style={props.style}
|
||||
{...props}
|
||||
items={[
|
||||
{
|
||||
type: 'item',
|
||||
title: t('Group'),
|
||||
component: GroupItem,
|
||||
},
|
||||
{
|
||||
type: 'item',
|
||||
title: t('Page'),
|
||||
component: PageMenuItem,
|
||||
},
|
||||
{
|
||||
type: 'item',
|
||||
title: t('Link'),
|
||||
component: LinkMenuItem,
|
||||
},
|
||||
]}
|
||||
>
|
||||
{t('Add menu item')}
|
||||
</SchemaInitializer.Button>
|
||||
);
|
||||
});
|
||||
|
||||
const itemWrap = SchemaInitializer.itemWrap;
|
||||
|
||||
export const GroupItem = itemWrap((props) => {
|
||||
const { insert } = props;
|
||||
const { t } = useTranslation();
|
||||
const options = useContext(SchemaOptionsContext);
|
||||
return (
|
||||
<SchemaInitializer.Item
|
||||
{...props}
|
||||
onClick={async () => {
|
||||
const values = await FormDialog('添加分组', () => {
|
||||
return (
|
||||
<SchemaComponentOptions scope={options.scope} components={{ ...options.components }}>
|
||||
<FormLayout layout={'vertical'}>
|
||||
<SchemaComponent
|
||||
schema={{
|
||||
properties: {
|
||||
title: {
|
||||
title: '分组标题',
|
||||
'x-component': 'Input',
|
||||
'x-decorator': 'FormItem',
|
||||
},
|
||||
icon: {
|
||||
title: '图标',
|
||||
'x-component': 'IconPicker',
|
||||
'x-decorator': 'FormItem',
|
||||
},
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</FormLayout>
|
||||
</SchemaComponentOptions>
|
||||
);
|
||||
}).open({
|
||||
initialValues: {},
|
||||
});
|
||||
const { title, icon } = values;
|
||||
insert({
|
||||
type: 'void',
|
||||
title,
|
||||
'x-component': 'Menu.SubMenu',
|
||||
'x-component-props': {
|
||||
icon,
|
||||
},
|
||||
});
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
export const PageMenuItem = itemWrap((props) => {
|
||||
const { insert } = props;
|
||||
const { t } = useTranslation();
|
||||
const options = useContext(SchemaOptionsContext);
|
||||
return (
|
||||
<SchemaInitializer.Item
|
||||
{...props}
|
||||
onClick={async () => {
|
||||
const values = await FormDialog('添加页面', () => {
|
||||
return (
|
||||
<SchemaComponentOptions scope={options.scope} components={{ ...options.components }}>
|
||||
<FormLayout layout={'vertical'}>
|
||||
<SchemaComponent
|
||||
schema={{
|
||||
properties: {
|
||||
title: {
|
||||
title: '页面标题',
|
||||
'x-component': 'Input',
|
||||
'x-decorator': 'FormItem',
|
||||
},
|
||||
icon: {
|
||||
title: '图标',
|
||||
'x-component': 'IconPicker',
|
||||
'x-decorator': 'FormItem',
|
||||
},
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</FormLayout>
|
||||
</SchemaComponentOptions>
|
||||
);
|
||||
}).open({
|
||||
initialValues: {},
|
||||
});
|
||||
const { title, icon } = values;
|
||||
insert({
|
||||
type: 'void',
|
||||
title,
|
||||
'x-component': 'Menu.Item',
|
||||
'x-component-props': {
|
||||
icon,
|
||||
},
|
||||
properties: {
|
||||
page: {
|
||||
type: 'void',
|
||||
'x-component': 'Page',
|
||||
'x-async': true,
|
||||
properties: {
|
||||
grid: {
|
||||
type: 'void',
|
||||
'x-component': 'Grid',
|
||||
'x-item-initializer': 'BlockInitializer',
|
||||
properties: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
export const LinkMenuItem = itemWrap((props) => {
|
||||
const { insert } = props;
|
||||
const { t } = useTranslation();
|
||||
const options = useContext(SchemaOptionsContext);
|
||||
return (
|
||||
<SchemaInitializer.Item
|
||||
{...props}
|
||||
onClick={async () => {
|
||||
const values = await FormDialog('添加链接', () => {
|
||||
return (
|
||||
<SchemaComponentOptions scope={options.scope} components={{ ...options.components }}>
|
||||
<FormLayout layout={'vertical'}>
|
||||
<SchemaComponent
|
||||
schema={{
|
||||
properties: {
|
||||
title: {
|
||||
title: '链接文字',
|
||||
'x-component': 'Input',
|
||||
'x-decorator': 'FormItem',
|
||||
},
|
||||
href: {
|
||||
title: '链接',
|
||||
'x-component': 'Input',
|
||||
'x-decorator': 'FormItem',
|
||||
},
|
||||
icon: {
|
||||
title: '图标',
|
||||
'x-component': 'IconPicker',
|
||||
'x-decorator': 'FormItem',
|
||||
},
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</FormLayout>
|
||||
</SchemaComponentOptions>
|
||||
);
|
||||
}).open({
|
||||
initialValues: {},
|
||||
});
|
||||
const { title, href, icon } = values;
|
||||
insert({
|
||||
type: 'void',
|
||||
title,
|
||||
'x-component': 'Menu.URL',
|
||||
'x-component-props': {
|
||||
icon,
|
||||
href,
|
||||
},
|
||||
});
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
@ -1,3 +1,4 @@
|
||||
export * from './Menu';
|
||||
export * from './MenuItemInitializer';
|
||||
export * from './util';
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { ISchema, Schema, SchemaOptionsContext, useField, useFieldSchema } from '@formily/react';
|
||||
import { uid } from '@formily/shared';
|
||||
import { message } from 'antd';
|
||||
import get from 'lodash/get';
|
||||
import set from 'lodash/set';
|
||||
import React, { useContext } from 'react';
|
||||
@ -92,6 +93,7 @@ export class Designable {
|
||||
method: 'post',
|
||||
});
|
||||
}
|
||||
message.success('配置保存成功!', 0.2);
|
||||
});
|
||||
this.on('patch', async ({ schema }) => {
|
||||
refresh();
|
||||
@ -104,6 +106,7 @@ export class Designable {
|
||||
},
|
||||
});
|
||||
}
|
||||
message.success('配置保存成功!', 0.2);
|
||||
});
|
||||
this.on('remove', async ({ removed }) => {
|
||||
refresh();
|
||||
@ -113,6 +116,7 @@ export class Designable {
|
||||
method: 'post',
|
||||
});
|
||||
}
|
||||
message.success('配置保存成功!', 0.2);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,11 @@
|
||||
import { useFieldSchema } from '@formily/react';
|
||||
import { useComponent } from '.';
|
||||
import { useComponent, useDesignable } from '.';
|
||||
|
||||
const Def = () => null;
|
||||
|
||||
export const useDesigner = () => {
|
||||
const { designable } = useDesignable();
|
||||
const fieldSchema = useFieldSchema();
|
||||
return useComponent(fieldSchema['x-designer'], Def);
|
||||
const component = useComponent(fieldSchema['x-designer'], Def);
|
||||
return designable ? component : Def;
|
||||
};
|
||||
|
@ -20,7 +20,7 @@ export const MarkdownBlock = itemWrap((props) => {
|
||||
'x-component': 'Markdown.Void',
|
||||
'x-editable': false,
|
||||
'x-component-props': {
|
||||
content: '# Markdown content',
|
||||
content: t('This is a demo text, **supports Markdown syntax**.'),
|
||||
},
|
||||
});
|
||||
}}
|
||||
|
@ -17,7 +17,7 @@ export const SchemaInitializer = () => null;
|
||||
|
||||
SchemaInitializer.Button = observer((props: SchemaInitializerButtonProps) => {
|
||||
const { insert, wrap = defaultWrap, items = [], insertPosition, dropdown, style, ...others } = props;
|
||||
let { insertAdjacent, findComponent } = useDesignable();
|
||||
let { insertAdjacent, findComponent, designable } = useDesignable();
|
||||
const [visible, setVisible] = useState(false);
|
||||
const insertSchema = (schema) => {
|
||||
if (props.insert) {
|
||||
@ -81,7 +81,9 @@ SchemaInitializer.Button = observer((props: SchemaInitializerButtonProps) => {
|
||||
</Menu>
|
||||
);
|
||||
|
||||
console.log('others', others);
|
||||
if (!designable) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Dropdown
|
||||
|
@ -6,7 +6,7 @@ import { DragHandler, useDesignable } from '../schema-component';
|
||||
import { SchemaSettings } from './SchemaSettings';
|
||||
|
||||
export const GeneralSchemaDesigner = (props: any) => {
|
||||
const { dn } = useDesignable();
|
||||
const { dn, designable } = useDesignable();
|
||||
const field = useField();
|
||||
const fieldSchema = useFieldSchema();
|
||||
const schemaSettingsProps = {
|
||||
@ -14,6 +14,9 @@ export const GeneralSchemaDesigner = (props: any) => {
|
||||
field,
|
||||
fieldSchema,
|
||||
};
|
||||
if (!designable) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<div className={'general-schema-designer'}>
|
||||
<div className={'general-schema-designer-icons'}>
|
||||
|
@ -20,6 +20,8 @@ export class UiRoutesStoragePlugin extends Plugin {
|
||||
uiSchema: {
|
||||
type: 'void',
|
||||
'x-component': 'Menu',
|
||||
'x-designer': 'Menu.Designer',
|
||||
'x-initializer': 'MenuItemInitializer',
|
||||
'x-component-props': {
|
||||
mode: 'mix',
|
||||
theme: 'dark',
|
||||
|
Loading…
Reference in New Issue
Block a user