Use status attribute to set a task as 'complete' (#3026)

This commit is contained in:
Thomas Bruederli 2014-05-19 18:20:23 +02:00
parent d87c46acac
commit 3a2d5eed5a
13 changed files with 87 additions and 28 deletions

View file

@ -44,7 +44,7 @@ class kolab_format_task extends kolab_format_xcal
$this->obj->setPercentComplete(intval($object['complete'])); $this->obj->setPercentComplete(intval($object['complete']));
$status = kolabformat::StatusUndefined; $status = kolabformat::StatusUndefined;
if ($object['complete'] == 100) if ($object['complete'] == 100 && !array_key_exists('status', $object))
$status = kolabformat::StatusCompleted; $status = kolabformat::StatusCompleted;
else if ($object['status'] && array_key_exists($object['status'], $this->status_map)) else if ($object['status'] && array_key_exists($object['status'], $this->status_map))
$status = $this->status_map[$object['status']]; $status = $this->status_map[$object['status']];
@ -113,7 +113,7 @@ class kolab_format_task extends kolab_format_xcal
{ {
$tags = array(); $tags = array();
if ($this->data['status'] == 'COMPLETED' || $this->data['complete'] == 100) if ($this->data['status'] == 'COMPLETED' || ($this->data['complete'] == 100 && empty($this->data['status'])))
$tags[] = 'x-complete'; $tags[] = 'x-complete';
if ($this->data['priority'] == 1) if ($this->data['priority'] == 1)

View file

@ -36,6 +36,7 @@ CREATE TABLE IF NOT EXISTS `tasks` (
`starttime` varchar(5) DEFAULT NULL, `starttime` varchar(5) DEFAULT NULL,
`flagged` tinyint(4) NOT NULL DEFAULT '0', `flagged` tinyint(4) NOT NULL DEFAULT '0',
`complete` float NOT NULL DEFAULT '0', `complete` float NOT NULL DEFAULT '0',
`status` enum('','NEEDS-ACTION','IN-PROCESS','COMPLETED','CANCELLED') NOT NULL DEFAULT '',
`alarms` varchar(255) DEFAULT NULL, `alarms` varchar(255) DEFAULT NULL,
`recurrence` varchar(255) DEFAULT NULL, `recurrence` varchar(255) DEFAULT NULL,
`organizer` varchar(255) DEFAULT NULL, `organizer` varchar(255) DEFAULT NULL,
@ -48,4 +49,4 @@ CREATE TABLE IF NOT EXISTS `tasks` (
REFERENCES `tasklists`(`tasklist_id`) ON DELETE CASCADE ON UPDATE CASCADE REFERENCES `tasklists`(`tasklist_id`) ON DELETE CASCADE ON UPDATE CASCADE
) /*!40000 ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci */; ) /*!40000 ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci */;
REPLACE INTO `system` (`name`, `value`) VALUES ('tasklist-database-version', '2013011000'); REPLACE INTO `system` (`name`, `value`) VALUES ('tasklist-database-version', '2014051900');

View file

@ -0,0 +1,3 @@
ALTER TABLE `tasks` ADD `status` ENUM('','NEEDS-ACTION','IN-PROCESS','COMPLETED','CANCELLED') NOT NULL DEFAULT '' AFTER `complete`;
UPDATE `tasks` SET status='COMPLETED' WHERE complete=1.0 AND status='';

View file

@ -49,6 +49,7 @@ CREATE TABLE tasks (
starttime varchar(5) DEFAULT NULL, starttime varchar(5) DEFAULT NULL,
flagged smallint NOT NULL DEFAULT 0, flagged smallint NOT NULL DEFAULT 0,
complete float NOT NULL DEFAULT 0, complete float NOT NULL DEFAULT 0,
status varchar(16) NOT NULL DEFAULT '',
alarms varchar(255) DEFAULT NULL, alarms varchar(255) DEFAULT NULL,
recurrence varchar(255) DEFAULT NULL, recurrence varchar(255) DEFAULT NULL,
organizer varchar(255) DEFAULT NULL, organizer varchar(255) DEFAULT NULL,
@ -60,4 +61,4 @@ CREATE TABLE tasks (
CREATE INDEX tasks_tasklisting_idx ON tasks (tasklist_id, del, date); CREATE INDEX tasks_tasklisting_idx ON tasks (tasklist_id, del, date);
CREATE INDEX tasks_uid_idx ON tasks (uid); CREATE INDEX tasks_uid_idx ON tasks (uid);
INSERT INTO system (name, value) VALUES ('tasklist-database-version', '2013011000'); INSERT INTO system (name, value) VALUES ('tasklist-database-version', '2014051900');

View file

@ -24,6 +24,8 @@
class tasklist_database_driver extends tasklist_driver class tasklist_database_driver extends tasklist_driver
{ {
const IS_COMPLETE_SQL = "(status='COMPLETED' OR (complete=1 AND status=''))";
public $undelete = true; // yes, we can public $undelete = true; // yes, we can
public $sortable = false; public $sortable = false;
public $alarm_types = array('DISPLAY'); public $alarm_types = array('DISPLAY');
@ -224,7 +226,7 @@ class tasklist_database_driver extends tasklist_driver
$result = $this->rc->db->query(sprintf( $result = $this->rc->db->query(sprintf(
"SELECT task_id, flagged, date FROM " . $this->db_tasks . " "SELECT task_id, flagged, date FROM " . $this->db_tasks . "
WHERE tasklist_id IN (%s) WHERE tasklist_id IN (%s)
AND del=0 AND complete<1", AND del=0 AND NOT " . self::IS_COMPLETE_SQL,
join(',', $list_ids) join(',', $list_ids)
)); ));
@ -286,9 +288,9 @@ class tasklist_database_driver extends tasklist_driver
$sql_add = ' AND date IS NULL'; $sql_add = ' AND date IS NULL';
if ($filter['mask'] & tasklist::FILTER_MASK_COMPLETE) if ($filter['mask'] & tasklist::FILTER_MASK_COMPLETE)
$sql_add .= ' AND complete=1'; $sql_add .= ' AND ' . self::IS_COMPLETE_SQL;
else if (empty($filter['since'])) // don't show complete tasks by default else if (empty($filter['since'])) // don't show complete tasks by default
$sql_add .= ' AND complete<1'; $sql_add .= ' AND NOT ' . self::IS_COMPLETE_SQL;
if ($filter['mask'] & tasklist::FILTER_MASK_FLAGGED) if ($filter['mask'] & tasklist::FILTER_MASK_FLAGGED)
$sql_add .= ' AND flagged=1'; $sql_add .= ' AND flagged=1';
@ -435,7 +437,7 @@ class tasklist_database_driver extends tasklist_driver
$result = $this->rc->db->query(sprintf( $result = $this->rc->db->query(sprintf(
"SELECT * FROM " . $this->db_tasks . " "SELECT * FROM " . $this->db_tasks . "
WHERE tasklist_id IN (%s) WHERE tasklist_id IN (%s)
AND notify <= %s AND complete < 1", AND notify <= %s AND NOT " . self::IS_COMPLETE_SQL,
join(',', $list_ids), join(',', $list_ids),
$this->rc->db->fromunixtime($time) $this->rc->db->fromunixtime($time)
)); ));
@ -529,7 +531,7 @@ class tasklist_database_driver extends tasklist_driver
$prop['recurrence'] = $this->serialize_recurrence($prop['recurrence']); $prop['recurrence'] = $this->serialize_recurrence($prop['recurrence']);
} }
foreach (array('parent_id', 'date', 'time', 'startdate', 'starttime', 'alarms', 'recurrence') as $col) { foreach (array('parent_id', 'date', 'time', 'startdate', 'starttime', 'alarms', 'recurrence', 'status') as $col) {
if (empty($prop[$col])) if (empty($prop[$col]))
$prop[$col] = null; $prop[$col] = null;
} }
@ -537,8 +539,8 @@ class tasklist_database_driver extends tasklist_driver
$notify_at = $this->_get_notification($prop); $notify_at = $this->_get_notification($prop);
$result = $this->rc->db->query(sprintf( $result = $this->rc->db->query(sprintf(
"INSERT INTO " . $this->db_tasks . " "INSERT INTO " . $this->db_tasks . "
(tasklist_id, uid, parent_id, created, changed, title, date, time, startdate, starttime, description, tags, flagged, complete, alarms, recurrence, notify) (tasklist_id, uid, parent_id, created, changed, title, date, time, startdate, starttime, description, tags, flagged, complete, status, alarms, recurrence, notify)
VALUES (?, ?, ?, %s, %s, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", VALUES (?, ?, ?, %s, %s, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
$this->rc->db->now(), $this->rc->db->now(),
$this->rc->db->now() $this->rc->db->now()
), ),
@ -554,6 +556,7 @@ class tasklist_database_driver extends tasklist_driver
join(',', (array)$prop['tags']), join(',', (array)$prop['tags']),
$prop['flagged'] ? 1 : 0, $prop['flagged'] ? 1 : 0,
intval($prop['complete']), intval($prop['complete']),
$prop['status'],
$prop['alarms'], $prop['alarms'],
$prop['recurrence'], $prop['recurrence'],
$notify_at $notify_at
@ -586,7 +589,7 @@ class tasklist_database_driver extends tasklist_driver
if (isset($prop[$col])) if (isset($prop[$col]))
$sql_set[] = $this->rc->db->quote_identifier($col) . '=' . $this->rc->db->quote($prop[$col]); $sql_set[] = $this->rc->db->quote_identifier($col) . '=' . $this->rc->db->quote($prop[$col]);
} }
foreach (array('parent_id', 'date', 'time', 'startdate', 'starttime', 'alarms', 'recurrence') as $col) { foreach (array('parent_id', 'date', 'time', 'startdate', 'starttime', 'alarms', 'recurrence', 'status') as $col) {
if (isset($prop[$col])) if (isset($prop[$col]))
$sql_set[] = $this->rc->db->quote_identifier($col) . '=' . (empty($prop[$col]) ? 'NULL' : $this->rc->db->quote($prop[$col])); $sql_set[] = $this->rc->db->quote_identifier($col) . '=' . (empty($prop[$col]) ? 'NULL' : $this->rc->db->quote($prop[$col]));
} }
@ -694,7 +697,7 @@ class tasklist_database_driver extends tasklist_driver
*/ */
private function _get_notification($task) private function _get_notification($task)
{ {
if ($task['valarms'] && $task['complete'] < 1) { if ($task['valarms'] && !$this->is_complete($task)) {
$alarm = libcalendaring::get_next_alarm($task, 'task'); $alarm = libcalendaring::get_next_alarm($task, 'task');
if ($alarm['time'] && in_array($alarm['action'], $this->alarm_types)) if ($alarm['time'] && in_array($alarm['action'], $this->alarm_types))

View file

@ -307,7 +307,7 @@ class tasklist_kolab_driver extends tasklist_driver
foreach ($folder->select(array(array('tags','!~','x-complete'))) as $record) { foreach ($folder->select(array(array('tags','!~','x-complete'))) as $record) {
$rec = $this->_to_rcube_task($record); $rec = $this->_to_rcube_task($record);
if ($rec['complete'] >= 1.0) // don't count complete tasks if ($this->is_complete($rec)) // don't count complete tasks
continue; continue;
$counts['all']++; $counts['all']++;
@ -603,7 +603,8 @@ class tasklist_kolab_driver extends tasklist_driver
'description' => $record['description'], 'description' => $record['description'],
'tags' => array_filter((array)$record['categories']), 'tags' => array_filter((array)$record['categories']),
'flagged' => $record['priority'] == 1, 'flagged' => $record['priority'] == 1,
'complete' => $record['status'] == 'COMPLETED' ? 1 : floatval($record['complete'] / 100), 'complete' => floatval($record['complete'] / 100),
'status' => $record['status'],
'parent_id' => $record['parent_id'], 'parent_id' => $record['parent_id'],
'recurrence' => $record['recurrence'], 'recurrence' => $record['recurrence'],
); );
@ -672,7 +673,7 @@ class tasklist_kolab_driver extends tasklist_driver
} }
$object['complete'] = $task['complete'] * 100; $object['complete'] = $task['complete'] * 100;
if ($task['complete'] == 1.0) if ($task['complete'] == 1.0 && empty($task['complete']))
$object['status'] = 'COMPLETED'; $object['status'] = 'COMPLETED';
if ($task['flagged']) if ($task['flagged'])

View file

@ -41,7 +41,7 @@
* 'categories' => 'Task category', * 'categories' => 'Task category',
* 'flagged' => 'Boolean value whether this record is flagged', * 'flagged' => 'Boolean value whether this record is flagged',
* 'complete' => 'Float value representing the completeness state (range 0..1)', * 'complete' => 'Float value representing the completeness state (range 0..1)',
* 'sensitivity' => 0|1|2, // Event sensitivity (0=public, 1=private, 2=confidential) * 'status' => 'Task status string according to (NEEDS-ACTION, IN-PROCESS, COMPLETED, CANCELLED) RFC 2445',
* 'valarms' => array( // List of reminders (new format), each represented as a hash array: * 'valarms' => array( // List of reminders (new format), each represented as a hash array:
* array( * array(
* 'trigger' => '-PT90M', // ISO 8601 period string prefixed with '+' or '-', or DateTime object * 'trigger' => '-PT90M', // ISO 8601 period string prefixed with '+' or '-', or DateTime object
@ -270,6 +270,17 @@ abstract class tasklist_driver
*/ */
public function get_attachment_body($id, $task) { } public function get_attachment_body($id, $task) { }
/**
* Helper method to determine whether the given task is considered "complete"
*
* @param array $task Hash array with event properties:
* @return boolean True if complete, False otherwiese
*/
public function is_complete($task)
{
return ($task['complete'] >= 1.0 && empty($task['status'])) || $task['status'] === 'COMPLETED';
}
/** /**
* List availabale categories * List availabale categories
* The default implementation reads them from config/user prefs * The default implementation reads them from config/user prefs

View file

@ -19,6 +19,11 @@ $labels['datetime'] = 'Due';
$labels['start'] = 'Start'; $labels['start'] = 'Start';
$labels['alarms'] = 'Reminder'; $labels['alarms'] = 'Reminder';
$labels['repeat'] = 'Repeat'; $labels['repeat'] = 'Repeat';
$labels['status'] = 'Status';
$labels['status-needs-action'] = 'Needs action';
$labels['status-in-process'] = 'In process';
$labels['status-completed'] = 'Completed';
$labels['status-cancelled'] = 'Cancelled';
$labels['all'] = 'All'; $labels['all'] = 'All';
$labels['flagged'] = 'Flagged'; $labels['flagged'] = 'Flagged';

View file

@ -141,6 +141,10 @@
<label><roundcube:label name="tasklist.complete" /></label> <label><roundcube:label name="tasklist.complete" /></label>
<span class="task-text"></span> <span class="task-text"></span>
</div> </div>
<div id="task-status" class="form-section">
<label><roundcube:label name="tasklist.status" /></label>
<span class="task-text"></span>
</div>
<div id="task-attachments" class="form-section"> <div id="task-attachments" class="form-section">
<label><roundcube:label name="attachments" /></label> <label><roundcube:label name="attachments" /></label>
<div class="task-text"></div> <div class="task-text"></div>

View file

@ -46,6 +46,10 @@
<input type="text" name="title" id="taskedit-completeness" size="3" tabindex="25" />&nbsp;% <input type="text" name="title" id="taskedit-completeness" size="3" tabindex="25" />&nbsp;%
<div id="taskedit-completeness-slider"></div> <div id="taskedit-completeness-slider"></div>
</div> </div>
<div class="form-section">
<label for="taskedit-status"><roundcube:label name="tasklist.status" /></label>
<roundcube:object name="plugin.status_select" id="taskedit-status" tabindex="26" />
</div>
<div class="form-section" id="tasklist-select"> <div class="form-section" id="tasklist-select">
<label for="taskedit-tasklist"><roundcube:label name="tasklist.list" /></label> <label for="taskedit-tasklist"><roundcube:label name="tasklist.list" /></label>
<roundcube:object name="plugin.tasklist_select" id="taskedit-tasklist" tabindex="26" /> <roundcube:object name="plugin.tasklist_select" id="taskedit-tasklist" tabindex="26" />

View file

@ -264,7 +264,7 @@ function rcube_tasklist_ui(settings)
if (rcmail.busy) if (rcmail.busy)
return false; return false;
rec.complete = e.target.checked ? 1 : 0; rec.status = e.target.checked ? 'COMPLETED' : (rec.complete == 1 ? 'NEEDS-ACTION' : '');
li.toggleClass('complete'); li.toggleClass('complete');
save_task(rec, 'edit'); save_task(rec, 'edit');
return true; return true;
@ -815,7 +815,7 @@ function rcube_tasklist_ui(settings)
var div = $('<div>').addClass('taskhead').html( var div = $('<div>').addClass('taskhead').html(
'<div class="progressbar"><div class="progressvalue" style="width:' + (rec.complete * 100) + '%"></div></div>' + '<div class="progressbar"><div class="progressvalue" style="width:' + (rec.complete * 100) + '%"></div></div>' +
'<input type="checkbox" name="completed[]" value="1" class="complete" ' + (rec.complete == 1.0 ? 'checked="checked" ' : '') + '/>' + '<input type="checkbox" name="completed[]" value="1" class="complete" ' + (is_complete(rec) ? 'checked="checked" ' : '') + '/>' +
'<span class="flagged"></span>' + '<span class="flagged"></span>' +
'<span class="title">' + text2html(Q(rec.title)) + '</span>' + '<span class="title">' + text2html(Q(rec.title)) + '</span>' +
'<span class="tags">' + tags_html + '</span>' + '<span class="tags">' + tags_html + '</span>' +
@ -835,7 +835,7 @@ function rcube_tasklist_ui(settings)
revertDuration: 300 revertDuration: 300
}); });
if (rec.complete == 1.0) if (is_complete(rec))
div.addClass('complete'); div.addClass('complete');
if (rec.flagged) if (rec.flagged)
div.addClass('flagged'); div.addClass('flagged');
@ -951,12 +951,20 @@ function rcube_tasklist_ui(settings)
*/ */
function task_cmp(a, b) function task_cmp(a, b)
{ {
var d = Math.floor(a.complete) - Math.floor(b.complete); var d = is_complete(a) - is_complete(b);
if (!d) d = (b._hasdate-0) - (a._hasdate-0); if (!d) d = (b._hasdate-0) - (a._hasdate-0);
if (!d) d = (a.datetime||99999999999) - (b.datetime||99999999999); if (!d) d = (a.datetime||99999999999) - (b.datetime||99999999999);
return d; return d;
} }
/**
* Determine whether the given task should be displayed as "complete"
*/
function is_complete(rec)
{
return ((rec.complete == 1.0 && !rec.status) || rec.status === 'COMPLETED') ? 1 : 0;
}
/** /**
* *
*/ */
@ -1144,6 +1152,7 @@ function rcube_tasklist_ui(settings)
$('#task-starttime').html(Q(rec.starttime || '')); $('#task-starttime').html(Q(rec.starttime || ''));
$('#task-alarm')[(rec.alarms_text ? 'show' : 'hide')]().children('.task-text').html(Q(rec.alarms_text)); $('#task-alarm')[(rec.alarms_text ? 'show' : 'hide')]().children('.task-text').html(Q(rec.alarms_text));
$('#task-completeness .task-text').html(((rec.complete || 0) * 100) + '%'); $('#task-completeness .task-text').html(((rec.complete || 0) * 100) + '%');
$('#task-status')[(rec.status ? 'show' : 'hide')]().children('.task-text').html(rcmail.gettext('status-'+String(rec.status).toLowerCase(),'tasklist'));
$('#task-list .task-text').html(Q(me.tasklists[rec.list] ? me.tasklists[rec.list].name : '')); $('#task-list .task-text').html(Q(me.tasklists[rec.list] ? me.tasklists[rec.list].name : ''));
var itags = get_inherited_tags(rec); var itags = get_inherited_tags(rec);
@ -1257,6 +1266,7 @@ function rcube_tasklist_ui(settings)
var recstarttime = $('#taskedit-starttime').val(rec.starttime || ''); var recstarttime = $('#taskedit-starttime').val(rec.starttime || '');
var complete = $('#taskedit-completeness').val((rec.complete || 0) * 100); var complete = $('#taskedit-completeness').val((rec.complete || 0) * 100);
completeness_slider.slider('value', complete.val()); completeness_slider.slider('value', complete.val());
var taskstatus = $('#taskedit-status').val(rec.status || '');
var tasklist = $('#taskedit-tasklist').val(rec.list || me.selected_list).prop('disabled', rec.parent_id ? true : false); var tasklist = $('#taskedit-tasklist').val(rec.list || me.selected_list).prop('disabled', rec.parent_id ? true : false);
// tag-edit line // tag-edit line
@ -1308,7 +1318,7 @@ function rcube_tasklist_ui(settings)
var buttons = {}; var buttons = {};
buttons[rcmail.gettext('save', 'tasklist')] = function() { buttons[rcmail.gettext('save', 'tasklist')] = function() {
// copy form field contents into task object to save // copy form field contents into task object to save
$.each({ title:title, description:description, date:recdate, time:rectime, startdate:recstartdate, starttime:recstarttime, list:tasklist }, function(key,input){ $.each({ title:title, description:description, date:recdate, time:rectime, startdate:recstartdate, starttime:recstarttime, status:taskstatus, list:tasklist }, function(key,input){
me.selected_task[key] = input.val(); me.selected_task[key] = input.val();
}); });
me.selected_task.tags = []; me.selected_task.tags = [];

View file

@ -214,7 +214,7 @@ class tasklist extends rcube_plugin
$child = array('id' => $cid, 'list' => $rec['list'], '_fromlist' => $rec['_fromlist']); $child = array('id' => $cid, 'list' => $rec['list'], '_fromlist' => $rec['_fromlist']);
if ($this->driver->move_task($child)) { if ($this->driver->move_task($child)) {
$r = $this->driver->get_task($child); $r = $this->driver->get_task($child);
if ((bool)($filter & self::FILTER_MASK_COMPLETE) == ($r['complete'] == 1.0)) { if ((bool)($filter & self::FILTER_MASK_COMPLETE) == $this->driver->is_complete($r)) {
$refresh[] = $r; $refresh[] = $r;
} }
} }
@ -237,7 +237,7 @@ class tasklist extends rcube_plugin
$child['id'] = $cid; $child['id'] = $cid;
if ($this->driver->move_task($child)) { if ($this->driver->move_task($child)) {
$r = $this->driver->get_task($child); $r = $this->driver->get_task($child);
if ((bool)($filter & self::FILTER_MASK_COMPLETE) == ($r['complete'] == 1.0)) { if ((bool)($filter & self::FILTER_MASK_COMPLETE) == $this->driver->is_complete($r)) {
$refresh[] = $r; $refresh[] = $r;
} }
} }
@ -524,7 +524,7 @@ class tasklist extends rcube_plugin
private function handle_recurrence(&$rec, $old) private function handle_recurrence(&$rec, $old)
{ {
$clone = null; $clone = null;
if ($rec['complete'] == 1.0 && $old && $old['complete'] < 1.0 && is_array($rec['recurrence'])) { if ($this->driver->is_complete($rec) && $old && $this->driver->is_complete($old) && is_array($rec['recurrence'])) {
$engine = libcalendaring::get_recurrence(); $engine = libcalendaring::get_recurrence();
$rrule = $rec['recurrence']; $rrule = $rec['recurrence'];
$updates = array(); $updates = array();
@ -569,6 +569,7 @@ class tasklist extends rcube_plugin
// update the task but unset completed flag // update the task but unset completed flag
$rec = array_merge($rec, $updates); $rec = array_merge($rec, $updates);
$rec['complete'] = $old['complete']; $rec['complete'] = $old['complete'];
$rec['satus'] = $old['satus'];
} }
} }
@ -718,7 +719,7 @@ class tasklist extends rcube_plugin
$tags = array_merge($tags, (array)$rec['tags']); $tags = array_merge($tags, (array)$rec['tags']);
// apply filter; don't trust the driver on this :-) // apply filter; don't trust the driver on this :-)
if ((!$f && $rec['complete'] < 1.0) || ($rec['mask'] & $f)) if ((!$f && !$this->driver->is_complete($rec)) || ($rec['mask'] & $f))
$data[] = $rec; $data[] = $rec;
} }
@ -845,7 +846,7 @@ class tasklist extends rcube_plugin
if ($rec['flagged']) if ($rec['flagged'])
$mask |= self::FILTER_MASK_FLAGGED; $mask |= self::FILTER_MASK_FLAGGED;
if ($rec['complete'] == 1.0) if ($this->driver->is_complete($rec))
$mask |= self::FILTER_MASK_COMPLETE; $mask |= self::FILTER_MASK_COMPLETE;
if (empty($rec['date'])) if (empty($rec['date']))

View file

@ -67,7 +67,7 @@ class tasklist_ui
{ {
$this->plugin->register_handler('plugin.tasklists', array($this, 'tasklists')); $this->plugin->register_handler('plugin.tasklists', array($this, 'tasklists'));
$this->plugin->register_handler('plugin.tasklist_select', array($this, 'tasklist_select')); $this->plugin->register_handler('plugin.tasklist_select', array($this, 'tasklist_select'));
$this->plugin->register_handler('plugin.category_select', array($this, 'category_select')); $this->plugin->register_handler('plugin.status_select', array($this, 'status_select'));
$this->plugin->register_handler('plugin.searchform', array($this->rc->output, 'search_form')); $this->plugin->register_handler('plugin.searchform', array($this->rc->output, 'search_form'));
$this->plugin->register_handler('plugin.quickaddform', array($this, 'quickadd_form')); $this->plugin->register_handler('plugin.quickaddform', array($this, 'quickadd_form'));
$this->plugin->register_handler('plugin.tasks', array($this, 'tasks_resultview')); $this->plugin->register_handler('plugin.tasks', array($this, 'tasks_resultview'));
@ -129,6 +129,21 @@ class tasklist_ui
return html::tag('ul', $attrib, $li, html::$common_attrib); return html::tag('ul', $attrib, $li, html::$common_attrib);
} }
/**
* Render HTML form for task status selector
*/
function status_select($attrib = array())
{
$attrib['name'] = 'status';
$select = new html_select($attrib);
$select->add('---', '');
$select->add($this->plugin->gettext('status-needs-action'), 'NEEDS-ACTION');
$select->add($this->plugin->gettext('status-in-process'), 'IN-PROCESS');
$select->add($this->plugin->gettext('status-completed'), 'COMPLETED');
$select->add($this->plugin->gettext('status-cancelled'), 'CANCELLED');
return $select->show(null);
}
/** /**
* Render a HTML select box for list selection * Render a HTML select box for list selection