Refactor attendance page, add components for the check and the status
This commit is contained in:
parent
abe60e7468
commit
f8b8347bb9
|
|
@ -1,27 +1,29 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import ItCheckbox from "@/components/ui/ItCheckbox.vue";
|
import ItCheckbox from "@/components/ui/ItCheckbox.vue";
|
||||||
import ItDropdownSelect from "@/components/ui/ItDropdownSelect.vue";
|
|
||||||
import ItPersonRow from "@/components/ui/ItPersonRow.vue";
|
import ItPersonRow from "@/components/ui/ItPersonRow.vue";
|
||||||
import { useCourseSessionDetailQuery, useCurrentCourseSession } from "@/composables";
|
import { useCourseSessionDetailQuery, useCurrentCourseSession } from "@/composables";
|
||||||
import type { AttendanceUserStatus } from "@/gql/graphql";
|
import type {
|
||||||
import { graphqlClient } from "@/graphql/client";
|
AttendanceUserStatus,
|
||||||
|
CourseSessionAttendanceCourseObjectType,
|
||||||
|
} from "@/gql/graphql";
|
||||||
import { ATTENDANCE_CHECK_MUTATION } from "@/graphql/mutations";
|
import { ATTENDANCE_CHECK_MUTATION } from "@/graphql/mutations";
|
||||||
import { ATTENDANCE_CHECK_QUERY } from "@/graphql/queries";
|
import { ATTENDANCE_CHECK_QUERY } from "@/graphql/queries";
|
||||||
import { exportAttendance } from "@/services/dashboard";
|
import { exportAttendance } from "@/services/dashboard";
|
||||||
|
import { useExpertCockpitStore } from "@/stores/expertCockpit";
|
||||||
import { useUserStore } from "@/stores/user";
|
import { useUserStore } from "@/stores/user";
|
||||||
import type { DropdownSelectable } from "@/types";
|
|
||||||
import { openDataAsXls } from "@/utils/export";
|
import { openDataAsXls } from "@/utils/export";
|
||||||
import { useMutation } from "@urql/vue";
|
import { useMutation, useQuery } from "@urql/vue";
|
||||||
import dayjs from "dayjs";
|
import { useDateFormat } from "@vueuse/core";
|
||||||
import { useTranslation } from "i18next-vue";
|
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
import { computed, onMounted, reactive, watch } from "vue";
|
import { computed, onMounted, ref } from "vue";
|
||||||
|
import AttendanceCheck from "../cockpitPage/AttendanceCheck.vue";
|
||||||
|
import AttendanceStatus from "../cockpitPage/AttendanceStatus.vue";
|
||||||
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const attendanceMutation = useMutation(ATTENDANCE_CHECK_MUTATION);
|
const attendanceMutation = useMutation(ATTENDANCE_CHECK_MUTATION);
|
||||||
const courseSessionDetailResult = useCourseSessionDetailQuery();
|
const courseSessionDetailResult = useCourseSessionDetailQuery();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const courseSession = useCurrentCourseSession();
|
const courseSession = useCurrentCourseSession();
|
||||||
|
const expertCockpitStore = useExpertCockpitStore();
|
||||||
|
|
||||||
const attendanceCourses = computed(() => {
|
const attendanceCourses = computed(() => {
|
||||||
return courseSessionDetailResult.courseSessionDetail.value?.attendance_courses ?? [];
|
return courseSessionDetailResult.courseSessionDetail.value?.attendance_courses ?? [];
|
||||||
|
|
@ -33,44 +35,28 @@ const courseSessionDetail = computed(() => {
|
||||||
|
|
||||||
const attendanceCourseCircleId = computed(() => {
|
const attendanceCourseCircleId = computed(() => {
|
||||||
const selectedAttendandeCourse = attendanceCourses.value.find(
|
const selectedAttendandeCourse = attendanceCourses.value.find(
|
||||||
(course) => course.id === state.attendanceCourseSelected.id
|
(course) => course.id === currentCourse.value.id
|
||||||
);
|
);
|
||||||
return selectedAttendandeCourse?.learning_content?.circle?.id;
|
return selectedAttendandeCourse?.learning_content?.circle?.id;
|
||||||
});
|
});
|
||||||
|
|
||||||
const presenceCoursesDropdownOptions = computed(() => {
|
// const currentCircle = computed(() => expertCockpitStore.currentCircle);
|
||||||
return attendanceCourses.value.map(
|
|
||||||
(attendanceCourse) =>
|
|
||||||
({
|
|
||||||
id: attendanceCourse.id,
|
|
||||||
name: `${t("a.Präsenzkurs")} ${
|
|
||||||
attendanceCourse.learning_content.circle?.title
|
|
||||||
} ${dayjs(attendanceCourse.due_date?.start).format("DD.MM.YYYY")}`,
|
|
||||||
}) as DropdownSelectable
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
const state = reactive({
|
const currentCourse = computed(() => expertCockpitStore.currentCourse);
|
||||||
userPresence: new Map<string, boolean>(),
|
// const currentCourse = computed(() => {
|
||||||
attendanceCourseSelected: presenceCoursesDropdownOptions.value[0],
|
// return attendanceCourses.value.find(
|
||||||
disclaimerConfirmed: false,
|
// (i) => i.learning_content.circle?.id == currentCircle.value?.id
|
||||||
attendanceSaved: false,
|
// );
|
||||||
});
|
// });
|
||||||
|
|
||||||
watch(
|
const userPresence = ref(new Map<string, boolean>());
|
||||||
attendanceCourses,
|
const disclaimerConfirmed = ref(false);
|
||||||
(newVal) => {
|
const attendanceSaved = ref(false);
|
||||||
if (newVal && newVal.length > 0) {
|
|
||||||
state.attendanceCourseSelected = presenceCoursesDropdownOptions.value[0];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ immediate: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
function resetState() {
|
function resetState() {
|
||||||
state.userPresence = new Map<string, boolean>();
|
userPresence.value = new Map<string, boolean>();
|
||||||
state.disclaimerConfirmed = false;
|
disclaimerConfirmed.value = false;
|
||||||
state.attendanceSaved = false;
|
attendanceSaved.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const onSubmit = async () => {
|
const onSubmit = async () => {
|
||||||
|
|
@ -78,54 +64,62 @@ const onSubmit = async () => {
|
||||||
user_id: string;
|
user_id: string;
|
||||||
status: AttendanceUserStatus;
|
status: AttendanceUserStatus;
|
||||||
};
|
};
|
||||||
const attendanceUserList: UserPresence[] = Array.from(state.userPresence.keys()).map(
|
console.log(Array.from(userPresence.value.keys()));
|
||||||
|
const attendanceUserList: UserPresence[] = Array.from(userPresence.value.keys()).map(
|
||||||
(key) => ({
|
(key) => ({
|
||||||
user_id: key,
|
user_id: key,
|
||||||
status: state.userPresence.get(key) ? "PRESENT" : "ABSENT",
|
status: userPresence.value.get(key) ? "PRESENT" : "ABSENT",
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
console.log(attendanceUserList);
|
||||||
const res = await attendanceMutation.executeMutation({
|
const res = await attendanceMutation.executeMutation({
|
||||||
attendanceCourseId: state.attendanceCourseSelected.id.toString(),
|
attendanceCourseId: (
|
||||||
|
currentCourse.value as CourseSessionAttendanceCourseObjectType
|
||||||
|
).id.toString(),
|
||||||
attendanceUserList: attendanceUserList,
|
attendanceUserList: attendanceUserList,
|
||||||
});
|
});
|
||||||
if (res.error) {
|
if (res.error) {
|
||||||
log.error("Could not submit attendance check: ", res.error);
|
log.error("Could not submit attendance check: ", res.error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
state.disclaimerConfirmed = false;
|
disclaimerConfirmed.value = false;
|
||||||
state.attendanceSaved = true;
|
attendanceSaved.value = true;
|
||||||
log.info("Attendance check submitted: ", res);
|
log.info("Attendance check submitted: ", res);
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadAttendanceData = async () => {
|
const loadAttendanceData = async () => {
|
||||||
resetState();
|
resetState();
|
||||||
// with changing variables `useQuery` does not seem to work correctly
|
// with changing variables `useQuery` does not seem to work correctly
|
||||||
if (state.attendanceCourseSelected) {
|
if (currentCourse.value) {
|
||||||
const res = await graphqlClient.query(
|
const result = await useQuery({
|
||||||
ATTENDANCE_CHECK_QUERY,
|
query: ATTENDANCE_CHECK_QUERY,
|
||||||
{
|
variables: {
|
||||||
courseSessionId: state.attendanceCourseSelected.id.toString(),
|
courseSessionId: currentCourse.value.id.toString(),
|
||||||
},
|
},
|
||||||
{
|
requestPolicy: "network-only",
|
||||||
requestPolicy: "network-only",
|
});
|
||||||
}
|
console.log(result.data.value?.course_session_attendance_course);
|
||||||
);
|
|
||||||
const attendanceUserList =
|
const attendanceUserList =
|
||||||
res.data?.course_session_attendance_course?.attendance_user_list ?? [];
|
result.data?.value?.course_session_attendance_course?.attendance_user_list ?? [];
|
||||||
|
console.log(attendanceUserList);
|
||||||
for (const user of attendanceUserList) {
|
for (const user of attendanceUserList) {
|
||||||
if (!user) continue;
|
if (!user) continue;
|
||||||
state.userPresence.set(user.user_id, user.status === "PRESENT");
|
userPresence.value.set(user.user_id, user.status === "PRESENT");
|
||||||
}
|
}
|
||||||
if (attendanceUserList.length !== 0) {
|
if (attendanceUserList.length !== 0) {
|
||||||
state.attendanceSaved = true;
|
attendanceSaved.value = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function editAgain() {
|
function editAgain() {
|
||||||
state.attendanceSaved = false;
|
attendanceSaved.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const toggleDisclaimer = (newValue: boolean) => {
|
||||||
|
disclaimerConfirmed.value = newValue;
|
||||||
|
};
|
||||||
|
|
||||||
async function exportData() {
|
async function exportData() {
|
||||||
const data = await exportAttendance(
|
const data = await exportAttendance(
|
||||||
{
|
{
|
||||||
|
|
@ -137,19 +131,26 @@ async function exportData() {
|
||||||
openDataAsXls(data.encoded_data, data.file_name);
|
openDataAsXls(data.encoded_data, data.file_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(async () => {
|
||||||
log.debug("AttendanceCheckPage mounted");
|
log.debug("AttendanceCheckPage mounted");
|
||||||
loadAttendanceData();
|
loadAttendanceData();
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(
|
const courseDueDate = computed(() => {
|
||||||
() => state.attendanceCourseSelected,
|
if (currentCourse.value && currentCourse.value.due_date?.start) {
|
||||||
() => {
|
return currentCourse.value.due_date.start;
|
||||||
log.debug("attendanceCourseSelected changed", state.attendanceCourseSelected);
|
}
|
||||||
loadAttendanceData();
|
return "";
|
||||||
},
|
});
|
||||||
{ immediate: true }
|
|
||||||
);
|
const formattedCourseDueDate = computed(() => {
|
||||||
|
if (courseDueDate.value) {
|
||||||
|
return useDateFormat(courseDueDate.value, "D. MMMM YYYY", {
|
||||||
|
locales: "de-CH",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -165,9 +166,8 @@ watch(
|
||||||
</router-link>
|
</router-link>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<h3 class="pb-4 text-xl font-bold">{{ $t("a.Anwesenheit Präsenzkurse") }}</h3>
|
|
||||||
<button
|
<button
|
||||||
v-if="state.attendanceSaved"
|
v-if="attendanceSaved"
|
||||||
class="flex"
|
class="flex"
|
||||||
data-cy="export-button"
|
data-cy="export-button"
|
||||||
@click="exportData"
|
@click="exportData"
|
||||||
|
|
@ -176,54 +176,32 @@ watch(
|
||||||
<span class="ml inline-block">{{ $t("a.Als Excel exportieren") }}</span>
|
<span class="ml inline-block">{{ $t("a.Als Excel exportieren") }}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<section v-if="attendanceCourses.length && state.attendanceCourseSelected">
|
<section v-if="attendanceCourses.length && currentCourse">
|
||||||
<div class="flex flex-row flex-wrap justify-between bg-white p-6">
|
<div class="flex flex-col justify-between gap-8 bg-white py-6">
|
||||||
<ItDropdownSelect
|
<div class="flex flex-col gap-2 px-6">
|
||||||
v-model="state.attendanceCourseSelected"
|
<h3 class="pb-1 text-4xl font-bold">{{ $t("a.Präsenzkurs") }}</h3>
|
||||||
:items="presenceCoursesDropdownOptions ?? []"
|
<h5>Circle "{{ currentCourse?.learning_content.circle?.title }}"</h5>
|
||||||
></ItDropdownSelect>
|
<h5>{{ formattedCourseDueDate }}</h5>
|
||||||
<div
|
|
||||||
v-if="!state.attendanceSaved"
|
|
||||||
class="flex flex-row flex-wrap items-center space-y-2 md:space-y-0"
|
|
||||||
>
|
|
||||||
<ItCheckbox
|
|
||||||
:checkbox-item="{
|
|
||||||
value: true,
|
|
||||||
checked: state.disclaimerConfirmed,
|
|
||||||
}"
|
|
||||||
@toggle="state.disclaimerConfirmed = !state.disclaimerConfirmed"
|
|
||||||
></ItCheckbox>
|
|
||||||
<p class="w-64 pr-4 text-sm">
|
|
||||||
{{
|
|
||||||
$t(
|
|
||||||
"Ich will die Anwesenheit der untenstehenden Personen definitiv bestätigen."
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
</p>
|
|
||||||
<button
|
|
||||||
class="btn-primary"
|
|
||||||
:disabled="!state.disclaimerConfirmed"
|
|
||||||
@click="onSubmit"
|
|
||||||
>
|
|
||||||
{{ $t("Anwesenheit bestätigen") }}
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="self-center">
|
<div class="px-6">
|
||||||
<p class="text-base">
|
<AttendanceStatus
|
||||||
{{ $t("a.Die Anwesenheit wurde definitiv bestätigt") }}
|
class="px-6"
|
||||||
</p>
|
:done="attendanceSaved"
|
||||||
<button class="btn-link link" @click="editAgain()">
|
:date="courseDueDate"
|
||||||
{{ $t("a.Erneut bearbeiten") }}
|
/>
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<AttendanceCheck
|
||||||
|
:attendance-saved="attendanceSaved"
|
||||||
|
:disclaimer-confirmed="disclaimerConfirmed"
|
||||||
|
@reopen="editAgain"
|
||||||
|
@toggle="toggleDisclaimer"
|
||||||
|
@confirm="onSubmit"
|
||||||
|
/>
|
||||||
|
|
||||||
<div class="mt-4 flex flex-col bg-white p-6">
|
<div class="border-t border-gray-500 px-6">
|
||||||
<div
|
|
||||||
v-for="(csu, index) in courseSessionDetailResult.filterMembers()"
|
|
||||||
:key="csu.user_id"
|
|
||||||
>
|
|
||||||
<ItPersonRow
|
<ItPersonRow
|
||||||
|
v-for="(csu, index) in courseSessionDetailResult.filterMembers()"
|
||||||
|
:key="csu.user_id"
|
||||||
:name="`${csu.first_name} ${csu.last_name}`"
|
:name="`${csu.first_name} ${csu.last_name}`"
|
||||||
:avatar-url="csu.avatar_url"
|
:avatar-url="csu.avatar_url"
|
||||||
:class="0 === index ? 'border-none' : ''"
|
:class="0 === index ? 'border-none' : ''"
|
||||||
|
|
@ -233,16 +211,13 @@ watch(
|
||||||
>
|
>
|
||||||
<template #leading>
|
<template #leading>
|
||||||
<ItCheckbox
|
<ItCheckbox
|
||||||
:disabled="state.attendanceSaved"
|
:disabled="attendanceSaved"
|
||||||
:checkbox-item="{
|
:checkbox-item="{
|
||||||
value: true,
|
value: true,
|
||||||
checked: state.userPresence.get(csu.user_id) as boolean,
|
checked: userPresence.get(csu.user_id) as boolean,
|
||||||
}"
|
}"
|
||||||
@toggle="
|
@toggle="
|
||||||
state.userPresence.set(
|
userPresence.set(csu.user_id, !userPresence.get(csu.user_id))
|
||||||
csu.user_id,
|
|
||||||
!state.userPresence.get(csu.user_id)
|
|
||||||
)
|
|
||||||
"
|
"
|
||||||
></ItCheckbox>
|
></ItCheckbox>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import ItCheckbox from "@/components/ui/ItCheckbox.vue";
|
||||||
|
export interface Props {
|
||||||
|
attendanceSaved: boolean;
|
||||||
|
disclaimerConfirmed: boolean;
|
||||||
|
}
|
||||||
|
defineProps<Props>();
|
||||||
|
defineEmits(["toggle", "reopen", "confirm"]);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div v-if="!attendanceSaved" class="flex flex-col gap-4 px-6">
|
||||||
|
<div class="flex flex-row content-center items-center">
|
||||||
|
<ItCheckbox
|
||||||
|
:checkbox-item="{
|
||||||
|
value: true,
|
||||||
|
checked: disclaimerConfirmed,
|
||||||
|
}"
|
||||||
|
@toggle="$emit('toggle', !disclaimerConfirmed)"
|
||||||
|
></ItCheckbox>
|
||||||
|
<p class="text-sm">
|
||||||
|
{{
|
||||||
|
$t(
|
||||||
|
"Ich will die Anwesenheit der untenstehenden Personen definitiv bestätigen."
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
class="btn-primary w-64"
|
||||||
|
:disabled="!disclaimerConfirmed"
|
||||||
|
@click="$emit('confirm')"
|
||||||
|
>
|
||||||
|
{{ $t("Anwesenheit bestätigen") }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div v-else class="px-6">
|
||||||
|
<p class="text-base">
|
||||||
|
{{ $t("a.Die Anwesenheit wurde definitiv bestätigt") }}
|
||||||
|
</p>
|
||||||
|
<button class="btn-link link" @click="$emit('reopen')">
|
||||||
|
{{ $t("a.Erneut bearbeiten") }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
@ -68,7 +68,7 @@ const text = computed(() => {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="space-between flex flex-row items-center gap-1 rounded py-1 pl-2 pr-4"
|
class="space-between inline-flex flex-row items-center gap-1 rounded py-1 pl-2 pr-4"
|
||||||
:class="style"
|
:class="style"
|
||||||
>
|
>
|
||||||
<component :is="icon" class="h-7 w-7" />
|
<component :is="icon" class="h-7 w-7" />
|
||||||
|
|
|
||||||
|
|
@ -1,50 +1,15 @@
|
||||||
import { useCourseData } from "@/composables";
|
import { useCourseData, useCourseSessionDetailQuery } from "@/composables";
|
||||||
|
import type { CourseSessionAttendanceCourseObjectType } from "@/gql/graphql";
|
||||||
import { useUserStore } from "@/stores/user";
|
import { useUserStore } from "@/stores/user";
|
||||||
import type { CircleLight, CourseSessionUser, ExpertSessionUser } from "@/types";
|
import type { CircleLight, CourseSessionUser, ExpertSessionUser } from "@/types";
|
||||||
import log from "loglevel";
|
import log from "loglevel";
|
||||||
import { defineStore } from "pinia";
|
import { defineStore } from "pinia";
|
||||||
|
import { computed, ref } from "vue";
|
||||||
|
|
||||||
type CircleExpertCockpit = CircleLight & {
|
type CircleExpertCockpit = CircleLight & {
|
||||||
name: string;
|
name: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ExpertCockpitStoreState = {
|
|
||||||
courseSessionMembers: CourseSessionUser[] | undefined;
|
|
||||||
circles: CircleExpertCockpit[] | undefined;
|
|
||||||
currentCircle: CircleExpertCockpit | undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useExpertCockpitStore = defineStore({
|
|
||||||
id: "expertCockpit",
|
|
||||||
state: () => {
|
|
||||||
return {
|
|
||||||
courseSessionMembers: undefined,
|
|
||||||
circles: [],
|
|
||||||
currentCircle: undefined,
|
|
||||||
} as ExpertCockpitStoreState;
|
|
||||||
},
|
|
||||||
actions: {
|
|
||||||
async loadCircles(
|
|
||||||
courseSlug: string,
|
|
||||||
currentCourseSessionUser: CourseSessionUser | undefined
|
|
||||||
) {
|
|
||||||
log.debug("loadCircles called", courseSlug);
|
|
||||||
|
|
||||||
this.circles = await courseCircles(courseSlug, currentCourseSessionUser);
|
|
||||||
|
|
||||||
if (this.circles?.length) {
|
|
||||||
await this.setCurrentCourseCircle(this.circles[0].slug);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async setCurrentCourseCircle(circleSlug: string) {
|
|
||||||
this.currentCircle = this.circles?.find((c) => c.slug === circleSlug);
|
|
||||||
},
|
|
||||||
async setCurrentCourseCircleFromEvent(event: CircleLight) {
|
|
||||||
await this.setCurrentCourseCircle(event.slug);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
async function courseCircles(
|
async function courseCircles(
|
||||||
courseSlug: string,
|
courseSlug: string,
|
||||||
currentCourseSessionUser: CourseSessionUser | undefined
|
currentCourseSessionUser: CourseSessionUser | undefined
|
||||||
|
|
@ -74,3 +39,57 @@ async function courseCircles(
|
||||||
|
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ExpertCockpitStoreState = {
|
||||||
|
courseSessionMembers: CourseSessionUser[] | undefined;
|
||||||
|
circles: CircleExpertCockpit[] | undefined;
|
||||||
|
currentCircle: CircleExpertCockpit | undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useExpertCockpitStore = defineStore("expertCockpit", () => {
|
||||||
|
const courseSessionMembers = ref<CourseSessionUser[] | undefined>(undefined);
|
||||||
|
const circles = ref<CircleExpertCockpit[] | undefined>([]);
|
||||||
|
const currentCircle = ref<CircleExpertCockpit | undefined>(undefined);
|
||||||
|
const courseSessionDetailResult = useCourseSessionDetailQuery();
|
||||||
|
|
||||||
|
const attendanceCourses = computed(() => {
|
||||||
|
return (
|
||||||
|
courseSessionDetailResult.courseSessionDetail.value?.attendance_courses ?? []
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const currentCourse = computed(() => {
|
||||||
|
return attendanceCourses.value.find(
|
||||||
|
(i) => i.learning_content.circle?.id == currentCircle.value?.id
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const loadCircles = async (
|
||||||
|
courseSlug: string,
|
||||||
|
currentCourseSessionUser: CourseSessionUser | undefined
|
||||||
|
) => {
|
||||||
|
log.debug("loadCircles called", courseSlug);
|
||||||
|
|
||||||
|
circles.value = await courseCircles(courseSlug, currentCourseSessionUser);
|
||||||
|
|
||||||
|
if (circles.value?.length) {
|
||||||
|
await setCurrentCourseCircle(circles.value[0].slug);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const setCurrentCourseCircle = async (circleSlug: string) => {
|
||||||
|
currentCircle.value = circles.value?.find((c) => c.slug === circleSlug);
|
||||||
|
};
|
||||||
|
const setCurrentCourseCircleFromEvent = async (event: CircleLight) => {
|
||||||
|
await setCurrentCourseCircle(event.slug);
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
courseSessionMembers,
|
||||||
|
circles,
|
||||||
|
currentCircle,
|
||||||
|
loadCircles,
|
||||||
|
currentCourse,
|
||||||
|
setCurrentCourseCircleFromEvent,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue