From 72a33c38c7524bf0eeb9482969c2bc9146cbe007 Mon Sep 17 00:00:00 2001 From: Dave Snider Date: Tue, 19 Oct 2021 00:44:07 -0400 Subject: [PATCH 1/5] Features integrations + mobile, copy, design tweaks --- src/core/public/rendering/_base.scss | 10 ++- .../empty_index_list_prompt.tsx | 2 +- .../elastic_agent_card.test.tsx.snap | 5 ++ .../__snapshots__/no_data_card.test.tsx.snap | 8 +- .../no_data_card/elastic_agent_card.tsx | 2 + .../no_data_card/no_data_card.tsx | 1 + .../epm/components/integration_preference.tsx | 3 +- .../epm/components/package_list_grid.tsx | 78 ++++++++++--------- .../epm/screens/home/available_packages.tsx | 64 ++++++++++++++- .../epm/screens/home/category_facets.tsx | 7 ++ .../epm/screens/home/installed_packages.tsx | 10 +-- .../components/app/header/header_menu.tsx | 2 +- .../public/app/home/global_header/index.tsx | 2 +- 13 files changed, 138 insertions(+), 56 deletions(-) diff --git a/src/core/public/rendering/_base.scss b/src/core/public/rendering/_base.scss index 32a297a4066d9..c97afbf14a8f6 100644 --- a/src/core/public/rendering/_base.scss +++ b/src/core/public/rendering/_base.scss @@ -43,10 +43,12 @@ top: $headerHeight; } - .kbnStickyMenu { - position: sticky; - max-height: calc(100vh - #{$headerHeight + $euiSize}); - top: $headerHeight + $euiSize; + @include euiBreakpoint('xl', 'l') { + .kbnStickyMenu { + position: sticky; + max-height: calc(100vh - #{$headerHeight + $euiSize}); + top: $headerHeight + $euiSize; + } } } diff --git a/src/plugins/index_pattern_editor/public/components/empty_prompts/empty_index_list_prompt/empty_index_list_prompt.tsx b/src/plugins/index_pattern_editor/public/components/empty_prompts/empty_index_list_prompt/empty_index_list_prompt.tsx index d00f9e2368e21..c7626bcdf3f1f 100644 --- a/src/plugins/index_pattern_editor/public/components/empty_prompts/empty_index_list_prompt/empty_index_list_prompt.tsx +++ b/src/plugins/index_pattern_editor/public/components/empty_prompts/empty_index_list_prompt/empty_index_list_prompt.tsx @@ -91,7 +91,7 @@ export const EmptyIndexListPrompt = ({ { - navigateToApp('home', { path: '/app/integrations/browse' }); + navigateToApp('integrations', { path: '/browse' }); closeFlyout(); }} icon={} diff --git a/src/plugins/kibana_react/public/page_template/no_data_page/no_data_card/__snapshots__/elastic_agent_card.test.tsx.snap b/src/plugins/kibana_react/public/page_template/no_data_page/no_data_card/__snapshots__/elastic_agent_card.test.tsx.snap index f66d05140b2e9..1168641e58537 100644 --- a/src/plugins/kibana_react/public/page_template/no_data_page/no_data_card/__snapshots__/elastic_agent_card.test.tsx.snap +++ b/src/plugins/kibana_react/public/page_template/no_data_page/no_data_card/__snapshots__/elastic_agent_card.test.tsx.snap @@ -13,6 +13,7 @@ exports[`ElasticAgentCard props button 1`] = ` href="/app/integrations/browse" image="/plugins/kibanaReact/assets/elastic_agent_card.svg" paddingSize="l" + textAlign="left" title={ @@ -36,6 +37,7 @@ exports[`ElasticAgentCard props category 1`] = ` href="/app/integrations/browse/custom" image="/plugins/kibanaReact/assets/elastic_agent_card.svg" paddingSize="l" + textAlign="left" title={ @@ -59,6 +61,7 @@ exports[`ElasticAgentCard props href 1`] = ` href="#" image="/plugins/kibanaReact/assets/elastic_agent_card.svg" paddingSize="l" + textAlign="left" title={ @@ -83,6 +86,7 @@ exports[`ElasticAgentCard props recommended 1`] = ` href="/app/integrations/browse" image="/plugins/kibanaReact/assets/elastic_agent_card.svg" paddingSize="l" + textAlign="left" title={ @@ -106,6 +110,7 @@ exports[`ElasticAgentCard renders 1`] = ` href="/app/integrations/browse" image="/plugins/kibanaReact/assets/elastic_agent_card.svg" paddingSize="l" + textAlign="left" title={ diff --git a/src/plugins/kibana_react/public/page_template/no_data_page/no_data_card/__snapshots__/no_data_card.test.tsx.snap b/src/plugins/kibana_react/public/page_template/no_data_page/no_data_card/__snapshots__/no_data_card.test.tsx.snap index fccbbe3a9e8ee..1eff83d9248e1 100644 --- a/src/plugins/kibana_react/public/page_template/no_data_page/no_data_card/__snapshots__/no_data_card.test.tsx.snap +++ b/src/plugins/kibana_react/public/page_template/no_data_page/no_data_card/__snapshots__/no_data_card.test.tsx.snap @@ -2,7 +2,7 @@ exports[`NoDataCard props button 1`] = `
= ({ {i18n.translate('kibana-react.noDataPage.elasticAgentCard.noPermission.title', { @@ -78,6 +79,7 @@ export const ElasticAgentCard: FunctionComponent = ({ return ( = ({ return ( ); @@ -115,6 +115,7 @@ export const IntegrationPreference = ({ initialType, onChange }: Props) => { name="preference" /> + ); }; diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_list_grid.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_list_grid.tsx index d2d361cd212a6..91bd29d14d0b3 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_list_grid.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/components/package_list_grid.tsx @@ -18,6 +18,7 @@ import { EuiText, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; + import { FormattedMessage } from '@kbn/i18n/react'; import { Loading } from '../../../components'; @@ -32,6 +33,7 @@ export interface Props { controls?: ReactNode | ReactNode[]; title?: string; list: IntegrationCardItem[]; + featuredList?: JSX.Element | null; initialSearch?: string; setSelectedCategory: (category: string) => void; onSearchChange: (search: string) => void; @@ -48,6 +50,7 @@ export const PackageListGrid: FunctionComponent = ({ onSearchChange, setSelectedCategory, showMissingIntegrationMessage = false, + featuredList = null, callout, }) => { const [searchTerm, setSearchTerm] = useState(initialSearch || ''); @@ -106,42 +109,45 @@ export const PackageListGrid: FunctionComponent = ({ } return ( -
- - - {controlsContent} - - - - {callout ? ( - <> - - {callout} - - ) : null} - - {gridContent} - {showMissingIntegrationMessage && ( - <> - - - - )} - - -
+ <> + {featuredList} +
+ + + {controlsContent} + + + + {callout ? ( + <> + + {callout} + + ) : null} + + {gridContent} + {showMissingIntegrationMessage && ( + <> + + + + )} + + +
+ ); }; diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/available_packages.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/available_packages.tsx index f5c521ebacf16..0ae82f57a6195 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/available_packages.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/available_packages.tsx @@ -8,7 +8,18 @@ import React, { memo, useMemo, useState } from 'react'; import { useLocation, useHistory, useParams } from 'react-router-dom'; import _ from 'lodash'; -import { EuiHorizontalRule, EuiFlexItem } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { + EuiHorizontalRule, + EuiFlexItem, + EuiFlexGrid, + EuiSpacer, + EuiCard, + EuiFlexGroup, + EuiIcon, +} from '@elastic/eui'; + +import { useStartServices } from '../../../../hooks'; import { pagePathGetters } from '../../../../constants'; import { @@ -98,6 +109,9 @@ export const AvailablePackages: React.FC = memo(() => { const [preference, setPreference] = useState('recommended'); useBreadcrumbs('integrations_all'); + const { http } = useStartServices(); + const addBasePath = http.basePath.prepend; + const { selectedCategory, searchParam } = getParams( useParams(), useLocation().search @@ -210,8 +224,56 @@ export const AvailablePackages: React.FC = memo(() => { return c.categories.includes(selectedCategory); }); + // TODO: Remove this hard coded list of integrations with a suggestion service + const featuredList = ( + <> + + + } + href={addBasePath('/app/integrations/detail/endpoint/')} + title={i18n.translate('xpack.observability.home.featuredSecurityTitle', { + defaultMessage: 'Endpoint Security', + })} + description={i18n.translate('xpack.observability.home.featuredSecurityDesc', { + defaultMessage: + 'Protect your hosts with threat prevention, detection, and deep security data visibility.', + })} + /> + + + } + /> + + + } + href={addBasePath('/app/enterprise_search/app_search')} + title={i18n.translate('xpack.observability.home.featuredObsTitle', { + defaultMessage: 'Web site crawler', + })} + description={i18n.translate('xpack.observability.home.featuredObsDesc', { + defaultMessage: 'Add search to your website with the App Search web crawler.', + })} + /> + + + + + ); + return ( { const { docLinks } = useStartServices(); @@ -56,10 +56,6 @@ const Callout = () => ( ); -const title = i18n.translate('xpack.fleet.epmList.installedTitle', { - defaultMessage: 'Installed integrations', -}); - // TODO: clintandrewhall - this component is hard to test due to the hooks, particularly those that use `http` // or `location` to load data. Ideally, we'll split this into "connected" and "pure" components. export const InstalledPackages: React.FC = memo(() => { @@ -115,7 +111,7 @@ export const InstalledPackages: React.FC = memo(() => { const categories: CategoryFacet[] = useMemo( () => [ { - ...ALL_CATEGORY, + ...INSTALLED_CATEGORY, count: allInstalledPackages.length, }, { @@ -153,7 +149,7 @@ export const InstalledPackages: React.FC = memo(() => { return ( Date: Tue, 19 Oct 2021 00:57:14 -0400 Subject: [PATCH 2/5] i18n --- .../sections/epm/screens/home/available_packages.tsx | 12 ++++++------ x-pack/plugins/translations/translations/ja-JP.json | 1 - x-pack/plugins/translations/translations/zh-CN.json | 1 - 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/available_packages.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/available_packages.tsx index 0ae82f57a6195..a25b8ca0f8126 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/available_packages.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/available_packages.tsx @@ -232,10 +232,10 @@ export const AvailablePackages: React.FC = memo(() => { } href={addBasePath('/app/integrations/detail/endpoint/')} - title={i18n.translate('xpack.observability.home.featuredSecurityTitle', { + title={i18n.translate('xpack.fleet.featuredSecurityTitle', { defaultMessage: 'Endpoint Security', })} - description={i18n.translate('xpack.observability.home.featuredSecurityDesc', { + description={i18n.translate('xpack.fleet.featuredSecurityDesc', { defaultMessage: 'Protect your hosts with threat prevention, detection, and deep security data visibility.', })} @@ -243,10 +243,10 @@ export const AvailablePackages: React.FC = memo(() => { { } href={addBasePath('/app/enterprise_search/app_search')} - title={i18n.translate('xpack.observability.home.featuredObsTitle', { + title={i18n.translate('xpack.fleet.featuredSearchTitle', { defaultMessage: 'Web site crawler', })} - description={i18n.translate('xpack.observability.home.featuredObsDesc', { + description={i18n.translate('xpack.fleet.featuredSearchDesc', { defaultMessage: 'Add search to your website with the App Search web crawler.', })} /> diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 852b01977b78b..66e16ef87365d 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -11010,7 +11010,6 @@ "xpack.fleet.epm.usedByLabel": "エージェントポリシー", "xpack.fleet.epm.versionLabel": "バージョン", "xpack.fleet.epmList.allPackagesFilterLinkText": "すべて", - "xpack.fleet.epmList.installedTitle": "インストールされている統合", "xpack.fleet.epmList.missingIntegrationPlaceholder": "検索用語と一致する統合が見つかりませんでした。別のキーワードを試すか、左側のカテゴリを使用して参照してください。", "xpack.fleet.epmList.noPackagesFoundPlaceholder": "パッケージが見つかりません", "xpack.fleet.epmList.searchPackagesPlaceholder": "統合を検索", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 9d88c757f1e58..ac7a518a699a0 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -11125,7 +11125,6 @@ "xpack.fleet.epm.usedByLabel": "代理策略", "xpack.fleet.epm.versionLabel": "版本", "xpack.fleet.epmList.allPackagesFilterLinkText": "全部", - "xpack.fleet.epmList.installedTitle": "已安装集成", "xpack.fleet.epmList.missingIntegrationPlaceholder": "我们未找到任何匹配搜索词的集成。请重试其他关键字,或使用左侧的类别浏览。", "xpack.fleet.epmList.noPackagesFoundPlaceholder": "未找到任何软件包", "xpack.fleet.epmList.searchPackagesPlaceholder": "搜索集成", From 1ef8d186bcee0bf644b8e702f1b82dd12bfe2e84 Mon Sep 17 00:00:00 2001 From: Dave Snider Date: Tue, 19 Oct 2021 01:26:09 -0400 Subject: [PATCH 3/5] ts fix --- .../sections/epm/screens/home/available_packages.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/available_packages.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/available_packages.tsx index a25b8ca0f8126..9695609714f30 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/available_packages.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/available_packages.tsx @@ -15,7 +15,6 @@ import { EuiFlexGrid, EuiSpacer, EuiCard, - EuiFlexGroup, EuiIcon, } from '@elastic/eui'; From 103b77f02a584d478b49a37741a5d5cc46ce146d Mon Sep 17 00:00:00 2001 From: Dave Snider Date: Tue, 19 Oct 2021 08:30:29 -0400 Subject: [PATCH 4/5] center button in no data card --- .../elastic_agent_card.test.tsx.snap | 58 +++++++++++++------ .../__snapshots__/no_data_card.test.tsx.snap | 58 +++++++++++++------ .../no_data_card/elastic_agent_card.tsx | 7 ++- .../no_data_card/no_data_card.tsx | 2 +- 4 files changed, 87 insertions(+), 38 deletions(-) diff --git a/src/plugins/kibana_react/public/page_template/no_data_page/no_data_card/__snapshots__/elastic_agent_card.test.tsx.snap b/src/plugins/kibana_react/public/page_template/no_data_page/no_data_card/__snapshots__/elastic_agent_card.test.tsx.snap index 1168641e58537..9d5ed70c2c33a 100644 --- a/src/plugins/kibana_react/public/page_template/no_data_page/no_data_card/__snapshots__/elastic_agent_card.test.tsx.snap +++ b/src/plugins/kibana_react/public/page_template/no_data_page/no_data_card/__snapshots__/elastic_agent_card.test.tsx.snap @@ -4,11 +4,16 @@ exports[`ElasticAgentCard props button 1`] = ` Button - + + Button + +
} href="/app/integrations/browse" image="/plugins/kibanaReact/assets/elastic_agent_card.svg" @@ -28,11 +33,15 @@ exports[`ElasticAgentCard props category 1`] = ` - Add Elastic Agent - + + Add Elastic Agent + +
} href="/app/integrations/browse/custom" image="/plugins/kibanaReact/assets/elastic_agent_card.svg" @@ -52,11 +61,16 @@ exports[`ElasticAgentCard props href 1`] = ` Button - + + Button + +
} href="#" image="/plugins/kibanaReact/assets/elastic_agent_card.svg" @@ -77,11 +91,15 @@ exports[`ElasticAgentCard props recommended 1`] = ` betaBadgeLabel="Recommended" description="Use Elastic Agent for a simple, unified way to collect data from your machines." footer={ - - Add Elastic Agent - + + Add Elastic Agent + +
} href="/app/integrations/browse" image="/plugins/kibanaReact/assets/elastic_agent_card.svg" @@ -101,11 +119,15 @@ exports[`ElasticAgentCard renders 1`] = ` - Add Elastic Agent - + + Add Elastic Agent + +
} href="/app/integrations/browse" image="/plugins/kibanaReact/assets/elastic_agent_card.svg" diff --git a/src/plugins/kibana_react/public/page_template/no_data_page/no_data_card/__snapshots__/no_data_card.test.tsx.snap b/src/plugins/kibana_react/public/page_template/no_data_page/no_data_card/__snapshots__/no_data_card.test.tsx.snap index 1eff83d9248e1..6959e2e29095a 100644 --- a/src/plugins/kibana_react/public/page_template/no_data_page/no_data_card/__snapshots__/no_data_card.test.tsx.snap +++ b/src/plugins/kibana_react/public/page_template/no_data_page/no_data_card/__snapshots__/no_data_card.test.tsx.snap @@ -25,20 +25,24 @@ exports[`NoDataCard props button 1`] = ` `; @@ -75,20 +79,24 @@ exports[`NoDataCard props href 1`] = ` `; @@ -126,6 +134,13 @@ exports[`NoDataCard props recommended 1`] = ` Recommended
+ `; @@ -151,5 +166,12 @@ exports[`NoDataCard renders 1`] = `

+ `; diff --git a/src/plugins/kibana_react/public/page_template/no_data_page/no_data_card/elastic_agent_card.tsx b/src/plugins/kibana_react/public/page_template/no_data_page/no_data_card/elastic_agent_card.tsx index a09ebf01795c6..33594a40a5a41 100644 --- a/src/plugins/kibana_react/public/page_template/no_data_page/no_data_card/elastic_agent_card.tsx +++ b/src/plugins/kibana_react/public/page_template/no_data_page/no_data_card/elastic_agent_card.tsx @@ -92,7 +92,12 @@ export const ElasticAgentCard: FunctionComponent = ({ defaultMessage: `Use Elastic Agent for a simple, unified way to collect data from your machines.`, })} betaBadgeLabel={recommended ? NO_DATA_RECOMMENDED : undefined} - footer={footer} + footer={ +
+ {button} + {footer} +
+ } layout={layout as 'vertical' | undefined} {...cardRest} /> diff --git a/src/plugins/kibana_react/public/page_template/no_data_page/no_data_card/no_data_card.tsx b/src/plugins/kibana_react/public/page_template/no_data_page/no_data_card/no_data_card.tsx index 524283a7c8336..ad40a4f8f5499 100644 --- a/src/plugins/kibana_react/public/page_template/no_data_page/no_data_card/no_data_card.tsx +++ b/src/plugins/kibana_react/public/page_template/no_data_page/no_data_card/no_data_card.tsx @@ -35,7 +35,7 @@ export const NoDataCard: FunctionComponent = ({ defaultMessage: `Proceed without collecting data`, })} betaBadgeLabel={recommended ? NO_DATA_RECOMMENDED : undefined} - footer={footer} + footer={
{footer}
} layout={layout as 'vertical' | undefined} {...cardRest} /> From ad1f3bf83fcdc21da1d172055c5452d18a851340 Mon Sep 17 00:00:00 2001 From: Dave Snider Date: Wed, 20 Oct 2021 08:31:49 -0400 Subject: [PATCH 5/5] tracking ids --- .../epm/screens/home/available_packages.tsx | 71 ++++++++++--------- 1 file changed, 39 insertions(+), 32 deletions(-) diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/available_packages.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/available_packages.tsx index 18f2b53a921b4..4f13a874532f1 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/available_packages.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/available_packages.tsx @@ -19,6 +19,7 @@ import { } from '@elastic/eui'; import { useStartServices } from '../../../../hooks'; +import { TrackApplicationView } from '../../../../../../../../../../src/plugins/usage_collection/public'; import { pagePathGetters } from '../../../../constants'; import { @@ -228,42 +229,48 @@ export const AvailablePackages: React.FC = memo(() => { <> - } - href={addBasePath('/app/integrations/detail/endpoint/')} - title={i18n.translate('xpack.fleet.featuredSecurityTitle', { - defaultMessage: 'Endpoint Security', - })} - description={i18n.translate('xpack.fleet.featuredSecurityDesc', { - defaultMessage: - 'Protect your hosts with threat prevention, detection, and deep security data visibility.', - })} - /> + + } + href={addBasePath('/app/integrations/detail/endpoint/')} + title={i18n.translate('xpack.fleet.featuredSecurityTitle', { + defaultMessage: 'Endpoint Security', + })} + description={i18n.translate('xpack.fleet.featuredSecurityDesc', { + defaultMessage: + 'Protect your hosts with threat prevention, detection, and deep security data visibility.', + })} + /> + - } - /> + + } + /> + - } - href={addBasePath('/app/enterprise_search/app_search')} - title={i18n.translate('xpack.fleet.featuredSearchTitle', { - defaultMessage: 'Web site crawler', - })} - description={i18n.translate('xpack.fleet.featuredSearchDesc', { - defaultMessage: 'Add search to your website with the App Search web crawler.', - })} - /> + + } + href={addBasePath('/app/enterprise_search/app_search')} + title={i18n.translate('xpack.fleet.featuredSearchTitle', { + defaultMessage: 'Web site crawler', + })} + description={i18n.translate('xpack.fleet.featuredSearchDesc', { + defaultMessage: 'Add search to your website with the App Search web crawler.', + })} + /> +