import { Route , RouteMatch , useMatchRoutes , } from '@kbn/typed-react-router-config' ; import { ChromeBreadcrumb } from 'kibana/public' ; import { compact , isEqual } from 'lodash' ; import React , { createContext , useMemo , useState } from 'react' ; import { useBreadcrumbs } from '../../../../observability/public' ; export interface Breadcrumb { title : string ; href : string ; } interface BreadcrumbApi { set ( route , breadcrumb ) : void ; unset ( route ) : void ; getBreadcrumbs ( matches ) : Breadcrumb [ ] ; } export const BreadcrumbsContext = createContext < BreadcrumbApi | undefined > ( undefined ) ; export function BreadcrumbsContextProvider ( { children , } ) { const [ , forceUpdate ] = useState ( { } ) ; const breadcrumbs = useMemo ( ( ) => { return new Map < Route , Breadcrumb [ ] > ( ) ; } , [ ] ) ; const matches = useMatchRoutes ( ) ; const api = useMemo < BreadcrumbApi > ( ( ) => ( { set ( route , breadcrumb ) { if ( ! isEqual ( breadcrumbs . get ( route ) , breadcrumb ) ) { breadcrumbs . set ( route , breadcrumb ) ; forceUpdate ( { } ) ; } } , unset ( route ) { if ( breadcrumbs . has ( route ) ) { breadcrumbs . delete ( route ) ; forceUpdate ( { } ) ; } } , getBreadcrumbs ( currentMatches ) { return compact ( currentMatches . flatMap ( ( match ) => { const breadcrumb = breadcrumbs . get ( match . route ) ; return breadcrumb ; } ) ) ; } , } ) , [ breadcrumbs ] ) ; const formattedBreadcrumbs = api . getBreadcrumbs ( matches ) . map ( ( breadcrumb , index , array ) => { return { text : breadcrumb . title , ... ( index === array . length - 1 ? { } : { href : breadcrumb . href , } ) , } ; } ) ; useBreadcrumbs ( formattedBreadcrumbs ) ; return ( < BreadcrumbsContext . Provider value = { api } > { children } < /BreadcrumbsContext.Provider>); }