From 5399375bc1e89aba1a46aaf1a0bc67c0152024ff Mon Sep 17 00:00:00 2001 From: Ivymaster Date: Mon, 29 Jun 2026 13:12:29 +0200 Subject: [PATCH] add tags extraction from nested rows --- .../Stv/Studentenverwaltung/List.js | 14 ++-- .../tabulator/filters/extendedHeaderFilter.js | 70 ++++++++++++------- 2 files changed, 54 insertions(+), 30 deletions(-) diff --git a/public/js/components/Stv/Studentenverwaltung/List.js b/public/js/components/Stv/Studentenverwaltung/List.js index 32791850f..34079dcf6 100644 --- a/public/js/components/Stv/Studentenverwaltung/List.js +++ b/public/js/components/Stv/Studentenverwaltung/List.js @@ -736,10 +736,16 @@ export default { }, updateTagFilterLabels() { this.tagFilterLabels.clear = this.$p.t("ui/filterdelete"); - this.tagFilterLabels.tag = 'Tag'; - this.tagFilterLabels.connectors.AND = this.$p.t("ui/andCondition").toUpperCase(); - this.tagFilterLabels.connectors.OR = this.$p.t("ui/orCondition").toUpperCase(); - this.tagFilterLabels.connectors.NOT = this.$p.t("ui/notCondition").toUpperCase(); + this.tagFilterLabels.tag = "Tag"; + this.tagFilterLabels.connectors.AND = this.$p + .t("ui/andCondition") + .toUpperCase(); + this.tagFilterLabels.connectors.OR = this.$p + .t("ui/orCondition") + .toUpperCase(); + this.tagFilterLabels.connectors.NOT = this.$p + .t("ui/notCondition") + .toUpperCase(); }, updateUrl(endpoint, first) { this.lastSelected = first ? undefined : this.selected; diff --git a/public/js/tabulator/filters/extendedHeaderFilter.js b/public/js/tabulator/filters/extendedHeaderFilter.js index 9115b0785..cbbc13875 100644 --- a/public/js/tabulator/filters/extendedHeaderFilter.js +++ b/public/js/tabulator/filters/extendedHeaderFilter.js @@ -61,33 +61,55 @@ export function buildTagHeaderFilterExpression(selectedTagOptions) { } export function buildTagOptionsFromRows(rows = []) { - const options = new Map(); + let options = []; + + let tags = [ + ...new Map( + getRawTagValuesFromRows(rows) + .filter((tag) => tag && tag.done !== true) + .map((tag) => { + return { + label: tag.beschreibung || tag.typ_kurzbz, + value: tag.beschreibung || tag.typ_kurzbz, + style: tag.style, + }; + }) + .map((obj) => [JSON.stringify(obj), obj]), + ).values(), + ]; + if (!Array.isArray(tags)) return; + + return tags; +} + +export function getRawTagValuesFromRows(rows = []) { + let tags = []; rows.forEach((row) => { - let tags = row.tags; + if (!row || (!row.tags?.length && !row._children?.length)) return; - if (typeof tags === "string") { - try { - tags = JSON.parse(tags); - } catch { - return; - } - } + let newTags = row.tags?.length + ? [row.tags] + : getRawTagValuesFromRows(row._children); - if (!Array.isArray(tags)) return; + newTags = newTags + .map((newTag) => { + if (typeof newTag === "string") { + try { + newTag = JSON.parse(newTag); + } catch { + return null; + } + } - tags - .filter((tag) => tag && tag.done !== true) - .forEach((tag) => { - options.set(tag.beschreibung, { - label: tag.beschreibung, - value: tag.beschreibung, - style: tag.style, - }); - }); + return newTag; + }) + .filter((newTag) => newTag !== null); + + tags = tags.concat(newTags); }); - return [...options.values()]; + return tags.flat(); } export function customTagFilter(cell, onRendered, success, cancel, params) { @@ -155,10 +177,7 @@ export function customTagFilter(cell, onRendered, success, cancel, params) { input.value = ""; if (Array.isArray(params.selectedOptions)) { - params.selectedOptions.splice( - 0, - params.selectedOptions.length, - ); + params.selectedOptions.splice(0, params.selectedOptions.length); } success(""); @@ -205,7 +224,7 @@ export function customTagFilter(cell, onRendered, success, cancel, params) { event.preventDefault(); event.stopPropagation(); - clearFilter({closeDropdownAfterClear: false}); + clearFilter({ closeDropdownAfterClear: false }); openDropdown(); }); @@ -335,7 +354,6 @@ function generateDropdownTable(options, selectedTagOptions, labels) { selectedTagOptions.splice(idx, 1); } } - }); td.appendChild(cb);