Cleanup dates/appointments handling in app
This commit is contained in:
parent
905d7a5290
commit
4925c1a178
|
|
@ -1,45 +0,0 @@
|
|||
<script setup lang="ts">
|
||||
import DueDatesList from "@/components/dueDates/DueDatesList.vue";
|
||||
import { useCourseSessionsStore } from "@/stores/courseSessions";
|
||||
import { useDashboardStore } from "@/stores/dashboard";
|
||||
import { getCockpitUrl } from "@/utils/utils";
|
||||
|
||||
const dashboardStore = useDashboardStore();
|
||||
const courseSessionsStore = useCourseSessionsStore();
|
||||
const allDueDates = courseSessionsStore.allDueDates();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<template v-if="dashboardStore.currentDashboardConfig">
|
||||
<h4 class="mb-6 text-xl font-bold">{{ $t("a.Aktueller Lehrgang") }}</h4>
|
||||
|
||||
<div class="mb-6 border border-gray-300 p-6">
|
||||
<h3 class="mb-6">{{ dashboardStore.currentDashboardConfig.name }}</h3>
|
||||
<router-link
|
||||
class="btn-blue"
|
||||
target="_blank"
|
||||
:to="getCockpitUrl(dashboardStore.currentDashboardConfig.slug)"
|
||||
>
|
||||
{{ $t("a.Cockpit anschauen") }}
|
||||
</router-link>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<router-link
|
||||
v-if="dashboardStore.dashboardConfigs.length > 1"
|
||||
class="block text-sm underline"
|
||||
to="/statistic/list"
|
||||
>
|
||||
{{ $t("a.Alle Lehrgänge anzeigen") }}
|
||||
</router-link>
|
||||
|
||||
<h3 class="mb-6 mt-16 text-xl font-bold">{{ $t("a.AlleTermine") }}</h3>
|
||||
<DueDatesList
|
||||
:due-dates="allDueDates"
|
||||
:max-count="13"
|
||||
:show-top-border="true"
|
||||
:show-all-due-dates-link="true"
|
||||
:show-bottom-border="true"
|
||||
:show-course-session="true"
|
||||
></DueDatesList>
|
||||
</template>
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
<script setup lang="ts">
|
||||
import DueDatesList from "@/components/dueDates/DueDatesList.vue";
|
||||
import { useCourseSessionsStore } from "@/stores/courseSessions";
|
||||
|
||||
const courseSessionsStore = useCourseSessionsStore();
|
||||
const allDueDates = courseSessionsStore.allDueDates();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h4 class="mb-6 text-xl font-bold">{{ $t("a.AlleTermine") }}</h4>
|
||||
<DueDatesList
|
||||
:due-dates="allDueDates"
|
||||
:max-count="13"
|
||||
:show-top-border="true"
|
||||
:show-all-due-dates-link="true"
|
||||
:show-bottom-border="true"
|
||||
:show-course-session="true"
|
||||
></DueDatesList>
|
||||
</template>
|
||||
|
|
@ -1,12 +1,11 @@
|
|||
<script lang="ts" setup>
|
||||
import type { CourseSession, DueDate } from "@/types";
|
||||
import { useCourseSessionsStore } from "@/stores/courseSessions";
|
||||
import { useTranslation } from "i18next-vue";
|
||||
import type { DashboardDueDate } from "@/services/dashboard";
|
||||
import { computed } from "vue";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
const props = defineProps<{
|
||||
dueDate: DueDate;
|
||||
dueDate: DashboardDueDate;
|
||||
singleLine?: boolean;
|
||||
showCourseSession?: boolean;
|
||||
}>();
|
||||
|
|
@ -15,27 +14,28 @@ const { t } = useTranslation();
|
|||
const dateType = t(props.dueDate.date_type_translation_key);
|
||||
const assignmentType = t(props.dueDate.assignment_type_translation_key);
|
||||
|
||||
const courseSessionsStore = useCourseSessionsStore();
|
||||
const courseSession = courseSessionsStore.allCourseSessions.find(
|
||||
(cs: CourseSession) => cs.id === props.dueDate.course_session_id
|
||||
);
|
||||
|
||||
if (!courseSession) {
|
||||
throw new Error("Course session not found");
|
||||
}
|
||||
|
||||
const url = courseSession.actions.includes("expert-cockpit")
|
||||
? props.dueDate.url_expert
|
||||
: props.dueDate.url;
|
||||
|
||||
const courseSessionTitle = computed(() => {
|
||||
if (props.dueDate.course_session_id) {
|
||||
return (
|
||||
courseSessionsStore.getCourseSessionById(props.dueDate.course_session_id)
|
||||
?.title ?? ""
|
||||
);
|
||||
const urlText = computed(() => {
|
||||
let result = "";
|
||||
if (dateType) {
|
||||
result += dateType;
|
||||
}
|
||||
return "";
|
||||
|
||||
if (assignmentType && !props.dueDate.title.startsWith(assignmentType)) {
|
||||
result += " " + assignmentType;
|
||||
}
|
||||
|
||||
if (props.dueDate.title) {
|
||||
result += " " + props.dueDate.title;
|
||||
}
|
||||
|
||||
return result.trim();
|
||||
});
|
||||
|
||||
const url = computed(() => {
|
||||
if (["SUPERVISOR", "EXPERT"].includes(props.dueDate.course_session.my_role)) {
|
||||
return props.dueDate.url_expert;
|
||||
}
|
||||
return props.dueDate.url;
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
@ -46,29 +46,23 @@ const courseSessionTitle = computed(() => {
|
|||
>
|
||||
<div class="space-y-1">
|
||||
<div>
|
||||
<a class="underline" :href="url">
|
||||
<span class="text-bold">
|
||||
<a :href="url">
|
||||
<span class="text-bold text-gray-900">
|
||||
{{ dayjs(props.dueDate.start).format("dddd D. MMMM YYYY") }}
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="flex gap-1">
|
||||
<div v-if="dateType">
|
||||
{{ dateType }}
|
||||
</div>
|
||||
|
||||
<div v-if="assignmentType && !props.dueDate.title.startsWith(assignmentType)">
|
||||
{{ assignmentType }}
|
||||
</div>
|
||||
|
||||
<div v-if="props.dueDate.title">
|
||||
{{ props.dueDate.title }}
|
||||
</div>
|
||||
<div>
|
||||
<a class="underline" :href="url">
|
||||
<span class="text-bold">
|
||||
{{ urlText }}
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="text-small text-gray-900">
|
||||
<div>
|
||||
<span v-if="props.showCourseSession ?? courseSessionTitle">
|
||||
{{ courseSessionTitle }}:
|
||||
<span v-if="props.dueDate.course_session.is_uk">
|
||||
{{ props.dueDate.course_session.session_title }}:
|
||||
</span>
|
||||
{{ $t("a.Circle") }} «{{ props.dueDate.circle?.title }}»
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
<script lang="ts" setup>
|
||||
import DueDateSingle from "@/components/dueDates/DueDateSingle.vue";
|
||||
import type { DueDate } from "@/types";
|
||||
import { computed } from "vue";
|
||||
import type { DashboardDueDate } from "@/services/dashboard";
|
||||
|
||||
const props = defineProps<{
|
||||
maxCount: number;
|
||||
dueDates: DueDate[];
|
||||
dueDates: DashboardDueDate[];
|
||||
showTopBorder: boolean;
|
||||
showBottomBorder: boolean;
|
||||
showAllDueDatesLink: boolean;
|
||||
|
|
|
|||
|
|
@ -1,37 +0,0 @@
|
|||
<script lang="ts" setup>
|
||||
import { useTranslation } from "i18next-vue";
|
||||
import type { DashboardDueDate } from "@/services/dashboard";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
const props = defineProps<{
|
||||
dueDate: DashboardDueDate;
|
||||
}>();
|
||||
|
||||
const { t } = useTranslation();
|
||||
const dateType = t(props.dueDate.date_type_translation_key);
|
||||
const assignmentType = t(props.dueDate.assignment_type_translation_key);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<article class="my-4">
|
||||
<div class="text-bold text-gray-900">
|
||||
{{ dayjs(props.dueDate.start).format("dd. DD. MMMM YYYY") }}
|
||||
</div>
|
||||
|
||||
<div v-if="dateType" class="text-bold">
|
||||
{{ dateType }}
|
||||
<span v-if="assignmentType && !props.dueDate.title.startsWith(assignmentType)">
|
||||
{{ assignmentType }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div v-if="props.dueDate.title">
|
||||
{{ props.dueDate.title }}
|
||||
</div>
|
||||
|
||||
<div v-if="props.dueDate.course_session.is_uk" class="text-gray-900">
|
||||
{{ props.dueDate.course_session.session_title }}
|
||||
{{ props.dueDate.circle?.title ?? "" }}
|
||||
</div>
|
||||
</article>
|
||||
</template>
|
||||
|
|
@ -4,7 +4,7 @@ import log from "loglevel";
|
|||
import { useDashboardPersons } from "@/composables";
|
||||
import { computed } from "vue";
|
||||
import _ from "lodash";
|
||||
import DashboardAsideDueDate from "@/pages/dashboard/DashboardAsideDueDate.vue";
|
||||
import DueDateSingle from "@/components/dueDates/DueDateSingle.vue";
|
||||
|
||||
log.debug("DashboardAsideWidget created");
|
||||
|
||||
|
|
@ -34,7 +34,7 @@ const displayDueDates = computed(() => {
|
|||
|
||||
<div v-for="dueDate in displayDueDates" :key="dueDate.id">
|
||||
<div class="border-b">
|
||||
<DashboardAsideDueDate :due-date="dueDate" />
|
||||
<DueDateSingle :due-date="dueDate" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import LoadingSpinner from "@/components/ui/LoadingSpinner.vue";
|
||||
import log from "loglevel";
|
||||
import { useCourseData, useDashboardPersons } from "@/composables";
|
||||
import { useDashboardPersons } from "@/composables";
|
||||
import ItDropdownSelect from "@/components/ui/ItDropdownSelect.vue";
|
||||
import { computed, ref, watch } from "vue";
|
||||
import { useTranslation } from "i18next-vue";
|
||||
|
|
@ -117,30 +117,54 @@ const filtersVisible = computed(() => {
|
|||
);
|
||||
});
|
||||
|
||||
const initialItemCircle: DropboxItem = {
|
||||
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("a.AlleCircle"),
|
||||
};
|
||||
const circles = ref<DropboxItem[]>([initialItemCircle]);
|
||||
},
|
||||
...circleList,
|
||||
];
|
||||
});
|
||||
const selectedCircle = ref<DropboxItem>(circles.value[0]);
|
||||
|
||||
async function loadCircleValues() {
|
||||
if (selectedCourse.value && selectedCourse.value.slug) {
|
||||
const learningPathQuery = useCourseData(selectedCourse.value.slug);
|
||||
await learningPathQuery.resultPromise;
|
||||
circles.value = [
|
||||
initialItemCircle,
|
||||
...(learningPathQuery.circles.value ?? []).map((circle) => ({
|
||||
id: circle.id,
|
||||
name: circle.title,
|
||||
})),
|
||||
];
|
||||
} else {
|
||||
circles.value = [initialItemCircle];
|
||||
}
|
||||
|
||||
selectedCircle.value = circles.value[0];
|
||||
}
|
||||
// async function loadCircleValues() {
|
||||
// if (selectedCourse.value && selectedCourse.value.slug) {
|
||||
// const learningPathQuery = useCourseData(selectedCourse.value.slug);
|
||||
// await learningPathQuery.resultPromise;
|
||||
// circles.value = [
|
||||
// initialItemCircle,
|
||||
// ...(learningPathQuery.circles.value ?? []).map((circle) => ({
|
||||
// id: circle.id,
|
||||
// name: circle.title,
|
||||
// })),
|
||||
// ];
|
||||
// } else {
|
||||
// circles.value = [initialItemCircle];
|
||||
// }
|
||||
//
|
||||
// selectedCircle.value = circles.value[0];
|
||||
// }
|
||||
|
||||
const dueDateTypes = computed(() => {
|
||||
const types = _(dashboardDueDates.value)
|
||||
|
|
@ -167,7 +191,7 @@ const selectedType = ref<DropboxItem>(dueDateTypes.value[0]);
|
|||
|
||||
watch(selectedCourse, async () => {
|
||||
selectedSession.value = courseSessions.value[0];
|
||||
await loadCircleValues();
|
||||
selectedCircle.value = circles.value[0];
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
@ -194,7 +218,6 @@ watch(selectedCourse, async () => {
|
|||
class="flex flex-col space-x-0 border-b bg-white lg:flex-row lg:space-x-3"
|
||||
>
|
||||
<ItDropdownSelect
|
||||
v-if="courses.length > 2"
|
||||
v-model="selectedCourse"
|
||||
data-cy="session-select"
|
||||
:items="courses"
|
||||
|
|
@ -202,7 +225,6 @@ watch(selectedCourse, async () => {
|
|||
></ItDropdownSelect>
|
||||
|
||||
<ItDropdownSelect
|
||||
v-if="courseSessions.length > 2"
|
||||
v-model="selectedSession"
|
||||
data-cy="session-select"
|
||||
:items="courseSessions"
|
||||
|
|
@ -210,7 +232,6 @@ watch(selectedCourse, async () => {
|
|||
></ItDropdownSelect>
|
||||
|
||||
<ItDropdownSelect
|
||||
v-if="circles.length > 2"
|
||||
v-model="selectedCircle"
|
||||
data-cy="appointments-circle-select"
|
||||
:items="circles"
|
||||
|
|
@ -218,7 +239,6 @@ watch(selectedCourse, async () => {
|
|||
></ItDropdownSelect>
|
||||
|
||||
<ItDropdownSelect
|
||||
v-if="dueDateTypes.length > 2"
|
||||
v-model="selectedType"
|
||||
data-cy="appointments-type-select"
|
||||
:items="dueDateTypes"
|
||||
|
|
|
|||
|
|
@ -1,36 +1,15 @@
|
|||
<script setup lang="ts">
|
||||
import type { Component } from "vue";
|
||||
import { onMounted } from "vue";
|
||||
import StatisticPage from "@/pages/dashboard/StatisticPage.vue";
|
||||
import ProgressPage from "@/pages/dashboard/ProgressPage.vue";
|
||||
import SimpleDates from "@/components/dashboard/SimpleDates.vue";
|
||||
import ItDropdownSelect from "@/components/ui/ItDropdownSelect.vue";
|
||||
import { useDashboardStore } from "@/stores/dashboard";
|
||||
import type { DashboardType } from "@/gql/graphql";
|
||||
import type { DashboardCourseConfigType } from "@/services/dashboard";
|
||||
import SimpleCoursePage from "@/pages/dashboard/SimpleCoursePage.vue";
|
||||
import LoadingSpinner from "@/components/ui/LoadingSpinner.vue";
|
||||
import CourseDetailDates from "@/components/dashboard/CourseDetailDates.vue";
|
||||
import NoCourseSession from "@/components/dashboard/NoCourseSession.vue";
|
||||
import MentorPage from "@/pages/dashboard/MentorPage.vue";
|
||||
import CoursePanel from "@/components/dashboard/CoursePanel.vue";
|
||||
import DashboardAsideWidget from "@/pages/dashboard/DashboardAsideWidget.vue";
|
||||
|
||||
const dashboardStore = useDashboardStore();
|
||||
|
||||
interface DashboardPage {
|
||||
main: Component;
|
||||
aside: Component;
|
||||
}
|
||||
|
||||
const boards: Record<DashboardType, DashboardPage> = {
|
||||
PROGRESS_DASHBOARD: { main: ProgressPage, aside: SimpleDates },
|
||||
SIMPLE_DASHBOARD: { main: SimpleCoursePage, aside: SimpleDates },
|
||||
STATISTICS_DASHBOARD: { main: StatisticPage, aside: CourseDetailDates },
|
||||
MENTOR_DASHBOARD: { main: MentorPage, aside: SimpleDates },
|
||||
PRAXISBILDNER_DASHBOARD: { main: CoursePanel, aside: SimpleDates },
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
await dashboardStore.loadDashboardDetails();
|
||||
});
|
||||
|
|
@ -68,23 +47,6 @@ function newDashboardConfigForId(id: string): DashboardCourseConfigType | undefi
|
|||
<CoursePanel :course-config="newDashboardConfigForId(config.course_id)" />
|
||||
</li>
|
||||
</ul>
|
||||
<!-- end of new way of dashboard -->
|
||||
<!-- keep until we unify the dashboard -->
|
||||
<!-- <CoursePanel-->
|
||||
<!-- v-if="-->
|
||||
<!-- ['PRAXISBILDNER_DASHBOARD', 'PROGRESS_DASHBOARD'].includes(-->
|
||||
<!-- dashboardStore.currentDashboardConfig.dashboard_type-->
|
||||
<!-- )-->
|
||||
<!-- "-->
|
||||
<!-- :course-config="-->
|
||||
<!-- newDashboardConfigForId(dashboardStore.currentDashboardConfig.id)-->
|
||||
<!-- "-->
|
||||
<!-- />-->
|
||||
<!-- <component-->
|
||||
<!-- :is="boards[dashboardStore.currentDashboardConfig.dashboard_type].main"-->
|
||||
<!-- v-else-->
|
||||
<!-- ></component>-->
|
||||
<!-- end of old way of dashboard -->
|
||||
</div>
|
||||
</main>
|
||||
<aside class="lg:order-2 lg:w-[384px] xl:w-[512px]">
|
||||
|
|
|
|||
|
|
@ -248,12 +248,13 @@ def get_dashboard_due_dates(request):
|
|||
due_dates = []
|
||||
today = date.today()
|
||||
for due_date in all_due_dates:
|
||||
if due_date.end:
|
||||
if due_date.end.date() >= today:
|
||||
due_dates.append(due_date)
|
||||
elif due_date.start:
|
||||
if due_date.start.date() >= today:
|
||||
due_dates.append(due_date)
|
||||
# if due_date.end:
|
||||
# if due_date.end.date() >= today:
|
||||
# due_dates.append(due_date)
|
||||
# elif due_date.start:
|
||||
# if due_date.start.date() >= today:
|
||||
# due_dates.append(due_date)
|
||||
|
||||
due_dates.sort(key=lambda x: x.start)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue