2026-07-04 10:09:21 -03:00
|
|
|
# OrganonTweaks -- umbrella plugin for small Kanboard tweaks
|
2026-07-01 09:30:31 -03:00
|
|
|
|
2026-07-04 10:09:21 -03:00
|
|
|
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).
|
2026-07-01 09:30:31 -03:00
|
|
|
|
2026-07-04 10:09:21 -03:00
|
|
|
## Tweaks
|
2026-07-01 09:30:31 -03:00
|
|
|
|
2026-07-04 10:09:21 -03:00
|
|
|
### 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.
|
2026-07-01 09:30:31 -03:00
|
|
|
|
2026-07-05 10:20:45 -03:00
|
|
|
### 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".
|
|
|
|
|
|
2026-07-06 21:12:26 -03:00
|
|
|
### 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
|
2026-07-18 22:43:41 -03:00
|
|
|
the far left -- so the view jumps back to the first column. A **full page reload** (for
|
2026-07-20 10:13:06 -03:00
|
|
|
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).
|
2026-07-06 21:12:26 -03:00
|
|
|
- **On by default.** Toggle it under "Settings -> Organon Tweaks".
|
|
|
|
|
|
2026-07-06 22:27:33 -03:00
|
|
|
### 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
|
2026-07-10 18:35:42 -03:00
|
|
|
the following `click`) and, if it was held longer than **120 ms**, swallows the click in the
|
2026-07-06 22:27:33 -03:00
|
|
|
capture phase before Kanboard's open handler -- so a drag never opens the card. Normal
|
2026-07-10 18:35:42 -03:00
|
|
|
clicks (well under 120 ms) still open cards as usual. The 120 ms threshold is fixed.
|
2026-07-06 22:27:33 -03:00
|
|
|
|
|
|
|
|
- **On by default.** Toggle it under "Settings -> Organon Tweaks".
|
|
|
|
|
|
2026-07-10 18:35:42 -03:00
|
|
|
### 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".
|
|
|
|
|
|
2026-07-07 09:40:51 -03:00
|
|
|
### 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".
|
|
|
|
|
|
2026-07-13 10:32:04 -03:00
|
|
|
### 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".
|
|
|
|
|
|
2026-07-18 22:43:41 -03:00
|
|
|
### Done/Todo badge
|
2026-07-18 21:24:36 -03:00
|
|
|
|
2026-07-18 22:43:41 -03:00
|
|
|
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.
|
2026-07-18 21:24:36 -03:00
|
|
|
|
|
|
|
|
- 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 `<style>` (`Template/layout/done_style.php`).
|
|
|
|
|
Shown only to users who may edit the task; on the board it appears on expanded (non-collapsed) cards.
|
|
|
|
|
- **Single source of truth, no drift with native Close/Open.** With *"Marking Done also closes the
|
|
|
|
|
task"* **on**, "Done" *means* the task is closed: the badge reads the task's own open/closed status,
|
|
|
|
|
so closing or reopening a task by any route (the badge, the native sidebar, bulk actions, the API)
|
|
|
|
|
always keeps the badge correct. A closed "Done" card is hidden from the board by Kanboard's default
|
|
|
|
|
open-only filter, but reappears if you clear the filter (or use the "Board: show all tasks" filter).
|
|
|
|
|
- With that option **off**, the badge is an independent marker stored in task metadata
|
|
|
|
|
(`organon_done`) that never touches the open/closed status.
|
2026-07-20 17:35:20 -03:00
|
|
|
- **Auto-mark on subtasks (opt-in).** When every subtask on a card is completed, the badge flips to
|
|
|
|
|
Done automatically (honoring the mode above -- marker or close). It only nudges at the moment the
|
|
|
|
|
last subtask completes: recomputing all-done on each subtask change and acting only on the
|
|
|
|
|
not-all-done -> all-done transition, so if you then set the badge back to Todo it is respected (the
|
|
|
|
|
subtasks stay done -- the description may hold unfinished business). It never auto-reverts to Todo.
|
|
|
|
|
Off by default; enable it in the Done badge settings.
|
2026-07-18 22:43:41 -03:00
|
|
|
- **Bulk per-column action.** The board column header dropdown gains a **Mark all as Done/Todo** entry
|
|
|
|
|
(`Template/board/mark_all_item.php`, moved into the menu by `relocate.js`). It opens a single modal
|
|
|
|
|
that both confirms and picks the direction -- **Mark all Done** or **Mark all Todo** -- then sets
|
|
|
|
|
every task in that column/swimlane to the chosen state (an overwrite, not a per-task toggle), honoring
|
|
|
|
|
the same close-mode/marker-mode semantics as the badge.
|
2026-07-18 21:24:36 -03:00
|
|
|
- **Off by default.** Toggle it under "Settings -> Organon Tweaks".
|
|
|
|
|
|
2026-08-04 10:57:10 -03:00
|
|
|
### Fix the subtask / column / swimlane menus on touch devices
|
|
|
|
|
|
|
|
|
|
On phones and tablets the little **gear menu** (edit / remove / convert) on a subtask row -- and the
|
|
|
|
|
same gear on the board **Columns** and **Swimlanes** config tables -- was almost impossible to tap:
|
|
|
|
|
roughly one tap in fifty opened it, while dragging to reorder worked fine. The cause is an upstream
|
|
|
|
|
Kanboard bug: those reorder tables set the drag handle to *every* icon in the row's first cell
|
|
|
|
|
(`handle: "td:first i"`), so the gear, its caret and the subtask status checkbox all count as drag
|
|
|
|
|
handles. On touch, Kanboard's bundled jQuery UI Touch Punch then treats a tap on them as a drag and
|
|
|
|
|
swallows the click. Desktop (mouse) is unaffected.
|
|
|
|
|
|
|
|
|
|
- `Asset/js/sortable-handle-fix.js` re-scopes those sortables' `handle` to the real drag icon
|
|
|
|
|
(`.draggable-row-handle`), so only the four-arrows drag and the gear/caret/checkbox are plain taps
|
|
|
|
|
again -- reordering still works. It re-applies after Kanboard re-renders a table (a debounced
|
|
|
|
|
MutationObserver), and only touches sortables whose handle is the buggy `td:first i`, so it is inert
|
|
|
|
|
everywhere else.
|
|
|
|
|
- **Always on** (no setting) -- it only corrects a broken interaction and does nothing on desktop.
|
|
|
|
|
|
2026-07-05 10:20:45 -03:00
|
|
|
## Settings
|
|
|
|
|
|
2026-07-10 18:35:42 -03:00
|
|
|
Global (per Kanboard instance) and admin-only, under "Settings -> Organon Tweaks", grouped as on
|
|
|
|
|
the page:
|
|
|
|
|
|
|
|
|
|
**Board card readability**
|
2026-07-05 10:20:45 -03:00
|
|
|
|
|
|
|
|
- **Always show the comment icon on board cards** -- default on.
|
2026-07-10 18:35:42 -03:00
|
|
|
- **Emphasize due date by default** -- default off (overridable per board under Settings -> Integrations).
|
|
|
|
|
|
|
|
|
|
**Board filters** (shared custom filters added to every board)
|
|
|
|
|
|
|
|
|
|
- **Add a "Show all tasks" filter to every board** -- default on.
|
|
|
|
|
- **Add month filters to every board** -- default on.
|
|
|
|
|
- **Add recurring filters to every board** -- default on.
|
|
|
|
|
|
|
|
|
|
**Card interaction**
|
|
|
|
|
|
2026-07-06 22:27:33 -03:00
|
|
|
- **Open a card only on a quick click** -- default on.
|
2026-07-10 18:35:42 -03:00
|
|
|
- **Show keyboard shortcuts on the task menu** -- default on.
|
|
|
|
|
- **Clicking a task title opens the edit form** -- default on.
|
|
|
|
|
|
2026-07-13 10:32:04 -03:00
|
|
|
**Board columns**
|
|
|
|
|
|
|
|
|
|
- **Per-column persistent sort** -- default on.
|
|
|
|
|
|
2026-07-18 21:24:36 -03:00
|
|
|
**Done badge**
|
|
|
|
|
|
2026-07-18 22:43:41 -03:00
|
|
|
- **Show a Done/Todo badge on cards** -- default off.
|
2026-07-18 21:24:36 -03:00
|
|
|
- **Marking Done also closes the task** -- default off.
|
|
|
|
|
|
2026-07-10 18:35:42 -03:00
|
|
|
Standalone:
|
|
|
|
|
|
|
|
|
|
- **Keep the board scroll position across refreshes** -- default on.
|
2026-07-07 09:40:51 -03:00
|
|
|
- **Enhance the recurrence dialog** -- default on.
|
2026-07-05 10:20:45 -03:00
|
|
|
|
2026-07-01 09:30:31 -03:00
|
|
|
## Requirements
|
|
|
|
|
|
|
|
|
|
- Kanboard >= 1.2.0
|
|
|
|
|
|
|
|
|
|
## Installation
|
|
|
|
|
|
2026-07-04 10:09:21 -03:00
|
|
|
Copy this folder into your Kanboard installation as `plugins/OrganonTweaks/`. The directory
|
|
|
|
|
name must be exactly `OrganonTweaks` (Kanboard derives the plugin namespace from the folder
|
|
|
|
|
name). No build step and no database migration.
|
2026-07-01 09:30:31 -03:00
|
|
|
|
|
|
|
|
## License
|
|
|
|
|
|
|
|
|
|
AGPL-3.0. See LICENSE.
|
2026-07-10 09:15:36 -03:00
|
|
|
|
2026-07-13 08:56:18 -03:00
|
|
|
## More Kanboard plugins by Dr. Beco
|
2026-07-10 09:15:36 -03:00
|
|
|
|
|
|
|
|
All free and AGPL-3.0, at [code.beco.cc](https://code.beco.cc/beco):
|
|
|
|
|
|
|
|
|
|
- **[RecoReco](https://code.beco.cc/beco/RecoReco)** -- calendar-scheduled recurring cards (yearly,
|
|
|
|
|
monthly, weekly, daily), driven by the card due date.
|
|
|
|
|
- **[FinanceBuddy](https://code.beco.cc/beco/FinanceBuddy)** -- attach a money value (debit/credit
|
|
|
|
|
and installments) to cards, shown on the card and totalled per column.
|
2026-07-13 08:49:00 -03:00
|
|
|
- **[QualKard](https://code.beco.cc/beco/QualKard)** -- flashcard spaced repetition: grade a card by
|
|
|
|
|
dragging it to a column, and it comes back when due (needs RecoReco).
|
|
|
|
|
- **[WorkspaceOrg](https://code.beco.cc/beco/WorkspaceOrg)** -- group your projects into personal
|
|
|
|
|
per-user workspaces, shown on a "My workspaces" dashboard page with a badge on each project.
|
2026-07-10 09:15:36 -03:00
|
|
|
- **[BulkMoveTasks](https://code.beco.cc/beco/BulkMoveTasks)** -- move every task from one board
|
|
|
|
|
column to another in a single action.
|
|
|
|
|
- **[ShrinkVertically](https://code.beco.cc/beco/ShrinkVertically)** -- shrink vertically-collapsed
|
|
|
|
|
board columns so the horizontal scrollbar stays within reach.
|
|
|
|
|
- **[TweakDrag](https://code.beco.cc/beco/TweakDrag)** -- board drag and touch niceties:
|
|
|
|
|
drag-to-scroll, a wider column gap, and smoother card dragging.
|