diff --git a/application/controllers/Cis/Zeitsperren.php b/application/controllers/Cis/Zeitsperren.php new file mode 100644 index 000000000..e337b2f98 --- /dev/null +++ b/application/controllers/Cis/Zeitsperren.php @@ -0,0 +1,30 @@ + ['basis/cis:r'], + ]); + + // Load Libraries + $this->load->library('VariableLib', ['uid' => getAuthUID()]); + } + + /** + * index loads the view Zeitsperren + * @access public + * @return void + */ + public function index() + { + $viewData = array( + 'uid'=>getAuthUID(), + ); + + $this->load->view('CisRouterView/CisRouterView.php',['viewData' => $viewData, 'route' => 'zeitsperren']); + } +} diff --git a/application/controllers/api/frontend/v1/Zeitsperren.php b/application/controllers/api/frontend/v1/Zeitsperren.php new file mode 100644 index 000000000..96a76da31 --- /dev/null +++ b/application/controllers/api/frontend/v1/Zeitsperren.php @@ -0,0 +1,49 @@ + self::PERM_LOGGED, + 'getTypenZeitsperren' => self::PERM_LOGGED, + ]); + + // Load Libraries + $this->load->library('VariableLib', ['uid' => getAuthUID()]); + $this->load->library('form_validation'); + + // Load language phrases + $this->loadPhrases([ + 'ui', + 'person' + ]); + + // Load models + $this->load->model('ressource/Zeitsperre_model', 'ZeitsperreModel'); + $this->load->model('ressource/Zeitsperretyp_model', 'ZeitsperretypModel'); + } + + public function getZeitsperrenUser($uid) + { + $result = $this->ZeitsperreModel->getZeitsperrenUser($uid); + + if (isError($result)) { + $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); + } + $this->terminateWithSuccess((getData($result) ?: [])); + } + + public function getTypenZeitsperren() + { + $this->ZeitsperretypModel->addOrder('beschreibung', 'ASC'); + $result = $this->ZeitsperretypModel->load(); + if (isError($result)) { + $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); + } + $this->terminateWithSuccess((getData($result) ?: [])); + } + +} diff --git a/application/models/ressource/Zeitsperre_model.php b/application/models/ressource/Zeitsperre_model.php index 078d29d8b..25eee4b9a 100644 --- a/application/models/ressource/Zeitsperre_model.php +++ b/application/models/ressource/Zeitsperre_model.php @@ -61,4 +61,39 @@ class Zeitsperre_model extends DB_Model return $this->execQuery($qry); } + + /** + * get Zeitsperren of a user + * + * @param $uid mitarbeiteruid + * @return array + */ + public function getZeitsperrenUser($uid, $bisgrenze=true) + { + //TODO(Manu) check if bisDate is needed +/* $parametersArray = array(); + array_push($parametersArray, $uid); + $parametersArray = [$uid];*/ + + $qry = " + SELECT tbl_zeitsperre.*, tbl_zeitsperretyp.*, tbl_erreichbarkeit.farbe AS erreichbarkeit_farbe, tbl_erreichbarkeit.beschreibung AS erreichbarkeit_beschreibung + FROM (campus.tbl_zeitsperre JOIN campus.tbl_zeitsperretyp USING (zeitsperretyp_kurzbz)) + LEFT JOIN campus.tbl_erreichbarkeit USING (erreichbarkeit_kurzbz) + WHERE mitarbeiter_uid= ? + "; + + if($bisgrenze) + { + $qry.=" + AND ( + (date_part('month',vondatum)>=9 AND date_part('year', vondatum)>='".(date('Y')-1)."') + OR + (date_part('month',vondatum)<9 AND date_part('year', vondatum)>='".(date('Y'))."') + )"; + } + + $qry.= " ORDER BY vondatum DESC"; + + return $this->execQuery($qry, array('mitarbeiter_uid' => $uid)); + } } diff --git a/public/js/api/factory/cis/zeitsperren.js b/public/js/api/factory/cis/zeitsperren.js new file mode 100644 index 000000000..bb8d4d891 --- /dev/null +++ b/public/js/api/factory/cis/zeitsperren.js @@ -0,0 +1,31 @@ +/** + * Copyright (C) 2026 fhcomplete.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +export default { + getTimelocksUser(uid) { + return { + method: 'get', + url: '/api/frontend/v1/Zeitsperren/getZeitsperrenUser/' + uid + }; + }, + getTypenZeitsperren(){ + return { + method: 'get', + url: '/api/frontend/v1/Zeitsperren/getTypenZeitsperren/' + }; + } +}; \ No newline at end of file diff --git a/public/js/apps/Dashboard/Fhc.js b/public/js/apps/Dashboard/Fhc.js index 190ed1a93..540d9619a 100644 --- a/public/js/apps/Dashboard/Fhc.js +++ b/public/js/apps/Dashboard/Fhc.js @@ -16,6 +16,7 @@ import AbgabetoolStudent from "../../components/Cis/Abgabetool/AbgabetoolStudent import AbgabetoolMitarbeiter from "../../components/Cis/Abgabetool/AbgabetoolMitarbeiter.js"; import DeadlineOverview from "../../components/Cis/Abgabetool/DeadlineOverview.js"; import Studium from "../../components/Cis/Studium/Studium.js"; +import Zeitsperren from "../../components/Cis/Zeitsperren/Zeitsperren.js"; import ApiRenderers from '../../api/factory/renderers.js'; import ApiRouteInfo from '../../api/factory/routeinfo.js'; @@ -216,6 +217,12 @@ const router = VueRouter.createRouter({ }; }, }, + { + path: `/Cis/Zeitsperren`, + name: 'Zeitsperren', + component: Zeitsperren, + props: true + }, ] }) diff --git a/public/js/components/Cis/Zeitsperren/Zeitsperren.js b/public/js/components/Cis/Zeitsperren/Zeitsperren.js new file mode 100644 index 000000000..e779bdbf6 --- /dev/null +++ b/public/js/components/Cis/Zeitsperren/Zeitsperren.js @@ -0,0 +1,272 @@ +import {CoreFilterCmpt} from "../../filter/Filter.js"; +import FormForm from '../../Form/Form.js'; +import FormInput from '../../Form/Input.js'; + +import ApiAuthinfo from '../../../api/factory/authinfo.js'; +import ApiTimelocks from "../../../api/factory/cis/zeitsperren.js"; + +export default { + name: 'ZeitsperrenComponent', + components: { + CoreFilterCmpt, + FormForm, + FormInput + }, + data(){ + return { + uid: null, + listTypenZeitsperren: [], + tabulatorOptions: null, + tabulatorEvents: [], + zeitsperreData: {} + }; + }, + methods: { + actionNewZeitsperre(){ + console.log("actionNewZeitsperre "); + }, + actionEditZeitsperre(zeitsperre_id){ + console.log("actionEditZeitsperre " + zeitsperre_id); + }, + actionDeleteZeitsperre(zeitsperre_id){ + console.log("actionDeleteZeitsperre " + zeitsperre_id); + }, + }, + created() { + this.$api.call(ApiAuthinfo.getAuthUID()).then(res => { + this.uid = res.data.uid; + //TODO(Manu) check if uid via props is better + this.tabulatorOptions = { + ajaxURL: 'dummy', + ajaxRequestFunc: () => + this.$api.call(ApiTimelocks.getTimelocksUser(this.uid)), + ajaxResponse: (url, params, response) => response.data, + columns: [ + {title:"beschreibung", field:"beschreibung"}, + {title:"Grund", field:"zeitsperretyp_kurzbz"}, + {title:"Von", field:"vondatum", + formatter: function (cell) { + const dateStr = cell.getValue(); + if (!dateStr) return ""; + + const date = new Date(dateStr); + return date.toLocaleString("de-DE", { + day: "2-digit", + month: "2-digit", + year: "numeric", + }); + } + }, + {title:"Bis", field:"bisdatum", + formatter: function (cell) { + const dateStr = cell.getValue(); + if (!dateStr) return ""; + + const date = new Date(dateStr); + return date.toLocaleString("de-DE", { + day: "2-digit", + month: "2-digit", + year: "numeric", + }); + } + }, + {title:"vonstunde", field:"vonstunde", visible: false}, + {title:"bisstunde", field:"bisstunde", visible: false}, + {title:"Vertretung", field:"vertretung_uid"}, + {title:"Erreichbarkeit", field:"erreichbarkeit_kurzbz"}, + {title:"zeitsperre_id", field:"zeitsperre_id", visible: false}, + {title:"mitarbeiter_uid", field:"mitarbeiter_uid", visible: false}, + {title: 'Aktionen', field: 'actions', + minWidth: 150, // Ensures Action-buttons will be always fully displayed + formatter: (cell, formatterParams, onRendered) => { + let container = document.createElement('div'); + container.className = "d-flex gap-2"; + + let button = document.createElement('button'); + button.className = 'btn btn-outline-secondary btn-action'; + button.innerHTML = ''; + button.title = this.$p.t('person', 'bankvb_edit'); + button.addEventListener('click', (event) => + this.actionEditZeitsperre(cell.getData().zeitsperre_id) + ); + container.append(button); + + button = document.createElement('button'); + button.className = 'btn btn-outline-secondary btn-action'; + button.innerHTML = ''; + button.title = this.$p.t('person', 'bankvb_delete'); + button.addEventListener('click', () => + this.actionDeleteZeitsperre(cell.getData().zeitsperre_id) + ); + container.append(button); + + return container; + }, + frozen: true + }, + ] + }; + }); + + this.$api + .call(ApiTimelocks.getTypenZeitsperren()) + .then(result => { + this.listTypenZeitsperren = result.data; + }) + .catch(this.$fhcAlert.handleSystemError); + + }, + +/* created(){ + this.$api + .call(ApiAuthinfo.getAuthUID()) + .then(res => { + this.uid = res.data.uid; + }); + + + },*/ + /* + + :label="$p.t('global/name')" + + :new-btn-label="this.$p.t('profil', 'zeitsperren')" + {title:"bezeichnung", field:"bezeichnung"}, + {title:"updateamum", field:"updateamum"}, + {title:"updatevon", field:"updatevon"}, + {title:"insertamum", field:"insertamum"}, + {title:"insertvon", field:"insertvon"}, + {title:"freigabevon", field:"freigabevon"}, + {title:"freigabeamum", field:"freigabeamum"}, + */ + + template: /* html */` +
+

Meine Zeitsperren ({{uid}})

+ + {{zeitsperreData}} + + + + +
+ + +
+ +
+ + + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+ + +
+ +
+
+ +
+
+
+ + + + + +
+ ` +}; \ No newline at end of file