wip: appointment filtering poc
This commit is contained in:
parent
18bbc6701c
commit
4672698895
|
|
@ -23,8 +23,14 @@ const breakpoints = useBreakpoints(breakpointsTailwind);
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const courseSessionsStore = useCourseSessionsStore();
|
const courseSessionsStore = useCourseSessionsStore();
|
||||||
const notificationsStore = useNotificationsStore();
|
const notificationsStore = useNotificationsStore();
|
||||||
const { inCockpit, inCompetenceProfile, inCourse, inLearningPath, inMediaLibrary } =
|
const {
|
||||||
useRouteLookups();
|
inCockpit,
|
||||||
|
inCompetenceProfile,
|
||||||
|
inCourse,
|
||||||
|
inLearningPath,
|
||||||
|
inMediaLibrary,
|
||||||
|
inDueDates,
|
||||||
|
} = useRouteLookups();
|
||||||
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
|
|
@ -159,6 +165,16 @@ onMounted(() => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-stretch justify-start space-x-8">
|
<div class="flex items-stretch justify-start space-x-8">
|
||||||
|
<router-link
|
||||||
|
v-if="userStore.loggedIn"
|
||||||
|
:to="`${''}/appointments`"
|
||||||
|
data-cy="all-duedates-link"
|
||||||
|
class="nav-item-no-mobile"
|
||||||
|
:class="{ 'nav-item--active': inDueDates() }"
|
||||||
|
>
|
||||||
|
<it-icon-media-library class="h-8 w-8" />
|
||||||
|
</router-link>
|
||||||
|
|
||||||
<router-link
|
<router-link
|
||||||
v-if="inCourse() && courseSessionsStore.currentCourseSession"
|
v-if="inCourse() && courseSessionsStore.currentCourseSession"
|
||||||
:to="courseSessionsStore.currentCourseSession.media_library_url"
|
:to="courseSessionsStore.currentCourseSession.media_library_url"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,118 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed, ref, watch } from "vue";
|
||||||
|
import { useCourseSessionsStore } from "@/stores/courseSessions";
|
||||||
|
import { useLearningPathStore } from "@/stores/learningPath";
|
||||||
|
import ItDropdownSelect from "@/components/ui/ItDropdownSelect.vue";
|
||||||
|
|
||||||
|
const UNFILTERED = Number.MAX_SAFE_INTEGER;
|
||||||
|
|
||||||
|
const courseSessionsStore = useCourseSessionsStore();
|
||||||
|
const learningPathStore = useLearningPathStore();
|
||||||
|
|
||||||
|
function getCourseSession(id: number) {
|
||||||
|
return courseSessionsStore.allCourseSessions.find((cs) => cs.id === id);
|
||||||
|
}
|
||||||
|
|
||||||
|
const allItem = {
|
||||||
|
id: UNFILTERED,
|
||||||
|
name: "Alle",
|
||||||
|
};
|
||||||
|
|
||||||
|
const circles = ref([{ ...allItem }]);
|
||||||
|
|
||||||
|
const courseSessions = [
|
||||||
|
{ ...allItem },
|
||||||
|
...courseSessionsStore.allCourseSessions.map((courseSession) => ({
|
||||||
|
id: courseSession.id,
|
||||||
|
name: courseSession.title,
|
||||||
|
})),
|
||||||
|
];
|
||||||
|
|
||||||
|
const selectedSession = ref(courseSessions[0]);
|
||||||
|
const selectedCircle = ref(circles.value[0]);
|
||||||
|
|
||||||
|
watch(selectedSession, async () => {
|
||||||
|
const cs = getCourseSession(selectedSession.value.id);
|
||||||
|
|
||||||
|
if (selectedSession.value.id === UNFILTERED || !cs) {
|
||||||
|
circles.value = [{ ...allItem }];
|
||||||
|
selectedCircle.value = circles.value[0];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await learningPathStore.loadLearningPath(
|
||||||
|
cs.course.slug + "-lp",
|
||||||
|
undefined,
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
circles.value =
|
||||||
|
data?.circles.map((circle) => ({
|
||||||
|
id: circle.id,
|
||||||
|
name: circle.title,
|
||||||
|
})) || [];
|
||||||
|
|
||||||
|
circles.value = [{ ...allItem }, ...circles.value];
|
||||||
|
selectedCircle.value = circles.value[0];
|
||||||
|
});
|
||||||
|
|
||||||
|
const appointments = computed(() => {
|
||||||
|
console.log("recomputing appointments");
|
||||||
|
console.log("current session", selectedSession.value.name);
|
||||||
|
console.log("current circle", selectedCircle.value.name);
|
||||||
|
const filtered = courseSessionsStore
|
||||||
|
.allDueDates()
|
||||||
|
.filter(
|
||||||
|
(appointment) =>
|
||||||
|
// first filter by course session
|
||||||
|
selectedSession.value.id === UNFILTERED ||
|
||||||
|
appointment.course_session === selectedSession.value.id
|
||||||
|
)
|
||||||
|
.filter(
|
||||||
|
(appointment) =>
|
||||||
|
// then filter by circle
|
||||||
|
selectedCircle.value.id === UNFILTERED ||
|
||||||
|
appointment.circle?.id === selectedCircle.value.id
|
||||||
|
);
|
||||||
|
console.table(filtered);
|
||||||
|
return filtered;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="bg-gray-200">
|
||||||
|
<div class="container-large px-8 py-8">
|
||||||
|
<header class="mb-6">
|
||||||
|
<h1>{{ $t("a.AlleTermine") }}</h1>
|
||||||
|
</header>
|
||||||
|
<main>
|
||||||
|
<div class="col flex">
|
||||||
|
<span>{{ $t("a.Durchfuehrung") }}:</span>
|
||||||
|
<ItDropdownSelect
|
||||||
|
v-model="selectedSession"
|
||||||
|
class="mt-4 w-full lg:mt-0 lg:w-96"
|
||||||
|
:items="courseSessions"
|
||||||
|
></ItDropdownSelect>
|
||||||
|
<template v-if="selectedSession.id !== UNFILTERED">
|
||||||
|
<span>{{ $t("a.Circle") }}:</span>
|
||||||
|
<ItDropdownSelect
|
||||||
|
v-model="selectedCircle"
|
||||||
|
class="mt-4 w-full lg:mt-0 lg:w-96"
|
||||||
|
:items="circles"
|
||||||
|
></ItDropdownSelect>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
<div class="bg-white px-4 py-4">
|
||||||
|
<ul>
|
||||||
|
<li v-for="appointment in appointments" :key="appointment.id">
|
||||||
|
{{ appointment.title }} - {{ appointment.start }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped></style>
|
||||||
|
|
@ -183,6 +183,10 @@ const router = createRouter({
|
||||||
path: "/notifications",
|
path: "/notifications",
|
||||||
component: () => import("@/pages/NotificationsPage.vue"),
|
component: () => import("@/pages/NotificationsPage.vue"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/appointments",
|
||||||
|
component: () => import("@/pages/AppointmentsPage.vue"),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: "/styleguide",
|
path: "/styleguide",
|
||||||
component: () => import("../pages/StyleGuidePage.vue"),
|
component: () => import("../pages/StyleGuidePage.vue"),
|
||||||
|
|
|
||||||
|
|
@ -27,5 +27,17 @@ export function useRouteLookups() {
|
||||||
return regex.test(route.path);
|
return regex.test(route.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
return { inMediaLibrary, inCockpit, inLearningPath, inCompetenceProfile, inCourse };
|
function inDueDates() {
|
||||||
|
const regex = new RegExp("/[^/]+/duedates");
|
||||||
|
return regex.test(route.path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
inMediaLibrary,
|
||||||
|
inCockpit,
|
||||||
|
inLearningPath,
|
||||||
|
inCompetenceProfile,
|
||||||
|
inCourse,
|
||||||
|
inDueDates,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue