Skip to content

Commit

Permalink
awesome Splitter/Slicer classes
Browse files Browse the repository at this point in the history
  • Loading branch information
arshaw committed Dec 6, 2018
1 parent 79c5d1f commit 04a67df
Show file tree
Hide file tree
Showing 8 changed files with 330 additions and 260 deletions.
3 changes: 1 addition & 2 deletions src/agenda/AbstractAgendaView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import { diffDays } from '../datelib/marker'
import { ComponentContext } from '../component/Component'
import { ViewSpec } from '../structs/view-spec'
import DateProfileGenerator from '../DateProfileGenerator'
import { memoizeSplitter } from '../component/event-splitting'
import AllDaySplitter from './AllDaySplitter'

const AGENDA_ALL_DAY_EVENT_LIMIT = 5
Expand All @@ -37,7 +36,7 @@ export default abstract class AgendaView extends View {
scroller: ScrollComponent
axisWidth: any // the width of the time axis running down the side

protected splitter = memoizeSplitter(new AllDaySplitter())
protected splitter = new AllDaySplitter()


constructor(
Expand Down
46 changes: 17 additions & 29 deletions src/agenda/AgendaView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,9 @@ export default class AgendaView extends AbstractAgendaView {
render(props: ViewProps) {
super.render(props) // for flags for updateSize

let { splitter } = this
let { dateProfile, dateSelection } = this.props
let { dateProfile, businessHours } = this.props
let dayTable = this.buildDayTable(dateProfile, this.dateProfileGenerator)

let eventStores = splitter.splitEventStore(props.eventStore)
let eventDrags = splitter.splitEventDrag(props.eventDrag)
let eventResizes = splitter.splitEventResize(props.eventResize)
let splitProps = this.splitter.splitProps(props)

if (this.header) {
this.header.receiveProps({
Expand All @@ -75,32 +71,24 @@ export default class AgendaView extends AbstractAgendaView {
})
}

this.simpleTimeGrid.receiveProps({
dateProfile,
dayTable,
businessHours: props.businessHours,
dateSelection: dateSelection && !dateSelection.allDay ? dateSelection : null,
eventStore: eventStores.timed,
eventUiBases: props.eventUiBases,
eventSelection: props.eventSelection,
eventDrag: eventDrags.timed,
eventResize: eventResizes.timed
})

if (this.simpleDayGrid) {
this.simpleDayGrid.receiveProps({
this.simpleTimeGrid.receiveProps(
Object.assign({}, splitProps['timed'] || splitProps[''], {
dateProfile,
dayTable,
businessHours: props.businessHours,
dateSelection: dateSelection && dateSelection.allDay ? dateSelection : null,
eventStore: eventStores.allDay,
eventUiBases: props.eventUiBases,
eventSelection: props.eventSelection,
eventDrag: eventDrags.allDay,
eventResize: eventResizes.allDay,
nextDayThreshold: this.nextDayThreshold,
isRigid: false
businessHours
})
)

if (this.simpleDayGrid) {
this.simpleDayGrid.receiveProps(
Object.assign({}, splitProps['allDay'] || splitProps[''], {
dateProfile,
dayTable,
businessHours,
nextDayThreshold: this.nextDayThreshold,
isRigid: false
})
)
}
}

Expand Down
11 changes: 8 additions & 3 deletions src/agenda/AllDaySplitter.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import { Splitter } from '../component/event-splitting'
import Splitter from '../component/event-splitting'
import { hasBgRendering } from '../component/event-rendering'
import { EventDef } from '../structs/event'
import { DateSpan } from '../structs/date-span'

export default class AllDaySplitter extends Splitter {

constructor() {
super([ 'allDay', 'timed' ])
getKeysForDateSpan(dateSpan: DateSpan): string[] {
if (dateSpan.allDay) {
return [ 'allDay' ]
} else {
return [ 'timed' ]
}
}

getKeysForEventDef(eventDef: EventDef): string[] {
Expand Down
81 changes: 30 additions & 51 deletions src/agenda/SimpleTimeGrid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import reselector from '../util/reselector'
import { intersectRanges, DateRange } from '../datelib/date-range'
import DayTable from '../common/DayTable'
import { DateEnv } from '../datelib/env'
import { DateMarker, addMs } from '../datelib/marker'
import { Slicer, memoizeSlicer } from '../common/slicing-utils'
import { DateMarker } from '../datelib/marker'
import Slicer from '../common/slicing-utils'
import OffsetTracker from '../common/OffsetTracker'
import { Hit } from '../interactions/HitDragging'

Expand All @@ -26,19 +26,14 @@ export interface SimpleTimeGridProps {
eventResize: EventInteractionState | null
}

export interface SimpleTimeGridSlicerArgs {
component: TimeGrid // TODO: kill
dayRanges: DateRange[]
}

export default class SimpleTimeGrid extends DateComponent<SimpleTimeGridProps> {

timeGrid: TimeGrid
dayRanges: DateRange[]
dayRanges: DateRange[] // for now indicator
offsetTracker: OffsetTracker

private buildDayRanges = reselector(buildDayRanges)
private slicer = memoizeSlicer(new Slicer(sliceTimeGridSegs))
private slicer = new TimeGridSlicer()

constructor(context, timeGrid: TimeGrid) {
super(context, timeGrid.el)
Expand All @@ -47,40 +42,20 @@ export default class SimpleTimeGrid extends DateComponent<SimpleTimeGridProps> {
}

render(props: SimpleTimeGridProps) {
let { slicer } = this
let { dateProfile, dayTable } = props

let dayRanges = this.dayRanges = this.buildDayRanges(dayTable, dateProfile, this.dateEnv)
let slicerArgs: SimpleTimeGridSlicerArgs = { dayRanges, component: this.timeGrid }
let segRes = slicer.eventStoreToSegs(
props.eventStore,
props.eventUiBases,
dateProfile,
null,
slicerArgs
)

this.timeGrid.receiveProps({
dateProfile,
cells: dayTable.cells[0],
businessHourSegs: slicer.businessHoursToSegs(props.businessHours, dateProfile, null, slicerArgs),
bgEventSegs: segRes.bg,
fgEventSegs: segRes.fg,
dateSelectionSegs: slicer.selectionToSegs(props.dateSelection, props.eventUiBases, slicerArgs),
eventSelection: props.eventSelection,
eventDrag: slicer.buildEventDrag(props.eventDrag, props.eventUiBases, dateProfile, null, slicerArgs),
eventResize: slicer.buildEventResize(props.eventResize, props.eventUiBases, dateProfile, null, slicerArgs)
})
this.timeGrid.receiveProps(
Object.assign({}, this.slicer.sliceProps(props, dateProfile, null, this.timeGrid, dayRanges), {
dateProfile,
cells: dayTable.cells[0]
})
)
}

renderNowIndicator(date: DateMarker) { // TODO: user slicer???
renderNowIndicator(date: DateMarker) {
this.timeGrid.renderNowIndicator(
// seg system might be overkill, but it handles scenario where line needs to be rendered
// more than once because of columns with the same date (resources columns for example)
sliceTimeGridSegs({
start: date,
end: addMs(date, 1) // protect against null range
}, { dayRanges: this.dayRanges, component: this.timeGrid }),
this.slicer.sliceNowDate(date, this.timeGrid, this.dayRanges),
date
)
}
Expand Down Expand Up @@ -140,23 +115,27 @@ export function buildDayRanges(dayTable: DayTable, dateProfile: DateProfile, dat
return ranges
}

export function sliceTimeGridSegs(range: DateRange, slicerArgs: SimpleTimeGridSlicerArgs): TimeGridSeg[] {
let { dayRanges } = slicerArgs
let segs: TimeGridSeg[] = []

for (let col = 0; col < dayRanges.length; col++) {
let segRange = intersectRanges(range, dayRanges[col])
export class TimeGridSlicer extends Slicer<TimeGridSeg, [DateRange[]]> {

if (segRange) {
segs.push({
start: segRange.start,
end: segRange.end,
isStart: segRange.start.valueOf() === range.start.valueOf(),
isEnd: segRange.end.valueOf() === range.end.valueOf(),
col
})
sliceRange(range: DateRange, dayRanges: DateRange[]): TimeGridSeg[] {
let segs: TimeGridSeg[] = []

for (let col = 0; col < dayRanges.length; col++) {
let segRange = intersectRanges(range, dayRanges[col])

if (segRange) {
segs.push({
start: segRange.start,
end: segRange.end,
isStart: segRange.start.valueOf() === range.start.valueOf(),
isEnd: segRange.end.valueOf() === range.end.valueOf(),
col
})
}
}

return segs
}

return segs
}
66 changes: 24 additions & 42 deletions src/basic/SimpleDayGrid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import DayTable from '../common/DayTable'
import { Duration } from '../datelib/duration'
import DateComponent from '../component/DateComponent'
import { DateRange } from '../datelib/date-range'
import { Slicer, memoizeSlicer } from '../common/slicing-utils'
import Slicer from '../common/slicing-utils'
import OffsetTracker from '../common/OffsetTracker'
import { Hit } from '../interactions/HitDragging'

Expand All @@ -26,18 +26,12 @@ export interface SimpleDayGridProps {
isRigid: boolean
}

export interface SimpleDayGridSlicerArgs {
component: DayGrid // TODO: kill
dayTable: DayTable
isRtl: boolean
}

export default class SimpleDayGrid extends DateComponent<SimpleDayGridProps> {

dayGrid: DayGrid
offsetTracker: OffsetTracker

private slicer = memoizeSlicer(new Slicer(sliceDayGridSegs))
private slicer = new DayGridSlicer()

constructor(context, dayGrid: DayGrid) {
super(context, dayGrid.el)
Expand All @@ -46,30 +40,16 @@ export default class SimpleDayGrid extends DateComponent<SimpleDayGridProps> {
}

render(props: SimpleDayGridProps) {
let { dayGrid, slicer, isRtl } = this
let { dateProfile, dayTable, nextDayThreshold } = props

let slicerArgs = { dayTable, isRtl, component: this.dayGrid }
let segRes = slicer.eventStoreToSegs(
props.eventStore,
props.eventUiBases,
dateProfile,
nextDayThreshold,
slicerArgs
let { dayGrid } = this
let { dateProfile, dayTable } = props

dayGrid.receiveProps(
Object.assign({}, this.slicer.sliceProps(props, dateProfile, props.nextDayThreshold, dayGrid, dayTable, this.isRtl), {
dateProfile,
cells: dayTable.cells,
isRigid: props.isRigid
})
)

dayGrid.receiveProps({
dateProfile,
cells: dayTable.cells,
businessHourSegs: slicer.businessHoursToSegs(props.businessHours, dateProfile, nextDayThreshold, slicerArgs),
bgEventSegs: segRes.bg,
fgEventSegs: segRes.fg,
dateSelectionSegs: slicer.selectionToSegs(props.dateSelection, props.eventUiBases, slicerArgs),
eventSelection: props.eventSelection,
eventDrag: slicer.buildEventDrag(props.eventDrag, props.eventUiBases, dateProfile, nextDayThreshold, slicerArgs),
eventResize: slicer.buildEventResize(props.eventResize, props.eventUiBases, dateProfile, nextDayThreshold, slicerArgs),
isRigid: props.isRigid
})
}

prepareHits() {
Expand Down Expand Up @@ -114,16 +94,18 @@ export default class SimpleDayGrid extends DateComponent<SimpleDayGridProps> {
SimpleDayGrid.prototype.isInteractable = true


export function sliceDayGridSegs(range: DateRange, slicerArgs: SimpleDayGridSlicerArgs): DayGridSeg[] {
let { dayTable, isRtl } = slicerArgs
export class DayGridSlicer extends Slicer<DayGridSeg, [DayTable, boolean]> {

sliceRange(dateRange: DateRange, dayTable: DayTable, isRtl: boolean): DayGridSeg[] {
return dayTable.sliceRange(dateRange).map(function(seg) {
return {
isStart: seg.isStart,
isEnd: seg.isEnd,
row: seg.row,
leftCol: isRtl ? (dayTable.colCnt - 1 - seg.lastCol) : seg.firstCol,
rightCol: isRtl ? (dayTable.colCnt - 1 - seg.firstCol) : seg.lastCol
}
})
}

return dayTable.sliceRange(range).map(function(seg) {
return {
isStart: seg.isStart,
isEnd: seg.isEnd,
row: seg.row,
leftCol: isRtl ? (dayTable.colCnt - 1 - seg.lastCol) : seg.firstCol,
rightCol: isRtl ? (dayTable.colCnt - 1 - seg.firstCol) : seg.lastCol
}
})
}

0 comments on commit 04a67df

Please sign in to comment.