2015-05-06 04:06:13 +02:00
|
|
|
/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
|
|
|
|
(function() {
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @ngInject
|
|
|
|
*/
|
2016-09-27 21:19:24 +02:00
|
|
|
AddressBooksController.$inject = ['$state', '$scope', '$rootScope', '$stateParams', '$timeout', '$window', '$mdDialog', '$mdToast', '$mdMedia', '$mdSidenav', 'FileUploader', 'sgConstant', 'sgHotkeys', 'sgFocus', 'Card', 'AddressBook', 'Dialog', 'sgSettings', 'User', 'stateAddressbooks'];
|
|
|
|
function AddressBooksController($state, $scope, $rootScope, $stateParams, $timeout, $window, $mdDialog, $mdToast, $mdMedia, $mdSidenav, FileUploader, sgConstant, sgHotkeys, focus, Card, AddressBook, Dialog, Settings, User, stateAddressbooks) {
|
|
|
|
var vm = this, hotkeys = [];
|
2015-05-06 04:06:13 +02:00
|
|
|
|
2015-05-28 19:48:45 +02:00
|
|
|
vm.activeUser = Settings.activeUser;
|
|
|
|
vm.service = AddressBook;
|
|
|
|
vm.select = select;
|
|
|
|
vm.newAddressbook = newAddressbook;
|
|
|
|
vm.edit = edit;
|
|
|
|
vm.revertEditing = revertEditing;
|
|
|
|
vm.save = save;
|
|
|
|
vm.confirmDelete = confirmDelete;
|
|
|
|
vm.importCards = importCards;
|
2015-06-12 17:21:02 +02:00
|
|
|
vm.showLinks = showLinks;
|
2015-11-04 16:38:24 +01:00
|
|
|
vm.showProperties = showProperties;
|
2015-05-28 19:48:45 +02:00
|
|
|
vm.share = share;
|
|
|
|
vm.subscribeToFolder = subscribeToFolder;
|
2016-08-05 22:08:04 +02:00
|
|
|
vm.isDroppableFolder = isDroppableFolder;
|
|
|
|
vm.dragSelectedCards = dragSelectedCards;
|
2015-05-06 04:06:13 +02:00
|
|
|
|
2016-09-27 21:19:24 +02:00
|
|
|
|
|
|
|
_registerHotkeys(hotkeys);
|
|
|
|
|
|
|
|
$scope.$on('$destroy', function() {
|
|
|
|
// Deregister hotkeys
|
|
|
|
_.forEach(hotkeys, function(key) {
|
|
|
|
sgHotkeys.deregisterHotkey(key);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
function _registerHotkeys(keys) {
|
|
|
|
keys.push(sgHotkeys.createHotkey({
|
|
|
|
key: 'backspace',
|
|
|
|
description: l('Delete selected card or address book'),
|
|
|
|
callback: function() {
|
|
|
|
if (AddressBook.selectedFolder && !AddressBook.selectedFolder.hasSelectedCard())
|
|
|
|
confirmDelete();
|
|
|
|
}
|
|
|
|
}));
|
|
|
|
|
|
|
|
// Register the hotkeys
|
|
|
|
_.forEach(keys, function(key) {
|
|
|
|
sgHotkeys.registerHotkey(key);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2015-09-24 17:12:02 +02:00
|
|
|
function select($event, folder) {
|
|
|
|
if ($state.params.addressbookId != folder.id &&
|
|
|
|
vm.editMode != folder.id) {
|
|
|
|
vm.editMode = false;
|
|
|
|
AddressBook.$query.value = '';
|
2015-11-25 17:12:30 +01:00
|
|
|
// Close sidenav on small devices
|
2016-05-18 20:35:24 +02:00
|
|
|
if (!$mdMedia(sgConstant['gt-md']))
|
2015-11-25 17:12:30 +01:00
|
|
|
$mdSidenav('left').close();
|
2015-09-24 17:12:02 +02:00
|
|
|
$state.go('app.addressbook', {addressbookId: folder.id});
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$event.preventDefault();
|
|
|
|
$event.stopPropagation();
|
|
|
|
}
|
2015-05-28 19:48:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
function newAddressbook() {
|
2016-10-21 16:55:59 +02:00
|
|
|
Dialog.prompt(l('New Addressbook...'),
|
|
|
|
l('Name of the Address Book'))
|
2015-05-06 04:06:13 +02:00
|
|
|
.then(function(name) {
|
|
|
|
var addressbook = new AddressBook(
|
|
|
|
{
|
|
|
|
name: name,
|
|
|
|
isEditable: true,
|
|
|
|
isRemote: false,
|
|
|
|
owner: UserLogin
|
|
|
|
}
|
|
|
|
);
|
|
|
|
AddressBook.$add(addressbook);
|
|
|
|
});
|
2015-05-28 19:48:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
function edit(folder) {
|
2015-05-06 04:06:13 +02:00
|
|
|
if (!folder.isRemote) {
|
2015-05-28 19:48:45 +02:00
|
|
|
vm.editMode = folder.id;
|
|
|
|
vm.originalAddressbook = angular.extend({}, folder.$omit());
|
2015-05-06 04:06:13 +02:00
|
|
|
focus('addressBookName_' + folder.id);
|
|
|
|
}
|
2015-05-28 19:48:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
function revertEditing(folder) {
|
|
|
|
folder.name = vm.originalAddressbook.name;
|
|
|
|
vm.editMode = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
function save(folder) {
|
2015-05-06 04:06:13 +02:00
|
|
|
var name = folder.name;
|
2015-05-28 19:48:45 +02:00
|
|
|
if (name && name.length > 0 && name != vm.originalAddressbook.name) {
|
2015-05-06 04:06:13 +02:00
|
|
|
folder.$rename(name)
|
|
|
|
.then(function(data) {
|
2015-05-28 19:48:45 +02:00
|
|
|
vm.editMode = false;
|
2015-05-06 04:06:13 +02:00
|
|
|
}, function(data, status) {
|
|
|
|
Dialog.alert(l('Warning'), data);
|
|
|
|
});
|
|
|
|
}
|
2015-05-28 19:48:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
function confirmDelete() {
|
|
|
|
if (vm.service.selectedFolder.isSubscription) {
|
2015-05-06 04:06:13 +02:00
|
|
|
// Unsubscribe without confirmation
|
2015-05-28 19:48:45 +02:00
|
|
|
vm.service.selectedFolder.$delete()
|
2015-05-06 04:06:13 +02:00
|
|
|
.then(function() {
|
2015-05-28 19:48:45 +02:00
|
|
|
vm.service.selectedFolder = null;
|
2015-05-06 04:06:13 +02:00
|
|
|
$state.go('app.addressbook', { addressbookId: 'personal' });
|
|
|
|
}, function(data, status) {
|
|
|
|
Dialog.alert(l('An error occured while deleting the addressbook "%{0}".',
|
2015-05-28 19:48:45 +02:00
|
|
|
vm.service.selectedFolder.name),
|
2015-05-06 04:06:13 +02:00
|
|
|
l(data.error));
|
|
|
|
});
|
|
|
|
}
|
|
|
|
else {
|
2016-03-22 19:19:09 +01:00
|
|
|
Dialog.confirm(l('Warning'), l('Are you sure you want to delete the addressbook "%{0}"?',
|
2016-02-10 16:52:46 +01:00
|
|
|
vm.service.selectedFolder.name),
|
|
|
|
{ ok: l('Delete') })
|
2015-05-28 19:48:45 +02:00
|
|
|
.then(function() {
|
|
|
|
return vm.service.selectedFolder.$delete();
|
|
|
|
})
|
2015-05-06 04:06:13 +02:00
|
|
|
.then(function() {
|
2015-05-28 19:48:45 +02:00
|
|
|
vm.service.selectedFolder = null;
|
2016-01-15 16:24:26 +01:00
|
|
|
$state.go('app.addressbook', { addressbookId: 'personal' });
|
2015-05-28 19:48:45 +02:00
|
|
|
return true;
|
|
|
|
})
|
2015-12-14 18:19:15 +01:00
|
|
|
.catch(function(response) {
|
2016-09-27 21:19:24 +02:00
|
|
|
if (response) {
|
|
|
|
var message = response.data.message || response.statusText;
|
|
|
|
Dialog.alert(l('An error occured while deleting the addressbook "%{0}".',
|
|
|
|
vm.service.selectedFolder.name),
|
|
|
|
message);
|
|
|
|
}
|
2015-05-06 04:06:13 +02:00
|
|
|
});
|
|
|
|
}
|
2015-05-28 19:48:45 +02:00
|
|
|
}
|
|
|
|
|
2015-08-22 02:56:21 +02:00
|
|
|
function importCards($event, folder) {
|
|
|
|
$mdDialog.show({
|
|
|
|
parent: angular.element(document.body),
|
|
|
|
targetEvent: $event,
|
|
|
|
clickOutsideToClose: true,
|
|
|
|
escapeToClose: true,
|
2015-11-10 21:05:41 +01:00
|
|
|
templateUrl: 'UIxContactsImportDialog',
|
2015-08-22 02:56:21 +02:00
|
|
|
controller: CardsImportDialogController,
|
2015-11-10 21:05:41 +01:00
|
|
|
controllerAs: '$CardsImportDialogController',
|
2015-08-22 02:56:21 +02:00
|
|
|
locals: {
|
|
|
|
folder: folder
|
|
|
|
}
|
|
|
|
});
|
2015-05-28 19:48:45 +02:00
|
|
|
|
2015-08-22 02:56:21 +02:00
|
|
|
/**
|
|
|
|
* @ngInject
|
|
|
|
*/
|
|
|
|
CardsImportDialogController.$inject = ['scope', '$mdDialog', 'folder'];
|
|
|
|
function CardsImportDialogController(scope, $mdDialog, folder) {
|
2015-11-10 21:05:41 +01:00
|
|
|
var vm = this;
|
2015-08-22 02:56:21 +02:00
|
|
|
|
2015-11-10 21:05:41 +01:00
|
|
|
vm.uploader = new FileUploader({
|
|
|
|
url: ApplicationBaseURL + [folder.id, 'import'].join('/'),
|
|
|
|
autoUpload: true,
|
|
|
|
queueLimit: 1,
|
|
|
|
filters: [{ name: filterByExtension, fn: filterByExtension }],
|
2015-08-22 02:56:21 +02:00
|
|
|
onSuccessItem: function(item, response, status, headers) {
|
2015-11-10 21:05:41 +01:00
|
|
|
var msg;
|
|
|
|
|
2015-08-22 02:56:21 +02:00
|
|
|
$mdDialog.hide();
|
2015-11-10 21:05:41 +01:00
|
|
|
|
|
|
|
if (response.imported === 0)
|
|
|
|
msg = l('No card was imported.');
|
|
|
|
else {
|
|
|
|
msg = l('A total of %{0} cards were imported in the addressbook.', response.imported);
|
|
|
|
AddressBook.selectedFolder.$reload();
|
|
|
|
}
|
|
|
|
|
2015-08-22 02:56:21 +02:00
|
|
|
$mdToast.show(
|
|
|
|
$mdToast.simple()
|
2015-11-10 21:05:41 +01:00
|
|
|
.content(msg)
|
2015-08-22 02:56:21 +02:00
|
|
|
.position('top right')
|
|
|
|
.hideDelay(3000));
|
|
|
|
},
|
|
|
|
onErrorItem: function(item, response, status, headers) {
|
2015-11-10 21:05:41 +01:00
|
|
|
$mdToast.show({
|
|
|
|
template: [
|
|
|
|
'<md-toast>',
|
2015-12-10 00:52:52 +01:00
|
|
|
' <div class="md-toast-content">',
|
|
|
|
' <md-icon class="md-warn md-hue-1">error_outline</md-icon>',
|
|
|
|
' <span>' + l('An error occured while importing contacts.') + '</span>',
|
|
|
|
' </div>',
|
2015-11-10 21:05:41 +01:00
|
|
|
'</md-toast>'
|
|
|
|
].join(''),
|
|
|
|
position: 'top right',
|
|
|
|
hideDelay: 3000
|
|
|
|
});
|
2015-08-22 02:56:21 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2015-11-10 21:05:41 +01:00
|
|
|
vm.close = function() {
|
2015-08-22 02:56:21 +02:00
|
|
|
$mdDialog.hide();
|
|
|
|
};
|
2015-11-10 21:05:41 +01:00
|
|
|
|
|
|
|
function filterByExtension(item) {
|
|
|
|
var isTextFile = item.type.indexOf('text') === 0 ||
|
|
|
|
/\.(ldif|vcf|vcard)$/.test(item.name);
|
|
|
|
|
|
|
|
if (!isTextFile)
|
|
|
|
$mdToast.show({
|
|
|
|
template: [
|
|
|
|
'<md-toast>',
|
2015-12-10 00:52:52 +01:00
|
|
|
' <div class="md-toast-content">',
|
|
|
|
' <md-icon class="md-warn md-hue-1">error_outline</md-icon>',
|
|
|
|
' <span>' + l('Select a vCard or LDIF file.') + '</span>',
|
|
|
|
' </div>',
|
2015-11-10 21:05:41 +01:00
|
|
|
'</md-toast>'
|
|
|
|
].join(''),
|
|
|
|
position: 'top right',
|
|
|
|
hideDelay: 3000
|
|
|
|
});
|
|
|
|
|
|
|
|
return isTextFile;
|
|
|
|
}
|
2015-08-22 02:56:21 +02:00
|
|
|
}
|
2015-05-28 19:48:45 +02:00
|
|
|
}
|
|
|
|
|
2015-08-17 22:21:10 +02:00
|
|
|
function showLinks(addressbook) {
|
2015-06-12 17:21:02 +02:00
|
|
|
$mdDialog.show({
|
|
|
|
parent: angular.element(document.body),
|
|
|
|
clickOutsideToClose: true,
|
|
|
|
escapeToClose: true,
|
2015-08-17 22:21:10 +02:00
|
|
|
templateUrl: addressbook.id + '/links',
|
|
|
|
controller: LinksDialogController,
|
|
|
|
controllerAs: 'links',
|
2015-06-12 17:21:02 +02:00
|
|
|
locals: {
|
2015-08-17 22:21:10 +02:00
|
|
|
addressbook: addressbook
|
|
|
|
}
|
2015-06-12 17:21:02 +02:00
|
|
|
});
|
2016-08-05 22:08:04 +02:00
|
|
|
|
2015-06-12 17:21:02 +02:00
|
|
|
/**
|
|
|
|
* @ngInject
|
|
|
|
*/
|
2015-08-17 22:21:10 +02:00
|
|
|
LinksDialogController.$inject = ['$mdDialog', 'addressbook'];
|
|
|
|
function LinksDialogController($mdDialog, addressbook) {
|
|
|
|
var vm = this;
|
|
|
|
this.addressbook = addressbook;
|
|
|
|
this.close = close;
|
|
|
|
|
|
|
|
function close() {
|
2015-06-12 17:21:02 +02:00
|
|
|
$mdDialog.hide();
|
2015-08-17 22:21:10 +02:00
|
|
|
}
|
2015-06-12 17:21:02 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-04 16:38:24 +01:00
|
|
|
function showProperties(addressbook) {
|
|
|
|
$mdDialog.show({
|
|
|
|
templateUrl: addressbook.id + '/properties',
|
|
|
|
controller: PropertiesDialogController,
|
|
|
|
controllerAs: 'properties',
|
|
|
|
clickOutsideToClose: true,
|
|
|
|
escapeToClose: true,
|
|
|
|
locals: {
|
|
|
|
srcAddressBook: addressbook
|
|
|
|
}
|
|
|
|
}).catch(function() {
|
|
|
|
// Do nothing
|
|
|
|
});
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @ngInject
|
|
|
|
*/
|
|
|
|
PropertiesDialogController.$inject = ['$scope', '$mdDialog', 'srcAddressBook'];
|
|
|
|
function PropertiesDialogController($scope, $mdDialog, srcAddressBook) {
|
|
|
|
var vm = this;
|
|
|
|
|
|
|
|
vm.addressbook = new AddressBook(srcAddressBook.$omit());
|
|
|
|
vm.saveProperties = saveProperties;
|
|
|
|
vm.close = close;
|
|
|
|
|
|
|
|
function saveProperties() {
|
2015-11-09 20:46:30 +01:00
|
|
|
vm.addressbook.$save().then(function() {
|
|
|
|
// Refresh list instance
|
|
|
|
srcAddressBook.init(vm.addressbook.$omit());
|
|
|
|
$mdDialog.hide();
|
|
|
|
});
|
2015-11-04 16:38:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function close() {
|
|
|
|
$mdDialog.cancel();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-28 19:48:45 +02:00
|
|
|
function share(addressbook) {
|
|
|
|
// Fetch list of ACL users
|
|
|
|
addressbook.$acl.$users().then(function() {
|
|
|
|
// Show ACL editor
|
|
|
|
$mdDialog.show({
|
|
|
|
templateUrl: addressbook.id + '/UIxAclEditor', // UI/Templates/UIxAclEditor.wox
|
2015-07-28 16:53:29 +02:00
|
|
|
controller: 'AclController', // from the ng module SOGo.Common
|
2015-05-28 19:48:45 +02:00
|
|
|
controllerAs: 'acl',
|
|
|
|
clickOutsideToClose: true,
|
|
|
|
escapeToClose: true,
|
|
|
|
locals: {
|
|
|
|
usersWithACL: addressbook.$acl.users,
|
|
|
|
User: User,
|
2015-07-04 03:44:28 +02:00
|
|
|
folder: addressbook
|
2015-05-28 19:48:45 +02:00
|
|
|
}
|
|
|
|
});
|
2015-05-06 04:06:13 +02:00
|
|
|
});
|
2015-05-28 19:48:45 +02:00
|
|
|
}
|
2015-05-06 04:06:13 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* subscribeToFolder - Callback of sgSubscribe directive
|
|
|
|
*/
|
2015-05-28 19:48:45 +02:00
|
|
|
function subscribeToFolder(addressbookData) {
|
2015-05-06 04:06:13 +02:00
|
|
|
console.debug('subscribeToFolder ' + addressbookData.owner + addressbookData.name);
|
2015-12-10 19:24:31 +01:00
|
|
|
AddressBook.$subscribe(addressbookData.owner, addressbookData.name).then(function(data) {
|
|
|
|
$mdToast.show(
|
|
|
|
$mdToast.simple()
|
2016-01-13 18:48:20 +01:00
|
|
|
.content(l('Successfully subscribed to address book'))
|
2015-12-10 19:24:31 +01:00
|
|
|
.position('top right')
|
|
|
|
.hideDelay(3000));
|
2015-05-06 04:06:13 +02:00
|
|
|
});
|
2015-05-28 19:48:45 +02:00
|
|
|
}
|
2016-08-05 22:08:04 +02:00
|
|
|
|
|
|
|
function isDroppableFolder(srcFolder, dstFolder) {
|
|
|
|
return (dstFolder.id != srcFolder.id) && (dstFolder.isOwned || dstFolder.acls.objectCreator);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see AddressBookController._selectedCardsOperation
|
|
|
|
*/
|
|
|
|
function dragSelectedCards(srcFolder, dstFolder, mode) {
|
2016-08-05 22:15:25 +02:00
|
|
|
var dstId, allCards, cards, ids, clearCardView, promise, success;
|
2016-08-05 22:08:04 +02:00
|
|
|
|
|
|
|
dstId = dstFolder.id;
|
|
|
|
clearCardView = false;
|
2016-08-05 22:15:25 +02:00
|
|
|
allCards = srcFolder.$selectedCards();
|
|
|
|
if (allCards.length === 0)
|
|
|
|
allCards = [srcFolder.$selectedCard()];
|
|
|
|
cards = _.filter(allCards, function(card) {
|
|
|
|
return card.$isCard();
|
|
|
|
});
|
2016-08-05 22:08:04 +02:00
|
|
|
|
2016-08-05 22:15:25 +02:00
|
|
|
if (cards.length != allCards.length)
|
2016-08-05 22:08:04 +02:00
|
|
|
$mdToast.show(
|
|
|
|
$mdToast.simple()
|
|
|
|
.content(l("Lists can't be moved or copied."))
|
|
|
|
.position('top right')
|
|
|
|
.hideDelay(2000));
|
|
|
|
|
2016-08-05 22:15:25 +02:00
|
|
|
if (cards.length) {
|
|
|
|
if (mode == 'copy') {
|
|
|
|
promise = srcFolder.$copyCards(cards, dstId);
|
|
|
|
success = l('%{0} card(s) copied', cards.length);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
promise = srcFolder.$moveCards(cards, dstId);
|
|
|
|
success = l('%{0} card(s) moved', cards.length);
|
|
|
|
// Check if currently displayed card will be moved
|
|
|
|
ids = _.map(cards, 'id');
|
|
|
|
clearCardView = (srcFolder.selectedCard && ids.indexOf(srcFolder.selectedCard) >= 0);
|
|
|
|
}
|
2016-08-05 22:08:04 +02:00
|
|
|
|
2016-08-05 22:15:25 +02:00
|
|
|
// Show success toast when action succeeds
|
|
|
|
promise.then(function() {
|
|
|
|
if (clearCardView)
|
|
|
|
$state.go('app.addressbook');
|
|
|
|
$mdToast.show(
|
|
|
|
$mdToast.simple()
|
|
|
|
.content(success)
|
|
|
|
.position('top right')
|
|
|
|
.hideDelay(2000));
|
|
|
|
});
|
|
|
|
}
|
2016-08-05 22:08:04 +02:00
|
|
|
}
|
|
|
|
|
2015-05-06 04:06:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
angular
|
2015-05-28 19:48:45 +02:00
|
|
|
.module('SOGo.ContactsUI')
|
|
|
|
.controller('AddressBooksController', AddressBooksController);
|
2015-05-06 04:06:13 +02:00
|
|
|
})();
|