diff --git a/src/core/public/chrome/ui/header/__snapshots__/header.test.tsx.snap b/src/core/public/chrome/ui/header/__snapshots__/header.test.tsx.snap index 6301583c130a..9e7906250949 100644 --- a/src/core/public/chrome/ui/header/__snapshots__/header.test.tsx.snap +++ b/src/core/public/chrome/ui/header/__snapshots__/header.test.tsx.snap @@ -4271,55 +4271,6 @@ exports[`Header renders 1`] = ` "thrownError": null, } } - breadcrumbsAppendExtension$={ - BehaviorSubject { - "_isScalar": false, - "_value": undefined, - "closed": false, - "hasError": false, - "isStopped": false, - "observers": Array [ - Subscriber { - "_parentOrParents": null, - "_subscriptions": Array [ - SubjectSubscription { - "_parentOrParents": [Circular], - "_subscriptions": null, - "closed": false, - "subject": [Circular], - "subscriber": [Circular], - }, - ], - "closed": false, - "destination": SafeSubscriber { - "_complete": undefined, - "_context": [Circular], - "_error": undefined, - "_next": [Function], - "_parentOrParents": null, - "_parentSubscriber": [Circular], - "_subscriptions": null, - "closed": false, - "destination": Object { - "closed": true, - "complete": [Function], - "error": [Function], - "next": [Function], - }, - "isStopped": false, - "syncErrorThrowable": false, - "syncErrorThrown": false, - "syncErrorValue": null, - }, - "isStopped": false, - "syncErrorThrowable": true, - "syncErrorThrown": false, - "syncErrorValue": null, - }, - ], - "thrownError": null, - } - } > ({ htmlIdGenerator: () => () => 'mockId', @@ -71,6 +72,9 @@ describe('Header', () => { const recentlyAccessed$ = new BehaviorSubject([ { link: '', label: 'dashboard', id: 'dashboard' }, ]); + const breadcrumbsAppendExtension$ = new BehaviorSubject< + undefined | ChromeBreadcrumbsAppendExtension + >(undefined); const component = mountWithIntl(
{ recentlyAccessed$={recentlyAccessed$} isLocked$={isLocked$} customNavLink$={customNavLink$} + breadcrumbsAppendExtension$={breadcrumbsAppendExtension$} /> ); expect(component.find('EuiHeader').exists()).toBeFalsy(); @@ -93,5 +98,19 @@ describe('Header', () => { component.update(); expect(component.find('nav[aria-label="Primary"]').exists()).toBeTruthy(); expect(component).toMatchSnapshot(); + + act(() => + breadcrumbsAppendExtension$.next({ + content: (root: HTMLDivElement) => { + root.innerHTML = '
__render__
'; + return () => (root.innerHTML = ''); + }, + }) + ); + component.update(); + expect(component.find('HeaderExtension').exists()).toBeTruthy(); + expect( + component.find('HeaderExtension').getDOMNode().querySelector('.my-extension') + ).toBeTruthy(); }); }); diff --git a/src/core/public/chrome/ui/header/header.tsx b/src/core/public/chrome/ui/header/header.tsx index ad13ada3adfb..8bb3de8c6708 100644 --- a/src/core/public/chrome/ui/header/header.tsx +++ b/src/core/public/chrome/ui/header/header.tsx @@ -7,6 +7,7 @@ */ import { + EuiFlexGroup, EuiHeader, EuiHeaderSection, EuiHeaderSectionItem, @@ -40,6 +41,7 @@ import { HeaderHelpMenu } from './header_help_menu'; import { HeaderLogo } from './header_logo'; import { HeaderNavControls } from './header_nav_controls'; import { HeaderActionMenu } from './header_action_menu'; +import { HeaderExtension } from './header_extension'; export interface HeaderProps { kibanaVersion: string; @@ -73,11 +75,13 @@ export function Header({ basePath, onIsLockedUpdate, homeHref, + breadcrumbsAppendExtension$, ...observables }: HeaderProps) { const isVisible = useObservable(observables.isVisible$, false); const isLocked = useObservable(observables.isLocked$, false); const [isNavOpen, setIsNavOpen] = useState(false); + const breadcrumbsAppendExtension = useObservable(breadcrumbsAppendExtension$); if (!isVisible) { return ; @@ -87,6 +91,10 @@ export function Header({ const navId = htmlIdGenerator()(); const className = classnames('hide-for-sharing', 'headerGlobalNav'); + const Breadcrumbs = ( + + ); + return ( <>
@@ -157,11 +165,23 @@ export function Header({ - + {!breadcrumbsAppendExtension ? ( + Breadcrumbs + ) : ( + + {Breadcrumbs} + + + )} diff --git a/src/core/public/chrome/ui/header/header_breadcrumbs.test.tsx b/src/core/public/chrome/ui/header/header_breadcrumbs.test.tsx index 33314f69278f..34f741caf850 100644 --- a/src/core/public/chrome/ui/header/header_breadcrumbs.test.tsx +++ b/src/core/public/chrome/ui/header/header_breadcrumbs.test.tsx @@ -11,17 +11,12 @@ import React from 'react'; import { act } from 'react-dom/test-utils'; import { BehaviorSubject } from 'rxjs'; import { HeaderBreadcrumbs } from './header_breadcrumbs'; -import { ChromeBreadcrumbsAppendExtension } from '../../chrome_service'; describe('HeaderBreadcrumbs', () => { it('renders updates to the breadcrumbs$ observable', () => { const breadcrumbs$ = new BehaviorSubject([{ text: 'First' }]); const wrapper = mount( - + ); expect(wrapper.find('.euiBreadcrumb')).toMatchSnapshot(); @@ -33,29 +28,4 @@ describe('HeaderBreadcrumbs', () => { wrapper.update(); expect(wrapper.find('.euiBreadcrumb')).toMatchSnapshot(); }); - - it('renders breadcrumbs extension', () => { - const breadcrumbs$ = new BehaviorSubject([{ text: 'First' }]); - const breadcrumbsAppendExtension$ = new BehaviorSubject< - undefined | ChromeBreadcrumbsAppendExtension - >({ - content: (root: HTMLDivElement) => { - root.innerHTML = '
__render__
'; - return () => (root.innerHTML = ''); - }, - }); - - const wrapper = mount( - - ); - - expect(wrapper.find('.euiBreadcrumb').getDOMNode().querySelector('my-extension')).toBeDefined(); - act(() => breadcrumbsAppendExtension$.next(undefined)); - wrapper.update(); - expect(wrapper.find('.euiBreadcrumb').getDOMNode().querySelector('my-extension')).toBeNull(); - }); }); diff --git a/src/core/public/chrome/ui/header/header_breadcrumbs.tsx b/src/core/public/chrome/ui/header/header_breadcrumbs.tsx index 3b9cb22f56d8..3797389fe484 100644 --- a/src/core/public/chrome/ui/header/header_breadcrumbs.tsx +++ b/src/core/public/chrome/ui/header/header_breadcrumbs.tsx @@ -6,24 +6,21 @@ * Public License, v 1. */ -import { EuiFlexGroup, EuiHeaderBreadcrumbs } from '@elastic/eui'; +import { EuiHeaderBreadcrumbs } from '@elastic/eui'; import classNames from 'classnames'; import React from 'react'; import useObservable from 'react-use/lib/useObservable'; import { Observable } from 'rxjs'; -import { ChromeBreadcrumb, ChromeBreadcrumbsAppendExtension } from '../../chrome_service'; -import { HeaderExtension } from './header_extension'; +import { ChromeBreadcrumb } from '../../chrome_service'; interface Props { appTitle$: Observable; breadcrumbs$: Observable; - breadcrumbsAppendExtension$: Observable; } -export function HeaderBreadcrumbs({ appTitle$, breadcrumbs$, breadcrumbsAppendExtension$ }: Props) { +export function HeaderBreadcrumbs({ appTitle$, breadcrumbs$ }: Props) { const appTitle = useObservable(appTitle$, 'Kibana'); const breadcrumbs = useObservable(breadcrumbs$, []); - const breadcrumbsAppendExtension = useObservable(breadcrumbsAppendExtension$); let crumbs = breadcrumbs; if (breadcrumbs.length === 0 && appTitle) { @@ -40,14 +37,5 @@ export function HeaderBreadcrumbs({ appTitle$, breadcrumbs$, breadcrumbsAppendEx ), })); - if (breadcrumbsAppendExtension && crumbs[crumbs.length - 1]) { - const lastCrumb = crumbs[crumbs.length - 1]; - lastCrumb.text = ( - -
{lastCrumb.text}
- -
- ); - } return ; } diff --git a/src/core/public/chrome/ui/header/header_extension.tsx b/src/core/public/chrome/ui/header/header_extension.tsx index 53f21d42c534..c5a101476bdb 100644 --- a/src/core/public/chrome/ui/header/header_extension.tsx +++ b/src/core/public/chrome/ui/header/header_extension.tsx @@ -12,6 +12,7 @@ import { MountPoint } from '../../../types'; interface Props { extension?: MountPoint; display?: 'block' | 'inlineBlock'; + containerClassName?: string; } export class HeaderExtension extends React.Component { @@ -39,6 +40,7 @@ export class HeaderExtension extends React.Component { return (
);