Migrate observability to new Kibana page template (#133021)

This commit is contained in:
Alison Goryachev 2022-06-08 10:55:58 -04:00 committed by GitHub
parent b7ae8a2efb
commit 346dea9cb5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 93 additions and 48 deletions

View file

@ -3,6 +3,7 @@
exports[`NoDataPage render 1`] = `
<div
className="kbnNoDataPageContents"
data-test-subj="kbnNoDataPage"
>
<EuiText
textAlign="center"

View file

@ -45,7 +45,10 @@ export const NoDataPage: FunctionComponent<NoDataPageProps> = ({
});
return (
<div className={classNames('kbnNoDataPageContents', rest.className)}>
<div
className={classNames('kbnNoDataPageContents', rest.className)}
data-test-subj="kbnNoDataPage"
>
<EuiText textAlign="center">
<KibanaSolutionAvatar name={solution} iconType={logo || `logo${solution}`} size="xxl" />
<EuiSpacer size="l" />

View file

@ -200,4 +200,4 @@ public start(coreStart: CoreStart, startPlugins: SharedUXPluginStartDeps): Share
## Use in Kibana plugins
In order to make consumption of these services easy by Kibana plugins, `src/plugins/shared_ux` provides a pre-wired set of services as part of the `start` lifecycle. Plugins can simply make `sharedUX` a dependency, import `SharedUsServicesProvider` and wrap their solution root (or any component). See the documentation for `sharedUX` for more details.
In order to make consumption of these services easy by Kibana plugins, `src/plugins/shared_ux` provides a pre-wired set of services as part of the `start` lifecycle. Plugins can simply make `sharedUX` a dependency, import `SharedUxServicesProvider` and wrap their solution root (or any component). See the documentation for `sharedUX` for more details.

View file

@ -0,0 +1,23 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { SharedUXPlugin } from './plugin';
export type Setup = jest.Mocked<ReturnType<SharedUXPlugin['setup']>>;
export type Start = jest.Mocked<ReturnType<SharedUXPlugin['start']>>;
const createStartContract = (): jest.Mocked<Start> => {
const startContract = {
getContextServices: jest.fn(),
};
return startContract;
};
export const sharedUXPluginMock = {
createStartContract,
};

View file

@ -8,10 +8,8 @@
import { EuiPageHeaderProps } from '@elastic/eui';
import React from 'react';
import { useLocation } from 'react-router-dom';
import {
useKibana,
KibanaPageTemplateProps,
} from '@kbn/kibana-react-plugin/public';
import { useKibana } from '@kbn/kibana-react-plugin/public';
import { KibanaPageTemplateProps } from '@kbn/shared-ux-components';
import { enableServiceGroups } from '@kbn/observability-plugin/public';
import { EnvironmentsContextProvider } from '../../../context/environments_context/environments_context';
import { useFetcher, FETCH_STATUS } from '../../../hooks/use_fetcher';

View file

@ -6,7 +6,7 @@
*/
import { i18n } from '@kbn/i18n';
import { KibanaPageTemplateProps } from '@kbn/kibana-react-plugin/public';
import { KibanaPageTemplateProps } from '@kbn/shared-ux-components';
export function getNoDataConfig({
docsLink,
@ -48,7 +48,7 @@ export function getNoDataConfig({
solution: i18n.translate('xpack.apm.noDataConfig.solutionName', {
defaultMessage: 'Observability',
}),
actions: {
action: {
elasticAgent: {
title: noDataConfigDetails.title,
description: i18n.translate('xpack.apm.ux.overview.agent.description', {

View file

@ -15,10 +15,8 @@ import {
} from '@elastic/eui';
import React from 'react';
import { i18n } from '@kbn/i18n';
import {
useKibana,
KibanaPageTemplateProps,
} from '@kbn/kibana-react-plugin/public';
import { useKibana } from '@kbn/kibana-react-plugin/public';
import { KibanaPageTemplateProps } from '@kbn/shared-ux-components';
import { enableServiceGroups } from '@kbn/observability-plugin/public';
import { useFetcher, FETCH_STATUS } from '../../../hooks/use_fetcher';
import { ApmPluginStartDeps } from '../../../plugin';

View file

@ -10,7 +10,8 @@ import { createMemoryHistory } from 'history';
import React from 'react';
import { Route, Router, Switch } from 'react-router-dom';
import { httpServiceMock } from '@kbn/core/public/mocks';
import { KibanaContextProvider, KibanaPageTemplate } from '@kbn/kibana-react-plugin/public';
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
import { KibanaPageTemplate } from '@kbn/shared-ux-components';
import { useLogView } from '../../hooks/use_log_view';
import {
createLoadedUseLogViewMock,

View file

@ -8,7 +8,8 @@
import React from 'react';
import { i18n } from '@kbn/i18n';
import type { LazyObservabilityPageTemplateProps } from '@kbn/observability-plugin/public';
import { KibanaPageTemplateProps, useKibana } from '@kbn/kibana-react-plugin/public';
import { useKibana } from '@kbn/kibana-react-plugin/public';
import { KibanaPageTemplateProps } from '@kbn/shared-ux-components';
import { useKibanaContextForPlugin } from '../../hooks/use_kibana';
interface LogsPageTemplateProps extends LazyObservabilityPageTemplateProps {
@ -38,7 +39,7 @@ export const LogsPageTemplate: React.FC<LogsPageTemplateProps> = ({
solution: i18n.translate('xpack.infra.logs.noDataConfig.solutionName', {
defaultMessage: 'Observability',
}),
actions: {
action: {
beats: {
title: i18n.translate('xpack.infra.logs.noDataConfig.beatsCard.title', {
defaultMessage: 'Add a logging integration',

View file

@ -8,7 +8,7 @@
import React from 'react';
import { i18n } from '@kbn/i18n';
import type { LazyObservabilityPageTemplateProps } from '@kbn/observability-plugin/public';
import { KibanaPageTemplateProps } from '@kbn/kibana-react-plugin/public';
import { KibanaPageTemplateProps } from '@kbn/shared-ux-components';
import { useKibanaContextForPlugin } from '../../hooks/use_kibana';
interface MetricsPageTemplateProps extends LazyObservabilityPageTemplateProps {
@ -35,7 +35,7 @@ export const MetricsPageTemplate: React.FC<MetricsPageTemplateProps> = ({
solution: i18n.translate('xpack.infra.metrics.noDataConfig.solutionName', {
defaultMessage: 'Observability',
}),
actions: {
action: {
beats: {
title: i18n.translate('xpack.infra.metrics.noDataConfig.beatsCard.title', {
defaultMessage: 'Add a metrics integration',

View file

@ -30,7 +30,8 @@
"timelines",
"triggersActionsUi",
"inspector",
"unifiedSearch"
"unifiedSearch",
"sharedUX"
],
"ui": true,
"server": true,

View file

@ -11,7 +11,7 @@ import React from 'react';
import { Observable } from 'rxjs';
import { AppMountParameters, CoreStart } from '@kbn/core/public';
import { themeServiceMock } from '@kbn/core/public/mocks';
import { KibanaPageTemplate } from '@kbn/kibana-react-plugin/public';
import { KibanaPageTemplate } from '@kbn/shared-ux-components';
import { ObservabilityPublicPluginsStart } from '../plugin';
import { createObservabilityRuleTypeRegistryMock } from '../rules/observability_rule_type_registry_mock';
import { renderApp } from '.';

View file

@ -17,7 +17,7 @@ import * as pluginContext from '../../../../hooks/use_plugin_context';
import { HasDataContextValue } from '../../../../context/has_data_context';
import { AppMountParameters } from '@kbn/core/public';
import { createObservabilityRuleTypeRegistryMock } from '../../../../rules/observability_rule_type_registry_mock';
import { KibanaPageTemplate } from '@kbn/kibana-react-plugin/public';
import { KibanaPageTemplate } from '@kbn/shared-ux-components';
jest.mock('react-router-dom', () => ({
useLocation: () => ({

View file

@ -10,6 +10,7 @@ import { render } from '@testing-library/react';
import { shallow } from 'enzyme';
import React from 'react';
import { of } from 'rxjs';
import { sharedUXPluginMock } from '@kbn/shared-ux-plugin/public/mocks';
import { createNavigationRegistry } from '../../../services/navigation_registry';
import { createLazyObservabilityPageTemplate } from './lazy_page_template';
import { ObservabilityPageTemplate } from './page_template';
@ -51,6 +52,7 @@ describe('Page template', () => {
getUrlForApp: () => '/test-url',
navigateToApp: async () => {},
navigationSections$: navigationRegistry.sections$,
getSharedUXContext: sharedUXPluginMock.createStartContract().getContextServices,
});
const component = shallow(
@ -74,6 +76,7 @@ describe('Page template', () => {
getUrlForApp={() => '/test-url'}
navigateToApp={async () => {}}
navigationSections$={navigationRegistry.sections$}
getSharedUXContext={sharedUXPluginMock.createStartContract().getContextServices}
pageHeader={{
pageTitle: 'Test title',
rightSideItems: [<span>Test side item</span>],
@ -94,6 +97,7 @@ describe('Page template', () => {
getUrlForApp={() => '/test-url'}
navigateToApp={async () => {}}
navigationSections$={navigationRegistry.sections$}
getSharedUXContext={sharedUXPluginMock.createStartContract().getContextServices}
pageHeader={{
pageTitle: 'Test title',
rightSideItems: [<span>Test side item</span>],

View file

@ -12,7 +12,9 @@ import { matchPath, useLocation } from 'react-router-dom';
import useObservable from 'react-use/lib/useObservable';
import type { Observable } from 'rxjs';
import type { ApplicationStart } from '@kbn/core/public';
import { KibanaPageTemplate, KibanaPageTemplateProps } from '@kbn/kibana-react-plugin/public';
import { SharedUxServicesProvider } from '@kbn/shared-ux-services';
import type { SharedUXPluginStart } from '@kbn/shared-ux-plugin/public';
import { KibanaPageTemplate, KibanaPageTemplateProps } from '@kbn/shared-ux-components';
import type { NavigationSection } from '../../../services/navigation_registry';
import { NavNameWithBadge, hideBadge } from './nav_name_with_badge';
@ -38,6 +40,7 @@ export interface ObservabilityPageTemplateDependencies {
getUrlForApp: ApplicationStart['getUrlForApp'];
navigateToApp: ApplicationStart['navigateToApp'];
navigationSections$: Observable<NavigationSection[]>;
getSharedUXContext: SharedUXPluginStart['getContextServices'];
}
export type ObservabilityPageTemplateProps = ObservabilityPageTemplateDependencies &
@ -49,12 +52,14 @@ export function ObservabilityPageTemplate({
getUrlForApp,
navigateToApp,
navigationSections$,
getSharedUXContext,
showSolutionNav = true,
...pageTemplateProps
}: ObservabilityPageTemplateProps): React.ReactElement | null {
const sections = useObservable(navigationSections$, []);
const currentAppId = useObservable(currentAppId$, undefined);
const { pathname: currentPath } = useLocation();
const sharedUXServices = getSharedUXContext();
const sideNavItems = useMemo<Array<EuiSideNavItemType<unknown>>>(
() =>
@ -118,21 +123,23 @@ export function ObservabilityPageTemplate({
);
return (
<KibanaPageTemplate
restrictWidth={false}
{...pageTemplateProps}
solutionNav={
showSolutionNav
? {
icon: 'logoObservability',
items: sideNavItems,
name: sideNavTitle,
}
: undefined
}
>
{children}
</KibanaPageTemplate>
<SharedUxServicesProvider {...sharedUXServices}>
<KibanaPageTemplate
restrictWidth={false}
{...pageTemplateProps}
solutionNav={
showSolutionNav
? {
icon: 'logoObservability',
items: sideNavItems,
name: sideNavTitle,
}
: undefined
}
>
{children}
</KibanaPageTemplate>
</SharedUxServicesProvider>
);
}

View file

@ -9,7 +9,8 @@ import React, { ComponentType } from 'react';
import { MemoryRouter } from 'react-router-dom';
import { AppMountParameters } from '@kbn/core/public';
import { CoreStart } from '@kbn/core/public';
import { createKibanaReactContext, KibanaPageTemplate } from '@kbn/kibana-react-plugin/public';
import { KibanaPageTemplate } from '@kbn/shared-ux-components';
import { createKibanaReactContext } from '@kbn/kibana-react-plugin/public';
import { casesFeatureId } from '../../../common';
import { PluginContext, PluginContextValue } from '../../context/plugin_context';
import { CasesPage } from '.';

View file

@ -11,7 +11,8 @@ import { AppMountParameters, CoreStart } from '@kbn/core/public';
import React, { ReactNode } from 'react';
import { MemoryRouter } from 'react-router-dom';
import { UI_SETTINGS } from '@kbn/data-plugin/public';
import { createKibanaReactContext, KibanaPageTemplate } from '@kbn/kibana-react-plugin/public';
import { createKibanaReactContext } from '@kbn/kibana-react-plugin/public';
import { KibanaPageTemplate } from '@kbn/shared-ux-components';
import { HasDataContextProvider } from '../../context/has_data_context';
import { PluginContext } from '../../context/plugin_context';
import { ObservabilityPublicPluginsStart } from '../../plugin';

View file

@ -15,7 +15,7 @@ import { RulesPage } from '.';
import { RulesTable } from './components/rules_table';
import { kibanaStartMock } from '../../utils/kibana_react.mock';
import * as pluginContext from '../../hooks/use_plugin_context';
import { KibanaPageTemplate } from '@kbn/kibana-react-plugin/public';
import { KibanaPageTemplate } from '@kbn/shared-ux-components';
import { createObservabilityRuleTypeRegistryMock } from '../../rules/observability_rule_type_registry_mock';
import { AppMountParameters } from '@kbn/core/public';
import { ALERTS_FEATURE_ID } from '@kbn/alerting-plugin/common';

View file

@ -27,6 +27,7 @@ import type { FeaturesPluginStart } from '@kbn/features-plugin/public';
import type { HomePublicPluginSetup, HomePublicPluginStart } from '@kbn/home-plugin/public';
import { CasesDeepLinkId, CasesUiStart, getCasesDeepLinks } from '@kbn/cases-plugin/public';
import type { LensPublicStart } from '@kbn/lens-plugin/public';
import type { SharedUXPluginStart } from '@kbn/shared-ux-plugin/public';
import {
TriggersAndActionsUIPublicPluginSetup,
TriggersAndActionsUIPublicPluginStart,
@ -68,6 +69,7 @@ export interface ObservabilityPublicPluginsStart {
discover: DiscoverStart;
features: FeaturesPluginStart;
kibanaFeatures: KibanaFeature[];
sharedUX: SharedUXPluginStart;
}
export type ObservabilityPublicStart = ReturnType<Plugin['start']>;
@ -148,6 +150,7 @@ export class Plugin
const { renderApp } = await import('./application');
// Get start services
const [coreStart, pluginsStart, { navigation }] = await coreSetup.getStartServices();
// Register alerts metadata
const { registerAlertsTableConfiguration } = await import(
'./config/register_alerts_table_configuration'
@ -293,6 +296,7 @@ export class Plugin
getUrlForApp: application.getUrlForApp,
navigateToApp: application.navigateToApp,
navigationSections$: this.navigationRegistry.sections$,
getSharedUXContext: pluginsStart.sharedUX.getContextServices,
});
return {

View file

@ -7,7 +7,7 @@
import { i18n } from '@kbn/i18n';
import { IBasePath } from '@kbn/core/public';
import { KibanaPageTemplateProps } from '@kbn/kibana-react-plugin/public';
import { KibanaPageTemplateProps } from '@kbn/shared-ux-components';
export function getNoDataConfig({
docsLink,
@ -23,7 +23,7 @@ export function getNoDataConfig({
solution: i18n.translate('xpack.observability.noDataConfig.solutionName', {
defaultMessage: 'Observability',
}),
actions: {
action: {
elasticAgent: {
title: i18n.translate('xpack.observability.noDataConfig.beatsCard.title', {
defaultMessage: 'Add integrations',

View file

@ -11,7 +11,8 @@ import { AppMountParameters } from '@kbn/core/public';
import { coreMock } from '@kbn/core/public/mocks';
import React from 'react';
import { __IntlProvider as IntlProvider } from '@kbn/i18n-react';
import { KibanaContextProvider, KibanaPageTemplate } from '@kbn/kibana-react-plugin/public';
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
import { KibanaPageTemplate } from '@kbn/shared-ux-components';
import translations from '@kbn/translations-plugin/translations/ja-JP.json';
import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common';
import { dataPluginMock } from '@kbn/data-plugin/public/mocks';

View file

@ -29,6 +29,7 @@
{ "path": "../spaces/tsconfig.json" },
{ "path": "../timelines/tsconfig.json"},
{ "path": "../translations/tsconfig.json" },
{ "path": "../../../src/plugins/unified_search/tsconfig.json"}
{ "path": "../../../src/plugins/unified_search/tsconfig.json"},
{ "path": "../../../src/plugins/shared_ux/tsconfig.json" },
]
}

View file

@ -8,7 +8,8 @@
import { i18n } from '@kbn/i18n';
import { useContext } from 'react';
import { useSelector } from 'react-redux';
import { KibanaPageTemplateProps, useKibana } from '@kbn/kibana-react-plugin/public';
import { useKibana } from '@kbn/kibana-react-plugin/public';
import { KibanaPageTemplateProps } from '@kbn/shared-ux-components';
import { UptimeSettingsContext } from '../contexts';
import { ClientPluginsStart } from '../../plugin';
import { indexStatusSelector } from '../state/selectors';
@ -28,7 +29,7 @@ export function useNoDataConfig(): KibanaPageTemplateProps['noDataConfig'] {
solution: i18n.translate('xpack.synthetics.noDataConfig.solutionName', {
defaultMessage: 'Observability',
}),
actions: {
action: {
beats: {
title: i18n.translate('xpack.synthetics.noDataConfig.beatsCard.title', {
defaultMessage: 'Add monitors with Heartbeat',

View file

@ -8,7 +8,7 @@
import React, { Fragment } from 'react';
import { i18n } from '@kbn/i18n';
import { EuiFlexGroup, EuiTitle, EuiFlexItem } from '@elastic/eui';
import { KibanaPageTemplateProps } from '@kbn/kibana-react-plugin/public';
import { KibanaPageTemplateProps } from '@kbn/shared-ux-components';
import { CsmSharedContextProvider } from './csm_shared_context';
import { WebApplicationSelect } from './panels/web_application_select';
import { UserPercentile } from './user_percentile';
@ -37,7 +37,7 @@ export function RumHome() {
solution: i18n.translate('xpack.ux.overview.solutionName', {
defaultMessage: 'Observability',
}),
actions: {
action: {
elasticAgent: {
title: i18n.translate('xpack.ux.overview.beatsCard.title', {
defaultMessage: 'Add RUM data',

View file

@ -8,7 +8,6 @@
import { FtrProviderContext } from '../../../ftr_provider_context';
export default function ({ loadTestFile }: FtrProviderContext) {
// FLAKY: https://github.com/elastic/kibana/issues/35932
describe('feature controls', function () {
this.tags('skipFirefox');
loadTestFile(require.resolve('./infrastructure_security'));