Skip to content

Commit

Permalink
Add breadcrumbs to header
Browse files Browse the repository at this point in the history
  • Loading branch information
rudolfs committed Nov 21, 2023
1 parent eeba820 commit 5868114
Show file tree
Hide file tree
Showing 12 changed files with 171 additions and 24 deletions.
10 changes: 6 additions & 4 deletions src/App/Header.svelte
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
<script lang="ts">
import { httpdStore } from "@app/lib/httpd";
import Authenticate from "./Header/Authenticate.svelte";
import Breadcrumbs from "./Header/Breadcrumbs.svelte";
import Connect from "@app/App/Header/Connect.svelte";
import Link from "@app/components/Link.svelte";
import NodeInfo from "@app/App/Header/NodeInfo.svelte";
import Authenticate from "./Header/Authenticate.svelte";
import { httpdStore } from "@app/lib/httpd";
</script>

<style>
Expand All @@ -12,8 +14,7 @@
justify-content: space-between;
align-items: center;
margin: 0;
padding: 1.5rem;
height: 5.5rem;
padding: 1rem;
}
.left,
.right {
Expand Down Expand Up @@ -45,6 +46,7 @@
alt="Radicle logo"
src="/radicle.svg" />
</Link>
<Breadcrumbs />
</div>

<div class="right layout-desktop-flex">
Expand Down
38 changes: 38 additions & 0 deletions src/App/Header/Breadcrumbs.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<script lang="ts">
import * as router from "@app/lib/router";
import * as utils from "@app/lib/utils";
import NodeSegment from "./Breadcrumbs/NodeSegment.svelte";
import ProjectSegment from "./Breadcrumbs/ProjectSegment.svelte";
import Separator from "./Breadcrumbs/Separator.svelte";
const activeRouteStore = router.activeRouteStore;
</script>

<style>
.breadcrumbs {
display: flex;
align-items: center;
gap: 0.25rem;
font-weight: var(--font-weight-semibold);
font-size: var(--font-size-small);
}
</style>

{#if $activeRouteStore.resource === "booting" || $activeRouteStore.resource === "home" || $activeRouteStore.resource === "session" || $activeRouteStore.resource === "loadError" || $activeRouteStore.resource === "notFound"}
<!-- Don't render breadcrumbs for these routes. -->
{:else if $activeRouteStore.resource === "nodes"}
<div class="breadcrumbs">
<NodeSegment baseUrl={$activeRouteStore.params.baseUrl} />
</div>
{:else if $activeRouteStore.resource === "project.source" || $activeRouteStore.resource === "project.history" || $activeRouteStore.resource === "project.commit" || $activeRouteStore.resource === "project.issues" || $activeRouteStore.resource === "project.newIssue" || $activeRouteStore.resource === "project.issue" || $activeRouteStore.resource === "project.patches" || $activeRouteStore.resource === "project.patch"}
<div class="breadcrumbs">
<NodeSegment baseUrl={$activeRouteStore.params.baseUrl} />

<Separator />

<ProjectSegment activeRoute={$activeRouteStore} />
</div>
{:else}
{utils.unreachable($activeRouteStore)}
{/if}
36 changes: 36 additions & 0 deletions src/App/Header/Breadcrumbs/NodeSegment.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<script lang="ts">
import type { BaseUrl } from "@httpd-client";
import { isLocal } from "@app/lib/utils";
import IconSmall from "@app/components/IconSmall.svelte";
import Link from "@app/components/Link.svelte";
export let baseUrl: BaseUrl;
</script>

<style>
.segment :global(a:hover) {
color: var(--color-fill-primary);
}
</style>

<span class="segment">
<Link
style="display: flex; align-items: center; gap: 0.25rem;"
route={{
resource: "nodes",
params: {
baseUrl,
projectPageIndex: 0,
},
}}>
{#if isLocal(baseUrl.hostname)}
<IconSmall name="device" />
Local Node
{:else}
<IconSmall name="globe" />
{baseUrl.hostname}
{/if}
</Link>
</span>
67 changes: 67 additions & 0 deletions src/App/Header/Breadcrumbs/ProjectSegment.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<script lang="ts">
import type { ProjectLoadedRoute } from "@app/views/projects/router";
import { capitalize } from "lodash";
import * as utils from "@app/lib/utils";
import CopyableId from "@app/components/CopyableId.svelte";
import Link from "@app/components/Link.svelte";
import Separator from "./Separator.svelte";
export let activeRoute: ProjectLoadedRoute;
</script>

<style>
.segment :global(a:hover) {
color: var(--color-fill-primary);
}
</style>

<span class="segment">
<Link
route={{
resource: "project.source",
project: activeRoute.params.project.id,
node: activeRoute.params.baseUrl,
}}>
{activeRoute.params.project.name}
</Link>
</span>

<Separator />

<span class="segment">
<Link
route={{
resource: "project.source",
project: activeRoute.params.project.id,
node: activeRoute.params.baseUrl,
}}>
{#if activeRoute.resource === "project.history" || activeRoute.resource === "project.commit"}
Commits
{:else if activeRoute.resource === "project.newIssue" || activeRoute.resource === "project.issue"}
Issues
{:else if activeRoute.resource === "project.patch"}
Patches
{:else}
{capitalize(activeRoute.resource.split(".")[1])}
{/if}
</Link>
</span>

{#if activeRoute.resource === "project.commit"}
<Separator />
<CopyableId id={activeRoute.params.commit.commit.id}>
{utils.formatCommit(activeRoute.params.commit.commit.id)}
</CopyableId>
{:else if activeRoute.resource === "project.issue"}
<Separator />
<CopyableId id={activeRoute.params.issue.id}>
{utils.formatObjectId(activeRoute.params.issue.id)}
</CopyableId>
{:else if activeRoute.resource === "project.patch"}
<Separator />
<CopyableId id={activeRoute.params.patch.id}>
{utils.formatObjectId(activeRoute.params.patch.id)}
</CopyableId>
{/if}
7 changes: 7 additions & 0 deletions src/App/Header/Breadcrumbs/Separator.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<script lang="ts">
import IconSmall from "@app/components/IconSmall.svelte";
</script>

<span style:color="var(--color-foreground-dim)">
<IconSmall name="chevron-right" />
</span>
6 changes: 6 additions & 0 deletions src/components/IconSmall.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
| "eye-open"
| "face"
| "file"
| "globe"
| "issue"
| "key"
| "logo"
Expand Down Expand Up @@ -282,6 +283,11 @@
fill-rule="evenodd"
clip-rule="evenodd"
d="M4.5 3.33329C4.5 3.24125 4.57462 3.16663 4.66667 3.16663H8.5898C8.79929 3.16663 9.0011 3.24553 9.15503 3.38762L11.2319 5.30473C11.4028 5.46249 11.5 5.68449 11.5 5.91707V12.6666C11.5 12.7587 11.4254 12.8333 11.3333 12.8333H4.66667C4.57462 12.8333 4.5 12.7587 4.5 12.6666V3.33329ZM4.66667 2.16663C4.02233 2.16663 3.5 2.68896 3.5 3.33329V12.6666C3.5 13.311 4.02233 13.8333 4.66667 13.8333H11.3333C11.9777 13.8333 12.5 13.311 12.5 12.6666V5.91707C12.5 5.40539 12.2862 4.91699 11.9102 4.56993L9.83331 2.65282C9.49466 2.34021 9.05068 2.16663 8.5898 2.16663H4.66667ZM6 4.16663C5.72386 4.16663 5.5 4.39048 5.5 4.66663C5.5 4.94277 5.72386 5.16663 6 5.16663H7.33333C7.60948 5.16663 7.83333 4.94277 7.83333 4.66663C7.83333 4.39048 7.60948 4.16663 7.33333 4.16663H6ZM6 6.83329C5.72386 6.83329 5.5 7.05715 5.5 7.33329C5.5 7.60944 5.72386 7.83329 6 7.83329H10C10.2761 7.83329 10.5 7.60944 10.5 7.33329C10.5 7.05715 10.2761 6.83329 10 6.83329H6ZM6 8.83329C5.72386 8.83329 5.5 9.05715 5.5 9.33329C5.5 9.60943 5.72386 9.83329 6 9.83329H8.66667C8.94281 9.83329 9.16667 9.60943 9.16667 9.33329C9.16667 9.05715 8.94281 8.83329 8.66667 8.83329H6ZM6 10.8333C5.72386 10.8333 5.5 11.0571 5.5 11.3333C5.5 11.6094 5.72386 11.8333 6 11.8333H9.33333C9.60948 11.8333 9.83333 11.6094 9.83333 11.3333C9.83333 11.0571 9.60948 10.8333 9.33333 10.8333H6Z" />
{:else if name === "globe"}
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M3.4424 6.38689C4.03734 6.07787 4.81337 5.8403 5.68923 5.68926C5.73546 5.42115 5.78981 5.16239 5.85182 4.91533C5.99241 4.35527 6.17243 3.85525 6.38686 3.44243C5.01515 3.92794 3.92791 5.01518 3.4424 6.38689ZM7.99999 2.16669C4.77833 2.16669 2.16666 4.77836 2.16666 8.00002C2.16666 11.2217 4.77833 13.8334 7.99999 13.8334C11.2217 13.8334 13.8333 11.2217 13.8333 8.00002C13.8333 4.77836 11.2217 2.16669 7.99999 2.16669ZM7.99999 3.16669C7.86865 3.16669 7.59893 3.29241 7.29002 3.87344C7.10927 4.21341 6.94711 4.65475 6.8174 5.17614C6.78706 5.2981 6.75849 5.42444 6.73188 5.55489C7.13996 5.51895 7.56447 5.50002 7.99999 5.50002C8.43551 5.50002 8.86002 5.51895 9.2681 5.55489C9.24022 5.41825 9.2102 5.28611 9.17825 5.15879C9.04926 4.64495 8.8887 4.20963 8.70996 3.87344C8.40105 3.29241 8.13133 3.16669 7.99999 3.16669ZM10.1537 4.93762C10.0123 4.36853 9.83039 3.86072 9.61312 3.44243C10.9848 3.92794 12.0721 5.01518 12.5576 6.38689C11.9626 6.07787 11.1866 5.8403 10.3108 5.68926C10.2659 5.4292 10.2134 5.17795 10.1537 4.93762ZM9.42501 6.575C8.97388 6.52628 8.49569 6.50002 7.99999 6.50002C7.50429 6.50002 7.0261 6.52628 6.57497 6.575C6.52625 7.02613 6.49999 7.50432 6.49999 8.00002C6.49999 8.49572 6.52625 8.97391 6.57497 9.42504C7.02609 9.47376 7.50429 9.50002 7.99999 9.50002C8.49569 9.50002 8.97388 9.47376 9.42501 9.42504C9.47373 8.97391 9.49999 8.49572 9.49999 8.00002C9.49999 7.50432 9.47372 7.02612 9.42501 6.575ZM9.2681 10.4452C8.86002 10.4811 8.43551 10.5 7.99999 10.5C7.56447 10.5 7.13996 10.4811 6.73188 10.4452C6.87227 11.1333 7.06699 11.7071 7.29002 12.1266C7.59893 12.7076 7.86865 12.8334 7.99999 12.8334C8.13133 12.8334 8.40105 12.7076 8.70996 12.1266C8.93299 11.7071 9.12771 11.1333 9.2681 10.4452ZM9.61312 12.5576C9.92214 11.9627 10.1597 11.1866 10.3108 10.3108C11.1866 10.1597 11.9626 9.92217 12.5576 9.61315C12.0721 10.9849 10.9848 12.0721 9.61312 12.5576ZM12.8333 8.00002C12.8333 7.86868 12.7076 7.59896 12.1266 7.29005C11.7071 7.06702 11.1332 6.8723 10.4451 6.73191C10.4811 7.13999 10.5 7.5645 10.5 8.00002C10.5 8.43554 10.4811 8.86005 10.4451 9.26813C11.1333 9.12774 11.7071 8.93302 12.1266 8.70999C12.7076 8.40108 12.8333 8.13136 12.8333 8.00002ZM6.38686 12.5576C5.01515 12.0721 3.92791 10.9849 3.4424 9.61315C4.03734 9.92218 4.81337 10.1597 5.68923 10.3108C5.84027 11.1866 6.07784 11.9627 6.38686 12.5576ZM5.55486 9.26813C4.86673 9.12774 4.2929 8.93302 3.87341 8.70999C3.29238 8.40108 3.16666 8.13136 3.16666 8.00002C3.16666 7.86868 3.29238 7.59896 3.87341 7.29005C4.2929 7.06702 4.86673 6.8723 5.55486 6.73191C5.51892 7.13999 5.49999 7.5645 5.49999 8.00002C5.49999 8.43554 5.51892 8.86005 5.55486 9.26813Z" />
{:else if name === "issue"}
<path
fill-rule="evenodd"
Expand Down
3 changes: 2 additions & 1 deletion src/components/Link.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
export let route: Route;
export let disabled: boolean = false;
export let title: string | undefined = undefined;
export let style: string | undefined = undefined;
const dispatch = createEventDispatcher<{
afterNavigate: null;
Expand All @@ -28,6 +29,6 @@
}
</script>

<a on:click={navigateToRoute} href={routeToPath(route)} {title}>
<a on:click={navigateToRoute} href={routeToPath(route)} {title} {style}>
<slot />
</a>
15 changes: 1 addition & 14 deletions src/views/projects/Layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@
import dompurify from "dompurify";
import markdown from "@app/lib/markdown";
import { twemoji, isLocal } from "@app/lib/utils";
import { twemoji } from "@app/lib/utils";
import Button from "@app/components/Button.svelte";
import CloneButton from "@app/views/projects/Header/CloneButton.svelte";
import Link from "@app/components/Link.svelte";
Expand Down Expand Up @@ -93,18 +92,6 @@
<div
class="layout-desktop-flex"
style="margin-left: auto; display: flex; gap: 0.5rem;">
<Link
route={{
resource: "nodes",
params: {
baseUrl,
projectPageIndex: 0,
},
}}>
<Button size="large" variant="outline">
{isLocal(baseUrl.hostname) ? "radicle.local" : baseUrl.hostname}
</Button>
</Link>
<TrackButton
{tracking}
trackings={project.trackings}
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/hashRouter.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ test("navigation between node and project pages", async ({ page }) => {
await expectBackAndForwardNavigationWorks("/#/nodes/radicle.local", page);
await expectUrlPersistsReload(page);

await page.getByRole("link", { name: "radicle.local" }).click();
await page.getByRole("link", { name: "Local Node" }).click();
await expect(page).toHaveURL("/#/nodes/127.0.0.1");
});

Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/historyRouter.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ test("navigation between node and project pages", async ({ page }) => {
await expectBackAndForwardNavigationWorks("/nodes/radicle.local", page);
await expectUrlPersistsReload(page);

await page.getByRole("link", { name: "radicle.local" }).click();
await page.getByRole("link", { name: "Local Node" }).click();
await expect(page).toHaveURL("/nodes/127.0.0.1");
});

Expand Down
4 changes: 2 additions & 2 deletions tests/e2e/project.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ test("navigate to project", async ({ page }) => {

// Header.
{
const name = page.getByText("source-browsing");
const name = page.getByRole("link", { name: "source-browsing" }).nth(1);
const id = page.getByText(sourceBrowsingRid);
const description = page.getByText(
"Git repository for source browsing tests",
Expand Down Expand Up @@ -331,7 +331,7 @@ test("peer and branch switching", async ({ page }) => {

// Reset the source browser by clicking the project title.
{
await page.getByText("source-browsing").click();
await page.getByRole("link", { name: "source-browsing" }).nth(1).click();

await expect(page.getByTitle("Change peer")).not.toContainText("alice");
await expect(page.getByTitle("Change peer")).not.toContainText("bob");
Expand Down
5 changes: 4 additions & 1 deletion tests/e2e/project/commits.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,10 @@ test("pushing changes while viewing history", async ({ page, peerManager }) => {
await expect(page.getByLabel("canonical-branch")).toHaveText("main");
await expect(page.getByTitle("Current HEAD")).toHaveText("516fa74");

await page.getByText("alice-project").click();
await page
.getByRole("banner")
.getByRole("link", { name: "alice-project" })
.click();
await expect(page).toHaveURL(`${alice.uiUrl()}/${rid}`);
await page.getByRole("link", { name: "2 commits" }).click();

Expand Down

0 comments on commit 5868114

Please sign in to comment.