Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Logs UI] Add shared observability page template and navigation #99380

Merged
merged 31 commits into from
May 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
240e9e6
Add and expose observability navigation registry
weltenwort May 5, 2021
2da5a42
Ensure app ancestor elements are all .kbnAppWrappers
weltenwort May 5, 2021
da3b0f6
Add and expose ObservabilityPageTemplate
weltenwort May 5, 2021
73de772
Render registered sections in sidebar
weltenwort May 5, 2021
4ba587b
Fix some unit tests
weltenwort May 6, 2021
66b38cb
Merge remote-tracking branch 'upstream/master' into obs-shared-naviga…
Kerry350 May 10, 2021
b0ed73c
Merge remote-tracking branch 'upstream/master' into obs-shared-naviga…
Kerry350 May 11, 2021
3a7bf51
EuiPageTemplate -> KibanaPageTemplate
Kerry350 May 11, 2021
9c68901
Add docs
Kerry350 May 12, 2021
edffa8a
Use the new ObservabilityPageTemplate component on the cases and aler…
Kerry350 May 13, 2021
716a0fe
Unit tests
Kerry350 May 14, 2021
8f70f54
Merge remote-tracking branch 'upstream/master' into obs-shared-naviga…
Kerry350 May 14, 2021
f2e53e8
Merge branch 'master' into obs-shared-navigation
kibanamachine May 19, 2021
7fcd976
Inject stub page template into obs overview story
weltenwort May 19, 2021
ca8ac77
Use the KibanaPageTemplate as a stub for tests
weltenwort May 19, 2021
0207eb1
Remove initial empty section array
weltenwort May 20, 2021
128e7e0
Make page template tests more specific
weltenwort May 20, 2021
d566116
Remove comments and unused imports
weltenwort May 20, 2021
6f70ef9
Merge branch 'master' into obs-shared-navigation
weltenwort May 20, 2021
6a89fcb
Merge branch 'master' into obs-shared-navigation
weltenwort May 25, 2021
d9640ae
Import from react-use more narrowly
weltenwort May 25, 2021
f71315b
Remove old header layout component
weltenwort May 25, 2021
15c2810
Merge branch 'master' into obs-shared-navigation
weltenwort May 25, 2021
ad51822
Use the stylized solution side nav
weltenwort May 25, 2021
064fc7c
Use the app wrapper class constant from core
weltenwort May 25, 2021
4107854
Remove unused header code
weltenwort May 25, 2021
05ad60f
Fix translation strings
weltenwort May 25, 2021
cd4aebd
Fix lazy wrapper prop type import
weltenwort May 25, 2021
c959474
Merge branch 'master' into obs-shared-navigation
weltenwort May 25, 2021
f5b47e2
Merge branch 'master' into obs-shared-navigation
weltenwort May 27, 2021
9f5f622
Fix full-page loading spinner
weltenwort May 27, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions x-pack/plugins/observability/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,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