From daf332a10283e00282a41f8fb3c29cf72af4626f Mon Sep 17 00:00:00 2001 From: Harald Bamberger Date: Fri, 6 Mar 2026 10:39:37 +0100 Subject: [PATCH 01/12] add query_studiensemester_kurzbz to result of fetchStudents, fetchPrestudents and search --- application/controllers/api/frontend/v1/stv/Students.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/application/controllers/api/frontend/v1/stv/Students.php b/application/controllers/api/frontend/v1/stv/Students.php index acacca052..53137a472 100644 --- a/application/controllers/api/frontend/v1/stv/Students.php +++ b/application/controllers/api/frontend/v1/stv/Students.php @@ -468,6 +468,8 @@ class Students extends FHCAPI_Controller $this->PrestudentModel->addSelect("'' AS verband"); $this->PrestudentModel->addSelect("'' AS gruppe"); $this->addSelectPrioRel(); + $query_studiensemester_kurzbz = $studiensemester_kurzbz ? $this->PrestudentModel->escape($studiensemester_kurzbz) : '\'NULL\''; + $this->PrestudentModel->addSelect($query_studiensemester_kurzbz . ' as query_studiensemester_kurzbz'); $this->addFilter($studiensemester_kurzbz); @@ -588,6 +590,7 @@ class Students extends FHCAPI_Controller $this->PrestudentModel->addSelect('v.verband'); $this->PrestudentModel->addSelect('v.gruppe'); $this->PrestudentModel->addSelect("'' AS priorisierung_relativ"); + $this->PrestudentModel->addSelect($this->PrestudentModel->escape($studiensemester_kurzbz) . ' as query_studiensemester_kurzbz'); $where = []; @@ -798,6 +801,7 @@ class Students extends FHCAPI_Controller $this->PrestudentModel->addSelect("COALESCE(v.semester::text, CASE WHEN public.get_rolle_prestudent(tbl_prestudent.prestudent_id, NULL) IN ('Aufgenommener', 'Bewerber', 'Wartender', 'interessent') THEN public.get_absem_prestudent(tbl_prestudent.prestudent_id, NULL)::text ELSE ''::text END) AS semester", false); $this->PrestudentModel->addSelect('v.verband'); $this->PrestudentModel->addSelect('v.gruppe'); + $this->PrestudentModel->addSelect($this->PrestudentModel->escape($studiensemester_kurzbz) . ' as query_studiensemester_kurzbz'); //add status per semester $this->PrestudentModel->addSelect( From 9b4fa132dc1fde8fe57fc7b9971f5a4e0f1abb53 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Fri, 6 Mar 2026 10:58:54 +0100 Subject: [PATCH 02/12] add status --- public/js/components/Stv/Studentenverwaltung.js | 3 ++- .../js/components/Stv/Studentenverwaltung/List.js | 13 ++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/public/js/components/Stv/Studentenverwaltung.js b/public/js/components/Stv/Studentenverwaltung.js index cfd229fb0..a7d97d4fc 100644 --- a/public/js/components/Stv/Studentenverwaltung.js +++ b/public/js/components/Stv/Studentenverwaltung.js @@ -208,6 +208,7 @@ export default { 'url_studiengang': function (newVal, oldVal) { if (newVal !== oldVal) { this.checkUrlStudiengang(); + this.$refs.stvList.clearSelection(); } }, 'url_mode': function () { @@ -420,7 +421,7 @@ export default { this.$refs.searchbar.$refs.input.blur(); this.$refs.searchbar.abort(); this.$refs.searchbar.hideresult(); - } + }, }, created() { if (!this.url_studiensemester_kurzbz) { diff --git a/public/js/components/Stv/Studentenverwaltung/List.js b/public/js/components/Stv/Studentenverwaltung/List.js index 045326ae6..af893f7de 100644 --- a/public/js/components/Stv/Studentenverwaltung/List.js +++ b/public/js/components/Stv/Studentenverwaltung/List.js @@ -324,10 +324,13 @@ export default { actionNewPrestudent() { this.$refs.new.open(); }, - rowSelectionChanged(data, rows) { + rowSelectionChanged(data, rows, selected, deselected) { this.selectedcount = data.length; - this.lastSelected = this.selected; - this.$emit('update:selected', data); + + if(selected.length > 0 || deselected.length > 0){ + this.lastSelected = this.selected; + this.$emit('update:selected', data); + } // set selected elements draggable const tableEl = this.$refs.table?.$refs?.table; @@ -471,6 +474,10 @@ export default { if (el != this.focusObj) this.changeFocus(this.focusObj, el); } + }, + clearSelection(){ + this.lastSelected = []; + this.$emit('update:selected',[]); } }, // TODO(chris): focusin, focusout, keydown and tabindex should be in the filter component From 2237e9f1b72f16e63f0d65da13e910272eb280be Mon Sep 17 00:00:00 2001 From: ma0068 Date: Mon, 9 Mar 2026 11:42:24 +0100 Subject: [PATCH 03/12] refactor detail Header, relaod array if semester changed, show no status if no status, phrase --- .../frontend/v1/detailheader/DetailHeader.php | 30 +++++++++++++ public/js/api/factory/detailHeader.js | 6 +++ .../components/DetailHeader/DetailHeader.js | 44 ++++++++++++++++--- .../js/components/Stv/Studentenverwaltung.js | 8 +++- .../Stv/Studentenverwaltung/Details.js | 29 +++++++++++- system/phrasesupdate.php | 20 +++++++++ 6 files changed, 129 insertions(+), 8 deletions(-) create mode 100644 application/controllers/api/frontend/v1/detailheader/DetailHeader.php diff --git a/application/controllers/api/frontend/v1/detailheader/DetailHeader.php b/application/controllers/api/frontend/v1/detailheader/DetailHeader.php new file mode 100644 index 000000000..be9fad27a --- /dev/null +++ b/application/controllers/api/frontend/v1/detailheader/DetailHeader.php @@ -0,0 +1,30 @@ + ['admin:r', 'assistenz:r'], + ]); + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + public function getSemesterStati($prestudent_id) + { + $this->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel'); + + $result = $this->PrestudentstatusModel->getAllPrestudentstatiWithStudiensemester($prestudent_id); + + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data); + } + +} diff --git a/public/js/api/factory/detailHeader.js b/public/js/api/factory/detailHeader.js index 74563bd4b..9e50e8ebb 100644 --- a/public/js/api/factory/detailHeader.js +++ b/public/js/api/factory/detailHeader.js @@ -34,4 +34,10 @@ export default { url: 'api/frontend/v1/vertraege/vertraege/getLeitungOrg/' + oekurzbz, }; }, + getSemesterStati(prestudent_id){ + return { + method: 'get', + url: 'api/frontend/v1/detailheader/DetailHeader/getSemesterStati/' + prestudent_id, + }; + }, } \ No newline at end of file diff --git a/public/js/components/DetailHeader/DetailHeader.js b/public/js/components/DetailHeader/DetailHeader.js index 04c6d1835..f0db9fe5d 100644 --- a/public/js/components/DetailHeader/DetailHeader.js +++ b/public/js/components/DetailHeader/DetailHeader.js @@ -7,6 +7,9 @@ export default { from: 'configDomain', default: 'technikum-wien.at' }, + currentSemester: { + from: 'currentSemester', + }, }, props: { headerData: { @@ -51,6 +54,10 @@ export default { console.error("Error loading department data:", error); }); } + + if(this.headerData){ + this.getSemesterStati(this.headerData[0].prestudent_id); + } }, watch: { person_id: { @@ -65,12 +72,27 @@ export default { }, deep: true, }, + currentSemester: { + handler(newVal) { + if (newVal) { + if(!this.semesterStati.some(item => item.studiensemester_kurzbz === this.currentSemester)) { + this.noCurrentStatus = true; + } + else + { + this.noCurrentStatus = false; + } + } + }, + deep: true, + }, }, data(){ return{ headerDataMa: {}, departmentData: {}, leitungData: {}, + noCurrentStatus: false }; }, methods: { @@ -109,6 +131,14 @@ export default { } else { return 'data:image/jpeg;base64,' + foto; } + }, + getSemesterStati(prestudent_id){ + return this.$api + .call(ApiDetailHeader.getSemesterStati(prestudent_id)) + .then(result => { + this.semesterStati = result.data; + }) + .catch(this.$fhcAlert.handleSystemError); } }, template: ` @@ -149,11 +179,11 @@ export default { {{headerData[0].person_id}} | {{$p.t('lehre', 'studiengang')}} {{headerData[0].stg_bezeichnung}} ({{headerData[0].studiengang}}) - | {{$p.t('lehre', 'semester')}} + | {{$p.t('lehre', 'semester')}} {{headerData[0].semester}} | {{$p.t('lehre', 'verband')}} {{headerData[0].verband}} - | {{$p.t('lehre', 'gruppe')}} + | {{$p.t('lehre', 'gruppe')}} {{headerData[0].gruppe}} @@ -162,12 +192,16 @@ export default { {{headerData[0].mail_intern}} - | Status - {{headerData[0].statusofsemester}} + | Status + + {{$p.t('lehre', 'textNoStatus')}} + + + {{headerData[0].statusofsemester}} + | {{$p.t('person', 'matrikelnummer')}} {{headerData[0].matr_nr}} - diff --git a/public/js/components/Stv/Studentenverwaltung.js b/public/js/components/Stv/Studentenverwaltung.js index a7d97d4fc..fae85b653 100644 --- a/public/js/components/Stv/Studentenverwaltung.js +++ b/public/js/components/Stv/Studentenverwaltung.js @@ -422,6 +422,12 @@ export default { this.$refs.searchbar.abort(); this.$refs.searchbar.hideresult(); }, + handleReloadStudent(students){ + this.$refs.stvList.updateUrl( + ApiStv.students.uid(students[0].uid,'CURRENT_SEMESTER'), + true + ); + } }, created() { if (!this.url_studiensemester_kurzbz) { @@ -629,7 +635,7 @@ export default { diff --git a/public/js/components/Stv/Studentenverwaltung/Details.js b/public/js/components/Stv/Studentenverwaltung/Details.js index dca08c07f..4d49aba0d 100644 --- a/public/js/components/Stv/Studentenverwaltung/Details.js +++ b/public/js/components/Stv/Studentenverwaltung/Details.js @@ -8,6 +8,11 @@ import ApiStvApp from '../../../api/factory/stv/app.js'; export default { name: "DetailsPrestudent", + inject: { + currentSemester: { + from: 'currentSemester', + }, + }, components: { FhcTabs, FhcHeader @@ -21,6 +26,9 @@ export default { props: { students: Array }, + emits: [ + 'reloadStudent:students' + ], computed: { appRoot() { return FHC_JS_DATA_STORAGE_OBJECT.app_root; @@ -39,13 +47,30 @@ export default { return Object.fromEntries(Object.entries(this.configStudents).filter(([ , value ]) => !value.showOnlyWithUid)); } return Object.fromEntries(Object.entries(this.configStudents).filter(([ , value ]) => !value.showOnlyWithUid && !value.showOnlyWithUid)); - } + }, +/* studiensemester(){ + if(this.students) + return this.students.query_studiensemester_kurzbz; + else + return null; + //return this.students?[0].query_studiensemester_kurzbz || null; + },*/ }, watch: { '$p.user_language.value'(n, o) { if (n !== o && o !== undefined) this.loadConfig(); + }, + currentSemester(newVal) { + if ( + this.students && + this.students.length > 0 && + newVal !== this.students[0].query_studiensemester_kurzbz + ) { + this.$emit('reloadStudent:students', this.students); + } } + }, methods: { loadConfig() { @@ -65,7 +90,7 @@ export default { reload() { if (this.$refs.tabs?.$refs?.current?.reload) this.$refs.tabs.$refs.current.reload(); - } + }, }, created() { this.loadConfig(); diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index 580f15bc2..b1f4b004a 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -56144,6 +56144,26 @@ I have been informed that I am under no obligation to consent to the transmissio ) ), // ### Refactor Messages END + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'textNoStatus', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Kein Status', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'No status', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), ); From 127ce312ea478027b827754c1ca2f889667d0638 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Tue, 10 Mar 2026 08:28:11 +0100 Subject: [PATCH 04/12] reload Details and Detailheader without updateUrl --- public/js/components/Stv/Studentenverwaltung.js | 15 ++++++++++++--- .../components/Stv/Studentenverwaltung/Details.js | 4 ++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/public/js/components/Stv/Studentenverwaltung.js b/public/js/components/Stv/Studentenverwaltung.js index fae85b653..52b4b9d07 100644 --- a/public/js/components/Stv/Studentenverwaltung.js +++ b/public/js/components/Stv/Studentenverwaltung.js @@ -423,10 +423,19 @@ export default { this.$refs.searchbar.hideresult(); }, handleReloadStudent(students){ - this.$refs.stvList.updateUrl( + //TODO(Manu) check with Harald + + this.$refs.details.reload(); //reload simply without updateUrl + //this.selected = students; + +/* this.$refs.stvList.updateUrl( ApiStv.students.uid(students[0].uid,'CURRENT_SEMESTER'), true - ); + );*/ +/* this.$refs.stvList.updateUrl( + ApiStv.students.uid(students[0].uid,'CURRENT_SEMESTER'), + true + );*/ } }, created() { @@ -635,7 +644,7 @@ export default { diff --git a/public/js/components/Stv/Studentenverwaltung/Details.js b/public/js/components/Stv/Studentenverwaltung/Details.js index 4d49aba0d..519b0b1b5 100644 --- a/public/js/components/Stv/Studentenverwaltung/Details.js +++ b/public/js/components/Stv/Studentenverwaltung/Details.js @@ -27,7 +27,7 @@ export default { students: Array }, emits: [ - 'reloadStudent:students' + 'reload-students:students' ], computed: { appRoot() { @@ -67,7 +67,7 @@ export default { this.students.length > 0 && newVal !== this.students[0].query_studiensemester_kurzbz ) { - this.$emit('reloadStudent:students', this.students); + this.$emit('reload-students', this.students); } } From dd87e893baa4ba0878310f97de1549ef5df2910b Mon Sep 17 00:00:00 2001 From: ma0068 Date: Wed, 11 Mar 2026 17:13:59 +0100 Subject: [PATCH 05/12] working version for relaod header and data without updateUrl --- .../components/DetailHeader/DetailHeader.js | 335 +++++++++--------- .../js/components/Stv/Studentenverwaltung.js | 9 +- .../Stv/Studentenverwaltung/Details.js | 51 ++- 3 files changed, 214 insertions(+), 181 deletions(-) diff --git a/public/js/components/DetailHeader/DetailHeader.js b/public/js/components/DetailHeader/DetailHeader.js index f0db9fe5d..3e7187d27 100644 --- a/public/js/components/DetailHeader/DetailHeader.js +++ b/public/js/components/DetailHeader/DetailHeader.js @@ -55,9 +55,9 @@ export default { }); } - if(this.headerData){ +/* if (this.headerData && this.headerData.length) { //bereits im watcher this.getSemesterStati(this.headerData[0].prestudent_id); - } + }*/ }, watch: { person_id: { @@ -86,167 +86,176 @@ export default { }, deep: true, }, + headerData: { + handler(newVal) { + if (this.typeHeader === 'student' && newVal?.length) { + this.getSemesterStati(newVal[0].prestudent_id); + } + }, + immediate: true + }, }, - data(){ - return{ - headerDataMa: {}, - departmentData: {}, - leitungData: {}, - noCurrentStatus: false - }; - }, - methods: { - getHeader(person_id) { - return this.$api - .call(ApiDetailHeader.getHeader(person_id)) - .then(result => { - this.headerDataMa = result.data; +data(){ +return{ + headerDataMa: {}, + departmentData: {}, + leitungData: {}, + noCurrentStatus: false +}; +}, +methods: { +getHeader(person_id) { + return this.$api + .call(ApiDetailHeader.getHeader(person_id)) + .then(result => { + this.headerDataMa = result.data; - }) - .catch(this.$fhcAlert.handleSystemError); - }, - loadDepartmentData(mitarbeiter_uid) { - return this.$api - .call(ApiDetailHeader.getPersonAbteilung(mitarbeiter_uid)) - .then(result => { - this.departmentData = result.data; - }) - .catch(this.$fhcAlert.handleSystemError); - }, - getLeitungOrg(oekurzbz){ - return this.$api - .call(ApiDetailHeader.getLeitungOrg(oekurzbz)) - .then(result => { - this.leitungData = result.data; - }) - .catch(this.$fhcAlert.handleSystemError); - }, - redirectToLeitung(){ - this.$emit('redirectToLeitung', { - person_id: this.leitungData.person_id}); - }, - getFotoSrc(foto) { - if(foto === null) { - return FHC_JS_DATA_STORAGE_OBJECT.app_root + 'skin/images/profilbild_dummy.jpg'; - } else { - return 'data:image/jpeg;base64,' + foto; - } - }, - getSemesterStati(prestudent_id){ - return this.$api - .call(ApiDetailHeader.getSemesterStati(prestudent_id)) - .then(result => { - this.semesterStati = result.data; - }) - .catch(this.$fhcAlert.handleSystemError); - } - }, - template: ` -
- - - - -
- ` + }) + .catch(this.$fhcAlert.handleSystemError); +}, +loadDepartmentData(mitarbeiter_uid) { + return this.$api + .call(ApiDetailHeader.getPersonAbteilung(mitarbeiter_uid)) + .then(result => { + this.departmentData = result.data; + }) + .catch(this.$fhcAlert.handleSystemError); +}, +getLeitungOrg(oekurzbz){ + return this.$api + .call(ApiDetailHeader.getLeitungOrg(oekurzbz)) + .then(result => { + this.leitungData = result.data; + }) + .catch(this.$fhcAlert.handleSystemError); +}, +redirectToLeitung(){ + this.$emit('redirectToLeitung', { + person_id: this.leitungData.person_id}); +}, +getFotoSrc(foto) { + if(foto === null) { + return FHC_JS_DATA_STORAGE_OBJECT.app_root + 'skin/images/profilbild_dummy.jpg'; + } else { + return 'data:image/jpeg;base64,' + foto; + } +}, +getSemesterStati(prestudent_id){ + return this.$api + .call(ApiDetailHeader.getSemesterStati(prestudent_id)) + .then(result => { + this.semesterStati = result.data; + //console.log("getSemesterStati loaded for prestudent_id " + prestudent_id); + }) + .catch(this.$fhcAlert.handleSystemError); +} +}, +template: ` +
+ + + + +
+` } diff --git a/public/js/components/Stv/Studentenverwaltung.js b/public/js/components/Stv/Studentenverwaltung.js index 52b4b9d07..e62ccfe7d 100644 --- a/public/js/components/Stv/Studentenverwaltung.js +++ b/public/js/components/Stv/Studentenverwaltung.js @@ -422,12 +422,13 @@ export default { this.$refs.searchbar.abort(); this.$refs.searchbar.hideresult(); }, - handleReloadStudent(students){ - //TODO(Manu) check with Harald - + handleReloadStudent_DEPR(students){ + // @reload-students="handleReloadStudent" + //TODO(Manu) delete this.$refs.details.reload(); //reload simply without updateUrl //this.selected = students; + //analoge to url_studiensemester_kurzbz /* this.$refs.stvList.updateUrl( ApiStv.students.uid(students[0].uid,'CURRENT_SEMESTER'), true @@ -644,7 +645,7 @@ export default { diff --git a/public/js/components/Stv/Studentenverwaltung/Details.js b/public/js/components/Stv/Studentenverwaltung/Details.js index 519b0b1b5..95d791ef9 100644 --- a/public/js/components/Stv/Studentenverwaltung/Details.js +++ b/public/js/components/Stv/Studentenverwaltung/Details.js @@ -2,6 +2,7 @@ import FhcTabs from "../../Tabs.js"; import FhcHeader from "../../DetailHeader/DetailHeader.js"; import ApiStvApp from '../../../api/factory/stv/app.js'; +import ApiStudent from '../../../api/factory/stv/students.js'; // TODO(chris): alt & title // TODO(chris): phrasen @@ -20,15 +21,13 @@ export default { data() { return { configStudent: {}, - configStudents: {} + configStudents: {}, + localStudent: null }; }, props: { students: Array }, - emits: [ - 'reload-students:students' - ], computed: { appRoot() { return FHC_JS_DATA_STORAGE_OBJECT.app_root; @@ -48,27 +47,29 @@ export default { } return Object.fromEntries(Object.entries(this.configStudents).filter(([ , value ]) => !value.showOnlyWithUid && !value.showOnlyWithUid)); }, -/* studiensemester(){ - if(this.students) - return this.students.query_studiensemester_kurzbz; - else - return null; - //return this.students?[0].query_studiensemester_kurzbz || null; - },*/ + //for reloading component if data changes + headerKey() { + return this.students?.[0]?.uid || this.localStudent?.[0]?.uid || "empty"; + } }, watch: { '$p.user_language.value'(n, o) { if (n !== o && o !== undefined) this.loadConfig(); }, + //ohne zusätzlichen Watcher reload header und details currentSemester(newVal) { if ( this.students && this.students.length > 0 && newVal !== this.students[0].query_studiensemester_kurzbz ) { - this.$emit('reload-students', this.students); + console.log("studiensemester_kurzbz " + this.students[0].query_studiensemester_kurzbz + " vs " + newVal); + this.reloadDataStudent(); } + }, + headerKey(newVal){ + this.reloadDataStudent(); } }, @@ -91,10 +92,31 @@ export default { if (this.$refs.tabs?.$refs?.current?.reload) this.$refs.tabs.$refs.current.reload(); }, + reloadDataStudent(){ + //TODO(check) + this.localStudent = null; + const studentArr = this.students; + + if (!studentArr || !studentArr.length) { + console.log("no data"); + return; + } + + console.log("uid " + studentArr[0].uid); + + this.$api + .call(ApiStudent.uid(studentArr[0].uid, this.currentSemester)) + .then(result => { + this.localStudent = result.data; + }); + } }, created() { this.loadConfig(); }, + /* //TODO(remove) + * {{headerKey}} {{localStudent?.[0]?.uid}}
{{ students?.[0]?.uid }} + * */ template: `
@@ -102,7 +124,8 @@ export default {
@@ -110,7 +133,7 @@ export default { v-if="students.length == 1" ref="tabs" :useprimevue="true" - :modelValue="students[0]" + :modelValue="localStudent[0] || students[0]" :config="config" :default="$route.params.tab" style="flex: 1 1 0%; height: 0%" From dd760f821089c5c2962951731e9f6af47a8b9ce8 Mon Sep 17 00:00:00 2001 From: Harald Bamberger Date: Thu, 12 Mar 2026 11:10:13 +0100 Subject: [PATCH 06/12] finetune behavior --- .../api/frontend/v1/stv/Student.php | 1 + .../components/DetailHeader/DetailHeader.js | 1 - .../js/components/Stv/Studentenverwaltung.js | 16 ------------ .../Stv/Studentenverwaltung/Details.js | 26 +++++++------------ 4 files changed, 10 insertions(+), 34 deletions(-) diff --git a/application/controllers/api/frontend/v1/stv/Student.php b/application/controllers/api/frontend/v1/stv/Student.php index 2fb354f0c..4711836db 100644 --- a/application/controllers/api/frontend/v1/stv/Student.php +++ b/application/controllers/api/frontend/v1/stv/Student.php @@ -140,6 +140,7 @@ class Student extends FHCAPI_Controller . $this->PrestudentModel->escape($studiensemester_kurzbz) . ") AS statusofsemester" ); + $this->PrestudentModel->addSelect($this->PrestudentModel->escape($studiensemester_kurzbz) . ' as query_studiensemester_kurzbz'); $this->PrestudentModel->addJoin('public.tbl_student s', 'prestudent_id', 'LEFT'); $this->PrestudentModel->addJoin('public.tbl_benutzer b', 'student_uid = uid', 'LEFT'); diff --git a/public/js/components/DetailHeader/DetailHeader.js b/public/js/components/DetailHeader/DetailHeader.js index 3e7187d27..b414f07ea 100644 --- a/public/js/components/DetailHeader/DetailHeader.js +++ b/public/js/components/DetailHeader/DetailHeader.js @@ -145,7 +145,6 @@ getSemesterStati(prestudent_id){ .call(ApiDetailHeader.getSemesterStati(prestudent_id)) .then(result => { this.semesterStati = result.data; - //console.log("getSemesterStati loaded for prestudent_id " + prestudent_id); }) .catch(this.$fhcAlert.handleSystemError); } diff --git a/public/js/components/Stv/Studentenverwaltung.js b/public/js/components/Stv/Studentenverwaltung.js index e62ccfe7d..a7d97d4fc 100644 --- a/public/js/components/Stv/Studentenverwaltung.js +++ b/public/js/components/Stv/Studentenverwaltung.js @@ -422,22 +422,6 @@ export default { this.$refs.searchbar.abort(); this.$refs.searchbar.hideresult(); }, - handleReloadStudent_DEPR(students){ - // @reload-students="handleReloadStudent" - //TODO(Manu) delete - this.$refs.details.reload(); //reload simply without updateUrl - //this.selected = students; - - //analoge to url_studiensemester_kurzbz -/* this.$refs.stvList.updateUrl( - ApiStv.students.uid(students[0].uid,'CURRENT_SEMESTER'), - true - );*/ -/* this.$refs.stvList.updateUrl( - ApiStv.students.uid(students[0].uid,'CURRENT_SEMESTER'), - true - );*/ - } }, created() { if (!this.url_studiensemester_kurzbz) { diff --git a/public/js/components/Stv/Studentenverwaltung/Details.js b/public/js/components/Stv/Studentenverwaltung/Details.js index 95d791ef9..8312097af 100644 --- a/public/js/components/Stv/Studentenverwaltung/Details.js +++ b/public/js/components/Stv/Studentenverwaltung/Details.js @@ -46,10 +46,6 @@ export default { return Object.fromEntries(Object.entries(this.configStudents).filter(([ , value ]) => !value.showOnlyWithUid)); } return Object.fromEntries(Object.entries(this.configStudents).filter(([ , value ]) => !value.showOnlyWithUid && !value.showOnlyWithUid)); - }, - //for reloading component if data changes - headerKey() { - return this.students?.[0]?.uid || this.localStudent?.[0]?.uid || "empty"; } }, watch: { @@ -57,21 +53,21 @@ export default { if (n !== o && o !== undefined) this.loadConfig(); }, - //ohne zusätzlichen Watcher reload header und details currentSemester(newVal) { if ( - this.students && - this.students.length > 0 && + Array.isArray(this.students) && + this.students.length === 1 && newVal !== this.students[0].query_studiensemester_kurzbz ) { - console.log("studiensemester_kurzbz " + this.students[0].query_studiensemester_kurzbz + " vs " + newVal); this.reloadDataStudent(); } + else { + this.localStudent = null; + } }, - headerKey(newVal){ - this.reloadDataStudent(); + students() { + this.localStudent = null; } - }, methods: { loadConfig() { @@ -114,9 +110,6 @@ export default { created() { this.loadConfig(); }, - /* //TODO(remove) - * {{headerKey}} {{localStudent?.[0]?.uid}}
{{ students?.[0]?.uid }} - * */ template: `
@@ -124,16 +117,15 @@ export default {
Date: Thu, 12 Mar 2026 16:02:44 +0100 Subject: [PATCH 07/12] update phrase noTextInSem --- public/js/components/DetailHeader/DetailHeader.js | 2 +- system/phrasesupdate.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/public/js/components/DetailHeader/DetailHeader.js b/public/js/components/DetailHeader/DetailHeader.js index 53ed9eee4..fe51f4500 100644 --- a/public/js/components/DetailHeader/DetailHeader.js +++ b/public/js/components/DetailHeader/DetailHeader.js @@ -306,7 +306,7 @@ export default { | Status - {{$p.t('lehre', 'textNoStatus')}} + {{$p.t('lehre', 'textNoStatusInSem', { sem: currentSemester}) }} {{headerData[0].statusofsemester}} diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index e3e15482f..22cf066fd 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -56951,18 +56951,18 @@ I have been informed that I am under no obligation to consent to the transmissio array( 'app' => 'core', 'category' => 'lehre', - 'phrase' => 'textNoStatus', + 'phrase' => 'textNoStatusInSem', 'insertvon' => 'system', 'phrases' => array( array( 'sprache' => 'German', - 'text' => 'Kein Status', + 'text' => 'Kein Status im {sem}', 'description' => '', 'insertvon' => 'system' ), array( 'sprache' => 'English', - 'text' => 'No status', + 'text' => 'No status in {sem}', 'description' => '', 'insertvon' => 'system' ) From 2682ea75ab386c2956445f97a6ac153b05fc117c Mon Sep 17 00:00:00 2001 From: ma0068 Date: Thu, 12 Mar 2026 16:58:48 +0100 Subject: [PATCH 08/12] use only one endpoint for detailheader --- .../frontend/v1/detailheader/DetailHeader.php | 30 ------------------- .../frontend/v1/detailheader/Detailheader.php | 12 ++++++++ public/js/api/factory/detailHeader.js | 2 +- 3 files changed, 13 insertions(+), 31 deletions(-) delete mode 100644 application/controllers/api/frontend/v1/detailheader/DetailHeader.php diff --git a/application/controllers/api/frontend/v1/detailheader/DetailHeader.php b/application/controllers/api/frontend/v1/detailheader/DetailHeader.php deleted file mode 100644 index be9fad27a..000000000 --- a/application/controllers/api/frontend/v1/detailheader/DetailHeader.php +++ /dev/null @@ -1,30 +0,0 @@ - ['admin:r', 'assistenz:r'], - ]); - } - - //------------------------------------------------------------------------------------------------------------------ - // Public methods - - public function getSemesterStati($prestudent_id) - { - $this->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel'); - - $result = $this->PrestudentstatusModel->getAllPrestudentstatiWithStudiensemester($prestudent_id); - - $data = $this->getDataOrTerminateWithError($result); - - $this->terminateWithSuccess($data); - } - -} diff --git a/application/controllers/api/frontend/v1/detailheader/Detailheader.php b/application/controllers/api/frontend/v1/detailheader/Detailheader.php index ada10c5b6..e35885efa 100644 --- a/application/controllers/api/frontend/v1/detailheader/Detailheader.php +++ b/application/controllers/api/frontend/v1/detailheader/Detailheader.php @@ -12,6 +12,7 @@ class Detailheader extends FHCAPI_Controller 'getHeader' => ['vertrag/mitarbeiter:r'], 'getPersonAbteilung' => ['vertrag/mitarbeiter:r'], 'getLeitungOrg' => ['vertrag/mitarbeiter:r'], + 'getSemesterStati' => ['admin:r', 'assistenz:r'] ]); } @@ -48,6 +49,17 @@ class Detailheader extends FHCAPI_Controller $this->terminateWithSuccess(current($data)); } + public function getSemesterStati($prestudent_id) + { + $this->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel'); + + $result = $this->PrestudentstatusModel->getAllPrestudentstatiWithStudiensemester($prestudent_id); + + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data); + } + } diff --git a/public/js/api/factory/detailHeader.js b/public/js/api/factory/detailHeader.js index 4b40d0c7f..02a371f15 100644 --- a/public/js/api/factory/detailHeader.js +++ b/public/js/api/factory/detailHeader.js @@ -37,7 +37,7 @@ export default { getSemesterStati(prestudent_id){ return { method: 'get', - url: 'api/frontend/v1/detailheader/DetailHeader/getSemesterStati/' + prestudent_id, + url: 'api/frontend/v1/detailheader/detailheader/getSemesterStati/' + prestudent_id, }; }, } \ No newline at end of file From 29a4b4aadc744cce19061767e77513907afca3b4 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Fri, 13 Mar 2026 09:11:00 +0100 Subject: [PATCH 09/12] use permission PERM_LOGGED for header, add condition one empty space for showing verband --- .../api/frontend/v1/detailheader/Detailheader.php | 8 ++++---- public/js/components/DetailHeader/DetailHeader.js | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/application/controllers/api/frontend/v1/detailheader/Detailheader.php b/application/controllers/api/frontend/v1/detailheader/Detailheader.php index e35885efa..719afb2c6 100644 --- a/application/controllers/api/frontend/v1/detailheader/Detailheader.php +++ b/application/controllers/api/frontend/v1/detailheader/Detailheader.php @@ -9,10 +9,10 @@ class Detailheader extends FHCAPI_Controller public function __construct() { parent::__construct([ - 'getHeader' => ['vertrag/mitarbeiter:r'], - 'getPersonAbteilung' => ['vertrag/mitarbeiter:r'], - 'getLeitungOrg' => ['vertrag/mitarbeiter:r'], - 'getSemesterStati' => ['admin:r', 'assistenz:r'] + 'getHeader' => self::PERM_LOGGED, + 'getPersonAbteilung' => self::PERM_LOGGED, + 'getLeitungOrg' => self::PERM_LOGGED, + 'getSemesterStati' => self::PERM_LOGGED, ]); } diff --git a/public/js/components/DetailHeader/DetailHeader.js b/public/js/components/DetailHeader/DetailHeader.js index fe51f4500..d3c23185e 100644 --- a/public/js/components/DetailHeader/DetailHeader.js +++ b/public/js/components/DetailHeader/DetailHeader.js @@ -293,9 +293,9 @@ export default { {{headerData[0].stg_bezeichnung}} ({{headerData[0].studiengang}}) | {{$p.t('lehre', 'semester')}} {{headerData[0].semester}} - | {{$p.t('lehre', 'verband')}} + | {{$p.t('lehre', 'verband')}} {{headerData[0].verband}} - | {{$p.t('lehre', 'gruppe')}} + | {{$p.t('lehre', 'gruppe')}} {{headerData[0].gruppe}} From df124db84a8c4f4bff02c5d5f983fd99bd4484b6 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Fri, 13 Mar 2026 12:40:29 +0100 Subject: [PATCH 10/12] use primeVue Skeleton while loading Data for Semester, Verband and Gruppe --- .../components/DetailHeader/DetailHeader.js | 121 ++++++++++-------- 1 file changed, 66 insertions(+), 55 deletions(-) diff --git a/public/js/components/DetailHeader/DetailHeader.js b/public/js/components/DetailHeader/DetailHeader.js index d3c23185e..dfd15e0be 100644 --- a/public/js/components/DetailHeader/DetailHeader.js +++ b/public/js/components/DetailHeader/DetailHeader.js @@ -1,11 +1,13 @@ import ApiDetailHeader from "../../api/factory/detailHeader.js"; import ApiHandleFoto from "../../api/factory/fotoHandling.js"; import ModalUploadFoto from "./Modal/UploadFoto.js"; +import PvSkeleton from "../../../../index.ci.php/public/js/components/primevue/skeleton/skeleton.esm.min.js"; export default { name: 'DetailHeader', components: { - ModalUploadFoto + ModalUploadFoto, + PvSkeleton }, props: { headerData: { @@ -276,67 +278,76 @@ export default { {{person.uid}}
-
-
-

- {{headerData[0].titelpre}} - {{headerData[0].vorname}} - {{headerData[0].nachname}} - , - {{headerData[0].titelpost}} -

-
unruly
-
+
+
+

+ {{headerData[0].titelpre}} + {{headerData[0].vorname}} + {{headerData[0].nachname}} + , + {{headerData[0].titelpost}} +

+
unruly
+
-
- {{$p.t('lehre', 'studiengang')}} - {{headerData[0].stg_bezeichnung}} ({{headerData[0].studiengang}}) +
+ {{$p.t('lehre', 'studiengang')}} + {{headerData[0].stg_bezeichnung}} ({{headerData[0].studiengang}}) + + +
-
- Email - - {{headerData[0].mail_intern}} - - | Status - - {{$p.t('lehre', 'textNoStatusInSem', { sem: currentSemester}) }} - - - {{headerData[0].statusofsemester}} - -
- -
-
-
-
- -
-
-

-
-
-
-

-
-
-
-

-
-
-
-

UID

-
-
+
+ Email + + {{headerData[0].mail_intern}} + + | Status + + {{$p.t('lehre', 'textNoStatusInSem', { sem: currentSemester}) }} + + + {{headerData[0].statusofsemester}} + +
+
+
+
+
+ +
+
+

+
+
+
+

+
+
+
+

+
+
+
+

UID

+
+
From c49e32c4ac1db69046d41cfb49ca7747e8f86fe7 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Mon, 16 Mar 2026 11:26:23 +0100 Subject: [PATCH 11/12] use skeletons for all data in studentHeader --- .../components/DetailHeader/DetailHeader.js | 68 +++++++++++++++---- .../Stv/Studentenverwaltung/Details.js | 4 ++ 2 files changed, 59 insertions(+), 13 deletions(-) diff --git a/public/js/components/DetailHeader/DetailHeader.js b/public/js/components/DetailHeader/DetailHeader.js index dfd15e0be..be335114b 100644 --- a/public/js/components/DetailHeader/DetailHeader.js +++ b/public/js/components/DetailHeader/DetailHeader.js @@ -44,6 +44,10 @@ export default { currentSemester: { type: String, default: '' + }, + isLoading: { + type: Boolean, + default: false } }, computed: { @@ -107,7 +111,10 @@ export default { leitungData: {}, isFetchingIssues: false, noCurrentStatus: false, - semesterStatiLoading: false + semesterStatiLoading: false, + leitungOrgLoading: false, + departmentDataLoading: false, + headerDataLoading: false }; }, methods: { @@ -123,29 +130,40 @@ export default { }); }, getHeader(person_id) { + this.headerDataLoading = true; return this.$api .call(ApiDetailHeader.getHeader(person_id)) .then(result => { this.headerDataMa = result.data; - }) - .catch(this.$fhcAlert.handleSystemError); + .catch(this.$fhcAlert.handleSystemError) + .finally(() => { + this.headerDataLoading = false; + }); }, loadDepartmentData(mitarbeiter_uid) { + this.departmentDataLoading = true; return this.$api .call(ApiDetailHeader.getPersonAbteilung(mitarbeiter_uid)) .then(result => { this.departmentData = result.data; }) - .catch(this.$fhcAlert.handleSystemError); + .catch(this.$fhcAlert.handleSystemError) + .finally(() => { + this.departmentDataLoading = false; + }); }, getLeitungOrg(oekurzbz){ + this.leitungOrgLoading = true; return this.$api .call(ApiDetailHeader.getLeitungOrg(oekurzbz)) .then(result => { this.leitungData = result.data; }) - .catch(this.$fhcAlert.handleSystemError); + .catch(this.$fhcAlert.handleSystemError) + .finally(() => { + this.leitungOrgLoading = false; + }); }, async goToLeitung() { this.loadHeaderData(this.leitungData.person_id, this.leitungData.uid); @@ -205,7 +223,7 @@ export default { }) .catch(this.$fhcAlert.handleSystemError) .finally(() => { - this.semesterStatiLoading = false + this.semesterStatiLoading = false; }); }, setNoCurrentStatus() { @@ -279,7 +297,7 @@ export default {
-
+

{{headerData[0].titelpre}} {{headerData[0].vorname}} @@ -289,10 +307,19 @@ export default {

unruly
+
+ +
unruly
+
{{$p.t('lehre', 'studiengang')}} + {{headerData[0].stg_bezeichnung}} ({{headerData[0].studiengang}}) + + + +
-
+
Email - + {{headerData[0].mail_intern}} + + + | Status {{$p.t('lehre', 'textNoStatusInSem', { sem: currentSemester}) }} @@ -332,19 +362,31 @@ export default {

-
+
+ + +

-
+
+ + +

-
+
+ + +

UID

-
+
+ + +
diff --git a/public/js/components/Stv/Studentenverwaltung/Details.js b/public/js/components/Stv/Studentenverwaltung/Details.js index eb996eda0..bd5d42f9f 100644 --- a/public/js/components/Stv/Studentenverwaltung/Details.js +++ b/public/js/components/Stv/Studentenverwaltung/Details.js @@ -47,6 +47,9 @@ export default { } return Object.fromEntries(Object.entries(this.configStudents).filter(([ , value ]) => !value.showOnlyWithUid && !value.showOnlyWithUid)); }, + isLoading() { + return this.students === null; //null-> loading, [] -> empty, [...] -> data, necessary for skeleton in tiles + }, tile_PersId(){ let tile = this.students[0].person_id != null ? this.students[0].person_id : '-'; return tile; @@ -133,6 +136,7 @@ export default { typeHeader="student" @reload="reloadList" fotoEditable + :isLoading="isLoading" > From 17f94aabdf73eabf3ebafa1027b2c36ae0ccc4a1 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Mon, 16 Mar 2026 17:16:40 +0100 Subject: [PATCH 12/12] add loading skeletons for mitarbeiterHeader --- .../components/DetailHeader/DetailHeader.js | 94 +++++++++++++------ .../Stv/Studentenverwaltung/Details.js | 2 +- 2 files changed, 66 insertions(+), 30 deletions(-) diff --git a/public/js/components/DetailHeader/DetailHeader.js b/public/js/components/DetailHeader/DetailHeader.js index be335114b..ada6034fc 100644 --- a/public/js/components/DetailHeader/DetailHeader.js +++ b/public/js/components/DetailHeader/DetailHeader.js @@ -45,7 +45,7 @@ export default { type: String, default: '' }, - isLoading: { + isLoading: { //if true, then parent isLoading type: Boolean, default: false } @@ -80,7 +80,7 @@ export default { } else if (this.typeHeader === 'mitarbeiter') { if (!this.person_id || !this.mitarbeiter_uid || !this.domain) { throw new Error( - '[DetailHeader] "person_id", "mitarbeiter_uid", and "domain" are requried.' + '[DetailHeader] "person_id", "mitarbeiter_uid", and "domain" are required.' ) } this.loadHeaderData(this.person_id, this.mitarbeiter_uid); @@ -114,7 +114,7 @@ export default { semesterStatiLoading: false, leitungOrgLoading: false, departmentDataLoading: false, - headerDataLoading: false + headerDataMaLoading: false }; }, methods: { @@ -130,7 +130,7 @@ export default { }); }, getHeader(person_id) { - this.headerDataLoading = true; + this.headerDataMaLoading = true; return this.$api .call(ApiDetailHeader.getHeader(person_id)) .then(result => { @@ -138,7 +138,7 @@ export default { }) .catch(this.$fhcAlert.handleSystemError) .finally(() => { - this.headerDataLoading = false; + this.headerDataMaLoading = false; }); }, loadDepartmentData(mitarbeiter_uid) { @@ -260,7 +260,6 @@ export default {