From 3878fce625fc5c5d3abe20797ea6151d81601a05 Mon Sep 17 00:00:00 2001 From: Johann Hoffmann Date: Wed, 5 Nov 2025 15:34:10 +0100 Subject: [PATCH] wip abgabetool; --- application/config/cis.php | 2 +- .../controllers/api/frontend/v1/Abgabe.php | 15 +- .../models/education/Projektarbeit_model.php | 2 - application/views/Cis/Abgabetool.php | 1 + .../views/CisRouterView/CisRouterView.php | 1 + public/js/api/factory/abgabe.js | 4 +- .../Cis/Abgabetool/AbgabeMitarbeiterDetail.js | 12 +- .../Cis/Abgabetool/AbgabetoolAssistenz.js | 295 ++++++++++++------ .../Cis/Abgabetool/AbgabetoolMitarbeiter.js | 3 +- .../Cis/Abgabetool/StatusLegende.js | 10 +- public/js/components/Dashboard/Item.js | 2 + public/js/plugins/Api.js | 3 +- system/phrasesupdate.php | 60 ++++ 13 files changed, 299 insertions(+), 111 deletions(-) diff --git a/application/config/cis.php b/application/config/cis.php index 8d3bc347e..430539392 100644 --- a/application/config/cis.php +++ b/application/config/cis.php @@ -4,7 +4,7 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); // CMS Content Id for CIS4 Menu Root -$config['cis_menu_root_content_id'] = 11087; +$config['cis_menu_root_content_id'] = 11091; // send Mails for ProfilUpdate $config['cis_send_profil_update_mails'] = true; // Vilesci CI BaseUrl diff --git a/application/controllers/api/frontend/v1/Abgabe.php b/application/controllers/api/frontend/v1/Abgabe.php index 3a05bd6f6..73f0d0a15 100644 --- a/application/controllers/api/frontend/v1/Abgabe.php +++ b/application/controllers/api/frontend/v1/Abgabe.php @@ -672,6 +672,7 @@ class Abgabe extends FHCAPI_Controller $paabgabetyp_kurzbz = $_POST['paabgabetyp_kurzbz']; $bezeichnung = $_POST['bezeichnung']; $kurzbz = $_POST['kurzbz']; + $fixtermin = $_POST['fixtermin']; if (!isset($projektarbeit_ids) || !is_array($projektarbeit_ids) || empty($projektarbeit_ids) || !isset($datum) || isEmptyString($datum) @@ -697,13 +698,14 @@ class Abgabe extends FHCAPI_Controller $this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel'); $res = []; + $abgaben = []; foreach ($projektarbeit_ids as $projektarbeit_id) { $result = $this->PaabgabeModel->insert( array( 'projektarbeit_id' => $projektarbeit_id, 'paabgabetyp_kurzbz' => $paabgabetyp_kurzbz, - 'fixtermin' => false, + 'fixtermin' => $fixtermin, 'datum' => $datum, 'kurzbz' => $kurzbz, 'insertvon' => getAuthUID(), @@ -711,7 +713,9 @@ class Abgabe extends FHCAPI_Controller ) ); - $data = $this->getDataOrTerminateWithError($result); + $dataAbgabe = $this->getDataOrTerminateWithError($result); + + $abgaben[]= getData($this->PaabgabeModel->load($dataAbgabe))[0]; // $res[] = $data; @@ -751,7 +755,7 @@ class Abgabe extends FHCAPI_Controller $this->logLib->logInfoDB(array('serientermin angelegt',$res, getAuthUID(), getAuthPersonId())); - $this->terminateWithSuccess($res); + $this->terminateWithSuccess(array($res, $abgaben)); } @@ -865,9 +869,6 @@ class Abgabe extends FHCAPI_Controller if (!isset($studiengang_kz) || isEmptyString($studiengang_kz)) $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general'); - // TODO revert arr return new/old -// $arr = $this->ProjektarbeitModel->getProjektarbeitenForStudiengang($studiengang_kz); -// $result = $arr[0]; $result = $this->ProjektarbeitModel->getProjektarbeitenForStudiengang($studiengang_kz); $projektarbeiten = $this->getDataOrTerminateWithError($result); @@ -904,7 +905,7 @@ class Abgabe extends FHCAPI_Controller $stg_allowed = $this->permissionlib->getSTG_isEntitledFor('basis/abgabe_assistenz:rw'); if($stg_allowed == false) { - $this->terminateWithError($this->p->t('global', 'keineBerechtigung'), 'general'); + $this->terminateWithError($this->p->t('ui', 'keineBerechtigung'), 'general'); } $this->load->model('organisation/Studiengang_model', 'StudiengangModel'); diff --git a/application/models/education/Projektarbeit_model.php b/application/models/education/Projektarbeit_model.php index 9cd28cdf8..1f35ea856 100644 --- a/application/models/education/Projektarbeit_model.php +++ b/application/models/education/Projektarbeit_model.php @@ -407,8 +407,6 @@ class Projektarbeit_model extends DB_Model LEFT JOIN public.tbl_benutzer betreuer_benutzer ON (betreuer_person.person_id = betreuer_benutzer.person_id) WHERE (projekttyp_kurzbz = 'Bachelor' OR projekttyp_kurzbz = 'Diplom') AND student_benutzer.aktiv AND (lehre.tbl_projektbetreuer.betreuerart_kurzbz = 'Erstbegutachter' OR lehre.tbl_projektbetreuer.betreuerart_kurzbz = 'Begutachter') - -- AND lehre.tbl_projektarbeit.note IS NULL - -- AND public.tbl_studiengang.studiengang_kz= 257 AND public.tbl_studiengang.studiengang_kz = ? ORDER BY tbl_projektarbeit.projektarbeit_id DESC, student_person.nachname ASC ) as tmp"; diff --git a/application/views/Cis/Abgabetool.php b/application/views/Cis/Abgabetool.php index d47f33283..422ae1087 100644 --- a/application/views/Cis/Abgabetool.php +++ b/application/views/Cis/Abgabetool.php @@ -25,6 +25,7 @@ $includesArray = array( 'vendor/npm-asset/primevue/speeddial/speeddial.min.js', 'vendor/npm-asset/primevue/textarea/textarea.min.js', 'vendor/npm-asset/primevue/timeline/timeline.min.js', + 'vendor/npm-asset/primevue/inplace/inplace.min.js', 'vendor/moment/luxonjs/luxon.min.js' ), 'customJSModules' => array( diff --git a/application/views/CisRouterView/CisRouterView.php b/application/views/CisRouterView/CisRouterView.php index 4fa215f3d..af35cd4eb 100644 --- a/application/views/CisRouterView/CisRouterView.php +++ b/application/views/CisRouterView/CisRouterView.php @@ -33,6 +33,7 @@ $includesArray = array( 'vendor/npm-asset/primevue/speeddial/speeddial.min.js', 'vendor/npm-asset/primevue/textarea/textarea.min.js', 'vendor/npm-asset/primevue/timeline/timeline.min.js', + 'vendor/npm-asset/primevue/inplace/inplace.min.js', 'vendor/moment/luxonjs/luxon.min.js' ), 'customJSModules' => array( diff --git a/public/js/api/factory/abgabe.js b/public/js/api/factory/abgabe.js index 1087ec2a0..12615ee76 100644 --- a/public/js/api/factory/abgabe.js +++ b/public/js/api/factory/abgabe.js @@ -73,11 +73,11 @@ export default { params: { paabgabe_id } }; }, - postSerientermin(datum, paabgabetyp_kurzbz, bezeichnung, kurzbz, projektarbeit_ids) { + postSerientermin(datum, paabgabetyp_kurzbz, bezeichnung, kurzbz, projektarbeit_ids, fixtermin) { return { method: 'post', url: '/api/frontend/v1/Abgabe/postSerientermin', - params: { datum, paabgabetyp_kurzbz, bezeichnung, kurzbz, projektarbeit_ids } + params: { datum, paabgabetyp_kurzbz, bezeichnung, kurzbz, projektarbeit_ids, fixtermin } }; }, fetchDeadlines(person_id) { diff --git a/public/js/components/Cis/Abgabetool/AbgabeMitarbeiterDetail.js b/public/js/components/Cis/Abgabetool/AbgabeMitarbeiterDetail.js index aa8b2b858..aa184b4f6 100644 --- a/public/js/components/Cis/Abgabetool/AbgabeMitarbeiterDetail.js +++ b/public/js/components/Cis/Abgabetool/AbgabeMitarbeiterDetail.js @@ -86,11 +86,17 @@ export const AbgabeMitarbeiterDetail = { } if(newTerminRes.note) newTerminRes.note = noteOpt const existingTerminRes = res.data[1] + + const abgabeOpt = this.abgabeTypeOptions.find(opt => opt.paabgabetyp_kurzbz == newTerminRes.paabgabetyp_kurzbz) + newTerminRes.bezeichnung = { bezeichnung: termin.bezeichnung?.bezeichnung, - paabgabetyp_kurzbz: termin.bezeichnung?.paabgabetyp_kurzbz + paabgabetyp_kurzbz: termin.bezeichnung?.paabgabetyp_kurzbz, + benotbar: abgabeOpt.benotbar } + + // only insert new abgabe if we actually created a new one, not when saving/editing existing if(!existingTerminRes){ this.projektarbeit.abgabetermine.push(newTerminRes) @@ -711,8 +717,8 @@ export const AbgabeMitarbeiterDetail = {

{{ $capitalize( $p.t('abgabetool/c4keineAbgabetermineGefunden') )}}

- - + + `, }; diff --git a/public/js/components/Cis/Abgabetool/AbgabetoolAssistenz.js b/public/js/components/Cis/Abgabetool/AbgabetoolAssistenz.js index 40baf97bc..0ca163e33 100644 --- a/public/js/components/Cis/Abgabetool/AbgabetoolAssistenz.js +++ b/public/js/components/Cis/Abgabetool/AbgabetoolAssistenz.js @@ -7,8 +7,14 @@ import VueDatePicker from '../../vueDatepicker.js.php'; import ApiAbgabe from '../../../api/factory/abgabe.js' import AbgabeterminStatusLegende from "./StatusLegende.js"; -const todayISO = '2025-08-08' -const today = new Date(todayISO) +// spoofed date testing +// const todayISO = '2025-08-08' +// const today = new Date(todayISO) +// const now = luxon.DateTime.fromISO(todayISO) + +// prod code +const today = new Date() +const now = luxon.DateTime.now() export const AbgabetoolAssistenz = { name: "AbgabetoolAssistenz", @@ -21,6 +27,7 @@ export const AbgabetoolAssistenz = { VerticalSplit, Checkbox: primevue.checkbox, Dropdown: primevue.dropdown, + Inplace: primevue.inplace, Textarea: primevue.textarea, Timeline: primevue.timeline, VueDatePicker @@ -45,6 +52,8 @@ export const AbgabetoolAssistenz = { }, data() { return { + notenOptionFilter: null, + inplaceToggle: false, headerFiltersRestored: false, filtersRestored: false, colLayoutRestored: false, @@ -54,7 +63,6 @@ export const AbgabetoolAssistenz = { selectedStudiengangOption: null, studiengaengeOptions: null, detailIsFullscreen: false, - showZweitbetreuerCol: false, phrasenPromise: null, phrasenResolved: false, turnitin_link: null, @@ -63,6 +71,7 @@ export const AbgabetoolAssistenz = { loading: false, abgabeTypeOptions: null, notenOptions: null, + allowedNotenFilterOptions: null, allowedNotenOptions: null, serienTermin: Vue.reactive({ datum: new Date(), @@ -70,7 +79,8 @@ export const AbgabetoolAssistenz = { paabgabetyp_kurzbz: 'zwischen', bezeichnung: 'Zwischenabgabe' }, - kurzbz: '' + kurzbz: '', + fixtermin: false }), showAll: false, tabulatorUuid: Vue.ref(0), @@ -91,6 +101,7 @@ export const AbgabetoolAssistenz = { selectable: true, selectableCheck: this.selectionCheck, rowHeight: 40, + renderVerticalBuffer: 2000, responsiveLayout: true, columns: [ { @@ -106,6 +117,7 @@ export const AbgabetoolAssistenz = { width: 40 }, {title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4details'))), field: 'details', formatter: this.formAction, tooltip:false, minWidth: 150,}, + {title: 'pa_id', field: 'projektarbeit_id', visible: true}, // {title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4details'))), field: 'details', formatter: this.detailFormatter, widthGrow: 1,responsive:0, tooltip: false}, {title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4personenkennzeichen'))), headerFilter: true, field: 'pkz', formatter: this.pkzTextFormatter,responsive:0, widthGrow: 1, tooltip: false}, // {title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4termineTimeLine'))), headerFilter: true, field: 'abgabetermine',responsive:2, formatter: this.timelineFormatter, widthGrow: 1, tooltip: false}, @@ -114,10 +126,11 @@ export const AbgabetoolAssistenz = { {title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4nachname'))), field: 'student_nachname', headerFilter: true,responsive:2, formatter: this.centeredTextFormatter, widthGrow: 1}, {title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4projekttyp'))), field: 'projekttyp_kurzbz', responsive:3, visible: false, formatter: this.centeredTextFormatter, widthGrow: 1}, {title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4stg'))), field: 'stg', headerFilter: true, responsive:3, visible: false, formatter: this.centeredTextFormatter, widthGrow: 1}, + {title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4note'))), field: 'note', headerFilter: true, responsive:3, visible: false, formatter: this.centeredTextFormatter, widthGrow: 1}, {title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4sem'))), field: 'studiensemester_kurzbz', headerFilter: true, visible: false, responsive:3,formatter: this.centeredTextFormatter, widthGrow: 1}, {title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4titel'))), field: 'titel', headerFilter: true, responsive:3, visible: false, formatter: this.centeredTextFormatter, widthGrow: 1}, {title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4erstbetreuer'))), field: 'erstbetreuer', headerFilter: true, responsive:3,formatter: this.centeredTextFormatter, widthGrow: 1}, - {title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4zweitbetreuer'))), field: 'zweitbetreuer', headerFilter: true, responsive:3,formatter: this.centeredTextFormatter, widthGrow: 1, visible: Vue.computed(()=>{return this.showZweitbetreuerCol})}, + {title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4zweitbetreuer'))), field: 'zweitbetreuer', headerFilter: true, responsive:3,formatter: this.centeredTextFormatter, widthGrow: 1, visible: false}, {title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4prevAbgabetermin'))), headerFilter: true, field: 'prevTermin', responsive:4, formatter: this.abgabterminFormatter, widthGrow: 1, width: 220, tooltip: false}, {title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4nextAbgabetermin'))), headerFilter: true, field: 'nextTermin', responsive:4, formatter: this.abgabterminFormatter, widthGrow: 1, width: 220, tooltip: false}, ], @@ -153,6 +166,31 @@ export const AbgabetoolAssistenz = { ]}; }, methods: { + checkAbgabetermineProjektarbeit(projekt) { + // calculate Abgabetermin time diff to now and assign last and next to projekt + projekt.abgabetermine.forEach(termin => { + + // while already looping through each termin, calculate datestyle beforehand + termin.dateStyle = this.getDateStyleClass(termin) + + const date = luxon.DateTime.fromISO(termin.datum) + termin.diffMs = date.toMillis() - now.toMillis(); // positive = future, negative = past + + if (termin.diffMs < 0) { + if (!projekt.prevTermin || + termin.diffMs > projekt.prevTermin.diffMs // larger (less negative) = closer to now + ) { + projekt.prevTermin = termin; + } + } else if (termin.diffMs > 0) { + if (!projekt.nextTermin || + termin.diffMs < projekt.nextTermin.diffMs // smaller positive = closer to now + ) { + projekt.nextTermin = termin; + } + } + }) + }, loadState() { return JSON.parse(localStorage.getItem(this.abgabeTableOptions.persistenceID) || "null"); }, @@ -214,7 +252,7 @@ export const AbgabetoolAssistenz = { table.on("renderComplete", () => { if(!this.stateRestored) { - debugger + if (saved?.columns && !this.colLayoutRestored) { const layout = saved.columns.map(col => ({ field: col.field, @@ -222,10 +260,13 @@ export const AbgabetoolAssistenz = { visible: col.visible, // add more if needed, but keep it simple })); - - console.log(layout) - table.setColumnLayout(layout); + const safeLayout = layout.filter(col => + col.field && !["rowSelection", "rowHandle", "rowNum", "zweitbetreuer"].includes(col.field) + ); + + table.setColumnLayout(safeLayout); + this.colLayoutRestored = true; } @@ -270,6 +311,9 @@ export const AbgabetoolAssistenz = { getOptionLabelStg(option){ return option.kurzbzlang + ' ' + option.bezeichnung }, + getNotenFilterOptionLabel(option) { + return option.bezeichnung + }, sgChanged(e) { debugger }, @@ -304,6 +348,7 @@ export const AbgabetoolAssistenz = { btn.style.height = "100%"; // fill parent container height btn.style.aspectRatio = "1 / 1"; // keep square shape (optional) btn.style.padding = "0"; // remove extra padding for compactness + if(iconClass == 'fa fa-timeline') btn.style.transform = "rotate(90deg)"; btn.innerHTML = ``; btn.title = this.$capitalize(this.$p.t(titleKey)); btn.addEventListener('click', (e) => { @@ -354,27 +399,88 @@ export const AbgabetoolAssistenz = { this.$refs.modalContainerAddSeries.show() }, addSeries() { + const pids = this.selectedData?.map(projekt => projekt.projektarbeit_id) this.saving = true this.$api.call(ApiAbgabe.postSerientermin( this.serienTermin.datum.toISOString(), this.serienTermin.bezeichnung.paabgabetyp_kurzbz, this.serienTermin.bezeichnung.bezeichnung, this.serienTermin.kurzbz, - this.selectedData?.map(projekt => projekt.projektarbeit_id) + pids, + this.serienTermin.fixtermin )).then(res => { + // TODO + // sticky lifetime somehow + if (res.meta.status === "success" && res.data) { this.$fhcAlert.alertSuccess(this.$p.t('abgabetool/serienTerminGespeichert')) // TODO: sticky lifetime erhöhen um sinnvoll lesen zu können? - this.$fhcAlert.alertInfo(this.$p.t('abgabetool/serienTerminEmailSentInfo', [this.createInfoString(res.data)])); + this.$fhcAlert.alertInfo(this.$p.t('abgabetool/serienTerminEmailSentInfo', [this.createInfoString(res.data[0])])); } else { this.$fhcAlert.alertError(this.$p.t('abgabetool/errorSerienterminSpeichern')) } + + // put new abgaben into projektarbeiten + const newAbgaben = res.data[1] + pids.forEach(pid => { + const abgabe = newAbgaben.find(abgabe => abgabe.projektarbeit_id == pid) + + const pa = this.projektarbeiten.find(pa => pa.projektarbeit_id == pid) + + abgabe.bezeichnung = this.abgabeTypeOptions.find(opt => opt.paabgabetyp_kurzbz == abgabe.paabgabetyp_kurzbz) + + pa.abgabetermine.push(abgabe) + pa.abgabetermine.sort((a, b) => new Date(a.datum) - new Date(b.datum)) + }) + + // reset selection to empty + this.$refs.abgabeTable.tabulator.deselectRow() + + const mappedData = this.mapProjekteToTableData(this.projektarbeiten) + + console.log('this.projektarbeiten', this.projektarbeiten) + console.log('mappedData', mappedData) + + this.$refs.abgabeTable.tabulator.clearData() + this.$refs.abgabeTable.tabulator.setColumns(this.abgabeTableOptions.columns) + this.$refs.abgabeTable.tabulator.replaceData(mappedData) + + // this.$refs.abgabeTable.tabulator.redraw(true) }).finally(()=>{ this.saving = false }) this.$refs.modalContainerAddSeries.hide() }, + mapProjekteToTableData(projekte) { + // const now = luxon.DateTime.now(); + return projekte.map(projekt => { + + projekt.prevTermin = null; + projekt.nextTermin = null; + + + this.checkAbgabetermineProjektarbeit(projekt) + + return { + ...projekt, + abgabetermine: projekt.abgabetermine, + details: { + student_uid: projekt.student_uid, + projektarbeit_id: projekt.projektarbeit_id, + }, + pkz: this.buildPKZ(projekt), + beurteilung: projekt.beurteilungLink ?? null, + sem: projekt.studiensemester_kurzbz, + stg: this.buildStg(projekt), + mail: this.buildMailToLink(projekt), + erstbetreuer: this.buildErstbetreuer(projekt), + zweitbetreuer: this.buildZweitbetreuer(projekt), + typ: projekt.projekttyp_kurzbz, + titel: projekt.titel + } + }) + }, createInfoString(data) { let str = ''; @@ -390,7 +496,7 @@ export const AbgabetoolAssistenz = { }, setDetailComponent(details){ - const pa = this.projektarbeiten.find(projekarbeit => projekarbeit.projektarbeit_id == details.projektarbeit_id) + const pa = this.projektarbeiten.find(projektarbeit => projektarbeit.projektarbeit_id == details.projektarbeit_id) // pa.isCurrent = res.data[1] @@ -445,7 +551,7 @@ export const AbgabetoolAssistenz = { const projekt = this.projektarbeiten.find(p => p.projektarbeit_id == val.projektarbeit_id) if(!projekt) { - this.$fhcAlert.alertInfo('keine projektarbeit gefunden') + this.$fhcAlert.alertInfo('Keine projektarbeit gefunden') return } @@ -455,7 +561,6 @@ export const AbgabetoolAssistenz = { termin.benotbar = terminTypOpt.benotbar }) this.timelineProjekt = projekt - // this.timelineAbgabetermine = projekt.abgabetermine this.$refs.drawer.show() }, centeredTextFormatter(cell) { @@ -503,7 +608,7 @@ export const AbgabetoolAssistenz = { case 'verpasst': icon = '' break - case 'verpasst': + case 'abzugeben': icon = '' break case 'standard': @@ -514,12 +619,14 @@ export const AbgabetoolAssistenz = { break } + const bezeichnung = val.bezeichnung?.bezeichnung ?? val.bezeichnung + return '
' + '
' + icon + '
' + '
' + - '

'+val.bezeichnung+' - '+ this.formatDate(val.datum)+'

' + + '

'+bezeichnung+' - '+ this.formatDate(val.datum)+'

' + '
'+ '
' @@ -550,64 +657,12 @@ export const AbgabetoolAssistenz = { setupData(data){ this.projektarbeiten = data[0] this.domain = data[1] - - const now = luxon.DateTime.fromISO(todayISO) - // const now = luxon.DateTime.now(); - const d = data[0].map(projekt => { - let mode = 'detailTermine' - - projekt.prevTermin = undefined; - projekt.nextTermin = undefined; - - // only show 2tbetreuer col if any projektarbeit has one - if(projekt.zweitbetreuer_full_name) this.showZweitbetreuerCol = true - - // calculate Abgabetermin time diff to now and assign last and next to projekt - projekt.abgabetermine.forEach(termin => { - - // while already looping through each termin, calculate datestyle beforehand - termin.dateStyle = this.getDateStyleClass(termin) - - const date = luxon.DateTime.fromISO(termin.datum) - termin.diffMs = date.toMillis() - now.toMillis(); // positive = future, negative = past - - if (termin.diffMs < 0) { - if (!projekt.prevTermin || - termin.diffMs > projekt.prevTermin.diffMs // larger (less negative) = closer to now - ) { - projekt.prevTermin = termin; - } - } else if (termin.diffMs > 0) { - if (!projekt.nextTermin || - termin.diffMs < projekt.nextTermin.diffMs // smaller positive = closer to now - ) { - projekt.nextTermin = termin; - } - } - }) - - return { - ...projekt, - abgabetermine: projekt.abgabetermine, - details: { - student_uid: projekt.student_uid, - projektarbeit_id: projekt.projektarbeit_id, - }, - pkz: this.buildPKZ(projekt), - beurteilung: projekt.beurteilungLink ?? null, - sem: projekt.studiensemester_kurzbz, - stg: this.buildStg(projekt), - mail: this.buildMailToLink(projekt), - erstbetreuer: this.buildErstbetreuer(projekt), - zweitbetreuer: this.buildZweitbetreuer(projekt), - typ: projekt.projekttyp_kurzbz, - titel: projekt.titel - } - }) - + + const mappedData = this.mapProjekteToTableData(this.projektarbeiten) + this.$refs.abgabeTable.tabulator.clearData() this.$refs.abgabeTable.tabulator.setColumns(this.abgabeTableOptions.columns) - this.$refs.abgabeTable.tabulator.setData(d); + this.$refs.abgabeTable.tabulator.setData(mappedData); }, loadProjektarbeiten(all = false, callback) { this.loading = true @@ -680,14 +735,12 @@ export const AbgabetoolAssistenz = { this.turnitin_link = res.data?.turnitin_link this.old_abgabe_beurteilung_link = res.data?.old_abgabe_beurteilung_link }).catch(e => { - console.log(e) this.loading = false }) // fetch studiengänge options this.$api.call(ApiAbgabe.getStudiengaenge()).then(res => { this.studiengaengeOptions = res.data - console.log(this.studiengaengeOptions) }).catch(e => { this.loading = false }) @@ -701,6 +754,26 @@ export const AbgabetoolAssistenz = { opt => opt.bezeichnung === 'Bestanden' || opt.bezeichnung === 'Nicht bestanden' ) + + // allowedNotenOptions apply to quality gates abgabetermine + // this selection is about graded projektarbeiten, so take different options here + this.allowedNotenFilterOptions = [ + { + bezeichnung: this.$p.t('abgabetool/keineNoteEingetragen'), + note: null, + }, + { + bezeichnung: this.$p.t('abgabetool/c4benotet'), + note: 1, + }, + { + bezeichnung: Vue.computed(this.$p.t('abgabetool/showAll')), + note: -1, + }, + ] + + this.notenOptionFilter = this.allowedNotenFilterOptions[0] + }).catch(e => { this.loading = false }) @@ -734,7 +807,7 @@ export const AbgabetoolAssistenz = { {{$p.t('abgabetool/c4fixterminv2')}}
- {{$p.t('abgabetool/c4zieldatum')}} + {{$capitalize($p.t('abgabetool/c4zieldatum'))}}
{{$p.t('abgabetool/c4abgabetypv2')}} @@ -802,19 +875,53 @@ export const AbgabetoolAssistenz = { ref="drawer" placement="end" :backdrop="true" - @shownBsOffcanvas="onShown" - @hiddenBsOffcanvas="onHidden" :style="{ '--bs-offcanvas-width': '600px' }" > + + +
+ + + + +
- + align="right" + >