diff --git a/web/src/modules/jira/index.tsx b/web/src/modules/jira/index.tsx index c72c7e8..d4ceabf 100644 --- a/web/src/modules/jira/index.tsx +++ b/web/src/modules/jira/index.tsx @@ -26,8 +26,8 @@ export const jiraModule: HubModule = { ], nav: [ { to: "/board", label: "Доска связей", icon: }, - { to: "/issues", label: "Задачи", icon: }, - { to: "/feed", label: "Лента", icon: }, + { to: "/issues", label: "Задачи", icon: , padded: true }, + { to: "/feed", label: "Лента", icon: , padded: true, keepSearch: true }, ], Provider: RefreshProvider, SidebarStatus, diff --git a/web/src/modules/types.ts b/web/src/modules/types.ts index 0e7157f..78e7bf3 100644 --- a/web/src/modules/types.ts +++ b/web/src/modules/types.ts @@ -1,7 +1,11 @@ import type { ComponentType, ReactNode } from "react"; import type { Location, RouteObject } from "react-router"; -export type NavItem = { to: string; label: string; icon: ReactNode }; +export type NavItem = { + to: string; label: string; icon: ReactNode; + padded?: boolean; // страница с полями (не во всю ширину): оболочка не ставит ей класс page--board; для адресов вне панели класс ставится + keepSearch?: boolean; // при смене проекта строка запроса страницы сохраняется (параметры не проектные); иначе сбрасывается +}; // окно поверх страницы (карточка задачи): pageLocation — адрес страницы под окном, null — окна нет export type Overlay = { pageLocation: Location | null; element: ReactNode }; diff --git a/web/src/shell/Layout.tsx b/web/src/shell/Layout.tsx index fc98b5d..3081458 100644 --- a/web/src/shell/Layout.tsx +++ b/web/src/shell/Layout.tsx @@ -10,7 +10,8 @@ import { PAGE_ROUTES } from "./pages.tsx"; import { Sidebar } from "./Sidebar.tsx"; import "./shell.css"; -const NAV_PATHS: readonly string[] = MODULES.flatMap((m) => m.nav.map((n) => n.to)); +const NAV = MODULES.flatMap((m) => m.nav); +const NAV_PATHS: readonly string[] = NAV.map((n) => n.to); export function Layout() { const location = useLocation(); @@ -44,7 +45,7 @@ export function Layout() { const [newOpen, setNewOpen] = useState(false); // смена проекта: фильтры доски и списка — проектные и сбрасываются; период и виды ленты от проекта не зависят (R-1) const select = useCallback((label: string) => { - void navigate({ pathname: section ?? NAV_PATHS[0], search: withProject(section === "/feed" ? pageLocation.search : "", label) }); + void navigate({ pathname: section ?? NAV_PATHS[0], search: withProject(NAV.find((n) => n.to === section)?.keepSearch ? pageLocation.search : "", label) }); }, [navigate, section, pageLocation.search]); const ctx = useMemo(() => ({ state, projects: projects.data ?? [], select, openNew: () => setNewOpen(true) }), [state, projects.data, select]); @@ -54,7 +55,7 @@ export function Layout() {
-
+
n.to === section)?.padded ? "" : " page--board")}> {page}
diff --git a/web/src/shell/NotFound.tsx b/web/src/shell/NotFound.tsx index 1d17bde..e2378bb 100644 --- a/web/src/shell/NotFound.tsx +++ b/web/src/shell/NotFound.tsx @@ -1,11 +1,15 @@ +import { Fragment } from "react"; import { Link } from "react-router"; +import { MODULES } from "../modules/index.ts"; import { Notice } from "../ui/index.ts"; +const NAV = MODULES.flatMap((m) => m.nav); + export function NotFound() { return (
Страница не найдена}> - Разделы приложения: Доска связей, Задачи, Лента. + Разделы приложения: {NAV.map((n, i) => {i > 0 && ", "}{n.label})}.
);