refactor(sidebar): group nav into sidebarGroups instead of slice(0,3)+slice(3) (P2-27)
Move Core vs Collaborate grouping from implicit array index to explicit sidebarGroups NavGroup[] structure surfaced from useUIController.
This commit is contained in:
1 parent
32687033fc
commit
0845187672
3 files changed
+29
-19
No files matched your search
@@ -170,7 +170,7 @@ export function App() {
|
|||||||
setSidebarCollapsed={ui.setSidebarCollapsed}
|
setSidebarCollapsed={ui.setSidebarCollapsed}
|
||||||
section={ui.section}
|
section={ui.section}
|
||||||
setSection={ui.setSection}
|
setSection={ui.setSection}
|
||||||
sidebarNav={ui.sidebarNav}
|
sidebarGroups={ui.sidebarGroups}
|
||||||
navBadges={company.navBadges}
|
navBadges={company.navBadges}
|
||||||
companySwitcherOpen={ui.companySwitcherOpen}
|
companySwitcherOpen={ui.companySwitcherOpen}
|
||||||
setCompanySwitcherOpen={ui.setCompanySwitcherOpen}
|
setCompanySwitcherOpen={ui.setCompanySwitcherOpen}
|
||||||
|
|||||||
@@ -23,12 +23,16 @@ import type { AppLocale } from "@shared/locale";
|
|||||||
|
|
||||||
type NavItemDef = { id: SectionId; labelKey: string; icon: typeof SquaresFour };
|
type NavItemDef = { id: SectionId; labelKey: string; icon: typeof SquaresFour };
|
||||||
export type NavItem = { id: SectionId; label: string; icon: typeof SquaresFour };
|
export type NavItem = { id: SectionId; label: string; icon: typeof SquaresFour };
|
||||||
|
export type NavGroup = { items: NavItem[] };
|
||||||
export type PaletteAction = { key: string; section: SectionId; entityId?: string };
|
export type PaletteAction = { key: string; section: SectionId; entityId?: string };
|
||||||
|
|
||||||
const sidebarNavDefs: NavItemDef[] = [
|
const sidebarCoreDefs: NavItemDef[] = [
|
||||||
{ id: "overview", labelKey: "nav.overview", icon: SquaresFour },
|
{ id: "overview", labelKey: "nav.overview", icon: SquaresFour },
|
||||||
{ id: "inbox", labelKey: "nav.inbox", icon: Tray },
|
{ id: "inbox", labelKey: "nav.inbox", icon: Tray },
|
||||||
{ id: "communication", labelKey: "nav.communication", icon: ChatCircle },
|
{ id: "communication", labelKey: "nav.communication", icon: ChatCircle },
|
||||||
|
];
|
||||||
|
|
||||||
|
const sidebarCollaborateDefs: NavItemDef[] = [
|
||||||
{ id: "tasks", labelKey: "nav.work", icon: ListChecks },
|
{ id: "tasks", labelKey: "nav.work", icon: ListChecks },
|
||||||
{ id: "approvals", labelKey: "nav.approvals", icon: ShieldCheck },
|
{ id: "approvals", labelKey: "nav.approvals", icon: ShieldCheck },
|
||||||
{ id: "agents", labelKey: "nav.agents", icon: UsersThree },
|
{ id: "agents", labelKey: "nav.agents", icon: UsersThree },
|
||||||
@@ -51,10 +55,17 @@ export function useUIController() {
|
|||||||
const locale = useAppStore((s) => s.locale);
|
const locale = useAppStore((s) => s.locale);
|
||||||
const t = useMemo(() => createTranslator(locale), [locale]);
|
const t = useMemo(() => createTranslator(locale), [locale]);
|
||||||
|
|
||||||
const sidebarNav: NavItem[] = useMemo(
|
const sidebarGroups: NavGroup[] = useMemo(
|
||||||
() => sidebarNavDefs.map((item) => ({ id: item.id, label: t(item.labelKey), icon: item.icon })),
|
() => [
|
||||||
|
{ items: sidebarCoreDefs.map((item) => ({ id: item.id, label: t(item.labelKey), icon: item.icon })) },
|
||||||
|
{ items: sidebarCollaborateDefs.map((item) => ({ id: item.id, label: t(item.labelKey), icon: item.icon })) },
|
||||||
|
],
|
||||||
[t],
|
[t],
|
||||||
);
|
);
|
||||||
|
const sidebarNav: NavItem[] = useMemo(
|
||||||
|
() => sidebarGroups.flatMap((group) => group.items),
|
||||||
|
[sidebarGroups],
|
||||||
|
);
|
||||||
const navItems: NavItem[] = useMemo(
|
const navItems: NavItem[] = useMemo(
|
||||||
() =>
|
() =>
|
||||||
sidebarNav
|
sidebarNav
|
||||||
@@ -160,6 +171,7 @@ export function useUIController() {
|
|||||||
t,
|
t,
|
||||||
handleLocaleChange,
|
handleLocaleChange,
|
||||||
sidebarNav,
|
sidebarNav,
|
||||||
|
sidebarGroups,
|
||||||
navItems,
|
navItems,
|
||||||
section,
|
section,
|
||||||
setSection,
|
setSection,
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import { SectionButton } from "../components/ui";
|
|||||||
import { NEW_ENTITY_ID } from "../lib/constants";
|
import { NEW_ENTITY_ID } from "../lib/constants";
|
||||||
|
|
||||||
type NavItem = { id: SectionId; label: string; icon: typeof Gear };
|
type NavItem = { id: SectionId; label: string; icon: typeof Gear };
|
||||||
|
type NavGroup = { items: NavItem[] };
|
||||||
|
|
||||||
interface SidebarViewProps {
|
interface SidebarViewProps {
|
||||||
isMac: boolean;
|
isMac: boolean;
|
||||||
@@ -19,7 +20,7 @@ interface SidebarViewProps {
|
|||||||
setSidebarCollapsed: (value: boolean) => void;
|
setSidebarCollapsed: (value: boolean) => void;
|
||||||
section: SectionId;
|
section: SectionId;
|
||||||
setSection: (section: SectionId) => void;
|
setSection: (section: SectionId) => void;
|
||||||
sidebarNav: NavItem[];
|
sidebarGroups: NavGroup[];
|
||||||
navBadges: Partial<Record<SectionId, { count: number; tone: "default" | "warn" | "danger" }>>;
|
navBadges: Partial<Record<SectionId, { count: number; tone: "default" | "warn" | "danger" }>>;
|
||||||
companySwitcherOpen: boolean;
|
companySwitcherOpen: boolean;
|
||||||
setCompanySwitcherOpen: (value: boolean) => void;
|
setCompanySwitcherOpen: (value: boolean) => void;
|
||||||
@@ -39,7 +40,7 @@ export function SidebarView({
|
|||||||
setSidebarCollapsed,
|
setSidebarCollapsed,
|
||||||
section,
|
section,
|
||||||
setSection,
|
setSection,
|
||||||
sidebarNav,
|
sidebarGroups,
|
||||||
navBadges,
|
navBadges,
|
||||||
companySwitcherOpen,
|
companySwitcherOpen,
|
||||||
setCompanySwitcherOpen,
|
setCompanySwitcherOpen,
|
||||||
@@ -152,19 +153,16 @@ export function SidebarView({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<nav aria-label="Main navigation" className={`flex-1 overflow-y-auto pb-3 ${sidebarCollapsed ? "px-1.5 pt-2" : "px-3 pt-2"}`}>
|
<nav aria-label="Main navigation" className={`flex-1 overflow-y-auto pb-3 ${sidebarCollapsed ? "px-1.5 pt-2" : "px-3 pt-2"}`}>
|
||||||
{/* Core: Overview, Team, Work */}
|
{sidebarGroups.map((group, idx) => (
|
||||||
<div className="space-y-0.5">
|
<div key={idx}>
|
||||||
{sidebarNav.slice(0, 3).map((item) => (
|
{idx > 0 ? <div className={`my-2 border-t border-border ${sidebarCollapsed ? "mx-1" : "mx-2"}`} /> : null}
|
||||||
<SectionButton key={item.id} active={section === item.id} label={item.label} icon={item.icon} onClick={() => setSection(item.id)} badge={navBadges[item.id]?.count} badgeTone={navBadges[item.id]?.tone} collapsed={sidebarCollapsed} />
|
<div className="space-y-0.5">
|
||||||
))}
|
{group.items.map((item) => (
|
||||||
</div>
|
<SectionButton key={item.id} active={section === item.id} label={item.label} icon={item.icon} onClick={() => setSection(item.id)} badge={navBadges[item.id]?.count} badgeTone={navBadges[item.id]?.tone} collapsed={sidebarCollapsed} />
|
||||||
<div className={`my-2 border-t border-border ${sidebarCollapsed ? "mx-1" : "mx-2"}`} />
|
))}
|
||||||
{/* Collaborate & Extend: Communication, Skills, Documents, Approvals, Social */}
|
</div>
|
||||||
<div className="space-y-0.5">
|
</div>
|
||||||
{sidebarNav.slice(3).map((item) => (
|
))}
|
||||||
<SectionButton key={item.id} active={section === item.id} label={item.label} icon={item.icon} onClick={() => setSection(item.id)} badge={navBadges[item.id]?.count} badgeTone={navBadges[item.id]?.tone} collapsed={sidebarCollapsed} />
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</nav>
|
</nav>
|
||||||
<div className={`border-t border-border py-2 ${sidebarCollapsed ? "px-1.5" : "px-3"}`}>
|
<div className={`border-t border-border py-2 ${sidebarCollapsed ? "px-1.5" : "px-3"}`}>
|
||||||
<SectionButton
|
<SectionButton
|
||||||
|
|||||||
Reference in new issue
Block a user