(js) New sgCalendarListItem component
parent
84edeb85cd
commit
02cbe23e78
|
@ -43,7 +43,7 @@
|
|||
<!-- User's calendars -->
|
||||
<section>
|
||||
<md-subheader class="sg-md-subheader--with-secondary-icon"
|
||||
md-colors="::{background: 'default-background-300'}">
|
||||
md-colors="::{color: 'default-background-700', background: 'default-background-300'}">
|
||||
<div layout="row" layout-align="space-between center">
|
||||
<span><var:string label:value="Calendars"/></span>
|
||||
<md-button class="sg-icon-button"
|
||||
|
@ -55,99 +55,19 @@
|
|||
</md-subheader>
|
||||
<md-list ng-model="app.service.$calendars"
|
||||
as-sortable="app.sortableCalendars" is-disabled="!app.sortableMode">
|
||||
<md-list-item ng-repeat="calendar in app.service.$calendars | filter:app.filter"
|
||||
as-sortable-item="as-sortable-item">
|
||||
<md-switch ng-model="calendar.active"
|
||||
ng-class="calendar.getClassName('md-switch')"
|
||||
ng-true-value="1"
|
||||
ng-false-value="0"
|
||||
label:aria-label="Enable"><!-- enable --></md-switch>
|
||||
<p class="sg-item-name"
|
||||
ng-dblclick="app.editFolder(calendar)"
|
||||
ng-show="app.editMode != calendar.id">
|
||||
<span ng-bind="calendar.name"><!-- name --></span>
|
||||
<md-tooltip md-delay="1000" md-autohide="true" ng-bind="calendar.name"><!-- tooltip --></md-tooltip>
|
||||
<span class="sg-counter-badge" ng-show="calendar.activeTasks" ng-bind="calendar.activeTasks"><!-- active tasks count --></span>
|
||||
</p>
|
||||
<md-input-container class="md-flex"
|
||||
ng-show="app.editMode == calendar.id">
|
||||
<input class="sg-item-name" type="text"
|
||||
label:aria-label="Name of the Calendar"
|
||||
ng-model="calendar.name"
|
||||
ng-blur="app.renameFolder(calendar)"
|
||||
sg-focus-on="calendarName_{{::calendar.id}}"
|
||||
sg-enter="app.renameFolder(calendar)"
|
||||
sg-escape="app.revertEditing(calendar)"/>
|
||||
</md-input-container>
|
||||
<md-button class="md-secondary md-icon-button" md-no-ink="md-no-ink"
|
||||
as-sortable-item-handle="as-sortable-item-handle">
|
||||
<md-icon md-colors="::{color: 'accent-400'}">drag_handle</md-icon>
|
||||
</md-button>
|
||||
<md-menu class="md-secondary sg-list-sortable-hide" label:aria-label="Options">
|
||||
<md-button class="md-icon-button" label:aria-label="Options"
|
||||
ng-click="$mdMenu.open()"
|
||||
md-menu-origin="md-menu-origin">
|
||||
<md-icon>more_vert</md-icon>
|
||||
</md-button>
|
||||
<md-menu-content width="2">
|
||||
<md-menu-item>
|
||||
<md-button ng-click="app.showOnly(calendar)">
|
||||
<var:string label:value="Show Only This Calendar"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="app.showAll()">
|
||||
<var:string label:value="Show All Calendars"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-divider><!-- divider --></md-menu-divider>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="app.showProperties(calendar)">
|
||||
<var:string label:value="Properties"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button type="button" ng-click="app.editFolder(calendar)">
|
||||
<var:string label:value="Rename"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item ng-show="calendar.id != 'personal'">
|
||||
<md-button ng-click="app.confirmDelete(calendar)">
|
||||
<var:string label:value="Delete"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-divider><!-- divider --></md-menu-divider>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="app.showLinks(calendar)">
|
||||
<var:string label:value="Links to this Calendar"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-divider><!-- divider --></md-menu-divider>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="app.importCalendar($event, calendar)">
|
||||
<var:string label:value="Import"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="calendar.export()">
|
||||
<var:string label:value="Export"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-divider><!-- divider --></md-menu-divider>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="app.share(calendar)">
|
||||
<var:string label:value="Sharing..."/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
</md-menu-content>
|
||||
</md-menu>
|
||||
<md-list-item
|
||||
class="sg-calendar-list-item"
|
||||
ng-repeat="calendar in app.service.$calendars | filter:app.filter"
|
||||
as-sortable-item="as-sortable-item"
|
||||
sg-calendar="calendar">
|
||||
<!-- sgCalendarListItem directive -->
|
||||
</md-list-item>
|
||||
</md-list>
|
||||
</section>
|
||||
<!-- Subscriptions -->
|
||||
<section>
|
||||
<md-subheader class="sg-md-subheader--with-secondary-icon"
|
||||
md-colors="::{background: 'default-background-300'}">
|
||||
md-colors="::{color: 'default-background-700', background: 'default-background-300'}">
|
||||
<div layout="row" layout-align="space-between center">
|
||||
<span><var:string label:value="Subscriptions"/></span>
|
||||
<md-button class="sg-icon-button"
|
||||
|
@ -160,85 +80,22 @@
|
|||
</md-subheader>
|
||||
<md-list ng-model="app.service.$subscriptions"
|
||||
as-sortable="app.sortableCalendars" is-disabled="!app.sortableMode">
|
||||
<md-list-item ng-repeat="calendar in app.service.$subscriptions | filter:app.filter"
|
||||
as-sortable-item="as-sortable-item">
|
||||
<md-switch ng-model="calendar.active"
|
||||
ng-class="calendar.getClassName('md-switch')"
|
||||
ng-true-value="1"
|
||||
ng-false-value="0"
|
||||
label:aria-label="Enable"><!-- enable --></md-switch>
|
||||
<p class="sg-item-name"
|
||||
ng-dblclick="app.editFolder(calendar)"
|
||||
ng-show="app.editMode != calendar.id">
|
||||
<span ng-bind="calendar.name"><!-- name --></span>
|
||||
<md-tooltip md-delay="1000" md-autohide="true" ng-bind="calendar.name"><!-- tooltip --></md-tooltip>
|
||||
<span class="sg-counter-badge" ng-show="calendar.activeTasks" ng-bind="calendar.activeTasks"><!-- active tasks count --></span>
|
||||
</p>
|
||||
<md-input-container class="md-flex"
|
||||
ng-show="app.editMode == calendar.id">
|
||||
<input class="sg-item-name" type="text"
|
||||
label:aria-label="Name of the Calendar"
|
||||
ng-model="calendar.name"
|
||||
ng-blur="app.renameFolder(calendar)"
|
||||
sg-focus-on="calendarName_{{::calendar.id}}"
|
||||
sg-enter="app.renameFolder(calendar)"
|
||||
sg-escape="app.revertEditing(calendar)"/>
|
||||
</md-input-container>
|
||||
<md-button class="md-secondary md-icon-button" md-no-ink="md-no-ink"
|
||||
as-sortable-item-handle="as-sortable-item-handle">
|
||||
<md-icon md-colors="::{color: 'accent-400'}">drag_handle</md-icon>
|
||||
</md-button>
|
||||
<md-menu class="md-secondary sg-list-sortable-hide" label:aria-label="Options">
|
||||
<md-button class="md-icon-button" label:aria-label="Options"
|
||||
ng-click="$mdMenu.open()"
|
||||
md-menu-origin="md-menu-origin">
|
||||
<md-icon>more_vert</md-icon>
|
||||
</md-button>
|
||||
<md-menu-content width="2">
|
||||
<md-menu-item>
|
||||
<md-button ng-click="app.showOnly(calendar)">
|
||||
<var:string label:value="Show Only This Calendar"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="app.showAll()">
|
||||
<var:string label:value="Show All Calendars"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-divider><!-- divider --></md-menu-divider>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="app.showProperties(calendar)">
|
||||
<var:string label:value="Properties"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button type="button" ng-click="app.editFolder(calendar)">
|
||||
<var:string label:value="Rename"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="app.confirmDelete(calendar)">
|
||||
<var:string label:value="Unsubscribe Calendar"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-divider><!-- divider --></md-menu-divider>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="app.showLinks(calendar)">
|
||||
<var:string label:value="Links to this Calendar"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
</md-menu-content>
|
||||
</md-menu>
|
||||
<md-list-item
|
||||
class="sg-calendar-list-item"
|
||||
ng-repeat="calendar in app.service.$subscriptions | filter:app.filter"
|
||||
as-sortable-item="as-sortable-item"
|
||||
sg-calendar="calendar">
|
||||
<!-- sgCalendarListItem directive -->
|
||||
</md-list-item>
|
||||
</md-list>
|
||||
</section>
|
||||
<!-- Web Calendars -->
|
||||
<section>
|
||||
<md-subheader class="sg-md-subheader--with-secondary-icon"
|
||||
md-colors="::{background: 'default-background-300'}">
|
||||
md-colors="::{color: 'default-background-700', background: 'default-background-300'}">
|
||||
<div layout="row" layout-align="space-between center">
|
||||
<span><var:string label:value="Web Calendars"/></span>
|
||||
<md-button class="sg-icon-button"
|
||||
<md-button class="md-icon-button"
|
||||
label:aria-label="Subscribe to a web calendar..."
|
||||
ng-click="app.addWebCalendar()">
|
||||
<md-icon>add_circle_outline</md-icon>
|
||||
|
@ -247,67 +104,12 @@
|
|||
</md-subheader>
|
||||
<md-list ng-model="app.service.$webcalendars"
|
||||
as-sortable="app.sortableCalendars" is-disabled="!app.sortableMode">
|
||||
<md-list-item ng-repeat="calendar in app.service.$webcalendars | filter:app.filter"
|
||||
as-sortable-item="as-sortable-item">
|
||||
<md-switch ng-model="calendar.active"
|
||||
ng-class="calendar.getClassName('md-switch')"
|
||||
ng-true-value="1"
|
||||
ng-false-value="0"
|
||||
label:aria-label="Enable"><!-- enable --></md-switch>
|
||||
<p class="sg-item-name"
|
||||
ng-dblclick="app.editFolder(calendar)"
|
||||
ng-show="app.editMode != calendar.id">
|
||||
<span class="ng-hide" ng-show="calendar.$error">
|
||||
<md-icon class="md-warn">warning</md-icon>
|
||||
<md-tooltip ng-bind="calendar.$error"><!-- error as a tooltip --></md-tooltip>
|
||||
</span>
|
||||
<md-tooltip md-delay="1000" md-autohide="true" ng-bind="calendar.name"><!-- tooltip --></md-tooltip>
|
||||
<span ng-bind="calendar.name"><!-- name --></span>
|
||||
</p>
|
||||
<md-input-container class="md-flex"
|
||||
ng-show="app.editMode == calendar.id">
|
||||
<input class="sg-item-name" type="text"
|
||||
label:aria-label="Name of the Calendar"
|
||||
ng-model="calendar.name"
|
||||
ng-blur="app.renameFolder(calendar)"
|
||||
sg-focus-on="calendarName_{{calendar.id}}"
|
||||
sg-enter="app.renameFolder(calendar)"
|
||||
sg-escape="app.revertEditing(calendar)"/>
|
||||
</md-input-container>
|
||||
<md-button class="md-secondary md-icon-button" md-no-ink="md-no-ink"
|
||||
as-sortable-item-handle="as-sortable-item-handle">
|
||||
<md-icon md-colors="::{color: 'accent-400'}">drag_handle</md-icon>
|
||||
</md-button>
|
||||
<md-menu class="md-secondary sg-list-sortable-hide" label:aria-label="Options">
|
||||
<md-button class="md-icon-button" label:aria-label="Options"
|
||||
ng-click="$mdMenu.open()"
|
||||
md-menu-origin="md-menu-origin">
|
||||
<md-icon>more_vert</md-icon>
|
||||
</md-button>
|
||||
<md-menu-content width="2">
|
||||
<md-menu-item>
|
||||
<md-button ng-click="app.showProperties(calendar)">
|
||||
<var:string label:value="Properties"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button type="button" ng-click="app.editFolder(calendar)">
|
||||
<var:string label:value="Rename"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="app.confirmDelete(calendar)">
|
||||
<var:string label:value="Delete"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-divider><!-- divider --></md-menu-divider>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="app.showLinks(calendar)">
|
||||
<var:string label:value="Links to this Calendar"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
</md-menu-content>
|
||||
</md-menu>
|
||||
<md-list-item
|
||||
class="sg-calendar-list-item"
|
||||
ng-repeat="calendar in app.service.$webcalendars | filter:app.filter"
|
||||
as-sortable-item="as-sortable-item"
|
||||
sg-calendar="calendar">
|
||||
<!-- sgCalendarListItem directive -->
|
||||
</md-list-item>
|
||||
</md-list>
|
||||
</section>
|
||||
|
@ -317,7 +119,7 @@
|
|||
<div class="md-toolbar-tools sg-toolbar-tools--dense"
|
||||
md-colors="::{backgroundColor: 'background-500'}"
|
||||
ng-hide="app.sortableMode">
|
||||
<md-input-container class="md-flex" md-no-float="md-no-float">
|
||||
<md-input-container class="md-flex" md-no-float="true">
|
||||
<md-icon>search</md-icon>
|
||||
<input ng-model="app.filter.name" type="search" label:placeholder="Filter"/>
|
||||
</md-input-container>
|
||||
|
@ -712,6 +514,71 @@
|
|||
</section>
|
||||
</script>
|
||||
|
||||
<!-- template of contextual menu for a calendar -->
|
||||
<script type="text/ng-template" id="UIxCalendarMenu">
|
||||
<div md-whiteframe="3">
|
||||
<md-menu-content width="2">
|
||||
<md-menu-item>
|
||||
<md-button ng-click="$menuCtrl.showOnly()">
|
||||
<var:string label:value="Show Only This Calendar"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="$menuCtrl.showAll()">
|
||||
<var:string label:value="Show All Calendars"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-divider><!-- divider --></md-menu-divider>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="$menuCtrl.showProperties($event)">
|
||||
<var:string label:value="Properties"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item>
|
||||
<md-button type="button" ng-click="$menuCtrl.editFolder()">
|
||||
<var:string label:value="Rename"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item ng-show="$menuCtrl.calendar.id != 'personal'">
|
||||
<md-button ng-click="$menuCtrl.confirmDelete($event)"
|
||||
ng-switch="$menuCtrl.calendar.isSubscription">
|
||||
<span ng-switch-when="true"><var:string label:value="Unsubscribe Calendar"/></span>
|
||||
<span ng-switch-when="false"><var:string label:value="Delete"/></span>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-divider><!-- divider --></md-menu-divider>
|
||||
<md-menu-item>
|
||||
<md-button ng-click="$menuCtrl.showLinks($event)">
|
||||
<var:string label:value="Links to this Calendar"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-divider
|
||||
ng-hide="::($menuCtrl.calendar.isSubscription || $menuCtrl.calendar.isWebCalendar)">
|
||||
<!-- divider -->
|
||||
</md-menu-divider>
|
||||
<md-menu-item ng-hide="::($menuCtrl.calendar.isSubscription || $menuCtrl.calendar.isWebCalendar)">
|
||||
<md-button ng-click="$menuCtrl.importCalendar($event)">
|
||||
<var:string label:value="Import"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-item ng-hide="::($menuCtrl.calendar.isSubscription || $menuCtrl.calendar.isWebCalendar)">
|
||||
<md-button ng-click="$menuCtrl.calendar.export()">
|
||||
<var:string label:value="Export"/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
<md-menu-divider
|
||||
ng-hide="::($menuCtrl.calendar.isSubscription || $menuCtrl.calendar.isWebCalendar)">
|
||||
<!-- divider -->
|
||||
</md-menu-divider>
|
||||
<md-menu-item ng-hide="::($menuCtrl.calendar.isSubscription || $menuCtrl.calendar.isWebCalendar)">
|
||||
<md-button ng-click="$menuCtrl.share()">
|
||||
<var:string label:value="Sharing..."/>
|
||||
</md-button>
|
||||
</md-menu-item>
|
||||
</md-menu-content>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<!-- modal inner content for acl editor -->
|
||||
<script type="text/ng-template" id="UIxUserRightsEditor">
|
||||
<var:component className="UIxCalUserRightsEditor" />
|
||||
|
|
|
@ -6,26 +6,15 @@
|
|||
/**
|
||||
* @ngInject
|
||||
*/
|
||||
CalendarsController.$inject = ['$rootScope', '$scope', '$window', '$mdDialog', '$log', '$mdToast', 'FileUploader', 'sgFocus', 'Dialog', 'sgSettings', 'Preferences', 'Calendar', 'User', 'stateCalendars'];
|
||||
function CalendarsController($rootScope, $scope, $window, $mdDialog, $log, $mdToast, FileUploader, focus, Dialog, Settings, Preferences, Calendar, User, stateCalendars) {
|
||||
CalendarsController.$inject = ['$rootScope', '$scope', '$window', '$mdDialog', '$log', '$mdToast', 'Dialog', 'sgSettings', 'Preferences', 'Calendar'];
|
||||
function CalendarsController($rootScope, $scope, $window, $mdDialog, $log, $mdToast, Dialog, Settings, Preferences, Calendar) {
|
||||
var vm = this;
|
||||
|
||||
vm.activeUser = Settings.activeUser;
|
||||
vm.service = Calendar;
|
||||
vm.newCalendar = newCalendar;
|
||||
vm.addWebCalendar = addWebCalendar;
|
||||
vm.confirmDelete = confirmDelete;
|
||||
vm.editFolder = editFolder;
|
||||
vm.revertEditing = revertEditing;
|
||||
vm.renameFolder = renameFolder;
|
||||
vm.share = share;
|
||||
vm.importCalendar = importCalendar;
|
||||
vm.showOnly = showOnly;
|
||||
vm.showAll = showAll;
|
||||
vm.showLinks = showLinks;
|
||||
vm.showProperties = showProperties;
|
||||
vm.subscribeToFolder = subscribeToFolder;
|
||||
// vm.today = today;
|
||||
|
||||
vm.filter = { name: '' };
|
||||
vm.sortableMode = false;
|
||||
|
@ -164,234 +153,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
function confirmDelete(folder) {
|
||||
if (folder.isSubscription) {
|
||||
// Unsubscribe without confirmation
|
||||
folder.$delete()
|
||||
.catch(function(data, status) {
|
||||
Dialog.alert(l('An error occured while deleting the calendar "%{0}".', folder.name),
|
||||
l(data.error));
|
||||
});
|
||||
}
|
||||
else {
|
||||
Dialog.confirm(l('Warning'), l('Are you sure you want to delete the calendar "%{0}"?', folder.name),
|
||||
{ ok: l('Delete') })
|
||||
.then(function() {
|
||||
folder.$delete()
|
||||
.catch(function(data, status) {
|
||||
Dialog.alert(l('An error occured while deleting the calendar "%{0}".', folder.name),
|
||||
l(data.error));
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function importCalendar($event, folder) {
|
||||
$mdDialog.show({
|
||||
parent: angular.element(document.body),
|
||||
targetEvent: $event,
|
||||
clickOutsideToClose: true,
|
||||
escapeToClose: true,
|
||||
templateUrl: 'UIxCalendarImportDialog',
|
||||
controller: CalendarImportDialogController,
|
||||
controllerAs: '$CalendarImportDialogController',
|
||||
locals: {
|
||||
folder: folder
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @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()
|
||||
.content(msg)
|
||||
.position('top right')
|
||||
.hideDelay(3000));
|
||||
},
|
||||
onErrorItem: function(item, response, status, headers) {
|
||||
$mdToast.show({
|
||||
template: [
|
||||
'<md-toast>',
|
||||
' <div class="md-toast-content">',
|
||||
' <md-icon class="md-warn md-hue-1">error_outline</md-icon>',
|
||||
' <span>' + l('An error occurred while importing calendar.') + '</span>',
|
||||
' </div>',
|
||||
'</md-toast>'
|
||||
].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: [
|
||||
'<md-toast>',
|
||||
' <div class="md-toast-content">',
|
||||
' <md-icon class="md-warn md-hue-1">error_outline</md-icon>',
|
||||
' <span>' + l('Select an iCalendar file (.ics).') + '</span>',
|
||||
' </div>',
|
||||
'</md-toast>'
|
||||
].join(''),
|
||||
position: 'top right',
|
||||
hideDelay: 3000
|
||||
});
|
||||
|
||||
return isTextFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function showOnly(calendar) {
|
||||
_.forEach(Calendar.$findAll(), function(o) {
|
||||
if (calendar.id == o.id)
|
||||
o.active = 1;
|
||||
else
|
||||
o.active = 0;
|
||||
});
|
||||
}
|
||||
|
||||
function showAll() {
|
||||
_.forEach(Calendar.$findAll(), function(o) { o.active = 1; });
|
||||
}
|
||||
|
||||
function showLinks(calendar) {
|
||||
$mdDialog.show({
|
||||
parent: angular.element(document.body),
|
||||
clickOutsideToClose: true,
|
||||
escapeToClose: true,
|
||||
templateUrl: calendar.id + '/links',
|
||||
controller: LinksDialogController,
|
||||
controllerAs: 'links',
|
||||
locals: {
|
||||
calendar: calendar
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @ngInject
|
||||
*/
|
||||
LinksDialogController.$inject = ['$mdDialog', 'calendar'];
|
||||
function LinksDialogController($mdDialog, calendar) {
|
||||
var vm = this;
|
||||
vm.calendar = calendar;
|
||||
vm.close = close;
|
||||
|
||||
function close() {
|
||||
$mdDialog.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function showProperties(calendar) {
|
||||
var color = calendar.color;
|
||||
$mdDialog.show({
|
||||
templateUrl: calendar.id + '/properties',
|
||||
controller: PropertiesDialogController,
|
||||
controllerAs: 'properties',
|
||||
clickOutsideToClose: true,
|
||||
escapeToClose: true,
|
||||
locals: {
|
||||
srcCalendar: calendar
|
||||
}
|
||||
}).catch(function() {
|
||||
// Restore original color when cancelling or closing the dialog
|
||||
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() {
|
||||
vm.calendar.$save();
|
||||
// Refresh list instance
|
||||
srcCalendar.init(vm.calendar.$omit());
|
||||
$mdDialog.hide();
|
||||
}
|
||||
|
||||
function close() {
|
||||
$mdDialog.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function editFolder(folder) {
|
||||
vm.calendarName = folder.name;
|
||||
vm.editMode = folder.id;
|
||||
focus('calendarName_' + folder.id);
|
||||
}
|
||||
|
||||
function revertEditing(folder) {
|
||||
folder.$reset();
|
||||
vm.editMode = false;
|
||||
}
|
||||
|
||||
function renameFolder(folder) {
|
||||
folder.$rename()
|
||||
.then(function(data) {
|
||||
vm.editMode = false;
|
||||
});
|
||||
}
|
||||
|
||||
function share(calendar) {
|
||||
calendar.$acl.$users().then(function() {
|
||||
$mdDialog.show({
|
||||
templateUrl: calendar.id + '/UIxAclEditor', // UI/Templates/UIxAclEditor.wox
|
||||
controller: 'AclController', // from the ng module SOGo.Common
|
||||
controllerAs: 'acl',
|
||||
clickOutsideToClose: true,
|
||||
escapeToClose: true,
|
||||
locals: {
|
||||
usersWithACL: calendar.$acl.users,
|
||||
User: User,
|
||||
folder: calendar
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Callback of sgSubscribe directive
|
||||
function subscribeToFolder(calendarData) {
|
||||
|
@ -405,14 +166,6 @@
|
|||
});
|
||||
}
|
||||
|
||||
// function today() {
|
||||
// var fragments = $window.location.hash.split('/'),
|
||||
// state = fragments[1],
|
||||
// view = fragments[2],
|
||||
// now = new Date(),
|
||||
// path = ['#', state, view, now.getDayString()];
|
||||
// $window.location = path.join('/');
|
||||
// }
|
||||
}
|
||||
|
||||
angular
|
||||
|
|
|
@ -0,0 +1,394 @@
|
|||
/* -*- 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: [
|
||||
'<md-switch ng-model="$ctrl.calendar.active"',
|
||||
' ng-class="$ctrl.calendar.getClassName(\'md-switch\')"',
|
||||
' ng-true-value="1"',
|
||||
' ng-false-value="0"',
|
||||
' aria-label="' + l('Enable') + '"></md-switch>',
|
||||
'<p class="sg-item-name"',
|
||||
' ng-dblclick="$ctrl.editFolder($event)">',
|
||||
' <span ng-bind="$ctrl.calendar.name"></span>',
|
||||
' <md-tooltip md-delay="1000"',
|
||||
' md-autohide="true"',
|
||||
' ng-bind="$ctrl.calendar.name"></md-tooltip>',
|
||||
' <span class="sg-counter-badge ng-hide"',
|
||||
' ng-show="calendar.activeTasks"',
|
||||
' ng-bind="calendar.activeTasks"></span>',
|
||||
'</p>',
|
||||
'<md-input-container class="md-flex ng-hide">',
|
||||
' <input class="sg-item-name" type="text"',
|
||||
' aria-label="' + l('Name of the Calendar') + '"',
|
||||
' ng-blur="$ctrl.saveFolder($event)"',
|
||||
' sg-enter="$ctrl.saveFolder($event)"',
|
||||
' sg-escape="$ctrl.revertEditing()" />',
|
||||
'</md-input-container>',
|
||||
'<md-button class="md-secondary md-icon-button" ',
|
||||
' as-sortable-item-handle="as-sortable-item-handle">',
|
||||
' <md-icon md-colors="::{color: \'accent-400\'}">drag_handle</md-icon>',
|
||||
'</md-button>',
|
||||
'<md-icon class="md-menu sg-list-sortable-hide"',
|
||||
' ng-click="$ctrl.showMenu($event)"',
|
||||
' aria-label="' + l("Options") + '">more_vert</md-icon>'
|
||||
].join(''),
|
||||
controller: 'sgCalendarListItemController',
|
||||
controllerAs: '$ctrl'
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @ngInject
|
||||
*/
|
||||
sgCalendarListItemController.$inject = ['$scope', '$element', '$mdToast', '$mdPanel', '$mdMedia', '$mdSidenav', 'sgConstant', 'Dialog', 'Calendar'];
|
||||
function sgCalendarListItemController($scope, $element, $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) {
|
||||
this.editMode = true;
|
||||
this.inputElement.value = this.calendar.name;
|
||||
this.clickableElement.classList.add('ng-hide');
|
||||
this.inputContainer.classList.remove('ng-hide');
|
||||
this.inputElement.focus();
|
||||
this.inputElement.select();
|
||||
if ($event) {
|
||||
$event.stopPropagation();
|
||||
$event.preventDefault();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
this.saveFolder = function($event) {
|
||||
if (this.inputElement.disabled)
|
||||
return;
|
||||
|
||||
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();
|
||||
})
|
||||
.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) {
|
||||
// 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() {
|
||||
vm.calendar.$save();
|
||||
// Refresh list instance
|
||||
srcCalendar.init(vm.calendar.$omit());
|
||||
$mdDialog.hide();
|
||||
}
|
||||
|
||||
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',
|
||||
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()
|
||||
.content(msg)
|
||||
.position('top right')
|
||||
.hideDelay(3000));
|
||||
},
|
||||
onErrorItem: function(item, response, status, headers) {
|
||||
$mdToast.show({
|
||||
template: [
|
||||
'<md-toast>',
|
||||
' <div class="md-toast-content">',
|
||||
' <md-icon class="md-warn md-hue-1">error_outline</md-icon>',
|
||||
' <span>' + l('An error occurred while importing calendar.') + '</span>',
|
||||
' </div>',
|
||||
'</md-toast>'
|
||||
].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: [
|
||||
'<md-toast>',
|
||||
' <div class="md-toast-content">',
|
||||
' <md-icon class="md-warn md-hue-1">error_outline</md-icon>',
|
||||
' <span>' + l('Select an iCalendar file (.ics).') + '</span>',
|
||||
' </div>',
|
||||
'</md-toast>'
|
||||
].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);
|
||||
})();
|
Loading…
Reference in New Issue