From c14f427195115f4d994795722c709bdc2ac44288 Mon Sep 17 00:00:00 2001 From: Matthew Herbst Date: Tue, 5 Mar 2019 19:02:01 -0800 Subject: [PATCH] feat: Add `onSelectEvent` & `onDoubleClickEvent` support to Agenda --- src/Agenda.js | 225 ++++++++++++++++++++++++++++---------------------- 1 file changed, 125 insertions(+), 100 deletions(-) diff --git a/src/Agenda.js b/src/Agenda.js index f185eec92..e993d67b0 100644 --- a/src/Agenda.js +++ b/src/Agenda.js @@ -9,69 +9,39 @@ import { navigate } from './utils/constants' import { inRange } from './utils/eventLevels' import { isSelected } from './utils/selection' -class Agenda extends React.Component { - componentDidMount() { - this._adjustHeader() - } - - componentDidUpdate() { - this._adjustHeader() - } - - render() { - let { length, date, events, accessors, localizer } = this.props - let { messages } = localizer - let end = dates.add(date, length, 'day') - - let range = dates.range(date, end, 'day') - - events = events.filter(event => inRange(event, date, end, accessors)) - - events.sort((a, b) => +accessors.start(a) - +accessors.start(b)) - - return ( -
- {events.length !== 0 ? ( - - - - - - - - - -
- {messages.date} - - {messages.time} - {messages.event}
-
- - - {range.map((day, idx) => this.renderDay(day, events, idx))} - -
-
-
- ) : ( - {messages.noEventsInRange} - )} -
- ) - } - - renderDay = (day, events, dayKey) => { - let { - selected, - getters, - accessors, - localizer, - components: { event: Event, date: AgendaDate }, - } = this.props +function Agenda({ + accessors, + components, + date, + events, + getters, + length, + localizer, + onDoubleClickEvent, + onSelectEvent, + selected, +}) { + const headerRef = useRef(null) + const dateColRef = useRef(null) + const timeColRef = useRef(null) + const contentRef = useRef(null) + const tbodyRef = useRef(null) + + useEffect(() => { + _adjustHeader() + }) + + const renderDay = (day, events, dayKey) => { + const { event: Event, date: AgendaDate } = components events = events.filter(e => - inRange(e, dates.startOf(day, 'day'), dates.endOf(day, 'day'), accessors) + inRange( + e, + localizer.startOf(day, 'day'), + localizer.endOf(day, 'day'), + accessors, + localizer + ) ) return events.map((event, idx) => { @@ -107,10 +77,14 @@ class Agenda extends React.Component { style={userProps.style} > {first} - - {this.timeRangeLabel(day, event)} - - + {timeRangeLabel(day, event)} + onSelectEvent && onSelectEvent(event, e)} + onDoubleClick={e => + onDoubleClickEvent && onDoubleClickEvent(event, e) + } + > {Event ? : title} @@ -118,9 +92,7 @@ class Agenda extends React.Component { }, []) } - timeRangeLabel = (day, event) => { - let { accessors, localizer, components } = this.props - + const timeRangeLabel = (day, event) => { let labelClass = '', TimeComponent = components.time, label = localizer.messages.allDay @@ -129,17 +101,19 @@ class Agenda extends React.Component { let start = accessors.start(event) if (!accessors.allDay(event)) { - if (dates.eq(start, end, 'day')) { + if (localizer.eq(start, end)) { + label = localizer.format(start, 'agendaTimeFormat') + } else if (localizer.isSameDate(start, end)) { label = localizer.format({ start, end }, 'agendaTimeRangeFormat') - } else if (dates.eq(day, start, 'day')) { + } else if (localizer.isSameDate(day, start)) { label = localizer.format(start, 'agendaTimeFormat') - } else if (dates.eq(day, end, 'day')) { + } else if (localizer.isSameDate(day, end)) { label = localizer.format(end, 'agendaTimeFormat') } } - if (dates.gt(day, start, 'day')) labelClass = 'rbc-continues-prior' - if (dates.lt(day, end, 'day')) labelClass += ' rbc-continues-after' + if (localizer.gt(day, start, 'day')) labelClass = 'rbc-continues-prior' + if (localizer.lt(day, end, 'day')) labelClass += ' rbc-continues-after' return ( @@ -152,66 +126,117 @@ class Agenda extends React.Component { ) } - _adjustHeader = () => { - if (!this.refs.tbody) return + const _adjustHeader = () => { + if (!tbodyRef.current) return - let header = this.refs.header - let firstRow = this.refs.tbody.firstChild + let header = headerRef.current + let firstRow = tbodyRef.current.firstChild if (!firstRow) return let isOverflowing = - this.refs.content.scrollHeight > this.refs.content.clientHeight - let widths = this._widths || [] + contentRef.current.scrollHeight > contentRef.current.clientHeight + + let _widths = [] + let widths = _widths - this._widths = [ - getWidth(firstRow.children[0]), - getWidth(firstRow.children[1]), - ] + _widths = [getWidth(firstRow.children[0]), getWidth(firstRow.children[1])] - if (widths[0] !== this._widths[0] || widths[1] !== this._widths[1]) { - this.refs.dateCol.style.width = this._widths[0] + 'px' - this.refs.timeCol.style.width = this._widths[1] + 'px' + if (widths[0] !== _widths[0] || widths[1] !== _widths[1]) { + dateColRef.current.style.width = _widths[0] + 'px' + timeColRef.current.style.width = _widths[1] + 'px' } if (isOverflowing) { - classes.addClass(header, 'rbc-header-overflowing') + addClass(header, 'rbc-header-overflowing') header.style.marginRight = scrollbarSize() + 'px' } else { - classes.removeClass(header, 'rbc-header-overflowing') + removeClass(header, 'rbc-header-overflowing') } } -} -Agenda.propTypes = { - events: PropTypes.array, - date: PropTypes.instanceOf(Date), - length: PropTypes.number.isRequired, + let { messages } = localizer + let end = localizer.add(date, length, 'day') - selected: PropTypes.object, + let range = localizer.range(date, end, 'day') + + events = events.filter(event => + inRange( + event, + localizer.startOf(date, 'day'), + localizer.endOf(end, 'day'), + accessors, + localizer + ) + ) + + events.sort((a, b) => +accessors.start(a) - +accessors.start(b)) + + return ( +
+ {events.length !== 0 ? ( + + + + + + + + + +
+ {messages.date} + + {messages.time} + {messages.event}
+
+ + + {range.map((day, idx) => renderDay(day, events, idx))} + +
+
+
+ ) : ( + {messages.noEventsInRange} + )} +
+ ) +} +Agenda.propTypes = { accessors: PropTypes.object.isRequired, components: PropTypes.object.isRequired, + date: PropTypes.instanceOf(Date), + events: PropTypes.array, getters: PropTypes.object.isRequired, + length: PropTypes.number.isRequired, localizer: PropTypes.object.isRequired, + onSelectEvent: PropTypes.func, + onDoubleClickEvent: PropTypes.func, + selected: PropTypes.object, } Agenda.defaultProps = { length: 30, } -Agenda.range = (start, { length = Agenda.defaultProps.length }) => { - let end = dates.add(start, length, 'day') +Agenda.range = (start, { length = Agenda.defaultProps.length, localizer }) => { + let end = localizer.add(start, length, 'day') return { start, end } } -Agenda.navigate = (date, action, { length = Agenda.defaultProps.length }) => { +Agenda.navigate = ( + date, + action, + { length = Agenda.defaultProps.length, localizer } +) => { switch (action) { case navigate.PREVIOUS: - return dates.add(date, -length, 'day') + return localizer.add(date, -length, 'day') case navigate.NEXT: - return dates.add(date, length, 'day') + return localizer.add(date, length, 'day') default: return date @@ -219,7 +244,7 @@ Agenda.navigate = (date, action, { length = Agenda.defaultProps.length }) => { } Agenda.title = (start, { length = Agenda.defaultProps.length, localizer }) => { - let end = dates.add(start, length, 'day') + let end = localizer.add(start, length, 'day') return localizer.format({ start, end }, 'agendaHeaderFormat') }