diff --git a/public/js/components/Cis/Profil/Profil.js b/public/js/components/Cis/Profil/Profil.js
index 0df4a86c2..5e656da77 100644
--- a/public/js/components/Cis/Profil/Profil.js
+++ b/public/js/components/Cis/Profil/Profil.js
@@ -24,7 +24,7 @@ Vue.$collapseFormatter = function (data) {
let item2 = document.createElement("div");
item2.classList.add("col-6");
- item.innerHTML = "placeholder";
+ item.innerHTML = "...";
item2.innerHTML = col.value ? col.value : "-";
list.appendChild(item);
diff --git a/public/js/components/filter/Filter.js b/public/js/components/filter/Filter.js
index 2c8cf59be..f25d07e7f 100644
--- a/public/js/components/filter/Filter.js
+++ b/public/js/components/filter/Filter.js
@@ -22,6 +22,9 @@ import TableDownload from './Table/Download.js';
import collapseAutoClose from '../../directives/collapseAutoClose.js';
import moduleLayoutFitDataStretchFrozen from '../../tabulator/layouts/fitDataStretchFrozen.js';
+import InternalToExternalEventBroadcastModule from "../../tabulator/customModules/InternalToExternalEventBroadcastModule.js"
+
+import { debounce } from "../../helpers/DebounceHelper.js";
import ApiFilter from '../../api/factory/filter.js';
import ApiPhrases from '../../api/factory/phrasen.js';
@@ -123,6 +126,27 @@ export const CoreFilterCmpt = {
group: false,
page: false,
},
+ collapsedHeadingLocalizationTimer: null,
+ localizeCollapsedColumnHeadings:
+ debounce(
+ () => {
+ const columnHeadings = this.tabulator?.getLang()?.columns;
+ if (!columnHeadings) return;
+
+ this.$refs.table
+ .querySelectorAll(".collapsedColumnHeading")
+ .forEach((collapsedColumnHeadingElement) => {
+ const field =
+ collapsedColumnHeadingElement.getAttribute(
+ "tabulator-column-field",
+ );
+ if (!field?.length) return;
+
+ collapsedColumnHeadingElement.innerHTML =
+ columnHeadings[field];
+ });
+ }, 200)
+ ,
};
},
computed: {
@@ -368,6 +392,11 @@ export const CoreFilterCmpt = {
this.localizeCollapsedColumnHeadings();
}
});
+ this.tabulator.on('layoutRefreshed', () => {
+ if (tabulatorOptions.locale && tabulatorOptions.responsiveLayoutCollapseFormatter) {
+ this.localizeCollapsedColumnHeadings();
+ }
+ });
},
async configureTabulatorLocalizations(tabulatorOptions) {
tabulatorOptions.locale = this.$p.user_language.value;
@@ -472,21 +501,6 @@ export const CoreFilterCmpt = {
return tabulatorOptions;
},
- async localizeCollapsedColumnHeadings() {
- const columnHeadings = this.tabulator?.getLang()?.columns;
- if (!columnHeadings) return;
-
- this.$refs.table
- .querySelectorAll(".collapsedColumnHeading")
- .forEach((collapsedColumnHeadingElement) => {
- const field =
- collapsedColumnHeadingElement.getAttribute("tabulator-column-field");
- if (!field?.length) return;
-
- collapsedColumnHeadingElement.innerHTML =
- columnHeadings[field];
- });
- },
updateTabulator() {
if (this.tabulator) {
if (this.tableBuilt)
@@ -814,6 +828,8 @@ export const CoreFilterCmpt = {
alert('"nwNewEntry" listener is mandatory when sideMenu is true');
this.uuid = _uuid++;
this.$emit('uuidDefined', this.uuid)
+
+ Tabulator.registerModule(InternalToExternalEventBroadcastModule);
},
mounted() {
this.initTabulator().then(() => {
diff --git a/public/js/helpers/DebounceHelper.js b/public/js/helpers/DebounceHelper.js
new file mode 100644
index 000000000..af5e80019
--- /dev/null
+++ b/public/js/helpers/DebounceHelper.js
@@ -0,0 +1,7 @@
+export const debounce = (callback, wait) => {
+ let timeoutId = null;
+ return (context) => {
+ window.clearTimeout(timeoutId);
+ timeoutId = window.setTimeout(() => callback(), wait);
+ }
+}
\ No newline at end of file
diff --git a/public/js/helpers/StringHelpers.js b/public/js/helpers/StringHelpers.js
index a67d0138f..e68d1d381 100644
--- a/public/js/helpers/StringHelpers.js
+++ b/public/js/helpers/StringHelpers.js
@@ -1,4 +1,49 @@
export function capitalize(string) {
- if (!string) return '';
+ if (!string) return "";
return string[0].toUpperCase() + string.slice(1);
-}
\ No newline at end of file
+}
+
+export function convertCase(string, from, to) {
+ const possibleCases = ["kebab", "snake", "camel"];
+ if (
+ from === to ||
+ !possibleCases.includes(from) ||
+ !possibleCases.includes(to)
+ )
+ return string;
+
+ const individualWords =
+ from === "kebab"
+ ? string.split("-")
+ : from === "snake"
+ ? string.split("_")
+ : splitWordsInCamelCase(string);
+
+ const formattedIndividualWords = ["snake", "kebab"].includes(to)
+ ? individualWords.map((word) => word.toLowerCase())
+ : individualWords.map((word, index) => {
+ if (!index) return word.toLowerCase();
+ return word.slice(0, 1).toUpperCase() + word.slice(1).toLowerCase();
+ });
+
+ const joinCharacter = to === "snake" ? "_" : to === "kebab" ? "-" : "";
+ return formattedIndividualWords.join(joinCharacter);
+}
+
+function splitWordsInCamelCase(string) {
+ const lastUpperCaseLetterIndex = string
+ .split("")
+ .findLastIndex((character) => {
+ return character.toUpperCase() === character;
+ });
+
+ if (lastUpperCaseLetterIndex < 1) {
+ return [string];
+ }
+
+ let splitWords = splitWordsInCamelCase(
+ string.slice(0, lastUpperCaseLetterIndex),
+ );
+ splitWords.push(string.slice(lastUpperCaseLetterIndex));
+ return splitWords;
+}
diff --git a/public/js/tabulator/customModules/InternalToExternalEventBroadcastModule.js b/public/js/tabulator/customModules/InternalToExternalEventBroadcastModule.js
new file mode 100644
index 000000000..85099d9ce
--- /dev/null
+++ b/public/js/tabulator/customModules/InternalToExternalEventBroadcastModule.js
@@ -0,0 +1,32 @@
+// changes within tabulator are often not adequately broadcast to the external component
+// this module exposes tabulator's internal events
+// if external event name is not specified, the dispatched external event will be the camelCase version of the kebab-case internal event
+
+import Module from "../../../../vendor/olifolkerd/tabulator5/src/js/core/Module.js";
+import { convertCase } from "../../helpers/StringHelpers.js";
+
+export default class InternalToExternalEventBroadcastModule extends Module {
+ static moduleName = "internalToExternalEventBroadcastModule";
+ static moduleInitNumber = 1;
+
+ constructor(table) {
+ super(table);
+
+ this.eventsToBroadcast = [
+ {
+ internal: "layout-refreshed",
+ external: null,
+ },
+ ];
+ }
+
+ initialize() {
+ this.eventsToBroadcast.forEach((event) => {
+ this.subscribe(event.internal, () => {
+ this.dispatchExternal(event.external ?? convertCase(event.internal, "kebab", "camel"));
+ });
+ });
+ }
+
+
+}