Skip to content

Commit

Permalink
[fixed] consistent handling of end dates as _exclusive_ ranges
Browse files Browse the repository at this point in the history
Ensures that date math is done the same way when calculating whether
things fall within a range. All event start-end are considered exclusive
ranges throughout.

fixes #62, fixes #36, fixes #32, closes #67, closes #65
  • Loading branch information
jquense committed Apr 3, 2016
1 parent 1c12b16 commit a2a49c8
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 22 deletions.
14 changes: 6 additions & 8 deletions src/Month.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ import Overlay from 'react-overlays/lib/Overlay';
import BackgroundCells from './BackgroundCells';

import { dateFormat } from './utils/propTypes';
import { segStyle, inRange, eventSegments, eventLevels, sortEvents } from './utils/eventLevels';

import {
segStyle, inRange, eventSegments
, endOfRange, eventLevels, sortEvents } from './utils/eventLevels';

let eventsForWeek = (evts, start, end, props) =>
evts.filter(e => inRange(e, start, end, props));
Expand Down Expand Up @@ -132,8 +133,7 @@ let MonthView = React.createClass({
},

renderWeek(week, weekIdx, content) {
let first = week[0]
let last = week[week.length - 1]
let { first, last } = endOfRange(week);
let evts = eventsForWeek(this.props.events, week[0], week[week.length - 1], this.props)

evts.sort((a, b) => sortEvents(a, b, this.props))
Expand Down Expand Up @@ -200,8 +200,7 @@ let MonthView = React.createClass({
},

renderRowLevel(segments, week, idx){
let first = week[0]
let last = week[week.length - 1]
let { first, last } = endOfRange(week);

return (
<EventRow
Expand All @@ -217,8 +216,7 @@ let MonthView = React.createClass({
},

renderShowMore(segments, extraSegments, week, weekIdx) {
let first = week[0]
let last = week[week.length - 1]
let { first, last } = endOfRange(week);

let onClick = slot => this._showMore(segments, week[slot - 1], weekIdx, slot)

Expand Down
8 changes: 5 additions & 3 deletions src/TimeGrid.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@ import { notify } from './utils/helpers';
import { navigate } from './utils/constants';
import { accessor as get } from './utils/accessors';

import { inRange, eventSegments, eventLevels, sortEvents, segStyle } from './utils/eventLevels';
import {
inRange, eventSegments, endOfRange
, eventLevels, sortEvents, segStyle } from './utils/eventLevels';

const MIN_ROWS = 2;


let TimeGrid = React.createClass({

propTypes: {
Expand Down Expand Up @@ -154,8 +157,7 @@ let TimeGrid = React.createClass({
},

renderAllDayEvents(range, levels){
let first = range[0]
, last = range[range.length - 1];
let { first, last } = endOfRange(range);

while (levels.length < MIN_ROWS )
levels.push([])
Expand Down
2 changes: 2 additions & 0 deletions src/utils/dates.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ let dates = Object.assign(dateMath, {
return Math.abs(+dateA - +dateB)

// the .round() handles an edge case
// with DST where the total won't be exact
// since one day in the range may be shorter/longer by an hour
return Math.round(Math.abs(
(+dates.startOf(dateA, unit) / MILLI[unit]) - (+dates.startOf(dateB, unit) / MILLI[unit])
))
Expand Down
28 changes: 17 additions & 11 deletions src/utils/eventLevels.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
import dates from './dates';
import { accessor as get } from './accessors';

export function eventSegments(event, first, last, { startAccessor, endAccessor, culture }){
export function endOfRange(dateRange, unit = 'day') {
return {
first: dateRange[0],
last: dates.add(dateRange[dateRange.length - 1], 1, unit)
}
}

export function eventSegments(event, first, last, { startAccessor, endAccessor, culture }) {
let slots = dates.diff(first, last, 'day')
let start = dates.max(dates.startOf(get(event, startAccessor), 'day'), first);
let end = dates.min(dates.ceil(get(event, endAccessor), 'day'), dates.add(last, 1, 'day'))
let end = dates.min(dates.ceil(get(event, endAccessor), 'day'), last)

let padding = dates.diff(first, start, 'day');
let span = dates.diff(start, end, 'day');

span = Math.floor(Math.max(Math.min(span, slots), 1));

let padding = Math.floor(dates.diff(first, start, 'day'));
span = Math.min(span, slots)
span = Math.max(span, 1);

return {
event,
Expand Down Expand Up @@ -54,14 +61,13 @@ export function eventLevels(rowSegments, limit = Infinity){
}

export function inRange(e, start, end, { startAccessor, endAccessor }){
let eStart = get(e, startAccessor)
let eEnd = get(e, endAccessor)
let eStart = dates.startOf(get(e, startAccessor), 'day')
let eEnd = dates.ceil(get(e, endAccessor), 'day')

let starts = dates.inRange(eStart, start, end, 'day')
let during = dates.lt(eStart, start, 'day') && dates.gt(eEnd, end, 'day')
let ends = dates.lt(eStart, start) && dates.inRange(eEnd, start, end, 'day')
let startsBeforeEnd = dates.lte(eStart, end, 'day')
let endsAfterStart = dates.gt(eEnd, start, 'day')

return starts || ends || during
return startsBeforeEnd && endsAfterStart
}


Expand Down

0 comments on commit a2a49c8

Please sign in to comment.