Create Task from Email feature (#896)

This commit is contained in:
Thomas Bruederli 2012-07-29 17:20:19 +02:00
parent 7a8fbddf0d
commit fd1f107b4c
6 changed files with 188 additions and 66 deletions

View file

@ -8,6 +8,7 @@ $labels['tags'] = 'Tags';
$labels['newtask'] = 'New Task';
$labels['createnewtask'] = 'Create new Task (e.g. Saturday, Mow the lawn)';
$labels['createfrommail'] = 'Create new task from email';
$labels['mark'] = 'Mark';
$labels['unmark'] = 'Unmark';
$labels['edit'] = 'Edit';

View file

@ -122,45 +122,7 @@
</div>
</div>
<div id="taskedit">
<form id="taskeditform" action="#" method="post" enctype="multipart/form-data">
<div class="form-section">
<label for="edit-title"><roundcube:label name="tasklist.title" /></label>
<br />
<input type="text" class="text" name="title" id="edit-title" size="60" tabindex="1" />
</div>
<div class="form-section">
<label for="edit-description"><roundcube:label name="tasklist.description" /></label>
<br />
<textarea name="description" id="edit-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" />
</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" /> &nbsp;
<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>
</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" /> &nbsp;
<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>
</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" />&nbsp;%
<div id="edit-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" />
</div>
</form>
</div>
<roundcube:include file="/templates/taskedit.html" />
<div id="tasklistform" class="uidialog">
<roundcube:object name="plugin.tasklist_editform" />

View file

@ -0,0 +1,39 @@
<div id="taskedit">
<form id="taskeditform" action="#" method="post" enctype="multipart/form-data">
<div class="form-section">
<label for="edit-title"><roundcube:label name="tasklist.title" /></label>
<br />
<input type="text" class="text" name="title" id="edit-title" size="60" tabindex="1" />
</div>
<div class="form-section">
<label for="edit-description"><roundcube:label name="tasklist.description" /></label>
<br />
<textarea name="description" id="edit-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" />
</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" /> &nbsp;
<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>
</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" /> &nbsp;
<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>
</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" />&nbsp;%
<div id="edit-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" />
</div>
</form>
</div>

View file

@ -20,7 +20,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
function rcube_tasklist(settings)
function rcube_tasklist_ui(settings)
{
/* constants */
var FILTER_MASK_ALL = 0;
@ -58,7 +58,6 @@ function rcube_tasklist(settings)
var listdata = {};
var tags = [];
var draghelper;
var completeness_slider;
var search_request;
var search_query;
var me = this;
@ -91,6 +90,21 @@ function rcube_tasklist(settings)
this.reset_search = reset_search;
this.list_remove = list_remove;
this.list_edit_dialog = list_edit_dialog;
this.unlock_saving = unlock_saving;
/* basic initializations */
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)) });
/**
@ -118,7 +132,7 @@ function rcube_tasklist(settings)
rcmail.addEventListener('plugin.insert_tasklist', insert_list);
rcmail.addEventListener('plugin.update_tasklist', update_list);
rcmail.addEventListener('plugin.reload_data', function(){ list_tasks(null); });
rcmail.addEventListener('plugin.unlock_saving', function(p){ rcmail.set_busy(false, null, saving_lock); });
rcmail.addEventListener('plugin.unlock_saving', unlock_saving);
// start loading tasks
fetch_counts();
@ -277,22 +291,11 @@ function rcube_tasklist(settings)
}
});
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)) });
// handle global document clicks: close popup menus
$(document.body).click(clear_popups);
// extended datepicker settings
extended_datepicker_settings = $.extend({
var extended_datepicker_settings = $.extend({
showButtonPanel: true,
beforeShow: function(input, inst) {
setTimeout(function(){
@ -462,13 +465,22 @@ function rcube_tasklist(settings)
{
if (!rcmail.busy) {
saving_lock = rcmail.set_busy(true, 'tasklist.savingdata');
rcmail.http_post('task', { action:action, t:rec, filter:filtermask });
rcmail.http_post('tasks/task', { action:action, t:rec, filter:filtermask });
return true;
}
return false;
}
/**
* Remove saving lock and free the UI for new input
*/
function unlock_saving()
{
if (saving_lock)
rcmail.set_busy(false, null, saving_lock);
}
/**
* Render the given task into the tasks list
*/
@ -1241,7 +1253,7 @@ jQuery.fn.sortElements = (function(){
var rctasks;
window.rcmail && rcmail.addEventListener('init', function(evt) {
rctasks = new rcube_tasklist(rcmail.env.tasklist_settings);
rctasks = new rcube_tasklist_ui(rcmail.env.tasklist_settings);
// register button commands
rcmail.register_command('newtask', function(){ rctasks.edit_task(null, 'new', {}); }, true);

View file

@ -81,6 +81,29 @@ class tasklist extends rcube_plugin
$this->register_action('tasklist', array($this, 'tasklist_action'));
$this->register_action('counts', array($this, 'fetch_counts'));
$this->register_action('fetch', array($this, 'fetch_tasks'));
$this->register_action('inlineui', array($this, 'get_inline_ui'));
$this->register_action('mail2task', array($this, 'mail_message2task'));
}
else if ($this->rc->task == 'mail') {
// TODO: register hooks to catch ical/vtodo email attachments
if ($this->rc->action == 'show' || $this->rc->action == 'preview') {
// $this->add_hook('message_load', array($this, 'mail_message_load'));
// $this->add_hook('template_object_messagebody', array($this, 'mail_messagebody_html'));
}
// add 'Create event' item to message menu
if ($this->api->output->type == 'html') {
$this->api->add_content(html::tag('li', null,
$this->api->output->button(array(
'command' => 'tasklist-create-from-mail',
'label' => 'tasklist.createfrommail',
'type' => 'link',
'classact' => 'icon taskaddlink active',
'class' => 'icon taskaddlink',
'innerclass' => 'icon taskadd',
))),
'messagemenu');
}
}
if (!$this->rc->output->ajax_call && !$this->rc->output->env['framed']) {
@ -525,6 +548,89 @@ class tasklist extends rcube_plugin
}
/**
*
*/
public function get_inline_ui()
{
foreach (array('save','cancel','savingdata') as $label)
$texts['tasklist.'.$label] = $this->gettext($label);
$texts['tasklist.newtask'] = $this->gettext('createfrommail');
$this->ui->init_templates();
echo $this->api->output->parse('tasklist.taskedit', false, false);
echo html::tag('script', array('type' => 'text/javascript'),
"rcmail.set_env('tasklists', " . json_encode($this->api->output->env['tasklists']) . ");\n".
// "rcmail.set_env('deleteicon', '" . $this->api->output->env['deleteicon'] . "');\n".
// "rcmail.set_env('cancelicon', '" . $this->api->output->env['cancelicon'] . "');\n".
// "rcmail.set_env('loadingicon', '" . $this->api->output->env['loadingicon'] . "');\n".
"rcmail.add_label(" . json_encode($texts) . ");\n"
);
exit;
}
/******* Email related function *******/
public function mail_message2task()
{
$uid = get_input_value('_uid', RCUBE_INPUT_POST);
$mbox = get_input_value('_mbox', RCUBE_INPUT_POST);
$task = array();
// establish imap connection
$imap = $this->rc->get_storage();
$imap->set_mailbox($mbox);
$message = new rcube_message($uid);
if ($message->headers) {
$task['title'] = trim($message->subject);
$task['description'] = trim($message->first_text_part());
/*
// copy mail attachments to event
if ($message->attachments) {
$eventid = 'cal:';
if (!is_array($_SESSION['event_session']) || $_SESSION['event_session']['id'] != $eventid) {
$_SESSION['event_session'] = array();
$_SESSION['event_session']['id'] = $eventid;
$_SESSION['event_session']['attachments'] = array();
}
foreach ((array)$message->attachments as $part) {
$attachment = array(
'data' => $imap->get_message_part($uid, $part->mime_id, $part),
'size' => $part->size,
'name' => $part->filename,
'mimetype' => $part->mimetype,
'group' => $eventid,
);
$attachment = $this->rc->plugins->exec_hook('attachment_save', $attachment);
if ($attachment['status'] && !$attachment['abort']) {
$id = $attachment['id'];
// store new attachment in session
unset($attachment['status'], $attachment['abort'], $attachment['data']);
$_SESSION['event_session']['attachments'][$id] = $attachment;
$attachment['id'] = 'rcmfile' . $attachment['id']; # add prefix to consider it 'new'
$event['attachments'][] = $attachment;
}
}
}
*/
$this->rc->output->command('plugin.mail2taskdialog', $task);
}
else {
$this->rc->output->command('display_message', $this->gettext('messageopenerror'), 'error');
}
$this->rc->output->send();
}
/******* Utility functions *******/
/**

View file

@ -52,6 +52,18 @@ class tasklist_ui
), 'taskbar');
$this->plugin->include_stylesheet($this->plugin->local_skin_path() . '/tasklist.css');
$this->plugin->include_script('tasklist_base.js');
// copy config to client
$defaults = $this->plugin->defaults;
$settings = array(
'date_format' => $this->rc->config->get('date_format', $defaults['date_format']),
'time_format' => $this->rc->config->get('time_format', $defaults['time_format']),
'first_day' => $this->rc->config->get('calendar_first_day', $defaults['first_day']),
);
$this->rc->output->set_env('tasklist_settings', $settings);
$this->ready = true;
}
@ -72,16 +84,6 @@ class tasklist_ui
$this->plugin->include_script('jquery.tagedit.js');
$this->plugin->include_script('tasklist.js');
// copy config to client
$defaults = $this->plugin->defaults;
$settings = array(
'date_format' => $this->rc->config->get('date_format', $defaults['date_format']),
'time_format' => $this->rc->config->get('time_format', $defaults['time_format']),
'first_day' => $this->rc->config->get('calendar_first_day', $defaults['first_day']),
);
$this->rc->output->set_env('tasklist_settings', $settings);
}
/**