adapt filter/tablePresets/tablePresetsModule to account for dynamic tables with a new presetColumns property. by default the preset holds all columns, if a scope is given it only holds those columns, their header filters and their sort; on apply the scope is merged into the current table columns so the dynamic ones keep their place;

This commit is contained in:
Johann Hoffmann
2026-08-26 16:45:06 +02:00
parent 6d9ce91302
commit 943999cef9
3 changed files with 117 additions and 39 deletions
@@ -8,27 +8,36 @@ export default class TablePresetsModule extends Module {
super(table);
}
applyPreset(preset) {
let columnsConfig = this.table.options.columns;
let reorderedColumnsConfig = [];
preset.displayedColumns.forEach((columnField) => {
let columnConfig = columnsConfig.find(
(column) => column.field === columnField,
);
if (!columnConfig) return;
columnConfig.visible = true;
reorderedColumnsConfig.push(columnConfig);
});
let hiddenColumnsConfig = columnsConfig
.filter((column) => !preset.displayedColumns.includes(column.field))
.map((column) => {
column.visible = false;
return column;
// presetColumns limits the preset to the given column fields. A table with dynamic
// columns gives the fields of its constant columns here.
applyPreset(preset, presetColumns = []) {
if (presetColumns.length) {
this.applyColumnsInScope(preset, presetColumns);
} else {
let columnsConfig = this.table.options.columns;
let reorderedColumnsConfig = [];
preset.displayedColumns.forEach((columnField) => {
let columnConfig = columnsConfig.find(
(column) => column.field === columnField,
);
if (!columnConfig) return;
columnConfig.visible = true;
reorderedColumnsConfig.push(columnConfig);
});
this.table.setColumns(
reorderedColumnsConfig.concat(hiddenColumnsConfig),
);
let hiddenColumnsConfig = columnsConfig
.filter(
(column) =>
!preset.displayedColumns.includes(column.field),
)
.map((column) => {
column.visible = false;
return column;
});
this.table.setColumns(
reorderedColumnsConfig.concat(hiddenColumnsConfig),
);
}
this.table.clearHeaderFilter();
if (preset.headerFilters) {
@@ -61,4 +70,44 @@ export default class TablePresetsModule extends Module {
);
}
}
// The preset orders and hides the columns of the scope only. A column outside the
// scope keeps its position, because the table does not show it in every state.
applyColumnsInScope(preset, presetColumns) {
const displayedColumns = preset.displayedColumns ?? [];
// a displayed column takes the rank of the preset. A column that the preset
// hides has no rank and keeps the current order at the end of its block.
const rank = (columnConfig) => {
const index = displayedColumns.indexOf(columnConfig.field);
return index === -1 ? displayedColumns.length : index;
};
let columnsConfig = [];
let scopeBlock = [];
// the sort runs for each block of neighbouring scope columns. This way a scope
// column never moves over a column outside the scope.
const addScopeBlock = () => {
scopeBlock.sort((a, b) => rank(a) - rank(b));
columnsConfig = columnsConfig.concat(scopeBlock);
scopeBlock = [];
};
this.table.getColumnDefinitions().forEach((columnConfig) => {
if (!presetColumns.includes(columnConfig.field)) {
addScopeBlock();
columnsConfig.push(columnConfig);
return;
}
columnConfig.visible = displayedColumns.includes(
columnConfig.field,
);
scopeBlock.push(columnConfig);
});
addScopeBlock();
this.table.setColumns(columnsConfig);
}
}