fix(sidebar): top-level nav rendered only dashboardItems[0]
The Search entry added in 1ee3555 was in the array, in the build, and
typed correctly — and never appeared. The top-level nav block rendered
`dashboardItems[0]` with a hardcoded index, so every entry after the
first was silently dropped. Caught when the operator asked where the
link was.
Rendered as a map so appending an entry just works.
Regression test asserts the whole top-level set (Dashboard + Search)
rather than "Search exists", so the next person to append an entry gets
a passing test instead of an invisible link. Verified it fails when the
map is limited back to a single entry while the three pre-existing
sidebar tests keep passing.
This commit is contained in:
parent
1ee3555239
commit
60ccfa8122
2 changed files with 41 additions and 6 deletions
|
|
@ -95,4 +95,31 @@ describe("Sidebar", () => {
|
|||
expect(ops.queryByText("Stock Orders")).not.toBeInTheDocument();
|
||||
expect(ops.queryByText("Pricelist")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders every top-level nav entry, not just the first", () => {
|
||||
// Regression guard. The top-level nav rendered `dashboardItems[0]`
|
||||
// — a hardcoded index — so any entry added after Dashboard existed
|
||||
// in the array and in the build but never appeared in the sidebar.
|
||||
// That's how the universal Search link shipped invisible: the
|
||||
// operator asked for it, the code was correct, the entry was simply
|
||||
// never rendered.
|
||||
//
|
||||
// Asserts the full top-level set rather than "Search exists" so the
|
||||
// next person to append an entry gets a passing test instead of a
|
||||
// silently invisible link.
|
||||
render(<Sidebar />);
|
||||
const desktop = screen.getAllByRole("complementary")[0];
|
||||
|
||||
for (const label of ["Dashboard", "Search"]) {
|
||||
expect(
|
||||
within(desktop).queryByText(label, { exact: true }),
|
||||
`top-level nav should render "${label}"`,
|
||||
).toBeInTheDocument();
|
||||
}
|
||||
|
||||
// And the Search entry must actually point at the route.
|
||||
const link = within(desktop).getByText("Search", { exact: true }).closest("a");
|
||||
expect(link).not.toBeNull();
|
||||
expect(link).toHaveAttribute("href", "/search");
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -330,12 +330,20 @@ function NavContent({ onLinkClick }: { onLinkClick?: () => void }) {
|
|||
{/* Nav */}
|
||||
<ScrollArea className="flex-1 px-3 py-3">
|
||||
<nav className="space-y-3">
|
||||
{/* Dashboard — single, top-level */}
|
||||
<NavLink
|
||||
item={dashboardItems[0]}
|
||||
active={isActive(dashboardItems[0].href, dashboardItems, pathname)}
|
||||
onClick={onLinkClick}
|
||||
/>
|
||||
{/* Dashboard + universal search — top-level, above the grouped nav.
|
||||
Rendered as a map rather than `dashboardItems[0]`: that
|
||||
hardcoded index silently dropped every entry past the
|
||||
first, which is exactly how the Search link went missing
|
||||
from the sidebar while existing in the array and in the
|
||||
build. */}
|
||||
{dashboardItems.map((item) => (
|
||||
<NavLink
|
||||
key={item.href}
|
||||
item={item}
|
||||
active={isActive(item.href, dashboardItems, pathname)}
|
||||
onClick={onLinkClick}
|
||||
/>
|
||||
))}
|
||||
|
||||
<Separator className="mx-1" />
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue