Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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