refactores the modal out of the view into its own modal component

This commit is contained in:
Simon Gschnell
2024-01-02 12:50:04 +01:00
parent bb0656c480
commit ddab42123b
5 changed files with 234 additions and 224 deletions
+1
View File
@@ -96,6 +96,7 @@ class Profil extends Auth_Controller
}
//? status code 200 OK
$update_res->code = 200;
$update_res->retval = $this->ProfilChangeModel->getTimestamp($this->uid)->change_timestamp;
echo json_encode($update_res);
}
+1 -7
View File
@@ -97,13 +97,7 @@ const app = Vue.createApp({
}
},
getFormatedDate: function(date){
return [
date.getDate().toString().padStart(2,'0'),
(date.getMonth()+1).toString().padStart(2,'0'),
date.getFullYear(),
].join('/');
},
},
created(){
@@ -0,0 +1,197 @@
import BsModal from "../../Bootstrap/Modal.js";
import Alert from "../../Bootstrap/Alert.js";
const infos = {};
export default {
components: {
BsModal,
Alert,
},
mixins: [BsModal],
props: {
value: Object,
timestamp: Object,
/*
* NOTE(chris):
* Hack to expose in "emits" declared events to $props which we use
* in the v-bind directive to forward all events.
* @see: https://github.com/vuejs/core/issues/3432
*/
onHideBsModal: Function,
onHiddenBsModal: Function,
onHidePreventedBsModal: Function,
onShowBsModal: Function,
onShownBsModal: Function,
},
data() {
return {
editData: this.value,
editTimestamp: this.timestamp,
result: true,
info: null,
}
},
methods: {
test(){
console.log("test");
},
submitProfilChange(){
if(this.isEditDataChanged){
//? inserts new row in public.tbl_cis_profil_update
Vue.$fhcapi.UserData.editProfil(this.editData).then((res)=>{
this.result = {
editData: this.editData,
timestamp: res.data.retval,
};
this.hide();
if(res.data.error == 0){
Alert.popup("Ihre Anfrage wurde erfolgreich gesendet. Bitte warten Sie, während sich das Team um Ihre Anfrage kümmert.");
}else{
Alert.popup("Ein Fehler ist aufgetreten: "+ JSON.stringify(res.data.retval));
}
//
});
}
},
},
computed: {
getFormatedDate: function(){
return [
this.editTimestamp.getDate().toString().padStart(2,'0'),
(this.editTimestamp.getMonth()+1).toString().padStart(2,'0'),
this.editTimestamp.getFullYear(),
].join('/');
},
isEditDataChanged(){
return this.originalEditData != JSON.stringify(this.editData)
},
},
created() {
this.originalEditData = JSON.stringify(this.editData);
/*
if (infos[this.lehrveranstaltung_id]) {
this.info = infos[this.lehrveranstaltung_id];
} else {
axios
.get(
FHC_JS_DATA_STORAGE_OBJECT.app_root +
FHC_JS_DATA_STORAGE_OBJECT.ci_router +
"/components/Cis/Mylv/Info/" +
this.studien_semester +
"/" +
this.lehrveranstaltung_id
)
.then((res) => {
this.info = infos[this.lehrveranstaltung_id] = res.data.retval || [];
})
.catch(() => (this.info = {}));
} */
},
mounted() {
this.modal = this.$refs.modalContainer.modal;
},
popup(options) {
return BsModal.popup.bind(this)(null, options);
},
template: `
<bs-modal ref="modalContainer" v-bind="$props" body-class="" dialog-class="modal-lg" class="bootstrap-alert" backdrop="false" >
<template v-slot:title>
{{"Profil bearbeiten" }}
</template>
<template v-slot:default>
<!-- START OF THE ACCORDION
<pre>{{JSON.stringify(data)}}</pre>
<pre>{{JSON.stringify(result)}}</pre>-->
<div class="accordion accordion-flush" id="accordionFlushExample" >
<div class="accordion-item" v-for="(value,key) in editData ">
<h2 class="accordion-header" :id="'flush-headingOne'+key">
<button style="font-weight:500" class="accordion-button collapsed" type="button" data-bs-toggle="collapse" :data-bs-target="'#flush-collapseOne'+key" aria-expanded="false" :aria-controls="'flush-collapseOne'+key">
{{key.replace("_"," ")}}
</button>
</h2>
<!-- SHOWING ALL MAILS IN THE FIRST PART OF THE ACCORDION -->
<div :id="'flush-collapseOne'+key" class="accordion-collapse collapse" aria-labelledby="flush-headingOne" data-bs-parent="#accordionFlushExample">
<div class="accordion-body">
<div v-if="Array.isArray(value)" class="row gy-5">
<template v-for="(object,objectkey) in value" >
<div class="col-12 ">
<div class="row gy-3">
<div v-for="(propertyValue,propertyKey) in object" class="col-12" >
<div class="form-underline ">
<div class="form-underline-titel">
<label :for="propertyKey+'input'" >{{propertyKey}}</label>
</div>
<div>
<input class="form-control" :id="propertyKey+'input'" v-model="editData[key][objectkey][propertyKey]" :placeholder="propertyValue">
</div>
</div>
</div>
</div>
</div>
<hr class="mb-0" v-if="value[value.length-1] != object">
</template>
</div>
<div v-else class="row gy-3">
<div v-for="(propertyValue,propertyKey) in value" class="col-12">
<div class="form-underline ">
<div class="form-underline-titel">
<label :for="propertyKey+'input'" >{{propertyKey}}</label>
</div>
<div>
<input type="email" class="form-control" :id="propertyKey+'input'" v-model="editData[key][propertyKey]" :placeholder="propertyValue">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- -->
<!-- END OF THE ACCORDION -->
</template>
<!-- optional footer -->
<template v-if="editTimestamp || isEditDataChanged" v-slot:footer>
<p v-if="editTimestamp" class="flex-fill">Letzte Anfrage: {{getFormatedDate}}</p>
<button v-if="isEditDataChanged" @click="submitProfilChange" role="button" class="btn btn-primary">Senden</button>
</template>
<!-- end of optional footer -->
</bs-modal>`,
};
@@ -1,15 +1,14 @@
import fhcapifactory from "../../../apps/api/fhcapifactory.js";
import { CoreFilterCmpt } from "../../../components/filter/Filter.js";
import BsModal from "../../Bootstrap/Modal.js";
import Alert from "../../Bootstrap/Alert.js";
import EditProfil from "./EditProfil.js"
export default {
components: {
CoreFilterCmpt,
BsModal,
Alert,
EditProfil,
},
data() {
return {
@@ -124,57 +123,36 @@ export default {
props: {
data: Object,
/*
* NOTE(chris):
* Hack to expose in "emits" declared events to $props which we use
* in the v-bind directive to forward all events.
* @see: https://github.com/vuejs/core/issues/3432
onHideBsModal: Function,
onHiddenBsModal: Function,
onHidePreventedBsModal: Function,
onShowBsModal: Function,
onShownBsModal: Function
*/
},
methods: {
showModal() {
this.$refs.bsmodal.show()
},
hideModal() {
this.$refs.bsmodal.hide();
},
submitProfilChange(){
if(this.isEditDataChanged){
//? inserts new row in public.tbl_cis_profil_update
Vue.$fhcapi.UserData.editProfil(this.data.editData).then((res)=>{
this.hideModal();
if(res.data.error == 0){
//? sets the requested changes as the current data state, so that computed property isEditDataChanged works properly
this.originalEditData = JSON.stringify(this.data.editData);
console.log(this.originalEditData != JSON.stringify(this.data.editData));
//* sets the returned timestamp from the response
this.data.editDataTimestamp = res.data.retval? new Date(res.data.retval) : null;
Alert.popup("Ihre Anfrage wurde erfolgreich gesendet. Bitte warten Sie, während sich das Team um Ihre Anfrage kümmert.");
}else{
Alert.popup("Ein Fehler ist aufgetreten: "+ res.data.retval);
EditProfil.popup({
value:JSON.parse(JSON.stringify(this.data.editData)),
timestamp:this.data.editDataTimestamp
}).then((res) => {
if(res.timestamp && res.editData){
this.data.editDataTimestamp = new Date(res.timestamp);
this.data.editData = res.editData;
}
//
}).catch((e) => {
console.log(e);
});
}
},
sperre_foto_function() {
if (!this.data) {
return;
}
fhcapifactory.UserData.sperre_foto_function(!this.data.foto_sperre).then((res) => {
Vue.$fhcapi.UserData.sperre_foto_function(!this.data.foto_sperre).then((res) => {
this.data.foto_sperre = res.data.foto_sperre;
});
},
@@ -200,9 +178,7 @@ export default {
},
isEditDataChanged(){
return this.originalEditData != JSON.stringify(this.data.editData)
},
get_mitarbeiter_standort_telefon(){
if(this.data.standort_telefon){
@@ -288,20 +264,16 @@ export default {
if(this.data.editData){
this.originalEditData = JSON.stringify(this.data.editData);
}else{
//? storing an original version of the editData to check if the editData was changed by the user and is not in the original state
this.originalEditData = JSON.stringify(
{
Personen_Informationen : {...this.personData, vorname: this.data.vorname, nachname: this.data.nachname},
Mitarbeiter_Informatinen: this.specialData,
Emails:this.data.emails,
Private_Kontakte: this.data.kontakte,
Private_Adressen:this.privateAdressen,
});
if(!this.data.editData){
this.data.editData = JSON.parse(this.originalEditData);
this.data.editData = {
Personen_Informationen : {...this.personData, vorname: this.data.vorname, nachname: this.data.nachname},
Mitarbeiter_Informatinen: this.specialData,
Emails:this.data.emails,
Private_Kontakte: this.data.kontakte,
Private_Adressen:this.privateAdressen,
};
}
},
@@ -323,8 +295,6 @@ export default {
template: `
<div class="row"><div class="col"><pre>{{JSON.stringify(JSON.parse(originalEditData),null,2)}}</pre></div><div class="col"><pre>{{JSON.stringify(data.editData,null,2)}}</pre></div></div>
<p>{{isEditDataChanged}}</p>
<div class="container-fluid text-break fhc-form" >
<!-- ROW -->
<div class="row">
@@ -531,95 +501,7 @@ export default {
</div>
</button>
<bs-modal ref="bsmodal" backdrop="false" >
<template v-slot:title>
{{"Profil bearbeiten" }}
</template>
<template v-slot:default>
<!-- START OF THE ACCORDION -->
<div class="accordion accordion-flush" id="accordionFlushExample" >
<div class="accordion-item" v-for="(value,key) in data.editData ">
<h2 class="accordion-header" :id="'flush-headingOne'+key">
<button style="font-weight:500" class="accordion-button collapsed" type="button" data-bs-toggle="collapse" :data-bs-target="'#flush-collapseOne'+key" aria-expanded="false" :aria-controls="'flush-collapseOne'+key">
{{key.replace("_"," ")}}
</button>
</h2>
<!-- SHOWING ALL MAILS IN THE FIRST PART OF THE ACCORDION -->
<div :id="'flush-collapseOne'+key" class="accordion-collapse collapse" aria-labelledby="flush-headingOne" data-bs-parent="#accordionFlushExample">
<div class="accordion-body">
<div v-if="Array.isArray(value)" class="row gy-5">
<template v-for="(object,objectkey) in value" >
<div class="col-12 ">
<div class="row gy-3">
<div v-for="(propertyValue,propertyKey) in object" class="col-12" >
<div class="form-underline ">
<div class="form-underline-titel">
<label :for="propertyKey+'input'" >{{propertyKey}}</label>
</div>
<div>
<input class="form-control" :id="propertyKey+'input'" v-model="data.editData[key][objectkey][propertyKey]" :placeholder="propertyValue">
</div>
</div>
</div>
</div>
</div>
<hr class="mb-0" v-if="value[value.length-1] != object">
</template>
</div>
<div v-else class="row gy-3">
<div v-for="(propertyValue,propertyKey) in value" class="col-12">
<div class="form-underline ">
<div class="form-underline-titel">
<label :for="propertyKey+'input'" >{{propertyKey}}</label>
</div>
<div>
<input type="email" class="form-control" :id="propertyKey+'input'" v-model="data.editData[key][propertyKey]" :placeholder="propertyValue">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- -->
<!-- END OF THE ACCORDION -->
</template>
<!-- optional footer -->
<template v-if="data.editDataTimestamp || isEditDataChanged" v-slot:footer>
<p v-if="data.editDataTimestamp" class="flex-fill">Letzte Anfrage: {{$parent.getFormatedDate(data.editDataTimestamp)}}</p>
<button v-if="isEditDataChanged" @click="submitProfilChange" role="button" class="btn btn-primary">Senden</button>
</template>
<!-- end of optional footer -->
</bs-modal>
<!-- simml -->
@@ -853,12 +735,9 @@ export default {
<!-- FIRST TABLE -->
<div class="col-12 mb-4" >
<div class="card">
<div class="card-header">Funktionen </div>
<div class="card-body">
<core-filter-cmpt ref="funktionenTable" :tabulator-options="funktionen_table_options" tableOnly :sideMenu="false" />
</div>
</div>
</div>
<!-- SECOND TABLE -->
@@ -1,61 +0,0 @@
export default {
data() {
return {
};
},
props: ["editData"],
methods: {
},
computed: {
},
mounted() {
console.log(this.editData);
},
template: `
<!-- Modal -->
<div class="modal fade" id="editProfil" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="editProfilLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="editProfilLabel">Edit Profil</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" @click="insertEditData" class="btn btn-primary">Understood</button>
</div>
</div>
</div>
</div>
<!-- end of trying the modal -->
`,
};