mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-07-24 02:12:17 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d40040efd8 |
@@ -101,6 +101,9 @@ class Widget extends FHCAPI_Controller
|
|||||||
$tmpsetup = json_decode($widget->setup);
|
$tmpsetup = json_decode($widget->setup);
|
||||||
$tmpsetup->file = absoluteJsImportUrl($tmpsetup->file);
|
$tmpsetup->file = absoluteJsImportUrl($tmpsetup->file);
|
||||||
$widget->setup = $tmpsetup;
|
$widget->setup = $tmpsetup;
|
||||||
|
$widget->permitted = empty($widget->berechtigung_kurzbz)
|
||||||
|
|| $this->permissionlib->isBerechtigt($widget->berechtigung_kurzbz);
|
||||||
|
|
||||||
return $widget;
|
return $widget;
|
||||||
}, $widgets);
|
}, $widgets);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import BsModal from "../Bootstrap/Modal.js";
|
import BsModal from "../Bootstrap/Modal.js";
|
||||||
import HeightTransition from "../Tranistion/HeightTransition.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";
|
import { enableDragDropTouch } from "../../../../vendor/drag-drop-touch-js/dragdroptouch/dist/drag-drop-touch.esm.min.js";
|
||||||
|
|
||||||
@@ -113,6 +114,12 @@ export default {
|
|||||||
isPinned() {
|
isPinned() {
|
||||||
return this.place?.pinned ? true : false;
|
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() {
|
ready() {
|
||||||
return this.component && this.arguments !== null;
|
return this.component && this.arguments !== null;
|
||||||
},
|
},
|
||||||
@@ -178,7 +185,11 @@ export default {
|
|||||||
&& this.widgetTemplate.widget_id
|
&& this.widgetTemplate.widget_id
|
||||||
&& this.widgetTemplate.arguments
|
&& 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.$options.components["widget" + this.widgetTemplate.widget_id] = component;
|
||||||
this.component = "widget" + this.widgetTemplate.widget_id;
|
this.component = "widget" + this.widgetTemplate.widget_id;
|
||||||
this.arguments = { ...this.widgetTemplate.arguments, ...this.config };
|
this.arguments = { ...this.widgetTemplate.arguments, ...this.config };
|
||||||
@@ -280,7 +291,7 @@ export default {
|
|||||||
</template>
|
</template>
|
||||||
<!-- widget link -->
|
<!-- widget link -->
|
||||||
<a
|
<a
|
||||||
v-if="widgetTemplate.setup.cis4link"
|
v-if="widgetTemplate.setup.cis4link && permitted"
|
||||||
:href="getWidgetC4Link(widgetTemplate)"
|
:href="getWidgetC4Link(widgetTemplate)"
|
||||||
class="col-auto ms-auto"
|
class="col-auto ms-auto"
|
||||||
:aria-label="$p.t('dashboard/widget_link')"
|
:aria-label="$p.t('dashboard/widget_link')"
|
||||||
|
|||||||
@@ -12,6 +12,12 @@ export default {
|
|||||||
data: () => ({
|
data: () => ({
|
||||||
callbacks: {}
|
callbacks: {}
|
||||||
}),
|
}),
|
||||||
|
computed: {
|
||||||
|
// filter widgets away the user has no permissions for
|
||||||
|
availableWidgets() {
|
||||||
|
return (this.widgets || []).filter(widget => widget.permitted !== false);
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getWidget() {
|
getWidget() {
|
||||||
return new Promise((resolve,reject) => {
|
return new Promise((resolve,reject) => {
|
||||||
@@ -37,17 +43,17 @@ export default {
|
|||||||
<bs-modal
|
<bs-modal
|
||||||
ref="modal"
|
ref="modal"
|
||||||
class="fade"
|
class="fade"
|
||||||
:dialog-class="{ 'modal-fullscreen-sm-down': 1, 'modal-xl': widgets && widgets.length > 0 }"
|
:dialog-class="{ 'modal-fullscreen-sm-down': 1, 'modal-xl': availableWidgets.length > 0 }"
|
||||||
@hiddenBsModal="close"
|
@hiddenBsModal="close"
|
||||||
>
|
>
|
||||||
<template v-slot:title>{{ $p.t('dashboard/createWidget') }}</template>
|
<template v-slot:title>{{ $p.t('dashboard/createWidget') }}</template>
|
||||||
<template v-slot:default>
|
<template v-slot:default>
|
||||||
<div v-if="widgets" class="row g-2">
|
<div v-if="widgets" class="row g-2">
|
||||||
<div v-if="!widgets.length">
|
<div v-if="!availableWidgets.length">
|
||||||
{{ $p.t('dashboard/noWidgetsAvailable') }}
|
{{ $p.t('dashboard/noWidgetsAvailable') }}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-for="widget in widgets"
|
v-for="widget in availableWidgets"
|
||||||
:key="widget.widget_id"
|
:key="widget.widget_id"
|
||||||
class="widget-icon-container col-sm-6 col-md-4 col-lg-3 col-xl-2"
|
class="widget-icon-container col-sm-6 col-md-4 col-lg-3 col-xl-2"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import AbstractWidget from './Abstract.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fallback screen rendered in place of a widget when the current user is missing
|
||||||
|
* the permission (berechtigung_kurzbz) linked to that widget. Used for widgets
|
||||||
|
* that are already on a user's dashboard but whose required permission the user
|
||||||
|
* no longer holds.
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
mixins: [
|
||||||
|
AbstractWidget
|
||||||
|
],
|
||||||
|
created() {
|
||||||
|
this.$emit('setConfig', false);
|
||||||
|
},
|
||||||
|
template: /*html*/`
|
||||||
|
<div class="dashboard-widget-missing-permission d-flex flex-column justify-content-center align-items-center text-center h-100 p-3 text-body-secondary">
|
||||||
|
<i class="fa-solid fa-lock fa-2x mb-2" aria-hidden="true"></i>
|
||||||
|
<p class="mb-0">{{ $p.t('dashboard/widget_missing_permission') }}</p>
|
||||||
|
</div>`
|
||||||
|
}
|
||||||
@@ -98,6 +98,7 @@ require_once('dbupdate_3.4/75888_reihungstest_mehrfachdurchfuehrung.php');
|
|||||||
require_once('dbupdate_3.4/76150_perm_other_lv_plan.php');
|
require_once('dbupdate_3.4/76150_perm_other_lv_plan.php');
|
||||||
require_once('dbupdate_3.4/68957_dashboard_bookmark_neue_Spalte_sort.php');
|
require_once('dbupdate_3.4/68957_dashboard_bookmark_neue_Spalte_sort.php');
|
||||||
require_once('dbupdate_3.4/68530_Dashboard_Cleanup.php');
|
require_once('dbupdate_3.4/68530_Dashboard_Cleanup.php');
|
||||||
|
require_once('dbupdate_3.4/77757_widgets_berechtigungen.php');
|
||||||
|
|
||||||
// *** Pruefung und hinzufuegen der neuen Attribute und Tabellen
|
// *** Pruefung und hinzufuegen der neuen Attribute und Tabellen
|
||||||
echo '<H2>Pruefe Tabellen und Attribute!</H2>';
|
echo '<H2>Pruefe Tabellen und Attribute!</H2>';
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
<?php
|
||||||
|
/* 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 2 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Beschreibung:
|
||||||
|
* Dashboard Widgets: Verknüpfung einer (einzelnen) Berechtigung pro Widget.
|
||||||
|
* Neue Spalte dashboard.tbl_widget.berechtigung_kurzbz mit FK auf
|
||||||
|
* system.tbl_berechtigung. Ist die Spalte NULL, erfordert das Widget keine
|
||||||
|
* gesonderte Berechtigung. Benutzer denen die verknüpfte Berechtigung fehlt,
|
||||||
|
* bekommen das Widget nicht mehr zur Auswahl angezeigt bzw. sehen (falls bereits
|
||||||
|
* am Dashboard) einen "Fehlende Berechtigung"-Screen.
|
||||||
|
*/
|
||||||
|
if (! defined('DB_NAME')) exit('No direct script access allowed');
|
||||||
|
|
||||||
|
// Add column dashboard.tbl_widget.berechtigung_kurzbz (FK => system.tbl_berechtigung)
|
||||||
|
if ($result = @$db->db_query("
|
||||||
|
SELECT 1
|
||||||
|
FROM information_schema.columns
|
||||||
|
WHERE table_schema = 'dashboard'
|
||||||
|
AND table_name = 'tbl_widget'
|
||||||
|
AND column_name = 'berechtigung_kurzbz';"))
|
||||||
|
{
|
||||||
|
if ($db->db_num_rows($result) == 0)
|
||||||
|
{
|
||||||
|
$qry = "
|
||||||
|
ALTER TABLE dashboard.tbl_widget
|
||||||
|
ADD COLUMN berechtigung_kurzbz VARCHAR(32) NULL;
|
||||||
|
|
||||||
|
ALTER TABLE dashboard.tbl_widget
|
||||||
|
ADD CONSTRAINT tbl_widget_berechtigung_fk
|
||||||
|
FOREIGN KEY (berechtigung_kurzbz)
|
||||||
|
REFERENCES system.tbl_berechtigung (berechtigung_kurzbz)
|
||||||
|
ON UPDATE CASCADE ON DELETE SET NULL;";
|
||||||
|
|
||||||
|
if (!$db->db_query($qry))
|
||||||
|
{
|
||||||
|
echo '<strong>dashboard.tbl_widget: '.$db->db_last_error().'</strong><br>';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
echo 'dashboard.tbl_widget: Spalte berechtigung_kurzbz (FK system.tbl_berechtigung) hinzugefuegt<br>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -32514,6 +32514,86 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
array(
|
||||||
|
'app' => 'anwesenheiten',
|
||||||
|
'category' => 'global',
|
||||||
|
'phrase' => 'anwKontrolle',
|
||||||
|
'insertvon' => 'system',
|
||||||
|
'phrases' => array(
|
||||||
|
array(
|
||||||
|
'sprache' => 'German',
|
||||||
|
'text' => 'Anwesenheitskontrolle',
|
||||||
|
'description' => '',
|
||||||
|
'insertvon' => 'system'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'sprache' => 'English',
|
||||||
|
'text' => 'Attendance check',
|
||||||
|
'description' => '',
|
||||||
|
'insertvon' => 'system'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'app' => 'anwesenheiten',
|
||||||
|
'category' => 'global',
|
||||||
|
'phrase' => 'anwKontrolleOeffnen',
|
||||||
|
'insertvon' => 'system',
|
||||||
|
'phrases' => array(
|
||||||
|
array(
|
||||||
|
'sprache' => 'German',
|
||||||
|
'text' => 'Anwesenheitskontrolle öffnen',
|
||||||
|
'description' => '',
|
||||||
|
'insertvon' => 'system'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'sprache' => 'English',
|
||||||
|
'text' => 'Open attendance check',
|
||||||
|
'description' => '',
|
||||||
|
'insertvon' => 'system'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'app' => 'anwesenheiten',
|
||||||
|
'category' => 'global',
|
||||||
|
'phrase' => 'anwKeinUnterricht',
|
||||||
|
'insertvon' => 'system',
|
||||||
|
'phrases' => array(
|
||||||
|
array(
|
||||||
|
'sprache' => 'German',
|
||||||
|
'text' => 'Kein Unterricht in diesem Zeitraum',
|
||||||
|
'description' => '',
|
||||||
|
'insertvon' => 'system'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'sprache' => 'English',
|
||||||
|
'text' => 'No lessons in this period',
|
||||||
|
'description' => '',
|
||||||
|
'insertvon' => 'system'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'app' => 'anwesenheiten',
|
||||||
|
'category' => 'global',
|
||||||
|
'phrase' => 'anwJetzt',
|
||||||
|
'insertvon' => 'system',
|
||||||
|
'phrases' => array(
|
||||||
|
array(
|
||||||
|
'sprache' => 'German',
|
||||||
|
'text' => 'Jetzt',
|
||||||
|
'description' => '',
|
||||||
|
'insertvon' => 'system'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'sprache' => 'English',
|
||||||
|
'text' => 'Now',
|
||||||
|
'description' => '',
|
||||||
|
'insertvon' => 'system'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
array(
|
array(
|
||||||
'app' => 'anwesenheiten',
|
'app' => 'anwesenheiten',
|
||||||
'category' => 'global',
|
'category' => 'global',
|
||||||
@@ -48681,6 +48761,26 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
array(
|
||||||
|
'app' => 'core',
|
||||||
|
'category' => 'dashboard',
|
||||||
|
'phrase' => 'widget_missing_permission',
|
||||||
|
'insertvon' => 'system',
|
||||||
|
'phrases' => array(
|
||||||
|
array(
|
||||||
|
'sprache' => 'German',
|
||||||
|
'text' => 'Ihnen fehlt die erforderliche Berechtigung, um dieses Widget anzuzeigen.',
|
||||||
|
'description' => '',
|
||||||
|
'insertvon' => 'system'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'sprache' => 'English',
|
||||||
|
'text' => 'You do not have the permission required to display this widget.',
|
||||||
|
'description' => '',
|
||||||
|
'insertvon' => 'system'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
// CIS4 phrases from legacy code end
|
// CIS4 phrases from legacy code end
|
||||||
// FHC4 Phrases Abschlusspruefung
|
// FHC4 Phrases Abschlusspruefung
|
||||||
array(
|
array(
|
||||||
|
|||||||
Reference in New Issue
Block a user