Skip to content

Commit

Permalink
event splitting
Browse files Browse the repository at this point in the history
  • Loading branch information
arshaw committed Dec 1, 2018
1 parent 6bd1c1e commit ef132ec
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 57 deletions.
54 changes: 3 additions & 51 deletions src/agenda/AbstractAgendaView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,13 @@ import TimeGrid from './TimeGrid'
import DayGrid from '../basic/DayGrid'
import { createDuration } from '../datelib/duration'
import { createFormatter } from '../datelib/formatting'
import { EventStore, filterEventStoreDefs } from '../structs/event-store'
import { EventInteractionUiState } from '../interactions/event-interaction-state'
import reselector from '../util/reselector'
import { hasBgRendering } from '../component/event-rendering'
import { buildGotoAnchorHtml, getAllDayHtml } from '../component/date-rendering'
import { diffDays } from '../datelib/marker'
import { ComponentContext } from '../component/Component'
import { ViewSpec } from '../structs/view-spec'
import DateProfileGenerator from '../DateProfileGenerator'
import { EventUiHash } from '../component/event-ui'
import { memoizeSplitter } from '../component/event-splitting'
import AllDaySplitter from './AllDaySplitter'

const AGENDA_ALL_DAY_EVENT_LIMIT = 5
const WEEK_HEADER_FORMAT = createFormatter({ week: 'short' })
Expand All @@ -40,13 +37,7 @@ export default abstract class AgendaView extends View {
scroller: ScrollComponent
axisWidth: any // the width of the time axis running down the side

// reselectors
filterEventsForTimeGrid = reselector(filterEventsForTimeGrid)
filterEventsForDayGrid = reselector(filterEventsForDayGrid)
buildEventDragForTimeGrid = reselector(buildInteractionForTimeGrid)
buildEventDragForDayGrid = reselector(buildInteractionForDayGrid)
buildEventResizeForTimeGrid = reselector(buildInteractionForTimeGrid)
buildEventResizeForDayGrid = reselector(buildInteractionForDayGrid)
splitter = memoizeSplitter(new AllDaySplitter())


constructor(
Expand Down Expand Up @@ -375,42 +366,3 @@ export default abstract class AgendaView extends View {
}

AgendaView.prototype.usesMinMaxTime = true // indicates that minTime/maxTime affects rendering


function filterEventsForTimeGrid(eventStore: EventStore, eventUis: EventUiHash): EventStore {
return filterEventStoreDefs(eventStore, function(eventDef) {
return !eventDef.allDay || hasBgRendering(eventUis[eventDef.defId])
})
}

function filterEventsForDayGrid(eventStore: EventStore, eventUis: EventUiHash): EventStore {
return filterEventStoreDefs(eventStore, function(eventDef) {
return eventDef.allDay
})
}

function buildInteractionForTimeGrid(state: EventInteractionUiState): EventInteractionUiState {
if (state) {
return {
affectedEvents: state.affectedEvents,
mutatedEvents: filterEventsForTimeGrid(state.mutatedEvents, state.eventUis),
eventUis: state.eventUis,
isEvent: state.isEvent,
origSeg: state.origSeg
}
}
return null
}

function buildInteractionForDayGrid(state: EventInteractionUiState): EventInteractionUiState {
if (state) {
return {
affectedEvents: state.affectedEvents,
mutatedEvents: filterEventsForDayGrid(state.mutatedEvents, state.eventUis),
eventUis: state.eventUis,
isEvent: state.isEvent,
origSeg: state.origSeg
}
}
return null
}
17 changes: 11 additions & 6 deletions src/agenda/AgendaView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,14 @@ 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 dayTable = this.buildDayTable(dateProfile, this.dateProfileGenerator)

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

if (this.header) {
this.header.receiveProps({
dateProfile,
Expand All @@ -75,11 +80,11 @@ export default class AgendaView extends AbstractAgendaView {
dayTable,
businessHours: props.businessHours,
dateSelection: dateSelection && !dateSelection.allDay ? dateSelection : null,
eventStore: this.filterEventsForTimeGrid(props.eventStore, props.eventUis),
eventStore: eventStores.timed,
eventUis: props.eventUis,
eventSelection: props.eventSelection,
eventDrag: this.buildEventDragForTimeGrid(props.eventDrag),
eventResize: this.buildEventResizeForTimeGrid(props.eventResize)
eventDrag: eventDrags.timed,
eventResize: eventResizes.timed
})

if (this.simpleDayGrid) {
Expand All @@ -88,11 +93,11 @@ export default class AgendaView extends AbstractAgendaView {
dayTable,
businessHours: props.businessHours,
dateSelection: dateSelection && dateSelection.allDay ? dateSelection : null,
eventStore: this.filterEventsForDayGrid(props.eventStore, props.eventUis),
eventStore: eventStores.allDay,
eventUis: props.eventUis,
eventSelection: props.eventSelection,
eventDrag: this.buildEventDragForDayGrid(props.eventDrag),
eventResize: this.buildEventResizeForDayGrid(props.eventResize),
eventDrag: eventDrags.allDay,
eventResize: eventResizes.allDay,
nextDayThreshold: this.nextDayThreshold,
isRigid: false
})
Expand Down
22 changes: 22 additions & 0 deletions src/agenda/AllDaySplitter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Splitter } from '../component/event-splitting'
import { EventUi } from '../component/event-ui'
import { hasBgRendering } from '../component/event-rendering'
import { EventDef } from '../structs/event'

export default class AllDaySplitter extends Splitter {

constructor() {
super([ 'allDay', 'timed' ])
}

getKeysForEventDef(eventDef: EventDef, eventUi: EventUi): string[] {
if (!eventDef.allDay) {
return [ 'timed' ]
} else if (hasBgRendering(eventUi)) {
return [ 'timed', 'allDay' ]
} else {
return [ 'allDay' ]
}
}

}
101 changes: 101 additions & 0 deletions src/component/event-splitting.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { EventStore, createEmptyEventStore } from '../structs/event-store'
import { EventDef } from '../structs/event'
import { EventInteractionUiState } from '../interactions/event-interaction-state'
import { mapHash } from '../util/object'
import { EventUi, EventUiHash } from '../component/event-ui'
import reselector from '../util/reselector'

export function memoizeSplitter(splitter: Splitter) {
return {
splitEventStore: reselector(splitter.splitEventStore),
splitEventDrag: reselector(splitter.splitInteraction),
splitEventResize: reselector(splitter.splitInteraction)
}
}

export abstract class Splitter { // not just EVENT splitting (rename file?)

allKeys: string[]

constructor(allKeys: string[]) {
this.allKeys = allKeys
}

splitInteraction = (state: EventInteractionUiState | null, allEventUis: EventUiHash) => {
let splitStates: { [key: string]: EventInteractionUiState } = {}

for (let key in this.allKeys) {
splitStates[key] = null
}

if (state) {
let mutatedStores = this.splitEventStorePopulated(state.mutatedEvents, state.eventUis)
let affectedStores = this.splitEventStorePopulated(state.affectedEvents, allEventUis)
let populate = function(key) {
if (!splitStates[key]) {
splitStates[key] = {
affectedEvents: affectedStores[key] || createEmptyEventStore(),
mutatedEvents: mutatedStores[key] || createEmptyEventStore(),
eventUis: state.eventUis,
isEvent: state.isEvent,
origSeg: state.origSeg
}
}
}

for (let key in affectedStores) {
populate(key)
}

for (let key in mutatedStores) {
populate(key)
}
}

return splitStates
}

splitEventStore = (eventStore: EventStore, eventUis: EventUiHash) => {
let splitStores = this.splitEventStorePopulated(eventStore, eventUis)

for (let key in this.allKeys) {
if (!splitStores[key]) {
splitStores[key] = createEmptyEventStore()
}
}

return splitStores
}

splitEventStorePopulated(eventStore: EventStore, eventUis: EventUiHash): { [key: string]: EventStore } {
let { defs, instances } = eventStore
let keysByDefId = mapHash(eventStore.defs, (eventDef: EventDef, defId: string) => {
return this.getKeysForEventDef(eventDef, eventUis[defId])
})
let splitStores = {}

for (let defId in defs) {
for (let key of keysByDefId[defId]) {

if (!splitStores[key]) {
splitStores[key] = createEmptyEventStore()
}

splitStores[key].defs[defId] = defs[defId]
}
}

for (let instanceId in instances) {
let instance = instances[instanceId]

for (let key of keysByDefId[instance.defId]) {
splitStores[key].instances[instanceId] = instance
}
}

return splitStores
}

abstract getKeysForEventDef(eventDef: EventDef, eventUi: EventUi): string[]

}
1 change: 1 addition & 0 deletions src/exports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export {
export { EventStore, filterEventStoreDefs, createEmptyEventStore } from './structs/event-store'
export { hasBgRendering } from './component/event-rendering'
export { EventUiHash } from './component/event-ui'
export { Splitter, memoizeSplitter } from './component/event-splitting'
export { buildGotoAnchorHtml, getAllDayHtml, getDayClasses } from './component/date-rendering'

export {
Expand Down

0 comments on commit ef132ec

Please sign in to comment.