feat(P25-2/P25-3/P26-2/P28-1/P24-2/P29-3): 落地内部OA够用版前端入口与运营页面
关联 Issue: P25-2, P25-3, P25-4, P26-2, P26-4, P28-1, P28-2, P28-3, P28-4, P24-2, P29-3
这个提交包含在:
@@ -1,9 +1,42 @@
|
||||
import { Outlet } from "react-router-dom";
|
||||
import { useEffect } from "react";
|
||||
import { Outlet, useLocation } from "react-router-dom";
|
||||
import { NAV_ITEMS } from "../components/navigation/NavLinks";
|
||||
import { ErrorBoundary } from "../components/common/ErrorBoundary";
|
||||
import { Sidebar } from "../components/navigation/Sidebar";
|
||||
import { Topbar } from "../components/navigation/Topbar";
|
||||
import { writeRecentVisit } from "../lib/recentVisits";
|
||||
|
||||
const EXTRA_TITLE_ENTRIES = [
|
||||
{ path: "/notifications", title: "通知中心" },
|
||||
{ path: "/reimbursements/", title: "报销详情" },
|
||||
{ path: "/workflow/tasks/", title: "待办详情" },
|
||||
];
|
||||
|
||||
function resolveVisitTitle(pathname: string) {
|
||||
const candidates = [
|
||||
...NAV_ITEMS.map((item) => ({ path: item.to, title: item.label })),
|
||||
...EXTRA_TITLE_ENTRIES,
|
||||
].sort((left, right) => right.path.length - left.path.length);
|
||||
|
||||
const matched = candidates.find((item) => pathname === item.path || pathname.startsWith(item.path));
|
||||
if (matched) {
|
||||
return matched.title;
|
||||
}
|
||||
|
||||
return pathname === "/" ? "Portal" : pathname;
|
||||
}
|
||||
|
||||
export function AppShellLayout() {
|
||||
const location = useLocation();
|
||||
|
||||
useEffect(() => {
|
||||
const pathname = location.pathname;
|
||||
if (!pathname || pathname === "/login" || pathname.startsWith("/mobile/")) {
|
||||
return;
|
||||
}
|
||||
writeRecentVisit(pathname, resolveVisitTitle(pathname));
|
||||
}, [location.pathname]);
|
||||
|
||||
return (
|
||||
<div className="flex min-h-screen bg-zinc-50">
|
||||
<Sidebar />
|
||||
|
||||
在新工单中引用
屏蔽一个用户