mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 12:32:43 +00:00
fix(nav): keep Settings and Notifications out of the mobile More hub
The mobile bottom-nav More overflow appended the shared utility tail (Settings, Notifications) after the feature destinations. Those two are already reachable from the user/avatar menu, so the hub duplicated them across two menus on the same screen. Return feature destinations only; the utilities stay in the user menu. Sidebar footer is unaffected. Flip the three hub assertions to lock the feature-only contract.
This commit is contained in:
1 parent
b0ae1b54f0
commit
472a4904cd
2 files changed
+17
-20
No files matched your search
@@ -160,8 +160,8 @@ describe("visibleNavDestinations module gate", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("mobileMoreHubDestinations — the F-1 mobile invariant (N-2)", () => {
|
||||
it("is exactly the visible feature destinations minus the primary slots, then the utility tail", () => {
|
||||
describe("mobileMoreHubDestinations — the F-1 mobile invariant (feature-only hub, N-2)", () => {
|
||||
it("is exactly the visible feature destinations minus the primary slots (no utility tail)", () => {
|
||||
const opts = {
|
||||
modules: { cycle: false } as const,
|
||||
};
|
||||
@@ -170,9 +170,9 @@ describe("mobileMoreHubDestinations — the F-1 mobile invariant (N-2)", () => {
|
||||
const expectedFeatures = visibleNavDestinations(opts.modules)
|
||||
.map((d) => d.href)
|
||||
.filter((href) => !BOTTOM_NAV_PRIMARY_SLOT_HREFS.includes(href));
|
||||
const expectedTail = visibleUtilityDestinations().map((d) => d.href);
|
||||
|
||||
expect(hub).toEqual([...expectedFeatures, ...expectedTail]);
|
||||
// Feature destinations only — the account utilities never ride the hub.
|
||||
expect(hub).toEqual(expectedFeatures);
|
||||
});
|
||||
|
||||
it("never contains a primary slot (Home / Meds / Insights)", () => {
|
||||
@@ -184,7 +184,7 @@ describe("mobileMoreHubDestinations — the F-1 mobile invariant (N-2)", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("keeps the feature destinations and the utility tail reachable in the hub", () => {
|
||||
it("keeps the feature destinations reachable but excludes the account utilities", () => {
|
||||
const hub = mobileMoreHubDestinations({
|
||||
modules: { cycle: false },
|
||||
}).map((d) => d.href);
|
||||
@@ -192,9 +192,10 @@ describe("mobileMoreHubDestinations — the F-1 mobile invariant (N-2)", () => {
|
||||
expect(hub).toContain("/measurements");
|
||||
expect(hub).toContain("/mood");
|
||||
expect(hub).toContain("/checkups");
|
||||
// The shared utility tail rides at the end.
|
||||
expect(hub).toContain("/settings/account");
|
||||
expect(hub).toContain("/notifications");
|
||||
// Settings + Notifications are account utilities — they live ONLY in the
|
||||
// user/avatar menu, never duplicated into the mobile More hub.
|
||||
expect(hub).not.toContain("/settings/account");
|
||||
expect(hub).not.toContain("/notifications");
|
||||
});
|
||||
|
||||
it("gates Cycle by the module map, same as the sidebar", () => {
|
||||
|
||||
@@ -300,26 +300,22 @@ export interface MobileMoreHubEntry {
|
||||
|
||||
/**
|
||||
* The ordered "More" hub for the mobile bottom-nav: every visible feature
|
||||
* destination that isn't a primary slot, in model order, followed by the
|
||||
* shared utility tail (Settings, Notifications). The desktop sidebar renders
|
||||
* the same feature list inline and consumes the same utility tail in its
|
||||
* footer + avatar menu, so the two bars cannot drift into two hand-curated
|
||||
* lists.
|
||||
* destination that isn't a primary slot, in model order. Feature destinations
|
||||
* only — the account utilities (Settings, Notifications) are NOT appended here.
|
||||
* They live solely in the user/avatar menu (mobile top-bar dropdown; desktop
|
||||
* sidebar avatar menu + footer), so surfacing them in the More hub too would
|
||||
* duplicate a utility across two menus reachable from the same screen. The
|
||||
* desktop sidebar renders the same feature list inline, so the two bars cannot
|
||||
* drift into two hand-curated feature lists.
|
||||
*/
|
||||
export function mobileMoreHubDestinations(opts: {
|
||||
modules: ModuleVisibilityMap | undefined;
|
||||
/** Hydration gate — see `isNavDestinationVisible`. Defaults to mounted. */
|
||||
mounted?: boolean;
|
||||
}): MobileMoreHubEntry[] {
|
||||
const features = visibleNavDestinations(opts.modules, opts.mounted ?? true)
|
||||
return visibleNavDestinations(opts.modules, opts.mounted ?? true)
|
||||
.filter((d) => !BOTTOM_NAV_PRIMARY_SLOT_HREFS.includes(d.href))
|
||||
.map((d) => ({ href: d.href, tKey: d.tKey, icon: d.icon }));
|
||||
const tail = visibleUtilityDestinations().map((d) => ({
|
||||
href: d.href,
|
||||
tKey: d.tKey,
|
||||
icon: d.icon,
|
||||
}));
|
||||
return [...features, ...tail];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in new issue
Block a user