Filter appointments by course

This commit is contained in:
Daniel Egger 2023-10-04 17:39:04 +02:00
parent 6048129507
commit a180c5c825
3 changed files with 83 additions and 85 deletions

View File

@ -27,6 +27,7 @@ const dueDatesDisplayed = computed(() => {
<li
v-for="dueDate in dueDatesDisplayed"
:key="dueDate.id"
class="cy-single-due-date"
:class="{ 'first:border-t': props.showTopBorder, 'border-b': true }"
>
<DueDateSingle

View File

@ -1,5 +1,5 @@
<script setup lang="ts">
import { computed, ref, watch } from "vue";
import { computed, onMounted, ref, watch } from "vue";
import { useCourseSessionsStore } from "@/stores/courseSessions";
import { useLearningPathStore } from "@/stores/learningPath";
import { useTranslation } from "i18next-vue";
@ -18,74 +18,71 @@ type Item = {
name: string;
};
const courses: (Item & { slug: string })[] =
courseSessionsStore.uniqueCourseSessionsByCourse.map((cs) => ({
id: cs.course.id,
name: cs.course.title,
slug: cs.course.slug,
}));
const selectedCourse = ref<Item>(courses[0]);
const courseSessions = computed(() => {
return [
{
id: UNFILTERED,
name: t("a.AlleDurchführungen"),
},
...courseSessionsStore.allCourseSessions
.filter((cs) => cs.course.id === selectedCourse.value.id)
.map((cs) => ({ id: cs.id, name: cs.title })),
];
});
const selectedSession = ref<Item>(courseSessions.value[0]);
const initialItemCircle: Item = {
id: UNFILTERED,
name: t("a.AlleCircle"),
};
const circles = ref<Item[]>([initialItemCircle]);
const courseSessions: Item[] = [
{
id: UNFILTERED,
name: t("a.AlleDurchführungen"),
},
...courseSessionsStore.allCourseSessions.map((cs) => ({ id: cs.id, name: cs.title })),
];
const selectedSession = ref<Item>(courseSessions[0]);
const selectedCircle = ref<Item>(circles.value[0]);
if (courseSessionsStore.currentCourseSession) {
selectedSession.value = {
id: courseSessionsStore.currentCourseSession.id,
name: courseSessionsStore.currentCourseSession.title,
};
}
watch(selectedSession, async () => {
// We don't have all circles for the unfiltered session,
// we fetch them from the learning path when the session changes
const isUnfiltered = selectedSession.value.id === UNFILTERED;
const courseSession = courseSessionsStore.allCourseSessions.find(
(item) => item.id === selectedSession.value.id
);
if (!courseSession || isUnfiltered) {
resetCircles();
return;
}
async function loadCircleValues() {
const data = await learningPathStore.loadLearningPath(
`${courseSession.course.slug}-lp`,
`${selectedCourse.value.slug}-lp`,
undefined,
false,
false
);
if (data) {
updateCircles(data.circles);
circles.value = [
initialItemCircle,
...data.circles.map((circle) => ({ id: circle.id, name: circle.title })),
];
} else {
resetCircles();
circles.value = [initialItemCircle];
}
selectedCircle.value = circles.value[0];
}
watch(selectedCourse, async () => {
selectedSession.value = courseSessions.value[0];
await loadCircleValues();
});
const resetCircles = () => {
circles.value = [initialItemCircle];
selectedCircle.value = circles.value[0];
};
const updateCircles = (newCircles: { id: number; title: string }[]) => {
circles.value = [
initialItemCircle,
...newCircles.map((circle) => ({ id: circle.id, name: circle.title })),
];
selectedCircle.value = circles.value[0];
};
onMounted(async () => {
await loadCircleValues();
});
const appointments = computed(() => {
return courseSessionsStore
.allDueDates()
.filter((dueDate) => isMatchingSession(dueDate) && isMatchingCircle(dueDate));
.filter(
(dueDate) =>
isMatchingCourse(dueDate) &&
isMatchingSession(dueDate) &&
isMatchingCircle(dueDate)
);
});
const isMatchingSession = (dueDate: DueDate) =>
@ -96,6 +93,9 @@ const isMatchingCircle = (dueDate: DueDate) =>
selectedCircle.value.id === UNFILTERED ||
dueDate.circle?.id === selectedCircle.value.id;
const isMatchingCourse = (dueDate: DueDate) =>
courseSessions.value.map((cs) => cs.id).includes(dueDate.course_session as number);
const numAppointmentsToShow = ref(7);
const canLoadMore = computed(() => {
return numAppointmentsToShow.value < appointments.value.length;
@ -109,8 +109,15 @@ async function loadAdditionalAppointments() {
<template>
<div class="bg-gray-200">
<div class="container-large px-8 py-8">
<header class="mb-6">
<header class="mb-6 flex flex-col lg:flex-row lg:items-center lg:justify-between">
<h1>{{ $t("a.AlleTermine") }}</h1>
<div>
<ItDropdownSelect
v-model="selectedCourse"
data-cy="appointments-course-select"
:items="courses"
></ItDropdownSelect>
</div>
</header>
<main>
<div class="flex flex-col space-y-2">
@ -121,14 +128,12 @@ async function loadAdditionalAppointments() {
:items="courseSessions"
borderless
></ItDropdownSelect>
<template v-if="selectedSession.id !== UNFILTERED">
<ItDropdownSelect
v-model="selectedCircle"
data-cy="appointments-circle-select"
:items="circles"
borderless
></ItDropdownSelect>
</template>
<ItDropdownSelect
v-model="selectedCircle"
data-cy="appointments-circle-select"
:items="circles"
borderless
></ItDropdownSelect>
</div>
<div class="bg-white px-5">
<DueDatesList

View File

@ -1,49 +1,41 @@
import {login} from "./helpers";
import { login } from "./helpers";
const CIRCLE_SELECT = '[data-cy=appointments-circle-select]';
const SESSION_SELECT = '[data-cy=appointments-session-select]';
const APPOINTMENTS = '[data-cy=appointments-list]';
// constants
const COURSE_SELECT = "[data-cy=appointments-course-select]";
const SESSION_SELECT = "[data-cy=appointments-session-select]";
const CIRCLE_SELECT = "[data-cy=appointments-circle-select]";
const APPOINTMENTS = "[data-cy=appointments-list]";
describe("appointments.cy.js", () => {
beforeEach(() => {
cy.manageCommand("cypress_reset");
login("test-student2@example.com", "test");
cy.visit("/course/test-lehrgang/appointments");
// Pre-Select Bern
cy.get(SESSION_SELECT).click();
cy.get(SESSION_SELECT).contains("Bern").click();
cy.get(SESSION_SELECT).should("contain", "Bern");
});
it("preselects the correct course session (Bern)", () => {
it("preselects first course (Test Lehrgang)", () => {
cy.visit("/course/test-lehrgang/appointments");
cy.get(SESSION_SELECT).should("contain", "Bern");
})
it("preselects NO course session (all)", () => {
cy.visit("/appointments");
cy.get(COURSE_SELECT).should("contain", "Test Lehrgang");
cy.get(SESSION_SELECT).should("contain", "Alle");
})
cy.get(CIRCLE_SELECT).should("contain", "Alle");
cy.get(".cy-single-due-date").should("have.length", 4);
});
it("can filter by circle", () => {
// TODO: Fix this test (somehow the circle select is not working)
// because it's loading on change of the session select?
cy.get(CIRCLE_SELECT).click();
cy.get(CIRCLE_SELECT).contains("Fahrzeug").click();
// cy.get(CIRCLE_SELECT).click();
// cy.get(CIRCLE_SELECT).contains("Fahrzeug").click();
//
// // THEN
// cy.get(APPOINTMENTS).should("not.contain", "Keine Termine");
})
// THEN
cy.get(APPOINTMENTS).should("not.contain", "Keine Termine");
});
it("can switch course session to Zurich", () => {
it("can switch course session", () => {
cy.get(SESSION_SELECT).click();
cy.get(SESSION_SELECT).contains("Zürich").click();
cy.get(SESSION_SELECT).should("contain", "Zürich");
// THEN
cy.get(APPOINTMENTS).should("contain", "Keine Termine");
})
})
});
});