Skip to content

Commit

Permalink
Use ris-ui Breadcrumb component RISDEV-5098 (#753)
Browse files Browse the repository at this point in the history
  • Loading branch information
hamo225 authored Nov 5, 2024
1 parent fef3ed7 commit 06fbff1
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 128 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ test.describe("Affected documents page", () => {
}

// Back
await page.getByText("Zurück").click()
await page.getByRole("link", { name: "Zurück" }).click()
await expect(page).toHaveURL("/amending-laws")
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ test.describe("Articles page", () => {
await expect(checkChangeCommandButton).toBeVisible()

// Back
await page.getByText("Zurück").click()
await page.getByRole("link", { name: "Zurück" }).click()
await expect(page).toHaveURL("/amending-laws")
})
}
Expand Down
44 changes: 0 additions & 44 deletions frontend/src/components/controls/RisHeader.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,51 +99,7 @@ describe("risHeader", () => {
expect(link).toBeInTheDocument()
expect(link).toHaveAttribute("href", "#/foo")
})

it("renders a separator between back button and breadcrumbs", () => {
// Given
render(RisHeader, {
global,
props: {
breadcrumbs: [{ title: "Bar", key: "0", to: { name: "Bar" } }],
},
})

// Then
expect(screen.getByTestId("back-button-separator")).toBeInTheDocument()
})

it("renders no separator if no back button exists", async () => {
// Given
render(RisHeader, {
global,
props: {
breadcrumbs: [{ title: "Foo", key: "0", to: { name: "Foo" } }],
},
})

// When
await router.push({ name: "Foo" })

// Then
expect(screen.queryByTestId("back-button-separator")).toBeFalsy()
})

it("renders no separator if no breadcrumbs exists", () => {
// Given
render(RisHeader, {
global,
props: {
backDestination: "history-back",
breadcrumbs: [],
},
})

// Then
expect(screen.queryByTestId("back-button-separator")).toBeFalsy()
})
})

describe("breadcrumbs", () => {
it("renders breadcrumbs", () => {
// Given
Expand Down
196 changes: 114 additions & 82 deletions frontend/src/components/controls/RisHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
import { RouteLocationRaw, RouterLink, useRouter } from "vue-router"
import IcBaselineArrowBack from "~icons/ic/baseline-arrow-back"
import { useDebounceFn } from "@vueuse/core"
import Breadcrumb from "primevue/breadcrumb"
const props = withDefaults(
defineProps<{
Expand Down Expand Up @@ -70,10 +71,51 @@ onMounted(() => {
*/
const localBreadcrumbs = shallowRef<HeaderBreadcrumb[]>([])
const allBreadcrumbs = computed(() => [
...props.breadcrumbs,
...localBreadcrumbs.value,
])
const allBreadcrumbs = computed(() => {
const breadcrumbs = []
if (props.backDestination) {
const backDestination = props.backDestination
if (backDestination === "breadcrumb-back") {
const currentFullPath = router.resolve(router.currentRoute.value).fullPath
const previousBreadcrumb = [
...props.breadcrumbs,
...localBreadcrumbs.value,
]
.filter((i) => Boolean(i.to))
.findLast((i) => {
// @ts-expect-error `to` is not undefined, trust me
const resolvedPath = router.resolve(i.to).fullPath
return resolvedPath !== currentFullPath
})
breadcrumbs.push({
key: "back-button",
title: "Zurück",
to: previousBreadcrumb?.to || "history-back",
type: "breadcrumb-back",
})
} else if (backDestination === "history-back") {
breadcrumbs.push({
key: "back-button",
title: "Zurück",
type: "history-back",
})
} else {
breadcrumbs.push({
key: "back-button",
title: "Zurück",
to: backDestination,
type: "route-back",
})
}
}
breadcrumbs.push(...props.breadcrumbs, ...localBreadcrumbs.value)
return breadcrumbs
})
function removeBreadcrumb(key: string) {
const index = localBreadcrumbs.value.findIndex((i) => i.key === key)
Expand Down Expand Up @@ -108,34 +150,6 @@ provide(HeaderContextProvider, {
pushBreadcrumb,
actionTeleportTarget: safeActionTargetId,
})
/* -------------------------------------------------- *
* Back button *
* -------------------------------------------------- */
const backbuttonTo = computed(() => {
if (props.backDestination === "breadcrumb-back") {
const current = router.resolve(router.currentRoute.value).fullPath
return allBreadcrumbs.value
.filter((i) => Boolean(i.to))
.findLast((i) => {
// @ts-expect-error `to` is not undefined, trust me
const resolved = router.resolve(i.to).fullPath
return resolved !== current
})?.to
} else if (props.backDestination === "history-back") {
return undefined
} else {
return props.backDestination
}
})
const showBackButtonSeparator = computed(
() =>
(backbuttonTo.value || props.backDestination === "history-back") &&
allBreadcrumbs.value?.length,
)
</script>

<script lang="ts">
Expand Down Expand Up @@ -206,58 +220,76 @@ export function useHeaderContext() {
v-bind="$attrs"
>
<section class="flex items-center">
<!-- Back button -->
<RouterLink
v-if="backbuttonTo"
:to="backbuttonTo"
class="ds-button ds-button-small ds-button-ghost ds-button-with-icon ds-button-with-icon-only"
>
<IcBaselineArrowBack />
<span class="sr-only">Zurück</span>
</RouterLink>
<Button
v-else-if="backDestination === 'history-back'"
label="Zurück"
severity="text"
@click="router.back()"
>
<template #icon>
<IcBaselineArrowBack />
</template>
</Button>

<span
v-if="showBackButtonSeparator"
class="mr-8 text-gray-700"
data-testid="back-button-separator"
>/</span
>

<!-- Bread crumbs -->
<nav class="line-clamp-2 leading-5">
<span
v-for="crumb in allBreadcrumbs"
:key="crumb.key"
class="ris-body1-regular after:mx-8 after:inline-block after:text-gray-700 after:content-['/'] last-of-type:after:hidden"
>
<RouterLink v-if="crumb.to" v-slot="link" :to="crumb.to" custom>
<a
v-if="!link.isExactActive"
class="ris-link1-bold underline"
:href="link.href"
@click="debouncedBreadcrumbClick(crumb.to)"
<Breadcrumb :model="allBreadcrumbs">
<template #item="{ item, props: slotProps }">
<template v-if="item.key === 'back-button'">
<RouterLink
v-if="item.to && item.to !== 'history-back'"
v-slot="{ href }"
:to="item.to"
custom
>
<a
:href="href"
v-bind="slotProps.action"
@click.prevent="debouncedBreadcrumbClick(item.to)"
>
<IcBaselineArrowBack />
<span class="sr-only">Zurück</span>
</a>
</RouterLink>

<Button
v-else-if="item.to === 'history-back' || !item.to"
label="Zurück"
severity="text"
@click="router.back()"
>
<template #icon>
<IcBaselineArrowBack />
</template>
</Button>
</template>

<template v-else>
<RouterLink
v-if="item.to"
v-slot="{ href, isExactActive }"
:to="item.to"
custom
>
{{ toValue(crumb.title) }}
</a>
<span v-else data-testid="current-route-breadcrumb">
{{ toValue(crumb.title) }}
<a
v-if="!isExactActive"
:href="href"
v-bind="slotProps.action"
@click.prevent="debouncedBreadcrumbClick(item.to)"
>
<span class="line-clamp-1 font-bold underline">{{
toValue(item.title)
}}</span>
</a>
<span
v-else
class="line-clamp-1"
data-testid="current-route-breadcrumb"
>
{{ toValue(item.title) }}
</span>
</RouterLink>
<span
v-else
data-testid="text-only-breadcrumb"
class="line-clamp-1"
>
{{ toValue(item.title) }}
</span>
</RouterLink>
<span v-else data-testid="text-only-breadcrumb">
{{ toValue(crumb.title) }}
</span>
</span>
</nav>
</template>
</template>

<template #separator>
<span>/</span>
</template>
</Breadcrumb>
</section>

<!-- Actions -->
Expand Down

0 comments on commit 06fbff1

Please sign in to comment.