improved designable styling
This commit is contained in:
parent
da418720aa
commit
2ba5e6f76f
@ -349,7 +349,6 @@ const schema: ISchema = {
|
||||
'x-component-props': {
|
||||
className: 'nb-table-operation',
|
||||
},
|
||||
'x-designable-bar': 'Table.Operation.DesignableBar',
|
||||
properties: {
|
||||
[uid()]: {
|
||||
type: 'void',
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { useContext, useEffect } from 'react';
|
||||
import { Button, Dropdown, Menu } from 'antd';
|
||||
import { Button, Dropdown, Menu, Spin } from 'antd';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { request } from '../../schemas';
|
||||
import { useRequest } from 'ahooks';
|
||||
@ -25,7 +25,7 @@ export function SystemSettingsProvider(props) {
|
||||
);
|
||||
return (
|
||||
<SystemSettingsContext.Provider value={{ service, resource }}>
|
||||
{props.children}
|
||||
{service.loading ? <Spin /> : props.children}
|
||||
</SystemSettingsContext.Provider>
|
||||
);
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ function LayoutWithMenu(props: LayoutWithMenuProps) {
|
||||
};
|
||||
return (
|
||||
<Layout>
|
||||
<Layout.Header style={{ display: 'flex' }}>
|
||||
<Layout.Header className={'site-header'} style={{ display: 'flex' }}>
|
||||
<SiteTitle />
|
||||
<SchemaRenderer
|
||||
schema={schema}
|
||||
|
@ -50,8 +50,9 @@
|
||||
|
||||
.nb-designable-toggle {
|
||||
background: none !important;
|
||||
border-radius: 0 !important;
|
||||
&.active {
|
||||
background: #1890ff !important;
|
||||
// background: #faad14 !important;
|
||||
}
|
||||
}
|
||||
|
||||
@ -76,3 +77,23 @@
|
||||
padding-right: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.site-header {
|
||||
.ant-menu.ant-menu-dark .ant-menu-item-selected, .ant-menu-submenu-popup.ant-menu-dark .ant-menu-item-selected {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
.ant-menu-dark.ant-menu-horizontal > .ant-menu-item:hover {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
.ant-btn {
|
||||
color: rgba(255, 255, 255, 0.65) !important;
|
||||
&.nb-designable-toggle:hover {
|
||||
color: #fff !important;
|
||||
background-color: #F18B62 !important
|
||||
}
|
||||
}
|
||||
.ant-btn:hover {
|
||||
color: #fff !important;
|
||||
background-color: rgba(255, 255, 255, 0.1) !important;
|
||||
}
|
||||
}
|
@ -214,7 +214,7 @@ function AddActionButton() {
|
||||
</Menu>
|
||||
}
|
||||
>
|
||||
<Button style={{ marginLeft: 8 }} type={'dashed'} icon={<PlusOutlined />}>
|
||||
<Button className={'designable-btn designable-btn-dash'} style={{ marginLeft: 8 }} type={'dashed'} icon={<PlusOutlined />}>
|
||||
配置操作
|
||||
</Button>
|
||||
</Dropdown>
|
||||
|
@ -339,101 +339,107 @@ Action.DesignableBar = (props: any) => {
|
||||
}}
|
||||
className={cls('designable-bar-actions', { active: visible })}
|
||||
>
|
||||
<DragHandle />
|
||||
<Dropdown
|
||||
trigger={['click']}
|
||||
visible={visible}
|
||||
onVisibleChange={(visible) => {
|
||||
setVisible(visible);
|
||||
}}
|
||||
overlay={
|
||||
<Menu>
|
||||
<Menu.Item
|
||||
onClick={async (e) => {
|
||||
const values = await FormDialog('修改名称和图标', () => {
|
||||
return (
|
||||
<FormLayout layout={'vertical'}>
|
||||
<SchemaField
|
||||
schema={{
|
||||
type: 'object',
|
||||
properties: {
|
||||
title: {
|
||||
type: 'string',
|
||||
title: '按钮名称',
|
||||
required: true,
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Input',
|
||||
<Space size={2}>
|
||||
<DragHandle />
|
||||
<Dropdown
|
||||
trigger={['click']}
|
||||
visible={visible}
|
||||
onVisibleChange={(visible) => {
|
||||
setVisible(visible);
|
||||
}}
|
||||
overlay={
|
||||
<Menu>
|
||||
<Menu.Item
|
||||
onClick={async (e) => {
|
||||
const values = await FormDialog('修改名称和图标', () => {
|
||||
return (
|
||||
<FormLayout layout={'vertical'}>
|
||||
<SchemaField
|
||||
schema={{
|
||||
type: 'object',
|
||||
properties: {
|
||||
title: {
|
||||
type: 'string',
|
||||
title: '按钮名称',
|
||||
required: true,
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Input',
|
||||
},
|
||||
icon: {
|
||||
type: 'string',
|
||||
title: '按钮图标',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'IconPicker',
|
||||
},
|
||||
},
|
||||
icon: {
|
||||
type: 'string',
|
||||
title: '按钮图标',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'IconPicker',
|
||||
},
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</FormLayout>
|
||||
);
|
||||
}).open({
|
||||
initialValues: {
|
||||
title: schema['title'],
|
||||
icon: schema['x-component-props']?.['icon'],
|
||||
},
|
||||
});
|
||||
schema['title'] = values.title;
|
||||
schema['x-component-props']['icon'] = values.icon;
|
||||
field.componentProps.icon = values.icon;
|
||||
field.title = values.title;
|
||||
updateSchema(schema);
|
||||
refresh();
|
||||
}}
|
||||
>
|
||||
修改名称和图标
|
||||
</Menu.Item>
|
||||
{isPopup && (
|
||||
<Menu.Item>
|
||||
在{' '}
|
||||
<Select
|
||||
bordered={false}
|
||||
size={'small'}
|
||||
defaultValue={'Action.Modal'}
|
||||
onChange={(value) => {
|
||||
const s = Object.values(schema.properties).shift();
|
||||
s['x-component'] = value;
|
||||
refresh();
|
||||
updateSchema(s);
|
||||
}}
|
||||
>
|
||||
<Select.Option value={'Action.Modal'}>对话框</Select.Option>
|
||||
<Select.Option value={'Action.Drawer'}>抽屉</Select.Option>
|
||||
<Select.Option value={'Action.Window'}>
|
||||
浏览器窗口
|
||||
</Select.Option>
|
||||
</Select>{' '}
|
||||
内打开
|
||||
}}
|
||||
/>
|
||||
</FormLayout>
|
||||
);
|
||||
}).open({
|
||||
initialValues: {
|
||||
title: schema['title'],
|
||||
icon: schema['x-component-props']?.['icon'],
|
||||
},
|
||||
});
|
||||
schema['title'] = values.title;
|
||||
schema['x-component-props']['icon'] = values.icon;
|
||||
field.componentProps.icon = values.icon;
|
||||
field.title = values.title;
|
||||
updateSchema(schema);
|
||||
refresh();
|
||||
}}
|
||||
>
|
||||
修改名称和图标
|
||||
</Menu.Item>
|
||||
)}
|
||||
<Menu.Divider />
|
||||
<Menu.Item
|
||||
onClick={async () => {
|
||||
const displayName =
|
||||
schema?.['x-decorator-props']?.['displayName'];
|
||||
const data = remove();
|
||||
await removeSchema(data);
|
||||
if (displayName) {
|
||||
displayed.remove(displayName);
|
||||
}
|
||||
setVisible(false);
|
||||
}}
|
||||
>
|
||||
移除
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
}
|
||||
>
|
||||
<MenuOutlined />
|
||||
</Dropdown>
|
||||
{isPopup && (
|
||||
<Menu.Item>
|
||||
在{' '}
|
||||
<Select
|
||||
bordered={false}
|
||||
size={'small'}
|
||||
defaultValue={'Action.Modal'}
|
||||
onChange={(value) => {
|
||||
const s = Object.values(schema.properties).shift();
|
||||
s['x-component'] = value;
|
||||
refresh();
|
||||
updateSchema(s);
|
||||
}}
|
||||
>
|
||||
<Select.Option value={'Action.Modal'}>
|
||||
对话框
|
||||
</Select.Option>
|
||||
<Select.Option value={'Action.Drawer'}>
|
||||
抽屉
|
||||
</Select.Option>
|
||||
<Select.Option value={'Action.Window'}>
|
||||
浏览器窗口
|
||||
</Select.Option>
|
||||
</Select>{' '}
|
||||
内打开
|
||||
</Menu.Item>
|
||||
)}
|
||||
<Menu.Divider />
|
||||
<Menu.Item
|
||||
onClick={async () => {
|
||||
const displayName =
|
||||
schema?.['x-decorator-props']?.['displayName'];
|
||||
const data = remove();
|
||||
await removeSchema(data);
|
||||
if (displayName) {
|
||||
displayed.remove(displayName);
|
||||
}
|
||||
setVisible(false);
|
||||
}}
|
||||
>
|
||||
移除
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
}
|
||||
>
|
||||
<MenuOutlined />
|
||||
</Dropdown>
|
||||
</Space>
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
|
@ -935,7 +935,7 @@ AddNew.CardItem = observer((props: any) => {
|
||||
{ghost ? (
|
||||
<PlusOutlined />
|
||||
) : (
|
||||
<Button type={'dashed'} icon={<PlusOutlined />}>
|
||||
<Button type={'dashed'} className={'designable-btn designable-btn-dash'} icon={<PlusOutlined />}>
|
||||
新增区块
|
||||
</Button>
|
||||
)}
|
||||
@ -1122,7 +1122,7 @@ AddNew.FormItem = observer((props: any) => {
|
||||
{ghost ? (
|
||||
<PlusOutlined />
|
||||
) : (
|
||||
<Button type={'dashed'} icon={<SettingOutlined />}>
|
||||
<Button type={'dashed'} className={'designable-btn designable-btn-dash'} icon={<SettingOutlined />}>
|
||||
配置字段
|
||||
</Button>
|
||||
)}
|
||||
@ -1326,7 +1326,7 @@ AddNew.PaneItem = observer((props: any) => {
|
||||
{ghost ? (
|
||||
<PlusOutlined />
|
||||
) : (
|
||||
<Button block type={'dashed'} icon={<PlusOutlined />}>
|
||||
<Button block className={'designable-btn designable-btn-dash'} type={'dashed'} icon={<PlusOutlined />}>
|
||||
新增区块
|
||||
</Button>
|
||||
)}
|
||||
|
@ -27,9 +27,6 @@
|
||||
color: #fff;
|
||||
z-index: 10;
|
||||
padding: 0 3px;
|
||||
.ant-space {
|
||||
gap: 1px !important;
|
||||
}
|
||||
.anticon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
|
@ -1,8 +1,71 @@
|
||||
@bgcolor: #F18B62;
|
||||
|
||||
.designable-info {
|
||||
position: absolute;
|
||||
font-size: 12px;
|
||||
background: #1890ff;
|
||||
background: @bgcolor;
|
||||
color: #fff;
|
||||
padding: 0 5px;
|
||||
line-height: 16px;
|
||||
height: 16px;
|
||||
border-bottom-right-radius: 2px;
|
||||
}
|
||||
|
||||
.designable-bar {
|
||||
border-radius: 1px !important;
|
||||
border: 2px solid @bgcolor !important;
|
||||
.designable-bar-actions {
|
||||
padding: 0 !important;
|
||||
background: none !important;
|
||||
display: flex !important;
|
||||
right: 2px !important;
|
||||
// .ant-space-item {
|
||||
// margin: 0 !important;
|
||||
// }
|
||||
.ant-space {
|
||||
gap: 2px !important;
|
||||
}
|
||||
.anticon {
|
||||
width: 16px !important;
|
||||
height: 16px !important;
|
||||
vertical-align: top;
|
||||
line-height: 16px !important;
|
||||
// font-size: 10px;
|
||||
// display: inline-flex;
|
||||
background-color: @bgcolor !important;
|
||||
border-bottom-left-radius: 1px;
|
||||
border-bottom-right-radius: 1px;
|
||||
// margin-left: 0 !important;
|
||||
// margin-right: 2px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.designable-btn-dash {
|
||||
border-color: @bgcolor !important;
|
||||
color: @bgcolor !important;
|
||||
}
|
||||
|
||||
.nb-add-new-menu-item.menu-mode-horizontal.designable {
|
||||
color: @bgcolor !important;
|
||||
border: 1px dashed !important;
|
||||
height: 32px !important;
|
||||
// &:hover {
|
||||
// color: #fff !important;
|
||||
// background: @bgcolor !important;
|
||||
// }
|
||||
// &:active {
|
||||
// color: #fff !important;
|
||||
// background: @bgcolor !important;
|
||||
// }
|
||||
}
|
||||
|
||||
.ant-menu-item-group.nb-menu-add-new {
|
||||
.menu-mode-horizontal {
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.nb-designable-toggle.active {
|
||||
background: @bgcolor !important;
|
||||
}
|
@ -62,7 +62,7 @@ export const FieldDesignableBar = observer((props) => {
|
||||
}}
|
||||
className={cls('designable-bar-actions', { active: visible })}
|
||||
>
|
||||
<Space size={'small'}>
|
||||
<Space size={2}>
|
||||
<AddNew.FormItem defaultAction={'insertAfter'} ghost />
|
||||
{dragRef && <DragOutlined ref={dragRef} />}
|
||||
<Dropdown
|
||||
|
@ -29,6 +29,7 @@ import {
|
||||
Dropdown,
|
||||
Modal,
|
||||
Button,
|
||||
Space,
|
||||
} from 'antd';
|
||||
import { uid } from '@formily/shared';
|
||||
import cls from 'classnames';
|
||||
@ -97,7 +98,7 @@ const SideMenu = (props: any) => {
|
||||
<Button
|
||||
block
|
||||
type={'dashed'}
|
||||
className={`nb-add-new-menu-item menu-mode-inline`}
|
||||
className={`nb-add-new-menu-item menu-mode-inline designable-btn designable-btn-dash`}
|
||||
>
|
||||
<PlusOutlined />
|
||||
</Button>
|
||||
@ -207,7 +208,7 @@ export const Menu: any = observer((props: any) => {
|
||||
<Menu.AddNew key={uid()} path={path}>
|
||||
{/* <PlusOutlined className={'nb-add-new-icon'} /> */}
|
||||
<Button
|
||||
className={`nb-add-new-menu-item menu-mode-${
|
||||
className={`designable-btn designable-btn-dash nb-add-new-menu-item designable menu-mode-${
|
||||
mode === 'mix' ? 'horizontal' : mode
|
||||
}`}
|
||||
block
|
||||
@ -660,350 +661,357 @@ Menu.DesignableBar = (props) => {
|
||||
}}
|
||||
className={'designable-bar-actions'}
|
||||
>
|
||||
<DragHandle />
|
||||
<Dropdown
|
||||
overlayStyle={{
|
||||
minWidth: 150,
|
||||
}}
|
||||
trigger={['click']}
|
||||
overlay={
|
||||
<AntdMenu
|
||||
onClick={async (info) => {
|
||||
if (['update', 'move', 'delete'].includes(info.key)) {
|
||||
return;
|
||||
}
|
||||
const methodLabels = {
|
||||
insertBefore: '之前',
|
||||
insertAfter: '之后',
|
||||
appendChild: '里',
|
||||
};
|
||||
const keys = info.key.split('.');
|
||||
const method = keys.shift();
|
||||
const type = keys.join('.');
|
||||
const config = schemas[type];
|
||||
if (!config) {
|
||||
return;
|
||||
}
|
||||
const values = await FormDialog(
|
||||
`在「${schema.title}」${methodLabels[method]}新建${config.title}`,
|
||||
() => {
|
||||
return (
|
||||
<FormLayout layout={'vertical'}>
|
||||
<SchemaField schema={config.schema} />
|
||||
</FormLayout>
|
||||
);
|
||||
},
|
||||
).open();
|
||||
const methods = {
|
||||
insertAfter,
|
||||
insertBefore,
|
||||
appendChild,
|
||||
};
|
||||
const defaults = generateDefaultSchema(type);
|
||||
const data = methods[method](deepmerge(defaults, values));
|
||||
await createSchema(data);
|
||||
}}
|
||||
>
|
||||
<AntdMenu.Item
|
||||
key={'update'}
|
||||
onClick={async () => {
|
||||
const initialValues = {};
|
||||
Object.keys(formConfig.schema.properties).forEach((name) => {
|
||||
_.set(initialValues, name, get(schema, name));
|
||||
});
|
||||
<Space size={2}>
|
||||
<DragHandle />
|
||||
<Dropdown
|
||||
overlayStyle={{
|
||||
minWidth: 150,
|
||||
}}
|
||||
trigger={['click']}
|
||||
overlay={
|
||||
<AntdMenu
|
||||
onClick={async (info) => {
|
||||
if (['update', 'move', 'delete'].includes(info.key)) {
|
||||
return;
|
||||
}
|
||||
const methodLabels = {
|
||||
insertBefore: '之前',
|
||||
insertAfter: '之后',
|
||||
appendChild: '里',
|
||||
};
|
||||
const keys = info.key.split('.');
|
||||
const method = keys.shift();
|
||||
const type = keys.join('.');
|
||||
const config = schemas[type];
|
||||
if (!config) {
|
||||
return;
|
||||
}
|
||||
const values = await FormDialog(
|
||||
`修改${formConfig.title}`,
|
||||
`在「${schema.title}」${methodLabels[method]}新建${config.title}`,
|
||||
() => {
|
||||
return (
|
||||
<FormLayout layout={'vertical'}>
|
||||
<SchemaField schema={formConfig.schema} />
|
||||
<SchemaField schema={config.schema} />
|
||||
</FormLayout>
|
||||
);
|
||||
},
|
||||
).open({
|
||||
initialValues,
|
||||
});
|
||||
if (values.title) {
|
||||
schema.title = values.title;
|
||||
}
|
||||
const icon = _.get(values, 'x-component-props.icon') || null;
|
||||
schema['x-component-props'] =
|
||||
schema['x-component-props'] || {};
|
||||
schema['x-component-props']['icon'] = icon;
|
||||
field.componentProps['icon'] = icon;
|
||||
refresh();
|
||||
await updateSchema(schema);
|
||||
).open();
|
||||
const methods = {
|
||||
insertAfter,
|
||||
insertBefore,
|
||||
appendChild,
|
||||
};
|
||||
const defaults = generateDefaultSchema(type);
|
||||
const data = methods[method](deepmerge(defaults, values));
|
||||
await createSchema(data);
|
||||
}}
|
||||
>
|
||||
<EditOutlined /> 修改{formConfig.title}
|
||||
</AntdMenu.Item>
|
||||
<AntdMenu.Item
|
||||
key={'move'}
|
||||
onClick={async () => {
|
||||
let menuSchema: Schema;
|
||||
let parent = schema.parent;
|
||||
while (parent) {
|
||||
if (parent['x-component'] === 'Menu') {
|
||||
menuSchema = parent;
|
||||
break;
|
||||
}
|
||||
parent = parent.parent;
|
||||
}
|
||||
|
||||
console.log({ menuSchema });
|
||||
|
||||
const toTreeData = (s: Schema) => {
|
||||
const items = [];
|
||||
Object.keys(s.properties || {}).forEach((name) => {
|
||||
const current = s.properties[name];
|
||||
if (
|
||||
!(current['x-component'] as string).startsWith('Menu.')
|
||||
) {
|
||||
return;
|
||||
}
|
||||
// if (current.name === schema.name) {
|
||||
// return;
|
||||
// }
|
||||
items.push({
|
||||
key: current['key'] || current.name,
|
||||
label: current.title,
|
||||
title: current.title,
|
||||
value: getSchemaPath(current).join('.'),
|
||||
children: toTreeData(current),
|
||||
});
|
||||
<AntdMenu.Item
|
||||
key={'update'}
|
||||
onClick={async () => {
|
||||
const initialValues = {};
|
||||
Object.keys(formConfig.schema.properties).forEach(
|
||||
(name) => {
|
||||
_.set(initialValues, name, get(schema, name));
|
||||
},
|
||||
);
|
||||
const values = await FormDialog(
|
||||
`修改${formConfig.title}`,
|
||||
() => {
|
||||
return (
|
||||
<FormLayout layout={'vertical'}>
|
||||
<SchemaField schema={formConfig.schema} />
|
||||
</FormLayout>
|
||||
);
|
||||
},
|
||||
).open({
|
||||
initialValues,
|
||||
});
|
||||
return items;
|
||||
};
|
||||
if (values.title) {
|
||||
schema.title = values.title;
|
||||
}
|
||||
const icon =
|
||||
_.get(values, 'x-component-props.icon') || null;
|
||||
schema['x-component-props'] =
|
||||
schema['x-component-props'] || {};
|
||||
schema['x-component-props']['icon'] = icon;
|
||||
field.componentProps['icon'] = icon;
|
||||
refresh();
|
||||
await updateSchema(schema);
|
||||
}}
|
||||
>
|
||||
<EditOutlined /> 修改{formConfig.title}
|
||||
</AntdMenu.Item>
|
||||
<AntdMenu.Item
|
||||
key={'move'}
|
||||
onClick={async () => {
|
||||
let menuSchema: Schema;
|
||||
let parent = schema.parent;
|
||||
while (parent) {
|
||||
if (parent['x-component'] === 'Menu') {
|
||||
menuSchema = parent;
|
||||
break;
|
||||
}
|
||||
parent = parent.parent;
|
||||
}
|
||||
|
||||
const dataSource = toTreeData(menuSchema);
|
||||
console.log({ menuSchema });
|
||||
|
||||
const values = await FormDialog(
|
||||
`将「${schema.title}」移动到`,
|
||||
() => {
|
||||
const toTreeData = (s: Schema) => {
|
||||
const items = [];
|
||||
Object.keys(s.properties || {}).forEach((name) => {
|
||||
const current = s.properties[name];
|
||||
if (
|
||||
!(current['x-component'] as string).startsWith(
|
||||
'Menu.',
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
// if (current.name === schema.name) {
|
||||
// return;
|
||||
// }
|
||||
items.push({
|
||||
key: current['key'] || current.name,
|
||||
label: current.title,
|
||||
title: current.title,
|
||||
value: getSchemaPath(current).join('.'),
|
||||
children: toTreeData(current),
|
||||
});
|
||||
});
|
||||
return items;
|
||||
};
|
||||
|
||||
const dataSource = toTreeData(menuSchema);
|
||||
|
||||
const values = await FormDialog(
|
||||
`将「${schema.title}」移动到`,
|
||||
() => {
|
||||
return (
|
||||
<FormLayout layout={'vertical'}>
|
||||
<SchemaField
|
||||
schema={{
|
||||
type: 'object',
|
||||
properties: {
|
||||
path: {
|
||||
type: 'string',
|
||||
title: '目标位置',
|
||||
enum: dataSource,
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'TreeSelect',
|
||||
},
|
||||
method: {
|
||||
type: 'string',
|
||||
default: 'insertAfter',
|
||||
enum: [
|
||||
{ label: '之后', value: 'insertAfter' },
|
||||
{ label: '之前', value: 'insertBefore' },
|
||||
],
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Radio.Group',
|
||||
},
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</FormLayout>
|
||||
);
|
||||
},
|
||||
).open({
|
||||
effects(form) {
|
||||
onFieldChange('path', (field) => {
|
||||
const target = findPropertyByPath(
|
||||
schema.root,
|
||||
// @ts-ignore
|
||||
field.value,
|
||||
);
|
||||
console.log({ field });
|
||||
field.query('method').take((f) => {
|
||||
// @ts-ignore
|
||||
// f.value = 'insertAfter';
|
||||
// @ts-ignore
|
||||
f.dataSource =
|
||||
target['x-component'] === 'Menu.SubMenu'
|
||||
? [
|
||||
{ label: '之后', value: 'insertAfter' },
|
||||
{ label: '之前', value: 'insertBefore' },
|
||||
{ label: '组里', value: 'appendChild' },
|
||||
]
|
||||
: [
|
||||
{ label: '之后', value: 'insertAfter' },
|
||||
{ label: '之前', value: 'insertBefore' },
|
||||
];
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
const methods = {
|
||||
insertAfter,
|
||||
insertBefore,
|
||||
appendChild,
|
||||
};
|
||||
const data = schema.toJSON();
|
||||
remove();
|
||||
const source = methods[values.method](data, values.path);
|
||||
await updateSchema(source);
|
||||
}}
|
||||
>
|
||||
<DragOutlined /> 移动到
|
||||
</AntdMenu.Item>
|
||||
<AntdMenu.Divider />
|
||||
<AntdMenu.SubMenu
|
||||
key={'insertBefore'}
|
||||
icon={<ArrowUpOutlined />}
|
||||
title={'当前菜单项之前'}
|
||||
>
|
||||
<AntdMenu.Item
|
||||
key={'insertBefore.Menu.Link'}
|
||||
icon={<MenuOutlined />}
|
||||
>
|
||||
新建菜单项
|
||||
</AntdMenu.Item>
|
||||
<AntdMenu.Item
|
||||
key={'insertBefore.Menu.SubMenu'}
|
||||
icon={<GroupOutlined />}
|
||||
>
|
||||
新建菜单分组
|
||||
</AntdMenu.Item>
|
||||
<AntdMenu.Item
|
||||
key={'insertBefore.Menu.URL'}
|
||||
icon={<LinkOutlined />}
|
||||
>
|
||||
添加自定义链接
|
||||
</AntdMenu.Item>
|
||||
</AntdMenu.SubMenu>
|
||||
<AntdMenu.SubMenu
|
||||
key={'insertAfter'}
|
||||
icon={<ArrowDownOutlined />}
|
||||
title={'当前菜单项之后'}
|
||||
>
|
||||
<AntdMenu.Item
|
||||
key={'insertAfter.Menu.Link'}
|
||||
icon={<MenuOutlined />}
|
||||
>
|
||||
新建菜单项
|
||||
</AntdMenu.Item>
|
||||
<AntdMenu.Item
|
||||
key={'insertAfter.Menu.SubMenu'}
|
||||
icon={<GroupOutlined />}
|
||||
>
|
||||
新建菜单分组
|
||||
</AntdMenu.Item>
|
||||
<AntdMenu.Item
|
||||
key={'insertAfter.Menu.URL'}
|
||||
icon={<LinkOutlined />}
|
||||
>
|
||||
添加自定义链接
|
||||
</AntdMenu.Item>
|
||||
</AntdMenu.SubMenu>
|
||||
{isSubMenu && (
|
||||
<AntdMenu.SubMenu
|
||||
key={'appendChild'}
|
||||
icon={<ArrowRightOutlined />}
|
||||
title={'当前菜单分组里'}
|
||||
>
|
||||
<AntdMenu.Item
|
||||
key={'appendChild.Menu.Link'}
|
||||
icon={<MenuOutlined />}
|
||||
>
|
||||
新建菜单项
|
||||
</AntdMenu.Item>
|
||||
<AntdMenu.Item
|
||||
key={'appendChild.Menu.SubMenu'}
|
||||
icon={<GroupOutlined />}
|
||||
>
|
||||
新建菜单分组
|
||||
</AntdMenu.Item>
|
||||
<AntdMenu.Item
|
||||
key={'appendChild.Menu.URL'}
|
||||
icon={<LinkOutlined />}
|
||||
>
|
||||
添加自定义链接
|
||||
</AntdMenu.Item>
|
||||
</AntdMenu.SubMenu>
|
||||
)}
|
||||
<AntdMenu.Item
|
||||
icon={<LockOutlined />}
|
||||
onClick={async () => {
|
||||
const loadRoles = async () => {
|
||||
const resource = Resource.make('roles');
|
||||
const data = await resource.list();
|
||||
console.log('loadRoles', data);
|
||||
return data?.data.map((item) => ({
|
||||
label: item.title,
|
||||
value: item.name,
|
||||
}));
|
||||
};
|
||||
const resource = Resource.make({
|
||||
associatedName: 'ui_schemas',
|
||||
associatedKey: schema['key'],
|
||||
resourceName: 'roles',
|
||||
});
|
||||
const uiSchemasRoles = await resource.list();
|
||||
console.log({ uiSchemasRoles });
|
||||
const values = await FormDialog(`设置权限`, () => {
|
||||
return (
|
||||
<FormLayout layout={'vertical'}>
|
||||
<SchemaField
|
||||
scope={{ loadRoles }}
|
||||
schema={{
|
||||
type: 'object',
|
||||
properties: {
|
||||
path: {
|
||||
type: 'string',
|
||||
title: '目标位置',
|
||||
enum: dataSource,
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'TreeSelect',
|
||||
},
|
||||
method: {
|
||||
type: 'string',
|
||||
default: 'insertAfter',
|
||||
enum: [
|
||||
{ label: '之后', value: 'insertAfter' },
|
||||
{ label: '之前', value: 'insertBefore' },
|
||||
roles: {
|
||||
type: 'array',
|
||||
title: '权限组',
|
||||
'x-reactions': [
|
||||
'{{useAsyncDataSource(loadRoles)}}',
|
||||
],
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Radio.Group',
|
||||
'x-decorator': 'FormilyFormItem',
|
||||
'x-component': 'Select',
|
||||
'x-component-props': {
|
||||
mode: 'tags',
|
||||
},
|
||||
},
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</FormLayout>
|
||||
);
|
||||
},
|
||||
).open({
|
||||
effects(form) {
|
||||
onFieldChange('path', (field) => {
|
||||
const target = findPropertyByPath(
|
||||
schema.root,
|
||||
// @ts-ignore
|
||||
field.value,
|
||||
);
|
||||
console.log({ field });
|
||||
field.query('method').take((f) => {
|
||||
// @ts-ignore
|
||||
// f.value = 'insertAfter';
|
||||
// @ts-ignore
|
||||
f.dataSource =
|
||||
target['x-component'] === 'Menu.SubMenu'
|
||||
? [
|
||||
{ label: '之后', value: 'insertAfter' },
|
||||
{ label: '之前', value: 'insertBefore' },
|
||||
{ label: '组里', value: 'appendChild' },
|
||||
]
|
||||
: [
|
||||
{ label: '之后', value: 'insertAfter' },
|
||||
{ label: '之前', value: 'insertBefore' },
|
||||
];
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
const methods = {
|
||||
insertAfter,
|
||||
insertBefore,
|
||||
appendChild,
|
||||
};
|
||||
const data = schema.toJSON();
|
||||
remove();
|
||||
const source = methods[values.method](data, values.path);
|
||||
await updateSchema(source);
|
||||
}}
|
||||
>
|
||||
<DragOutlined /> 移动到
|
||||
</AntdMenu.Item>
|
||||
<AntdMenu.Divider />
|
||||
<AntdMenu.SubMenu
|
||||
key={'insertBefore'}
|
||||
icon={<ArrowUpOutlined />}
|
||||
title={'当前菜单项之前'}
|
||||
>
|
||||
<AntdMenu.Item
|
||||
key={'insertBefore.Menu.Link'}
|
||||
icon={<MenuOutlined />}
|
||||
}).open({
|
||||
initialValues: {
|
||||
roles: uiSchemasRoles?.data?.map((role) => role.name),
|
||||
},
|
||||
});
|
||||
await Resource.make({
|
||||
resourceName: 'ui_schemas',
|
||||
resourceKey: schema['key'],
|
||||
}).save(values);
|
||||
}}
|
||||
>
|
||||
新建菜单项
|
||||
设置权限
|
||||
</AntdMenu.Item>
|
||||
<AntdMenu.Divider />
|
||||
<AntdMenu.Item
|
||||
key={'insertBefore.Menu.SubMenu'}
|
||||
icon={<GroupOutlined />}
|
||||
key={'delete'}
|
||||
onClick={() => {
|
||||
Modal.confirm({
|
||||
title: '删除菜单',
|
||||
content: '确认删除此菜单项吗?',
|
||||
onOk: async () => {
|
||||
const target = remove();
|
||||
await removeSchema(target);
|
||||
ctx.onRemove && ctx.onRemove(target);
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
新建菜单分组
|
||||
<DeleteOutlined /> 删除
|
||||
</AntdMenu.Item>
|
||||
<AntdMenu.Item
|
||||
key={'insertBefore.Menu.URL'}
|
||||
icon={<LinkOutlined />}
|
||||
>
|
||||
添加自定义链接
|
||||
</AntdMenu.Item>
|
||||
</AntdMenu.SubMenu>
|
||||
<AntdMenu.SubMenu
|
||||
key={'insertAfter'}
|
||||
icon={<ArrowDownOutlined />}
|
||||
title={'当前菜单项之后'}
|
||||
>
|
||||
<AntdMenu.Item
|
||||
key={'insertAfter.Menu.Link'}
|
||||
icon={<MenuOutlined />}
|
||||
>
|
||||
新建菜单项
|
||||
</AntdMenu.Item>
|
||||
<AntdMenu.Item
|
||||
key={'insertAfter.Menu.SubMenu'}
|
||||
icon={<GroupOutlined />}
|
||||
>
|
||||
新建菜单分组
|
||||
</AntdMenu.Item>
|
||||
<AntdMenu.Item
|
||||
key={'insertAfter.Menu.URL'}
|
||||
icon={<LinkOutlined />}
|
||||
>
|
||||
添加自定义链接
|
||||
</AntdMenu.Item>
|
||||
</AntdMenu.SubMenu>
|
||||
{isSubMenu && (
|
||||
<AntdMenu.SubMenu
|
||||
key={'appendChild'}
|
||||
icon={<ArrowRightOutlined />}
|
||||
title={'当前菜单分组里'}
|
||||
>
|
||||
<AntdMenu.Item
|
||||
key={'appendChild.Menu.Link'}
|
||||
icon={<MenuOutlined />}
|
||||
>
|
||||
新建菜单项
|
||||
</AntdMenu.Item>
|
||||
<AntdMenu.Item
|
||||
key={'appendChild.Menu.SubMenu'}
|
||||
icon={<GroupOutlined />}
|
||||
>
|
||||
新建菜单分组
|
||||
</AntdMenu.Item>
|
||||
<AntdMenu.Item
|
||||
key={'appendChild.Menu.URL'}
|
||||
icon={<LinkOutlined />}
|
||||
>
|
||||
添加自定义链接
|
||||
</AntdMenu.Item>
|
||||
</AntdMenu.SubMenu>
|
||||
)}
|
||||
<AntdMenu.Item
|
||||
icon={<LockOutlined />}
|
||||
onClick={async () => {
|
||||
const loadRoles = async () => {
|
||||
const resource = Resource.make('roles');
|
||||
const data = await resource.list();
|
||||
console.log('loadRoles', data);
|
||||
return data?.data.map((item) => ({
|
||||
label: item.title,
|
||||
value: item.name,
|
||||
}));
|
||||
};
|
||||
const resource = Resource.make({
|
||||
associatedName: 'ui_schemas',
|
||||
associatedKey: schema['key'],
|
||||
resourceName: 'roles',
|
||||
});
|
||||
const uiSchemasRoles = await resource.list();
|
||||
console.log({ uiSchemasRoles });
|
||||
const values = await FormDialog(`设置权限`, () => {
|
||||
return (
|
||||
<FormLayout layout={'vertical'}>
|
||||
<SchemaField
|
||||
scope={{ loadRoles }}
|
||||
schema={{
|
||||
type: 'object',
|
||||
properties: {
|
||||
roles: {
|
||||
type: 'array',
|
||||
title: '权限组',
|
||||
'x-reactions': [
|
||||
'{{useAsyncDataSource(loadRoles)}}',
|
||||
],
|
||||
'x-decorator': 'FormilyFormItem',
|
||||
'x-component': 'Select',
|
||||
'x-component-props': {
|
||||
mode: 'tags',
|
||||
},
|
||||
},
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</FormLayout>
|
||||
);
|
||||
}).open({
|
||||
initialValues: {
|
||||
roles: uiSchemasRoles?.data?.map((role) => role.name),
|
||||
},
|
||||
});
|
||||
await Resource.make({
|
||||
resourceName: 'ui_schemas',
|
||||
resourceKey: schema['key'],
|
||||
}).save(values);
|
||||
}}
|
||||
>
|
||||
设置权限
|
||||
</AntdMenu.Item>
|
||||
<AntdMenu.Divider />
|
||||
<AntdMenu.Item
|
||||
key={'delete'}
|
||||
onClick={() => {
|
||||
Modal.confirm({
|
||||
title: '删除菜单',
|
||||
content: '确认删除此菜单项吗?',
|
||||
onOk: async () => {
|
||||
const target = remove();
|
||||
await removeSchema(target);
|
||||
ctx.onRemove && ctx.onRemove(target);
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
<DeleteOutlined /> 删除
|
||||
</AntdMenu.Item>
|
||||
</AntdMenu>
|
||||
}
|
||||
>
|
||||
<MenuOutlined />
|
||||
</Dropdown>
|
||||
</AntdMenu>
|
||||
}
|
||||
>
|
||||
<MenuOutlined />
|
||||
</Dropdown>
|
||||
</Space>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -110,4 +110,4 @@
|
||||
.nb-add-new-menu-item.menu-mode-inline {
|
||||
margin: 0 14px;
|
||||
width: calc(100% - 28px);
|
||||
}
|
||||
}
|
||||
|
@ -510,7 +510,11 @@ function AddColumn() {
|
||||
</Menu>
|
||||
}
|
||||
>
|
||||
<Button type={'dashed'} icon={<SettingOutlined />}>
|
||||
<Button
|
||||
type={'dashed'}
|
||||
className={'designable-btn designable-btn-dash'}
|
||||
icon={<SettingOutlined />}
|
||||
>
|
||||
配置字段
|
||||
</Button>
|
||||
</Dropdown>
|
||||
@ -1089,7 +1093,12 @@ function AddActionButton() {
|
||||
</Menu>
|
||||
}
|
||||
>
|
||||
<Button style={{ marginLeft: 8 }} type={'dashed'} icon={<PlusOutlined />}>
|
||||
<Button
|
||||
className={'designable-btn designable-btn-dash'}
|
||||
style={{ marginLeft: 8 }}
|
||||
type={'dashed'}
|
||||
icon={<PlusOutlined />}
|
||||
>
|
||||
配置操作
|
||||
</Button>
|
||||
</Dropdown>
|
||||
@ -1350,108 +1359,111 @@ Table.Filter.DesignableBar = () => {
|
||||
}}
|
||||
className={cls('designable-bar-actions', { active: visible })}
|
||||
>
|
||||
<DragHandle />
|
||||
<Dropdown
|
||||
trigger={['click']}
|
||||
visible={visible}
|
||||
onVisibleChange={(visible) => {
|
||||
setVisible(visible);
|
||||
}}
|
||||
overlay={
|
||||
<Menu>
|
||||
<Menu.ItemGroup title={'筛选字段'}>
|
||||
{fields
|
||||
.filter((collectionField) => {
|
||||
const option = interfaces.get(collectionField.interface);
|
||||
return option.operations?.length;
|
||||
})
|
||||
.map((collectionField) => (
|
||||
<SwitchMenuItem
|
||||
title={collectionField?.uiSchema?.title}
|
||||
checked={fieldNames.includes(collectionField.name)}
|
||||
onChange={async (checked) => {
|
||||
if (checked) {
|
||||
fieldNames.push(collectionField.name);
|
||||
} else {
|
||||
const index = fieldNames.indexOf(
|
||||
collectionField.name,
|
||||
);
|
||||
if (index > -1) {
|
||||
fieldNames.splice(index, 1);
|
||||
<Space>
|
||||
<DragHandle />
|
||||
<Dropdown
|
||||
trigger={['click']}
|
||||
visible={visible}
|
||||
onVisibleChange={(visible) => {
|
||||
setVisible(visible);
|
||||
}}
|
||||
overlay={
|
||||
<Menu>
|
||||
<Menu.ItemGroup title={'筛选字段'}>
|
||||
{fields
|
||||
.filter((collectionField) => {
|
||||
const option = interfaces.get(collectionField.interface);
|
||||
return option.operations?.length;
|
||||
})
|
||||
.map((collectionField) => (
|
||||
<SwitchMenuItem
|
||||
title={collectionField?.uiSchema?.title}
|
||||
checked={fieldNames.includes(collectionField.name)}
|
||||
onChange={async (checked) => {
|
||||
if (checked) {
|
||||
fieldNames.push(collectionField.name);
|
||||
} else {
|
||||
const index = fieldNames.indexOf(
|
||||
collectionField.name,
|
||||
);
|
||||
if (index > -1) {
|
||||
fieldNames.splice(index, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log({ fieldNames, field });
|
||||
schema['x-component-props']['fieldNames'] = fieldNames;
|
||||
field.componentProps.fieldNames = fieldNames;
|
||||
updateSchema(schema);
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</Menu.ItemGroup>
|
||||
<Menu.Divider />
|
||||
<Menu.Item
|
||||
onClick={async (e) => {
|
||||
const values = await FormDialog('修改名称和图标', () => {
|
||||
return (
|
||||
<FormLayout layout={'vertical'}>
|
||||
<SchemaField
|
||||
schema={{
|
||||
type: 'object',
|
||||
properties: {
|
||||
title: {
|
||||
type: 'string',
|
||||
title: '按钮名称',
|
||||
required: true,
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Input',
|
||||
console.log({ fieldNames, field });
|
||||
schema['x-component-props']['fieldNames'] =
|
||||
fieldNames;
|
||||
field.componentProps.fieldNames = fieldNames;
|
||||
updateSchema(schema);
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</Menu.ItemGroup>
|
||||
<Menu.Divider />
|
||||
<Menu.Item
|
||||
onClick={async (e) => {
|
||||
const values = await FormDialog('修改名称和图标', () => {
|
||||
return (
|
||||
<FormLayout layout={'vertical'}>
|
||||
<SchemaField
|
||||
schema={{
|
||||
type: 'object',
|
||||
properties: {
|
||||
title: {
|
||||
type: 'string',
|
||||
title: '按钮名称',
|
||||
required: true,
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Input',
|
||||
},
|
||||
icon: {
|
||||
type: 'string',
|
||||
title: '按钮图标',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'IconPicker',
|
||||
},
|
||||
},
|
||||
icon: {
|
||||
type: 'string',
|
||||
title: '按钮图标',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'IconPicker',
|
||||
},
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</FormLayout>
|
||||
);
|
||||
}).open({
|
||||
initialValues: {
|
||||
title: schema['title'],
|
||||
icon: schema['x-component-props']?.['icon'],
|
||||
},
|
||||
});
|
||||
schema['title'] = values.title;
|
||||
schema['x-component-props']['icon'] = values.icon;
|
||||
field.componentProps.icon = values.icon;
|
||||
field.title = values.title;
|
||||
updateSchema(schema);
|
||||
refresh();
|
||||
}}
|
||||
>
|
||||
修改名称和图标
|
||||
</Menu.Item>
|
||||
<Menu.Divider />
|
||||
<Menu.Item
|
||||
onClick={async () => {
|
||||
const displayName =
|
||||
schema?.['x-decorator-props']?.['displayName'];
|
||||
const data = remove();
|
||||
await removeSchema(data);
|
||||
if (displayName) {
|
||||
displayed.remove(displayName);
|
||||
}
|
||||
setVisible(false);
|
||||
}}
|
||||
>
|
||||
移除
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
}
|
||||
>
|
||||
<MenuOutlined />
|
||||
</Dropdown>
|
||||
}}
|
||||
/>
|
||||
</FormLayout>
|
||||
);
|
||||
}).open({
|
||||
initialValues: {
|
||||
title: schema['title'],
|
||||
icon: schema['x-component-props']?.['icon'],
|
||||
},
|
||||
});
|
||||
schema['title'] = values.title;
|
||||
schema['x-component-props']['icon'] = values.icon;
|
||||
field.componentProps.icon = values.icon;
|
||||
field.title = values.title;
|
||||
updateSchema(schema);
|
||||
refresh();
|
||||
}}
|
||||
>
|
||||
修改名称和图标
|
||||
</Menu.Item>
|
||||
<Menu.Divider />
|
||||
<Menu.Item
|
||||
onClick={async () => {
|
||||
const displayName =
|
||||
schema?.['x-decorator-props']?.['displayName'];
|
||||
const data = remove();
|
||||
await removeSchema(data);
|
||||
if (displayName) {
|
||||
displayed.remove(displayName);
|
||||
}
|
||||
setVisible(false);
|
||||
}}
|
||||
>
|
||||
移除
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
}
|
||||
>
|
||||
<MenuOutlined />
|
||||
</Dropdown>
|
||||
</Space>
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
@ -1475,101 +1487,105 @@ Table.ExportActionDesignableBar = () => {
|
||||
}}
|
||||
className={cls('designable-bar-actions', { active: visible })}
|
||||
>
|
||||
<DragHandle />
|
||||
<Dropdown
|
||||
trigger={['click']}
|
||||
visible={visible}
|
||||
onVisibleChange={(visible) => {
|
||||
setVisible(visible);
|
||||
}}
|
||||
overlay={
|
||||
<Menu>
|
||||
<Menu.ItemGroup title={'导出字段'}>
|
||||
{fields.map((collectionField) => (
|
||||
<SwitchMenuItem
|
||||
title={collectionField?.uiSchema?.title}
|
||||
checked={fieldNames.includes(collectionField.name)}
|
||||
onChange={async (checked) => {
|
||||
if (checked) {
|
||||
fieldNames.push(collectionField.name);
|
||||
} else {
|
||||
const index = fieldNames.indexOf(collectionField.name);
|
||||
if (index > -1) {
|
||||
fieldNames.splice(index, 1);
|
||||
<Space>
|
||||
<DragHandle />
|
||||
<Dropdown
|
||||
trigger={['click']}
|
||||
visible={visible}
|
||||
onVisibleChange={(visible) => {
|
||||
setVisible(visible);
|
||||
}}
|
||||
overlay={
|
||||
<Menu>
|
||||
<Menu.ItemGroup title={'导出字段'}>
|
||||
{fields.map((collectionField) => (
|
||||
<SwitchMenuItem
|
||||
title={collectionField?.uiSchema?.title}
|
||||
checked={fieldNames.includes(collectionField.name)}
|
||||
onChange={async (checked) => {
|
||||
if (checked) {
|
||||
fieldNames.push(collectionField.name);
|
||||
} else {
|
||||
const index = fieldNames.indexOf(
|
||||
collectionField.name,
|
||||
);
|
||||
if (index > -1) {
|
||||
fieldNames.splice(index, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log({ fieldNames, field });
|
||||
schema['x-component-props']['fieldNames'] = fieldNames;
|
||||
field.componentProps.fieldNames = fieldNames;
|
||||
updateSchema(schema);
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</Menu.ItemGroup>
|
||||
<Menu.Divider />
|
||||
<Menu.Item
|
||||
onClick={async (e) => {
|
||||
const values = await FormDialog('修改名称和图标', () => {
|
||||
return (
|
||||
<FormLayout layout={'vertical'}>
|
||||
<SchemaField
|
||||
schema={{
|
||||
type: 'object',
|
||||
properties: {
|
||||
title: {
|
||||
type: 'string',
|
||||
title: '按钮名称',
|
||||
required: true,
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Input',
|
||||
console.log({ fieldNames, field });
|
||||
schema['x-component-props']['fieldNames'] = fieldNames;
|
||||
field.componentProps.fieldNames = fieldNames;
|
||||
updateSchema(schema);
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</Menu.ItemGroup>
|
||||
<Menu.Divider />
|
||||
<Menu.Item
|
||||
onClick={async (e) => {
|
||||
const values = await FormDialog('修改名称和图标', () => {
|
||||
return (
|
||||
<FormLayout layout={'vertical'}>
|
||||
<SchemaField
|
||||
schema={{
|
||||
type: 'object',
|
||||
properties: {
|
||||
title: {
|
||||
type: 'string',
|
||||
title: '按钮名称',
|
||||
required: true,
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Input',
|
||||
},
|
||||
icon: {
|
||||
type: 'string',
|
||||
title: '按钮图标',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'IconPicker',
|
||||
},
|
||||
},
|
||||
icon: {
|
||||
type: 'string',
|
||||
title: '按钮图标',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'IconPicker',
|
||||
},
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</FormLayout>
|
||||
);
|
||||
}).open({
|
||||
initialValues: {
|
||||
title: schema['title'],
|
||||
icon: schema['x-component-props']?.['icon'],
|
||||
},
|
||||
});
|
||||
schema['title'] = values.title;
|
||||
schema['x-component-props']['icon'] = values.icon;
|
||||
field.componentProps.icon = values.icon;
|
||||
field.title = values.title;
|
||||
updateSchema(schema);
|
||||
refresh();
|
||||
}}
|
||||
>
|
||||
修改名称和图标
|
||||
</Menu.Item>
|
||||
<Menu.Divider />
|
||||
<Menu.Item
|
||||
onClick={async () => {
|
||||
const displayName =
|
||||
schema?.['x-decorator-props']?.['displayName'];
|
||||
const data = remove();
|
||||
await removeSchema(data);
|
||||
if (displayName) {
|
||||
displayed.remove(displayName);
|
||||
}
|
||||
setVisible(false);
|
||||
}}
|
||||
>
|
||||
移除
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
}
|
||||
>
|
||||
<MenuOutlined />
|
||||
</Dropdown>
|
||||
}}
|
||||
/>
|
||||
</FormLayout>
|
||||
);
|
||||
}).open({
|
||||
initialValues: {
|
||||
title: schema['title'],
|
||||
icon: schema['x-component-props']?.['icon'],
|
||||
},
|
||||
});
|
||||
schema['title'] = values.title;
|
||||
schema['x-component-props']['icon'] = values.icon;
|
||||
field.componentProps.icon = values.icon;
|
||||
field.title = values.title;
|
||||
updateSchema(schema);
|
||||
refresh();
|
||||
}}
|
||||
>
|
||||
修改名称和图标
|
||||
</Menu.Item>
|
||||
<Menu.Divider />
|
||||
<Menu.Item
|
||||
onClick={async () => {
|
||||
const displayName =
|
||||
schema?.['x-decorator-props']?.['displayName'];
|
||||
const data = remove();
|
||||
await removeSchema(data);
|
||||
if (displayName) {
|
||||
displayed.remove(displayName);
|
||||
}
|
||||
setVisible(false);
|
||||
}}
|
||||
>
|
||||
移除
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
}
|
||||
>
|
||||
<MenuOutlined />
|
||||
</Dropdown>
|
||||
</Space>
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
@ -1580,9 +1596,7 @@ Table.Operation = observer((props: any) => {
|
||||
return (
|
||||
<div className={'nb-table-column'}>
|
||||
操作
|
||||
{designable && schema['x-designable-bar'] && (
|
||||
<Table.Operation.DesignableBar path={props.path} />
|
||||
)}
|
||||
<Table.Operation.DesignableBar path={props.path} />
|
||||
</div>
|
||||
);
|
||||
});
|
||||
@ -1600,9 +1614,10 @@ Table.Operation.Cell = observer((props: any) => {
|
||||
Table.Operation.DesignableBar = (props) => {
|
||||
const { schema, remove, refresh, appendChild } = useDesignable(props.path);
|
||||
const [visible, setVisible] = useState(false);
|
||||
if (!schema['x-designable-bar']) {
|
||||
if (!schema?.parent?.parent['x-designable-bar']) {
|
||||
return null;
|
||||
}
|
||||
console.log('Table.Operation.DesignableBar', schema?.parent?.parent);
|
||||
const map = new Map();
|
||||
schema.mapProperties((s) => {
|
||||
if (!s['x-action-type']) {
|
||||
@ -1618,52 +1633,54 @@ Table.Operation.DesignableBar = (props) => {
|
||||
}}
|
||||
className={cls('designable-bar-actions', { active: visible })}
|
||||
>
|
||||
<DragHandle />
|
||||
<Dropdown
|
||||
trigger={['click']}
|
||||
visible={visible}
|
||||
onVisibleChange={(visible) => {
|
||||
setVisible(visible);
|
||||
}}
|
||||
overlay={
|
||||
<Menu>
|
||||
<Menu.ItemGroup title={'操作展示'}>
|
||||
{[
|
||||
{ title: '查看', name: 'view' },
|
||||
{ title: '编辑', name: 'update' },
|
||||
{ title: '删除', name: 'destroy' },
|
||||
].map((item) => (
|
||||
<SwitchMenuItem
|
||||
key={item.name}
|
||||
title={item.title}
|
||||
checked={map.has(item.name)}
|
||||
onChange={async (checked) => {
|
||||
if (checked) {
|
||||
const s = generateMenuActionSchema(item.name);
|
||||
const data = appendChild(s);
|
||||
await createSchema(data);
|
||||
} else if (map.get(item.name)) {
|
||||
const removed = remove([
|
||||
...props.path,
|
||||
map.get(item.name),
|
||||
]);
|
||||
await removeSchema(removed);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</Menu.ItemGroup>
|
||||
<Menu.Divider />
|
||||
<Menu.SubMenu title={'自定义'}>
|
||||
<Menu.Item style={{ minWidth: 120 }}>函数操作</Menu.Item>
|
||||
<Menu.Item>弹窗表单</Menu.Item>
|
||||
<Menu.Item>复杂弹窗</Menu.Item>
|
||||
</Menu.SubMenu>
|
||||
</Menu>
|
||||
}
|
||||
>
|
||||
<MenuOutlined />
|
||||
</Dropdown>
|
||||
<Space>
|
||||
<DragHandle />
|
||||
<Dropdown
|
||||
trigger={['click']}
|
||||
visible={visible}
|
||||
onVisibleChange={(visible) => {
|
||||
setVisible(visible);
|
||||
}}
|
||||
overlay={
|
||||
<Menu>
|
||||
<Menu.ItemGroup title={'操作展示'}>
|
||||
{[
|
||||
{ title: '查看', name: 'view' },
|
||||
{ title: '编辑', name: 'update' },
|
||||
{ title: '删除', name: 'destroy' },
|
||||
].map((item) => (
|
||||
<SwitchMenuItem
|
||||
key={item.name}
|
||||
title={item.title}
|
||||
checked={map.has(item.name)}
|
||||
onChange={async (checked) => {
|
||||
if (checked) {
|
||||
const s = generateMenuActionSchema(item.name);
|
||||
const data = appendChild(s);
|
||||
await createSchema(data);
|
||||
} else if (map.get(item.name)) {
|
||||
const removed = remove([
|
||||
...props.path,
|
||||
map.get(item.name),
|
||||
]);
|
||||
await removeSchema(removed);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</Menu.ItemGroup>
|
||||
<Menu.Divider />
|
||||
<Menu.SubMenu title={'自定义'}>
|
||||
<Menu.Item style={{ minWidth: 120 }}>函数操作</Menu.Item>
|
||||
<Menu.Item>弹窗表单</Menu.Item>
|
||||
<Menu.Item>复杂弹窗</Menu.Item>
|
||||
</Menu.SubMenu>
|
||||
</Menu>
|
||||
}
|
||||
>
|
||||
<MenuOutlined />
|
||||
</Dropdown>
|
||||
</Space>
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
@ -1686,109 +1703,115 @@ Table.Action.DesignableBar = () => {
|
||||
}}
|
||||
className={cls('designable-bar-actions', { active: visible })}
|
||||
>
|
||||
<DragHandle />
|
||||
<Dropdown
|
||||
trigger={['click']}
|
||||
visible={visible}
|
||||
onVisibleChange={(visible) => {
|
||||
setVisible(visible);
|
||||
}}
|
||||
overlay={
|
||||
<Menu>
|
||||
<Menu.Item
|
||||
onClick={async (e) => {
|
||||
const values = await FormDialog('修改名称和图标', () => {
|
||||
return (
|
||||
<FormLayout layout={'vertical'}>
|
||||
<SchemaField
|
||||
schema={{
|
||||
type: 'object',
|
||||
properties: {
|
||||
title: {
|
||||
type: 'string',
|
||||
title: '按钮名称',
|
||||
required: true,
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Input',
|
||||
<Space>
|
||||
<DragHandle />
|
||||
<Dropdown
|
||||
trigger={['click']}
|
||||
visible={visible}
|
||||
onVisibleChange={(visible) => {
|
||||
setVisible(visible);
|
||||
}}
|
||||
overlay={
|
||||
<Menu>
|
||||
<Menu.Item
|
||||
onClick={async (e) => {
|
||||
const values = await FormDialog('修改名称和图标', () => {
|
||||
return (
|
||||
<FormLayout layout={'vertical'}>
|
||||
<SchemaField
|
||||
schema={{
|
||||
type: 'object',
|
||||
properties: {
|
||||
title: {
|
||||
type: 'string',
|
||||
title: '按钮名称',
|
||||
required: true,
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Input',
|
||||
},
|
||||
icon: {
|
||||
type: 'string',
|
||||
title: '按钮图标',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'IconPicker',
|
||||
},
|
||||
},
|
||||
icon: {
|
||||
type: 'string',
|
||||
title: '按钮图标',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'IconPicker',
|
||||
},
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</FormLayout>
|
||||
);
|
||||
}).open({
|
||||
initialValues: {
|
||||
title: schema['title'],
|
||||
icon: schema['x-component-props']?.['icon'],
|
||||
},
|
||||
});
|
||||
schema['title'] = values.title;
|
||||
schema['x-component-props']['icon'] = values.icon;
|
||||
field.componentProps.icon = values.icon;
|
||||
field.title = values.title;
|
||||
updateSchema(schema);
|
||||
refresh();
|
||||
}}
|
||||
>
|
||||
修改名称和图标
|
||||
</Menu.Item>
|
||||
{isPopup && (
|
||||
<Menu.Item>
|
||||
在{' '}
|
||||
<Select
|
||||
bordered={false}
|
||||
size={'small'}
|
||||
defaultValue={'Action.Modal'}
|
||||
onChange={(value) => {
|
||||
const s = Object.values(schema.properties).shift();
|
||||
s['x-component'] = value;
|
||||
refresh();
|
||||
updateSchema(s);
|
||||
// const f = field.query(getSchemaPath(s)).take()
|
||||
// console.log('fffffff', { schema, f });
|
||||
}}
|
||||
>
|
||||
<Select.Option value={'Action.Modal'}>对话框</Select.Option>
|
||||
<Select.Option value={'Action.Drawer'}>抽屉</Select.Option>
|
||||
<Select.Option value={'Action.Window'}>
|
||||
浏览器窗口
|
||||
</Select.Option>
|
||||
</Select>{' '}
|
||||
内打开
|
||||
}}
|
||||
/>
|
||||
</FormLayout>
|
||||
);
|
||||
}).open({
|
||||
initialValues: {
|
||||
title: schema['title'],
|
||||
icon: schema['x-component-props']?.['icon'],
|
||||
},
|
||||
});
|
||||
schema['title'] = values.title;
|
||||
schema['x-component-props']['icon'] = values.icon;
|
||||
field.componentProps.icon = values.icon;
|
||||
field.title = values.title;
|
||||
updateSchema(schema);
|
||||
refresh();
|
||||
}}
|
||||
>
|
||||
修改名称和图标
|
||||
</Menu.Item>
|
||||
)}
|
||||
{!inActionBar && (
|
||||
<Menu.Item>
|
||||
点击表格行时触发
|
||||
<Switch size={'small'} defaultChecked />
|
||||
{isPopup && (
|
||||
<Menu.Item>
|
||||
在{' '}
|
||||
<Select
|
||||
bordered={false}
|
||||
size={'small'}
|
||||
defaultValue={'Action.Modal'}
|
||||
onChange={(value) => {
|
||||
const s = Object.values(schema.properties).shift();
|
||||
s['x-component'] = value;
|
||||
refresh();
|
||||
updateSchema(s);
|
||||
// const f = field.query(getSchemaPath(s)).take()
|
||||
// console.log('fffffff', { schema, f });
|
||||
}}
|
||||
>
|
||||
<Select.Option value={'Action.Modal'}>
|
||||
对话框
|
||||
</Select.Option>
|
||||
<Select.Option value={'Action.Drawer'}>
|
||||
抽屉
|
||||
</Select.Option>
|
||||
<Select.Option value={'Action.Window'}>
|
||||
浏览器窗口
|
||||
</Select.Option>
|
||||
</Select>{' '}
|
||||
内打开
|
||||
</Menu.Item>
|
||||
)}
|
||||
{!inActionBar && (
|
||||
<Menu.Item>
|
||||
点击表格行时触发
|
||||
<Switch size={'small'} defaultChecked />
|
||||
</Menu.Item>
|
||||
)}
|
||||
<Menu.Divider />
|
||||
<Menu.Item
|
||||
onClick={async () => {
|
||||
const displayName =
|
||||
schema?.['x-decorator-props']?.['displayName'];
|
||||
const data = remove();
|
||||
await removeSchema(data);
|
||||
if (displayName) {
|
||||
displayed.remove(displayName);
|
||||
}
|
||||
setVisible(false);
|
||||
}}
|
||||
>
|
||||
移除
|
||||
</Menu.Item>
|
||||
)}
|
||||
<Menu.Divider />
|
||||
<Menu.Item
|
||||
onClick={async () => {
|
||||
const displayName =
|
||||
schema?.['x-decorator-props']?.['displayName'];
|
||||
const data = remove();
|
||||
await removeSchema(data);
|
||||
if (displayName) {
|
||||
displayed.remove(displayName);
|
||||
}
|
||||
setVisible(false);
|
||||
}}
|
||||
>
|
||||
移除
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
}
|
||||
>
|
||||
<MenuOutlined />
|
||||
</Dropdown>
|
||||
</Menu>
|
||||
}
|
||||
>
|
||||
<MenuOutlined />
|
||||
</Dropdown>
|
||||
</Space>
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
@ -1860,77 +1883,80 @@ Table.Column.DesignableBar = () => {
|
||||
}}
|
||||
className={cls('designable-bar-actions', { active: visible })}
|
||||
>
|
||||
<DragHandle />
|
||||
<Dropdown
|
||||
trigger={['click']}
|
||||
visible={visible}
|
||||
onVisibleChange={(visible) => {
|
||||
setVisible(visible);
|
||||
}}
|
||||
overlay={
|
||||
<Menu>
|
||||
<Menu.Item
|
||||
onClick={async (e) => {
|
||||
const values = await FormDialog('修改列标题', () => {
|
||||
return (
|
||||
<FormLayout layout={'vertical'}>
|
||||
<SchemaField
|
||||
schema={{
|
||||
type: 'object',
|
||||
properties: {
|
||||
fieldName: {
|
||||
type: 'string',
|
||||
title: '原字段名称',
|
||||
'x-read-pretty': true,
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Input',
|
||||
<Space>
|
||||
<DragHandle />
|
||||
<Dropdown
|
||||
trigger={['click']}
|
||||
visible={visible}
|
||||
onVisibleChange={(visible) => {
|
||||
setVisible(visible);
|
||||
}}
|
||||
overlay={
|
||||
<Menu>
|
||||
<Menu.Item
|
||||
onClick={async (e) => {
|
||||
const values = await FormDialog('修改列标题', () => {
|
||||
return (
|
||||
<FormLayout layout={'vertical'}>
|
||||
<SchemaField
|
||||
schema={{
|
||||
type: 'object',
|
||||
properties: {
|
||||
fieldName: {
|
||||
type: 'string',
|
||||
title: '原字段名称',
|
||||
'x-read-pretty': true,
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Input',
|
||||
},
|
||||
title: {
|
||||
type: 'string',
|
||||
title: '自定义列标题',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Input',
|
||||
},
|
||||
},
|
||||
title: {
|
||||
type: 'string',
|
||||
title: '自定义列标题',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Input',
|
||||
},
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</FormLayout>
|
||||
);
|
||||
}).open({
|
||||
initialValues: {
|
||||
fieldName: collectionField?.uiSchema?.title,
|
||||
title: schema['title'],
|
||||
},
|
||||
});
|
||||
const title = values.title || null;
|
||||
field.title = title;
|
||||
schema.title = title;
|
||||
refresh();
|
||||
await updateSchema({
|
||||
key: schema['key'],
|
||||
title: title,
|
||||
});
|
||||
setVisible(false);
|
||||
}}
|
||||
>
|
||||
修改列标题
|
||||
</Menu.Item>
|
||||
<Menu.Divider />
|
||||
<Menu.Item
|
||||
onClick={async () => {
|
||||
const s = remove();
|
||||
const fieldName = schema['x-component-props']?.['fieldName'];
|
||||
displayed.remove(fieldName);
|
||||
await removeSchema(s);
|
||||
}}
|
||||
>
|
||||
移除
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
}
|
||||
>
|
||||
<MenuOutlined />
|
||||
</Dropdown>
|
||||
}}
|
||||
/>
|
||||
</FormLayout>
|
||||
);
|
||||
}).open({
|
||||
initialValues: {
|
||||
fieldName: collectionField?.uiSchema?.title,
|
||||
title: schema['title'],
|
||||
},
|
||||
});
|
||||
const title = values.title || null;
|
||||
field.title = title;
|
||||
schema.title = title;
|
||||
refresh();
|
||||
await updateSchema({
|
||||
key: schema['key'],
|
||||
title: title,
|
||||
});
|
||||
setVisible(false);
|
||||
}}
|
||||
>
|
||||
修改列标题
|
||||
</Menu.Item>
|
||||
<Menu.Divider />
|
||||
<Menu.Item
|
||||
onClick={async () => {
|
||||
const s = remove();
|
||||
const fieldName =
|
||||
schema['x-component-props']?.['fieldName'];
|
||||
displayed.remove(fieldName);
|
||||
await removeSchema(s);
|
||||
}}
|
||||
>
|
||||
移除
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
}
|
||||
>
|
||||
<MenuOutlined />
|
||||
</Dropdown>
|
||||
</Space>
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
@ -1957,14 +1983,16 @@ Table.DesignableBar = observer((props) => {
|
||||
console.log({ collectionName });
|
||||
return (
|
||||
<div className={cls('designable-bar', { active: visible })}>
|
||||
<div className={'designable-info'}>{collection?.title || collection?.name}</div>
|
||||
<div className={'designable-info'}>
|
||||
{collection?.title || collection?.name}
|
||||
</div>
|
||||
<span
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
}}
|
||||
className={cls('designable-bar-actions', { active: visible })}
|
||||
>
|
||||
<Space size={'small'}>
|
||||
<Space size={2}>
|
||||
<AddNew.CardItem defaultAction={'insertAfter'} ghost />
|
||||
{dragRef && <DragOutlined ref={dragRef} />}
|
||||
<Dropdown
|
||||
@ -2245,7 +2273,10 @@ Table.useActionLogDetailsResource = ({ onSuccess }) => {
|
||||
});
|
||||
const service = useRequest(
|
||||
(params?: any) => {
|
||||
return resource.get({ ...params, appends: ['changes', 'user', 'collection'] });
|
||||
return resource.get({
|
||||
...params,
|
||||
appends: ['changes', 'user', 'collection'],
|
||||
});
|
||||
},
|
||||
{
|
||||
formatResult: (result) => result?.data,
|
||||
|
Loading…
Reference in New Issue
Block a user