Крошки переработаны

This commit is contained in:
Александр Сироткин 2022-12-06 00:56:02 +05:00
parent 1a737b6afe
commit 043f73fde3
4 changed files with 23 additions and 22 deletions

View File

@ -1,7 +1,7 @@
import { Breadcrumb, Layout, LayoutProps, Menu, SiderProps } from 'antd' import { Breadcrumb, Layout, LayoutProps, Menu, SiderProps } from 'antd'
import { Key, memo, ReactNode, Suspense, useCallback, useEffect, useMemo, useState } from 'react' import { Key, memo, ReactNode, Suspense, useCallback, useEffect, useMemo, useState } from 'react'
import { ItemType } from 'antd/lib/menu/hooks/useItems' import { ItemType } from 'antd/lib/menu/hooks/useItems'
import { Link, Outlet } from 'react-router-dom' import { Link, Outlet, useLocation } from 'react-router-dom'
import { import {
ApartmentOutlined, ApartmentOutlined,
CodeOutlined, CodeOutlined,
@ -31,7 +31,7 @@ export type LayoutPortalProps = Omit<LayoutProps, 'children'> & {
siderProps?: SiderProps & { userMenuProps?: UserMenuProps } siderProps?: SiderProps & { userMenuProps?: UserMenuProps }
isAdmin?: boolean isAdmin?: boolean
fallback?: JSX.Element fallback?: JSX.Element
breadcrumb?: boolean | JSX.Element breadcrumb?: boolean | ((path: string) => JSX.Element)
topRightBlock?: JSX.Element topRightBlock?: JSX.Element
} }
@ -49,6 +49,7 @@ const _LayoutPortal = memo(() => {
const [userMenuOpen, setUserMenuOpen] = useState<boolean>(false) const [userMenuOpen, setUserMenuOpen] = useState<boolean>(false)
const [currentWell, setCurrentWell] = useState<string>('') const [currentWell, setCurrentWell] = useState<string>('')
const [props, setProps] = useState<LayoutPortalProps>(defaultProps) const [props, setProps] = useState<LayoutPortalProps>(defaultProps)
const location = useLocation()
const { isAdmin, title, sheet, showSelector, selectorProps, sider, siderProps, fallback, breadcrumb, topRightBlock, ...other } = useMemo(() => props, [props]) const { isAdmin, title, sheet, showSelector, selectorProps, sider, siderProps, fallback, breadcrumb, topRightBlock, ...other } = useMemo(() => props, [props])
@ -66,6 +67,8 @@ const _LayoutPortal = memo(() => {
makeItem('Профиль', 'profile', <UserOutlined/>, null, () => setUserMenuOpen((prev) => !prev)), makeItem('Профиль', 'profile', <UserOutlined/>, null, () => setUserMenuOpen((prev) => !prev)),
].filter(Boolean) as ItemType[], [isAdmin, currentWell]) ].filter(Boolean) as ItemType[], [isAdmin, currentWell])
const breadcrumbItems = useMemo(() => typeof breadcrumb === 'function' && breadcrumb(location.pathname), [breadcrumb, location.pathname])
return ( return (
<Layout className={`page-layout ${isAdmin ? 'page-layout-admin' : ''}`}> <Layout className={`page-layout ${isAdmin ? 'page-layout-admin' : ''}`}>
{(sider || siderProps) && ( {(sider || siderProps) && (
@ -114,7 +117,7 @@ const _LayoutPortal = memo(() => {
<a style={{ userSelect: 'none' }} onClick={() => setWellsTreeOpen((prev) => !prev)}>{currentWell}</a> <a style={{ userSelect: 'none' }} onClick={() => setWellsTreeOpen((prev) => !prev)}>{currentWell}</a>
</Breadcrumb.Item> </Breadcrumb.Item>
)} )}
{breadcrumb !== true && breadcrumb} {breadcrumbItems}
</Breadcrumb> </Breadcrumb>
)} )}
{topRightBlock} {topRightBlock}

View File

@ -21,13 +21,12 @@ export const makeBreadcrumbItems = (items: PrivateMenuItem[], pathParts: string[
return out return out
} }
export const makeMenuBreadcrumbItems = ( export const makeMenuBreadcrumbItemsRender = (
menuItems: PrivateMenuItem[], menuItems: PrivateMenuItem[],
path: string,
pathRoot: RegExp = /^\//, pathRoot: RegExp = /^\//,
itemsProps?: FunctionalValue<(item: PrivateMenuItem) => BreadcrumbItemProps>, itemsProps?: FunctionalValue<(item: PrivateMenuItem) => BreadcrumbItemProps>,
itemRender?: (item: PrivateMenuItem) => JSX.Element, itemRender?: (item: PrivateMenuItem) => JSX.Element,
) => { ) => (path: string) => {
const getItemProps = getFunctionalValue(itemsProps) const getItemProps = getFunctionalValue(itemsProps)
const rootPart = pathRoot.exec(path) const rootPart = pathRoot.exec(path)

View File

@ -1,9 +1,9 @@
import { Navigate, Route, Routes, useLocation } from 'react-router-dom' import { Navigate, Route, Routes } from 'react-router-dom'
import { lazy, memo, useEffect, useMemo } from 'react' import { lazy, memo, useEffect, useMemo } from 'react'
import { RootPathContext, useLayoutProps, useRootPath } from '@asb/context' import { RootPathContext, useLayoutProps, useRootPath } from '@asb/context'
import { FastRunMenu } from '@components/FastRunMenu' import { FastRunMenu } from '@components/FastRunMenu'
import { makeMenuBreadcrumbItems } from '@components/MenuBreadcrumb' import { makeMenuBreadcrumbItemsRender } from '@components/MenuBreadcrumb'
import { NoAccessComponent, withPermissions } from '@utils' import { NoAccessComponent, withPermissions } from '@utils'
import { AdminNavigationMenu, menuItems } from './AdminNavigationMenu' import { AdminNavigationMenu, menuItems } from './AdminNavigationMenu'
@ -21,21 +21,18 @@ const TelemetryViewer = lazy(() => import('./Telemetry/TelemetryViewer'))
const TelemetryMerger = lazy(() => import('./Telemetry/TelemetryMerger')) const TelemetryMerger = lazy(() => import('./Telemetry/TelemetryMerger'))
const VisitLog = lazy(() => import('./VisitLog')) const VisitLog = lazy(() => import('./VisitLog'))
const layoutProps = {
sider: <AdminNavigationMenu />,
title: 'Администраторская панель',
isAdmin: true,
breadcrumb: makeMenuBreadcrumbItemsRender(menuItems, /^\/admin\//),
}
const AdminPanel = memo(() => { const AdminPanel = memo(() => {
const location = useLocation()
const root = useRootPath() const root = useRootPath()
const rootPath = useMemo(() => `${root}/admin`, [root]) const rootPath = useMemo(() => `${root}/admin`, [root])
const setLayoutProps = useLayoutProps() useLayoutProps(layoutProps)
useEffect(() => {
setLayoutProps({
sider: <AdminNavigationMenu />,
title: 'Администраторская панель',
isAdmin: true,
breadcrumb: makeMenuBreadcrumbItems(menuItems, location.pathname, /^\/admin\//),
})
}, [location.pathname])
return ( return (
<RootPathContext.Provider value={rootPath}> <RootPathContext.Provider value={rootPath}>

View File

@ -4,7 +4,7 @@ import { Navigate, Route, Routes, useLocation, useParams } from 'react-router-do
import { WellContext, RootPathContext, useRootPath, useLayoutProps, TopRightBlockContext } from '@asb/context' import { WellContext, RootPathContext, useRootPath, useLayoutProps, TopRightBlockContext } from '@asb/context'
import { FastRunMenu } from '@components/FastRunMenu' import { FastRunMenu } from '@components/FastRunMenu'
import { invokeWebApiWrapperAsync } from '@components/factory' import { invokeWebApiWrapperAsync } from '@components/factory'
import { makeMenuBreadcrumbItems } from '@components/MenuBreadcrumb' import { makeMenuBreadcrumbItemsRender } from '@components/MenuBreadcrumb'
import { NoAccessComponent, withPermissions } from '@utils' import { NoAccessComponent, withPermissions } from '@utils'
import { WellService } from '@api' import { WellService } from '@api'
@ -40,6 +40,8 @@ const DiagramReport = lazy(() => import('./Reports/DiagramReport'))
const Statistics = lazy(() => import('./Analytics/Statistics')) const Statistics = lazy(() => import('./Analytics/Statistics'))
const WellCompositeEditor = lazy(() => import('./Analytics/WellCompositeEditor')) const WellCompositeEditor = lazy(() => import('./Analytics/WellCompositeEditor'))
const breadcrumb = makeMenuBreadcrumbItemsRender(menuItems, /^\/well\/[^\/#?]+\//)
const Well = memo(() => { const Well = memo(() => {
const { idWell } = useParams() const { idWell } = useParams()
@ -82,9 +84,9 @@ const Well = memo(() => {
useEffect(() => setLayoutProps({ useEffect(() => setLayoutProps({
sider: <WellNavigationMenu variables={{ idWell: well.id }} />, sider: <WellNavigationMenu variables={{ idWell: well.id }} />,
breadcrumb: makeMenuBreadcrumbItems(menuItems, location.pathname, /^\/well\/[0-9]+\//), breadcrumb,
topRightBlock: topRightBlock?.(well), topRightBlock: topRightBlock?.(well),
}), [well, location.pathname, setLayoutProps, topRightBlock]) }), [well, setLayoutProps, topRightBlock])
return ( return (
<RootPathContext.Provider value={rootPath}> <RootPathContext.Provider value={rootPath}>