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

[Observability] New "No Data" screens #107709

Merged
merged 102 commits into from
Oct 6, 2021
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
202fba7
Initial commit of new NoDataPage and accompanying cards
Aug 4, 2021
e6c1290
Adding to Security Solution and forcing view in TemplateWrapper
Aug 4, 2021
0ac66b8
Center page
Aug 4, 2021
5274c96
Better customizations & sorting on `recommended`
Aug 5, 2021
66445f8
Adding custom size to Solution Nav Avatar for reuse and working on pa…
Aug 5, 2021
495e905
Put SetupGuideCTA back
Aug 5, 2021
4600e9a
Fix TS
Aug 5, 2021
80e2063
Added empty state to Infra/Logs
Aug 5, 2021
d7c2e29
Added to APM
Aug 5, 2021
4563cad
Added to Metrics template
Aug 5, 2021
b774ecb
Added to Uptime and fixed layouts
Aug 5, 2021
b2ce1c3
Fixing UX layout
Aug 5, 2021
5f98d10
Merge remote-tracking branch 'upstream/master' into design/add_data_s…
Aug 5, 2021
ab8c4bd
Faked in for UX
Aug 5, 2021
c981540
Removing outer template from no data page
Aug 5, 2021
549ee0a
Optimizing some prop usages
Aug 6, 2021
8c0acc4
Making `noDataConfig` a view in KibanaPageTemplate
Aug 6, 2021
67c7b6a
Working on links
Aug 6, 2021
6e4e53b
Obs Getting Started page (without solution nav)
Aug 9, 2021
7850037
Cleanup
Aug 9, 2021
a0128dd
Fix i18n
Aug 9, 2021
0f3b96b
Dev docs
Aug 9, 2021
b3152c6
Only one link for solutions
snide Aug 11, 2021
23ad9ac
Fix double templates in Uptime
Aug 11, 2021
6fe3a39
Move styles to page contents Sass file and only add min width when th…
Aug 11, 2021
a5defa0
cleanup
Aug 11, 2021
3e6d656
Adding tests to template.
Aug 11, 2021
31676e3
Removing a few hard-coded checks to test tests
Aug 11, 2021
fbf3267
Actually fix tests for cards
Aug 11, 2021
20b0e4e
i18n
Aug 11, 2021
d3fdc9e
Merge branch 'master' into design/add_data_screens
cchaos Aug 11, 2021
c13cfe3
Merge branch 'elastic:master' into design/add_data_screens
cchaos Aug 12, 2021
76da749
Merge remote-tracking branch 'upstream/master' into design/add_data_s…
Aug 13, 2021
64661d7
Rebase fixes
Aug 13, 2021
7e3e60a
Mroe rebase fixes, cleanup, and links
Aug 13, 2021
57a66d6
Merge branch 'master' into design/add_data_screens
cchaos Aug 13, 2021
81a444b
Fix ES test
Aug 13, 2021
da83c6c
Skipping security solution test for now
Aug 13, 2021
82d2f40
Hopefully fixing some tests
Aug 13, 2021
9bc06ae
Merge remote-tracking branch 'upstream/master' into design/add_data_s…
Aug 14, 2021
82e5649
Revert "Skipping security solution test for now"
Aug 16, 2021
3be7b0d
Revert "Adding to Security Solution and forcing view in TemplateWrapper"
Aug 16, 2021
255acbe
More Security Solution reverts
Aug 16, 2021
f957968
Merge branch 'master' into design/add_data_screens
cchaos Aug 16, 2021
33f922f
Update beats card default text to just `Add data`
Aug 16, 2021
ab018d7
Updated RUM copy
Aug 16, 2021
54d0d49
Updating Uptime copy
Aug 16, 2021
5c852fb
Update APM copy
Aug 16, 2021
6e9c8ce
Updating Logs copy and reverting changes to `page_no_indices_content`…
Aug 16, 2021
25e711a
Updated copy for Metrics
Aug 16, 2021
4f0613c
Updated copy for landing and overview pages
Aug 16, 2021
7ef38f3
[ElasticBeatsCard] Reuse `title` as default button label
Aug 16, 2021
2e9346f
Better SS revert
Aug 16, 2021
d041c81
`agent` not `Agent`
Aug 16, 2021
bd8d2b1
Merge branch 'master' into design/add_data_screens
cchaos Aug 18, 2021
7cd45fc
Merge branch 'master' into design/add_data_screens
cchaos Aug 25, 2021
683c1f1
logic to show no data screen
cauemarcondes Sep 8, 2021
26fcbbf
Merge pull request #31 from cauemarcondes/apm-new-no-data-screen
cchaos Sep 8, 2021
a9f9989
Merge remote-tracking branch upstream/master into design/add_data_scr…
Sep 8, 2021
a72d42e
i18n
Sep 8, 2021
4f233c1
Merge remote-tracking branch 'upstream/master' into design/add_data_s…
Sep 9, 2021
30f86a8
Merge branch 'master' into design/add_data_screens
cchaos Sep 13, 2021
5f39a8f
Fixing bad rebase in APM template
cchaos Sep 13, 2021
b92fca9
Delete historical_data.ts
cchaos Sep 13, 2021
33dc8dc
Fix from rebase to Overview page
cchaos Sep 13, 2021
1276d50
Merge branch 'master' into design/add_data_screens
cchaos Sep 16, 2021
604f590
Fix RumHome from rebase
cchaos Sep 16, 2021
fdd84aa
Use KibanaPageTemplateProps
cchaos Sep 17, 2021
f6cc266
Merge branch 'master' into design/add_data_screens
cchaos Sep 20, 2021
30b7d6f
Add `hasData` prop to `LogsPageTemplate`
Sep 21, 2021
edf7e97
Check for data in log pages
Sep 21, 2021
8921313
Add `hasData` prop to `MetricsPageTemplate`
Sep 21, 2021
89c16eb
Check for data in metrics pages
Sep 21, 2021
e4a5a23
Merge branch 'master' into design/add_data_screens
cchaos Sep 21, 2021
6c7d151
Fix bad rebase to routes
cchaos Sep 21, 2021
1493eab
Add test subject to no data screen
Sep 22, 2021
bbfc4e5
Fix log entry categories tab test
Sep 22, 2021
fa13307
Fix infrastructure_security test
Sep 22, 2021
9d6e9af
Remove hard-coded DTS on NoDataPage and ensure one is passed through …
Sep 22, 2021
0372ce0
Fix lint error
Sep 22, 2021
9aad198
Merge branch 'master' into design/add_data_screens
kibanamachine Sep 22, 2021
cc4ae52
Remove DTS test 🤦‍♀️
Sep 22, 2021
bc2b3f4
enable no data view on tls certificate route
shahzad31 Sep 22, 2021
45b0070
Fix uptime page layout
Sep 22, 2021
d5fc41f
Remove unnecessary check for the metrics settings page
Sep 27, 2021
6c5823e
Merge branch 'master' into design/add_data_screens
kibanamachine Sep 28, 2021
b6f42aa
Merge branch 'master' into design/add_data_screens
kibanamachine Sep 30, 2021
847fec7
Fix metrics no indices test
Oct 1, 2021
d2fbe0f
Fix more tests
Oct 1, 2021
e976f05
Fix logEntryRate test
Oct 4, 2021
a6507b2
Fix spaces tests
Oct 4, 2021
f0142d9
Merge branch 'master' of github.com:elastic/kibana into design/add_da…
shahzad31 Oct 4, 2021
6923af0
Merge branch 'master' into design/add_data_screens
kibanamachine Oct 4, 2021
94cc373
update timeout
shahzad31 Oct 5, 2021
83b50e0
Fix even more tests
Oct 5, 2021
1a9bf58
update test
shahzad31 Oct 5, 2021
7ac8c56
Fix test for new index patterns
Oct 5, 2021
87d5be8
Merge branch 'master' into design/add_data_screens
cchaos Oct 5, 2021
9461716
Merge branch 'master' into design/add_data_screens
kibanamachine Oct 5, 2021
b3164c5
Merge branch 'master' into design/add_data_screens
kibanamachine Oct 6, 2021
69abe1d
Merge branch 'master' into design/add_data_screens
kibanamachine Oct 6, 2021
0707c30
remove uptime flaky test
shahzad31 Oct 6, 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
1 change: 1 addition & 0 deletions src/plugins/kibana_react/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export * from './overlays';
export * from './ui_settings';
export * from './field_icon';
export * from './field_button';
export * from './no_data_page';
export * from './table_list_view';
export * from './toolbar_button';
export * from './split_panel';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.kbnNoDataPageContents__item:only-child {
min-width: 400px;

@include euiBreakpoint('xs', 's') {
min-width: auto;
}
}
202 changes: 202 additions & 0 deletions src/plugins/kibana_react/public/no_data_page/no_data_page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
/*
* 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 './no_data_page.scss';

import React, { ReactNode, useMemo, FunctionComponent, MouseEventHandler } from 'react';
import {
EuiFlexItem,
EuiCardProps,
EuiFlexGrid,
EuiSpacer,
EuiText,
EuiTextColor,
EuiLink,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import { KibanaPageTemplateProps, KibanaPageTemplateSolutionNavAvatar } from '../page_template';

import { ElasticAgentCard, ElasticBeatsCard, NoDataCard } from './no_data_card';

export const NO_DATA_PAGE_MAX_WIDTH = 950;
export const NO_DATA_PAGE_TEMPLATE_PROPS: KibanaPageTemplateProps = {
restrictWidth: NO_DATA_PAGE_MAX_WIDTH,
template: 'centeredBody',
pageContentProps: {
hasShadow: false,
color: 'transparent',
},
};

export const NO_DATA_RECOMMENDED = i18n.translate(
'kibana-react.noDataPage.noDataPage.recommended',
{
defaultMessage: 'Recommended',
}
);

export type NoDataPageActions = Partial<EuiCardProps> & {
/**
* Applies the `Recommended` beta badge and makes the button `fill`
*/
recommended?: boolean;
/**
* Provide just a string for the button's label, or a whole component
*/
button?: string | ReactNode;
/**
* Remapping `onClick` to any element
*/
onClick?: MouseEventHandler<HTMLElement>;
};

export type NoDataPageActionsProps = Record<string, NoDataPageActions>;

export interface NoDataPageProps {
/**
* Single name for the current solution, used to auto-generate the title, logo, description, and button label
*/
solution: string;
/**
* Optionally replace the auto-generated logo
*/
logo?: string;
/**
* Required to set the docs link for the whole solution
*/
docsLink: string;
/**
* Optionally replace the auto-generated page title (h1)
*/
pageTitle?: string;
/**
* An object of `NoDataPageActions` configurations with unique primary keys.
* Use `elasticAgent` or `beats` as the primary key for pre-configured cards of this type.
* Otherwise use a custom key that contains `EuiCard` props.
*/
actions: NoDataPageActionsProps;
}

export const NoDataPage: FunctionComponent<NoDataPageProps> = ({
solution,
logo,
actions,
docsLink,
pageTitle,
}) => {
// Convert obj data into an iterable array
const entries = Object.entries(actions);

// This sort fn may look nonsensical, but it's some Good Ol' Javascript (TM)
// Sort functions want either a 1, 0, or -1 returned to determine order,
// and it turns out in JS you CAN minus booleans from each other to get a 1, 0, or -1 - e.g., (true - false == 1) :whoa:
const sortedEntries = entries.sort(([, firstObj], [, secondObj]) => {
// The `??` fallbacks are because the recommended key can be missing or undefined
return Number(secondObj.recommended ?? false) - Number(firstObj.recommended ?? false);
});

// Convert the iterated [[key, value]] array format back into an object
const sortedData = Object.fromEntries(sortedEntries);
const actionsKeys = Object.keys(sortedData);
const renderActions = useMemo(() => {
return Object.values(sortedData).map((action, i) => {
if (actionsKeys[i] === 'elasticAgent') {
return (
<EuiFlexItem key={`empty-page-agent-action`} className="kbnNoDataPageContents__item">
<ElasticAgentCard solution={solution} {...action} />
</EuiFlexItem>
);
} else if (actionsKeys[i] === 'beats') {
return (
<EuiFlexItem key={`empty-page-beats-action`} className="kbnNoDataPageContents__item">
<ElasticBeatsCard solution={solution} {...action} />
</EuiFlexItem>
);
} else {
return (
<EuiFlexItem
key={`empty-page-${actionsKeys[i]}-action`}
className="kbnNoDataPageContents__item"
>
<NoDataCard {...action} />
</EuiFlexItem>
);
}
});
}, [actions, sortedData, actionsKeys]);

return (
<div className="kbnNoDataPageContents">
<EuiText textAlign="center">
<KibanaPageTemplateSolutionNavAvatar
name={solution}
iconType={logo || `logo${solution}`}
size="xxl"
/>
<EuiSpacer />
<h1>
{pageTitle || (
<FormattedMessage
id="kibana-react.noDataPage.welcomeTitle"
defaultMessage="Welcome to Elastic {solution}!"
values={{ solution }}
/>
)}
</h1>
<EuiTextColor color="subdued">
<p>
<FormattedMessage
id="kibana-react.noDataPage.intro"
defaultMessage="Add your data to get started or {link} about {solution}."
values={{
solution,
link: (
<EuiLink href={docsLink}>
<FormattedMessage
id="kibana-react.noDataPage.intro.link"
defaultMessage="learn more"
/>
</EuiLink>
),
}}
/>
</p>
</EuiTextColor>
</EuiText>
<EuiSpacer size="xxl" />
<EuiSpacer size="l" />
<EuiFlexGrid columns={2} style={{ justifyContent: 'space-around' }}>
{renderActions}
</EuiFlexGrid>
{actionsKeys.length > 1 ? (
<>
<EuiSpacer size="xxl" />
<EuiText textAlign="center" color="subdued">
<p>
<FormattedMessage
id="kibana-react.noDataPage.cantDecide"
defaultMessage="Confused on which to use? {link}"
values={{
link: (
<EuiLink href="https://www.elastic.co/guide/en/fleet/current/beats-agent-comparison.html">
<FormattedMessage
id="kibana-react.noDataPage.cantDecide.link"
defaultMessage="Check our docs for more information."
/>
</EuiLink>
),
}}
/>
</p>
</EuiText>
</>
) : undefined}
</div>
);
};
14 changes: 11 additions & 3 deletions x-pack/plugins/apm/public/application/uxApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { UXActionMenu } from '../components/app/RumDashboard/ActionMenu';
import { redirectTo } from '../components/routing/redirect_to';
import { useBreadcrumbs } from '../../../observability/public';
import { useApmPluginContext } from '../context/apm_plugin/use_apm_plugin_context';
import { APP_WRAPPER_CLASS } from '../../../../../src/core/public';

export const uxRoutes: APMRouteDefinition[] = [
{
Expand Down Expand Up @@ -66,7 +67,11 @@ function UxApp() {
darkMode,
})}
>
<div data-test-subj="csmMainContainer" role="main">
<div
className={APP_WRAPPER_CLASS}
data-test-subj="csmMainContainer"
role="main"
>
cchaos marked this conversation as resolved.
Show resolved Hide resolved
<ReactRouterRoute component={ScrollToTopOnPathChange} />
<RumHome />
</div>
Expand Down Expand Up @@ -104,14 +109,17 @@ export function UXAppRoot({
};

return (
<RedirectAppLinks application={core.application}>
<RedirectAppLinks
className={APP_WRAPPER_CLASS}
application={core.application}
>
<ApmPluginContext.Provider value={apmPluginContextValue}>
<KibanaContextProvider
services={{ ...core, ...plugins, embeddable, data }}
>
<i18nCore.Context>
<RouterProvider history={history} router={uxRouter}>
<UrlParamsProvider>
<UrlParamsProvider className={APP_WRAPPER_CLASS}>
<UxApp />
<UXActionMenu appMountParameters={appMountParameters} />
</UrlParamsProvider>
Expand Down
25 changes: 22 additions & 3 deletions x-pack/plugins/apm/public/components/app/RumDashboard/RumHome.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,52 @@
* 2.0.
*/

import React from 'react';
import React, { useContext } from 'react';
import { i18n } from '@kbn/i18n';
import { EuiFlexGroup, EuiTitle, EuiFlexItem } from '@elastic/eui';
import { RumOverview } from '../RumDashboard';
import { CsmSharedContextProvider } from './CsmSharedContext';
import { CsmSharedContext, CsmSharedContextProvider } from './CsmSharedContext';
import { WebApplicationSelect } from './Panels/WebApplicationSelect';
import { DatePicker } from '../../shared/DatePicker';
import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_context';
import { EnvironmentFilter } from '../../shared/EnvironmentFilter';
import { UserPercentile } from './UserPercentile';
import { useBreakPoints } from '../../../hooks/use_break_points';
import { KibanaPageTemplateProps } from '../../../../../../../src/plugins/kibana_react/public';

export const UX_LABEL = i18n.translate('xpack.apm.ux.title', {
defaultMessage: 'User Experience',
});

export function RumHome() {
const { observability } = useApmPluginContext();
const { core, observability } = useApmPluginContext();
const PageTemplateComponent = observability.navigation.PageTemplate;

const { isSmall, isXXL } = useBreakPoints();

const envStyle = isSmall ? {} : { maxWidth: 500 };

// TODO: NOT THE RIGHT METRIC TO CHECK
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are you still planing to make this PR work? if yes i can help with this metric check,

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shahzad31 Yes, this PR is slated for 7.16 and anywhere there are "TODO" or "HELP" comments, are parts that I need Obs folks to jump in on. So all the help is gratefully needed!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a PR for UX app has no data screen #111866

const {
sharedData: { totalPageViews },
} = useContext(CsmSharedContext);
const noDataConfig: KibanaPageTemplateProps['noDataConfig'] = totalPageViews
? {
solution: 'Observability',
pageTitle: 'Set up User Experience Tracking for Observability!',
actions: {
beats: {
href: core.http.basePath.prepend(`/app/home#/tutorial/apm`),
},
},
docsLink: '#',
}
: undefined;

return (
<CsmSharedContextProvider>
<PageTemplateComponent
noDataConfig={noDataConfig}
pageHeader={
isXXL
? {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@
* 2.0.
*/

import { EuiPageHeaderProps, EuiPageTemplateProps } from '@elastic/eui';
import { EuiPageHeaderProps } from '@elastic/eui';
import React from 'react';
import { useKibana } from '../../../../../../../src/plugins/kibana_react/public';
import {
useKibana,
KibanaPageTemplateProps,
} from '../../../../../../../src/plugins/kibana_react/public';
import { ApmPluginStartDeps } from '../../../plugin';
import { EnvironmentFilter } from '../../shared/EnvironmentFilter';

Expand All @@ -29,14 +32,33 @@ export function ApmMainTemplate({
pageTitle?: React.ReactNode;
pageHeader?: EuiPageHeaderProps;
children: React.ReactNode;
} & EuiPageTemplateProps) {
} & KibanaPageTemplateProps) {
const { http } = useKibana().services;
const basePath = http!.basePath.get();
const { services } = useKibana<ApmPluginStartDeps>();

const ObservabilityPageTemplate =
services.observability.navigation.PageTemplate;

// TODO: NEEDS A DATA CHECK
const hasData = true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ES query for doing the check for data is here:
https://github.com/elastic/kibana/blob/c6dc6e207a8ed8d30d74f84b9a554b1af5c27d2c/x-pack/plugins/apm/server/lib/services/get_services/has_historical_agent_data.ts#L12-L32

I suggest a new api endpoint is added like /apm/api/has_data. Routes can be added to https://github.com/elastic/kibana/tree/c6dc6e207a8ed8d30d74f84b9a554b1af5c27d2c/x-pack/plugins/apm/server/routes

To fetch data use useFetcher:

  const { data, status, error } = useFetcher(
    (callApmApi) => callApmApi({ endpoint: 'GET /api/apm/has_data' }),
    []
  );

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, that seems to be beyond my technical means to convert to usable code. Would you mind creating a PR against this branch? Or write out explicitly what needs to be done to achieve this?

Copy link
Member

@sorenlouv sorenlouv Aug 17, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally makes sense. Is this still scheduled for 7.15? FF is today and it would be easier for us to plan it into the 7.16 schedule or 8.0.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, yeah it looks like this won't be getting in for 7.15. I'd appreciate all the help to get this one over the line after FF.

const noDataConfig: KibanaPageTemplateProps['noDataConfig'] = !hasData
? {
solution: 'Observability',
pageTitle: 'Set up APM for Observability!',
actions: {
beats: {
href: basePath + `/app/home#/tutorial/apm`,
},
},
docsLink: '#',
}
: undefined;

// TODO: GET A CHECK
return (
<ObservabilityPageTemplate
noDataConfig={noDataConfig}
pageHeader={{
pageTitle,
rightSideItems: [<EnvironmentFilter />],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const LicenseCallout: React.FC = () => {
if (hasPlatinumLicense && !isTrial) return null;

return (
<EuiPanel hasShadow={false} hasBorder className="productCard" paddingSize="l">
<EuiPanel hasBorder color="transparent" paddingSize="l">
<EuiFlexGroup gutterSize="s" alignItems="center" justifyContent="spaceBetween">
<EuiFlexItem grow={7}>
<EuiText>
Expand Down
Loading