diff --git a/application/controllers/api/frontend/v1/detailheader/Detailheader.php b/application/controllers/api/frontend/v1/detailheader/Detailheader.php index ada10c5b6..719afb2c6 100644 --- a/application/controllers/api/frontend/v1/detailheader/Detailheader.php +++ b/application/controllers/api/frontend/v1/detailheader/Detailheader.php @@ -9,9 +9,10 @@ class Detailheader extends FHCAPI_Controller public function __construct() { parent::__construct([ - 'getHeader' => ['vertrag/mitarbeiter:r'], - 'getPersonAbteilung' => ['vertrag/mitarbeiter:r'], - 'getLeitungOrg' => ['vertrag/mitarbeiter:r'], + 'getHeader' => self::PERM_LOGGED, + 'getPersonAbteilung' => self::PERM_LOGGED, + 'getLeitungOrg' => self::PERM_LOGGED, + 'getSemesterStati' => self::PERM_LOGGED, ]); } @@ -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/application/controllers/api/frontend/v1/stv/Student.php b/application/controllers/api/frontend/v1/stv/Student.php index 7694807e7..4ee37c954 100644 --- a/application/controllers/api/frontend/v1/stv/Student.php +++ b/application/controllers/api/frontend/v1/stv/Student.php @@ -144,6 +144,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/application/controllers/api/frontend/v1/stv/Students.php b/application/controllers/api/frontend/v1/stv/Students.php index 34db64751..ae83fa4ff 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( diff --git a/public/js/api/factory/detailHeader.js b/public/js/api/factory/detailHeader.js index 3c7d95bb1..02a371f15 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/detailheader/detailheader/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 0b846df9c..ada6034fc 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: { @@ -38,6 +40,14 @@ export default { 'mitarbeiter', ].includes(value) } + }, + currentSemester: { + type: String, + default: '' + }, + isLoading: { //if true, then parent isLoading + type: Boolean, + default: false } }, computed: { @@ -60,8 +70,7 @@ export default { }, hasTileUIDSlot() { return !!this.$slots.uid - }, - + } }, created(){ if (this.typeHeader === 'student') { @@ -71,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); @@ -86,13 +95,26 @@ 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: {}, - isFetchingIssues: false + isFetchingIssues: false, + noCurrentStatus: false, + semesterStatiLoading: false, + leitungOrgLoading: false, + departmentDataLoading: false, + headerDataMaLoading: false }; }, methods: { @@ -108,29 +130,40 @@ export default { }); }, getHeader(person_id) { + this.headerDataMaLoading = 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.headerDataMaLoading = 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); @@ -179,6 +212,33 @@ export default { } else { return 'data:image/jpeg;base64,' + foto; } + }, + getSemesterStati(prestudent_id){ + this.semesterStatiLoading = true; + this.$api + .call(ApiDetailHeader.getSemesterStati(prestudent_id)) + .then(result => { + this.semesterStati = result.data; + this.setNoCurrentStatus(); + }) + .catch(this.$fhcAlert.handleSystemError) + .finally(() => { + this.semesterStatiLoading = false; + }); + }, + setNoCurrentStatus() { + if(!Array.isArray(this.semesterStati)) + { + this.noCurrentStatus = false; + } + + if(!this.semesterStati.some(item => item.studiensemester_kurzbz === this.currentSemester)) { + this.noCurrentStatus = true; + } + else + { + this.noCurrentStatus = false; + } } }, template: ` @@ -200,7 +260,6 @@ export default { @@ -330,27 +427,51 @@ export default {
-

{{headerDataMa.titelpre}} {{headerDataMa.vorname}} {{headerDataMa.nachname}}, {{headerDataMa.titelpost}}

- {{departmentData.organisationseinheittyp_kurzbz}} - {{departmentData.bezeichnung}} - | - Vorgesetzte*r - - {{leitungData.titelpre}} {{leitungData.vorname}} {{leitungData.nachname}} - -

- Email - - - {{ mitarbeiter_uid }}@{{ domain }} +

{{headerDataMa.titelpre}} {{headerDataMa.vorname}} {{headerDataMa.nachname}}, {{headerDataMa.titelpost}}

+

+
+ {{departmentData.organisationseinheittyp_kurzbz}} + + {{departmentData.bezeichnung}} + + + + + | + Vorgesetzte*r + + + {{leitungData.titelpre}} {{leitungData.vorname}} {{leitungData.nachname}} - {{headerDataMa.alias}}@{{domain}} + - | DW {{headerDataMa?.telefonklappe}} -

+
+ +
+
+ Email + + +
+ +
+ | + DW + + +
+
+ +
@@ -360,20 +481,33 @@ export default {

-
+
+ + +

-
+
+ + +

-
+
+ + +

UID

-
+
+ + +
+ diff --git a/public/js/components/Stv/Studentenverwaltung.js b/public/js/components/Stv/Studentenverwaltung.js index 5c887602c..c810fef91 100644 --- a/public/js/components/Stv/Studentenverwaltung.js +++ b/public/js/components/Stv/Studentenverwaltung.js @@ -251,6 +251,7 @@ export default { 'url_studiengang': function (newVal, oldVal) { if (newVal !== oldVal) { this.checkUrlStudiengang(); + this.$refs.stvList.clearSelection(); } }, 'url_mode': function () { diff --git a/public/js/components/Stv/Studentenverwaltung/Details.js b/public/js/components/Stv/Studentenverwaltung/Details.js index a03c7f50f..799030730 100644 --- a/public/js/components/Stv/Studentenverwaltung/Details.js +++ b/public/js/components/Stv/Studentenverwaltung/Details.js @@ -2,12 +2,18 @@ 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 export default { name: "DetailsPrestudent", + inject: { + currentSemester: { + from: 'currentSemester', + }, + }, components: { FhcTabs, FhcHeader @@ -16,7 +22,8 @@ export default { return { configStudent: {}, configStudents: {}, - activeTab: null + activeTab: null, + localStudent: null }; }, props: { @@ -41,6 +48,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 child + }, tile_PersId(){ let tile = this.students[0].person_id != null ? this.students[0].person_id : '-'; return tile; @@ -58,6 +68,21 @@ export default { '$p.user_language.value'(n, o) { if (n !== o && o !== undefined) this.loadConfig(); + }, + currentSemester(newVal) { + if ( + Array.isArray(this.students) && + this.students.length === 1 && + newVal !== this.students[0].query_studiensemester_kurzbz + ) { + this.reloadDataStudent(); + } + else { + this.localStudent = null; + } + }, + students() { + this.localStudent = null; } }, methods: { @@ -83,6 +108,20 @@ export default { if (this.$refs.tabs?.$refs?.current?.reload) this.$refs.tabs.$refs.current.reload(); }, + reloadDataStudent(){ + this.localStudent = null; + const studentArr = this.students; + + if (!studentArr || !studentArr.length) { + return; + } + + this.$api + .call(ApiStudent.uid(studentArr[0].uid, this.currentSemester)) + .then(result => { + this.localStudent = result.data; + }); + }, reloadList() { this.$emit('reload'); }, @@ -97,10 +136,12 @@ export default {
@@ -112,9 +153,9 @@ export default { 0 || deselected.length > 0){ + this.lastSelected = this.selected; + this.$emit('update:selected', data); + } //for tags this.selectedRows = this.$refs.table.tabulator.getSelectedRows(); this.selectedColumnValues = this.selectedRows.filter(row => row.getData().prestudent_id !== undefined && row.getData().prestudent_id).map(row => row.getData().prestudent_id); - - this.$emit('update:selected', data); }, autoSelectRows(data) { if (Array.isArray(this.lastSelected) && this.lastSelected.length){ @@ -571,6 +573,10 @@ export default { this.changeFocus(this.focusObj, el); } }, + clearSelection(){ + this.lastSelected = []; + this.$emit('update:selected',[]); + }, //methods tags addedTag(addedTag) { diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index 33105f18c..05bdfbbef 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -58357,6 +58357,26 @@ I have been informed that I am under no obligation to consent to the transmissio ) ) ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'textNoStatusInSem', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Kein Status im {sem}', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'No status in {sem}', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), );