Skip to content

Commit 43fdf83

Browse files
authored
feat: implement breadcrumbs according to design (#131)
* move breadcrumbs out of App.tsx * fix breadcrumbs in chat route * remove breadcrubms from dashboard route * add breadcrumbs to workspaces page * add breadcrumbs to edit workspace page * extract <BreadcrumbHome /> component * simplify implementation of visual gaps on routes * fix breadcrum test on workspace settings page * add breadcrumbs for test * add breadcrumbs to certificates * add breadcrumbs to certificate security * delete unused code
1 parent 8904d8b commit 43fdf83

18 files changed

+449
-538
lines changed

src/App.test.tsx

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,4 @@ describe("App", () => {
5656
).toBeVisible(),
5757
);
5858
});
59-
60-
it("should render breadcrumb", async () => {
61-
render(<App />);
62-
await waitFor(() =>
63-
expect(
64-
screen.getByRole("link", { name: "CodeGate Dashboard" }),
65-
).toBeVisible(),
66-
);
67-
expect(screen.getByRole("link", { name: "Dashboard" })).toBeVisible();
68-
});
6959
});

src/App.tsx

Lines changed: 2 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,9 @@
11
import { Header } from "./components/Header";
22
import { PromptList } from "./components/PromptList";
3-
import { Routes, Route, Link } from "react-router-dom";
3+
import { Routes, Route } from "react-router-dom";
44
import { usePromptsData } from "./hooks/usePromptsData";
55
import { Sidebar } from "./components/Sidebar";
66
import { useSse } from "./hooks/useSse";
7-
import {
8-
Breadcrumb,
9-
BreadcrumbList,
10-
BreadcrumbItem,
11-
BreadcrumbSeparator,
12-
BreadcrumbPage,
13-
} from "./components/ui/breadcrumb";
14-
import { useBreadcrumb } from "./hooks/useBreadcrumb";
157
import { RouteWorkspace } from "./routes/route-workspace";
168
import { RouteWorkspaces } from "./routes/route-workspaces";
179
import { RouteCertificates } from "./routes/route-certificates";
@@ -23,7 +15,6 @@ import { RouteCertificateSecurity } from "./routes/route-certificate-security";
2315
function App() {
2416
const { data: prompts, isLoading } = usePromptsData();
2517
useSse();
26-
const breadcrumb = useBreadcrumb();
2718

2819
return (
2920
<div className="flex w-screen h-screen">
@@ -33,27 +24,7 @@ function App() {
3324
<div className="flex-1 flex flex-col overflow-hidden">
3425
<Header />
3526

36-
<div className="px-6 py-3">
37-
<Breadcrumb>
38-
<BreadcrumbList>
39-
<BreadcrumbItem>
40-
<Link to="/">Dashboard</Link>
41-
</BreadcrumbItem>
42-
{breadcrumb && (
43-
<>
44-
<BreadcrumbSeparator />
45-
<BreadcrumbItem>
46-
<BreadcrumbPage className="w-96 truncate">
47-
{breadcrumb}
48-
</BreadcrumbPage>
49-
</BreadcrumbItem>
50-
</>
51-
)}
52-
</BreadcrumbList>
53-
</Breadcrumb>
54-
</div>
55-
56-
<div className="flex-1 overflow-y-auto p-6">
27+
<div className="flex-1 overflow-y-auto p-6 flex flex-col gap-3">
5728
<Routes>
5829
<Route path="/" element={<RouteDashboard />} />
5930
<Route path="/prompt/:id" element={<RouteChat />} />

src/components/BreadcrumbHome.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { Breadcrumb } from "@stacklok/ui-kit";
2+
3+
export function BreadcrumbHome() {
4+
return <Breadcrumb href="/">Dashboard</Breadcrumb>;
5+
}

src/components/ui/breadcrumb.tsx

Lines changed: 0 additions & 114 deletions
This file was deleted.

src/hooks/__tests__/useBreadcrumb.test.tsx

Lines changed: 0 additions & 52 deletions
This file was deleted.

src/hooks/useBreadcrumb.ts

Lines changed: 0 additions & 39 deletions
This file was deleted.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { render } from "@/lib/test-utils";
2+
import { screen, within } from "@testing-library/react";
3+
import { describe, expect, it } from "vitest";
4+
import { RouteCertificateSecurity } from "../route-certificate-security";
5+
6+
describe("Certificate security", () => {
7+
it("has breadcrumbs", () => {
8+
render(<RouteCertificateSecurity />);
9+
10+
const breadcrumbs = screen.getByRole("list", { name: "Breadcrumbs" });
11+
expect(breadcrumbs).toBeVisible();
12+
expect(
13+
within(breadcrumbs).getByRole("link", { name: "Dashboard" }),
14+
).toHaveAttribute("href", "/");
15+
expect(
16+
within(breadcrumbs).getByText(/certificate security/i),
17+
).toBeVisible();
18+
});
19+
});

src/routes/__tests__/route-certificates.test.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { render } from "@/lib/test-utils";
2-
import { screen } from "@testing-library/react";
2+
import { screen, within } from "@testing-library/react";
33
import { describe, expect, it } from "vitest";
44
import userEvent from "@testing-library/user-event";
55
import { RouteCertificates } from "../route-certificates";
@@ -27,6 +27,17 @@ describe("Certificates", () => {
2727
expect(screen.getByText("Linux")).toBeVisible();
2828
});
2929

30+
it("has breadcrumbs", () => {
31+
render(<RouteCertificates />);
32+
33+
const breadcrumbs = screen.getByRole("list", { name: "Breadcrumbs" });
34+
expect(breadcrumbs).toBeVisible();
35+
expect(
36+
within(breadcrumbs).getByRole("link", { name: "Dashboard" }),
37+
).toHaveAttribute("href", "/");
38+
expect(within(breadcrumbs).getByText(/certificates/i)).toBeVisible();
39+
});
40+
3041
it("should render macOS certificate installation", async () => {
3142
render(<RouteCertificates />);
3243

src/routes/__tests__/route-chat.test.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ vi.mock("@/hooks/usePromptsData", () => ({
4949
}));
5050

5151
describe("Chat", () => {
52-
it("should render secret issue chat", () => {
52+
it("render secret issue chat", () => {
5353
render(<RouteChat />, {
5454
routeConfig: {
5555
initialEntries: ["/prompt/chatcmpl-7d87679de7ed41639eb91d8ebbaa6f72"],
@@ -60,9 +60,6 @@ describe("Chat", () => {
6060
expect(screen.getByText(/REDACTED</i)).toBeVisible();
6161
expect(screen.getByTestId("avatar-user")).toBeVisible();
6262
expect(screen.getByTestId("avatar-ai")).toBeVisible();
63-
expect(
64-
screen.getByText(/do you see any security issue\?\./i),
65-
).toBeVisible();
6663
expect(
6764
screen.getByRole("heading", {
6865
name: /recommendations for security improvements/i,
@@ -76,5 +73,14 @@ describe("Chat", () => {
7673
.getByRole("code")
7774
.className.includes("language-tsx"),
7875
).toBeTruthy();
76+
77+
const breadcrumbs = screen.getByRole("list", { name: "Breadcrumbs" });
78+
expect(breadcrumbs).toBeVisible();
79+
expect(
80+
within(breadcrumbs).getByRole("link", { name: "Dashboard" }),
81+
).toHaveAttribute("href", "/");
82+
expect(
83+
within(breadcrumbs).getByText(/do you see any security issue/i),
84+
).toBeVisible();
7985
});
8086
});
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { render } from "@/lib/test-utils";
2+
import { screen, within } from "@testing-library/react";
3+
import { describe, expect, it } from "vitest";
4+
import { RouteHelp } from "../route-help";
5+
6+
describe("Help page", () => {
7+
it("has breadcrumbs", () => {
8+
render(<RouteHelp />, {
9+
routeConfig: {
10+
initialEntries: ["/help/continue-setup"],
11+
},
12+
pathConfig: "/help/:id",
13+
});
14+
const breadcrumbs = screen.getByRole("list", { name: "Breadcrumbs" });
15+
expect(breadcrumbs).toBeVisible();
16+
expect(
17+
within(breadcrumbs).getByRole("link", { name: "Dashboard" }),
18+
).toHaveAttribute("href", "/");
19+
expect(within(breadcrumbs).getByText(/help/i)).toBeVisible();
20+
});
21+
});

0 commit comments

Comments
 (0)