Update icons on landing page (#159114)

Fixes: https://github.com/elastic/kibana/issues/154117
Fixes: https://github.com/elastic/kibana/issues/155341

This PR updates the guided onboarding landing page icons, removes the
solution badge and updates the solution view to a grouped layout so
cards remain grouped on narrow screens.

### Screenshots
<img width="954" alt="Screenshot 2023-06-06 at 13 37 35"
src="5a173833-48df-49ff-8e55-612d4aa52e07">

#### Narrow
<img width="872" alt="Screenshot 2023-06-06 at 14 26 58"
src="87256b3e-1375-402d-9a14-2bf10c58422e">


#### Mobile
<img width="295" alt="Screenshot 2023-06-06 at 13 37 03"
src="101f4259-17df-4b41-a9df-e48bb269dd8b">

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
claracruz 2023-06-07 19:53:33 +01:00 committed by GitHub
parent fd95b37c10
commit 9adb53f2a4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 370 additions and 326 deletions

View file

@ -1,303 +1,336 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`guide cards snapshots should render all cards 1`] = `
<EuiFlexGroup
justifyContent="center"
responsive={false}
wrap={true}
>
<EuiFlexGroup>
<EuiFlexItem
grow={false}
key="0"
>
<GuideCard
activateGuide={[MockFunction]}
activeFilter="all"
card={
Object {
"guideId": "appSearch",
"order": 1,
"solution": "search",
"telemetryId": "onboarding--search--application",
"title": <FormattedMessage
defaultMessage="Build an application on {lineBreak} top of Elasticsearch"
id="guidedOnboardingPackage.gettingStarted.cards.appSearch.title"
values={
Object {
"lineBreak": <br />,
}
<EuiFlexGroup
alignItems="center"
direction="column"
>
<EuiFlexItem
grow={false}
key="0"
>
<GuideCard
activateGuide={[MockFunction]}
activeFilter="all"
card={
Object {
"guideId": "appSearch",
"icon": "wrench",
"order": 1,
"solution": "search",
"telemetryId": "onboarding--search--application",
"title": <FormattedMessage
defaultMessage="Build an application on {lineBreak} top of Elasticsearch"
id="guidedOnboardingPackage.gettingStarted.cards.appSearch.title"
values={
Object {
"lineBreak": <br />,
}
}
/>,
}
/>,
}
}
guidesState={Array []}
navigateToApp={[MockFunction]}
/>
<EuiSpacer
size="m"
/>
}
guidesState={Array []}
navigateToApp={[MockFunction]}
/>
<EuiSpacer
size="m"
/>
</EuiFlexItem>
<EuiFlexItem
grow={false}
key="1"
>
<GuideCard
activateGuide={[MockFunction]}
activeFilter="all"
card={
Object {
"guideId": "websiteSearch",
"icon": "search",
"order": 4,
"solution": "search",
"telemetryId": "onboarding--search--website",
"title": "Add search to my website",
}
}
guidesState={Array []}
navigateToApp={[MockFunction]}
/>
<EuiSpacer
size="m"
/>
</EuiFlexItem>
<EuiFlexItem
grow={false}
key="2"
>
<GuideCard
activateGuide={[MockFunction]}
activeFilter="all"
card={
Object {
"guideId": "databaseSearch",
"icon": "database",
"order": 7,
"solution": "search",
"telemetryId": "onboarding--search--database",
"title": <FormattedMessage
defaultMessage="Search across databases and {lineBreak} business systems"
id="guidedOnboardingPackage.gettingStarted.cards.databaseSearch.title"
values={
Object {
"lineBreak": <br />,
}
}
/>,
}
}
guidesState={Array []}
navigateToApp={[MockFunction]}
/>
<EuiSpacer
size="m"
/>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
<EuiFlexItem
grow={false}
key="1"
>
<GuideCard
activateGuide={[MockFunction]}
activeFilter="all"
card={
Object {
"navigateTo": Object {
"appId": "integrations",
"path": "/browse?q=log",
},
"order": 2,
"solution": "observability",
"telemetryId": "onboarding--observability--logs",
"title": "Collect and analyze my logs",
}
}
guidesState={Array []}
navigateToApp={[MockFunction]}
/>
<EuiSpacer
size="m"
/>
<EuiFlexGroup
alignItems="center"
direction="column"
>
<EuiFlexItem
grow={false}
key="0"
>
<GuideCard
activateGuide={[MockFunction]}
activeFilter="all"
card={
Object {
"icon": "logstashInput",
"navigateTo": Object {
"appId": "integrations",
"path": "/browse?q=log",
},
"order": 2,
"solution": "observability",
"telemetryId": "onboarding--observability--logs",
"title": "Collect and analyze my logs",
}
}
guidesState={Array []}
navigateToApp={[MockFunction]}
/>
<EuiSpacer
size="m"
/>
</EuiFlexItem>
<EuiFlexItem
grow={false}
key="1"
>
<GuideCard
activateGuide={[MockFunction]}
activeFilter="all"
card={
Object {
"icon": "apmTrace",
"navigateTo": Object {
"appId": "home",
"path": "#/tutorial/apm",
},
"order": 5,
"solution": "observability",
"telemetryId": "onboarding--observability--apm",
"title": <FormattedMessage
defaultMessage="Monitor my application {lineBreak} performance (APM / tracing)"
id="guidedOnboardingPackage.gettingStarted.cards.apmObservability.title"
values={
Object {
"lineBreak": <br />,
}
}
/>,
}
}
guidesState={Array []}
navigateToApp={[MockFunction]}
/>
<EuiSpacer
size="m"
/>
</EuiFlexItem>
<EuiFlexItem
grow={false}
key="2"
>
<GuideCard
activateGuide={[MockFunction]}
activeFilter="all"
card={
Object {
"icon": "visBarVertical",
"navigateTo": Object {
"appId": "integrations",
"path": "/browse/os_system",
},
"order": 8,
"solution": "observability",
"telemetryId": "onboarding--observability--hosts",
"title": "Monitor my host metrics",
}
}
guidesState={Array []}
navigateToApp={[MockFunction]}
/>
<EuiSpacer
size="m"
/>
</EuiFlexItem>
<EuiFlexItem
grow={false}
key="3"
>
<GuideCard
activateGuide={[MockFunction]}
activeFilter="all"
card={
Object {
"guideId": "kubernetes",
"icon": "cluster",
"order": 11,
"solution": "observability",
"telemetryId": "onboarding--observability--kubernetes",
"title": "Monitor Kubernetes clusters",
}
}
guidesState={Array []}
navigateToApp={[MockFunction]}
/>
<EuiSpacer
size="m"
/>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
<EuiFlexItem
grow={false}
key="2"
>
<GuideCard
activateGuide={[MockFunction]}
activeFilter="all"
card={
Object {
"guideId": "siem",
"order": 3,
"solution": "security",
"telemetryId": "onboarding--security--siem",
"title": <FormattedMessage
defaultMessage="Detect threats in my {lineBreak} data with SIEM"
id="guidedOnboardingPackage.gettingStarted.cards.siemSecurity.title"
values={
Object {
"lineBreak": <br />,
}
<EuiFlexGroup
alignItems="center"
direction="column"
>
<EuiFlexItem
grow={false}
key="0"
>
<GuideCard
activateGuide={[MockFunction]}
activeFilter="all"
card={
Object {
"guideId": "siem",
"icon": "securitySignal",
"order": 3,
"solution": "security",
"telemetryId": "onboarding--security--siem",
"title": <FormattedMessage
defaultMessage="Detect threats in my {lineBreak} data with SIEM"
id="guidedOnboardingPackage.gettingStarted.cards.siemSecurity.title"
values={
Object {
"lineBreak": <br />,
}
}
/>,
}
/>,
}
}
guidesState={Array []}
navigateToApp={[MockFunction]}
/>
<EuiSpacer
size="m"
/>
</EuiFlexItem>
<EuiFlexItem
grow={false}
key="3"
>
<GuideCard
activateGuide={[MockFunction]}
activeFilter="all"
card={
Object {
"guideId": "websiteSearch",
"order": 4,
"solution": "search",
"telemetryId": "onboarding--search--website",
"title": "Add search to my website",
}
}
guidesState={Array []}
navigateToApp={[MockFunction]}
/>
<EuiSpacer
size="m"
/>
</EuiFlexItem>
<EuiFlexItem
grow={false}
key="4"
>
<GuideCard
activateGuide={[MockFunction]}
activeFilter="all"
card={
Object {
"navigateTo": Object {
"appId": "home",
"path": "#/tutorial/apm",
},
"order": 5,
"solution": "observability",
"telemetryId": "onboarding--observability--apm",
"title": <FormattedMessage
defaultMessage="Monitor my application {lineBreak} performance (APM / tracing)"
id="guidedOnboardingPackage.gettingStarted.cards.apmObservability.title"
values={
Object {
"lineBreak": <br />,
}
}
guidesState={Array []}
navigateToApp={[MockFunction]}
/>
<EuiSpacer
size="m"
/>
</EuiFlexItem>
<EuiFlexItem
grow={false}
key="1"
>
<GuideCard
activateGuide={[MockFunction]}
activeFilter="all"
card={
Object {
"icon": "inputOutput",
"navigateTo": Object {
"appId": "integrations",
"path": "/detail/endpoint/overview",
},
"order": 6,
"solution": "security",
"telemetryId": "onboarding--security--hosts",
"title": <FormattedMessage
defaultMessage="Secure my hosts with {lineBreak} endpoint security"
id="guidedOnboardingPackage.gettingStarted.cards.hostsSecurity.title"
values={
Object {
"lineBreak": <br />,
}
}
/>,
}
/>,
}
}
guidesState={Array []}
navigateToApp={[MockFunction]}
/>
<EuiSpacer
size="m"
/>
</EuiFlexItem>
<EuiFlexItem
grow={false}
key="5"
>
<GuideCard
activateGuide={[MockFunction]}
activeFilter="all"
card={
Object {
"navigateTo": Object {
"appId": "integrations",
"path": "/detail/endpoint/overview",
},
"order": 6,
"solution": "security",
"telemetryId": "onboarding--security--hosts",
"title": <FormattedMessage
defaultMessage="Secure my hosts with {lineBreak} endpoint security"
id="guidedOnboardingPackage.gettingStarted.cards.hostsSecurity.title"
values={
Object {
"lineBreak": <br />,
}
}
guidesState={Array []}
navigateToApp={[MockFunction]}
/>
<EuiSpacer
size="m"
/>
</EuiFlexItem>
<EuiFlexItem
grow={false}
key="2"
>
<GuideCard
activateGuide={[MockFunction]}
activeFilter="all"
card={
Object {
"icon": "lock",
"navigateTo": Object {
"appId": "integrations",
"path": "/detail/cloud_security_posture/overview?integration=cspm",
},
"order": 9,
"solution": "security",
"telemetryId": "onboarding--security--cloud",
"title": <FormattedMessage
defaultMessage="Secure my cloud assets with {lineBreak} cloud security posture management (CSPM)"
id="guidedOnboardingPackage.gettingStarted.cards.cloudSecurity.title"
values={
Object {
"lineBreak": <br />,
}
}
/>,
}
/>,
}
}
guidesState={Array []}
navigateToApp={[MockFunction]}
/>
<EuiSpacer
size="m"
/>
</EuiFlexItem>
<EuiFlexItem
grow={false}
key="6"
>
<GuideCard
activateGuide={[MockFunction]}
activeFilter="all"
card={
Object {
"guideId": "databaseSearch",
"order": 7,
"solution": "search",
"telemetryId": "onboarding--search--database",
"title": <FormattedMessage
defaultMessage="Search across databases and {lineBreak} business systems"
id="guidedOnboardingPackage.gettingStarted.cards.databaseSearch.title"
values={
Object {
"lineBreak": <br />,
}
}
/>,
}
}
guidesState={Array []}
navigateToApp={[MockFunction]}
/>
<EuiSpacer
size="m"
/>
</EuiFlexItem>
<EuiFlexItem
grow={false}
key="7"
>
<GuideCard
activateGuide={[MockFunction]}
activeFilter="all"
card={
Object {
"navigateTo": Object {
"appId": "integrations",
"path": "/browse/os_system",
},
"order": 8,
"solution": "observability",
"telemetryId": "onboarding--observability--hosts",
"title": "Monitor my host metrics",
}
}
guidesState={Array []}
navigateToApp={[MockFunction]}
/>
<EuiSpacer
size="m"
/>
</EuiFlexItem>
<EuiFlexItem
grow={false}
key="8"
>
<GuideCard
activateGuide={[MockFunction]}
activeFilter="all"
card={
Object {
"navigateTo": Object {
"appId": "integrations",
"path": "/detail/cloud_security_posture/overview?integration=cspm",
},
"order": 9,
"solution": "security",
"telemetryId": "onboarding--security--cloud",
"title": <FormattedMessage
defaultMessage="Secure my cloud assets with {lineBreak} cloud security posture management (CSPM)"
id="guidedOnboardingPackage.gettingStarted.cards.cloudSecurity.title"
values={
Object {
"lineBreak": <br />,
}
}
/>,
}
}
guidesState={Array []}
navigateToApp={[MockFunction]}
/>
<EuiSpacer
size="m"
/>
</EuiFlexItem>
<EuiFlexItem
grow={false}
key="9"
>
<GuideCard
activateGuide={[MockFunction]}
activeFilter="all"
card={
Object {
"guideId": "kubernetes",
"order": 11,
"solution": "observability",
"telemetryId": "onboarding--observability--kubernetes",
"title": "Monitor Kubernetes clusters",
}
}
guidesState={Array []}
navigateToApp={[MockFunction]}
/>
<EuiSpacer
size="m"
/>
}
guidesState={Array []}
navigateToApp={[MockFunction]}
/>
<EuiSpacer
size="m"
/>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
</EuiFlexGroup>
`;

View file

@ -14,7 +14,6 @@ import {
EuiFlexGroup,
EuiFlexItem,
EuiIcon,
EuiSpacer,
EuiTextColor,
useEuiTheme,
} from '@elastic/eui';
@ -24,18 +23,6 @@ import { GuideState } from '../../types';
import { GuideCardConstants } from './guide_cards.constants';
import { GuideCardsProps } from './guide_cards';
const cardCss = css`
position: relative;
min-height: 110px;
width: 380px;
.euiCard__content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
`;
const getProgressLabel = (guideState: GuideState | undefined): string | undefined => {
if (!guideState) {
return undefined;
@ -84,6 +71,20 @@ export const GuideCard = ({
const isHighlighted = activeFilter === 'all' || activeFilter === card.solution;
const isComplete = guideState && guideState.status === 'complete';
const progress = getProgressLabel(guideState);
const cardCss = css`
position: relative;
min-height: 140px;
width: 380px;
@media (max-width: ${euiTheme.breakpoint.s}px) {
max-width: 335px;
}
@media (min-width: 768px) and (max-width: 1210px) {
max-width: 230px;
height: 175px;
}
`;
return (
<EuiCard
// data-test-subj used for FS tracking
@ -93,16 +94,9 @@ export const GuideCard = ({
css={cardCss}
display={isHighlighted ? undefined : 'transparent'}
hasBorder={!isHighlighted}
title={
<>
<EuiSpacer size="s" />
<h3 style={{ fontWeight: 600 }}>{card.title}</h3>
</>
}
title={<h3 style={{ fontWeight: 600 }}>{card.title}</h3>}
titleSize="xs"
betaBadgeProps={{
label: card.solution,
}}
icon={<EuiIcon size="l" type={card.icon} />}
description={
<>
{progress && (
@ -111,7 +105,12 @@ export const GuideCard = ({
</EuiTextColor>
)}
{isComplete && (
<EuiFlexGroup gutterSize="s" alignItems="center" responsive={false}>
<EuiFlexGroup
gutterSize="s"
alignItems="center"
responsive={false}
justifyContent="center"
>
<EuiFlexItem grow={false}>
<EuiIcon type="checkInCircleFilled" color={euiTheme.colors.success} />
</EuiFlexItem>
@ -124,7 +123,6 @@ export const GuideCard = ({
</EuiFlexItem>
</EuiFlexGroup>
)}
{card.navigateTo && <EuiIcon type="document" />}
</>
}
/>

View file

@ -27,11 +27,13 @@ export interface GuideCardConstants {
// see this issue https://github.com/elastic/kibana/issues/146672
telemetryId: string;
order: number;
icon: string;
}
export const guideCards: GuideCardConstants[] = [
{
solution: 'search',
icon: 'wrench',
title: (
<FormattedMessage
id="guidedOnboardingPackage.gettingStarted.cards.appSearch.title"
@ -47,6 +49,7 @@ export const guideCards: GuideCardConstants[] = [
},
{
solution: 'search',
icon: 'search',
title: i18n.translate('guidedOnboardingPackage.gettingStarted.cards.websiteSearch.title', {
defaultMessage: 'Add search to my website',
}),
@ -56,6 +59,7 @@ export const guideCards: GuideCardConstants[] = [
},
{
solution: 'search',
icon: 'database',
title: (
<FormattedMessage
id="guidedOnboardingPackage.gettingStarted.cards.databaseSearch.title"
@ -71,6 +75,7 @@ export const guideCards: GuideCardConstants[] = [
},
{
solution: 'observability',
icon: 'logstashInput',
title: i18n.translate('guidedOnboardingPackage.gettingStarted.cards.logsObservability.title', {
defaultMessage: 'Collect and analyze my logs',
}),
@ -83,6 +88,7 @@ export const guideCards: GuideCardConstants[] = [
},
{
solution: 'observability',
icon: 'apmTrace',
title: (
<FormattedMessage
id="guidedOnboardingPackage.gettingStarted.cards.apmObservability.title"
@ -101,6 +107,7 @@ export const guideCards: GuideCardConstants[] = [
},
{
solution: 'observability',
icon: 'visBarVertical',
title: i18n.translate('guidedOnboardingPackage.gettingStarted.cards.hostsObservability.title', {
defaultMessage: 'Monitor my host metrics',
}),
@ -113,6 +120,7 @@ export const guideCards: GuideCardConstants[] = [
},
{
solution: 'observability',
icon: 'cluster',
title: i18n.translate(
'guidedOnboardingPackage.gettingStarted.cards.kubernetesObservability.title',
{
@ -125,6 +133,7 @@ export const guideCards: GuideCardConstants[] = [
},
{
solution: 'security',
icon: 'securitySignal',
title: (
<FormattedMessage
id="guidedOnboardingPackage.gettingStarted.cards.siemSecurity.title"
@ -140,6 +149,7 @@ export const guideCards: GuideCardConstants[] = [
},
{
solution: 'security',
icon: 'inputOutput',
title: (
<FormattedMessage
id="guidedOnboardingPackage.gettingStarted.cards.hostsSecurity.title"
@ -158,6 +168,7 @@ export const guideCards: GuideCardConstants[] = [
},
{
solution: 'security',
icon: 'lock',
title: (
<FormattedMessage
id="guidedOnboardingPackage.gettingStarted.cards.cloudSecurity.title"

View file

@ -9,6 +9,7 @@
import React from 'react';
import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui';
import { groupBy, keys } from 'lodash';
import { ApplicationStart } from '@kbn/core-application-browser';
@ -26,14 +27,25 @@ export interface GuideCardsProps {
guidesState: GuideState[];
}
export const GuideCards = (props: GuideCardsProps) => {
const groupedGuideCards = groupBy(guideCards, 'solution');
return (
<EuiFlexGroup wrap justifyContent="center" responsive={false}>
{guideCards.map((card, index) => (
<EuiFlexItem key={index} grow={false}>
<GuideCard card={card} {...props} />
<EuiSpacer size="m" />
</EuiFlexItem>
))}
<EuiFlexGroup>
{keys(groupedGuideCards).map((groupedGuideCard, groupIndex) => {
const cards = groupedGuideCards[groupedGuideCard];
return (
<EuiFlexItem key={groupIndex}>
<EuiFlexGroup direction="column" alignItems="center">
{cards.map((card, index) => (
<EuiFlexItem key={index} grow={false}>
<GuideCard card={card} {...props} />
<EuiSpacer size="m" />
</EuiFlexItem>
))}
</EuiFlexGroup>
</EuiFlexItem>
);
})}
</EuiFlexGroup>
);
};

View file

@ -16,10 +16,8 @@ import {
EuiSpacer,
EuiText,
EuiTitle,
useEuiTheme,
} from '@elastic/eui';
import { css } from '@emotion/react';
import { useHistory, useLocation } from 'react-router-dom';
import { METRIC_TYPE } from '@kbn/analytics';
import { i18n } from '@kbn/i18n';
@ -38,10 +36,10 @@ const title = i18n.translate('home.guidedOnboarding.gettingStarted.useCaseSelect
defaultMessage: 'What would you like to do first?',
});
const subtitle = i18n.translate('home.guidedOnboarding.gettingStarted.useCaseSelectionSubtitle', {
defaultMessage: `Select an option and we'll help you get started.`,
defaultMessage: `Select a guide to help you make the most of your data.`,
});
const skipText = i18n.translate('home.guidedOnboarding.gettingStarted.skip.buttonLabel', {
defaultMessage: `Id like to do something else.`,
defaultMessage: `Id like to explore on my own.`,
});
export const GettingStarted = () => {
@ -126,10 +124,6 @@ export const GettingStarted = () => {
trackUiMetric(METRIC_TYPE.CLICK, 'guided_onboarding__skipped');
application.navigateToApp('home');
};
const { euiTheme } = useEuiTheme();
const paddingCss = css`
padding: calc(${euiTheme.size.base}*3) calc(${euiTheme.size.base}*4);
`;
const activateGuide = useCallback(
async (guideId: GuideId, guideState?: GuideState) => {
@ -202,11 +196,7 @@ export const GettingStarted = () => {
return (
<KibanaPageTemplate panelled={false} grow>
<EuiPageTemplate.Section
alignment="center"
css={paddingCss}
data-test-subj="guided-onboarding--landing-page"
>
<EuiPageTemplate.Section alignment="center" data-test-subj="guided-onboarding--landing-page">
<EuiTitle size="l" className="eui-textCenter">
<h1>{title}</h1>
</EuiTitle>