mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[Serverless] Support banner header (#160912)
## Summary
Closes https://github.com/elastic/kibana/issues/160052
This PR adds support for the header banner in serverless projects.
<img width="1437" alt="image"
src="c950bbe7
-46bb-4b82-b9ee-406aef7748dc">
**NOTE:** This PR adds support for the header banner by applying the
same techniques as in the "classic" layout: special class names of
`header__bar`/`header_firstBar`/`header__secondBar`. The effect is the
"header action menu" bar, which is an optional 2nd bar in the chrome
header, works better after this change when it is always visible. This
is a temporary issue that unblocks the header banner, and fixes other
overlapping issues with the current project layout stylings.
_As followup work_, the @elastic/appex-sharedux team will investigate
converting the Kibana page template to the new
[EuiPageTemplate](https://elastic.github.io/eui/#/templates/page-template/examples)
which supports horizontal sections of a page that have dynamic height --
we need this for the dynamic presence of the header banner, and the
intended dynamic presence of the header action menu.
### Checklist
Delete any items that are not applicable to this PR.
- [x] Any UI touched in this PR is usable by keyboard only (learn more
about [keyboard accessibility](https://webaim.org/techniques/keyboard/))
- [x] Any UI touched in this PR does not create any new axe failures
(run axe in browser:
[FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/),
[Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))
- [x] This renders correctly on smaller devices using a responsive
layout. (You can test this [in your
browser](https://www.browserstack.com/guide/responsive-testing-on-local-server))
- [x] This was checked for [cross-browser
compatibility](https://www.elastic.co/support/matrix#matrix_browsers)
This commit is contained in:
parent
1d783110b3
commit
f82588ba5e
5 changed files with 106 additions and 100 deletions
|
@ -310,6 +310,7 @@ export class ChromeService {
|
|||
navControlsCenter$={navControls.getCenter$()}
|
||||
navControlsRight$={navControls.getRight$()}
|
||||
loadingCount$={http.getLoadingCount$()}
|
||||
headerBanner$={headerBanner$.pipe(takeUntil(this.stop$))}
|
||||
homeHref$={projectNavigation.getProjectHome$()}
|
||||
docLinks={docLinks}
|
||||
kibanaVersion={injectedMetadata.getKibanaVersion()}
|
||||
|
|
|
@ -23,6 +23,7 @@ describe('Header', () => {
|
|||
actionMenu$: Rx.of(undefined),
|
||||
docLinks: docLinksServiceMock.createStartContract(),
|
||||
globalHelpExtensionMenuLinks$: Rx.of([]),
|
||||
headerBanner$: Rx.of(),
|
||||
helpExtension$: Rx.of(undefined),
|
||||
helpSupportUrl$: Rx.of('app/help'),
|
||||
helpMenuLinks$: Rx.of([]),
|
||||
|
|
|
@ -19,28 +19,30 @@ import {
|
|||
} from '@elastic/eui';
|
||||
import { css } from '@emotion/react';
|
||||
import type { InternalApplicationStart } from '@kbn/core-application-browser-internal';
|
||||
import { RedirectAppLinks } from '@kbn/shared-ux-link-redirect-app';
|
||||
import {
|
||||
ChromeBreadcrumb,
|
||||
ChromeGlobalHelpExtensionMenuLink,
|
||||
ChromeHelpExtension,
|
||||
ChromeHelpMenuLink,
|
||||
ChromeNavControl,
|
||||
ChromeUserBanner,
|
||||
} from '@kbn/core-chrome-browser/src';
|
||||
import type { DocLinksStart } from '@kbn/core-doc-links-browser';
|
||||
import type { HttpStart } from '@kbn/core-http-browser';
|
||||
import { MountPoint } from '@kbn/core-mount-utils-browser';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import React, { createRef, useCallback, useState } from 'react';
|
||||
import { RedirectAppLinks } from '@kbn/shared-ux-link-redirect-app';
|
||||
import { Router } from '@kbn/shared-ux-router';
|
||||
import React, { createRef, useCallback, useState } from 'react';
|
||||
import useLocalStorage from 'react-use/lib/useLocalStorage';
|
||||
import useObservable from 'react-use/lib/useObservable';
|
||||
import { Observable, debounceTime } from 'rxjs';
|
||||
import type { DocLinksStart } from '@kbn/core-doc-links-browser';
|
||||
|
||||
import { debounceTime, Observable, of } from 'rxjs';
|
||||
import { HeaderActionMenu, useHeaderActionMenuMounter } from '../header/header_action_menu';
|
||||
import { HeaderBreadcrumbs } from '../header/header_breadcrumbs';
|
||||
import { HeaderHelpMenu } from '../header/header_help_menu';
|
||||
import { HeaderNavControls } from '../header/header_nav_controls';
|
||||
import { HeaderTopBanner } from '../header/header_top_banner';
|
||||
import { ScreenReaderRouteAnnouncements, SkipToMainContent } from '../header/screen_reader_a11y';
|
||||
import { ProjectNavigation } from './navigation';
|
||||
|
||||
const headerCss = {
|
||||
|
@ -88,6 +90,7 @@ const headerStrings = {
|
|||
};
|
||||
|
||||
export interface Props {
|
||||
headerBanner$: Observable<ChromeUserBanner | undefined>;
|
||||
breadcrumbs$: Observable<ChromeBreadcrumb[]>;
|
||||
actionMenu$: Observable<MountPoint | undefined>;
|
||||
docLinks: DocLinksStart;
|
||||
|
@ -175,94 +178,110 @@ export const ProjectHeader = ({
|
|||
|
||||
return (
|
||||
<>
|
||||
<EuiHeader position="fixed" data-test-subj="kibanaProjectHeader">
|
||||
<EuiHeaderSection grow={false}>
|
||||
<EuiHeaderSectionItem css={headerCss.nav.toggleNavButton}>
|
||||
<Router history={application.history}>
|
||||
<ProjectNavigation
|
||||
isOpen={isOpen!}
|
||||
closeNav={() => {
|
||||
setIsOpen(false);
|
||||
if (toggleCollapsibleNavRef.current) {
|
||||
toggleCollapsibleNavRef.current.focus();
|
||||
}
|
||||
}}
|
||||
button={
|
||||
<EuiHeaderSectionItemButton
|
||||
data-test-subj="toggleNavButton"
|
||||
aria-label={headerStrings.nav.closeNavAriaLabel}
|
||||
onClick={() => setIsOpen(!isOpen)}
|
||||
aria-expanded={isOpen!}
|
||||
aria-pressed={isOpen!}
|
||||
aria-controls={navId}
|
||||
ref={toggleCollapsibleNavRef}
|
||||
<ScreenReaderRouteAnnouncements
|
||||
breadcrumbs$={observables.breadcrumbs$}
|
||||
customBranding$={of()}
|
||||
appId$={application.currentAppId$}
|
||||
/>
|
||||
<SkipToMainContent />
|
||||
|
||||
<HeaderTopBanner headerBanner$={observables.headerBanner$} />
|
||||
<header data-test-subj="kibanaProjectHeader">
|
||||
<div id="globalHeaderBars" data-test-subj="headerGlobalNav" className="header__bars">
|
||||
<EuiHeader position="fixed" className="header__firstBar">
|
||||
<EuiHeaderSection grow={false}>
|
||||
<EuiHeaderSectionItem css={headerCss.nav.toggleNavButton}>
|
||||
<Router history={application.history}>
|
||||
<ProjectNavigation
|
||||
isOpen={isOpen!}
|
||||
closeNav={() => {
|
||||
setIsOpen(false);
|
||||
if (toggleCollapsibleNavRef.current) {
|
||||
toggleCollapsibleNavRef.current.focus();
|
||||
}
|
||||
}}
|
||||
button={
|
||||
<EuiHeaderSectionItemButton
|
||||
data-test-subj="toggleNavButton"
|
||||
aria-label={headerStrings.nav.closeNavAriaLabel}
|
||||
onClick={() => setIsOpen(!isOpen)}
|
||||
aria-expanded={isOpen!}
|
||||
aria-pressed={isOpen!}
|
||||
aria-controls={navId}
|
||||
ref={toggleCollapsibleNavRef}
|
||||
>
|
||||
<EuiIcon type={isOpen ? 'menuLeft' : 'menuRight'} size="m" />
|
||||
</EuiHeaderSectionItemButton>
|
||||
}
|
||||
>
|
||||
<EuiIcon type={isOpen ? 'menuLeft' : 'menuRight'} size="m" />
|
||||
</EuiHeaderSectionItemButton>
|
||||
}
|
||||
>
|
||||
{children}
|
||||
</ProjectNavigation>
|
||||
</Router>
|
||||
</EuiHeaderSectionItem>
|
||||
{children}
|
||||
</ProjectNavigation>
|
||||
</Router>
|
||||
</EuiHeaderSectionItem>
|
||||
|
||||
<EuiHeaderSectionItem>
|
||||
<Logo
|
||||
prependBasePath={prependBasePath}
|
||||
application={application}
|
||||
homeHref$={observables.homeHref$}
|
||||
loadingCount$={observables.loadingCount$}
|
||||
/>
|
||||
</EuiHeaderSectionItem>
|
||||
<EuiHeaderSectionItem>
|
||||
<Logo
|
||||
prependBasePath={prependBasePath}
|
||||
application={application}
|
||||
homeHref$={observables.homeHref$}
|
||||
loadingCount$={observables.loadingCount$}
|
||||
/>
|
||||
</EuiHeaderSectionItem>
|
||||
|
||||
<EuiHeaderSectionItem>
|
||||
<HeaderNavControls navControls$={observables.navControlsLeft$} />
|
||||
</EuiHeaderSectionItem>
|
||||
<EuiHeaderSectionItem>
|
||||
<HeaderNavControls navControls$={observables.navControlsLeft$} />
|
||||
</EuiHeaderSectionItem>
|
||||
|
||||
<EuiHeaderSectionItem>
|
||||
<EuiHeaderLink href="https://cloud.elastic.co/deployments">
|
||||
{headerStrings.cloud.linkToDeployments}
|
||||
</EuiHeaderLink>
|
||||
</EuiHeaderSectionItem>
|
||||
<EuiHeaderSectionItem>
|
||||
<EuiHeaderLink href="https://cloud.elastic.co/deployments">
|
||||
{headerStrings.cloud.linkToDeployments}
|
||||
</EuiHeaderLink>
|
||||
</EuiHeaderSectionItem>
|
||||
|
||||
<EuiHeaderSectionItem>
|
||||
<RedirectAppLinks coreStart={{ application }}>
|
||||
<HeaderBreadcrumbs breadcrumbs$={observables.breadcrumbs$} />
|
||||
</RedirectAppLinks>
|
||||
</EuiHeaderSectionItem>
|
||||
</EuiHeaderSection>
|
||||
<EuiHeaderSectionItem>
|
||||
<RedirectAppLinks coreStart={{ application }}>
|
||||
<HeaderBreadcrumbs breadcrumbs$={observables.breadcrumbs$} />
|
||||
</RedirectAppLinks>
|
||||
</EuiHeaderSectionItem>
|
||||
</EuiHeaderSection>
|
||||
|
||||
<EuiHeaderSection side="right">
|
||||
<EuiHeaderSectionItem>
|
||||
<HeaderNavControls navControls$={observables.navControlsCenter$} />
|
||||
<HeaderNavControls navControls$={observables.navControlsRight$} />
|
||||
</EuiHeaderSectionItem>
|
||||
<EuiHeaderSection side="right">
|
||||
<EuiHeaderSectionItem>
|
||||
<HeaderNavControls navControls$={observables.navControlsCenter$} />
|
||||
<HeaderNavControls navControls$={observables.navControlsRight$} />
|
||||
</EuiHeaderSectionItem>
|
||||
|
||||
<EuiHeaderSectionItem>
|
||||
<HeaderHelpMenu
|
||||
globalHelpExtensionMenuLinks$={observables.globalHelpExtensionMenuLinks$}
|
||||
helpExtension$={observables.helpExtension$}
|
||||
helpSupportUrl$={observables.helpSupportUrl$}
|
||||
defaultContentLinks$={observables.helpMenuLinks$}
|
||||
kibanaDocLink={docLinks.links.elasticStackGetStarted}
|
||||
docLinks={docLinks}
|
||||
kibanaVersion={kibanaVersion}
|
||||
navigateToUrl={application.navigateToUrl}
|
||||
/>
|
||||
</EuiHeaderSectionItem>
|
||||
</EuiHeaderSection>
|
||||
</EuiHeader>
|
||||
<EuiHeaderSectionItem>
|
||||
<HeaderHelpMenu
|
||||
globalHelpExtensionMenuLinks$={observables.globalHelpExtensionMenuLinks$}
|
||||
helpExtension$={observables.helpExtension$}
|
||||
helpSupportUrl$={observables.helpSupportUrl$}
|
||||
defaultContentLinks$={observables.helpMenuLinks$}
|
||||
kibanaDocLink={docLinks.links.elasticStackGetStarted}
|
||||
docLinks={docLinks}
|
||||
kibanaVersion={kibanaVersion}
|
||||
navigateToUrl={application.navigateToUrl}
|
||||
/>
|
||||
</EuiHeaderSectionItem>
|
||||
</EuiHeaderSection>
|
||||
</EuiHeader>
|
||||
|
||||
{headerActionMenuMounter.mount && (
|
||||
<EuiHeader data-test-subj="kibanaProjectHeaderActionMenu">
|
||||
<EuiHeaderSection />
|
||||
<EuiHeaderSection side="right">
|
||||
<EuiHeaderSectionItem>
|
||||
<HeaderActionMenu mounter={headerActionMenuMounter} />
|
||||
</EuiHeaderSectionItem>
|
||||
</EuiHeaderSection>
|
||||
</EuiHeader>
|
||||
)}
|
||||
<EuiHeader
|
||||
position="fixed"
|
||||
className="header__secondBar"
|
||||
data-test-subj="kibanaProjectHeaderActionMenu"
|
||||
>
|
||||
<EuiHeaderSection />
|
||||
{headerActionMenuMounter.mount && (
|
||||
<EuiHeaderSection side="right">
|
||||
<EuiHeaderSectionItem>
|
||||
<HeaderActionMenu mounter={headerActionMenuMounter} />
|
||||
</EuiHeaderSectionItem>
|
||||
</EuiHeaderSection>
|
||||
)}
|
||||
</EuiHeader>
|
||||
</div>
|
||||
</header>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -75,9 +75,6 @@
|
|||
&.kbnBody--chromeHidden {
|
||||
@include kbnAffordForHeader(0);
|
||||
}
|
||||
&.kbnBody--projectLayout {
|
||||
@include kbnAffordForHeader($euiHeaderHeightCompensation);
|
||||
}
|
||||
&.kbnBody--chromeHidden.kbnBody--hasHeaderBanner {
|
||||
@include kbnAffordForHeader($kbnHeaderBannerHeight);
|
||||
}
|
||||
|
|
|
@ -89,18 +89,6 @@ const PageOverlayGlobalStyles = createGlobalStyle<{ theme: EuiTheme }>`
|
|||
body.${PAGE_OVERLAY_DOCUMENT_BODY_FULLSCREEN_CLASSNAME} {
|
||||
${FULL_SCREEN_CONTENT_OVERRIDES_CSS_STYLESHEET}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------
|
||||
// Style overrides for when Page Overlay is displayed in serverless project
|
||||
//-------------------------------------------------------------------------------------------
|
||||
// With serverless, there is 1 less header displayed, thus the display of the page overlay
|
||||
// need to be adjusted slightly so that it still display below the header
|
||||
//-------------------------------------------------------------------------------------------
|
||||
body.kbnBody.kbnBody--projectLayout:not(.${PAGE_OVERLAY_DOCUMENT_BODY_FULLSCREEN_CLASSNAME}) .${PAGE_OVERLAY_CSS_CLASSNAME} {
|
||||
top: ${({ theme: { eui } }) => eui.euiHeaderHeightCompensation};
|
||||
height: calc(100% - (${({ theme: { eui } }) => eui.euiHeaderHeightCompensation}));
|
||||
}
|
||||
|
||||
`;
|
||||
|
||||
const setDocumentBodyOverlayIsVisible = () => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue