import { __assign } from 'tslib' ; import { EventStore , createEmptyEventStore } from '../structs/event-store' ; import { EventDef } from '../structs/event-def' ; import { EventInteractionState } from '../interactions/event-interaction-state' ; import { mapHash } from '../util/object' ; import { memoize } from '../util/memoize' ; import { EventUiHash , EventUi , combineEventUis } from './event-ui' ; import { DateSpan } from '../structs/date-span' ; export interface SplittableProps { businessHours : EventStore | null ; dateSelection : DateSpan | null ; eventStore : EventStore ; eventUiBases : EventUiHash ; eventSelection : string ; eventDrag : EventInteractionState | null ; eventResize : EventInteractionState | null ; } const EMPTY_EVENT_STORE = createEmptyEventStore ( ) ; export abstract class Splitter < PropsType extends SplittableProps = SplittableProps > { private getKeysForEventDefs = memoize ( this . _getKeysForEventDefs ) ; private splitDateSelection = memoize ( this . _splitDateSpan ) ; private splitEventStore = memoize ( this . _splitEventStore ) ; private splitIndividualUi = memoize ( this . _splitIndividualUi ) ; private splitEventDrag = memoize ( this . _splitInteraction ) ; private splitEventResize = memoize ( this . _splitInteraction ) ; private eventUiBuilders = { } ; abstract getKeyInfo ( props ) ; abstract getKeysForDateSpan ( dateSpan ) ; abstract getKeysForEventDef ( eventDef ) ; splitProps ( props ) { let keyInfos = this . getKeyInfo ( props ) ; let defKeys = this . getKeysForEventDefs ( props . eventStore ) ; let dateSelections = this . splitDateSelection ( props . dateSelection ) ; let individualUi = this . splitIndividualUi ( props . eventUiBases , defKeys ) ; let eventStores = this . splitEventStore ( props . eventStore , defKeys ) ; let eventDrags = this . splitEventDrag ( props . eventDrag ) ; let eventResizes = this . splitEventResize ( props . eventResize ) ; let splitProps = { } ; this . eventUiBuilders = mapHash ( keyInfos , ( info , key ) => this . eventUiBuilders [ key ] || memoize ( buildEventUiForKey ) ) ; for ( let key in keyInfos ) { let keyInfo = keyInfos [ key ] ; let eventStore = eventStores [ key ] || EMPTY_EVENT_STORE ; let buildEventUi = this . eventUiBuilders [ key ] ; splitProps [ key ] = { businessHours : keyInfo . businessHours || props . businessHours , dateSelection : dateSelections [ key ] || null , eventStore , eventUiBases : buildEventUi ( props . eventUiBases [ '' ] , keyInfo . ui , individualUi [ key ] ) , eventSelection : eventStore . instances [ props . eventSelection ] ? props . eventSelection : '' , eventDrag : eventDrags [ key ] || null , eventResize : eventResizes [ key ] || null , } ; } return splitProps ; } private _splitDateSpan ( dateSpan ) { let dateSpans = { } ; if ( dateSpan ) { let keys = this . getKeysForDateSpan ( dateSpan ) ; for ( let key of keys ) { dateSpans [ key ] = dateSpan ; } } return dateSpans ; } private _getKeysForEventDefs ( eventStore ) { return mapHash ( eventStore . defs , ( eventDef ) => this . getKeysForEventDef ( eventDef ) ) ; } private _splitEventStore ( eventStore , defKeys ) { let { defs , instances } = eventStore ; let splitStores = { } ; for ( let defId in defs ) { for ( let key of defKeys [ defId ] ) { if ( ! splitStores [ key ] ) { splitStores [ key ] = createEmptyEventStore ( ) ; } splitStores [ key ] . defs [ defId ] = defs [ defId ] ; } } for ( let instanceId in instances ) { let instance = instances [ instanceId ] ; for ( let key of defKeys [ instance . defId ] ) { if ( splitStores [ key ] ) { splitStores [ key ] . instances [ instanceId ] = instance ; } } } return splitStores ; } private _splitIndividualUi ( eventUiBases , defKeys ) { let splitHashes = { } ; for ( let defId in eventUiBases ) { if ( defId ) { for ( let key of defKeys [ defId ] ) { if ( ! splitHashes [ key ] ) { splitHashes [ key ] = { } ; } splitHashes [ key ] [ defId ] = eventUiBases [ defId ] ; } } } return splitHashes ; } private _splitInteraction ( interaction ) { let splitStates = { } ; if ( interaction ) { let affectedStores = this . _splitEventStore ( interaction . affectedEvents , this . _getKeysForEventDefs ( interaction . affectedEvents ) ) ; let mutatedKeysByDefId = this . _getKeysForEventDefs ( interaction . mutatedEvents ) ; let mutatedStores = this . _splitEventStore ( interaction . mutatedEvents , mutatedKeysByDefId ) ; let populate = ( key ) => { if ( ! splitStates [ key ] ) { splitStates [ key ] = { affectedEvents : affectedStores [ key ] || EMPTY_EVENT_STORE , mutatedEvents : mutatedStores [ key ] || EMPTY_EVENT_STORE , isEvent : interaction . isEvent , } ; } } ; for ( let key in affectedStores ) { populate ( key ) ; } for ( let key in mutatedStores ) { populate ( key ) ; } } return splitStates ; } } function buildEventUiForKey ( allUi , eventUiForKey , individualUi ) { let baseParts = [ ] ; if ( allUi ) { baseParts . push ( allUi ) ; } if ( eventUiForKey ) { baseParts . push ( eventUiForKey ) ; } let stuff = { '' : combineEventUis ( baseParts ) , } ; if ( individualUi ) { __assign ( stuff , individualUi ) ; } return stuff ; }