mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-09 09:06:36 +08:00
feat(settings): support full console menu display management in settings other-tab
- Rebuild MENU_GROUPS in `other-tab.tsx` to include all 13 business console items with safety read-only constraints on Dashboard. - Support reactive filtering in `OpenFlareSidebarMenu` using `menu_display_config` to hide items and empty collapsible groups. - Fix React Hydration Error #418 when directly loading dynamic websites on SSR by wrapping client component with mounted state hook. - Add `bytes_sent` to `NodeAccessLog` on both Agent and Master Server. - Create ClickHouse migration `202607120001_add_bytes_sent_to_node_access_logs.sql`. - Refactor duplicate stats structs by centralizing them into `analyticsmodel` package with type aliases. - Simplify access log store delegations and remove redundant mapping loops. - Regenerate Swagger documentation. - Update changelog index.md.
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
import Link from 'next/link';
|
||||
import {usePathname} from 'next/navigation';
|
||||
import {useEffect, useState} from 'react';
|
||||
import {useEffect, useMemo, useState} from 'react';
|
||||
import {ChevronRight} from 'lucide-react';
|
||||
|
||||
import {Collapsible, CollapsibleContent, CollapsibleTrigger} from '@/components/ui/collapsible';
|
||||
@@ -20,6 +20,24 @@ import {
|
||||
openflareSidebarNav,
|
||||
isNavGroupActive,
|
||||
} from '@/lib/navigation/openflare-nav';
|
||||
import {usePublicConfig} from '@/hooks/use-public-config';
|
||||
|
||||
function parseMenuDisplayConfig(raw: string | undefined): Record<string, boolean> {
|
||||
if (!raw) return {};
|
||||
try {
|
||||
const parsed: unknown = JSON.parse(raw);
|
||||
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return {};
|
||||
|
||||
return Object.entries(parsed).reduce<Record<string, boolean>>((result, [key, value]) => {
|
||||
if (typeof value === 'boolean') {
|
||||
result[key] = value;
|
||||
}
|
||||
return result;
|
||||
}, {});
|
||||
} catch {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
function SidebarNavGroupMenuItem({
|
||||
group,
|
||||
@@ -81,21 +99,30 @@ export function OpenFlareSidebarMenu({
|
||||
onNavigate?: () => void;
|
||||
}) {
|
||||
const pathname = usePathname();
|
||||
const { config } = usePublicConfig();
|
||||
const displayConfig = useMemo(() => parseMenuDisplayConfig(config?.menu_display_config), [config]);
|
||||
|
||||
return (
|
||||
<SidebarMenu className="gap-1">
|
||||
{openflareSidebarNav.map((entry) => {
|
||||
if (entry.kind === 'group') {
|
||||
const filteredItems = entry.items.filter((item) => displayConfig[item.url] !== false);
|
||||
if (filteredItems.length === 0) return null;
|
||||
|
||||
return (
|
||||
<SidebarNavGroupMenuItem
|
||||
key={entry.title}
|
||||
group={entry}
|
||||
group={{ ...entry, items: filteredItems }}
|
||||
pathname={pathname}
|
||||
onNavigate={onNavigate}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (displayConfig[entry.url] === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<SidebarMenuItem key={entry.title}>
|
||||
<SidebarMenuButton
|
||||
|
||||
Reference in New Issue
Block a user