Преглед изворни кода

render the event store directly

Adam Shaw пре 7 година
родитељ
комит
ddc3d1bceb

+ 6 - 24
src/View.ts

@@ -11,8 +11,7 @@ import UnzonedRange from './models/UnzonedRange'
 import { DateMarker, addDays, addMs, diffWholeDays } from './datelib/marker'
 import { createDuration } from './datelib/duration'
 import { createFormatter } from './datelib/formatting'
-import { EventStore, EventInstance } from './reducers/event-store'
-import { EventRenderRange } from './reducers/event-rendering'
+import { EventInstance } from './reducers/event-store'
 import { Selection } from './reducers/selection'
 
 
@@ -326,9 +325,9 @@ export default abstract class View extends InteractiveDateComponent {
   // -----------------------------------------------------------------------------------------------------------------
 
 
-  requestEventStoreRender(eventStore) {
+  requestRenderEvents(eventStore) {
     this.requestRender(() => {
-      this.renderEventStore(eventStore)
+      this.renderEvents(eventStore)
       this.whenSizeUpdated(
         this.triggerAfterEventsRendered
       )
@@ -336,7 +335,7 @@ export default abstract class View extends InteractiveDateComponent {
   }
 
 
-  requestEventsUnrender() {
+  requestUnrenderEvents() {
     this.requestRender(() => {
       this.triggerBeforeEventsDestroyed()
       this.unrenderEvents()
@@ -344,23 +343,6 @@ export default abstract class View extends InteractiveDateComponent {
   }
 
 
-  renderEventStore(eventStore: EventStore) {
-    let eventRanges: EventRenderRange[] = []
-
-    for (let instanceId in eventStore.instances) {
-      let eventInstance = eventStore.instances[instanceId]
-
-      eventRanges.push({
-        eventDef: eventStore.defs[eventInstance.defId],
-        eventInstance,
-        range: eventInstance.range
-      })
-    }
-
-    this.renderEventRanges(eventRanges)
-  }
-
-
   // Business Hour High-level Rendering
   // -----------------------------------------------------------------------------------------------------------------
 
@@ -852,9 +834,9 @@ View.watch('displayingBusinessHours', [ 'displayingDates' ], function() {
 
 
 View.watch('displayingEvents', [ 'displayingDates', 'eventStore' ], function(deps) {
-  this.requestEventStoreRender(deps.eventStore)
+  this.requestRenderEvents(deps.eventStore)
 }, function() {
-  this.requestEventsUnrender()
+  this.requestUnrenderEvents()
 })
 
 

+ 29 - 16
src/agenda/AgendaView.ts

@@ -13,7 +13,7 @@ import TimeGrid from './TimeGrid'
 import DayGrid from '../basic/DayGrid'
 import { createDuration } from '../datelib/duration'
 import { createFormatter } from '../datelib/formatting'
-import { EventRenderRange } from '../reducers/event-rendering'
+import { EventStore } from '../reducers/event-store'
 import { Selection } from '../reducers/selection'
 
 const AGENDA_ALL_DAY_EVENT_LIMIT = 5
@@ -288,13 +288,13 @@ export default class AgendaView extends View {
   /* Event Rendering
   ------------------------------------------------------------------------------------------------------------------*/
 
-  renderEventRanges(eventRanges: EventRenderRange[]) {
-    let groups = groupEventRangesByAllDay(eventRanges)
+  renderEvents(eventStore: EventStore) {
+    let groups = divideEventStoreByAllDay(eventStore)
 
-    this.timeGrid.renderEventRanges(groups.timed)
+    this.timeGrid.renderEvents(groups.timed)
 
     if (this.dayGrid) {
-      this.dayGrid.renderEventRanges(groups.allDay)
+      this.dayGrid.renderEvents(groups.allDay)
     }
   }
 
@@ -304,8 +304,8 @@ export default class AgendaView extends View {
 
 
   // A returned value of `true` signals that a mock "helper" event has been rendered.
-  renderDrag(eventRanges: EventRenderRange[], origSeg, isTouch) {
-    let groups = groupEventRangesByAllDay(eventRanges)
+  renderDrag(eventStore: EventStore, origSeg, isTouch) {
+    let groups = divideEventStoreByAllDay(eventStore)
     let renderedHelper = false
 
     renderedHelper = this.timeGrid.renderDrag(groups.timed, origSeg, isTouch)
@@ -318,8 +318,8 @@ export default class AgendaView extends View {
   }
 
 
-  renderEventResize(eventRanges: EventRenderRange[], origSeg, isTouch) {
-    let groups = groupEventRangesByAllDay(eventRanges)
+  renderEventResize(eventStore: EventStore, origSeg, isTouch) {
+    let groups = divideEventStoreByAllDay(eventStore)
 
     this.timeGrid.renderEventResize(groups.timed, origSeg, isTouch)
 
@@ -422,15 +422,28 @@ agendaDayGridMethods = {
 }
 
 
-function groupEventRangesByAllDay(eventRanges: EventRenderRange[]) {
-  let allDay = []
-  let timed = []
+function divideEventStoreByAllDay(eventStore: EventStore) {
+  let allDay: EventStore = { defs: {}, instances: {} }
+  let timed: EventStore = { defs: {}, instances: {} }
 
-  for (let eventRange of eventRanges) {
-    if (eventRange.eventDef.isAllDay) {
-      allDay.push(eventRange)
+  for (let defId in eventStore.defs) {
+    let def = eventStore.defs[defId]
+
+    if (def.isAllDay) {
+      allDay.defs[defId] = def
+    } else {
+      timed.defs[defId] = def
+    }
+  }
+
+  for (let instanceId in eventStore.instances) {
+    let instance = eventStore.instances[instanceId]
+    let def = eventStore.defs[instance.defId]
+
+    if (def.isAllDay) {
+      allDay.instances[instanceId] = instance
     } else {
-      timed.push(eventRange)
+      timed.instances[instanceId] = instance
     }
   }
 

+ 6 - 6
src/agenda/TimeGrid.ts

@@ -12,8 +12,8 @@ import { Duration, createDuration, addDurations, wholeDivideDurations, asRoughMs
 import { startOfDay, DateMarker, addMs } from '../datelib/marker'
 import { DateFormatter, createFormatter, formatIsoTimeString } from '../datelib/formatting'
 import { Seg } from '../reducers/seg'
-import { EventRenderRange } from '../reducers/event-rendering'
 import { Selection } from '../reducers/selection'
+import { EventStore } from '../reducers/event-store'
 
 /* A component that renders one or more columns of vertical time slots
 ----------------------------------------------------------------------------------------------------------------------*/
@@ -587,12 +587,12 @@ export default class TimeGrid extends InteractiveDateComponent {
 
   // Renders a visual indication of an event being dragged over the specified date(s).
   // A returned value of `true` signals that a mock "helper" event has been rendered.
-  renderDrag(eventRanges: EventRenderRange[], origSeg, isTouch) {
-    let segs = this.eventRangesToSegs(eventRanges)
+  renderDrag(eventStore: EventStore, origSeg, isTouch) {
+    let segs = this.eventStoreToSegs(eventStore)
 
     if (origSeg) { // if there is event information for this drag, render a helper event
 
-      if (eventRanges.length) {
+      if (segs.length) {
         this.helperRenderer.renderEventDraggingSegs(segs, origSeg, isTouch)
 
         // signal that a helper has been rendered
@@ -616,8 +616,8 @@ export default class TimeGrid extends InteractiveDateComponent {
 
 
   // Renders a visual indication of an event being resized
-  renderEventResize(eventRanges: EventRenderRange[], origSeg, isTouch) {
-    let segs = this.eventRangesToSegs(eventRanges)
+  renderEventResize(eventStore: EventStore, origSeg, isTouch) {
+    let segs = this.eventStoreToSegs(eventStore)
 
     this.helperRenderer.renderEventResizingSegs(segs, origSeg, isTouch)
   }

+ 6 - 6
src/basic/DayGrid.ts

@@ -22,7 +22,7 @@ import DayGridFillRenderer from './DayGridFillRenderer'
 import { addDays } from '../datelib/marker'
 import { createFormatter } from '../datelib/formatting'
 import { Seg } from '../reducers/seg'
-import { EventRenderRange } from '../reducers/event-rendering'
+import { EventStore } from '../reducers/event-store'
 
 const DAY_NUM_FORMAT = createFormatter({ day: 'numeric' })
 const WEEK_NUM_FORMAT = createFormatter({ week: 'numeric' })
@@ -319,13 +319,13 @@ export default class DayGrid extends InteractiveDateComponent {
 
   // Renders a visual indication of an event or external element being dragged.
   // `eventLocation` has zoned start and end (optional)
-  renderDrag(eventRanges: EventRenderRange[], origSeg, isTouch) {
-    let segs = this.eventRangesToSegs(eventRanges)
+  renderDrag(eventStore: EventStore, origSeg, isTouch) {
+    let segs = this.eventStoreToSegs(eventStore)
 
     this.renderHighlightSegs(segs)
 
     // render drags from OTHER components as helpers
-    if (eventRanges.length && origSeg && origSeg.component !== this) {
+    if (segs.length && origSeg && origSeg.component !== this) {
       this.helperRenderer.renderEventDraggingSegs(segs, origSeg, isTouch)
 
       return true // signal helpers rendered
@@ -345,8 +345,8 @@ export default class DayGrid extends InteractiveDateComponent {
 
 
   // Renders a visual indication of an event being resized
-  renderEventResize(eventRanges: EventRenderRange[], origSeg, isTouch) {
-    let segs = this.eventRangesToSegs(eventRanges)
+  renderEventResize(eventStore: EventStore, origSeg, isTouch) {
+    let segs = this.eventStoreToSegs(eventStore)
 
     this.renderHighlightSegs(segs)
 

+ 18 - 29
src/component/DateComponent.ts

@@ -5,12 +5,12 @@ import View from '../View'
 import { DateProfile } from '../DateProfileGenerator'
 import { DateMarker, DAY_IDS, addDays, startOfDay, diffDays, diffWholeDays } from '../datelib/marker'
 import { Duration, createDuration, asRoughMs } from '../datelib/duration'
-import { EventRenderRange, sliceEventRanges } from '../reducers/event-rendering'
+import { sliceEventStore } from '../reducers/event-rendering'
 import { Selection } from '../reducers/selection'
 import UnzonedRange from '../models/UnzonedRange'
 import { Seg } from '../reducers/seg'
-import { EventDef, EventInstance, parseDef, createInstance } from '../reducers/event-store'
-import { BusinessHourDef, buildBusinessHourEventRenderRanges } from '../reducers/business-hours'
+import { EventStore } from '../reducers/event-store'
+import { BusinessHourDef, buildBusinessHourEventStore } from '../reducers/business-hours'
 
 
 export default abstract class DateComponent extends Component {
@@ -187,8 +187,8 @@ export default abstract class DateComponent extends Component {
   renderBusinessHours(businessHoursDef: BusinessHourDef) {
     if (this.businessHourRenderer) {
       this.businessHourRenderer.renderSegs(
-        this.eventRangesToSegs(
-          buildBusinessHourEventRenderRanges(
+        this.eventStoreToSegs(
+          buildBusinessHourEventStore(
             businessHoursDef,
             this.hasAllDayBusinessHours,
             this.dateProfile.activeUnzonedRange,
@@ -236,19 +236,16 @@ export default abstract class DateComponent extends Component {
   // -----------------------------------------------------------------------------------------------------------------
 
 
-  renderEventRanges(eventRanges: EventRenderRange[]) {
+  renderEvents(eventStore: EventStore) {
 
     if (this.eventRenderer) {
       this.eventRenderer.rangeUpdated() // poorly named now
       this.eventRenderer.renderSegs(
-        this.eventRangesToSegs(eventRanges)
+        this.eventStoreToSegs(eventStore)
       )
     }
-    // else if (this['renderEvents']) { // legacy
-    //   this['renderEvents'](convertEventsPayloadToLegacyArray(eventsPayload, this._getCalendar()))
-    // }
 
-    this.callChildren('renderEventRanges', arguments)
+    this.callChildren('renderEvents', arguments)
   }
 
 
@@ -383,11 +380,11 @@ export default abstract class DateComponent extends Component {
   // Renders a visual indication of a event or external-element drag over the given drop zone.
   // If an external-element, seg will be `null`.
   // Must return elements used for any mock events.
-  renderDrag(eventRanges: EventRenderRange[], origSeg?, isTouch = false) {
+  renderDrag(eventStore: EventStore, origSeg?, isTouch = false) {
     let renderedHelper = false
 
     this.iterChildren(function(child) {
-      if (child.renderDrag(eventRanges, origSeg, isTouch)) {
+      if (child.renderDrag(eventStore, origSeg, isTouch)) {
         renderedHelper = true
       }
     })
@@ -427,7 +424,7 @@ export default abstract class DateComponent extends Component {
 
 
   // Renders a visual indication of an event being resized.
-  renderEventResize(eventRanges: EventRenderRange[], seg, isTouch) {
+  renderEventResize(eventStore: EventStore, seg, isTouch) {
     this.callChildren('renderEventResize', arguments)
   }
 
@@ -487,14 +484,9 @@ export default abstract class DateComponent extends Component {
   ------------------------------------------------------------------------------------------------------------------*/
 
 
-  selectionToSegs(selection: Selection): Seg[] {
-    return this.rangeToSegs(selection.range, selection.isAllDay)
-  }
-
-
-  eventRangesToSegs(eventRanges: EventRenderRange[]): Seg[] {
+  eventStoreToSegs(eventStore: EventStore): Seg[] {
     let activeUnzonedRange = this.dateProfile.activeUnzonedRange
-    let eventRenderRanges = sliceEventRanges(eventRanges, activeUnzonedRange)
+    let eventRenderRanges = sliceEventStore(eventStore, activeUnzonedRange)
     let allSegs: Seg[] = []
 
     for (let eventRenderRange of eventRenderRanges) {
@@ -510,6 +502,11 @@ export default abstract class DateComponent extends Component {
   }
 
 
+  selectionToSegs(selection: Selection): Seg[] {
+    return this.rangeToSegs(selection.range, selection.isAllDay)
+  }
+
+
   // must implement if want to use many of the rendering utils
   rangeToSegs(range: UnzonedRange, isAllDay: boolean): Seg[] {
     return []
@@ -696,11 +693,3 @@ export default abstract class DateComponent extends Component {
   }
 
 }
-
-
-export function fabricateEventRange(range: UnzonedRange, isAllDay: boolean): EventRenderRange {
-  let eventDef: EventDef = parseDef({}, null, isAllDay, true)
-  let eventInstance: EventInstance = createInstance(eventDef.defId, range)
-
-  return { eventDef, eventInstance, range }
-}

+ 11 - 28
src/reducers/business-hours.ts

@@ -1,10 +1,9 @@
 import Calendar from '../Calendar'
-import { EventRenderRange, sliceEventRanges } from '../reducers/event-rendering'
 import UnzonedRange from '../models/UnzonedRange'
 import { EventInput } from './event-store'
 import { assignTo } from '../util/object'
 import { expandRecurring } from './recurring-events'
-import { parseDef, createInstance } from './event-store'
+import { EventStore, parseDef, createInstance } from './event-store'
 
 export type BusinessHourDef = boolean | EventInput | EventInput[] // TODO: rename to plural?
 
@@ -13,52 +12,36 @@ const BUSINESS_HOUR_EVENT_DEFAULTS = {
   endTime: '17:00',
   daysOfWeek: [ 1, 2, 3, 4, 5 ], // monday - friday
   rendering: 'inverse-background',
-  groupId: 'business-hours', // for inverse-rendering
   className: 'fc-nonbusiness'
 }
 
 
-export function buildBusinessHourEventRenderRanges(
+export function buildBusinessHourEventStore(
   input: BusinessHourDef,
   isAllDay: boolean,
   framingRange: UnzonedRange,
   calendar: Calendar
-): EventRenderRange[] {
-  let eventRanges = buildBusinessHourEventRanges(input, isAllDay, framingRange, calendar)
-
-  return sliceEventRanges(eventRanges, framingRange)
-}
-
-
-export function buildBusinessHourEventRanges(
-  input: BusinessHourDef,
-  isAllDay: boolean,
-  framingRange: UnzonedRange,
-  calendar: Calendar
-): EventRenderRange[] {
+): EventStore {
   let eventInputs = refineEventInputs(input, isAllDay)
-  let eventRanges: EventRenderRange[] = []
+  let eventStore: EventStore = {
+    defs: {},
+    instances: {}
+  }
 
   for (let eventInput of eventInputs) {
-    let ranges = expandRecurring(eventInput, framingRange, calendar).ranges
     let def = parseDef(eventInput, null, isAllDay, true)
+    let ranges = expandRecurring(eventInput, framingRange, calendar).ranges
 
-    // if (!ranges.length) {
-    //   ranges.push(new UnzonedRange(framingRange.end, framingRange.end))
-    // }
+    eventStore.defs[def.defId] = def
 
     for (let range of ranges) {
       let instance = createInstance(def.defId, range)
 
-      eventRanges.push({
-        eventDef: def,
-        eventInstance: instance,
-        range
-      })
+      eventStore.instances[instance.instanceId] = instance
     }
   }
 
-  return eventRanges
+  return eventStore
 }
 
 

+ 49 - 40
src/reducers/event-rendering.ts

@@ -1,70 +1,79 @@
 import UnzonedRange from '../models/UnzonedRange'
-import { EventDef, EventInstance } from './event-store'
+import { EventStore, EventDef, EventInstance } from './event-store'
 
 export interface EventRenderRange {
   eventDef: EventDef
-  eventInstance: EventInstance
+  eventInstance?: EventInstance
   range: UnzonedRange
 }
 
 
-export function sliceEventRanges(origRanges: EventRenderRange[], windowRange: UnzonedRange): EventRenderRange[] {
+export function sliceEventStore(eventStore: EventStore, windowRange: UnzonedRange) {
+  let inverseBgByGroupId: { [groupId: string]: UnzonedRange[] } = {}
+  let inverseBgByDefId: { [defId: string]: UnzonedRange[] } = {}
+  let defByGroupId: { [groupId: string]: EventDef } = {}
   let renderRanges: EventRenderRange[] = []
-  let inverseBgGroups: { [groupId: string]: EventRenderRange[] } = {}
 
-  for (let origRange of origRanges) {
-    let { eventDef, eventInstance } = origRange
+  for (let defId in eventStore.defs) {
+    let def = eventStore.defs[defId]
 
-    if (eventDef.rendering === 'inverse-background') {
-      let groupId = eventDef.groupId
+    if (def.rendering === 'inverse-background') {
+      if (def.groupId) {
+        inverseBgByGroupId[def.groupId] = []
 
-      if (groupId) {
-        (inverseBgGroups[groupId] || (inverseBgGroups[groupId] = []))
-          .push(origRange)
-
-      } else {
-        let invertedRanges = UnzonedRange.invertRanges([ eventInstance.range ], windowRange)
-
-        for (let invertedRange of invertedRanges) {
-          renderRanges.push({
-            eventDef,
-            eventInstance,
-            range: invertedRange
-          })
+        if (!defByGroupId[def.groupId]) {
+          defByGroupId[def.groupId] = def
         }
+      } else {
+        inverseBgByDefId[defId] = []
       }
-    } else {
-      let range = eventInstance.range.intersect(windowRange)
+    }
+  }
+
+  for (let instanceId in eventStore.instances) {
+    let instance = eventStore.instances[instanceId]
+    let def = eventStore.defs[instance.defId]
 
-      if (range) {
-        renderRanges.push({
-          eventDef,
-          eventInstance,
-          range
-        })
+    if (def.rendering === 'inverse-background') {
+      if (def.groupId) {
+        inverseBgByGroupId[def.groupId].push(instance.range)
+      } else {
+        inverseBgByDefId[instance.defId].push(instance.range)
       }
+    } else {
+      renderRanges.push({
+        eventDef: def,
+        eventInstance: instance,
+        range: instance.range
+      })
     }
   }
 
-  for (let groupId in inverseBgGroups) {
-    let inverseBgGroup = inverseBgGroups[groupId]
-    let { eventDef, eventInstance } = inverseBgGroup[0]
-    let origRanges = inverseBgGroup.map(getRange)
-    let invertedRanges = UnzonedRange.invertRanges(origRanges, windowRange)
+  for (let groupId in inverseBgByGroupId) {
+    let ranges = inverseBgByGroupId[groupId]
+    let invertedRanges = UnzonedRange.invertRanges(ranges, windowRange)
 
     for (let invertedRange of invertedRanges) {
+      let def = defByGroupId[groupId]
+
       renderRanges.push({
-        eventDef,
-        eventInstance,
+        eventDef: def,
         range: invertedRange
       })
     }
   }
 
-  return renderRanges
-}
+  for (let defId in inverseBgByDefId) {
+    let ranges = inverseBgByDefId[defId]
+    let invertedRanges = UnzonedRange.invertRanges(ranges, windowRange)
 
+    for (let invertedRange of invertedRanges) {
+      renderRanges.push({
+        eventDef: eventStore.defs[defId],
+        range: invertedRange
+      })
+    }
+  }
 
-function getRange(eventRange: EventRenderRange) {
-  return eventRange.range
+  return renderRanges
 }