import React , { memo , useCallback , useMemo , useState , useEffect } from 'react' ; import { AppMountParameters , OverlayRef } from 'opensearch-dashboards/public' ; import { i18n } from '@osd/i18n' ; import { useOpenSearchDashboards } from '../../../../opensearch_dashboards_react/public' ; import { VisualizeServices , VisualizeAppState , VisualizeAppStateContainer , VisualizeEditorVisInstance , } from '../types' ; import { APP_NAME } from '../visualize_constants' ; import { getTopNavConfig } from '../utils' ; import type { IndexPattern } from '../../../../data/public' ; interface VisualizeTopNavProps { currentAppState : VisualizeAppState ; isChromeVisible ? : boolean ; isEmbeddableRendered : boolean ; hasUnsavedChanges : boolean ; setHasUnsavedChanges : ( value : boolean ) => void ; hasUnappliedChanges : boolean ; originatingApp ? : string ; visInstance : VisualizeEditorVisInstance ; setOriginatingApp ? : ( originatingApp : string | undefined ) => void ; stateContainer : VisualizeAppStateContainer ; visualizationIdFromUrl ? : string ; embeddableId ? : string ; onAppLeave : AppMountParameters [ 'onAppLeave' ] ; } const TopNav = ( { currentAppState , isChromeVisible , isEmbeddableRendered , hasUnsavedChanges , setHasUnsavedChanges , hasUnappliedChanges , originatingApp , setOriginatingApp , visInstance , stateContainer , visualizationIdFromUrl , embeddableId , onAppLeave , } ) => { const { services } = useOpenSearchDashboards < VisualizeServices > ( ) ; const { TopNavMenu } = services . navigation . ui ; const { setHeaderActionMenu , visualizeCapabilities } = services ; const { embeddableHandler , vis } = visInstance ; const [ inspectorSession , setInspectorSession ] = useState < OverlayRef > ( ) ; const openInspector = useCallback ( ( ) => { const session = embeddableHandler . openInspector ( ) ; setInspectorSession ( session ) ; } , [ embeddableHandler ] ) ; const handleRefresh = useCallback ( ( _payload , isUpdate ? ) => { if ( isUpdate === false ) { visInstance . embeddableHandler . reload ( ) ; } } , [ visInstance . embeddableHandler ] ) ; const stateTransfer = services . embeddable . getStateTransfer ( ) ; const config = useMemo ( ( ) => { if ( isEmbeddableRendered ) { return getTopNavConfig ( { hasUnsavedChanges , setHasUnsavedChanges , hasUnappliedChanges , openInspector , originatingApp , setOriginatingApp , visInstance , stateContainer , visualizationIdFromUrl , stateTransfer , embeddableId , onAppLeave , } , services ) ; } } , [ isEmbeddableRendered , hasUnsavedChanges , setHasUnsavedChanges , hasUnappliedChanges , openInspector , originatingApp , visInstance , setOriginatingApp , stateContainer , visualizationIdFromUrl , services , embeddableId , stateTransfer , onAppLeave , ] ) ; const [ indexPatterns , setIndexPatterns ] = useState < IndexPattern [ ] > ( vis . data . indexPattern ? [ vis . data . indexPattern ] : [ ] ) ; const showDatePicker = ( ) => { const hasTimeField = vis . data . indexPattern ? ! ! vis . data . indexPattern . timeFieldName : true ; return vis . type . options . showTimePicker && hasTimeField ; } ; const showFilterBar = vis . type . options . showFilterBar ; const showQueryInput = vis . type . requiresSearch && vis . type . options . showQueryBar ; useEffect ( ( ) => { return ( ) => { if ( inspectorSession ) { inspectorSession . close ( ) ; } } ; } , [ inspectorSession ] ) ; useEffect ( ( ) => { onAppLeave ( ( actions ) => { if ( ( ( originatingApp && originatingApp === 'dashboards' ) || originatingApp === 'canvas' ) && ( hasUnappliedChanges || hasUnsavedChanges ) ) { return actions . confirm ( i18n . translate ( 'visualize.confirmModal.confirmTextDescription' , { defaultMessage : 'Leave Visualize editor with unsaved changes?' , } ) , i18n . translate ( 'visualize.confirmModal.title' , { defaultMessage : 'Unsaved changes' , } ) ) ; } return actions . default ( ) ; } ) ; } , [ onAppLeave , hasUnappliedChanges , hasUnsavedChanges , visualizeCapabilities . save , originatingApp , ] ) ; useEffect ( ( ) => { const asyncSetIndexPattern = async ( ) => { let indexes ; if ( vis . type . getUsedIndexPattern ) { indexes = await vis . type . getUsedIndexPattern ( vis . params ) ; } if ( ! indexes || ! indexes . length ) { const defaultIndex = await services . data . indexPatterns . getDefault ( ) ; if ( defaultIndex ) { indexes = [ defaultIndex ] ; } } if ( indexes ) { setIndexPatterns ( indexes ) ; } } ; if ( ! vis . data . indexPattern ) { asyncSetIndexPattern ( ) ; } } , [ vis . params , vis . type , services . data . indexPatterns , vis . data . indexPattern ] ) ; return isChromeVisible ? ( < TopNavMenu appName = { APP_NAME } config = { config } setMenuMountPoint = { setHeaderActionMenu } onQuerySubmit = { handleRefresh } savedQueryId = { currentAppState . savedQuery } onSavedQueryIdChange = { stateContainer . transitions . updateSavedQuery } indexPatterns = { indexPatterns } screenTitle = { vis . title } showAutoRefreshOnly = { ! showDatePicker ( ) } showDatePicker = { showDatePicker ( ) } showFilterBar = { showFilterBar } showQueryInput = { showQueryInput } showSaveQuery = { services . visualizeCapabilities . saveQuery } showSearchBar useDefaultBehaviors />) : showFilterBar ? ( < TopNavMenu appName = { APP_NAME } setMenuMountPoint = { setHeaderActionMenu } indexPatterns = { indexPatterns } showSearchBar showSaveQuery = { false } showDatePicker = { false } showQueryInput = { false } / > ) : null ; } ; export const VisualizeTopNav = memo ( TopNav ) ;