feat: навигация на ui-kit SIdebar + мобильный drawer
Tests / frontend-test (push) Successful in 1m9s
Tests / frontend-test (push) Successful in 1m9s
This commit is contained in:
@@ -2,7 +2,8 @@ import * as React from 'react';
|
||||
import styles from './RequestPortal.module.scss';
|
||||
import '@tnsu/ui-kit/styles.css';
|
||||
import type { IRequestPortalProps } from './IRequestPortalProps';
|
||||
import { IconSprite } from '@tnsu/ui-kit';
|
||||
import { IconSprite, Sidebar, SidebarToggle } from '@tnsu/ui-kit';
|
||||
import type { ISidebarItem } from '@tnsu/ui-kit';
|
||||
import { ConfirmHost } from '../shared/ui';
|
||||
import {
|
||||
navigate,
|
||||
@@ -20,7 +21,6 @@ import {
|
||||
} from '../shared/routing';
|
||||
import { onRequestsChanged, emitRequestsChanged } from '../shared/requestEvents';
|
||||
import { confirmDiscardFormChanges, markFormClean, markFormDirty } from '../shared/unsavedChanges';
|
||||
import { SideNav } from './SideNav/SideNav';
|
||||
import { Drawer } from './Drawer/Drawer';
|
||||
import { CategoryTabs } from './CategoryTabs/CategoryTabs';
|
||||
import { CATEGORIES, DEFAULT_CATEGORY_ID } from '../data/categories';
|
||||
@@ -59,6 +59,7 @@ const RequestPortal: React.FC<IRequestPortalProps> = ({ hasTeamsContext, context
|
||||
|
||||
const route = useRoute();
|
||||
const [navCollapsed, setNavCollapsed] = React.useState<boolean>(false);
|
||||
const [mobileNavOpen, setMobileNavOpen] = React.useState<boolean>(false);
|
||||
const [navCounts, setNavCounts] = React.useState<INavCounts | undefined>(undefined);
|
||||
|
||||
const [activeCategoryId, setActiveCategoryId] = React.useState<string>(() => {
|
||||
@@ -250,26 +251,38 @@ const RequestPortal: React.FC<IRequestPortalProps> = ({ hasTeamsContext, context
|
||||
}).catch(() => undefined);
|
||||
};
|
||||
|
||||
// Разделы бокового меню для пакетного Sidebar (счётчики — из navCounts).
|
||||
const navItems: ISidebarItem[] = [
|
||||
{ id: 'new', title: 'Новая заявка', icon: 'plus' },
|
||||
{ id: 'approvals', title: 'На согласовании', icon: 'user-check', count: navCounts?.approvals },
|
||||
{ id: 'execution', title: 'На исполнении', icon: 'helmet', count: navCounts?.execution },
|
||||
{ id: 'rework', title: 'Доработка', icon: 'edit', count: navCounts?.rework },
|
||||
{ id: 'own', title: 'Мои заявки', icon: 'clipboard' },
|
||||
{ id: 'search', title: 'Поиск', icon: 'search' },
|
||||
];
|
||||
|
||||
return (
|
||||
<section className={rootClasses}>
|
||||
<IconSprite />
|
||||
<ConfirmHost />
|
||||
<div className={styles.layout}>
|
||||
<div className={styles.side}>
|
||||
<SideNav
|
||||
<Sidebar
|
||||
items={navItems}
|
||||
activeId={route.nav}
|
||||
onChange={goto}
|
||||
counts={{
|
||||
approvals: navCounts?.approvals,
|
||||
execution: navCounts?.execution,
|
||||
rework: navCounts?.rework,
|
||||
}}
|
||||
onChange={(id) => goto(id as NavSection)}
|
||||
brand="Портал заявок"
|
||||
collapsed={navCollapsed}
|
||||
onToggleCollapsed={() => setNavCollapsed((v) => !v)}
|
||||
mobileOpen={mobileNavOpen}
|
||||
onMobileClose={() => setMobileNavOpen(false)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<main className={styles.main}>
|
||||
<div className={styles.mobileNav}>
|
||||
<SidebarToggle onClick={() => setMobileNavOpen(true)} />
|
||||
</div>
|
||||
{/* Раздел «Новая заявка» держим СМОНТИРОВАННЫМ и просто прячем стилем,
|
||||
когда открыта другая вкладка. Иначе React размонтировал бы форму, и
|
||||
всё введённое пропадало бы при переключении на «Мои заявки» и
|
||||
|
||||
Reference in New Issue
Block a user