Переглянути джерело

no more InteractiveDateComponent

Adam Shaw 7 роки тому
батько
коміт
fab483742d

+ 2 - 2
src/View.ts

@@ -2,7 +2,7 @@ import { assignTo } from './util/object'
 import { parseFieldSpecs } from './util/misc'
 import Calendar from './Calendar'
 import { default as DateProfileGenerator, DateProfile } from './DateProfileGenerator'
-import InteractiveDateComponent from './component/InteractiveDateComponent'
+import DateComponent from './component/DateComponent'
 import UnzonedRange from './models/UnzonedRange'
 import { DateMarker, addDays, addMs, diffWholeDays } from './datelib/marker'
 import { createDuration } from './datelib/duration'
@@ -13,7 +13,7 @@ import { default as EmitterMixin, EmitterInterface } from './common/EmitterMixin
 /* An abstract class from which other views inherit from
 ----------------------------------------------------------------------------------------------------------------------*/
 
-export default abstract class View extends InteractiveDateComponent {
+export default abstract class View extends DateComponent {
 
   on: EmitterInterface['on']
   one: EmitterInterface['one']

+ 4 - 3
src/agenda/TimeGrid.ts

@@ -1,6 +1,5 @@
 import { htmlEscape } from '../util/html'
 import { htmlToElement, findElements, createElement, removeElement, applyStyle } from '../util/dom-manip'
-import InteractiveDateComponent from '../component/InteractiveDateComponent'
 import BusinessHourRenderer from '../component/renderers/BusinessHourRenderer'
 import { default as DayTableMixin, DayTableInterface } from '../component/DayTableMixin'
 import CoordCache from '../common/CoordCache'
@@ -11,7 +10,7 @@ import TimeGridFillRenderer from './TimeGridFillRenderer'
 import { Duration, createDuration, addDurations, multiplyDuration, wholeDivideDurations, asRoughMs } from '../datelib/duration'
 import { startOfDay, DateMarker, addMs } from '../datelib/marker'
 import { DateFormatter, createFormatter, formatIsoTimeString } from '../datelib/formatting'
-import { Seg } from '../component/DateComponent'
+import DateComponent, { Seg } from '../component/DateComponent'
 import { Selection } from '../reducers/selection'
 import { EventStore } from '../reducers/event-store'
 
@@ -29,7 +28,7 @@ const AGENDA_STOCK_SUB_DURATIONS = [
   { seconds: 15 }
 ]
 
-export default class TimeGrid extends InteractiveDateComponent {
+export default class TimeGrid extends DateComponent {
 
   dayDates: DayTableInterface['dayDates']
   daysPerRow: DayTableInterface['daysPerRow']
@@ -40,6 +39,8 @@ export default class TimeGrid extends InteractiveDateComponent {
   bookendCells: DayTableInterface['bookendCells']
   getCellDate: DayTableInterface['getCellDate']
 
+  isInteractable = true
+
   view: any // TODO: make more general and/or remove
   helperRenderer: any
 

+ 3 - 3
src/agenda/TimeGridEventRenderer.ts

@@ -73,9 +73,9 @@ export default class TimeGridEventRenderer extends EventRenderer {
     let eventRange = seg.eventRange
     let eventDef = eventRange.eventDef
     let isAllDay = eventDef.isAllDay
-    let isDraggable = view.isEventDefDraggable(eventDef)
-    let isResizableFromStart = !disableResizing && seg.isStart && view.isEventDefResizableFromStart(eventDef)
-    let isResizableFromEnd = !disableResizing && seg.isEnd && view.isEventDefResizableFromEnd(eventDef)
+    let isDraggable = this.isEventDefDraggable(eventDef)
+    let isResizableFromStart = !disableResizing && seg.isStart && this.isEventDefResizableFromStart(eventDef)
+    let isResizableFromEnd = !disableResizing && seg.isEnd && this.isEventDefResizableFromEnd(eventDef)
     let classes = this.getSegClasses(seg, isDraggable, isResizableFromStart || isResizableFromEnd)
     let skinCss = cssToStr(this.getSkinCss(eventDef))
     let timeText

+ 4 - 3
src/basic/DayGrid.ts

@@ -14,14 +14,13 @@ import CoordCache from '../common/CoordCache'
 import Popover from '../common/Popover'
 import UnzonedRange from '../models/UnzonedRange'
 import BusinessHourRenderer from '../component/renderers/BusinessHourRenderer'
-import InteractiveDateComponent from '../component/InteractiveDateComponent'
 import { default as DayTableMixin, DayTableInterface } from '../component/DayTableMixin'
 import DayGridEventRenderer from './DayGridEventRenderer'
 import DayGridHelperRenderer from './DayGridHelperRenderer'
 import DayGridFillRenderer from './DayGridFillRenderer'
 import { addDays } from '../datelib/marker'
 import { createFormatter } from '../datelib/formatting'
-import { Seg } from '../component/DateComponent'
+import DateComponent, { Seg } from '../component/DateComponent'
 import { EventStore } from '../reducers/event-store'
 import { Selection } from '../reducers/selection'
 
@@ -32,7 +31,7 @@ const WEEK_NUM_FORMAT = createFormatter({ week: 'numeric' })
 /* A component that renders a grid of whole-days that runs horizontally. There can be multiple rows, one per week.
 ----------------------------------------------------------------------------------------------------------------------*/
 
-export default class DayGrid extends InteractiveDateComponent {
+export default class DayGrid extends DateComponent {
 
   rowCnt: DayTableInterface['rowCnt']
   colCnt: DayTableInterface['colCnt']
@@ -48,6 +47,8 @@ export default class DayGrid extends InteractiveDateComponent {
   bookendCells: DayTableInterface['bookendCells']
   breakOnWeeks: DayTableInterface['breakOnWeeks']
 
+  isInteractable = true
+
   view: View // TODO: make more general and/or remove
   helperRenderer: any
 

+ 3 - 4
src/basic/DayGridEventRenderer.ts

@@ -237,15 +237,14 @@ export default class DayGridEventRenderer extends EventRenderer {
 
   // Builds the HTML to be used for the default element for an individual segment
   fgSegHtml(seg: Seg, disableResizing) {
-    let view = this.view
     let eventRange = seg.eventRange
     let eventDef = eventRange.eventDef
     let isAllDay = eventDef.isAllDay
-    let isDraggable = view.isEventDefDraggable(eventDef)
+    let isDraggable = this.isEventDefDraggable(eventDef)
     let isResizableFromStart = !disableResizing && isAllDay &&
-      seg.isStart && view.isEventDefResizableFromStart(eventDef)
+      seg.isStart && this.isEventDefResizableFromStart(eventDef)
     let isResizableFromEnd = !disableResizing && isAllDay &&
-      seg.isEnd && view.isEventDefResizableFromEnd(eventDef)
+      seg.isEnd && this.isEventDefResizableFromEnd(eventDef)
     let classes = this.getSegClasses(seg, isDraggable, isResizableFromStart || isResizableFromEnd)
     let skinCss = cssToStr(this.getSkinCss(eventDef))
     let timeHtml = ''

+ 5 - 5
src/common/GlobalContext.ts

@@ -1,4 +1,4 @@
-import InteractiveDateComponent from '../component/InteractiveDateComponent'
+import DateComponent from '../component/DateComponent'
 import DateClicking from '../interactions/DateClicking'
 import DateSelecting from '../interactions/DateSelecting'
 import EventClicking from '../interactions/EventClicking'
@@ -11,7 +11,7 @@ export default {
 
   // TODO: event hovering
 
-  registerComponent(component: InteractiveDateComponent) {
+  registerComponent(component: DateComponent) {
     componentHash[component.uid] = component
     componentCnt++
 
@@ -22,7 +22,7 @@ export default {
     this.bindComponent(component)
   },
 
-  unregisterComponent(component: InteractiveDateComponent) {
+  unregisterComponent(component: DateComponent) {
     delete componentHash[component.uid]
     componentCnt--
 
@@ -41,14 +41,14 @@ export default {
     this.dateSelecting.destroy()
   },
 
-  bindComponent(component: InteractiveDateComponent) {
+  bindComponent(component: DateComponent) {
     listenerHash[component.uid] = {
       dateClicking: new DateClicking(component),
       eventClicking: new EventClicking(component)
     }
   },
 
-  unbindComponent(component: InteractiveDateComponent) {
+  unbindComponent(component: DateComponent) {
     let listeners = listenerHash[component.uid]
     listeners.dateClicking.destroy()
     listeners.eventClicking.destroy()

+ 52 - 2
src/component/DateComponent.ts

@@ -1,4 +1,5 @@
 import { attrsToStr, htmlEscape } from '../util/html'
+import { elementClosest } from '../util/dom-manip'
 import { default as Component, RenderForceFlags } from './Component'
 import Calendar from '../Calendar'
 import View from '../View'
@@ -14,6 +15,7 @@ import { DateEnv } from '../datelib/env'
 import Theme from '../theme/Theme'
 import { EventInteractionState } from '../reducers/event-interaction'
 import { assignTo } from '../util/object'
+import GlobalContext from '../common/GlobalContext'
 
 
 export interface DateComponentRenderState {
@@ -34,10 +36,21 @@ export interface Seg {
   [otherProp: string]: any
 }
 
+export type DateComponentHash = { [id: string]: DateComponent }
+
+let uid = 0
+
 
 export default abstract class DateComponent extends Component {
 
-  static guid: number = 0 // TODO: better system for this?
+  // self-config, overridable by subclasses
+  isInteractable: boolean = false
+  segSelector: string = '.fc-event-container > *' // what constitutes an event element?
+
+  // if defined, holds the unit identified (ex: "year" or "month") that determines the level of granularity
+  // of the date areas. if not defined, assumes to be day and time granularity.
+  // TODO: port isTimeScale into same system?
+  largeUnit: any
 
   eventRendererClass: any
   helperRendererClass: any
@@ -83,7 +96,7 @@ export default abstract class DateComponent extends Component {
       this['options'] = _options
     }
 
-    this.uid = String(DateComponent.guid++)
+    this.uid = String(uid++)
     this.childrenByUid = {}
 
     this.nextDayThreshold = createDuration(this.opt('nextDayThreshold'))
@@ -140,6 +153,29 @@ export default abstract class DateComponent extends Component {
   }
 
 
+  queryHit(leftOffset, topOffset): Selection {
+    return null // this should be abstract
+  }
+
+
+  buildCoordCaches() {
+  }
+
+
+  bindGlobalHandlers() {
+    if (this.isInteractable) {
+      GlobalContext.registerComponent(this)
+    }
+  }
+
+
+  unbindGlobalHandlers() {
+    if (this.isInteractable) {
+      GlobalContext.unregisterComponent(this)
+    }
+  }
+
+
   // Options
   // -----------------------------------------------------------------------------------------------------------------
 
@@ -869,4 +905,18 @@ export default abstract class DateComponent extends Component {
     return diffDays(dayRange.start, dayRange.end) > 1
   }
 
+
+  isValidSegInteraction(evTarget: HTMLElement) {
+    return !elementClosest(evTarget, '.fc-helper') &&
+      !this.dragState &&
+      !this.eventResizeState
+  }
+
+
+  isValidDateInteraction(evTarget: HTMLElement) {
+    return !elementClosest(evTarget, this.segSelector) &&
+      !elementClosest(evTarget, '.fc-more') && // a "more.." link
+      !elementClosest(evTarget, 'a[data-goto]') // a clickable nav link
+  }
+
 }

+ 0 - 96
src/component/InteractiveDateComponent.ts

@@ -1,96 +0,0 @@
-import { elementClosest } from '../util/dom-manip'
-import DateComponent from './DateComponent'
-import { Selection } from '../reducers/selection'
-import GlobalContext from '../common/GlobalContext'
-
-export type InteractiveDateComponentHash = {
-  [uid: string]: InteractiveDateComponent
-}
-
-export default abstract class InteractiveDateComponent extends DateComponent {
-
-  // self-config, overridable by subclasses
-  segSelector: string = '.fc-event-container > *' // what constitutes an event element?
-
-  // if defined, holds the unit identified (ex: "year" or "month") that determines the level of granularity
-  // of the date areas. if not defined, assumes to be day and time granularity.
-  // TODO: port isTimeScale into same system?
-  largeUnit: any
-
-
-  queryHit(leftOffset, topOffset): Selection {
-    return null // this should be abstract
-  }
-
-
-  buildCoordCaches() {
-  }
-
-
-  bindGlobalHandlers() {
-    GlobalContext.registerComponent(this)
-  }
-
-
-  unbindGlobalHandlers() {
-    GlobalContext.unregisterComponent(this)
-  }
-
-
-  isValidSegInteraction(evTarget: HTMLElement) {
-    return !elementClosest(evTarget, '.fc-helper') &&
-      !this.dragState &&
-      !this.eventResizeState
-  }
-
-
-  isValidDateInteraction(evTarget: HTMLElement) {
-    return !elementClosest(evTarget, this.segSelector) &&
-      !elementClosest(evTarget, '.fc-more') && // a "more.." link
-      !elementClosest(evTarget, 'a[data-goto]') // a clickable nav link
-  }
-
-
-  // Event Drag-n-Drop
-  // ---------------------------------------------------------------------------------------------------------------
-
-
-  // Computes if the given event is allowed to be dragged by the user
-  isEventDefDraggable(eventDef) {
-    return this.isEventDefStartEditable(eventDef)
-  }
-
-
-  isEventDefStartEditable(eventDef) {
-    return false // TODO
-  }
-
-
-  isEventDefGenerallyEditable(eventDef) {
-    return false // TODO
-  }
-
-
-
-  // Event Resizing
-  // ---------------------------------------------------------------------------------------------------------------
-
-
-  // Computes if the given event is allowed to be resized from its starting edge
-  isEventDefResizableFromStart(eventDef) {
-    return this.opt('eventResizableFromStart') && this.isEventDefResizable(eventDef)
-  }
-
-
-  // Computes if the given event is allowed to be resized from its ending edge
-  isEventDefResizableFromEnd(eventDef) {
-    return this.isEventDefResizable(eventDef)
-  }
-
-
-  // Computes if the given event is allowed to be resized by the user at all
-  isEventDefResizable(eventDef) {
-    return false // TODO
-  }
-
-}

+ 34 - 0
src/component/renderers/EventRenderer.ts

@@ -438,4 +438,38 @@ export default class EventRenderer {
       )
   }
 
+
+  // Computes if the given event is allowed to be dragged by the user
+  isEventDefDraggable(eventDef) {
+    return this.isEventDefStartEditable(eventDef)
+  }
+
+
+  isEventDefStartEditable(eventDef) {
+    return false // TODO
+  }
+
+
+  isEventDefGenerallyEditable(eventDef) {
+    return false // TODO
+  }
+
+
+  // Computes if the given event is allowed to be resized from its starting edge
+  isEventDefResizableFromStart(eventDef) {
+    return this.opt('eventResizableFromStart') && this.isEventDefResizable(eventDef)
+  }
+
+
+  // Computes if the given event is allowed to be resized from its ending edge
+  isEventDefResizableFromEnd(eventDef) {
+    return this.isEventDefResizable(eventDef)
+  }
+
+
+  // Computes if the given event is allowed to be resized by the user at all
+  isEventDefResizable(eventDef) {
+    return false // TODO
+  }
+
 }

+ 4 - 4
src/dnd/HitDragListener.ts

@@ -1,11 +1,11 @@
 import EmitterMixin from '../common/EmitterMixin'
 import { PointerDragEvent } from './PointerDragListener'
 import { default as IntentfulDragListener, IntentfulDragOptions } from './IntentfulDragListener'
-import InteractiveDateComponent from '../component/InteractiveDateComponent'
+import DateComponent from '../component/DateComponent'
 import { Selection } from '../reducers/selection'
 
 export interface Hit extends Selection {
-  component: InteractiveDateComponent
+  component: DateComponent
 }
 
 /*
@@ -17,14 +17,14 @@ fires:
 */
 export default class HitDragListener {
 
-  droppableComponents: InteractiveDateComponent[]
+  droppableComponents: DateComponent[]
   emitter: EmitterMixin
   dragListener: IntentfulDragListener
   initialHit: Hit
   movingHit: Hit
   finalHit: Hit // won't ever be populated if options.ignoreMove is false
 
-  constructor(options: IntentfulDragOptions, droppableComponents: InteractiveDateComponent[]) {
+  constructor(options: IntentfulDragOptions, droppableComponents: DateComponent[]) {
     this.droppableComponents = droppableComponents
     this.emitter = new EmitterMixin()
     this.dragListener = new IntentfulDragListener(options)

+ 0 - 1
src/exports.ts

@@ -79,7 +79,6 @@ export { default as CoordCache } from './common/CoordCache'
 export { default as Scroller } from './common/Scroller'
 export { default as Theme } from './theme/Theme'
 export { default as DateComponent } from './component/DateComponent'
-export { default as InteractiveDateComponent } from './component/InteractiveDateComponent'
 export { default as Calendar } from './Calendar'
 export { default as View } from './View'
 export { defineView, getViewConfig } from './ViewRegistry'

+ 3 - 3
src/interactions/DateClicking.ts

@@ -1,13 +1,13 @@
-import InteractiveDateComponent from '../component/InteractiveDateComponent'
+import DateComponent from '../component/DateComponent'
 import HitDragListener, { isHitsEqual } from '../dnd/HitDragListener'
 import { PointerDragEvent } from '../dnd/PointerDragListener'
 
 export default class DateClicking {
 
-  component: InteractiveDateComponent
+  component: DateComponent
   hitListener: HitDragListener
 
-  constructor(component: InteractiveDateComponent) {
+  constructor(component: DateComponent) {
     this.component = component
     this.hitListener = new HitDragListener({
       containerEl: component.el

+ 7 - 7
src/interactions/DateSelecting.ts

@@ -1,6 +1,6 @@
 import { compareNumbers } from '../util/misc'
 import { elementClosest } from '../util/dom-manip'
-import InteractiveDateComponent, { InteractiveDateComponentHash } from '../component/InteractiveDateComponent'
+import DateComponent, { DateComponentHash } from '../component/DateComponent'
 import HitDragListener, { Hit } from '../dnd/HitDragListener'
 import { Selection } from '../reducers/selection'
 import UnzonedRange from '../models/UnzonedRange'
@@ -8,15 +8,15 @@ import PointerDragListener, { PointerDragEvent } from '../dnd/PointerDragListene
 
 export default class DateSelecting {
 
-  componentHash: InteractiveDateComponentHash
+  componentHash: DateComponentHash
   pointerListener: PointerDragListener
   hitListener: HitDragListener
-  dragComponent: InteractiveDateComponent
+  dragComponent: DateComponent
   dragSelection: Selection
-  activeComponent: InteractiveDateComponent
+  activeComponent: DateComponent
   activeSelection: Selection
 
-  constructor(componentHash: InteractiveDateComponentHash) {
+  constructor(componentHash: DateComponentHash) {
     this.componentHash = componentHash
     this.pointerListener = new PointerDragListener(
       document as any, // TODO: better
@@ -56,7 +56,7 @@ export default class DateSelecting {
     }
   }
 
-  queryComponent(ev: PointerDragEvent): InteractiveDateComponent {
+  queryComponent(ev: PointerDragEvent): DateComponent {
     let componentEl = elementClosest(
       ev.origEvent.target as any, // TODO: better
       '[data-fc-com-uid]'
@@ -125,7 +125,7 @@ export default class DateSelecting {
     }
   }
 
-  setActiveSelection(component: InteractiveDateComponent, selection: Selection, ev: PointerDragEvent) {
+  setActiveSelection(component: DateComponent, selection: Selection, ev: PointerDragEvent) {
     this.clearActiveSelection(ev)
     this.activeComponent = component
     this.activeSelection = selection

+ 3 - 3
src/interactions/EventClicking.ts

@@ -1,12 +1,12 @@
-import InteractiveDateComponent from '../component/InteractiveDateComponent'
+import DateComponent from '../component/DateComponent'
 import { listenBySelector } from '../util/dom-event'
 
 export default class EventClicking {
 
-  component: InteractiveDateComponent
+  component: DateComponent
   destroy: () => void
 
-  constructor(component: InteractiveDateComponent) {
+  constructor(component: DateComponent) {
     this.component = component
     this.destroy = listenBySelector(component.el, 'click', component.segSelector, this.onSegClick)
   }