|
| 1 | +/* eslint-disable no-console */ |
| 2 | +import React, { Component } from 'react' |
| 3 | +import moment from 'moment' |
| 4 | + |
| 5 | +import Timeline, { |
| 6 | + TimelineMarkers, |
| 7 | + TimelineHeaders, |
| 8 | + TodayMarker, |
| 9 | + CustomMarker, |
| 10 | + CursorMarker, |
| 11 | + CustomHeader, |
| 12 | + SidebarHeader, |
| 13 | + DateHeader |
| 14 | +} from 'react-calendar-timeline' |
| 15 | + |
| 16 | +import generateFakeData from '../generate-fake-data' |
| 17 | + |
| 18 | +var minTime = moment() |
| 19 | + .add(-6, 'months') |
| 20 | + .valueOf() |
| 21 | +var maxTime = moment() |
| 22 | + .add(6, 'months') |
| 23 | + .valueOf() |
| 24 | + |
| 25 | +var keys = { |
| 26 | + groupIdKey: 'id', |
| 27 | + groupTitleKey: 'title', |
| 28 | + groupRightTitleKey: 'rightTitle', |
| 29 | + itemIdKey: 'id', |
| 30 | + itemTitleKey: 'title', |
| 31 | + itemDivTitleKey: 'title', |
| 32 | + itemGroupKey: 'group', |
| 33 | + itemTimeStartKey: 'start', |
| 34 | + itemTimeEndKey: 'end' |
| 35 | +} |
| 36 | + |
| 37 | +export default class App extends Component { |
| 38 | + constructor(props) { |
| 39 | + super(props) |
| 40 | + |
| 41 | + const { groups, items } = generateFakeData() |
| 42 | + const defaultTimeStart = moment() |
| 43 | + .startOf('day') |
| 44 | + .toDate() |
| 45 | + const defaultTimeEnd = moment() |
| 46 | + .startOf('day') |
| 47 | + .add(1, 'day') |
| 48 | + .toDate() |
| 49 | + |
| 50 | + this.state = { |
| 51 | + groups, |
| 52 | + items, |
| 53 | + defaultTimeStart, |
| 54 | + defaultTimeEnd, |
| 55 | + selected: undefined, |
| 56 | + } |
| 57 | + } |
| 58 | + |
| 59 | + handleCanvasClick = (groupId, time) => { |
| 60 | + console.log('Canvas clicked', groupId, moment(time).format()) |
| 61 | + } |
| 62 | + |
| 63 | + handleCanvasDoubleClick = (groupId, time) => { |
| 64 | + console.log('Canvas double clicked', groupId, moment(time).format()) |
| 65 | + } |
| 66 | + |
| 67 | + handleCanvasContextMenu = (group, time) => { |
| 68 | + console.log('Canvas context menu', group, moment(time).format()) |
| 69 | + } |
| 70 | + |
| 71 | + handleItemClick = (itemId, _, time) => { |
| 72 | + console.log('Clicked: ' + itemId, moment(time).format()) |
| 73 | + } |
| 74 | + |
| 75 | + handleItemSelect = (itemId, _, time) => { |
| 76 | + this.setState({ |
| 77 | + selected: [itemId] |
| 78 | + }) |
| 79 | + console.log('Selected: ' + itemId, moment(time).format()) |
| 80 | + } |
| 81 | + |
| 82 | + handleItemDeselect = () => { |
| 83 | + this.setState({selected: undefined}) |
| 84 | + } |
| 85 | + |
| 86 | + handleItemDoubleClick = (itemId, _, time) => { |
| 87 | + console.log('Double Click: ' + itemId, moment(time).format()) |
| 88 | + } |
| 89 | + |
| 90 | + handleItemContextMenu = (itemId, _, time) => { |
| 91 | + console.log('Context Menu: ' + itemId, moment(time).format()) |
| 92 | + } |
| 93 | + |
| 94 | + handleItemMove = (itemId, dragTime, newGroupOrder) => { |
| 95 | + const { items, groups } = this.state |
| 96 | + |
| 97 | + const group = groups[newGroupOrder] |
| 98 | + |
| 99 | + this.setState({ |
| 100 | + items: items.map( |
| 101 | + item => |
| 102 | + item.id === itemId |
| 103 | + ? Object.assign({}, item, { |
| 104 | + start: dragTime, |
| 105 | + end: dragTime + (item.end - item.start), |
| 106 | + group: group.id |
| 107 | + }) |
| 108 | + : item |
| 109 | + ) |
| 110 | + }) |
| 111 | + |
| 112 | + console.log('Moved', itemId, dragTime, newGroupOrder) |
| 113 | + } |
| 114 | + |
| 115 | + handleItemResize = (itemId, time, edge) => { |
| 116 | + const { items } = this.state |
| 117 | + |
| 118 | + this.setState({ |
| 119 | + items: items.map( |
| 120 | + item => |
| 121 | + item.id === itemId |
| 122 | + ? Object.assign({}, item, { |
| 123 | + start: edge === 'left' ? time : item.start, |
| 124 | + end: edge === 'left' ? item.end : time |
| 125 | + }) |
| 126 | + : item |
| 127 | + ) |
| 128 | + }) |
| 129 | + |
| 130 | + console.log('Resized', itemId, time, edge) |
| 131 | + } |
| 132 | + |
| 133 | + // this limits the timeline to -6 months ... +6 months |
| 134 | + handleTimeChange = (visibleTimeStart, visibleTimeEnd, updateScrollCanvas) => { |
| 135 | + if (visibleTimeStart < minTime && visibleTimeEnd > maxTime) { |
| 136 | + updateScrollCanvas(minTime, maxTime) |
| 137 | + } else if (visibleTimeStart < minTime) { |
| 138 | + updateScrollCanvas(minTime, minTime + (visibleTimeEnd - visibleTimeStart)) |
| 139 | + } else if (visibleTimeEnd > maxTime) { |
| 140 | + updateScrollCanvas(maxTime - (visibleTimeEnd - visibleTimeStart), maxTime) |
| 141 | + } else { |
| 142 | + updateScrollCanvas(visibleTimeStart, visibleTimeEnd) |
| 143 | + } |
| 144 | + } |
| 145 | + |
| 146 | + moveResizeValidator = (action, item, time) => { |
| 147 | + if (time < new Date().getTime()) { |
| 148 | + var newTime = |
| 149 | + Math.ceil(new Date().getTime() / (15 * 60 * 1000)) * (15 * 60 * 1000) |
| 150 | + return newTime |
| 151 | + } |
| 152 | + |
| 153 | + return time |
| 154 | + } |
| 155 | + |
| 156 | + render() { |
| 157 | + const { groups, items, defaultTimeStart, defaultTimeEnd } = this.state |
| 158 | + |
| 159 | + return ( |
| 160 | + <Timeline |
| 161 | + groups={groups} |
| 162 | + items={items} |
| 163 | + keys={keys} |
| 164 | + sidebarWidth={150} |
| 165 | + sidebarContent={<div>Above The Left</div>} |
| 166 | + canMove |
| 167 | + canResize="right" |
| 168 | + canSelect |
| 169 | + itemsSorted |
| 170 | + itemTouchSendsClick={false} |
| 171 | + stackItems |
| 172 | + itemHeightRatio={0.75} |
| 173 | + defaultTimeStart={defaultTimeStart} |
| 174 | + defaultTimeEnd={defaultTimeEnd} |
| 175 | + onCanvasClick={this.handleCanvasClick} |
| 176 | + onCanvasDoubleClick={this.handleCanvasDoubleClick} |
| 177 | + onCanvasContextMenu={this.handleCanvasContextMenu} |
| 178 | + onItemClick={this.handleItemClick} |
| 179 | + onItemSelect={this.handleItemSelect} |
| 180 | + onItemContextMenu={this.handleItemContextMenu} |
| 181 | + onItemMove={this.handleItemMove} |
| 182 | + onItemResize={this.handleItemResize} |
| 183 | + onItemDoubleClick={this.handleItemDoubleClick} |
| 184 | + onTimeChange={this.handleTimeChange} |
| 185 | + moveResizeValidator={this.moveResizeValidator} |
| 186 | + selected={this.state.selected} |
| 187 | + onItemDeselect={this.handleItemDeselect} |
| 188 | + > |
| 189 | + <TimelineMarkers> |
| 190 | + <TodayMarker /> |
| 191 | + <CustomMarker |
| 192 | + date={ |
| 193 | + moment() |
| 194 | + .startOf('day') |
| 195 | + .valueOf() + |
| 196 | + 1000 * 60 * 60 * 2 |
| 197 | + } |
| 198 | + /> |
| 199 | + <CustomMarker |
| 200 | + date={moment() |
| 201 | + .add(3, 'day') |
| 202 | + .valueOf()} |
| 203 | + > |
| 204 | + {({ styles }) => { |
| 205 | + const newStyles = { ...styles, backgroundColor: 'blue' } |
| 206 | + return <div style={newStyles} /> |
| 207 | + }} |
| 208 | + </CustomMarker> |
| 209 | + <CursorMarker /> |
| 210 | + </TimelineMarkers> |
| 211 | + </Timeline> |
| 212 | + ) |
| 213 | + } |
| 214 | +} |
0 commit comments