(js,css) Add sg-now-line directive
parent
77e3d7ca0c
commit
66267b17f2
1
NEWS
1
NEWS
|
@ -14,6 +14,7 @@ Enhancements
|
||||||
- [web] disable JavaScript theme generation when SOGoUIxDebugEnabled is set to NO
|
- [web] disable JavaScript theme generation when SOGoUIxDebugEnabled is set to NO
|
||||||
- [web] added Serbian (sr) translation - thanks to Bogdanović Bojan
|
- [web] added Serbian (sr) translation - thanks to Bogdanović Bojan
|
||||||
- [web] added sort by arrival date in Mail module (#708)
|
- [web] added sort by arrival date in Mail module (#708)
|
||||||
|
- [web] restored "now" line in Calendar module
|
||||||
- [web] updated CKEditor to version 4.5.11
|
- [web] updated CKEditor to version 4.5.11
|
||||||
- [eas] propagate message submission errors to EAS clients (#3774)
|
- [eas] propagate message submission errors to EAS clients (#3774)
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,7 @@
|
||||||
|
|
||||||
<!-- The quarters grid -->
|
<!-- The quarters grid -->
|
||||||
<div class="daysView">
|
<div class="daysView">
|
||||||
<div class="days">
|
<div class="days sg-now-line">
|
||||||
<var:foreach list="daysToDisplay" item="currentTableDay">
|
<var:foreach list="daysToDisplay" item="currentTableDay">
|
||||||
<sg-calendar-day var:class="dayClasses"
|
<sg-calendar-day var:class="dayClasses"
|
||||||
var:id="currentDayId"
|
var:id="currentDayId"
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
/* jshint loopfunc: true */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -132,16 +133,32 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateView() {
|
function updateView() {
|
||||||
|
// The list of calendars has changed; update the views
|
||||||
// See stateEventsBlocks in Scheduler.app.js
|
// See stateEventsBlocks in Scheduler.app.js
|
||||||
Component.$eventsBlocksForView($stateParams.view, $stateParams.day.asDate()).then(function(data) {
|
Component.$eventsBlocksForView($stateParams.view, $stateParams.day.asDate()).then(function(data) {
|
||||||
vm.views = data;
|
var i, j, view;
|
||||||
_.forEach(vm.views, function(view) {
|
for (i = 0; i < data.length; i++) {
|
||||||
|
view = data[i];
|
||||||
|
if (vm.views[i]) {
|
||||||
|
_.forEach(view.allDayBlocks, function(blocks, day) {
|
||||||
|
vm.views[i].allDayBlocks[day] = blocks;
|
||||||
|
});
|
||||||
|
_.forEach(view.blocks, function(blocks, day) {
|
||||||
|
vm.views[i].blocks[day] = blocks;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
vm.views[i] = view;
|
||||||
|
}
|
||||||
if (view.id) {
|
if (view.id) {
|
||||||
// Note: this can't be done in Component service since it would make Component dependent on
|
// Note: this can't be done in Component service since it would make Component dependent on
|
||||||
// the Calendar service and create a circular dependency
|
// the Calendar service and create a circular dependency
|
||||||
view.calendar = new Calendar({ id: view.id, name: view.calendarName });
|
vm.views[i].calendar = new Calendar({ id: view.id, name: view.calendarName });
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
// Remove previous views
|
||||||
|
for (j = vm.views.length; j >= i; j--)
|
||||||
|
vm.views.splice(j, 1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,10 +25,15 @@
|
||||||
},
|
},
|
||||||
controller: sgCalendarScrollViewController,
|
controller: sgCalendarScrollViewController,
|
||||||
link: function(scope, element, attrs, controller) {
|
link: function(scope, element, attrs, controller) {
|
||||||
var view, type;
|
var view, type, isMultiColumn = false;
|
||||||
|
|
||||||
view = null;
|
view = null;
|
||||||
type = scope.type; // multiday, multiday-allday, monthly, unknown?
|
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
|
// Update the "view" object literal once the Angular template has been transformed
|
||||||
$timeout(initView);
|
$timeout(initView);
|
||||||
|
@ -54,6 +59,10 @@
|
||||||
view.element.scrollTop = hourCell.offsetTop + quartersOffset;
|
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() {
|
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');
|
days = this.element.getElementsByTagName('sg-calendar-day');
|
||||||
|
|
||||||
return _.map(days, function(el, index) {
|
return _.map(days, function(el, index) {
|
||||||
|
|
|
@ -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('<sg-now-line>');
|
||||||
|
|
||||||
|
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);
|
||||||
|
})();
|
|
@ -240,6 +240,16 @@ $quarter_height: 10px;
|
||||||
position: relative;
|
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
|
// Events from editable calendars are draggable
|
||||||
.sg-draggable-calendar-block,
|
.sg-draggable-calendar-block,
|
||||||
.sg-event--ghost {
|
.sg-event--ghost {
|
||||||
|
@ -697,4 +707,4 @@ $quarter_height: 10px;
|
||||||
background-color: sg-color($sogoBlue, 300);
|
background-color: sg-color($sogoBlue, 300);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue