2016-03-03 19:38:54 +01:00
|
|
|
/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2014-09-19 02:46:52 +02:00
|
|
|
|
2014-06-19 21:47:33 +02:00
|
|
|
(function() {
|
2014-09-19 02:46:52 +02:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @name AddressBook
|
|
|
|
* @constructor
|
2014-11-25 22:13:53 +01:00
|
|
|
* @param {object} futureAddressBookData - either an object literal or a promise
|
2014-09-19 02:46:52 +02:00
|
|
|
*/
|
|
|
|
function AddressBook(futureAddressBookData) {
|
|
|
|
// Data is immediately available
|
|
|
|
if (typeof futureAddressBookData.then !== 'function') {
|
2015-04-24 14:45:39 +02:00
|
|
|
this.init(futureAddressBookData);
|
2014-09-19 02:46:52 +02:00
|
|
|
if (this.name && !this.id) {
|
|
|
|
// Create a new addressbook on the server
|
|
|
|
var newAddressBookData = AddressBook.$$resource.create('createFolder', this.name);
|
|
|
|
this.$unwrap(newAddressBookData);
|
2016-01-15 16:25:13 +01:00
|
|
|
this.acls = {'objectEditor': 1, 'objectCreator': 1, 'objectEraser': 1};
|
2014-09-19 02:46:52 +02:00
|
|
|
}
|
2014-11-03 18:19:35 +01:00
|
|
|
else if (this.id) {
|
2014-12-12 19:39:02 +01:00
|
|
|
this.$acl = new AddressBook.$$Acl('Contacts/' + this.id);
|
2014-10-17 17:01:56 +02:00
|
|
|
}
|
2014-09-19 02:46:52 +02:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
// The promise will be unwrapped first
|
|
|
|
this.$unwrap(futureAddressBookData);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-23 17:52:47 +02:00
|
|
|
/**
|
|
|
|
* @memberof AddressBook
|
|
|
|
* @desc The factory we'll use to register with Angular
|
|
|
|
* @returns the AddressBook constructor
|
|
|
|
*/
|
2016-02-20 05:19:07 +01:00
|
|
|
AddressBook.$factory = ['$q', '$timeout', '$log', 'sgSettings', 'sgAddressBook_PRELOAD', 'Resource', 'Card', 'Acl', 'Preferences', function($q, $timeout, $log, Settings, AddressBook_PRELOAD, Resource, Card, Acl, Preferences) {
|
2014-09-19 02:46:52 +02:00
|
|
|
angular.extend(AddressBook, {
|
|
|
|
$q: $q,
|
|
|
|
$timeout: $timeout,
|
2015-01-08 22:11:07 +01:00
|
|
|
$log: $log,
|
2016-02-20 05:19:07 +01:00
|
|
|
PRELOAD: AddressBook_PRELOAD,
|
2015-08-03 17:53:54 +02:00
|
|
|
$$resource: new Resource(Settings.activeUser('folderURL') + 'Contacts', Settings.activeUser()),
|
2014-10-17 17:01:56 +02:00
|
|
|
$Card: Card,
|
2014-11-03 21:58:54 +01:00
|
|
|
$$Acl: Acl,
|
2015-07-31 01:47:53 +02:00
|
|
|
$Preferences: Preferences,
|
2017-11-21 21:56:16 +01:00
|
|
|
$query: {value: '', sort: 'c_cn', asc: 1},
|
2015-08-03 22:18:23 +02:00
|
|
|
activeUser: Settings.activeUser(),
|
2015-07-31 01:47:53 +02:00
|
|
|
selectedFolder: null,
|
|
|
|
$refreshTimeout: null
|
2014-09-19 02:46:52 +02:00
|
|
|
});
|
2015-08-14 21:22:59 +02:00
|
|
|
// Initialize sort parameters from user's settings
|
2017-06-01 19:46:57 +02:00
|
|
|
if (Preferences.settings.Contact.SortingState) {
|
|
|
|
AddressBook.$query.sort = Preferences.settings.Contact.SortingState[0];
|
|
|
|
AddressBook.$query.asc = parseInt(Preferences.settings.Contact.SortingState[1]);
|
|
|
|
}
|
|
|
|
|
2014-09-19 02:46:52 +02:00
|
|
|
return AddressBook; // return constructor
|
|
|
|
}];
|
|
|
|
|
2015-07-29 17:47:01 +02:00
|
|
|
/**
|
|
|
|
* @module SOGo.ContactsUI
|
|
|
|
* @desc Factory registration of AddressBook in Angular module.
|
|
|
|
*/
|
|
|
|
try {
|
|
|
|
angular.module('SOGo.ContactsUI');
|
|
|
|
}
|
|
|
|
catch(e) {
|
2015-10-09 22:01:06 +02:00
|
|
|
angular.module('SOGo.ContactsUI', ['SOGo.Common', 'SOGo.PreferencesUI']);
|
2015-07-29 17:47:01 +02:00
|
|
|
}
|
2014-09-19 02:46:52 +02:00
|
|
|
angular.module('SOGo.ContactsUI')
|
2016-02-20 05:19:07 +01:00
|
|
|
.constant('sgAddressBook_PRELOAD', {
|
|
|
|
LOOKAHEAD: 50,
|
|
|
|
SIZE: 100
|
|
|
|
})
|
2015-05-06 04:06:13 +02:00
|
|
|
.factory('AddressBook', AddressBook.$factory);
|
2014-09-23 17:52:47 +02:00
|
|
|
|
2014-12-12 19:39:02 +01:00
|
|
|
/**
|
|
|
|
* @memberof AddressBook
|
|
|
|
* @desc Search for cards among all addressbooks matching some criterias.
|
|
|
|
* @param {string} search - the search string to match
|
2014-12-18 22:30:59 +01:00
|
|
|
* @param {object} [options] - additional options to the query (excludeGroups and excludeLists)
|
2015-08-05 22:44:25 +02:00
|
|
|
* @param {object[]} excludedCards - a list of Card objects that must be excluded from the results
|
2014-12-12 19:39:02 +01:00
|
|
|
* @returns a collection of Cards instances
|
|
|
|
*/
|
2015-08-05 22:44:25 +02:00
|
|
|
AddressBook.$filterAll = function(search, options, excludedCards) {
|
2016-02-10 15:32:44 +01:00
|
|
|
var params = { search: search };
|
2014-12-12 19:39:02 +01:00
|
|
|
|
2015-08-05 22:44:25 +02:00
|
|
|
if (!search) {
|
|
|
|
// No query specified
|
|
|
|
AddressBook.$cards = [];
|
|
|
|
return AddressBook.$q.when(AddressBook.$cards);
|
|
|
|
}
|
|
|
|
if (angular.isUndefined(AddressBook.$cards)) {
|
|
|
|
// First session query
|
|
|
|
AddressBook.$cards = [];
|
|
|
|
}
|
|
|
|
|
2014-12-12 19:39:02 +01:00
|
|
|
angular.extend(params, options);
|
2015-08-05 22:44:25 +02:00
|
|
|
|
2014-12-12 19:39:02 +01:00
|
|
|
return AddressBook.$$resource.fetch(null, 'allContactSearch', params).then(function(response) {
|
2015-08-05 22:44:25 +02:00
|
|
|
var results, card, index,
|
|
|
|
compareIds = function(data) {
|
|
|
|
return this.id == data.id;
|
|
|
|
};
|
|
|
|
if (excludedCards) {
|
|
|
|
// Remove excluded cards from results
|
|
|
|
results = _.filter(response.contacts, function(data) {
|
2016-03-03 19:38:54 +01:00
|
|
|
return _.isUndefined(_.find(excludedCards, _.bind(compareIds, data)));
|
2015-08-05 22:44:25 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
results = response.contacts;
|
|
|
|
}
|
|
|
|
// Remove cards that no longer match the search query
|
|
|
|
for (index = AddressBook.$cards.length - 1; index >= 0; index--) {
|
|
|
|
card = AddressBook.$cards[index];
|
2016-03-03 19:38:54 +01:00
|
|
|
if (_.isUndefined(_.find(results, _.bind(compareIds, card)))) {
|
2015-08-05 22:44:25 +02:00
|
|
|
AddressBook.$cards.splice(index, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Add new cards matching the search query
|
2016-03-03 19:38:54 +01:00
|
|
|
_.forEach(results, function(data, index) {
|
|
|
|
if (_.isUndefined(_.find(AddressBook.$cards, _.bind(compareIds, data)))) {
|
2016-06-16 22:21:24 +02:00
|
|
|
var card = new AddressBook.$Card(_.mapKeys(data, function(value, key) {
|
|
|
|
return key.toLowerCase();
|
|
|
|
}), search);
|
2015-08-05 22:44:25 +02:00
|
|
|
AddressBook.$cards.splice(index, 0, card);
|
|
|
|
}
|
2014-12-12 19:39:02 +01:00
|
|
|
});
|
2015-09-15 03:35:34 +02:00
|
|
|
AddressBook.$log.debug(AddressBook.$cards);
|
2015-08-05 22:44:25 +02:00
|
|
|
return AddressBook.$cards;
|
2014-12-12 19:39:02 +01:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2014-09-23 17:52:47 +02:00
|
|
|
/**
|
|
|
|
* @memberof AddressBook
|
|
|
|
* @desc Add a new addressbook to the static list of addressbooks
|
|
|
|
* @param {AddressBook} addressbook - an Addressbook object instance
|
|
|
|
*/
|
|
|
|
AddressBook.$add = function(addressbook) {
|
|
|
|
// Insert new addressbook at proper index
|
2015-04-24 14:45:39 +02:00
|
|
|
var list, sibling, i;
|
2014-11-03 18:19:35 +01:00
|
|
|
|
2015-04-24 14:45:39 +02:00
|
|
|
list = addressbook.isSubscription? this.$subscriptions : this.$addressbooks;
|
|
|
|
sibling = _.find(list, function(o) {
|
2015-07-24 22:14:53 +02:00
|
|
|
return (addressbook.id == 'personal' ||
|
|
|
|
(o.id != 'personal' &&
|
|
|
|
o.name.localeCompare(addressbook.name) === 1));
|
2014-09-23 17:52:47 +02:00
|
|
|
});
|
2016-03-03 19:38:54 +01:00
|
|
|
i = sibling ? _.indexOf(_.map(list, 'id'), sibling.id) : 1;
|
2015-04-24 14:45:39 +02:00
|
|
|
list.splice(i, 0, addressbook);
|
2014-09-23 17:52:47 +02:00
|
|
|
};
|
2014-09-19 02:46:52 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @memberof AddressBook
|
2015-07-31 01:47:53 +02:00
|
|
|
* @desc Set or get the list of addressbooks. Will instantiate a new AddressBook object for each item.
|
2014-09-19 02:46:52 +02:00
|
|
|
* @param {array} [data] - the metadata of the addressbooks
|
|
|
|
* @returns the list of addressbooks
|
|
|
|
*/
|
2014-09-23 17:52:47 +02:00
|
|
|
AddressBook.$findAll = function(data) {
|
2014-09-29 17:06:46 +02:00
|
|
|
var _this = this;
|
2014-09-19 02:46:52 +02:00
|
|
|
if (data) {
|
2015-04-24 14:45:39 +02:00
|
|
|
this.$addressbooks = [];
|
|
|
|
this.$subscriptions = [];
|
|
|
|
this.$remotes = [];
|
2014-09-19 02:46:52 +02:00
|
|
|
// Instanciate AddressBook objects
|
2015-04-24 14:45:39 +02:00
|
|
|
angular.forEach(data, function(o, i) {
|
|
|
|
var addressbook = new AddressBook(o);
|
|
|
|
if (addressbook.isRemote)
|
|
|
|
_this.$remotes.push(addressbook);
|
|
|
|
else if (addressbook.isSubscription)
|
|
|
|
_this.$subscriptions.push(addressbook);
|
|
|
|
else
|
|
|
|
_this.$addressbooks.push(addressbook);
|
2014-09-19 02:46:52 +02:00
|
|
|
});
|
|
|
|
}
|
2015-08-21 01:37:30 +02:00
|
|
|
return _.union(this.$addressbooks, this.$subscriptions, this.$remotes);
|
2014-09-19 02:46:52 +02:00
|
|
|
};
|
|
|
|
|
2014-11-11 17:14:55 +01:00
|
|
|
/**
|
|
|
|
* @memberOf AddressBook
|
|
|
|
* @desc Subscribe to another user's addressbook and add it to the list of addressbooks.
|
2014-11-25 22:13:53 +01:00
|
|
|
* @param {string} uid - user id
|
|
|
|
* @param {string} path - path of folder for specified user
|
2014-11-11 17:14:55 +01:00
|
|
|
* @returns a promise of the HTTP query result
|
|
|
|
*/
|
|
|
|
AddressBook.$subscribe = function(uid, path) {
|
|
|
|
var _this = this;
|
|
|
|
return AddressBook.$$resource.userResource(uid).fetch(path, 'subscribe').then(function(addressbookData) {
|
|
|
|
var addressbook = new AddressBook(addressbookData);
|
2015-07-24 22:14:53 +02:00
|
|
|
if (_.isUndefined(_.find(_this.$subscriptions, function(o) {
|
2014-11-11 17:14:55 +01:00
|
|
|
return o.id == addressbookData.id;
|
2015-07-24 22:14:53 +02:00
|
|
|
}))) {
|
2015-04-24 14:45:39 +02:00
|
|
|
// Not already subscribed
|
2014-11-11 17:14:55 +01:00
|
|
|
AddressBook.$add(addressbook);
|
|
|
|
}
|
|
|
|
return addressbook;
|
|
|
|
});
|
|
|
|
};
|
2014-09-19 02:46:52 +02:00
|
|
|
|
2016-11-08 18:24:56 +01:00
|
|
|
/**
|
|
|
|
* @memberof AddressBook
|
|
|
|
* @desc Reload the list of known addressbooks.
|
|
|
|
*/
|
|
|
|
AddressBook.$reloadAll = function() {
|
|
|
|
var _this = this;
|
|
|
|
|
|
|
|
return AddressBook.$$resource.fetch('addressbooksList').then(function(data) {
|
|
|
|
_.forEach(data.addressbooks, function(addressbookData) {
|
|
|
|
var group, addressbook;
|
|
|
|
|
|
|
|
if (addressbookData.isRemote)
|
|
|
|
group = _this.$remotes;
|
|
|
|
else if (addressbookData.owner != AddressBook.activeUser.login)
|
|
|
|
group = _this.$subscriptions;
|
|
|
|
else
|
|
|
|
group = _this.$addressbooks;
|
|
|
|
|
|
|
|
addressbook = _.find(group, function(o) { return o.id == addressbookData.id; });
|
|
|
|
if (addressbook)
|
|
|
|
addressbook.init(addressbookData);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2015-04-24 14:45:39 +02:00
|
|
|
/**
|
|
|
|
* @function init
|
|
|
|
* @memberof AddressBook.prototype
|
|
|
|
* @desc Extend instance with new data and compute additional attributes.
|
|
|
|
* @param {object} data - attributes of addressbook
|
|
|
|
*/
|
2015-11-09 20:46:30 +01:00
|
|
|
AddressBook.prototype.init = function(data, options) {
|
2016-02-20 05:19:07 +01:00
|
|
|
var _this = this;
|
|
|
|
if (!this.$$cards) {
|
|
|
|
// Array of cards for "dry" searches (see $filter)
|
|
|
|
this.$$cards = [];
|
2015-11-09 20:46:30 +01:00
|
|
|
}
|
2016-02-20 05:19:07 +01:00
|
|
|
this.idsMap = {};
|
2016-09-27 21:19:24 +02:00
|
|
|
this.$cards = [];
|
2016-02-20 05:19:07 +01:00
|
|
|
// Extend instance with all attributes of data except headers
|
|
|
|
angular.forEach(data, function(value, key) {
|
|
|
|
if (key != 'headers' && key != 'cards') {
|
|
|
|
_this[key] = value;
|
|
|
|
}
|
|
|
|
});
|
2015-04-24 14:45:39 +02:00
|
|
|
// Add 'isOwned' and 'isSubscription' attributes based on active user (TODO: add it server-side?)
|
|
|
|
this.isOwned = AddressBook.activeUser.isSuperUser || this.owner == AddressBook.activeUser.login;
|
|
|
|
this.isSubscription = !this.isRemote && this.owner != AddressBook.activeUser.login;
|
|
|
|
};
|
|
|
|
|
2014-11-11 17:14:55 +01:00
|
|
|
/**
|
|
|
|
* @function $id
|
|
|
|
* @memberof AddressBook.prototype
|
|
|
|
* @desc Resolve the addressbook id.
|
|
|
|
* @returns a promise of the addressbook id
|
|
|
|
*/
|
2014-09-19 02:46:52 +02:00
|
|
|
AddressBook.prototype.$id = function() {
|
2015-05-28 19:48:45 +02:00
|
|
|
if (this.id) {
|
|
|
|
// Object already unwrapped
|
|
|
|
return AddressBook.$q.when(this.id);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Wait until object is unwrapped
|
|
|
|
return this.$futureAddressBookData.then(function(addressbook) {
|
|
|
|
return addressbook.id;
|
|
|
|
});
|
|
|
|
}
|
2014-09-19 02:46:52 +02:00
|
|
|
};
|
|
|
|
|
2016-02-20 05:19:07 +01:00
|
|
|
/**
|
|
|
|
* @function getLength
|
|
|
|
* @memberof AddressBook.prototype
|
|
|
|
* @desc Used by md-virtual-repeat / md-on-demand
|
|
|
|
* @returns the number of cards in the addressbook
|
|
|
|
*/
|
|
|
|
AddressBook.prototype.getLength = function() {
|
|
|
|
return this.$cards.length;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @function getItemAtIndex
|
|
|
|
* @memberof AddressBook.prototype
|
|
|
|
* @desc Used by md-virtual-repeat / md-on-demand
|
|
|
|
* @returns the card at the specified index
|
|
|
|
*/
|
|
|
|
AddressBook.prototype.getItemAtIndex = function(index) {
|
|
|
|
var card;
|
|
|
|
|
|
|
|
if (!this.$isLoading && index >= 0 && index < this.$cards.length) {
|
|
|
|
card = this.$cards[index];
|
|
|
|
this.$lastVisibleIndex = Math.max(0, index - 3); // Magic number is NUM_EXTRA from virtual-repeater.js
|
|
|
|
|
|
|
|
if (this.$loadCard(card))
|
|
|
|
return card;
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @function $loadCard
|
|
|
|
* @memberof AddressBook.prototype
|
|
|
|
* @desc Check if the card is loaded and in any case, fetch more cards headers from the server.
|
|
|
|
* @returns true if the card metadata are already fetched
|
|
|
|
*/
|
|
|
|
AddressBook.prototype.$loadCard = function(card) {
|
|
|
|
var cardId = card.id,
|
|
|
|
startIndex = this.idsMap[cardId],
|
|
|
|
endIndex,
|
|
|
|
index,
|
|
|
|
max = this.$cards.length,
|
|
|
|
loaded = false,
|
|
|
|
ids,
|
|
|
|
futureHeadersData;
|
|
|
|
|
|
|
|
if (angular.isUndefined(this.ids) && card.id) {
|
|
|
|
loaded = true;
|
|
|
|
}
|
|
|
|
else if (angular.isDefined(startIndex) && startIndex < this.$cards.length) {
|
|
|
|
// Index is valid
|
|
|
|
if (card.$loaded != AddressBook.$Card.STATUS.NOT_LOADED) {
|
|
|
|
// Card headers are loaded or data is coming
|
|
|
|
loaded = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Preload more headers if possible
|
|
|
|
endIndex = Math.min(startIndex + AddressBook.PRELOAD.LOOKAHEAD, max - 1);
|
|
|
|
if (this.$cards[endIndex].$loaded != AddressBook.$Card.STATUS.NOT_LOADED) {
|
|
|
|
index = Math.max(startIndex - AddressBook.PRELOAD.LOOKAHEAD, 0);
|
|
|
|
if (this.$cards[index].$loaded != AddressBook.$Card.STATUS.LOADED) {
|
|
|
|
// Previous cards not loaded; preload more headers further up
|
|
|
|
endIndex = startIndex;
|
|
|
|
startIndex = Math.max(startIndex - AddressBook.PRELOAD.SIZE, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
// Next cards not load; preload more headers further down
|
|
|
|
endIndex = Math.min(startIndex + AddressBook.PRELOAD.SIZE, max - 1);
|
|
|
|
|
|
|
|
if (this.$cards[startIndex].$loaded == AddressBook.$Card.STATUS.NOT_LOADED ||
|
|
|
|
this.$cards[endIndex].$loaded == AddressBook.$Card.STATUS.NOT_LOADED) {
|
|
|
|
|
|
|
|
for (ids = []; startIndex < endIndex && startIndex < max; startIndex++) {
|
|
|
|
if (this.$cards[startIndex].$loaded != AddressBook.$Card.STATUS.NOT_LOADED) {
|
|
|
|
// Card at this index is already loaded; increase the end index
|
|
|
|
endIndex++;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Card at this index will be loaded
|
|
|
|
ids.push(this.$cards[startIndex].id);
|
|
|
|
this.$cards[startIndex].$loaded = AddressBook.$Card.STATUS.LOADING;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
AddressBook.$log.debug('Loading Ids ' + ids.join(' ') + ' (' + ids.length + ' cards)');
|
|
|
|
if (ids.length > 0) {
|
|
|
|
futureHeadersData = AddressBook.$$resource.post(this.id, 'headers', {ids: ids});
|
|
|
|
this.$unwrapHeaders(futureHeadersData);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return loaded;
|
|
|
|
};
|
|
|
|
|
2016-08-05 22:08:04 +02:00
|
|
|
/**
|
|
|
|
* @function hasSelectedMessage
|
|
|
|
* @memberof AddressBook.prototype
|
|
|
|
* @desc Check if a card is selected.
|
|
|
|
* @returns true if the a card is selected
|
|
|
|
*/
|
|
|
|
AddressBook.prototype.hasSelectedCard = function() {
|
|
|
|
return angular.isDefined(this.selectedCard);
|
|
|
|
};
|
|
|
|
|
2015-12-21 17:40:01 +01:00
|
|
|
/**
|
|
|
|
* @function isSelectedCard
|
|
|
|
* @memberof AddressBook.prototype
|
|
|
|
* @desc Check if the specified card is selected.
|
|
|
|
* @param {string} CardId
|
|
|
|
* @returns true if the specified card is selected
|
|
|
|
*/
|
|
|
|
AddressBook.prototype.isSelectedCard = function(cardId) {
|
2016-08-05 22:08:04 +02:00
|
|
|
return this.hasSelectedCard() && this.selectedCard == cardId;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @function $selectedCard
|
|
|
|
* @memberof AddressBook.prototype
|
|
|
|
* @desc Return the currently visible card.
|
|
|
|
* @returns a Card instance or undefined if no card is displayed
|
|
|
|
*/
|
|
|
|
AddressBook.prototype.$selectedCard = function() {
|
|
|
|
var _this = this;
|
|
|
|
|
|
|
|
return _.find(this.$cards, function(card) { return card.id == _this.selectedCard; });
|
|
|
|
};
|
|
|
|
|
2016-09-27 21:19:24 +02:00
|
|
|
/**
|
|
|
|
* @function $selectedCardIndex
|
|
|
|
* @memberof AddressBook.prototype
|
|
|
|
* @desc Return the index of the currently visible card.
|
|
|
|
* @returns a number or undefined if no card is selected
|
|
|
|
*/
|
|
|
|
AddressBook.prototype.$selectedCardIndex = function() {
|
|
|
|
return _.indexOf(_.map(this.$cards, 'id'), this.selectedCard);
|
|
|
|
};
|
|
|
|
|
2016-08-05 22:08:04 +02:00
|
|
|
/**
|
|
|
|
* @function $selectedCards
|
|
|
|
* @memberof AddressBook.prototype
|
|
|
|
* @desc Return the cards selected by the user.
|
|
|
|
* @returns Card instances
|
|
|
|
*/
|
|
|
|
AddressBook.prototype.$selectedCards = function() {
|
|
|
|
return _.filter(this.$cards, function(card) { return card.selected; });
|
2015-12-21 17:40:01 +01:00
|
|
|
};
|
|
|
|
|
2015-05-08 22:42:46 +02:00
|
|
|
/**
|
|
|
|
* @function $selectedCount
|
|
|
|
* @memberof AddressBook.prototype
|
|
|
|
* @desc Return the number of cards selected by the user.
|
|
|
|
* @returns the number of selected cards
|
|
|
|
*/
|
|
|
|
AddressBook.prototype.$selectedCount = function() {
|
|
|
|
var count;
|
|
|
|
|
|
|
|
count = 0;
|
2016-02-20 05:19:07 +01:00
|
|
|
if (this.$cards) {
|
|
|
|
count = (_.filter(this.$cards, function(card) { return card.selected; })).length;
|
2015-05-08 22:42:46 +02:00
|
|
|
}
|
|
|
|
return count;
|
|
|
|
};
|
|
|
|
|
2015-07-31 01:47:53 +02:00
|
|
|
/**
|
|
|
|
* @function $startRefreshTimeout
|
|
|
|
* @memberof AddressBook.prototype
|
|
|
|
* @desc Starts the refresh timeout for the current selected address book
|
2015-07-31 15:05:56 +02:00
|
|
|
*/
|
2015-07-31 01:47:53 +02:00
|
|
|
AddressBook.prototype.$startRefreshTimeout = function() {
|
|
|
|
if (AddressBook.$refreshTimeout)
|
|
|
|
AddressBook.$timeout.cancel(AddressBook.$refreshTimeout);
|
|
|
|
|
2017-06-01 19:46:57 +02:00
|
|
|
// Restart the refresh timer, if needed
|
|
|
|
var refreshViewCheck = AddressBook.$Preferences.defaults.SOGoRefreshViewCheck;
|
|
|
|
if (refreshViewCheck && refreshViewCheck != 'manually') {
|
|
|
|
var f = angular.bind(this, AddressBook.prototype.$reload);
|
|
|
|
AddressBook.$refreshTimeout = AddressBook.$timeout(f, refreshViewCheck.timeInterval()*1000);
|
|
|
|
}
|
2015-07-31 01:47:53 +02:00
|
|
|
};
|
|
|
|
|
2014-09-19 02:46:52 +02:00
|
|
|
/**
|
2015-05-28 19:48:45 +02:00
|
|
|
* @function $reload
|
|
|
|
* @memberof AddressBook.prototype
|
|
|
|
* @desc Reload list of cards
|
|
|
|
* @returns a promise of the Cards instances
|
|
|
|
*/
|
|
|
|
AddressBook.prototype.$reload = function() {
|
|
|
|
var _this = this;
|
|
|
|
|
2015-07-31 01:47:53 +02:00
|
|
|
this.$startRefreshTimeout();
|
2015-08-27 20:09:43 +02:00
|
|
|
return this.$filter();
|
2015-05-28 19:48:45 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2014-09-19 02:46:52 +02:00
|
|
|
* @function $filter
|
|
|
|
* @memberof AddressBook.prototype
|
|
|
|
* @desc Search for cards matching some criterias
|
|
|
|
* @param {string} search - the search string to match
|
2016-01-15 16:07:59 +01:00
|
|
|
* @param {object} [options] - additional options to the query (dry, excludeList)
|
2014-09-19 02:46:52 +02:00
|
|
|
* @returns a collection of Cards instances
|
|
|
|
*/
|
2015-07-16 22:26:09 +02:00
|
|
|
AddressBook.prototype.$filter = function(search, options, excludedCards) {
|
2016-02-20 05:19:07 +01:00
|
|
|
var _this = this, query,
|
|
|
|
dry = options && options.dry;
|
2015-05-28 19:48:45 +02:00
|
|
|
|
2016-02-20 05:19:07 +01:00
|
|
|
if (dry) {
|
2016-01-15 16:07:59 +01:00
|
|
|
// Don't keep a copy of the query in dry mode
|
2017-12-04 21:36:29 +01:00
|
|
|
query = {value: '', sort: 'c_cn', asc: 1};
|
2016-01-15 16:07:59 +01:00
|
|
|
}
|
2016-02-20 05:19:07 +01:00
|
|
|
else {
|
|
|
|
this.$isLoading = true;
|
|
|
|
query = AddressBook.$query;
|
|
|
|
if (!this.isRemote) query.partial = 1;
|
|
|
|
}
|
2015-08-27 20:09:43 +02:00
|
|
|
|
2017-06-01 19:46:57 +02:00
|
|
|
if (options) {
|
|
|
|
angular.extend(query, options);
|
|
|
|
if (dry) {
|
|
|
|
if (!search) {
|
|
|
|
// No query specified
|
|
|
|
_this.$$cards = [];
|
|
|
|
return AddressBook.$q.when(_this.$$cards);
|
2015-05-27 21:06:42 +02:00
|
|
|
}
|
|
|
|
}
|
2017-06-01 19:46:57 +02:00
|
|
|
}
|
2015-07-20 20:24:36 +02:00
|
|
|
|
2017-06-01 19:46:57 +02:00
|
|
|
if (angular.isDefined(search))
|
|
|
|
query.value = search;
|
|
|
|
|
|
|
|
return _this.$id().then(function(addressbookId) {
|
2017-11-21 21:56:16 +01:00
|
|
|
var futureData = AddressBook.$$resource.post(addressbookId, 'view', query);
|
2017-06-01 19:46:57 +02:00
|
|
|
|
|
|
|
if (dry) {
|
|
|
|
return futureData.then(function(response) {
|
|
|
|
var results, headers, card, index, fields, idFieldIndex,
|
|
|
|
cards = _this.$$cards,
|
|
|
|
compareIds = function(card) {
|
|
|
|
return this == card.id;
|
|
|
|
};
|
|
|
|
|
|
|
|
if (response.headers) {
|
|
|
|
// First entry of 'headers' are keys
|
|
|
|
fields = _.invokeMap(response.headers[0], 'toLowerCase');
|
|
|
|
idFieldIndex = fields.indexOf('id');
|
|
|
|
response.headers.splice(0, 1);
|
2017-12-04 21:36:29 +01:00
|
|
|
results = _.map(response.headers, function(data) {
|
|
|
|
return data[idFieldIndex];
|
|
|
|
});
|
2017-06-01 19:46:57 +02:00
|
|
|
}
|
2016-02-20 05:19:07 +01:00
|
|
|
|
2017-12-04 21:36:29 +01:00
|
|
|
if (response.ids) {
|
|
|
|
if (excludedCards)
|
|
|
|
// Remove excluded cards from results
|
|
|
|
results = _.filter(response.ids, function(id) {
|
|
|
|
return _.isUndefined(_.find(excludedCards, _.bind(compareIds, id)));
|
|
|
|
});
|
|
|
|
else
|
|
|
|
results = response.ids;
|
|
|
|
}
|
2017-06-01 19:46:57 +02:00
|
|
|
|
|
|
|
// Remove cards that no longer match the search query
|
|
|
|
for (index = cards.length - 1; index >= 0; index--) {
|
|
|
|
card = cards[index];
|
|
|
|
if (_.isUndefined(_.find(results, _.bind(compareIds, card.id)))) {
|
|
|
|
cards.splice(index, 1);
|
|
|
|
}
|
|
|
|
}
|
2016-02-20 05:19:07 +01:00
|
|
|
|
2017-06-01 19:46:57 +02:00
|
|
|
// Add new cards matching the search query
|
|
|
|
_.forEach(results, function(cardId, index) {
|
|
|
|
if (_.isUndefined(_.find(cards, _.bind(compareIds, cardId)))) {
|
|
|
|
var data = { pid: addressbookId, id: cardId };
|
|
|
|
var card = new AddressBook.$Card(data, search);
|
|
|
|
cards.splice(index, 0, card);
|
|
|
|
}
|
|
|
|
});
|
2016-02-20 05:19:07 +01:00
|
|
|
|
2017-06-01 19:46:57 +02:00
|
|
|
// Respect the order of the results
|
|
|
|
_.forEach(results, function(cardId, index) {
|
|
|
|
var oldIndex, removedCards;
|
|
|
|
if (cards[index].id != cardId) {
|
|
|
|
oldIndex = _.findIndex(cards, _.bind(compareIds, cardId));
|
|
|
|
removedCards = cards.splice(oldIndex, 1);
|
|
|
|
cards.splice(index, 0, removedCards[0]);
|
|
|
|
}
|
|
|
|
});
|
2016-02-20 05:19:07 +01:00
|
|
|
|
2017-06-01 19:46:57 +02:00
|
|
|
// Extend Card objects with received headers
|
|
|
|
_.forEach(response.headers, function(data) {
|
|
|
|
var card, index = _.findIndex(cards, _.bind(compareIds, data[idFieldIndex]));
|
|
|
|
if (index > -1) {
|
|
|
|
card = _.zipObject(fields, data);
|
|
|
|
cards[index].init(card, search);
|
|
|
|
}
|
2015-08-14 21:22:59 +02:00
|
|
|
});
|
2017-06-01 19:46:57 +02:00
|
|
|
|
|
|
|
return cards;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Unwrap promise and instantiate or extend Cards objets
|
|
|
|
return _this.$unwrap(futureData);
|
|
|
|
}
|
2015-05-28 19:48:45 +02:00
|
|
|
});
|
2014-09-19 02:46:52 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @function $rename
|
|
|
|
* @memberof AddressBook.prototype
|
2015-01-08 22:11:07 +01:00
|
|
|
* @desc Rename the addressbook and keep the list sorted
|
2014-09-19 02:46:52 +02:00
|
|
|
* @param {string} name - the new name
|
|
|
|
* @returns a promise of the HTTP operation
|
|
|
|
*/
|
|
|
|
AddressBook.prototype.$rename = function(name) {
|
2016-12-02 20:48:59 +01:00
|
|
|
var i, list;
|
|
|
|
|
|
|
|
list = this.isSubscription? AddressBook.$subscriptions : AddressBook.$addressbooks;
|
|
|
|
i = _.indexOf(_.map(list, 'id'), this.id);
|
2014-09-19 02:46:52 +02:00
|
|
|
this.name = name;
|
2016-12-02 20:48:59 +01:00
|
|
|
list.splice(i, 1);
|
2014-09-19 02:46:52 +02:00
|
|
|
AddressBook.$add(this);
|
2016-12-02 20:48:59 +01:00
|
|
|
|
2014-09-19 02:46:52 +02:00
|
|
|
return this.$save();
|
|
|
|
};
|
|
|
|
|
2014-11-25 22:13:53 +01:00
|
|
|
/**
|
|
|
|
* @function $delete
|
|
|
|
* @memberof AddressBook.prototype
|
|
|
|
* @desc Delete the addressbook from the server and the static list of addressbooks.
|
|
|
|
* @returns a promise of the HTTP operation
|
|
|
|
*/
|
2014-09-19 02:46:52 +02:00
|
|
|
AddressBook.prototype.$delete = function() {
|
2014-11-03 18:19:35 +01:00
|
|
|
var _this = this,
|
2014-11-11 17:14:55 +01:00
|
|
|
d = AddressBook.$q.defer(),
|
2015-04-24 14:45:39 +02:00
|
|
|
list,
|
2014-11-11 17:14:55 +01:00
|
|
|
promise;
|
|
|
|
|
2015-04-24 14:45:39 +02:00
|
|
|
if (this.isSubscription) {
|
2014-11-11 17:14:55 +01:00
|
|
|
promise = AddressBook.$$resource.fetch(this.id, 'unsubscribe');
|
2015-04-24 14:45:39 +02:00
|
|
|
list = AddressBook.$subscriptions;
|
|
|
|
}
|
|
|
|
else {
|
2014-11-12 16:44:43 +01:00
|
|
|
promise = AddressBook.$$resource.remove(this.id);
|
2015-04-24 14:45:39 +02:00
|
|
|
list = AddressBook.$addressbooks;
|
|
|
|
}
|
2014-11-11 17:14:55 +01:00
|
|
|
|
|
|
|
promise.then(function() {
|
2016-03-03 19:38:54 +01:00
|
|
|
var i = _.indexOf(_.map(list, 'id'), _this.id);
|
2015-04-24 14:45:39 +02:00
|
|
|
list.splice(i, 1);
|
|
|
|
d.resolve();
|
2015-12-14 18:19:15 +01:00
|
|
|
}, d.reject);
|
2014-09-19 02:46:52 +02:00
|
|
|
return d.promise;
|
|
|
|
};
|
|
|
|
|
2016-08-05 22:08:04 +02:00
|
|
|
/**
|
|
|
|
* @function $_deleteCards
|
|
|
|
* @memberof AddressBook.prototype
|
|
|
|
* @desc Delete multiple cards from AddressBook object.
|
|
|
|
* @param {string[]} ids - the cards ids
|
|
|
|
*/
|
|
|
|
AddressBook.prototype.$_deleteCards = function(ids) {
|
|
|
|
var _this = this;
|
|
|
|
|
|
|
|
// Remove cards from $cards and idsMap
|
|
|
|
_.forEachRight(this.$cards, function(card, index) {
|
|
|
|
var selectedIndex = _.findIndex(ids, function(id) {
|
|
|
|
return card.id == id;
|
|
|
|
});
|
|
|
|
if (selectedIndex > -1) {
|
|
|
|
ids.splice(selectedIndex, 1);
|
|
|
|
delete _this.idsMap[card.id];
|
|
|
|
if (_this.isSelectedCard(card.id))
|
|
|
|
delete _this.selectedCard;
|
|
|
|
_this.$cards.splice(index, 1);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
_this.idsMap[card.id] -= ids.length;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2015-05-08 21:47:09 +02:00
|
|
|
/**
|
|
|
|
* @function $deleteCards
|
|
|
|
* @memberof AddressBook.prototype
|
|
|
|
* @desc Delete multiple cards from addressbook.
|
|
|
|
* @return a promise of the HTTP operation
|
|
|
|
*/
|
|
|
|
AddressBook.prototype.$deleteCards = function(cards) {
|
2016-03-03 19:38:54 +01:00
|
|
|
var _this = this,
|
2016-08-05 22:08:04 +02:00
|
|
|
ids = _.map(cards, 'id');
|
2016-12-07 20:37:59 +01:00
|
|
|
|
2016-03-03 19:38:54 +01:00
|
|
|
return AddressBook.$$resource.post(this.id, 'batchDelete', {uids: ids}).then(function() {
|
2016-08-05 22:08:04 +02:00
|
|
|
_this.$_deleteCards(ids);
|
2015-05-08 21:47:09 +02:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2015-08-10 15:48:47 +02:00
|
|
|
/**
|
|
|
|
* @function $copyCards
|
|
|
|
* @memberof AddressBook.prototype
|
|
|
|
* @desc Copy multiple cards from addressbook to an other one.
|
|
|
|
* @return a promise of the HTTP operation
|
|
|
|
*/
|
|
|
|
AddressBook.prototype.$copyCards = function(cards, folder) {
|
2016-08-05 22:08:04 +02:00
|
|
|
var uids = _.map(cards, 'id');
|
2015-08-10 15:48:47 +02:00
|
|
|
return AddressBook.$$resource.post(this.id, 'copy', {uids: uids, folder: folder});
|
|
|
|
};
|
|
|
|
|
2016-08-05 22:08:04 +02:00
|
|
|
/**
|
|
|
|
* @function $moveCards
|
|
|
|
* @memberof AddressBook.prototype
|
|
|
|
* @desc Move multiple cards from the current addressbook to a target one
|
|
|
|
* @param {object[]} cards - instances of Card object
|
|
|
|
* @param {string} folder - the destination folder id
|
|
|
|
* @return a promise of the HTTP operation
|
|
|
|
*/
|
|
|
|
AddressBook.prototype.$moveCards = function(cards, folder) {
|
|
|
|
var _this = this, uids;
|
|
|
|
|
|
|
|
uids = _.map(cards, 'id');
|
|
|
|
return AddressBook.$$resource.post(this.id, 'move', {uids: uids, folder: folder})
|
|
|
|
.then(function() {
|
|
|
|
return _this.$_deleteCards(uids);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2014-11-25 22:13:53 +01:00
|
|
|
/**
|
|
|
|
* @function $save
|
|
|
|
* @memberof AddressBook.prototype
|
|
|
|
* @desc Save the addressbook to the server. This currently can only affect the name of the addressbook.
|
|
|
|
* @returns a promise of the HTTP operation
|
|
|
|
*/
|
2014-09-19 02:46:52 +02:00
|
|
|
AddressBook.prototype.$save = function() {
|
2014-11-03 18:19:35 +01:00
|
|
|
return AddressBook.$$resource.save(this.id, this.$omit()).then(function(data) {
|
2014-09-19 02:46:52 +02:00
|
|
|
return data;
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2016-05-04 20:15:18 +02:00
|
|
|
/**
|
|
|
|
* @function $exportCards
|
|
|
|
* @memberof AddressBook.prototype
|
|
|
|
* @desc Export the selected/all cards
|
|
|
|
* @returns a promise of the HTTP operation
|
|
|
|
*/
|
|
|
|
AddressBook.prototype.exportCards = function(selectedOnly) {
|
2016-12-07 20:37:59 +01:00
|
|
|
var data = null, options, selectedCards;
|
|
|
|
|
|
|
|
options = {
|
|
|
|
type: 'application/octet-stream',
|
|
|
|
filename: this.name + '.ldif'
|
|
|
|
};
|
2016-05-04 20:15:18 +02:00
|
|
|
|
|
|
|
if (selectedOnly) {
|
2016-12-07 20:37:59 +01:00
|
|
|
selectedCards = _.filter(this.$cards, function(card) { return card.selected; });
|
|
|
|
data = { uids: _.map(selectedCards, 'id') };
|
2016-05-04 20:15:18 +02:00
|
|
|
}
|
|
|
|
|
2018-05-16 22:46:00 +02:00
|
|
|
if (data) {
|
|
|
|
return AddressBook.$$resource.download(this.id, 'export', data, options);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return AddressBook.$$resource.open(this.id, 'export', data, options);
|
|
|
|
}
|
2016-05-04 20:15:18 +02:00
|
|
|
};
|
|
|
|
|
2014-11-25 22:13:53 +01:00
|
|
|
/**
|
|
|
|
* @function $unwrap
|
|
|
|
* @memberof AddressBook.prototype
|
|
|
|
* @desc Unwrap a promise and instanciate new Card objects using received data.
|
|
|
|
* @param {promise} futureAddressBookData - a promise of the AddressBook's data
|
|
|
|
*/
|
2014-09-19 02:46:52 +02:00
|
|
|
AddressBook.prototype.$unwrap = function(futureAddressBookData) {
|
2014-09-29 17:06:46 +02:00
|
|
|
var _this = this;
|
2014-09-19 02:46:52 +02:00
|
|
|
|
2016-02-20 05:19:07 +01:00
|
|
|
this.$isLoading = true;
|
|
|
|
|
2015-11-24 21:05:03 +01:00
|
|
|
// Expose and resolve the promise
|
2016-02-20 05:19:07 +01:00
|
|
|
this.$futureAddressBookData = futureAddressBookData.then(function(response) {
|
2015-05-28 19:48:45 +02:00
|
|
|
return AddressBook.$timeout(function() {
|
2016-02-20 05:19:07 +01:00
|
|
|
var headers;
|
|
|
|
|
|
|
|
if (!response.ids || _this.$topIndex > response.ids.length - 1)
|
|
|
|
_this.$topIndex = 0;
|
|
|
|
|
2015-05-28 19:48:45 +02:00
|
|
|
// Extend AddressBook instance from data of addressbooks list.
|
2014-09-19 02:46:52 +02:00
|
|
|
// Will inherit attributes such as isEditable and isRemote.
|
2014-09-23 17:52:47 +02:00
|
|
|
angular.forEach(AddressBook.$findAll(), function(o, i) {
|
2016-02-20 05:19:07 +01:00
|
|
|
if (o.id == response.id) {
|
2014-09-29 17:06:46 +02:00
|
|
|
angular.extend(_this, o);
|
2014-09-19 02:46:52 +02:00
|
|
|
}
|
2014-06-19 21:47:33 +02:00
|
|
|
});
|
2016-02-20 05:19:07 +01:00
|
|
|
|
2015-05-28 19:48:45 +02:00
|
|
|
// Extend AddressBook instance with received data
|
2016-02-20 05:19:07 +01:00
|
|
|
_this.init(response);
|
|
|
|
|
|
|
|
if (_this.ids) {
|
|
|
|
AddressBook.$log.debug('unwrapping ' + _this.ids.length + ' cards');
|
|
|
|
|
|
|
|
// Instanciate Card objects
|
|
|
|
_.reduce(_this.ids, function(cards, card, i) {
|
2016-05-30 18:29:58 +02:00
|
|
|
var data = { pid: _this.id, id: card };
|
2016-02-20 05:19:07 +01:00
|
|
|
|
|
|
|
// Build map of ID <=> index
|
|
|
|
_this.idsMap[data.id] = i;
|
|
|
|
|
|
|
|
cards.push(new AddressBook.$Card(data));
|
|
|
|
|
|
|
|
return cards;
|
|
|
|
}, _this.$cards);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (response.headers) {
|
|
|
|
// First entry of 'headers' are keys
|
2016-03-03 19:38:54 +01:00
|
|
|
headers = _.invokeMap(response.headers[0], 'toLowerCase');
|
2016-02-20 05:19:07 +01:00
|
|
|
response.headers.splice(0, 1);
|
|
|
|
|
|
|
|
if (_this.ids) {
|
|
|
|
// Extend Card objects with received headers
|
2016-03-03 19:38:54 +01:00
|
|
|
_.forEach(response.headers, function(data) {
|
|
|
|
var o = _.zipObject(headers, data),
|
2016-02-20 05:19:07 +01:00
|
|
|
i = _this.idsMap[o.id];
|
|
|
|
_this.$cards[i].init(o);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Instanciate Card objects
|
|
|
|
_this.$cards = [];
|
|
|
|
angular.forEach(response.headers, function(data) {
|
2016-03-03 19:38:54 +01:00
|
|
|
var o = _.zipObject(headers, data);
|
2016-06-06 16:32:45 +02:00
|
|
|
angular.extend(o, { pid: _this.id });
|
2016-02-20 05:19:07 +01:00
|
|
|
_this.$cards.push(new AddressBook.$Card(o));
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-17 17:01:56 +02:00
|
|
|
// Instanciate Acl object
|
2014-12-12 19:39:02 +01:00
|
|
|
_this.$acl = new AddressBook.$$Acl('Contacts/' + _this.id);
|
2015-07-31 01:47:53 +02:00
|
|
|
|
|
|
|
_this.$startRefreshTimeout();
|
|
|
|
|
2015-08-27 20:09:43 +02:00
|
|
|
_this.$isLoading = false;
|
|
|
|
|
2016-02-20 05:19:07 +01:00
|
|
|
AddressBook.$log.debug('addressbook ' + _this.id + ' ready');
|
|
|
|
|
2015-05-28 19:48:45 +02:00
|
|
|
return _this;
|
2014-09-19 02:46:52 +02:00
|
|
|
});
|
|
|
|
}, function(data) {
|
2015-01-08 22:11:07 +01:00
|
|
|
_this.isError = true;
|
|
|
|
if (angular.isObject(data)) {
|
|
|
|
AddressBook.$timeout(function() {
|
|
|
|
angular.extend(_this, data);
|
|
|
|
});
|
|
|
|
}
|
2014-09-19 02:46:52 +02:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2016-02-20 05:19:07 +01:00
|
|
|
/**
|
|
|
|
* @function $unwrapHeaders
|
|
|
|
* @memberof AddressBook.prototype
|
|
|
|
* @desc Unwrap a promise and extend matching Card objects with received data.
|
|
|
|
* @param {promise} futureHeadersData - a promise of the metadata of some cards
|
|
|
|
*/
|
|
|
|
AddressBook.prototype.$unwrapHeaders = function(futureHeadersData) {
|
|
|
|
var _this = this;
|
|
|
|
|
|
|
|
futureHeadersData.then(function(data) {
|
|
|
|
AddressBook.$timeout(function() {
|
|
|
|
var headers, j;
|
|
|
|
if (data.length > 0) {
|
|
|
|
// First entry of 'headers' are keys
|
2016-03-03 19:38:54 +01:00
|
|
|
headers = _.invokeMap(data[0], 'toLowerCase');
|
2016-02-20 05:19:07 +01:00
|
|
|
data.splice(0, 1);
|
2016-03-03 19:38:54 +01:00
|
|
|
_.forEach(data, function(cardHeaders) {
|
|
|
|
cardHeaders = _.zipObject(headers, cardHeaders);
|
2016-02-20 05:19:07 +01:00
|
|
|
j = _this.idsMap[cardHeaders.id];
|
|
|
|
if (angular.isDefined(j)) {
|
|
|
|
_this.$cards[j].init(cardHeaders);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2014-11-25 22:13:53 +01:00
|
|
|
/**
|
|
|
|
* @function $omit
|
|
|
|
* @memberof AddressBook.prototype
|
|
|
|
* @desc Return a sanitized object used to send to the server.
|
|
|
|
* @return an object literal copy of the Addressbook instance
|
|
|
|
*/
|
2014-09-19 02:46:52 +02:00
|
|
|
AddressBook.prototype.$omit = function() {
|
|
|
|
var addressbook = {};
|
|
|
|
angular.forEach(this, function(value, key) {
|
|
|
|
if (key != 'constructor' &&
|
2016-12-02 20:48:59 +01:00
|
|
|
key != 'acls' &&
|
2016-02-20 05:19:07 +01:00
|
|
|
key != 'ids' &&
|
2016-12-02 20:48:59 +01:00
|
|
|
key != 'idsMap' &&
|
|
|
|
key != 'urls' &&
|
2014-09-19 02:46:52 +02:00
|
|
|
key[0] != '$') {
|
|
|
|
addressbook[key] = value;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return addressbook;
|
|
|
|
};
|
2014-06-19 21:47:33 +02:00
|
|
|
})();
|