diff --git a/application/controllers/Cis/ProfilUpdate.php b/application/controllers/Cis/ProfilUpdate.php
index df7dd4ae8..a16248a3b 100755
--- a/application/controllers/Cis/ProfilUpdate.php
+++ b/application/controllers/Cis/ProfilUpdate.php
@@ -12,6 +12,7 @@ class ProfilUpdate extends Auth_Controller
public function __construct(){
parent::__construct([
'index' => ['student/stammdaten:r','mitarbeiter/stammdaten:r'],
+ 'id' => ['student/stammdaten:r','mitarbeiter/stammdaten:r'],
'getProfilUpdateWithPermission' => ['student/stammdaten:r','mitarbeiter/stammdaten:r'],
'acceptProfilRequest'=>['student/stammdaten:rw','mitarbeiter/stammdaten:rw'],
'denyProfilRequest'=>['student/stammdaten:rw','mitarbeiter/stammdaten:rw'],
@@ -25,6 +26,7 @@ class ProfilUpdate extends Auth_Controller
'getProfilRequestFiles' => ['student/anrechnung_beantragen:r', 'user:r'],
+
]);
@@ -51,6 +53,9 @@ class ProfilUpdate extends Auth_Controller
$this->load->view('Cis/ProfilUpdate');
}
+ public function id($profil_update_id=null){
+ $this->load->view('Cis/ProfilUpdate',['profil_update_id'=>$profil_update_id]);
+ }
private function sendEmail_onProfilUpdate_response($uid,$topic,$status){
@@ -60,15 +65,15 @@ class ProfilUpdate extends Auth_Controller
//? translation of the english version of the status to german
$status_de = $status == 'accepted' ? 'akzeptiert' : 'abgelehnt';
- $mail_res = sendSanchoMail("profil_update_response",['topic'=>$topic,'status_de'=>$status_de,'status_en'=>$status,'href'=>'https://c3p0.ma0594.technikum-wien.at/fh-core/cis.php/Cis/Profil'],$email,("Profil Änderung ".$status));
+ $mail_res = sendSanchoMail("profil_update_response",['topic'=>$topic,'status_de'=>$status_de,'status_en'=>$status,'href'=>APP_ROOT.'Cis/Profil'],$email,("Profil Änderung ".$status));
if(!$mail_res){
show_error("failed to send email to " . $email);
}
- var_dump($mail_res);
}
- private function sendEmail_onProfilUpdate_insertion($uid,$topic){
+ private function sendEmail_onProfilUpdate_insertion($uid,$profil_update_id,$topic){
+
$this->load->helper('hlp_sancho_helper');
$emails = [];
@@ -125,7 +130,7 @@ class ProfilUpdate extends Auth_Controller
$mail_res =[];
//? sending email
foreach($emails as $email){
- array_push($mail_res,sendSanchoMail("profil_update",['uid'=>$uid,'topic'=>$topic,'href'=>'https://c3p0.ma0594.technikum-wien.at/fh-core/cis.php/Cis/ProfilUpdate'],$email,("Profil Änderung von ".$uid)));
+ array_push($mail_res,sendSanchoMail("profil_update",['uid'=>$uid,'topic'=>$topic,'href'=>APP_ROOT.'Cis/ProfilUpdate/id/'.$profil_update_id],$email,("Profil Änderung von ".$uid)));
}
foreach($mail_res as $m_res){
if(!$m_res){
@@ -153,7 +158,7 @@ class ProfilUpdate extends Auth_Controller
{
// Get file to be downloaded from DMS
$newFilename= $this->uid."/document_".$dms_id;
- $download = $this->dmslib->download($dms_id, $newFilename);
+ $download = $this->dmslib->download($dms_id);
if (isError($download)) return $download;
// Download file
@@ -219,6 +224,7 @@ class ProfilUpdate extends Auth_Controller
];
$tmp_res=$this->dmslib->upload($dms , 'files', array("jpg", "png", "pdf"));
+
$tmp_res = hasData($tmp_res)? getData($tmp_res) : null;
array_push($res,$tmp_res);
}
@@ -292,6 +298,7 @@ class ProfilUpdate extends Auth_Controller
public function insertProfilRequest()
{
+
$json = json_decode($this->input->raw_input_stream);
$payload = $json->payload;
@@ -354,7 +361,7 @@ class ProfilUpdate extends Auth_Controller
$insertID = hasData($insertID)? getData($insertID): null;
//? sends emails to the correspondents of the $uid
- $this->sendEmail_onProfilUpdate_insertion($this->uid,$json->topic);
+ $this->sendEmail_onProfilUpdate_insertion($this->uid,$insertID,$json->topic);
echo json_encode(success($insertID));
}
}
@@ -374,6 +381,7 @@ class ProfilUpdate extends Auth_Controller
//catch error
}else{
$updateID = hasData($updateID)? getData($updateID)[0]: null;
+ //TODO: should an email be sent to the responsable people when the user changes his profil update
echo json_encode(success($updateID));
}
}
diff --git a/application/views/Cis/ProfilUpdate.php b/application/views/Cis/ProfilUpdate.php
index 1c50bf458..ff303b159 100755
--- a/application/views/Cis/ProfilUpdate.php
+++ b/application/views/Cis/ProfilUpdate.php
@@ -8,8 +8,9 @@ $includesArray = ['title'=> 'Profil Änderungen',
$this->load->view('templates/CISHTML-Header',$includesArray);
?>
-
+
load->view('templates/CISHTML-Footer',$includesArray); ?>
\ No newline at end of file
diff --git a/public/js/apps/Cis/ProfilUpdateRequests.js b/public/js/apps/Cis/ProfilUpdateRequests.js
index cfc824b90..5132b84bb 100755
--- a/public/js/apps/Cis/ProfilUpdateRequests.js
+++ b/public/js/apps/Cis/ProfilUpdateRequests.js
@@ -1,275 +1,19 @@
import fhcapifactory from "../api/fhcapifactory.js";
-import { CoreFilterCmpt } from "../../components/filter/Filter.js";
-import AcceptDenyUpdate from "../../components/Cis/ProfilUpdate/AcceptDenyUpdate.js";
-import Alert from "../../components/Bootstrap/Alert.js";
+import ProfilUpdateView from "../../components/Cis/ProfilUpdate/ProfilUpdateView.js";
Vue.$fhcapi = fhcapifactory;
-const sortProfilUpdates = (ele1, ele2) => {
- let result = 0;
- if (ele1.status === "pending") {
- result = -1;
- } else if (ele1.status === "accepted") {
- result = ele2.status === "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;
-};
+
const app = Vue.createApp({
components: {
- CoreFilterCmpt,
+ ['profil-update-view']:ProfilUpdateView
+
},
data() {
return {
- showAll: false,
-
- profil_updates_table_options: {
- ajaxURL:
- FHC_JS_DATA_STORAGE_OBJECT.app_root +
- FHC_JS_DATA_STORAGE_OBJECT.ci_router +
- `/Cis/ProfilUpdate/`,
-
- ajaxURLGenerator: (url, config, params) => {
- //? this function needs to be an array function in order to access the this properties of the Vue component
- if (this.showAll) {
- return url + "getProfilUpdateWithPermission";
- } else {
- return url + "getProfilUpdateWithPermission/pending";
- }
- },
- ajaxResponse: function (url, params, response) {
- //url - the URL of the request
- //params - the parameters passed with the request
- //response - the JSON object returned in the body of the response.
- //? sorts the response data from the backend
- if (response) response.sort(sortProfilUpdates);
-
- return response;
- },
- //? adds tooltip with the status message of a profil update request if its status is not pending
- columnDefaults: {
- tooltip: (e, cell, onRendered) =>{
- //e - mouseover event
- //cell - cell component
- //onRendered - onRendered callback registration function
- let statusMessage = cell.getData().status_message;
- let statusDate = cell.getData().status_timestamp;
- let status = cell.getData().status;
- if (!statusMessage) {
- return null;
- }
- let el = document.createElement("div");
- el.classList.add("border", "border-dark");
-
- let statusDateEl = document.createElement("span");
- statusDateEl.classList.add("d-block","mb-1");
- statusDateEl.innerHTML =
- "Request was " + status + " on " + statusDate;
- let statusMessageEl = document.createElement("span");
- statusMessageEl.innerHTML = "Status message: " + statusMessage;
-
- el.appendChild(statusDateEl);
- el.appendChild(statusMessageEl);
- return el;
- },
- },
- rowContextMenu: (e, component) => {
- let menu = [];
- if (component.getData().status === "pending") {
- menu.push(
- {
- label: "
Accept Request",
- action: (e, column) => {
- Vue.$fhcapi.ProfilUpdate.acceptProfilRequest(column.getData())
- .then((res) => {
- this.$refs.UpdatesTable.tabulator.setData();
- })
- .catch((e) => {
- Alert.popup(Vue.h('div',{innerHTML:e.response.data}));
- });
- },
- },
- {
- separator: true,
- },
- {
- label:
- "
Deny Request",
- action: (e, column) => {
- Vue.$fhcapi.ProfilUpdate.denyProfilRequest(
- column.getData()
- ).then((res) => {
- this.$refs.UpdatesTable.tabulator.setData();
- }).catch((e) => {
- Alert.popup(Vue.h('div',{innerHTML:e.response.data}));
- });
- },
- },
- {
- separator: true,
- },
- {
- label: "
Show Request",
- action: (e, column) => {
- this.showModal(column.getData());
-
- },
- }
- );
- } else {
- menu.push({
- label: "
Show Request",
- action: (e, column) => {
- this.showModal(column.getData());
- },
- });
- }
- return menu;
- },
-
- height: 600,
- layout: "fitColumns",
-
- columns: [
- {
- title: "UID",
- field: "uid",
- minWidth: 200,
- resizable: true,
- headerFilter: true,
- //responsive:0,
- },
- {
- title: "Name",
- field: "name",
- minWidth: 200,
- resizable: true,
- headerFilter: true,
- //responsive:0,
- },
- {
- title: "Topic",
- field: "topic",
- resizable: true,
- minWidth: 200,
- headerFilter: true,
- //responsive:0,
- },
- {
- title: "Insert Date",
- field: "insertamum",
- resizable: true,
- headerFilter: true,
- minWidth: 200,
- //responsive:0,
- },
- {
- title: "Status",
- field: "status",
- hozAlign: "center",
- headerFilter: true,
- formatter: function (cell, para) {
- switch (cell.getValue()) {
- case "pending":
- return "
";
- case "accepted":
- return "
";
- case "rejected":
- return "
";
- default:
- return "
default
";
- }
- },
-
- resizable: true,
- minWidth: 200,
- //responsive:0,
- },
- {
- title: "View",
- formatter: function () {
- return "
";
- },
- resizable: true,
- minWidth: 200,
- hozAlign: "center",
- cellClick: (e, cell) => {
- //! function that is called when clicking on a row in the table
- let cellData = cell.getRow().getData();
- this.showModal(cellData);
- },
- //responsive:0,
- },
- ],
- },
- };
- },
- computed: {
- getFetchUrl: function () {
- let url =
- FHC_JS_DATA_STORAGE_OBJECT.app_root +
- FHC_JS_DATA_STORAGE_OBJECT.ci_router +
- `/Cis/ProfilUpdate/`;
- if (this.showAll) {
- url + "getAllRequests";
- } else {
- url + "getPendingRequests";
- }
- return url;
- },
- },
- methods: {
- showModal: function (value) {
- AcceptDenyUpdate.popup({ value: value })
- .then((res) => {
-
- //? refetches the data, if any request was denied or accepted
- //* setData will call the ajaxURL again to refresh the data
- this.$refs.UpdatesTable.tabulator.setData();
- }).catch(err=>{
-
- })
-
- },
- updateData: function (event) {
- this.$refs.UpdatesTable.tabulator.setData();
- //? store the selected view in the session storage of the browser
- sessionStorage.setItem("showAll", event.target.value);
- },
- },
- mounted() {
-
- if (!(sessionStorage.getItem("showAll") === null)) {
- //? converting string into a boolean: https://sentry.io/answers/how-can-i-convert-a-string-to-a-boolean-in-javascript/
- this.showAll = sessionStorage.getItem("showAll")==="true";
-
}
},
- template: `
-
`,
});
app.mount("#content");
diff --git a/public/js/components/Cis/Profil/EditProfil.js b/public/js/components/Cis/Profil/EditProfil.js
index d72925639..9fac1ffbe 100755
--- a/public/js/components/Cis/Profil/EditProfil.js
+++ b/public/js/components/Cis/Profil/EditProfil.js
@@ -114,6 +114,7 @@ export default {
await Vue.$fhcapi.ProfilUpdate.insertFile(formData,this.editData.updateID).then(res => {
return res.data?.map((file) => file.dms_id);
})
+
:
//? fresh insert of new attachment
await Vue.$fhcapi.ProfilUpdate.insertFile(formData).then(res => {
diff --git a/public/js/components/Cis/Profil/MitarbeiterProfil.js b/public/js/components/Cis/Profil/MitarbeiterProfil.js
index 818858473..96587dd1c 100755
--- a/public/js/components/Cis/Profil/MitarbeiterProfil.js
+++ b/public/js/components/Cis/Profil/MitarbeiterProfil.js
@@ -243,7 +243,6 @@ export default {
},
template: /*html*/`
-
test
diff --git a/public/js/components/Cis/ProfilUpdate/ProfilUpdateView.js b/public/js/components/Cis/ProfilUpdate/ProfilUpdateView.js
new file mode 100644
index 000000000..e04bf321b
--- /dev/null
+++ b/public/js/components/Cis/ProfilUpdate/ProfilUpdateView.js
@@ -0,0 +1,297 @@
+
+import { CoreFilterCmpt } from "../../filter/Filter.js";
+import AcceptDenyUpdate from "./AcceptDenyUpdate.js";
+import Alert from "../../../components/Bootstrap/Alert.js";
+
+
+const sortProfilUpdates = (ele1, ele2) => {
+ let result = 0;
+ if (ele1.status === "pending") {
+ result = -1;
+ } else if (ele1.status === "accepted") {
+ result = ele2.status === "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;
+};
+
+export default{
+ components: {
+ CoreFilterCmpt,
+ },
+ props:{
+ id:{
+ type:Number,
+ }
+ },
+ data() {
+ return {
+
+ showAll: false,
+ events:[],
+ profil_update_id:Number(this.id),
+ profil_updates_table_options: {
+
+ ajaxURL:
+ FHC_JS_DATA_STORAGE_OBJECT.app_root +
+ FHC_JS_DATA_STORAGE_OBJECT.ci_router +
+ `/Cis/ProfilUpdate/`,
+
+ ajaxURLGenerator: (url, config, params) => {
+ //? this function needs to be an array function in order to access the this properties of the Vue component
+ if (this.showAll) {
+ return url + "getProfilUpdateWithPermission";
+ } else {
+ return url + "getProfilUpdateWithPermission/pending";
+ }
+ },
+ ajaxResponse: function (url, params, response) {
+ //url - the URL of the request
+ //params - the parameters passed with the request
+ //response - the JSON object returned in the body of the response.
+ //? sorts the response data from the backend
+ if (response) response.sort(sortProfilUpdates);
+
+ return response;
+ },
+ //? adds tooltip with the status message of a profil update request if its status is not pending
+ columnDefaults: {
+ tooltip: (e, cell, onRendered) =>{
+ //e - mouseover event
+ //cell - cell component
+ //onRendered - onRendered callback registration function
+ let statusMessage = cell.getData().status_message;
+ let statusDate = cell.getData().status_timestamp;
+ let status = cell.getData().status;
+ if (!statusMessage) {
+ return null;
+ }
+ let el = document.createElement("div");
+ el.classList.add("border", "border-dark");
+
+ let statusDateEl = document.createElement("span");
+ statusDateEl.classList.add("d-block","mb-1");
+ statusDateEl.innerHTML =
+ "Request was " + status + " on " + statusDate;
+ let statusMessageEl = document.createElement("span");
+ statusMessageEl.innerHTML = "Status message: " + statusMessage;
+
+ el.appendChild(statusDateEl);
+ el.appendChild(statusMessageEl);
+ return el;
+ },
+ },
+ rowContextMenu: (e, component) => {
+ let menu = [];
+ if (component.getData().status === "pending") {
+ menu.push(
+ {
+ label: "
Accept Request",
+ action: (e, column) => {
+ Vue.$fhcapi.ProfilUpdate.acceptProfilRequest(column.getData())
+ .then((res) => {
+ this.$refs.UpdatesTable.tabulator.setData();
+ })
+ .catch((e) => {
+ Alert.popup(Vue.h('div',{innerHTML:e.response.data}));
+ });
+ },
+ },
+ {
+ separator: true,
+ },
+ {
+ label:
+ "
Deny Request",
+ action: (e, column) => {
+ Vue.$fhcapi.ProfilUpdate.denyProfilRequest(
+ column.getData()
+ ).then((res) => {
+ this.$refs.UpdatesTable.tabulator.setData();
+ }).catch((e) => {
+ Alert.popup(Vue.h('div',{innerHTML:e.response.data}));
+ });
+ },
+ },
+ {
+ separator: true,
+ },
+ {
+ label: "
Show Request",
+ action: (e, column) => {
+ this.showModal(column.getData());
+
+ },
+ }
+ );
+ } else {
+ menu.push({
+ label: "
Show Request",
+ action: (e, column) => {
+ this.showModal(column.getData());
+ },
+ });
+ }
+ return menu;
+ },
+
+ height: 600,
+ layout: "fitColumns",
+
+ columns: [
+ {
+ title: "UID",
+ field: "uid",
+ minWidth: 200,
+ resizable: true,
+ headerFilter: true,
+ //responsive:0,
+ },
+ {
+ title: "Name",
+ field: "name",
+ minWidth: 200,
+ resizable: true,
+ headerFilter: true,
+ //responsive:0,
+ },
+ {
+ title: "Topic",
+ field: "topic",
+ resizable: true,
+ minWidth: 200,
+ headerFilter: true,
+ //responsive:0,
+ },
+ {
+ title: "Insert Date",
+ field: "insertamum",
+ resizable: true,
+ headerFilter: true,
+ minWidth: 200,
+ //responsive:0,
+ },
+ {
+ title: "Status",
+ field: "status",
+ hozAlign: "center",
+ headerFilter: true,
+ formatter: function (cell, para) {
+ switch (cell.getValue()) {
+ case "pending":
+ return "
";
+ case "accepted":
+ return "
";
+ case "rejected":
+ return "
";
+ default:
+ return "
default
";
+ }
+ },
+
+ resizable: true,
+ minWidth: 200,
+ //responsive:0,
+ },
+ {
+ title: "View",
+ formatter: function () {
+ return "
";
+ },
+ resizable: true,
+ minWidth: 200,
+ hozAlign: "center",
+ cellClick: (e, cell) => {
+ //! function that is called when clicking on a row in the table
+ let cellData = cell.getRow().getData();
+ this.showModal(cellData);
+ },
+ //responsive:0,
+ },
+ ],
+ },
+ };
+ },
+ computed: {
+ getFetchUrl: function () {
+ let url =
+ FHC_JS_DATA_STORAGE_OBJECT.app_root +
+ FHC_JS_DATA_STORAGE_OBJECT.ci_router +
+ `/Cis/ProfilUpdate/`;
+ if (this.showAll) {
+ url + "getAllRequests";
+ } else {
+ url + "getPendingRequests";
+ }
+ return url;
+ },
+ },
+ methods: {
+
+ showModal: function (value) {
+ AcceptDenyUpdate.popup({ value: value })
+ .then((res) => {
+
+ //? refetches the data, if any request was denied or accepted
+ //* setData will call the ajaxURL again to refresh the data
+ this.$refs.UpdatesTable.tabulator.setData();
+ }).catch(err=>{
+
+ })
+
+ },
+ updateData: function (event) {
+ this.$refs.UpdatesTable.tabulator.setData();
+ //? store the selected view in the session storage of the browser
+ sessionStorage.setItem("showAll", event.target.value);
+ },
+ },
+
+ mounted() {
+
+ //? opens the AcceptDenyUpdate Modal if the a preselected profil_update_id was passed to the component (used for email links)
+ if(this.profil_update_id){
+
+ this.$refs.UpdatesTable.tabulator.on("dataProcessed", ()=>{
+ const arrayRowData = this.$refs.UpdatesTable.tabulator.getData().filter(row => {
+ return row.profil_update_id === this.profil_update_id;
+ });
+ if(arrayRowData.length){
+ this.showModal(arrayRowData[0]);
+ }
+ })
+ }
+
+
+ if (!(sessionStorage.getItem("showAll") === null)) {
+ //? converting string into a boolean: https://sentry.io/answers/how-can-i-convert-a-string-to-a-boolean-in-javascript/
+ this.showAll = sessionStorage.getItem("showAll")==="true";
+
+ }
+ },
+ template: `
+
`,
+};