Create Task from Email feature (#896)
This commit is contained in:
parent
7a8fbddf0d
commit
fd1f107b4c
6 changed files with 188 additions and 66 deletions
|
@ -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';
|
||||
|
|
|
@ -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" />
|
||||
<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" />
|
||||
<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" /> %
|
||||
<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" />
|
||||
|
|
39
plugins/tasklist/skins/larry/templates/taskedit.html
Normal file
39
plugins/tasklist/skins/larry/templates/taskedit.html
Normal 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" />
|
||||
<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" />
|
||||
<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" /> %
|
||||
<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>
|
|
@ -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);
|
||||
|
|
|
@ -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 *******/
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Reference in a new issue