Переработан PrivateMenu для работы с любыми указанными переменными

This commit is contained in:
Александр Сироткин 2022-12-05 20:35:29 +05:00
parent 540da341da
commit cb8be79274
6 changed files with 33 additions and 33 deletions

View File

@ -5,11 +5,11 @@ import { AutoComplete } from 'antd'
import { join } from 'path'
import { useWell } from '@asb/context'
import { makeItem, PrivateWellMenuItem } from './PrivateWellMenu'
import { makeItem, PrivateMenuItem } from './PrivateMenu'
import { hasPermission, isURLAvailable } from '@utils'
import { menuItems as adminMenuItems } from '@pages/AdminPanel/AdminNavigationMenu'
import { menuItems as wellMenuItems } from '@pages/Well/NavigationMenu'
import { menuItems as wellMenuItems } from '@pages/Well/WellNavigationMenu'
import '@styles/fast_run_menu.less'
@ -29,7 +29,7 @@ const transliterateToEn = (text: string) => Object.entries(transliterationTable)
const applyVars = (route: string, vars?: object): string => !vars ? route :
Object.entries(vars).reduce((out, [key, value]) => out.replaceAll(`{${key}}`, value), route)
const makeOptions = (items: PrivateWellMenuItem[], vars?: object): OptionType[] => {
const makeOptions = (items: PrivateMenuItem[], vars?: object): OptionType[] => {
const out: OptionType[] = []
items.forEach((item) => {
if (!hasPermission(item.permissions)) return
@ -78,7 +78,7 @@ export const FastRunMenu = memo(() => {
]
if (isURLAvailable('/admin'))
menus.push(makeItem('Панель администратора', '/admin', [], undefined, adminMenuItems as PrivateWellMenuItem[]))
menus.push(makeItem('Панель администратора', '/admin', [], undefined, adminMenuItems as PrivateMenuItem[]))
if (well.id)
menus.push(

View File

@ -2,16 +2,16 @@ import { Breadcrumb, BreadcrumbItemProps } from 'antd'
import { Link } from 'react-router-dom'
import { join } from 'path'
import { PrivateWellMenuItem } from '@components/PrivateWellMenu'
import { PrivateMenuItem } from '@components/PrivateMenu'
import { FunctionalValue, getFunctionalValue, } from '@utils'
export const makeBreadcrumbItems = (items: PrivateWellMenuItem[], pathParts: string[], root: string = '/') => {
export const makeBreadcrumbItems = (items: PrivateMenuItem[], pathParts: string[], root: string = '/') => {
const out = []
const parts = [...pathParts]
let route = root
let arr: PrivateWellMenuItem[] | undefined = items
let arr: PrivateMenuItem[] | undefined = items
while (arr && parts.length > 0) {
const child: PrivateWellMenuItem | undefined = arr.find(elm => elm.route.toLowerCase() === parts[0].toLowerCase())
const child: PrivateMenuItem | undefined = arr.find(elm => elm.route.toLowerCase() === parts[0].toLowerCase())
if (!child) break
route = join(route, child.route)
out.push({ ...child, route })
@ -22,11 +22,11 @@ export const makeBreadcrumbItems = (items: PrivateWellMenuItem[], pathParts: str
}
export const makeMenuBreadcrumbItems = (
menuItems: PrivateWellMenuItem[],
menuItems: PrivateMenuItem[],
path: string,
pathRoot: RegExp = /^\//,
itemsProps?: FunctionalValue<(item: PrivateWellMenuItem) => BreadcrumbItemProps>,
itemRender?: (item: PrivateWellMenuItem) => JSX.Element,
itemsProps?: FunctionalValue<(item: PrivateMenuItem) => BreadcrumbItemProps>,
itemRender?: (item: PrivateMenuItem) => JSX.Element,
) => {
const getItemProps = getFunctionalValue(itemsProps)

View File

@ -1,21 +1,21 @@
import { ItemType } from 'antd/lib/menu/hooks/useItems'
import { Menu, MenuProps } from 'antd'
import { memo, ReactNode, useMemo } from 'react'
import { Link, useLocation } from 'react-router-dom'
import { join } from 'path'
import { Menu, MenuProps } from 'antd'
import { hasPermission, Permission } from '@utils'
export type PrivateWellMenuItem = {
export type PrivateMenuItem = {
title: string
route: string
permissions: Permission | Permission[]
icon?: ReactNode
visible?: boolean
children?: PrivateWellMenuItem[]
children?: PrivateMenuItem[]
}
const makeItems = (items: PrivateWellMenuItem[], parentRoute: string, pathParser?: (path: string, parent: string) => string): ItemType[] => {
const makeItems = (items: PrivateMenuItem[], parentRoute: string, pathParser?: (path: string, parent: string) => string): ItemType[] => {
return items.map((item) => {
if (item.visible === false || !(item.visible === true || hasPermission(item.permissions))) return null
@ -43,11 +43,11 @@ const makeItems = (items: PrivateWellMenuItem[], parentRoute: string, pathParser
}).filter(Boolean)
}
const makeItemList = (items: PrivateWellMenuItem[], rootPath: string, wellId?: number): ItemType[] => {
const makeItemList = (items: PrivateMenuItem[], rootPath: string, variables: Record<string, number | string>): ItemType[] => {
const parser = (path: string, parent: string) => {
if (!path.startsWith('/'))
path = join(parent, path)
return path.replace(/\{wellId\}/, String(wellId))
return Object.entries(variables).reduce((out, [key, value]) => out.replaceAll(`{${key}}`, String(value)), path)
}
return makeItems(items, rootPath, parser)
@ -58,9 +58,9 @@ export const makeItem = (
route: string,
permissions: Permission | Permission[],
icon?: ReactNode,
children?: PrivateWellMenuItem[],
children?: PrivateMenuItem[],
visible?: boolean
): PrivateWellMenuItem => ({
): PrivateMenuItem => ({
title,
route,
icon,
@ -69,16 +69,16 @@ export const makeItem = (
visible,
})
export type PrivateWellMenuProps = Omit<MenuProps, 'items'> & {
idWell?: number
items: PrivateWellMenuItem[]
export type PrivateMenuProps = Omit<MenuProps, 'items'> & {
variables?: Record<string, number | string>
items: PrivateMenuItem[]
rootPath?: string
}
export const PrivateWellMenu = memo<PrivateWellMenuProps>(({ idWell, items, rootPath = '/', ...other }) => {
export const PrivateMenu = memo<PrivateMenuProps>(({ variables, items, rootPath = '/', ...other }) => {
const location = useLocation()
const menuItems = useMemo(() => makeItemList(items, rootPath, idWell), [items, rootPath, idWell])
const menuItems = useMemo(() => makeItemList(items, rootPath, variables || {}), [items, rootPath, variables])
const tabKeys = useMemo(() => {
const out = []

View File

@ -12,7 +12,7 @@ import {
UserOutlined,
} from '@ant-design/icons'
import { makeItem, PrivateWellMenu } from '@components/PrivateWellMenu'
import { makeItem, PrivateMenu } from '@components/PrivateMenu'
import { isDev } from '@utils'
export const menuItems = [
@ -33,7 +33,7 @@ export const menuItems = [
].filter(Boolean)
export const AdminNavigationMenu = memo((props) => (
<PrivateWellMenu
<PrivateMenu
{...props}
items={menuItems}
rootPath={'/admin'}

View File

@ -13,7 +13,7 @@ import {
TableOutlined,
} from '@ant-design/icons'
import { makeItem, PrivateWellMenu } from '@components/PrivateWellMenu'
import { makeItem, PrivateMenu } from '@components/PrivateMenu'
export const menuItems = [
makeItem('Телеметрия', 'telemetry', [], <FundViewOutlined />, [
@ -59,15 +59,15 @@ export const menuItems = [
makeItem('Дело скважины', 'well_case', [], <FolderOutlined />),
]
export const NavigationMenu = memo((props) => (
<PrivateWellMenu
export const WellNavigationMenu = memo((props) => (
<PrivateMenu
{...props}
items={menuItems}
rootPath={'/well/{wellId}'}
rootPath={'/well/{idWell}'}
mode={'inline'}
theme={'dark'}
style={{ backgroundColor: 'transparent' }}
/>
))
export default NavigationMenu
export default WellNavigationMenu

View File

@ -8,7 +8,7 @@ import { makeMenuBreadcrumbItems } from '@components/MenuBreadcrumb'
import { NoAccessComponent, withPermissions } from '@utils'
import { WellService } from '@api'
import { NavigationMenu, menuItems } from './NavigationMenu'
import { WellNavigationMenu, menuItems } from './WellNavigationMenu'
import '@styles/index.css'
@ -81,7 +81,7 @@ const Well = memo(() => {
}, [idWell])
useEffect(() => setLayoutProps({
sider: <NavigationMenu idWell={well.id} />,
sider: <WellNavigationMenu variables={{ idWell: well.id }} />,
breadcrumb: makeMenuBreadcrumbItems(menuItems, location.pathname, /^\/well\/[0-9]+\//),
topRightBlock: topRightBlock?.(well),
}), [well, location.pathname, setLayoutProps, topRightBlock])