refactor(web): оболочка берёт padded и keepSearch из пунктов панели модулей (#87)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
9ea84c7edd
commit
93007f471b
@ -26,8 +26,8 @@ export const jiraModule: HubModule = {
|
||||
],
|
||||
nav: [
|
||||
{ to: "/board", label: "Доска связей", icon: <IconBoard /> },
|
||||
{ to: "/issues", label: "Задачи", icon: <IconList /> },
|
||||
{ to: "/feed", label: "Лента", icon: <IconHistory /> },
|
||||
{ to: "/issues", label: "Задачи", icon: <IconList />, padded: true },
|
||||
{ to: "/feed", label: "Лента", icon: <IconHistory />, padded: true, keepSearch: true },
|
||||
],
|
||||
Provider: RefreshProvider,
|
||||
SidebarStatus,
|
||||
|
||||
@ -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 };
|
||||
|
||||
|
||||
@ -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<ProjectCtx>(() => ({ state, projects: projects.data ?? [], select, openNew: () => setNewOpen(true) }),
|
||||
[state, projects.data, select]);
|
||||
@ -54,7 +55,7 @@ export function Layout() {
|
||||
<ProjectContext value={ctx}>
|
||||
<div className="shell">
|
||||
<Sidebar section={section} project={okLabel} />
|
||||
<main className={"page" + (section !== "/issues" && section !== "/feed" ? " page--board" : "")}>
|
||||
<main className={"page" + (NAV.find((n) => n.to === section)?.padded ? "" : " page--board")}>
|
||||
<ErrorBoundary key={at}>{page}</ErrorBoundary>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
@ -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 (
|
||||
<div className="crash">
|
||||
<Notice tone="warning" title={<h2>Страница не найдена</h2>}>
|
||||
Разделы приложения: <Link to="/board">Доска связей</Link>, <Link to="/issues">Задачи</Link>, <Link to="/feed">Лента</Link>.
|
||||
Разделы приложения: {NAV.map((n, i) => <Fragment key={n.to}>{i > 0 && ", "}<Link to={n.to}>{n.label}</Link></Fragment>)}.
|
||||
</Notice>
|
||||
</div>
|
||||
);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user