Contacts: Add possibility to add/delete objects
This commit is contained in:
parent
1c858e846d
commit
3e0965287a
|
@ -92,26 +92,41 @@
|
|||
<div data-ng-app="SOGo.Contacts">
|
||||
|
||||
<div data-ng-controller="AddressBookCtrl" data-ng-init="init()">
|
||||
|
||||
<!-- dropdown menu for addressbook options button -->
|
||||
<div id="addressbookProperties" class="f-dropdown icons-dropdown" data-dropdown-content="dropdown-content">
|
||||
<ul class="button-group">
|
||||
<li><span class="button"><i class="icon-hyperlink"><!-- links --></i></span></li>
|
||||
<li><span class="button"><i class="icon-pencil" data-ng-click="edit()"><!-- rename --></i></span></li>
|
||||
<li><span class="button" data-ng-click="sharing()"><i class="icon-earth"><!-- share --></i></span></li>
|
||||
<li><span class="button"><i class="icon-trash"><!-- delete --></i></span></li>
|
||||
<li>
|
||||
<span class="button"><i class="icon-hyperlink"><!-- links --></i></span>
|
||||
</li>
|
||||
<li data-ng-show="!addressbook.isRemote">
|
||||
<span class="button"><i class="icon-pencil" data-ng-click="edit()"><!-- rename --></i></span>
|
||||
</li>
|
||||
<li data-ng-show="!addressbook.isRemote">
|
||||
<span class="button" data-ng-click="share()"><i class="icon-earth"><!-- share --></i></span>
|
||||
</li>
|
||||
<li data-ng-show="!addressbook.isRemote">
|
||||
<span class="button" data-ng-click="confirmDelete(addressbook)"><i class="icon-trash"><!-- delete --></i></span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- dropdown menu for new card split button -->
|
||||
<ul id="newListDrop" class="f-dropdown">
|
||||
<li><a class="tiny" data-ui-sref="addressbook.new({addressbook_id: addressbook.id, contact_type: 'list'})"><var:string label:value="New List"/></a></li>
|
||||
</ul>
|
||||
|
||||
<!-- modal for addressbook sharing options -->
|
||||
<script type="text/ng-template" id="addressbookSharing.html">
|
||||
<h2>Sharing</h2>
|
||||
<p class="lead"></p>
|
||||
<p></p>
|
||||
<span class="close-reveal-modal" data-ng-click="closeModal()"><i class="icon-close"><!-- close --></i></span>
|
||||
</script>
|
||||
|
||||
<div id="addressbooksList" class="folders-list">
|
||||
<div class="newItemsToolbar">
|
||||
<a href="#" class="button tiny radius split"><var:string label:value="New Card"/><span data-dropdown-toggle="#newListDrop"></span></a><br/>
|
||||
<ul id="newListDrop" class="f-dropdown" data-dropdown-content="dropdown-content">
|
||||
<li><a href="#"><var:string label:value="New List"/></a></li>
|
||||
</ul>
|
||||
<a class="button tiny radius split" data-ui-sref="addressbook.new({addressbook_id: addressbook.id, contact_type: 'card'})"><var:string label:value="New Card"/><span data-dropdown-toggle="#newListDrop"></span></a><br/>
|
||||
</div>
|
||||
<ul id="contactFolders">
|
||||
<li data-ng-repeat="folder in addressbooks"
|
||||
|
@ -119,7 +134,7 @@
|
|||
data-ng-dblclick="edit($index)">
|
||||
<i class="icon" data-ng-class="{'icon-earth': folder.isRemote, 'icon-address-book': folder.isEditable}"><!-- icon --></i>
|
||||
<form data-ng-submit="save($index)">
|
||||
<a href="#/{{folder.id}}"
|
||||
<a data-ui-sref="addressbook({addressbook_id: folder.id})"
|
||||
data-ng-click="select($index)"
|
||||
data-ng-show="editMode!=folder.id"
|
||||
data-ng-cloak="ng-cloak">{{folder.name}}</a>
|
||||
|
@ -129,18 +144,18 @@
|
|||
data-ng-cloak="ng-cloak"
|
||||
data-sg-focus-on="addressBookName_{{$index}}"/>
|
||||
</form>
|
||||
<span data-ng-cloak="ng-cloak"><a class="icon" href="#" data-dropdown-toggle="#addressbookProperties" data-options="align:right" data-ng-show="addressbook.id==folder.id"><i class="icon-cog"><!-- options --></i></a></span>
|
||||
<span class="icon" data-ng-cloak="ng-cloak"><a class="icon" href="#" data-dropdown-toggle="#addressbookProperties" data-options="align:right" data-ng-show="addressbook.id==folder.id"><i class="icon-cog"><!-- options --></i></a></span>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="buttonsToolbar">
|
||||
<a href="#" class="button small" label:title="New Addressbook..."><i class="icon-plus"><!-- new --></i></a>
|
||||
<a href="#" class="button small" label:title="Subscribe to an Addressbook..."><i class="icon-earth"><!-- subscribe --></i></a>
|
||||
</div>
|
||||
<var:if condition="hasContactSelectionButtons">
|
||||
<!--<var:if condition="hasContactSelectionButtons">
|
||||
<div class="contactSelection">
|
||||
<var:component value="selectorComponent" />
|
||||
</div>
|
||||
</var:if>
|
||||
</var:if>-->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -169,20 +184,21 @@
|
|||
<div data-ng-switch-when="no-result" class="alert-bg">
|
||||
<i class="icon-ion-search"><!-- no result --></i><var:string label:value="No matching card"/>
|
||||
</div>
|
||||
<div data-ng-switch-when="remote-addressbook" class="alert-bg">
|
||||
<div data-ng-switch-when="remote-addressbook" data-ng-show="addressbook.cards.length == 0" class="alert-bg">
|
||||
<i class="icon-ion-search"><!-- search --></i><var:string label:value="Initiate a search"/>
|
||||
</div>
|
||||
</div>
|
||||
<ul>
|
||||
<li data-ng-repeat="card in addressbook.cards"
|
||||
data-ng-class="{_selected: addressbook.card.id==card.c_name}">
|
||||
<a href="#/{{addressbook.id}}/{{card.c_name}}">
|
||||
<span class="card-picture">
|
||||
<i data-ng-show="card.c_component == 'vcard'" class="icon-ion-ios7-person"><!-- card --></i>
|
||||
<i data-ng-show="card.c_component == 'vlist'" class="icon-ion-ios7-people"><!-- list --></i>
|
||||
data-ng-class="{_selected: addressbook.card.id == card.id}">
|
||||
<input type="checkbox" class="card-picture left"/>
|
||||
<a data-ui-sref="addressbook.card({addressbook_id: addressbook.id, card_id: card.id})">
|
||||
<span class="card-picture" data-ng-switch="card.tag">
|
||||
<i data-ng-switch-when="vcard" class="icon-ion-ios7-person"><!-- card --></i>
|
||||
<i data-ng-switch-when="vlist" class="icon-ion-ios7-people"><!-- list --></i>
|
||||
</span>
|
||||
<div class="name" data-ng-bind="card.c_cn"><!-- cn --></div>
|
||||
<div><span data-ng-show="card.c_mail"><i class="icon-ion-ios7-email-outline"><!-- email --></i> {{card.c_mail}}</span><var:entity const:name="nbsp" /></div>
|
||||
<div class="name" data-ng-bind-html="card.$fullname()"><!-- cn --></div>
|
||||
<div><span data-ng-show="card.emails"><i class="icon-ion-ios7-email-outline"><!-- email --></i> {{card.$preferredEmail()}}</span><var:entity const:name="nbsp" /></div>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -203,7 +219,7 @@
|
|||
<div class="buttonsToolbar">
|
||||
<span data-ng-show="addressbook.isEditable">
|
||||
<span class="button tiny radius" data-ng-click="edit()"><i class="icon-pencil"><!-- edit --></i></span>
|
||||
<span class="button tiny radius alert"><i class="icon-trash"><!-- delete --></i></span>
|
||||
<span class="button tiny radius alert" data-ng-click="confirmDelete(addressbook.card)"><i class="icon-trash"><!-- delete --></i></span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="attr" data-ng-show="addressbook.card.birthday">
|
||||
|
|
|
@ -2,18 +2,19 @@
|
|||
'use strict';
|
||||
|
||||
/* Constructor */
|
||||
function Resource($http, $q, path) {
|
||||
function Resource($http, $q, path, options) {
|
||||
angular.extend(this, {
|
||||
_http: $http,
|
||||
_q: $q,
|
||||
_path: path
|
||||
});
|
||||
angular.extend(this, options);
|
||||
}
|
||||
|
||||
/* The factory we'll use to register with Angular */
|
||||
Resource.$factory = ['$http', '$q', function($http, $q) {
|
||||
return function(path) {
|
||||
return new Resource($http, $q, path);
|
||||
return function(path, options) {
|
||||
return new Resource($http, $q, path, options);
|
||||
};
|
||||
}];
|
||||
|
||||
|
@ -29,7 +30,8 @@
|
|||
Resource.prototype.find = function(uid) {
|
||||
var deferred = this._q.defer();
|
||||
|
||||
this._http.get(this.path(uid))
|
||||
this._http
|
||||
.get(this.path(uid))
|
||||
.success(deferred.resolve)
|
||||
.error(deferred.reject);
|
||||
|
||||
|
@ -50,9 +52,22 @@
|
|||
return deferred.promise;
|
||||
};
|
||||
|
||||
Resource.prototype.set = function(uid, newValue) {
|
||||
Resource.prototype.newguid = function(uid) {
|
||||
var deferred = this._q.defer();
|
||||
var path = this._path + '/' + uid + '/save';
|
||||
var path = this._path + '/' + uid + '/newguid';
|
||||
|
||||
this._http
|
||||
.get(path)
|
||||
.success(deferred.resolve)
|
||||
.error(deferred.reject);
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
Resource.prototype.set = function(uid, newValue, options) {
|
||||
var deferred = this._q.defer();
|
||||
var action = (options && options.action)? options.action : 'save';
|
||||
var path = this._path + '/' + uid + '/' + action;
|
||||
|
||||
this._http
|
||||
.post(path, newValue)
|
||||
|
@ -62,4 +77,15 @@
|
|||
return deferred.promise;
|
||||
};
|
||||
|
||||
Resource.prototype.remove = function(uid) {
|
||||
var deferred = this._q.defer();
|
||||
var path = this._path + '/' + uid + '/delete';
|
||||
|
||||
this._http
|
||||
.get(path)
|
||||
.success(deferred.resolve)
|
||||
.error(deferred.reject);
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
})();
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
/* Factory registration in Angular module */
|
||||
angular.module('SOGo.Contacts').factory('sgAddressBook', AddressBook.$factory);
|
||||
|
||||
/* Set or get the list of addressbooks */
|
||||
AddressBook.$all = function(data) {
|
||||
if (data) {
|
||||
this.$addressbooks = data;
|
||||
|
@ -34,10 +35,10 @@
|
|||
return this.$addressbooks;
|
||||
};
|
||||
|
||||
/* Fetch list of cards */
|
||||
/* Fetch list of cards and return an AddressBook instance */
|
||||
AddressBook.$find = function(addressbook_id) {
|
||||
var futureAddressBookData = AddressBook.$$resource.find(addressbook_id); // should return attributes of addressbook +
|
||||
// AddressBook.$selectedId(addressbook_id);
|
||||
var futureAddressBookData = AddressBook.$$resource.find(addressbook_id);
|
||||
|
||||
return new AddressBook(futureAddressBookData);
|
||||
};
|
||||
|
||||
|
@ -59,32 +60,35 @@
|
|||
return this.$id().then(function(addressbook_id) {
|
||||
var futureAddressBookData = AddressBook.$$resource.filter(addressbook_id, params);
|
||||
return futureAddressBookData.then(function(data) {
|
||||
return AddressBook.$timeout(function() {
|
||||
self.cards = data.cards;
|
||||
return self.cards;
|
||||
self.cards = data.cards;
|
||||
// Instanciate Card objects
|
||||
angular.forEach(self.cards, function(o, i) {
|
||||
self.cards[i] = new AddressBook.$Card(o);
|
||||
});
|
||||
return self.cards;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
AddressBook.prototype.$delete = function() {
|
||||
return AddressBook.$$resource.remove(this.id);
|
||||
};
|
||||
|
||||
AddressBook.prototype.$save = function() {
|
||||
return AddressBook.$$resource.set(this.id, this.$omit()).then(function (data) {
|
||||
return data;
|
||||
});
|
||||
};
|
||||
|
||||
AddressBook.prototype.$getCard = function(card_id) {
|
||||
var self = this;
|
||||
return this.$id().then(function(addressbook_id) {
|
||||
var card = AddressBook.$Card.$find(addressbook_id, card_id);
|
||||
|
||||
AddressBook.$timeout(function() {
|
||||
self.card = card;
|
||||
});
|
||||
|
||||
return card.$futureCardData.then(function() {
|
||||
angular.forEach(self.cards, function(o, i) {
|
||||
if (o.c_name == card_id) {
|
||||
angular.extend(self.card, o);
|
||||
}
|
||||
});
|
||||
|
||||
return self.card;
|
||||
self.card = AddressBook.$Card.$find(addressbook_id, card_id);
|
||||
self.card.$id().catch(function() {
|
||||
// Card not found
|
||||
self.card = null;
|
||||
});
|
||||
return self.card;
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -93,7 +97,7 @@
|
|||
};
|
||||
|
||||
AddressBook.prototype.$viewerIsActive = function(editMode) {
|
||||
return (!angular.isUndefined(this.card) && !editMode);
|
||||
return (this.card != null && !editMode);
|
||||
};
|
||||
|
||||
// Unwrap a promise
|
||||
|
@ -104,12 +108,16 @@
|
|||
this.$futureAddressBookData.then(function(data) {
|
||||
AddressBook.$timeout(function() {
|
||||
angular.extend(self, data);
|
||||
self.$id().then(function(addressbook_id) {
|
||||
angular.forEach(AddressBook.$all(), function(o, i) {
|
||||
if (o.id == addressbook_id) {
|
||||
angular.extend(self, o);
|
||||
}
|
||||
});
|
||||
// Also extend AddressBook instance from data of addressbooks list.
|
||||
// Will inherit attributes such as isEditable and isRemote.
|
||||
angular.forEach(AddressBook.$all(), function(o, i) {
|
||||
if (o.id == self.id) {
|
||||
angular.extend(self, o);
|
||||
}
|
||||
});
|
||||
// Instanciate Card objects
|
||||
angular.forEach(self.cards, function(o, i) {
|
||||
self.cards[i] = new AddressBook.$Card(o);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -128,10 +136,4 @@
|
|||
});
|
||||
return addressbook;
|
||||
};
|
||||
|
||||
AddressBook.prototype.$save = function() {
|
||||
return AddressBook.$$resource.set(this.id, this.$omit()).then(function (data) {
|
||||
return data;
|
||||
});
|
||||
};
|
||||
})();
|
||||
|
|
|
@ -2,16 +2,21 @@
|
|||
'use strict';
|
||||
|
||||
/* Constructor */
|
||||
|
||||
function Card(futureCardData) {
|
||||
|
||||
/* DATA IS IMMEDIATELY AVAILABLE */
|
||||
// if (!futureCardData.inspect) {
|
||||
// angular.extend(this, futureCardData);
|
||||
// return;
|
||||
// }
|
||||
// Data is immediately available
|
||||
if (typeof futureCardData.then !== 'function') {
|
||||
angular.extend(this, futureCardData);
|
||||
if (this.pid && !this.id) {
|
||||
// Prepare for the creation of a new card;
|
||||
// Get UID from the server.
|
||||
var newCardData = Card.$$resource.newguid(this.pid);
|
||||
this.$unwrap(newCardData);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* THE PROMISE WILL BE UNWRAPPED FIRST */
|
||||
// The promise will be unwrapped first
|
||||
this.$unwrap(futureCardData);
|
||||
}
|
||||
|
||||
|
@ -20,7 +25,7 @@
|
|||
Card.$url_types = ['work', 'home', 'pref'];
|
||||
Card.$address_types = ['work', 'home'];
|
||||
|
||||
/* THE FACTORY WE'LL USE TO REGISTER WITH ANGULAR */
|
||||
/* The factory we'll use to register with Angular */
|
||||
Card.$factory = ['$timeout', 'sgSettings', 'sgResource', function($timeout, Settings, Resource) {
|
||||
angular.extend(Card, {
|
||||
$$resource: new Resource(Settings.baseURL),
|
||||
|
@ -30,10 +35,11 @@
|
|||
return Card; // return constructor
|
||||
}];
|
||||
|
||||
/* ANGULAR MODULE REGISTRATION */
|
||||
/* Factory registration in Angular module */
|
||||
angular.module('SOGo.Contacts')
|
||||
.factory('sgCard', Card.$factory)
|
||||
|
||||
// Directive to format a postal address
|
||||
.directive('sgAddress', function() {
|
||||
return {
|
||||
restrict: 'A',
|
||||
|
@ -57,12 +63,8 @@
|
|||
}
|
||||
});
|
||||
|
||||
|
||||
/* FETCH A UNIT */
|
||||
/* Fetch a card */
|
||||
Card.$find = function(addressbook_id, card_id) {
|
||||
|
||||
/* FALLS BACK ON AN INSTANCE OF RESOURCE */
|
||||
// Fetch data over the wire.
|
||||
var futureCardData = this.$$resource.find([addressbook_id, card_id].join('/'));
|
||||
|
||||
if (card_id) return new Card(futureCardData); // a single card
|
||||
|
@ -70,26 +72,53 @@
|
|||
return Card.$unwrapCollection(futureCardData); // a collection of cards
|
||||
};
|
||||
|
||||
// Instance methods
|
||||
/* Unwrap to a collection of Card instances */
|
||||
Card.$unwrapCollection = function(futureCardData) {
|
||||
var collection = {};
|
||||
|
||||
collection.$futureCardData = futureCardData;
|
||||
|
||||
futureCardData.then(function(cards) {
|
||||
Card.$timeout(function() {
|
||||
angular.forEach(cards, function(data, index) {
|
||||
collection[data.id] = new Card(data);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return collection;
|
||||
};
|
||||
|
||||
/* Instance methods */
|
||||
|
||||
Card.prototype.$id = function() {
|
||||
//var self = this;
|
||||
return this.$futureAddressBookData.then(function(data) {
|
||||
return this.$futureCardData.then(function(data) {
|
||||
return data.id;
|
||||
});
|
||||
};
|
||||
|
||||
// Unwrap a promise
|
||||
Card.prototype.$unwrap = function(futureCardData) {
|
||||
var self = this;
|
||||
|
||||
this.$futureCardData = futureCardData;
|
||||
this.$futureCardData.then(function(data) {
|
||||
// The success callback. Calling _.extend from $timeout will wrap it into a try/catch call.
|
||||
Card.$timeout(function() {
|
||||
angular.extend(self, data);
|
||||
Card.prototype.$save = function() {
|
||||
var action = 'saveAsContact';
|
||||
if (this.tag == 'VLIST') action = 'saveAsList';
|
||||
//var action = 'saveAs' + this.tag.substring(1).capitalize();
|
||||
return Card.$$resource.set([this.pid, this.id || '_new_'].join('/'),
|
||||
this.$omit(),
|
||||
{ 'action': action })
|
||||
.then(function (data) {
|
||||
return data;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
Card.prototype.$delete = function(attribute, index) {
|
||||
if (attribute) {
|
||||
if (index > -1 && this[attribute].length > index) {
|
||||
this[attribute].splice(index, 1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// No arguments -- delete card
|
||||
return Card.$$resource.remove([this.pid, this.id].join('/'));
|
||||
}
|
||||
};
|
||||
|
||||
Card.prototype.$fullname = function() {
|
||||
|
@ -110,6 +139,9 @@
|
|||
else if (this.emails && this.emails.length > 0) {
|
||||
fn = _.find(this.emails, function(i) { return i.value != ''; }).value;
|
||||
}
|
||||
else if (this.c_cn && this.c_cn.length > 0) {
|
||||
fn = this.c_cn;
|
||||
}
|
||||
}
|
||||
|
||||
return fn;
|
||||
|
@ -130,22 +162,30 @@
|
|||
return description.join(', ');
|
||||
};
|
||||
|
||||
Card.prototype.$preferredEmail = function() {
|
||||
var email = _.find(this.emails, function(o) {
|
||||
return o.type == 'pref';
|
||||
});
|
||||
if (email) {
|
||||
email = email.value;
|
||||
}
|
||||
else if (this.emails && this.emails.length) {
|
||||
email = this.emails[0].value;
|
||||
}
|
||||
|
||||
return email;
|
||||
};
|
||||
|
||||
Card.prototype.$birthday = function() {
|
||||
return new Date(this.birthday*1000);
|
||||
};
|
||||
|
||||
Card.prototype.$isCard = function() {
|
||||
return this.tag == 'VCARD';
|
||||
return this.tag == 'vcard';
|
||||
};
|
||||
|
||||
Card.prototype.$isList = function() {
|
||||
return this.tag == 'VLIST';
|
||||
};
|
||||
|
||||
Card.prototype.$delete = function(attribute, index) {
|
||||
if (index > -1 && this[attribute].length > index) {
|
||||
this[attribute].splice(index, 1);
|
||||
}
|
||||
return this.tag == 'vlist';
|
||||
};
|
||||
|
||||
Card.prototype.$addOrgUnit = function(orgUnit) {
|
||||
|
@ -226,24 +266,21 @@
|
|||
return this.addresses.length - 1;
|
||||
};
|
||||
|
||||
/* never call for now */
|
||||
Card.$unwrapCollection = function(futureCardData) {
|
||||
var collection = {};
|
||||
// Unwrap a promise
|
||||
Card.prototype.$unwrap = function(futureCardData) {
|
||||
var self = this;
|
||||
|
||||
collection.$futureCardData = futureCardData;
|
||||
|
||||
futureCardData.then(function(cards) {
|
||||
this.$futureCardData = futureCardData;
|
||||
this.$futureCardData.then(function(data) {
|
||||
// The success callback. Calling _.extend from $timeout will wrap it into a try/catch call and return
|
||||
// a promise resolved immediately.
|
||||
Card.$timeout(function() {
|
||||
angular.forEach(cards, function(data, index) {
|
||||
collection[data.id] = new Card(data);
|
||||
});
|
||||
angular.extend(self, data);
|
||||
});
|
||||
});
|
||||
|
||||
return collection;
|
||||
};
|
||||
|
||||
// $omit returns a sanitized object used to send to the server
|
||||
// Return a sanitized object used to send to the server
|
||||
Card.prototype.$omit = function() {
|
||||
var card = {};
|
||||
angular.forEach(this, function(value, key) {
|
||||
|
@ -253,11 +290,4 @@
|
|||
});
|
||||
return card;
|
||||
};
|
||||
|
||||
Card.prototype.$save = function() {
|
||||
return Card.$$resource.set([this.pid, this.id].join('/'), this.$omit()).then(function (data) {
|
||||
return data;
|
||||
});
|
||||
};
|
||||
|
||||
})();
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
angular.module('SOGo.Common', []);
|
||||
|
||||
angular.module('SOGo.Contacts', ['ngSanitize', 'ui.router', 'mm.foundation', 'mm.foundation.offcanvas', 'SOGo.Common'])
|
||||
angular.module('SOGo.Contacts', ['ngSanitize', 'ui.router', 'mm.foundation', 'mm.foundation.offcanvas', 'SOGo.Common', 'SOGo.UIDesktop'])
|
||||
|
||||
.constant('sgSettings', {
|
||||
'baseURL': ApplicationBaseURL
|
||||
|
@ -31,6 +31,15 @@
|
|||
controller: 'cardCtrl'
|
||||
}
|
||||
}
|
||||
})
|
||||
.state('addressbook.new', {
|
||||
url: "/:contact_type/new",
|
||||
views: {
|
||||
'card': {
|
||||
templateUrl: "card.html",
|
||||
controller: 'cardCtrl'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// if none of the above states are matched, use this as the fallback
|
||||
|
@ -56,31 +65,36 @@
|
|||
}
|
||||
}])
|
||||
|
||||
.controller('AddressBookCtrl', ['$state', '$scope', '$rootScope', '$stateParams', '$timeout', '$modal', 'sgFocus', 'sgCard', 'sgAddressBook', function($state, $scope, $rootScope, $stateParams, $timeout, $modal, focus, Card, AddressBook) {
|
||||
.controller('AddressBookCtrl', ['$state', '$scope', '$rootScope', '$stateParams', '$timeout', '$modal', 'sgFocus', 'sgCard', 'sgAddressBook', 'sgDialog', function($state, $scope, $rootScope, $stateParams, $timeout, $modal, focus, Card, AddressBook, Dialog) {
|
||||
// $scope objects
|
||||
$scope.search = { 'status': null, 'filter': null, 'last_filter': null };
|
||||
|
||||
if ($stateParams.addressbook_id &&
|
||||
($rootScope.addressbook == undefined || $stateParams.addressbook_id != $rootScope.addressbook.id)) {
|
||||
// Selected addressbook has changed
|
||||
// Selected addressbook has changed; fetch list of contacts
|
||||
$rootScope.addressbook = AddressBook.$find($stateParams.addressbook_id);
|
||||
// Extend resulting model instance with parameters from addressbooks listing
|
||||
// Adjust search status depending on addressbook type
|
||||
var o = _.find($rootScope.addressbooks, function(o) {
|
||||
return o.id == $stateParams.addressbook_id;
|
||||
});
|
||||
$scope.search.status = (o.isRemote)? 'remote-addressbook' : '';
|
||||
$scope.search.status = (o && o.isRemote)? 'remote-addressbook' : '';
|
||||
}
|
||||
// Initialize with data from template
|
||||
$scope.init = function() {
|
||||
$rootScope.addressbooks = AddressBook.$all(contactFolders);
|
||||
};
|
||||
// $scope functions
|
||||
$scope.select = function(rowIndex) {
|
||||
$scope.editMode = false;
|
||||
};
|
||||
$scope.edit = function(i) {
|
||||
if (angular.isUndefined(i)) {
|
||||
i = _.indexOf(_.pluck($rootScope.addressbooks, 'id'), $rootScope.addressbook.id);
|
||||
if (!$rootScope.addressbook.isRemote) {
|
||||
if (angular.isUndefined(i)) {
|
||||
i = _.indexOf(_.pluck($rootScope.addressbooks, 'id'), $rootScope.addressbook.id);
|
||||
}
|
||||
$scope.editMode = $rootScope.addressbook.id;
|
||||
focus('addressBookName_' + i);
|
||||
}
|
||||
$scope.editMode = $rootScope.addressbook.id;
|
||||
focus('addressBookName_' + i);
|
||||
};
|
||||
$scope.save = function(i) {
|
||||
$rootScope.addressbook.name = $rootScope.addressbooks[i].name;
|
||||
|
@ -92,7 +106,22 @@
|
|||
console.debug("failed");
|
||||
});
|
||||
};
|
||||
$scope.sharing = function() {
|
||||
$scope.confirmDelete = function() {
|
||||
Dialog.confirm(l('Warning'), l('Are you sure you want to delete the addressbook "%{0}"?',
|
||||
$rootScope.addressbook.name), function() {
|
||||
$rootScope.addressbook.$delete()
|
||||
.then(function() {
|
||||
$rootScope.addressbooks = _.reject($rootScope.addressbooks, function(o) {
|
||||
return o.id == $rootScope.addressbook.id;
|
||||
});
|
||||
$rootScope.addressbook = null;
|
||||
}, function(data, status) {
|
||||
Dialog.alert(l('Warning'), l('An error occured while deleting the addressbook "%{0}".',
|
||||
$rootScope.addressbook.name));
|
||||
});
|
||||
});
|
||||
};
|
||||
$scope.share = function() {
|
||||
var modal = $modal.open({
|
||||
templateUrl: 'addressbookSharing.html',
|
||||
//controller: 'addressbookSharingCtrl'
|
||||
|
@ -130,26 +159,27 @@
|
|||
};
|
||||
}])
|
||||
|
||||
// angular.module('SOGo').controller('addressbookSharingCtrl', ['$scope', '$modalInstance', function($scope, modal) {
|
||||
// $scope.closeModal = function() {
|
||||
// console.debug('please close it');
|
||||
// modal.close();
|
||||
// };
|
||||
// }]);
|
||||
|
||||
.controller('cardCtrl', ['$scope', '$rootScope', 'sgAddressBook', 'sgCard', 'sgFocus', '$stateParams', function($scope, $rootScope, AddressBook, Card, focus, $stateParams) {
|
||||
.controller('cardCtrl', ['$scope', '$rootScope', 'sgAddressBook', 'sgCard', 'sgDialog', 'sgFocus', '$state', '$stateParams', function($scope, $rootScope, AddressBook, Card, Dialog, focus, $state, $stateParams) {
|
||||
if ($stateParams.card_id) {
|
||||
// Show existing card
|
||||
if ($rootScope.addressbook == null) {
|
||||
// Card is directly access with URL fragment
|
||||
$rootScope.addressbook = AddressBook.$find($stateParams.addressbook_id);
|
||||
}
|
||||
$rootScope.addressbook.$getCard($stateParams.card_id);
|
||||
$rootScope.addressbook.$getCard($stateParams.card_id)
|
||||
$scope.editMode = false;
|
||||
}
|
||||
else if ($stateParams.contact_type) {
|
||||
// Create new card or list
|
||||
var tag = 'v' + $stateParams.contact_type;
|
||||
$scope.addressbook.card = new Card({ 'pid': $stateParams.addressbook_id, 'tag': tag });
|
||||
$scope.editMode = true;
|
||||
}
|
||||
$scope.allEmailTypes = Card.$email_types;
|
||||
$scope.allTelTypes = Card.$tel_types;
|
||||
$scope.allUrlTypes = Card.$url_types;
|
||||
$scope.allAddressTypes = Card.$address_types;
|
||||
|
||||
$scope.edit = function() {
|
||||
$rootScope.master_card = angular.copy($rootScope.addressbook.card);
|
||||
$scope.editMode = true;
|
||||
|
@ -180,12 +210,20 @@
|
|||
focus('address_' + i);
|
||||
};
|
||||
$scope.save = function(cardForm) {
|
||||
console.debug("save");
|
||||
if (cardForm.$valid) {
|
||||
$rootScope.addressbook.card.$save()
|
||||
.then(function(data) {
|
||||
console.debug("saved!");
|
||||
$scope.editMode = false;
|
||||
var i = _.indexOf(_.pluck($rootScope.addressbook.cards, 'id'), $rootScope.addressbook.card.id);
|
||||
if (i < 0) {
|
||||
// Reload contacts list and show addressbook in which the card has been created
|
||||
$rootScope.addressbook = AddressBook.$find(data.pid);
|
||||
}
|
||||
else {
|
||||
// Update contacts list with new version of the Card object
|
||||
$rootScope.addressbook.cards[i] = angular.copy($rootScope.addressbook.card);
|
||||
}
|
||||
}, function(data, status) {
|
||||
console.debug("failed");
|
||||
});
|
||||
|
@ -198,6 +236,22 @@
|
|||
$scope.reset = function() {
|
||||
$rootScope.addressbook.card = angular.copy($rootScope.master_card);
|
||||
};
|
||||
$scope.confirmDelete = function(card) {
|
||||
Dialog.confirm(l('Warning'),
|
||||
l('Are you sure you want to delete the card of "%{0}"?', card.$fullname()),
|
||||
function() {
|
||||
card.$delete()
|
||||
.then(function() {
|
||||
$rootScope.addressbook.cards = _.reject($rootScope.addressbook.cards, function(o) {
|
||||
return o.id == card.id;
|
||||
});
|
||||
$rootScope.addressbook.card = null;
|
||||
}, function(data, status) {
|
||||
Dialog.alert(l('Warning'), l('An error occured while deleting the card "%{0}".',
|
||||
card.$fullname()));
|
||||
});
|
||||
});
|
||||
};
|
||||
}]);
|
||||
|
||||
})();
|
||||
|
|
|
@ -9,7 +9,7 @@ $module-color: #6F5A73;
|
|||
$module-secondary-color: #8EC588; // light green
|
||||
$module-secondary-color: #3D792A; // green
|
||||
$module-secondary-color: #B996BF;
|
||||
$module-secondary-color: #B59BB9;
|
||||
$module-secondary-color: #B59BB9; // SOGo green
|
||||
$module-light-color: #F7ECFF;
|
||||
$topbar-bg-color: $module-color;
|
||||
$topbar-link-bg-active-hover: scale-color($module-secondary-color, $lightness: -14%);
|
||||
|
@ -66,6 +66,7 @@ $topbar-link-bg-hover: scale-color($module-color, $lightness: -14%);
|
|||
//vertical-align: middle;
|
||||
}
|
||||
.icon {
|
||||
//vertical-align: middle; // causes glitch when selecting row
|
||||
width: 2em;
|
||||
}
|
||||
form {
|
||||
|
@ -77,7 +78,7 @@ $topbar-link-bg-hover: scale-color($module-color, $lightness: -14%);
|
|||
display: block;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
padding-left: $off-canvas-link-padding;
|
||||
//padding-left: $off-canvas-link-padding;
|
||||
}
|
||||
input {
|
||||
border: 0;
|
||||
|
@ -117,7 +118,7 @@ $column-gutter: 0;
|
|||
height: 40px;
|
||||
border-radius: 20px;
|
||||
color: $input-disabled-bg;
|
||||
line-height: 40px;
|
||||
//line-height: 40px;
|
||||
text-align: center;
|
||||
border: 1px solid $input-disabled-bg;
|
||||
margin-right: 1em;
|
||||
|
@ -130,6 +131,15 @@ $column-gutter: 0;
|
|||
#pageContent {
|
||||
@include grid-row($behavior: nest);
|
||||
|
||||
#newListDrop {
|
||||
a {
|
||||
text-transform: uppercase;
|
||||
&.tiny {
|
||||
@include button-size($padding:$button-tny);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#addressbooksList {
|
||||
position: absolute;
|
||||
overflow: auto;
|
||||
|
@ -393,14 +403,14 @@ $column-gutter: 0;
|
|||
}
|
||||
input {
|
||||
display: table-cell;
|
||||
/* transition: background-color 300ms ease; */
|
||||
//transition: all 300ms ease;
|
||||
//background-color: $secondary-color;
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
box-shadow: none;
|
||||
margin-bottom: 0;
|
||||
/* &:focus { */
|
||||
/* background-color: #fff; */
|
||||
/* border: 1px solid blue; */
|
||||
/* } */
|
||||
}
|
||||
}
|
||||
|
@ -439,21 +449,6 @@ $column-gutter: 0;
|
|||
}
|
||||
|
||||
.f-dropdown {
|
||||
dd {
|
||||
a {
|
||||
background-color: $module-secondary-color;
|
||||
color: #fff;
|
||||
&:hover {
|
||||
background-color: $module-color;
|
||||
}
|
||||
}
|
||||
&.active {
|
||||
a {
|
||||
background-color: $module-color;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.icons-dropdown {
|
||||
width: auto;
|
||||
//background-color: $primary-color;
|
||||
|
|
Loading…
Reference in a new issue