From fdaea2de7fa822e25733bf94f153fd917144c226 Mon Sep 17 00:00:00 2001 From: Matt Lewis Date: Wed, 29 Jun 2016 13:03:48 +0100 Subject: [PATCH] feat(weekView): bucket sort events into columns rather than having each event sit on its own line BREAKING CHANGE: the UX of the week view has now changed. The template has also changed heavily if you were using a custom template. Closes #381 --- package.json | 6 +- src/less/week.less | 30 ++++++++++ src/services/calendarHelper.js | 59 +++++++++++--------- src/templates/calendarWeekView.html | 57 ++++++++++--------- test/unit/services/calendarHelper.spec.js | 67 ++++++++++++----------- 5 files changed, 131 insertions(+), 88 deletions(-) diff --git a/package.json b/package.json index 179be89c..98cad186 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "html-loader": "~0.4.0", "htmlhint-loader": "~0.1.0", "istanbul-instrumenter-loader": "~0.2.0", - "karma": "~1.1.0", + "karma": "~0.13.22", "karma-chai-plugins": "~0.7.0", "karma-coverage": "~1.0.0", "karma-mocha": "~1.1.1", @@ -82,5 +82,9 @@ "commitizen": { "path": "node_modules/cz-conventional-changelog" } + }, + "dependencies": { + "calendar-utils": "0.0.1", + "es6-set": "~0.1.4" } } diff --git a/src/less/week.less b/src/less/week.less index 566f54b7..0bb85545 100755 --- a/src/less/week.less +++ b/src/less/week.less @@ -1,5 +1,6 @@ .cal-week-box { position: relative; + [data-event-class] { white-space: nowrap; height: 30px; @@ -15,6 +16,35 @@ .cal-day-panel { border: 0px !important; } + +} + +.cal-week-box:not(.cal-day-box) { + + .cal-row-fluid { + margin-bottom: 2px; + } + + .cal-row-fluid:hover, + [class*="cal-cell"]:hover { + background-color: inherit !important; + } + + [data-event-class] { + margin-left: 2px; + margin-right: 2px; + } + + .border-left-rounded { + border-top-left-radius: 5px; + border-bottom-left-radius: 5px; + } + + .border-right-rounded { + border-top-right-radius: 5px; + border-bottom-right-radius: 5px; + } + } .cal-week-box.cal-day-box { diff --git a/src/services/calendarHelper.js b/src/services/calendarHelper.js index 52b0809b..f220ef74 100644 --- a/src/services/calendarHelper.js +++ b/src/services/calendarHelper.js @@ -1,6 +1,8 @@ 'use strict'; var angular = require('angular'); +require('es6-set/implement'); +var calendarUtils = require('calendar-utils'); angular .module('mwl.calendar') @@ -195,41 +197,34 @@ angular dayCounter.add(1, 'day'); } - var eventsSorted = filterEventsInPeriod(events, startOfWeek, endOfWeek).map(function(event) { + var eventRows = calendarUtils.getWeekView({ + viewDate: viewDate, + events: filterEventsInPeriod(events, startOfWeek, endOfWeek).map(function(event) { - var weekViewStart = moment(startOfWeek).startOf('day'); - var weekViewEnd = moment(endOfWeek).startOf('day'); + var weekViewStart = moment(startOfWeek).startOf('day'); - var eventPeriod = getRecurringEventPeriod({ - start: moment(event.startsAt).startOf('day'), - end: moment(event.endsAt || event.startsAt).startOf('day') - }, event.recursOn, weekViewStart); + var eventPeriod = getRecurringEventPeriod({ + start: moment(event.startsAt).startOf('day'), + end: moment(event.endsAt || event.startsAt).startOf('day').add(1, 'second') + }, event.recursOn, weekViewStart); - var eventStart = eventPeriod.start; - var eventEnd = eventPeriod.end; + eventPeriod.originalEvent = event; - var offset; - if (eventStart.isBefore(weekViewStart) || eventStart.isSame(weekViewStart)) { - offset = 0; - } else { - offset = eventStart.diff(weekViewStart, 'days'); - } + return eventPeriod; - if (eventEnd.isAfter(weekViewEnd)) { - eventEnd = weekViewEnd; - } + }) + }).map(function(eventRow) { - if (eventStart.isBefore(weekViewStart)) { - eventStart = weekViewStart; - } + eventRow.row = eventRow.row.map(function(rowEvent) { + rowEvent.event = rowEvent.event.originalEvent; + return rowEvent; + }); - event.daySpan = moment(eventEnd).diff(eventStart, 'days') + 1; - event.dayOffset = offset; + return eventRow; - return event; }); - return {days: days, events: eventsSorted}; + return {days: days, eventRows: eventRows}; } @@ -316,8 +311,14 @@ angular function getWeekViewWithTimes(events, viewDate, dayViewStart, dayViewEnd, dayViewSplit) { var weekView = getWeekView(events, viewDate); var newEvents = []; + var flattenedEvents = []; + weekView.eventRows.forEach(function(row) { + row.row.forEach(function(eventRow) { + flattenedEvents.push(eventRow.event); + }); + }); weekView.days.forEach(function(day) { - var dayEvents = weekView.events.filter(function(event) { + var dayEvents = flattenedEvents.filter(function(event) { return moment(event.startsAt).startOf('day').isSame(moment(day.date).startOf('day')); }); var newDayEvents = getDayView( @@ -329,7 +330,11 @@ angular ); newEvents = newEvents.concat(newDayEvents); }); - weekView.events = newEvents; + weekView.eventRows = [{ + row: newEvents.map(function(event) { + return {event: event}; + }) + }]; return weekView; } diff --git a/src/templates/calendarWeekView.html b/src/templates/calendarWeekView.html index ed1f1c54..ed188d3a 100644 --- a/src/templates/calendarWeekView.html +++ b/src/templates/calendarWeekView.html @@ -41,38 +41,41 @@ ng-if="vm.showTimes"> -
+
-
+
- - - + left: vm.showTimes ? (vm.dayColumnDimensions.width * eventRow.offset) + 15 + 'px' : '' + }"> +
+ + + +
diff --git a/test/unit/services/calendarHelper.spec.js b/test/unit/services/calendarHelper.spec.js index 9b676adb..ff4f4d49 100644 --- a/test/unit/services/calendarHelper.spec.js +++ b/test/unit/services/calendarHelper.spec.js @@ -445,7 +445,8 @@ describe('calendarHelper', function() { }); it('should only contain events for that week', function() { - expect(weekView.events).to.eql([events[0], events[1]]); + expect(weekView.eventRows[0].row[0].event).to.eql(events[0]); + expect(weekView.eventRows[1].row[0].event).to.eql(events[1]); }); describe('setting the correct span and offset', function() { @@ -455,8 +456,8 @@ describe('calendarHelper', function() { startsAt: new Date(2015, 9, 20, 1), endsAt: new Date(2015, 9, 21, 15) }], calendarDay); - expect(weekView.events[0].daySpan).to.equal(2); - expect(weekView.events[0].dayOffset).to.equal(2); + expect(weekView.eventRows[0].row[0].span).to.equal(2); + expect(weekView.eventRows[0].row[0].offset).to.equal(2); }); it('should pass when the event starts before the current week view and ends within it', function() { @@ -464,8 +465,8 @@ describe('calendarHelper', function() { startsAt: new Date(2015, 8, 20, 1), endsAt: new Date(2015, 9, 21, 15) }], calendarDay); - expect(weekView.events[0].daySpan).to.equal(4); - expect(weekView.events[0].dayOffset).to.equal(0); + expect(weekView.eventRows[0].row[0].span).to.equal(4); + expect(weekView.eventRows[0].row[0].offset).to.equal(0); }); it('should pass when the event starts before the current week view and ends after the end of the week', function() { @@ -473,8 +474,8 @@ describe('calendarHelper', function() { startsAt: new Date(2015, 8, 20, 1), endsAt: new Date(2015, 10, 21, 15) }], calendarDay); - expect(weekView.events[0].daySpan).to.equal(7); - expect(weekView.events[0].dayOffset).to.equal(0); + expect(weekView.eventRows[0].row[0].span).to.equal(7); + expect(weekView.eventRows[0].row[0].offset).to.equal(0); }); it('should pass when the event starts within the current week but ends after it', function() { @@ -482,8 +483,8 @@ describe('calendarHelper', function() { startsAt: new Date(2015, 9, 20, 1), endsAt: new Date(2015, 10, 21, 15) }], calendarDay); - expect(weekView.events[0].daySpan).to.equal(5); - expect(weekView.events[0].dayOffset).to.equal(2); + expect(weekView.eventRows[0].row[0].span).to.equal(5); + expect(weekView.eventRows[0].row[0].offset).to.equal(2); }); }); @@ -495,8 +496,8 @@ describe('calendarHelper', function() { startsAt: new Date(2016, 0, 9, 1), recursOn: 'month' }], new Date(2016, 1, 9, 1)); - expect(weekView.events[0].daySpan).to.equal(1); - expect(weekView.events[0].dayOffset).to.equal(2); + expect(weekView.eventRows[0].row[0].span).to.equal(1); + expect(weekView.eventRows[0].row[0].offset).to.equal(2); }); }); @@ -620,36 +621,36 @@ describe('calendarHelper', function() { it('should calculate the week view with times', function() { var expectedEventsWeekView = [ { - startsAt: new Date('October 19, 2015 11:00:00'), - endsAt: new Date('October 21, 2015 11:00:00'), - daySpan: 3, - dayOffset: 1, - top: 658, - height: 782, - left: 0 + event: { + top: 658, + height: 782, + left: 0, + startsAt: new Date('October 19, 2015 11:00:00'), + endsAt: new Date('October 21, 2015 11:00:00') + } }, { - startsAt: new Date('October 20, 2015 11:00:00'), - endsAt: new Date('October 21, 2015 11:00:00'), - daySpan: 2, - dayOffset: 2, - top: 658, - height: 782, - left: 0 + event: { + top: 658, + height: 782, + left: 0, + startsAt: new Date('October 20, 2015 11:00:00'), + endsAt: new Date('October 21, 2015 11:00:00') + } }, { - startsAt: new Date('October 20, 2015 11:00:00'), - endsAt: new Date('October 20, 2015 12:00:00'), - daySpan: 1, - dayOffset: 2, - top: 658, - height: 60, - left: 150 + event: { + startsAt: new Date('October 20, 2015 11:00:00'), + endsAt: new Date('October 20, 2015 12:00:00'), + top: 658, + height: 60, + left: 150 + } } ]; expect(weekViewWithTimes.days.length).to.equal(7); - expect(weekViewWithTimes.events).to.eql(expectedEventsWeekView); + expect(weekViewWithTimes.eventRows[0].row).to.eql(expectedEventsWeekView); }); });