From 9689b7d112dd9dba4a5424808de08fdd5738db79 Mon Sep 17 00:00:00 2001 From: NathanPriebe <37284011+NathanBP@users.noreply.github.com> Date: Fri, 24 May 2019 23:05:48 +1000 Subject: [PATCH] fix: bug where appointments can appear outside the calendar (#1204) * Fixed bug where appointments can appear outside the calendar * Modfied change to stop moving all appointments up by 2% * Updated code to get top of appointment * Added range tests, to ensure appointments don't appear outside calendar --- examples/App.js | 1 + examples/demos/dndresource.js | 30 ++++++++++++++ src/utils/TimeSlots.js | 5 ++- test/utils/TimeSlots.test.js | 78 +++++++++++++++++++++++++++++++++++ 4 files changed, 113 insertions(+), 1 deletion(-) diff --git a/examples/App.js b/examples/App.js index d5957c12d..358e8d9e4 100644 --- a/examples/App.js +++ b/examples/App.js @@ -44,6 +44,7 @@ const EXAMPLES = { customView: 'Custom Calendar Views', resource: 'Resource Scheduling', dnd: 'Addon: Drag and drop', + dndresource: 'Resource Drag and drop', dndOutsideSource: 'Addon: Drag and drop (from outside calendar)', } diff --git a/examples/demos/dndresource.js b/examples/demos/dndresource.js index 2fbc6d887..75364af1d 100644 --- a/examples/demos/dndresource.js +++ b/examples/demos/dndresource.js @@ -28,6 +28,13 @@ const events = [ end: new Date(2018, 0, 29, 12, 30, 0), resourceId: 3, }, + { + id: 10, + title: 'Board meeting', + start: new Date(2018, 0, 30, 23, 0, 0), + end: new Date(2018, 0, 30, 23, 59, 0), + resourceId: 1, + }, { id: 11, title: 'Birthday Party', @@ -35,6 +42,27 @@ const events = [ end: new Date(2018, 0, 30, 10, 30, 0), resourceId: 4, }, + { + id: 12, + title: 'Board meeting', + start: new Date(2018, 0, 29, 23, 59, 0), + end: new Date(2018, 0, 30, 13, 0, 0), + resourceId: 1, + }, + { + id: 13, + title: 'Board meeting', + start: new Date(2018, 0, 29, 23, 50, 0), + end: new Date(2018, 0, 30, 13, 0, 0), + resourceId: 2, + }, + { + id: 14, + title: 'Board meeting', + start: new Date(2018, 0, 29, 23, 40, 0), + end: new Date(2018, 0, 30, 13, 0, 0), + resourceId: 4, + }, ] const resourceMap = [ @@ -103,6 +131,8 @@ class Dnd extends React.Component { resourceTitleAccessor="resourceTitle" onEventResize={this.resizeEvent} defaultView="day" + step={15} + showMultiDayTimes={true} defaultDate={new Date(2018, 0, 29)} /> ) diff --git a/src/utils/TimeSlots.js b/src/utils/TimeSlots.js index d70e01475..85a2de2c7 100644 --- a/src/utils/TimeSlots.js +++ b/src/utils/TimeSlots.js @@ -130,7 +130,10 @@ export function getSlotMetrics({ min: start, max: end, step, timeslots }) { const rangeStartMin = positionFromDate(rangeStart) const rangeEndMin = positionFromDate(rangeEnd) - const top = (rangeStartMin / (step * numSlots)) * 100 + const top = + rangeEndMin - rangeStartMin < step + ? ((rangeStartMin - step) / (step * numSlots)) * 100 + : (rangeStartMin / (step * numSlots)) * 100 return { top, diff --git a/test/utils/TimeSlots.test.js b/test/utils/TimeSlots.test.js index aff02b015..d36edac52 100644 --- a/test/utils/TimeSlots.test.js +++ b/test/utils/TimeSlots.test.js @@ -22,3 +22,81 @@ describe('getSlotMetrics', () => { expect(diff).toBe(60) }) }) + +describe('getRange', () => { + const min = dates.startOf(new Date(), 'day') + const max = dates.endOf(new Date(), 'day') + const slotMetrics = getSlotMetrics({ min, max, step: 60, timeslots: 1 }) + + test('getRange: 15 minute start of day appointment stays within calendar', () => { + let range = slotMetrics.getRange( + new Date(2018, 0, 29, 0, 0, 0), + new Date(2018, 0, 29, 0, 15, 0) + ) + expect(range.top + range.height).toBeLessThan(100) + expect(range.height).toBeGreaterThan(0) + }) + + test('getRange: 1 hour start of day appointment stays within calendar', () => { + let range = slotMetrics.getRange( + new Date(2018, 0, 29, 0, 0, 0), + new Date(2018, 0, 29, 1, 0, 0) + ) + expect(range.top + range.height).toBeLessThan(100) + expect(range.height).toBeGreaterThan(0) + }) + + test('getRange: 1 hour mid range appointment stays within calendar', () => { + let range = slotMetrics.getRange( + new Date(2018, 0, 29, 14, 0, 0), + new Date(2018, 0, 29, 15, 0, 0) + ) + expect(range.top + range.height).toBeLessThan(100) + expect(range.height).toBeGreaterThan(0) + }) + + test('getRange: 3 hour mid range appointment stays within calendar', () => { + let range = slotMetrics.getRange( + new Date(2018, 0, 29, 14, 0, 0), + new Date(2018, 0, 29, 17, 0, 0) + ) + expect(range.top + range.height).toBeLessThan(100) + expect(range.height).toBeGreaterThan(0) + }) + + test('getRange: full day appointment stays within calendar', () => { + let range = slotMetrics.getRange( + new Date(2018, 0, 29, 0, 0, 0), + new Date(2018, 0, 29, 23, 59, 0) + ) + expect(range.top + range.height).toBeLessThan(100) + expect(range.height).toBeGreaterThan(0) + }) + + test('getRange: 1 hour end of day appointment stays within calendar', () => { + let range = slotMetrics.getRange( + new Date(2018, 0, 29, 23, 0, 0), + new Date(2018, 0, 29, 23, 59, 0) + ) + expect(range.top + range.height).toBeLessThan(100) + expect(range.height).toBeGreaterThan(0) + }) + + test('getRange: 15 minute end of day appointment stays within calendar', () => { + let range = slotMetrics.getRange( + new Date(2018, 0, 29, 23, 45, 0), + new Date(2018, 0, 29, 23, 59, 0) + ) + expect(range.top + range.height).toBeLessThan(100) + expect(range.height).toBeGreaterThan(0) + }) + + test('getRange: multi day appointment stays within calendar', () => { + let range = slotMetrics.getRange( + new Date(2018, 0, 29, 0, 0, 0), + new Date(2018, 0, 30, 4, 0, 0) + ) + expect(range.top + range.height).toBeLessThan(100) + expect(range.height).toBeGreaterThan(0) + }) +})