269 lines
7.0 KiB
Vue
269 lines
7.0 KiB
Vue
<script setup lang="ts">
|
|
import DueDateSingle from "@/components/dueDates/DueDateSingle.vue";
|
|
import ItDropdownSelect from "@/components/ui/ItDropdownSelect.vue";
|
|
import LoadingSpinner from "@/components/ui/LoadingSpinner.vue";
|
|
import { useDashboardPersonsDueDates } from "@/composables";
|
|
import { getPreviousRoute } from "@/router/history";
|
|
import { useRouteQuery } from "@vueuse/router";
|
|
import { useTranslation } from "i18next-vue";
|
|
import _ from "lodash";
|
|
import log from "loglevel";
|
|
import { computed, ref, watch } from "vue";
|
|
|
|
log.debug("DashboardPersonsPage created");
|
|
|
|
const UNFILTERED = "0";
|
|
|
|
type DropboxItem = {
|
|
id: string;
|
|
name: string;
|
|
};
|
|
|
|
type CourseItem = DropboxItem & {
|
|
slug: string;
|
|
};
|
|
|
|
const { t } = useTranslation();
|
|
|
|
const { loading, currentDueDates: dashboardDueDates } = useDashboardPersonsDueDates();
|
|
|
|
const courses = computed(() => {
|
|
return [
|
|
{
|
|
id: UNFILTERED,
|
|
name: `${t("Lehrgang")}: ${t("a.Alle")}`,
|
|
slug: "",
|
|
},
|
|
..._(dashboardDueDates.value)
|
|
.map((dueDate) => {
|
|
return {
|
|
name: dueDate.course_session.course_title,
|
|
id: dueDate.course_session.course_id,
|
|
slug: dueDate.course_session.course_slug,
|
|
};
|
|
})
|
|
.uniqBy("id")
|
|
.orderBy("name")
|
|
.value(),
|
|
];
|
|
});
|
|
|
|
const selectedCourse = ref<CourseItem>(courses.value[0]);
|
|
|
|
const courseSessions = computed(() => {
|
|
let sessions = _(dashboardDueDates.value)
|
|
.map((dueDate) => {
|
|
return Object.assign({}, dueDate.course_session, {
|
|
name: dueDate.course_session.session_title,
|
|
id: dueDate.course_session.id,
|
|
});
|
|
})
|
|
.uniqBy("id")
|
|
.orderBy("name")
|
|
.value();
|
|
|
|
// filter by selected course
|
|
if (selectedCourse.value.id !== UNFILTERED) {
|
|
sessions = sessions.filter((cs) => cs.course_id === selectedCourse.value.id);
|
|
}
|
|
|
|
return [
|
|
{
|
|
id: UNFILTERED,
|
|
name: `${t("Durchführung")}: ${t("a.Alle")}`,
|
|
},
|
|
...sessions,
|
|
];
|
|
});
|
|
|
|
const selectedSessionRouteQuery = useRouteQuery("session", UNFILTERED, {
|
|
mode: "replace",
|
|
});
|
|
const selectedSession = ref<DropboxItem>(courseSessions.value[0]);
|
|
|
|
watch(selectedSession, () => {
|
|
// @ts-ignore
|
|
selectedSessionRouteQuery.value = selectedSession.value.id;
|
|
});
|
|
|
|
watch(courseSessions, () => {
|
|
if (courseSessions.value.length > 0 && selectedSessionRouteQuery.value) {
|
|
// preselect session from route query
|
|
const selectedSessionFromRoute = courseSessions.value.find(
|
|
(cs) => cs.id === selectedSessionRouteQuery.value
|
|
);
|
|
if (selectedSessionFromRoute) {
|
|
selectedSession.value = selectedSessionFromRoute;
|
|
return;
|
|
}
|
|
}
|
|
selectedSession.value = courseSessions.value[0];
|
|
});
|
|
|
|
const filteredDueDates = computed(() => {
|
|
return _.orderBy(
|
|
dashboardDueDates.value
|
|
.filter((dueDate) => {
|
|
if (selectedCourse.value.id === UNFILTERED) {
|
|
return true;
|
|
}
|
|
return dueDate.course_session.course_id === selectedCourse.value.id;
|
|
})
|
|
.filter((dueDate) => {
|
|
if (selectedSession.value.id === UNFILTERED) {
|
|
return true;
|
|
}
|
|
return dueDate.course_session.id === selectedSession.value.id;
|
|
})
|
|
.filter((dueDate) => {
|
|
if (selectedCircle.value.id === UNFILTERED) {
|
|
return true;
|
|
}
|
|
return dueDate.circle?.id === selectedCircle.value.id;
|
|
})
|
|
.filter((dueDate) => {
|
|
if (selectedType.value.id === UNFILTERED) {
|
|
return true;
|
|
}
|
|
return dueDate.translatedType === selectedType.value.id;
|
|
}),
|
|
|
|
["start"]
|
|
);
|
|
});
|
|
|
|
const filtersVisible = computed(() => {
|
|
return (
|
|
courses.value.length > 2 ||
|
|
courseSessions.value.length > 2 ||
|
|
circles.value.length > 2 ||
|
|
dueDateTypes.value.length > 2
|
|
);
|
|
});
|
|
|
|
const circles = computed(() => {
|
|
const dueDatesBySelectedCourse = dashboardDueDates.value.filter((dueDate) => {
|
|
if (selectedCourse.value.id === UNFILTERED) {
|
|
return true;
|
|
}
|
|
return dueDate.course_session.course_id === selectedCourse.value.id;
|
|
});
|
|
const circleList = _(dueDatesBySelectedCourse)
|
|
.filter((dueDate) => {
|
|
return !!dueDate.circle;
|
|
})
|
|
.map((dueDate) => {
|
|
return {
|
|
name: dueDate.circle?.title ?? "",
|
|
id: dueDate.circle?.id ?? "",
|
|
};
|
|
})
|
|
.uniqBy("id")
|
|
.orderBy("name")
|
|
.value();
|
|
|
|
return [
|
|
{
|
|
id: UNFILTERED,
|
|
name: `${t("Circle")}: ${t("a.Alle")}`,
|
|
},
|
|
...circleList,
|
|
];
|
|
});
|
|
const selectedCircle = ref<DropboxItem>(circles.value[0]);
|
|
|
|
const dueDateTypes = computed(() => {
|
|
const types = _(dashboardDueDates.value)
|
|
.map((dueDate) => {
|
|
return {
|
|
name: dueDate.translatedType,
|
|
id: dueDate.translatedType,
|
|
};
|
|
})
|
|
.uniqBy("id")
|
|
.orderBy("name")
|
|
.value();
|
|
|
|
return [
|
|
{
|
|
id: UNFILTERED,
|
|
name: t("a.AlleTypen"),
|
|
},
|
|
...types,
|
|
];
|
|
});
|
|
|
|
const selectedType = ref<DropboxItem>(dueDateTypes.value[0]);
|
|
|
|
watch(selectedCourse, async () => {
|
|
selectedSession.value = courseSessions.value[0];
|
|
selectedCircle.value = circles.value[0];
|
|
selectedType.value = dueDateTypes.value[0];
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<div>
|
|
<div v-if="loading" class="m-8 flex justify-center">
|
|
<LoadingSpinner />
|
|
</div>
|
|
<div v-else class="bg-gray-200">
|
|
<div class="container-large">
|
|
<router-link
|
|
:to="getPreviousRoute() || '/'"
|
|
class="btn-text inline-flex items-center p-0"
|
|
data-cy="back-button"
|
|
>
|
|
<it-icon-arrow-left class="-ml-1 mr-1 h-5 w-5"></it-icon-arrow-left>
|
|
<span class="inline">{{ $t("general.back") }}</span>
|
|
</router-link>
|
|
|
|
<h2 class="my-4" data-cy="title">{{ $t("a.Termine") }}</h2>
|
|
<div class="bg-white px-4 py-2">
|
|
<section
|
|
v-if="filtersVisible"
|
|
class="flex flex-col space-x-0 border-b bg-white lg:flex-row lg:space-x-3"
|
|
>
|
|
<ItDropdownSelect
|
|
v-model="selectedCourse"
|
|
data-cy="select-course"
|
|
:items="courses"
|
|
borderless
|
|
></ItDropdownSelect>
|
|
|
|
<ItDropdownSelect
|
|
v-model="selectedSession"
|
|
data-cy="select-session"
|
|
:items="courseSessions"
|
|
borderless
|
|
></ItDropdownSelect>
|
|
|
|
<ItDropdownSelect
|
|
v-model="selectedCircle"
|
|
data-cy="select-circle"
|
|
:items="circles"
|
|
borderless
|
|
></ItDropdownSelect>
|
|
|
|
<ItDropdownSelect
|
|
v-model="selectedType"
|
|
data-cy="select-type"
|
|
:items="dueDateTypes"
|
|
borderless
|
|
></ItDropdownSelect>
|
|
</section>
|
|
|
|
<section data-cy="due-date-list">
|
|
<div v-for="dueDate in filteredDueDates" :key="dueDate.id" class="border-b">
|
|
<DueDateSingle :single-line="true" :due-date="dueDate"></DueDateSingle>
|
|
</div>
|
|
<div v-if="!filteredDueDates.length" class="mt-4">
|
|
<p>{{ $t("dueDates.noDueDatesAvailable") }}</p>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|