Finish z-push config: group folders by type; implement delete-device command
This commit is contained in:
parent
f33ce42c01
commit
95f0d84cfe
8 changed files with 212 additions and 51 deletions
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* Client scripts for the Kolab Z-Push configuration utitlity
|
||||
*
|
||||
* @version 0.1
|
||||
* @version 0.2
|
||||
* @author Thomas Bruederli <roundcube@gmail.com>
|
||||
*
|
||||
* Copyright (C) 2011, Kolab Systems AG
|
||||
|
@ -25,19 +25,26 @@ function kolab_zpush_config()
|
|||
devicelist.addEventListener('select', select_device);
|
||||
devicelist.init();
|
||||
|
||||
rcmail.register_command('plugin.save-config', save_config, true);
|
||||
rcmail.register_command('plugin.save-config', save_config);
|
||||
rcmail.register_command('plugin.delete-device', delete_device_config);
|
||||
rcmail.addEventListener('plugin.zpush_data_ready', device_data_ready);
|
||||
rcmail.addEventListener('plugin.zpush_save_complete', save_complete);
|
||||
|
||||
$('input.subscription').change(function(e){ $('#'+this.id+'_alarm').prop('disabled', !this.checked); });
|
||||
$(window).bind('resize', resize_ui);
|
||||
|
||||
|
||||
// select the one and only device from list
|
||||
if (rcmail.env.devicecount == 1) {
|
||||
for (var imei in rcmail.env.devices)
|
||||
break;
|
||||
devicelist.select(imei);
|
||||
}
|
||||
|
||||
/* private methods */
|
||||
function select_device(list)
|
||||
{
|
||||
active_device = list.get_single_selection();
|
||||
rcmail.enable_command('plugin.save-config');
|
||||
rcmail.enable_command('plugin.save-config', 'plugin.delete-device', true);
|
||||
|
||||
if (active_device) {
|
||||
http_lock = rcmail.set_busy(true, 'loading');
|
||||
|
@ -109,14 +116,23 @@ function kolab_zpush_config()
|
|||
rcmail.env.devices[p.id].ALIAS = p.devicealias;
|
||||
}
|
||||
}
|
||||
|
||||
// handler for delete commands
|
||||
function delete_device_config()
|
||||
{
|
||||
if (active_device && confirm(rcmail.gettext('devicedeleteconfirm', 'kolab_zpush'))) {
|
||||
http_lock = rcmail.set_busy(true, 'kolab_zpush.savingdata');
|
||||
rcmail.http_post('plugin.zpushjson', { cmd:'delete', id:active_device }, http_lock);
|
||||
}
|
||||
}
|
||||
|
||||
// handler for window resize events: sets max-height of folders list scroll container
|
||||
function resize_ui()
|
||||
{
|
||||
if (active_device) {
|
||||
var h = $(window).height();
|
||||
var pos = $('#folderscrollist').offset();
|
||||
$('#folderscrollist').css('max-height', (h - pos.top - 90) + 'px');
|
||||
var pos = $('#foldersubscriptions').offset();
|
||||
$('#foldersubscriptions').css('max-height', (h - pos.top - 90) + 'px');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,6 +54,9 @@ class kolab_zpush extends rcube_plugin
|
|||
|
||||
$this->register_action('plugin.zpushconfig', array($this, 'config_view'));
|
||||
$this->register_action('plugin.zpushjson', array($this, 'json_command'));
|
||||
|
||||
if ($this->rc->action == 'plugin.zpushconfig')
|
||||
$this->require_plugin('kolab_core');
|
||||
}
|
||||
|
||||
|
||||
|
@ -173,6 +176,56 @@ class kolab_zpush extends rcube_plugin
|
|||
$this->rc->output->show_message($this->gettext('successfullysaved'), 'confirmation');
|
||||
|
||||
break;
|
||||
|
||||
case 'delete':
|
||||
$this->init_imap();
|
||||
$devices = $this->list_devices();
|
||||
|
||||
if ($device = $devices[$imei]) {
|
||||
unset($this->root_meta['DEVICE'][$imei], $this->root_meta['FOLDER'][$imei]);
|
||||
|
||||
// update annotation and cached meta data
|
||||
if ($success = $this->rc->imap->set_metadata(self::ROOT_MAILBOX, array(self::ACTIVESYNC_KEY => $this->serialize_metadata($this->root_meta)))) {
|
||||
$this->cache->remove('devicemeta');
|
||||
$this->cache->write('devicemeta', $this->rc->imap->get_metadata(self::ROOT_MAILBOX, self::ACTIVESYNC_KEY));
|
||||
|
||||
// remove device annotation in every folder
|
||||
foreach ($this->folders_meta() as $folder => $meta) {
|
||||
// skip root folder (already handled above)
|
||||
if ($folder == self::ROOT_MAILBOX)
|
||||
continue;
|
||||
|
||||
if (isset($meta[$imei])) {
|
||||
$type = $meta['TYPE']; // remember folder type
|
||||
unset($meta[$imei], $meta['TYPE']);
|
||||
|
||||
// read metadata first and update FOLDER property
|
||||
$folderdata = $this->rc->imap->get_metadata($folder, array(self::ACTIVESYNC_KEY));
|
||||
if ($asyncdata = $folderdata[$folder][self::ACTIVESYNC_KEY])
|
||||
$metadata = $this->unserialize_metadata($asyncdata);
|
||||
$metadata['FOLDER'] = $meta;
|
||||
|
||||
if ($this->rc->imap->set_metadata($folder, array(self::ACTIVESYNC_KEY => $this->serialize_metadata($metadata)))) {
|
||||
$this->folders_meta[$folder] = $metadata;
|
||||
$this->folders_meta[$folder]['TYPE'] = $type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update cache
|
||||
$this->cache->remove('folders');
|
||||
$this->cache->write('folders', $this->folders_meta);
|
||||
}
|
||||
}
|
||||
|
||||
if ($success) {
|
||||
$this->rc->output->show_message($this->gettext('successfullydeleted'), 'confirmation');
|
||||
$this->rc->output->redirect(array('action' => 'plugin.zpushconfig')); // reload UI
|
||||
}
|
||||
else
|
||||
$this->rc->output->show_message($this->gettext('savingerror'), 'error');
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
$this->rc->output->send();
|
||||
|
|
|
@ -79,6 +79,9 @@ class kolab_zpush_ui
|
|||
$checkbox = new html_checkbox(array('name' => 'laxpic', 'value' => '1', 'id' => $field_id));
|
||||
$table->add('title', $this->config->gettext('imageformat'));
|
||||
$table->add(null, html::label($field_id, $checkbox->show() . ' ' . $this->config->gettext('laxpiclabel')));
|
||||
|
||||
if ($attrib['form'])
|
||||
$this->rc->output->add_gui_object('editform', $attrib['form']);
|
||||
|
||||
return $table->show($attrib);
|
||||
}
|
||||
|
@ -88,22 +91,81 @@ class kolab_zpush_ui
|
|||
{
|
||||
if (!$attrib['id'])
|
||||
$attrib['id'] = 'foldersubscriptions';
|
||||
|
||||
$table = new html_table();
|
||||
$table->add_header('foldername', $this->config->gettext('folder'));
|
||||
$table->add_header('subscription', $attrib['syncicon'] ? html::img(array('src' => $this->skin_path . $attrib['syncicon'], 'title' => $this->config->gettext('synchronize'))) : '');
|
||||
$table->add_header('alarm', $attrib['alarmicon'] ? html::img(array('src' => $this->skin_path . $attrib['alarmicon'], 'title' => $this->config->gettext('withalarms'))) : '');
|
||||
|
||||
$folders_tree = array();
|
||||
$delimiter = $this->rc->imap->get_hierarchy_delimiter();
|
||||
foreach ($this->config->list_folders() as $folder)
|
||||
rcmail_build_folder_tree($folders_tree, $folder, $delimiter);
|
||||
|
||||
$this->render_folders($folders_tree, $table, 0);
|
||||
|
||||
|
||||
// group folders by type
|
||||
$folder_groups = array('mail' => array(), 'contact' => array(), 'event' => array());
|
||||
$folder_meta = $this->config->folders_meta();
|
||||
foreach ($this->config->list_folders() as $folder) {
|
||||
$type = $folder_meta[$folder]['TYPE'] ? $folder_meta[$folder]['TYPE'] : 'mail';
|
||||
$folder_groups[$type][] = $folder;
|
||||
}
|
||||
|
||||
// build block for every folder type
|
||||
foreach ($folder_groups as $type => $group) {
|
||||
if (empty($group))
|
||||
continue;
|
||||
$attrib['type'] = $type;
|
||||
$html .= html::div('subscriptionblock',
|
||||
html::tag('h3', $type, $this->config->gettext($type)) .
|
||||
$this->folder_subscriptions_block($group, $attrib));
|
||||
}
|
||||
|
||||
$this->rc->output->add_gui_object('subscriptionslist', $attrib['id']);
|
||||
|
||||
return html::div($attrib, $html);
|
||||
}
|
||||
|
||||
return $table->show($attrib);
|
||||
public function folder_subscriptions_block($a_folders, $attrib)
|
||||
{
|
||||
$alarms = ($attrib['type'] == 'event' || $attrib['type'] == 'task');
|
||||
|
||||
$table = new html_table(array('cellspacing' => 0));
|
||||
$table->add_header('subscription', $attrib['syncicon'] ? html::img(array('src' => $this->skin_path . $attrib['syncicon'], 'title' => $this->config->gettext('synchronize'))) : '');
|
||||
$table->add_header('alarm', $alarms && $attrib['alarmicon'] ? html::img(array('src' => $this->skin_path . $attrib['alarmicon'], 'title' => $this->config->gettext('withalarms'))) : '');
|
||||
$table->add_header('foldername', $this->config->gettext('folder'));
|
||||
|
||||
$checkbox_sync = new html_checkbox(array('name' => 'subscribed[]', 'class' => 'subscription'));
|
||||
$checkbox_alarm = new html_checkbox(array('name' => 'alarm[]', 'class' => 'alarm', 'disabled' => true));
|
||||
|
||||
$names = array();
|
||||
foreach ($a_folders as $folder) {
|
||||
$foldername = $origname = preg_replace('/^INBOX »\s+/', '', rcube_kolab::object_name($folder));
|
||||
|
||||
// find folder prefix to truncate (the same code as in kolab_addressbook plugin)
|
||||
for ($i = count($names)-1; $i >= 0; $i--) {
|
||||
if (strpos($foldername, $names[$i].' » ') === 0) {
|
||||
$length = strlen($names[$i].' » ');
|
||||
$prefix = substr($foldername, 0, $length);
|
||||
$count = count(explode(' » ', $prefix));
|
||||
$foldername = str_repeat(' ', $count-1) . '» ' . substr($foldername, $length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$names[] = $origname;
|
||||
|
||||
$classes = array('mailbox');
|
||||
|
||||
if ($folder_class = rcmail_folder_classname($folder)) {
|
||||
$foldername = rcube_label($folder_class);
|
||||
$classes[] = $folder_class;
|
||||
}
|
||||
|
||||
$folder_id = 'rcmf' . html_identifier($folder);
|
||||
$padding = str_repeat(' ', $level);
|
||||
|
||||
$table->add_row(array('class' => (($level+1) * $idx++) % 2 == 0 ? 'even' : 'odd'));
|
||||
$table->add('subscription', $checkbox_sync->show('', array('value' => $folder, 'id' => $folder_id)));
|
||||
|
||||
if ($alarms)
|
||||
$table->add('alarm', $checkbox_alarm->show('', array('value' => $folder, 'id' => $folder_id.'_alarm')));
|
||||
else
|
||||
$table->add('alarm', '');
|
||||
|
||||
$table->add(join(' ', $classes), html::label($folder_id, $padding . Q($foldername)));
|
||||
}
|
||||
|
||||
return $table->show();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -13,6 +13,11 @@ $labels['withalarms'] = 'Mit Erinnerungen';
|
|||
$labels['syncsettings'] = 'Synchronisationseinstellungen';
|
||||
$labels['deviceconfig'] = 'Gerätekonfiguration';
|
||||
$labels['folderstosync'] = 'Order zum Synchronisieren';
|
||||
$labels['mail'] = 'E-Mail';
|
||||
$labels['contact'] = 'Adressbücher';
|
||||
$labels['event'] = 'Kalendar';
|
||||
$labels['task'] = 'Aufgaben';
|
||||
$labels['note'] = 'Notizen';
|
||||
$labels['deletedevice'] = 'Gerät löschen';
|
||||
$labels['imageformat'] = 'Bildformat';
|
||||
$labels['laxpiclabel'] = 'Erlaube PNG- und GIF-Bilder';
|
||||
|
@ -21,5 +26,7 @@ $labels['nodevices'] = 'Es sind noch keine Geräte registriert.<br/><br/>Um ein
|
|||
$labels['savingdata'] = 'Daten werden gespeichert...';
|
||||
$labels['savingerror'] = 'Fehler beim Speichern';
|
||||
$labels['notsupported'] = 'Ihr Server unterstützt keine Activesync-Konfiguration';
|
||||
$labels['devicedeleteconfirm'] = 'Wollen Sie wirklich alle Einstellungen für dieses Gerät löschen?';
|
||||
$labels['successfullydeleted'] = 'Die Geräteinstellungen wurden erfolgreich gelöscht';
|
||||
|
||||
?>
|
|
@ -13,6 +13,11 @@ $labels['withalarms'] = 'With alarms';
|
|||
$labels['syncsettings'] = 'Synchronization settings';
|
||||
$labels['deviceconfig'] = 'Device configration';
|
||||
$labels['folderstosync'] = 'Folders to synchronize';
|
||||
$labels['mail'] = 'Email';
|
||||
$labels['contact'] = 'Address Books';
|
||||
$labels['event'] = 'Calendars';
|
||||
$labels['task'] = 'Tasks';
|
||||
$labels['note'] = 'Notes';
|
||||
$labels['deletedevice'] = 'Delete device';
|
||||
$labels['imageformat'] = 'Image format';
|
||||
$labels['laxpiclabel'] = 'Allow PNG and GIF images';
|
||||
|
@ -21,5 +26,7 @@ $labels['nodevices'] = 'There are currently no devices registered.<br/><br/>In o
|
|||
$labels['savingdata'] = 'Saving data...';
|
||||
$labels['savingerror'] = 'Failed to save configuration';
|
||||
$labels['notsupported'] = 'Your server does not support metadata/annotations';
|
||||
$labels['devicedeleteconfirm'] = 'Do you really want to delete the configuration for this device?';
|
||||
$labels['successfullydeleted'] = 'The device configuration was successfully removed';
|
||||
|
||||
?>
|
|
@ -1,4 +1,7 @@
|
|||
/* Stylesheets for the Kolab Z-Push configuration UI */
|
||||
#configform {
|
||||
padding-top: 15px;
|
||||
}
|
||||
|
||||
#devices-table {
|
||||
width: 100%;
|
||||
|
@ -19,16 +22,52 @@
|
|||
color: #ccc;
|
||||
}
|
||||
|
||||
.boxfooter a.button.delete,
|
||||
.boxfooter a.buttonPas.delete {
|
||||
background-image: url(deviceactions.png);
|
||||
}
|
||||
|
||||
div.subscriptionblock {
|
||||
float: left;
|
||||
margin: 0.5em 3em 2em 0;
|
||||
padding: 0;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
|
||||
div.subscriptionblock h3 {
|
||||
font-size: 12px;
|
||||
color: #333;
|
||||
margin: 0 0 0.4em 0;
|
||||
padding: 4px 4px 5px 30px;
|
||||
background: url(foldertypes.png) 4px 4px no-repeat #fbfbfb;
|
||||
}
|
||||
|
||||
div.subscriptionblock h3.contact {
|
||||
background-position: 4px -16px;
|
||||
}
|
||||
|
||||
div.subscriptionblock h3.event {
|
||||
background-position: 4px -36px;
|
||||
}
|
||||
|
||||
div.subscriptionblock h3.task {
|
||||
background-position: 4px -56x;
|
||||
}
|
||||
|
||||
div.subscriptionblock h3.note {
|
||||
background-position: 4px -76px;
|
||||
}
|
||||
|
||||
#foldersubscriptions thead td {
|
||||
color: #999;
|
||||
font-weight: bold;
|
||||
padding: 4px;
|
||||
padding: 3px 5px;
|
||||
min-width: 2em;
|
||||
}
|
||||
|
||||
|
||||
#foldersubscriptions tbody td {
|
||||
padding: 2px 4px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
padding: 2px 5px;
|
||||
border-top: 1px solid #ddd;
|
||||
}
|
||||
|
||||
#foldersubscriptions td label {
|
||||
|
@ -37,36 +76,15 @@
|
|||
|
||||
#foldersubscriptions td.mailbox {
|
||||
padding-right: 3em;
|
||||
padding-left: 30px;
|
||||
padding-left: 2px;
|
||||
min-width: 12em;
|
||||
background: url(foldertypes.png) 2px 2px no-repeat;
|
||||
}
|
||||
|
||||
#foldersubscriptions td.virtual {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
#foldersubscriptions td.mail {
|
||||
background-position: 2px -17px;
|
||||
}
|
||||
|
||||
#foldersubscriptions td.event {
|
||||
background-position: 2px -37px;
|
||||
}
|
||||
|
||||
#foldersubscriptions td.contact {
|
||||
background-position: 2px -57px;
|
||||
}
|
||||
|
||||
#foldersubscriptions td.note {
|
||||
background-position: 2px -77px;
|
||||
}
|
||||
|
||||
#foldersubscriptions td.task {
|
||||
background-position: 2px -97px;
|
||||
}
|
||||
|
||||
#folderscrollist {
|
||||
#foldersubscriptions {
|
||||
overflow: auto;
|
||||
max-height: 400px;
|
||||
margin-top: 0.5em;
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.2 KiB |
|
@ -20,7 +20,7 @@
|
|||
<roundcube:object name="plugin.devicelist" id="devices-table" class="records-table" cellspacing="0" />
|
||||
</div>
|
||||
<div class="boxfooter">
|
||||
<roundcube:button command="device-create" type="link" title="newcontactgroup" class="buttonPas adddevice" classAct="button adddevice" content=" " />
|
||||
<roundcube:button type="link" command="plugin.delete-device" title="kolab_zpush.deletedevice" class="buttonPas delete" classAct="button delete" content=" " />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -33,9 +33,7 @@
|
|||
</fieldset>
|
||||
<fieldset>
|
||||
<legend><roundcube:label name="kolab_zpush.folderstosync" /></legend>
|
||||
<div id="folderscrollist">
|
||||
<roundcube:object name="plugin.foldersubscriptions" form="configform" id="foldersubscriptions" cellspacing="0" summary="Folder subscription table" syncicon="synchronize.png" alarmicon="alarm-clock.png" />
|
||||
</div>
|
||||
<roundcube:object name="plugin.foldersubscriptions" form="configform" id="foldersubscriptions" syncicon="synchronize.png" alarmicon="alarm-clock.png" />
|
||||
</fieldset>
|
||||
<p class="formbuttons">
|
||||
<roundcube:button type="input" class="button mainaction" command="plugin.save-config" label="save" />
|
||||
|
|
Loading…
Add table
Reference in a new issue