Parcourir la source

isLoading refactoring. fixes #5896. solves #5729

Adam Shaw il y a 5 ans
Parent
commit
386b30301b

+ 1 - 1
packages-premium

@@ -1 +1 @@
-Subproject commit 82adef6b8997917ea5417864110c5512c71f847c
+Subproject commit 74fc4e7bd892d3eedcfce91a9518cfc93b070f9f

+ 5 - 0
packages/common/src/global-plugins.ts

@@ -9,6 +9,8 @@ import { handleDateProfile } from './dates-set'
 import { handleEventStore } from './event-crud'
 import { isArraysEqual } from './util/array'
 import { removeElement } from './util/dom-manip'
+import { computeEventSourcesLoading } from './reducers/eventSources'
+import { CalendarDataManagerState } from './reducers/data-types'
 
 /*
 this array is exposed on the root namespace so that UMD plugins can add to it.
@@ -21,6 +23,9 @@ export const globalPlugins: PluginDef[] = [ // TODO: make a const?
   simpleRecurringEventsPlugin,
   changeHandlerPlugin,
   createPlugin({ // misc...
+    isLoadingFuncs: [
+      (state: CalendarDataManagerState) => computeEventSourcesLoading(state.eventSources),
+    ],
     contentTypeHandlers: {
       html: () => ({ render: injectHtml }),
       domNodes: () => ({ render: injectDomNodes }),

+ 3 - 1
packages/common/src/plugin-system-struct.ts

@@ -21,7 +21,7 @@ import { ElementDraggingClass } from './interactions/ElementDragging'
 import { ComponentChildren } from './vdom'
 import { ScrollGridImpl } from './scrollgrid/ScrollGridImpl'
 import { ContentTypeHandlers } from './common/render-hook'
-import { GenericRefiners, GenericListenerRefiners } from './options'
+import { GenericRefiners, GenericListenerRefiners, Dictionary } from './options'
 import { CalendarData } from './reducers/data-types'
 
 // TODO: easier way to add new hooks? need to update a million things
@@ -29,6 +29,7 @@ import { CalendarData } from './reducers/data-types'
 export interface PluginDefInput {
   deps?: PluginDef[]
   reducers?: ReducerFunc[]
+  isLoadingFuncs?: ((state: Dictionary) => boolean)[]
   contextInit?: (context: CalendarContext) => void
   eventRefiners?: GenericRefiners // why not an array like others?
   eventDefMemberAdders?: EventDefMemberAdder[]
@@ -65,6 +66,7 @@ export interface PluginDefInput {
 
 export interface PluginHooks {
   reducers: ReducerFunc[]
+  isLoadingFuncs: ((state: Dictionary) => boolean)[]
   contextInit: ((context: CalendarContext) => void)[]
   eventRefiners: GenericRefiners
   eventDefMemberAdders: EventDefMemberAdder[]

+ 3 - 0
packages/common/src/plugin-system.ts

@@ -9,6 +9,7 @@ export function createPlugin(input: PluginDefInput): PluginDef {
     id: guid(),
     deps: input.deps || [],
     reducers: input.reducers || [],
+    isLoadingFuncs: input.isLoadingFuncs || [],
     contextInit: [].concat(input.contextInit || []),
     eventRefiners: input.eventRefiners || {},
     eventDefMemberAdders: input.eventDefMemberAdders || [],
@@ -48,6 +49,7 @@ function buildPluginHooks(pluginDefs: PluginDef[], globalDefs: PluginDef[]): Plu
   let isAdded: { [pluginId: string]: boolean } = {}
   let hooks: PluginHooks = {
     reducers: [],
+    isLoadingFuncs: [],
     contextInit: [],
     eventRefiners: {},
     eventDefMemberAdders: [],
@@ -119,6 +121,7 @@ export function buildBuildPluginHooks() { // memoizes
 function combineHooks(hooks0: PluginHooks, hooks1: PluginHooks): PluginHooks {
   return {
     reducers: hooks0.reducers.concat(hooks1.reducers),
+    isLoadingFuncs: hooks0.isLoadingFuncs.concat(hooks1.isLoadingFuncs),
     contextInit: hooks0.contextInit.concat(hooks1.contextInit),
     eventRefiners: { ...hooks0.eventRefiners, ...hooks1.eventRefiners },
     eventDefMemberAdders: hooks0.eventDefMemberAdders.concat(hooks1.eventDefMemberAdders),

+ 19 - 11
packages/common/src/reducers/CalendarDataManager.ts

@@ -15,7 +15,7 @@ import { reduceViewType } from './view-type'
 import { getInitialDate, reduceCurrentDate } from './current-date'
 import { reduceDynamicOptionOverrides } from './options'
 import { reduceDateProfile } from './date-profile'
-import { reduceEventSources, initEventSources, reduceEventSourcesNewTimeZone, computeEventSourceLoadingLevel } from './eventSources'
+import { reduceEventSources, initEventSources, reduceEventSourcesNewTimeZone, computeEventSourcesLoading } from './eventSources'
 import { reduceEventStore, rezoneEventStoreDates } from './eventStore'
 import { reduceDateSelection } from './date-selection'
 import { reduceSelectedEvent } from './selected-event'
@@ -147,7 +147,6 @@ export class CalendarDataManager {
       businessHours: this.parseContextBusinessHours(calendarContext), // weird to have this in state
       eventSources,
       eventUiBases: {},
-      loadingLevel: computeEventSourceLoadingLevel(eventSources),
       eventStore: createEmptyEventStore(),
       renderableEventStore: createEmptyEventStore(),
       dateSelection: null,
@@ -162,7 +161,7 @@ export class CalendarDataManager {
       __assign(initialState, reducer(null, null, contextAndState))
     }
 
-    if (initialState.loadingLevel) {
+    if (computeIsLoading(initialState, calendarContext)) {
       this.emitter.trigger('loading', true) // NOT DRY
     }
 
@@ -237,11 +236,11 @@ export class CalendarDataManager {
     }
 
     let eventSources = reduceEventSources(state.eventSources, action, dateProfile, calendarContext)
-    let eventSourceLoadingLevel = computeEventSourceLoadingLevel(eventSources)
     let eventStore = reduceEventStore(state.eventStore, action, eventSources, dateProfile, calendarContext)
+    let isEventsLoading = computeEventSourcesLoading(eventSources) // BAD. also called in this func in computeIsLoading
 
     let renderableEventStore =
-      (eventSourceLoadingLevel && !currentViewData.options.progressiveEventRendering) ?
+      (isEventsLoading && !currentViewData.options.progressiveEventRendering) ?
         (state.renderableEventStore || eventStore) : // try from previous state
         eventStore
 
@@ -249,9 +248,6 @@ export class CalendarDataManager {
     let eventUiBySource = this.buildEventUiBySource(eventSources)
     let eventUiBases = this.buildEventUiBases(renderableEventStore.defs, eventUiSingleBase, eventUiBySource)
 
-    let prevLoadingLevel = state.loadingLevel || 0
-    let loadingLevel = eventSourceLoadingLevel
-
     let newState: CalendarDataManagerState = {
       dynamicOptionOverrides,
       currentViewType,
@@ -262,7 +258,6 @@ export class CalendarDataManager {
       renderableEventStore,
       selectionConfig,
       eventUiBases,
-      loadingLevel,
       businessHours: this.parseContextBusinessHours(calendarContext), // will memoize obj
       dateSelection: reduceDateSelection(state.dateSelection, action),
       eventSelection: reduceSelectedEvent(state.eventSelection, action),
@@ -275,10 +270,13 @@ export class CalendarDataManager {
       __assign(newState, reducer(state, action, contextAndState)) // give the OLD state, for old value
     }
 
+    let wasLoading = computeIsLoading(state, calendarContext)
+    let isLoading = computeIsLoading(newState, calendarContext)
+
     // TODO: use propSetHandlers in plugin system
-    if (!prevLoadingLevel && loadingLevel) {
+    if (!wasLoading && isLoading) {
       emitter.trigger('loading', true)
-    } else if (prevLoadingLevel && !loadingLevel) {
+    } else if (wasLoading && !isLoading) {
       emitter.trigger('loading', false)
     }
 
@@ -646,6 +644,16 @@ function buildViewUiProps(calendarContext: CalendarContext) {
   }
 }
 
+function computeIsLoading(state: CalendarDataManagerState, context: CalendarContext) {
+  for (let isLoadingFunc of context.pluginHooks.isLoadingFuncs) {
+    if (isLoadingFunc(state)) {
+      return true
+    }
+  }
+
+  return false
+}
+
 function parseContextBusinessHours(calendarContext: CalendarContext) {
   return parseBusinessHours(calendarContext.options.businessHours, calendarContext)
 }

+ 0 - 1
packages/common/src/reducers/data-types.ts

@@ -23,7 +23,6 @@ export interface CalendarDataManagerState {
   businessHours: EventStore
   eventSources: EventSourceHash
   eventUiBases: EventUiHash
-  loadingLevel: number
   eventStore: EventStore
   renderableEventStore: EventStore
   dateSelection: DateSpan | null

+ 3 - 5
packages/common/src/reducers/eventSources.ts

@@ -76,16 +76,14 @@ export function reduceEventSourcesNewTimeZone(eventSources: EventSourceHash, dat
   )
 }
 
-export function computeEventSourceLoadingLevel(eventSources: EventSourceHash): number {
-  let cnt = 0
-
+export function computeEventSourcesLoading(eventSources: EventSourceHash): boolean {
   for (let sourceId in eventSources) {
     if (eventSources[sourceId].isFetching) {
-      cnt += 1
+      return true
     }
   }
 
-  return cnt
+  return false
 }
 
 function addSources(