132 lines
4.4 KiB
Vue
132 lines
4.4 KiB
Vue
<script setup lang="ts">
|
|
import type {
|
|
AssignmentCompletionMetricsType,
|
|
AssignmentStatisticsRecordType,
|
|
BaseStatisticsType,
|
|
StatisticsCircleDataType,
|
|
} from "@/gql/graphql";
|
|
import StatisticFilterList from "@/components/dashboard/StatisticFilterList.vue";
|
|
import { getDateString } from "@/components/dueDates/dueDatesUtils";
|
|
import dayjs from "dayjs";
|
|
import ItProgress from "@/components/ui/ItProgress.vue";
|
|
import { type Ref, ref } from "vue";
|
|
import { exportDataAsXls } from "@/utils/export";
|
|
import { exportCompetenceElements } from "@/services/dashboard";
|
|
import { useUserStore } from "@/stores/user";
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
const props = defineProps<{
|
|
courseStatistics: BaseStatisticsType;
|
|
courseSessionName: (sessionId: string) => string;
|
|
circleMeta: (circleId: string) => StatisticsCircleDataType;
|
|
detailBaseUrl?: string;
|
|
}>();
|
|
|
|
const statisticFilter: Ref<typeof StatisticFilterList | null> = ref(null);
|
|
const userStore = useUserStore();
|
|
|
|
const assignmentStats = (metrics: AssignmentCompletionMetricsType) => {
|
|
if (!metrics.ranking_completed) {
|
|
return {
|
|
SUCCESS: 0,
|
|
FAIL: 0,
|
|
UNKNOWN: 0,
|
|
};
|
|
}
|
|
|
|
return {
|
|
SUCCESS: metrics.passed_count,
|
|
FAIL: metrics.failed_count,
|
|
UNKNOWN: metrics.unranked_count,
|
|
};
|
|
};
|
|
|
|
const total = (metrics: AssignmentCompletionMetricsType) => {
|
|
return metrics.passed_count + metrics.failed_count + metrics.unranked_count;
|
|
};
|
|
|
|
async function exportData() {
|
|
if (!statisticFilter.value) {
|
|
return;
|
|
}
|
|
const filteredItems = statisticFilter.value.getFilteredItems();
|
|
await exportDataAsXls(filteredItems, exportCompetenceElements, userStore.language);
|
|
}
|
|
|
|
const itemDetailUrl = (item: AssignmentStatisticsRecordType) => {
|
|
if (props.detailBaseUrl) {
|
|
return `${props.detailBaseUrl}${item.learning_content_id}?courseSessionId=${item.course_session_id}`;
|
|
}
|
|
return item.details_url;
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<main>
|
|
<div class="mb-10 flex items-center justify-between">
|
|
<h3>{{ $t("a.Kompetenznachweis-Elemente") }}</h3>
|
|
<button v-if="true" class="flex" data-cy="export-button" @click="exportData">
|
|
<it-icon-export></it-icon-export>
|
|
<span class="ml inline-block">{{ $t("a.Als Excel exportieren") }}</span>
|
|
</button>
|
|
</div>
|
|
<div v-if="courseStatistics?.assignments.records" class="mt-8 bg-white">
|
|
<StatisticFilterList
|
|
ref="statisticFilter"
|
|
:course-session-properties="courseStatistics?.course_session_properties"
|
|
:items="courseStatistics.assignments.records"
|
|
>
|
|
<template #default="{ item }">
|
|
<div
|
|
class="flex justify-between"
|
|
:data-cy="`${(item as AssignmentStatisticsRecordType).assignment_title}@${(item as AssignmentStatisticsRecordType).course_session_id}`"
|
|
>
|
|
<div>
|
|
<h4 class="font-bold">
|
|
{{ (item as AssignmentStatisticsRecordType).assignment_title }}
|
|
</h4>
|
|
<div>
|
|
{{ $t("a.Durchfuehrung") }} «{{
|
|
courseSessionName(item.course_session_id)
|
|
}}» - Circle «{{ circleMeta(item.circle_id)?.name }}»
|
|
</div>
|
|
<div class="mt-4">
|
|
{{ $t("a.Abgabetermin") }}:
|
|
{{
|
|
getDateString(
|
|
dayjs((item as AssignmentStatisticsRecordType).deadline)
|
|
)
|
|
}}
|
|
</div>
|
|
</div>
|
|
<div class="w-72">
|
|
<div
|
|
v-if="
|
|
(item as AssignmentStatisticsRecordType).metrics.ranking_completed
|
|
"
|
|
>
|
|
{{ (item as AssignmentStatisticsRecordType).metrics.passed_count }} von
|
|
{{ total((item as AssignmentStatisticsRecordType).metrics) }}
|
|
bestanden
|
|
</div>
|
|
<div v-else>Noch nicht bestätigt</div>
|
|
<ItProgress
|
|
:status-count="
|
|
assignmentStats((item as AssignmentStatisticsRecordType).metrics)
|
|
"
|
|
></ItProgress>
|
|
<router-link
|
|
class="underline"
|
|
:to="itemDetailUrl(item as AssignmentStatisticsRecordType)"
|
|
data-cy="details-link"
|
|
>
|
|
{{ $t("a.Details anschauen") }}
|
|
</router-link>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</StatisticFilterList>
|
|
</div>
|
|
</main>
|
|
</template>
|