card icons + clone message-modal + re-recur guard (v1.2)
This commit is contained in:
@@ -19,9 +19,10 @@ class RecurrenceController extends BaseController
|
||||
{
|
||||
$task = $this->getTask();
|
||||
$columns = $this->targetColumns($task);
|
||||
$meta = $this->taskMetadataModel->getAll($task['id']);
|
||||
|
||||
if (empty($values)) {
|
||||
$values = $this->getStoredValues($task, $columns);
|
||||
$values = $this->getStoredValues($meta, $task, $columns);
|
||||
}
|
||||
|
||||
$this->response->html($this->template->render('recoReco:recurrence/edit', array(
|
||||
@@ -33,6 +34,8 @@ class RecurrenceController extends BaseController
|
||||
'has_due_date' => ! empty($task['date_due']),
|
||||
'is_native' => $task['recurrence_status'] != TaskModel::RECURRING_STATUS_NONE,
|
||||
'has_target' => ! empty($columns),
|
||||
'is_clone' => isset($meta['recoreco_clone']) && $meta['recoreco_clone'] == 1,
|
||||
'source_id' => isset($meta['recoreco_source']) ? (int) $meta['recoreco_source'] : 0,
|
||||
)));
|
||||
}
|
||||
|
||||
@@ -42,9 +45,14 @@ class RecurrenceController extends BaseController
|
||||
$input = $this->request->getValues();
|
||||
$columns = $this->targetColumns($task);
|
||||
|
||||
// Only a plain card (a due date, not native-recurring, and a valid target) may be enabled.
|
||||
// A clone can never be made recurring (that would recurse). Guard even though the modal
|
||||
// hides the form for clones.
|
||||
$is_clone = (int) $this->taskMetadataModel->get($task['id'], 'recoreco_clone', 0) === 1;
|
||||
|
||||
// Only a plain card (a due date, not native-recurring, not a clone, a valid target) may enable.
|
||||
$can_recur = ! empty($task['date_due'])
|
||||
&& $task['recurrence_status'] == TaskModel::RECURRING_STATUS_NONE
|
||||
&& ! $is_clone
|
||||
&& ! empty($columns);
|
||||
$enabled = ($can_recur && isset($input['recoreco_enabled']) && $input['recoreco_enabled'] == 1) ? 1 : 0;
|
||||
|
||||
@@ -104,10 +112,8 @@ class RecurrenceController extends BaseController
|
||||
return empty($keys) ? 0 : (int) $keys[0];
|
||||
}
|
||||
|
||||
private function getStoredValues(array $task, array $columns)
|
||||
private function getStoredValues(array $meta, array $task, array $columns)
|
||||
{
|
||||
$meta = $this->taskMetadataModel->getAll($task['id']);
|
||||
|
||||
return array(
|
||||
'recoreco_enabled' => isset($meta['recoreco_enabled']) ? (int) $meta['recoreco_enabled'] : 0,
|
||||
'recoreco_target_column' => $this->resolveTarget(isset($meta['recoreco_target_column']) ? $meta['recoreco_target_column'] : 0, $columns),
|
||||
|
||||
38
Helper/RecoRecoHelper.php
Normal file
38
Helper/RecoRecoHelper.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Plugin\RecoReco\Helper;
|
||||
|
||||
use Kanboard\Core\Base;
|
||||
use Kanboard\Model\TaskModel;
|
||||
|
||||
/**
|
||||
* Board helper: which RecoReco icon a card should show.
|
||||
*
|
||||
* Single-icon rule -- RecoReco only renders when the card is NOT native-recurring
|
||||
* (recurrence_status == NONE), so native's icon and RecoReco's icon can never appear together.
|
||||
*/
|
||||
class RecoRecoHelper extends Base
|
||||
{
|
||||
/**
|
||||
* @param array $task A board task row (has recurrence_status and id).
|
||||
* @return string 'template', 'clone', or '' (no RecoReco icon).
|
||||
*/
|
||||
public function iconType(array $task)
|
||||
{
|
||||
if ((int) $task['recurrence_status'] !== TaskModel::RECURRING_STATUS_NONE) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$meta = $this->taskMetadataModel->getAll($task['id']);
|
||||
|
||||
if (isset($meta['recoreco_enabled']) && $meta['recoreco_enabled'] == 1) {
|
||||
return 'template';
|
||||
}
|
||||
|
||||
if (isset($meta['recoreco_clone']) && $meta['recoreco_clone'] == 1) {
|
||||
return 'clone';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
12
Plugin.php
12
Plugin.php
@@ -17,6 +17,9 @@ class Plugin extends Base
|
||||
'template' => 'plugins/RecoReco/Asset/js/recoreco-modal.js',
|
||||
));
|
||||
|
||||
// Board card icon: black on a recurring template, white (inverse) on a generated copy.
|
||||
$this->template->hook->attach('template:board:task:icons', 'recoReco:board/task_icon');
|
||||
|
||||
// The scheduling engine runs from the CLI (cron). Registered CLI-only so web requests do
|
||||
// not build the console app.
|
||||
if (php_sapi_name() === 'cli') {
|
||||
@@ -24,6 +27,13 @@ class Plugin extends Base
|
||||
}
|
||||
}
|
||||
|
||||
public function getHelpers()
|
||||
{
|
||||
return array(
|
||||
'Plugin\RecoReco\Helper' => array('RecoRecoHelper'),
|
||||
);
|
||||
}
|
||||
|
||||
public function getPluginName()
|
||||
{
|
||||
return 'RecoReco';
|
||||
@@ -41,7 +51,7 @@ class Plugin extends Base
|
||||
|
||||
public function getPluginVersion()
|
||||
{
|
||||
return '1.1.2';
|
||||
return '1.2.0';
|
||||
}
|
||||
|
||||
public function getPluginHomepage()
|
||||
|
||||
10
Template/board/task_icon.php
Normal file
10
Template/board/task_icon.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php $type = $this->RecoRecoHelper->iconType($task) ?>
|
||||
<?php if ($type === 'template'): ?>
|
||||
<span title="<?= t('RecoReco: recurring template') ?>">
|
||||
<i class="fa fa-refresh fa-rotate-90" role="img" aria-label="<?= t('RecoReco: recurring template') ?>"></i>
|
||||
</span>
|
||||
<?php elseif ($type === 'clone'): ?>
|
||||
<span title="<?= t('RecoReco: generated copy') ?>">
|
||||
<i class="fa fa-refresh fa-rotate-90 fa-inverse" role="img" aria-label="<?= t('RecoReco: generated copy') ?>"></i>
|
||||
</span>
|
||||
<?php endif ?>
|
||||
@@ -9,47 +9,60 @@
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<?php $can_recur = $has_due_date && ! $is_native && $has_target ?>
|
||||
<?php if ($is_clone): ?>
|
||||
|
||||
<?php if (! $has_due_date): ?>
|
||||
<p class="alert alert-info"><?= t('Please set a due date first. RecoReco uses the card due date as the recurrence anchor.') ?></p>
|
||||
<?php elseif ($is_native): ?>
|
||||
<p class="alert alert-info">
|
||||
<?= t('This card uses Kanboard built-in recurrence.') ?>
|
||||
<?= $this->url->link(t('Edit built-in recurrence'), 'TaskRecurrenceController', 'edit', array('task_id' => $task['id']), false, 'js-modal-medium') ?>
|
||||
<?= t('This card is a copy generated by RecoReco, so it cannot itself be made recurring.') ?>
|
||||
<?php if ($source_id): ?>
|
||||
<?= $this->url->link(t('Open the recurring template'), 'TaskViewController', 'show', array('task_id' => $source_id)) ?>
|
||||
<?php endif ?>
|
||||
</p>
|
||||
<?php elseif (! $has_target): ?>
|
||||
<p class="alert alert-info"><?= t('Add a target column first.') ?></p>
|
||||
|
||||
<?php else: ?>
|
||||
|
||||
<?php $can_recur = $has_due_date && ! $is_native && $has_target ?>
|
||||
|
||||
<?php if (! $has_due_date): ?>
|
||||
<p class="alert alert-info"><?= t('Please set a due date first. RecoReco uses the card due date as the recurrence anchor.') ?></p>
|
||||
<?php elseif ($is_native): ?>
|
||||
<p class="alert alert-info">
|
||||
<?= t('This card uses Kanboard built-in recurrence.') ?>
|
||||
<?= $this->url->link(t('Edit built-in recurrence'), 'TaskRecurrenceController', 'edit', array('task_id' => $task['id']), false, 'js-modal-medium') ?>
|
||||
</p>
|
||||
<?php elseif (! $has_target): ?>
|
||||
<p class="alert alert-info"><?= t('Add a target column first.') ?></p>
|
||||
<?php endif ?>
|
||||
|
||||
<form method="post" action="<?= $this->url->href('RecurrenceController', 'save', array('plugin' => 'RecoReco', 'task_id' => $task['id'])) ?>" autocomplete="off">
|
||||
<?= $this->form->csrf() ?>
|
||||
|
||||
<?= $this->form->label(t('Make recurring'), 'recoreco_enabled') ?>
|
||||
<div class="recoreco-radios">
|
||||
<label style="display:inline-block; margin-right:16px;">
|
||||
<input type="radio" name="recoreco_enabled" value="0" <?= $values['recoreco_enabled'] == 1 ? '' : 'checked="checked"' ?>> <?= t('No') ?>
|
||||
</label>
|
||||
<label style="display:inline-block; margin-right:16px;">
|
||||
<input type="radio" name="recoreco_enabled" value="1" <?= $values['recoreco_enabled'] == 1 ? 'checked="checked"' : '' ?> <?= $can_recur ? '' : 'disabled="disabled"' ?>> <?= t('Yes') ?>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<?= $this->form->label(t('Target column (where the copy appears)'), 'recoreco_target_column') ?>
|
||||
<?= $this->form->select('recoreco_target_column', $columns_list, $values) ?>
|
||||
|
||||
<?= $this->form->label(t('Frequency'), 'recoreco_frequency') ?>
|
||||
<?= $this->form->select('recoreco_frequency', $frequency_list, $values) ?>
|
||||
|
||||
<div class="recoreco-lastday">
|
||||
<?= $this->form->checkbox('recoreco_last_day', t('Fires on last day/weekday of the month'), 1, $values['recoreco_last_day'] == 1) ?>
|
||||
</div>
|
||||
|
||||
<?= $this->form->label(t('Create the copy this many days before the due date'), 'recoreco_days_before') ?>
|
||||
<input type="number" name="recoreco_days_before" min="0" value="<?= $this->text->e($values['recoreco_days_before']) ?>">
|
||||
|
||||
<?= $this->form->checkbox('recoreco_link_copies', t('Link copies to the template'), 1, $values['recoreco_link_copies'] == 1) ?>
|
||||
<p class="form-help"><?= t('Links each copy back to the template (a count and quick navigation). Off by default.') ?></p>
|
||||
|
||||
<?= $this->modal->submitButtons() ?>
|
||||
</form>
|
||||
|
||||
<?php endif ?>
|
||||
|
||||
<form method="post" action="<?= $this->url->href('RecurrenceController', 'save', array('plugin' => 'RecoReco', 'task_id' => $task['id'])) ?>" autocomplete="off">
|
||||
<?= $this->form->csrf() ?>
|
||||
|
||||
<?= $this->form->label(t('Make recurring'), 'recoreco_enabled') ?>
|
||||
<div class="recoreco-radios">
|
||||
<label style="display:inline-block; margin-right:16px;">
|
||||
<input type="radio" name="recoreco_enabled" value="0" <?= $values['recoreco_enabled'] == 1 ? '' : 'checked="checked"' ?>> <?= t('No') ?>
|
||||
</label>
|
||||
<label style="display:inline-block; margin-right:16px;">
|
||||
<input type="radio" name="recoreco_enabled" value="1" <?= $values['recoreco_enabled'] == 1 ? 'checked="checked"' : '' ?> <?= $can_recur ? '' : 'disabled="disabled"' ?>> <?= t('Yes') ?>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<?= $this->form->label(t('Target column (where the copy appears)'), 'recoreco_target_column') ?>
|
||||
<?= $this->form->select('recoreco_target_column', $columns_list, $values) ?>
|
||||
|
||||
<?= $this->form->label(t('Frequency'), 'recoreco_frequency') ?>
|
||||
<?= $this->form->select('recoreco_frequency', $frequency_list, $values) ?>
|
||||
|
||||
<div class="recoreco-lastday">
|
||||
<?= $this->form->checkbox('recoreco_last_day', t('Fires on last day/weekday of the month'), 1, $values['recoreco_last_day'] == 1) ?>
|
||||
</div>
|
||||
|
||||
<?= $this->form->label(t('Create the copy this many days before the due date'), 'recoreco_days_before') ?>
|
||||
<input type="number" name="recoreco_days_before" min="0" value="<?= $this->text->e($values['recoreco_days_before']) ?>">
|
||||
|
||||
<?= $this->form->checkbox('recoreco_link_copies', t('Link copies to the template'), 1, $values['recoreco_link_copies'] == 1) ?>
|
||||
<p class="form-help"><?= t('Links each copy back to the template (a count and quick navigation). Off by default.') ?></p>
|
||||
|
||||
<?= $this->modal->submitButtons() ?>
|
||||
</form>
|
||||
|
||||
Reference in New Issue
Block a user