You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

175 lines
6.2 KiB

import { useTranslation } from '@/i18n.ts'
import { PageContainer, ProCard } from '@ant-design/pro-components'
import { Button, Form, Input, message, Radio, TreeSelect, InputNumber, notification } from 'antd'
import { useAtomValue } from 'jotai'
import { menuDataAtom, saveOrUpdateMenuAtom, selectedMenuAtom } from './store.ts'
import IconPicker from '@/components/icon/picker'
import ButtonTable from './components/ButtonTable.tsx'
import { Flexbox } from 'react-layout-kit'
import { DraggablePanel } from '@/components/draggable-panel'
import { useStyle } from './style.ts'
import { MenuItem } from '@/types'
import MenuTree from './components/MenuTree.tsx'
import BatchButton from '@/pages/system/menus/components/BatchButton.tsx'
import { useEffect } from 'react'
import { createLazyFileRoute } from '@tanstack/react-router'
const Menus = () => {
const { styles } = useStyle()
const { t } = useTranslation()
const [ form ] = Form.useForm()
const { mutate, isPending, isSuccess, error, isError } = useAtomValue(saveOrUpdateMenuAtom)
const { data = [] } = useAtomValue(menuDataAtom)
const currentMenu = useAtomValue<MenuItem>(selectedMenuAtom) ?? {}
useEffect(() => {
if (isSuccess) {
message.success(t('saveSuccess', '保存成功'))
}
if (isError) {
notification.error({
message: t('errorTitle', '错误'),
description: (error as any).message ?? t('saveFail', '保存失败'),
})
}
}, [ isError, isSuccess ])
return (
<PageContainer breadcrumbRender={false} title={false} className={styles.container}>
<Flexbox horizontal>
<DraggablePanel expandable={false}
placement="left"
defaultSize={{ width: 300 }}
maxWidth={500}
>
<ProCard title={t('system.menus.title', '菜单')}
extra={
<BatchButton/>
}
>
<MenuTree form={form}/>
</ProCard>
</DraggablePanel>
<Flexbox className={styles.box}>
<Form form={form}
initialValues={currentMenu!}
labelCol={{ flex: '110px' }}
labelAlign="left"
labelWrap
wrapperCol={{ flex: 1 }}
colon={false}
className={styles.form}
>
<ProCard title={t('system.menus.setting', '配置')}
className={styles.formSetting}
>
<Form.Item hidden={true} label={'id'} name={'id'}>
<Input disabled={true}/>
</Form.Item>
<Form.Item label={t('system.menus.form.title', '菜单名称')} name={'title'}>
<Input/>
</Form.Item>
<Form.Item label={t('system.menus.form.parent', '上级菜单')} name={'parent_id'}>
<TreeSelect
treeData={[
{ id: 0, title: '顶级菜单', children: data as any },
]}
treeDefaultExpandAll={true}
fieldNames={{
label: 'title',
value: 'id'
}}/>
</Form.Item>
<Form.Item label={t('system.menus.form.type', '类型')} name={'type'}>
<Radio.Group
options={[
{
label: t('system.menus.form.typeOptions.menu', '菜单'),
value: 'menu'
},
{
label: t('system.menus.form.typeOptions.iframe', 'iframe'),
value: 'iframe'
},
{
label: t('system.menus.form.typeOptions.link', '外链'),
value: 'link'
},
{
label: t('system.menus.form.typeOptions.button', '按钮'),
value: 'button'
},
]}
optionType="button"
buttonStyle="solid"
/>
</Form.Item>
<Form.Item label={t('system.menus.form.name', '别名')} name={'name'}>
<Input/>
</Form.Item>
<Form.Item label={t('system.menus.form.icon', '图标')} name={'icon'}>
<IconPicker placement={'left'}/>
</Form.Item>
<Form.Item label={t('system.menus.form.sort', '排序')} name={'sort'}>
<InputNumber/>
</Form.Item>
<Form.Item label={t('system.menus.form.path', '路由')} name={'path'}>
<Input/>
</Form.Item>
<Form.Item label={t('system.menus.form.component', '视图')}
name={'component'}
help={t('system.menus.form.component.componentHelp', '视图路径,相对于src/pages')}
>
<Input addonBefore={'pages/'}/>
</Form.Item>
<Form.Item label={' '}>
<Button type="primary"
htmlType={'submit'}
loading={isPending}
onClick={() => {
form.validateFields().then((values) => {
mutate(values)
})
}}
>
{t('system.menus.form.save', '保存')}
</Button>
</Form.Item>
</ProCard>
<ProCard title={t('system.menus.form.button', '按钮')}
className={styles.formButtons}
colSpan={8}>
<Form.Item noStyle={true} name={'button'}
shouldUpdate={(prevValues: MenuItem, curValues) => {
return prevValues.id !== curValues.id
}}>
<ButtonTable form={form} key={(currentMenu as any).id}/>
</Form.Item>
</ProCard>
</Form>
</Flexbox>
</Flexbox>
</PageContainer>
)
}
export const Route = createLazyFileRoute('/system/menus')({
component: Menus
})
export default Menus