mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-07-11 12:02:26 +00:00
localizing collapsed tabulator column headings; tabulator custom modules; debounce helper
This commit is contained in:
@@ -24,7 +24,7 @@ Vue.$collapseFormatter = function (data) {
|
||||
let item2 = document.createElement("div");
|
||||
item2.classList.add("col-6");
|
||||
|
||||
item.innerHTML = "<strong class=\"collapsedColumnHeading\" tabulator-column-field=\"" + col.field + "\">placeholder</strong>";
|
||||
item.innerHTML = "<strong class=\"collapsedColumnHeading\" tabulator-column-field=\"" + col.field + "\">...</strong>";
|
||||
item2.innerHTML = col.value ? col.value : "-";
|
||||
|
||||
list.appendChild(item);
|
||||
|
||||
@@ -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(() => {
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
export const debounce = (callback, wait) => {
|
||||
let timeoutId = null;
|
||||
return (context) => {
|
||||
window.clearTimeout(timeoutId);
|
||||
timeoutId = window.setTimeout(() => callback(), wait);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,49 @@
|
||||
export function capitalize(string) {
|
||||
if (!string) return '';
|
||||
if (!string) return "";
|
||||
return string[0].toUpperCase() + string.slice(1);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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"));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user