mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
Filter guided onboarding solutions based on cloud discovery questions… (#153367)
Related to #148911 This PR updates the guided onboarding landing page to filter solutions based on user selected use case in cloud discovery questions. The value will be passed as querystring parameter `?cloudDiscoveryUseCase=[value]` from Cloud UI. --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
d718066d75
commit
cb3a42a880
4 changed files with 93 additions and 86 deletions
|
@ -10,6 +10,7 @@ import React from 'react';
|
|||
import { EuiButton, EuiFlexGroup, EuiFlexItem, useEuiTheme } from '@elastic/eui';
|
||||
import { css } from '@emotion/react';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { ApplicationStart } from '@kbn/core-application-browser';
|
||||
import { GuideCardSolutions } from './guide_cards';
|
||||
|
||||
const filterButtonCss = css`
|
||||
|
@ -27,22 +28,34 @@ const filterButtonCss = css`
|
|||
}
|
||||
`;
|
||||
export type GuideFilterValues = GuideCardSolutions | 'all';
|
||||
interface GuideFiltersProps {
|
||||
export interface GuideFiltersProps {
|
||||
activeFilter: GuideFilterValues;
|
||||
setActiveFilter: React.Dispatch<React.SetStateAction<GuideFilterValues>>;
|
||||
application: ApplicationStart;
|
||||
}
|
||||
export const GuideFilters = ({ activeFilter, setActiveFilter }: GuideFiltersProps) => {
|
||||
export const GuideFilters = ({ activeFilter, setActiveFilter, application }: GuideFiltersProps) => {
|
||||
const { euiTheme } = useEuiTheme();
|
||||
const activeFilterFill = css`
|
||||
background: ${euiTheme.colors.darkestShade};
|
||||
color: ${euiTheme.colors.lightestShade};
|
||||
`;
|
||||
const setQuerystringParams = ({ useCase }: { useCase: string }) => {
|
||||
application.navigateToApp('home', { path: `#/getting_started?useCase=${useCase}` });
|
||||
};
|
||||
const onSelectFilter = (e: React.BaseSyntheticEvent) => {
|
||||
const {
|
||||
currentTarget: { dataset },
|
||||
} = e;
|
||||
setQuerystringParams({ useCase: dataset.filterId });
|
||||
setActiveFilter(dataset.filterId);
|
||||
};
|
||||
|
||||
return (
|
||||
<EuiFlexGroup justifyContent="center" gutterSize="s">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton
|
||||
onClick={() => setActiveFilter('all')}
|
||||
onClick={onSelectFilter}
|
||||
data-filter-id="all"
|
||||
color="text"
|
||||
css={[filterButtonCss, activeFilter === 'all' && activeFilterFill]}
|
||||
>
|
||||
|
@ -54,7 +67,8 @@ export const GuideFilters = ({ activeFilter, setActiveFilter }: GuideFiltersProp
|
|||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton
|
||||
onClick={() => setActiveFilter('search')}
|
||||
onClick={onSelectFilter}
|
||||
data-filter-id="search"
|
||||
color="text"
|
||||
css={[filterButtonCss, activeFilter === 'search' && activeFilterFill]}
|
||||
>
|
||||
|
@ -66,7 +80,8 @@ export const GuideFilters = ({ activeFilter, setActiveFilter }: GuideFiltersProp
|
|||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton
|
||||
onClick={() => setActiveFilter('observability')}
|
||||
onClick={onSelectFilter}
|
||||
data-filter-id="observability"
|
||||
color="text"
|
||||
css={[filterButtonCss, activeFilter === 'observability' && activeFilterFill]}
|
||||
>
|
||||
|
@ -78,7 +93,8 @@ export const GuideFilters = ({ activeFilter, setActiveFilter }: GuideFiltersProp
|
|||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton
|
||||
onClick={() => setActiveFilter('security')}
|
||||
onClick={onSelectFilter}
|
||||
data-filter-id="security"
|
||||
color="text"
|
||||
css={[filterButtonCss, activeFilter === 'security' && activeFilterFill]}
|
||||
>
|
||||
|
|
|
@ -1,74 +0,0 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`getting started should render getting started component 1`] = `
|
||||
<_KibanaPageTemplate
|
||||
grow={true}
|
||||
panelled={false}
|
||||
>
|
||||
<_EuiPageSection
|
||||
alignment="center"
|
||||
css={
|
||||
Object {
|
||||
"map": undefined,
|
||||
"name": "hdi05h",
|
||||
"next": undefined,
|
||||
"styles": "
|
||||
padding: calc(16px*3) calc(16px*4);
|
||||
",
|
||||
"toString": [Function],
|
||||
}
|
||||
}
|
||||
data-test-subj="onboarding--landing-page"
|
||||
>
|
||||
<EuiTitle
|
||||
className="eui-textCenter"
|
||||
size="l"
|
||||
>
|
||||
<h1>
|
||||
What would you like to do first?
|
||||
</h1>
|
||||
</EuiTitle>
|
||||
<EuiSpacer
|
||||
size="s"
|
||||
/>
|
||||
<EuiText
|
||||
size="m"
|
||||
textAlign="center"
|
||||
>
|
||||
<p>
|
||||
Select an option and we'll help you get started.
|
||||
</p>
|
||||
</EuiText>
|
||||
<EuiSpacer
|
||||
size="s"
|
||||
/>
|
||||
<EuiSpacer
|
||||
size="xxl"
|
||||
/>
|
||||
<GuideFilters
|
||||
activeFilter="all"
|
||||
setActiveFilter={[Function]}
|
||||
/>
|
||||
<EuiSpacer
|
||||
size="xxl"
|
||||
/>
|
||||
<GuideCards
|
||||
activateGuide={[Function]}
|
||||
activeFilter="all"
|
||||
guidesState={Array []}
|
||||
navigateToApp={[MockFunction]}
|
||||
/>
|
||||
<EuiSpacer />
|
||||
<div
|
||||
className="eui-textCenter"
|
||||
>
|
||||
<EuiLink
|
||||
data-test-subj="onboarding--skipGuideLink"
|
||||
onClick={[Function]}
|
||||
>
|
||||
I’d like to do something else.
|
||||
</EuiLink>
|
||||
</div>
|
||||
</_EuiPageSection>
|
||||
</_KibanaPageTemplate>
|
||||
`;
|
|
@ -9,13 +9,16 @@
|
|||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { findTestSubject, registerTestBed, TestBed } from '@kbn/test-jest-helpers';
|
||||
import { findTestSubject, registerTestBed, TestBed, mountWithIntl } from '@kbn/test-jest-helpers';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { cloudMock } from '@kbn/cloud-plugin/public/mocks';
|
||||
import { chromeServiceMock, applicationServiceMock, httpServiceMock } from '@kbn/core/public/mocks';
|
||||
import { ApiService } from '@kbn/guided-onboarding-plugin/public/services/api.service';
|
||||
|
||||
import { GettingStarted } from './getting_started';
|
||||
import { KEY_ENABLE_WELCOME } from '../home';
|
||||
import { GuideFiltersProps } from '@kbn/guided-onboarding/src/components/landing_page/guide_filters';
|
||||
import { ReactWrapper } from '@kbn/test-jest-helpers/src/testbed/types';
|
||||
|
||||
const mockCloud = cloudMock.createSetup();
|
||||
const mockChrome = chromeServiceMock.createStartContract();
|
||||
|
@ -48,9 +51,13 @@ describe('getting started', () => {
|
|||
});
|
||||
|
||||
test('should render getting started component', async () => {
|
||||
const component = await shallow(<GettingStarted />);
|
||||
const component = await shallow(
|
||||
<MemoryRouter>
|
||||
<GettingStarted />
|
||||
</MemoryRouter>
|
||||
);
|
||||
|
||||
expect(component).toMatchSnapshot();
|
||||
expect(component.find('GettingStarted').exists()).toBe(true);
|
||||
});
|
||||
|
||||
test('displays loading indicator', async () => {
|
||||
|
@ -99,4 +106,37 @@ describe('getting started', () => {
|
|||
|
||||
expect(localStorage.getItem(KEY_ENABLE_WELCOME)).toBe('false');
|
||||
});
|
||||
|
||||
test('should set default guide filter value if querystring parameter does NOT exist', async () => {
|
||||
let component: ReactWrapper;
|
||||
|
||||
await act(async () => {
|
||||
component = mountWithIntl(
|
||||
<MemoryRouter>
|
||||
<GettingStarted />
|
||||
</MemoryRouter>
|
||||
);
|
||||
});
|
||||
|
||||
const guideFilters = component!.find('[data-test-subj="onboarding--guideFilters"]');
|
||||
expect((guideFilters.props() as GuideFiltersProps).activeFilter).toBe('all');
|
||||
});
|
||||
|
||||
test('should auto-select guide filter value based on querystring parameter', async () => {
|
||||
const cloudDiscoveryUseCase = 'observability';
|
||||
let component: ReactWrapper;
|
||||
|
||||
await act(async () => {
|
||||
component = mountWithIntl(
|
||||
<MemoryRouter
|
||||
initialEntries={[{ pathname: '/', search: `?useCase=${cloudDiscoveryUseCase}` }]}
|
||||
>
|
||||
<GettingStarted />
|
||||
</MemoryRouter>
|
||||
);
|
||||
});
|
||||
|
||||
const guideFilters = component!.find('[data-test-subj="onboarding--guideFilters"]');
|
||||
expect((guideFilters.props() as GuideFiltersProps).activeFilter).toBe(cloudDiscoveryUseCase);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*/
|
||||
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { parse } from 'query-string';
|
||||
import {
|
||||
EuiButton,
|
||||
EuiLink,
|
||||
|
@ -19,7 +20,7 @@ import {
|
|||
} from '@elastic/eui';
|
||||
|
||||
import { css } from '@emotion/react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { useHistory, useLocation } from 'react-router-dom';
|
||||
import { METRIC_TYPE } from '@kbn/analytics';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template';
|
||||
|
@ -48,7 +49,26 @@ export const GettingStarted = () => {
|
|||
const [guidesState, setGuidesState] = useState<GuideState[]>([]);
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
const [isError, setIsError] = useState<boolean>(false);
|
||||
const [filter, setFilter] = useState<GuideFilterValues>('all');
|
||||
const { search } = useLocation();
|
||||
const query = parse(search);
|
||||
|
||||
const isTypeOfGuideFilterValue = (useCase: string | string[] | null) => {
|
||||
const filterValues: string[] = ['search', 'observability', 'security', 'all']; // list of GuideFilterValues types
|
||||
|
||||
if (!useCase) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (useCase instanceof Array) {
|
||||
return filterValues.includes(useCase[0]);
|
||||
}
|
||||
|
||||
return filterValues.includes(useCase);
|
||||
};
|
||||
|
||||
const [filter, setFilter] = useState<GuideFilterValues>(
|
||||
isTypeOfGuideFilterValue(query.useCase) ? (query.useCase as GuideFilterValues) : 'all'
|
||||
);
|
||||
const history = useHistory();
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -196,7 +216,12 @@ export const GettingStarted = () => {
|
|||
</EuiText>
|
||||
<EuiSpacer size="s" />
|
||||
<EuiSpacer size="xxl" />
|
||||
<GuideFilters activeFilter={filter} setActiveFilter={setFilter} />
|
||||
<GuideFilters
|
||||
application={application}
|
||||
activeFilter={filter}
|
||||
setActiveFilter={setFilter}
|
||||
data-test-subj="onboarding--guideFilters"
|
||||
/>
|
||||
<EuiSpacer size="xxl" />
|
||||
<GuideCards
|
||||
activateGuide={activateGuide}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue