Skip to content

Commit

Permalink
[Unified Observability] Add feature flag for the new overview page (#…
Browse files Browse the repository at this point in the history
…119193)

* Add feature flag to display a blank overview page when enabled

* Add tests for overview page feature flag

* Fix types

* Fix more types

* Remove duplicated BucketSize type

* fix linter

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
estermv and kibanamachine committed Nov 29, 2021
1 parent d9ee4d7 commit 2c41962
Show file tree
Hide file tree
Showing 12 changed files with 333 additions and 128 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,13 @@ describe('renderApp', () => {
uiSettings: { get: () => false },
http: { basePath: { prepend: (path: string) => path } },
} as unknown as CoreStart;
const config = { unsafe: { alertingExperience: { enabled: true }, cases: { enabled: true } } };
const config = {
unsafe: {
alertingExperience: { enabled: true },
cases: { enabled: true },
overviewNext: { enabled: false },
},
};
const params = {
element: window.document.createElement('div'),
history: createMemoryHistory(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,13 @@ describe('APMSection', () => {
http: { basePath: { prepend: jest.fn() } },
} as unknown as CoreStart,
appMountParameters: {} as AppMountParameters,
config: { unsafe: { alertingExperience: { enabled: true }, cases: { enabled: true } } },
config: {
unsafe: {
alertingExperience: { enabled: true },
cases: { enabled: true },
overviewNext: { enabled: false },
},
},
observabilityRuleTypeRegistry: createObservabilityRuleTypeRegistryMock(),
plugins: {
data: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,13 @@ describe('UXSection', () => {
http: { basePath: { prepend: jest.fn() } },
} as unknown as CoreStart,
appMountParameters: {} as AppMountParameters,
config: { unsafe: { alertingExperience: { enabled: true }, cases: { enabled: true } } },
config: {
unsafe: {
alertingExperience: { enabled: true },
cases: { enabled: true },
overviewNext: { enabled: false },
},
},
plugins: {
data: {
query: {
Expand Down
16 changes: 14 additions & 2 deletions x-pack/plugins/observability/public/hooks/use_time_range.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,13 @@ describe('useTimeRange', () => {
jest.spyOn(pluginContext, 'usePluginContext').mockImplementation(() => ({
core: {} as CoreStart,
appMountParameters: {} as AppMountParameters,
config: { unsafe: { alertingExperience: { enabled: true }, cases: { enabled: true } } },
config: {
unsafe: {
alertingExperience: { enabled: true },
cases: { enabled: true },
overviewNext: { enabled: false },
},
},
plugins: {
data: {
query: {
Expand Down Expand Up @@ -67,7 +73,13 @@ describe('useTimeRange', () => {
jest.spyOn(pluginContext, 'usePluginContext').mockImplementation(() => ({
core: {} as CoreStart,
appMountParameters: {} as AppMountParameters,
config: { unsafe: { alertingExperience: { enabled: true }, cases: { enabled: true } } },
config: {
unsafe: {
alertingExperience: { enabled: true },
cases: { enabled: true },
overviewNext: { enabled: false },
},
},
plugins: {
data: {
query: {
Expand Down
6 changes: 5 additions & 1 deletion x-pack/plugins/observability/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ export type {
export { enableInspectEsQueries } from '../common/ui_settings_keys';

export interface ConfigSchema {
unsafe: { alertingExperience: { enabled: boolean }; cases: { enabled: boolean } };
unsafe: {
alertingExperience: { enabled: boolean };
cases: { enabled: boolean };
overviewNext: { enabled: boolean };
};
}

export const plugin: PluginInitializer<
Expand Down
51 changes: 51 additions & 0 deletions x-pack/plugins/observability/public/pages/overview/index.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* 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 React from 'react';
import { shallow } from 'enzyme';
import * as PluginContext from '../../hooks/use_plugin_context';
import { PluginContextValue } from '../../context/plugin_context';
import { OverviewPage } from './';
import { OverviewPage as OldOverviewPage } from './old_overview_page';
import { OverviewPage as NewOverviewPage } from './overview_page';

describe('Overview page', () => {
it('should render the old overview page when feature flag is disabled', () => {
const pluginContext = {
config: {
unsafe: {
overviewNext: { enabled: false },
},
},
};

jest
.spyOn(PluginContext, 'usePluginContext')
.mockReturnValue(pluginContext as PluginContextValue);

const component = shallow(<OverviewPage routeParams={{ query: {} }} />);
expect(component.find(OldOverviewPage)).toHaveLength(1);
expect(component.find(NewOverviewPage)).toHaveLength(0);
});

it('should render the new overview page when feature flag is enabled', () => {
const pluginContext = {
config: {
unsafe: {
overviewNext: { enabled: true },
},
},
};

jest
.spyOn(PluginContext, 'usePluginContext')
.mockReturnValue(pluginContext as PluginContextValue);

const component = shallow(<OverviewPage routeParams={{ query: {} }} />);
expect(component.find(OldOverviewPage)).toHaveLength(0);
expect(component.find(NewOverviewPage)).toHaveLength(1);
});
});
131 changes: 11 additions & 120 deletions x-pack/plugins/observability/public/pages/overview/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,133 +4,24 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiPanel } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import { useTrackPageview } from '../..';
import { EmptySections } from '../../components/app/empty_sections';
import { ObservabilityHeaderMenu } from '../../components/app/header';
import { NewsFeed } from '../../components/app/news_feed';
import { Resources } from '../../components/app/resources';
import { AlertsSection } from '../../components/app/section/alerts';
import { DatePicker } from '../../components/shared/date_picker';
import { useBreadcrumbs } from '../../hooks/use_breadcrumbs';
import { useFetcher } from '../../hooks/use_fetcher';
import { useHasData } from '../../hooks/use_has_data';
import { usePluginContext } from '../../hooks/use_plugin_context';
import { useTimeRange } from '../../hooks/use_time_range';
import { RouteParams } from '../../routes';
import { getNewsFeed } from '../../services/get_news_feed';
import { getBucketSize } from '../../utils/get_bucket_size';
import { getNoDataConfig } from '../../utils/no_data_config';
import { DataSections } from './data_sections';
import { LoadingObservability } from './loading_observability';
import { usePluginContext } from '../../hooks/use_plugin_context';
import { OverviewPage as OldOverviewPage } from './old_overview_page';
import { OverviewPage as NewOverviewPage } from './overview_page';

export type { BucketSize } from './old_overview_page';

interface Props {
routeParams: RouteParams<'/overview'>;
}
export type BucketSize = ReturnType<typeof calculateBucketSize>;
function calculateBucketSize({ start, end }: { start?: number; end?: number }) {
if (start && end) {
return getBucketSize({ start, end, minInterval: '60s' });
}
}

export function OverviewPage({ routeParams }: Props) {
useTrackPageview({ app: 'observability-overview', path: 'overview' });
useTrackPageview({ app: 'observability-overview', path: 'overview', delay: 15000 });
useBreadcrumbs([
{
text: i18n.translate('xpack.observability.breadcrumbs.overviewLinkText', {
defaultMessage: 'Overview',
}),
},
]);

const { core, ObservabilityPageTemplate } = usePluginContext();

const { relativeStart, relativeEnd, absoluteStart, absoluteEnd } = useTimeRange();

const relativeTime = { start: relativeStart, end: relativeEnd };
const absoluteTime = { start: absoluteStart, end: absoluteEnd };
export function OverviewPage(props: Props) {
const { config } = usePluginContext();

const { data: newsFeed } = useFetcher(() => getNewsFeed({ core }), [core]);

const { hasDataMap, hasAnyData, isAllRequestsComplete } = useHasData();

if (hasAnyData === undefined) {
return <LoadingObservability />;
if (config.unsafe.overviewNext.enabled) {
return <NewOverviewPage {...props} />;
} else {
return <OldOverviewPage {...props} />;
}

const hasData = hasAnyData === true || (isAllRequestsComplete === false ? undefined : false);

const noDataConfig = getNoDataConfig({
hasData,
basePath: core.http.basePath,
docsLink: core.docLinks.links.observability.guide,
});

const { refreshInterval = 10000, refreshPaused = true } = routeParams.query;

const bucketSize = calculateBucketSize({
start: absoluteTime.start,
end: absoluteTime.end,
});

return (
<ObservabilityPageTemplate
noDataConfig={noDataConfig}
pageHeader={
hasData
? {
pageTitle: overviewPageTitle,
rightSideItems: [
<DatePicker
rangeFrom={relativeTime.start}
rangeTo={relativeTime.end}
refreshInterval={refreshInterval}
refreshPaused={refreshPaused}
/>,
],
}
: undefined
}
>
{hasData && (
<>
<ObservabilityHeaderMenu />
<EuiFlexGroup>
<EuiFlexItem grow={6}>
{/* Data sections */}
{hasAnyData && <DataSections bucketSize={bucketSize} />}
<EmptySections />
<EuiSpacer size="l" />
<EuiFlexGroup>
<EuiFlexItem>
{/* Resources / What's New sections */}
<EuiPanel hasBorder={true}>
<Resources />
<EuiSpacer size="l" />
{!!newsFeed?.items?.length && <NewsFeed items={newsFeed.items.slice(0, 5)} />}
</EuiPanel>
</EuiFlexItem>
{hasDataMap?.alert?.hasData && (
<EuiFlexItem>
<EuiPanel hasBorder={true}>
<AlertsSection />
</EuiPanel>
</EuiFlexItem>
)}
</EuiFlexGroup>
</EuiFlexItem>
</EuiFlexGroup>
</>
)}
</ObservabilityPageTemplate>
);
}

const overviewPageTitle = i18n.translate('xpack.observability.overview.pageTitle', {
defaultMessage: 'Overview',
});
Loading

0 comments on commit 2c41962

Please sign in to comment.