From 6cd0e3a57451a6d94eb801ce5a98446e41793d6e Mon Sep 17 00:00:00 2001 From: Johann Hoffmann Date: Mon, 17 Nov 2025 15:57:53 +0100 Subject: [PATCH] email tbl_vorlage inserts dbupdate script; index.ci.php/Abgabetool/Assistenz/stg_kz? optional param route in old cis & cis4; no data placeholder phrase fix; --- application/config/routes.php | 3 +- application/controllers/Cis/Abgabetool.php | 13 +-- application/views/Cis/Abgabetool.php | 5 +- public/js/apps/Abgabetool/Abgabetool.js | 12 ++- public/js/apps/Dashboard/Fhc.js | 2 +- .../Cis/Abgabetool/AbgabeMitarbeiterDetail.js | 4 +- .../Cis/Abgabetool/AbgabetoolAssistenz.js | 85 +++++++------------ .../Cis/Abgabetool/AbgabetoolMitarbeiter.js | 5 +- .../Cis/Abgabetool/StatusLegende.js | 2 +- .../61164_abgabetool_quality_gates.php | 46 +++++++++- system/phrasesupdate.php | 2 +- 11 files changed, 104 insertions(+), 75 deletions(-) diff --git a/application/config/routes.php b/application/config/routes.php index 11315f47d..e561753ba 100644 --- a/application/config/routes.php +++ b/application/config/routes.php @@ -66,9 +66,10 @@ $route['Cis/MyLvPlan/.*'] = 'Cis/MyLvPlan/index/$1'; $route['Cis/MyLv/.*'] = 'Cis/MyLv/index/$1'; $route['Abgabetool/Assistenz'] = 'Cis/Abgabetool/Assistenz'; +$route['Abgabetool/Assistenz/(:any)'] = 'Cis/Abgabetool/Assistenz/$1'; $route['Abgabetool/Mitarbeiter'] = 'Cis/Abgabetool/Mitarbeiter'; $route['Abgabetool/Student'] = 'Cis/Abgabetool/Student'; -$route['Abgabetool/Student/.*'] = 'Cis/Abgabetool/Student/$1'; +$route['Abgabetool/Student/(:any)'] = 'Cis/Abgabetool/Student/$1'; $route['Abgabetool/Deadlines'] = 'Cis/Abgabetool/Deadlines'; // Studierendenverwaltung List Routes diff --git a/application/controllers/Cis/Abgabetool.php b/application/controllers/Cis/Abgabetool.php index 6bf7d951c..04338b1a9 100644 --- a/application/controllers/Cis/Abgabetool.php +++ b/application/controllers/Cis/Abgabetool.php @@ -29,7 +29,7 @@ class Abgabetool extends Auth_Controller */ public function index() { - // TODO: do we even need this? + // TODO: routing from index based on berechtigung? $viewData = array( 'uid'=>getAuthUID(), @@ -44,12 +44,9 @@ class Abgabetool extends Auth_Controller public function Student($student_uid_prop = '') { - $viewData = array( 'uid'=>getAuthUID(), ); - - if(defined('CIS4') && CIS4) { $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'AbgabetoolStudent']); @@ -60,7 +57,6 @@ class Abgabetool extends Auth_Controller public function Mitarbeiter() { - $viewData = array( 'uid'=>getAuthUID(), ); @@ -72,9 +68,9 @@ class Abgabetool extends Auth_Controller } } - public function Assistenz() + public function Assistenz($stg_kz_prop = '') { - + $viewData = array( 'uid'=>getAuthUID(), ); @@ -82,13 +78,12 @@ class Abgabetool extends Auth_Controller if(defined('CIS4') && CIS4) { $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'AbgabetoolAssistenz']); } else { - $this->load->view('Cis/Abgabetool.php', ['uid' => getAuthUID(), 'route' => 'AbgabetoolAssistenz']); + $this->load->view('Cis/Abgabetool.php', ['uid' => getAuthUID(), 'route' => 'AbgabetoolAssistenz', 'stg_kz_prop' => $stg_kz_prop]); } } public function Deadlines() { - $viewData = array( 'uid'=>getAuthUID(), ); diff --git a/application/views/Cis/Abgabetool.php b/application/views/Cis/Abgabetool.php index 2e1daf2cd..1d53cfa77 100644 --- a/application/views/Cis/Abgabetool.php +++ b/application/views/Cis/Abgabetool.php @@ -37,7 +37,10 @@ $includesArray = array( $this->load->view('templates/FHC-Header', $includesArray); ?> -
uid= student_uid_prop=> +
+ uid= student_uid_prop= + stg_kz_prop= + >
load->view('templates/FHC-Footer', $includesArray); ?> diff --git a/public/js/apps/Abgabetool/Abgabetool.js b/public/js/apps/Abgabetool/Abgabetool.js index ac73779e8..9d9e34214 100644 --- a/public/js/apps/Abgabetool/Abgabetool.js +++ b/public/js/apps/Abgabetool/Abgabetool.js @@ -1,6 +1,7 @@ import PluginsPhrasen from '../../plugins/Phrasen.js'; import AbgabetoolStudent from "../../components/Cis/Abgabetool/AbgabetoolStudent.js"; import AbgabetoolMitarbeiter from "../../components/Cis/Abgabetool/AbgabetoolMitarbeiter.js"; +import AbgabetoolAssistenz from "../../components/Cis/Abgabetool/AbgabetoolAssistenz.js"; import DeadlineOverview from "../../components/Cis/Abgabetool/DeadlineOverview.js"; import {capitalize} from "../../helpers/StringHelpers.js"; @@ -9,13 +10,15 @@ const app = Vue.createApp({ components: { AbgabetoolStudent, AbgabetoolMitarbeiter, + AbgabetoolAssistenz, DeadlineOverview }, data: function() { return { comp: null, uid: null, - student_uid: null + student_uid: null, + stg_kz: null }; }, methods: { @@ -27,6 +30,9 @@ const app = Vue.createApp({ }, student_uid_computed() { return this.student_uid ?? null + }, + stg_kz_computed() { + return this.stg_kz ?? null } }, created() { @@ -40,6 +46,9 @@ const app = Vue.createApp({ const uid = root.getAttribute("uid"); this.uid = uid + const stg_kz = root.getAttribute("stg_kz_prop"); + this.stg_kz = stg_kz + const student_uid = root.getAttribute("student_uid_prop"); this.student_uid = student_uid @@ -48,6 +57,7 @@ const app = Vue.createApp({ ` diff --git a/public/js/apps/Dashboard/Fhc.js b/public/js/apps/Dashboard/Fhc.js index 0a11c4986..540a74f06 100644 --- a/public/js/apps/Dashboard/Fhc.js +++ b/public/js/apps/Dashboard/Fhc.js @@ -58,7 +58,7 @@ const router = VueRouter.createRouter({ props: true }, { - path: `/Cis/Abgabetool/Assistenz`, + path: `/Cis/Abgabetool/Assistenz/:stg_kz_prop?`, name: 'AbgabetoolAssistenz', component: AbgabetoolAssistenz, props: true diff --git a/public/js/components/Cis/Abgabetool/AbgabeMitarbeiterDetail.js b/public/js/components/Cis/Abgabetool/AbgabeMitarbeiterDetail.js index e46067c38..aaffad68d 100644 --- a/public/js/components/Cis/Abgabetool/AbgabeMitarbeiterDetail.js +++ b/public/js/components/Cis/Abgabetool/AbgabeMitarbeiterDetail.js @@ -125,7 +125,7 @@ export const AbgabeMitarbeiterDetail = { 'paabgabe_id': -1, 'projektarbeit_id': this.projektarbeit.projektarbeit_id, 'fixtermin': false, - 'inertedFixtermin': true, + 'invertedFixtermin': true, 'kurzbz': '', // todo kurzbz textfield value vorschlag für qualgates 'datum': new Date().toISOString().split('T')[0], 'note': this.allowedNotenOptions.find(opt => opt.note == 9), @@ -492,7 +492,7 @@ export const AbgabeMitarbeiterDetail = {

{{$p.t('abgabetool/c4abgabeQualGateNegativAddNewAutomagisch')}}

-
{{$p.t('abgabetool/c4fixtermin')}}
+
{{$p.t('abgabetool/c4fixterminv4')}}
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: '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}, @@ -134,7 +137,7 @@ export const AbgabetoolAssistenz = { {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_bez', 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/c4sem'))), field: 'studiensemester_kurzbz', headerFilter: true, visible: true, responsive:2,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: false}, @@ -150,26 +153,12 @@ export const AbgabetoolAssistenz = { this.tableBuiltResolve() } }, - // { - // event: "cellClick", - // handler: async (e, cell) => { - // if(cell.getColumn().getField() === "details") { - // this.setDetailComponent(cell.getValue()) - // this.undoSelection(cell) - // } else if (cell.getColumn().getField() === "mail") { - // this.undoSelection(cell) - // } else if (cell.getColumn().getField() === "abgabetermine") { - // this.openTimeline(cell.getValue()) - // this.undoSelection(cell) - // } - // } - // }, - { - event: "rowSelectionChanged", - handler: async(data) => { - this.selectedData = data - } + { + event: "rowSelectionChanged", + handler: async(data) => { + this.selectedData = data } + } ]}; }, methods: { @@ -409,15 +398,6 @@ export const AbgabetoolAssistenz = { + '/Cis/Abgabetool/Deadlines' window.open(link, '_blank') }, - toggleShowAll(showall) { - this.showAll = showall - this.loading = true - this.loadProjektarbeiten(showall, () => { - this.$refs.abgabeTable?.tabulator.redraw(true) - this.$refs.abgabeTable?.tabulator.setSort([]); - this.loading = false - }) - }, openAddSeriesModal() { this.$refs.modalContainerAddSeries.show() }, @@ -460,6 +440,9 @@ export const AbgabetoolAssistenz = { this.$refs.abgabeTable.tabulator.deselectRow() const mappedData = this.mapProjekteToTableData(this.projektarbeiten) + + + if(!this.$refs.abgabeTable.tabulator) return this.$refs.abgabeTable.tabulator.clearData() this.$refs.abgabeTable.tabulator.setColumns(this.abgabeTableOptions.columns) @@ -541,8 +524,6 @@ export const AbgabetoolAssistenz = { }) - // TODO: do same thing for sidebar - const vorname = pa.vorname ?? pa.student_vorname const nachname = pa.nachname ?? pa.student_nachname pa.student = `${vorname} ${nachname}` @@ -694,7 +675,7 @@ export const AbgabetoolAssistenz = { loadProjektarbeiten(all = false, callback) { this.loading = true this.$api.call(ApiAbgabe.getProjektarbeitenForStudiengang( - this.getCurrentStudiengang, + this.selectedStudiengangOption.studiengang_kz, this.notenOptionFilter?.benotet ?? 0 )) .then(res => { @@ -730,37 +711,27 @@ export const AbgabetoolAssistenz = { async setupMounted() { this.tableBuiltPromise = new Promise(this.tableResolve) await this.tableBuiltPromise - - // called through notenOptionFilter watcher on startup + // called through notenOptionFilter/selectedStudiengangOption watcher on startup // this.loadProjektarbeiten() - // this.$refs.verticalsplit.collapseBottom() this.calcMaxTableHeight() - - }, - sendEmailBegutachter() { - // TODO: implement - }, - sendEmailStudierende() { - // TODO: implement } }, watch: { selectedStudiengangOption(newVal, oldVal) { - this.loadProjektarbeiten() + // implicitely avoids juggling around promises for created api calls, + // since we need note & stg flags for loadProjektarbeiten + if(this.notenOptionFilter !== null && this.selectedStudiengangOption !== null) { + this.loadProjektarbeiten() + } }, notenOptionFilter(newVal) { // that single where clause is worth a decent load time so rather not filter tabulator but just // adapt the qry - this.loadProjektarbeiten() - } - }, - computed: { - getCurrentStudiengang() { - // TODO: sophisticated logic pulling from default value by viewData or dropdown select - - return this.selectedStudiengangOption?.studiengang_kz ?? 257 + if(this.notenOptionFilter !== null && this.selectedStudiengangOption !== null) { + this.loadProjektarbeiten() + } } }, created() { @@ -778,6 +749,13 @@ export const AbgabetoolAssistenz = { // fetch studiengänge options this.$api.call(ApiAbgabe.getStudiengaenge()).then(res => { this.studiengaengeOptions = res.data + if(this.studiengaengeOptions?.length) { + + // use this.stg_kz_prop as default selected in case of url param usage + + this.selectedStudiengangOption = this.stg_kz_prop ? res.data.find(stgOpt => stgOpt.studiengang_kz == this.stg_kz_prop) : res.data[0] + } + }).catch(e => { this.loading = false }) @@ -1035,8 +1013,7 @@ export const AbgabetoolAssistenz = { :style="{'width': '100%', 'scroll-behavior': 'auto !important'}" :optionLabel="getOptionLabelStg" v-model="selectedStudiengangOption" - :options="studiengaengeOptions" - showClear + :options="studiengaengeOptions" :tabindex="2" >