import React , { useEffect , useState } from 'react' ; import { cloneDeep , isEqual } from 'lodash' ; import { map } from 'rxjs/operators' ; import { EventEmitter } from 'events' ; import { i18n } from '@osd/i18n' ; import { MarkdownSimple , toMountPoint } from '../../../../../opensearch_dashboards_react/public' ; import { migrateLegacyQuery } from '../migrate_legacy_query' ; import { opensearchFilters , connectToQueryState } from '../../../../../data/public' ; import { VisualizeServices , VisualizeAppStateContainer , VisualizeEditorVisInstance , } from '../../types' ; import { visStateToEditorState } from '../utils' ; import { createVisualizeAppState } from '../create_visualize_app_state' ; import { VisualizeConstants } from '../../visualize_constants' ; /**
 * This effect is responsible for instantiating the visualize app state container,
 * which is in sync with "_a" url param
 */ export const useVisualizeAppState = ( services , eventEmitter , instance ? ) => { const [ hasUnappliedChanges , setHasUnappliedChanges ] = useState ( false ) ; const [ appState , setAppState ] = useState < VisualizeAppStateContainer | null > ( null ) ; useEffect ( ( ) => { if ( instance ) { const stateDefaults = visStateToEditorState ( instance , services ) ; const byValue = ! ( 'savedVis' in instance ) ; const { stateContainer , stopStateSync } = createVisualizeAppState ( { stateDefaults , osdUrlStateStorage : services . osdUrlStateStorage , byValue , } ) ; const onDirtyStateChange = ( { isDirty } ) => { if ( ! isDirty ) { stateContainer . transitions . updateVisState ( visStateToEditorState ( instance , services ) . vis ) ; } setHasUnappliedChanges ( isDirty ) ; } ; eventEmitter . on ( 'dirtyStateChange' , onDirtyStateChange ) ; const { filterManager , queryString } = services . data . query ; filterManager . setAppFilters ( cloneDeep ( stateContainer . getState ( ) . filters ) ) ; queryString . setQuery ( migrateLegacyQuery ( stateContainer . getState ( ) . query ) ) ; const stopSyncingAppFilters = connectToQueryState ( services . data . query , { set : ( { filters , query } ) => { stateContainer . transitions . set ( 'filters' , filters ) ; stateContainer . transitions . set ( 'query' , query ) ; } , get : ( ) => { return { filters : stateContainer . getState ( ) . filters , query : stateContainer . getState ( ) . query , } ; } , state$ : stateContainer . state$ . pipe ( map ( ( state ) => ( { filters : state . filters , query : state . query , } ) ) ) , } , { filters : opensearchFilters . FilterStateStore . APP_STATE , query : true , } ) ; if ( ! isEqual ( stateContainer . getState ( ) . vis , stateDefaults . vis ) ) { const { aggs , ... visState } = stateContainer . getState ( ) . vis ; instance . vis . setState ( { ... visState , data : { aggs } } ) . then ( ( ) => { setAppState ( stateContainer ) ; } ) . catch ( ( error ) => { services . toastNotifications . addWarning ( { title : i18n . translate ( 'visualize.visualizationLoadingFailedErrorMessage' , { defaultMessage : 'Failed to load the visualization' , } ) , text : toMountPoint ( < MarkdownSimple > { error . message } < /MarkdownSimple>), } ) ; services . history . replace ( `${ VisualizeConstants . LANDING_PAGE_PATH }?notFound=visualization` ) ; } ) ; } else { setAppState ( stateContainer ) ; } return ( ) => { eventEmitter . off ( 'dirtyStateChange' , onDirtyStateChange ) ; stopStateSync ( ) ; stopSyncingAppFilters ( ) ; } ; } } , [ eventEmitter , instance , services ] ) ; return { appState , hasUnappliedChanges } ; } ;