From bc266ff9696854b104c55548d2c6f25b0c9ff6d4 Mon Sep 17 00:00:00 2001
From: Ruben Carlo Benante
Date: Wed, 8 Jul 2026 21:09:30 -0300
Subject: [PATCH] auto-managed shared "Show all tasks" filter on every board +
config toggle v1.5
---
Controller/ConfigController.php | 13 ++++
Helper/OrganonProjectHelper.php | 80 +++++++++++++++++++++
Plugin.php | 9 ++-
Template/config/show.php | 7 ++
Template/project_header/show_all_filter.php | 1 +
VERSION | 2 +-
6 files changed, 110 insertions(+), 2 deletions(-)
create mode 100644 Template/project_header/show_all_filter.php
diff --git a/Controller/ConfigController.php b/Controller/ConfigController.php
index 58c77f5..a35c829 100644
--- a/Controller/ConfigController.php
+++ b/Controller/ConfigController.php
@@ -19,6 +19,7 @@ class ConfigController extends BaseController
'organon_tweaks_quick_click_only' => (int) $this->configModel->get('organon_tweaks_quick_click_only', 1),
'organon_tweaks_enhance_recurrence' => (int) $this->configModel->get('organon_tweaks_enhance_recurrence', 1),
'organon_tweaks_emphasize_duedate_default' => (int) $this->configModel->get('organon_tweaks_emphasize_duedate_default', 0),
+ 'organon_tweaks_show_all_filter' => (int) $this->configModel->get('organon_tweaks_show_all_filter', 1),
),
'errors' => array(),
)));
@@ -33,6 +34,7 @@ class ConfigController extends BaseController
$quickClickOnly = isset($values['organon_tweaks_quick_click_only']) ? 1 : 0;
$enhanceRecurrence = isset($values['organon_tweaks_enhance_recurrence']) ? 1 : 0;
$emphasizeDueDateDefault = isset($values['organon_tweaks_emphasize_duedate_default']) ? 1 : 0;
+ $showAllFilter = isset($values['organon_tweaks_show_all_filter']) ? 1 : 0;
if ($this->configModel->save(array(
'organon_tweaks_always_comment_icon' => $alwaysCommentIcon,
@@ -40,12 +42,23 @@ class ConfigController extends BaseController
'organon_tweaks_quick_click_only' => $quickClickOnly,
'organon_tweaks_enhance_recurrence' => $enhanceRecurrence,
'organon_tweaks_emphasize_duedate_default' => $emphasizeDueDateDefault,
+ 'organon_tweaks_show_all_filter' => $showAllFilter,
))) {
$this->flash->success(t('Settings saved successfully.'));
} else {
$this->flash->failure(t('Unable to save your settings.'));
}
+ // Apply the "Show all tasks" toggle across all boards immediately: on -> (re)create the
+ // filter everywhere, off -> remove every one (it is a plugin-managed, reserved-name filter).
+ $projectHelper = new \Kanboard\Plugin\OrganonTweaks\Helper\OrganonProjectHelper($this->container);
+
+ if ($showAllFilter === 1) {
+ $projectHelper->addShowAllFilterToAllProjects();
+ } else {
+ $projectHelper->removeAllShowAllFilters();
+ }
+
$this->response->redirect($this->helper->url->to('ConfigController', 'show', array('plugin' => 'OrganonTweaks')));
}
}
diff --git a/Helper/OrganonProjectHelper.php b/Helper/OrganonProjectHelper.php
index 0179a52..35ed748 100644
--- a/Helper/OrganonProjectHelper.php
+++ b/Helper/OrganonProjectHelper.php
@@ -3,6 +3,7 @@
namespace Kanboard\Plugin\OrganonTweaks\Helper;
use Kanboard\Core\Base;
+use Kanboard\Model\CustomFilterModel;
/**
* Per-board helper for OrganonTweaks.
@@ -14,12 +15,21 @@ use Kanboard\Core\Base;
* The stored values are the non-falsy strings 'on'/'off' (not '1'/'0'): Kanboard's
* MetadataModel::get() uses `?:`, and PHP treats the string "0" as falsy, so a stored "0" would
* come back as the 'default' fallback and "Always off" would never be honored.
+ *
+ * Also maintains a shared "Show all tasks" custom filter (an empty query) on every board, so there
+ * is always a one-click way to clear the board filter and reveal open + closed tasks.
*/
class OrganonProjectHelper extends Base
{
const EMPHASIZE_KEY = 'organon_tweaks_emphasize_duedate';
const EMPHASIZE_DEFAULT_KEY = 'organon_tweaks_emphasize_duedate_default';
+ const SHOW_ALL_FILTER_KEY = 'organon_tweaks_show_all_filter';
+
+ // The plugin RESERVES this custom-filter name: a fixed (non-translated) string so the dedup is
+ // stable across locales. A user's own filter with this name is absorbed into the canonical form.
+ const SHOW_ALL_FILTER_NAME = 'Show all tasks';
+
/**
* Should the current board emphasize the due date? Board pages only (project_id in the route).
*
@@ -46,4 +56,74 @@ class OrganonProjectHelper extends Base
// 'default' (or absent) -> follow the live global default.
return (int) $this->configModel->get(self::EMPHASIZE_DEFAULT_KEY, 0) === 1;
}
+
+ /**
+ * Ensure the board has exactly one canonical "Show all tasks" filter (empty query, shared).
+ * Idempotent: create it when absent, force a same-named one back to the canonical form (reserved
+ * name), and drop any duplicates. Called lazily on every project-header render, so it covers old
+ * and new boards alike. No-op without a real project and a real owner (custom_filters.user_id has
+ * a FK to users, so a system id like 0 would fail the insert).
+ *
+ * @param int $project_id
+ */
+ public function ensureShowAllFilter($project_id)
+ {
+ $project_id = (int) $project_id;
+ $user_id = (int) $this->userSession->getId();
+
+ if ($project_id <= 0 || $user_id <= 0) {
+ return;
+ }
+
+ $existing = $this->db->table(CustomFilterModel::TABLE)
+ ->eq('project_id', $project_id)
+ ->eq('name', self::SHOW_ALL_FILTER_NAME)
+ ->findAll();
+
+ if (empty($existing)) {
+ $this->db->table(CustomFilterModel::TABLE)->insert(array(
+ 'filter' => '',
+ 'project_id' => $project_id,
+ 'user_id' => $user_id,
+ 'name' => self::SHOW_ALL_FILTER_NAME,
+ 'is_shared' => 1,
+ 'append' => 0,
+ ));
+ return;
+ }
+
+ // Reserved name: keep one, force it to the canonical empty + shared form, drop the rest.
+ $keep = array_shift($existing);
+
+ if ($keep['filter'] !== '' || (int) $keep['is_shared'] !== 1) {
+ $this->db->table(CustomFilterModel::TABLE)
+ ->eq('id', $keep['id'])
+ ->update(array('filter' => '', 'is_shared' => 1));
+ }
+
+ foreach ($existing as $duplicate) {
+ $this->db->table(CustomFilterModel::TABLE)->eq('id', $duplicate['id'])->remove();
+ }
+ }
+
+ /**
+ * Toggle turned ON: eagerly (re)create the "Show all tasks" filter on every existing board.
+ * ensureShowAllFilter() keeps covering boards created afterwards.
+ */
+ public function addShowAllFilterToAllProjects()
+ {
+ foreach ($this->projectModel->getAll() as $project) {
+ $this->ensureShowAllFilter((int) $project['id']);
+ }
+ }
+
+ /**
+ * Toggle turned OFF: remove every "Show all tasks" filter across all boards (reserved name).
+ */
+ public function removeAllShowAllFilters()
+ {
+ $this->db->table(CustomFilterModel::TABLE)
+ ->eq('name', self::SHOW_ALL_FILTER_NAME)
+ ->remove();
+ }
}
diff --git a/Plugin.php b/Plugin.php
index 2198924..fda3f36 100644
--- a/Plugin.php
+++ b/Plugin.php
@@ -57,6 +57,13 @@ class Plugin extends Base
'template' => 'plugins/OrganonTweaks/Asset/js/enhance-recurrence.js',
));
}
+
+ // Tweak: keep a shared "Show all tasks" custom filter (empty query -> open + closed) on every
+ // board as a one-click "clear the filter". Ensured lazily when a project header renders, so
+ // it covers old and new boards. The config toggle bulk-adds/removes them (ConfigController).
+ if ((int) $this->configModel->get('organon_tweaks_show_all_filter', 1) === 1) {
+ $this->template->hook->attach('template:project:header:before', 'organonTweaks:project_header/show_all_filter');
+ }
}
public function getHelpers()
@@ -83,7 +90,7 @@ class Plugin extends Base
public function getPluginVersion()
{
- return '1.4.2';
+ return '1.5.0';
}
public function getPluginHomepage()
diff --git a/Template/config/show.php b/Template/config/show.php
index 70f011f..c2eae37 100644
--- a/Template/config/show.php
+++ b/Template/config/show.php
@@ -40,6 +40,13 @@