(js) Improve attendees editor performance
parent
4df69587a2
commit
991f1d25a4
|
@ -43,11 +43,11 @@
|
|||
<md-icon>person</md-icon>
|
||||
</div>
|
||||
<sg-avatar-image class="md-avatar"
|
||||
sg-email="editor.component.organizer.email"
|
||||
sg-email="::editor.component.organizer.email"
|
||||
size="40">person</sg-avatar-image>
|
||||
<div class="sg-tile-content sg-padded--right">
|
||||
<div class="sg-md-subhead"><div>{{editor.component.organizer.name}}</div></div>
|
||||
<div class="sg-md-body"><div>{{editor.component.organizer.email}}</div></div>
|
||||
<div class="sg-md-subhead"><div>{{::editor.component.organizer.name}}</div></div>
|
||||
<div class="sg-md-body"><div>{{::editor.component.organizer.email}}</div></div>
|
||||
</div>
|
||||
<md-divider><!-- divider --></md-divider>
|
||||
</md-list-item>
|
||||
|
@ -78,7 +78,7 @@
|
|||
<md-divider><!-- divider --></md-divider>
|
||||
</md-list-item>
|
||||
</md-list>
|
||||
<md-content id="freebusy">
|
||||
<md-content id="freebusy" class="sg-freebusy" sg-component="editor.component">
|
||||
<!-- freebusy -->
|
||||
<md-list class="day"
|
||||
id="freebusy_day_{{ day.getDayString }}"
|
||||
|
@ -93,45 +93,16 @@
|
|||
</div>
|
||||
</md-list-item>
|
||||
<!-- organizer freebusy -->
|
||||
<md-list-item>
|
||||
<div class="hour"
|
||||
ng-class="{'sg-no-freebusy': !editor.component.organizer.uid}"
|
||||
ng-repeat="hour in ::editor.attendeesEditor.hours">
|
||||
<div class="quarter" ng-class="{event: editor.coversFreeBusy(day.getDayString, hour, 0)}">
|
||||
<div class="busy" ng-show="editor.component.organizer.freebusy[day.getDayString][hour][0]"><!-- 15 minutes --></div>
|
||||
</div>
|
||||
<div class="quarter" ng-class="{event: editor.coversFreeBusy(day.getDayString, hour, 1)}">
|
||||
<div class="busy" ng-show="editor.component.organizer.freebusy[day.getDayString][hour][1]"><!-- 15 minutes --></div>
|
||||
</div>
|
||||
<div class="quarter" ng-class="{event: editor.coversFreeBusy(day.getDayString, hour, 2)}">
|
||||
<div class="busy" ng-show="editor.component.organizer.freebusy[day.getDayString][hour][2]"><!-- 15 minutes --></div>
|
||||
</div>
|
||||
<div class="quarter" ng-class="{event: editor.coversFreeBusy(day.getDayString, hour, 3)}">
|
||||
<div class="busy" ng-show="editor.component.organizer.freebusy[day.getDayString][hour][3]"><!-- 15 minutes --></div>
|
||||
</div>
|
||||
</div>
|
||||
<md-divider><!-- divider --></md-divider>
|
||||
</md-list-item>
|
||||
<sg-freebusy-day
|
||||
sg-day="day.getDayString"
|
||||
sg-attendees="editor.component.$attendees"
|
||||
sg-attendee="editor.component.organizer"><!-- organizer --></sg-freebusy-day>
|
||||
<!-- attendees freebusy -->
|
||||
<md-list-item ng-repeat="currentAttendee in editor.component.attendees track by currentAttendee.email">
|
||||
<div class="hour"
|
||||
ng-class="{'sg-no-freebusy': !currentAttendee.uid}"
|
||||
ng-repeat="hour in ::editor.attendeesEditor.hours">
|
||||
<div class="quarter" ng-class="{event: editor.coversFreeBusy(day.getDayString, hour, 0)}">
|
||||
<div class="busy" ng-show="currentAttendee.freebusy[day.getDayString][hour][0]"><!-- 15 minutes --></div>
|
||||
</div>
|
||||
<div class="quarter" ng-class="{event: editor.coversFreeBusy(day.getDayString, hour, 1)}">
|
||||
<div class="busy" ng-show="currentAttendee.freebusy[day.getDayString][hour][1]"><!-- 15 minutes --></div>
|
||||
</div>
|
||||
<div class="quarter" ng-class="{event: editor.coversFreeBusy(day.getDayString, hour, 2)}">
|
||||
<div class="busy" ng-show="currentAttendee.freebusy[day.getDayString][hour][2]"><!-- 15 minutes --></div>
|
||||
</div>
|
||||
<div class="quarter" ng-class="{event: editor.coversFreeBusy(day.getDayString, hour, 3)}">
|
||||
<div class="busy" ng-show="currentAttendee.freebusy[day.getDayString][hour][3]"><!-- 15 minutes --></div>
|
||||
</div>
|
||||
</div>
|
||||
<md-divider><!-- divider --></md-divider>
|
||||
</md-list-item>
|
||||
<sg-freebusy-day
|
||||
ng-repeat="currentAttendee in editor.component.attendees track by currentAttendee.email"
|
||||
sg-day="day.getDayString"
|
||||
sg-attendees="editor.component.$attendees"
|
||||
sg-attendee="currentAttendee"><!-- attendees --></sg-freebusy-day>
|
||||
</md-list>
|
||||
</md-content>
|
||||
</div><!-- row -->
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
this.slotEndTimeLimit.setMinutes(0);
|
||||
this.slotEndTimeLimit.setHours(Attendees.dayEndHour);
|
||||
this.$days = [];
|
||||
this.$futureFreebusyData = {};
|
||||
this.updateFreeBusyCoverage();
|
||||
this.updateFreeBusy();
|
||||
}
|
||||
|
@ -432,6 +433,8 @@
|
|||
promise = Attendees.$q.when();
|
||||
}
|
||||
|
||||
this.$futureFreebusyData[attendee.uid] = promise;
|
||||
|
||||
return promise;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
|
||||
(function() {
|
||||
|
||||
/**
|
||||
* sgFreebusy - A directive that watches some attributes of a component. Any child component
|
||||
* should depends on this directive and extend the 'onUpdate' method instead of creating new
|
||||
* independent watchers.
|
||||
* @memberof SOGo.SchedulerUI
|
||||
*/
|
||||
function sgFreebusy() {
|
||||
return {
|
||||
restrict: 'C',
|
||||
scope: {},
|
||||
bindToController: {
|
||||
component: '=sgComponent'
|
||||
},
|
||||
controller: sgFreebusyController
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @ngInject
|
||||
*/
|
||||
sgFreebusyController.$inject = ['$scope', '$element', '$q'];
|
||||
function sgFreebusyController($scope, $element, $q) {
|
||||
var $ctrl = this;
|
||||
|
||||
this.$onInit = function () {
|
||||
var watchedAttrs = ['start', 'end', 'attendees'];
|
||||
|
||||
$scope.$watch(
|
||||
function() {
|
||||
return $ctrl.component? [ _.pick($ctrl.component, watchedAttrs) ] : null;
|
||||
},
|
||||
function(newId, oldId) {
|
||||
if ($ctrl.component) {
|
||||
// Component has changed
|
||||
$q.all(_.values($ctrl.component.$attendees.$futureFreebusyData)).then(function() {
|
||||
$ctrl.onUpdate();
|
||||
});
|
||||
}
|
||||
},
|
||||
true // compare for object equality
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
this.onUpdate = function () {
|
||||
// console.debug('dates or attendees changed -- refresh freebusy');
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
angular
|
||||
.module('SOGo.SchedulerUI')
|
||||
.directive('sgFreebusy', sgFreebusy);
|
||||
})();
|
|
@ -0,0 +1,116 @@
|
|||
/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
|
||||
(function() {
|
||||
|
||||
/*
|
||||
* sgFreebusyDay - A representation of the freebusy data for an attendee for one day.
|
||||
* @memberof SOGo.SchedulerUI
|
||||
* @restrict element
|
||||
* @param {string} sgDay - the day string
|
||||
* @param {object} sgAttendees - the Attendees object instance of the component
|
||||
* @param {object} sgAttendee - the object representing the attendee
|
||||
*
|
||||
* @example:
|
||||
|
||||
<sg-freebusy-day
|
||||
ng-repeat="currentAttendee in component.attendees"
|
||||
sg-day="day.getDayString"
|
||||
sg-attendees="component.$attendees"
|
||||
sg-attendee="currentAttendee" />
|
||||
*/
|
||||
function sgFreebusyDay() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
require: '^^sgFreebusy',
|
||||
bindToController: {
|
||||
day: '=sgDay',
|
||||
attendees: '=sgAttendees',
|
||||
attendee: '=sgAttendee'
|
||||
},
|
||||
replace: true,
|
||||
template: function(tElement, tAttrs) {
|
||||
var template = [
|
||||
'<md-list-item>'
|
||||
];
|
||||
for (var hour = 0; hour < 24; hour++) {
|
||||
template.push(' <div class="hour">');
|
||||
for (var quarter = 0; quarter < 4; quarter++) {
|
||||
template.push(' <div class="quarter">');
|
||||
template.push(' <div class="busy ng-hide"></div>');
|
||||
template.push(' </div>');
|
||||
}
|
||||
template.push(' </div>');
|
||||
}
|
||||
template.push(' <md-divider><!-- divider --></md-divider>');
|
||||
template.push('</md-list-item>');
|
||||
|
||||
return template.join('');
|
||||
},
|
||||
link: postLink,
|
||||
controller: sgFreebusyDayController,
|
||||
controllerAs: '$ctrl'
|
||||
};
|
||||
|
||||
function postLink(scope, element, attrs, parentController) {
|
||||
scope.parentController = parentController;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @ngInject
|
||||
*/
|
||||
sgFreebusyDayController.$inject = ['$scope', '$element'];
|
||||
function sgFreebusyDayController($scope, $element) {
|
||||
var $ctrl = this;
|
||||
|
||||
this.$postLink = function () {
|
||||
var hours = [], quarters = [], busys = [], parentControllerOnUpdate;
|
||||
|
||||
this.parentController = $scope.parentController;
|
||||
parentControllerOnUpdate = this.parentController.onUpdate;
|
||||
|
||||
_.forEach($element.find('div'), function(div) {
|
||||
if (div.className.startsWith('hour')) hours.push(div);
|
||||
else if (div.className.startsWith('quarter')) quarters.push(div);
|
||||
else if (div.className.startsWith('busy')) busys.push(div);
|
||||
});
|
||||
|
||||
this.parentController.onUpdate = function () {
|
||||
var freebusys = $ctrl.attendee.freebusy[$ctrl.day];
|
||||
|
||||
if (!$ctrl.attendee.uid) {
|
||||
_.forEach(hours, function(div) {
|
||||
div.classList.add('sg-no-freebusy');
|
||||
});
|
||||
}
|
||||
|
||||
for (var hour = 0; hour < 24; hour++) {
|
||||
for (var quarter = 0; quarter < 4; quarter++) {
|
||||
var index = hour * 4 + quarter;
|
||||
if ($ctrl.coversFreebusy(hour, quarter)) {
|
||||
quarters[index].classList.add('event');
|
||||
} else {
|
||||
quarters[index].classList.remove('event');
|
||||
}
|
||||
if (freebusys[hour][quarter]) {
|
||||
busys[index].classList.remove('ng-hide');
|
||||
} else {
|
||||
busys[index].classList.add('ng-hide');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Call original method on parent controller
|
||||
angular.bind($ctrl.parentController, parentControllerOnUpdate)();
|
||||
};
|
||||
};
|
||||
|
||||
this.coversFreebusy = function (hour, quarter) {
|
||||
return $ctrl.attendees.coversFreeBusy($ctrl.day, hour, quarter);
|
||||
};
|
||||
}
|
||||
|
||||
angular
|
||||
.module('SOGo.SchedulerUI')
|
||||
.directive('sgFreebusyDay', sgFreebusyDay);
|
||||
})();
|
Loading…
Reference in New Issue