From d40040efd8de7b0354a10d16a81045b0e54de4f7 Mon Sep 17 00:00:00 2001 From: Johann Hoffmann Date: Tue, 21 Jul 2026 18:07:23 +0200 Subject: [PATCH] added new fkey to tbl_widget for system.tbl_berechtigung; check for permission status during load & in widget picker; if widget was already picked/configured but not permitted anymore -> show a generalized "missing permission" screen via fallback component during widget init; --- .../api/frontend/v1/dashboard/Widget.php | 3 + public/js/components/Dashboard/Item.js | 15 ++- .../js/components/Dashboard/Widget/Picker.js | 12 ++- .../DashboardWidget/MissingPermission.js | 21 ++++ system/dbupdate_3.4.php | 1 + .../77757_widgets_berechtigungen.php | 57 ++++++++++ system/phrasesupdate.php | 100 ++++++++++++++++++ 7 files changed, 204 insertions(+), 5 deletions(-) create mode 100644 public/js/components/DashboardWidget/MissingPermission.js create mode 100644 system/dbupdate_3.4/77757_widgets_berechtigungen.php diff --git a/application/controllers/api/frontend/v1/dashboard/Widget.php b/application/controllers/api/frontend/v1/dashboard/Widget.php index ac8c682e8..99865b6db 100644 --- a/application/controllers/api/frontend/v1/dashboard/Widget.php +++ b/application/controllers/api/frontend/v1/dashboard/Widget.php @@ -101,6 +101,9 @@ class Widget extends FHCAPI_Controller $tmpsetup = json_decode($widget->setup); $tmpsetup->file = absoluteJsImportUrl($tmpsetup->file); $widget->setup = $tmpsetup; + $widget->permitted = empty($widget->berechtigung_kurzbz) + || $this->permissionlib->isBerechtigt($widget->berechtigung_kurzbz); + return $widget; }, $widgets); diff --git a/public/js/components/Dashboard/Item.js b/public/js/components/Dashboard/Item.js index 20c195178..a1623df58 100644 --- a/public/js/components/Dashboard/Item.js +++ b/public/js/components/Dashboard/Item.js @@ -1,5 +1,6 @@ import BsModal from "../Bootstrap/Modal.js"; import HeightTransition from "../Tranistion/HeightTransition.js"; +import MissingPermissionWidget from "../DashboardWidget/MissingPermission.js"; import { enableDragDropTouch } from "../../../../vendor/drag-drop-touch-js/dragdroptouch/dist/drag-drop-touch.esm.min.js"; @@ -113,6 +114,12 @@ export default { isPinned() { return this.place?.pinned ? true : false; }, + permitted() { + // widgets without a linked permission (or before the template loaded) + // are considered permitted; the backend sets permitted === false only + // when the user is missing the widget's required permission + return this.widgetTemplate?.permitted !== false; + }, ready() { return this.component && this.arguments !== null; }, @@ -178,7 +185,11 @@ export default { && this.widgetTemplate.widget_id && this.widgetTemplate.arguments ) { - let component = (await import(this.widgetTemplate.setup.file)).default; + // render the "missing permission" screen instead of the actual + // widget when the user does not hold the widget's linked permission + let component = this.permitted + ? (await import(this.widgetTemplate.setup.file)).default + : MissingPermissionWidget; this.$options.components["widget" + this.widgetTemplate.widget_id] = component; this.component = "widget" + this.widgetTemplate.widget_id; this.arguments = { ...this.widgetTemplate.arguments, ...this.config }; @@ -280,7 +291,7 @@ export default { ({ callbacks: {} }), + computed: { + // filter widgets away the user has no permissions for + availableWidgets() { + return (this.widgets || []).filter(widget => widget.permitted !== false); + } + }, methods: { getWidget() { return new Promise((resolve,reject) => { @@ -37,17 +43,17 @@ export default {