Give every admin page a breadcrumb trail
The trail is twui's Breadcrumbs reading Home, the sections and the page off the address, rendered as the first thing in SettingsShell's content column, so every page that is not a conversation gets one without a page touching it. The last crumb is named by the page's own title rather than the address: a record reads Scout instead of its id, /admin/logs reads Activity, and /admin/settings/mcps reads MCPs. That replaces the breadcrumb_title prop the four settings record pages had to pass, so settings-breadcrumbs.tsx goes. hasBreadcrumbTrail drops the trail on the crew of bots, home, and on anything outside /admin; the trailing slash and query string are ignored, so a folder in the files browser keeps the trail of the page it is on.
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import hasBreadcrumbTrail from "./has-breadcrumb-trail";
|
||||
|
||||
describe("hasBreadcrumbTrail", () => {
|
||||
test("a top-level page has one, so a lone page never goes without", () => {
|
||||
expect(hasBreadcrumbTrail({ pathname: "/admin/routines" })).toBe(true);
|
||||
});
|
||||
|
||||
test("a nested page has one", () => {
|
||||
expect(hasBreadcrumbTrail({ pathname: "/admin/settings/general" })).toBe(
|
||||
true,
|
||||
);
|
||||
expect(hasBreadcrumbTrail({ pathname: "/admin/settings/bots/3" })).toBe(
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
test("the crew of bots is home, so it has none", () => {
|
||||
expect(hasBreadcrumbTrail({ pathname: "/admin/bots" })).toBe(false);
|
||||
expect(hasBreadcrumbTrail({ pathname: "/admin/bots/" })).toBe(false);
|
||||
});
|
||||
|
||||
test("the address that only redirects to home has none either", () => {
|
||||
expect(hasBreadcrumbTrail({ pathname: "/admin" })).toBe(false);
|
||||
expect(hasBreadcrumbTrail({ pathname: "/admin/" })).toBe(false);
|
||||
});
|
||||
|
||||
test("a folder in the files browser keeps the trail of its page", () => {
|
||||
expect(
|
||||
hasBreadcrumbTrail({
|
||||
pathname: "/admin/files?volume=bot&owner=1&path=reports",
|
||||
}),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
test("nothing outside the admin pages has one", () => {
|
||||
expect(hasBreadcrumbTrail({ pathname: "/auth/login" })).toBe(false);
|
||||
expect(hasBreadcrumbTrail({ pathname: "/" })).toBe(false);
|
||||
expect(hasBreadcrumbTrail({ pathname: "" })).toBe(false);
|
||||
expect(hasBreadcrumbTrail({})).toBe(false);
|
||||
expect(hasBreadcrumbTrail({ pathname: null })).toBe(false);
|
||||
});
|
||||
|
||||
test("a path that merely starts like admin does not count", () => {
|
||||
expect(hasBreadcrumbTrail({ pathname: "/administrator" })).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,31 @@
|
||||
import { AdminHomePath } from "@/src/dict/admin-sections-dict";
|
||||
|
||||
type Params = {
|
||||
pathname?: string | null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Whether an address has a trail above it: `Home`, then every section it
|
||||
* passes through, then the page. `twui`'s `Breadcrumbs` draws the trail
|
||||
* itself from the path, so this only answers which pages get one.
|
||||
*
|
||||
* The crew of bots is where the app lands, and its own address would
|
||||
* read `Home / Bots`, both the same page, so it has none. Neither does
|
||||
* anything outside the admin pages, since everything else redirects to
|
||||
* the bots.
|
||||
*
|
||||
* The trailing slash and the query string are ignored, so a folder opened
|
||||
* in the files browser keeps the trail of the page it is on.
|
||||
*/
|
||||
export default function hasBreadcrumbTrail({ pathname }: Params): boolean {
|
||||
if (!pathname) return false;
|
||||
|
||||
const path = pathname.split("?")[0]!.replace(/\/$/, "");
|
||||
|
||||
if (path != "/admin" && !path.startsWith("/admin/")) return false;
|
||||
|
||||
/**
|
||||
* `/admin` only redirects to the crew of bots, which is home.
|
||||
*/
|
||||
return path != AdminHomePath && path != "/admin";
|
||||
}
|
||||
Reference in New Issue
Block a user