Add addressbook subscriptions widget

This commit is contained in:
Francis Lachapelle
2014-11-11 11:14:55 -05:00
parent a5c19a79e1
commit 34e59743ce
9 changed files with 194 additions and 65 deletions
+1 -1
View File
@@ -47,7 +47,7 @@
pageName = "UIxContactFoldersView";
actionName = "checkRights";
};
userFolders = {
userFoldersTemplate = {
protectedBy = "View";
pageName = "UIxContactsUserFolders";
};
@@ -111,7 +111,7 @@
<script type="text/ng-template" id="addressbooks.html">
<!-- dropdown menu for addressbook options button -->
<div id="addressbookProperties" class="f-dropdown icons-dropdown" data-dropdown-content="dropdown-content">
<div id="addressbookProperties" class="f-dropdown icons-dropdown">
<ul class="button-group">
<li>
<span class="button"><i class="icon-hyperlink"><!-- links --></i></span>
@@ -139,6 +139,11 @@
<li><a class="tiny" data-ui-sref="addressbook.new({addressbookId: addressbook.id, contactType: 'list'})"><var:string label:value="New List"/></a></li>
</ul>
<!-- dropdown menu for subscriptions -->
<div id="folderSubscribe" class="sg-dropdown-content"
data-sg-subscribe="contact"
data-sg-subscribe-on-select="subscribeToFolder"><!-- subscription dropdown --></div>
<div id="addressbooksList" class="folders-list">
<div class="newItemsToolbar">
<a class="button tiny radius split" data-ui-sref="addressbook.new({addressbookId: addressbook.id, contactType: 'card'})"><var:string label:value="New Card"/><span data-dropdown-toggle="#newListDrop"></span></a><br/>
@@ -161,12 +166,18 @@
data-sg-focus-on="addressBookName_{{$index}}"
data-sg-escape="revertEditing($index)"/>
</form>
<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>
<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">
<button data-ng-click="newAddressbook()" class="button small" label:title="New Addressbook..."><i class="icon-plus"><!-- new --></i></button>
<a href="#" class="button small" label:title="Subscribe to an Addressbook..."><i class="icon-earth"><!-- subscribe --></i></a>
<a href="#" class="button small" label:title="Subscribe to an Addressbook..."
data-sg-dropdown-content-toggle="#folderSubscribe"><i class="icon-earth"><!-- subscribe --></i></a>
</div>
<!--<var:if condition="hasContactSelectionButtons">
<div class="contactSelection">
@@ -411,7 +422,10 @@
<label class="right inline"><var:string label:value="Category"/></label>
</div>
<div class="value">
<input type="text" label:placeholder="category" data-ng-model="category.value" data-sg-focus-on="category_{{$index}}" data-typeahead="cat for cat in card.allCategories | filter:$viewValue"/>
<input type="text" label:placeholder="category"
data-ng-model="category.value"
data-sg-focus-on="category_{{$index}}"
data-typeahead="cat for cat in card.allCategories | filter:$viewValue"/>
</div>
</div>
<div class="attr">
@@ -1,23 +1,45 @@
<?xml version='1.0' standalone='yes'?>
<!DOCTYPE var:component>
<var:component
xmlns="http://www.w3.org/1999/xhtml"
xmlns:var="http://www.skyrix.com/od/binding"
xmlns:const="http://www.skyrix.com/od/constant"
xmlns:rsrc="OGo:url"
xmlns:uix="OGo:uix"
xmlns:label="OGo:label"
className="UIxPageFrame"
title="name"
const:toolbar="none"
const:popup="YES"
const:jsFiles="dtree.js">
<var:component className="UIxContactsFilterPanel" qualifier="qualifier" />
<div id="folders"><!-- space --></div>
<div id="buttons">
<a id="addButton" class="button actionButton disabled" href="#">
<span><var:string label:value="Add" /></span></a>
<a id="doneButton" class="button" name="done">
<span><var:string label:value="Done"/></span></a>
</div>
</var:component>
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE container>
<container
xmlns="http://www.w3.org/1999/xhtml"
xmlns:var="http://www.skyrix.com/od/binding"
xmlns:const="http://www.skyrix.com/od/constant"
xmlns:uix="OGo:uix"><var:string var:value="doctype" const:escapeHTML="NO" />
<ul>
<li class="title"><var:string label:value="Subscribe"/></li>
<li class="search">
<input type="text" label:placeholder="Search"
data-ng-model="searchString"
data-sg-user-typeahead="sg-user-typeahead" />
</li>
<li class="item"
data-ng-repeat="user in users">
<a data-ng-click="selectUser($index)"
data-ng-mouseenter="selectActive($index)">
<span data-bind-html-unsafe="user.$shortFormat() | typeaheadHighlight:query"><!-- user --></span>
<i class="icon right"
data-ng-class="{'icon-arrow-right': user.uid != selectedUser.uid, 'icon-arrow-down': user.uid == selectedUser.uid}"><!-- arrow --></i>
</a>
<ul class="subitems"
data-ng-if="user.uid == selectedUser.uid">
<li class="item"
data-ng-show="user.$$folders.length == 0">
<a class="disabled">
<i class="icon icon-notification"><!-- no subscription --></i>
<var:string label:value="No possible subscription"/>
</a>
</li>
<li class="item"
data-ng-repeat="folder in user.$$folders">
<a>
<i class="icon"
data-ng-class="{'icon-address-book': folder.type == 'Contact'}"><!-- type --></i>
<span data-ng-bind="folder.displayName"><!-- folder --></span>
<button class="button tiny right"
data-ng-click="selectFolder(folder)">Subscribe</button>
</a>
</li>
</ul>
</li>
</ul>
</container>
+2 -2
View File
@@ -27,8 +27,8 @@
* @return a new Resource object
*/
Resource.$factory = ['$http', '$q', function($http, $q) {
return function(path, options) {
return new Resource($http, $q, path, options);
return function(path, activeUser, options) {
return new Resource($http, $q, path, activeUser, options);
};
}];
+27 -2
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)
$$resource: new Resource(Settings.baseURL, Settings.activeUser)
});
return User;
@@ -91,7 +91,7 @@
return data;
});
}
return deferred;
return deferred.promise;
};
/**
@@ -169,6 +169,31 @@
}
};
/**
* @function $folders
* @memberof User.prototype
* @desc Retrive 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) {
var _this = this,
deferred = User.$q.defer(),
param = {type: type};
if (this.$$folders) {
deferred.resolve(this.$$folders);
}
else {
User.$$resource.userResource(this.uid).fetch(null, 'foldersSearch', param).then(function(data) {
_this.$$folders = data;
deferred.resolve(data);
console.debug(JSON.stringify(data, undefined, 2));
return data;
});
}
return deferred.promise;
};
/**
* @function $omit
* @memberof User.prototype
@@ -36,7 +36,7 @@
angular.extend(AddressBook, {
$q: $q,
$timeout: $timeout,
$$resource: new Resource(Settings.baseURL),
$$resource: new Resource(Settings.baseURL, Settings.activeUser),
$Card: Card,
$$Acl: Acl,
activeUser: Settings.activeUser
@@ -58,8 +58,11 @@
// Insert new addressbook at proper index
var sibling, i;
addressbook.isOwned = this.activeUser.isSuperUser || addressbook.owner == this.activeUser.login;
sibling = _.find(this.$addressbooks, function(o) {
return (o.isRemote || (o.id != 'personal' && o.name.localeCompare(addressbook.name) === 1));
return (o.isRemote || (o.id != 'personal'
&& o.isOwned == addressbook.isOwned
&& o.name.localeCompare(addressbook.name) === 1));
});
i = sibling ? _.indexOf(_.pluck(this.$addressbooks, 'id'), sibling.id) : 1;
this.$addressbooks.splice(i, 0, addressbook);
@@ -88,7 +91,7 @@
/**
* @memberOf AddressBook
* @desc Fetch list of cards and return an AddressBook instance
* @desc Fetch list of cards and return an AddressBook instance.
* @param {string} addressbookId - the addressbook identifier
* @returns an AddressBook object instance
*/
@@ -98,8 +101,32 @@
return new AddressBook(futureAddressBookData);
};
/* Instance methods */
/**
* @memberOf AddressBook
* @desc Subscribe to another user's addressbook and add it to the list of addressbooks.
* @param {String} uid - user id
* @param {String} path - path of folder for specified user
* @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);
if (!_.find(_this.$addressbooks, function(o) {
return o.id == addressbookData.id;
})) {
AddressBook.$add(addressbook);
}
return addressbook;
});
};
/**
* @function $id
* @memberof AddressBook.prototype
* @desc Resolve the addressbook id.
* @returns a promise of the addressbook id
*/
AddressBook.prototype.$id = function() {
return this.$futureAddressBookData.then(function(data) {
return data.id;
@@ -166,15 +193,21 @@
AddressBook.prototype.$delete = function() {
var _this = this,
d = AddressBook.$q.defer();
AddressBook.$$resource.remove(this.id)
.then(function() {
var i = _.indexOf(_.pluck(AddressBook.$addressbooks, 'id'), _this.id);
AddressBook.$addressbooks.splice(i, 1);
d.resolve(true);
}, function(data, status) {
d.reject(data);
});
d = AddressBook.$q.defer(),
promise;
if (this.isOwned)
promise = AddressBook.$$resource.remove(this.id);
else
promise = AddressBook.$$resource.fetch(this.id, 'unsubscribe');
promise.then(function() {
var i = _.indexOf(_.pluck(AddressBook.$addressbooks, 'id'), _this.id);
AddressBook.$addressbooks.splice(i, 1);
d.resolve(true);
}, function(data, status) {
d.reject(data);
});
return d.promise;
};
+41 -16
View File
@@ -131,7 +131,8 @@
{
name: name,
isEditable: true,
isRemote: false
isRemote: false,
owner: UserLogin
}
);
AddressBook.$add(addressbook);
@@ -164,20 +165,34 @@
}
};
$scope.confirmDelete = function() {
Dialog.confirm(l('Warning'), l('Are you sure you want to delete the addressbook <em>%{0}</em>?',
$rootScope.addressbook.name))
.then(function(res) {
if (res) {
$rootScope.addressbook.$delete()
.then(function() {
$rootScope.addressbook = null;
}, function(data, status) {
Dialog.alert(l('An error occured while deleting the addressbook "%{0}".',
$rootScope.addressbook.name),
l(data.error));
});
}
});
if ($scope.addressbook.isOwned) {
Dialog.confirm(l('Warning'), l('Are you sure you want to delete the addressbook <em>%{0}</em>?',
$scope.addressbook.name))
.then(function(res) {
if (res) {
$rootScope.addressbook.$delete()
.then(function() {
$rootScope.addressbook = null;
}, function(data, status) {
Dialog.alert(l('An error occured while deleting the addressbook "%{0}".',
$rootScope.addressbook.name),
l(data.error));
});
}
});
}
else {
// Unsubscribe without confirmation
$rootScope.addressbook.$delete()
.then(function() {
$rootScope.addressbook = null;
}, function(data, status) {
Dialog.alert(l('An error occured while deleting the addressbook "%{0}".',
$rootScope.addressbook.name),
l(data.error));
});
}
};
$scope.importCards = function() {
@@ -187,7 +202,7 @@
};
$scope.share = function() {
var modal = $modal.open({
templateUrl: stateAddressbook.id + '/aclsTemplate',
templateUrl: stateAddressbook.id + '/aclsTemplate', // UI/Templates/UIxAclEditor.wox
resolve: {
modalUsers: function() {
return stateAddressbook.$acl.$users();
@@ -266,6 +281,16 @@
}
$scope.search.lastFilter = $scope.search.filter;
};
/**
* subscribeToFolder - Callback of sgSubscribe directive
*/
$scope.subscribeToFolder = function(addressbookData) {
console.debug('subscribeToFolder ' + addressbookData.owner + addressbookData.name);
AddressBook.$subscribe(addressbookData.owner, addressbookData.name).catch(function(data) {
Dialog.alert(l('Warning'), l('An error occured please try again.'));
});
};
}])
/**
+10 -4
View File
@@ -9,7 +9,13 @@
angular.module('SOGo.ContactsUI', ['ionic', 'SOGo.Common', 'SOGo.UIMobile'])
.constant('sgSettings', {
baseURL: ApplicationBaseURL
baseURL: ApplicationBaseURL,
activeUser: {
login: UserLogin,
language: UserLanguage,
folderURL: UserFolderURL,
isSuperUser: IsSuperUser
}
})
.run(function($ionicPlatform) {
@@ -52,9 +58,9 @@
templateUrl: 'addressbook.html',
controller: 'AddressBookCtrl',
resolve: {
stateAddressbook: function($stateParams, sgAddressBook) {
return sgAddressBook.$find($stateParams.addressbookId);
}
stateAddressbook: ['$stateParams', 'sgAddressBook', function($stateParams, AddressBook) {
return AddressBook.$find($stateParams.addressbookId);
}]
}
}
}
@@ -461,6 +461,10 @@ $column-gutter: 0;
}
}
#folderSubscribe {
width: 350px;
}
.buttonsToolbar {
text-align: right;
.button {