From c5911946e61fbfea491db9ed4098b74070276037 Mon Sep 17 00:00:00 2001 From: Zhdanov Date: Fri, 24 Jan 2020 13:05:25 +0300 Subject: [PATCH] implement availableTimes property for DateTimePicker --- packages/react-widgets/src/DateTimePicker.js | 13 +++++++ packages/react-widgets/src/TimeList.js | 37 ++++++++++++++++++- .../react-widgets/test/DateTimePicker-test.js | 29 +++++++++++++++ 3 files changed, 78 insertions(+), 1 deletion(-) diff --git a/packages/react-widgets/src/DateTimePicker.js b/packages/react-widgets/src/DateTimePicker.js index b3e97a33f..0c381b4f7 100644 --- a/packages/react-widgets/src/DateTimePicker.js +++ b/packages/react-widgets/src/DateTimePicker.js @@ -134,6 +134,17 @@ let propTypes = { */ timeComponent: CustomPropTypes.elementType, + /** + * Customize available time range for time select, includeLastStep defines whether last + * time element will be in time range list + * + * @example { hours: [8, 9, 10], includeLastStep: true } + */ + availableTimes: PropTypes.shape({ + hours: PropTypes.arrayOf(PropTypes.number), + includeLastStep: PropTypes.bool + }), + /** Specify the element used to render the calendar dropdown icon. */ dateIcon: PropTypes.node, @@ -490,6 +501,7 @@ class DateTimePicker extends React.Component { timeComponent, timeListProps, popupTransition, + availableTimes } = this.props return ( @@ -505,6 +517,7 @@ class DateTimePicker extends React.Component { min={min} max={max} step={step} + availableTimes={availableTimes} listProps={timeListProps} currentDate={currentDate} activeId={activeOptionId} diff --git a/packages/react-widgets/src/TimeList.js b/packages/react-widgets/src/TimeList.js index b473a1b9d..3ec24bfc4 100644 --- a/packages/react-widgets/src/TimeList.js +++ b/packages/react-widgets/src/TimeList.js @@ -56,7 +56,15 @@ function getBounds({ min, max, currentDate, value, preserveDate }) { } } -function getDates({ step, culture, ...props }) { +function getDates({ step, culture, availableTimes, ...props }) { + if(availableTimes) { + return fetchAvailableTimes({ step, culture, availableTimes, ...props }) + } + + return fetchDefaultTimes({ step, culture, ...props }) +} + +function fetchDefaultTimes({ step, culture, ...props }) { let times = [] let { min, max } = getBounds(props) let startDay = dates.date(min) @@ -66,8 +74,31 @@ function getDates({ step, culture, ...props }) { date: min, label: dateLocalizer.format(min, format(props), culture), }) + + min = dates.add(min, step || 30, 'minutes') + } + + return times +} + +function fetchAvailableTimes({ step, culture, availableTimes, ...props }) { + let times = [] + let { min, max } = getBounds(props) + let startDay = dates.date(min) + + while (dates.date(min) === startDay && dates.lte(min, max)) { + if(availableTimes.hours.includes(min.getHours())) { + times.push({ + date: min, + label: dateLocalizer.format(min, format(props), culture), + }) + } + min = dates.add(min, step || 30, 'minutes') } + + if(!availableTimes.includeLastStep) times.pop() + return times } @@ -87,6 +118,10 @@ class TimeList extends React.Component { min: PropTypes.instanceOf(Date), max: PropTypes.instanceOf(Date), currentDate: PropTypes.instanceOf(Date), + availableTimes: PropTypes.shape({ + hours: PropTypes.arrayOf(PropTypes.number), + includeLastStep: PropTypes.bool + }), itemComponent: CustomPropTypes.elementType, listProps: PropTypes.object, diff --git a/packages/react-widgets/test/DateTimePicker-test.js b/packages/react-widgets/test/DateTimePicker-test.js index 6bd99b11d..e3e0bdb40 100644 --- a/packages/react-widgets/test/DateTimePicker-test.js +++ b/packages/react-widgets/test/DateTimePicker-test.js @@ -318,5 +318,34 @@ describe('DateTimePicker', () => { expect(dates[1].date.getHours()).to.equal(2) expect(dates[2].date.getHours()).to.equal(4) }) + + it('should set availableTimes property', () => { + let availableTimes = { + hours: [8, 9] + } + let dates = mount() + .find(TimeList) + .instance().state.data + + expect(dates.length).to.equal(3) + expect(dates[0].date.getHours()).to.equal(8) + expect(dates[1].date.getHours()).to.equal(8) + expect(dates[2].date.getHours()).to.equal(9) + + availableTimes = { + hours: [8, 9], + includeLastStep: true + } + + dates = mount() + .find(TimeList) + .instance().state.data + + expect(dates.length).to.equal(4) + expect(dates[0].date.getHours()).to.equal(8) + expect(dates[1].date.getHours()).to.equal(8) + expect(dates[2].date.getHours()).to.equal(9) + expect(dates[3].date.getHours()).to.equal(9) + }) }) })