Merge remote-tracking branch 'origin/feature-25999/C4_cleanup' into feature-25999/C4_cleanup

# Conflicts:
#	application/libraries/dashboard/DashboardLib.php
#	public/js/components/Dashboard/Dashboard.js
#	public/js/components/Dashboard/Section.js
This commit is contained in:
Johann Hoffmann
2025-04-23 12:49:16 +02:00
8 changed files with 158 additions and 35 deletions
+6 -6
View File
@@ -65,7 +65,7 @@ class Config extends Auth_Controller
$preset_decoded = json_decode($preset->preset, true);
$this->DashboardLib->addWidgetsToWidgets($preset_decoded['widgets'], $dashboard_kurzbz, $funktion_kurzbz, $input->widgets);
$this->DashboardLib->addWidgetsToWidgets($preset_decoded, $dashboard_kurzbz, $funktion_kurzbz, $input->widgets);
$preset->preset = json_encode($preset_decoded);
@@ -92,7 +92,7 @@ class Config extends Auth_Controller
}
$preset_decoded = json_decode($preset->preset, true);
if (!$this->DashboardLib->removeWidgetFromWidgets($preset_decoded['widgets'], $funktion_kurzbz, $widgetid))
if (!$this->DashboardLib->removeWidgetFromWidgets($preset_decoded, $funktion_kurzbz, $widgetid))
{
http_response_code(404);
$this->terminateWithJsonError('widgetid ' . $widgetid . ' not found');
@@ -119,7 +119,7 @@ class Config extends Auth_Controller
$override_decoded = json_decode($override->override, true);
$this->DashboardLib->addWidgetsToWidgets($override_decoded['widgets'], $dashboard_kurzbz, $funktion_kurzbz, $input->widgets);
$this->DashboardLib->addWidgetsToWidgets($override_decoded, $dashboard_kurzbz, $funktion_kurzbz, $input->widgets);
$override->override = json_encode($override_decoded);
@@ -148,7 +148,7 @@ class Config extends Auth_Controller
$override_decoded = json_decode($override->override, true);
if (!$this->DashboardLib->removeWidgetFromWidgets($override_decoded['widgets'], $funktion_kurzbz, $widgetid))
if (!$this->DashboardLib->removeWidgetFromWidgets($override_decoded, $funktion_kurzbz, $widgetid))
{
http_response_code(404);
$this->terminateWithJsonError('widgetid ' . $widgetid . ' not found');
@@ -202,10 +202,10 @@ class Config extends Auth_Controller
if ($conf)
{
$preset = json_decode($conf->preset, true);
if (!isset($preset['widgets']) || !isset($preset['widgets'][$funktion]))
if (!isset($preset[$funktion]) || !isset($preset[$funktion]['widgets']))
$result[$funktion] = [];
else
$result[$funktion] = $preset['widgets'][$funktion];
$result[$funktion] = $preset[$funktion]['widgets'];
}
else
$result[$funktion] = [];
@@ -53,6 +53,7 @@ class DashboardLib
$userconfig = $this->getUserConfig($dashboard_id, $uid);
$mergedconfig = array_replace_recursive($defaultconfig, $userconfig);
return $mergedconfig;
}
@@ -106,7 +107,7 @@ class DashboardLib
$emptyoverride = new stdClass();
$emptyoverride->dashboard_id = $dashboard->dashboard_id;
$emptyoverride->uid = $uid;
$emptyoverride->override = '{"widgets": {"' . self::USEROVERRIDE_SECTION . '": {}}}';
$emptyoverride->override = '{"' . self::USEROVERRIDE_SECTION . '": {"widgets":{}}}}';
return $emptyoverride;
}
@@ -126,7 +127,7 @@ class DashboardLib
$emptypreset->dashboard_id = $dashboard->dashboard_id;
$emptypreset->funktion_kurzbz = $funktion_kurzbz;
$section = ($funktion_kurzbz !== null) ? $funktion_kurzbz : self::SECTION_IF_FUNKTION_KURZBZ_IS_NULL;
$emptypreset->preset = '{"widgets": {"' . $section . '": {}}}';
$emptypreset->preset = '{"' . $section . '": { "widgets" : {}},"custom": { "widgets" : {}}}';
return $emptypreset;
}
@@ -205,7 +206,7 @@ class DashboardLib
public function addWidgetToWidgets(&$widgets, $section, $widget, $widgetid)
{
$section = ($section !== null) ? $section : self::SECTION_IF_FUNKTION_KURZBZ_IS_NULL;
if (!isset($widgets[$section]) || !is_array($widgets[$section]))
if (!isset($widgets[$section]) || !isset($widgets[$section]["widgets"]) || !is_array($widgets[$section]))
{
$widgets[$section] = array();
$widgets[$section]["widgets"] = array();
@@ -217,7 +218,7 @@ class DashboardLib
public function removeWidgetFromWidgets(&$widgets, $section, $widgetid)
{
$section = ($section !== null) ? $section : self::SECTION_IF_FUNKTION_KURZBZ_IS_NULL;
if (isset($widgets[$section]["widgets"]) && isset($widgets[$section]["widgets"][$widgetid]))
if (isset($widgets[$section]) && isset($widgets[$section]["widgets"][$widgetid]))
{
unset($widgets[$section]["widgets"][$widgetid]);
if(empty($widgets[$section]["widgets"]) && $section !== self::USEROVERRIDE_SECTION) {
+2 -1
View File
@@ -1,5 +1,6 @@
import {CoreNavigationCmpt} from '../components/navigation/Navigation.js';
import DashboardAdmin from '../components/Dashboard/Admin.js';
import Phrases from "../plugin/Phrasen.js"
Vue.createApp({
name: 'DashboardAdminApp',
@@ -12,4 +13,4 @@ Vue.createApp({
},
mounted() {
}
}).mount('#main');
}).use(Phrases).mount('#main');
@@ -42,7 +42,7 @@ export default {
funktion_kurzbz: section_name,
widgets: [widget]
}).then(result => {
let newId = Object.keys(result.data.retval.data.widgets[section_name]).pop();
let newId = Object.keys(result.data.retval.data[section_name].widgets).pop();
widget.id = newId;
widget.custom = 1;
this.sections.forEach(section => {
@@ -126,7 +126,6 @@ export default {
}}).then(res => {
if (this.tmpLoading !== funktionen.join('###'))
return; // NOTE(chris): prevent race condition
for (var section in res.data.retval) {
let widgets = [];
for (var wid in res.data.retval[section]) {
+9 -9
View File
@@ -70,7 +70,7 @@ export default {
funktion_kurzbz: section_name,
widgets: [widget]
}).then(result => {
let newId = Object.keys(result.data.retval.data.widgets[section_name]).pop();
let newId = Object.keys(result.data.retval.data[section_name].widgets).pop();
widget.id = newId;
this.sections.forEach(section => {
if (section.name == section_name) {
@@ -143,7 +143,7 @@ export default {
}
},
created() {
this.$p.loadCategory('dashboard');
axios.get(this.apiurl + '/Widget/getWidgetsForDashboard', {
params: {
db: this.dashboard
@@ -159,23 +159,23 @@ export default {
axios.get(this.apiurl + '/Config', {params:{
db: this.dashboard
}}).then(res => {
for (var name in res.data.retval.widgets) {
for (var name in res.data.retval) {
let widgets = [];
let remove = [];
for (var wid in res.data.retval.widgets[name].widgets) {
res.data.retval.widgets[name].widgets[wid].id = wid;
if (res.data.retval.widgets[name].widgets[wid].custom || res.data.retval.widgets[name].widgets[wid].preset)
widgets.push(res.data.retval.widgets[name].widgets[wid]);
for (var wid in res.data.retval[name].widgets) {
res.data.retval[name].widgets[wid].id = wid;
if (res.data.retval[name].widgets[wid].custom || res.data.retval[name].widgets[wid].preset)
widgets.push(res.data.retval[name].widgets[wid]);
else
remove.push(wid);
}
this.sections.push({
name: name,
description:res.data.retval.widgets[name].description,
widgets: widgets
});
remove.forEach(wid => this.widgetRemove(name, wid));
}
this.sections = this.sections.sort((section1, section2) => section2.widgets.length - section1.widgets.length);
}).catch(err => console.error('ERROR:', err));
},
async beforeMount() {
@@ -190,7 +190,7 @@ export default {
{{ $p.t('global/personalGreeting', [ viewDataInternal?.name ]) }}
<button style="margin-left: 8px;" class="btn" @click="editMode = !editMode"><i class="fa-solid fa-gear"></i></button>
</h3>
<dashboard-section v-for="(section, index) in sections" :key="section.name" :seperator="index" :name="section.name" :description="section.description" :widgets="section.widgets" @widgetAdd="widgetAdd" @widgetUpdate="widgetUpdate" @widgetRemove="widgetRemove"></dashboard-section>
<dashboard-section v-for="(section, index) in sections" :key="section.name" :seperator="index" :name="section.name" :widgets="section.widgets" @widgetAdd="widgetAdd" @widgetUpdate="widgetUpdate" @widgetRemove="widgetRemove"></dashboard-section>
<dashboard-widget-picker ref="widgetpicker" :widgets="widgets"></dashboard-widget-picker>
</div>`
}
+31 -11
View File
@@ -14,8 +14,8 @@ export default {
},
inject: {
widgetsSetup:{
type: Object,
default: {},
type: Array,
default: [],
},
adminMode: {
type: Boolean,
@@ -28,8 +28,7 @@ export default {
},
props: [
"name",
"widgets",
"description"
"widgets"
],
emits: [
"widgetAdd",
@@ -86,7 +85,7 @@ export default {
if(!item?.widgetid && item?.id){
item.widgetid = item.id;
}
return { ...item, ...(item.place[this.gridWidth] || { x: 0, y: 0, w: 1, h: 1 } )};
return { ...item, reorder: false, ...(item.place[this.gridWidth] || { reorder: true, ...{ x: 0, y: 0, w: 1, h: 1 } })};
});
return placedItems;
@@ -94,8 +93,29 @@ export default {
},
methods: {
sectionNameTranslation(){
switch(this.name){
case "general":
return this.$p.t('dashboard',this.name);
break;
case "custom":
return this.$p.t('dashboard',this.name);
break;
default:
return this.name;
break;
}
},
showSectionInformation(){
SectionModal.popup(this.description);
if (this.name == "general"){
SectionModal.popup(this.$p.t('dashboard', 'dashboardGeneralSectionDescription'));
}
else if(this.name == "custom"){
SectionModal.popup(this.$p.t('dashboard', 'dashboardCustomSectionDescription'));
}
else{
SectionModal.popup(this.$p.t('dashboard', 'dashboardSectionDescription', [this.name]));
}
},
handleConfigOpened() {
this.configOpened = true
@@ -189,11 +209,11 @@ export default {
});
},
template: `
<h4 v-if="items.length>0 && editMode" >
<h4 v-if="editModeIsActive" class=" mb-0">
<i @click="showSectionInformation(name)" class="fa-solid fa-circle-info section-info" ></i>
{{name}}:
{{sectionNameTranslation()}}:
</h4>
<div class="dashboard-section position-relative pb-3 border-1" ref="container" :style="getSectionStyle">
<div class="dashboard-section position-relative pb-3 border-bottom" ref="container" :style="getSectionStyle">
<drop-grid v-model:cols="gridWidth" :items="items" :itemsSetup="computedWidgetsSetup" :active="editModeIsActive" :resize-limit="checkResizeLimit" :margin-for-extra-row=".01" @draggedItem="draggedItem=$event" @rearrange-items="updatePositions" @gridHeight="gridHeight=$event" >
<template #default="item">
<div v-if="item.placeholder" class="empty-tile-hover" @click="$emit('widgetAdd', name, { widget: 1, config: {}, place: {[gridWidth]: {x:item.x,y:item.y,w:1,h:1}}, custom: 1 })"></div>
@@ -204,12 +224,12 @@ export default {
:widgetID="item.id"
:width="item.w"
:height="item.h"
:item_data="{config:item.config, custom:item.custom, h:item.h, w:item.w,id:item.id,place:item.place,widget:item.widget,widgetid:item.widgetid,x:item.x,y:item.y}"
:item_data="{config:item.config, custom:item.custom, h:item.h, w:item.w,id:item.id,reorder:item.reorder,place:item.place,widget:item.widget,widgetid:item.widgetid,x:item.x,y:item.y}"
:loading="item.loading"
:config="item.config"
:custom="item.custom"
:hidden="item.hidden"
:editMode="editMode"
:editMode="editModeIsActive"
:place="item.place[gridWidth]"
:setup="computedWidgetsSetup[item.widget]"
@change="saveConfig($event, item)"
+1 -1
View File
@@ -614,7 +614,7 @@ export default {
<TransitionGroup tag="div">
<grid-item
ref="gridItems"
v-for="(item,index) in (mode == 0 && active ? placedItems_withPlaceholders : placedItems)"
v-for="(item,index) in ((mode != 1 || mode != 2) && active ? placedItems_withPlaceholders : placedItems)"
:key="item.data.id"
:item="item"
@start-move="startMove"
+103 -1
View File
@@ -38354,6 +38354,106 @@ array(
)
),
// ### STUDIENGANG_INFORMATIONEN PHRASEN ENDE
array(
'app' => 'core',
'category' => 'dashboard',
'phrase' => 'general',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Allgemein',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'General',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'dashboard',
'phrase' => 'custom',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Benutzerdefiniert',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Custom',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'dashboard',
'phrase' => 'dashboardGeneralSectionDescription',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Hier befinden sich die vordefinierten Widgets',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Here are the predefined widgets',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'dashboard',
'phrase' => 'dashboardCustomSectionDescription',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Hier befinden sich die Widgets Ihrer persönlichen Anpassungen',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Here are the widgets of your personal cutomizations',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'dashboard',
'phrase' => 'dashboardSectionDescription',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Hier befinden sich die Widgets der {0} Funktion',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Here are the widgets of the {0} function',
'description' => '',
'insertvon' => 'system'
)
)
),
// CIS4 phrases from legacy code end
array(
'app' => 'core',
@@ -38414,7 +38514,9 @@ array(
'insertvon' => 'system'
)
)
)
),
);