Browse Source

update: show menu-editor icons

dev
powersir 1 year ago
parent
commit
449db92e1f
2 changed files with 79 additions and 24 deletions
  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 View File

@@ -10,13 +10,6 @@ import menuService from '@/request/service/menu';
import { formatDate } from '@/utils/formatTime' import { formatDate } from '@/utils/formatTime'
import MenuEditor from './menu-editor'; 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 MenuListPage: React.FC = () => {


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


console.log()


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


+ 79
- 16
src/pages/system/menu/menu-editor.tsx View File

@@ -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 menuService from '@/request/service/menu';
import { useRequest } from '@/hooks/use-request'; import { useRequest } from '@/hooks/use-request';
import type { DefaultOptionType } from 'antd/es/select'; import type { DefaultOptionType } from 'antd/es/select';
import type { Menu } from '@/models' import type { Menu } from '@/models'
import { antdUtils } from '@/utils/antd'; 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 = { const layout = {
labelCol: { span: 4, }, labelCol: { span: 4, },
@@ -29,6 +88,8 @@ const MenuEditor: React.FC<MenuEditorProps> = (props) => {
const { runAsync: updateMenu } = useRequest(menuService.updateMenu, { manual: true }); const { runAsync: updateMenu } = useRequest(menuService.updateMenu, { manual: true });
const { runAsync: createMenu } = useRequest(menuService.createMenu, { manual: true }); const { runAsync: createMenu } = useRequest(menuService.createMenu, { manual: true });




const isEdit = !!editData; const isEdit = !!editData;


const menu2Tree = (menu: Menu) => { const menu2Tree = (menu: Menu) => {
@@ -66,28 +127,29 @@ const MenuEditor: React.FC<MenuEditorProps> = (props) => {
const save = async () => { const save = async () => {
setSaveLoading(true); setSaveLoading(true);
const menuValues = form.getFieldsValue(); 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: '', permission: '',
icon: '', icon: '',
keepAlive:true,
keepAlive: true,
createTime: new Date(), createTime: new Date(),
...menuValues, ...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); onSave(newValue);
} else { } else {
antdUtils.message?.open({ antdUtils.message?.open({
type: 'error', type: 'error',
content: msg??'操作失败',
content: msg ?? '操作失败',
}); });
} }
setSaveLoading(false); setSaveLoading(false);
} }



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


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

</Form.Item> </Form.Item>


<Form.Item name="path" label="路由地址" <Form.Item name="path" label="路由地址"
@@ -159,11 +222,11 @@ const MenuEditor: React.FC<MenuEditorProps> = (props) => {
// return { checked } // return { checked }
// }} // }}
valuePropName="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="关闭" /> <Switch checkedChildren="开启" unCheckedChildren="关闭" />
</Form.Item> </Form.Item>




Loading…
Cancel
Save