parent
07fa202523
commit
721428c88f
1
NEWS
1
NEWS
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
New features
|
New features
|
||||||
- [web] new images viewer in Mail module
|
- [web] new images viewer in Mail module
|
||||||
|
- [web] create list from selected cards (#3561)
|
||||||
- [eas] initial EAS v16 and email drafts support
|
- [eas] initial EAS v16 and email drafts support
|
||||||
- [core] load-testing scripts to evaluate SOGo performance
|
- [core] load-testing scripts to evaluate SOGo performance
|
||||||
|
|
||||||
|
|
|
@ -386,6 +386,11 @@
|
||||||
</md-menu-content>
|
</md-menu-content>
|
||||||
</md-menu>
|
</md-menu>
|
||||||
</md-menu-item>
|
</md-menu-item>
|
||||||
|
<md-menu-item ng-hide="addressbook.selectedFolder.isRemote">
|
||||||
|
<md-button ng-click="addressbook.newListWithSelectedCards()">
|
||||||
|
<var:string label:value="Create a new list"/>
|
||||||
|
</md-button>
|
||||||
|
</md-menu-item>
|
||||||
<md-menu-item ng-hide="addressbook.selectedFolder.isRemote">
|
<md-menu-item ng-hide="addressbook.selectedFolder.isRemote">
|
||||||
<md-button ng-click="addressbook.selectedFolder.exportCards(true)">
|
<md-button ng-click="addressbook.selectedFolder.exportCards(true)">
|
||||||
<var:string label:value="Export"/>
|
<var:string label:value="Export"/>
|
||||||
|
|
|
@ -10,63 +10,50 @@
|
||||||
function AddressBookController($scope, $q, $window, $state, $timeout, $mdDialog, $mdToast, Account, Card, AddressBook, focus, Dialog, Settings, sgHotkeys, stateAddressbooks, stateAddressbook) {
|
function AddressBookController($scope, $q, $window, $state, $timeout, $mdDialog, $mdToast, Account, Card, AddressBook, focus, Dialog, Settings, sgHotkeys, stateAddressbooks, stateAddressbook) {
|
||||||
var vm = this, hotkeys = [];
|
var vm = this, hotkeys = [];
|
||||||
|
|
||||||
AddressBook.selectedFolder = stateAddressbook;
|
this.$onInit = function() {
|
||||||
|
AddressBook.selectedFolder = stateAddressbook;
|
||||||
|
|
||||||
vm.service = AddressBook;
|
this.service = AddressBook;
|
||||||
vm.selectedFolder = stateAddressbook;
|
this.selectedFolder = stateAddressbook;
|
||||||
vm.selectCard = selectCard;
|
this.mode = { search: false, multiple: 0 };
|
||||||
vm.toggleCardSelection = toggleCardSelection;
|
|
||||||
vm.newComponent = newComponent;
|
|
||||||
vm.unselectCards = unselectCards;
|
|
||||||
vm.confirmDeleteSelectedCards = confirmDeleteSelectedCards;
|
|
||||||
vm.copySelectedCards = copySelectedCards;
|
|
||||||
vm.moveSelectedCards = moveSelectedCards;
|
|
||||||
vm.selectAll = selectAll;
|
|
||||||
vm.sort = sort;
|
|
||||||
vm.sortedBy = sortedBy;
|
|
||||||
vm.searchMode = searchMode;
|
|
||||||
vm.cancelSearch = cancelSearch;
|
|
||||||
vm.newMessage = newMessage;
|
|
||||||
vm.newMessageWithSelectedCards = newMessageWithSelectedCards;
|
|
||||||
vm.newMessageWithRecipient = newMessageWithRecipient;
|
|
||||||
vm.mode = { search: false, multiple: 0 };
|
|
||||||
|
|
||||||
|
|
||||||
_registerHotkeys(hotkeys);
|
_registerHotkeys(hotkeys);
|
||||||
|
|
||||||
$scope.$on('$destroy', function() {
|
$scope.$on('$destroy', function() {
|
||||||
// Deregister hotkeys
|
// Deregister hotkeys
|
||||||
_.forEach(hotkeys, function(key) {
|
_.forEach(hotkeys, function(key) {
|
||||||
sgHotkeys.deregisterHotkey(key);
|
sgHotkeys.deregisterHotkey(key);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
};
|
||||||
|
|
||||||
|
|
||||||
function _registerHotkeys(keys) {
|
function _registerHotkeys(keys) {
|
||||||
keys.push(sgHotkeys.createHotkey({
|
keys.push(sgHotkeys.createHotkey({
|
||||||
key: l('hotkey_search'),
|
key: l('hotkey_search'),
|
||||||
description: l('Search'),
|
description: l('Search'),
|
||||||
callback: searchMode
|
callback: angular.bind(vm, vm.searchMode)
|
||||||
}));
|
}));
|
||||||
keys.push(sgHotkeys.createHotkey({
|
keys.push(sgHotkeys.createHotkey({
|
||||||
key: l('key_create_card'),
|
key: l('key_create_card'),
|
||||||
description: l('Create a new address book card'),
|
description: l('Create a new address book card'),
|
||||||
callback: angular.bind(vm, newComponent, 'card')
|
callback: angular.bind(vm, vm.newComponent, 'card')
|
||||||
}));
|
}));
|
||||||
keys.push(sgHotkeys.createHotkey({
|
keys.push(sgHotkeys.createHotkey({
|
||||||
key: l('key_create_list'),
|
key: l('key_create_list'),
|
||||||
description: l('Create a new list'),
|
description: l('Create a new list'),
|
||||||
callback: angular.bind(vm, newComponent, 'list')
|
callback: angular.bind(vm, vm.newComponent, 'list')
|
||||||
}));
|
}));
|
||||||
keys.push(sgHotkeys.createHotkey({
|
keys.push(sgHotkeys.createHotkey({
|
||||||
key: 'space',
|
key: 'space',
|
||||||
description: l('Toggle item'),
|
description: l('Toggle item'),
|
||||||
callback: toggleCardSelection
|
callback: angular.bind(vm, vm.toggleCardSelection)
|
||||||
}));
|
}));
|
||||||
keys.push(sgHotkeys.createHotkey({
|
keys.push(sgHotkeys.createHotkey({
|
||||||
key: 'shift+space',
|
key: 'shift+space',
|
||||||
description: l('Toggle range of items'),
|
description: l('Toggle range of items'),
|
||||||
callback: toggleCardSelection
|
callback: angular.bind(vm, vm.toggleCardSelection)
|
||||||
}));
|
}));
|
||||||
keys.push(sgHotkeys.createHotkey({
|
keys.push(sgHotkeys.createHotkey({
|
||||||
key: 'up',
|
key: 'up',
|
||||||
|
@ -92,7 +79,7 @@
|
||||||
keys.push(sgHotkeys.createHotkey({
|
keys.push(sgHotkeys.createHotkey({
|
||||||
key: hotkey,
|
key: hotkey,
|
||||||
description: l('Delete selected card or address book'),
|
description: l('Delete selected card or address book'),
|
||||||
callback: confirmDeleteSelectedCards
|
callback: angular.bind(vm, vm.confirmDeleteSelectedCards)
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -102,18 +89,18 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectCard(card) {
|
this.selectCard = function(card) {
|
||||||
$state.go('app.addressbook.card.view', {cardId: card.id});
|
$state.go('app.addressbook.card.view', {cardId: card.id});
|
||||||
}
|
};
|
||||||
|
|
||||||
function toggleCardSelection($event, card) {
|
this.toggleCardSelection = function($event, card) {
|
||||||
var folder = vm.selectedFolder,
|
var folder = this.selectedFolder,
|
||||||
selectedIndex, nextSelectedIndex, i;
|
selectedIndex, nextSelectedIndex, i;
|
||||||
|
|
||||||
if (!card)
|
if (!card)
|
||||||
card = folder.$selectedCard();
|
card = folder.$selectedCard();
|
||||||
card.selected = !card.selected;
|
card.selected = !card.selected;
|
||||||
vm.mode.multiple += card.selected? 1 : -1;
|
this.mode.multiple += card.selected? 1 : -1;
|
||||||
|
|
||||||
// Select closest range of cards when shift key is pressed
|
// Select closest range of cards when shift key is pressed
|
||||||
if ($event.shiftKey && folder.$selectedCount() > 1) {
|
if ($event.shiftKey && folder.$selectedCount() > 1) {
|
||||||
|
@ -140,18 +127,18 @@
|
||||||
|
|
||||||
$event.preventDefault();
|
$event.preventDefault();
|
||||||
$event.stopPropagation();
|
$event.stopPropagation();
|
||||||
}
|
};
|
||||||
|
|
||||||
function newComponent(type) {
|
this.newComponent = function(type) {
|
||||||
$state.go('app.addressbook.new', { contactType: type });
|
$state.go('app.addressbook.new', { contactType: type });
|
||||||
}
|
};
|
||||||
|
|
||||||
function unselectCards() {
|
this.unselectCards = function() {
|
||||||
_.forEach(vm.selectedFolder.$cards, function(card) {
|
_.forEach(this.selectedFolder.$cards, function(card) {
|
||||||
card.selected = false;
|
card.selected = false;
|
||||||
});
|
});
|
||||||
vm.mode.multiple = 0;
|
this.mode.multiple = 0;
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User has pressed up arrow key
|
* User has pressed up arrow key
|
||||||
|
@ -171,7 +158,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index > -1)
|
if (index > -1)
|
||||||
selectCard(vm.selectedFolder.$cards[index]);
|
vm.selectCard(vm.selectedFolder.$cards[index]);
|
||||||
|
|
||||||
$event.preventDefault();
|
$event.preventDefault();
|
||||||
|
|
||||||
|
@ -194,7 +181,7 @@
|
||||||
index = 0;
|
index = 0;
|
||||||
|
|
||||||
if (index < vm.selectedFolder.$cards.length)
|
if (index < vm.selectedFolder.$cards.length)
|
||||||
selectCard(vm.selectedFolder.$cards[index]);
|
vm.selectCard(vm.selectedFolder.$cards[index]);
|
||||||
else
|
else
|
||||||
index = -1;
|
index = -1;
|
||||||
|
|
||||||
|
@ -223,8 +210,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function confirmDeleteSelectedCards($event) {
|
this.confirmDeleteSelectedCards = function($event) {
|
||||||
var selectedCards = vm.selectedFolder.$selectedCards();
|
var selectedCards = this.selectedFolder.$selectedCards();
|
||||||
|
|
||||||
if (_.size(selectedCards) > 0)
|
if (_.size(selectedCards) > 0)
|
||||||
Dialog.confirm(l('Warning'),
|
Dialog.confirm(l('Warning'),
|
||||||
|
@ -240,7 +227,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
$event.preventDefault();
|
$event.preventDefault();
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see AddressBooksController.dragSelectedCards
|
* @see AddressBooksController.dragSelectedCards
|
||||||
|
@ -288,40 +275,40 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function copySelectedCards(folder) {
|
this.copySelectedCards = function(folder) {
|
||||||
_selectedCardsOperation('copy', folder);
|
_selectedCardsOperation('copy', folder);
|
||||||
}
|
};
|
||||||
|
|
||||||
function moveSelectedCards(folder) {
|
this.moveSelectedCards = function(folder) {
|
||||||
_selectedCardsOperation('move', folder);
|
_selectedCardsOperation('move', folder);
|
||||||
}
|
};
|
||||||
|
|
||||||
function selectAll() {
|
this.selectAll = function() {
|
||||||
_.forEach(vm.selectedFolder.$cards, function(card) {
|
_.forEach(this.selectedFolder.$cards, function(card) {
|
||||||
card.selected = true;
|
card.selected = true;
|
||||||
});
|
});
|
||||||
vm.mode.multiple = vm.selectedFolder.$cards.length;
|
this.mode.multiple = this.selectedFolder.$cards.length;
|
||||||
}
|
};
|
||||||
|
|
||||||
function sort(field) {
|
this.sort = function(field) {
|
||||||
vm.selectedFolder.$filter('', { sort: field });
|
this.selectedFolder.$filter('', { sort: field });
|
||||||
}
|
};
|
||||||
|
|
||||||
function sortedBy(field) {
|
this.sortedBy = function(field) {
|
||||||
return AddressBook.$query.sort == field;
|
return AddressBook.$query.sort == field;
|
||||||
}
|
};
|
||||||
|
|
||||||
function searchMode() {
|
this.searchMode = function() {
|
||||||
vm.mode.search = true;
|
vm.mode.search = true;
|
||||||
focus('search');
|
focus('search');
|
||||||
}
|
};
|
||||||
|
|
||||||
function cancelSearch() {
|
this.cancelSearch = function() {
|
||||||
vm.mode.search = false;
|
this.mode.search = false;
|
||||||
vm.selectedFolder.$filter('');
|
this.selectedFolder.$filter('');
|
||||||
}
|
};
|
||||||
|
|
||||||
function newMessage($event, recipients, recipientsField) {
|
this.newMessage = function($event, recipients, recipientsField) {
|
||||||
Account.$findAll().then(function(accounts) {
|
Account.$findAll().then(function(accounts) {
|
||||||
var account = _.find(accounts, function(o) {
|
var account = _.find(accounts, function(o) {
|
||||||
if (o.id === 0)
|
if (o.id === 0)
|
||||||
|
@ -349,17 +336,17 @@
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
function newMessageWithRecipient($event, recipient, fn) {
|
this.newMessageWithRecipient = function($event, recipient, fn) {
|
||||||
var recipients = [fn + ' <' + recipient + '>'];
|
var recipients = [fn + ' <' + recipient + '>'];
|
||||||
vm.newMessage($event, recipients, 'to');
|
this.newMessage($event, recipients, 'to');
|
||||||
$event.stopPropagation();
|
$event.stopPropagation();
|
||||||
$event.preventDefault();
|
$event.preventDefault();
|
||||||
}
|
};
|
||||||
|
|
||||||
function newMessageWithSelectedCards($event, recipientsField) {
|
this.newMessageWithSelectedCards = function($event, recipientsField) {
|
||||||
var selectedCards = _.filter(vm.selectedFolder.$cards, function(card) { return card.selected; });
|
var selectedCards = _.filter(this.selectedFolder.$cards, function(card) { return card.selected; });
|
||||||
var promises = [], recipients = [];
|
var promises = [], recipients = [];
|
||||||
|
|
||||||
_.forEach(selectedCards, function(card) {
|
_.forEach(selectedCards, function(card) {
|
||||||
|
@ -390,7 +377,44 @@
|
||||||
if (recipients.length)
|
if (recipients.length)
|
||||||
vm.newMessage($event, recipients, recipientsField);
|
vm.newMessage($event, recipients, recipientsField);
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
|
this.newListWithSelectedCards = function() {
|
||||||
|
var selectedCards = _.filter(this.selectedFolder.$cards, function(card) { return card.selected; });
|
||||||
|
var promises = [], refs = [];
|
||||||
|
|
||||||
|
_.forEach(selectedCards, function(card) {
|
||||||
|
if (card.$isList({expandable: true})) {
|
||||||
|
// If the list's members were already fetch, use them
|
||||||
|
if (angular.isDefined(card.refs) && card.refs.length) {
|
||||||
|
_.forEach(card.refs, function(ref) {
|
||||||
|
if (ref.email.length)
|
||||||
|
refs.push(ref);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
promises.push(card.$reload().then(function(card) {
|
||||||
|
_.forEach(card.refs, function(ref) {
|
||||||
|
if (ref.email.length)
|
||||||
|
refs.push(ref);
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (card.$$email && card.$$email.length) {
|
||||||
|
refs.push(card);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$q.all(promises).then(function() {
|
||||||
|
refs = _.uniqBy(_.map(refs, function(o) {
|
||||||
|
return { reference: o.id || o.reference, email: o.$$email || o.email };
|
||||||
|
}), 'reference');
|
||||||
|
if (refs.length)
|
||||||
|
$state.go('app.addressbook.new', { contactType: 'list', refs: refs });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
angular
|
angular
|
||||||
|
|
|
@ -136,8 +136,10 @@
|
||||||
Card.prototype.init = function(data, partial) {
|
Card.prototype.init = function(data, partial) {
|
||||||
var _this = this;
|
var _this = this;
|
||||||
|
|
||||||
this.refs = [];
|
if (angular.isUndefined(this.refs))
|
||||||
this.categories = [];
|
this.refs = [];
|
||||||
|
if (angular.isUndefined(this.categories))
|
||||||
|
this.categories = [];
|
||||||
this.c_screenname = null;
|
this.c_screenname = null;
|
||||||
angular.extend(this, data);
|
angular.extend(this, data);
|
||||||
if (!this.$$fullname)
|
if (!this.$$fullname)
|
||||||
|
|
|
@ -43,6 +43,9 @@
|
||||||
})
|
})
|
||||||
.state('app.addressbook.new', {
|
.state('app.addressbook.new', {
|
||||||
url: '/{contactType:(?:card|list)}/new',
|
url: '/{contactType:(?:card|list)}/new',
|
||||||
|
params: {
|
||||||
|
refs: { array: true }
|
||||||
|
},
|
||||||
views: {
|
views: {
|
||||||
card: {
|
card: {
|
||||||
templateUrl: 'UIxContactEditorTemplate', // UI/Templates/Contacts/UIxContactEditorTemplate.wox
|
templateUrl: 'UIxContactEditorTemplate', // UI/Templates/Contacts/UIxContactEditorTemplate.wox
|
||||||
|
@ -123,7 +126,7 @@
|
||||||
stateNewCard.$inject = ['$stateParams', 'stateAddressbook', 'Card'];
|
stateNewCard.$inject = ['$stateParams', 'stateAddressbook', 'Card'];
|
||||||
function stateNewCard($stateParams, stateAddressbook, Card) {
|
function stateNewCard($stateParams, stateAddressbook, Card) {
|
||||||
var tag = 'v' + $stateParams.contactType,
|
var tag = 'v' + $stateParams.contactType,
|
||||||
card = new Card({ pid: $stateParams.addressbookId, c_component: tag });
|
card = new Card({ pid: $stateParams.addressbookId, c_component: tag, refs: $stateParams.refs });
|
||||||
stateAddressbook.selectedCard = true;
|
stateAddressbook.selectedCard = true;
|
||||||
return card;
|
return card;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue