mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-06-11 21:39:43 +00:00
Add addressbook subscriptions widget
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
}];
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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.'));
|
||||
});
|
||||
};
|
||||
}])
|
||||
|
||||
/**
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user