mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[k7/Infra UI] Integrate with K7 Breadcrumbs (#25938)
This changes the header to be conditionally rendered based on the k7design UI setting. If the setting is false, the header is rendered as before. If it is true, the header is hidden and the breadcrumbs are set via the Kibana breadcrumbs api.
This commit is contained in:
parent
3427a08108
commit
ddd243dade
8 changed files with 214 additions and 83 deletions
|
@ -22,6 +22,15 @@ import { uiModules } from 'ui/modules';
|
|||
import { Breadcrumb, ChromeStartContract } from '../../../../core/public/chrome';
|
||||
export { Breadcrumb };
|
||||
|
||||
export interface BreadcrumbsApi {
|
||||
get$(): ReturnType<ChromeStartContract['getBreadcrumbs$']>;
|
||||
set(newBreadcrumbs: Breadcrumb[]): void;
|
||||
}
|
||||
|
||||
export interface WithBreadcrumbsApi {
|
||||
breadcrumbs: BreadcrumbsApi;
|
||||
}
|
||||
|
||||
let newPlatformChrome: ChromeStartContract;
|
||||
export function __newPlatformInit__(instance: ChromeStartContract) {
|
||||
if (newPlatformChrome) {
|
||||
|
|
31
src/ui/public/chrome/index.d.ts
vendored
31
src/ui/public/chrome/index.d.ts
vendored
|
@ -18,26 +18,27 @@
|
|||
*/
|
||||
|
||||
import { Brand } from '../../../core/public/chrome';
|
||||
import { WithBreadcrumbsApi } from './api/breadcrumbs';
|
||||
|
||||
interface IInjector {
|
||||
get<T>(injectable: string): T;
|
||||
}
|
||||
|
||||
declare class Chrome {
|
||||
public addBasePath<T = string>(path: T): T;
|
||||
public dangerouslyGetActiveInjector(): Promise<IInjector>;
|
||||
public getBasePath(): string;
|
||||
public getXsrfToken(): string;
|
||||
public getKibanaVersion(): string;
|
||||
public getUiSettingsClient(): any;
|
||||
public setVisible(visible: boolean): any;
|
||||
public getInjected(key: string, defaultValue?: any): any;
|
||||
public setRootController(name: string, Controller: any): any;
|
||||
public setBrand(brand: Brand): this;
|
||||
public getBrand(key: keyof Brand): Brand[keyof Brand];
|
||||
public addApplicationClass(classNames: string | string[]): this;
|
||||
public removeApplicationClass(classNames: string | string[]): this;
|
||||
public getApplicationClasses(): string;
|
||||
declare interface Chrome extends WithBreadcrumbsApi {
|
||||
addBasePath<T = string>(path: T): T;
|
||||
dangerouslyGetActiveInjector(): Promise<IInjector>;
|
||||
getBasePath(): string;
|
||||
getXsrfToken(): string;
|
||||
getKibanaVersion(): string;
|
||||
getUiSettingsClient(): any;
|
||||
setVisible(visible: boolean): any;
|
||||
getInjected(key: string, defaultValue?: any): any;
|
||||
setRootController(name: string, Controller: any): any;
|
||||
setBrand(brand: Brand): this;
|
||||
getBrand(key: keyof Brand): Brand[keyof Brand];
|
||||
addApplicationClass(classNames: string | string[]): this;
|
||||
removeApplicationClass(classNames: string | string[]): this;
|
||||
getApplicationClasses(): string;
|
||||
}
|
||||
|
||||
declare const chrome: Chrome;
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import {
|
||||
EuiBreadcrumbDefinition,
|
||||
EuiHeader,
|
||||
EuiHeaderBreadcrumbs,
|
||||
EuiHeaderSection,
|
||||
} from '@elastic/eui';
|
||||
import { InjectedIntl, injectI18n } from '@kbn/i18n/react';
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
interface HeaderProps {
|
||||
breadcrumbs?: EuiBreadcrumbDefinition[];
|
||||
appendSections?: React.ReactNode;
|
||||
intl: InjectedIntl;
|
||||
}
|
||||
|
||||
export const Header = injectI18n(
|
||||
class extends React.PureComponent<HeaderProps> {
|
||||
public static displayName = 'Header';
|
||||
|
||||
public render() {
|
||||
const { breadcrumbs = [], appendSections = null, intl } = this.props;
|
||||
const staticBreadcrumbs = [
|
||||
{
|
||||
href: '#/',
|
||||
text: intl.formatMessage({
|
||||
id: 'xpack.infra.header.infrastructureTitle',
|
||||
defaultMessage: 'Infrastructure',
|
||||
}),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<HeaderWrapper>
|
||||
<EuiHeaderSection>
|
||||
<EuiHeaderBreadcrumbs breadcrumbs={[...staticBreadcrumbs, ...breadcrumbs]} />
|
||||
</EuiHeaderSection>
|
||||
{appendSections}
|
||||
</HeaderWrapper>
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const HeaderWrapper = styled(EuiHeader)`
|
||||
height: 29px;
|
||||
`;
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import isEqual from 'lodash/fp/isEqual';
|
||||
import React from 'react';
|
||||
|
||||
import { Breadcrumb } from 'ui/chrome/api/breadcrumbs';
|
||||
|
||||
interface ExternalHeaderProps {
|
||||
breadcrumbs?: Breadcrumb[];
|
||||
setBreadcrumbs: (breadcrumbs: Breadcrumb[]) => void;
|
||||
}
|
||||
|
||||
export class ExternalHeader extends React.Component<ExternalHeaderProps> {
|
||||
public componentDidMount() {
|
||||
this.setBreadcrumbs();
|
||||
}
|
||||
|
||||
public componentDidUpdate(prevProps: ExternalHeaderProps) {
|
||||
if (!isEqual(this.props.breadcrumbs, prevProps.breadcrumbs)) {
|
||||
this.setBreadcrumbs();
|
||||
}
|
||||
}
|
||||
|
||||
public render() {
|
||||
return null;
|
||||
}
|
||||
|
||||
private setBreadcrumbs = () => {
|
||||
this.props.setBreadcrumbs(this.props.breadcrumbs || []);
|
||||
};
|
||||
}
|
44
x-pack/plugins/infra/public/components/header/header.tsx
Normal file
44
x-pack/plugins/infra/public/components/header/header.tsx
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { InjectedIntl, injectI18n } from '@kbn/i18n/react';
|
||||
import { Breadcrumb } from 'ui/chrome/api/breadcrumbs';
|
||||
import { WithKibanaChrome } from '../../containers/with_kibana_chrome';
|
||||
import { ExternalHeader } from './external_header';
|
||||
import { LegacyHeader } from './legacy_header';
|
||||
|
||||
interface HeaderProps {
|
||||
breadcrumbs?: Breadcrumb[];
|
||||
appendSections?: React.ReactNode;
|
||||
intl: InjectedIntl;
|
||||
}
|
||||
|
||||
export const Header = injectI18n(({ appendSections, breadcrumbs = [], intl }: HeaderProps) => {
|
||||
const prefixedBreadcrumbs = [
|
||||
{
|
||||
href: '#/',
|
||||
text: intl.formatMessage({
|
||||
id: 'xpack.infra.header.infrastructureTitle',
|
||||
defaultMessage: 'Infrastructure',
|
||||
}),
|
||||
},
|
||||
...(breadcrumbs || []),
|
||||
];
|
||||
|
||||
return (
|
||||
<WithKibanaChrome>
|
||||
{({ setBreadcrumbs, uiSettings: { k7Design } }) =>
|
||||
k7Design ? (
|
||||
<ExternalHeader breadcrumbs={prefixedBreadcrumbs} setBreadcrumbs={setBreadcrumbs} />
|
||||
) : (
|
||||
<LegacyHeader appendSections={appendSections} breadcrumbs={prefixedBreadcrumbs} />
|
||||
)
|
||||
}
|
||||
</WithKibanaChrome>
|
||||
);
|
||||
});
|
7
x-pack/plugins/infra/public/components/header/index.ts
Normal file
7
x-pack/plugins/infra/public/components/header/index.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
export { Header } from './header';
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { EuiHeader, EuiHeaderBreadcrumbs, EuiHeaderSection } from '@elastic/eui';
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { Breadcrumb } from 'ui/chrome/api/breadcrumbs';
|
||||
|
||||
interface LegacyHeaderProps {
|
||||
breadcrumbs?: Breadcrumb[];
|
||||
appendSections?: React.ReactNode;
|
||||
}
|
||||
|
||||
export const LegacyHeader: React.SFC<LegacyHeaderProps> = ({
|
||||
appendSections,
|
||||
breadcrumbs = [],
|
||||
}) => (
|
||||
<HeaderWrapper>
|
||||
<EuiHeaderSection>
|
||||
<EuiHeaderBreadcrumbs breadcrumbs={breadcrumbs} />
|
||||
</EuiHeaderSection>
|
||||
{appendSections}
|
||||
</HeaderWrapper>
|
||||
);
|
||||
|
||||
const HeaderWrapper = styled(EuiHeader)`
|
||||
height: 29px;
|
||||
`;
|
|
@ -4,25 +4,81 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import chrome from 'ui/chrome';
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
|
||||
import chrome from 'ui/chrome';
|
||||
import { Breadcrumb } from 'ui/chrome/api/breadcrumbs';
|
||||
import { RendererFunction } from '../utils/typed_react';
|
||||
|
||||
interface WithKibanaChromeProps {
|
||||
children: RendererFunction<{
|
||||
basePath: string;
|
||||
}>;
|
||||
// replace with import from platform core when available
|
||||
interface UiSettings {
|
||||
k7Design: boolean;
|
||||
}
|
||||
|
||||
export const WithKibanaChrome: React.SFC<WithKibanaChromeProps> = ({ children }) =>
|
||||
children({
|
||||
// replace with import from platform core when available
|
||||
type UiSettings$ = Observable<{
|
||||
key: string;
|
||||
oldValue: any;
|
||||
newValue: any;
|
||||
}>;
|
||||
|
||||
interface WithKibanaChromeProps {
|
||||
children: RendererFunction<
|
||||
{
|
||||
setBreadcrumbs: (newBreadcrumbs: Breadcrumb[]) => void;
|
||||
} & WithKibanaChromeState
|
||||
>;
|
||||
}
|
||||
|
||||
interface WithKibanaChromeState {
|
||||
basePath: string;
|
||||
uiSettings: UiSettings;
|
||||
}
|
||||
|
||||
const uiSettingsKeys = ['k7Design'];
|
||||
|
||||
export class WithKibanaChrome extends React.Component<
|
||||
WithKibanaChromeProps,
|
||||
WithKibanaChromeState
|
||||
> {
|
||||
public state: WithKibanaChromeState = {
|
||||
uiSettings: {
|
||||
k7Design: chrome.getUiSettingsClient().get('k7design'),
|
||||
},
|
||||
basePath: chrome.getBasePath(),
|
||||
});
|
||||
};
|
||||
|
||||
private uiSettingsSubscription?: Subscription;
|
||||
|
||||
public componentDidMount() {
|
||||
this.uiSettingsSubscription = (chrome
|
||||
.getUiSettingsClient()
|
||||
.getUpdate$() as UiSettings$).subscribe({
|
||||
next: ({ key, newValue }) => {
|
||||
if (uiSettingsKeys.includes(key)) {
|
||||
this.setState(state => ({
|
||||
...state,
|
||||
uiSettings: {
|
||||
...state.uiSettings,
|
||||
[key]: newValue,
|
||||
},
|
||||
}));
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
public componentWillUnmount() {
|
||||
if (this.uiSettingsSubscription) {
|
||||
this.uiSettingsSubscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
||||
public render() {
|
||||
return this.props.children({
|
||||
...this.state,
|
||||
setBreadcrumbs: chrome.breadcrumbs.set,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue