diff --git a/application/models/education/Lehrveranstaltung_model.php b/application/models/education/Lehrveranstaltung_model.php index 463c7bcfb..4c4dcb425 100644 --- a/application/models/education/Lehrveranstaltung_model.php +++ b/application/models/education/Lehrveranstaltung_model.php @@ -1353,7 +1353,9 @@ class Lehrveranstaltung_model extends DB_Model tbl_lehrveranstaltung.semester as lv_semester, tbl_lehrveranstaltung.bezeichnung as lv_bezeichnung, (SELECT kurzbz FROM public.tbl_mitarbeiter - WHERE mitarbeiter_uid=tbl_lehreinheitmitarbeiter.mitarbeiter_uid) as lektor + WHERE mitarbeiter_uid=tbl_lehreinheitmitarbeiter.mitarbeiter_uid) as lektor, + lehre.tbl_lehrveranstaltung.orgform_kurzbz as orgform + FROM lehre.tbl_lehreinheit JOIN lehre.tbl_lehreinheitmitarbeiter USING(lehreinheit_id) JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id) diff --git a/content/statistik/notenspiegel_erweitert.php b/content/statistik/notenspiegel_erweitert.php index 67097ed22..264324154 100644 --- a/content/statistik/notenspiegel_erweitert.php +++ b/content/statistik/notenspiegel_erweitert.php @@ -95,37 +95,37 @@ foreach ($result_student as $row) if ($uids == '') die('Es befinden sich keine Studierende in diesem Semester'); -$qry = "SELECT - lehrveranstaltung_id, bezeichnung, studiengang_kz, semester, ects - FROM - lehre.tbl_lehrveranstaltung - WHERE - lehrveranstaltung_id IN - ( - SELECT - distinct lehrveranstaltung_id - FROM - campus.vw_student_lehrveranstaltung, public.tbl_studentlehrverband - WHERE - tbl_studentlehrverband.studiengang_kz=".$db->db_add_param($studiengang_kz, FHC_INTEGER)." AND - tbl_studentlehrverband.semester=".$db->db_add_param($semester, FHC_INTEGER)." AND - vw_student_lehrveranstaltung.studiensemester_kurzbz=".$db->db_add_param($semester_aktuell)." AND - uid=student_uid AND - vw_student_lehrveranstaltung.studiensemester_kurzbz=tbl_studentlehrverband.studiensemester_kurzbz +$qry = "SELECT + lehrveranstaltung_id, bezeichnung, studiengang_kz, semester, ects + FROM + lehre.tbl_lehrveranstaltung + WHERE + lehrveranstaltung_id IN ( + SELECT + DISTINCT lehrveranstaltung_id + FROM + campus.vw_student_lehrveranstaltung + JOIN public.tbl_studentlehrverband ON(student_uid = uid) + WHERE + tbl_studentlehrverband.studiengang_kz = ".$db->db_add_param($studiengang_kz, FHC_INTEGER)." + AND tbl_studentlehrverband.semester = ".$db->db_add_param($semester, FHC_INTEGER)." + AND vw_student_lehrveranstaltung.studiensemester_kurzbz = ".$db->db_add_param($semester_aktuell)." + AND vw_student_lehrveranstaltung.studiensemester_kurzbz = tbl_studentlehrverband.studiensemester_kurzbz ) - AND studiengang_kz<>0 + AND studiengang_kz != 0 AND zeugnis - UNION - SELECT - lehrveranstaltung_id, bezeichnung, studiengang_kz, semester, ects - FROM - lehre.tbl_lehrveranstaltung JOIN lehre.tbl_zeugnisnote USING(lehrveranstaltung_id) - WHERE - tbl_lehrveranstaltung.studiengang_kz=".$db->db_add_param($studiengang_kz, FHC_INTEGER)." AND - tbl_zeugnisnote.student_uid in($uids) AND - tbl_zeugnisnote.studiensemester_kurzbz=".$db->db_add_param($semester_aktuell)." AND - zeugnis - ORDER BY bezeichnung"; + UNION + SELECT + lehrveranstaltung_id, bezeichnung, studiengang_kz, semester, ects + FROM + lehre.tbl_lehrveranstaltung + JOIN lehre.tbl_zeugnisnote USING(lehrveranstaltung_id) + WHERE + tbl_lehrveranstaltung.studiengang_kz = ".$db->db_add_param($studiengang_kz, FHC_INTEGER)." + AND tbl_zeugnisnote.student_uid IN ($uids) + AND tbl_zeugnisnote.studiensemester_kurzbz = ".$db->db_add_param($semester_aktuell)." + AND zeugnis + ORDER BY bezeichnung"; if (!$result_lva = $db->db_query($qry)) die('Fehler beim Ermitteln der Lehrveranstaltungen'); @@ -338,6 +338,10 @@ if ($typ == 'xls') } $anzahl_lvspalten = $spalte - 2; + $worksheet->write($zeile, ++$spalte, 'ECTS Summe zugeteilt', $format_bold); + $maxlength[$spalte] = 20; + $worksheet->write($zeile, ++$spalte, 'ECTS Summe gewichtet', $format_bold); + $maxlength[$spalte] = 20; $worksheet->write($zeile, ++$spalte, 'Notendurchschnitt', $format_bold); $maxlength[$spalte] = 15; $worksheet->write($zeile, ++$spalte, "Gewichteter\nNotendurchschnitt", $format_bold_wrap); @@ -372,9 +376,12 @@ if ($typ == 'xls') $worksheet->write($zeile, ++$spalte, $row_student->gruppe, $format_bold_left); $worksheet->write($zeile, ++$spalte, $row_student->matrikelnr, $format_bold); - //Alle Zeugnisnoten des Studierenden holen + // Alle Zeugnisnoten des Studierenden holen $noten = array(); - $qry = "SELECT * FROM lehre.tbl_zeugnisnote WHERE student_uid=".$db->db_add_param($row_student->uid)." AND studiensemester_kurzbz=".$db->db_add_param($semester_aktuell); + $qry = "SELECT lehrveranstaltung_id, note + FROM lehre.tbl_zeugnisnote + WHERE student_uid = ".$db->db_add_param($row_student->uid)." + AND studiensemester_kurzbz = ".$db->db_add_param($semester_aktuell); if ($result = $db->db_query($qry)) while ($row = $db->db_fetch_object($result)) $noten[$row->lehrveranstaltung_id] = $row->note; @@ -382,15 +389,16 @@ if ($typ == 'xls') //Zu jeder Lehrveranstaltungsnote Prüfungstyp (Anzahl der Antritte) holen $pruefungstypen = array(); $qry = "SELECT tbl_lehrveranstaltung.lehrveranstaltung_id, pruefungstyp_kurzbz, sort, datum - FROM - lehre.tbl_pruefung - JOIN - lehre.tbl_lehreinheit using(lehreinheit_id) - JOIN - lehre.tbl_lehrveranstaltung using(lehrveranstaltung_id) - WHERE - student_uid=".$db->db_add_param($row_student->uid)." AND studiensemester_kurzbz=".$db->db_add_param($semester_aktuell)." - ORDER BY lehrveranstaltung_id, sort, datum"; + FROM + lehre.tbl_pruefung + JOIN + lehre.tbl_lehreinheit USING(lehreinheit_id) + JOIN + lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id) + WHERE + student_uid = ".$db->db_add_param($row_student->uid)." + AND studiensemester_kurzbz = ".$db->db_add_param($semester_aktuell)." + ORDER BY lehrveranstaltung_id, sort, datum"; if ($result = $db->db_query($qry)) { while ($row = $db->db_fetch_object($result)) @@ -399,15 +407,14 @@ if ($typ == 'xls') } } - //Alle LVs holen zu denen der Studierende zugeteilt ist + // Alle LVs holen zu denen der Studierende zugeteilt ist $zugeteilte_lvs = array(); - $qry = "SELECT distinct lehrveranstaltung_id - FROM - campus.vw_student_lehrveranstaltung - WHERE - uid=".$db->db_add_param($row_student->uid)." AND - studiensemester_kurzbz=".$db->db_add_param($semester_aktuell); - + $qry = "SELECT DISTINCT lehrveranstaltung_id + FROM + campus.vw_student_lehrveranstaltung + WHERE + uid = ".$db->db_add_param($row_student->uid)." + AND studiensemester_kurzbz = ".$db->db_add_param($semester_aktuell); if ($result = $db->db_query($qry)) while ($row = $db->db_fetch_object($result)) $zugeteilte_lvs[] = $row->lehrveranstaltung_id; @@ -416,17 +423,20 @@ if ($typ == 'xls') $summe = 0; $rowcount = 0; $summeects = 0; + $total_ects = 0; $gewichtetenote = 0; while ($rowcount < $db->db_num_rows($result_lva)) { $row_lva = $db->db_fetch_object($result_lva, $rowcount); $rowcount++; + //wenn es eine Note gibt if (isset($noten[$row_lva->lehrveranstaltung_id])) { $note = $noten[$row_lva->lehrveranstaltung_id]; $format = 0; + $total_ects += $row_lva->ects; //wenn für die LV der Studierende eine Nachprüfung hat (z.B. 2 Termin, kommissionelle...) if (isset($pruefungstypen[$row_lva->lehrveranstaltung_id])) @@ -472,6 +482,7 @@ if ($typ == 'xls') //Keine Note fuer diese LV vorhanden if (in_array($row_lva->lehrveranstaltung_id, $zugeteilte_lvs)) { + $total_ects += $row_lva->ects; $worksheet->write($zeile, ++$spalte, '', $format_colored_nichteingetragen); } else @@ -489,6 +500,8 @@ if ($typ == 'xls') if ($summeects != 0) $gewichtetenote /= $summeects; + $worksheet->write($zeile, ++$spalte, sprintf("%.2f", $total_ects), $format_number); + $worksheet->write($zeile, ++$spalte, sprintf("%.2f", $summeects), $format_number); $worksheet->write($zeile, ++$spalte, sprintf("%.2f", $schnitt), $format_number); $worksheet->write($zeile, ++$spalte, sprintf("%.2f", $gewichtetenote), $format_number); if ($gewichtetenote != 0) @@ -529,6 +542,8 @@ if ($typ == 'xls') $schnitt = $summe_schnitt / $anzahl_schnitt; else $schnitt = 0; + $worksheet->write($zeile, ++$spalte, '-', $format_bold_center); + $worksheet->write($zeile, ++$spalte, '-', $format_bold_center); $worksheet->write($zeile, ++$spalte, sprintf("%.2f", $schnitt), $format_number); if ($anzahlgewichtet != 0) $summegewichtet = $summegewichtet / $anzahlgewichtet; diff --git a/public/js/apps/Cis/Cis.js b/public/js/apps/Cis/Cis.js index 2896775b4..7702ffd55 100644 --- a/public/js/apps/Cis/Cis.js +++ b/public/js/apps/Cis/Cis.js @@ -101,7 +101,7 @@ const router = VueRouter.createRouter({ props: true }, { - path: `/Cis/Benotungstool/:lv_id/:sem_kurzbz`, + path: `/Cis/Benotungstool/:lv_id?/:sem_kurzbz?`, name: 'Benotungstool', component: Benotungstool, props: true diff --git a/public/js/components/Cis/Benotungstool/Benotungstool.js b/public/js/components/Cis/Benotungstool/Benotungstool.js index 8abaef7ad..0440ffba0 100644 --- a/public/js/components/Cis/Benotungstool/Benotungstool.js +++ b/public/js/components/Cis/Benotungstool/Benotungstool.js @@ -1,6 +1,7 @@ import {CoreFilterCmpt} from "../../filter/Filter.js"; import ApiLehre from "../../../api/factory/lehre.js"; import ApiNoten from "../../../api/factory/noten.js"; +import ApiAuthinfo from "../../../api/factory/authinfo.js"; import ApiStudiensemester from "../../../api/factory/studiensemester.js"; import BsModal from '../../Bootstrap/Modal.js'; import BsOffcanvas from '../../Bootstrap/Offcanvas.js'; @@ -9,7 +10,7 @@ import LehreinheitenModule from '../../DropdownModes/LehreinheitenModule.js'; import MobilityLegende from '../../Mobility/Legende.js'; import FhcOverlay from "../../Overlay/FhcOverlay.js"; import {debounce} from "../../../helpers/debounce.js"; -import {centeredFormatter} from "../../../tabulator/formatter/centered.js"; +import {centeredTextFormatter} from "../../../tabulator/formatter/centered.js"; export const Benotungstool = { name: "Benotungstool", @@ -30,25 +31,20 @@ export const Benotungstool = { props: { lv_id: { default: null, - required: true + required: false }, sem_kurzbz: { default: null, - required: true - }, - viewData: { - type: Object, - required: true, - default: () => ({uid: ''}), - validator(value) { - return value && value.uid - } + required: false } }, data() { return { + uid: null, headerFiltersRestored: false, filtersRestored: false, + filteredRows: null, + filteredcount: 0, colLayoutRestored: false, sortRestored: false, stateRestored: false, @@ -137,10 +133,32 @@ export const Benotungstool = { this.undoSelection(cell) } } + }, + { + event: 'dataFiltered', + handler: (filters, rows) => { + this.filteredRows = rows; + this.filteredcount = rows.length; + + if (!this.selectedUids.length) return; + + const visibleData = new Set(rows.map(r => r.getData())); + const filteredOut = this.selectedUids.filter(su => !visibleData.has(su)); + if (!filteredOut.length) return; + + const filteredOutSet = new Set(filteredOut); + this.$refs.notenTable.tabulator.getSelectedRows() + .filter(r => filteredOutSet.has(r.getData())) + .forEach(r => r.deselect()); + } } ]}; }, methods: { + async fetchAuthUID() { + const authIdResponse = await this.$api.call(ApiAuthinfo.getAuthUID()); + this.uid = authIdResponse.data.uid; + }, loadState() { return JSON.parse(localStorage.getItem(this.persistenceID) || "null"); }, @@ -724,12 +742,13 @@ export const Benotungstool = { virtualDom: true, virtualDomBuffer: 5000, index: 'uid', - layout: 'fitDataStretch', + layout: 'fitData', placeholder: this.$capitalize(this.$p.t('global/noDataAvailable')), selectable: true, selectableRangeMode: "click", // shift+click selectablePersistence: false, // reset selection on table reload selectableCheck: this.selectableCheck, + rowHeight: 30, rowFormatter: this.fixTabulatorSelectionFormatter, columns: this.getColumnsDefinition(), persistence: false, @@ -797,18 +816,18 @@ export const Benotungstool = { field: 'selectCol', title: '' }) - columns.push({title: 'UID', field: 'uid', tooltip: false, widthGrow: 1, topCalc: this.sumCalcFunc, formatter: centeredFormatter, cssClass: 'sticky-col'}) - columns.push({title: Vue.computed(() => this.$capitalize(this.$p.t('benotungstool/c4mail'))), field: 'email', formatter: this.mailFormatter, tooltip: false, visible: false, widthGrow: 1, variableHeight: true}) - columns.push({title: Vue.computed(() => this.$capitalize(this.$p.t('benotungstool/c4antrittCountv2'))), field: 'hoechsterAntritt', formatter: centeredFormatter, tooltip: false, widthGrow: 1}) - columns.push({title: Vue.computed(() => this.$capitalize(this.$p.t('benotungstool/c4vorname'))), field: 'vorname', formatter: centeredFormatter, headerFilter: true, tooltip: false, widthGrow: 1}) - columns.push({title: Vue.computed(() => this.$capitalize(this.$p.t('benotungstool/c4nachname'))), field: 'nachname', formatter: centeredFormatter, headerFilter: true, widthGrow: 1}) - columns.push({title: Vue.computed(() => this.$capitalize(this.$p.t('benotungstool/c4anwesenheitsquote'))), field: 'anwquote', widthGrow: 1, formatter: this.percentFormatter}) - columns.push({title: Vue.computed(() => this.$capitalize(this.$p.t('benotungstool/c4mobility'))), field: 'mobility_zusatz', formatter: centeredFormatter, headerFilter: true, widthGrow: 1, visible: false}) + columns.push({title: 'UID', field: 'uid', tooltip: false, topCalc: this.sumCalcFunc, formatter: centeredTextFormatter, cssClass: 'sticky-col'}) + columns.push({title: Vue.computed(() => this.$capitalize(this.$p.t('benotungstool/c4mail'))), field: 'email', formatter: this.mailFormatter, tooltip: false, visible: false, variableHeight: true}) + columns.push({title: Vue.computed(() => this.$capitalize(this.$p.t('benotungstool/c4antrittCountv2'))), field: 'hoechsterAntritt', formatter: centeredTextFormatter, tooltip: false}) + columns.push({title: Vue.computed(() => this.$capitalize(this.$p.t('benotungstool/c4vorname'))), field: 'vorname', formatter: centeredTextFormatter, headerFilter: true, tooltip: false}) + columns.push({title: Vue.computed(() => this.$capitalize(this.$p.t('benotungstool/c4nachname'))), field: 'nachname', formatter: centeredTextFormatter, headerFilter: true}) + columns.push({title: Vue.computed(() => this.$capitalize(this.$p.t('benotungstool/c4anwesenheitsquote'))), field: 'anwquote', formatter: this.percentFormatter}) + columns.push({title: Vue.computed(() => this.$capitalize(this.$p.t('benotungstool/c4mobility'))), field: 'mobility_zusatz', formatter: centeredTextFormatter, headerFilter: true, visible: false}) if(this.config?.CIS_GESAMTNOTE_PRUEFUNG_MOODLE_LE_NOTE) { - columns.push({title: Vue.computed(() => this.$capitalize(this.$p.t('benotungstool/c4teilnoten'))), field: 'teilnote', widthGrow: 1, formatter: this.teilnotenFormatter, variableHeight: true}) + columns.push({title: Vue.computed(() => this.$capitalize(this.$p.t('benotungstool/c4teilnoten'))), field: 'teilnote', formatter: this.teilnotenFormatter, variableHeight: true}) } if(this.config?.CIS_GESAMTNOTE_PUNKTE) { - columns.push({title: Vue.computed(() => this.$capitalize(this.$p.t('benotungstool/c4punkte'))), field: 'punkte', widthGrow: 1, + columns.push({title: Vue.computed(() => this.$capitalize(this.$p.t('benotungstool/c4punkte'))), field: 'punkte', editor: this.liveNumberEditor, editable: (cell) => { const rowData = cell.getRow().getData(); @@ -856,8 +875,7 @@ export const Benotungstool = { if(val === undefined) return '' if(p || !match?.lkt_ueberschreibbar) style = 'color: gray;font-style: italic; background-color: #f0f0f0;pointer-events: none;opacity: 0.6;user-select: none;cursor: not-allowed;' return '
' + val + '
' - }, - widthGrow: 1 + } }) columns.push({title: Vue.computed(() => this.$capitalize(this.$p.t('benotungstool/c4notenvorschlagUebernehmen'))), field: 'übernehmen', width: 150, hozAlign: 'center', formatter: this.arrowFormatter, cellClick: this.saveNote, @@ -868,10 +886,9 @@ export const Benotungstool = { headerFilterParams: () => { return { values: ["\u00A0",this.$p.t('benotungstool/c4noteEmpty') ,this.$p.t('benotungstool/c4positiv'), this.$p.t('benotungstool/c4negativ') ,...this.notenOptions.map(opt => opt.bezeichnung)] } }, - headerFilterFunc: this.notenFilterFunc, - widthGrow: 1 + headerFilterFunc: this.notenFilterFunc }) - columns.push({title: Vue.computed(() => this.$capitalize(this.$p.t('benotungstool/c4freigabe'))), field: 'freigegeben', widthGrow: 1, formatter: this.freigabeFormatter, variableHeight: true}) + columns.push({title: Vue.computed(() => this.$capitalize(this.$p.t('benotungstool/c4freigabe'))), field: 'freigegeben', formatter: this.freigabeFormatter, variableHeight: true}) columns.push({title: Vue.computed(() => this.$capitalize(this.$p.t('benotungstool/c4zeugnisnote'))), field: 'note', formatter: this.notenFormatter, @@ -881,8 +898,7 @@ export const Benotungstool = { headerFilterParams: () => { return { values: ["\u00A0", this.$p.t('benotungstool/c4noteEmpty'),this.$p.t('benotungstool/c4positiv'), this.$p.t('benotungstool/c4negativ') ,...this.notenOptions.map(opt => opt.bezeichnung)] } }, - headerFilterFunc: this.notenFilterFunc, - widthGrow: 1 + headerFilterFunc: this.notenFilterFunc }) columns.push({title: Vue.computed(() => this.$capitalize(this.$p.t('benotungstool/c4kommPruef'))), field: 'kommPruef', widthGrow: 1, @@ -918,19 +934,19 @@ export const Benotungstool = { }, selectAllHandler(e, cell) { const table = cell.getTable(); - const rows = table.getRows(); + const rows = this.filteredRows ?? table.getRows(); - // custom select all logic const allowed = rows.filter(r => r.getData().selectable); const selected = allowed.every(r => r.isSelected()); - if(selected){ + if (selected) { allowed.forEach(r => r.deselect()); + e.target.checked = false; } else { allowed.forEach(r => r.select()); + e.target.checked = true; } - // stop built-in handler e.stopPropagation(); return false; }, @@ -1031,7 +1047,7 @@ export const Benotungstool = { notenFormatter(cell) { const value = cell.getValue() const field = cell.getField() - let style = 'display: flex; justify-content: center; align-items: center; height: 100%;'; + let style = 'display: flex; justify-content: start; align-items: center; height: 100%;'; // Wenn sich die Zeugnisnote von der von Ihnen freigegebenen Note unterscheidet, // wird erstere rot umrandet markiert. @@ -1494,6 +1510,7 @@ export const Benotungstool = { this.$refs.notenTable.tabulator.redraw(true); }, loadNoten(lv_id, sem_kurzbz) { + if (!lv_id || !sem_kurzbz) return this.loading = true this.$api.call(ApiNoten.getStudentenNoten(lv_id, sem_kurzbz)) .then(res => { @@ -1515,8 +1532,21 @@ export const Benotungstool = { this.notenTableOptions.height = window.visualViewport.height - rect.top - 50 this.$refs.notenTable.tabulator.setHeight(this.notenTableOptions.height) }, + loadLehrveranstaltungen(sem_kurzbz, preselectLvId = null) { + return this.$api.call(ApiLehre.getZugewieseneLv(this.uid, sem_kurzbz)).then(res => { + this.lehrveranstaltungen = res.data + this.lehrveranstaltungen.forEach(lva => { + lva.fullString = `${lva.stg_kurzbz} - ${lva.lv_semester} - ${lva.orgform}: ${lva.lv_bezeichnung}` + }) + this.selectedLehrveranstaltung = preselectLvId + ? this.lehrveranstaltungen.find(lva => lva.lehrveranstaltung_id == preselectLvId) ?? null + : null + }) + }, async setupCreated() { this.loading = true + + await this.fetchAuthUID() this.debouncedFetchPunkteForPruefung = debounce(this.fetchNoteForPunktePruefung, 500) @@ -1524,28 +1554,33 @@ export const Benotungstool = { const configPromise = this.$api.call(ApiNoten.getCisConfig()).then(res => { this.config = res.data }) - - // fetch lva dropdown - this.$api.call(ApiLehre.getZugewieseneLv(this.viewData?.uid, this.sem_kurzbz)).then(res => { - this.lehrveranstaltungen = res.data + + this.$api.call(ApiStudiensemester.getAllStudiensemesterAndAktOrNext()).then(res => { + this.studiensemester = res.data[0] - // build dropdown option string - this.lehrveranstaltungen.forEach(lva => { - lva.fullString = `${lva.stg_kurzbz} - ${lva.lv_semester}: ${lva.lv_bezeichnung}` - }) - - this.selectedLehrveranstaltung = this.lehrveranstaltungen.find(lva => lva.lehrveranstaltung_id == this.lv_id) + let defaultSem = this.sem_kurzbz + ? this.studiensemester.find(s => s.studiensemester_kurzbz === this.sem_kurzbz) + : null + + if (!defaultSem) { + const aktOrNext = res.data[1] + let aktKurzbz = null + if (typeof aktOrNext === 'string') aktKurzbz = aktOrNext + else if (Array.isArray(aktOrNext)) aktKurzbz = aktOrNext[0]?.studiensemester_kurzbz ?? aktOrNext[0] + else if (aktOrNext && typeof aktOrNext === 'object') aktKurzbz = aktOrNext.studiensemester_kurzbz + + defaultSem = this.studiensemester.find(s => s.studiensemester_kurzbz === aktKurzbz) + } + + this.selectedSemester = defaultSem ?? this.studiensemester[0] ?? null + + const sem = this.selectedSemester?.studiensemester_kurzbz + if (sem) this.loadLehrveranstaltungen(sem, this.lv_id) }) LehreinheitenModule.setupContext(this.$.appContext.config.globalProperties) LehreinheitenModule.bindParams(Vue.ref(Vue.computed(() => this.LeDropdownParams))); - // fetch sem_kurzbz dropdown - this.$api.call(ApiStudiensemester.getStudiensemester()).then(res => { - this.studiensemester = res.data[0] - this.selectedSemester = this.studiensemester.find(sem => sem.studiensemester_kurzbz === this.sem_kurzbz) - }) - // fetch noten dropdown this.$api.call(ApiNoten.getNoten()).then(async res => { this.notenOptions = res.data @@ -1562,50 +1597,46 @@ export const Benotungstool = { async setupMounted() { this.tableBuiltPromise = new Promise(this.tableResolve) await this.tableBuiltPromise - - this.loadNoten(this.lv_id, this.sem_kurzbz) + + if (this.lv_id && this.sem_kurzbz) { + this.loadNoten(this.lv_id, this.sem_kurzbz) + } else { + this.loading = false + } this.calcMaxTableHeight() - }, lvChanged(e) { + const sem = this.selectedSemester?.studiensemester_kurzbz ?? this.sem_kurzbz this.$router.push({ name: "Benotungstool", params: { - sem_kurzbz: this.sem_kurzbz, + sem_kurzbz: sem, lv_id: e.value.lehrveranstaltung_id } }) // reload data - this.loadNoten(e.value.lehrveranstaltung_id, this.sem_kurzbz) + this.loadNoten(e.value.lehrveranstaltung_id, sem) }, ssChanged(e) { - // change url params & write history - this.$router.push({ - name: "Benotungstool", - params: { - sem_kurzbz: e.value.studiensemester_kurzbz, - lv_id: this.lv_id - } - }) + const sem = e.value.studiensemester_kurzbz + const keepLvId = this.selectedLehrveranstaltung?.lehrveranstaltung_id ?? this.lv_id this.loading = true - // diff lv_id -> reload zugewiesene lv - this.$api.call(ApiLehre.getZugewieseneLv(this.viewData?.uid, e.value.studiensemester_kurzbz)).then(res => { - this.lehrveranstaltungen = res.data + this.loadLehrveranstaltungen(sem, keepLvId).then(() => { + const lvId = this.selectedLehrveranstaltung?.lehrveranstaltung_id ?? null - // build dropdown option string - this.lehrveranstaltungen.forEach(lva => { - lva.fullString = `${lva.stg_kurzbz} - ${lva.lv_semester}: ${lva.lv_bezeichnung}` + this.$router.push({ + name: "Benotungstool", + params: { sem_kurzbz: sem, lv_id: lvId ?? undefined } }) - this.selectedLehrveranstaltung = this.lehrveranstaltungen.find(lva => lva.lehrveranstaltung_id == this.lv_id) - }).then(()=>{ - - // reload data - this.loadNoten(this.lv_id, e.value.studiensemester_kurzbz) - }).finally( () => this.loading = false) - + if (lvId) { + this.loadNoten(lvId, sem) + } else if (this.$refs.notenTable?.tabulator) { + this.$refs.notenTable.tabulator.setData([]) // no matching LV -> clear + } + }).finally(() => this.loading = false) }, getOptionLabel(option) { return option.studiensemester_kurzbz @@ -1644,6 +1675,8 @@ export const Benotungstool = { const typ = this.pruefung ? this.pruefung.pruefungstyp_kurzbz : this.getPruefungstypForStudentByAntritt(this.pruefungStudent) const note = this.selectedPruefungNote?.note ?? 9 // noch nicht eingetragen const punkte = this.selectedPruefungPunkte ?? 0 + + this.loading = true this.$api.call(ApiNoten.saveStudentPruefung( this.pruefungStudent.uid, note, @@ -1701,6 +1734,7 @@ export const Benotungstool = { }).finally(()=> { this.pruefungStudent = null this.pruefung = null + this.loading = false }) this.$refs.modalContainerPruefung.hide() @@ -1846,6 +1880,7 @@ export const Benotungstool = { }) }, saveNoteneingabe() { + this.loading = true this.$api.call(ApiNoten.saveStudentenNoten(this.password, this.changedNoten, this.lv_id, this.sem_kurzbz)) .then((res) => { if(res.meta.status === 'success') { @@ -1866,6 +1901,8 @@ export const Benotungstool = { this.changedNotenCounter++; this.$refs.notenTable.tabulator.redraw(true) + }).finally(() => { + this.loading = false }) this.$refs.modalContainerNotenSpeichern.hide() @@ -1882,9 +1919,6 @@ export const Benotungstool = { getOptionLabelNotePruefung(option) { return option.bezeichnung }, - leChanged(e) { - this.selectedLehreinheit = e.value - }, addPruefung(){ this.$refs.modalContainerNeuesPruefungsdatum.hide() @@ -2041,9 +2075,16 @@ export const Benotungstool = { }, selectedLehreinheit(newVal) { if(!this.$refs.notenTable) return - this.$refs.notenTable.tabulator.clearFilter(); + this.$refs.notenTable.tabulator.getFilters() + .filter(f => f.field === 'lehreinheit_id') + .forEach(() => table.removeFilter("lehreinheit_id", "=", undefined)) if(newVal) this.$refs.notenTable.tabulator.setFilter("lehreinheit_id", "=", newVal.lehreinheit_id); }, + selectedLehrveranstaltung(newVal, oldVal) { + if (this.selectedLehreinheit) { + this.selectedLehreinheit = null + } + }, getKommPruefCount(newVal) { if(!this.config.CIS_GESAMTNOTE_PRUEFUNG_KOMMPRUEF) return 0 if(this.$refs.notenTable?.tabulator && newVal > 0) { @@ -2056,6 +2097,16 @@ export const Benotungstool = { } }, computed: { + countsToHTML() { + return this.$p.t('global/ausgewaehlt') + + ': ' + (this.selectedUids.length || 0) + '' + + ' | ' + + this.$p.t('global/gefiltert') + + ': ' + (this.filteredcount || 0) + '' + + ' | ' + + this.$p.t('global/gesamt') + + ': ' + (this.studenten?.length || 0) + ''; + }, maxAntrittCount() { let maxAntritte = 1; @@ -2077,9 +2128,9 @@ export const Benotungstool = { }, LeDropdownParams() { return { - lv_id: this.lv_id, - sem_kurzbz: this.sem_kurzbz - } + lv_id: this.selectedLehrveranstaltung?.lehrveranstaltung_id ?? null, + sem_kurzbz: this.selectedSemester?.studiensemester_kurzbz ?? null + } }, getStudentenOptions() { return this.studenten ? this.studenten.filter(s => s.selectable) : [] @@ -2128,14 +2179,16 @@ export const Benotungstool = { this.setupMounted() }, template: ` - + - + @showBsModal="neuesPruefungsdatumModalVisible = true"> - + - + - +