Skip to content

Commit

Permalink
[Logs UI] Add shared observability page template and navigation (#99380)
Browse files Browse the repository at this point in the history
Co-authored-by: Kerry Gallagher <471693+Kerry350@users.noreply.github.com>
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
3 people committed May 27, 2021
1 parent 7fc4a1f commit 06d276e
Show file tree
Hide file tree
Showing 30 changed files with 680 additions and 234 deletions.
4 changes: 4 additions & 0 deletions x-pack/plugins/observability/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ xpack.ruleRegistry.write.enabled: true
When both of the these are set to `true`, your alerts should show on the alerts page.

## Shared navigation

The Observability plugin maintains a navigation registry for Observability solutions, and exposes a shared page template component. Please refer to the docs in [the component directory](./components/shared/page_template/README.md) for more information on registering your solution's navigation structure, and rendering the navigation via the shared component.

## Unit testing

Note: Run the following commands from `kibana/x-pack/plugins/observability`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { createMemoryHistory } from 'history';
import React from 'react';
import { Observable } from 'rxjs';
import { AppMountParameters, CoreStart } from 'src/core/public';
import { KibanaPageTemplate } from '../../../../../src/plugins/kibana_react/public';
import { ObservabilityPublicPluginsStart } from '../plugin';
import { createObservabilityRuleTypeRegistryMock } from '../rules/observability_rule_type_registry_mock';
import { renderApp } from './';
Expand Down Expand Up @@ -59,6 +60,7 @@ describe('renderApp', () => {
plugins,
appMountParameters: params,
observabilityRuleTypeRegistry: createObservabilityRuleTypeRegistryMock(),
ObservabilityPageTemplate: KibanaPageTemplate,
});
unmount();
}).not.toThrowError();
Expand Down
19 changes: 16 additions & 3 deletions x-pack/plugins/observability/public/application/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import React, { MouseEvent, useEffect } from 'react';
import ReactDOM from 'react-dom';
import { Route, Router, Switch } from 'react-router-dom';
import { EuiThemeProvider } from '../../../../../src/plugins/kibana_react/common';
import { AppMountParameters, CoreStart } from '../../../../../src/core/public';
import { AppMountParameters, APP_WRAPPER_CLASS, CoreStart } from '../../../../../src/core/public';
import {
KibanaContextProvider,
RedirectAppLinks,
Expand All @@ -19,6 +19,7 @@ import { PluginContext } from '../context/plugin_context';
import { usePluginContext } from '../hooks/use_plugin_context';
import { useRouteParams } from '../hooks/use_route_params';
import { ObservabilityPublicPluginsStart } from '../plugin';
import type { LazyObservabilityPageTemplateProps } from '../components/shared/page_template/lazy_page_template';
import { HasDataContextProvider } from '../context/has_data_context';
import { Breadcrumbs, routes } from '../routes';
import { Storage } from '../../../../../src/plugins/kibana_utils/public';
Expand Down Expand Up @@ -74,12 +75,14 @@ export const renderApp = ({
plugins,
appMountParameters,
observabilityRuleTypeRegistry,
ObservabilityPageTemplate,
}: {
config: ConfigSchema;
core: CoreStart;
plugins: ObservabilityPublicPluginsStart;
observabilityRuleTypeRegistry: ObservabilityRuleTypeRegistry;
appMountParameters: AppMountParameters;
ObservabilityPageTemplate: React.ComponentType<LazyObservabilityPageTemplateProps>;
}) => {
const { element, history } = appMountParameters;
const i18nCore = core.i18n;
Expand All @@ -92,15 +95,25 @@ export const renderApp = ({
links: [{ linkType: 'discuss', href: 'https://ela.st/observability-discuss' }],
});

// ensure all divs are .kbnAppWrappers
element.classList.add(APP_WRAPPER_CLASS);

ReactDOM.render(
<KibanaContextProvider services={{ ...core, ...plugins, storage: new Storage(localStorage) }}>
<PluginContext.Provider
value={{ appMountParameters, config, core, plugins, observabilityRuleTypeRegistry }}
value={{
appMountParameters,
config,
core,
plugins,
observabilityRuleTypeRegistry,
ObservabilityPageTemplate,
}}
>
<Router history={history}>
<EuiThemeProvider darkMode={isDarkMode}>
<i18nCore.Context>
<RedirectAppLinks application={core.application}>
<RedirectAppLinks application={core.application} className={APP_WRAPPER_CLASS}>
<HasDataContextProvider>
<App />
</HasDataContextProvider>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { EuiHeaderLink, EuiHeaderLinks } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import { usePluginContext } from '../../../hooks/use_plugin_context';
import HeaderMenuPortal from '../../shared/header_menu_portal';

export function ObservabilityHeaderMenu(): React.ReactElement | null {
const {
appMountParameters: { setHeaderActionMenu },
core: {
http: {
basePath: { prepend },
},
},
} = usePluginContext();

return (
<HeaderMenuPortal setHeaderActionMenu={setHeaderActionMenu}>
<EuiHeaderLinks>
<EuiHeaderLink
color="primary"
href={prepend('/app/home#/tutorial_directory/logging')}
iconType="indexOpen"
>
{addDataLinkText}
</EuiHeaderLink>
</EuiHeaderLinks>
</HeaderMenuPortal>
);
}

const addDataLinkText = i18n.translate('xpack.observability.home.addData', {
defaultMessage: 'Add data',
});

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,81 +5,4 @@
* 2.0.
*/

import {
EuiFlexGroup,
EuiFlexItem,
EuiHeaderLink,
EuiHeaderLinks,
EuiIcon,
EuiSpacer,
EuiTitle,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React, { ReactNode } from 'react';
import styled from 'styled-components';
import { usePluginContext } from '../../../hooks/use_plugin_context';
import HeaderMenuPortal from '../../shared/header_menu_portal';

const Container = styled.div<{ color: string }>`
background: ${(props) => props.color};
border-bottom: ${(props) => props.theme.eui.euiBorderThin};
`;

const Wrapper = styled.div<{ restrictWidth?: number }>`
width: 100%;
max-width: ${(props) => `${props.restrictWidth}px`};
margin: 0 auto;
overflow: hidden;
padding: 0 16px;
`;

interface Props {
color: string;
datePicker?: ReactNode;
restrictWidth?: number;
}

export function Header({ color, datePicker = null, restrictWidth }: Props) {
const { appMountParameters, core } = usePluginContext();
const { setHeaderActionMenu } = appMountParameters;
const { prepend } = core.http.basePath;

return (
<Container color={color}>
<HeaderMenuPortal setHeaderActionMenu={setHeaderActionMenu}>
<EuiHeaderLinks>
<EuiHeaderLink
color="primary"
href={prepend('/app/home#/tutorial_directory/logging')}
iconType="indexOpen"
>
{i18n.translate('xpack.observability.home.addData', { defaultMessage: 'Add data' })}
</EuiHeaderLink>
</EuiHeaderLinks>
</HeaderMenuPortal>
<Wrapper restrictWidth={restrictWidth}>
<EuiSpacer size="l" />
<EuiFlexGroup justifyContent="spaceBetween" alignItems="center">
<EuiFlexItem>
<EuiFlexGroup>
<EuiFlexItem grow={false}>
<EuiIcon type="logoObservability" size="xxl" data-test-subj="observability-logo" />
</EuiFlexItem>
<EuiFlexItem grow={false} style={{ alignSelf: 'center' }}>
<EuiTitle>
<h1>
{i18n.translate('xpack.observability.home.title', {
defaultMessage: 'Observability',
})}
</h1>
</EuiTitle>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
<EuiFlexItem grow={false}>{datePicker}</EuiFlexItem>
</EuiFlexGroup>
<EuiSpacer size="l" />
</Wrapper>
</Container>
);
}
export * from './header_menu';

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { HasDataContextValue } from '../../../../context/has_data_context';
import { AppMountParameters, CoreStart } from 'kibana/public';
import { ObservabilityPublicPluginsStart } from '../../../../plugin';
import { createObservabilityRuleTypeRegistryMock } from '../../../../rules/observability_rule_type_registry_mock';
import { KibanaPageTemplate } from '../../../../../../../../src/plugins/kibana_react/public';

jest.mock('react-router-dom', () => ({
useLocation: () => ({
Expand Down Expand Up @@ -57,6 +58,7 @@ describe('APMSection', () => {
},
},
} as unknown) as ObservabilityPublicPluginsStart,
ObservabilityPageTemplate: KibanaPageTemplate,
}));
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { render } from '../../../../utils/test_helper';
import { UXSection } from './';
import { response } from './mock_data/ux.mock';
import { createObservabilityRuleTypeRegistryMock } from '../../../../rules/observability_rule_type_registry_mock';
import { KibanaPageTemplate } from '../../../../../../../../src/plugins/kibana_react/public';

jest.mock('react-router-dom', () => ({
useLocation: () => ({
Expand Down Expand Up @@ -56,6 +57,7 @@ describe('UXSection', () => {
},
} as unknown) as ObservabilityPublicPluginsStart,
observabilityRuleTypeRegistry: createObservabilityRuleTypeRegistryMock(),
ObservabilityPageTemplate: KibanaPageTemplate,
}));
});
it('renders with core web vitals', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import React, { lazy, Suspense } from 'react';
import type { CoreVitalProps, HeaderMenuPortalProps } from './types';
import type { FieldValueSuggestionsProps } from './field_value_suggestions/types';

export { createLazyObservabilityPageTemplate } from './page_template';

const CoreVitalsLazy = lazy(() => import('./core_web_vitals/index'));

export function getCoreVitalsComponent(props: CoreVitalProps) {
Expand Down
Loading

0 comments on commit 06d276e

Please sign in to comment.