Make task alarm properties available in the UI (no triggering yet); use globally unique identifiers for form elements
This commit is contained in:
parent
0fc3c6f288
commit
627f970dea
9 changed files with 288 additions and 84 deletions
|
@ -26,6 +26,7 @@ class tasklist_database_driver extends tasklist_driver
|
|||
{
|
||||
public $undelete = true; // yes, we can
|
||||
public $sortable = false;
|
||||
public $alarm_types = array('DISPLAY','EMAIL');
|
||||
|
||||
private $rc;
|
||||
private $plugin;
|
||||
|
@ -367,14 +368,15 @@ class tasklist_database_driver extends tasklist_driver
|
|||
if (!$this->lists[$list_id] || $this->lists[$list_id]['readonly'])
|
||||
return false;
|
||||
|
||||
foreach (array('parent_id', 'date', 'time') as $col) {
|
||||
foreach (array('parent_id', 'date', 'time', 'startdate', 'starttime', 'alarms') as $col) {
|
||||
if (empty($prop[$col]))
|
||||
$prop[$col] = null;
|
||||
}
|
||||
|
||||
$notify_at = $this->_get_notification($prop);
|
||||
$result = $this->rc->db->query(sprintf(
|
||||
"INSERT INTO " . $this->db_tasks . "
|
||||
(tasklist_id, uid, parent_id, created, changed, title, date, time, description, tags)
|
||||
(tasklist_id, uid, parent_id, created, changed, title, date, time, starttime, starttime, description, tags, alarms, notify)
|
||||
VALUES (?, ?, ?, %s, %s, ?, ?, ?, ?, ?)",
|
||||
$this->rc->db->now(),
|
||||
$this->rc->db->now()
|
||||
|
@ -385,8 +387,12 @@ class tasklist_database_driver extends tasklist_driver
|
|||
$prop['title'],
|
||||
$prop['date'],
|
||||
$prop['time'],
|
||||
$prop['startdate'],
|
||||
$prop['starttime'],
|
||||
strval($prop['description']),
|
||||
join(',', (array)$prop['tags'])
|
||||
join(',', (array)$prop['tags']),
|
||||
$prop['alarms'],
|
||||
$notify_at
|
||||
);
|
||||
|
||||
if ($result)
|
||||
|
@ -409,13 +415,18 @@ class tasklist_database_driver extends tasklist_driver
|
|||
if (isset($prop[$col]))
|
||||
$sql_set[] = $this->rc->db->quote_identifier($col) . '=' . $this->rc->db->quote($prop[$col]);
|
||||
}
|
||||
foreach (array('parent_id', 'date', 'time', 'startdate', 'starttime') as $col) {
|
||||
foreach (array('parent_id', 'date', 'time', 'startdate', 'starttime', 'alarms') as $col) {
|
||||
if (isset($prop[$col]))
|
||||
$sql_set[] = $this->rc->db->quote_identifier($col) . '=' . (empty($prop[$col]) ? 'NULL' : $this->rc->db->quote($prop[$col]));
|
||||
}
|
||||
if (isset($prop['tags']))
|
||||
$sql_set[] = $this->rc->db->quote_identifier('tags') . '=' . $this->rc->db->quote(join(',', (array)$prop['tags']));
|
||||
|
||||
if (isset($prop['date']) || isset($prop['time']) || isset($prop['alarms'])) {
|
||||
$notify_at = $this->_get_notification($prop);
|
||||
$sql_set[] = $this->rc->db->quote_identifier('notify') . '=' . (empty($notify_at) ? 'NULL' : $this->rc->db->quote($notify_at));
|
||||
}
|
||||
|
||||
// moved from another list
|
||||
if ($prop['_fromlist'] && ($newlist = $prop['list'])) {
|
||||
$sql_set[] = 'tasklist_id=' . $this->rc->db->quote($newlist);
|
||||
|
@ -495,4 +506,31 @@ class tasklist_database_driver extends tasklist_driver
|
|||
return $this->rc->db->affected_rows($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute absolute time to notify the user
|
||||
*/
|
||||
private function _get_notification($task)
|
||||
{
|
||||
// fake object properties to suit the expectations of calendar::get_next_alarm()
|
||||
// TODO: move all that to libcalendaring plugin
|
||||
if ($task['date'])
|
||||
$task['start'] = new DateTime($task['date'] . ' ' . ($task['time'] ?: '23:00'), $this->plugin->timezone);
|
||||
if ($task['startdate'])
|
||||
$task['end'] = new DateTime($task['startdate'] . ' ' . ($task['starttime'] ?: '06:00'), $this->plugin->timezone);
|
||||
else
|
||||
$task['end'] = $tast['start'];
|
||||
|
||||
if (!$task['start'])
|
||||
$task['end'] = $task['start'];
|
||||
|
||||
if ($task['alarms'] && $task['start'] > new DateTime() || strpos($task['alarms'], '@') !== false) {
|
||||
$alarm = calendar::get_next_alarm($task);
|
||||
|
||||
if ($alarm['time'] && $alarm['action'] == 'DISPLAY')
|
||||
return date('Y-m-d H:i:s', $alarm['time']);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -347,6 +347,10 @@ class tasklist_kolab_driver extends tasklist_driver
|
|||
$task['changed'] = $record['dtstamp'];
|
||||
}
|
||||
|
||||
if ($record['alarms']) {
|
||||
$task['alarms'] = $record['alarms'];
|
||||
}
|
||||
|
||||
if (!empty($record['_attachments'])) {
|
||||
foreach ($record['_attachments'] as $key => $attachment) {
|
||||
if ($attachment !== false) {
|
||||
|
|
|
@ -41,9 +41,9 @@ $labels['tabrecurrence'] = 'Recurrence';
|
|||
$labels['tabattachments'] = 'Attachments';
|
||||
$labels['tabsharing'] = 'Sharing';
|
||||
|
||||
$labels['editlist'] = 'Edit resource';
|
||||
$labels['createlist'] = 'Add resource';
|
||||
$labels['listactions'] = 'Resource options...';
|
||||
$labels['editlist'] = 'Edit list';
|
||||
$labels['createlist'] = 'Add list';
|
||||
$labels['listactions'] = 'List options...';
|
||||
$labels['listname'] = 'Name';
|
||||
$labels['showalarms'] = 'Show alarms';
|
||||
$labels['import'] = 'Import';
|
||||
|
|
|
@ -616,7 +616,7 @@ label.block {
|
|||
margin-bottom: 0.3em;
|
||||
}
|
||||
|
||||
#edit-completeness-slider {
|
||||
#taskedit-completeness-slider {
|
||||
display: inline-block;
|
||||
margin-left: 2em;
|
||||
width: 30em;
|
||||
|
@ -624,7 +624,7 @@ label.block {
|
|||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
#edit-tagline {
|
||||
#taskedit-tagline {
|
||||
width: 97%;
|
||||
}
|
||||
|
||||
|
|
|
@ -112,6 +112,10 @@
|
|||
<span class="task-text"></span>
|
||||
<span id="task-starttime"></span>
|
||||
</div>
|
||||
<div id="task-alarm" class="form-section">
|
||||
<label><roundcube:label name="calendar.alarms" /></label>
|
||||
<span class="task-text"></span>
|
||||
</div>
|
||||
<div id="task-list" class="form-section">
|
||||
<label><roundcube:label name="tasklist.list" /></label>
|
||||
<span class="task-text"></span>
|
||||
|
|
|
@ -6,48 +6,52 @@
|
|||
<!-- basic info -->
|
||||
<div id="taskedit-tab-1">
|
||||
<div class="form-section">
|
||||
<label for="edit-title"><roundcube:label name="tasklist.title" /></label>
|
||||
<label for="taskedit-title"><roundcube:label name="tasklist.title" /></label>
|
||||
<br />
|
||||
<input type="text" class="text" name="title" id="edit-title" size="60" tabindex="1" />
|
||||
<input type="text" class="text" name="title" id="taskedit-title" size="60" tabindex="1" />
|
||||
</div>
|
||||
<div class="form-section">
|
||||
<label for="edit-description"><roundcube:label name="tasklist.description" /></label>
|
||||
<label for="taskedit-description"><roundcube:label name="tasklist.description" /></label>
|
||||
<br />
|
||||
<textarea name="description" id="edit-description" class="text" rows="5" cols="60" tabindex="2"></textarea>
|
||||
<textarea name="description" id="taskedit-description" class="text" rows="5" cols="60" tabindex="2"></textarea>
|
||||
</div>
|
||||
<div class="form-section">
|
||||
<label for="edit-tags"><roundcube:label name="tasklist.tags" /></label>
|
||||
<roundcube:object name="plugin.tags_editline" id="edit-tagline" class="tagedit" tabindex="3" />
|
||||
<label for="taskedit-tags"><roundcube:label name="tasklist.tags" /></label>
|
||||
<roundcube:object name="plugin.tags_editline" id="taskedit-tagline" class="tagedit" tabindex="3" />
|
||||
</div>
|
||||
<div class="form-section">
|
||||
<label for="edit-date"><roundcube:label name="tasklist.datetime" /></label>
|
||||
<input type="text" name="date" size="10" id="edit-date" tabindex="20" />
|
||||
<input type="text" name="time" size="6" id="edit-time" tabindex="21" />
|
||||
<a href="#nodate" style="margin-left:1em" class="edit-nodate" rel="#edit-date,#edit-time"><roundcube:label name="tasklist.nodate" /></a>
|
||||
<label for="taskedit-date"><roundcube:label name="tasklist.datetime" /></label>
|
||||
<input type="text" name="date" size="10" id="taskedit-date" tabindex="20" />
|
||||
<input type="text" name="time" size="6" id="taskedit-time" tabindex="21" />
|
||||
<a href="#nodate" style="margin-left:1em" class="edit-nodate" rel="#taskedit-date,#taskedit-time"><roundcube:label name="tasklist.nodate" /></a>
|
||||
</div>
|
||||
<div class="form-section">
|
||||
<label for="edit-startdate"><roundcube:label name="tasklist.start" /></label>
|
||||
<input type="text" name="startdate" size="10" id="edit-startdate" tabindex="23" />
|
||||
<input type="text" name="starttime" size="6" id="edit-starttime" tabindex="24" />
|
||||
<a href="#nodate" style="margin-left:1em" class="edit-nodate" rel="#edit-startdate,#edit-starttime"><roundcube:label name="tasklist.nodate" /></a>
|
||||
<label for="taskedit-startdate"><roundcube:label name="tasklist.start" /></label>
|
||||
<input type="text" name="startdate" size="10" id="taskedit-startdate" tabindex="23" />
|
||||
<input type="text" name="starttime" size="6" id="taskedit-starttime" tabindex="24" />
|
||||
<a href="#nodate" style="margin-left:1em" class="edit-nodate" rel="#taskedit-startdate,#taskedit-starttime"><roundcube:label name="tasklist.nodate" /></a>
|
||||
</div>
|
||||
<div class="form-section" id="taskedit-alarms">
|
||||
<label for="taskedit-alarm"><roundcube:label name="calendar.alarms" /></label>
|
||||
<roundcube:object name="plugin.alarm_select" />
|
||||
</div>
|
||||
<div class="form-section">
|
||||
<label for="edit-completeness"><roundcube:label name="tasklist.complete" /></label>
|
||||
<input type="text" name="title" id="edit-completeness" size="3" tabindex="25" /> %
|
||||
<div id="edit-completeness-slider"></div>
|
||||
<label for="taskedit-completeness"><roundcube:label name="tasklist.complete" /></label>
|
||||
<input type="text" name="title" id="taskedit-completeness" size="3" tabindex="25" /> %
|
||||
<div id="taskedit-completeness-slider"></div>
|
||||
</div>
|
||||
<div class="form-section" id="tasklist-select">
|
||||
<label for="edit-tasklist"><roundcube:label name="tasklist.list" /></label>
|
||||
<roundcube:object name="plugin.tasklist_select" id="edit-tasklist" tabindex="26" />
|
||||
<label for="taskedit-tasklist"><roundcube:label name="tasklist.list" /></label>
|
||||
<roundcube:object name="plugin.tasklist_select" id="taskedit-tasklist" tabindex="26" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- attachments list (with upload form) -->
|
||||
<div id="taskedit-tab-2">
|
||||
<div id="taskedit-attachments">
|
||||
<roundcube:object name="plugin.attachments_list" id="attachment-list" class="attachmentslist" />
|
||||
<roundcube:object name="plugin.attachments_list" id="taskedit-attachment-list" class="attachmentslist" />
|
||||
</div>
|
||||
<div id="taskedit-attachments-form">
|
||||
<roundcube:object name="plugin.attachments_form" id="tasklist-attachment-form" attachmentFieldSize="30" />
|
||||
<roundcube:object name="plugin.attachments_form" id="taskedit-attachment-form" attachmentFieldSize="30" />
|
||||
</div>
|
||||
<roundcube:object name="plugin.filedroparea" id="taskedit-tab-2" />
|
||||
</div>
|
||||
|
|
|
@ -60,6 +60,7 @@ function rcube_tasklist_ui(settings)
|
|||
var draghelper;
|
||||
var search_request;
|
||||
var search_query;
|
||||
var completeness_slider;
|
||||
var me = this;
|
||||
|
||||
// general datepicker settings
|
||||
|
@ -93,22 +94,6 @@ function rcube_tasklist_ui(settings)
|
|||
this.unlock_saving = unlock_saving;
|
||||
|
||||
|
||||
/* basic initializations */
|
||||
|
||||
$('#taskedit').tabs();
|
||||
|
||||
var completeness_slider = $('#edit-completeness-slider').slider({
|
||||
range: 'min',
|
||||
slide: function(e, ui){
|
||||
var v = completeness_slider.slider('value');
|
||||
if (v >= 98) v = 100;
|
||||
if (v <= 2) v = 0;
|
||||
$('#edit-completeness').val(v);
|
||||
}
|
||||
});
|
||||
$('#edit-completeness').change(function(e){ completeness_slider.slider('value', parseInt(this.value)) });
|
||||
|
||||
|
||||
/**
|
||||
* initialize the tasks UI
|
||||
*/
|
||||
|
@ -312,6 +297,45 @@ function rcube_tasklist_ui(settings)
|
|||
}, datepicker_settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* initialize task edit form elements
|
||||
*/
|
||||
function init_taskedit()
|
||||
{
|
||||
$('#taskedit').tabs();
|
||||
|
||||
completeness_slider = $('#taskedit-completeness-slider').slider({
|
||||
range: 'min',
|
||||
slide: function(e, ui){
|
||||
var v = completeness_slider.slider('value');
|
||||
if (v >= 98) v = 100;
|
||||
if (v <= 2) v = 0;
|
||||
$('#taskedit-completeness').val(v);
|
||||
}
|
||||
});
|
||||
$('#taskedit-completeness').change(function(e){
|
||||
completeness_slider.slider('value', parseInt(this.value))
|
||||
});
|
||||
|
||||
// register events on alarm fields
|
||||
$('#taskedit select.edit-alarm-type').change(function(){
|
||||
$(this).parent().find('span.edit-alarm-values')[(this.selectedIndex>0?'show':'hide')]();
|
||||
});
|
||||
$('#taskedit select.edit-alarm-offset').change(function(){
|
||||
var mode = $(this).val() == '@' ? 'show' : 'hide';
|
||||
$(this).parent().find('.edit-alarm-date, .edit-alarm-time')[mode]();
|
||||
$(this).parent().find('.edit-alarm-value').prop('disabled', mode == 'show');
|
||||
});
|
||||
|
||||
$('#taskedit-date, #taskedit-startdate, #taskedit .edit-alarm-date').datepicker(datepicker_settings);
|
||||
|
||||
$('a.edit-nodate').click(function(){
|
||||
var sel = $(this).attr('rel');
|
||||
if (sel) $(sel).val('');
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Request counts from the server
|
||||
*/
|
||||
|
@ -725,6 +749,7 @@ function rcube_tasklist_ui(settings)
|
|||
$('#task-time').html(Q(rec.time || ''));
|
||||
$('#task-start')[(rec.startdate ? 'show' : 'hide')]().children('.task-text').html(Q(rec.startdate || ''));
|
||||
$('#task-starttime').html(Q(rec.starttime || ''));
|
||||
$('#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-list .task-text').html(Q(me.tasklists[rec.list] ? me.tasklists[rec.list].name : ''));
|
||||
|
||||
|
@ -793,16 +818,19 @@ function rcube_tasklist_ui(settings)
|
|||
if (!me.selected_task.id)
|
||||
me.selected_task.id = -(++idcount);
|
||||
|
||||
// reset dialog first
|
||||
$('#taskeditform').get(0).reset();
|
||||
|
||||
// fill form data
|
||||
var title = $('#edit-title').val(rec.title || '');
|
||||
var description = $('#edit-description').val(rec.description || '');
|
||||
var recdate = $('#edit-date').val(rec.date || '').datepicker(datepicker_settings);
|
||||
var rectime = $('#edit-time').val(rec.time || '');
|
||||
var recstartdate = $('#edit-startdate').val(rec.startdate || '').datepicker(datepicker_settings);
|
||||
var recstarttime = $('#edit-starttime').val(rec.starttime || '');
|
||||
var complete = $('#edit-completeness').val((rec.complete || 0) * 100);
|
||||
var title = $('#taskedit-title').val(rec.title || '');
|
||||
var description = $('#taskedit-description').val(rec.description || '');
|
||||
var recdate = $('#taskedit-date').val(rec.date || '');
|
||||
var rectime = $('#taskedit-time').val(rec.time || '');
|
||||
var recstartdate = $('#taskedit-startdate').val(rec.startdate || '');
|
||||
var recstarttime = $('#taskedit-starttime').val(rec.starttime || '');
|
||||
var complete = $('#taskedit-completeness').val((rec.complete || 0) * 100);
|
||||
completeness_slider.slider('value', complete.val());
|
||||
var tasklist = $('#edit-tasklist').val(rec.list || 0).prop('disabled', rec.parent_id ? true : false);
|
||||
var tasklist = $('#taskedit-tasklist').val(rec.list || 0).prop('disabled', rec.parent_id ? true : false);
|
||||
|
||||
// tag-edit line
|
||||
var tagline = $(rcmail.gui_objects.edittagline).empty();
|
||||
|
@ -823,11 +851,32 @@ function rcube_tasklist_ui(settings)
|
|||
texts: { removeLinkTitle: rcmail.gettext('removetag', 'tasklist') }
|
||||
});
|
||||
|
||||
$('a.edit-nodate').unbind('click').click(function(){
|
||||
var sel = $(this).attr('rel');
|
||||
if (sel) $(sel).val('');
|
||||
return false;
|
||||
})
|
||||
// set alarm(s)
|
||||
if (rec.alarms) {
|
||||
if (typeof rec.alarms == 'string')
|
||||
rec.alarms = rec.alarms.split(';');
|
||||
|
||||
for (var alarm, i=0; i < rec.alarms.length; i++) {
|
||||
alarm = String(rec.alarms[i]).split(':');
|
||||
if (!alarm[1] && alarm[0]) alarm[1] = 'DISPLAY';
|
||||
$('#taskedit select.edit-alarm-type').val(alarm[1]);
|
||||
|
||||
if (alarm[0].match(/@(\d+)/)) {
|
||||
var ondate = fromunixtime(parseInt(RegExp.$1));
|
||||
$('#taskedit select.edit-alarm-offset').val('@');
|
||||
$('#taskedit input.edit-alarm-date').val(format_datetime(ondate, 1));
|
||||
$('#taskedit input.edit-alarm-time').val(format_datetime(ondate, 2));
|
||||
}
|
||||
else if (alarm[0].match(/([-+])(\d+)([MHD])/)) {
|
||||
$('#taskedit input.edit-alarm-value').val(RegExp.$2);
|
||||
$('#taskedit select.edit-alarm-offset').val(''+RegExp.$1+RegExp.$3);
|
||||
}
|
||||
|
||||
break; // only one alarm is currently supported
|
||||
}
|
||||
}
|
||||
// set correct visibility by triggering onchange handlers
|
||||
$('#taskedit select.edit-alarm-type, #taskedit select.edit-alarm-offset').change();
|
||||
|
||||
// attachments
|
||||
rcmail.enable_command('remove-attachment', !list.readonly);
|
||||
|
@ -874,6 +923,16 @@ function rcube_tasklist_ui(settings)
|
|||
me.selected_task.tags.push(elem.value);
|
||||
});
|
||||
|
||||
// serialize alarm settings
|
||||
var alarm = $('#taskedit select.edit-alarm-type').val();
|
||||
if (alarm) {
|
||||
var val, offset = $('#taskedit select.edit-alarm-offset').val();
|
||||
if (offset == '@')
|
||||
me.selected_task.alarms = '@' + date2unixtime(parse_datetime($('#taskedit input.edit-alarm-time').val(), $('#taskedit input.edit-alarm-date').val())) + ':' + alarm;
|
||||
else if ((val = parseInt($('#taskedit input.edit-alarm-value').val())) && !isNaN(val) && val >= 0)
|
||||
me.selected_task.alarms = offset[0] + val + offset[1] + ':' + alarm;
|
||||
}
|
||||
|
||||
// uploaded attachments list
|
||||
for (var i in rcmail.env.attachments) {
|
||||
if (i.match(/^rcmfile(.+)/))
|
||||
|
@ -1069,9 +1128,9 @@ function rcube_tasklist_ui(settings)
|
|||
list = { name:'', editable:true, showalarms:true };
|
||||
|
||||
// fill edit form
|
||||
var name = $('#edit-tasklistame').prop('disabled', !list.editable).val(list.editname || list.name),
|
||||
alarms = $('#edit-showalarms').prop('checked', list.showalarms).get(0),
|
||||
parent = $('#edit-parentfolder').val(list.parentfolder);
|
||||
var name = $('#taskedit-tasklistame').prop('disabled', !list.editable).val(list.editname || list.name),
|
||||
alarms = $('#taskedit-showalarms').prop('checked', list.showalarms).get(0),
|
||||
parent = $('#taskedit-parentfolder').val(list.parentfolder);
|
||||
|
||||
// dialog buttons
|
||||
var buttons = {};
|
||||
|
@ -1351,6 +1410,73 @@ function rcube_tasklist_ui(settings)
|
|||
})
|
||||
.data('id', id);
|
||||
}
|
||||
|
||||
|
||||
/**** calendaring utility functions *****/
|
||||
/* TO BE MOVED TO libcalendaring plugin */
|
||||
|
||||
var gmt_offset = (new Date().getTimezoneOffset() / -60) - (rcmail.env.calendar_settings.timezone || 0) - (rcmail.env.calendar_settings.dst || 0);
|
||||
var client_timezone = new Date().getTimezoneOffset();
|
||||
|
||||
/**
|
||||
* from time and date strings to a real date object
|
||||
*/
|
||||
function parse_datetime(time, date)
|
||||
{
|
||||
// we use the utility function from datepicker to parse dates
|
||||
var date = date ? $.datepicker.parseDate(datepicker_settings.dateFormat, date, datepicker_settings) : new Date();
|
||||
|
||||
var time_arr = time.replace(/\s*[ap][.m]*/i, '').replace(/0([0-9])/g, '$1').split(/[:.]/);
|
||||
if (!isNaN(time_arr[0])) {
|
||||
date.setHours(time_arr[0]);
|
||||
if (time.match(/p[.m]*/i) && date.getHours() < 12)
|
||||
date.setHours(parseInt(time_arr[0]) + 12);
|
||||
else if (time.match(/a[.m]*/i) && date.getHours() == 12)
|
||||
date.setHours(0);
|
||||
}
|
||||
if (!isNaN(time_arr[1]))
|
||||
date.setMinutes(time_arr[1]);
|
||||
|
||||
return date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the given date object according to user's prefs
|
||||
*/
|
||||
function format_datetime(date, mode)
|
||||
{
|
||||
var format =
|
||||
mode == 2 ? rcmail.env.calendar_settings['time_format'] :
|
||||
(mode == 1 ? rcmail.env.calendar_settings['date_format'] :
|
||||
rcmail.env.calendar_settings['date_format'] + ' '+ rcmail.env.calendar_settings['time_format']);
|
||||
|
||||
return $.fullCalendar.formatDate(date, format);
|
||||
}
|
||||
|
||||
/**
|
||||
* convert the given Date object into a unix timestamp respecting browser's and user's timezone settings
|
||||
*/
|
||||
function date2unixtime(date)
|
||||
{
|
||||
var dst_offset = (client_timezone - date.getTimezoneOffset()) * 60; // adjust DST offset
|
||||
return Math.round(date.getTime()/1000 + gmt_offset * 3600 + dst_offset);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function fromunixtime(ts)
|
||||
{
|
||||
ts -= gmt_offset * 3600;
|
||||
var date = new Date(ts * 1000),
|
||||
dst_offset = (client_timezone - date.getTimezoneOffset()) * 60;
|
||||
if (dst_offset) // adjust DST offset
|
||||
date.setTime((ts + 3600) * 1000);
|
||||
return date;
|
||||
}
|
||||
|
||||
// init dialog by default
|
||||
init_taskedit();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -301,6 +301,10 @@ class tasklist extends rcube_plugin
|
|||
}
|
||||
}
|
||||
|
||||
// alarms cannot work without a date
|
||||
if ($rec['alarms'] && !$rec['date'] && !$rec['startdate'] && strpos($task['alarms'], '@') === false)
|
||||
$rec['alarms'] = '';
|
||||
|
||||
$attachments = array();
|
||||
$taskid = $rec['id'];
|
||||
if (is_array($_SESSION['tasklist_session']) && $_SESSION['tasklist_session']['id'] == $taskid) {
|
||||
|
@ -501,6 +505,9 @@ class tasklist extends rcube_plugin
|
|||
}
|
||||
}
|
||||
|
||||
if ($rec['alarms'])
|
||||
$rec['alarms_text'] = calendar::alarms_text($rec['alarms']);
|
||||
|
||||
foreach ((array)$rec['attachments'] as $k => $attachment) {
|
||||
$rec['attachments'][$k]['classname'] = rcmail_filetype2classname($attachment['mimetype'], $attachment['name']);
|
||||
}
|
||||
|
|
|
@ -81,6 +81,7 @@ class tasklist_ui
|
|||
$this->plugin->register_handler('plugin.tasks', array($this, 'tasks_resultview'));
|
||||
$this->plugin->register_handler('plugin.tagslist', array($this, 'tagslist'));
|
||||
$this->plugin->register_handler('plugin.tags_editline', array($this, 'tags_editline'));
|
||||
$this->plugin->register_handler('plugin.alarm_select', array($this, 'alarm_select'));
|
||||
$this->plugin->register_handler('plugin.attachments_form', array($this, 'attachments_form'));
|
||||
$this->plugin->register_handler('plugin.attachments_list', array($this, 'attachments_list'));
|
||||
$this->plugin->register_handler('plugin.filedroparea', array($this, 'file_drop_area'));
|
||||
|
@ -156,22 +157,22 @@ class tasklist_ui
|
|||
{
|
||||
$fields = array(
|
||||
'name' => array(
|
||||
'id' => 'edit-tasklistame',
|
||||
'id' => 'taskedit-tasklistame',
|
||||
'label' => $this->plugin->gettext('listname'),
|
||||
'value' => html::tag('input', array('id' => 'edit-tasklistame', 'name' => 'name', 'type' => 'text', 'class' => 'text', 'size' => 40)),
|
||||
'value' => html::tag('input', array('id' => 'taskedit-tasklistame', 'name' => 'name', 'type' => 'text', 'class' => 'text', 'size' => 40)),
|
||||
),
|
||||
/*
|
||||
'color' => array(
|
||||
'id' => 'edit-color',
|
||||
'id' => 'taskedit-color',
|
||||
'label' => $this->plugin->gettext('color'),
|
||||
'value' => html::tag('input', array('id' => 'edit-color', 'name' => 'color', 'type' => 'text', 'class' => 'text colorpicker', 'size' => 6)),
|
||||
),
|
||||
'showalarms' => array(
|
||||
'id' => 'edit-showalarms',
|
||||
'label' => $this->plugin->gettext('showalarms'),
|
||||
'value' => html::tag('input', array('id' => 'edit-showalarms', 'name' => 'color', 'type' => 'checkbox')),
|
||||
'value' => html::tag('input', array('id' => 'taskedit-color', 'name' => 'color', 'type' => 'text', 'class' => 'text colorpicker', 'size' => 6)),
|
||||
),
|
||||
*/
|
||||
'showalarms' => array(
|
||||
'id' => 'taskedit-showalarms',
|
||||
'label' => $this->plugin->gettext('showalarms'),
|
||||
'value' => html::tag('input', array('id' => 'taskedit-showalarms', 'name' => 'color', 'type' => 'checkbox')),
|
||||
),
|
||||
);
|
||||
|
||||
return html::tag('form', array('action' => "#", 'method' => "post", 'id' => 'tasklisteditform'),
|
||||
|
@ -180,18 +181,38 @@ class tasklist_ui
|
|||
}
|
||||
|
||||
/**
|
||||
* Render a HTML select box to select a task category
|
||||
* Render HTML form for alarm configuration
|
||||
*/
|
||||
function category_select($attrib = array())
|
||||
function alarm_select($attrib = array())
|
||||
{
|
||||
$attrib['name'] = 'categories';
|
||||
$select = new html_select($attrib);
|
||||
$select->add('---', '');
|
||||
foreach ((array)$this->plugin->driver->list_categories() as $cat => $color) {
|
||||
$select->add($cat, $cat);
|
||||
}
|
||||
unset($attrib['name']);
|
||||
$select_type = new html_select(array('name' => 'alarmtype[]', 'class' => 'edit-alarm-type'));
|
||||
$select_type->add(rcube_label('none'), '');
|
||||
foreach ($this->plugin->driver->alarm_types as $type)
|
||||
$select_type->add(rcube_label(strtolower("calendar.alarm{$type}option")), $type);
|
||||
|
||||
return $select->show(null);
|
||||
$input_value = new html_inputfield(array('name' => 'alarmvalue[]', 'class' => 'edit-alarm-value', 'size' => 3));
|
||||
$input_date = new html_inputfield(array('name' => 'alarmdate[]', 'class' => 'edit-alarm-date', 'size' => 10));
|
||||
$input_time = new html_inputfield(array('name' => 'alarmtime[]', 'class' => 'edit-alarm-time', 'size' => 6));
|
||||
|
||||
$select_offset = new html_select(array('name' => 'alarmoffset[]', 'class' => 'edit-alarm-offset'));
|
||||
foreach (array('-M','-H','-D','+M','+H','+D','@') as $trigger)
|
||||
$select_offset->add(rcube_label('calendar.trigger' . $trigger), $trigger);
|
||||
|
||||
// pre-set with default values from user settings
|
||||
$preset = calendar::parse_alaram_value($this->rc->config->get('calendar_default_alarm_offset', '-15M'));
|
||||
$hidden = array('style' => 'display:none');
|
||||
$html = html::span('edit-alarm-set',
|
||||
$select_type->show($this->rc->config->get('calendar_default_alarm_type', '')) . ' ' .
|
||||
html::span(array('class' => 'edit-alarm-values', 'style' => 'display:none'),
|
||||
$input_value->show($preset[0]) . ' ' .
|
||||
$select_offset->show($preset[1]) . ' ' .
|
||||
$input_date->show('', $hidden) . ' ' .
|
||||
$input_time->show('', $hidden)
|
||||
)
|
||||
);
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -226,7 +247,7 @@ class tasklist_ui
|
|||
*/
|
||||
function tagslist($attrib)
|
||||
{
|
||||
$attrib += array('id' => 'rcmtagslist');
|
||||
$attrib += array('id' => 'rcmtasktagslist');
|
||||
unset($attrib['name']);
|
||||
|
||||
$this->rc->output->add_gui_object('tagslist', $attrib['id']);
|
||||
|
@ -238,7 +259,7 @@ class tasklist_ui
|
|||
*/
|
||||
function tags_editline($attrib)
|
||||
{
|
||||
$attrib += array('id' => 'rcmtagsedit');
|
||||
$attrib += array('id' => 'rcmtasktagsedit');
|
||||
$this->rc->output->add_gui_object('edittagline', $attrib['id']);
|
||||
|
||||
$input = new html_inputfield(array('name' => 'tags[]', 'class' => 'tag', 'size' => $attrib['size'], 'tabindex' => $attrib['tabindex']));
|
||||
|
@ -251,7 +272,7 @@ class tasklist_ui
|
|||
function attachments_list($attrib = array())
|
||||
{
|
||||
if (!$attrib['id'])
|
||||
$attrib['id'] = 'rcmAttachmentList';
|
||||
$attrib['id'] = 'rcmtaskattachmentlist';
|
||||
|
||||
$this->rc->output->add_gui_object('attachmentlist', $attrib['id']);
|
||||
|
||||
|
@ -265,7 +286,7 @@ class tasklist_ui
|
|||
{
|
||||
// add ID if not given
|
||||
if (!$attrib['id'])
|
||||
$attrib['id'] = 'rcmUploadForm';
|
||||
$attrib['id'] = 'rcmtaskuploadform';
|
||||
|
||||
// Get max filesize, enable upload progress bar
|
||||
$max_filesize = rcube_upload_init();
|
||||
|
|
Loading…
Add table
Reference in a new issue