Auto-completion of mail addresses in mail editor

This commit is contained in:
Francis Lachapelle
2014-12-12 13:39:02 -05:00
parent c2c15e4968
commit e2929f552f
8 changed files with 50 additions and 16 deletions

View File

@@ -111,6 +111,7 @@
"cc" = "Cc";
"bcc" = "Bcc";
"Add a recipient" = "Add a recipient";
"Edit Draft..." = "Edit Draft...";
"Load Images" = "Load Images";

View File

@@ -15,7 +15,8 @@
<label><var:string label:value="To"/>
<tags-input type="text" name="to"
ng-model="message.editable.to"
label:placeholder="Add a recipient"><!-- to --></tags-input></label>
label:placeholder="Add a recipient">
<auto-complete data-source="userFilter($query)"><!-- to --></auto-complete></tags-input></label>
<label><var:string label:value="Subject"/>
<input type="text" name="subject" ng-model="message.editable.subject"/></label>
<textarea name="content" var:class="editorClass" ng-model="message.editable.text"/>

View File

@@ -10,7 +10,7 @@
title="title"
const:userDefaultsKeys="SOGoMailMessageCheck,SOGoRefreshViewCheck,SOGoMailSortByThreads,SOGoMailListViewColumnsOrder,SOGoMailDisplayRemoteInlineImages,SOGoMailComposeMessageType,SOGoMailReplyPlacement"
const:userSettingsKeys="Mail"
const:jsFiles="Common/resource.js, Mailer/message-model.js, Mailer/mailbox-model.js, Mailer/account-model.js, vendor/ckeditor/ckeditor.js, vendor/ckeditor/ck.js, vendor/ng-tags-input.js, vendor/angular-file-upload.js"
const:jsFiles="Common/resource.js, Common/user-model.js, Common/acl-model.js, Contacts/card-model.js, Contacts/addressbook-model.js, Mailer/message-model.js, Mailer/mailbox-model.js, Mailer/account-model.js, vendor/ckeditor/ckeditor.js, vendor/ckeditor/ck.js, vendor/ng-tags-input.js, vendor/angular-file-upload.js"
const:cssFiles="ng-tags-input.css">
<script type="text/javascript">
var mailAccounts = <var:string value="mailAccounts" const:escapeHTML="NO"/>;

View File

@@ -19,7 +19,7 @@
angular.extend(Acl, {
$q: $q,
$timeout: $timeout,
$$resource: new Resource(Settings.baseURL),
$$resource: new Resource(Settings.baseURL, Settings.activeUser),
$User: User
});

View File

@@ -19,6 +19,8 @@
_activeUser: activeUser
});
angular.extend(this, options);
// Trim trailing slash
this._path = this._path.replace(/\/$/, '');
}
/**

View File

@@ -19,7 +19,7 @@
User.factory = ['$q', 'sgSettings', 'sgResource', function($q, Settings, Resource) {
angular.extend(User, {
$q: $q,
$$resource: new Resource(Settings.baseURL, Settings.activeUser)
$$resource: new Resource(Settings.activeUser.folderURL, Settings.activeUser)
});
return User;
@@ -34,7 +34,7 @@
/**
* @memberof User
* @desc Search for users that match a string.
* @param {String} search - a string used to performed the search
* @param {string} search - a string used to performed the search
* @return a promise of an array of matching User objects
*/
User.$filter = function(search) {
@@ -57,9 +57,10 @@
*/
User.prototype.$shortFormat = function(options) {
var fullname = this.cn || this.c_email;
var email = this.c_email;
var no_email = options && options.email === false;
if (!no_email && this.c_email && fullname != this.c_email) {
fullname += ' (' + this.c_email + ')';
if (!no_email && email && fullname != email) {
fullname += ' (' + email + ')';
}
return fullname;
};
@@ -68,7 +69,7 @@
* @function $acl
* @memberof User.prototype
* @desc Fetch the user rights associated to a specific folder and populate the 'rights' attribute.
* @param {String} the folder ID
* @param {string} the folder ID
* @return a promise
*/
User.prototype.$acl = function(folderId) {
@@ -154,7 +155,7 @@
* @function $resetRights
* @memberof User.prototype
* @desc Restore initial rights or disable all rights
* @param {Boolean} [zero] - reset all rights to zero when true
* @param {boolean} [zero] - reset all rights to zero when true
*/
User.prototype.$resetRights = function(zero) {
var _this = this;
@@ -173,8 +174,8 @@
/**
* @function $folders
* @memberof User.prototype
* @desc Retrive the list of folders of a specific type
* @param {String} type - either 'contact' or 'calendar'
* @desc Retrieve the list of folders of a specific type
* @param {string} type - either 'contact' or 'calendar'
* @return a promise of the HTTP query result or the cached result
*/
User.prototype.$folders = function(type) {

View File

@@ -18,7 +18,7 @@
this.$unwrap(newAddressBookData);
}
else if (this.id) {
this.$acl = new AddressBook.$$Acl(this.id);
this.$acl = new AddressBook.$$Acl('Contacts/' + this.id);
}
}
else {
@@ -36,7 +36,7 @@
angular.extend(AddressBook, {
$q: $q,
$timeout: $timeout,
$$resource: new Resource(Settings.baseURL, Settings.activeUser),
$$resource: new Resource(Settings.activeUser.folderURL + '/Contacts', Settings.activeUser),
$Card: Card,
$$Acl: Acl,
activeUser: Settings.activeUser
@@ -49,6 +49,27 @@
angular.module('SOGo.ContactsUI')
.factory('sgAddressBook', AddressBook.$factory);
/**
* @memberof AddressBook
* @desc Search for cards among all addressbooks matching some criterias.
* @param {string} search - the search string to match
* @param {hash} [options] - additional options to the query (excludeGroups and excludeLists)
* @returns a collection of Cards instances
*/
AddressBook.$filterAll = function(search, options) {
var params = {search: search};
angular.extend(params, options);
return AddressBook.$$resource.fetch(null, 'allContactSearch', params).then(function(response) {
var results = [];
angular.forEach(response.contacts, function(data) {
var card = new AddressBook.$Card(data);
results.push(card);
});
return results;
});
};
/**
* @memberof AddressBook
* @desc Add a new addressbook to the static list of addressbooks
@@ -270,7 +291,7 @@
_this.cards[i] = new AddressBook.$Card(o);
});
// Instanciate Acl object
_this.$acl = new AddressBook.$$Acl(_this.id);
_this.$acl = new AddressBook.$$Acl('Contacts/' + _this.id);
});
}, function(data) {
AddressBook.$timeout(function() {

View File

@@ -5,8 +5,9 @@
'use strict';
angular.module('SOGo.Common', []);
angular.module('SOGo.ContactsUI', []);
angular.module('SOGo.MailerUI', ['ngSanitize', 'ui.router', 'mm.foundation', 'vs-repeat', 'ck', 'ngTagsInput', 'SOGo.Common', 'SOGo.UICommon', 'SOGo.UIDesktop'])
angular.module('SOGo.MailerUI', ['ngSanitize', 'ui.router', 'mm.foundation', 'vs-repeat', 'ck', 'ngTagsInput', 'SOGo.Common', 'SOGo.UICommon', 'SOGo.UIDesktop', 'SOGo.ContactsUI'])
.constant('sgSettings', {
baseURL: ApplicationBaseURL,
@@ -229,7 +230,7 @@
};
}])
.controller('MessageEditorCtrl', ['$scope', '$rootScope', '$stateParams', '$state', 'stateAccounts', 'stateMessage', '$timeout', '$modal', 'sgFocus', 'sgDialog', 'sgAccount', 'sgMailbox', function($scope, $rootScope, $stateParams, $state, stateAccounts, stateMessage, $timeout, $modal, focus, Dialog, Account, Mailbox) {
.controller('MessageEditorCtrl', ['$scope', '$rootScope', '$stateParams', '$state', '$q', 'stateAccounts', 'stateMessage', '$timeout', '$modal', 'sgFocus', 'sgDialog', 'sgAccount', 'sgMailbox', 'sgAddressBook', function($scope, $rootScope, $stateParams, $state, $q, stateAccounts, stateMessage, $timeout, $modal, focus, Dialog, Account, Mailbox, AddressBook) {
if (angular.isDefined(stateMessage)) {
$scope.message = stateMessage;
}
@@ -242,6 +243,13 @@
console.debug('failure ' + JSON.stringify(data, undefined, 2));
});
};
$scope.userFilter = function($query) {
var deferred = $q.defer();
AddressBook.$filterAll($query).then(function(results) {
deferred.resolve(_.invoke(results, '$shortFormat'));
});
return deferred.promise;
};
}]);
})();