Просмотр исходного кода

update: show menu-editor icons

dev
powersir 1 год назад
Родитель
Сommit
449db92e1f
2 измененных файлов: 79 добавлений и 24 удалений
  1. +0
    -8
      src/pages/system/menu/index.tsx
  2. +79
    -16
      src/pages/system/menu/menu-editor.tsx

+ 0
- 8
src/pages/system/menu/index.tsx Просмотреть файл

@@ -10,13 +10,6 @@ import menuService from '@/request/service/menu';
import { formatDate } from '@/utils/formatTime'
import MenuEditor from './menu-editor';

import * as Icon from "@ant-design/icons";
// 编写生成ReactNode的方法
const icon2Element = (name: string) =>
React.createElement(Icon && (Icon as any)[name], {
style: { fontSize: '16px' }
})

const MenuListPage: React.FC = () => {

const [menuEditorVisable, seMenuEditorVisable] = useState<boolean>(false);
@@ -24,7 +17,6 @@ const MenuListPage: React.FC = () => {
const [dataSource, setDataSource] = useState<Menu[]>([]);
const [searchFrom] = Form.useForm();

console.log()

const { runAsync: getMenuList } = useRequest(menuService.getMenuList, { manual: true });
const { runAsync: deleteMenu } = useRequest(menuService.deleteMenu, { manual: true });


+ 79
- 16
src/pages/system/menu/menu-editor.tsx Просмотреть файл

@@ -1,11 +1,70 @@
import React, { useEffect, useState } from 'react'
import { CloseOutlined, DeleteOutlined, PlusOutlined } from '@ant-design/icons';
import { TreeSelect, Form, Input, InputNumber, Radio, Modal, Switch } from 'antd'
import React, { lazy, useEffect, useState } from 'react'
import { TreeSelect, Form, Input, InputNumber, Radio, Modal, Switch, Popover, Button, Space, List } from 'antd';
import { ProList } from '@ant-design/pro-components';
import menuService from '@/request/service/menu';
import { useRequest } from '@/hooks/use-request';
import type { DefaultOptionType } from 'antd/es/select';
import type { Menu } from '@/models'
import { antdUtils } from '@/utils/antd';
import * as Icon from "@ant-design/icons";
// 编写生成ReactNode的方法
const icon2Element = (name: string) => {
return <React.Suspense fallback={<></>}>
{React.createElement((Icon as any)[name], {
style: { fontSize: '16px' }
})}
</React.Suspense>
}

interface MenuIconProps {
value?: string;
onChange?: (value: string) => void;
}

const MenuIcon: React.FC<MenuIconProps> = ({ value = '', onChange }) => {
const [hovered, setHovered] = useState(false);
const icons: string[] = [];
for (const i in Icon) {
if (i != 'default') icons.push(i)
}
const girdItems = icons.filter(i => i.endsWith('Outlined'))
if (value === '' || girdItems.indexOf(value) < 0) {
value = 'MenuUnfoldOutlined'
}
const triggerChange = (changedValue: string) => {
onChange?.(changedValue);
setHovered(false)
};
const renderIcons = () => {
return (<List
className='w-[400px]'
grid={{ column: 10 }}
dataSource={girdItems}
pagination={{
defaultPageSize: 80,
showSizeChanger: false,
}}
size='small'
renderItem={(item) => (
<List.Item onClick={() => { triggerChange(item) }}>
<div className='w-[16px]'>{icon2Element(item)}</div>
</List.Item>
)}
/>)
}

return <Popover placement="bottom"
content={renderIcons}
open={hovered}
trigger="click">
<Space>
<Input value={value} />
{icon2Element(value)}
</Space>
</Popover>
};



const layout = {
labelCol: { span: 4, },
@@ -29,6 +88,8 @@ const MenuEditor: React.FC<MenuEditorProps> = (props) => {
const { runAsync: updateMenu } = useRequest(menuService.updateMenu, { manual: true });
const { runAsync: createMenu } = useRequest(menuService.createMenu, { manual: true });



const isEdit = !!editData;

const menu2Tree = (menu: Menu) => {
@@ -66,28 +127,29 @@ const MenuEditor: React.FC<MenuEditorProps> = (props) => {
const save = async () => {
setSaveLoading(true);
const menuValues = form.getFieldsValue();
if(typeof(menuValues.status) === 'boolean') {
menuValues.status = menuValues.status? 0 : 1
if (typeof (menuValues.status) === 'boolean') {
menuValues.status = menuValues.status ? 0 : 1
}
const newValue = isEdit? {...editData, ...menuValues} : {
const newValue = isEdit ? { ...editData, ...menuValues } : {
permission: '',
icon: '',
keepAlive:true,
keepAlive: true,
createTime: new Date(),
...menuValues,
}
const [error, { msg, code }] = isEdit? await updateMenu(newValue): await createMenu(newValue);
if(!error && code === 0) {
const [error, { msg, code }] = isEdit ? await updateMenu(newValue) : await createMenu(newValue);
if (!error && code === 0) {
onSave(newValue);
} else {
antdUtils.message?.open({
type: 'error',
content: msg??'操作失败',
content: msg ?? '操作失败',
});
}
setSaveLoading(false);
}


return (
<>
<Modal
@@ -130,7 +192,8 @@ const MenuEditor: React.FC<MenuEditorProps> = (props) => {
</Form.Item>

<Form.Item name="icon" label="菜单图标" >
<Input />
<MenuIcon />

</Form.Item>

<Form.Item name="path" label="路由地址"
@@ -159,11 +222,11 @@ const MenuEditor: React.FC<MenuEditorProps> = (props) => {
// return { checked }
// }}
valuePropName="checked"
// normalize={(value: boolean) => {
// // prevValues.status = value ? 0 : 1
// return value ? 0 : 1
// }}
>
// normalize={(value: boolean) => {
// // prevValues.status = value ? 0 : 1
// return value ? 0 : 1
// }}
>
<Switch checkedChildren="开启" unCheckedChildren="关闭" />
</Form.Item>



Загрузка…
Отмена
Сохранить