13 Commits
v1.2.1 ... v1.6

Author SHA1 Message Date
4d7f88aa94 v1.6 duemonth/aroundmonth search keywords + auto-added month filter bookmarks 2026-07-09 06:49:15 -03:00
bc266ff969 auto-managed shared "Show all tasks" filter on every board + config toggle v1.5 2026-07-08 21:09:30 -03:00
8a97c5cb94 fix Always-off (on/off/default safe values) + bump emphasis to 1.375em (v1.4.2) 2026-07-08 13:03:35 -03:00
d1178bc463 fix stuck enhance-recurrence toggle + clarify label (v1.4.1) 2026-07-08 09:13:07 -03:00
c747d33491 per-board "Emphasize due date" with global default (v1.4) 2026-07-08 09:00:50 -03:00
850127e712 increase click-guard.js to 110ms differentiate drag/click t3 try remove cached js first 2026-07-07 22:05:19 -03:00
70f42352b0 increase click-guard.js to 120ms differentiate drag/click t2 2026-07-07 22:04:14 -03:00
d57544ebfd increase Asset/js/click-guard.js 100ms to 110ms differentiate drag/click v1.3.3 2026-07-07 22:02:34 -03:00
c3896e1962 enhance-recurrence radio button only on display bugfix v1.3.2 2026-07-07 09:51:38 -03:00
065825269e v1.3.1 bump 2026-07-07 09:45:17 -03:00
6726dfa456 enhance recurrence dialog yes/no side-by-side v1.3.1 2026-07-07 09:43:54 -03:00
17ebfcccd9 OrganonTweaks: enhance recurrence dialog -- Yes/No radios + [+7] factor button (JS); added asset , v1.3.0 2026-07-07 09:41:15 -03:00
95561e5565 OrganonTweaks: enhance recurrence dialog -- Yes/No radios + [+7] factor button (JS); v1.3.0 2026-07-07 09:40:51 -03:00
12 changed files with 512 additions and 4 deletions

View File

@@ -13,7 +13,7 @@
(function () { (function () {
"use strict"; "use strict";
var THRESHOLD = 100; // ms; a press on a card held longer than this is a drag, not a click var THRESHOLD = 110; // ms; a press on a card held longer than this is a drag, not a click
var pressStart = 0; var pressStart = 0;
function onDown(e) { function onDown(e) {

View File

@@ -0,0 +1,105 @@
/*
* OrganonTweaks -- enhance Kanboard's native "Edit recurrence" dialog.
*
* That template (task_recurrence/edit.php) has no hook, so we transform the form in JS when
* the modal opens:
* 1. Replace the "Generate recurrent task" Yes/No dropdown with two radio buttons (one
* click instead of open + select). The original <select> is kept, hidden, and stays in
* sync, so the form still submits recurrence_status normally.
* 2. Add a small [+7] button next to the "Factor" input that adds 7 (a week of days).
*
* Detection: the modal is injected into #modal-box dynamically, so we watch the document for
* an un-enhanced recurrence form appearing. Loaded only when the setting is enabled.
*/
(function () {
"use strict";
function enhanceStatus(select) {
var group = document.createElement("span");
group.className = "ot-recurrence-status";
var radios = [];
for (var i = 0; i < select.options.length; i++) {
var opt = select.options[i];
var label = document.createElement("label");
// Kanboard styles form labels as display:block; force inline so Yes/No sit
// side by side instead of stacked.
label.style.display = "inline-block";
label.style.marginRight = "14px";
label.style.cursor = "pointer";
var radio = document.createElement("input");
radio.type = "radio";
// No name attribute on purpose: a named radio would be SUBMITTED with the form,
// and Kanboard rejects the extra key ("invalid identifier"). These are display
// only -- the hidden <select> carries the value -- so we enforce the mutual
// exclusivity ourselves.
radio.value = opt.value;
radio.checked = opt.value === select.value;
radio.style.marginRight = "4px";
radios.push(radio);
radio.addEventListener("change", function () {
for (var k = 0; k < radios.length; k++) {
radios[k].checked = (radios[k] === this);
}
select.value = this.value;
select.dispatchEvent(new Event("change", { bubbles: true }));
});
label.appendChild(radio);
label.appendChild(document.createTextNode(opt.text));
group.appendChild(label);
}
select.style.display = "none";
select.parentNode.insertBefore(group, select.nextSibling);
}
function enhanceFactor(input) {
var btn = document.createElement("button");
btn.type = "button";
btn.className = "btn";
btn.textContent = "+7";
btn.title = "Add 7 (one week of days)";
btn.style.marginLeft = "6px";
btn.addEventListener("click", function () {
input.value = (parseInt(input.value, 10) || 0) + 7;
input.dispatchEvent(new Event("change", { bubbles: true }));
});
input.parentNode.insertBefore(btn, input.nextSibling);
}
function enhance() {
var select = document.querySelector('select[name="recurrence_status"]:not([data-ot-recurrence])');
if (!select) {
return;
}
select.setAttribute("data-ot-recurrence", "1");
enhanceStatus(select);
var factor = document.querySelector('input[name="recurrence_factor"]:not([data-ot-recurrence])');
if (factor) {
factor.setAttribute("data-ot-recurrence", "1");
enhanceFactor(factor);
}
}
function init() {
enhance();
if (window.MutationObserver) {
new MutationObserver(enhance).observe(document.body, { childList: true, subtree: true });
}
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", init);
} else {
init();
}
})();

View File

@@ -17,6 +17,10 @@ class ConfigController extends BaseController
'organon_tweaks_always_comment_icon' => (int) $this->configModel->get('organon_tweaks_always_comment_icon', 1), 'organon_tweaks_always_comment_icon' => (int) $this->configModel->get('organon_tweaks_always_comment_icon', 1),
'organon_tweaks_keep_scroll' => (int) $this->configModel->get('organon_tweaks_keep_scroll', 1), 'organon_tweaks_keep_scroll' => (int) $this->configModel->get('organon_tweaks_keep_scroll', 1),
'organon_tweaks_quick_click_only' => (int) $this->configModel->get('organon_tweaks_quick_click_only', 1), '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),
'organon_tweaks_month_filters' => (int) $this->configModel->get('organon_tweaks_month_filters', 1),
), ),
'errors' => array(), 'errors' => array(),
))); )));
@@ -29,17 +33,41 @@ class ConfigController extends BaseController
$alwaysCommentIcon = isset($values['organon_tweaks_always_comment_icon']) ? 1 : 0; $alwaysCommentIcon = isset($values['organon_tweaks_always_comment_icon']) ? 1 : 0;
$keepScroll = isset($values['organon_tweaks_keep_scroll']) ? 1 : 0; $keepScroll = isset($values['organon_tweaks_keep_scroll']) ? 1 : 0;
$quickClickOnly = isset($values['organon_tweaks_quick_click_only']) ? 1 : 0; $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;
$monthFilters = isset($values['organon_tweaks_month_filters']) ? 1 : 0;
if ($this->configModel->save(array( if ($this->configModel->save(array(
'organon_tweaks_always_comment_icon' => $alwaysCommentIcon, 'organon_tweaks_always_comment_icon' => $alwaysCommentIcon,
'organon_tweaks_keep_scroll' => $keepScroll, 'organon_tweaks_keep_scroll' => $keepScroll,
'organon_tweaks_quick_click_only' => $quickClickOnly, 'organon_tweaks_quick_click_only' => $quickClickOnly,
'organon_tweaks_enhance_recurrence' => $enhanceRecurrence,
'organon_tweaks_emphasize_duedate_default' => $emphasizeDueDateDefault,
'organon_tweaks_show_all_filter' => $showAllFilter,
'organon_tweaks_month_filters' => $monthFilters,
))) { ))) {
$this->flash->success(t('Settings saved successfully.')); $this->flash->success(t('Settings saved successfully.'));
} else { } else {
$this->flash->failure(t('Unable to save your settings.')); $this->flash->failure(t('Unable to save your settings.'));
} }
// Apply each filter-group toggle across all boards immediately: on -> (re)create the group's
// reserved-name filters everywhere, off -> remove them (they are plugin-managed).
$projectHelper = new \Kanboard\Plugin\OrganonTweaks\Helper\OrganonProjectHelper($this->container);
if ($showAllFilter === 1) {
$projectHelper->addGroupToAllProjects($projectHelper::GROUP_SHOW_ALL);
} else {
$projectHelper->removeGroup($projectHelper::GROUP_SHOW_ALL);
}
if ($monthFilters === 1) {
$projectHelper->addGroupToAllProjects($projectHelper::GROUP_MONTH);
} else {
$projectHelper->removeGroup($projectHelper::GROUP_MONTH);
}
$this->response->redirect($this->helper->url->to('ConfigController', 'show', array('plugin' => 'OrganonTweaks'))); $this->response->redirect($this->helper->url->to('ConfigController', 'show', array('plugin' => 'OrganonTweaks')));
} }
} }

View File

@@ -0,0 +1,92 @@
<?php
namespace Kanboard\Plugin\OrganonTweaks\Filter;
use Kanboard\Core\Filter\FilterInterface;
use Kanboard\Filter\BaseFilter;
use Kanboard\Model\TaskModel;
/**
* Filter tasks by a whole calendar month, optionally padded.
*
* Registered twice by the plugin (via $container->extend('taskLexer', ...)):
* - `duemonth:VALUE` -- padDays 0: due within the target month.
* - `aroundmonth:VALUE` -- padDays 10: the month minus 10 days .. plus 10 days (i.e. the last
* 10 days of the previous month, the whole month, and the first 10 days of the next month).
*
* VALUE is `this` (also `next` / `last`) or an explicit month such as `2026-01` or `january-2026`
* (anything strtotime() can parse). Bounds are computed with mktime (correct for any month length)
* at search time, so the filter auto-rolls.
*
* Both bounds (gte start, lte end) are added inside this single apply() on the single-value path,
* so they AND -- the range Kanboard's saved-filter string syntax cannot express (repeating the
* same attribute ORs via OrCriteria, and there is no AND keyword).
*/
class TaskMonthRangeFilter extends BaseFilter implements FilterInterface
{
private $attribute = 'duemonth';
private $padDays = 0;
public function setAttribute($attribute)
{
$this->attribute = $attribute;
return $this;
}
public function setPadDays($days)
{
$this->padDays = (int) $days;
return $this;
}
public function getAttributes()
{
return array($this->attribute);
}
public function apply()
{
$reference = $this->resolveMonthTimestamp((string) $this->value);
if ($reference === false) {
return $this; // unknown/typo value -> no-op (matches nothing added)
}
$month = (int) date('n', $reference);
$year = (int) date('Y', $reference);
$first = mktime(0, 0, 0, $month, 1, $year);
$last = mktime(23, 59, 59, $month + 1, 0, $year); // day 0 of next month = last day of this
$pad = $this->padDays * 86400;
$this->query->neq(TaskModel::TABLE.'.date_due', 0);
$this->query->gte(TaskModel::TABLE.'.date_due', $first - $pad);
$this->query->lte(TaskModel::TABLE.'.date_due', $last + $pad);
return $this;
}
/**
* Resolve the filter value to any timestamp inside the target month (or false if unparseable).
*
* @param string $value
* @return int|false
*/
private function resolveMonthTimestamp($value)
{
$value = strtolower(trim($value));
if ($value === '' || $value === 'this') {
return strtotime('first day of this month');
}
if ($value === 'next') {
return strtotime('first day of next month');
}
if ($value === 'last' || $value === 'prev' || $value === 'previous') {
return strtotime('first day of last month');
}
return strtotime($value); // 2026-01, january-2026, "last day of january 2026", ...
}
}

View File

@@ -0,0 +1,175 @@
<?php
namespace Kanboard\Plugin\OrganonTweaks\Helper;
use Kanboard\Core\Base;
use Kanboard\Model\CustomFilterModel;
/**
* Per-board helper for OrganonTweaks.
*
* Resolves the 3-state "emphasize due date" setting for the CURRENT board (read from the route
* project_id, which the router populates for pretty URLs before the layout renders):
* per-board 'on' -> on, 'off' -> off, 'default'/absent -> follow the LIVE global default.
*
* 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 shared, reserved-name custom filters on every board (v1.5 "Show all tasks", v1.6
* "Due this month" / "Around this month"), each group gated by its own config toggle.
*/
class OrganonProjectHelper extends Base
{
const EMPHASIZE_KEY = 'organon_tweaks_emphasize_duedate';
const EMPHASIZE_DEFAULT_KEY = 'organon_tweaks_emphasize_duedate_default';
// Config toggles for the auto-managed custom-filter groups.
const SHOW_ALL_FILTER_KEY = 'organon_tweaks_show_all_filter';
const MONTH_FILTERS_KEY = 'organon_tweaks_month_filters';
// Reserved custom-filter groups: each row is [name, query, append]. The NAME is reserved by the
// plugin (fixed, non-translated strings so dedup is stable across locales); a user's own filter
// with a reserved name is absorbed into the canonical form. "Show all tasks" is a REPLACE filter
// (append 0) so it clears; the rest are APPEND (1) so clicks stack (distinct attributes AND).
const GROUP_SHOW_ALL = array(
array('Show all tasks', '', 0),
);
const GROUP_MONTH = array(
array('Due this month', 'duemonth:this', 1),
array('Around this month', 'aroundmonth:this', 1),
);
/**
* Should the current board emphasize the due date? Board pages only (project_id in the route).
*
* @return bool
*/
public function isEmphasizeDueDate()
{
$project_id = $this->request->getIntegerParam('project_id');
if ($project_id <= 0) {
return false;
}
$value = $this->projectMetadataModel->get($project_id, self::EMPHASIZE_KEY, 'default');
if ($value === 'on') {
return true;
}
if ($value === 'off') {
return false;
}
// 'default' (or absent) -> follow the live global default.
return (int) $this->configModel->get(self::EMPHASIZE_DEFAULT_KEY, 0) === 1;
}
/**
* Ensure one canonical reserved custom filter on a board (shared). Idempotent: create when
* absent, force a same-named one back to the canonical form (query + shared + append) since the
* name is reserved, and drop duplicates. 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
* @param string $name
* @param string $query
* @param int $append
*/
public function ensureReservedFilter($project_id, $name, $query, $append)
{
$project_id = (int) $project_id;
$user_id = (int) $this->userSession->getId();
if ($project_id <= 0 || $user_id <= 0) {
return;
}
$append = $append ? 1 : 0;
$existing = $this->db->table(CustomFilterModel::TABLE)
->eq('project_id', $project_id)
->eq('name', $name)
->findAll();
if (empty($existing)) {
$this->db->table(CustomFilterModel::TABLE)->insert(array(
'filter' => $query,
'project_id' => $project_id,
'user_id' => $user_id,
'name' => $name,
'is_shared' => 1,
'append' => $append,
));
return;
}
// Reserved name: keep one, force it to the canonical form, drop the rest.
$keep = array_shift($existing);
if ($keep['filter'] !== $query || (int) $keep['is_shared'] !== 1 || (int) $keep['append'] !== $append) {
$this->db->table(CustomFilterModel::TABLE)
->eq('id', $keep['id'])
->update(array('filter' => $query, 'is_shared' => 1, 'append' => $append));
}
foreach ($existing as $duplicate) {
$this->db->table(CustomFilterModel::TABLE)->eq('id', $duplicate['id'])->remove();
}
}
/**
* Ensure every ENABLED group's filters on a board. Called lazily on each project-header render,
* so it covers old and new boards alike.
*
* @param int $project_id
*/
public function ensureBoardFilters($project_id)
{
if ((int) $this->configModel->get(self::SHOW_ALL_FILTER_KEY, 1) === 1) {
$this->ensureGroup($project_id, self::GROUP_SHOW_ALL);
}
if ((int) $this->configModel->get(self::MONTH_FILTERS_KEY, 1) === 1) {
$this->ensureGroup($project_id, self::GROUP_MONTH);
}
}
private function ensureGroup($project_id, array $rows)
{
foreach ($rows as $row) {
$this->ensureReservedFilter($project_id, $row[0], $row[1], $row[2]);
}
}
/**
* Toggle turned ON: eagerly (re)create a group's filters on every existing board.
* ensureBoardFilters() keeps covering boards created afterwards.
*
* @param array $rows
*/
public function addGroupToAllProjects(array $rows)
{
foreach ($this->projectModel->getAll() as $project) {
$this->ensureGroup((int) $project['id'], $rows);
}
}
/**
* Toggle turned OFF: remove a group's filters across all boards (by their reserved names).
*
* @param array $rows
*/
public function removeGroup(array $rows)
{
$names = array();
foreach ($rows as $row) {
$names[] = $row[0];
}
$this->db->table(CustomFilterModel::TABLE)->in('name', $names)->remove();
}
}

View File

@@ -20,6 +20,13 @@ class Plugin extends Base
// Settings page for the plugin's tweaks. // Settings page for the plugin's tweaks.
$this->template->hook->attach('template:config:sidebar', 'organonTweaks:config/sidebar'); $this->template->hook->attach('template:config:sidebar', 'organonTweaks:config/sidebar');
// Per-board tweak: emphasize the due date on the board. Configured with 3-state radios on the
// board's Settings -> Integrations (Use default / Always on / Always off); the global default
// (for "Use default" boards) lives in the plugin settings above. The emphasis <style> is
// emitted into the head only on enabled board pages (gated by OrganonProjectHelper).
$this->template->hook->attach('template:project:integrations', 'organonTweaks:project/integration');
$this->template->hook->attach('template:layout:head', 'organonTweaks:layout/emphasize_duedate');
// Tweak: always show a comment icon on board cards. When a card has no comments // Tweak: always show a comment icon on board cards. When a card has no comments
// yet, add a bubble "+" that opens the same comment modal (add the first comment // yet, add a bubble "+" that opens the same comment modal (add the first comment
// straight from the board). Cards with comments already show the native count. // straight from the board). Cards with comments already show the native count.
@@ -42,12 +49,43 @@ class Plugin extends Base
'template' => 'plugins/OrganonTweaks/Asset/js/click-guard.js', 'template' => 'plugins/OrganonTweaks/Asset/js/click-guard.js',
)); ));
} }
// Tweak: enhance the native "Edit recurrence" dialog (Yes/No radios + a [+7] button
// on the factor). No template hook there, so it is done in JS.
if ((int) $this->configModel->get('organon_tweaks_enhance_recurrence', 1) === 1) {
$this->hook->on('template:layout:js', array(
'template' => 'plugins/OrganonTweaks/Asset/js/enhance-recurrence.js',
));
}
// Auto-managed shared custom filters (v1.5 "Show all tasks", v1.6 month filters). Ensured
// lazily whenever a project header renders (covers old + new boards); each group is gated by
// its own config toggle inside OrganonProjectHelper::ensureBoardFilters(). The toggles also
// bulk add/remove the filters (ConfigController).
$showAllFilters = (int) $this->configModel->get('organon_tweaks_show_all_filter', 1) === 1;
$monthFilters = (int) $this->configModel->get('organon_tweaks_month_filters', 1) === 1;
if ($showAllFilters || $monthFilters) {
$this->template->hook->attach('template:project:header:before', 'organonTweaks:project_header/board_filters');
}
// Custom board-search keywords, registered into the task lexer by extending its factory
// service (Pimple preserves factory status on extend, so the lexer stays per-request fresh).
// `duemonth:VALUE` = a whole calendar month; `aroundmonth:VALUE` = that month padded by 10
// days on each side. Always available to type, independent of the bookmark toggles above.
// Guarded so a future Kanboard service rename no-ops (keyword absent) instead of breaking.
if (isset($this->container['taskLexer'])) {
$this->container->extend('taskLexer', function ($builder, $c) {
return $builder
->withFilter((new \Kanboard\Plugin\OrganonTweaks\Filter\TaskMonthRangeFilter())->setAttribute('duemonth')->setPadDays(0))
->withFilter((new \Kanboard\Plugin\OrganonTweaks\Filter\TaskMonthRangeFilter())->setAttribute('aroundmonth')->setPadDays(10));
});
}
} }
public function getHelpers() public function getHelpers()
{ {
return array( return array(
'Plugin\OrganonTweaks\Helper' => array('OrganonColumnHelper'), 'Plugin\OrganonTweaks\Helper' => array('OrganonColumnHelper', 'OrganonProjectHelper'),
); );
} }
@@ -68,7 +106,7 @@ class Plugin extends Base
public function getPluginVersion() public function getPluginVersion()
{ {
return '1.2.1'; return '1.6.0';
} }
public function getPluginHomepage() public function getPluginHomepage()

View File

@@ -58,6 +58,19 @@ clicks (well under 100 ms) still open cards as usual. The 100 ms threshold is fi
- **On by default.** Toggle it under "Settings -> Organon Tweaks". - **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".
## Settings ## Settings
Global (per Kanboard instance) and admin-only, under "Settings -> Organon Tweaks": Global (per Kanboard instance) and admin-only, under "Settings -> Organon Tweaks":
@@ -65,6 +78,7 @@ Global (per Kanboard instance) and admin-only, under "Settings -> Organon Tweaks
- **Always show the comment icon on board cards** -- default on. - **Always show the comment icon on board cards** -- default on.
- **Keep the board scroll position across refreshes** -- default on. - **Keep the board scroll position across refreshes** -- default on.
- **Open a card only on a quick click** -- default on. - **Open a card only on a quick click** -- default on.
- **Enhance the recurrence dialog** -- default on.
## Requirements ## Requirements

View File

@@ -26,6 +26,34 @@
</p> </p>
</fieldset> </fieldset>
<fieldset>
<?= $this->form->checkbox('organon_tweaks_enhance_recurrence', t('Enhance the native recurrence dialog'), 1, isset($values['organon_tweaks_enhance_recurrence']) && $values['organon_tweaks_enhance_recurrence'] == 1) ?>
<p class="form-help">
<?= t('In the native "Edit recurrence" dialog, replace the Generate recurrent task dropdown with Yes/No radio buttons (one click), and add a [+7] button next to the factor that adds 7 (one week of days).') ?>
</p>
</fieldset>
<fieldset>
<?= $this->form->checkbox('organon_tweaks_emphasize_duedate_default', t('Emphasize due date by default'), 1, isset($values['organon_tweaks_emphasize_duedate_default']) && $values['organon_tweaks_emphasize_duedate_default'] == 1) ?>
<p class="form-help">
<?= t('Default for boards set to "Use default": enlarge and bold the due date on the board. Each board can override this under its own Settings -> Integrations.') ?>
</p>
</fieldset>
<fieldset>
<?= $this->form->checkbox('organon_tweaks_show_all_filter', t('Add a "Show all tasks" filter to every board'), 1, isset($values['organon_tweaks_show_all_filter']) && $values['organon_tweaks_show_all_filter'] == 1) ?>
<p class="form-help">
<?= t('Keep a shared "Show all tasks" custom filter (an empty query, so open and closed tasks are shown) on every board, old and new. It appears in the board filter bookmark menu as a one-click way to clear the filter. Turning this off removes it from all boards; turning it on recreates it everywhere.') ?>
</p>
</fieldset>
<fieldset>
<?= $this->form->checkbox('organon_tweaks_month_filters', t('Add month filters to every board'), 1, isset($values['organon_tweaks_month_filters']) && $values['organon_tweaks_month_filters'] == 1) ?>
<p class="form-help">
<?= t('Keep shared "Due this month" and "Around this month" custom filters on every board (using the duemonth: and aroundmonth: search keywords this plugin adds). They are append filters, so clicking them stacks onto the current filter. Turning this off removes them from all boards; turning it on recreates them everywhere.') ?>
</p>
</fieldset>
<div class="form-actions"> <div class="form-actions">
<button type="submit" class="btn btn-blue"><?= t('Save') ?></button> <button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
</div> </div>

View File

@@ -0,0 +1,3 @@
<?php if ($this->OrganonProjectHelper->isEmphasizeDueDate()): ?>
<style>.task-date { font-size: 1.375em; font-weight: bold; }</style>
<?php endif ?>

View File

@@ -0,0 +1,24 @@
<?php $choice = isset($values['organon_tweaks_emphasize_duedate']) && in_array($values['organon_tweaks_emphasize_duedate'], array('on', 'off'), true) ? $values['organon_tweaks_emphasize_duedate'] : 'default' ?>
<h3><i class="fa fa-umbrella fa-fw" aria-hidden="true"></i> <?= t('OrganonTweaks') ?></h3>
<div class="listing">
<p><strong><?= t('Emphasize due date on the board') ?></strong></p>
<label style="display:inline-block; margin-right:16px;">
<input type="radio" name="organon_tweaks_emphasize_duedate" value="default" <?= $choice === 'default' ? 'checked="checked"' : '' ?>> <?= t('Use default') ?>
</label>
<label style="display:inline-block; margin-right:16px;">
<input type="radio" name="organon_tweaks_emphasize_duedate" value="on" <?= $choice === 'on' ? 'checked="checked"' : '' ?>> <?= t('Always on') ?>
</label>
<label style="display:inline-block; margin-right:16px;">
<input type="radio" name="organon_tweaks_emphasize_duedate" value="off" <?= $choice === 'off' ? 'checked="checked"' : '' ?>> <?= t('Always off') ?>
</label>
<p class="form-help">
<?= t('Enlarge and bold the due date on this board. "Use default" follows the global OrganonTweaks setting.') ?>
</p>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
</div>

View File

@@ -0,0 +1 @@
<?php $this->OrganonProjectHelper->ensureBoardFilters($project['id']) ?>

View File

@@ -1 +1 @@
OrganonTweaks v1.2.1 OrganonTweaks v1.6