Initial JavaScript models for addressbooks module

pull/91/head
Francis Lachapelle 2014-06-19 15:47:33 -04:00
parent 3ad4352ffe
commit 825c45f872
2 changed files with 376 additions and 0 deletions

View File

@ -0,0 +1,135 @@
(function() {
'use strict';
function AddressBook(futureAddressBookData) {
/* DATA IS IMMEDIATELY AVAILABLE */
if (typeof futureAddressBookData.then !== 'function') {
angular.extend(this, futureAddressBookData);
return;
}
/* THE PROMISE WILL BE UNWRAPPED FIRST */
this.$unwrap(futureAddressBookData);
}
/* THE FACTORY WE'LL USE TO REGISTER WITH ANGULAR */
AddressBook.$factory = ['$timeout', 'sgSettings', 'sgResource', 'sgContact', function($timeout, Settings, Resource, Contact) {
angular.extend(AddressBook, {
$$resource: new Resource(Settings.baseURL),
$timeout: $timeout,
$Contact: Contact
});
return AddressBook; // return constructor
}];
/* ANGULAR MODULE REGISTRATION */
angular.module('SOGo').factory('sgAddressBook', AddressBook.$factory);
// AddressBook.$selectedId = function(addressbook_id) {
// if (addressbook_id) angular.extend(AddressBook, { $selected_id: addressbook_id });
// console.debug("selected id = " + AddressBook.$selected_id);
// return AddressBook.$selected_id;
// };
/* Fetch list of contacts */
AddressBook.$find = function(addressbook_id) {
var futureAddressBookData = this.$$resource.find(addressbook_id); // should return attributes of addressbook +
// AddressBook.$selectedId(addressbook_id);
return new AddressBook(futureAddressBookData);
};
// Instance methods
AddressBook.prototype.$id = function() {
var self = this;
return this.$futureAddressBookData.then(function(data) {
return data.id;
});
};
AddressBook.prototype.$getContact = function(contact_id) {
var self = this;
// return this.$futureAddressBookData.then(function(data) {
// return data.id;
// }).then(function(addressbook_id) {
return this.$id().then(function(addressbook_id) {
var contact = AddressBook.$Contact.$find(addressbook_id, contact_id);
AddressBook.$timeout(function() {
self.contact = contact;
});
return contact.$futureContactData.then(function() {
return self.contact;
});
});
};
AddressBook.prototype.$resetContact = function() {
this.$getContact(this.contact.id);
};
AddressBook.prototype.$viewerIsActive = function(editMode) {
return (typeof this.contact != "undefined" && !editMode);
};
// AddressBook.prototype.$getContacts = function() {
// var self = this;
// return AddressBook.$timeout(function() {
// var contacts = [];
// angular.forEach(self.contacts, function(addressBookContact, index) {
// var contact = AddressBook.$Contact.$find(addressBookContact.c_name);
// angular.extend(contact, addressBookContact); // useless?
// this.push(contact);
// }, contacts);
// AddressBook.$timeout(function() {
// self.contacts = contacts;
// });
// var futureContactData = [];
// angular.forEach(contacts, function(contact, index) {
// this.push(contact.$futureContactData);
// }, futureContactData);
// return this._q.all(futureContactData).then(function() {
// //self.$$emitter.emit('update');
// return self.contacts;
// });
// });
// };
// Unwrap a promise
AddressBook.prototype.$unwrap = function(futureAddressBookData) {
var self = this;
this.$futureAddressBookData = futureAddressBookData;
this.$futureAddressBookData.then(function(data) {
// The success callback. Calling _.extend from $timeout will wrap it into a try/catch call
// and return a promise.
AddressBook.$timeout(function() { angular.extend(self, data); });
});
};
// $omit returns a sanitized object used to send to the server
AddressBook.prototype.$omit = function() {
var addressbook = {};
angular.forEach(this, function(value, key) {
if (key != 'constructor' &&
key != 'contact' &&
key != 'contacts' &&
key[0] != '$') {
addressbook[key] = value;
}
});
console.debug(angular.toJson(addressbook));
return addressbook;
};
AddressBook.prototype.$save = function() {
return AddressBook.$$resource.set(this.id, this.$omit()).then(function (data) {
return data;
});
};
})();

View File

@ -0,0 +1,241 @@
(function() {
'use strict';
/* Constructor */
function Contact(futureContactData) {
/* DATA IS IMMEDIATELY AVAILABLE */
// if (!futureContactData.inspect) {
// angular.extend(this, futureContactData);
// return;
// }
/* THE PROMISE WILL BE UNWRAPPED FIRST */
this.$unwrap(futureContactData);
}
Contact.$tel_types = [_('work'), 'home', 'cell', 'fax', 'pager'];
Contact.$email_types = ['work', 'home', 'pref'];
Contact.$url_types = ['work', 'home', 'pref'];
Contact.$address_types = ['work', 'home'];
/* THE FACTORY WE'LL USE TO REGISTER WITH ANGULAR */
Contact.$factory = ['$timeout', 'sgSettings', 'sgResource', function($timeout, Settings, Resource) {
angular.extend(Contact, {
$$resource: new Resource(Settings.baseURL),
$timeout: $timeout
});
return Contact; // return constructor
}];
/* ANGULAR MODULE REGISTRATION */
angular.module('SOGo').factory('sgContact', Contact.$factory);
/* FETCH A UNIT */
Contact.$find = function(addressbook_id, contact_id) {
/* FALLS BACK ON AN INSTANCE OF RESOURCE */
// Fetch data over the wire.
var futureContactData = this.$$resource.find([addressbook_id, contact_id].join('/'));
if (contact_id) return new Contact(futureContactData); // a single contact
return Contact.$unwrapCollection(futureContactData); // a collection of contacts
};
// Instance methods
Contact.prototype.$id = function() {
//var self = this;
return this.$futureAddressBookData.then(function(data) {
return data.id;
});
};
// Unwrap a promise
Contact.prototype.$unwrap = function(futureContactData) {
var self = this;
this.$futureContactData = futureContactData;
this.$futureContactData.then(function(data) {
// The success callback. Calling _.extend from $timeout will wrap it into a try/catch call.
// I guess this is the only reason to do this.
Contact.$timeout(function() {
angular.extend(self, data);
});
});
};
Contact.prototype.$fullname = function() {
var fn = this.fn || '';
if (fn.length == 0) {
var names = [];
if (this.givenname && this.givenname.length > 0)
names.push(this.givenname);
if (this.nickname && this.nickname.length > 0)
names.push("<em>" + this.nickname + "</em>");
if (this.sn && this.sn.length > 0)
names.push(this.sn);
if (names.length > 0)
fn = names.join(' ');
else if (this.org && this.org.length > 0) {
fn = this.org;
}
else if (this.emails && this.emails.length > 0) {
fn = _.find(this.emails, function(i) { return i.value != ''; }).value;
}
}
return fn;
};
Contact.prototype.$description = function() {
var description = [];
if (this.title) description.push(this.title);
if (this.role) description.push(this.role);
if (this.orgUnits && this.orgUnits.length > 0)
_.forEach(this.orgUnits, function(unit) {
if (unit.value != '')
description.push(unit.value);
});
if (this.org) description.push(this.org);
if (this.description) description.push(this.description);
return description.join(', ');
};
Contact.prototype.$birthday = function() {
return new Date(this.birthday*1000);
};
Contact.prototype.$isContact = function() {
return this.tag == 'VCARD';
};
Contact.prototype.$isList = function() {
return this.tag == 'VLIST';
};
Contact.prototype.$delete = function(attribute, index) {
if (index > -1 && this[attribute].length > index) {
this[attribute].splice(index, 1);
}
};
Contact.prototype.$addOrgUnit = function(orgUnit) {
if (angular.isUndefined(this.orgUnits)) {
this.orgUnits = [{value: orgUnit}];
}
else {
console.debug(angular.toJson(this.orgUnits));
for (var i = 0; i < this.orgUnits.length; i++) {
if (this.orgUnits[i].value == orgUnit) {
break;
}
}
if (i == this.orgUnits.length)
this.orgUnits.push({value: orgUnit});
}
return this.orgUnits.length - 1;
};
Contact.prototype.$addCategory = function(category) {
if (angular.isUndefined(this.categories)) {
this.categories = [{value: category}];
}
else {
for (var i = 0; i < this.categories.length; i++) {
if (this.categories[i].value == category) {
break;
}
}
if (i == this.categories.length)
this.categories.push({value: category});
}
return this.categories.length - 1;
};
Contact.prototype.$addEmail = function(type) {
if (angular.isUndefined(this.emails)) {
this.emails = [{type: type, value: ''}];
}
else if (!_.find(this.emails, function(i) { return i.value == ''; })) {
this.emails.push({type: type, value: ''});
}
return this.emails.length - 1;
};
Contact.prototype.$addPhone = function(type) {
if (angular.isUndefined(this.phones)) {
this.phones = [{type: type, value: ''}];
}
else if (!_.find(this.phones, function(i) { return i.value == ''; })) {
this.phones.push({type: type, value: ''});
}
return this.phones.length - 1;
};
Contact.prototype.$addUrl = function(type, url) {
if (angular.isUndefined(this.urls)) {
this.urls = [{type: type, value: url}];
}
else if (!_.find(this.urls, function(i) { return i.value == url; })) {
this.urls.push({type: type, value: url});
}
return this.urls.length - 1;
};
Contact.prototype.$addAddress = function(type, postoffice, street, street2, locality, region, country, postalcode) {
if (angular.isUndefined(this.addresses)) {
this.addresses = [{type: type, postoffice: postoffice, street: street, street2: street2, locality: locality, region: region, country: country, postalcode: postalcode}];
}
else if (!_.find(this.addresses, function(i) {
return i.street == street
&& i.street2 == street2
&& i.locality == locality
&& i.country == country
&& i.postalcode == postalcode;
})) {
this.addresses.push({type: type, postoffice: postoffice, street: street, street2: street2, locality: locality, region: region, country: country, postalcode: postalcode});
}
return this.addresses.length - 1;
};
/* never call for now */
Contact.$unwrapCollection = function(futureContactData) {
var collection = {};
collection.$futureContactData = futureContactData;
futureContactData.then(function(contacts) {
Contact.$timeout(function() {
angular.forEach(contacts, function(data, index) {
collection[data.id] = new Contact(data);
});
});
});
return collection;
};
// $omit returns a sanitized object used to send to the server
Contact.prototype.$omit = function() {
var contact = {};
angular.forEach(this, function(value, key) {
if (key != 'constructor' && key[0] != '$') {
contact[key] = value;
}
});
console.debug(angular.toJson(contact));
return contact;
};
Contact.prototype.$save = function() {
return Contact.$$resource.set([this.pid, this.id].join('/'), this.$omit()).then(function (data) {
return data;
});
};
})();