Todo/Done menu mark all in this column

This commit is contained in:
2026-07-18 22:43:41 -03:00
parent c88e52ab01
commit 8136c01403
13 changed files with 204 additions and 38 deletions

View File

@@ -1,18 +1,41 @@
/*
* OrganonTweaks -- keep the board's horizontal scroll position across refreshes.
* OrganonTweaks -- keep the board's horizontal scroll position across refreshes AND full reloads.
*
* When you drop a card (and on Kanboard's periodic AJAX polling) the board is rebuilt with
* `$("#board-container").replaceWith(data)` (BoardDragAndDrop.refresh). The brand-new
* element starts at scrollLeft 0, so the board snaps back to the first column -- a jarring
* jump. This remembers the last scroll position and restores it the moment a replacement
* container appears, so the view stays put.
* Two cases lose the horizontal scroll and snap the board back to the first column:
* 1. AJAX rebuild -- dropping a card / periodic polling replaces #board-container
* (BoardDragAndDrop.refresh), and the new element starts at scrollLeft 0.
* 2. Full page reload -- e.g. clicking the Done/Todo badge, which navigates and redirects back to
* the board; a fresh page starts at scrollLeft 0.
*
* We observe the STABLE parent (the container itself is replaced) and read the scroll from
* whichever #board-container is current, so it keeps working after every rebuild.
* We remember the last position and restore it: in-memory for the AJAX rebuild (observing the STABLE
* parent, since the container itself is replaced), and in sessionStorage (keyed per board) so it
* survives a full reload as well.
*/
(function () {
"use strict";
function boardKey() {
var m = location.href.match(/board\/(\d+)/) || location.href.match(/project_id=(\d+)/);
return "organon-board-scroll-" + (m ? m[1] : location.pathname);
}
function readStored() {
try {
var v = window.sessionStorage.getItem(boardKey());
return v ? parseInt(v, 10) : 0;
} catch (e) {
return 0;
}
}
function writeStored(value) {
try {
window.sessionStorage.setItem(boardKey(), value);
} catch (e) {
// sessionStorage unavailable (private mode / disabled) -- degrade to AJAX-only restore.
}
}
function init() {
var container = document.getElementById("board-container");
if (!container) {
@@ -20,20 +43,27 @@
}
var parent = container.parentNode;
var lastScrollLeft = container.scrollLeft;
var stored = readStored();
var lastScrollLeft = stored || container.scrollLeft;
var lastContainer = container;
// Remember the position whenever the board is scrolled (capture: scroll does not
// bubble, and this survives the container being replaced).
// Restore across a full page reload (badge click, etc.), not only AJAX rebuilds.
if (stored && container.scrollLeft !== stored) {
container.scrollLeft = stored;
}
// Remember the position whenever the board is scrolled (capture: scroll does not bubble, and
// this survives the container being replaced).
document.addEventListener("scroll", function (e) {
var c = document.getElementById("board-container");
if (c && e.target === c) {
lastScrollLeft = c.scrollLeft;
writeStored(lastScrollLeft);
}
}, true);
// When the board is rebuilt, #board-container becomes a new element at scrollLeft 0;
// restore the remembered position before the browser paints it.
// When the board is rebuilt, #board-container becomes a new element at scrollLeft 0; restore
// the remembered position before the browser paints it.
if (window.MutationObserver) {
new MutationObserver(function () {
var c = document.getElementById("board-container");