import { i18n } from '@osd/i18n' ; import { ApplicationStart } from 'opensearch-dashboards/public' ; import { Action } from 'src/plugins/ui_actions/public' ; import { take } from 'rxjs/operators' ; import { ViewMode } from '../types' ; import { EmbeddableFactoryNotFoundError } from '../errors' ; import { EmbeddableStart } from '../../plugin' ; import { IEmbeddable , EmbeddableEditorState , EmbeddableStateTransfer , SavedObjectEmbeddableInput , EmbeddableInput , Container , } from '../..' ; export const ACTION_EDIT_PANEL = 'editPanel' ; interface ActionContext { embeddable : IEmbeddable ; } interface NavigationContext { app : string ; path : string ; state ? : EmbeddableEditorState ; } export class EditPanelAction implements Action < ActionContext > { public readonly type = ACTION_EDIT_PANEL ; public readonly id = ACTION_EDIT_PANEL ; public order = 50 ; public currentAppId : string | undefined ; constructor ( private readonly getEmbeddableFactory , private readonly application , private readonly stateTransfer ? ) { if ( this . application ?. currentAppId$ ) { this . application . currentAppId$ . pipe ( take ( 1 ) ) . subscribe ( ( appId ) => ( this . currentAppId = appId ) ) ; } } public getDisplayName ( { embeddable } ) { const factory = this . getEmbeddableFactory ( embeddable . type ) ; if ( ! factory ) { throw new EmbeddableFactoryNotFoundError ( embeddable . type ) ; } return i18n . translate ( 'embeddableApi.panel.editPanel.displayName' , { defaultMessage : 'Edit {value}' , values : { value : factory . getDisplayName ( ) , } , } ) ; } getIconType ( ) { return 'pencil' ; } public async isCompatible ( { embeddable } ) { const canEditEmbeddable = Boolean ( embeddable && embeddable . getOutput ( ) . editable && ( embeddable . getOutput ( ) . editUrl || ( embeddable . getOutput ( ) . editApp && embeddable . getOutput ( ) . editPath ) ) ) ; const inDashboardEditMode = embeddable . getInput ( ) . viewMode === ViewMode . EDIT ; return Boolean ( canEditEmbeddable && inDashboardEditMode ) ; } public async execute ( context ) { const appTarget = this . getAppTarget ( context ) ; if ( appTarget ) { if ( this . stateTransfer && appTarget . state ) { await this . stateTransfer . navigateToEditor ( appTarget . app , { path : appTarget . path , state : appTarget . state , } ) ; } else { await this . application . navigateToApp ( appTarget . app , { path : appTarget . path } ) ; } return ; } const href = await this . getHref ( context ) ; if ( href ) { window . location . href = href ; return ; } } public getAppTarget ( { embeddable } ) { const app = embeddable ? embeddable . getOutput ( ) . editApp : undefined ; const path = embeddable ? embeddable . getOutput ( ) . editPath : undefined ; if ( app && path ) { if ( this . currentAppId ) { const byValueMode = ! ( embeddable . getInput ( ) as SavedObjectEmbeddableInput ) . savedObjectId ; const state = { originatingApp : this . currentAppId , valueInput : byValueMode ? this . getExplicitInput ( { embeddable } ) : undefined , embeddableId : embeddable . id , } ; return { app , path , state } ; } return { app , path } ; } } public async getHref ( { embeddable } ) { const editUrl = embeddable ? embeddable . getOutput ( ) . editUrl : undefined ; return editUrl ? editUrl : '' ; } private getExplicitInput ( { embeddable } ) { return ( ( embeddable . getRoot ( ) as Container ) ?. getInput ( ) ?. panels ?. [ embeddable . id ] ?. explicitInput ?? embeddable . getInput ( ) ) ; } }