diff --git a/NEWS b/NEWS index 80bd1a16c..3007c204e 100644 --- a/NEWS +++ b/NEWS @@ -7,7 +7,8 @@ New features Enchancements - major refactoring of the GCS component saving code (dropped OGoContentStore) - printing calendars in colors is now possible in all views; list, daily, weekly and multicolumns - - new option to print calendars events and tasks with a background color or with a border color + - new option to print calendars events and tasks with a background color or with a border color + - labels tagging only make one AJAX call for all the selected messages instead of one AJAX call per message Bug fixes - fixed crasher when subscribing users to resources (#2892) diff --git a/UI/MailerUI/UIxMailActions.m b/UI/MailerUI/UIxMailActions.m index b21cd160f..71bb05f8f 100644 --- a/UI/MailerUI/UIxMailActions.m +++ b/UI/MailerUI/UIxMailActions.m @@ -203,74 +203,4 @@ return response; } -- (WOResponse *) addLabelAction -{ - WOResponse *response; - SOGoMailObject *co; - NSException *error; - NSArray *flags; - NSString *flag; - - flag = [[[self->context request] formValueForKey: @"flag"] fromCSSIdentifier]; - co = [self clientObject]; - flags = [NSArray arrayWithObject: flag]; - - error = [co addFlags: flags]; - if (error) - response = (WOResponse *) error; - else - response = [self responseWith204]; - - return response; -} - -- (WOResponse *) removeLabelAction -{ - WOResponse *response; - SOGoMailObject *co; - NSException *error; - NSArray *flags; - NSString *flag; - - flag = [[[self->context request] formValueForKey: @"flag"] fromCSSIdentifier]; - co = [self clientObject]; - flags = [NSArray arrayWithObject: flag]; - - error = [co removeFlags: flags]; - if (error) - response = (WOResponse *) error; - else - response = [self responseWith204]; - - return response; -} - -- (WOResponse *) removeAllLabelsAction -{ - NSMutableArray *flags; - WOResponse *response; - SOGoMailObject *co; - NSException *error; - NSDictionary *v; - - - co = [self clientObject]; - - v = [[[context activeUser] userDefaults] mailLabelsColors]; - - // We always unconditionally remove the Mozilla tags - flags = [NSMutableArray arrayWithObjects: @"$Label1", @"$Label2", @"$Label3", - @"$Label4", @"$Label5", nil]; - - [flags addObjectsFromArray: [v allKeys]]; - - error = [co removeFlags: flags]; - if (error) - response = (WOResponse *) error; - else - response = [self responseWith204]; - - return response; -} - @end diff --git a/UI/MailerUI/UIxMailFolderActions.m b/UI/MailerUI/UIxMailFolderActions.m index 0e1ca9123..91312d583 100644 --- a/UI/MailerUI/UIxMailFolderActions.m +++ b/UI/MailerUI/UIxMailFolderActions.m @@ -618,4 +618,70 @@ return response; } +- (WOResponse *) addOrRemoveLabelAction +{ + WOResponse *response; + WORequest *request; + SOGoMailFolder *co; + NSException *error; + NSArray *msgUIDs, *flags; + NSString *operation; + NSDictionary *content, *result; + BOOL addOrRemove; + NGImap4Client *client; + + request = [context request]; + content = [[request contentAsString] objectFromJSONString]; + flags = [NSArray arrayWithObject:[content objectForKey:@"flags"]]; + msgUIDs = [NSArray arrayWithArray:[content objectForKey:@"msgUIDs"]]; + operation = [content objectForKey:@"operation"]; + addOrRemove = ([operation isEqualToString:@"add"]? YES: NO); + + co = [self clientObject]; + client = [[co imap4Connection] client]; + [[co imap4Connection] selectFolder: [co imap4URL]]; + result = [client storeFlags:flags forUIDs:msgUIDs addOrRemove:addOrRemove]; + if ([[result valueForKey: @"result"] boolValue]) + response = [self responseWith204]; + else + response = [self responseWithStatus:500 andJSONRepresentation:result]; + + return response; +} + +- (WOResponse *) removeAllLabelsAction +{ + WOResponse *response; + WORequest *request; + SOGoMailFolder *co; + NGImap4Client *client; + NSArray *msgUIDs; + NSMutableArray *flags; + NSDictionary *v, *content, *result; + + request = [context request]; + content = [[request contentAsString] objectFromJSONString]; + msgUIDs = [NSArray arrayWithArray:[content objectForKey:@"msgUIDs"]]; + + // We always unconditionally remove the Mozilla tags + flags = [NSMutableArray arrayWithObjects: @"$Label1", @"$Label2", @"$Label3", + @"$Label4", @"$Label5", nil]; + + co = [self clientObject]; + v = [[[context activeUser] userDefaults] mailLabelsColors]; + [flags addObjectsFromArray: [v allKeys]]; + + client = [[co imap4Connection] client]; + [[co imap4Connection] selectFolder: [co imap4URL]]; + result = [client storeFlags:flags forUIDs:msgUIDs addOrRemove:NO]; + + if ([[result valueForKey: @"result"] boolValue]) + response = [self responseWith204]; + else + response = [self responseWithStatus:500 andJSONRepresentation:result]; + + return response; +} + + @end diff --git a/UI/MailerUI/product.plist b/UI/MailerUI/product.plist index 4956cf286..d35b9c5ae 100644 --- a/UI/MailerUI/product.plist +++ b/UI/MailerUI/product.plist @@ -181,6 +181,16 @@ pageName = "UIxMailUserRightsEditor"; actionName = "saveUserRights"; }; + addOrRemoveLabel = { + protectedBy = "View"; + actionClass = "UIxMailFolderActions"; + actionName = "addOrRemoveLabel"; + }; + removeAllLabels = { + protectedBy = "View"; + actionClass = "UIxMailFolderActions"; + actionName = "removeAllLabels"; + }; }; }; @@ -272,21 +282,6 @@ actionClass = "UIxMailActions"; actionName = "markMessageRead"; }; - addLabel = { - protectedBy = "View"; - actionClass = "UIxMailActions"; - actionName = "addLabel"; - }; - removeLabel = { - protectedBy = "View"; - actionClass = "UIxMailActions"; - actionName = "removeLabel"; - }; - removeAllLabels = { - protectedBy = "View"; - actionClass = "UIxMailActions"; - actionName = "removeAllLabels"; - }; }; }; diff --git a/UI/WebServerResources/MailerUI.js b/UI/WebServerResources/MailerUI.js index 3ce06319c..4e7567d0d 100644 --- a/UI/WebServerResources/MailerUI.js +++ b/UI/WebServerResources/MailerUI.js @@ -930,14 +930,28 @@ function openMailbox(mailbox, reload) { * Called from SOGoDataTable.render() */ function messageListCallback(row, data, isNew) { - var currentMessage = Mailer.currentMessages[Mailer.currentMailbox]; + var currentMessages = []; + if (!Object.isArray(document.menuTarget)) { + // Menu called from one selection in message list view + currentMessages.push(Mailer.currentMessages[Mailer.currentMailbox]); + } + else { + // Menu called from multiple selection in messages list view + var rows = $(document.menuTarget); + for (var i = 0; i < rows.length; i++) { + var _row = $(rows[i]); + if (_row) { + currentMessages.push(rows[i].substr(4)); + } + } + } row.id = data['rowID']; row.writeAttribute('labels', (data['labels']?data['labels']:"")); row.className = data['rowClasses']; row.show(); // make sure the row is visible // Restore previous selection - if (data['uid'] == currentMessage) + if (currentMessages.indexOf(String(data['uid'])) != -1) row.addClassName('_selected'); if (data['Thread']) @@ -2491,63 +2505,115 @@ function onMenuToggleMessageRead(event) { } function onMenuLabelNone() { - var messages = []; + var msgUIDs = []; + var url = ApplicationBaseURL + encodeURI(Mailer.currentMailbox); - if (document.menuTarget.tagName == "DIV") - // Menu called from message content view - messages.push(Mailer.currentMessages[Mailer.currentMailbox]); - else if (Object.isArray(document.menuTarget)) + if (!Object.isArray(document.menuTarget)) { + if (document.menuTarget.tagName == "DIV") + // Menu called from message content view + msgUIDs.push(Mailer.currentMessages[Mailer.currentMailbox]); + + else + // Menu called from one selection in message list view + msgUIDs.push(document.menuTarget.getAttribute("id").substr(4)); + } + else { // Menu called from multiple selection in messages list view - $(document.menuTarget).collect(function(rowID) { - messages.push(rowID.substr(4)); - }); - else - // Menu called from one selection in messages list view - messages.push(document.menuTarget.getAttribute("id").substr(4)); + var rows = $(document.menuTarget); + for (var i = 0; i < rows.length; i++) { + var row = $(rows[i]); + if (row) { + msgUIDs.push(rows[i].substr(4)); + } + } + } - var url = ApplicationBaseURL + encodeURI(Mailer.currentMailbox) + "/"; - messages.each(function(id) { - triggerAjaxRequest(url + id + "/removeAllLabels", - messageFlagCallback, - { mailbox: Mailer.currentMailbox, msg: id, label: null } ); - }); + var callbackData = { mailbox: Mailer.currentMailbox, msgUIDs: msgUIDs }; + var content = { mailbox: Mailer.currentMailbox, msgUIDs: msgUIDs }; + content = Object.toJSON(content); + triggerAjaxRequest(url + "/removeAllLabels", messageFlagCallback, callbackData, content); } function onMenuLabelFlag() { - var messages = new Hash(); - var flag = this.readAttribute("data-name"); + var url = ApplicationBaseURL + encodeURI(Mailer.currentMailbox); + var operation = "add"; + var msgUIDs = []; + var msgLabels; - if (document.menuTarget.tagName == "DIV") - // Menu called from message content view - messages.set(Mailer.currentMessages[Mailer.currentMailbox], - $('row_' + Mailer.currentMessages[Mailer.currentMailbox]).getAttribute("labels")); - else if (Object.isArray(document.menuTarget)) - // Menu called from multiple selection in messages list view - $(document.menuTarget).collect(function(rowID) { - var row = $(rowID); - if (row) - messages.set(rowID.substr(4), - row.getAttribute("labels")); - }); - else - // Menu called from one selection in messages list view - messages.set(document.menuTarget.getAttribute("id").substr(4), - document.menuTarget.getAttribute("labels")); - - var url = ApplicationBaseURL + encodeURI(Mailer.currentMailbox) + "/"; - messages.keys().each(function(id) { - var flags = messages.get(id).split(" "); - var operation = "add"; - + if (!Object.isArray(document.menuTarget)) { + msgUIDs.push(Mailer.currentMessages[Mailer.currentMailbox]); + if (document.menuTarget.tagName == "DIV") + // Menu called from message content view + msgLabels = $('row_' + msgUIDs[0]).getAttribute("labels"); + else + // Menu called from one selection in messages list view + msgLabels = document.menuTarget.getAttribute("labels"); + + var flags = msgLabels.split(" "); if (flags.indexOf(flag) > -1) operation = "remove"; + } + else { + // Menu called from multiple selection in messages list view + var rows = $(document.menuTarget); + var blockedOperation = false; + for (var i = 0; i < rows.length; i++) { + var row = $(rows[i]); + if (row) { + msgUIDs.push(rows[i].substr(4)); + msgLabels = row.getAttribute("labels"); + + var flags = msgLabels.split(" "); + if (flags.indexOf(flag) > -1 && !blockedOperation) { + operation = "remove"; + } + else { + blockedOperation = true; + operation = "add"; + } + } + } + } - triggerAjaxRequest(url + id + "/" + operation + "Label?flag=" + flag.asCSSIdentifier(), - messageFlagCallback, - { mailbox: Mailer.currentMailbox, msg: id, - label: operation + flag } ); - }); + var callbackData = { mailbox: Mailer.currentMailbox, operation: operation, flag: flag, msgUIDs: msgUIDs}; + var content = {flags: flag.asCSSIdentifier(), msgUIDs: msgUIDs, operation: operation}; + content = Object.toJSON(content); + triggerAjaxRequest(url + "/addOrRemoveLabel", messageFlagCallback, callbackData, content); +} + +function messageFlagCallback(http) { + if (http.readyState == 4 + && isHttpStatus204(http.status)) { + var data = http.callbackData; + if (data["mailbox"] == Mailer.currentMailbox) { + var msgUIDs = data["msgUIDs"]; + for (var i = 0; i < msgUIDs.length; i++) { + Mailer.dataTable.invalidate(msgUIDs[i]); + var row = $("row_" + msgUIDs[i]); + var operation = data["operation"]; + if (operation) { + var labels = row.getAttribute("labels"); + var flags = []; + if (labels.length > 0) + flags = labels.split(" "); + if (operation == "add") { + if (flags.indexOf(data["flag"]) == -1) + flags.push(data["flag"]); + } + else { + // Remove flag + var flag = data["flag"]; + var idx = flags.indexOf(flag); + flags.splice(idx, 1); + } + row.writeAttribute("labels", flags.join(" ")); + } + else + row.writeAttribute("labels", ""); + } + } + } } function onMenuToggleMessageFlag(event) { @@ -2602,35 +2668,6 @@ function folderRefreshCallback(http) { } } -function messageFlagCallback(http) { - if (http.readyState == 4 - && isHttpStatus204(http.status)) { - var data = http.callbackData; - if (data["mailbox"] == Mailer.currentMailbox) { - Mailer.dataTable.invalidate(data["msg"]); - var row = $("row_" + data["msg"]); - var operation = data["label"]; - if (operation) { - var labels = row.getAttribute("labels"); - var flags = []; - if (labels.length > 0) - flags = labels.split(" "); - if (operation.substr(0, 3) == "add") - flags.push(operation.substr(3)); - else { - // Remove flag - var flag = operation.substr(6); - var idx = flags.indexOf(flag); - flags.splice(idx, 1); - } - row.writeAttribute("labels", flags.join(" ")); - } - else - row.writeAttribute("labels", ""); - } - } -} - function onMessageListMenuPrepareVisibility() { /* This method attaches the right mailbox-menu to the generic message list menu. */