import { BehaviorSubject } from 'rxjs' ; import { i18n } from '@osd/i18n' ; import { filter , map } from 'rxjs/operators' ; import { createHashHistory } from 'history' ; import { AppMountParameters , AppUpdater , CoreSetup , CoreStart , Plugin , PluginInitializerContext , ScopedHistory , } from 'opensearch-dashboards/public' ; import { Storage , createOsdUrlTracker , createOsdUrlStateStorage , withNotifyOnErrors , } from '../../opensearch_dashboards_utils/public' ; import { DataPublicPluginStart , DataPublicPluginSetup , opensearchFilters } from '../../data/public' ; import { NavigationPublicPluginStart as NavigationStart } from '../../navigation/public' ; import { SharePluginStart , SharePluginSetup } from '../../share/public' ; import { UrlForwardingSetup , UrlForwardingStart } from '../../url_forwarding/public' ; import { VisualizationsStart } from '../../visualizations/public' ; import { VisualizeConstants } from './application/visualize_constants' ; import { FeatureCatalogueCategory , HomePublicPluginSetup } from '../../home/public' ; import { VisualizeServices } from './application/types' ; import { DEFAULT_APP_CATEGORIES } from '../../../core/public' ; import { SavedObjectsStart } from '../../saved_objects/public' ; import { EmbeddableStart } from '../../embeddable/public' ; import { DashboardStart } from '../../dashboard/public' ; import { UiActionsSetup , VISUALIZE_FIELD_TRIGGER } from '../../ui_actions/public' ; import { setUISettings , setApplication , setIndexPatterns , setQueryService , setShareService , } from './services' ; import { visualizeFieldAction } from './actions/visualize_field_action' ; import { createVisualizeUrlGenerator } from './url_generator' ; export interface VisualizePluginStartDependencies { data : DataPublicPluginStart ; navigation : NavigationStart ; share ? : SharePluginStart ; visualizations : VisualizationsStart ; embeddable : EmbeddableStart ; urlForwarding : UrlForwardingStart ; savedObjects : SavedObjectsStart ; dashboard : DashboardStart ; } export interface VisualizePluginSetupDependencies { home ? : HomePublicPluginSetup ; urlForwarding : UrlForwardingSetup ; data : DataPublicPluginSetup ; share ? : SharePluginSetup ; uiActions : UiActionsSetup ; } export class VisualizePlugin implements Plugin < void , void , VisualizePluginSetupDependencies , VisualizePluginStartDependencies > { private appStateUpdater = new BehaviorSubject < AppUpdater > ( ( ) => ( { } ) ) ; private stopUrlTracking : ( ( ) => void ) | undefined = undefined ; private currentHistory : ScopedHistory | undefined = undefined ; constructor ( private initializerContext ) { } public async setup ( core , { home , urlForwarding , data , share , uiActions } ) { const { appMounted , appUnMounted , stop : stopUrlTracker , setActiveUrl , restorePreviousUrl , } = createOsdUrlTracker ( { baseUrl : core . http . basePath . prepend ( '/app/visualize' ) , defaultSubUrl : '#/' , storageKey : `lastUrl:${ core . http . basePath . get ( ) }:visualize` , navLinkUpdater$ : this . appStateUpdater , toastNotifications : core . notifications . toasts , stateParams : [ { osdUrlKey : '_g' , stateUpdate$ : data . query . state$ . pipe ( filter ( ( { changes } ) => ! ! ( changes . globalFilters || changes . time || changes . refreshInterval ) ) , map ( ( { state } ) => ( { ... state , filters : state . filters ?. filter ( opensearchFilters . isFilterPinned ) , } ) ) ) , } , ] , getHistory : ( ) => this . currentHistory ! , } ) ; this . stopUrlTracking = ( ) => { stopUrlTracker ( ) ; } ; if ( share ) { share . urlGenerators . registerUrlGenerator ( createVisualizeUrlGenerator ( async ( ) => { const [ coreStart ] = await core . getStartServices ( ) ; return { appBasePath : coreStart . application . getUrlForApp ( 'visualize' ) , useHashedUrl : coreStart . uiSettings . get ( 'state:storeInSessionStorage' ) , } ; } ) ) ; } setUISettings ( core . uiSettings ) ; uiActions . addTriggerAction ( VISUALIZE_FIELD_TRIGGER , visualizeFieldAction ) ; core . application . register ( { id : 'visualize' , title : 'Visualize' , order : 8000 , euiIconType : 'inputOutput' , defaultPath : '#/' , category : DEFAULT_APP_CATEGORIES . opensearchDashboards , updater$ : this . appStateUpdater . asObservable ( ) , mount : async ( params ) => { const [ coreStart , pluginsStart ] = await core . getStartServices ( ) ; this . currentHistory = params . history ; pluginsStart . data . indexPatterns . clearCache ( ) ; await pluginsStart . data . indexPatterns . ensureDefaultIndexPattern ( ) ; appMounted ( ) ; const unlistenParentHistory = params . history . listen ( ( ) => { window . dispatchEvent ( new HashChangeEvent ( 'hashchange' ) ) ; } ) ; /**
                 * current implementation uses 2 history objects:
                 * 1. the hash history (used for the react hash router)
                 * 2. and the scoped history (used for url tracking)
                 * this should be replaced to use only scoped history after moving legacy apps to browser routing
                 */ const history = createHashHistory ( ) ; const services = { ... coreStart , history , osdUrlStateStorage : createOsdUrlStateStorage ( { history , useHash : coreStart . uiSettings . get ( 'state:storeInSessionStorage' ) , ... withNotifyOnErrors ( coreStart . notifications . toasts ) , } ) , urlForwarding : pluginsStart . urlForwarding , pluginInitializerContext : this . initializerContext , chrome : coreStart . chrome , data : pluginsStart . data , localStorage : new Storage ( localStorage ) , navigation : pluginsStart . navigation , savedVisualizations : pluginsStart . visualizations . savedVisualizationsLoader , share : pluginsStart . share , toastNotifications : coreStart . notifications . toasts , visualizeCapabilities : coreStart . application . capabilities . visualize , visualizations : pluginsStart . visualizations , embeddable : pluginsStart . embeddable , setActiveUrl , createVisEmbeddableFromObject : pluginsStart . visualizations . __LEGACY . createVisEmbeddableFromObject , savedObjectsPublic : pluginsStart . savedObjects , scopedHistory : params . history , restorePreviousUrl , dashboard : pluginsStart . dashboard , setHeaderActionMenu : params . setHeaderActionMenu , } ; params . element . classList . add ( 'visAppWrapper' ) ; const { renderApp } = await import ( './application' ) ; const unmount = renderApp ( params , services ) ; return ( ) => { params . element . classList . remove ( 'visAppWrapper' ) ; unlistenParentHistory ( ) ; unmount ( ) ; appUnMounted ( ) ; } ; } , } ) ; urlForwarding . forwardApp ( 'visualize' , 'visualize' ) ; if ( home ) { home . featureCatalogue . register ( { id : 'visualize' , title : 'Visualize' , description : i18n . translate ( 'visualize.visualizeDescription' , { defaultMessage : 'Create visualizations and aggregate data stores in your OpenSearch indices.' , } ) , icon : 'visualizeApp' , path : `/app/visualize#${ VisualizeConstants . LANDING_PAGE_PATH }` , showOnHomePage : false , category : FeatureCatalogueCategory . DATA , } ) ; } } public start ( core , plugins ) { setApplication ( core . application ) ; setIndexPatterns ( plugins . data . indexPatterns ) ; setQueryService ( plugins . data . query ) ; if ( plugins . share ) { setShareService ( plugins . share ) ; } } stop ( ) { if ( this . stopUrlTracking ) { this . stopUrlTracking ( ) ; } } }