mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-06-01 12:19:28 +00:00
396 lines
10 KiB
JavaScript
396 lines
10 KiB
JavaScript
import StudentProfil from "./StudentProfil.js";
|
|
import MitarbeiterProfil from "./MitarbeiterProfil.js";
|
|
import ViewStudentProfil from "./StudentViewProfil.js";
|
|
import ViewMitarbeiterProfil from "./MitarbeiterViewProfil.js";
|
|
import Loading from "../../Loader.js";
|
|
|
|
import ApiProfil from '../../../api/factory/profil.js';
|
|
import ApiProfilUpdate from '../../../api/factory/profilUpdate.js';
|
|
|
|
Vue.$collapseFormatter = function (data) {
|
|
//data - an array of objects containing the column title and value for each cell
|
|
var container = document.createElement("div");
|
|
container.classList.add("tabulator-collapsed-row");
|
|
container.classList.add("text-break");
|
|
|
|
var list = document.createElement("div");
|
|
list.classList.add("row");
|
|
|
|
container.appendChild(list);
|
|
|
|
data.forEach(function (col) {
|
|
let item = document.createElement("div");
|
|
item.classList.add("col-6");
|
|
let item2 = document.createElement("div");
|
|
item2.classList.add("col-6");
|
|
|
|
item.innerHTML = "<strong>" + col.title + "</strong>";
|
|
item2.innerHTML = col.value ? col.value : "-";
|
|
|
|
list.appendChild(item);
|
|
list.appendChild(item2);
|
|
});
|
|
|
|
return Object.keys(data).length ? container : "";
|
|
};
|
|
|
|
export const Profil = {
|
|
name: 'Profil',
|
|
components: {
|
|
StudentProfil,
|
|
MitarbeiterProfil,
|
|
ViewStudentProfil,
|
|
ViewMitarbeiterProfil,
|
|
Loading,
|
|
},
|
|
props: {
|
|
uid: {
|
|
type: String,
|
|
required:false,
|
|
},
|
|
viewData: {
|
|
type: Object,
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
//? loading property is used for showing/hiding the loading modal
|
|
loading: false,
|
|
profilUpdateStates: null,
|
|
profilUpdateTopic: null,
|
|
view: null,
|
|
data: null,
|
|
// notfound is null by default, but contains an UID if no user exists with that UID
|
|
notFoundUID: null,
|
|
isEditable: this.viewData.editable ?? false,
|
|
};
|
|
},
|
|
provide() {
|
|
return {
|
|
isEditable: Vue.computed(()=>this.isEditable),
|
|
profilUpdateStates: Vue.computed(() =>
|
|
this.profilUpdateStates ? this.profilUpdateStates : false
|
|
),
|
|
profilUpdateTopic: Vue.computed(() =>
|
|
this.profilUpdateTopic ? this.profilUpdateTopic : false
|
|
),
|
|
setLoading: (newValue) => {
|
|
this.loading = newValue;
|
|
},
|
|
getZustellkontakteCount: this.zustellKontakteCount,
|
|
getZustelladressenCount: this.zustellAdressenCount,
|
|
collapseFunction: (e, column) => {
|
|
//* check if property doesn't exist already and add it to the reactive this properties
|
|
if (this[e.target.id] === undefined) {
|
|
this[e.target.id] = true;
|
|
}
|
|
this[e.target.id] = !this[e.target.id];
|
|
|
|
//* gets all event icons of the different rows to use the onClick event later
|
|
let allClickableIcons = column._column.cells.map((row) => {
|
|
return row.element.children[0];
|
|
});
|
|
|
|
//* changes the icon that shows or hides all the collapsed columns
|
|
//* if the replace function does not find the class to replace, it just simply returns false
|
|
if (this[e.target.id]) {
|
|
e.target.classList.replace("fa-angle-up", "fa-angle-down");
|
|
} else {
|
|
e.target.classList.replace("fa-angle-down", "fa-angle-up");
|
|
}
|
|
|
|
//* changes the icon for every collapsed column to open or closed
|
|
if (this[e.target.id]) {
|
|
allClickableIcons
|
|
.filter((column) => {
|
|
return !column.classList.contains("open");
|
|
})
|
|
.forEach((col) => {
|
|
col.click();
|
|
});
|
|
} else {
|
|
allClickableIcons
|
|
.filter((column) => {
|
|
return column.classList.contains("open");
|
|
})
|
|
.forEach((col) => {
|
|
col.click();
|
|
});
|
|
}
|
|
},
|
|
sortProfilUpdates: (ele1, ele2) => {
|
|
let result = 0;
|
|
if (ele1.status.toLowerCase() === "pending") {
|
|
result = -1;
|
|
} else if (ele1.status.toLowerCase() === "accepted") {
|
|
result = ele2.status.toLowerCase() === "rejected" ? -1 : 1;
|
|
} else {
|
|
result = 1;
|
|
}
|
|
//? if they have the same status the insert date is used for ordering
|
|
if (ele1.status === ele2.status) {
|
|
result =
|
|
new Date(ele2.insertamum.split(".").reverse().join("-")) -
|
|
new Date(ele1.insertamum.split(".").reverse().join("-"));
|
|
}
|
|
return result;
|
|
},
|
|
};
|
|
},
|
|
methods: {
|
|
async load() {
|
|
// fetch profilUpdateStates to provide them to children components
|
|
await this.$api
|
|
.call(ApiProfilUpdate.getStatus())
|
|
.then((response) => {
|
|
this.profilUpdateStates = response.data;
|
|
})
|
|
.catch((error) => {
|
|
console.error(error);
|
|
});
|
|
|
|
this.$api
|
|
.call(ApiProfilUpdate.getTopic())
|
|
.then((response) => {
|
|
this.profilUpdateTopic = response.data;
|
|
})
|
|
.catch((error) => {
|
|
console.error(error);
|
|
});
|
|
|
|
|
|
this.$api
|
|
.call(ApiProfil.profilViewData(this.$route.params.uid??null))
|
|
.then((response) => response.data).then(data=>{
|
|
this.view = data?.profil_data.view;
|
|
this.data = data?.profil_data.data;
|
|
this.isEditable = data?.editable ?? false;
|
|
})
|
|
.catch((error) => {
|
|
console.error(error);
|
|
});
|
|
|
|
|
|
},
|
|
zustellAdressenCount() {
|
|
if (!this.data || !this.data.adressen) {
|
|
return null;
|
|
}
|
|
|
|
let adressenArray = [];
|
|
if (this.data.profilUpdates?.length) {
|
|
adressenArray = adressenArray.concat(
|
|
this.data.profilUpdates
|
|
.filter((update) => {
|
|
return update.requested_change.zustelladresse;
|
|
})
|
|
.map((adresse) => {
|
|
return adresse.requested_change.adresse_id;
|
|
})
|
|
);
|
|
}
|
|
|
|
if (
|
|
!this.data.profilUpdates?.length ||
|
|
!this.data.adressen
|
|
.filter((adresse) => adresse.zustelladresse)
|
|
.every((adresse) =>
|
|
this.data.profilUpdates.some(
|
|
(update) =>
|
|
update.requested_change.adresse_id == adresse.adresse_id
|
|
)
|
|
)
|
|
) {
|
|
adressenArray = adressenArray.concat(
|
|
this.data.adressen
|
|
.filter((adresse) => {
|
|
return adresse.zustelladresse;
|
|
})
|
|
.map((adr) => {
|
|
return adr.adresse_id;
|
|
})
|
|
);
|
|
}
|
|
|
|
return [...new Set(adressenArray)];
|
|
|
|
},
|
|
zustellKontakteCount() {
|
|
if (!this.data || !this.data.kontakte) {
|
|
return null;
|
|
}
|
|
|
|
let kontakteArray = [];
|
|
|
|
if (this.data.profilUpdates?.length) {
|
|
kontakteArray = kontakteArray.concat(
|
|
this.data.profilUpdates
|
|
.filter((update) => {
|
|
return update.status === 'Pending' && update.requested_change.zustellung;
|
|
})
|
|
.map((kontant) => {
|
|
return {
|
|
kontakt_id: kontant.requested_change.kontakt_id,
|
|
kontakttyp: kontant.requested_change.kontakttyp
|
|
};
|
|
})
|
|
);
|
|
}
|
|
|
|
if (
|
|
!this.data.profilUpdates?.length ||
|
|
!this.data.kontakte
|
|
.filter((kontakt) => kontakt.zustellung)
|
|
.every((kontakt) =>
|
|
this.data.profilUpdates.some(
|
|
(update) =>
|
|
update.status === 'Pending' && update.requested_change.kontakt_id == kontakt.kontakt_id
|
|
)
|
|
)
|
|
) {
|
|
kontakteArray = kontakteArray.concat(
|
|
this.data.kontakte
|
|
.filter((kontakt) => {
|
|
return kontakt.zustellung;
|
|
})
|
|
.map((kon) => {
|
|
return {
|
|
kontakt_id: kon.kontakt_id,
|
|
kontakttyp: kon.kontakttyp
|
|
};
|
|
})
|
|
);
|
|
}
|
|
|
|
return [...new Set(kontakteArray)];
|
|
},
|
|
},
|
|
computed: {
|
|
|
|
filteredEditData() {
|
|
if (!this.data) {
|
|
return;
|
|
}
|
|
|
|
return {
|
|
view: null,
|
|
data: {
|
|
Personen_Informationen: {
|
|
title: this.$p.t("profil", "personenInformationen"),
|
|
topic: "Personen_informationen",
|
|
view: null,
|
|
data: {
|
|
vorname: {
|
|
title: this.$p.t("person", "vorname"),
|
|
topic: this.profilUpdateTopic?.["Vorname"],
|
|
view: "TextInputDokument",
|
|
withFiles: true,
|
|
data: {
|
|
titel: "vorname",
|
|
value: this.data.vorname,
|
|
},
|
|
},
|
|
nachname: {
|
|
title: this.$p.t("person", "nachname"),
|
|
topic: this.profilUpdateTopic?.["Nachname"],
|
|
view: "TextInputDokument",
|
|
withFiles: true,
|
|
data: {
|
|
titel: "nachname",
|
|
value: this.data.nachname,
|
|
},
|
|
},
|
|
titel: {
|
|
title: this.$p.t("global", "titel"),
|
|
topic: this.profilUpdateTopic?.["Titel"],
|
|
view: "TextInputDokument",
|
|
withFiles: true,
|
|
data: {
|
|
titel: "titel",
|
|
value: this.data.titel,
|
|
},
|
|
},
|
|
postnomen: {
|
|
title: this.$p.t("profil", "postnomen"),
|
|
topic: this.profilUpdateTopic?.["Postnomen"],
|
|
view: "TextInputDokument",
|
|
withFiles: true,
|
|
data: {
|
|
titel: "postnomen",
|
|
value: this.data.postnomen,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Private_Kontakte: {
|
|
title: this.$p.t("profil", "privateKontakte"),
|
|
topic: this.profilUpdateTopic?.["Private Kontakte"],
|
|
data: this.data.kontakte
|
|
?.filter((item) => {
|
|
// excludes all contacts that are already used in pending profil update requests
|
|
return !this.data.profilUpdates?.some(
|
|
(update) =>
|
|
update.status === this.profilUpdateStates["Pending"] &&
|
|
update.requested_change?.kontakt_id === item.kontakt_id
|
|
);
|
|
})
|
|
.map((kontakt) => {
|
|
return {
|
|
listview: "Kontakt",
|
|
view: "EditKontakt",
|
|
data: kontakt,
|
|
};
|
|
}),
|
|
},
|
|
Private_Adressen: {
|
|
title: this.$p.t("profil", "privateAdressen"),
|
|
topic: this.profilUpdateTopic?.["Private Adressen"],
|
|
data: this.data.adressen
|
|
?.filter((item) => {
|
|
return !this.data.profilUpdates?.some((update) => {
|
|
return (
|
|
update.status === this.profilUpdateStates["Pending"] &&
|
|
update.requested_change?.adresse_id == item.adresse_id
|
|
);
|
|
});
|
|
})
|
|
.map((adresse) => {
|
|
return {
|
|
listview: "Adresse",
|
|
view: "EditAdresse",
|
|
data: adresse,
|
|
};
|
|
}),
|
|
},
|
|
},
|
|
};
|
|
},
|
|
},
|
|
watch: {
|
|
loading: function (newValue) {
|
|
if (newValue) {
|
|
this.$refs.loadingModalRef.show();
|
|
} else {
|
|
this.$refs.loadingModalRef.hide();
|
|
}
|
|
},
|
|
uid (newVal, oldVal) {
|
|
this.load()
|
|
}
|
|
},
|
|
created() {
|
|
this.load()
|
|
},
|
|
template: `
|
|
<div>
|
|
<div v-if="notFoundUID">
|
|
<h3>Es wurde keine Person mit der UID {{this.notFoundUID}} gefunden</h3>
|
|
</div>
|
|
<div v-else>
|
|
<loading ref="loadingModalRef" :timeout="0"></loading>
|
|
<component :is="view" :data="data" :editData="filteredEditData" ></component>
|
|
</div>
|
|
</div>`,
|
|
}
|
|
|
|
export default Profil |