Simplify Subnavigation and create component to handle external vs
internal links
This commit is contained in:
parent
28027eb96f
commit
6c6bbb9e22
|
|
@ -0,0 +1,35 @@
|
|||
<script setup lang="ts">
|
||||
import { computed } from "vue";
|
||||
import { RouterLink } from "vue-router";
|
||||
// https://router.vuejs.org/guide/advanced/extending-router-link
|
||||
|
||||
defineOptions({
|
||||
inheritAttrs: false,
|
||||
});
|
||||
|
||||
const props = defineProps({
|
||||
// @ts-expect-error the example above mentions needing @ts-ignore
|
||||
...RouterLink.props,
|
||||
});
|
||||
|
||||
const isExternalLink = computed(() => {
|
||||
return typeof props.to === "string" && props.to.startsWith("https");
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a v-if="isExternalLink" v-bind="$attrs" :href="to" target="_blank">
|
||||
<slot />
|
||||
<it-icon-external-link />
|
||||
</a>
|
||||
<router-link v-else v-slot="{ isActive, href, navigate }" v-bind="$props" custom>
|
||||
<a
|
||||
v-bind="$attrs"
|
||||
:class="isActive ? activeClass : ''"
|
||||
:href="href"
|
||||
@click="navigate"
|
||||
>
|
||||
<slot />
|
||||
</a>
|
||||
</router-link>
|
||||
</template>
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import SubNavItem from "@/components/header/SubNavItem.vue";
|
||||
import { useCurrentCourseSession, useEvaluationWithFeedback } from "@/composables";
|
||||
import {
|
||||
CERTIFICATES_ROUTE,
|
||||
|
|
@ -7,29 +8,16 @@ import {
|
|||
SELF_EVALUATION_ROUTE,
|
||||
} from "@/router/names";
|
||||
import { Listbox, ListboxButton, ListboxOption, ListboxOptions } from "@headlessui/vue";
|
||||
import { useTranslation } from "i18next-vue";
|
||||
import * as log from "loglevel";
|
||||
import { onMounted } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import { computed, onMounted } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
|
||||
log.debug("CompetenceParentPage created");
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
function routeInOverview() {
|
||||
return route.path.endsWith("/competence");
|
||||
}
|
||||
|
||||
function routeInCompetenceCertificate() {
|
||||
return route.path.includes("/certificate");
|
||||
}
|
||||
|
||||
function routeInActionCompetences() {
|
||||
return route.path.endsWith("/competences");
|
||||
}
|
||||
|
||||
function routeInSelfEvaluationAndFeedback() {
|
||||
return route.path.endsWith("/self-evaluation-and-feedback");
|
||||
}
|
||||
const { t } = useTranslation();
|
||||
|
||||
const currentCourseSession = useCurrentCourseSession();
|
||||
const hasEvaluationFeedback = useEvaluationWithFeedback().hasFeedback;
|
||||
|
|
@ -38,13 +26,6 @@ onMounted(async () => {
|
|||
log.debug("CompetenceParentPage mounted");
|
||||
});
|
||||
|
||||
const items = [
|
||||
{ id: 0, name: "Übersicht" },
|
||||
{ id: 1, name: "Teilnehmer" },
|
||||
{ id: 2, name: "Unterlagen" },
|
||||
{ id: 3, name: "MS Teams", iconName: "it-icon-external-link" },
|
||||
{ id: 4, name: "Vorschau Teilnehmer", iconName: "it-icon-external-link" },
|
||||
];
|
||||
const competenceRoute = {
|
||||
name: COMPETENCE_ROUTE,
|
||||
};
|
||||
|
|
@ -57,6 +38,48 @@ const selfEvaluationRoute = {
|
|||
const competencesRoute = {
|
||||
name: COMPETENCES_ROUTE,
|
||||
};
|
||||
|
||||
const isCurrentRoute = (route: { name: string } | string) => {
|
||||
return typeof route !== "string" && route?.name === router.currentRoute.value.name;
|
||||
};
|
||||
|
||||
const items = [
|
||||
{ id: 0, name: t("a.Übersicht"), route: competenceRoute },
|
||||
...(currentCourseSession.value.course.configuration.enable_competence_certificates
|
||||
? [
|
||||
{
|
||||
id: 1,
|
||||
name: t("a.Kompetenznachweise"),
|
||||
route: certificatesRoute,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
{
|
||||
id: 2,
|
||||
name: hasEvaluationFeedback.value
|
||||
? t("a.Selbst- und Fremdeinschätzungen")
|
||||
: t("a.Selbsteinschätzungen"),
|
||||
route: selfEvaluationRoute,
|
||||
},
|
||||
{ id: 3, name: t("a.Handlungskompetenzen"), route: competencesRoute },
|
||||
|
||||
{
|
||||
id: 3,
|
||||
name: "MS Teams",
|
||||
iconName: "it-icon-external-link",
|
||||
route: "https://iterativ.ch",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "Vorschau Teilnehmer",
|
||||
iconName: "it-icon-external-link",
|
||||
route: "https://iterativ.ch",
|
||||
},
|
||||
// { id: 4, name: "Vorschau Teilnehmer", iconName: "it-icon-external-link" },
|
||||
];
|
||||
const currentRouteName = computed(() => {
|
||||
return items.find((item) => isCurrentRoute(item.route))?.name || "";
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
@ -67,7 +90,7 @@ const competencesRoute = {
|
|||
<ListboxButton
|
||||
class="relative flex w-full cursor-default flex-row items-center border bg-white py-3 pl-5 pr-10 text-left"
|
||||
>
|
||||
Übersicht
|
||||
{{ currentRouteName }}
|
||||
<span
|
||||
class="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2"
|
||||
>
|
||||
|
|
@ -77,69 +100,28 @@ const competencesRoute = {
|
|||
<ListboxOptions
|
||||
class="absolute top-14 flex w-full cursor-default flex-col rounded-xl border-0 bg-white text-left shadow-lg"
|
||||
>
|
||||
<ListboxOption
|
||||
v-for="item in items"
|
||||
:key="item.id"
|
||||
as="router-link"
|
||||
class="flex w-full items-center gap-2 border-b py-3 pl-5 pr-10 last:border-b-0"
|
||||
>
|
||||
<router-link to="/">
|
||||
<ListboxOption v-for="item in items" :key="item.id">
|
||||
<SubNavItem
|
||||
class="flex w-full items-center gap-2 border-b py-3 pl-5 pr-10 last:border-b-0"
|
||||
:to="item.route"
|
||||
>
|
||||
{{ item.name }}
|
||||
</router-link>
|
||||
<component :is="item.iconName" v-if="item.iconName"></component>
|
||||
</SubNavItem>
|
||||
</ListboxOption>
|
||||
</ListboxOptions>
|
||||
</div>
|
||||
</Listbox>
|
||||
<ul class="hidden flex-col lg:flex lg:flex-row">
|
||||
<ul class="hidden flex-col gap-12 lg:flex lg:flex-row">
|
||||
<li
|
||||
v-for="item in items"
|
||||
:key="item.id"
|
||||
class="border-t-2 border-t-transparent"
|
||||
:class="{ 'border-b-2 border-b-blue-900': routeInOverview() }"
|
||||
:class="{ 'border-b-2 border-b-blue-900': isCurrentRoute(item.route) }"
|
||||
>
|
||||
<router-link :to="competenceRoute" class="block py-3">
|
||||
{{ $t("a.Übersicht") }}
|
||||
</router-link>
|
||||
<SubNavItem :to="item.route" class="block py-3">
|
||||
{{ item.name }}
|
||||
</SubNavItem>
|
||||
</li>
|
||||
<li
|
||||
v-if="
|
||||
currentCourseSession.course.configuration.enable_competence_certificates
|
||||
"
|
||||
class="border-t-2 border-t-transparent lg:ml-12"
|
||||
:class="{ 'border-b-2 border-b-blue-900': routeInCompetenceCertificate() }"
|
||||
>
|
||||
<router-link :to="certificatesRoute" class="block py-3">
|
||||
{{ $t("a.Kompetenznachweise") }}
|
||||
</router-link>
|
||||
</li>
|
||||
<li
|
||||
class="border-t-2 border-t-transparent lg:ml-12"
|
||||
:class="{
|
||||
'border-b-2 border-b-blue-900': routeInSelfEvaluationAndFeedback(),
|
||||
}"
|
||||
>
|
||||
<router-link
|
||||
:to="selfEvaluationRoute"
|
||||
class="block py-3"
|
||||
data-cy="self-evaluation-and-feedback-navigation-link"
|
||||
>
|
||||
{{
|
||||
hasEvaluationFeedback
|
||||
? $t("a.Selbst- und Fremdeinschätzungen")
|
||||
: $t("a.Selbsteinschätzungen")
|
||||
}}
|
||||
</router-link>
|
||||
</li>
|
||||
<li
|
||||
class="border-t-2 border-t-transparent lg:ml-12"
|
||||
:class="{ 'border-b-2 border-b-blue-900': routeInActionCompetences() }"
|
||||
>
|
||||
<router-link :to="competencesRoute" class="block py-3">
|
||||
{{ $t("a.Handlungskompetenzen") }}
|
||||
</router-link>
|
||||
</li>
|
||||
|
||||
<!-- Add similar logic for other `li` items as you expand the list -->
|
||||
<li class="ml-6 inline-block lg:ml-12"></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<main>
|
||||
|
|
|
|||
Loading…
Reference in New Issue