| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282 |
- <template>
- <table class="mt-5 w-full text-left main-table">
- <tbody>
- <tr>
- <td class="font-bold">
- <span>ECTS</span>
- </td>
- <td>
- <span>{{ module?.ects ?? "-" }}</span>
- </td>
- </tr>
- <tr>
- <td class="font-bold">
- <span>Benotung</span>
- </td>
- <td>
- <span>{{ module ? module.marksClean : "?" }}</span>
- </td>
- </tr>
- <tr v-if="(module.for_degrees?.length ?? 0) > 1">
- <td class="font-bold">
- <span>Studiengänge</span>
- </td>
- <td>
- <ul class="list-disc ml-4">
- <li
- v-for="degree in module.for_degrees"
- :key="degree"
- >
- {{ degree }}
- </li>
- </ul>
- </td>
- </tr>
- <tr v-else>
- <td class="font-bold">
- <span>Studiengang</span>
- </td>
- <td>
- <span>{{ module.for_degrees ? module.for_degrees[0] : "-" }}</span>
- </td>
- </tr>
- <tr>
- <td class="font-bold">
- <span>Detailbeschreibung</span>
- </td>
- <td>
- <a
- :href="`${URLS.ADDITIONAL_MODULE_INFORMATION}${module?.module_id}`"
- target="_blank"
- class="external-link"
- :title="
- module?.module_id === null
- ? 'Keine Modul-ID vorhanden'
- : `${SCHOOL_NAME} Modulbeschreibung`
- "
- >
- <span class="mr-2">{{ SCHOOL_NAME }}</span>
- <font-awesome-icon icon="fa-solid fa-arrow-up-right-from-square" />
- </a>
- </td>
- </tr>
- <!------------------------->
- <tr>
- <td class="font-bold">
- <span>Abgeschlossen</span>
- </td>
- <td>
- <span>{{ completionStateString }}</span>
- </td>
- </tr>
- <tr>
- <td class="font-bold">
- <span>Bisherige Versuche</span>
- </td>
- <td>
- <span>{{
- module.attemptCount > 0 ? module.attemptCount : "Keine"
- }}</span>
- </td>
- </tr>
- <tr>
- <td
- :colspan="moduleClasses.length == 0 ? 1 : 2"
- class="font-bold"
- >
- <span>Nächste Durchführungen</span>
- </td>
- <td>
- <span v-if="moduleClasses.length == 0">Keine</span>
- </td>
- </tr>
- <tr v-if="moduleClasses.length > 0">
- <td
- colspan="2"
- class="pb-5"
- >
- <CurrentModuleExecutions :module-classes="moduleClasses" />
- </td>
- </tr>
- <tr>
- <td
- class="font-bold"
- :colspan="previousClasses.length == 0 ? 1 : 2"
- >
- <button
- v-if="previousClasses.length > 0"
- class="action-button mr-2"
- :title="
- 'Vergangene Durchführungen ' +
- (showingPastClasses ? 'ausblenden' : 'einblenden')
- "
- @click="() => (showingPastClasses = !showingPastClasses)"
- >
- <font-awesome-icon
- v-if="showingPastClasses"
- icon="fa-solid fa-chevron-down"
- />
- <font-awesome-icon
- v-else
- icon="fa-solid fa-chevron-right"
- />
- </button>
- <span>Vergangene Durchführungen</span>
- <span
- v-if="previousClasses.length > 0"
- class="font-bold"
- >
- ({{ previousClasses.length }})</span>
- </td>
- <td>
- <span v-if="previousClasses.length == 0">Keine</span>
- </td>
- </tr>
- <tr v-if="previousClasses.length > 0 && showingPastClasses">
- <td
- colspan="2"
- class="pb-5"
- >
- <PreviousModuleExecutions :previous-classes="previousClasses" />
- </td>
- </tr>
- <tr>
- <td class="font-bold">
- <span>Abhängigkeiten</span>
- <div
- title="Abhängigkeiten sind teilweise sehr unklar von der Schule definiert und variieren basierend auf verschiedenen Dokumenten. Teilweise ist es nicht möglich, die Abhängigkeiten automatisch zu detektieren (keine Modulkürzel in der Abhängigkeitsbeschreibung)."
- class="mx-2 w-5 text-xs aspect-square rounded-full bg-gray-200 dark:bg-gray-400 inline-flex items-center justify-center cursor-help"
- >
- <font-awesome-icon icon="fa-solid fa-info" />
- </div>
- </td>
- <td>
- <span>{{ module ? (hasModuleDeps ? "" : "Keine") : "-" }}</span>
- </td>
- </tr>
- </tbody>
- </table>
- </template>
- <script lang="ts">
- import { PropType } from "vue";
- import {
- classesPDFLink,
- dayMap,
- toTime,
- MAX_ATTEMPT_COUNT,
- } from "../../helpers";
- import { useClassesStore } from "../../stores/classes";
- import { useLecturersStore } from "../../stores/lecturers";
- import { useModulesStore } from "../../stores/modules";
- import { usePlanningStore } from "../../stores/planning";
- import { useStateStore } from "../../stores/state";
- import { useStudenthubStore } from "../../stores/studenthub";
- import { HistoricClassEntry, Module, TaughtClass } from "../../types";
- import CurrentModuleExecutions from "./CurrentModuleExecutions.vue";
- import PreviousModuleExecutions from "./PreviousModuleExecutions.vue";
- import { URLS, SCHOOL_NAME } from "../../globals";
- export default {
- name: "ModuleInfo",
- components: { CurrentModuleExecutions, PreviousModuleExecutions },
- props: {
- module: {
- type: Object as PropType<Module>,
- required: true,
- },
- },
- setup() {
- const modulesStore = useModulesStore();
- const lecturersStore = useLecturersStore();
- const planningStore = usePlanningStore();
- const stateStore = useStateStore();
- const studenthubStore = useStudenthubStore();
- const classesStore = useClassesStore();
- return {
- modulesStore,
- lecturersStore,
- planningStore,
- stateStore,
- studenthubStore,
- classesStore,
- dayMap,
- toTime,
- classesPDFLink,
- URLS,
- SCHOOL_NAME,
- };
- },
- data() {
- return {
- showingPastClasses: false,
- };
- },
- computed: {
- hasCompletedModule(): boolean {
- return this.studenthubStore.hasCompletedModule(
- this.module?.module_id ?? null
- );
- },
- hasModuleDeps(): boolean {
- if (this.module === null) return false;
- return (
- Object.values(this.module.dependencies).reduce(
- (sum, dep) => sum + dep.length,
- 0
- ) > 0
- );
- },
- maxAttemptsReached(): boolean {
- return this.module.attemptCount >= MAX_ATTEMPT_COUNT;
- },
- moduleClasses(): TaughtClass[] {
- return this.classesStore.classesForModule(this.module.short);
- },
- previousClasses(): HistoricClassEntry[] {
- return this.modulesStore.history[this.module.short] ?? [];
- },
- completionStateString(): string {
- if (this.module.hasCompleted) return "Ja";
- if (this.module.isActive) return "In Bearbeitung";
- if (this.module.hasFailed) return "Fehlgeschlagen";
- return "Nein";
- },
- },
- };
- </script>
- <style scoped>
- @reference "../../style.css";
- .action-button {
- @apply text-center
- bg-gray-200
- hover:bg-gray-300
- active:bg-gray-400
- dark:bg-gray-600
- dark:hover:bg-gray-700
- dark:active:bg-gray-900
- rounded-sm
- cursor-pointer
- w-6
- p-0
- transition-all
- duration-200
- disabled:dark:bg-gray-600
- disabled:text-gray-500
- disabled:bg-gray-100
- disabled:pointer-events-none;
- }
- .main-table td {
- @apply py-1 align-top;
- }
- </style>
|