import { Button, Layout, LayoutProps, Menu, SiderProps } from 'antd' import { Key, memo, ReactNode, Suspense, useCallback, useEffect, useMemo, useState } from 'react' import { ItemType } from 'antd/lib/menu/hooks/useItems' import { Link, Outlet } from 'react-router-dom' import { ApartmentOutlined, CodeOutlined, HomeOutlined, MenuFoldOutlined, MenuUnfoldOutlined, UserOutlined, } from '@ant-design/icons' import { LayoutPropsContext } from '@asb/context' import PageHeader from '@components/PageHeader' import { UserMenu, UserMenuProps } from '@components/UserMenu' import { WellTreeSelector, WellTreeSelectorProps } from '@components/selectors/WellTreeSelector' import { isURLAvailable, wrapPrivateComponent } from '@utils' import SuspenseFallback from './SuspenseFallback' import '@styles/layout.less' const { Content, Sider } = Layout export type LayoutPortalProps = Omit & { title?: ReactNode sheet?: boolean showSelector?: boolean selectorProps?: WellTreeSelectorProps sider?: boolean | JSX.Element siderProps?: SiderProps & { userMenuProps?: UserMenuProps } isAdmin?: boolean fallback?: JSX.Element } const defaultProps: LayoutPortalProps = { title: 'Единая цифровая платформа', sider: true, sheet: true, } const makeItem = (title: string, key: Key, icon: JSX.Element, label?: ReactNode, onClick?: () => void) => ({ icon, key, title, label: label ?? title, onClick }) const _LayoutPortal = memo(() => { const [menuCollapsed, setMenuCollapsed] = useState(true) const [wellsTreeOpen, setWellsTreeOpen] = useState(false) const [userMenuOpen, setUserMenuOpen] = useState(false) const [currentWell, setCurrentWell] = useState('') const [props, setProps] = useState(defaultProps) const { isAdmin, title, sheet, showSelector, selectorProps, sider, siderProps, fallback, ...other } = useMemo(() => props, [props]) const setLayoutProps = useCallback((props: LayoutPortalProps) => setProps({ ...defaultProps, ...props}), []) useEffect(() => { if (typeof showSelector === 'boolean') setWellsTreeOpen(showSelector) }, [showSelector]) const menuItems = useMemo(() => [ !isAdmin && makeItem(currentWell, 'well', , null, () => setWellsTreeOpen((prev) => !prev)), isAdmin && makeItem('Вернуться на сайт', 'go_back', , Домой), !isAdmin && isURLAvailable('/admin') && makeItem('Панель администратора', 'admin_panel', , Панель администратора), makeItem('Профиль', 'profile', , null, () => setUserMenuOpen((prev) => !prev)), ].filter(Boolean) as ItemType[], [isAdmin, currentWell]) return ( {(sider || siderProps) && (
{sider}
setUserMenuOpen(false)} isAdmin={isAdmin} {...siderProps?.userMenuProps} />
)} {isAdmin ? ( ) : ( <> setWellsTreeOpen(false)} {...selectorProps} onChange={(well) => setCurrentWell(well ?? 'Выберите месторождение')} /> )} }>
) }) export const LayoutPortal = wrapPrivateComponent(_LayoutPortal, { requirements: ['Deposit.get'], }) export default LayoutPortal