Expose all email addresses in autocompletion

This change is immediately applicable to LDAP-based system address
books. However, personal SQL-based address books must have their quick
tables recreated. To do so, one must use sogo-tool to backup and restore
the user's data.

Resolves #3443, #3526
This commit is contained in:
Francis Lachapelle 2016-05-25 10:25:53 -04:00
parent 6dc80e1159
commit fd4b09428f
6 changed files with 103 additions and 28 deletions

3
NEWS
View file

@ -1,6 +1,9 @@
3.1.1 (2016-MM-DD) 3.1.1 (2016-MM-DD)
------------------ ------------------
Enhancements
- [web] expose all email addresses in autocompletion of message editor (#3443)
Bug fixes Bug fixes
- [web] fixed creation of chip on blur (sgTransformOnBlur directive) - [web] fixed creation of chip on blur (sgTransformOnBlur directive)
- [web] fixed composition of new messages from Contacts module - [web] fixed composition of new messages from Contacts module

View file

@ -294,7 +294,7 @@ convention:
ou = [ldifRecord objectForKey: @"ou"]; ou = [ldifRecord objectForKey: @"ou"];
if ([ou isKindOfClass: [NSArray class]]) if ([ou isKindOfClass: [NSArray class]])
units = [NSArray arrayWithArray: ou]; units = [NSArray arrayWithArray: (NSArray *)ou];
else if (ou) else if (ou)
units = [NSArray arrayWithObject: ou]; units = [NSArray arrayWithObject: ou];
else else
@ -723,6 +723,29 @@ convention:
return fn; return fn;
} }
- (NSArray *) emails
{
NSArray *elements;
NSMutableArray *emails;
NSString *email;
int i;
emails = [NSMutableArray array];
elements = [self childrenWithTag: @"email"];
for (i = [elements count]-1; i >= 0; i--)
{
email = [[elements objectAtIndex: i] flattenedValuesForKey: @""];
if ([email caseInsensitiveCompare: [self preferredEMail]] == NSOrderedSame)
// First element of array is the preferred email address
[emails insertObject: email atIndex: 0];
else
[emails addObject: email];
}
return emails;
}
- (NSArray *) secondaryEmails - (NSArray *) secondaryEmails
{ {
NSMutableArray *emails; NSMutableArray *emails;
@ -849,10 +872,12 @@ convention:
value = [self preferredTel]; value = [self preferredTel];
if (value) if (value)
[fields setObject: value forKey: @"c_telephonenumber"]; [fields setObject: value forKey: @"c_telephonenumber"];
value = [self preferredEMail]; v = [self emails];
if (![value isNotNull]) if ([v count] > 0)
value = @""; [fields setObject: [v componentsJoinedByString: @","]
[fields setObject: value forKey: @"c_mail"]; forKey: @"c_mail"];
else
[fields setObject: [NSNull null] forKey: @"c_mail"];
element = [self org]; element = [self org];
[fields setObject: [element flattenedValueAtIndex: 0 forKey: @""] [fields setObject: [element flattenedValueAtIndex: 0 forKey: @""]
forKey: @"c_o"]; forKey: @"c_o"];

View file

@ -264,9 +264,23 @@ static NSArray *folderListingFields = nil;
data = [contactRecord objectForKey: @"c_mail"]; data = [contactRecord objectForKey: @"c_mail"];
if ([data length]) if ([data length])
{ {
NSArray *values;
NSDictionary *email; NSDictionary *email;
email = [NSDictionary dictionaryWithObjectsAndKeys: @"pref", @"type", data, @"value", nil]; NSMutableArray *emails;
[contactRecord setObject: [NSArray arrayWithObject: email] forKey: @"emails"]; NSString *type, *value;
int i, max;
values = [data componentsSeparatedByString: @","];
max = [values count];
emails = [NSMutableArray arrayWithCapacity: max];
for (i = 0; i < max; i++)
{
type = (i == 0)? @"pref" : @"home";
value = [values objectAtIndex: i];
email = [NSDictionary dictionaryWithObjectsAndKeys: type, @"type", value, @"value", nil];
[emails addObject: email];
}
[contactRecord setObject: emails forKey: @"emails"];
} }
else else
{ {

View file

@ -64,7 +64,7 @@
md-selected-item="editor.autocomplete.to.selected" md-selected-item="editor.autocomplete.to.selected"
md-items="user in editor.contactFilter(editor.autocomplete.to.searchText)" md-items="user in editor.contactFilter(editor.autocomplete.to.searchText)"
md-min-length="3" md-min-length="3"
md-delay="300" md-delay="150"
md-no-cache="true" md-no-cache="true"
label:placeholder="Add a recipient"> label:placeholder="Add a recipient">
<md-item-template> <md-item-template>

View file

@ -424,6 +424,27 @@
return this.refs.length - 1; return this.refs.length - 1;
}; };
/**
* @function explode
* @memberof Card.prototype
* @desc Create a new Card associated to each email address of this card.
* @return an array of Card instances
*/
Card.prototype.explode = function() {
var _this = this, cards = [], data;
if (this.emails.length > 1) {
data = this.$omit();
_.forEach(this.emails, function(email) {
var card = new Card(angular.extend({}, data, {emails: [email]}));
cards.push(card);
});
return cards;
}
else
return [this];
};
/** /**
* @function $reset * @function $reset
* @memberof Card.prototype * @memberof Card.prototype

View file

@ -197,8 +197,20 @@
} }
function contactFilter($query) { function contactFilter($query) {
AddressBook.$filterAll($query); return AddressBook.$filterAll($query).then(function(cards) {
return AddressBook.$cards; // Divide the matching cards by email addresses so the user can select
// the recipient address of her choice
var explodedCards = [];
_.forEach(_.invokeMap(cards, 'explode'), function(manyCards) {
_.forEach(manyCards, function(card) {
explodedCards.push(card);
});
});
// Remove duplicates
return _.uniqBy(explodedCards, function(card) {
return card.$$fullname + ' ' + card.$$email;
});
});
} }
function addRecipient(contact, field) { function addRecipient(contact, field) {