Use sub routes

This commit is contained in:
Christian Cueni 2024-04-22 20:08:37 +02:00
parent 073c2a8a60
commit 0d982f937c
5 changed files with 178 additions and 173 deletions

View File

@ -28,6 +28,7 @@ const isLoaded = computed(() => !selfEvaluationFeedbackSummaries.loading.value);
</script>
<template>
<div>
<template v-if="isLoaded">
<!-- Self Evaluation -->
<div class="bg-white px-8 py-4 lg:mb-8 lg:py-8">
@ -126,6 +127,7 @@ const isLoaded = computed(() => !selfEvaluationFeedbackSummaries.loading.value);
</button>
</div>
</template>
</div>
</template>
<style scoped></style>

View File

@ -1,6 +1,9 @@
<script setup lang="ts">
import log from "loglevel";
import { COMPETENCE_NAVI_CERTIFICATE_QUERY } from "@/graphql/queries";
import {
COMPETENCE_NAVI_CERTIFICATE_FOR_USER_QUERY,
COMPETENCE_NAVI_CERTIFICATE_QUERY,
} from "@/graphql/queries";
import { useQuery } from "@urql/vue";
import { computed, onMounted } from "vue";
import type { CompetenceCertificate } from "@/types";
@ -10,25 +13,44 @@ import CompetenceCertificateComponent from "@/pages/competence/CompetenceCertifi
const props = defineProps<{
courseSlug: string;
certificateSlug: string;
userId?: string;
}>();
log.debug("CompetenceCertificateDetailPage setup", props);
const courseSession = useCurrentCourseSession();
const certificatesQuery = useQuery({
const certificatesQuery = (() => {
if (props.userId) {
return useQuery({
query: COMPETENCE_NAVI_CERTIFICATE_FOR_USER_QUERY,
variables: {
courseSlug: props.courseSlug,
courseSessionId: courseSession.value.id,
userId: props.userId,
},
});
} else {
return useQuery({
query: COMPETENCE_NAVI_CERTIFICATE_QUERY,
variables: {
courseSlug: props.courseSlug,
courseSessionId: courseSession.value.id,
},
});
}
})();
const certificate = computed(() => {
const certificate = props.userId
? certificatesQuery.data?.value?.competence_certificate_list_for_user
: certificatesQuery.data?.value?.competence_certificate_list;
if (certificate) {
return (
(certificatesQuery.data.value?.competence_certificate_list
?.competence_certificates as unknown as CompetenceCertificate[]) ?? []
(certificate.competence_certificates as unknown as CompetenceCertificate[]) ?? []
).find((cc) => cc.slug.endsWith(props.certificateSlug));
}
return null;
});
onMounted(async () => {

View File

@ -1,21 +1,8 @@
<script setup lang="ts">
import CockpitProfileContent from "@/components/userProfile/UserProfileContent.vue";
import { computed } from "vue";
import SelfEvaluationAndFeedbackList from "@/components/selfEvaluationFeedback/SelfEvaluationAndFeedbackList.vue";
import SelfEvaluationAndFeedbackOverview from "@/components/selfEvaluationFeedback/SelfEvaluationAndFeedbackOverview.vue";
import { useCurrentCourseSession } from "@/composables";
import CompetenceCertificateListPage from "@/pages/competence/CompetenceCertificateListPage.vue";
import CompetenceCertificateDetailPage from "@/pages/competence/CompetenceCertificateDetailPage.vue";
import { useRoute } from "vue-router";
type SubMenuType = "OVERVIEW" | "EVALUATIONS" | "CERTIFICATES" | "CERTIFICATE_DETAIL";
const subMenuOptions: SubMenuType[] = [
"OVERVIEW",
"EVALUATIONS",
"CERTIFICATES",
"CERTIFICATE_DETAIL",
];
const props = defineProps<{
userId: string;
courseSlug: string;
@ -23,56 +10,47 @@ const props = defineProps<{
}>();
interface SubMenuItem {
type: SubMenuType;
label: string;
url: string;
inMenu: boolean;
routeMatch: string[];
}
const SUBPAGES: SubMenuItem[] = [
{
type: "OVERVIEW",
label: "a.Übersicht",
url: `/course/${props.courseSlug}/profile/${props.userId}/competence`,
inMenu: true,
routeMatch: ["competenceMain"],
},
{
type: "EVALUATIONS",
label: useCurrentCourseSession().value.course.configuration.is_vv
? "a.Selbst- und Fremdeinschätzungen"
: "a.Selbsteinschätzungen",
url: `/course/${props.courseSlug}/profile/${props.userId}/competence/evaluations`,
inMenu: true,
routeMatch: ["competenceEvaluations"],
},
];
if (useCurrentCourseSession().value.course.configuration.is_uk) {
SUBPAGES.push(
{
type: "CERTIFICATES",
label: "Kompetenznachweise",
url: `/course/${props.courseSlug}/profile/${props.userId}/competence/certificates`,
inMenu: true,
routeMatch: ["competenceCertificates", "competenceCertificateDetail"],
},
{
type: "CERTIFICATE_DETAIL",
label: "",
url: "",
inMenu: false,
routeMatch: [],
}
);
}
const route = useRoute();
const active = computed(() => {
const index = subMenuOptions.findIndex((option) =>
option.startsWith(route.meta?.subpage)
);
if (index > -1) {
return SUBPAGES[index];
}
return SUBPAGES[0];
});
</script>
<template>
@ -84,37 +62,26 @@ const active = computed(() => {
class="mb-2"
>
<router-link
v-if="active"
:to="entry.url"
class="flex w-full items-center space-x-2 p-2 pr-4 text-blue-900 hover:bg-gray-200 lg:pr-8"
:class="{ 'text-bold bg-gray-200': entry.type.startsWith(active.type) }"
:class="{
'text-bold bg-gray-200': route.matched.some((record) =>
entry.routeMatch.includes(record.name)
),
}"
>
<span>{{ $t(entry.label) }}</span>
</router-link>
</div>
</template>
<template #main>
<div v-if="active" class="container-large">
<SelfEvaluationAndFeedbackOverview
v-if="active.type === 'OVERVIEW'"
<div class="container-large">
<router-view
:profile-user-id="props.userId"
/>
<SelfEvaluationAndFeedbackList
v-else-if="active.type === 'EVALUATIONS'"
class="w-full"
:profile-user-id="props.userId"
/>
<CompetenceCertificateListPage
v-else-if="active.type === 'CERTIFICATES'"
:course-slug="useCurrentCourseSession().value.course.slug"
:user-id="userId"
/>
<CompetenceCertificateDetailPage
v-else-if="active.type === 'CERTIFICATE_DETAIL'"
:user-id="props.userId"
:course-slug="useCurrentCourseSession().value.course.slug"
:certificate-slug="certificateSlug ? certificateSlug : ''"
:user-id="userId"
/>
></router-view>
</div>
</template>
</CockpitProfileContent>

View File

@ -13,8 +13,16 @@ const props = defineProps<{
const { t } = useTranslation();
const pages = ref([
{ label: t("general.learningPath"), route: "profileLearningPath" },
{ label: t("a.KompetenzNavi"), route: "profileCompetence" },
{
label: t("general.learningPath"),
route: "profileLearningPath",
routeMatch: "profileLearningPath",
},
{
label: t("a.KompetenzNavi"),
route: "competenceMain",
routeMatch: "profileCompetence",
},
]);
const courseSession = useCurrentCourseSession();
@ -54,7 +62,11 @@ onMounted(() => {
v-for="page in pages"
:key="page.route"
class="relative top-px mr-12 pb-3"
:class="[route.name === page.route ? 'border-b-2 border-blue-900 pb-3' : '']"
:class="[
route.matched.some((record) => record.name === page.routeMatch)
? 'border-b-2 border-blue-900 pb-3'
: '',
]"
>
<router-link :to="{ name: page.route }">
{{ page.label }}

View File

@ -178,29 +178,31 @@ const router = createRouter({
{
path: "",
name: "competenceMain",
meta: { subpage: "OVERVIEW" },
component: () => import("@/pages/userProfile/CompetenceProfilePage.vue"),
component: () =>
import(
"@/components/selfEvaluationFeedback/SelfEvaluationAndFeedbackOverview.vue"
),
},
{
path: "evaluations",
name: "competenceEvaluations",
meta: { subpage: "EVALUATIONS" },
component: () => import("@/pages/userProfile/CompetenceProfilePage.vue"),
component: () =>
import(
"@/components/selfEvaluationFeedback/SelfEvaluationAndFeedbackList.vue"
),
},
{
path: "certificates/:certificateSlug",
name: "competenceCertificateDetail",
props: true,
component: () =>
import("@/pages/competence/CompetenceCertificateDetailPage.vue"),
},
{
path: "certificates",
name: "profileCompetences",
meta: { subpage: "CERTIFICATES" },
component: () => import("@/pages/userProfile/CompetenceProfilePage.vue"),
children: [
{
path: ":certificateSlug",
props: true,
meta: { subpage: "CERTIFICATE_DETAIL" },
name: "competenceCertificates",
component: () =>
import("@/pages/userProfile/CompetenceProfilePage.vue"),
},
],
import("@/pages/competence/CompetenceCertificateListPage.vue"),
},
],
},