splits the ProfilComponents.js file into multiple components in the ProfilComponents Folder and StudentProfil uses the components

This commit is contained in:
SimonGschnell
2024-01-19 15:07:57 +01:00
parent 84b23a148e
commit 0d5e8e89a6
12 changed files with 572 additions and 1059 deletions
@@ -45,8 +45,7 @@ export default {
//? inserts new row in public.tbl_cis_profil_update
//* calls the update api call if an update field is present in the data that was passed to the module
Vue.$fhcapi.UserData[this.editData.update?'updateProfilRequest':'insertProfilRequest'](this.topic,this.profilUpdate).then((res)=>{
console.log("topic",this.topic);
console.log("profilUpdate",this.profilUpdate);
if(res.data.error == 0){
this.result= true;
this.hide();
@@ -79,7 +78,6 @@ export default {
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>
@@ -1,5 +1,7 @@
import {Kontakt, EditKontakt, Adresse, EditAdresse} from "./ProfilComponents.js";
import Kontakt from "./ProfilComponents/Kontakt.js";
import EditKontakt from "./ProfilComponents/EditKontakt.js";
import Adresse from "./ProfilComponents/Adresse.js";
import EditAdresse from "./ProfilComponents/EditAdresse.js";
export default {
components: {
@@ -91,7 +93,7 @@ export default {
},
profilUpdateEmit: function(event){
console.log(event);
//? passes the updated profil information to the parent component
this.$emit('update:profilUpdate',event);
},
@@ -1,7 +1,9 @@
import { CoreFilterCmpt } from "../../../components/filter/Filter.js";
import EditProfil from "./EditProfil.js";
import {Adresse, Kontakt, FetchProfilUpdates} from "./ProfilComponents.js";
import Adresse from "./ProfilComponents/Adresse.js";
import Kontakt from "./ProfilComponents/Kontakt.js";
import FetchProfilUpdates from "./ProfilComponents/FetchProfilUpdates.js";
import Mailverteiler from "./ProfilComponents/Mailverteiler.js";
import AusweisStatus from "./ProfilComponents/FhAusweisStatus.js";
import QuickLinks from "./ProfilComponents/QuickLinks.js";
@@ -165,7 +167,7 @@ export default {
}
}).catch((e) => {
console.log(e);
// Wenn der User das Modal abbricht ohne Änderungen
});
@@ -314,25 +316,23 @@ export default {
template: `
<div class="container-fluid text-break fhc-form" >
<!-- ROW -->
<div class="row">
<!-- HIDDEN QUICK LINKS -->
<div class="d-md-none col-12 ">
<div class="row mb-3">
<div class="col">
<!-- MOBILE QUICK LINKS -->
<quick-links :mobile="true"></quick-links>
</div>
</div>
<!-- HERE STARTS THE ROW WITH REQUESTED CHANGES FROM THE USER -->
<div class="row mb-3">
<div class="col">
<!-- MOBILE PROFIL UPDATES -->
<fetch-profil-updates @fetchUpdates="fetchProfilUpdates" :data="data.profilUpdates"></fetch-profil-updates>
</div>
</div>
@@ -342,10 +342,6 @@ export default {
<!-- END OF HIDDEN ROW (HIDDEN IN VIEWPORTS GREATER THEN-EQUAL MD) -->
<!-- MAIN PANNEL -->
<div class="col-sm-12 col-md-8 col-xxl-9 ">
<!-- ROW WITH PROFIL IMAGE AND INFORMATION -->
@@ -356,79 +352,49 @@ export default {
<!-- ROW WITH THE PROFIL INFORMATION -->
<div class="row mb-4">
<!-- FIRST KAESTCHEN -->
<div class="col-lg-12 col-xl-6 ">
<div class="row mb-4">
<div class="col">
<!-- PROFIL INFORMATION -->
<profil-information title="MitarbeiterIn" :data="profilInformation"></profil-information>
</div>
</div>
</div>
<div class="row mb-4">
<div class=" col-lg-12">
<!-- MITARBEITER INFO -->
<!-- MITARBEITER INFO -->
<role-information title="Mitarbeiter Information" :data="roleInformation"></role-information>
</div>
<!-- END OF THE FIRST KAESTCHEN -->
</div>
</div>
<!-- START OF SECOND PROFIL INFORMATION COLUMN -->
<!-- END OF PROFIL INFORMATION ROW -->
<!-- INFORMATION CONTENT END -->
</div>
<div class="col-xl-6 col-lg-12 ">
<div class="row mb-4">
<div class="col">
<!-- EMAILS -->
<profil-emails :data="personEmails" ></profil-emails>
</div>
</div>
</div></div>
<!-- HIER SIND DIE PRIVATEN KONTAKTE-->
<div class="row mb-4 ">
<div class="col">
<div class="card">
<!-- PRIVATE KONTAKTE-->
<div class="card">
<div class="card-header">
Private Kontakte
</div>
@@ -445,12 +411,14 @@ export default {
</div>
</div>
</div>
<!-- -->
<!-- HIER SIND DIE PRIVATEN ADRESSEN-->
<div class="row mb-4">
<div class="col">
<div class="card">
<!-- PRIVATE ADRESSEN-->
<div class="card">
<div class="card-header">Private Adressen</div>
<div class="card-body">
@@ -464,61 +432,51 @@ export default {
</div>
</div>
</div>
<!-- -->
<!-- END OF THE SECOND INFORMATION COLUMN -->
</div>
<!-- START OF THE SECOND PROFIL INFORMATION ROW -->
<!-- ROW WITH PROFIL IMAGE AND INFORMATION END -->
</div >
<!-- SECOND ROW UNDER THE PROFIL IMAGE AND INFORMATION WITH THE TABLES -->
<div class="row">
<!-- FIRST TABLE -->
<div class="col-12 mb-4" >
<!-- FUNKTIONEN TABELLE -->
<core-filter-cmpt title="Funktionen" ref="funktionenTable" :tabulator-options="funktionen_table_options" tableOnly :sideMenu="false" />
</div>
<!-- SECOND TABLE -->
<div class="col-12 mb-4" >
<!-- BETRIEBSMITTEL TABELLE -->
<core-filter-cmpt title="Entlehnte Betriebsmittel" ref="betriebsmittelTable" :tabulator-options="betriebsmittel_table_options" tableOnly :sideMenu="false" />
</div>
<!-- END OF THE ROW WITH THE TABLES UNDER THE PROFIL INFORMATION -->
</div>
<!-- END OF MAIN CONTENT COL -->
</div>
<!-- START OF SIDE PANEL -->
<div class="col-md-4 col-xxl-3 col-sm-12 text-break" >
<!-- Bearbeiten Button -->
<div class="row d-none d-md-block mb-3">
<div class="col mb-3">
<button @click="showModal" type="button" class="text-start w-100 btn btn-outline-secondary" >
<div class="row">
<div class="col-2">
<i class="fa fa-edit"></i>
</div>
<div class="col-10">Bearbeiten</div>
</div>
</button>
</div>
</div>
<div v-if="data.profilUpdates" class="row d-none d-md-block mb-3">
<div class="col mb-3">
@@ -1,422 +0,0 @@
const Adresse = {
props:{data:Object, view:String},
data(){
return{}
},
created(){
},
template:`
<div class="gy-2 row justify-content-center align-items-center">
<!-- column 1 in the address row -->
<div class="col-1 text-center">
<i class="fa fa-location-dot fa-lg" style="color:#00649C "></i>
</div>
<div class="col-11 col-sm-8 col-xl-11 col-xxl-8 order-1">
<div class="form-underline ">
<div class="form-underline-titel">Strasse</div>
<span class="form-underline-content">{{data.strasse}} </span>
</div>
</div>
<!-- column 2 in the address row -->
<div class="offset-1 offset-sm-0 offset-xl-1 offset-xxl-0 order-2 order-sm-4 order-xl-2 order-xxl-4 col-11 col-sm-5 col-xl-11 col-xxl-5 ">
<div class="form-underline ">
<div class="form-underline-titel">Typ</div>
<span class="form-underline-content">{{data.adr_typ}} </span>
</div>
</div>
<div class="offset-1 order-3 order-sm-3 col-11 col-sm-6 col-xl-7 col-xxl-6 ">
<div class="form-underline ">
<div class="form-underline-titel">Ort</div>
<span class="form-underline-content">{{data.ort}} </span>
</div>
</div>
<div class="offset-1 offset-sm-0 order-4 order-sm-2 order-xl-4 order-xxl-2 col-11 col-sm-3 col-xl-4 col-xxl-3 ">
<div class="form-underline ">
<div class="form-underline-titel">PLZ</div>
<span class="form-underline-content">{{data.plz}} </span>
</div>
</div>
</div>
`
};
const EditAdresse = {
props:{data:Object},
data(){
return{
originalValue:null,
}
},
methods:{
updateValue: function(event,bind){
//? sets the value of a property to null when an empty string is entered to keep the isChanged function valid
this.data[bind] = event.target.value === "" ? null : event.target.value;
this.$emit('profilUpdate',this.isChanged?this.data:null);
},
},
computed:{
isChanged: function(){
return this.originalValue !== JSON.stringify(this.data);
},
},
created(){
this.originalValue = JSON.stringify(this.data);
},
template:`
<div class="gy-3 row justify-content-center align-items-center">
<!-- column 1 in the address row -->
<div class="col-12 col-sm-9 col-xl-12 col-xxl-9 order-1">
<div class="form-underline ">
<div class="form-underline-titel">Strasse</div>
<input class="form-control" :value="data.strasse" @input="updateValue($event,'strasse')" :placeholder="data.strasse">
</div>
</div>
<!-- column 2 in the address row -->
<div class=" order-2 order-sm-4 order-xl-3 order-xxl-4 col-12 col-sm-5 col-xl-8 col-xxl-5 ">
<div class="form-underline ">
<div class="form-underline-titel">Typ</div>
<input class="form-control" :value="data.adr_typ" @input="updateValue($event,'adr_typ')" :placeholder="data.adr_typ">
</div>
</div>
<div class="order-3 order-sm-3 order-xl-2 order-xxl-3 col-12 col-sm-7 col-xl-12 col-xxl-7 ">
<div class="form-underline ">
<div class="form-underline-titel">Ort</div>
<input class="form-control" :value="data.ort" @input="updateValue($event,'ort')" :placeholder="data.ort">
</div>
</div>
<div class="order-4 order-sm-2 order-xl-4 order-xxl-2 col-12 col-sm-3 col-xl-4 col-xxl-3 ">
<div class="form-underline ">
<div class="form-underline-titel">PLZ</div>
<input class="form-control" :value="data.plz" @input="updateValue($event,'plz')" :placeholder="data.plz">
</div>
</div>
</div>
`
};
const Kontakt = {
props:{
view:String,
data:Object,
},
data(){
return {
}
},
created(){
},
template:`
<div class=" row align-items-center justify-content-center">
<div class="col-1 text-center" >
<i class="fa-solid " :class="{...(data.kontakt.includes('@')?{'fa-envelope':true}:{'fa-phone':true})}" style="color:rgb(0, 100, 156)"></i>
</div>
<div :class="{...(data.anmerkung? {'col-11':true, 'col-md-6':true, 'col-xl-11':true, 'col-xxl-6':true} : {'col-10':true, 'col-xl-9':true, 'col-xxl-10':true})}">
<!-- rendering KONTAKT emails -->
<div class="form-underline ">
<div class="form-underline-titel">{{data.kontakttyp}}</div>
<a v-if="data.kontakt.includes('@')" role="link" :aria-disabled="view?true:false" :href="!view?('mailto:'+data.kontakt):null" class="form-underline-content">{{data.kontakt}} </a>
<a v-else role="link" :aria-disabled="view?true:false" :href="!view?('tel:'+data.kontakt):null" class="form-underline-content">{{data.kontakt}} </a>
</div>
</div>
<div v-if="data?.anmerkung" class="offset-1 offset-md-0 offset-xl-1 offset-xxl-0 order-2 order-sm-1 col-10 col-md-4 col-xl-9 col-xxl-4 ">
<div class="form-underline ">
<div class="form-underline-titel">Anmerkung</div>
<span class="form-underline-content">{{data.anmerkung}} </span>
</div>
</div>
<div class="text-center col-1 col-sm-1 order-2 order-lg-1 col-xl-2 col-xxl-1 allign-middle">
<i v-if="data.zustellung" class="fa-solid fa-check"></i>
<i v-else="data.zustellung" class="fa-solid fa-xmark"></i>
</div>
</div>
</div>
`,
};
const EditKontakt = {
props:{
data:Object,
},
data(){
return{
originalValue:null,
}
},
methods:{
updateValue: function(event,bind){
if(bind === 'zustellung'){
this.data[bind] = event.target.checked;
}else{
//? sets the value of a property to null when an empty string is entered to keep the isChanged function valid
this.data[bind] = event.target.value === "" ? null: event.target.value;
}
this.$emit('profilUpdate',this.isChanged?this.data:null);
},
},
computed:{
isChanged: function(){
//? returns true if the original passed data object was changed
return JSON.stringify(this.data) !== this.originalValue;
}
},
created(){
this.originalValue = JSON.stringify(this.data);
},
template:
`
<div class="gy-3 row align-items-center justify-content-center">
<div v-if="!data.kontakt_id" class="col-12">
<div class="form-underline">
<div class="form-underline-titel">Kontakttyp</div>
<select :value="data.kontakttyp" @change="updateValue($event,'kontakttyp')" class="form-select" aria-label="Select Kontakttyp">
<option selected></option>
<option value="email">Email</option>
<option value="telefon">Telefon</option>
<option value="notfallkontakt">Notfallkontakt</option>
</select>
</div>
</div>
<div class="col-12">
<!-- rendering KONTAKT emails -->
<div class="form-underline">
<div class="form-underline-titel">{{data.kontakttyp?data.kontakttyp:'Kontakt'}}</div>
<input :disabled="data.kontakttyp?false:true" class="form-control" :value="data.kontakt" @input="updateValue($event,'kontakt')" :placeholder="data.kontakt">
</div>
</div>
<div class="col-12">
<div class="form-underline">
<div class="form-underline-titel">Anmerkung</div>
<input class="form-control" :value="data.anmerkung" @input="updateValue($event,'anmerkung')" :placeholder="data.anmerkung">
</div>
</div>
<div class="d-flex flex-row justify-content-start col-12 allign-middle">
<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">
</div>
</div>
`
};
//? used to edit already requested profil changes
import EditProfil from "./EditProfil.js";
const FetchProfilUpdates = {
props:{
data:{
type:Object,
},
},
emits:["fetchUpdates"],
data(){
return {
}
},
methods:{
deleteRequest: function(item){
Vue.$fhcapi.UserData.deleteProfilRequest(item.profil_update_id).then((res)=>{
if(res.data.error){
//? open alert
console.log(res.data);
}else{
this.$emit('fetchUpdates');
}
});
},
getView: function(topic){
switch(topic){
case "Private Kontakte" : return "EditKontakt"; break;
case "Private Adressen" : return "EditAdresse"; break;
case "Add Adressen" : return "EditAdresse"; break;
case "Add Kontakte" : return "EditKontakt"; break;
case "Delete Adressen" : return "EditAdresse"; break;
case "Delete Kontakte" : return "EditKontakt"; break;
default: return "text_input"; break;
}
},
openModal(updateRequest) {
let view = this.getView(updateRequest.topic);
let content =null;
if(view === 'text_input'){
content={
view:view,
data:{
titel:updateRequest.topic,
value:updateRequest.requested_change,
},
update:true,
topic:updateRequest.topic,
}
}else{
content = {
view: view,
data: updateRequest.requested_change,
update:true,
topic:updateRequest.topic,
}
}
//? only show the popup if also the right content is available
if(content){
EditProfil.popup({
value:content,
timestamp:null,
}).then((res) => {
if(res === true){
this.$emit('fetchUpdates');
}
}).catch(e => {
console.log(e);
});
}
},
},
created(){
},
computed:{
},
template:`
<div class="card">
<div class="card-header">
Profil Updates
</div>
<div class="card-body" >
<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 v-if="item.topic.toLowerCase().includes('delete')" class="align-middle text-center" >{{item.requested_change.adr_typ?item.requested_change.adr_typ:item.requested_change.kontakt}}</td>
<td v-else 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>
</div>
</div>
`
};
export {Adresse, EditAdresse, Kontakt, EditKontakt, FetchProfilUpdates};
@@ -0,0 +1,55 @@
export default {
props:{data:Object, view:String},
data(){
return{}
},
created(){
},
template:`
<div class="gy-2 row justify-content-center align-items-center">
<!-- column 1 in the address row -->
<div class="col-1 text-center">
<i class="fa fa-location-dot fa-lg" style="color:#00649C "></i>
</div>
<div class="col-11 col-sm-8 col-xl-11 col-xxl-8 order-1">
<div class="form-underline ">
<div class="form-underline-titel">Strasse</div>
<span class="form-underline-content">{{data.strasse}} </span>
</div>
</div>
<!-- column 2 in the address row -->
<div class="offset-1 offset-sm-0 offset-xl-1 offset-xxl-0 order-2 order-sm-4 order-xl-2 order-xxl-4 col-11 col-sm-5 col-xl-11 col-xxl-5 ">
<div class="form-underline ">
<div class="form-underline-titel">Typ</div>
<span class="form-underline-content">{{data.adr_typ}} </span>
</div>
</div>
<div class="offset-1 order-3 order-sm-3 col-11 col-sm-6 col-xl-7 col-xxl-6 ">
<div class="form-underline ">
<div class="form-underline-titel">Ort</div>
<span class="form-underline-content">{{data.ort}} </span>
</div>
</div>
<div class="offset-1 offset-sm-0 order-4 order-sm-2 order-xl-4 order-xxl-2 col-11 col-sm-3 col-xl-4 col-xxl-3 ">
<div class="form-underline ">
<div class="form-underline-titel">PLZ</div>
<span class="form-underline-content">{{data.plz}} </span>
</div>
</div>
</div>
`
};
@@ -0,0 +1,97 @@
export default {
props:{data:Object},
data(){
return{
originalValue:null,
}
},
methods:{
updateValue: function(event,bind){
//? sets the value of a property to null when an empty string is entered to keep the isChanged function valid
this.data[bind] = event.target.value === "" ? null : event.target.value;
this.$emit('profilUpdate',this.isChanged?this.data:null);
},
},
computed:{
isChanged: function(){
if(!this.data.strasse || !this.data.plz || !this.data.ort || !this.data.adr_typ){
return false;
}
return this.originalValue !== JSON.stringify(this.data);
},
},
created(){
this.originalValue = JSON.stringify(this.data);
},
template:`
<pre>{{isChanged}}</pre>
<div class="gy-3 row justify-content-center align-items-center">
<!-- column 1 in the address row -->
<div class="col-12 col-sm-9 col-xl-12 col-xxl-9 order-1">
<div class="form-underline ">
<div class="form-underline-titel">Strasse</div>
<input class="form-control" :value="data.strasse" @input="updateValue($event,'strasse')" :placeholder="data.strasse">
</div>
</div>
<!-- column 2 in the address row -->
<div class=" order-2 order-sm-4 order-xl-3 order-xxl-4 col-12 col-sm-5 col-xl-8 col-xxl-5 ">
<template v-if="data.adresse_id">
<div class="form-underline ">
<div class="form-underline-titel">Typ</div>
<input class="form-control" :value="data.adr_typ" @input="updateValue($event,'adr_typ')" :placeholder="data.adr_typ">
</div>
</template>
<template v-else>
<div class="form-underline">
<div class="form-underline-titel">Kontakttyp</div>
<select :value="data.adr_typ" @change="updateValue($event,'adr_typ')" class="form-select" aria-label="Select Kontakttyp">
<option selected></option>
<option value="Rechnungsadresse">Rechnungsadresse</option>
<option value="Nebenwohnsitz">Nebenwohnsitz</option>
<option value="Homeoffice">Homeoffice</option>
<option value="Hauptwohnsitz">Hauptwohnsitz</option>
<option value="Firma">Firma</option>
</select>
</div>
</template>
</div>
<div class="order-3 order-sm-3 order-xl-2 order-xxl-3 col-12 col-sm-7 col-xl-12 col-xxl-7 ">
<div class="form-underline ">
<div class="form-underline-titel">Ort</div>
<input class="form-control" :value="data.ort" @input="updateValue($event,'ort')" :placeholder="data.ort">
</div>
</div>
<div class="order-4 order-sm-2 order-xl-4 order-xxl-2 col-12 col-sm-3 col-xl-4 col-xxl-3 ">
<div class="form-underline ">
<div class="form-underline-titel">PLZ</div>
<input class="form-control" :value="data.plz" @input="updateValue($event,'plz')" :placeholder="data.plz">
</div>
</div>
</div>
`
};
@@ -0,0 +1,106 @@
export default {
props:{
data:Object,
},
data(){
return{
originalValue:null,
}
},
methods:{
updateValue: function(event,bind){
if(bind === 'zustellung'){
this.data[bind] = event.target.checked;
}else{
//? sets the value of a property to null when an empty string is entered to keep the isChanged function valid
this.data[bind] = event.target.value === "" ? null: event.target.value;
}
this.$emit('profilUpdate',this.isChanged?this.data:null);
},
},
computed:{
isChanged: function(){
//? returns true if the original passed data object was changed
if(!this.data.kontakt || !this.data.kontakttyp) {return false;}
return JSON.stringify(this.data) !== this.originalValue;
}
},
created(){
this.originalValue = JSON.stringify(this.data);
},
template:
`
<div class="gy-3 row align-items-center justify-content-center">
<div v-if="!data.kontakt_id" class="col-12">
<div class="form-underline">
<div class="form-underline-titel">Kontakttyp</div>
<select :value="data.kontakttyp" @change="updateValue($event,'kontakttyp')" class="form-select" aria-label="Select Kontakttyp">
<option selected></option>
<option value="email">Email</option>
<option value="telefon">Telefon</option>
<option value="notfallkontakt">Notfallkontakt</option>
</select>
</div>
</div>
<div class="col-12">
<!-- rendering KONTAKT emails -->
<div class="form-underline">
<div class="form-underline-titel">{{data.kontakttyp?data.kontakttyp:'Kontakt'}}</div>
<input :disabled="data.kontakttyp?false:true" class="form-control" :value="data.kontakt" @input="updateValue($event,'kontakt')" :placeholder="data.kontakt">
</div>
</div>
<div class="col-12">
<div class="form-underline">
<div class="form-underline-titel">Anmerkung</div>
<input class="form-control" :value="data.anmerkung" @input="updateValue($event,'anmerkung')" :placeholder="data.anmerkung">
</div>
</div>
<div class="d-flex flex-row justify-content-start col-12 allign-middle">
<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">
</div>
</div>
`
};
@@ -0,0 +1,128 @@
import EditProfil from "../EditProfil.js";
//? EditProfil is the modal used to edit the profil updates
export default {
props:{
data:{
type:Object,
},
},
emits:["fetchUpdates"],
data(){
return {
}
},
methods:{
deleteRequest: function(item){
Vue.$fhcapi.UserData.deleteProfilRequest(item.profil_update_id).then((res)=>{
if(res.data.error){
//? open alert
console.log(res.data);
}else{
this.$emit('fetchUpdates');
}
});
},
getView: function(topic){
switch(topic){
case "Private Kontakte" : return "EditKontakt"; break;
case "Private Adressen" : return "EditAdresse"; break;
case "Add Adressen" : return "EditAdresse"; break;
case "Add Kontakte" : return "EditKontakt"; break;
case "Delete Adressen" : return "EditAdresse"; break;
case "Delete Kontakte" : return "EditKontakt"; break;
default: return "text_input"; break;
}
},
openModal(updateRequest) {
let view = this.getView(updateRequest.topic);
let content =null;
if(view === 'text_input'){
content={
view:view,
data:{
titel:updateRequest.topic,
value:updateRequest.requested_change,
},
update:true,
topic:updateRequest.topic,
}
}else{
content = {
view: view,
data: updateRequest.requested_change,
update:true,
topic:updateRequest.topic,
}
}
//? only show the popup if also the right content is available
if(content){
EditProfil.popup({
value:content,
timestamp:null,
}).then((res) => {
if(res === true){
this.$emit('fetchUpdates');
}
}).catch(e => {
// Wenn der User das Modal abbricht ohne Änderungen
});
}
},
},
created(){
},
computed:{
},
template:`
<div class="card">
<div class="card-header">
Profil Updates
</div>
<div class="card-body" >
<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 v-if="item.topic.toLowerCase().includes('delete')" class="align-middle text-center" >{{item.requested_change.adr_typ?item.requested_change.adr_typ:item.requested_change.kontakt}}</td>
<td v-else 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>
</div>
</div>
`
};
@@ -0,0 +1,56 @@
export default{
props:{
view:String,
data:Object,
},
data(){
return {
}
},
created(){
},
template:`
<div class=" row align-items-center justify-content-center">
<div class="col-1 text-center" >
<i class="fa-solid " :class="{...(data.kontakt.includes('@')?{'fa-envelope':true}:{'fa-phone':true})}" style="color:rgb(0, 100, 156)"></i>
</div>
<div :class="{...(data.anmerkung? {'col-11':true, 'col-md-6':true, 'col-xl-11':true, 'col-xxl-6':true} : {'col-10':true, 'col-xl-9':true, 'col-xxl-10':true})}">
<!-- rendering KONTAKT emails -->
<div class="form-underline ">
<div class="form-underline-titel">{{data.kontakttyp}}</div>
<a v-if="data.kontakt.includes('@')" role="link" :aria-disabled="view?true:false" :href="!view?('mailto:'+data.kontakt):null" class="form-underline-content">{{data.kontakt}} </a>
<a v-else role="link" :aria-disabled="view?true:false" :href="!view?('tel:'+data.kontakt):null" class="form-underline-content">{{data.kontakt}} </a>
</div>
</div>
<div v-if="data?.anmerkung" class="offset-1 offset-md-0 offset-xl-1 offset-xxl-0 order-2 order-sm-1 col-10 col-md-4 col-xl-9 col-xxl-4 ">
<div class="form-underline ">
<div class="form-underline-titel">Anmerkung</div>
<span class="form-underline-content">{{data.anmerkung}} </span>
</div>
</div>
<div class="text-center col-1 col-sm-1 order-2 order-lg-1 col-xl-2 col-xxl-1 allign-middle">
<i v-if="data.zustellung" class="fa-solid fa-check"></i>
<i v-else="data.zustellung" class="fa-solid fa-xmark"></i>
</div>
</div>
</div>
`,
};
@@ -27,10 +27,6 @@ export default {
<div class="card-body">
<div class="gy-3 row">
<div v-for="(wert,bez) in data" class="col-md-6 col-sm-12 ">
<div class="form-underline">
<div class="form-underline-titel">{{bez }}</div>
@@ -42,28 +38,9 @@ export default {
<span v-else class="form-underline-content">{{wert?wert:'-'}}</span>
</div>
</div>
<!-- Bearbeiten Button -->
<div class="col-md-6 col-sm-12 ">
<button @click="showModal" type="button" class="text-start w-100 btn btn-outline-primary" >
<div class="row">
<div class="col-2">
<i class="fa fa-edit"></i>
</div>
<div class="col-10">Bearbeiten</div>
</div>
</button>
</div>
</div>
</div>
+76 -389
View File
@@ -1,9 +1,26 @@
import fhcapifactory from "../../../apps/api/fhcapifactory.js";
import { CoreFilterCmpt } from "../../../components/filter/Filter.js";
import Mailverteiler from "./ProfilComponents/Mailverteiler.js";
import AusweisStatus from "./ProfilComponents/FhAusweisStatus.js";
import QuickLinks from "./ProfilComponents/QuickLinks.js";
import Adresse from "./ProfilComponents/Adresse.js";
import Kontakt from "./ProfilComponents/Kontakt.js";
import ProfilEmails from "./ProfilComponents/ProfilEmails.js";
import RoleInformation from "./ProfilComponents/RoleInformation.js";
import ProfilInformation from "./ProfilComponents/ProfilInformation.js";
export default {
components: {
CoreFilterCmpt,
Mailverteiler,
AusweisStatus,
QuickLinks,
Adresse,
Kontakt,
ProfilEmails,
RoleInformation,
ProfilInformation,
},
data() {
return {
@@ -82,33 +99,30 @@ export default {
},
//? this computed function returns all the informations for the first column in the profil
personData() {
profilInformation() {
if (!this.data) {
return {};
}
return {
Vorname: this.data.vorname,
Nachname: this.data.nachname,
Username: this.data.username,
Anrede: this.data.anrede,
Matrikelnummer: this.data.matrikelnummer,
Titel: this.data.titelpre,
Titel: this.data.titel,
Postnomen: this.data.postnomen,
foto_sperre:this.data.foto_sperre,
foto:this.data.foto,
};
},
personKontakt() {
if (!this.data) {
return {};
}
return {
emails: this.data.emails,
};
personEmails() {
return this.data?.emails ? this.data.emails : [];
},
specialData() {
roleInformation() {
if (!this.data) {
return {};
}
@@ -128,22 +142,16 @@ export default {
if (!this.data) {
return {};
}
return this.data.kontakte;
},
privateAdressen() {
if (!this.data) {
return {};
}
return this.data.adressen;
},
},
mounted() {
@@ -172,26 +180,8 @@ export default {
<div class="row py-2">
<div class="col">
<p class="m-0">
<div class="card">
<a class=" w-100 btn " data-bs-toggle="collapse" href="#collapseExample" role="button" aria-expanded="false" aria-controls="collapseExample">
<u> Quick links</u>
</a>
</div>
</p>
<div class="mt-1 collapse" id="collapseExample">
<div class="list-group">
<a href="#" class="list-group-item list-group-item-action">Zeitwünsche</a>
<a href="#" class="list-group-item list-group-item-action">Lehrveranstaltungen</a>
<a href="#" class="list-group-item list-group-item-action ">Zeitsperren</a>
</div>
</div>
<quick-links :mobile="true"></quick-links>
</div>
</div>
@@ -227,222 +217,55 @@ export default {
<!-- FIRST KAESTCHEN -->
<div class="col-lg-12 col-xl-6 ">
<div class="row mb-4 ">
<div class="col">
<div class="card h-100">
<div class="card-header">
StudentIn
</div>
<div class="card-body">
<div class="col-lg-12 col-xl-6 ">
<div class="row mb-4">
<div class="col">
<!-- PROFIL INFORMATION -->
<profil-information title="StudentIn" :data="profilInformation"></profil-information>
<div class="row gy-3 align-items-center">
<!-- SQUEEZING THE IMAGE INSIDE THE FIRST INFORMATION COLUMN -->
<!-- START OF THE FIRST ROW WITH THE PROFIL IMAGE -->
<div class="col-12 col-sm-6 mb-2">
<div class="row justify-content-center">
<div class="col-auto " style="position:relative">
<img class=" img-thumbnail " style=" max-height:150px; " :src="get_image_base64_src"></img>
<!-- LOCKING IMAGE FUNCTIONALITY -->
<div role="button" @click.prevent="sperre_foto_function" class="image-lock" >
<i :class="{'fa':true, ...(data.foto_sperre?{'fa-lock':true}:{'fa-lock-open':true})} " ></i>
</div>
</div>
</div>
<!-- END OF THE ROW WITH THE IMAGE -->
</div>
<!-- END OF SQUEEZE -->
</div>
<div class="row mb-4">
<div class=" col-lg-12">
<!-- MITARBEITER INFO -->
<role-information title="Student Information" :data="roleInformation"></role-information>
<!-- COLUMNS WITH MULTIPLE ROWS NEXT TO PROFIL PICTURE -->
<div class="col-12 col-sm-6">
<div class="row gy-4">
<div class="col-12">
<div class="form-underline ">
<div class="form-underline-titel">Vorname</div>
<span class="form-underline-content">{{data.vorname}} </span>
</div>
</div>
<div class="col-12">
<div class="form-underline ">
<div class="form-underline-titel">Nachname</div>
<span class="form-underline-content">{{data.nachname}} </span>
</div>
</div>
</div>
</div>
<div v-for="(wert,bez) in personData" class="col-md-6 col-sm-12 ">
<div class="form-underline ">
<div class="form-underline-titel">{{bez}}</div>
<span class="form-underline-content">{{wert?wert:'-'}} </span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row mb-4 ">
<div class=" col-lg-12">
<div class="card">
<div class="card-header">
Studenten Information
</div>
<div class="card-body">
<div class="row gy-3">
<div v-for="(wert,bez) in specialData" class="col-md-6 col-sm-12 ">
<div class="form-underline ">
<div class="form-underline-titel">{{bez}}</div>
<span class="form-underline-content">{{wert?wert:'-'}} </span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- START OF SECOND PROFIL INFORMATION COLUMN -->
</div>
<!-- END OF THE FIRST KAESTCHEN -->
</div>
<!-- START OF SECOND PROFIL INFORMATION COLUMN -->
<!-- END OF PROFIL INFORMATION ROW -->
<!-- INFORMATION CONTENT END -->
</div>
<div class="col-xl-6 col-lg-12 ">
<div class="row mb-4">
<div class="col">
<div class="card ">
<div class="card-header">
Mails
<!-- EMAILS -->
<profil-emails :data="personEmails" ></profil-emails>
</div>
</div>
<div class="card-body">
<div v-for="(wert,bezeichnung) in personKontakt">
<!-- HIER SIND DIE EMAILS -->
<div v-if="typeof wert === 'object' && bezeichnung == 'emails'" class="row gy-3 justify-content-center ">
<div v-for="email in wert" class="col-12 ">
<div class="row align-items-center">
<!--
<div class="col-1 text-center">
<i class="fa-solid fa-envelope" style="color:rgb(0, 100, 156)"></i>
</div>
-->
<div class="col">
<div class=" form-floating mb-2">
<div class="form-underline ">
<div class="form-underline-titel">{{email.type}}</div>
<a :href="'mailto'+email.email" class="form-underline-content">{{email.email}} </a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div></div>
<!-- HIER SIND DIE PRIVATEN KONTAKTE-->
<div class="row mb-4 ">
<div class="col">
<div class="card">
<!-- PRIVATE KONTAKTE-->
<div class="card">
<div class="card-header">
Private Kontakte
</div>
@@ -450,144 +273,54 @@ export default {
<div class="gy-3 row ">
<div v-for="element in privateKontakte" class="col-12">
<div class="gy-3 row align-items-center justify-content-center">
<div class="col-1 text-center" >
<i class="fa-solid " :class="{...(element.kontakt.includes('@')?{'fa-envelope':true}:{'fa-phone':true})}" style="color:rgb(0, 100, 156)"></i>
</div>
<div :class="{...(element.anmerkung? {'col-11':true, 'col-md-6':true, 'col-xl-11':true, 'col-xxl-6':true} : {'col-10':true, 'col-xl-9':true, 'col-xxl-10':true})}">
<!-- rendering KONTAKT emails -->
<div class="form-underline ">
<div class="form-underline-titel">{{element.kontakttyp}}</div>
<a :href="'mailto:'+element.kontakt" v-if="element.kontakt.includes('@')" class="form-underline-content">{{element.kontakt}} </a>
<a v-else :href="'tel:'+element.kontakt" class="form-underline-content">{{element.kontakt}} </a>
</div>
</div>
<div v-if="element?.anmerkung" class="offset-1 offset-md-0 offset-xl-1 offset-xxl-0 order-2 order-sm-1 col-10 col-md-4 col-xl-9 col-xxl-4 ">
<div class="form-underline ">
<div class="form-underline-titel">Anmerkung</div>
<span class="form-underline-content">{{element.anmerkung}} </span>
</div>
</div>
<div class="col-1 col-sm-1 order-2 order-lg-1 col-xl-2 col-xxl-1 allign-middle">
<i v-if="element.zustellung" class="fa-solid fa-check"></i>
<i v-else="element.zustellung" class="fa-solid fa-xmark"></i>
</div>
</div>
<Kontakt :data="element"></Kontakt>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- -->
<!-- HIER SIND DIE PRIVATEN ADRESSEN-->
<div class="row mb-4">
<div class="col">
<div class="card">
<div class="card-header">Private Adressen</div>
<div class="col">
<!-- PRIVATE ADRESSEN-->
<div class="card">
<div class="card-header">Private Adressen</div>
<div class="card-body">
<div class="gy-3 row ">
<div v-for="element in privateAdressen" class="col-12">
<div class="gy-3 row justify-content-center align-items-center">
<!-- column 1 in the address row -->
<div class="col-1 text-center">
<i class="fa fa-location-dot fa-lg" style="color:#00649C "></i>
</div>
<div class="col-11 col-sm-8 col-xl-11 col-xxl-8 order-1">
<div class="form-underline ">
<div class="form-underline-titel">Strasse</div>
<span class="form-underline-content">{{element.strasse}} </span>
</div>
</div>
<!-- column 2 in the address row -->
<div class="offset-1 offset-sm-0 offset-xl-1 offset-xxl-0 order-2 order-sm-4 order-xl-2 order-xxl-4 col-11 col-sm-5 col-xl-11 col-xxl-5 ">
<div class="form-underline ">
<div class="form-underline-titel">Typ</div>
<span class="form-underline-content">{{element.adr_typ}} </span>
</div>
</div>
<div class="offset-1 order-3 order-sm-3 col-11 col-sm-6 col-xl-7 col-xxl-6 ">
<div class="form-underline ">
<div class="form-underline-titel">Ort</div>
<span class="form-underline-content">{{element.ort}} </span>
</div>
</div>
<div class="offset-1 offset-sm-0 order-4 order-sm-2 order-xl-4 order-xxl-2 col-11 col-sm-3 col-xl-4 col-xxl-3 ">
<div class="form-underline ">
<div class="form-underline-titel">PLZ</div>
<span class="form-underline-content">{{element.plz}} </span>
</div>
</div>
<div v-for="element in privateAdressen" class="col-12">
<Adresse :data="element"></Adresse>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- -->
</div>
<!-- END OF THE SECOND INFORMATION COLUMN -->
</div>
<!-- START OF THE SECOND PROFIL INFORMATION ROW -->
<!-- ROW WITH PROFIL IMAGE AND INFORMATION END -->
</div >
<!-- SECOND ROW UNDER THE PROFIL IMAGE AND INFORMATION WITH THE TABLES -->
<div class="row">
<!-- FIRST TABLE -->
<div class="col-12 mb-4" >
<core-filter-cmpt title="Entlehnte Betriebsmittel" ref="betriebsmittelTable" :tabulator-options="betriebsmittel_table_options" tableOnly :sideMenu="false" />
</div>
<!-- SECOND TABLE -->
<div class="col-12 mb-4" >
<core-filter-cmpt title="Zutrittsgruppen" ref="zutrittsgruppenTable" :tabulator-options="zutrittsgruppen_table_options" tableOnly :sideMenu="false" noColumnFilter />
</div>
<!-- END OF THE ROW WITH THE TABLES UNDER THE PROFIL INFORMATION -->
</div>
@@ -606,29 +339,13 @@ export default {
<div class="col-md-4 col-xxl-3 col-sm-12 text-break" >
<!-- SRART OF QUICK LINKS IN THE SIDE PANEL -->
<!-- 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 class="col">
<div class="card">
<div class="card-header">
Quick Links
</div>
<div class="card-body">
<a style="text-decoration:none" class="my-1 d-block" href="#">Zeitwuensche</a>
<a style="text-decoration:none" class="my-1 d-block" href="#">Lehrveranstaltungen</a>
<a style="text-decoration:none" class="my-1 d-block" href="#">Zeitsperren</a>
</div>
</div>
<!-- QUICK LINKS -->
<quick-links ></quick-links>
</div>
@@ -641,12 +358,7 @@ export default {
<div class="card">
<div class="card-body">
<span>Der FH Ausweis ist am <b>{{data.zutrittsdatum}}</b> ausgegeben worden.</span>
</div>
</div>
<ausweis-status :data="data.zutrittsdatum"></ausweis-status>
</div>
@@ -662,32 +374,7 @@ export default {
<!-- HIER SIND DIE MAILVERTEILER -->
<div class="card">
<div class="card-header">
Mailverteilers
</div>
<div class="card-body">
<h6 class="card-title">Sie sind Mitgglied in folgenden Verteilern:</h6>
<div class="card-text row text-break mb-2" v-for="verteiler in data?.mailverteiler">
<div class="col-12 ">
<div class="row">
<div class="col-1 ">
<i class="fa-solid fa-envelope" style="color: #00649C;"></i>
</div>
<div class="col">
<a :href="verteiler.mailto"><b>{{verteiler.gruppe_kurzbz}}</b></a>
</div>
</div>
</div>
<div class="col-11 offset-1 ">{{verteiler.beschreibung}}</div>
</div>
</div>
</div>
<mailverteiler :data="data?.mailverteiler"></mailverteiler>
@@ -1,129 +0,0 @@
// Legacy function that constructed a result object where the old and the new versions of the changed data was stored
updateData: function(event,key,ArrayKey,ObjectKey=null){
const cleanUpObjectProperties= () => {
Object.entries(this.changesData).forEach( ([property, value]) => { if(!Object.keys(value).length) delete this.changesData[property]; })
}
let newValue = event.target.value;
if(!this.changesData[key]){
Array.isArray(this.editData[key])? this.changesData[key] = [] : this.changesData[key] = {};
}
if(Array.isArray(this.editData[key])){
if(newValue.length > 0) this.editData[key][ArrayKey][ObjectKey]= newValue;
else this.editData[key][ArrayKey][ObjectKey]= null;
let Obj = {key:ArrayKey, new: this.editData[key][ArrayKey], old: JSON.parse(this.originalEditData)[key][ArrayKey]};
if(JSON.stringify(this.editData[key][ArrayKey]) === JSON.stringify(JSON.parse(this.originalEditData)[key][ArrayKey]) ){
this.changesData[key] = this.changesData[key].filter( arrayElement => arrayElement.key !== ArrayKey );
cleanUpObjectProperties();
}else{
if(!this.changesData[key].filter( arrayElement => arrayElement.key === ArrayKey ).length){
this.changesData[key].push(Obj);
}
}
}else{
if(newValue.length > 0) this.editData[key][ArrayKey]= newValue;
else this.editData[key][ArrayKey]= null;
let Obj = { new: this.editData[key][ArrayKey], old: JSON.parse(this.originalEditData)[key][ArrayKey]};
if(JSON.stringify(this.editData[key][ArrayKey]) === JSON.stringify(JSON.parse(this.originalEditData)[key][ArrayKey])){
delete this.changesData[key][ArrayKey];
cleanUpObjectProperties();
}else{
this.changesData[key][ArrayKey]= Obj;
}
}
},
<!-- START OF THE ACCORDION
<pre>{{JSON.stringify(changesData,null,2)}}</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-3">
<template v-for="(object,objectKey) in value" >
<div class="card card-body col-12 ">
<div class="row gy-3">
<div v-for="(propertyValue,propertyKey) in object" class="col-6" >
<div class="form-underline ">
<div class="form-underline-titel">
<label :for="propertyKey+'input'" >{{propertyKey}}</label>
</div>
<div>
<input class="form-control" :id="propertyKey+'input'" :value="editData[key][objectKey][propertyKey]" @input="updateData($event,key,objectKey,propertyKey)" :placeholder="propertyValue">
</div>
</div>
</div>
</div>
</div>
</template>
</div>
<div v-else class="row gy-3">
<div v-for="(propertyValue,propertyKey) in value" class="col-6">
<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'" :value="editData[key][propertyKey]" @input="updateData($event,key,propertyKey)" :placeholder="propertyValue">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- -->
<!-- END OF THE ACCORDION -->