feat: 业务链条配置管理导航与顶栏用户名统一
业务链条页增加配置管理入口与返回导航;配置管理页通过 aliasPaths 保持侧栏选中;顶栏用户名与设置个人信息页共用 getAccountDisplayName。
This commit is contained in:
1 parent
d8102e8db8
commit
318f6c0c0c
8 files changed
+544
-507
No files matched your search
@@ -6,6 +6,8 @@ import { getStoredAuth } from "@/core/auth";
|
||||
import { isWujieEnv } from "@/core/embed/wujie";
|
||||
import {
|
||||
defaultExpandedIds,
|
||||
menuItemContainsPath,
|
||||
menuItemMatchesPath,
|
||||
type MenuItem,
|
||||
} from "@/core/page-layout/sidebar-menu";
|
||||
import { useSidebarMenuItems } from "@/core/page-layout/use-sidebar-menu";
|
||||
@@ -53,13 +55,7 @@ export function PageSidebarDark({ collapsed, onToggleCollapsed }: PageSidebarDar
|
||||
}, 180);
|
||||
};
|
||||
|
||||
const hasActiveChild = (item: MenuItem): boolean => {
|
||||
if (item.path && (pathname === item.path || pathname.startsWith(item.path + "/"))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return item.children?.some(hasActiveChild) ?? false;
|
||||
};
|
||||
const hasActiveChild = (item: MenuItem): boolean => menuItemContainsPath(item, pathname);
|
||||
|
||||
// lazy init:仅在首次 render 计算一次 active id;之后由下面的 useEffect 跟随 pathname 同步
|
||||
const [activeTopId, setActiveTopId] = useState<string>(
|
||||
@@ -152,9 +148,9 @@ export function PageSidebarDark({ collapsed, onToggleCollapsed }: PageSidebarDar
|
||||
const isSidebarItemActive = (item: MenuItem) =>
|
||||
inWujieEnv
|
||||
? item.id === activeTopId
|
||||
: item.path
|
||||
? pathname === item.path || pathname.startsWith(item.path + "/")
|
||||
: hasActiveChild(item);
|
||||
: item.path || item.aliasPaths?.length
|
||||
? menuItemMatchesPath(item, pathname)
|
||||
: menuItemContainsPath(item, pathname);
|
||||
const handleSidebarItemClick = (item: MenuItem) => {
|
||||
if (inWujieEnv) {
|
||||
handleTopItemClick(item);
|
||||
@@ -176,7 +172,9 @@ export function PageSidebarDark({ collapsed, onToggleCollapsed }: PageSidebarDar
|
||||
{items.map((item) => {
|
||||
const hasChildren = !!item.children?.length;
|
||||
const isExpanded = expandedIds.has(item.id);
|
||||
const isSelected = item.path ? pathname === item.path : hasActiveChild(item);
|
||||
const isSelected = item.path || item.aliasPaths?.length
|
||||
? menuItemMatchesPath(item, pathname)
|
||||
: hasActiveChild(item);
|
||||
|
||||
return (
|
||||
<div
|
||||
|
||||
@@ -28,6 +28,8 @@ import { useUnreadCount } from "@/core/notifications";
|
||||
import {
|
||||
defaultExpandedIds,
|
||||
getActiveThirdLevelItems,
|
||||
menuItemContainsPath,
|
||||
menuItemMatchesPath,
|
||||
type MenuItem,
|
||||
} from "@/core/page-layout/sidebar-menu";
|
||||
import { useSidebarMenuItems } from "@/core/page-layout/use-sidebar-menu";
|
||||
@@ -41,12 +43,8 @@ type PageSidebarProps = {
|
||||
|
||||
type SettingsSection = "account" | "appearance" | "memory" | "tools" | "about";
|
||||
|
||||
const hasActiveChild = (item: MenuItem, pathname: string): boolean => {
|
||||
if (item.path && (pathname === item.path || pathname.startsWith(item.path + "/"))) {
|
||||
return true;
|
||||
}
|
||||
return item.children?.some((child) => hasActiveChild(child, pathname)) ?? false;
|
||||
};
|
||||
const hasActiveChild = (item: MenuItem, pathname: string): boolean =>
|
||||
menuItemContainsPath(item, pathname);
|
||||
|
||||
const findFirstRoutePath = (items?: MenuItem[]): string | null => {
|
||||
if (!items?.length) {
|
||||
@@ -116,9 +114,9 @@ function SecondaryNavSidebar() {
|
||||
const secondaryItems = activeTopItem?.children ?? [];
|
||||
|
||||
const isItemActive = (item: MenuItem) =>
|
||||
item.path
|
||||
? pathname === item.path || pathname.startsWith(item.path + "/")
|
||||
: hasActiveChild(item, pathname);
|
||||
item.path || item.aliasPaths?.length
|
||||
? menuItemMatchesPath(item, pathname)
|
||||
: menuItemContainsPath(item, pathname);
|
||||
|
||||
const handleItemClick = (item: MenuItem) => {
|
||||
const path = item.path ?? findFirstRoutePath(item.children);
|
||||
@@ -211,9 +209,8 @@ function SecondaryNavSidebar() {
|
||||
<nav className="light-sidebar-subnav" aria-label="三级菜单">
|
||||
{thirdItems.map((child) => {
|
||||
const ChildIcon = child.icon;
|
||||
const childActive = child.path
|
||||
? pathname === child.path || pathname.startsWith(child.path + "/")
|
||||
: hasActiveChild(child, pathname);
|
||||
const childActive = menuItemMatchesPath(child, pathname)
|
||||
|| (child.children?.length ? menuItemContainsPath(child, pathname) : false);
|
||||
return (
|
||||
<button
|
||||
key={child.id}
|
||||
@@ -301,7 +298,7 @@ function LegacyAccordionSidebar({
|
||||
|
||||
const renderLeaf = (item: MenuItem, depth = 0) => {
|
||||
const Icon = item.icon;
|
||||
const isActive = !!item.path && pathname === item.path;
|
||||
const isActive = menuItemMatchesPath(item, pathname);
|
||||
|
||||
return (
|
||||
<button
|
||||
|
||||
@@ -6,7 +6,7 @@ import { toast } from "sonner";
|
||||
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { clearStoredAuth, getStoredAuth } from "@/core/auth";
|
||||
import { clearStoredAuth, getAccountDisplayName, getStoredAuth } from "@/core/auth";
|
||||
|
||||
import { SettingsSection } from "./settings-section";
|
||||
|
||||
@@ -37,8 +37,7 @@ export function AccountSettingsPage() {
|
||||
);
|
||||
}
|
||||
|
||||
const usernameFromEmail = (auth.email ?? "").split("@")[0] ?? "";
|
||||
const displayName = usernameFromEmail || auth.user_id;
|
||||
const displayName = getAccountDisplayName(auth);
|
||||
|
||||
const handleLogout = () => {
|
||||
clearStoredAuth();
|
||||
|
||||
Reference in new issue
Block a user