Filter appointments by course
This commit is contained in:
parent
6048129507
commit
a180c5c825
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 initialItemCircle: Item = {
|
||||
id: UNFILTERED,
|
||||
name: t("a.AlleCircle"),
|
||||
};
|
||||
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 circles = ref<Item[]>([initialItemCircle]);
|
||||
const courseSessions: Item[] = [
|
||||
const courseSessions = computed(() => {
|
||||
return [
|
||||
{
|
||||
id: UNFILTERED,
|
||||
name: t("a.AlleDurchführungen"),
|
||||
},
|
||||
...courseSessionsStore.allCourseSessions.map((cs) => ({ id: cs.id, name: cs.title })),
|
||||
...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 selectedSession = ref<Item>(courseSessions[0]);
|
||||
const initialItemCircle: Item = {
|
||||
id: UNFILTERED,
|
||||
name: t("a.AlleCircle"),
|
||||
};
|
||||
const circles = ref<Item[]>([initialItemCircle]);
|
||||
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);
|
||||
} else {
|
||||
resetCircles();
|
||||
}
|
||||
});
|
||||
|
||||
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 })),
|
||||
...data.circles.map((circle) => ({ id: circle.id, name: circle.title })),
|
||||
];
|
||||
} else {
|
||||
circles.value = [initialItemCircle];
|
||||
}
|
||||
|
||||
selectedCircle.value = circles.value[0];
|
||||
};
|
||||
}
|
||||
|
||||
watch(selectedCourse, async () => {
|
||||
selectedSession.value = courseSessions.value[0];
|
||||
await loadCircleValues();
|
||||
});
|
||||
|
||||
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>
|
||||
</div>
|
||||
<div class="bg-white px-5">
|
||||
<DueDatesList
|
||||
|
|
|
|||
|
|
@ -1,49 +1,41 @@
|
|||
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");
|
||||
})
|
||||
|
||||
})
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue