diff --git a/packages-premium b/packages-premium index 82adef6b89..74fc4e7bd8 160000 --- a/packages-premium +++ b/packages-premium @@ -1 +1 @@ -Subproject commit 82adef6b8997917ea5417864110c5512c71f847c +Subproject commit 74fc4e7bd892d3eedcfce91a9518cfc93b070f9f diff --git a/packages/common/src/global-plugins.ts b/packages/common/src/global-plugins.ts index 17a0f4fdb4..7e566324ec 100644 --- a/packages/common/src/global-plugins.ts +++ b/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 }), diff --git a/packages/common/src/plugin-system-struct.ts b/packages/common/src/plugin-system-struct.ts index 185a953e40..7905e372cc 100644 --- a/packages/common/src/plugin-system-struct.ts +++ b/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[] diff --git a/packages/common/src/plugin-system.ts b/packages/common/src/plugin-system.ts index 6a5f87feae..69762055bc 100644 --- a/packages/common/src/plugin-system.ts +++ b/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), diff --git a/packages/common/src/reducers/CalendarDataManager.ts b/packages/common/src/reducers/CalendarDataManager.ts index a0684b44a5..2384c99a7f 100644 --- a/packages/common/src/reducers/CalendarDataManager.ts +++ b/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) } diff --git a/packages/common/src/reducers/data-types.ts b/packages/common/src/reducers/data-types.ts index 00c8695a88..094b561cb9 100644 --- a/packages/common/src/reducers/data-types.ts +++ b/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 diff --git a/packages/common/src/reducers/eventSources.ts b/packages/common/src/reducers/eventSources.ts index dcf16543d8..18f70803d6 100644 --- a/packages/common/src/reducers/eventSources.ts +++ b/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(