mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-07-20 00:12:15 +00:00
changes how to display the hr table with all the user update requests and the update request table in the profil view, also adds some new columns to the cis_profil_update table to store the status, status date and status message
This commit is contained in:
@@ -94,7 +94,7 @@ class Profil extends Auth_Controller
|
||||
$payload = $json->payload;
|
||||
$type = isset($json->payload->kontakt_id)? "kontakt_id" : "adresse_id";
|
||||
|
||||
$data = ["topic"=>$json->topic,"uid" => $this->uid, "requested_change" => json_encode($payload), "change_timestamp" => "NOW()" ];
|
||||
$data = ["topic"=>$json->topic,"uid" => $this->uid, "requested_change" => json_encode($payload), "change_timestamp" => "NOW()","status"=>"pending" ];
|
||||
|
||||
//? loops over all updateRequests from a user to validate if the new request is valid
|
||||
$res = $this->ProfilChangeModel->loadWhere(["uid"=>$this->uid]);
|
||||
@@ -148,7 +148,7 @@ class Profil extends Auth_Controller
|
||||
$json = json_decode($this->input->raw_input_stream);
|
||||
|
||||
|
||||
$data = ["topic"=>$json->topic,"uid" => $this->uid, "requested_change" => json_encode($json->payload), "change_timestamp" => "NOW()" ];
|
||||
$data = ["topic"=>$json->topic,"uid" => $this->uid, "requested_change" => json_encode($json->payload), "change_timestamp" => "NOW()","status"=>"pending" ];
|
||||
|
||||
//? gets all the requested changes from a user
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@ class ProfilUpdate extends Auth_Controller
|
||||
parent::__construct([
|
||||
'index' => ['student/anrechnung_beantragen:r', 'user:r'], // TODO(chris): permissions?
|
||||
'getAllRequests' => ['student/anrechnung_beantragen:r', 'user:r'],
|
||||
'acceptProfilRequest'=>['user:r'],
|
||||
'denyProfilRequest'=>['user:r'],
|
||||
|
||||
]);
|
||||
//? put the uid and pid inside the controller to reuse in controller
|
||||
@@ -28,22 +30,39 @@ class ProfilUpdate extends Auth_Controller
|
||||
}
|
||||
|
||||
public function getAllRequests(){
|
||||
|
||||
$res = $this->ProfilChangeModel->load();
|
||||
if(isError($res)){
|
||||
// catch exception
|
||||
echo $res->retval->data;
|
||||
return;
|
||||
}else{
|
||||
if(hasData($res)){
|
||||
$res = getData($res);
|
||||
foreach($res as $element){
|
||||
$element->change_timestamp = date_create($element->change_timestamp)->format('d/m/Y H:i');
|
||||
}
|
||||
}else{
|
||||
$res = null;
|
||||
}
|
||||
}
|
||||
$res = $this->ProfilChangeModel->getProfilUpdate();
|
||||
$res = hasData($res)? getData($res) : null;
|
||||
echo json_encode($res);
|
||||
}
|
||||
|
||||
public function acceptProfilRequest(){
|
||||
$_POST = json_decode($this->input->raw_input_stream,true);
|
||||
|
||||
$id = $this->input->post('requestID',true);
|
||||
|
||||
if(isset($id)){
|
||||
$res =$this->ProfilChangeModel->update([$id], ["status"=>"accepted","status_timestamp"=>"NOW()"]);
|
||||
echo json_encode($res);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function denyProfilRequest(){
|
||||
$_POST = json_decode($this->input->raw_input_stream,true);
|
||||
|
||||
$id = $this->input->post('requestID',true);
|
||||
|
||||
if(isset($id)){
|
||||
var_dump($id);
|
||||
//! instead of deleting the rejected profil update, the status of the db entry is set to rejected
|
||||
//$res = $this->ProfilChangeModel->delete([$id]);
|
||||
|
||||
|
||||
$res = $this->ProfilChangeModel->update([$id],["status"=>"rejected","status_timestamp"=>"NOW()"]);
|
||||
echo json_encode($res);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -30,8 +30,13 @@ class Profil_change_model extends DB_Model
|
||||
* returns a profil update with id
|
||||
* returns all profil updates if id is set to null
|
||||
*/
|
||||
public function getProfilUpdate($uid,$id=null){
|
||||
$whereClause = ["uid"=>$uid];
|
||||
public function getProfilUpdate($uid=null,$id=null){
|
||||
$whereClause=[];
|
||||
|
||||
if(!is_null($uid)){
|
||||
$whereClause['uid']=$uid;
|
||||
}
|
||||
//?
|
||||
if(!is_null($id)){
|
||||
$whereClause['profil_update_id']=$id;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ $includesArray = array(
|
||||
'title' => 'Stundenplan',
|
||||
'customJSModules' => ['public/js/apps/Cis/Profil.js'],
|
||||
'tabulator5' => true,
|
||||
'customCSSs' => ['public/css/components/calendar.css', 'public/css/components/FilterComponent.css','public/css/components/Profil.css'],
|
||||
'customCSSs' => ['public/css/components/calendar.css', 'public/css/components/FilterComponent.css','public/css/components/Profil.css','public/css/components/FormUnderline.css'],
|
||||
|
||||
);
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
$includesArray = ['title'=> 'Profil Änderungen',
|
||||
'customJSModules'=> ['public/js/apps/Cis/ProfilUpdateRequests.js'],
|
||||
'tabulator5'=> true,
|
||||
'customCSSs'=>['public/css/components/FilterComponent.css'],
|
||||
'customCSSs'=>['public/css/components/FilterComponent.css','public/css/components/FormUnderline.css'],
|
||||
];
|
||||
|
||||
$this->load->view('templates/CISHTML-Header',$includesArray);
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/* FORM UNDERLINE
|
||||
*/
|
||||
.form-underline{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-content: space-between;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
.form-underline .form-underline-content{
|
||||
border-width: 1px;
|
||||
border-color: transparent transparent #dee2e6 transparent;
|
||||
border-style: solid;
|
||||
padding-bottom: 0.25rem;
|
||||
padding-left: 0.5rem;
|
||||
|
||||
/*optional not wrapping text that is horizontally scrollable and does not display a scrollbar */
|
||||
white-space: nowrap;
|
||||
overflow: auto;
|
||||
scrollbar-width: none;
|
||||
|
||||
}
|
||||
|
||||
.form-underline .form-underline-content::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.form-underline .form-underline-titel{
|
||||
opacity: 0.65;
|
||||
font-size: .85rem;
|
||||
padding-left: 0.5rem;
|
||||
}
|
||||
@@ -41,41 +41,7 @@
|
||||
}
|
||||
|
||||
|
||||
/* FORM UNDERLINE
|
||||
*/
|
||||
.form-underline{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-content: space-between;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
.form-underline .form-underline-content{
|
||||
border-width: 1px;
|
||||
border-color: transparent transparent #dee2e6 transparent;
|
||||
border-style: solid;
|
||||
padding-bottom: 0.25rem;
|
||||
padding-left: 0.5rem;
|
||||
|
||||
/*optional not wrapping text that is horizontally scrollable and does not display a scrollbar */
|
||||
white-space: nowrap;
|
||||
overflow: auto;
|
||||
scrollbar-width: none;
|
||||
|
||||
}
|
||||
|
||||
.form-underline .form-underline-content::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.form-underline .form-underline-titel{
|
||||
opacity: 0.65;
|
||||
font-size: .85rem;
|
||||
padding-left: 0.5rem;
|
||||
}
|
||||
|
||||
.btn-circle {
|
||||
width: 30px;
|
||||
|
||||
@@ -1,53 +1,100 @@
|
||||
import fhcapifactory from "../api/fhcapifactory.js";
|
||||
import {CoreFilterCmpt} from '../../components/filter/Filter.js'
|
||||
import {CoreFilterCmpt} from "../../components/filter/Filter.js";
|
||||
import AcceptDenyUpdate from "../../components/Cis/ProfilUpdate/AcceptDenyUpdate.js";
|
||||
Vue.$fhcapi = fhcapifactory;
|
||||
/*
|
||||
data: [
|
||||
{
|
||||
uid: "",
|
||||
profil_changes: "",
|
||||
change_timestamp: "",
|
||||
},
|
||||
], */
|
||||
|
||||
|
||||
let printIcon= function(cell, formatterParams, onRendered){ //plain text value
|
||||
return "<i class='fa fa-eye'></i>";
|
||||
};
|
||||
|
||||
const app = Vue.createApp({
|
||||
components:{
|
||||
CoreFilterCmpt,
|
||||
|
||||
},
|
||||
data(){
|
||||
return{
|
||||
|
||||
profil_updates_table_options:{
|
||||
ajaxURL:FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + '/Cis/ProfilUpdate/getAllRequests',
|
||||
height:300,
|
||||
layout:'fitColumns',
|
||||
responsiveLayout: "collapse",
|
||||
responsiveLayoutCollapseUseFormatters:false,
|
||||
responsiveLayoutCollapseFormatter:this.collapseFormatter,
|
||||
|
||||
columns: [
|
||||
{
|
||||
title: "Uid",
|
||||
field: "uid",
|
||||
title: "Topic",
|
||||
field: "topic",
|
||||
resizable: true,
|
||||
minWidth: 200,
|
||||
responsive:0,
|
||||
//responsive:0,
|
||||
},
|
||||
{
|
||||
title: "Update",
|
||||
field: "profil_changes",
|
||||
minWidth: 10000,
|
||||
responsive:3,
|
||||
title: "UID",
|
||||
field: "uid",
|
||||
minWidth: 200,
|
||||
//responsive:0,
|
||||
},
|
||||
|
||||
{
|
||||
title: "Date",
|
||||
field: "change_timestamp",
|
||||
resizable: true,
|
||||
minWidth: 200,
|
||||
responsive:0,
|
||||
//responsive:0,
|
||||
},
|
||||
{
|
||||
title: "Status",
|
||||
field: "status",
|
||||
hozAlign:'center',
|
||||
formatter: function(cell,para){
|
||||
let res =Object.getPrototypeOf(cell);
|
||||
//console.log(res);
|
||||
|
||||
switch(cell.getValue()){
|
||||
case "pending": return "<i class='fa fa-circle-info text-info fa-lg'></i> pending";
|
||||
case "accepted": return "<i class='fa fa-circle-check text-success fa-lg'></i> accepted";
|
||||
case "rejected": return "<i class='fa-solid fa-circle-xmark text-danger fa-lg '></i> rejected";
|
||||
default: return "<p>default</p>";
|
||||
}
|
||||
},
|
||||
|
||||
resizable: true,
|
||||
minWidth: 200,
|
||||
//responsive:0,
|
||||
},
|
||||
{
|
||||
title: "View",
|
||||
formatter:printIcon,
|
||||
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();
|
||||
AcceptDenyUpdate.popup({value:cellData}).then(res=>{
|
||||
console.log("res of the modal: ",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(e=>{
|
||||
//? catches the rejected Promise if the result of the modal was falsy
|
||||
console.log("catch of the modal: ",e);
|
||||
});
|
||||
|
||||
},
|
||||
//responsive:0,
|
||||
},
|
||||
|
||||
|
||||
|
||||
],
|
||||
},
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
|
||||
},
|
||||
methods:{
|
||||
sideMenuFunction: function(){
|
||||
@@ -82,7 +129,9 @@ const app = Vue.createApp({
|
||||
},
|
||||
created(){
|
||||
|
||||
|
||||
Vue.$fhcapi.ProfilUpdate.getProfilUpdateRequest().then((res)=>{
|
||||
console.log(res.data);
|
||||
})
|
||||
|
||||
|
||||
},
|
||||
@@ -93,6 +142,7 @@ const app = Vue.createApp({
|
||||
template:`
|
||||
<div>
|
||||
|
||||
|
||||
<core-filter-cmpt title="Update Requests" ref="UpdatesTable" :tabulator-options="profil_updates_table_options" tableOnly :sideMenu="false" />
|
||||
|
||||
</div>`,
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import Search from "./search.js";
|
||||
import UserData from "./userdata.js";
|
||||
import ProfilUpdate from "./profilUpdate.js"
|
||||
|
||||
export default {
|
||||
"Search": Search,
|
||||
"UserData": UserData
|
||||
"UserData": UserData,
|
||||
"ProfilUpdate": ProfilUpdate,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
export default {
|
||||
|
||||
//! API calls for profil update requests
|
||||
|
||||
getProfilUpdateRequest: function(){
|
||||
const url = FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + '/Cis/ProfilUpdate/getAllRequests';
|
||||
return axios.get(url);
|
||||
},
|
||||
|
||||
acceptProfilRequest: function(requestID){
|
||||
const url = FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + '/Cis/ProfilUpdate/acceptProfilRequest';
|
||||
return axios.post(url,{requestID: requestID});
|
||||
},
|
||||
|
||||
denyProfilRequest: function(requestID){
|
||||
const url = FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + '/Cis/ProfilUpdate/denyProfilRequest';
|
||||
return axios.post(url,{requestID: requestID});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -56,12 +56,6 @@ export default {
|
||||
},
|
||||
|
||||
|
||||
//! API Calls for Profil Update View
|
||||
|
||||
getProfilUpdateRequest: function(){
|
||||
const url = FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + '/Cis/ProfilUpdate/getAllRequests';
|
||||
return axios.get(url);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -33,12 +33,13 @@ export default {
|
||||
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;
|
||||
case "Delete Adressen" : return "Adresse"; break;
|
||||
case "Delete Kontakte" : return "Kontakt"; break;
|
||||
default: return "text_input"; break;
|
||||
}
|
||||
},
|
||||
openModal(updateRequest) {
|
||||
console.log(JSON.stringify(updateRequest));
|
||||
|
||||
let view = this.getView(updateRequest.topic);
|
||||
let content =null;
|
||||
@@ -104,18 +105,42 @@ export default {
|
||||
<thead>
|
||||
<tr >
|
||||
<th scope="col">Topic</th>
|
||||
<th scope="col">Status</th>
|
||||
<th scope="col">Date of Request</th>
|
||||
<th scope="col">Bearbeiten</th>
|
||||
<th style="white-space:normal" scope="col">Löschen</th>
|
||||
|
||||
<th scope="col">Action</th>
|
||||
|
||||
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="item in data">
|
||||
<!-- :class="{'bg-success':item.status === 'accepted', 'bg-danger':item.status === 'rejected', 'text-white':item.status =='rejected' || item.status=='accepted'}" -->
|
||||
<tr v-for="item in data" :style="item.status=='accepted'?'background-color:lightgreen':item.status==='rejected'?'background-color:lightcoral':''">
|
||||
<td class="align-middle">{{item.topic}}</td>
|
||||
<td class="align-middle text-center" >{{item.status}}</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>
|
||||
|
||||
|
||||
|
||||
<template v-if="item.status === 'pending'">
|
||||
<td>
|
||||
<template v-if="item.topic.toLowerCase().includes('delete')">
|
||||
<!-- old edit view for delete requests <div class="align-middle text-center" >{{item.requested_change.adr_typ?item.requested_change.adr_typ:item.requested_change.kontakt}}</div>-->
|
||||
<div class="align-middle text-center"><i style="color:gray" role="button" @click="openModal(item)" class="fa fa-eye"></i></div>
|
||||
</template>
|
||||
<template v-else >
|
||||
<div class="align-middle text-center" ><i style="color:#00639c" @click="openModal(item)" role="button" class="fa fa-edit"></i></div>
|
||||
</template>
|
||||
|
||||
<div class="align-middle text-center"><i style="color:red" role="button" @click="deleteRequest(item)" class="fa fa-trash"></i></div>
|
||||
|
||||
</td>
|
||||
</template>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
import BsModal from "../../Bootstrap/Modal.js";
|
||||
import Alert from "../../Bootstrap/Alert.js";
|
||||
import Kontakt from "../Profil/ProfilComponents/Kontakt.js";
|
||||
import Adresse from "../Profil/ProfilComponents/Adresse.js";
|
||||
|
||||
|
||||
export default {
|
||||
components: {
|
||||
BsModal,
|
||||
Alert,
|
||||
Kontakt,
|
||||
Adresse,
|
||||
|
||||
},
|
||||
mixins: [BsModal],
|
||||
props: {
|
||||
title:{
|
||||
type:String,
|
||||
default:"Profil Update Request"
|
||||
},
|
||||
value: {
|
||||
type:Object,
|
||||
},
|
||||
/*
|
||||
* NOTE(chris):
|
||||
* Hack to expose in "emits" declared events to $props which we use
|
||||
* in the v-bind directive to forward all events.
|
||||
* @see: https://github.com/vuejs/core/issues/3432
|
||||
*/
|
||||
onHideBsModal: Function,
|
||||
onHiddenBsModal: Function,
|
||||
onHidePreventedBsModal: Function,
|
||||
onShowBsModal: Function,
|
||||
onShownBsModal: Function,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
data: this.value,
|
||||
//? result is returned from the Promise when the modal is closed
|
||||
result: false,
|
||||
info: null,
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
acceptRequest: function(){
|
||||
console.log(this.data.profil_update_id);
|
||||
Vue.$fhcapi.ProfilUpdate.acceptProfilRequest(this.data.profil_update_id).then(res =>{
|
||||
console.log("res",res);
|
||||
console.log("res.data",res.data);
|
||||
this.result = true;
|
||||
})
|
||||
this.hide();
|
||||
},
|
||||
|
||||
denyRequest: function(){
|
||||
console.log(this.data.profil_update_id);
|
||||
Vue.$fhcapi.ProfilUpdate.denyProfilRequest(this.data.profil_update_id).then(res =>{
|
||||
console.log("res",res);
|
||||
console.log("res.data",res.data);
|
||||
this.result = true;
|
||||
})
|
||||
this.hide();
|
||||
},
|
||||
|
||||
submitProfilChange(){
|
||||
//TODO: check if the updated value is different from the original value before submitting the request
|
||||
if(false){
|
||||
|
||||
//? 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)=>{
|
||||
|
||||
if(res.data.error == 0){
|
||||
this.result= true;
|
||||
this.hide();
|
||||
Alert.popup("Ihre Anfrage wurde erfolgreich gesendet. Bitte warten Sie, während sich das Team um Ihre Anfrage kümmert.");
|
||||
}else{
|
||||
this.result= false;
|
||||
this.hide();
|
||||
Alert.popup("Ein Fehler ist aufgetreten: "+ JSON.stringify(res.data.retval));
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
getComponentView: function(){
|
||||
|
||||
if(this.data.topic.toLowerCase().includes("kontakt")){
|
||||
return "kontakt";
|
||||
}else if (this.data.topic.toLowerCase().includes("adresse")){
|
||||
return "adresse";
|
||||
}else{
|
||||
return "text_input";
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
console.log("data passed as prop",this.data);
|
||||
|
||||
},
|
||||
mounted() {
|
||||
this.modal = this.$refs.modalContainer.modal;
|
||||
},
|
||||
popup(options) {
|
||||
return BsModal.popup.bind(this)(null, options);
|
||||
},
|
||||
template: `
|
||||
<bs-modal ref="modalContainer" v-bind="$props" body-class="" dialog-class="modal-lg" class="bootstrap-alert" backdrop="false" >
|
||||
|
||||
<template v-slot:title>
|
||||
{{title}}
|
||||
</template>
|
||||
|
||||
|
||||
<template v-slot:default>
|
||||
<pre>{{JSON.stringify(data.profil_update_id,null,2)}}</pre>
|
||||
<!-- debugging prints
|
||||
<pre>view {{getComponentView}}</pre>
|
||||
<pre>topic {{JSON.stringify(data.topic,null,2)}}</pre>
|
||||
<pre>data {{JSON.stringify(data.requested_change,null,2)}}</pre>
|
||||
-->
|
||||
|
||||
<div class="form-underline mb-2">
|
||||
<div class="form-underline-titel">UserID: </div>
|
||||
|
||||
<span class="form-underline-content" >{{data.uid}}</span>
|
||||
</div>
|
||||
|
||||
<div class="form-underline mb-2">
|
||||
<div class="form-underline-titel">Topic of Request: </div>
|
||||
|
||||
<span class="form-underline-content" >{{data.topic}}</span>
|
||||
</div>
|
||||
|
||||
<div class="form-underline mb-2">
|
||||
<div class="form-underline-titel">Date of Request:</div>
|
||||
|
||||
<span class="form-underline-content" >{{data.change_timestamp}}</span>
|
||||
</div>
|
||||
|
||||
<div v-if="getComponentView==='text_input'" class="form-underline mb-2">
|
||||
<div class="form-underline-titel">{{data.topic}}</div>
|
||||
|
||||
<span class="form-underline-content" >{{data.requested_change}}</span>
|
||||
</div>
|
||||
|
||||
<component v-else :is="getComponentView" :data="data.requested_change"></component>
|
||||
</template>
|
||||
|
||||
|
||||
<template v-slot:footer>
|
||||
<button @click="acceptRequest" class="btn btn-primary">Accept <i class="fa fa-check"></i></button>
|
||||
<button @click="denyRequest" class="btn btn-danger">Deny <i class="fa fa-xmark"></i></button>
|
||||
</template>
|
||||
|
||||
</bs-modal>`,
|
||||
};
|
||||
@@ -8,6 +8,9 @@
|
||||
uid VARCHAR(32) NOT NULL,
|
||||
requested_change jsonb NOT NULL,
|
||||
change_timestamp TIMESTAMP NOT NULL,
|
||||
status VARCHAR(32) NOT NULL,
|
||||
status_timestamp TIMESTAMP NULL,
|
||||
status_message TEXT NULL,
|
||||
CONSTRAINT tbl_cis_profil_update_pk PRIMARY KEY(profil_update_id),
|
||||
CONSTRAINT tbl_cis_profil_update_fk FOREIGN KEY(uid) REFERENCES public.tbl_benutzer(uid)
|
||||
);
|
||||
@@ -19,6 +22,7 @@
|
||||
CACHE 1;
|
||||
|
||||
ALTER TABLE public.tbl_cis_profil_update ALTER COLUMN profil_update_id SET DEFAULT nextval('public.tbl_cis_profil_update_id_seq');
|
||||
ALTER TABLE public.tbl_cis_profil_update ADD CONSTRAINT tbl_cis_profil_update_restricted_status CHECK (status IN ('pending','accepted','rejected'));
|
||||
--ALTER TABLE public.tbl_cis_profil_update ADD CONSTRAINT cis_profil_udpate_topic_uid_unique UNIQUE (uid,topic);
|
||||
|
||||
GRANT SELECT, INSERT, UPDATE, DELETE ON public.tbl_cis_profil_update TO vilesci;
|
||||
|
||||
Reference in New Issue
Block a user