diff --git a/application/config/navigation.php b/application/config/navigation.php index 31ac08766..55a97e7f9 100644 --- a/application/config/navigation.php +++ b/application/config/navigation.php @@ -45,6 +45,14 @@ $config['navigation_header'] = array( 'expand' => true, 'sort' => 30, 'requiredPermissions' => 'admin:w' + ), + 'roomManagerOverview' => array( + 'link' => site_url('RoomManager'), + 'icon' => '', + 'description' => 'Raumverwaltung', + 'expand' => true, + 'sort' => 40, + 'requiredPermissions' => 'admin:w' ) ) ), diff --git a/application/controllers/RoomManager.php b/application/controllers/RoomManager.php index 9591f5f36..2221709eb 100644 --- a/application/controllers/RoomManager.php +++ b/application/controllers/RoomManager.php @@ -15,7 +15,7 @@ class RoomManager extends Auth_Controller { parent::__construct( array( - 'index' => array('lehre/unterrichtszeiten_gk:r'), + 'index' => array('basis/ort:r') ) ); @@ -42,7 +42,11 @@ class RoomManager extends Auth_Controller // Public methods public function index() { - return $this->load->view('room_manager/index'); + return $this->load->view('room_manager/index', [ + 'permissions' => [ + 'basis/ort_w' => $this->permissionlib->isBerechtigt('basis/ort', 'suid'), + ], + ]); } // ----------------------------------------------------------------------------------------------------------------- diff --git a/application/controllers/api/frontend/v1/Ort.php b/application/controllers/api/frontend/v1/Ort.php index aecebfb6d..c43ad8cdf 100644 --- a/application/controllers/api/frontend/v1/Ort.php +++ b/application/controllers/api/frontend/v1/Ort.php @@ -32,15 +32,15 @@ class Ort extends FHCAPI_Controller public function __construct() { parent::__construct([ - 'getAllRooms' => self::PERM_LOGGED, + 'getAllRooms' => array('basis/ort:r'), 'getRooms' => self::PERM_LOGGED, 'getTypes' => self::PERM_LOGGED, 'ContentID' => self::PERM_LOGGED, 'getOrtKurzbzContent' => self::PERM_LOGGED, 'getRoom' => self::PERM_LOGGED, - 'createRoom' => self::PERM_LOGGED, - 'updateRoom' => self::PERM_LOGGED, - 'deleteRoom' => self::PERM_LOGGED, + 'createRoom' => array('basis/ort:rw'), + 'updateRoom' => array('basis/ort:rw'), + 'deleteRoom' => array('basis/ort:rw'), ]); $this->load->library('form_validation'); @@ -82,16 +82,16 @@ class Ort extends FHCAPI_Controller $queryWhereFragments = []; - $searchableIdAttributes = ['standort_id', 'oe_kurzbz', 'gebteil']; - $searchableTextAttributes = ['ort_kurzbz', 'bezeichnung', 'planbezeichnung', 'oe_kurzbz', 'oe_bezeichnung']; + $searchableIdAttributes = ['standort_id', 'gebteil']; + $searchableTextAttributes = ['ort_kurzbz', 'parent_ort_kurzbz', 'bezeichnung', 'planbezeichnung', 'oe_kurzbz', 'oe_bezeichnung']; $searchableBooleanAttributes = ['lehre', 'reservieren', 'aktiv']; - $searchableNumericAttributes = ['max_person', 'arbeitsplaetze']; + $searchableNumericAttributes = ['max_person', 'arbeitsplaetze', 'kosten', 'stockwerk']; $searchableNumericSpanAttributes = ['m2']; foreach ($searchableIdAttributes as $attribute) { if (isset($filter[$attribute]) && $filter[$attribute] !== '') { $queryWhereFragments[] = "public.tbl_ort.$attribute = ?"; - $filterData[] = $filter[$attribute]; + $filterData[] = trim($filter[$attribute]); } } @@ -102,7 +102,7 @@ class Ort extends FHCAPI_Controller } if (isset($filter[$attribute]) && $filter[$attribute] !== '') { $queryWhereFragments[] = "$tableAttribute ILIKE ?"; - $filterData[] = '%' . $filter[$attribute] . '%'; + $filterData[] = '%' . trim($filter[$attribute]) . '%'; } } @@ -116,15 +116,15 @@ class Ort extends FHCAPI_Controller foreach ($searchableNumericAttributes as $attribute) { if (isset($filter[$attribute]) && $filter[$attribute] !== '') { $queryWhereFragments[] = "public.tbl_ort.$attribute = ?"; - $filterData[] = $filter[$attribute]; + $filterData[] = trim($filter[$attribute]); } } foreach ($searchableNumericSpanAttributes as $attribute) { if (isset($filter[$attribute]) && $filter[$attribute] !== '') { $queryWhereFragments[] = "public.tbl_ort.$attribute >= ? AND public.tbl_ort.$attribute <= ?"; - $filterData[] = $filter[$attribute] - 1; - $filterData[] = $filter[$attribute] + 1; + $filterData[] = trim($filter[$attribute]) - 1; + $filterData[] = trim($filter[$attribute]) + 1; } } diff --git a/application/controllers/api/frontend/v1/RoomToRoomTypeApi.php b/application/controllers/api/frontend/v1/RoomToRoomTypeApi.php index 0cf4afcb9..dce9e4b37 100644 --- a/application/controllers/api/frontend/v1/RoomToRoomTypeApi.php +++ b/application/controllers/api/frontend/v1/RoomToRoomTypeApi.php @@ -33,9 +33,9 @@ class RoomToRoomTypeApi extends FHCAPI_Controller { // NOTE(chris): additional permission checks will be done in SearchBarLib parent::__construct([ - 'getRoomToRoomTypeRelationsByRoomShortCode' => self::PERM_LOGGED, - 'createRoomToRoomTypeRelation' => self::PERM_LOGGED, - 'deleteRoomToRoomTypeRelation' => self::PERM_LOGGED, + 'getRoomToRoomTypeRelationsByRoomShortCode' => array('basis/ort:r'), + 'createRoomToRoomTypeRelation' => array('basis/ort:rw'), + 'deleteRoomToRoomTypeRelation' => array('basis/ort:rw'), ]); $this->load->library('form_validation'); @@ -101,6 +101,7 @@ class RoomToRoomTypeApi extends FHCAPI_Controller public function deleteRoomToRoomTypeRelation() { $this->form_validation->set_rules('roomShortCode', 'roomShortCode', 'required'); $this->form_validation->set_rules('roomTypeShortCode', 'roomTypeShortCode', 'required'); + $this->form_validation->set_rules('hierarchy', 'hierarchy', 'required|integer'); if ($this->form_validation->run() === false) { return $this->terminateWithError(validation_errors()); @@ -109,6 +110,7 @@ class RoomToRoomTypeApi extends FHCAPI_Controller $result = $this->OrtRoomTypeModel->db->delete($this->OrtRoomTypeModel->getDbTable(), [ 'ort_kurzbz' => $this->input->post('roomShortCode'), 'raumtyp_kurzbz' => $this->input->post('roomTypeShortCode'), + 'hierarchie' => $this->input->post('hierarchy'), ]); if ($result === false) { diff --git a/application/controllers/api/frontend/v1/RoomTypeApi.php b/application/controllers/api/frontend/v1/RoomTypeApi.php index d1dcda770..d8ded8500 100644 --- a/application/controllers/api/frontend/v1/RoomTypeApi.php +++ b/application/controllers/api/frontend/v1/RoomTypeApi.php @@ -32,8 +32,8 @@ class RoomTypeApi extends FHCAPI_Controller public function __construct() { parent::__construct([ - 'getAllRoomTypes' => self::PERM_LOGGED, - 'createRoomType' => self::PERM_LOGGED, + 'getAllRoomTypes' => array('basis/ort:r'), + 'createRoomType' => array('basis/ort:rw'), ]); $this->load->library('form_validation'); diff --git a/application/views/room_manager/index.php b/application/views/room_manager/index.php index 0b39d760d..c5c26c55a 100644 --- a/application/views/room_manager/index.php +++ b/application/views/room_manager/index.php @@ -32,7 +32,8 @@ $this->load->view('templates/FHC-Header', $includesArray);
diff --git a/public/js/api/factory/roomToRoomType.js b/public/js/api/factory/roomToRoomType.js index e62e4426f..a2ba6fe58 100644 --- a/public/js/api/factory/roomToRoomType.js +++ b/public/js/api/factory/roomToRoomType.js @@ -33,13 +33,14 @@ export default { }, } }, - deleteRoomToRoomTypeRelation(roomShortCode, roomTypeShortCode) { + deleteRoomToRoomTypeRelation(roomShortCode, roomTypeShortCode, hierarchy) { return { method: 'post', url: `api/frontend/v1/RoomToRoomTypeApi/deleteRoomToRoomTypeRelation`, params: { roomShortCode, - roomTypeShortCode + roomTypeShortCode, + hierarchy }, } } diff --git a/public/js/components/RoomManager/RoomManagerOverview.js b/public/js/components/RoomManager/RoomManagerOverview.js index 3d710d40b..0172cbcac 100644 --- a/public/js/components/RoomManager/RoomManagerOverview.js +++ b/public/js/components/RoomManager/RoomManagerOverview.js @@ -17,6 +17,16 @@ export default { RoomFormModal, RoomTypeFormModal, }, + props: { + permissions: Object, + }, + provide() { + return { + cisRoot: this.cisRoot, + hasBasisOrtWPermission: + this.permissions["basis/ort_w"] || false, + }; + }, watch: { filterData: { handler(newValue) { @@ -76,6 +86,9 @@ export default { }; }, computed: { + hasBasisOrtWPermission() { + return this.permissions["basis/ort_w"] || false; + }, tabulatorOptions() { const options = { ajaxURL: "dummy", @@ -125,7 +138,7 @@ export default { ); }, ajaxResponse: (url, params, response) => response, - persistenceID: "room_manager_overview_table", + persistenceID: "room_manager_overview_table1111222233333", selectableRows: true, index: "ort_kurzbz", columns: [ @@ -222,6 +235,7 @@ export default { title: this.$capitalize(this.$p.t("ui", "parentRoom")), field: "pr_ort_kurzbz", headerFilter: true, + width_: 120, }, { title: this.$capitalize(this.$p.t("global", "actions")), @@ -229,33 +243,39 @@ export default { width: 120, formatter: (cell, formatterParams, onRendered) => { let container = document.createElement("div"); - container.className = "d-flex gap-2"; + container.className = "d-flex gap-2 justify-content-center"; + + let roomTypeBtn = document.createElement("button"); + roomTypeBtn.className = "btn btn-outline-secondary btn-action"; + roomTypeBtn.innerHTML = ''; + roomTypeBtn.title = this.$capitalize(this.$p.t("ui", "btn_editRoomType")); + roomTypeBtn.addEventListener("click", (event) => + this.editRoomType(cell.getData().ort_kurzbz), + ); + + if (!this.hasBasisOrtWPermission) { + container.append(roomTypeBtn); + return container; + }2222 let button = document.createElement("button"); button = document.createElement("button"); button.className = "btn btn-outline-secondary btn-action"; button.innerHTML = ''; - button.title = this.$p.t("ui", "btn_editRoom"); + button.title = this.$capitalize(this.$p.t("ui", "btn_editRoom")); button.addEventListener("click", (event) => this.editRoom(cell.getData().ort_kurzbz), ); container.append(button); - button = document.createElement("button"); - button.className = "btn btn-outline-secondary btn-action"; - button.innerHTML = ''; - button.title = this.$p.t("ui", "btn_editRoomType"); - button.addEventListener("click", (event) => - this.editRoomType(cell.getData().ort_kurzbz), - ); - container.append(button); + container.append(roomTypeBtn); button = document.createElement("button"); button.className = "btn btn-outline-secondary btn-action bg-danger"; button.innerHTML = ''; - button.title = this.$p.t("ui", "btn_deleteRoom"); + button.title = this.$capitalize(this.$p.t("ui", "btn_deleteRoom")); button.addEventListener("click", () => { let isDeletionConfirmed = confirm( this.$p.t("ui", "deleteRoomConfirmation"), @@ -441,7 +461,7 @@ export default { template: /* html */ `

{{ $capitalize($p.t("ui", "roomManagerOverviewHeading")) }}

-
+
diff --git a/public/js/components/RoomManager/RoomTypeFormModal.js b/public/js/components/RoomManager/RoomTypeFormModal.js index 07e4fec4b..2a86e95a2 100644 --- a/public/js/components/RoomManager/RoomTypeFormModal.js +++ b/public/js/components/RoomManager/RoomTypeFormModal.js @@ -15,6 +15,7 @@ export default { FormInput, CoreFilterCmpt, }, + inject: ["hasBasisOrtWPermission"], props: { isVisible: { type: Boolean, @@ -79,10 +80,12 @@ export default { { title: this.$capitalize(this.$p.t("ui", "roomType")), field: "raumtyp_kurzbz", + width: 150, }, { title: this.$capitalize(this.$p.t("ui", "hierarchy")), field: "hierarchie", + width: 50, }, { title: this.$capitalize(this.$p.t("gruppenmanagement", "beschreibung")), @@ -91,11 +94,12 @@ export default { { title: this.$capitalize(this.$p.t("global", "actions")), field: "actions", - minWidth: 150, - maxWidth: 150, + width: 50, formatter: (cell, formatterParams, onRendered) => { + if (!this.hasBasisOrtWPermission) return ""; + let container = document.createElement("div"); - container.className = "d-flex gap-2"; + container.className = "d-flex justify-content-center"; let button = document.createElement("button"); @@ -116,6 +120,7 @@ export default { this.deleteRoomToRoomTypeRelation( cell.getData().ort_kurzbz, cell.getData().raumtyp_kurzbz, + cell.getData().hierarchie, ); }); container.append(button); @@ -123,8 +128,10 @@ export default { return container; }, frozen: true, + visible: this.hasBasisOrtWPermission, }, ], + layout: "fitColumns", }; return options; }, @@ -199,12 +206,13 @@ export default { this.$refs.roomTypesTable.tabulator.replaceData("/"); }); }, - deleteRoomToRoomTypeRelation(roomShortCode, roomTypeShortCode) { + deleteRoomToRoomTypeRelation(roomShortCode, roomTypeShortCode, hierarchy) { return this.$api .call( ApiRoomToRoomType.deleteRoomToRoomTypeRelation( roomShortCode, roomTypeShortCode, + hierarchy ), ) .then((response) => { @@ -254,14 +262,20 @@ export default { }); }, template: /* html */ ` - +