# OrganonTweaks -- umbrella plugin for small Kanboard tweaks A home for small, unrelated Kanboard adjustments that are not big enough to deserve their own plugin. Each tweak is self-contained; more will be added over time. If a tweak grows into a real subsystem it graduates into its own plugin (see PLAN-organon-tweaks-plugin.md). ## Tweaks ### Remove an empty column Adds a **Remove this Column** entry (trash icon) to a board column's header dropdown, next to the other column actions. It appears only when the column is completely empty -- no tasks, open or closed -- because Kanboard's column removal is a plain delete and a non-empty column would orphan its tasks. Clicking it asks for confirmation, then removes the column and returns to the board. - The menu entry is rendered by the `template:board:column:dropdown` hook (which sits outside the native menu list), then moved into the menu by `Asset/js/relocate.js`. - The empty check counts open and closed tasks via a helper (`Helper/OrganonColumnHelper.php`, `taskFinderModel->countByColumnId(...)`), since the board's own count is open-only. - Only users allowed to manage columns see it, and the controller re-checks both the permission and the emptiness before deleting. ### Always show the comment icon Kanboard shows the comment icon on a board card only once it has at least one comment, so adding the *first* comment means opening the card and finding the sidebar link. With this tweak on, a card with no comments shows a comment bubble with a **"+"** that opens the same comment modal, letting you add the first comment straight from the board. Cards that already have comments keep showing the count as before. - Rendered by the `template:board:task:icons` hook (`Template/board/task_comment_icon.php`), only when the card has no comments and the user may create one (so it does not show for read-only viewers). - **On by default.** Toggle it under "Settings -> Organon Tweaks". ### Keep the board scroll position across refreshes When you drop a card (or Kanboard auto-refreshes the board via polling), it rebuilds the board with `$("#board-container").replaceWith(...)`, and the new element starts scrolled to the far left -- so the view jumps back to the first column. A **full page reload** (for example clicking the Todo/Done badge or the "Mark all" action, which navigate and redirect back to the board) does the same. This tweak remembers the scroll position -- **horizontal and vertical** -- and restores it in both cases, so the board stays where you were. - Implemented in `Asset/js/keep-scroll.js`: it observes the stable parent (the container itself is replaced) and restores, on whichever `#board-container` is current after an AJAX rebuild and again after a full reload (persisted per board in `sessionStorage`): - the **horizontal** position (`#board-container.scrollLeft`); - the **page vertical** position in expanded mode (`window.scrollY`); - the **per-column vertical** position in compact/collapsed mode -- each native `.board-task-list-compact` list, keyed by its `data-swimlane-id` + `data-column-id`, so every column keeps its own place independently (works with or without ShrinkVertically). - **On by default.** Toggle it under "Settings -> Organon Tweaks". ### Open a card only on a quick click Dropping a card sometimes leaks a trailing "click" that opens the card -- an unwanted side effect of the drag. A real click is a quick press-release; a drag is a press held much longer. So `Asset/js/click-guard.js` times the press on a card (`mousedown`/`touchstart` to the following `click`) and, if it was held longer than **120 ms**, swallows the click in the capture phase before Kanboard's open handler -- so a drag never opens the card. Normal clicks (well under 120 ms) still open cards as usual. The 120 ms threshold is fixed. - **On by default.** Toggle it under "Settings -> Organon Tweaks". ### Show keyboard shortcuts on the task menu Kanboard already binds handy keys on the task view (`e` = edit, `s` = new sub-task, `c` = new comment, `l` = new internal link) but never shows them, so they go undiscovered. This tweak adds a small key hint next to each of those items in the task **Actions** sidebar. It is **display only**: it adds no new bindings, it just surfaces the ones Kanboard already has. - Implemented in `Asset/js/shortcut-labels.js`, matching the menu items by their FontAwesome icon class, so it is independent of the URL format and the interface language. - **On by default.** Toggle it under "Settings -> Organon Tweaks". ### Click a title to edit By default, clicking a card title (on the board) or the title on the card view lands you on the read-only card view. With this tweak on, clicking the title opens the **edit** form directly, reusing Kanboard's own modal -- so from the board you edit and, on Save, come straight back to the board. It applies only where you may edit (a read-only viewer keeps the normal title), and shared/public boards are untouched. - Implemented in `Asset/js/title-click-edit.js` -- a capture-phase click that reuses `KB.modal.open`. On the board, a hidden marker (`Template/board/title_edit.php`, rendered by `template:board:private:task:before-title` only when the user may edit) carries the server-generated edit URL; on the card view the title reuses `#task-view`'s `data-edit-url`. - **On by default.** Toggle it under "Settings -> Organon Tweaks". ### Enhance the recurrence dialog Kanboard's native "Edit recurrence" dialog is a plain form. This makes two small usability edits when it opens (there is no template hook, so it is done in JS, `Asset/js/enhance-recurrence.js`): - the "Generate recurrent task" **Yes/No dropdown** becomes two **radio buttons** (one click to set, instead of open + select). The original select is kept hidden and stays in sync, so the form submits exactly as before. - a small **[+7]** button next to the "Factor" input adds 7 to it (one week of days). - **On by default.** Toggle it under "Settings -> Organon Tweaks". ### Persistent column sort Kanboard's native column sort is a one-shot physical reorder: it rewrites task positions once, so the order already survives refreshes, but a newly created or dropped-in card lands out of order until you sort again -- and there is no sort-by-title. This tweak replaces the per-column sort control with one that: - adds a **number-aware Title sort** (A to Z / Z to A), so "Task 2" sorts before "Task 10"; - adds a **Persistent sort: ON / OFF** toggle. When ON, the column is re-sorted (server-side, physically) whenever a card is dropped into it or created in it, so it **stays** sorted; when OFF it behaves exactly like the native one-shot sort. The header icon shows the state: the native double-arrow when persistent is OFF, and a **red single arrow** (up for ascending, down for descending) when it is ON. - Reorders reuse core's `TaskReorderModel` for the native criteria (id / priority / assignee / due date) and add the title sort; the sticky re-apply runs on the move / creation events. - The control is injected via the `template:board:column:dropdown` hook + `Asset/js/relocate.js` (which also hides the native sort menu). Per-column state lives in project metadata. - **On by default.** Toggle it under "Settings -> Organon Tweaks". ### Done/Todo badge A two-state toggle badge for marking a card done, shown on the board card face (above the title) and on the task view (4th column, near the due date). It reads **Todo** (black on light red) while the task is pending; one click flips it to **Done** (black on light green). The card itself is not recolored -- only the badge. - Rendered server-side (no JavaScript) via `template:board:private:task:before-title` (`Template/board/done_badge.php`), `template:task:details:fourth-column` (`Template/task/done_badge.php`), and a small head `