|
|
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
|