*Mail: New feature for mail folder tree, called Folder Management:

- Folder Management dialog is located under mail context-menu and implemented in order to ease deleting multiple folders from a mail tree.
This commit is contained in:
Hadi Nategh 2015-08-17 15:15:16 +00:00
commit 44a8ac5fe1
8 changed files with 366 additions and 31 deletions

View File

@ -46,6 +46,7 @@ class mail_ui
'importMessage' => True,
'importMessageFromVFS2DraftAndDisplay'=>True,
'subscription' => True,
'folderManagement' => true,
);
/**
@ -592,6 +593,12 @@ class mail_ui
'onExecute' => 'javaScript:app.mail.unsubscribe_folder',
'group' => $group,
),
'foldermanagement' => array(
'caption' => 'Folder Management ...',
'enabled' => 'javaScript:app.mail.mail_CheckFolderNoSelect',
'onExecute' => 'javaScript:app.mail.folderManagement',
'group' => $group,
),
'sieve' => array(
'caption' => 'Mail filter',
'onExecute' => 'javaScript:app.mail.edit_sieve',
@ -697,6 +704,7 @@ class mail_ui
unset($tree_actions['add']);
unset($tree_actions['move']);
unset($tree_actions['delete']);
unset($tree_actions['foldermanagement']);
// manage folders should not affect the ability to subscribe or unsubscribe
// to existing folders, it should only affect add/rename/move/delete
}
@ -3725,9 +3733,10 @@ class mail_ui
/**
* ajax_deleteFolder - its called via json, so the function must start with ajax (or the class-name must contain ajax)
* @param string $_folderName folder to delete
* @param boolean $_return = false wheter return the success value (true) or send response to client (false)
* @return nothing
*/
function ajax_deleteFolder($_folderName)
function ajax_deleteFolder($_folderName, $_return = false)
{
//error_log(__METHOD__.__LINE__.' OldFolderName:'.array2string($_folderName));
$success = false;
@ -3805,22 +3814,10 @@ class mail_ui
$msg = lang("refused to delete folder INBOX");
}
}
if ($_return) return $success;
$response = egw_json_response::get();
if ($success)
{
$folders2return = egw_cache::getCache(egw_cache::INSTANCE,'email','folderObjects'.trim($GLOBALS['egw_info']['user']['account_id']),null,array(),$expiration=60*60*1);
if (isset($folders2return[$this->mail_bo->profileID]))
{
//error_log(__METHOD__.__LINE__.array2string($folders2return[$this->mail_bo->profileID]));
if (empty($subFolders)) $subFolders = array($folderName);
//error_log(__METHOD__.__LINE__.array2string($subFolders));
foreach($subFolders as $i => $f)
{
//error_log(__METHOD__.__LINE__.$f.'->'.array2string($folders2return[$this->mail_bo->profileID][$f]));
if (isset($folders2return[$this->mail_bo->profileID][$f])) unset($folders2return[$this->mail_bo->profileID][$f]);
}
}
egw_cache::setCache(egw_cache::INSTANCE,'email','folderObjects'.trim($GLOBALS['egw_info']['user']['account_id']),$folders2return, $expiration=60*60*1);
//error_log(__METHOD__.__LINE__.array2string($oA));
$response->call('app.mail.mail_removeLeaf',$oA);
}
@ -4593,4 +4590,67 @@ class mail_ui
if(mail_bo::$debug) error_log(__METHOD__."-> No messages selected.");
}
}
/**
* Autoloading function to load branches of tree node
* of management folder tree
*
* @param type $_id
*/
function ajax_folderMgmtTree_autoloading ($_id = null)
{
$mail_ui = new mail_ui();
$_id = $_id? $_id:$_GET['id'];
etemplate_widget_tree::send_quote_json($mail_ui->mail_tree->getTree($_id,'',1,true,false,false,false));
}
/**
* Main function to handle folder management dialog
*
* @param array $content content of dialog
*/
function folderManagement (array $content = null)
{
$dtmpl = new etemplate_new('mail.folder_management');
$profileID = $_GET['acc_id']? $_GET['acc_id']: $content['acc_id'];
$sel_options['tree'] = $this->mail_tree->getTree(null,$profileID, 1, true, false, false);
if (!is_array($content))
{
$content = array ('acc_id' => $profileID);
}
$readonlys = array();
// Preserv
$preserv = array(
'acc_id' => $content['acc_id'] // preserve acc id to be used in client-side
);
$dtmpl->exec('mail.mail_ui.folderManagement', $content,$sel_options,$readonlys,$preserv,2);
}
/**
* Function to delete folder for management longTask dialog
* it sends successfully deleted folder as response to be
* used in long task response handler.
*
* @param type $_folderName
*/
function ajax_folderMgmt_delete ($_folderName)
{
if ($_folderName)
{
$success = $this->ajax_deleteFolder($_folderName,true);
$response = egw_json_response::get();
list(,$folderName) = explode(self::$delimiter, $_folderName);
if ($success)
{
$res = $folderName;
}
else
{
$res = lang("Failed to delete %1",$folderName);
}
$response->data($res);
}
}
}

View File

@ -272,6 +272,9 @@ app.classes.mail = AppJS.extend(
tree.input.loadJSONObject(tree._htmlencode_node(state));
}
break;
case 'mail.folder_management':
this.egw.message('If you would like to select multiple folders in one action, you can hold ctrl key then select a folder as start range and another folder within a same level as end range, all folders in between will be selected or unselected based on their current status.','info',true);
}
},
@ -1618,6 +1621,38 @@ app.classes.mail = AppJS.extend(
// setting class of row, the old style
},
/**
* mail_emptySpam
*
* @param {object} action
* @param {object} _senders
*/
mail_emptySpam: function(action,_senders) {
var server = _senders[0].iface.id.split('::');
var activeFilters = this.mail_getActiveFilters();
var self = this;
this.egw.message(this.egw.lang('empty junk'));
egw.json('mail.mail_ui.ajax_emptySpam',[server[0], activeFilters['selectedFolder']? activeFilters['selectedFolder']:null],function(){self.unlock_tree();})
.sendRequest(true);
// Directly delete any trash cache for selected server
if(window.localStorage)
{
for(var i = 0; i < window.localStorage.length; i++)
{
var key = window.localStorage.key(i);
// Find directly by what the key would look like
if(key.indexOf('cached_fetch_mail::{"selectedFolder":"'+server[0]+'::') == 0 &&
key.toLowerCase().indexOf(egw.lang('junk').toLowerCase()) > 0)
{
window.localStorage.removeItem(key);
}
}
}
},
/**
* mail_emptyTrash
*
@ -4525,5 +4560,180 @@ app.classes.mail = AppJS.extend(
{
et2_dialog.alert('You need to save the message as draft first before to be able to save it into VFS','Save into VFS','info');
}
},
/**
* Folder Management, opens the folder magnt. dialog
* with the selected acc_id from index tree
*
* @param {egw action object} _action actions
* @param {object} _senders selected node
*/
folderManagement: function (_action,_senders)
{
var acc_id = parseInt(_senders[0].id);
this.egw.open_link('mail.mail_ui.folderManagement&acc_id='+acc_id, '_blank', '720x500');
},
/**
* Show ajax-loader when the autoloading get started
*
* @param {type} _id item id
* @param {type} _widget tree widget
* @returns {Boolean}
*/
folderMgmt_autoloadingStart: function(_id, _widget)
{
return this.subscription_autoloadingStart (_id, _widget);
},
/**
* Revert back the icon after autoloading is finished
* @returns {Boolean}
*/
folderMgmt_autoloadingEnd: function(_id, _widget)
{
return true;
},
/**
*
* @param {type} _ids
* @param {type} _widget
* @returns {undefined}
*/
folderMgmt_onSelect: function(_ids, _widget)
{
// Flag to reset selected items
var resetSelection = false;
var self = this;
/**
* helper function to multiselect range of nodes in same level
*
* @param {string} _a start node id
* @param {string} _b end node id
* @param {string} _branch totall node ids in the level
*/
var rangeSelector = function(_a,_b, _branch)
{
var branchItems = _branch.split(_widget.input.dlmtr);
var _aIndex = _widget.input.getIndexById(_a);
var _bIndex = _widget.input.getIndexById(_b);
if (_bIndex<_aIndex)
{
var tmpIndex = _aIndex;
_aIndex = _bIndex;
_bIndex = tmpIndex;
}
for(var i =_aIndex;i<=_bIndex;i++)
{
self.folderMgmt_setCheckbox(_widget, branchItems[i], !_widget.input.isItemChecked(branchItems[i]));
}
};
// extract items ids
var itemIds = _ids.split(_widget.input.dlmtr);
if(itemIds.length == 2) // there's a range selected
{
var branch = _widget.input.getSubItems(_widget.input.getParentId(itemIds[0]));
// Set range of selected/unselected
rangeSelector(itemIds[0], itemIds[1], branch);
}
else if(itemIds.length != 1)
{
resetSelection = true;
}
if (resetSelection)
{
_widget.input._unselectItems();
}
},
/**
* Set enable/disable checkbox
*
* @param {object} _widget tree widget
* @param {string} _itemId item tree id
* @param {boolean} _stat - status to be set on checkbox true/false
*/
folderMgmt_setCheckbox: function (_widget, _itemId, _stat)
{
if (_widget)
{
_widget.input.setCheck(_itemId, _stat);
_widget.input.setSubChecked(_itemId,_stat);
}
},
/**
*
* @param {type} _id
* @param {type} _widget
* @TODO: Implement onCheck handler in order to select or deselect subItems
* of a checked parent node
*/
folderMgmt_onCheck: function (_id, _widget)
{
var selected = _widget.input.getAllChecked();
if (selected && selected.split(_widget.input.dlmtr).length > 5)
{
egw.message(egw.lang('If you would like to select multiple folders in one action, you can hold ctrl key then select a folder as start range and another folder within a same level as end range, all folders in between will be selected or unselected based on their current status.'));
}
},
/**
* Detele button handler
* triggers longTask dialog and send delete operation url
*
*/
folderMgmt_deleteBtn: function ()
{
var tree = etemplate2.getByApplication('mail')[0].widgetContainer.getWidgetById('tree');
var menuaction= 'mail.mail_ui.ajax_folderMgmt_delete';
var callbackDialog = function(_btn)
{
if (_btn === et2_dialog.YES_BUTTON)
{
if (tree)
{
var selFolders = tree.input.getAllChecked();
if (selFolders)
{
var selFldArr = selFolders.split(tree.input.dlmtr);
var msg = egw.lang('Deleting %1 folders in progress ...', selFldArr.length);
et2_dialog.long_task(function(_val, _resp){
console.log(_val, _resp);
if (_val && _resp.type !== 'error')
{
var stat = [];
var folderName = '';
for(var i=0;i<selFldArr.length;i++)
{
folderName = selFldArr[i].split('::');
stat[selFldArr[i]] = folderName[1];
}
// delete the item from index folderTree
egw.window.app.mail.mail_removeLeaf(stat);
}
else
{
// submit
etemplate2.getByApplication('mail')[0].widgetContainer._inst.submit();
}
}, msg, 'Deleting folders', menuaction, selFldArr, 'mail');
return true;
}
}
}
};
et2_dialog.show_dialog(callbackDialog, egw.lang('Are you sure you want to delete all selected folders?'), egw.lang('Delete folder'), {},
et2_dialog.BUTTON_YES_NO, et2_dialog.WARNING_MESSAGE, undefined, egw);
}
});

View File

@ -40,6 +40,8 @@ any of mail de mit einem
any status mail de Alle Status
append mail de hinzufügen
appended after reply before sending mail de Einfügen nach dem zitierten Text im Zuge des Versendens
application mail expected but got: %1 mail de Anwendung Mail erwarted, aber %1 erhalten!
are you sure you want to delete all selected folders? mail de Sollen alle selektierten Ordner gelöcht werden?
arrival mail de Empfangsdatum
attach users vcard at compose to every new mail mail de Füge die VCard des aktiven Benutzers an jede neue E-Mail an
attach vcard mail de vCard hinzufügen
@ -91,6 +93,7 @@ delete folder %1 ? mail de Ordner %1 löschen?
deleted mail de gelöscht
deleted %1 messages in %2 mail de Es wurden %1 Nachricht(en) in %2 gelöscht
deleted! mail de gelöscht!
deleting %1 folders in progress ... mail de %1 Ordner in Bearbeitung zum Löschen
deny certain groups access to following features mail de Den Zugriff auf bestimmte Funktionen im E-Mail Modul einschränken.
directories have to be shared. mail de Verzeichnisse müssen freigegeben werden.
disable mail de Deaktivieren
@ -162,6 +165,7 @@ event details follow mail de Details zum Termin folgen
everyone mail de Alle Anwender
extended mail de Erweitert
extra sent folders mail de Anzeigeschema Gesendet Ordner
failed to delete %1 mail de Löschen von %1 fehlgeschlagen
failed to delete %1 ! reason: %2 mail de Löschen von %1 fehlgeschlagen! Grund: %2
failed to delete %1. server responded: mail de Löschen von %1 fehlgeschlagen! Grund: %2
failed to move %1 ! reason: %2 mail de Verschieben von %1 fehlgeschlagen! Grund: %2
@ -182,6 +186,7 @@ flagged %1 messages as unflagged in %2 mail de Bei %1 Nachricht(en) wurde die Ma
flagged / unflagged mail de Markierung
folder mail de Ordner
folder %1 %2 failed! mail de Ordner %1 %2 fehlgeschlagen!
folder management ... mail de Ordner Verwaltung ...
folder settings mail de Ordner Einstellungen
for e.g.: mpeg mail de z.B. mpeg
for eg.: mpeg mail de z.B. für mpeg
@ -226,6 +231,7 @@ if shown, which folders should appear on the home page mail de Welche E-Mail Ord
if subject contains:(*) mail de wenn Betreff enthält:(*)
if to contains:(*) mail de wenn An enthält:(*)
if you want to see a preview of a mail by single clicking onto the subject, enable this. mail de Wenn Sie die Vorschau einer E-Mail durch einfaches Anklicken sehen wollen, wählen Sie diese Option aus.
if you would like to select multiple folders in one action, you can hold ctrl key then select a folder as start range and another folder within a same level as end range, all folders in between will be selected or unselected based on their current status. mail de Wenn Sie mehrere Ordner einer Ebene selektieren wollen in einer Aktion, können sie mit der STR-Taste gedrückt den ersten und letzten Ordner auswählen. Dann werden alle Ordner dazwischen selektiert oder de-selektiert.
imap mail de Posteingang-Server
imap - incoming mail mail de IMAP - Posteingang-Server
imap administration mail de Administrator IMAP-Server
@ -365,6 +371,7 @@ rule priority position mail de Priorität der Filterregel
rule with priority mail de Regel mit Priorität
rules mail de Filter Regeln
save all mail de Alle speichern
save as calendar mail de Als Termin speichern
save as default mail de Als Vorgabe speichern
save as draft mail de Als Entwurf speichern
save as draft and print mail de Als Entwurf speichern und drucken

View File

@ -41,6 +41,7 @@ any status mail en any status
append mail en append
appended after reply before sending mail en Appended after reply before sending
application mail expected but got: %1 mail en Application mail expected but got: %1
are you sure you want to delete all selected folders? mail en Are you sure you want to delete all selected folders?
arrival mail en Recieved
attach users vcard at compose to every new mail mail en attach users VCard at compose to every new mail
attach vcard mail en Attach vCard
@ -92,6 +93,7 @@ delete folder %1 ? mail en DELETE Folder %1 ?
deleted mail en deleted
deleted %1 messages in %2 mail en deleted %1 messages in %2
deleted! mail en deleted!
deleting %1 folders in progress ... mail en Deleting %1 folders in progress ...
deny certain groups access to following features mail en Deny certain groups access to following features
directories have to be shared. mail en Directories have to be shared.
disable mail en Disable
@ -143,6 +145,7 @@ email notification update failed mail en email notification update failed
email notification update failed! you need to set an email address! mail en email notification update failed! You need to set an email address!
emailaddress admin en emailaddress
emailadmin: profilemanagement mail en eMailAdmin: Profilemanagement
empty junk mail en empty junk/spam folder
empty trash mail en empty trash
enable mail en Enable
enabled! mail en enabled!
@ -162,6 +165,7 @@ event details follow mail en Event Details follow
everyone mail en Everyone
extended mail en Extended
extra sent folders mail en Extra sent folders
failed to delete %1 mail en Failed to delete %1
failed to delete %1 ! reason: %2 mail en failed to delete %1 ! Reason: %2
failed to delete %1. server responded: mail en Failed to delete %1. Server responded:
failed to move %1 ! reason: %2 mail en failed to move %1 ! Reason: %2
@ -182,6 +186,7 @@ flagged %1 messages as unflagged in %2 mail en flagged %1 messages as unflagged
flagged / unflagged mail en Flagged / Unflagged
folder mail en Folder
folder %1 %2 failed! mail en Folder %1 %2 failed!
folder management ... mail en Folder Management ...
folder settings mail en Folder settings
for e.g.: mpeg mail en for e.g.: mpeg
for eg.: mpeg mail en for eg.: mpeg
@ -226,6 +231,7 @@ if shown, which folders should appear on the home page mail en if shown, which f
if subject contains:(*) mail en If subject contains:(*)
if to contains:(*) mail en If to contains:(*)
if you want to see a preview of a mail by single clicking onto the subject, enable this. mail en If you want to see a preview of a mail by single clicking onto the subject, enable this.
if you would like to select multiple folders in one action, you can hold ctrl key then select a folder as start range and another folder within a same level as end range, all folders in between will be selected or unselected based on their current status. mail en If you would like to select multiple folders in one action, you can hold ctrl key then select a folder as start range and another folder within a same level as end range, all folders in between will be selected or unselected based on their current status.
imap mail en IMAP
imap - incoming mail mail en IMAP - incoming mail
imap administration mail en IMAP administration
@ -365,6 +371,7 @@ rule priority position mail en Rule priority position
rule with priority mail en rule with priority
rules mail en rules
save all mail en Save all
save as calendar mail en Save as Calendar
save as default mail en save as default
save as draft mail en Save as Draft
save as draft and print mail en Save as Draft and Print

View File

@ -703,17 +703,19 @@ div.mailPreviewHeaders #mail-index_previewAttachmentArea.visible {
background-repeat: no-repeat;
}
.mail_subscription_header
.mail_subscription_header, .mail_folder_management_header
{
font-weight: bold;
font-size: 150%;
padding-bottom: 20px;
}
#mail-subscribe table.et2_grid tr td {
#mail-subscribe table.et2_grid tr td,
#mail-folder_management table.et2_grid tr td {
padding: 0px;
}
#mail-subscribe table.et2_grid tr td div.et2_box {
#mail-subscribe table.et2_grid tr td div.et2_box,
#mail-folder_management table.et2_grid tr td .mail_subscription_header {
height: 500px;
overflow: auto;
}

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE overlay PUBLIC "-//Stylite AG//eTemplate 2//EN" "http://www.egroupware.org/etemplate2.dtd">
<!-- $Id$ -->
<overlay>
<template id="mail.folder_management" template="" lang="" group="0" version="1.9.001">
<grid width="100%">
<columns>
<column width="20%"/>
</columns>
<rows>
<row class="dialogHeader" >
<description value="Folder Management" class="mail_folder_management_header"/>
</row>
<row>
<box scrolling="auto">
<tree id="tree" multiple="true" autoloading="mail_ui::ajax_folderMgmtTree_autoloading" multimarking="strict" oncheck="app.mail.folderMgmt_onCheck" onselect="app.mail.folderMgmt_onSelect" onopenstart="app.mail.folderMgmt_autoloadingStart" onopenend="app.mail.folderMgmt_autoloadingEnd" highlighting="true"/>
</box>
</row>
</rows>
</grid>
<hbox class="dialogFooterToolbar">
<button statustext="Delete" label="Delete" id="button[delete]" onclick="app.mail.folderMgmt_deleteBtn"/>
<button label="Cancel" id="button[cancel]" onclick="window.close()"/>
</hbox>
</template>
</overlay>

View File

@ -701,15 +701,18 @@ div.mailPreviewHeaders #mail-index_previewAttachmentArea.visible {
background-position: left top;
background-repeat: no-repeat;
}
.mail_subscription_header {
.mail_subscription_header,
.mail_folder_management_header {
font-weight: bold;
font-size: 150%;
padding-bottom: 20px;
}
#mail-subscribe table.et2_grid tr td {
#mail-subscribe table.et2_grid tr td,
#mail-folder_management table.et2_grid tr td {
padding: 0px;
}
#mail-subscribe table.et2_grid tr td div.et2_box {
#mail-subscribe table.et2_grid tr td div.et2_box,
#mail-folder_management table.et2_grid tr td .mail_subscription_header {
height: 500px;
overflow: auto;
}
@ -1080,10 +1083,12 @@ body {
.egw_fw_ui_category_content .selectedTreeRow_lor {
background-color: #ffc200;
color: #1e1e1e;
text-decoration: none;
}
.egw_fw_ui_category_content .standartTreeRow_lor {
background-color: #f2f2f2;
background-color: rgba(103, 159, 210, 0.2);
color: #1e1e1e;
text-decoration: none;
}
/* ##################################################################################
* E-Mail Dialog "Compose"
@ -1670,11 +1675,13 @@ div#displayToolbar-menulist img {
*
* ##################################################################################
*/
#mail-subscribe table.et2_grid tr td {
#mail-subscribe table.et2_grid tr td,
#mail-folder_management table.et2_grid tr td {
padding: 0px;
/*Label*/
}
#mail-subscribe table.et2_grid tr td .mail_subscription_header {
#mail-subscribe table.et2_grid tr td .mail_subscription_header,
#mail-folder_management table.et2_grid tr td .mail_subscription_header {
/*line-height: 270%;*/
margin: 0.6em 0 0;
font-weight: lighter;
@ -1683,12 +1690,28 @@ div#displayToolbar-menulist img {
font-size: 150%;
padding-bottom: 20px;
}
#mail-subscribe table.et2_grid tr td div.et2_box {
#mail-subscribe table.et2_grid tr td div.et2_box,
#mail-folder_management table.et2_grid tr td div.et2_box {
margin-top: 16px;
height: 484px;
overflow: auto;
}
.mail_subscription_header {
#mail-subscribe .selectedTreeRow,
#mail-folder_management .selectedTreeRow,
#mail-subscribe .selectedTreeRow_lor,
#mail-folder_management .selectedTreeRow_lor {
background-color: #ffc200;
color: #1e1e1e;
text-decoration: none;
}
#mail-subscribe .standartTreeRow_lor,
#mail-folder_management .standartTreeRow_lor {
background-color: rgba(103, 159, 210, 0.2);
color: #1e1e1e;
text-decoration: none;
}
.mail_subscription_header,
.mail_folder_management_header {
font-weight: bold;
font-size: 150%;
padding-bottom: 20px;

View File

@ -287,9 +287,9 @@ body {
// color - selected tree item
.selectedTreeRow, .selectedTreeRow_lor {background-color: @egw_color_1_a; color: @gray_90;}
.selectedTreeRow, .selectedTreeRow_lor {background-color: @egw_color_1_a; color: @gray_90;text-decoration: none;}
.standartTreeRow_lor {background-color: @gray_5; color: @gray_90;}
.standartTreeRow_lor {background-color: rgba(103, 159, 210, 0.2); color: @gray_90;text-decoration: none;}
/*new mail in FOlder
span.standartTreeRow b {color: @egw_color_2_a;}
*/
@ -863,7 +863,7 @@ div#displayToolbar-menulist{
*
* ##################################################################################
*/
#mail-subscribe{
#mail-subscribe, #mail-folder_management{
table.et2_grid tr td {
padding: 0px;
@ -891,13 +891,13 @@ div#displayToolbar-menulist{
}
// color - selected tree item
.selectedTreeRow,.selectedTreeRow_lor {background-color: @egw_color_1_a; color: @gray_90;}
.selectedTreeRow,.selectedTreeRow_lor {background-color: @egw_color_1_a; color: @gray_90;text-decoration: none;}
// color - hover over standard tree item
.standartTreeRow_lor {background-color: @gray_5; color: @gray_90;}
.standartTreeRow_lor {background-color: rgba(103, 159, 210, 0.2); color: @gray_90;text-decoration: none;}
} // #mail-subscribe
.mail_subscription_header
.mail_subscription_header, .mail_folder_management_header
{
font-weight: bold;
font-size: 150%;