import React from 'react' ; import ReactDOM from 'react-dom' ; import { Subscription } from 'rxjs' ; import { Embeddable , EmbeddableInput , IContainer , EmbeddableOutput , SavedObjectEmbeddableInput , ReferenceOrValueEmbeddable , AttributeService , } from '../../../../src/plugins/embeddable/public' ; import { BookSavedObjectAttributes } from '../../common' ; import { BookEmbeddableComponent } from './book_component' ; export const BOOK_EMBEDDABLE = 'book' ; export type BookEmbeddableInput = BookByValueInput | BookByReferenceInput ; export interface BookEmbeddableOutput extends EmbeddableOutput { hasMatch : boolean ; attributes : BookSavedObjectAttributes ; } interface BookInheritedInput extends EmbeddableInput { search ? : string ; } export type BookByValueInput = { attributes : BookSavedObjectAttributes ; } & BookInheritedInput ; export type BookByReferenceInput = SavedObjectEmbeddableInput & BookInheritedInput ; param search param savedAttributes function getHasMatch ( search ? , savedAttributes ? ) { if ( ! search ) return true ; if ( ! savedAttributes ) return false ; return Boolean ( ( savedAttributes . author && savedAttributes . author . match ( search ) ) || ( savedAttributes . title && savedAttributes . title . match ( search ) ) ) ; } export class BookEmbeddable extends Embeddable < BookEmbeddableInput , BookEmbeddableOutput > implements ReferenceOrValueEmbeddable < BookByValueInput , BookByReferenceInput > { public readonly type = BOOK_EMBEDDABLE ; private subscription : Subscription ; private node ? : HTMLElement ; private savedObjectId ? : string ; private attributes ? : BookSavedObjectAttributes ; constructor ( initialInput , private attributeService , { parent , } ) { super ( initialInput , { } as BookEmbeddableOutput , parent ) ; this . subscription = this . getInput$ ( ) . subscribe ( async ( ) => { const savedObjectId = ( this . getInput ( ) as BookByReferenceInput ) . savedObjectId ; const attributes = ( this . getInput ( ) as BookByValueInput ) . attributes ; if ( this . attributes !== attributes || this . savedObjectId !== savedObjectId ) { this . savedObjectId = savedObjectId ; this . reload ( ) ; } else { this . updateOutput ( { attributes : this . attributes , defaultTitle : this . attributes . title , hasMatch : getHasMatch ( this . input . search , this . attributes ) , } ) ; } } ) ; } readonly inputIsRefType = ( input ) : input is BookByReferenceInput => { return this . attributeService . inputIsRefType ( input ) ; } ; readonly getInputAsValueType = async ( ) : Promise < BookByValueInput > => { return this . attributeService . getInputAsValueType ( this . getExplicitInput ( ) ) ; } ; readonly getInputAsRefType = async ( ) : Promise < BookByReferenceInput > => { return this . attributeService . getInputAsRefType ( this . getExplicitInput ( ) , { showSaveModal : true , saveModalTitle : this . getTitle ( ) , } ) ; } ; public render ( node ) { if ( this . node ) { ReactDOM . unmountComponentAtNode ( this . node ) ; } this . node = node ; ReactDOM . render ( < BookEmbeddableComponent embeddable = { this } / > , node ) ; } public async reload ( ) { this . attributes = ( await this . attributeService . unwrapAttributes ( this . input ) ) . attributes ; this . updateOutput ( { attributes : this . attributes , defaultTitle : this . attributes . title , hasMatch : getHasMatch ( this . input . search , this . attributes ) , } ) ; } public getTitle ( ) { return this . getOutput ( ) ?. title || this . getOutput ( ) . attributes ?. title ; } public destroy ( ) { super . destroy ( ) ; this . subscription . unsubscribe ( ) ; if ( this . node ) { ReactDOM . unmountComponentAtNode ( this . node ) ; } } }