diff --git a/public/js/components/Dashboard/Dashboard.js b/public/js/components/Dashboard/Dashboard.js
index bf45ad227..e390f16d4 100644
--- a/public/js/components/Dashboard/Dashboard.js
+++ b/public/js/components/Dashboard/Dashboard.js
@@ -62,6 +62,9 @@ export default {
return [type, result];
}));
+ },
+ hiddenWidgets() {
+ return this.widgets.filter(widget => widget.hidden);
}
},
methods: {
@@ -69,6 +72,9 @@ export default {
this.$refs.widgetpicker
.getWidget()
.then(widget_id => {
+ if (widget_id.hidden)
+ this.widgetUnhide(widget_id, widget.place);
+
widget.widget = widget_id;
// NOTE(chris): min size
widget.place = Object.fromEntries(Object.entries(widget.place).map(([key, value]) => {
@@ -131,17 +137,6 @@ export default {
this.widgets.forEach((widget, i) => {
if (failed.includes(widget.id)) {
this.widgets[i] = structuredClone(ObjectUtils.deepToRaw(this.originalWidgets[widget.id]));
- /** NOTE(chris): if you wanna hide or unhide a
- * preset and it fails: switch around the hidden
- * value to revert it properly (checkboxes can't
- * really handle it otherwise)
- */
- if (payload[widget.id].hidden !== undefined) {
- this.widgets[i].hidden = payload[widget.id].hidden;
- this.$nextTick(() => {
- this.widgets[i] = structuredClone(ObjectUtils.deepToRaw(this.originalWidgets[widget.id]));
- });
- }
} else if (payload[widget.id]) {
payload[widget.id].id = widget.id;
payload[widget.id].index = widget.index;
@@ -160,6 +155,31 @@ export default {
})
.catch(this.$fhcAlert.handleSystemError);
},
+ widgetUnhide(orig, place) {
+ place = Object.fromEntries(Object.entries(place).map(([key, value]) => {
+ value.w = this.sizeLimits[orig.widget].width.min;
+ value.h = this.sizeLimits[orig.widget].height.min;
+ // NOTE(chris): unpin pinned widgets because they got a new placement
+ value.pinned = false;
+ return [key, value];
+ }));
+ // NOTE(chris): clear placement in other screensizes
+ Object.keys(orig.place).forEach(key => {
+ if (!place[key]) {
+ place[key] = {
+ x: undefined,
+ y: undefined,
+ pinned: false
+ };
+ }
+ });
+ let payload = {};
+ payload[orig.id] = {
+ hidden: false,
+ place
+ };
+ return this.widgetUpdate(payload);
+ },
async fetchViewData() {
let viewDataResult = await this.$api.call(ApiDashboard.getViewData());
const viewData = viewDataResult.data;
@@ -204,15 +224,23 @@ export default {
},
template: /* html */`
-
- {{ userFirstName ? $p.t('global/personalGreeting', [ userFirstName ]) : '' }}
-
-
+
`
}
diff --git a/public/js/components/Dashboard/Item.js b/public/js/components/Dashboard/Item.js
index 20c195178..160b34e91 100644
--- a/public/js/components/Dashboard/Item.js
+++ b/public/js/components/Dashboard/Item.js
@@ -36,7 +36,6 @@ export default {
"width",
"height",
"custom",
- "hidden",
"editMode",
"loading", // widget got added and is waiting for backend to save in db
"item_data",
@@ -115,14 +114,6 @@ export default {
},
ready() {
return this.component && this.arguments !== null;
- },
- visible: {
- get() {
- return !this.hidden;
- },
- set(value) {
- this.$emit('remove', this.hidden);
- }
}
},
methods: {
@@ -202,10 +193,8 @@ export default {
},
template: /*html*/ `
@@ -299,9 +288,9 @@ export default {
>
-
+
-
-
-
-
-
-
diff --git a/public/js/components/Dashboard/Section.js b/public/js/components/Dashboard/Section.js
index e8c56fd4e..b55eefb7a 100644
--- a/public/js/components/Dashboard/Section.js
+++ b/public/js/components/Dashboard/Section.js
@@ -124,8 +124,6 @@ export default {
return { ...item, ...placement, weight };
});
- if (this.editModeIsActive)
- return placedItems;
return placedItems.filter(item => !item.hidden);
}
},
@@ -141,22 +139,12 @@ export default {
handleConfigClosed() {
this.configOpened = false
},
- removeWidget(item, revert) {
+ removeWidget(item) {
if (item.custom) {
BsConfirm.popup(this.$p.t('dashboard', 'alert_deleteWidget')).then(() => this.$emit('widgetRemove', item.id, this.name));
} else {
let update = {};
- update[item.id] = { hidden: !revert };
-
- if (!revert) {
- // NOTE(chris): move to last line
- update[item.id].place = [];
- let y = this.gridHeight;
- if (this.additionalRow)
- y--;
- update[item.id].place[this.gridWidth] = { x: 0, y };
- }
-
+ update[item.id] = { hidden: true };
this.updatePreset(update);
}
},
@@ -251,13 +239,12 @@ export default {
:loading="item.loading"
:config="item.config"
:custom="item.custom"
- :hidden="item.hidden"
:editMode="editModeIsActive"
:place="item.place[gridWidth]"
:widget-template="indexedWidgetsTemplates[item.widget]"
:source="adminMode ? null : item.source || 'custom'"
@change="saveConfig($event, item)"
- @remove="removeWidget(item, $event)"
+ @remove="removeWidget(item)"
@config-opened="handleConfigOpened"
@config-closed="handleConfigClosed"
@pin-item="updatePositions"
diff --git a/public/js/components/Dashboard/Widget/Picker.js b/public/js/components/Dashboard/Widget/Picker.js
index 260b95874..5d738213a 100644
--- a/public/js/components/Dashboard/Widget/Picker.js
+++ b/public/js/components/Dashboard/Widget/Picker.js
@@ -7,11 +7,21 @@ export default {
WidgetIcon,
},
props: [
- "widgets"
+ "widgets",
+ "hiddenWidgets"
],
data: () => ({
callbacks: {}
}),
+ computed: {
+ hasAnyWidgets() {
+ if (!this.widgets)
+ return false;
+ if (!this.widgets.length && !this.hiddenWidgets?.length)
+ return false;
+ return true;
+ }
+ },
methods: {
getWidget() {
return new Promise((resolve,reject) => {
@@ -37,23 +47,46 @@ export default {
{{ $p.t('dashboard/createWidget') }}
-
-
- {{ $p.t('dashboard/noWidgetsAvailable') }}
-
+
-
+
+
+
+
+
diff --git a/public/js/components/Drop/Grid.js b/public/js/components/Drop/Grid.js
index 6d9777c28..d4d8c90d9 100644
--- a/public/js/components/Drop/Grid.js
+++ b/public/js/components/Drop/Grid.js
@@ -233,6 +233,14 @@ export default {
if (value == oldValue)
return;
+ /** NOTE(chris): tempPositionUpdates depends on the cols not to be
+ * updated. So if they do we reset to get a clean value. In case the
+ * drag and drop operation is still motion on the next tick this
+ * will be correct again and if there is no such operation we clean
+ * up.
+ */
+ this.tempPositionUpdates = null;
+
this.reinitGrid();
},
rows: {
@@ -246,6 +254,11 @@ export default {
},
indexedItems: {
handler(value) {
+ /** NOTE(chris): there was an update of the items, so in case
+ * it came from a drag and drop operation we need to clean up
+ */
+ this.tempPositionUpdates = null;
+
this.reinitGrid();
},
immediate: true,
diff --git a/public/js/components/searchbar/searchbar.js b/public/js/components/searchbar/searchbar.js
index 3b73c44f2..8fb4a5cd4 100644
--- a/public/js/components/searchbar/searchbar.js
+++ b/public/js/components/searchbar/searchbar.js
@@ -40,7 +40,7 @@ export default {
query: Vue.computed(() => this.lastQuery),
};
},
- inject: ["isMobile"],
+ inject: { isMobile: { default: false } },
data: function () {
return {
searchtimer: null,
diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php
index 4f29de1d6..5e5c47589 100644
--- a/system/phrasesupdate.php
+++ b/system/phrasesupdate.php
@@ -29742,6 +29742,46 @@ array(
)
)
),
+ array(
+ 'app' => 'core',
+ 'category' => 'profil',
+ 'phrase' => 'name_title_clipboard_copy_confirmation',
+ 'insertvon' => 'system',
+ 'phrases' => array(
+ array(
+ 'sprache' => 'German',
+ 'text' => 'Name mit Titel in die Zwischenablage kopiert.',
+ 'description' => '',
+ 'insertvon' => 'system'
+ ),
+ array(
+ 'sprache' => 'English',
+ 'text' => 'Full name with title copied to clipboard.',
+ 'description' => '',
+ 'insertvon' => 'system'
+ )
+ )
+ ),
+ array(
+ 'app' => 'core',
+ 'category' => 'profil',
+ 'phrase' => 'name_title_copy',
+ 'insertvon' => 'system',
+ 'phrases' => array(
+ array(
+ 'sprache' => 'German',
+ 'text' => 'Name mit Titel kopieren',
+ 'description' => '',
+ 'insertvon' => 'system'
+ ),
+ array(
+ 'sprache' => 'English',
+ 'text' => 'Copy full name with title',
+ 'description' => '',
+ 'insertvon' => 'system'
+ )
+ )
+ ),
array(
'app' => 'core',
'category' => 'profil',
@@ -60932,6 +60972,26 @@ I have been informed that I am under no obligation to consent to the transmissio
)
)
),
+ array(
+ 'app' => 'core',
+ 'category' => 'LvPlan',
+ 'phrase' => 'copy',
+ 'insertvon' => 'system',
+ 'phrases' => array(
+ array(
+ 'sprache' => 'German',
+ 'text' => 'Kopieren',
+ 'description' => '',
+ 'insertvon' => 'system'
+ ),
+ array(
+ 'sprache' => 'English',
+ 'text' => 'Copy',
+ 'description' => '',
+ 'insertvon' => 'system'
+ )
+ )
+ ),
// ### LvPlanStgOrg END ###
// DMS-Link Phrasen Start
array(