adds breadcrumb to modal and adjusts controller functions and api calls

This commit is contained in:
SimonGschnell
2024-01-16 15:44:04 +01:00
parent 73792d1e78
commit b53dec6a31
8 changed files with 174 additions and 206 deletions
+22 -18
View File
@@ -22,7 +22,7 @@ class Profil extends Auth_Controller
'insertProfilRequest' => ['student/anrechnung_beantragen:r', 'user:r'],
'updateProfilRequest' => ['student/anrechnung_beantragen:r', 'user:r'],
'deleteProfilRequest' => ['student/anrechnung_beantragen:r', 'user:r'],
'selectProfilRequest' => ['student/anrechnung_beantragen:r', 'user:r'],
]);
$this->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel');
@@ -67,7 +67,23 @@ class Profil extends Auth_Controller
public function selectProfilRequest(){
$uid =json_decode($this->input->get("uid"));
$id =json_decode($this->input->get("id"));
if($uid && $id){
$res= $this->ProfilChangeModel->getProfilUpdate($uid, $id);
}elseif($uid){
$res= $this->ProfilChangeModel->getProfilUpdate($uid);
}elseif($id){
$res= $this->ProfilChangeModel->getProfilUpdate($this->uid, $id);
}else{
$res= $this->ProfilChangeModel->getProfilUpdate($this->uid);
}
echo json_encode($res);
}
public function insertProfilRequest()
{
@@ -151,11 +167,8 @@ class Profil extends Auth_Controller
public function deleteProfilRequest(){
$json = json_decode($this->input->raw_input_stream);
$delete_res = $this->ProfilChangeModel->delete([$json]);
echo json_encode($delete_res);
}
@@ -297,8 +310,6 @@ class Profil extends Auth_Controller
private function viewStudentProfil($uid)
{
if (
isSuccess($this->PersonModel->addSelect('gruppe_kurzbz, beschreibung')) &&
isSuccess($this->PersonModel->addJoin('tbl_benutzer', 'person_id')) &&
@@ -555,7 +566,7 @@ class Profil extends Auth_Controller
//? querying if the user has profil update requests
$profilUpdates = $this->ProfilChangeModel->loadWhere(["uid"=>$this->uid]);
$profilUpdates = $this->ProfilChangeModel->getProfilUpdate($this->uid);
if(isError($profilUpdates)){
//error handling
}else{
@@ -604,11 +615,8 @@ class Profil extends Auth_Controller
$res->standort_telefon = $telefon_res;
$res->profilUpdates = $profilUpdates?: null;
if($res->profilUpdates){
foreach($res->profilUpdates as $update){
$update->requested_change = json_decode($update->requested_change);
$update->change_timestamp = date_create($update->change_timestamp)->format('d.m.Y');
}}
return $res;
}
@@ -763,7 +771,7 @@ class Profil extends Auth_Controller
}
//? querying if the user has profil update requests
$profilUpdates = $this->ProfilChangeModel->loadWhere(["uid"=>$this->uid]);
$profilUpdates = $this->ProfilChangeModel->getProfilUpdate($this->uid);
if(isError($profilUpdates)){
//error handling
}else{
@@ -810,11 +818,7 @@ class Profil extends Auth_Controller
$res->mailverteiler = $mailverteiler_res;
$res->profilUpdates = $profilUpdates?: null;
if($res->profilUpdates){
foreach($res->profilUpdates as $update){
$update->requested_change = json_decode($update->requested_change);
$update->change_timestamp = date_create($update->change_timestamp)->format('d.m.Y');
}}
return $res;
@@ -15,7 +15,8 @@ class Profil_change_model extends DB_Model
}
/**
* getLastStatuses
* getTimestamp
* returns insert or update timestamp of a certain profil update
*/
public function getTimestamp($uid){
$this->addSelect(['change_timestamp']);
@@ -23,4 +24,31 @@ class Profil_change_model extends DB_Model
return hasData($res) ? getData($res)[0]->change_timestamp : null;
}
/**
*
* getProfilUpdate
* returns a profil update with id
* returns all profil updates if id is set to null
*/
public function getProfilUpdate($uid,$id=null){
$whereClause = ["uid"=>$uid];
if(!is_null($id)){
$whereClause['profil_update_id']=$id;
}
$res = $this->loadWhere($whereClause);
if(isError($res)){
// catch error
}else{
if(hasData($res)){
foreach($res->retval as $update){
$update->requested_change = json_decode($update->requested_change);
$update->change_timestamp = date_create($update->change_timestamp)->format('d.m.Y');
}
}
}
return $res;
}
}
+7
View File
@@ -3,6 +3,13 @@ export default {
//! API Calls for Profil Views
selectProfilRequest: function(uid=null,id=null) {
const url = FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router+
`/Cis/Profil/selectProfilRequest?uid=${uid}&id=${id}`;
return axios.get(url);
},
insertProfilRequest: function(topic, payload) {
const url = FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router+
`/Cis/Profil/insertProfilRequest`;
+26 -66
View File
@@ -1,20 +1,17 @@
import BsModal from "../../Bootstrap/Modal.js";
import Alert from "../../Bootstrap/Alert.js";
import BreadCrumb from "../Selection/Breadcrumb.js";
import EditProfilSelect from "./EditProfilSelect.js";
export default {
components: {
BsModal,
Alert,
BreadCrumb,
EditProfilSelect,
},
mixins: [BsModal],
props: {
value: Object,
timestamp: Object,
/*
* NOTE(chris):
@@ -30,31 +27,12 @@ export default {
},
data() {
return {
propertySelected: false,
testValue:null,
testListe:{
privateInfo:{username:"hans33",Titel:"Doktor", Anrede:"Herr"},
privateKontakte:[{strasse:"strasse1",plz:100},{strasse:"strasse1",plz:100},{strasse:"strasse1",plz:100}],
privateAdressen:[{kontakt:"telefon",anmerkung:"1"},{kontakt:"email",anmerkung:"2"},{kontakt:"telefon",anmerkung:"3"}]
},
testSelectedItems:[],
profilUpdate:null,
topic:null,
firstSelectedOption:null,
secondSelectedOption: null,
secondSelectedOptionIndex: null,
inputField:null,
profilUpdate:null,
editData: this.value,
//? tracks what specific profil data was changed
changesData: {},
editTimestamp: this.timestamp,
breadcrumb:null,
result: true,
result: false,
info: null,
}
},
@@ -62,69 +40,44 @@ export default {
methods: {
selectEvent: function (option){
this.editData = this.editData[option];
},
createDeepCopy: function(object){
//? using Vue.toRaw because deep clones with structuredClone can not be done on proxies
return structuredClone(Vue.toRaw(object));
},
changeInput: function(event, inputField,index){
let newValue = event.target.value? event.target.value: null;
inputField[index] = newValue;
},
submitProfilChange(){
//* only inserts new row if the inputField value is different from the original value
if(this.topic && this.profilUpdate){
if(this.topic && this.profilUpdate){
//? inserts new row in public.tbl_cis_profil_update
if(this.editData.update){
Vue.$fhcapi.UserData.updateProfilRequest(this.topic,this.profilUpdate).then((res)=>{
this.result = {
editData: this.editData,
timestamp: res.data.retval,
};
this.hide();
if(res.data.error == 0){
this.result= true;
this.hide();
Alert.popup("Ihre Anfrage wurde erfolgreich gesendet. Bitte warten Sie, während sich das Team um Ihre Anfrage kümmert.");
}else{
this.result= false;
this.hide();
Alert.popup("Ein Fehler ist aufgetreten: "+ JSON.stringify(res.data.retval));
}
//
});
//
}else{
Vue.$fhcapi.UserData.insertProfilRequest(this.topic,this.profilUpdate).then((res)=>{
this.result = {
editData: this.editData,
timestamp: res.data.retval,
};
this.hide();
if(res.data.error == 0){
this.result= true;
this.hide();
Alert.popup("Ihre Anfrage wurde erfolgreich gesendet. Bitte warten Sie, während sich das Team um Ihre Anfrage kümmert.");
}else{
this.result= false;
this.hide();
Alert.popup("Ein Fehler ist aufgetreten: "+ JSON.stringify(res.data.retval));
}
//
});
}
}
@@ -135,7 +88,7 @@ export default {
created() {
if(this.editData.topic){
//? if the topic was passed through the prop add it to the reactive data
//? if the topic was passed through the prop add it to the component
this.topic = this.editData.topic;
}
@@ -145,7 +98,6 @@ export default {
this.modal = this.$refs.modalContainer.modal;
},
popup(options) {
console.log("popup start");
return BsModal.popup.bind(this)(null, options);
},
template: `
@@ -156,7 +108,15 @@ export default {
{{"Profil bearbeiten" }}
</template>
<template v-slot:default>
<edit-profil-select v-model:topic="topic" v-model:profilUpdate="profilUpdate" ariaLabel="test" :list="editData"></edit-profil-select>
<nav aria-label="breadcrumb" class="ps-2 ">
<ol class="breadcrumb ">
<li class="breadcrumb-item" v-for="element in breadcrumb">{{element}}</li>
</ol>
</nav>
<edit-profil-select v-model:breadcrumb="breadcrumb" v-model:topic="topic" v-model:profilUpdate="profilUpdate" ariaLabel="test" :list="editData"></edit-profil-select>
</template>
@@ -25,6 +25,7 @@ export default {
},
profilUpdate:String,
topic:String,
breadcrumb:String,
},
@@ -32,6 +33,7 @@ export default {
//? update:modelValue event is needed to notify the v-model when the value has changed
['update:profilUpdate']:null,
['update:topic']:null,
['update:breadcrumb']:null,
select:null,
},
@@ -39,6 +41,7 @@ export default {
return {
view:null,
data:null,
breadcrumbItems:[],
}
},
@@ -52,44 +55,35 @@ export default {
this.data=item.data;
this.view=item.view;
//? emits the selected topic to the parent component
if(item.title){
//? emits the selected topic to the parent component
this.$emit('update:topic',item.title);
//? emits the new item for the breadcrumb in the parent component
this.breadcrumbItems.push(item.title);
}else{
if(item.data.kontakttyp){
this.breadcrumbItems.push(item.data.kontakttyp);
this.breadcrumbItems.push(item.data.kontakt);
}else if(item.data.strasse){
this.breadcrumbItems.push(item.data.strasse);
}
}
this.$emit('update:breadcrumb',this.breadcrumbItems);
},
},
computed: {
listLength: function(){
return this.list.length;
},
lastElement: function(){
return this.list[this.list.length-1];
},
computedList: function(){
if(Array.isArray(this.list)){
//? the passed data is an array
return this.list;
}else if(typeof(this.list) === 'object' && this.list !== null){
//? the passed data is an object
return Object.keys(this.list);
}else{
console.warn("The passed data is neither an Array or an Object");
return null;
//! the passed data is neither an object or an array
}
}
},
created() {
this.data = JSON.parse(JSON.stringify(this.list.data));
this.view = JSON.parse(JSON.stringify(this.list.view));
//? sets the default length of the options to show equal to the number of elements in the list
if(!this.optionLength){
//? if it is an object, then it will take the length of the object keys, otherwise it takes the normal length
this.optionLength = this.computedList.length;
}
},
mounted() {
},
@@ -122,31 +122,43 @@ export default {
props: {
data: Object,
},
methods: {
fetchProfilUpdates: function(){
Vue.$fhcapi.UserData.selectProfilRequest().then((res)=>{
if(!res.error){
this.data.profilUpdates = res.data.retval?.length ? res.data.retval : null ;
}
});
},
showModal() {
EditProfil.popup({
value:JSON.parse(JSON.stringify(this.data.editData)),
timestamp:this.data.editDataTimestamp
}).then((res) => {
if(res.timestamp && res.editData){
this.data.editDataTimestamp = res.timestamp;
this.data.editData = res.editData;
}).then((popup_result) => {
if(popup_result){
Vue.$fhcapi.UserData.selectProfilRequest()
.then((res) =>{
if(!res.error){
this.data.profilUpdates = res.data.retval;
}else{
alert("Error when fetching profile updates: " +res.data.retval);
}
})
.catch(err=>alert(err));
}
}).catch((e) => {
console.log(e);
});
},
sperre_foto_function() {
if (!this.data) {
@@ -161,15 +173,11 @@ export default {
computed: {
//? legacy mailto link to create an email with information that should be changed
refreshMailTo() {
return `mailto:info.mio@technikum-wien.at?subject=Datenkorrektur&body=Die%20Profildaten%20für%20User%20'${this.data.username}'%20sind%20nicht%20korrekt.%0DHier, die richtigen Daten:%0A%0ANachname:%20${this.data.nachname}%0AVorname:%20${this.data.vorname}%0AGeburtsdatum:${this.data.gebdatum}%0AGeburtsort:%20${this.data.gebort}%0ATitelPre:${this.data.titel}%20%0ATitelPost:${this.data.postnomen}%20%0A%0A***%0DPlatz für weitere (nicht angeführte Daten)%0D***%0A%0A[Bitte%20übermitteln%20Sie%20uns%20etwaige%20Dokumente%20zum%20Beleg%20der%20Änderung]`;
},
get_image_base64_src() {
if (!this.data) {
return "";
@@ -177,9 +185,6 @@ export default {
return "data:image/jpeg;base64," + this.data.foto;
},
get_mitarbeiter_standort_telefon(){
if(this.data.standort_telefon){
return "tel:"+ this.data.telefonklappe + this.data.standort_telefon;
@@ -320,7 +325,7 @@ export default {
};
console.log(JSON.stringify(this.data.editData,null,2));
},
mounted() {
@@ -332,10 +337,6 @@ export default {
this.$refs.funktionenTable.tabulator.setData(this.data.funktionen);
});
},
template: `
@@ -378,7 +379,8 @@ export default {
<div class="card-header">
Profil Informations Änderungen Anfragen</div>
<div class="card-body">
<fetch-profil-updates></fetch-profil-updates>
<fetch-profil-updates @fetchUpdates="fetchProfilUpdates" :data="data.profilUpdates"></fetch-profil-updates>
</div>
</div>
@@ -761,15 +763,16 @@ export default {
<!-- START OF THE FIRDT ROW IN THE SIDE PANEL -->
<!-- THESE QUCK LINKS ARE ONLY VISIBLE UNTIL VIEWPORT MD -->
<div class="row d-none d-md-block mb-3">
<div v-if="data.profilUpdates" class="row d-none d-md-block mb-3">
<div class="col mb-3">
<div class="card">
<div class="card">
<div class="card-header">
Profil Updates
</div>
<fetch-profil-updates :modal="EditProfil" :data="data.profilUpdates"></fetch-profil-updates>
</div>
<div class="card-body">
<fetch-profil-updates @fetchUpdates="fetchProfilUpdates" :data="data.profilUpdates"></fetch-profil-updates>
</div>
</div>
@@ -195,7 +195,7 @@ const EditKontakt = {
},
},
created(){
console.log(this.$props);
},
template:
`
@@ -240,7 +240,7 @@ const EditKontakt = {
<span style="opacity: 0.65; font-size: .85rem; " class="px-2">Zustellungs Adresse</span>
<span style="opacity: 0.65; font-size: .85rem; " class="px-2">Zustellungs Kontakt</span>
<input class="form-check-input " type="checkbox" :checked="data.zustellung" @change="updateValue($event,'zustellung')" id="flexCheckDefault">
@@ -261,21 +261,28 @@ const FetchProfilUpdates = {
data:{
type:Object,
},
},
emits:["fetchUpdates"],
data(){
return {}
return {
}
},
methods:{
deleteRequest: function(item){
Vue.$fhcapi.UserData.deleteProfilRequest(item.profil_update_id).then((res)=>{
console.log(res);
if(res.data.error){
//? open alert
console.log(res.data);
}else{
this.$emit('fetchUpdates');
}
});
},
getView: function(topic){
console.log("the topic is here",topic);
switch(topic){
case "Private Kontakte" : return "EditKontakt"; break;
case "Private Adressen" : return "EditAdresse"; break;
@@ -316,10 +323,9 @@ const FetchProfilUpdates = {
value:content,
timestamp:null,
}).then((res) => {
/* if(res.timestamp && res.editData){
this.data.editDataTimestamp = res.timestamp;
this.data.editData = res.editData;
} */
if(res === true){
this.$emit('fetchUpdates');
}
}).catch(e => {
console.log(e);
@@ -333,28 +339,31 @@ const FetchProfilUpdates = {
},
created(){
},
computed:{
},
template:`
<pre>{{JSON.stringify(data,null,2)}}</pre>
<table class="table table-sm table-hover">
<thead>
<tr >
<th scope="col">Topic</th>
<th scope="col">Date of Request</th>
<th scope="col">Bearbeiten</th>
<th scope="col">Löschen</th>
</tr>
</thead>
<tbody>
<tr v-for="item in data">
<td >{{item.topic}}</td>
<td >{{item.change_timestamp}}</td>
<td class="text-center" ><i style="color:#00639c" @click="openModal(item)" role="button" class="fa fa-edit"></i></td>
<td class="text-center"><i style="color:red" role="button" @click="deleteRequest(item)" class="fa fa-trash"></i></td>
</tr>
</tbody>
</table>
<div class="table-responsive">
<table class="m-0 table table-hover">
<thead>
<tr >
<th scope="col">Topic</th>
<th scope="col">Date of Request</th>
<th scope="col">Bearbeiten</th>
<th style="white-space:normal" scope="col">Löschen</th>
</tr>
</thead>
<tbody>
<tr v-for="item in data">
<td class="align-middle">{{item.topic}}</td>
<td class="align-middle">{{item.change_timestamp}}</td>
<td class="align-middle text-center" ><i style="color:#00639c" @click="openModal(item)" role="button" class="fa fa-edit"></i></td>
<td class="align-middle text-center"><i style="color:red" role="button" @click="deleteRequest(item)" class="fa fa-trash"></i></td>
</tr>
</tbody>
</table>
</div>
`
};
@@ -1,37 +0,0 @@
export default {
components: {
},
props: {
//! this should throw an error in the js console, have to check later
list:Number,
},
data() {
return {
}
},
methods: {
},
computed: {
lastElement: function(){
return this.list[this.list.length-1];
}
},
created() {
},
mounted() {
},
template: `
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<!-- https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-current -->
<li class="breadcrumb-item" :class="{'active':element===lastElement}" :aria-current="element===lastElement?'page':'false'" v-for="element in list">{{element}}</li>
</ol>
</nav>`,
};