bootgrid: maintain scrolling position for both datatree and command actions. Closes https://github.com/opnsense/core/issues/9151

The usage of scrollToRow has been considered, but this contains
too much magic causing all kinds of jumps in scroll position,
causing a user to lose track of the changes they made. The only
downside to this is that when a datatree is expanded at the bottom
of a grid, the associated rows aren't immediately visible until
manually scrolled to.
This commit is contained in:
Stephan de Wit 2026-04-03 13:47:26 +02:00
parent da2c0bdab3
commit 75e60e8519

View file

@ -127,6 +127,7 @@ class UIBootgrid {
this.treeStorageKey = `tabulator-${this.persistenceID}-openTree`;
this.rememberedTreeIds = new Set(JSON.parse(localStorage.getItem(this.treeStorageKey) || '[]'));
this.isVisible = false;
this.scrollPos = 0;
// wrapper-specific options
this.options = {
@ -756,6 +757,7 @@ class UIBootgrid {
if (!id) return;
open ? this.rememberedTreeIds.add(id) : this.rememberedTreeIds.delete(id);
localStorage.setItem(this.treeStorageKey, JSON.stringify([...this.rememberedTreeIds]));
this._maintainScrollPosition(this.scrollPos);
};
this.table.on('dataTreeRowExpanded', (row) => rememberTree(row, true));
@ -876,6 +878,10 @@ class UIBootgrid {
intersectObserver.observe(this.$element[0]);
});
this.table.on('scrollVertical', (top) => {
this.scrollPos = top;
});
}
_renderFooter() {
@ -1595,14 +1601,20 @@ class UIBootgrid {
_reload(inplace=false) {
let page = this.table.getPage();
const scrollPos = this.scrollPos;
// both calls trigger an ajax request
if (inplace) {
this.table.setPage(page);
this.table.setPage(page).then(() => this._maintainScrollPosition(scrollPos));
} else {
this.table.replaceData();
this.table.replaceData().then(() => this._maintainScrollPosition(scrollPos));
}
}
_maintainScrollPosition(pos) {
$(`#${this.id} > .tabulator-tableholder`)[0].scrollTop = pos;
}
_getPlaceholder() {
return $(`#${this.id}-placeholder`);
}