Skip to content

Commit c14f427

Browse files
committed
feat: Add onSelectEvent & onDoubleClickEvent support to Agenda
1 parent 7aef31f commit c14f427

File tree

1 file changed

+125
-100
lines changed

1 file changed

+125
-100
lines changed

src/Agenda.js

Lines changed: 125 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -9,69 +9,39 @@ import { navigate } from './utils/constants'
99
import { inRange } from './utils/eventLevels'
1010
import { isSelected } from './utils/selection'
1111

12-
class Agenda extends React.Component {
13-
componentDidMount() {
14-
this._adjustHeader()
15-
}
16-
17-
componentDidUpdate() {
18-
this._adjustHeader()
19-
}
20-
21-
render() {
22-
let { length, date, events, accessors, localizer } = this.props
23-
let { messages } = localizer
24-
let end = dates.add(date, length, 'day')
25-
26-
let range = dates.range(date, end, 'day')
27-
28-
events = events.filter(event => inRange(event, date, end, accessors))
29-
30-
events.sort((a, b) => +accessors.start(a) - +accessors.start(b))
31-
32-
return (
33-
<div className="rbc-agenda-view">
34-
{events.length !== 0 ? (
35-
<React.Fragment>
36-
<table ref="header" className="rbc-agenda-table">
37-
<thead>
38-
<tr>
39-
<th className="rbc-header" ref="dateCol">
40-
{messages.date}
41-
</th>
42-
<th className="rbc-header" ref="timeCol">
43-
{messages.time}
44-
</th>
45-
<th className="rbc-header">{messages.event}</th>
46-
</tr>
47-
</thead>
48-
</table>
49-
<div className="rbc-agenda-content" ref="content">
50-
<table className="rbc-agenda-table">
51-
<tbody ref="tbody">
52-
{range.map((day, idx) => this.renderDay(day, events, idx))}
53-
</tbody>
54-
</table>
55-
</div>
56-
</React.Fragment>
57-
) : (
58-
<span className="rbc-agenda-empty">{messages.noEventsInRange}</span>
59-
)}
60-
</div>
61-
)
62-
}
63-
64-
renderDay = (day, events, dayKey) => {
65-
let {
66-
selected,
67-
getters,
68-
accessors,
69-
localizer,
70-
components: { event: Event, date: AgendaDate },
71-
} = this.props
12+
function Agenda({
13+
accessors,
14+
components,
15+
date,
16+
events,
17+
getters,
18+
length,
19+
localizer,
20+
onDoubleClickEvent,
21+
onSelectEvent,
22+
selected,
23+
}) {
24+
const headerRef = useRef(null)
25+
const dateColRef = useRef(null)
26+
const timeColRef = useRef(null)
27+
const contentRef = useRef(null)
28+
const tbodyRef = useRef(null)
29+
30+
useEffect(() => {
31+
_adjustHeader()
32+
})
33+
34+
const renderDay = (day, events, dayKey) => {
35+
const { event: Event, date: AgendaDate } = components
7236

7337
events = events.filter(e =>
74-
inRange(e, dates.startOf(day, 'day'), dates.endOf(day, 'day'), accessors)
38+
inRange(
39+
e,
40+
localizer.startOf(day, 'day'),
41+
localizer.endOf(day, 'day'),
42+
accessors,
43+
localizer
44+
)
7545
)
7646

7747
return events.map((event, idx) => {
@@ -107,20 +77,22 @@ class Agenda extends React.Component {
10777
style={userProps.style}
10878
>
10979
{first}
110-
<td className="rbc-agenda-time-cell">
111-
{this.timeRangeLabel(day, event)}
112-
</td>
113-
<td className="rbc-agenda-event-cell">
80+
<td className="rbc-agenda-time-cell">{timeRangeLabel(day, event)}</td>
81+
<td
82+
className="rbc-agenda-event-cell"
83+
onClick={e => onSelectEvent && onSelectEvent(event, e)}
84+
onDoubleClick={e =>
85+
onDoubleClickEvent && onDoubleClickEvent(event, e)
86+
}
87+
>
11488
{Event ? <Event event={event} title={title} /> : title}
11589
</td>
11690
</tr>
11791
)
11892
}, [])
11993
}
12094

121-
timeRangeLabel = (day, event) => {
122-
let { accessors, localizer, components } = this.props
123-
95+
const timeRangeLabel = (day, event) => {
12496
let labelClass = '',
12597
TimeComponent = components.time,
12698
label = localizer.messages.allDay
@@ -129,17 +101,19 @@ class Agenda extends React.Component {
129101
let start = accessors.start(event)
130102

131103
if (!accessors.allDay(event)) {
132-
if (dates.eq(start, end, 'day')) {
104+
if (localizer.eq(start, end)) {
105+
label = localizer.format(start, 'agendaTimeFormat')
106+
} else if (localizer.isSameDate(start, end)) {
133107
label = localizer.format({ start, end }, 'agendaTimeRangeFormat')
134-
} else if (dates.eq(day, start, 'day')) {
108+
} else if (localizer.isSameDate(day, start)) {
135109
label = localizer.format(start, 'agendaTimeFormat')
136-
} else if (dates.eq(day, end, 'day')) {
110+
} else if (localizer.isSameDate(day, end)) {
137111
label = localizer.format(end, 'agendaTimeFormat')
138112
}
139113
}
140114

141-
if (dates.gt(day, start, 'day')) labelClass = 'rbc-continues-prior'
142-
if (dates.lt(day, end, 'day')) labelClass += ' rbc-continues-after'
115+
if (localizer.gt(day, start, 'day')) labelClass = 'rbc-continues-prior'
116+
if (localizer.lt(day, end, 'day')) labelClass += ' rbc-continues-after'
143117

144118
return (
145119
<span className={labelClass.trim()}>
@@ -152,74 +126,125 @@ class Agenda extends React.Component {
152126
)
153127
}
154128

155-
_adjustHeader = () => {
156-
if (!this.refs.tbody) return
129+
const _adjustHeader = () => {
130+
if (!tbodyRef.current) return
157131

158-
let header = this.refs.header
159-
let firstRow = this.refs.tbody.firstChild
132+
let header = headerRef.current
133+
let firstRow = tbodyRef.current.firstChild
160134

161135
if (!firstRow) return
162136

163137
let isOverflowing =
164-
this.refs.content.scrollHeight > this.refs.content.clientHeight
165-
let widths = this._widths || []
138+
contentRef.current.scrollHeight > contentRef.current.clientHeight
139+
140+
let _widths = []
141+
let widths = _widths
166142

167-
this._widths = [
168-
getWidth(firstRow.children[0]),
169-
getWidth(firstRow.children[1]),
170-
]
143+
_widths = [getWidth(firstRow.children[0]), getWidth(firstRow.children[1])]
171144

172-
if (widths[0] !== this._widths[0] || widths[1] !== this._widths[1]) {
173-
this.refs.dateCol.style.width = this._widths[0] + 'px'
174-
this.refs.timeCol.style.width = this._widths[1] + 'px'
145+
if (widths[0] !== _widths[0] || widths[1] !== _widths[1]) {
146+
dateColRef.current.style.width = _widths[0] + 'px'
147+
timeColRef.current.style.width = _widths[1] + 'px'
175148
}
176149

177150
if (isOverflowing) {
178-
classes.addClass(header, 'rbc-header-overflowing')
151+
addClass(header, 'rbc-header-overflowing')
179152
header.style.marginRight = scrollbarSize() + 'px'
180153
} else {
181-
classes.removeClass(header, 'rbc-header-overflowing')
154+
removeClass(header, 'rbc-header-overflowing')
182155
}
183156
}
184-
}
185157

186-
Agenda.propTypes = {
187-
events: PropTypes.array,
188-
date: PropTypes.instanceOf(Date),
189-
length: PropTypes.number.isRequired,
158+
let { messages } = localizer
159+
let end = localizer.add(date, length, 'day')
190160

191-
selected: PropTypes.object,
161+
let range = localizer.range(date, end, 'day')
162+
163+
events = events.filter(event =>
164+
inRange(
165+
event,
166+
localizer.startOf(date, 'day'),
167+
localizer.endOf(end, 'day'),
168+
accessors,
169+
localizer
170+
)
171+
)
172+
173+
events.sort((a, b) => +accessors.start(a) - +accessors.start(b))
174+
175+
return (
176+
<div className="rbc-agenda-view">
177+
{events.length !== 0 ? (
178+
<React.Fragment>
179+
<table ref={headerRef} className="rbc-agenda-table">
180+
<thead>
181+
<tr>
182+
<th className="rbc-header" ref={dateColRef}>
183+
{messages.date}
184+
</th>
185+
<th className="rbc-header" ref={timeColRef}>
186+
{messages.time}
187+
</th>
188+
<th className="rbc-header">{messages.event}</th>
189+
</tr>
190+
</thead>
191+
</table>
192+
<div className="rbc-agenda-content" ref={contentRef}>
193+
<table className="rbc-agenda-table">
194+
<tbody ref={tbodyRef}>
195+
{range.map((day, idx) => renderDay(day, events, idx))}
196+
</tbody>
197+
</table>
198+
</div>
199+
</React.Fragment>
200+
) : (
201+
<span className="rbc-agenda-empty">{messages.noEventsInRange}</span>
202+
)}
203+
</div>
204+
)
205+
}
192206

207+
Agenda.propTypes = {
193208
accessors: PropTypes.object.isRequired,
194209
components: PropTypes.object.isRequired,
210+
date: PropTypes.instanceOf(Date),
211+
events: PropTypes.array,
195212
getters: PropTypes.object.isRequired,
213+
length: PropTypes.number.isRequired,
196214
localizer: PropTypes.object.isRequired,
215+
onSelectEvent: PropTypes.func,
216+
onDoubleClickEvent: PropTypes.func,
217+
selected: PropTypes.object,
197218
}
198219

199220
Agenda.defaultProps = {
200221
length: 30,
201222
}
202223

203-
Agenda.range = (start, { length = Agenda.defaultProps.length }) => {
204-
let end = dates.add(start, length, 'day')
224+
Agenda.range = (start, { length = Agenda.defaultProps.length, localizer }) => {
225+
let end = localizer.add(start, length, 'day')
205226
return { start, end }
206227
}
207228

208-
Agenda.navigate = (date, action, { length = Agenda.defaultProps.length }) => {
229+
Agenda.navigate = (
230+
date,
231+
action,
232+
{ length = Agenda.defaultProps.length, localizer }
233+
) => {
209234
switch (action) {
210235
case navigate.PREVIOUS:
211-
return dates.add(date, -length, 'day')
236+
return localizer.add(date, -length, 'day')
212237

213238
case navigate.NEXT:
214-
return dates.add(date, length, 'day')
239+
return localizer.add(date, length, 'day')
215240

216241
default:
217242
return date
218243
}
219244
}
220245

221246
Agenda.title = (start, { length = Agenda.defaultProps.length, localizer }) => {
222-
let end = dates.add(start, length, 'day')
247+
let end = localizer.add(start, length, 'day')
223248
return localizer.format({ start, end }, 'agendaHeaderFormat')
224249
}
225250

0 commit comments

Comments
 (0)