mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-07-18 15:32:17 +00:00
allows user to make profil changes requests and to oversee his requested changes
This commit is contained in:
@@ -19,7 +19,8 @@ class Profil extends Auth_Controller
|
||||
'index' => ['student/anrechnung_beantragen:r', 'user:r'], // TODO(chris): permissions?
|
||||
'foto_sperre_function' => ['student/anrechnung_beantragen:r', 'user:r'],
|
||||
'getView' => ['student/anrechnung_beantragen:r', 'user:r'],
|
||||
'editProfil' => ['student/anrechnung_beantragen:r', 'user:r'],
|
||||
'insertProfilRequest' => ['student/anrechnung_beantragen:r', 'user:r'],
|
||||
'updateProfilRequest' => ['student/anrechnung_beantragen:r', 'user:r'],
|
||||
|
||||
|
||||
]);
|
||||
@@ -67,13 +68,13 @@ class Profil extends Auth_Controller
|
||||
|
||||
|
||||
|
||||
public function editProfil()
|
||||
public function insertProfilRequest()
|
||||
{
|
||||
|
||||
$json = json_decode($this->input->raw_input_stream);
|
||||
|
||||
|
||||
$data = ["uid" => $this->uid, "requested_change" => json_encode($json->payload), "change_timestamp" => "NOW()", "topic"=>$json->topic];
|
||||
$data = ["topic"=>$json->topic,"uid" => $this->uid, "requested_change" => json_encode($json->payload), "change_timestamp" => "NOW()" ];
|
||||
|
||||
//? gets all the requested changes from a user
|
||||
$res = $this->ProfilChangeModel->loadWhere(["uid"=>$this->uid]);
|
||||
@@ -81,13 +82,14 @@ class Profil extends Auth_Controller
|
||||
|
||||
//? checks if the user already made a request to change a topic
|
||||
//! which is an constraint added to the public.tbl_cis_profil_update table
|
||||
if($res){
|
||||
foreach($res as $update_request){
|
||||
if($update_request->topic == $json->topic && $update_request->uid == $this->uid){
|
||||
|
||||
echo json_encode(error("uid and topic combination exists already"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}}
|
||||
|
||||
|
||||
$insert_res = $this->ProfilChangeModel->insert($data);
|
||||
@@ -119,6 +121,32 @@ class Profil extends Auth_Controller
|
||||
|
||||
}
|
||||
|
||||
public function updateProfilRequest()
|
||||
{
|
||||
|
||||
$json = json_decode($this->input->raw_input_stream);
|
||||
|
||||
|
||||
$data = ["topic"=>$json->topic,"uid" => $this->uid, "requested_change" => json_encode($json->payload), "change_timestamp" => "NOW()" ];
|
||||
|
||||
//? gets all the requested changes from a user
|
||||
|
||||
if(isSuccess($this->ProfilChangeModel->addSelect(["profil_update_id"])) ){
|
||||
$requestID = $this->ProfilChangeModel->loadWhere(["uid"=>$this->uid,"topic"=>$json->topic]);
|
||||
$requestID = hasData($requestID) ? getData($requestID)[0]->profil_update_id : null;
|
||||
};
|
||||
|
||||
$update_res =$this->ProfilChangeModel->update([$requestID],$data);
|
||||
if(isError($update_res)){
|
||||
//catch error
|
||||
}else{
|
||||
$editTimestamp = $this->ProfilChangeModel->getTimestamp($update_res->retval[0]);
|
||||
|
||||
$update_res->retval = date_create($editTimestamp)->format('d.m.Y');
|
||||
echo json_encode($update_res);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private function viewMitarbeiterProfil($uid)
|
||||
@@ -414,7 +442,7 @@ class Profil extends Auth_Controller
|
||||
|
||||
if (
|
||||
|
||||
isSuccess($adresse_res = $this->AdresseModel->addSelect(array("strasse", "tbl_adressentyp.bezeichnung as adr_typ", "plz", "ort"))) &&
|
||||
isSuccess($adresse_res = $this->AdresseModel->addSelect(["adresse_id","strasse", "tbl_adressentyp.bezeichnung as adr_typ", "plz", "ort"])) &&
|
||||
isSuccess($adresse_res = $this->AdresseModel->addOrder("zustelladresse", "DESC")) &&
|
||||
isSuccess($adresse_res = $this->AdresseModel->addOrder("sort")) &&
|
||||
isSuccess($adresse_res = $this->AdresseModel->addJoin("tbl_adressentyp", "typ=adressentyp_kurzbz"))
|
||||
@@ -565,7 +593,11 @@ 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;
|
||||
}
|
||||
@@ -623,7 +655,7 @@ class Profil extends Auth_Controller
|
||||
|
||||
if (
|
||||
|
||||
isSuccess($adresse_res = $this->AdresseModel->addSelect(array("strasse", "tbl_adressentyp.bezeichnung as adr_typ", "plz", "ort"))) &&
|
||||
isSuccess($adresse_res = $this->AdresseModel->addSelect(["adresse_id","strasse", "tbl_adressentyp.bezeichnung as adr_typ", "plz", "ort"])) &&
|
||||
isSuccess($adresse_res = $this->AdresseModel->addOrder("zustelladresse", "DESC")) &&
|
||||
isSuccess($adresse_res = $this->AdresseModel->addOrder("sort")) &&
|
||||
isSuccess($adresse_res = $this->AdresseModel->addJoin("tbl_adressentyp", "typ=adressentyp_kurzbz"))
|
||||
@@ -767,6 +799,11 @@ 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;
|
||||
|
||||
|
||||
@@ -50,6 +50,9 @@
|
||||
align-content: space-between;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
.form-underline .form-underline-content{
|
||||
border-width: 1px;
|
||||
border-color: transparent transparent #dee2e6 transparent;
|
||||
@@ -75,11 +78,7 @@
|
||||
}
|
||||
|
||||
|
||||
option:checked{
|
||||
background: linear-gradient(#005485, #005485);
|
||||
|
||||
}
|
||||
|
||||
#SelectStyle{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -3,9 +3,16 @@ export default {
|
||||
|
||||
//! API Calls for Profil Views
|
||||
|
||||
editProfil: function(topic, payload) {
|
||||
insertProfilRequest: function(topic, payload) {
|
||||
const url = FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router+
|
||||
`/Cis/Profil/editProfil`;
|
||||
`/Cis/Profil/insertProfilRequest`;
|
||||
|
||||
return axios.post(url,{topic, payload});
|
||||
},
|
||||
|
||||
updateProfilRequest: function(topic, payload) {
|
||||
const url = FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router+
|
||||
`/Cis/Profil/updateProfilRequest`;
|
||||
|
||||
return axios.post(url,{topic, payload});
|
||||
},
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import BsModal from "../../Bootstrap/Modal.js";
|
||||
import Alert from "../../Bootstrap/Alert.js";
|
||||
import BreadCrumb from "../Selection/Breadcrumb.js";
|
||||
import Select from "../Selection/Select.js";
|
||||
import EditProfilSelect from "./EditProfilSelect.js";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
BsModal,
|
||||
Alert,
|
||||
BreadCrumb,
|
||||
Select,
|
||||
EditProfilSelect,
|
||||
},
|
||||
mixins: [BsModal],
|
||||
props: {
|
||||
@@ -37,6 +37,8 @@ export default {
|
||||
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,
|
||||
@@ -58,12 +60,11 @@ export default {
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
|
||||
testEvent: function(){
|
||||
if(!this.propertySelected){
|
||||
this.testListe = this.testListe[this.testValue];
|
||||
this.propertySelected = true;
|
||||
}
|
||||
|
||||
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
|
||||
@@ -83,11 +84,12 @@ export default {
|
||||
|
||||
|
||||
//* only inserts new row if the inputField value is different from the original value
|
||||
if(this.isInputFieldChanged && this.topic){
|
||||
if(this.topic && this.profilUpdate){
|
||||
|
||||
//? inserts new row in public.tbl_cis_profil_update
|
||||
|
||||
Vue.$fhcapi.UserData.editProfil(this.topic,this.inputField).then((res)=>{
|
||||
if(this.editData.update){
|
||||
|
||||
Vue.$fhcapi.UserData.updateProfilRequest(this.topic,this.profilUpdate).then((res)=>{
|
||||
this.result = {
|
||||
editData: this.editData,
|
||||
timestamp: res.data.retval,
|
||||
@@ -102,116 +104,68 @@ export default {
|
||||
}
|
||||
//
|
||||
});
|
||||
//
|
||||
|
||||
}
|
||||
}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){
|
||||
|
||||
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: {
|
||||
|
||||
isInputFieldChanged: function(){
|
||||
if(this.inputField){
|
||||
return JSON.stringify(this.inputField) !== JSON.stringify(this.secondSelectedOption);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
firstSelection(){
|
||||
return Object.keys(this.value);
|
||||
},
|
||||
|
||||
secondSelection(){
|
||||
switch(this.firstSelectedOption){
|
||||
case "Personen_Informationen": return Object.keys(this.editData[this.firstSelectedOption]);
|
||||
case "Private_Kontakte": return this.editData[this.firstSelectedOption];
|
||||
case "Private_Adressen": return this.editData[this.firstSelectedOption];
|
||||
default: return [];
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
},
|
||||
created() {
|
||||
|
||||
if(this.editData.topic){
|
||||
//? if the topic was passed through the prop add it to the reactive data
|
||||
this.topic = this.editData.topic;
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
mounted() {
|
||||
this.modal = this.$refs.modalContainer.modal;
|
||||
},
|
||||
popup(options) {
|
||||
console.log("popup start");
|
||||
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 v-slot:title>
|
||||
{{"Profil bearbeiten" }}
|
||||
</template>
|
||||
<template v-slot:default>
|
||||
|
||||
<bread-crumb :list="['this','is a','test']" ></bread-crumb>
|
||||
<p>{{testValue}}</p>
|
||||
<Select ariaLabel="test" v-model="testValue" @select="testEvent" :list="testListe"></Select>
|
||||
<!-- DONT FORGET TO UNCOMMENT THIS -->
|
||||
<!-- Breadcrumbs
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item" v-if="firstSelectedOption">{{firstSelectedOption}}</li>
|
||||
<li class="breadcrumb-item" v-if="secondSelectedOption" >{{firstSelectedOption ==="Personen_Informationen" ? Object.keys(secondSelectedOption)[0] : secondSelectedOptionIndex+1 }}</li>
|
||||
|
||||
</ol>
|
||||
</nav>
|
||||
-->
|
||||
<edit-profil-select v-model:topic="topic" v-model:profilUpdate="profilUpdate" ariaLabel="test" :list="editData"></edit-profil-select>
|
||||
|
||||
|
||||
|
||||
<select v-if="!firstSelectedOption" v-model="firstSelectedOption" class="form-select" size="3" aria-label="size 3 select example">
|
||||
<option v-for="(option,index) in firstSelection" :value="option">{{option.replace("_"," ")}}</option>
|
||||
</select>
|
||||
|
||||
<select v-if="firstSelectedOption && !secondSelectedOption" class="form-select" size="3" aria-label="size 3 select example">
|
||||
<option @click="
|
||||
|
||||
if(Array.isArray(editData[firstSelectedOption])){
|
||||
secondSelectedOptionIndex = index;
|
||||
secondSelectedOption = createDeepCopy(option);
|
||||
inputField= createDeepCopy(option);
|
||||
//* topic is the property in which the array is stored when it is an array
|
||||
topic = firstSelectedOption;
|
||||
}else{
|
||||
secondSelectedOption={[option]:editData[firstSelectedOption][option]};
|
||||
inputField={[option]:editData[firstSelectedOption][option]};
|
||||
//* topic is the selected property if is an object
|
||||
topic = option;
|
||||
}" v-for="(option, index) in secondSelection" :value="option"><div v-if="typeof(option)==='object'">
|
||||
<div class="row m-2" v-for="(value,property) in option">
|
||||
<div class="col"><span>{{property}}</span></div>
|
||||
<div class="col"><span>{{value}}</span></div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<template v-else>{{option}}</template>
|
||||
</option>
|
||||
</select>
|
||||
<div v-if="inputField">
|
||||
<div v-for="(field,index) in inputField">
|
||||
|
||||
<div class="form-underline">
|
||||
<div class="form-underline-titel">{{index}}</div>
|
||||
|
||||
<input class="form-control" :id="index" :value="inputField[index]" @input="changeInput($event,inputField,index)" :placeholder="field">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</template>
|
||||
<!-- optional footer -->
|
||||
<template v-slot:footer>
|
||||
<button class="btn btn-outline-danger " @click="hide">Abbrechen</button>
|
||||
<!--<p v-if="editTimestamp" class="flex-fill">Letzte Anfrage: {{editTimestamp}}</p>-->
|
||||
|
||||
<button v-if="isInputFieldChanged" @click="submitProfilChange" role="button" class="btn btn-primary">Senden</button>
|
||||
<button v-if="profilUpdate" @click="submitProfilChange" role="button" class="btn btn-primary">Senden</button>
|
||||
</template>
|
||||
<!-- end of optional footer -->
|
||||
</bs-modal>`,
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
import {Kontakt, EditKontakt, Adresse, EditAdresse} from "./ProfilComponents.js";
|
||||
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Kontakt,
|
||||
EditKontakt,
|
||||
Adresse,
|
||||
EditAdresse,
|
||||
},
|
||||
props: {
|
||||
|
||||
//! this should throw an error in the js console, have to check later
|
||||
list:Object,
|
||||
|
||||
//? Prop used to determine how many options the select should initially show
|
||||
size:{
|
||||
type:Number,
|
||||
default: null,
|
||||
},
|
||||
//? Content for the aria label of the select
|
||||
ariaLabel:{
|
||||
type:String,
|
||||
required:true,
|
||||
},
|
||||
profilUpdate:String,
|
||||
topic:String,
|
||||
|
||||
|
||||
},
|
||||
emits:{
|
||||
//? update:modelValue event is needed to notify the v-model when the value has changed
|
||||
['update:profilUpdate']:null,
|
||||
['update:topic']:null,
|
||||
select:null,
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
view:null,
|
||||
data:null,
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
profilUpdateEmit: function(event){
|
||||
console.log(event);
|
||||
//? passes the updated profil information to the parent component
|
||||
this.$emit('update:profilUpdate',event);
|
||||
},
|
||||
updateOptions: function(event, item){
|
||||
|
||||
this.data=item.data;
|
||||
this.view=item.view;
|
||||
//? emits the selected topic to the parent component
|
||||
if(item.title){
|
||||
this.$emit('update:topic',item.title);
|
||||
}
|
||||
},
|
||||
|
||||
},
|
||||
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() {
|
||||
},
|
||||
|
||||
template: `
|
||||
|
||||
|
||||
<div v-if="!view" class="list-group">
|
||||
<button type="button" class=" list-group-item list-group-item-action" @click="updateOptions($event,item)" v-for="item in data">
|
||||
|
||||
<p v-if="item.title" class="my-1" >{{item.title}}</p>
|
||||
<!-- this is used for multiple elements in the select -->
|
||||
<component class="my-2" :is="item.listview" v-bind="item"></component>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
<div v-else-if="view==='text_input'" class="form-underline">
|
||||
<div class="form-underline-titel">{{data.titel?data.titel:'titel'}}</div>
|
||||
|
||||
<input class="form-control" @input="$emit('update:profilUpdate',data.value)" v-model="data.value" :placeholder="data.value">
|
||||
</div>
|
||||
|
||||
|
||||
<!-- if it not a normal text input field then reder the custom edit input component -->
|
||||
<!-- custom component is required to emit an profilUpdate event to register the new entered value -->
|
||||
<template v-else>
|
||||
<component @profilUpdate="profilUpdateEmit" :is="view" :data="data"></component>
|
||||
</template>
|
||||
`,
|
||||
};
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
|
||||
import { CoreFilterCmpt } from "../../../components/filter/Filter.js";
|
||||
import EditProfil from "./EditProfil.js"
|
||||
|
||||
|
||||
import EditProfil from "./EditProfil.js";
|
||||
import {Adresse, Kontakt, FetchProfilUpdates} from "./ProfilComponents.js";
|
||||
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CoreFilterCmpt,
|
||||
EditProfil,
|
||||
Adresse,
|
||||
Kontakt,
|
||||
FetchProfilUpdates,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -260,24 +262,65 @@ export default {
|
||||
created() {
|
||||
|
||||
|
||||
|
||||
if(!this.data.editData){
|
||||
|
||||
|
||||
|
||||
|
||||
this.data.editData = {
|
||||
Personen_Informationen : {...this.personData, vorname: this.data.vorname, nachname: this.data.nachname},
|
||||
Private_Kontakte: this.data.kontakte,
|
||||
Private_Adressen:this.privateAdressen,
|
||||
view:null,
|
||||
data:{
|
||||
Personen_Informationen : {
|
||||
title:"Personen Informationen",
|
||||
view:null,
|
||||
data:{
|
||||
username:{
|
||||
title:"username",
|
||||
view:"text_input",
|
||||
data:{
|
||||
titel:"username",
|
||||
value:this.data.username,
|
||||
}
|
||||
},
|
||||
vorname: {
|
||||
title:"vorname",
|
||||
view:"text_input",
|
||||
data:{
|
||||
titel:"vorname",
|
||||
value:this.data.vorname,
|
||||
}},
|
||||
nachname: {
|
||||
title:"nachname",
|
||||
view:"text_input",
|
||||
data:{
|
||||
titel:"nachname",
|
||||
value:this.data.nachname,
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Private_Kontakte: {
|
||||
title:"Private Kontakte" ,
|
||||
data:this.privateKontakte.map(kontakt => {
|
||||
return {
|
||||
listview:'Kontakt',
|
||||
view:'EditKontakt',
|
||||
data:kontakt
|
||||
}})
|
||||
},
|
||||
Private_Adressen: {
|
||||
title: "Private Adressen",
|
||||
data:this.privateAdressen.map(kontakt => {
|
||||
return {
|
||||
listview:'Adresse',
|
||||
view:'EditAdresse',
|
||||
data:kontakt
|
||||
}})
|
||||
},
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
}else{
|
||||
this.data.editData = {
|
||||
Personen_Informationen : {...this.personData, vorname: this.data.vorname, nachname: this.data.nachname},
|
||||
Private_Kontakte: this.data.kontakte,
|
||||
Private_Adressen:this.privateAdressen,
|
||||
};
|
||||
|
||||
}
|
||||
console.log(JSON.stringify(this.data.editData,null,2));
|
||||
},
|
||||
mounted() {
|
||||
|
||||
@@ -335,7 +378,7 @@ export default {
|
||||
<div class="card-header">
|
||||
Profil Informations Änderungen Anfragen</div>
|
||||
<div class="card-body">
|
||||
<p v-for="update in data.profilUpdates">{{update.requested_change}}</p>
|
||||
<fetch-profil-updates></fetch-profil-updates>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -629,39 +672,9 @@ 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>
|
||||
@@ -675,60 +688,20 @@ export default {
|
||||
<div class="col">
|
||||
<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">
|
||||
<div class="card-body">
|
||||
|
||||
<!-- column 1 in the address row -->
|
||||
|
||||
<div class="col-1 text-center">
|
||||
<div class="gy-3 row ">
|
||||
<div v-for="element in privateAdressen" class="col-12">
|
||||
<Adresse :data="element"></Adresse>
|
||||
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- -->
|
||||
|
||||
<!-- -->
|
||||
|
||||
|
||||
|
||||
@@ -795,11 +768,7 @@ export default {
|
||||
<div class="card-header">
|
||||
Profil Updates
|
||||
</div>
|
||||
<div class="card-body d-flex justify-content-start flex-wrap">
|
||||
<!-- -->
|
||||
<button v-for="update in data.profilUpdates" class="btn m-1" :class="{'btn-outline-primary':(update.topic !== 'Private_Kontakte' || update.topic !== 'Private_Adressen'), 'btn-outline-danger':update.topic == 'Private_Kontakte', 'btn-outline-success':update.topic == 'Private_Adressen'}" ><i class="fa fa-edit"></i> {{update.topic}}</button>
|
||||
|
||||
</div>
|
||||
<fetch-profil-updates :modal="EditProfil" :data="data.profilUpdates"></fetch-profil-updates>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,352 @@
|
||||
|
||||
|
||||
|
||||
const Adresse = {
|
||||
props:{data:Object, view:String},
|
||||
data(){
|
||||
return{}
|
||||
},
|
||||
created(){
|
||||
|
||||
},
|
||||
template:`
|
||||
<div class="my-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{}
|
||||
},
|
||||
methods:{
|
||||
updateValue: function(event,bind){
|
||||
this.data[bind] = event.target.value;
|
||||
this.$emit('profilUpdate',this.data);
|
||||
},
|
||||
},
|
||||
created(){
|
||||
|
||||
},
|
||||
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>
|
||||
|
||||
|
||||
|
||||
|
||||
`,
|
||||
};
|
||||
|
||||
const EditKontakt = {
|
||||
props:{
|
||||
data:Object,
|
||||
},
|
||||
data(){
|
||||
return{
|
||||
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
updateValue: function(event,bind){
|
||||
if(bind === 'zustellung'){
|
||||
this.data[bind] = event.target.checked;
|
||||
}else{
|
||||
this.data[bind] = event.target.value;
|
||||
}
|
||||
|
||||
this.$emit('profilUpdate',this.data);
|
||||
},
|
||||
},
|
||||
created(){
|
||||
console.log(this.$props);
|
||||
},
|
||||
template:
|
||||
`
|
||||
|
||||
<div class="gy-3 row align-items-center justify-content-center">
|
||||
|
||||
|
||||
<div class="col-12">
|
||||
|
||||
<!-- rendering KONTAKT emails -->
|
||||
|
||||
|
||||
<div class="form-underline">
|
||||
<div class="form-underline-titel">{{data.kontakttyp}}</div>
|
||||
|
||||
<input class="form-control" :value="data.kontakt" @input="updateValue($event,'kontakt')" :placeholder="data.kontakt">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<div v-if="data?.anmerkung" 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 Adresse</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,
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
data(){
|
||||
return {}
|
||||
},
|
||||
methods:{
|
||||
getView: function(topic){
|
||||
console.log("the topic is here",topic);
|
||||
switch(topic){
|
||||
case "Private Kontakte" : return "EditKontakt"; break;
|
||||
case "Private Adressen" : return "EditAdresse"; 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.timestamp && res.editData){
|
||||
this.data.editDataTimestamp = res.timestamp;
|
||||
this.data.editData = res.editData;
|
||||
} */
|
||||
|
||||
}).catch(e => {
|
||||
console.log(e);
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
},
|
||||
created(){
|
||||
|
||||
},
|
||||
template:`
|
||||
|
||||
|
||||
<table class="table table-sm table-hover">
|
||||
<thead>
|
||||
<tr >
|
||||
<th scope="col">Topic</th>
|
||||
<th scope="col">Date of Request</th>
|
||||
<th scope="col"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="item in data">
|
||||
<td >{{item.topic}}</td>
|
||||
<td >{{item.change_timestamp}}</td>
|
||||
<td ><i @click="openModal(item)" role="button" class="fa fa-edit"></i></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
`
|
||||
};
|
||||
|
||||
export {Adresse, EditAdresse, Kontakt, EditKontakt, FetchProfilUpdates};
|
||||
@@ -1,86 +0,0 @@
|
||||
|
||||
|
||||
export default {
|
||||
components: {
|
||||
},
|
||||
props: {
|
||||
|
||||
//! this should throw an error in the js console, have to check later
|
||||
list:[Array,Object],
|
||||
//? prop modelValue allows v-model on custom Components
|
||||
modelValue:String,
|
||||
//? Prop used to determine how many options the select should initially show
|
||||
size:{
|
||||
type:Number,
|
||||
default: null,
|
||||
},
|
||||
//? Content for the aria label of the select
|
||||
ariaLabel:{
|
||||
type:String,
|
||||
required:true,
|
||||
},
|
||||
|
||||
},
|
||||
emits:{
|
||||
//? update:modelValue event is needed to notify the v-model when the value has changed
|
||||
['update:modelValue']:null,
|
||||
select:null,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selectedOption: [],
|
||||
optionLength:this.size,
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
},
|
||||
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() {
|
||||
console.log(this.optionLength);
|
||||
//? 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() {
|
||||
},
|
||||
template: `
|
||||
<p>size:{{optionLength}}</p>
|
||||
<!-- styling des Selects und dessen Options könnte man noch anpassen -->
|
||||
<div id="SelectStyle">
|
||||
<select v-model="selectedOption" class="form-select" :size="this.optionLength" :aria-label="ariaLabel">
|
||||
<option @click="$emit('update:modelValue', option); $emit('select')" v-for="(option,index) in computedList" :value="option">
|
||||
<template v-if="typeof(option) === 'object' && option !== null" >
|
||||
<div class="row " v-for="(element,index) in option"><div class="col">{{index}} : </div><div class="col">{{element}}</div></div>
|
||||
</template>
|
||||
<template v-else >
|
||||
{{option}}
|
||||
</template>
|
||||
</option>
|
||||
</select>
|
||||
</div>`,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user