+
= i; j--)
+ vm.views.splice(j, 1);
});
}
diff --git a/UI/WebServerResources/js/Scheduler/sgCalendarScrollView.directive.js b/UI/WebServerResources/js/Scheduler/sgCalendarScrollView.directive.js
index 77f08ea0e..710086c00 100644
--- a/UI/WebServerResources/js/Scheduler/sgCalendarScrollView.directive.js
+++ b/UI/WebServerResources/js/Scheduler/sgCalendarScrollView.directive.js
@@ -25,10 +25,15 @@
},
controller: sgCalendarScrollViewController,
link: function(scope, element, attrs, controller) {
- var view, type;
+ var view, type, isMultiColumn = false;
view = null;
type = scope.type; // multiday, multiday-allday, monthly, unknown?
+ isMultiColumn = (element.attr('sg-view') == 'multicolumndayview');
+
+ // Expose isMultiColumn in the controller
+ // See sgNowLine directive
+ controller.isMultiColumn = isMultiColumn;
// Update the "view" object literal once the Angular template has been transformed
$timeout(initView);
@@ -54,6 +59,10 @@
view.element.scrollTop = hourCell.offsetTop + quartersOffset;
}
});
+
+ // Expose quarter height to the controller
+ // See sgNowLine directive
+ controller.quarterHeight = view.quarterHeight;
}
/**
@@ -133,11 +142,8 @@
getDayNumbers: function() {
- var viewType = null, isMultiColumn, days, total, sum;
+ var viewType = null, days, total, sum;
- if (this.element.attributes['sg-view'])
- viewType = this.element.attributes['sg-view'].value;
- isMultiColumn = (viewType == 'multicolumndayview');
days = this.element.getElementsByTagName('sg-calendar-day');
return _.map(days, function(el, index) {
diff --git a/UI/WebServerResources/js/Scheduler/sgNowLine.directive.js b/UI/WebServerResources/js/Scheduler/sgNowLine.directive.js
new file mode 100644
index 000000000..037208623
--- /dev/null
+++ b/UI/WebServerResources/js/Scheduler/sgNowLine.directive.js
@@ -0,0 +1,112 @@
+/* -*- Mode: js; indent-tabs-mode: nil; js-indent-level: 2 -*- */
+
+(function() {
+ /* jshint validthis: true */
+ 'use strict';
+
+ /*
+ * sgNowLine - Now line to be displayed on top of current day
+ * @restrict class
+ */
+ function sgNowLine() {
+ return {
+ restrict: 'C',
+ require: '^^sgCalendarScrollView',
+ link: link,
+ controller: sgNowLineController
+ };
+
+ function link(scope, iElement, iAttr, sgCalendarScrollViewCtrl) {
+ function _getDays() {
+ return iElement.find('sg-calendar-day');
+ }
+ function _getView() {
+ return sgCalendarScrollViewCtrl.quarterHeight;
+ }
+
+ // We need to wait for the view to be compiled
+ var _unwatchView = scope.$watch(_getView, function(quarterHeight) {
+ if (quarterHeight) {
+ _unwatchView(); // self release
+ scope.quarterHeight = quarterHeight;
+ // We need to wait for the days to be compiled
+ var _unwatchDays = scope.$watch(_getDays, function(days) {
+ if (days.length) {
+ _unwatchDays(); // self release
+ scope.days = days;
+ // Draw the line
+ scope.updateLine();
+ }
+ });
+ }
+ });
+ }
+ }
+
+ /**
+ * @ngInject
+ */
+ sgNowLineController.$inject = ['$scope', '$element', '$timeout'];
+ function sgNowLineController($scope, $element, $timeout) {
+ var _this = this, updater,
+ scrollViewCtrl = $element.controller('sgCalendarScrollView');
+
+ $scope.nowDay = null;
+ $scope.lineElement = null;
+ $scope.updateLine = _updateLine;
+
+ $scope.$on('$destroy', function() {
+ if (updater)
+ $timeout.cancel(updater);
+ });
+
+
+ function _updateLine(force) {
+ var now = new Date(), // TODO: adjust to user's timezone
+ nowDay = now.getDayString(),
+ hours = now.getHours(),
+ hourHeight = $scope.quarterHeight * 4,
+ minutes = now.getMinutes(),
+ minuteHeight = $scope.quarterHeight/15,
+ position = parseInt(hours * hourHeight +
+ minutes * minuteHeight -
+ 1);
+
+ if (force || nowDay != $scope.nowDay) {
+ if ($scope.lineElement)
+ $scope.lineElement.remove();
+ $scope.lineElement = _addLine(nowDay, $scope.days);
+ $scope.nowDay = nowDay;
+ }
+
+ if ($scope.lineElement) {
+ // Current day is displayed
+ $scope.lineElement.css('top', position + "px");
+ // Update line every minute
+ updater = $timeout(angular.bind(_this, $scope.updateLine), 60000);
+ }
+ }
+
+ function _addLine(nowDay, days) {
+ var $lineElement = angular.element('');
+
+ if (scrollViewCtrl.isMultiColumn) {
+ // In multicolumn day view, the line must go over all columns
+ if (days && days[0].attributes['sg-day'].value == nowDay)
+ $element.append($lineElement);
+ }
+ else
+ _.forEach(days, function(dayElement) {
+ if (dayElement.attributes['sg-day'].value == nowDay) {
+ angular.element(dayElement).find('div').eq(0).append($lineElement);
+ }
+ });
+
+ return $lineElement;
+ }
+ }
+
+ angular
+ .module('SOGo.SchedulerUI')
+ .directive('sgNowLine', sgNowLine);
+})();
diff --git a/UI/WebServerResources/scss/views/SchedulerUI.scss b/UI/WebServerResources/scss/views/SchedulerUI.scss
index 7762fab0e..da484f965 100644
--- a/UI/WebServerResources/scss/views/SchedulerUI.scss
+++ b/UI/WebServerResources/scss/views/SchedulerUI.scss
@@ -240,6 +240,16 @@ $quarter_height: 10px;
position: relative;
}
+ // The "now" line that overlaps the current day in day/week/multicolumn views
+ sg-now-line {
+ display: block;
+ position: absolute;
+ width: 100%;
+ height: 2px;
+ background: red;
+ z-index: $z-index-view + 1;
+ }
+
// Events from editable calendars are draggable
.sg-draggable-calendar-block,
.sg-event--ghost {
@@ -697,4 +707,4 @@ $quarter_height: 10px;
background-color: sg-color($sogoBlue, 300);
}
}
-}
\ No newline at end of file
+}