import React from 'react' ; import ReactDOM from 'react-dom' ; import { Subscription } from 'rxjs' ; import { TodoSavedObjectAttributes } from 'examples/embeddable_examples/common' ; import { SavedObjectsClientContract } from 'opensearch-dashboards/public' ; import { Embeddable , IContainer , EmbeddableOutput , SavedObjectEmbeddableInput , } from '../../../../src/plugins/embeddable/public' ; import { TodoRefEmbeddableComponent } from './todo_ref_component' ; export const TODO_REF_EMBEDDABLE = 'TODO_REF_EMBEDDABLE' ; export interface TodoRefInput extends SavedObjectEmbeddableInput { /**
     * Optional search string which will be used to highlight search terms as
     * well as calculate `output.hasMatch`.
     */ search ? : string ; } export interface TodoRefOutput extends EmbeddableOutput { /**
     * Should be true if input.search is defined and the task or title contain
     * search as a substring.
     */ hasMatch : boolean ; /**
     * Will contain the saved object attributes of the Todo Saved Object that matches
     * `input.savedObjectId`. If the id is invalid, this may be undefined.
     */ savedAttributes ? : TodoSavedObjectAttributes ; } param search param savedAttributes function getHasMatch ( search ? , savedAttributes ? ) { if ( ! search ) return true ; if ( ! savedAttributes ) return false ; return Boolean ( ( savedAttributes . task && savedAttributes . task . match ( search ) ) || ( savedAttributes . title && savedAttributes . title . match ( search ) ) ) ; } /**
 * This is an example of an embeddable that is backed by a saved object. It's essentially the
 * same as `TodoEmbeddable` but that is "by value", while this is "by reference".
 */ export class TodoRefEmbeddable extends Embeddable < TodoRefInput , TodoRefOutput > { public readonly type = TODO_REF_EMBEDDABLE ; private subscription : Subscription ; private node ? : HTMLElement ; private savedObjectsClient : SavedObjectsClientContract ; private savedObjectId ? : string ; constructor ( initialInput , { parent , savedObjectsClient , } ) { super ( initialInput , { hasMatch : false } , parent ) ; this . savedObjectsClient = savedObjectsClient ; this . subscription = this . getInput$ ( ) . subscribe ( async ( ) => { let savedAttributes ; if ( this . savedObjectId !== this . input . savedObjectId ) { this . savedObjectId = this . input . savedObjectId ; const todoSavedObject = await this . savedObjectsClient . get < TodoSavedObjectAttributes > ( 'todo' , this . input . savedObjectId ) ; savedAttributes = todoSavedObject ?. attributes ; } this . updateOutput ( { hasMatch : getHasMatch ( this . input . search , savedAttributes ) , savedAttributes , } ) ; } ) ; } public render ( node ) { if ( this . node ) { ReactDOM . unmountComponentAtNode ( this . node ) ; } this . node = node ; ReactDOM . render ( < TodoRefEmbeddableComponent embeddable = { this } / > , node ) ; } /**
     * Lets re-sync our saved object to make sure it's up to date!
     */ public async reload ( ) { this . savedObjectId = this . input . savedObjectId ; const todoSavedObject = await this . savedObjectsClient . get < TodoSavedObjectAttributes > ( 'todo' , this . input . savedObjectId ) ; const savedAttributes = todoSavedObject ?. attributes ; this . updateOutput ( { hasMatch : getHasMatch ( this . input . search , savedAttributes ) , savedAttributes , } ) ; } public destroy ( ) { super . destroy ( ) ; this . subscription . unsubscribe ( ) ; if ( this . node ) { ReactDOM . unmountComponentAtNode ( this . node ) ; } } }