diff --git a/src/plugins/home/public/application/components/__snapshots__/home.test.tsx.snap b/src/plugins/home/public/application/components/__snapshots__/home.test.tsx.snap
index b6679dd7ba493..f38bdb9ac53f0 100644
--- a/src/plugins/home/public/application/components/__snapshots__/home.test.tsx.snap
+++ b/src/plugins/home/public/application/components/__snapshots__/home.test.tsx.snap
@@ -21,10 +21,28 @@ exports[`home change home route should render a link to change the default route
/>
-
-
-
-`;
-
-exports[`home welcome should show the normal home page if loading fails 1`] = `
-,
- }
- }
- template="empty"
->
-
-
-
-
-
-`;
-
-exports[`home welcome should show the normal home page if welcome screen is disabled locally 1`] = `
-,
+ application={
+ Object {
+ "capabilities": Object {
+ "navLinks": Object {
+ "integrations": true,
+ },
+ },
+ }
}
- }
- template="empty"
->
-
-
-
-
-`;
-
-exports[`home welcome should show the welcome screen if enabled, and there are no index patterns defined 1`] = `
-
-`;
-
-exports[`home welcome stores skip welcome setting if skipped 1`] = `
-,
- }
- }
- template="empty"
->
-
-
-
({
getServices: () => ({
getBasePath: () => 'path',
@@ -22,6 +24,13 @@ jest.mock('../kibana_services', () => ({
chrome: {
setBreadcrumbs: () => {},
},
+ application: {
+ capabilities: {
+ navLinks: {
+ integrations: mockHasIntegrationsPermission,
+ },
+ },
+ },
}),
}));
@@ -35,6 +44,7 @@ describe('home', () => {
let defaultProps: HomeProps;
beforeEach(() => {
+ mockHasIntegrationsPermission = true;
defaultProps = {
directories: [],
solutions: [],
@@ -182,7 +192,7 @@ describe('home', () => {
expect(defaultProps.localStorage.getItem).toHaveBeenCalledTimes(1);
- expect(component).toMatchSnapshot();
+ expect(component.find(Welcome).exists()).toBe(true);
});
test('stores skip welcome setting if skipped', async () => {
@@ -196,7 +206,7 @@ describe('home', () => {
expect(defaultProps.localStorage.setItem).toHaveBeenCalledWith('home:welcome:show', 'false');
- expect(component).toMatchSnapshot();
+ expect(component.find(Welcome).exists()).toBe(false);
});
test('should show the normal home page if loading fails', async () => {
@@ -205,7 +215,7 @@ describe('home', () => {
const hasUserIndexPattern = jest.fn(() => Promise.reject('Doh!'));
const component = await renderHome({ hasUserIndexPattern });
- expect(component).toMatchSnapshot();
+ expect(component.find(Welcome).exists()).toBe(false);
});
test('should show the normal home page if welcome screen is disabled locally', async () => {
@@ -213,7 +223,15 @@ describe('home', () => {
const component = await renderHome();
- expect(component).toMatchSnapshot();
+ expect(component.find(Welcome).exists()).toBe(false);
+ });
+
+ test("should show the normal home page if user doesn't have access to integrations", async () => {
+ mockHasIntegrationsPermission = false;
+
+ const component = await renderHome();
+
+ expect(component.find(Welcome).exists()).toBe(false);
});
});
diff --git a/src/plugins/home/public/application/components/home.tsx b/src/plugins/home/public/application/components/home.tsx
index d398311d30255..2a08754889c28 100644
--- a/src/plugins/home/public/application/components/home.tsx
+++ b/src/plugins/home/public/application/components/home.tsx
@@ -45,10 +45,10 @@ export class Home extends Component {
constructor(props: HomeProps) {
super(props);
- const isWelcomeEnabled = !(
- getServices().homeConfig.disableWelcomeScreen ||
- props.localStorage.getItem(KEY_ENABLE_WELCOME) === 'false'
- );
+ const isWelcomeEnabled =
+ !getServices().homeConfig.disableWelcomeScreen &&
+ getServices().application.capabilities.navLinks.integrations &&
+ props.localStorage.getItem(KEY_ENABLE_WELCOME) !== 'false';
const body = document.querySelector('body')!;
body.classList.add('isHomPage');
diff --git a/src/plugins/home/public/application/components/home_app.js b/src/plugins/home/public/application/components/home_app.js
index b0ba4d46646d0..1dbcaa6f50fa1 100644
--- a/src/plugins/home/public/application/components/home_app.js
+++ b/src/plugins/home/public/application/components/home_app.js
@@ -17,8 +17,11 @@ import { getTutorial } from '../load_tutorials';
import { replaceTemplateStrings } from './tutorial/replace_template_strings';
import { getServices } from '../kibana_services';
+const REDIRECT_TO_INTEGRATIONS_TAB_IDS = ['all', 'logging', 'metrics', 'security'];
+
export function HomeApp({ directories, solutions }) {
const {
+ application,
savedObjectsClient,
getBasePath,
addBasePath,
@@ -30,10 +33,17 @@ export function HomeApp({ directories, solutions }) {
const isCloudEnabled = environment.cloud;
const renderTutorialDirectory = (props) => {
+ // Redirect to integrations app unless a specific tab that is still supported was specified.
+ const tabId = props.match.params.tab;
+ if (!tabId || REDIRECT_TO_INTEGRATIONS_TAB_IDS.includes(tabId)) {
+ application.navigateToApp('integrations', { replace: true });
+ return null;
+ }
+
return (
);
diff --git a/src/plugins/home/public/application/components/tutorial/tutorial.js b/src/plugins/home/public/application/components/tutorial/tutorial.js
index 508a236bf45d4..4af5e362baca9 100644
--- a/src/plugins/home/public/application/components/tutorial/tutorial.js
+++ b/src/plugins/home/public/application/components/tutorial/tutorial.js
@@ -26,9 +26,8 @@ const INSTRUCTIONS_TYPE = {
ON_PREM_ELASTIC_CLOUD: 'onPremElasticCloud',
};
-const homeTitle = i18n.translate('home.breadcrumbs.homeTitle', { defaultMessage: 'Home' });
-const addDataTitle = i18n.translate('home.breadcrumbs.addDataTitle', {
- defaultMessage: 'Add data',
+const integrationsTitle = i18n.translate('home.breadcrumbs.integrationsAppTitle', {
+ defaultMessage: 'Integrations',
});
class TutorialUi extends React.Component {
@@ -80,12 +79,8 @@ class TutorialUi extends React.Component {
getServices().chrome.setBreadcrumbs([
{
- text: homeTitle,
- href: '#/',
- },
- {
- text: addDataTitle,
- href: '#/tutorial_directory',
+ text: integrationsTitle,
+ href: this.props.addBasePath('/app/integrations/browse'),
},
{
text: tutorial ? tutorial.name : this.props.tutorialId,
diff --git a/src/plugins/home/public/application/components/tutorial_directory.js b/src/plugins/home/public/application/components/tutorial_directory.js
index 83e629a7c891e..ac0d1524145a1 100644
--- a/src/plugins/home/public/application/components/tutorial_directory.js
+++ b/src/plugins/home/public/application/components/tutorial_directory.js
@@ -18,12 +18,10 @@ import { getServices } from '../kibana_services';
import { KibanaPageTemplate } from '../../../../kibana_react/public';
import { getTutorials } from '../load_tutorials';
-const ALL_TAB_ID = 'all';
const SAMPLE_DATA_TAB_ID = 'sampleData';
-const homeTitle = i18n.translate('home.breadcrumbs.homeTitle', { defaultMessage: 'Home' });
-const addDataTitle = i18n.translate('home.breadcrumbs.addDataTitle', {
- defaultMessage: 'Add data',
+const integrationsTitle = i18n.translate('home.breadcrumbs.integrationsAppTitle', {
+ defaultMessage: 'Integrations',
});
class TutorialDirectoryUi extends React.Component {
@@ -48,7 +46,7 @@ class TutorialDirectoryUi extends React.Component {
})),
];
- let openTab = ALL_TAB_ID;
+ let openTab = SAMPLE_DATA_TAB_ID;
if (
props.openTab &&
this.tabs.some((tab) => {
@@ -72,10 +70,9 @@ class TutorialDirectoryUi extends React.Component {
getServices().chrome.setBreadcrumbs([
{
- text: homeTitle,
- href: '#/',
+ text: integrationsTitle,
+ href: this.props.addBasePath(`/app/integrations/browse`),
},
- { text: addDataTitle },
]);
const tutorialConfigs = await getTutorials();
@@ -155,6 +152,15 @@ class TutorialDirectoryUi extends React.Component {
renderTabContent = () => {
const tab = this.tabs.find(({ id }) => id === this.state.selectedTabId);
if (tab?.content) {
+ getServices().chrome.setBreadcrumbs([
+ {
+ text: integrationsTitle,
+ href: this.props.addBasePath(`/app/integrations/browse`),
+ },
+ {
+ text: tab.name,
+ },
+ ]);
return tab.content;
}
@@ -163,7 +169,7 @@ class TutorialDirectoryUi extends React.Component {
{this.state.tutorialCards
.filter((tutorial) => {
return (
- this.state.selectedTabId === ALL_TAB_ID ||
+ this.state.selectedTabId === SAMPLE_DATA_TAB_ID ||
this.state.selectedTabId === tutorial.category
);
})
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..8e1d0cb92e006 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
@@ -1,117 +1,177 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ElasticAgentCard props button 1`] = `
-
- Button
-
+
-
- Add Elastic Agent
-
-
- }
-/>
+>
+
+ Button
+
+ }
+ href="/app/integrations/browse"
+ image="/plugins/kibanaReact/assets/elastic_agent_card.svg"
+ paddingSize="l"
+ title={
+
+
+ Add Elastic Agent
+
+
+ }
+ />
+
`;
exports[`ElasticAgentCard props category 1`] = `
-
- Add Elastic Agent
-
+
-
+>
+
Add Elastic Agent
-
-
- }
-/>
+
+ }
+ href="/app/integrations/browse/custom"
+ image="/plugins/kibanaReact/assets/elastic_agent_card.svg"
+ paddingSize="l"
+ title={
+
+
+ Add Elastic Agent
+
+
+ }
+ />
+
`;
exports[`ElasticAgentCard props href 1`] = `
-
- Button
-
+
-
- Add Elastic Agent
-
-
- }
-/>
+>
+
+ Button
+
+ }
+ href="#"
+ image="/plugins/kibanaReact/assets/elastic_agent_card.svg"
+ paddingSize="l"
+ title={
+
+
+ Add Elastic Agent
+
+
+ }
+ />
+
`;
exports[`ElasticAgentCard props recommended 1`] = `
-
- Add Elastic Agent
-
+
-
+>
+
Add Elastic Agent
-
-
- }
-/>
+
+ }
+ href="/app/integrations/browse"
+ image="/plugins/kibanaReact/assets/elastic_agent_card.svg"
+ paddingSize="l"
+ title={
+
+
+ Add Elastic Agent
+
+
+ }
+ />
+
`;
exports[`ElasticAgentCard renders 1`] = `
-
- Add Elastic Agent
-
+
-
+>
+
Add Elastic Agent
-
-
- }
-/>
+
+ }
+ href="/app/integrations/browse"
+ image="/plugins/kibanaReact/assets/elastic_agent_card.svg"
+ paddingSize="l"
+ title={
+
+
+ Add Elastic Agent
+
+
+ }
+ />
+
`;
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 5a91e568471d1..b9d412fe4df89 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
@@ -12,6 +12,7 @@ import { CoreStart } from 'kibana/public';
import { EuiButton, EuiCard, EuiTextColor, EuiScreenReaderOnly } from '@elastic/eui';
import { useKibana } from '../../../context';
import { NoDataPageActions, NO_DATA_RECOMMENDED } from '../no_data_page';
+import { RedirectAppLinks } from '../../../app_links';
export type ElasticAgentCardProps = NoDataPageActions & {
solution: string;
@@ -76,23 +77,25 @@ export const ElasticAgentCard: FunctionComponent = ({
);
return (
-
- {defaultCTAtitle}
-
- }
- description={i18n.translate('kibana-react.noDataPage.elasticAgentCard.description', {
- defaultMessage: `Use Elastic Agent for a simple, unified way to collect data from your machines.`,
- })}
- betaBadgeLabel={recommended ? NO_DATA_RECOMMENDED : undefined}
- footer={footer}
- layout={layout as 'vertical' | undefined}
- {...cardRest}
- />
+
+
+ {defaultCTAtitle}
+
+ }
+ description={i18n.translate('kibana-react.noDataPage.elasticAgentCard.description', {
+ defaultMessage: `Use Elastic Agent for a simple, unified way to collect data from your machines.`,
+ })}
+ betaBadgeLabel={recommended ? NO_DATA_RECOMMENDED : undefined}
+ footer={footer}
+ layout={layout as 'vertical' | undefined}
+ {...cardRest}
+ />
+
);
};
diff --git a/test/functional/apps/home/_add_data.js b/test/functional/apps/home/_add_data.ts
similarity index 59%
rename from test/functional/apps/home/_add_data.js
rename to test/functional/apps/home/_add_data.ts
index c69e0a02c26e4..3fd69c1a488f4 100644
--- a/test/functional/apps/home/_add_data.js
+++ b/test/functional/apps/home/_add_data.ts
@@ -6,20 +6,15 @@
* Side Public License, v 1.
*/
-import expect from '@kbn/expect';
+import { FtrProviderContext } from '../../ftr_provider_context';
-export default function ({ getService, getPageObjects }) {
- const retry = getService('retry');
+export default function ({ getService, getPageObjects }: FtrProviderContext) {
const PageObjects = getPageObjects(['common', 'header', 'home', 'dashboard']);
describe('add data tutorials', function describeIndexTests() {
- it('directory should display registered tutorials', async () => {
+ it('directory should redirect to integrations app', async () => {
await PageObjects.common.navigateToUrl('home', 'tutorial_directory', { useActualUrl: true });
- await PageObjects.header.waitUntilLoadingHasFinished();
- await retry.try(async () => {
- const tutorialExists = await PageObjects.home.doesSynopsisExist('netflowlogs');
- expect(tutorialExists).to.be(true);
- });
+ await PageObjects.common.waitUntilUrlIncludes('/app/integrations');
});
});
}
diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json
index aac0f651b8dee..b9a2d8164eb2c 100644
--- a/x-pack/plugins/translations/translations/ja-JP.json
+++ b/x-pack/plugins/translations/translations/ja-JP.json
@@ -2915,7 +2915,6 @@
"home.addData.sampleDataButtonLabel": "サンプルデータを試す",
"home.addData.sectionTitle": "データを追加して開始する",
"home.addData.text": "データの操作を開始するには、多数の取り込みオプションのいずれかを使用します。アプリまたはサービスからデータを収集するか、ファイルをアップロードします。独自のデータを使用する準備ができていない場合は、サンプルデータセットを追加してください。",
- "home.breadcrumbs.addDataTitle": "データの追加",
"home.breadcrumbs.homeTitle": "ホーム",
"home.dataManagementDisableCollection": " 収集を停止するには、",
"home.dataManagementDisableCollectionLink": "ここで使用状況データを無効にします。",
diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json
index 50d90f5144585..4cf42a2aa84ee 100644
--- a/x-pack/plugins/translations/translations/zh-CN.json
+++ b/x-pack/plugins/translations/translations/zh-CN.json
@@ -2944,7 +2944,6 @@
"home.addData.sampleDataButtonLabel": "试用样例数据",
"home.addData.sectionTitle": "首先添加您的数据",
"home.addData.text": "要开始使用您的数据,请使用我们众多采集选项中的一个选项。从应用或服务收集数据,或上传文件。如果未准备好使用自己的数据,请添加示例数据集。",
- "home.breadcrumbs.addDataTitle": "添加数据",
"home.breadcrumbs.homeTitle": "主页",
"home.dataManagementDisableCollection": " 要停止收集,",
"home.dataManagementDisableCollectionLink": "请在此禁用使用情况数据。",