From 43925e3088eca46b54b5886e232057e87aa1a166 Mon Sep 17 00:00:00 2001 From: Johann Hoffmann Date: Tue, 25 Nov 2025 17:23:49 +0100 Subject: [PATCH] custom sticky css; offcanvas mobility legende; mobiltiy zusatz in seperate column; added getMobilityZusatzForUids & formatZusatz similar to digital anw mobility zusaetze; --- application/controllers/Cis/Benotungstool.php | 2 +- .../controllers/api/frontend/v1/Noten.php | 33 ++-- application/models/codex/Mobilitaet_model.php | 69 ++++++++ application/models/crm/Prestudent_model.php | 4 - .../views/CisRouterView/CisRouterView.php | 1 + application/views/templates/CISVUE-Header.php | 2 +- public/css/Cis4/Benotungstool.css | 41 +++++ public/css/Cis4/Cis.css | 17 -- public/js/components/Bootstrap/Offcanvas.js | 151 ++++++++++++++++ .../Cis/Benotungstool/Benotungstool.js | 164 +++++++++++------- system/phrasesupdate.php | 26 ++- 11 files changed, 406 insertions(+), 104 deletions(-) create mode 100644 public/css/Cis4/Benotungstool.css create mode 100644 public/js/components/Bootstrap/Offcanvas.js diff --git a/application/controllers/Cis/Benotungstool.php b/application/controllers/Cis/Benotungstool.php index 3ca3c62ef..c22ed42f3 100644 --- a/application/controllers/Cis/Benotungstool.php +++ b/application/controllers/Cis/Benotungstool.php @@ -31,7 +31,7 @@ class Benotungstool extends Auth_Controller // TODO: check if related CIS config is also loaded when being routed in Cis4 by vuerouter // TODO: check if new benotungstool should be configurable the exact same way? - + // TODO: move this to some config api? $viewData = array( 'uid'=>getAuthUID(), diff --git a/application/controllers/api/frontend/v1/Noten.php b/application/controllers/api/frontend/v1/Noten.php index 252727776..92952bb1c 100644 --- a/application/controllers/api/frontend/v1/Noten.php +++ b/application/controllers/api/frontend/v1/Noten.php @@ -59,6 +59,8 @@ class Noten extends FHCAPI_Controller $this->load->model('person/Person_model', 'PersonModel'); $this->load->model('organisation/Studienplan_model', 'StudienplanModel'); $this->load->model('crm/Student_model', 'StudentModel'); + $this->load->model('codex/Mobilitaet_model', 'MobilitaetModel'); + $this->load->model('organisation/Erhalter_model', 'ErhalterModel'); $this->load->helper('hlp_sancho_helper'); @@ -92,26 +94,24 @@ class Noten extends FHCAPI_Controller $grades = array(); $student_uids = array_map($func, $studentenData); + if(count($student_uids) > 0) { + $mobres = $this->MobilitaetModel->getMobilityZusatzForUids($student_uids); + $mobData = $this->getDataOrTerminateWithError($mobres); + + $result = $this->ErhalterModel->load(); + $erhalter = getData($result)[0]; + + $erhalter_kz = '9' . sprintf("%03s", $erhalter->erhalter_kz); + foreach($mobData as $mob) { + $grades[$mob->uid]['mobility_zusatz'] = $this->MobilitaetModel->formatZusatz($mob, $erhalter_kz); + } + } + foreach($student_uids as $uid) { $grades[$uid]['grades'] = []; $res = $this->StudentModel->load([$uid]); if(!isError($res) && hasData($res)) $student = getData($res)[0]; - - $prestudent_id = $student->prestudent_id; - - - // TODO: last class to get rid of but this one is complicated - $mobility = new mobilitaet(); - $mobility->loadPrestudent($prestudent_id); - $output = $mobility->result; - $eintrag = ''; - foreach ($output as $k) - { - if(($k->mobilitaetstyp_kurzbz == 'GS') && ($k->studiensemester_kurzbz == $sem_kurzbz)) - $eintrag = ' (d.d.)'; - } - $grades[$uid]['mobility'] = $eintrag; $result = $this->LvgesamtnoteModel->getLvGesamtNoten($lv_id, $uid, $sem_kurzbz); @@ -131,6 +131,7 @@ class Noten extends FHCAPI_Controller // send $grades reference to moodle addon // TODO: DONT LET FAULTY MOODLE TOKEN BREAK THE STARTUP + // Events::trigger( // 'getExternalGrades', // function & () use (&$grades) @@ -142,6 +143,8 @@ class Noten extends FHCAPI_Controller // 'stsem' => $sem_kurzbz // ] // ); + + // calculate notenvorschläge from teilnoten foreach($studentenData as $student) { diff --git a/application/models/codex/Mobilitaet_model.php b/application/models/codex/Mobilitaet_model.php index 13f966d50..107c1ebb1 100644 --- a/application/models/codex/Mobilitaet_model.php +++ b/application/models/codex/Mobilitaet_model.php @@ -11,4 +11,73 @@ class Mobilitaet_model extends DB_Model $this->dbTable = 'bis.tbl_mobilitaet'; $this->pk = 'mobilitaet_id'; } + + public function getMobilityZusatzForUids($uids) { + $qry = "SELECT distinct on(nachname, vorname, public.tbl_benutzer.person_id) uid, + tbl_mitarbeiter.mitarbeiter_uid, + tbl_note.lkt_ueberschreibbar, tbl_note.anmerkung, + tbl_mobilitaet.mobilitaetstyp_kurzbz, + (CASE WHEN bis.tbl_mobilitaet.studiensemester_kurzbz = vw_student_lehrveranstaltung.studiensemester_kurzbz THEN 1 ELSE 0 END) as doubledegree, + public.tbl_prestudent.gsstudientyp_kurzbz as ddtype, + (SELECT status_kurzbz FROM public.tbl_prestudentstatus + WHERE prestudent_id=tbl_student.prestudent_id + ORDER BY datum DESC, insertamum DESC, ext_id DESC LIMIT 1) as studienstatus + FROM + campus.vw_student_lehrveranstaltung + JOIN public.tbl_benutzer USING(uid) + JOIN public.tbl_person USING(person_id) + LEFT JOIN public.tbl_student ON(uid=student_uid) + LEFT JOIN public.tbl_mitarbeiter ON(uid=mitarbeiter_uid) + LEFT JOIN public.tbl_studentlehrverband USING(student_uid,studiensemester_kurzbz) + LEFT JOIN lehre.tbl_zeugnisnote on(vw_student_lehrveranstaltung.lehrveranstaltung_id=tbl_zeugnisnote.lehrveranstaltung_id + AND tbl_zeugnisnote.student_uid=tbl_student.student_uid + AND tbl_zeugnisnote.studiensemester_kurzbz=tbl_studentlehrverband.studiensemester_kurzbz) + LEFT JOIN lehre.tbl_note USING (note) + LEFT JOIN bis.tbl_bisio ON(uid=tbl_bisio.student_uid) + LEFT JOIN public.tbl_studiengang ON(tbl_student.studiengang_kz=tbl_studiengang.studiengang_kz) + LEFT JOIN bis.tbl_mobilitaet USING(prestudent_id) + LEFT JOIN public.tbl_prestudent USING(prestudent_id) + WHERE uid IN ?"; + + return $this->execReadOnlyQuery($qry, [$uids]); + } + + public function formatZusatz($entry, $erhalter_kz) { + $zusatz = ''; + + if (isset($entry->studienstatus) && $entry->studienstatus === 'Incoming') { + $zusatz = '(i)'; + } + + if (isset($entry->lkt_ueberschreibbar) && $entry->lkt_ueberschreibbar === false) { + $zusatz .= ' (' . ($entry->anmerkung ?? '') . ')'; + } + + if (isset($entry->mitarbeiter_uid) && $entry->mitarbeiter_uid !== null) { + $zusatz .= ' (ma)'; + } + + if (isset($entry->stg_kz_student) && $entry->stg_kz_student == $erhalter_kz) { + $zusatz .= ' (a.o.)'; + } + + if ( + isset($entry->mobilitaetstyp_kurzbz) && $entry->mobilitaetstyp_kurzbz && + isset($entry->doubledegree) && $entry->doubledegree === 1 + ) { + $zusatz .= ' (d.d.'; + + $ddtype = $entry->ddtype ?? null; + + if ($ddtype == 'Intern') { + $zusatz .= 'i.)'; + } elseif ($ddtype == 'Extern') { + $zusatz .= 'o.)'; + } else { + $zusatz .= ')'; + } + } + + return $zusatz; + } } diff --git a/application/models/crm/Prestudent_model.php b/application/models/crm/Prestudent_model.php index 678d3d022..ad5c3e141 100644 --- a/application/models/crm/Prestudent_model.php +++ b/application/models/crm/Prestudent_model.php @@ -898,8 +898,4 @@ class Prestudent_model extends DB_Model return true; } - - public function getMobilityPrestudent(){ - - } } diff --git a/application/views/CisRouterView/CisRouterView.php b/application/views/CisRouterView/CisRouterView.php index b181a3c76..742c7ad8d 100644 --- a/application/views/CisRouterView/CisRouterView.php +++ b/application/views/CisRouterView/CisRouterView.php @@ -24,6 +24,7 @@ $includesArray = array( 'public/css/components/FormUnderline.css', 'public/css/Cis4/Cms.css', 'public/css/Cis4/Studium.css', + 'public/css/Cis4/Benotungstool.css' ), 'customJSs' => array( 'vendor/npm-asset/primevue/accordion/accordion.min.js', diff --git a/application/views/templates/CISVUE-Header.php b/application/views/templates/CISVUE-Header.php index 358fc75c9..804a43821 100644 --- a/application/views/templates/CISVUE-Header.php +++ b/application/views/templates/CISVUE-Header.php @@ -36,4 +36,4 @@ $this->load->view('templates/FHC-Header', $includesArray); > -
\ No newline at end of file +
\ No newline at end of file diff --git a/public/css/Cis4/Benotungstool.css b/public/css/Cis4/Benotungstool.css new file mode 100644 index 000000000..45b17d019 --- /dev/null +++ b/public/css/Cis4/Benotungstool.css @@ -0,0 +1,41 @@ +/* 1. Stick the Header */ +#notentable .tabulator-header .tabulator-col.sticky-col { + position: sticky; + left: 0; + z-index: 10; /* Must be higher than other headers */ + background-color: #fff; /* Opaque background is required */ + border-right: 2px solid #ddd; /* Optional: Separator line */ +} + +/* 2. Stick the Data Cells */ +#notentable .tabulator-tableholder .tabulator-row .tabulator-cell.sticky-col { + position: sticky; + left: 0; + z-index: 10; /* Ensure it floats above other cells */ + background-color: #fff; /* Match your row background color */ + border-right: 2px solid #ddd; /* Optional: Separator line */ +} + +/* 3. Fix for Hover Effects (Optional) */ +/* If you use hover rows, you need to ensure the sticky cell matches the hover color */ +#notentable .tabulator-row:hover .tabulator-cell.sticky-col { + background-color: #ccc; /* Match your existing hover color */ +} + + +/* styling for editable dropdown column of notenvorschläge in benotungstool*/ +#notentable .tabulator-tableholder .tabulator-editable { + position: relative; + background-color: rgba(255, 255, 157, 0.73); + cursor: pointer; +} + +#notentable .tabulator-tableholder .tabulator-editable::after { + content: "▾"; + position: absolute; + right: 6px; + color: rgba(176, 176, 106, 0.73);; + font-size: x-large; + bottom: 6px; + pointer-events: none; +} \ No newline at end of file diff --git a/public/css/Cis4/Cis.css b/public/css/Cis4/Cis.css index 7237a4739..ff1b181dd 100644 --- a/public/css/Cis4/Cis.css +++ b/public/css/Cis4/Cis.css @@ -854,21 +854,4 @@ html { #cis-main .modal-footer { background-color: var(--fhc-secondary); -} - -/* styling for editable dropdown column of notenvorschläge in benotungstool*/ -#notentable .tabulator-tableholder .tabulator-editable { - position: relative; - background-color: rgba(255, 255, 157, 0.73); - cursor: pointer; -} - -#notentable .tabulator-tableholder .tabulator-editable::after { - content: "▾"; - position: absolute; - right: 6px; - color: rgba(176, 176, 106, 0.73);; - font-size: x-large; - bottom: 6px; - pointer-events: none; } \ No newline at end of file diff --git a/public/js/components/Bootstrap/Offcanvas.js b/public/js/components/Bootstrap/Offcanvas.js new file mode 100644 index 000000000..461d80821 --- /dev/null +++ b/public/js/components/Bootstrap/Offcanvas.js @@ -0,0 +1,151 @@ +export default { + name: 'BootstrapOffcanvas', + data: () => ({ + offcanvas: null + }), + props: { + backdrop: { + type: [Boolean, String], + default: true, + validator(value) { + return ['static', true, false].includes(value); + } + }, + keyboard: { + type: Boolean, + default: true + }, + scroll: { + type: Boolean, + default: false + }, + placement: { + type: String, + default: 'start', // start | end | top | bottom + validator(value) { + return ['start', 'end', 'top', 'bottom'].includes(value); + } + }, + noCloseBtn: Boolean, + headerClass: { + type: [String, Array, Object], + default: '' + }, + bodyClass: { + type: [String, Array, Object], + default: 'p-4' + }, + footerClass: { + type: [String, Array, Object], + default: '' + }, + dialogClass: [String, Array, Object] + }, + emits: [ + "hideBsOffcanvas", + "hiddenBsOffcanvas", + "hidePreventedBsOffcanvas", + "showBsOffcanvas", + "shownBsOffcanvas" + ], + methods: { + dispose() { + return this.offcanvas?.dispose(); + }, + hide() { + return this.offcanvas?.hide(); + }, + show(relatedTarget) { + return this.offcanvas?.show(relatedTarget); + }, + toggle() { + return this.offcanvas?.toggle(); + }, + popup(body, options, title, footer) { + const BsOffcanvas = this, + slots = {}; + + if (body !== undefined) + slots.default = () => body; + if (title !== undefined) + slots.title = () => title; + if (footer !== undefined) + slots.footer = () => footer; + + let includedPrimevue = false; + if (typeof primevue !== 'undefined') + includedPrimevue = true; + + return new Promise((resolve, reject) => { + const instance = Vue.createApp({ + name: 'OffcanvasTmpApp', + setup() { + return () => + Vue.h(BsOffcanvas, { + class: 'offcanvas-wrapper', + ref: 'offcanvas', + ...options + }, slots); + }, + mounted() { + this.$refs.offcanvas.show(); + }, + beforeUnmount() { + if (this.$refs.offcanvas) + this.$refs.offcanvas.result !== false ? resolve(this.$refs.offcanvas.result) : reject(); + }, + unmounted() { + wrapper.parentElement.removeChild(wrapper); + } + }); + const wrapper = document.createElement('div'); + + if (includedPrimevue) { + instance.use(primevue.config.default, { zIndex: { overlay: 9999 } }); + } + + import('../../plugins/Phrasen.js').then((Phrasen) => { + instance.use(Phrasen.default); + instance.mount(wrapper); + document.body.appendChild(wrapper); + }); + }); + } + }, + mounted() { + if (this.$refs.offcanvas) { + this.offcanvas = new bootstrap.Offcanvas(this.$refs.offcanvas, { + backdrop: this.backdrop, + keyboard: this.keyboard, + scroll: this.scroll + }); + } + }, + template: ` +
+
+
+ +
+ +
+ +
+ +
+ + +
+ ` +} \ No newline at end of file diff --git a/public/js/components/Cis/Benotungstool/Benotungstool.js b/public/js/components/Cis/Benotungstool/Benotungstool.js index 8f96ef298..9d0da55b5 100644 --- a/public/js/components/Cis/Benotungstool/Benotungstool.js +++ b/public/js/components/Cis/Benotungstool/Benotungstool.js @@ -3,6 +3,7 @@ import ApiLehre from "../../../api/factory/lehre.js"; import ApiNoten from "../../../api/factory/noten.js"; import ApiStudiensemester from "../../../api/factory/studiensemester.js"; import BsModal from '../../Bootstrap/Modal.js'; +import BsOffcanvas from '../../Bootstrap/Offcanvas.js'; import VueDatePicker from '../../vueDatepicker.js.php'; import LehreinheitenModule from '../../DropdownModes/LehreinheitenModule'; import MobilityLegende from '../../Mobility/Legende.js'; @@ -12,6 +13,7 @@ export const Benotungstool = { name: "Benotungstool", components: { BsModal, + BsOffcanvas, CoreFilterCmpt, MobilityLegende, Dropdown: primevue.dropdown, @@ -43,8 +45,6 @@ export const Benotungstool = { data() { return { neuesPruefungsdatumModalVisible: false, - offsetLeft: 0, - headerEl: null, loading: false, selectedUids: [], // shared selection state selectedLehreinheit: null, @@ -116,6 +116,17 @@ export const Benotungstool = { row.reformat() // trigger reformat of arrow } } + }, + { + event: "cellClick", + handler: async (e, cell) => { + const field = cell.getField() + + if(field == "mobility_zusatz") { + this.$refs.drawer.show() + e.stopPropagation() + } + } } ]}; }, @@ -258,7 +269,12 @@ export const Benotungstool = { this.loading = true this.$api.call(ApiNoten.saveNotenvorschlagBulk(this.lv_id, this.sem_kurzbz, notenbulk)).then(res => { if(res.meta.status === 'success') { - this.$fhcAlert.alertSuccess(this.$p.t('benotungstool/notenImportSuccessAlert')) + this.$fhcAlert.alertDefault( + 'success', + 'Info', + this.$p.t('benotungstool/notenImportSuccessAlert'), + true + ) const lvNoten = res.data @@ -289,7 +305,12 @@ export const Benotungstool = { this.$api.call(ApiNoten.saveStudentPruefungBulk(this.lv_id, this.sem_kurzbz, pruefungenbulk)) .then((res)=> { if(res.meta.status === 'success') { - this.$fhcAlert.alertSuccess(this.$p.t('benotungstool/pruefungImportSuccessAlert')) + this.$fhcAlert.alertDefault( + 'success', + 'Info', + this.$p.t('benotungstool/pruefungImportSuccessAlert'), + true + ) this.handleAddNewPruefungenResponse(res, pruefungenbulk) } }).finally(()=>{this.loading = false}) @@ -426,8 +447,8 @@ export const Benotungstool = { }, getNotenTableOptions() { return { - rowHeight: 40, height: 700, + virtualDom: false, index: 'uid', layout: 'fitDataStretch', placeholder: this.$p.t('global/noDataAvailable'), @@ -442,6 +463,7 @@ export const Benotungstool = { return true; // student can be selected to add pruefung }, + rowHeight: 40, rowFormatter: this.fixTabulatorSelectionFormatter, columns: [ { @@ -488,13 +510,15 @@ export const Benotungstool = { handleClick: this.selectAllHandler }, width: 50, - }, - {title: Vue.computed(() => this.$p.t('benotungstool/c4mail')), field: 'email', formatter: this.mailFormatter, tooltip: false, widthGrow: 1}, - {title: Vue.computed(() => this.$p.t('benotungstool/c4antrittCount')), field: 'hoechsterAntritt', tooltip: false, widthGrow: 1}, - {title: 'UID', field: 'uid', tooltip: false, widthGrow: 1, topCalc: this.sumCalcFunc}, + cssClass: 'sticky-col' + }, + {title: 'UID', field: 'uid', tooltip: false, widthGrow: 1, topCalc: this.sumCalcFunc, cssClass: 'sticky-col'}, + {title: Vue.computed(() => this.$p.t('benotungstool/c4mail')), field: 'email', formatter: this.mailFormatter, tooltip: false, visible: false, widthGrow: 1, variableHeight: true}, + {title: Vue.computed(() => this.$p.t('benotungstool/c4antrittCountv2')), field: 'hoechsterAntritt', tooltip: false, widthGrow: 1}, {title: Vue.computed(() => this.$p.t('benotungstool/c4vorname')), field: 'vorname', headerFilter: true, tooltip: false, widthGrow: 1}, - {title: Vue.computed(() => this.$p.t('benotungstool/c4nachname')), field: 'nachname', headerFilter: true, widthGrow: 1}, - {title: Vue.computed(() => this.$p.t('benotungstool/c4teilnoten')), field: 'teilnote', widthGrow: 1, formatter: this.teilnotenFormatter}, + {title: Vue.computed(() => this.$p.t('benotungstool/c4nachname')), field: 'nachname', headerFilter: true, widthGrow: 1}, + {title: Vue.computed(() => this.$p.t('benotungstool/c4mobility')), field: 'mobility_zusatz', headerFilter: true, widthGrow: 1, visible: false}, + {title: Vue.computed(() => this.$p.t('benotungstool/c4teilnoten')), field: 'teilnote', widthGrow: 1, formatter: this.teilnotenFormatter, variableHeight: true}, {title: Vue.computed(() => this.$p.t('benotungstool/c4note')), field: 'note_vorschlag', editor: 'list', editorParams: (cell) => { @@ -531,8 +555,9 @@ export const Benotungstool = { 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}, - {title: '', width: 50, hozAlign: 'center', formatter: this.arrowFormatter, cellClick: this.saveNote}, + widthGrow: 1 + }, + {title: '', width: 50, hozAlign: 'center', formatter: this.arrowFormatter, cellClick: this.saveNote, variableHeight: true}, {title: Vue.computed(() => this.$p.t('benotungstool/c4lvnote')), field: 'lv_note', formatter: this.notenFormatter, headerFilter: 'list', @@ -540,8 +565,9 @@ export const Benotungstool = { 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}, - {title: Vue.computed(() => this.$p.t('benotungstool/c4freigabe')), field: 'freigegeben', widthGrow: 1, formatter: this.freigabeFormatter}, + widthGrow: 1 + }, + {title: Vue.computed(() => this.$p.t('benotungstool/c4freigabe')), field: 'freigegeben', widthGrow: 1, formatter: this.freigabeFormatter, variableHeight: true}, {title: Vue.computed(() => this.$p.t('benotungstool/c4zeugnisnote')), field: 'note', formatter: this.notenFormatter, @@ -552,13 +578,15 @@ export const Benotungstool = { 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}, + widthGrow: 1 + }, {title: Vue.computed(() => this.$p.t('benotungstool/c4kommPruef')), field: 'kommPruef', widthGrow: 1, formatter: this.pruefungFormatter, topCalc: this.terminCalcFunc, topCalcFormatter: this.terminCalcFormatter, - hozAlign:"center", minWidth: 150} + hozAlign:"center", minWidth: 150, visible: false + } ], persistence: false, } @@ -701,14 +729,16 @@ export const Benotungstool = { freigabeFormatter(cell) { const value = cell.getValue() + let style = 'display: flex; justify-content: center; align-items: center; height: 100%;' + if(value === 'ok') { - return '
' + + return '
' + '
' } else if (value === 'offen') { - return '
' + + return '
' + '
' } else if (value === 'changed') { - return '
' + + return '
' + '
' } @@ -741,11 +771,14 @@ export const Benotungstool = { }, teilnotenFormatter(cell) { const val = cell.getValue() - return '
'+val+'
' + + let style = 'white-space: pre-line;' + + return '
'+val+'
' }, pruefungFormatter(cell) { const data = cell.getData() - + const noteDef = data.note ? this.notenOptions.find(n => n.note == data.note) : null if(!data.note || !noteDef?.lkt_ueberschreibbar) { return '' @@ -901,18 +934,23 @@ export const Benotungstool = { const row = cell.getRow() const data = row.getData() + let style = 'display: flex; justify-content: center; align-items: center; height: 100%;' + if(!data.note_vorschlag || (data.note_vorschlag == data.lv_note)) { // uncolored arrow - return '
' + + return '
' + '
' } // can save a notenvorschlag -> colored - return '
' + + return '
' + '
' }, mailFormatter(cell) { const val = cell.getValue() - return '
' + + + let style = 'display: flex; justify-content: center; align-items: center; height: 100%;' + + return '
' + '
' }, buildMailToLink(student){ @@ -999,7 +1037,7 @@ export const Benotungstool = { const grades = this.teilnoten[s.uid].grades s.teilnote = '' - + s.mobility_zusatz = this.teilnoten[s.uid].mobility_zusatz grades.forEach(g => { const notenOption = this.notenOptions.find(n=>n.note == g.grade) if(notenOption.positiv) s.teilnote += (''+g.text +''+ '
') @@ -1121,29 +1159,8 @@ export const Benotungstool = { this.tableBuiltPromise = new Promise(this.tableResolve) await this.tableBuiltPromise - this.headerEl = document.getElementById('nav-main') - if(this.headerEl) { - this.headerEl.addEventListener("shown.bs.collapse", this.handleSidebar); - this.headerEl.addEventListener("hidden.bs.collapse", this.handleSidebar); - this.handleSidebar() - } - - - - this.loadNoten(this.lv_id, this.sem_kurzbz) - // this.calcMaxTableHeight() - - }, - handleSidebar() { - // this.$refs.notenTable.tabulator.blockRedraw(); // stop automatic resizes - - this.offsetLeft = this.headerEl.getBoundingClientRect().width; - - // setTimeout(() => { - // this.$refs.notenTable.tabulator.restoreRedraw(); // re-enable - // this.$refs.notenTable.tabulator.redraw(true); // manual recalculation - // }, 400); // after animation finishes + this.calcMaxTableHeight() }, lvChanged(e) { @@ -1233,8 +1250,12 @@ export const Benotungstool = { typ )).then(res => { if(res.meta.status === 'success') { //'Prüfung für Student ' + this.pruefungStudent.uid + ' bearbeitet oder angelegt' - this.$fhcAlert.alertSuccess(this.$p.t('benotungstool/pruefungSaveForUid', [this.pruefungStudent.uid])) - + this.$fhcAlert.alertDefault( + 'success', + 'Info', + this.$p.t('benotungstool/pruefungSaveForUid', [this.pruefungStudent.uid]), + true + ) const s = this.studenten.find(s => s.uid === res.data[1]?.student_uid) s.freigabedatum = this.parseDate(res.data[1]?.['freigabedatum']) @@ -1357,7 +1378,12 @@ export const Benotungstool = { this.$api.call(ApiNoten.saveStudentenNoten(this.password, this.changedNoten, this.lv_id, this.sem_kurzbz)) .then((res) => { if(res.meta.status === 'success') { - this.$fhcAlert.alertWarning('Noten gespeichert') + this.$fhcAlert.alertDefault( + 'success', + 'Info', + 'Noten gespeichert', + true + ) } res.data.forEach(d => { @@ -1416,8 +1442,12 @@ export const Benotungstool = { this.sem_kurzbz, )).then(res => { if(res.meta.status === "success") { - this.$fhcAlert.alertSuccess(this.$p.t('benotungstool/pruefungAngelegtAn', [dateStrFront])) - + this.$fhcAlert.alertDefault( + 'success', + 'Info', + this.$p.t('benotungstool/pruefungAngelegtAn', [dateStrFront]), + true + ) this.handleAddNewPruefungenResponse(res, uids) @@ -1558,13 +1588,6 @@ export const Benotungstool = { mounted() { this.setupMounted() }, - unmounted() { - if(this.headerEl) { - this.headerEl.removeEventListener("shown.bs.collapse", this.handleSidebar) - this.headerEl.removeEventListener("hidden.bs.collapse", this.handleSidebar) - this.headerEl = null - } - }, template: ` @@ -1672,6 +1695,23 @@ export const Benotungstool = { + + + + + + + +
@@ -1721,7 +1761,7 @@ export const Benotungstool = {

-
+
- - `, }; diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index 94690e340..3647ade5f 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -50698,18 +50698,18 @@ and represent the current state of research on the topic. The prescribed citatio array( 'app' => 'core', 'category' => 'benotungstool', - 'phrase' => 'c4antrittCount', + 'phrase' => 'c4antrittCountv2', 'insertvon' => 'system', 'phrases' => array( array( 'sprache' => 'German', - 'text' => 'Anzahl Prüfungsantritte', + 'text' => 'Antritte', 'description' => '', 'insertvon' => 'system' ), array( 'sprache' => 'English', - 'text' => 'Number of exam attempts', + 'text' => 'Attempts', 'description' => '', 'insertvon' => 'system' ) @@ -50735,6 +50735,26 @@ and represent the current state of research on the topic. The prescribed citatio ) ) ), + array( + 'app' => 'core', + 'category' => 'benotungstool', + 'phrase' => 'c4mobility', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Mobilität', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Mobility', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), array( 'app' => 'core', 'category' => 'benotungstool',