designable bar

This commit is contained in:
chenos 2021-07-01 00:16:43 +08:00
parent 75cd158a27
commit 46e4089140
12 changed files with 976 additions and 361 deletions

View File

@ -1,6 +1,6 @@
import React, { createContext, useState } from 'react';
import {
FormItem,
// FormItem,
FormLayout,
FormButtonGroup,
Submit,
@ -41,6 +41,9 @@ import { Table } from './table';
import { Tabs } from './tabs';
import { TimePicker } from './time-picker';
import { Upload } from './upload';
import { FormItem } from './form-item';
export const BlockContext = createContext({ dragRef: null });
const Div = (props) => <div {...props} />;
@ -51,7 +54,6 @@ const scope = {
};
const components = {
Div,
Space,
Card,
@ -87,13 +89,13 @@ const components = {
};
export function registerScope(scopes) {
Object.keys(scopes).forEach(key => {
Object.keys(scopes).forEach((key) => {
scope[key] = scopes[key];
});
}
export function registerComponents(values) {
Object.keys(values).forEach(key => {
Object.keys(values).forEach((key) => {
components[key] = values[key];
});
}
@ -123,6 +125,9 @@ export function DesignableProvider(props) {
);
}
export const DesignableContext =
createContext<{ schema: Schema; refresh: any }>(null);
export function DesignableSchemaField(props: { schema?: ISchema }) {
return (
<DesignableProvider schema={new Schema(props.schema)}>

View File

@ -127,8 +127,8 @@ export type ActionType = React.FC<ActionProps> & {
DesignableBar?: React.FC<any>;
};
function Blank({ children }) {
return children;
function Blank() {
return null;
}
function useDesignableBar() {
@ -171,7 +171,6 @@ export const Action: ActionType = observer((props) => {
);
}
return (
<DesignableBar>
<Button
{...others}
onClick={async () => {
@ -208,8 +207,8 @@ export const Action: ActionType = observer((props) => {
}}
>
{field.title}
<DesignableBar />
</Button>
</DesignableBar>
);
});
@ -228,17 +227,17 @@ Action.URL = observer((props) => {
);
});
Action.DesignableBar = (props) => {
Action.DesignableBar = () => {
const field = useField();
const { schema, refresh } = useSchemaQuery();
const [visible, setVisible] = useState(false);
return (
<div className={'designable'}>
<div className={classNames('designable-bar', { active: visible })}>
<span
onClick={(e) => {
e.stopPropagation();
}}
className={classNames('designable-bar', { active: visible })}
className={classNames('designable-bar-actions', { active: visible })}
>
<Dropdown
trigger={['click']}
@ -266,7 +265,6 @@ Action.DesignableBar = (props) => {
<MenuOutlined />
</Dropdown>
</span>
{props.children}
</div>
);
};

View File

@ -1,6 +1,25 @@
.designable {
display: inline-block;
position: relative;
// .designable {
// display: inline-block;
// position: relative;
// &:hover {
// .designable-bar {
// display: block;
// }
// }
// .designable-bar {
// display: none;
// background: #fff;
// z-index: 2;
// position: absolute;
// right: 10px;
// top: 50%;
// transform: translateY(-50%);
// &.active {
// display: block;
// }
// }
// }
.ant-btn {
&:hover {
.designable-bar {
display: block;
@ -8,14 +27,27 @@
}
.designable-bar {
display: none;
background: #fff;
z-index: 2;
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%);
top: -1px;
right: -1px;
left: -1px;
bottom: -1px;
border-radius: 2px;
border: 2px solid #1890ff;
&.active {
display: block;
}
.designable-bar-actions {
position: absolute;
right: 0;
line-height: 1rem;
background-color: #1890ff;
color: #fff;
z-index: 10;
padding: 0 3px;
.anticon {
font-size: 10px;
}
}
}
}

View File

@ -75,10 +75,6 @@ const row = (schema) => {
[`gb_${uid()}`]: {
type: 'void',
'x-component': 'Grid.Block',
'x-component-props': {
DesignableBar: `${component}.DesignableBar`,
},
'x-designable-bar': `${component}.DesignableBar`,
properties: {
[`gbn_${uid()}`]: schema,
},
@ -394,6 +390,7 @@ AddNew.FormItem = observer((props) => {
name: `f_${uid()}`,
title: `字段${uid()}`,
'x-decorator': 'FormItem',
'x-designable-bar': 'FormItem.DesignableBar',
'x-component': 'Input',
});
console.log({ rowData });

View File

@ -41,11 +41,19 @@ const schema = {
interface: 'icon',
type: 'string',
title: `阅读模式`,
name: 'name2',
'x-read-pretty': true,
'x-decorator': 'FormItem',
'x-component': 'ColorSelect',
}
},
designable: {
interface: 'icon',
type: 'string',
title: `配置模式`,
// 'x-read-pretty': true,
'x-decorator': 'FormItem',
'x-designable-bar': 'FormItem.DesignableBar',
'x-component': 'ColorSelect',
},
}
};

View File

@ -0,0 +1,71 @@
import React, { useContext, useState } from 'react';
import { connect, mapProps, mapReadPretty, SchemaOptionsContext, useField, useFieldSchema } from '@formily/react';
import { FormItem as FormilyFormItem } from '@formily/antd';
import { Dropdown, Menu } from 'antd';
import classNames from 'classnames';
import { MenuOutlined } from '@ant-design/icons';
import './style.less';
import get from 'lodash/get';
import { BlockContext } from '../SchemaField';
function Blank() {
return null;
}
function useDesignableBar() {
const schema = useFieldSchema();
const options = useContext(SchemaOptionsContext);
const DesignableBar = get(options.components, schema['x-designable-bar']);
return {
DesignableBar: DesignableBar || Blank,
};
}
export const FormItem: any = connect((props) => {
const { DesignableBar } = useDesignableBar();
const { dragRef } = useContext(BlockContext);
return (
<div className={'designable-form-item'}>
<FormilyFormItem {...props} />
{dragRef && <div ref={dragRef}>Drag</div>}
<DesignableBar/>
</div>
);
});
FormItem.DesignableBar = () => {
const field = useField();
const [visible, setVisible] = useState(false);
return (
<div className={classNames('designable-bar', { active: visible })}>
<span
onClick={(e) => {
e.stopPropagation();
}}
className={classNames('designable-bar-actions', { active: visible })}
>
<Dropdown
trigger={['click']}
visible={visible}
onVisibleChange={(visible) => {
setVisible(visible);
}}
overlay={
<Menu>
<Menu.Item
onClick={(e) => {
setVisible(false);
}}
>
</Menu.Item>
</Menu>
}
>
<MenuOutlined />
</Dropdown>
</span>
</div>
);
};

View File

@ -0,0 +1,36 @@
.designable-form-item {
position: relative;
&:hover {
.designable-bar {
display: block;
}
}
.designable-bar {
z-index: 1;
pointer-events: none;
display: none;
position: absolute;
top: 0;
right: -0;
left: -0;
bottom: -0;
border-radius: 2px;
border: 2px solid #1890ff;
&.active {
display: block;
}
.designable-bar-actions {
pointer-events: auto;
position: absolute;
right: 0;
line-height: 1rem;
background-color: #1890ff;
color: #fff;
z-index: 10;
padding: 0 3px;
.anticon {
font-size: 10px;
}
}
}
}

View File

@ -1,4 +1,4 @@
import React, { useState, useContext } from 'react';
import React, { useState, useContext, createContext } from 'react';
import { useDrag, mergeRefs, useDrop } from './DND';
import classNames from 'classnames';
import {
@ -17,6 +17,7 @@ import {
DeleteOutlined,
} from '@ant-design/icons';
import get from 'lodash/get';
import { BlockContext } from '../SchemaField';
export const Block = observer((props: any) => {
const { children, title, DesignableBar } = props;
@ -50,6 +51,8 @@ export const Block = observer((props: any) => {
console.log({ DesignableBarComponent, DesignableBar });
const { addBlock } = useSchemaQuery();
console.log({ children });
return (
<div
data-type={'block'}
@ -57,10 +60,12 @@ export const Block = observer((props: any) => {
className={classNames('block', { 'top-half': onTopHalf, hover: isOver })}
// style={{ textAlign: 'center', lineHeight: '60px', background: '#f1f1f1' }}
>
{DesignableBarComponent && (
<DefaultActionBar DesignableBarComponent={DesignableBarComponent} dragRef={dragRef} />
)}
<BlockContext.Provider value={{ dragRef }}>
{children}
</BlockContext.Provider>
{/* {DesignableBarComponent && (
<DefaultActionBar DesignableBarComponent={DesignableBarComponent} dragRef={dragRef} />
)} */}
</div>
);
});

View File

@ -30,7 +30,7 @@ const schema = {
menu1: {
type: 'void',
'x-component': 'Menu',
// 'x-decorator': 'Menu.Designable',
'x-designable-bar': 'Menu.DesignableBar',
'x-component-props': {
mode: 'horizontal',
},
@ -124,7 +124,7 @@ const schema = {
export default () => {
return (
<SchemaBlock schema={schema} />
<div style={{width: 200}}><SchemaBlock schema={schema} /></div>
);
};
```

View File

@ -3,6 +3,7 @@ import React, {
createContext,
useContext,
useEffect,
useRef,
useState,
} from 'react';
import {
@ -14,6 +15,7 @@ import {
useFieldSchema,
RecursionField,
Schema,
SchemaOptionsContext,
} from '@formily/react';
import {
Menu as AntdMenu,
@ -49,20 +51,44 @@ import {
} from '@ant-design/icons';
import './style.less';
import { Icon } from '../icon-picker';
import {
useHistory,
} from 'react-router-dom';
import { useHistory } from 'react-router-dom';
import cls from 'classnames';
export type MenuType = React.FC<MenuProps & { hideSubMenu?: boolean }> & {
Item?: React.FC<MenuItemProps>;
SubMenu?: React.FC<SubMenuProps>;
Divider?: React.FC<DividerProps>;
Designable?: React.FC<any>;
DesignableBar?: React.FC<any>;
AddNew?: React.FC<any>;
Link?: React.FC<MenuItemProps>;
Url?: React.FC<MenuItemProps & { url: string }>;
};
function Blank() {
return null;
}
function useDesignableBar() {
const schema = useFieldSchema();
let s = schema;
let DesignableBarName;
while (s.parent) {
if (s.parent['x-component'] === 'Menu') {
DesignableBarName = s.parent['x-designable-bar'];
break;
}
s = s.parent;
}
const options = useContext(SchemaOptionsContext);
const DesignableBar = DesignableBarName ? get(options.components, DesignableBarName) : null;
return {
DesignableBar: DesignableBar || Blank,
};
}
export function removeProperty(property: Schema) {
property.parent.removeProperty(property.name);
}
@ -98,7 +124,7 @@ export function useSchemaQuery(segments?: any[]) {
const getSchemaByPath = (path) => {
let s: Schema = context;
const names = [...path];
console.log('names', [...names], path, context)
console.log('names', [...names], path, context);
// names.shift();
while (s && names.length) {
const name = names.shift();
@ -247,21 +273,28 @@ const AddNewAction = () => {
const SettingAction = () => {
const field = useField();
const [visible, setVisible] = useState(false);
const { schema, refresh, remove, insertBefore, insertAfter, appendChild } =
useSchemaQuery();
const text = schema['x-component'] === 'Menu.SubMenu' ? '当前菜单组' : '当前菜单';
const text =
schema['x-component'] === 'Menu.SubMenu' ? '当前菜单组' : '当前菜单';
return (
<div className={cls('designable-bar', { active: visible })}>
<div
onClick={(e) => {
e.stopPropagation();
e.preventDefault();
}}
className={'designable-action'}
className={'designable-bar-actions'}
>
<Dropdown
overlayStyle={{
minWidth: 150,
}}
visible={visible}
onVisibleChange={(visible) => {
setVisible(visible);
}}
trigger={['click']}
overlay={
<AntdMenu>
@ -404,7 +437,10 @@ const SettingAction = () => {
<LinkOutlined />
</AntdMenu.Item>
</AntdMenu.SubMenu>
<AntdMenu.SubMenu icon={<ArrowDownOutlined />} title={`${text}`}>
<AntdMenu.SubMenu
icon={<ArrowDownOutlined />}
title={`${text}`}
>
<AntdMenu.Item
onClick={() => {
FormDialog(`新建菜单`, () => {
@ -500,7 +536,10 @@ const SettingAction = () => {
</AntdMenu.Item>
</AntdMenu.SubMenu>
{schema['x-component'] === 'Menu.SubMenu' ? (
<AntdMenu.SubMenu icon={<ArrowRightOutlined />} title={`${text}`}>
<AntdMenu.SubMenu
icon={<ArrowRightOutlined />}
title={`${text}`}
>
<AntdMenu.Item
onClick={() => {
FormDialog(`新建菜单`, () => {
@ -614,6 +653,7 @@ const SettingAction = () => {
<MenuOutlined />
</Dropdown>
</div>
</div>
);
};
@ -680,27 +720,424 @@ Menu.Link = observer((props) => {
Menu.Item = observer((props) => {
const field = useField();
const { DesignableBar } = useDesignableBar();
const { schema, refresh } = useSchemaQuery();
return (
<AntdMenu.Item
{...props}
onMouseEnter={(e) => {
const el = e.domEvent.target as HTMLElement;
console.log(
'onMouseEnter',
el.offsetTop,
el.offsetLeft,
el.clientWidth,
el.clientHeight,
);
}}
onMouseLeave={() => {
console.log('onMouseLeave');
}}
schema={schema}
// @ts-ignore
eventKey={schema.name}
key={schema.name}
icon={props.icon ? <Icon type={props.icon as string} /> : undefined}
>
{field.title} <SettingAction />
{field.title}
<DesignableBar />
</AntdMenu.Item>
);
});
// Menu
Menu.Designable = (props) => {
return props.children;
Menu.DesignableBar = (props) => {
const field = useField();
const [visible, setVisible] = useState(false);
const { schema, refresh, remove, insertBefore, insertAfter, appendChild } =
useSchemaQuery();
const text =
schema['x-component'] === 'Menu.SubMenu' ? '当前菜单组' : '当前菜单';
return (
<div className={cls('designable-bar', { active: visible })}>
<div
onClick={(e) => {
e.stopPropagation();
e.preventDefault();
}}
className={'designable-bar-actions'}
>
<Dropdown
overlayStyle={{
minWidth: 150,
}}
visible={visible}
onVisibleChange={(visible) => {
setVisible(visible);
}}
trigger={['click']}
overlay={
<AntdMenu>
<AntdMenu.Item
onClick={() => {
FormDialog('编辑菜单', () => {
return (
<FormLayout layout={'vertical'}>
<SchemaField>
<SchemaField.String
name="title"
required
title="菜单名称"
x-decorator="FormItem"
x-component="Input"
/>
<SchemaField.String
name=".icon"
title="图标"
x-decorator="FormItem"
x-component="IconPicker"
/>
</SchemaField>
{/* <FormDialog.Footer>
<span style={{ marginLeft: 4 }}></span>
</FormDialog.Footer> */}
</FormLayout>
);
})
.open({
initialValues: {
title: schema.title,
icon: schema['x-component-props']?.['icon'],
},
})
.then((data) => {
schema.title = data.title;
const componentProps = schema['x-component-props'] || {};
componentProps['icon'] = data.icon;
field.setTitle(data.title);
field.setComponentProps(componentProps);
refresh();
});
}}
>
<EditOutlined />
</AntdMenu.Item>
<AntdMenu.Item>
<ArrowRightOutlined />
</AntdMenu.Item>
<AntdMenu.Divider />
<AntdMenu.SubMenu icon={<ArrowUpOutlined />} title={`${text}`}>
<AntdMenu.Item
onClick={() => {
FormDialog(`新建菜单`, () => {
return (
<FormLayout layout={'vertical'}>
<SchemaField>
<SchemaField.String
name="title"
required
title="名称"
x-decorator="FormItem"
x-component="Input"
/>
<SchemaField.String
name="icon"
title="图标"
x-decorator="FormItem"
x-component="IconPicker"
/>
</SchemaField>
</FormLayout>
);
})
.open({})
.then((data) => {
insertBefore({
name: `m_${uid()}`,
type: 'void',
title: data.title,
'x-component': 'Menu.Item',
'x-component-props': {
icon: data.icon,
},
});
});
}}
style={{ minWidth: 150 }}
>
<MenuOutlined />
</AntdMenu.Item>
<AntdMenu.Item
onClick={() => {
FormDialog(`新建菜单组`, () => {
return (
<FormLayout layout={'vertical'}>
<SchemaField>
<SchemaField.String
name="title"
required
title="名称"
x-decorator="FormItem"
x-component="Input"
/>
<SchemaField.String
name="icon"
title="图标"
x-decorator="FormItem"
x-component="IconPicker"
/>
</SchemaField>
</FormLayout>
);
})
.open({})
.then((data) => {
insertBefore({
name: `m_${uid()}`,
type: 'void',
title: data.title,
'x-component': 'Menu.SubMenu',
'x-component-props': {
icon: data.icon,
},
properties: {
[`m_${uid()}`]: {
type: 'void',
title: `菜单 ${uid()}`,
'x-component': 'Menu.Item',
},
},
});
});
}}
>
<GroupOutlined />
</AntdMenu.Item>
<AntdMenu.Item>
<LinkOutlined />
</AntdMenu.Item>
</AntdMenu.SubMenu>
<AntdMenu.SubMenu
icon={<ArrowDownOutlined />}
title={`${text}`}
>
<AntdMenu.Item
onClick={() => {
FormDialog(`新建菜单`, () => {
return (
<FormLayout layout={'vertical'}>
<SchemaField>
<SchemaField.String
name="title"
required
title="名称"
x-decorator="FormItem"
x-component="Input"
/>
<SchemaField.String
name="icon"
title="图标"
x-decorator="FormItem"
x-component="IconPicker"
/>
</SchemaField>
</FormLayout>
);
})
.open({})
.then((data) => {
insertAfter(
new Schema({
name: `m_${uid()}`,
type: 'void',
title: data.title,
'x-component': 'Menu.Item',
'x-component-props': {
icon: data.icon,
},
}),
);
});
}}
style={{ minWidth: 150 }}
>
<MenuOutlined />
</AntdMenu.Item>
<AntdMenu.Item
onClick={() => {
FormDialog(`新建菜单组`, () => {
return (
<FormLayout layout={'vertical'}>
<SchemaField>
<SchemaField.String
name="title"
required
title="名称"
x-decorator="FormItem"
x-component="Input"
/>
<SchemaField.String
name="icon"
title="图标"
x-decorator="FormItem"
x-component="IconPicker"
/>
</SchemaField>
</FormLayout>
);
})
.open({})
.then((data) => {
insertAfter(
new Schema({
name: `m_${uid()}`,
type: 'void',
title: data.title,
'x-component': 'Menu.SubMenu',
'x-component-props': {
icon: data.icon,
},
properties: {
[`m_${uid()}`]: {
type: 'void',
title: `菜单 ${uid()}`,
'x-component': 'Menu.Item',
},
},
}),
);
});
}}
>
<GroupOutlined />
</AntdMenu.Item>
<AntdMenu.Item>
<LinkOutlined />
</AntdMenu.Item>
</AntdMenu.SubMenu>
{schema['x-component'] === 'Menu.SubMenu' ? (
<AntdMenu.SubMenu
icon={<ArrowRightOutlined />}
title={`${text}`}
>
<AntdMenu.Item
onClick={() => {
FormDialog(`新建菜单`, () => {
return (
<FormLayout layout={'vertical'}>
<SchemaField>
<SchemaField.String
name="title"
required
title="名称"
x-decorator="FormItem"
x-component="Input"
/>
<SchemaField.String
name="icon"
title="图标"
x-decorator="FormItem"
x-component="IconPicker"
/>
</SchemaField>
</FormLayout>
);
})
.open({})
.then((data) => {
appendChild(
new Schema({
name: `m_${uid()}`,
type: 'void',
title: data.title,
'x-component': 'Menu.Item',
'x-component-props': {
icon: data.icon,
},
}),
);
});
}}
style={{ minWidth: 150 }}
>
<MenuOutlined />
</AntdMenu.Item>
<AntdMenu.Item
onClick={() => {
FormDialog(`新建菜单组`, () => {
return (
<FormLayout layout={'vertical'}>
<SchemaField>
<SchemaField.String
name="title"
required
title="名称"
x-decorator="FormItem"
x-component="Input"
/>
<SchemaField.String
name="icon"
title="图标"
x-decorator="FormItem"
x-component="IconPicker"
/>
</SchemaField>
</FormLayout>
);
})
.open({})
.then((data) => {
appendChild(
new Schema({
name: `m_${uid()}`,
type: 'void',
title: data.title,
'x-component': 'Menu.SubMenu',
'x-component-props': {
icon: data.icon,
},
properties: {
[`m_${uid()}`]: {
type: 'void',
title: `菜单 ${uid()}`,
'x-component': 'Menu.Item',
},
},
}),
);
});
}}
>
<GroupOutlined />
</AntdMenu.Item>
<AntdMenu.Item>
<LinkOutlined />
</AntdMenu.Item>
</AntdMenu.SubMenu>
) : null}
<AntdMenu.Divider />
<AntdMenu.Item
onClick={() => {
Modal.confirm({
title: '删除菜单',
content: '确认删除此菜单项吗?',
onOk: remove,
});
}}
>
<DeleteOutlined />
</AntdMenu.Item>
</AntdMenu>
}
>
<MenuOutlined />
</Dropdown>
</div>
</div>
);
};
Menu.SubMenu = observer((props) => {
const { DesignableBar } = useDesignableBar();
const schema = useFieldSchema();
let s = schema;
let hideSubMenu;
@ -721,7 +1158,7 @@ Menu.SubMenu = observer((props) => {
schema={schema}
title={
<>
{schema.title} <SettingAction />
{schema.title} <DesignableBar />
</>
}
eventKey={schema.name}

View File

@ -1,34 +1,62 @@
.designable-action {
position: absolute;
right: 16px;
display: none;
z-index: 10;
}
.ant-menu-dark.ant-menu-horizontal {
width: 100%;
}
.ant-menu-dark .ant-menu-item-active .designable-action {
background-color: #001529;
.ant-menu-dark .ant-menu-item-active .designable-bar {
display: inline-block;
}
.ant-menu-dark .ant-menu-item-active:hover .designable-action,
.ant-menu-dark .ant-menu-item-active.ant-menu-item-selected .designable-action {
.ant-menu-dark .ant-menu-item-active:hover .designable-bar,
.ant-menu-dark .ant-menu-item-active.ant-menu-item-selected .designable-bar {
display: inline-block;
}
.ant-menu-light .ant-menu-submenu-active > .ant-menu-submenu-title .designable-bar,
.ant-menu-light .ant-menu-item-active .designable-bar {
display: inline-block;
}
// .ant-menu-sub.ant-menu-inline .ant-menu-submenu-active > .ant-menu-submenu-title .designable-action,
// .ant-menu-sub.ant-menu-inline .ant-menu-item-active .designable-action {
// background-color: #fafafa;
// }
// .ant-menu-light .ant-menu-item-selected .designable-action {
// background-color: #e6f7ff !important;
// }
.ant-menu {
.designable-bar {
display: none;
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
border: 2px solid #1890ff;
&.active {
display: block;
}
.designable-bar-actions {
position: absolute;
right: 0;
line-height: 1rem;
background-color: #1890ff;
display: inline-block;
color: #fff;
font-size: 12px;
z-index: 10;
.anticon {
font-size: 10px;
}
}
}
}
.ant-menu-light .ant-menu-submenu-active > .ant-menu-submenu-title .designable-action,
.ant-menu-light .ant-menu-item-active .designable-action {
background-color: #fff;
display: inline-block;
}
.ant-menu-sub.ant-menu-inline .ant-menu-submenu-active > .ant-menu-submenu-title .designable-action,
.ant-menu-sub.ant-menu-inline .ant-menu-item-active .designable-action {
background-color: #fafafa;
}
.ant-menu-light .ant-menu-item-selected .designable-action {
background-color: #e6f7ff !important;
.ant-menu-submenu-horizontal > .ant-menu-submenu-title {
.designable-bar {
position: absolute;
left: -20px;
right: -20px;
border: 2px solid #1890ff;
}
}

View File

@ -189,11 +189,11 @@ function useMenuSchema({ schema, selectedKey }) {
// const topMenuSchema = new Schema(cloneDeep(schema.toJSON()));
let selected = find(schema).shift() as Schema;
let selected = find(topMenuSchema).shift() as Schema;
console.log({ topMenuSchema, selected, schema });
if (selected.properties) {
if (selected && selected.properties) {
const findChild = (properties) => {
const keys = Object.keys(properties || {});
const firstKey = keys.shift();
@ -420,8 +420,6 @@ function Content({ activeKey }) {
export function AdminLayout({ route, children }: any) {
const match = useRouteMatch<any>();
console.log('match.params', match.params);
const { data = {}, loading } = useRequest(
`/api/blocks:getSchema/${route.blockId}`,
{