/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ (function() { /** * sgCalendarListItem - A directive that defines the content of a md-list-item for a calendar. * @memberof SOGo.SchedulerUI */ function sgCalendarListItem() { return { restrict: 'C', scope: {}, bindToController: { calendar: '=sgCalendar' }, template: [ '', '

', ' ', ' error', ' ', ' ', '

', '', ' ', '', 'drag_handle', 'more_vert' ].join(''), controller: 'sgCalendarListItemController', controllerAs: '$ctrl' }; } /** * @ngInject */ sgCalendarListItemController.$inject = ['$rootScope', '$scope', '$element', '$timeout', '$mdToast', '$mdPanel', '$mdMedia', '$mdSidenav', 'sgConstant', 'Dialog', 'Calendar']; function sgCalendarListItemController($rootScope, $scope, $element, $timeout, $mdToast, $mdPanel, $mdMedia, $mdSidenav, sgConstant, Dialog, Calendar) { var $ctrl = this; this.$onInit = function() { this.editMode = false; }; this.$postLink = function() { this.clickableElement = $element.find('p')[0]; this.nameElements = this.clickableElement.getElementsByClassName('sg-calendar-name'); this.inputContainer = $element.find('md-input-container')[0]; this.inputElement = $element.find('input')[0]; this.moreOptionsButton = _.last($element.find('md-icon')); this.updateCalendarName(); }; this.updateCalendarName = function() { _.forEach(this.nameElements, function(e) { e.innerHTML = $ctrl.calendar.name; }); }; this.editFolder = function($event) { $event.stopPropagation(); $event.preventDefault(); this.editMode = true; this.inputElement.value = this.calendar.name; this.clickableElement.classList.add('ng-hide'); this.inputContainer.classList.remove('ng-hide'); if ($event.srcEvent && $event.srcEvent.type == 'touchend') { $timeout(function() { $ctrl.inputElement.focus(); $ctrl.inputElement.select(); }, 200); // delayed focus for iOS } else { this.inputElement.select(); this.inputElement.focus(); } if (this.panel) { this.panel.close(); } }; this.saveFolder = function($event) { if (this.inputElement.disabled) return; if (this.inputElement.value.length === 0) this.revertEditing(); this.calendar.name = this.inputElement.value; this.inputElement.disabled = true; this.calendar.$rename() .then(function(data) { $ctrl.editMode = false; $ctrl.inputContainer.classList.add('ng-hide'); $ctrl.clickableElement.classList.remove('ng-hide'); $ctrl.updateCalendarName(); }, function() { $ctrl.editMode = true; $ctrl.inputElement.value = $ctrl.calendar.name; $timeout(function() { $ctrl.inputElement.focus(); $ctrl.inputElement.select(); }, 200); // delayed focus for iOS }) .finally(function() { $ctrl.inputElement.disabled = false; }); }; this.revertEditing = function() { this.editMode = false; this.clickableElement.classList.remove('ng-hide'); this.inputContainer.classList.add('ng-hide'); this.inputElement.value = this.calendar.name; }; this.confirmDelete = function() { if (this.calendar.isSubscription) { // Unsubscribe without confirmation this.calendar.$delete() .catch(function(data, status) { Dialog.alert(l('An error occured while deleting the calendar "%{0}".', $ctrl.calendar.name), l(data.error)); }); } else { Dialog.confirm(l('Warning'), l('Are you sure you want to delete the calendar "%{0}"?', this.calendar.name), { ok: l('Delete') }) .then(function() { $ctrl.calendar.$delete() .catch(function(data, status) { Dialog.alert(l('An error occured while deleting the calendar "%{0}".', $ctrl.calendar.name), l(data.error)); }); }); } }; this.showMenu = function($event) { var panelPosition = $mdPanel.newPanelPosition() .relativeTo(this.moreOptionsButton) .addPanelPosition( $mdPanel.xPosition.ALIGN_START, $mdPanel.yPosition.ALIGN_TOPS ); var panelAnimation = $mdPanel.newPanelAnimation() .openFrom(this.moreOptionsButton) .duration(100) .withAnimation($mdPanel.animation.FADE); var config = { attachTo: angular.element(document.body), locals: { itemCtrl: this, calendar: this.calendar, editFolder: angular.bind(this, this.editFolder), confirmDelete: angular.bind(this, this.confirmDelete) }, bindToController: true, controller: MenuController, controllerAs: '$menuCtrl', position: panelPosition, animation: panelAnimation, targetEvent: $event, templateUrl: 'UIxCalendarMenu', trapFocus: true, clickOutsideToClose: true, escapeToClose: true, focusOnOpen: true }; $mdPanel.open(config) .then(function(panelRef) { $ctrl.panel = panelRef; // Automatically close panel when clicking inside of it panelRef.panelEl.one('click', function() { panelRef.close(); }); }); MenuController.$inject = ['mdPanelRef', '$mdDialog', 'FileUploader', 'User']; function MenuController(mdPanelRef, $mdDialog, FileUploader, User) { var $menuCtrl = this; this.showOnly = function() { _.forEach(Calendar.$findAll(), function(o) { if ($menuCtrl.calendar.id == o.id) o.active = 1; else o.active = 0; }); }; this.showAll = function() { _.forEach(Calendar.$findAll(), function(o) { o.active = 1; }); }; this.showProperties = function() { var color = this.calendar.color; $mdDialog.show({ templateUrl: this.calendar.id + '/properties', controller: PropertiesDialogController, controllerAs: 'properties', clickOutsideToClose: true, escapeToClose: true, locals: { srcCalendar: this.calendar } }).catch(function() { // Restore original color when cancelling or closing the dialog $menuCtrl.calendar.color = color; }); /** * @ngInject */ PropertiesDialogController.$inject = ['$scope', '$mdDialog', 'srcCalendar']; function PropertiesDialogController($scope, $mdDialog, srcCalendar) { var vm = this; vm.calendar = new Calendar(srcCalendar.$omit()); vm.saveProperties = saveProperties; vm.close = close; $scope.$watch(function() { return vm.calendar.color; }, function() { srcCalendar.color = vm.calendar.color; }); function saveProperties(form) { if (form.$valid) { vm.calendar.$save().then(function() { // Refresh list instance srcCalendar.init(vm.calendar.$omit()); $mdDialog.hide(); }, function() { form.$setPristine(); }); } } function close() { $mdDialog.cancel(); } } }; this.showLinks = function() { $mdDialog.show({ parent: angular.element(document.body), clickOutsideToClose: true, escapeToClose: true, templateUrl: this.calendar.id + '/links', controller: LinksDialogController, controllerAs: 'links', locals: { calendar: this.calendar } }); /** * @ngInject */ LinksDialogController.$inject = ['$mdDialog', 'calendar']; function LinksDialogController($mdDialog, calendar) { var vm = this; vm.calendar = calendar; vm.close = close; function close() { $mdDialog.hide(); } } }; this.importCalendar = function() { $mdDialog.show({ parent: angular.element(document.body), targetEvent: $event, clickOutsideToClose: true, escapeToClose: true, templateUrl: 'UIxCalendarImportDialog', // subtemplate of UIxCalMainView.wox controller: CalendarImportDialogController, controllerAs: '$CalendarImportDialogController', locals: { folder: this.calendar } }); /** * @ngInject */ CalendarImportDialogController.$inject = ['scope', '$mdDialog', 'folder']; function CalendarImportDialogController(scope, $mdDialog, folder) { var vm = this; vm.uploader = new FileUploader({ url: ApplicationBaseURL + [folder.id, 'import'].join('/'), autoUpload: true, queueLimit: 1, filters: [{ name: filterByExtension, fn: filterByExtension }], onSuccessItem: function(item, response, status, headers) { var msg; $mdDialog.hide(); if (response.imported === 0) msg = l('No event was imported.'); else { msg = l('A total of %{0} events were imported in the calendar.', response.imported); $rootScope.$emit('calendars:list'); } $mdToast.show( $mdToast.simple() .textContent(msg) .position('top right') .hideDelay(3000)); }, onErrorItem: function(item, response, status, headers) { $mdToast.show({ template: [ '', '
', ' error_outline', ' ' + l('An error occurred while importing calendar.') + '', '
', '
' ].join(''), position: 'top right', hideDelay: 3000 }); } }); vm.close = function() { $mdDialog.hide(); }; function filterByExtension(item) { var isTextFile = item.type.indexOf('text') === 0 || /\.(ics)$/.test(item.name); if (!isTextFile) $mdToast.show({ template: [ '', '
', ' error_outline', ' ' + l('Select an iCalendar file (.ics).') + '', '
', '
' ].join(''), position: 'top right', hideDelay: 3000 }); return isTextFile; } } }; this.share = function() { // Fetch list of ACL users this.calendar.$acl.$users().then(function() { // Show ACL editor $mdDialog.show({ templateUrl: $menuCtrl.calendar.id + '/UIxAclEditor', // UI/Templates/UIxAclEditor.wox controller: 'AclController', // from the ng module SOGo.Common controllerAs: 'acl', clickOutsideToClose: true, escapeToClose: true, locals: { usersWithACL: $menuCtrl.calendar.$acl.users, User: User, folder: $menuCtrl.calendar } }); }); }; } // MenuController }; } angular .module('SOGo.SchedulerUI') .controller('sgCalendarListItemController', sgCalendarListItemController) .directive('sgCalendarListItem', sgCalendarListItem); })();