Quellcode durchsuchen

move daytable generation into views

Adam Shaw vor 7 Jahren
Ursprung
Commit
1472c607e0

+ 17 - 3
src/agenda/AgendaView.ts

@@ -23,7 +23,7 @@ import { DateMarker } from '../datelib/marker'
 import DayTable from '../component/DayTable';
 import { ComponentContext } from '../component/Component';
 import { ViewSpec } from '../structs/view-spec';
-import DateProfileGenerator from '../DateProfileGenerator';
+import DateProfileGenerator, { DateProfile } from '../DateProfileGenerator';
 
 const AGENDA_ALL_DAY_EVENT_LIMIT = 5
 const WEEK_HEADER_FORMAT = createFormatter({ week: 'short' })
@@ -172,12 +172,15 @@ export default class AgendaView extends View {
       }
     }
 
+    let dayTable = this.buildDayTable(props.dateProfile)
+
     this.timeGrid.receiveProps(
       assignTo({}, props, {
         eventStore: this.filterEventsForTimeGrid(props.eventStore, props.eventUis),
         dateSelection: timedSelection,
         eventDrag: this.buildEventDragForTimeGrid(props.eventDrag),
-        eventResize: this.buildEventResizeForTimeGrid(props.eventResize)
+        eventResize: this.buildEventResizeForTimeGrid(props.eventResize),
+        dayTable
       })
     )
 
@@ -187,13 +190,24 @@ export default class AgendaView extends View {
           eventStore: this.filterEventsForDayGrid(props.eventStore, props.eventUis),
           dateSelection: allDaySeletion,
           eventDrag: this.buildEventDragForDayGrid(props.eventDrag),
-          eventResize: this.buildEventResizeForDayGrid(props.eventResize)
+          eventResize: this.buildEventResizeForDayGrid(props.eventResize),
+          dayTable
         })
       )
     }
   }
 
 
+  buildDayTable = reselector(function(this: AgendaView, dateProfile: DateProfile) {
+    return new DayTable(
+      dateProfile,
+      this.dateProfileGenerator,
+      this.isRtl,
+      false
+    )
+  }) as any
+
+
   /* Now Indicator
   ------------------------------------------------------------------------------------------------------------------*/
 

+ 16 - 18
src/agenda/TimeGrid.ts

@@ -39,7 +39,6 @@ export interface RenderProps {
 
 export default class TimeGrid extends StandardDateComponent {
 
-  dayTable: DayTable
   mirrorRenderer: any
   renderProps: RenderProps
 
@@ -100,7 +99,7 @@ export default class TimeGrid extends StandardDateComponent {
 
   // Slices up the given span (unzoned start/end with other misc data) into an array of segments
   rangeToSegs(range: DateRange): Seg[] {
-    let { dayTable } = this
+    let dayTable = (this.props as any).dayTable
 
     range = intersectRanges(range, this.props.dateProfile.validRange)
 
@@ -130,7 +129,7 @@ export default class TimeGrid extends StandardDateComponent {
 
 
   sliceRangeByTimes(range) {
-    let { dayTable } = this
+    let dayTable = (this.props as any).dayTable
     let segs = []
     let segRange
     let dayIndex
@@ -223,14 +222,7 @@ export default class TimeGrid extends StandardDateComponent {
   ------------------------------------------------------------------------------------------------------------------*/
 
 
-  renderDates(dateProfile) {
-    this.dayTable = new DayTable(
-      dateProfile,
-      this.view.dateProfileGenerator,
-      this.isRtl,
-      false
-    )
-
+  renderDates() {
     this.renderSlats()
     this.renderColumns()
   }
@@ -307,7 +299,8 @@ export default class TimeGrid extends StandardDateComponent {
 
 
   renderColumns() {
-    let { theme, dateEnv, dayTable} = this
+    let { theme, dateEnv } = this
+    let dayTable = (this.props as any).dayTable
     let { dayDates } = dayTable
     let dateProfile = this.props.dateProfile
 
@@ -325,7 +318,7 @@ export default class TimeGrid extends StandardDateComponent {
         dateProfile,
         dates: dayDates,
         datesRepDistinctDays: true,
-        renderIntroHtml: this.renderProps.renderHeadIntroHtml.bind(null, this.dayTable)
+        renderIntroHtml: this.renderProps.renderHeadIntroHtml.bind(null, dayTable)
       })
     }
 
@@ -363,6 +356,7 @@ export default class TimeGrid extends StandardDateComponent {
 
   // Renders the DOM that the view's content will live in
   renderContentSkeleton() {
+    let dayTable = (this.props as any).dayTable
     let parts = []
     let skeletonEl: HTMLElement
 
@@ -370,7 +364,7 @@ export default class TimeGrid extends StandardDateComponent {
       this.renderProps.renderIntroHtml()
     )
 
-    for (let i = 0; i < this.dayTable.colCnt; i++) {
+    for (let i = 0; i < dayTable.colCnt; i++) {
       parts.push(
         '<td>' +
           '<div class="fc-content-col">' +
@@ -414,10 +408,11 @@ export default class TimeGrid extends StandardDateComponent {
 
   // Given a flat array of segments, return an array of sub-arrays, grouped by each segment's col
   groupSegsByCol(segs) {
+    let dayTable = (this.props as any).dayTable
     let segsByCol = []
     let i
 
-    for (i = 0; i < this.dayTable.colCnt; i++) {
+    for (i = 0; i < dayTable.colCnt; i++) {
       segsByCol.push([])
     }
 
@@ -432,11 +427,12 @@ export default class TimeGrid extends StandardDateComponent {
   // Given segments grouped by column, insert the segments' elements into a parallel array of container
   // elements, each living within a column.
   attachSegsByCol(segsByCol, containerEls: HTMLElement[]) {
+    let dayTable = (this.props as any).dayTable
     let col
     let segs
     let i
 
-    for (col = 0; col < this.dayTable.colCnt; col++) { // iterate each column grouping
+    for (col = 0; col < dayTable.colCnt; col++) { // iterate each column grouping
       segs = segsByCol[col]
 
       for (i = 0; i < segs.length; i++) {
@@ -549,6 +545,7 @@ export default class TimeGrid extends StandardDateComponent {
 
   // For each segment in an array, computes and assigns its top and bottom properties
   computeSegVerticals(segs) {
+    let dayTable = (this.props as any).dayTable
     let eventMinHeight = this.opt('agendaEventMinHeight')
     let i
     let seg
@@ -556,7 +553,7 @@ export default class TimeGrid extends StandardDateComponent {
 
     for (i = 0; i < segs.length; i++) {
       seg = segs[i]
-      dayDate = this.dayTable.dayDates[seg.dayIndex]
+      dayDate = dayTable.dayDates[seg.dayIndex]
 
       seg.top = this.computeDateTop(seg.start, dayDate)
       seg.bottom = Math.max(
@@ -615,6 +612,7 @@ export default class TimeGrid extends StandardDateComponent {
 
   queryHit(leftOffset, topOffset): Hit {
     let { dateEnv, snapsPerSlot, slatPositions, colPositions, offsetTracker } = this
+    let dayTable = (this.props as any).dayTable
 
     if (offsetTracker.isWithinClipping(leftOffset, topOffset)) {
       let leftOrigin = offsetTracker.computeLeft()
@@ -629,7 +627,7 @@ export default class TimeGrid extends StandardDateComponent {
         let localSnapIndex = Math.floor(partial * snapsPerSlot) // the snap # relative to start of slat
         let snapIndex = slatIndex * snapsPerSlot + localSnapIndex
 
-        let dayDate = this.dayTable.getCellDate(0, colIndex) // row=0
+        let dayDate = dayTable.getCellDate(0, colIndex) // row=0
         let time = addDurations(
           this.props.dateProfile.minTime,
           multiplyDuration(this.snapDuration, snapIndex)

+ 2 - 2
src/agenda/TimeGridEventRenderer.ts

@@ -49,7 +49,7 @@ export default class TimeGridEventRenderer extends FgEventRenderer {
 
   computeSizes() {
     let { timeGrid, segsByCol } = this
-    let colCnt = timeGrid.dayTable.colCnt
+    let colCnt = (timeGrid.props as any).dayTable.colCnt
 
     if (segsByCol) {
       for (let col = 0; col < colCnt; col++) {
@@ -64,7 +64,7 @@ export default class TimeGridEventRenderer extends FgEventRenderer {
 
   assignSizes() {
     let { timeGrid, segsByCol } = this
-    let colCnt = timeGrid.dayTable.colCnt
+    let colCnt = (timeGrid.props as any).dayTable.colCnt
 
     if (segsByCol) {
       for (let col = 0; col < colCnt; col++) {

+ 15 - 2
src/basic/BasicView.ts

@@ -19,7 +19,8 @@ import { assignTo } from '../util/object'
 import DayTable from '../component/DayTable';
 import { ComponentContext } from '../component/Component'
 import { ViewSpec } from '../structs/view-spec'
-import DateProfileGenerator from '../DateProfileGenerator'
+import DateProfileGenerator, { DateProfile } from '../DateProfileGenerator'
+import reselector from '../util/reselector';
 
 const WEEK_NUM_FORMAT = createFormatter({ week: 'numeric' })
 
@@ -96,14 +97,26 @@ export default class BasicView extends View {
   render(props: StandardDateComponentProps) {
     super.render(props)
 
+    let dayTable = this.buildDayTable(props.dateProfile)
+
     this.dayGrid.receiveProps(
       assignTo({}, props, {
-        breakOnWeeks: /year|month|week/.test(props.dateProfile.currentRangeUnit)
+        dayTable
       })
     )
   }
 
 
+  buildDayTable = reselector(function(this: BasicView, dateProfile: DateProfile) {
+    return new DayTable(
+      dateProfile,
+      this.dateProfileGenerator,
+      this.isRtl,
+      /year|month|week/.test(dateProfile.currentRangeUnit)
+    )
+  }) as any
+
+
   // Builds the HTML skeleton for the view.
   // The day-grid component will render inside of a container defined by this HTML.
   renderSkeletonHtml() {

+ 32 - 33
src/basic/DayGrid.ts

@@ -49,7 +49,6 @@ export interface RenderProps {
 
 export default class DayGrid extends StandardDateComponent {
 
-  dayTable: DayTable
   eventRenderer: DayGridEventRenderer
   renderProps: RenderProps
 
@@ -86,7 +85,7 @@ export default class DayGrid extends StandardDateComponent {
 
   // Slices up the given span (unzoned start/end with other misc data) into an array of segments
   rangeToSegs(range: DateRange): Seg[] {
-    let { dayTable } = this
+    let dayTable = (this.props as any).dayTable
 
     range = intersectRanges(range, this.props.dateProfile.validRange)
 
@@ -138,25 +137,8 @@ export default class DayGrid extends StandardDateComponent {
 
 
   renderDates(dateProfile) {
-    this.dayTable = new DayTable(
-      dateProfile,
-      this.view.dateProfileGenerator,
-      this.isRtl,
-      (this.props as any).breakOnWeeks // HACK
-    )
-
-    this.renderGrid()
-  }
-
-
-  unrenderDates() {
-    this.removeSegPopover()
-  }
-
-
-  // Renders the rows and columns into the component's `this.el`, which should already be assigned.
-  renderGrid() {
-    let { view, dateEnv, dayTable } = this
+    let { view, dateEnv } = this
+    let dayTable = (this.props as any).dayTable
     let rowCnt = dayTable.rowCnt
     let colCnt = dayTable.colCnt
     let html = ''
@@ -167,10 +149,10 @@ export default class DayGrid extends StandardDateComponent {
       // TODO: destroy?
       let header = new DayTableHeader(this.context, this.headerContainerEl)
       header.receiveProps({
-        dateProfile: this.props.dateProfile,
+        dateProfile,
         dates: dayTable.dayDates.slice(0, dayTable.colCnt), // because might be mult rows
         datesRepDistinctDays: dayTable.rowCnt === 1,
-        renderIntroHtml: this.renderProps.renderHeadIntroHtml.bind(null, this.dayTable)
+        renderIntroHtml: this.renderProps.renderHeadIntroHtml.bind(null, dayTable)
       })
     }
 
@@ -211,10 +193,16 @@ export default class DayGrid extends StandardDateComponent {
   }
 
 
+  unrenderDates() {
+    this.removeSegPopover()
+  }
+
+
   // Generates the HTML for a single row, which is a div that wraps a table.
   // `row` is the row number.
   renderDayRowHtml(row, isRigid) {
-    let { theme, dayTable } = this
+    let { theme } = this
+    let dayTable = (this.props as any).dayTable
     let { daysPerRow } = dayTable
     let classes = [ 'fc-row', 'fc-week', theme.getClass('dayRow') ]
 
@@ -262,7 +250,9 @@ export default class DayGrid extends StandardDateComponent {
 
 
   getIsDayNumbersVisible() {
-    return this.dayTable.rowCnt > 1
+    let dayTable = (this.props as any).dayTable
+
+    return dayTable.rowCnt > 1
   }
 
 
@@ -271,7 +261,8 @@ export default class DayGrid extends StandardDateComponent {
 
 
   renderNumberTrHtml(row: number) {
-    let intro = this.renderProps.renderNumberIntroHtml(row, this.dayTable)
+    let dayTable = (this.props as any).dayTable
+    let intro = this.renderProps.renderNumberIntroHtml(row, dayTable)
 
     return '' +
       '<tr>' +
@@ -283,7 +274,7 @@ export default class DayGrid extends StandardDateComponent {
 
 
   renderNumberCellsHtml(row) {
-    let { dayTable } = this
+    let dayTable = (this.props as any).dayTable
     let htmls = []
     let col
     let date
@@ -355,9 +346,11 @@ export default class DayGrid extends StandardDateComponent {
 
 
   buildPositionCaches() {
+    let dayTable = (this.props as any).dayTable
+
     this.colPositions.build()
     this.rowPositions.build()
-    this.rowPositions.bottoms[this.dayTable.rowCnt - 1] += this.bottomCoordPadding // hack
+    this.rowPositions.bottoms[dayTable.rowCnt - 1] += this.bottomCoordPadding // hack
   }
 
 
@@ -376,7 +369,8 @@ export default class DayGrid extends StandardDateComponent {
 
 
   queryHit(leftOffset, topOffset): Hit {
-    let { colPositions, rowPositions, offsetTracker, dayTable } = this
+    let { colPositions, rowPositions, offsetTracker } = this
+    let dayTable = (this.props as any).dayTable
 
     if (offsetTracker.isWithinClipping(leftOffset, topOffset)) {
       let leftOrigin = offsetTracker.computeLeft()
@@ -411,7 +405,9 @@ export default class DayGrid extends StandardDateComponent {
 
 
   getCellEl(row, col) {
-    return this.cellEls[row * this.dayTable.colCnt + col]
+    let dayTable = (this.props as any).dayTable
+
+    return this.cellEls[row * dayTable.colCnt + col]
   }
 
 
@@ -512,6 +508,7 @@ export default class DayGrid extends StandardDateComponent {
   // `row` is the row number.
   // `levelLimit` is a number for the maximum (inclusive) number of levels allowed.
   limitRow(row, levelLimit) {
+    let dayTable = (this.props as any).dayTable
     let rowStruct = this.eventRenderer.rowStructs[row]
     let moreNodes = [] // array of "more" <a> links and <td> DOM nodes
     let col = 0 // col #, left-to-right (not chronologically)
@@ -597,7 +594,7 @@ export default class DayGrid extends StandardDateComponent {
         }
       }
 
-      emptyCellsUntil(this.dayTable.colCnt) // finish off the level
+      emptyCellsUntil(dayTable.colCnt) // finish off the level
       rowStruct.moreEls = moreNodes // for easy undoing later
       rowStruct.limitedEls = limitedNodes // for easy undoing later
     }
@@ -627,12 +624,13 @@ export default class DayGrid extends StandardDateComponent {
   // Responsible for attaching click handler as well.
   renderMoreLink(row, col, hiddenSegs) {
     let { view, dateEnv } = this
+    let dayTable = (this.props as any).dayTable
 
     let a = createElement('a', { className: 'fc-more' })
     a.innerText = this.getMoreLinkText(hiddenSegs.length)
     a.addEventListener('click', (ev) => {
       let clickOption = this.opt('eventLimitClick')
-      let date = this.dayTable.getCellDate(row, col)
+      let date = dayTable.getCellDate(row, col)
       let moreEl = ev.currentTarget as HTMLElement
       let dayEl = this.getCellEl(row, col)
       let allSegs = this.getCellSegs(row, col)
@@ -670,7 +668,8 @@ export default class DayGrid extends StandardDateComponent {
 
   // Reveals the popover that displays all events within a cell
   showSegPopover(row, col, moreLink: HTMLElement, segs) {
-    let { calendar, view, theme, dayTable } = this
+    let { calendar, view, theme } = this
+    let dayTable = (this.props as any).dayTable
     let moreWrap = moreLink.parentNode as HTMLElement // the <div> wrapper around the <a>
     let topEl: HTMLElement // the element we want to match the top coordinate of
     let options

+ 6 - 3
src/basic/DayGridEventRenderer.ts

@@ -72,7 +72,7 @@ export default class DayGridEventRenderer extends SimpleDayGridEventRenderer {
   // NOTE: modifies rowSegs
   renderSegRow(row, rowSegs) {
     let { dayGrid } = this
-    let colCnt = dayGrid.dayTable.colCnt
+    let colCnt = (dayGrid.props as any).dayTable.colCnt
     let segLevels = this.buildSegLevels(rowSegs) // group into sub-arrays of levels
     let levelCnt = Math.max(1, segLevels.length) // ensure at least one level
     let tbody = document.createElement('tbody')
@@ -203,10 +203,11 @@ export default class DayGridEventRenderer extends SimpleDayGridEventRenderer {
 
   // Given a flat array of segments, return an array of sub-arrays, grouped by each segment's row
   groupSegRows(segs: Seg[]) {
+    let dayTable = (this.dayGrid.props as any).dayTable
     let segRows = []
     let i
 
-    for (i = 0; i < this.dayGrid.dayTable.rowCnt; i++) {
+    for (i = 0; i < dayTable.rowCnt; i++) {
       segRows.push([])
     }
 
@@ -220,7 +221,9 @@ export default class DayGridEventRenderer extends SimpleDayGridEventRenderer {
 
   // Computes a default `displayEventEnd` value if one is not expliclty defined
   computeDisplayEventEnd() {
-    return this.dayGrid.dayTable.colCnt === 1 // we'll likely have space if there's only one day
+    let dayTable = (this.dayGrid.props as any).dayTable
+
+    return dayTable.colCnt === 1 // we'll likely have space if there's only one day
   }
 
 }

+ 1 - 1
src/basic/DayGridFillRenderer.ts

@@ -34,7 +34,7 @@ export default class DayGridFillRenderer extends FillRenderer {
   // Generates the HTML needed for one row of a fill. Requires the seg's el to be rendered.
   renderFillRow(type, seg: Seg): HTMLElement {
     let { dayGrid } = this
-    let colCnt = dayGrid.dayTable.colCnt
+    let colCnt = (dayGrid.props as any).dayTable.colCnt
     let startCol = seg.leftCol
     let endCol = seg.rightCol + 1
     let className

+ 1 - 1
src/basic/MonthView.ts

@@ -14,7 +14,7 @@ export default class MonthView extends BasicView {
 
     // if auto, make the height of each row the height that it would be if there were 6 weeks
     if (isAuto) {
-      height *= this.dayGrid.dayTable.rowCnt / 6
+      height *= (this.dayGrid.props as any).dayTable.rowCnt / 6
     }
 
     distributeHeight(this.dayGrid.rowEls, height, !isAuto) // if auto, don't compensate for height-hogging rows