From b1cd9bb3bae69c4fc32dd53fb5db13aec5cb0e51 Mon Sep 17 00:00:00 2001 From: Christopher Davies Date: Fri, 27 Jul 2018 09:31:15 -0400 Subject: [PATCH 01/13] Add a welcome screen to Kibana home if this is a "new" Kibana instance. New is determined by whether or not there are any index patterns defined. --- .../kibana/public/home/components/home.js | 131 ++++++++++-------- .../kibana/public/home/components/welcome.js | 126 +++++++++++++++++ src/core_plugins/kibana/public/home/home.less | 46 ++++++ .../settings/lib/get_category_name.js | 17 +-- .../kibana/ui_setting_defaults.js | 7 + 5 files changed, 264 insertions(+), 63 deletions(-) create mode 100644 src/core_plugins/kibana/public/home/components/welcome.js diff --git a/src/core_plugins/kibana/public/home/components/home.js b/src/core_plugins/kibana/public/home/components/home.js index a138983226a9f..9dcd52edb36bb 100644 --- a/src/core_plugins/kibana/public/home/components/home.js +++ b/src/core_plugins/kibana/public/home/components/home.js @@ -22,6 +22,7 @@ import PropTypes from 'prop-types'; import { Synopsis } from './synopsis'; import { AddData } from './add_data'; import { RecentlyAccessed, recentlyAccessedShape } from './recently_accessed'; +import chrome from 'ui/chrome'; import { EuiButton, @@ -36,13 +37,16 @@ import { EuiPageBody, } from '@elastic/eui'; +import { Welcome, WelcomePreference } from './welcome'; + import { FeatureCatalogueCategory } from 'ui/registry/feature_catalogue'; export class Home extends Component { - state = { + isLoading: true, isNewKibanaInstance: false, - } + isWelcomeEnabled: WelcomePreference.isEnabled, + }; componentWillUnmount() { this._isMounted = false; @@ -54,37 +58,39 @@ export class Home extends Component { } fetchIsNewKibanaInstance = async () => { - let resp; + chrome.loadingCount.increment(); + try { - resp = await this.props.find({ - type: 'index-pattern', - fields: ['title'], - search: `*`, - search_fields: ['title'], - perPage: 1 - }); - } catch (error) { - // ignore error - find is not critical for page functioning, - // just used to add some extra styling when there are no index-patterns - return; + const resp = await this.props + .find({ + type: 'index-pattern', + fields: ['title'], + search: `*`, + search_fields: ['title'], + perPage: 1, + }); + this._isMounted && this.setState({ isNewKibanaInstance: resp.total === 0 }); + } catch (err) { + // An error here is relatively unimportant, as it only means we don't provide + // some UI niceties. } - if (!this._isMounted) { - return; - } + this._isMounted && this.setState({ isLoading: false }); + chrome.loadingCount.decrement(); + }; - this.setState({ - isNewKibanaInstance: resp.total === 0 - }); - } + skipWelcome = () => { + WelcomePreference.isEnabled = false; + this._isMounted && this.setState({ isWelcomeEnabled: false }); + }; - renderDirectories = (category) => { + renderDirectories = category => { const { addBasePath, directories } = this.props; return directories - .filter((directory) => { + .filter(directory => { return directory.showOnHomePage && directory.category === category; }) - .map((directory) => { + .map(directory => { return ( 0) { recentlyAccessedPanel = ( - + ); @@ -117,7 +120,6 @@ export class Home extends Component { return ( - {recentlyAccessedPanel} -

- Visualize and Explore Data -

+

Visualize and Explore Data

- + - { this.renderDirectories(FeatureCatalogueCategory.DATA) } + {this.renderDirectories(FeatureCatalogueCategory.DATA)}
-

- Manage and Administer the Elastic Stack -

+

Manage and Administer the Elastic Stack

- + - { this.renderDirectories(FeatureCatalogueCategory.ADMIN) } + {this.renderDirectories(FeatureCatalogueCategory.ADMIN)}
@@ -161,14 +159,10 @@ export class Home extends Component { -

- Didn’t find what you were looking for? -

+

Didn’t find what you were looking for?

- + View full directory of Kibana plugins
@@ -177,19 +171,46 @@ export class Home extends Component { ); } + + // For now, loading is just an empty page w/ the standard + // Kibana chrome.loadingCount.increment() indicator. + renderLoading() { + return ''; + } + + renderWelcome() { + return ; + } + + render() { + const { isLoading, isWelcomeEnabled, isNewKibanaInstance } = this.state; + + if (isWelcomeEnabled) { + if (isLoading) { + return this.renderLoading(); + } + if (isNewKibanaInstance) { + return this.renderWelcome(); + } + } + + return this.renderNormal(); + } } Home.propTypes = { addBasePath: PropTypes.func.isRequired, - directories: PropTypes.arrayOf(PropTypes.shape({ - id: PropTypes.string.isRequired, - title: PropTypes.string.isRequired, - description: PropTypes.string.isRequired, - icon: PropTypes.string.isRequired, - path: PropTypes.string.isRequired, - showOnHomePage: PropTypes.bool.isRequired, - category: PropTypes.string.isRequired - })), + directories: PropTypes.arrayOf( + PropTypes.shape({ + id: PropTypes.string.isRequired, + title: PropTypes.string.isRequired, + description: PropTypes.string.isRequired, + icon: PropTypes.string.isRequired, + path: PropTypes.string.isRequired, + showOnHomePage: PropTypes.bool.isRequired, + category: PropTypes.string.isRequired, + }) + ), apmUiEnabled: PropTypes.bool.isRequired, recentlyAccessed: PropTypes.arrayOf(recentlyAccessedShape).isRequired, find: PropTypes.func.isRequired, diff --git a/src/core_plugins/kibana/public/home/components/welcome.js b/src/core_plugins/kibana/public/home/components/welcome.js new file mode 100644 index 0000000000000..9e7c523f26f7d --- /dev/null +++ b/src/core_plugins/kibana/public/home/components/welcome.js @@ -0,0 +1,126 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* + * The UI and related logic for the welcome screen that *should* show only + * when it is enabled (the default) and there is no Kibana-consumed data + * in Elasticsearch. + */ + +import React from 'react'; +import PropTypes from 'prop-types'; +import chrome from 'ui/chrome'; +import { + EuiCard, + EuiTitle, + EuiSpacer, + EuiFlexGroup, + EuiFlexItem, + EuiText, + EuiIcon, +} from '@elastic/eui'; + +const ENABLE_WELCOME = 'home:welcome:show'; + +/** + * A lightweight wrapper around the 'home:welcome:show' setting. + */ +export const WelcomePreference = { + get isEnabled() { + return chrome.getUiSettingsClient().get(ENABLE_WELCOME, true); + }, + set isEnabled(val) { + return chrome.getUiSettingsClient().set(ENABLE_WELCOME, val); + }, +}; + +/** + * Shows a full-screen welcome page that gives helpful quick links to beginners. + */ +export class Welcome extends React.Component { + hideOnEsc = (e) => { + if (e.key === 'Escape') { + this.props.skipWelcome(); + } + } + + componentDidMount() { + document.addEventListener('keydown', this.hideOnEsc); + } + + componentWillUnmount() { + document.removeEventListener('keydown', this.hideOnEsc); + } + + render() { + const { skipWelcome, kibanaVersion } = this.props; + const majorVersion = kibanaVersion.split('.')[0]; + + return ( +
+
+
+ + + + + +

Welcome to Kibana {majorVersion}

+
+ Your window into the Elastic stack + +
+
+
+
+ + + Choose a way to start your journey + + +
+ + + + } + title="Play around with sample data" + description="See what Kibana is capable of without all the setup." + href="#/home/tutorial_directory/sampleData" + /> + + + } + title="I don't need help" + description="Skip the tour. I know what I'm doing." + onClick={skipWelcome} + /> + + +
+
+ ); + } +} + +Welcome.propTypes = { + kibanaVersion: PropTypes.string.isRequired, + skipWelcome: PropTypes.func.isRequired, +}; diff --git a/src/core_plugins/kibana/public/home/home.less b/src/core_plugins/kibana/public/home/home.less index 010b83cb4d74f..c7fcc4014affd 100644 --- a/src/core_plugins/kibana/public/home/home.less +++ b/src/core_plugins/kibana/public/home/home.less @@ -22,3 +22,49 @@ home-app { .homeDirectoryTab { background-color: @globalColorLightestGray; } + +.home-welcome { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 100000; + background: inherit; + color: inherit; + opacity: 0; + animation: homeFadeIn 0.5s ease-in 0s forwards; +} + +.home-welcome-header { + background: #0079A5; + color: white; +} + +.home-welcome-title { + color: inherit; +} + +.home-welcome-logo { + display: inline-block; + margin-bottom: 24px; + background-color: white; + border-radius: 100%; + padding: 16px; +} + +.home-welcome-content { + margin: auto; + max-width: 800px; + padding-left: 32px; + padding-right: 32px; +} + +@keyframes homeFadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } +} \ No newline at end of file diff --git a/src/core_plugins/kibana/public/management/sections/settings/lib/get_category_name.js b/src/core_plugins/kibana/public/management/sections/settings/lib/get_category_name.js index cad3f28a5ad16..65fd1a4dfb84b 100644 --- a/src/core_plugins/kibana/public/management/sections/settings/lib/get_category_name.js +++ b/src/core_plugins/kibana/public/management/sections/settings/lib/get_category_name.js @@ -20,14 +20,15 @@ import { StringUtils } from 'ui/utils/string_utils'; const names = { - 'general': 'General', - 'timelion': 'Timelion', - 'notifications': 'Notifications', - 'visualizations': 'Visualizations', - 'discover': 'Discover', - 'dashboard': 'Dashboard', - 'reporting': 'Reporting', - 'search': 'Search', + general: 'General', + timelion: 'Timelion', + notifications: 'Notifications', + visualizations: 'Visualizations', + discover: 'Discover', + dashboard: 'Dashboard', + reporting: 'Reporting', + search: 'Search', + home: 'Home', }; export function getCategoryName(category) { diff --git a/src/core_plugins/kibana/ui_setting_defaults.js b/src/core_plugins/kibana/ui_setting_defaults.js index dc00edaad0b27..587e9a2800859 100644 --- a/src/core_plugins/kibana/ui_setting_defaults.js +++ b/src/core_plugins/kibana/ui_setting_defaults.js @@ -416,6 +416,13 @@ export function getUiSettingDefaults() { target="_blank" rel="noopener noreferrer">accepted formats), "display" (the title to be displayed), and "section" (which column to put the option in).` }, + 'home:welcome:show': { + name: 'Show the welcome screen', + value: true, + description: `Toggles whether or not to show the welcome screen if + this is a new installation of Kibana.`, + category: ['home'], + }, 'dashboard:defaultDarkTheme': { name: 'Dark theme', value: false, From 052fb9d369b8f1aeadd1e1ba1b1c6fe236ed218b Mon Sep 17 00:00:00 2001 From: Christopher Davies Date: Fri, 27 Jul 2018 11:11:46 -0400 Subject: [PATCH 02/13] Add tests for welcome experience --- .../__snapshots__/home.test.js.snap | 251 ++++++++++++- .../kibana/public/home/components/home.js | 31 +- .../public/home/components/home.test.js | 342 ++++++++++-------- .../kibana/public/home/components/home_app.js | 6 + .../kibana/public/home/components/welcome.js | 15 - 5 files changed, 467 insertions(+), 178 deletions(-) diff --git a/src/core_plugins/kibana/public/home/components/__snapshots__/home.test.js.snap b/src/core_plugins/kibana/public/home/components/__snapshots__/home.test.js.snap index 0c3bf9f9614bc..7c7bb679e1790 100644 --- a/src/core_plugins/kibana/public/home/components/__snapshots__/home.test.js.snap +++ b/src/core_plugins/kibana/public/home/components/__snapshots__/home.test.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`directories should not render directory entry when showOnHomePage is false 1`] = ` +exports[`home directories should not render directory entry when showOnHomePage is false 1`] = ` `; -exports[`directories should render ADMIN directory entry in "Manage" panel 1`] = ` +exports[`home directories should render ADMIN directory entry in "Manage" panel 1`] = ` `; -exports[`directories should render DATA directory entry in "Explore Data" panel 1`] = ` +exports[`home directories should render DATA directory entry in "Explore Data" panel 1`] = ` `; -exports[`isNewKibanaInstance should safely handle execeptions 1`] = ` +exports[`home isNewKibanaInstance should safely handle execeptions 1`] = ` `; -exports[`isNewKibanaInstance should set isNewKibanaInstance to false when there are index patterns 1`] = ` +exports[`home isNewKibanaInstance should set isNewKibanaInstance to false when there are index patterns 1`] = ` `; -exports[`isNewKibanaInstance should set isNewKibanaInstance to true when there are no index patterns 1`] = ` +exports[`home isNewKibanaInstance should set isNewKibanaInstance to true when there are no index patterns 1`] = ` `; -exports[`should not contain RecentlyAccessed panel when there is no recentlyAccessed history 1`] = ` +exports[`home should not contain RecentlyAccessed panel when there is no recentlyAccessed history 1`] = ` `; -exports[`should render home component 1`] = ` +exports[`home should render home component 1`] = ` `; + +exports[`home welcome should show the normal home page if loading fails 1`] = ` + + + + + + + + +

+ Visualize and Explore Data +

+
+ + +
+
+ + + +

+ Manage and Administer the Elastic Stack +

+
+ + +
+
+
+ + + + +

+ Didn’t find what you were looking for? +

+
+ + + View full directory of Kibana plugins + +
+
+
+
+`; + +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`] = ` + + + + + + + + +

+ Visualize and Explore Data +

+
+ + +
+
+ + + +

+ Manage and Administer the Elastic Stack +

+
+ + +
+
+
+ + + + +

+ Didn’t find what you were looking for? +

+
+ + + View full directory of Kibana plugins + +
+
+
+
+`; diff --git a/src/core_plugins/kibana/public/home/components/home.js b/src/core_plugins/kibana/public/home/components/home.js index 9dcd52edb36bb..7b8cef0783f79 100644 --- a/src/core_plugins/kibana/public/home/components/home.js +++ b/src/core_plugins/kibana/public/home/components/home.js @@ -22,7 +22,6 @@ import PropTypes from 'prop-types'; import { Synopsis } from './synopsis'; import { AddData } from './add_data'; import { RecentlyAccessed, recentlyAccessedShape } from './recently_accessed'; -import chrome from 'ui/chrome'; import { EuiButton, @@ -37,16 +36,21 @@ import { EuiPageBody, } from '@elastic/eui'; -import { Welcome, WelcomePreference } from './welcome'; - +import { Welcome } from './welcome'; import { FeatureCatalogueCategory } from 'ui/registry/feature_catalogue'; +const KEY_ENABLE_WELCOME = 'home:welcome:show'; + export class Home extends Component { - state = { - isLoading: true, - isNewKibanaInstance: false, - isWelcomeEnabled: WelcomePreference.isEnabled, - }; + constructor(props) { + super(props); + + this.state = { + isLoading: true, + isNewKibanaInstance: false, + isWelcomeEnabled: props.settingsClient.get(KEY_ENABLE_WELCOME, true), + }; + } componentWillUnmount() { this._isMounted = false; @@ -58,7 +62,7 @@ export class Home extends Component { } fetchIsNewKibanaInstance = async () => { - chrome.loadingCount.increment(); + this.props.loadingCount.increment(); try { const resp = await this.props @@ -76,11 +80,11 @@ export class Home extends Component { } this._isMounted && this.setState({ isLoading: false }); - chrome.loadingCount.decrement(); + this.props.loadingCount.decrement(); }; skipWelcome = () => { - WelcomePreference.isEnabled = false; + this.props.settingsClient.set(KEY_ENABLE_WELCOME, false); this._isMounted && this.setState({ isWelcomeEnabled: false }); }; @@ -179,7 +183,7 @@ export class Home extends Component { } renderWelcome() { - return ; + return ; } render() { @@ -214,4 +218,7 @@ Home.propTypes = { apmUiEnabled: PropTypes.bool.isRequired, recentlyAccessed: PropTypes.arrayOf(recentlyAccessedShape).isRequired, find: PropTypes.func.isRequired, + loadingCount: PropTypes.object.isRequired, + kibanaVersion: PropTypes.string.isRequired, + settingsClient: PropTypes.object.isRequired, }; diff --git a/src/core_plugins/kibana/public/home/components/home.test.js b/src/core_plugins/kibana/public/home/components/home.test.js index 590a8727d3f25..6b6840492da99 100644 --- a/src/core_plugins/kibana/public/home/components/home.test.js +++ b/src/core_plugins/kibana/public/home/components/home.test.js @@ -18,175 +18,231 @@ */ import React from 'react'; +import sinon from 'sinon'; import { shallow } from 'enzyme'; import { Home } from './home'; import { FeatureCatalogueCategory } from 'ui/registry/feature_catalogue'; -const addBasePath = (url) => { return `base_path/${url}`; }; -const findMock = () => { - return Promise.resolve({ total: 1 }); -}; - -test('should render home component', () => { - const recentlyAccessed = [ - { - label: 'my vis', - link: 'link_to_my_vis', - id: '1' - } - ]; - const component = shallow(); - - expect(component).toMatchSnapshot(); // eslint-disable-line -}); - -test('should not contain RecentlyAccessed panel when there is no recentlyAccessed history', () => { - const component = shallow(); - - expect(component).toMatchSnapshot(); // eslint-disable-line -}); - -describe('directories', () => { - test('should render DATA directory entry in "Explore Data" panel', () => { - const directoryEntry = { - id: 'dashboard', - title: 'Dashboard', - description: 'Display and share a collection of visualizations and saved searches.', - icon: 'dashboardApp', - path: 'dashboard_landing_page', - showOnHomePage: true, - category: FeatureCatalogueCategory.DATA +describe('home', () => { + let defaultProps; + + beforeEach(() => { + defaultProps = { + recentlyAccessed: [], + directories: [], + apmUiEnabled: true, + kibanaVersion: '99.2.1', + addBasePath(url) { + return `base_path/${url}`; + }, + find() { + return Promise.resolve({ total: 1 }); + }, + loadingCount: { + increment: sinon.mock(), + decrement: sinon.mock(), + }, + settingsClient: { + get: sinon.spy((path, defaultVal) => { + expect(path).toEqual('home:welcome:show'); + expect(defaultVal).toBeTruthy(); + return true; + }), + set: sinon.mock(), + }, }; + }); + async function renderHome(props) { const component = shallow(); - expect(component).toMatchSnapshot(); // eslint-disable-line - }); + // Ensure all promises resolve + await new Promise(resolve => process.nextTick(resolve)); + // Ensure the state changes are reflected + component.update(); - test('should render ADMIN directory entry in "Manage" panel', () => { - const directoryEntry = { - id: 'index_patterns', - title: 'Index Patterns', - description: 'Manage the index patterns that help retrieve your data from Elasticsearch.', - icon: 'indexPatternApp', - path: 'index_management_landing_page', - showOnHomePage: true, - category: FeatureCatalogueCategory.ADMIN - }; + return component; + } - const component = shallow(); + test('should render home component', async () => { + const component = await renderHome({ + recentlyAccessed: [ + { + label: 'my vis', + link: 'link_to_my_vis', + id: '1' + } + ], + }); - expect(component).toMatchSnapshot(); // eslint-disable-line + expect(component).toMatchSnapshot(); }); - test('should not render directory entry when showOnHomePage is false', () => { - const directoryEntry = { - id: 'management', - title: 'Management', - description: 'Your center console for managing the Elastic Stack.', - icon: 'managementApp', - path: 'management_landing_page', - showOnHomePage: false, - category: FeatureCatalogueCategory.ADMIN - }; + test('should not contain RecentlyAccessed panel when there is no recentlyAccessed history', async () => { + const component = await renderHome({ + recentlyAccessed: [], + }); - const component = shallow(); + expect(component).toMatchSnapshot(); + }); - expect(component).toMatchSnapshot(); // eslint-disable-line + describe('directories', () => { + test('should render DATA directory entry in "Explore Data" panel', async () => { + const directoryEntry = { + id: 'dashboard', + title: 'Dashboard', + description: 'Display and share a collection of visualizations and saved searches.', + icon: 'dashboardApp', + path: 'dashboard_landing_page', + showOnHomePage: true, + category: FeatureCatalogueCategory.DATA + }; + + const component = await renderHome({ + directories: [directoryEntry], + }); + + expect(component).toMatchSnapshot(); + }); + + test('should render ADMIN directory entry in "Manage" panel', async () => { + const directoryEntry = { + id: 'index_patterns', + title: 'Index Patterns', + description: 'Manage the index patterns that help retrieve your data from Elasticsearch.', + icon: 'indexPatternApp', + path: 'index_management_landing_page', + showOnHomePage: true, + category: FeatureCatalogueCategory.ADMIN + }; + + const component = await renderHome({ + directories: [directoryEntry], + }); + + expect(component).toMatchSnapshot(); + }); + + test('should not render directory entry when showOnHomePage is false', async () => { + const directoryEntry = { + id: 'management', + title: 'Management', + description: 'Your center console for managing the Elastic Stack.', + icon: 'managementApp', + path: 'management_landing_page', + showOnHomePage: false, + category: FeatureCatalogueCategory.ADMIN + }; + + const component = await renderHome({ + directories: [directoryEntry], + }); + + expect(component).toMatchSnapshot(); + }); }); -}); -describe('isNewKibanaInstance', () => { - test('should set isNewKibanaInstance to true when there are no index patterns', async () => { - const component = shallow( { - return Promise.resolve({ total: 0 }); - } - } - />); + describe('loading', () => { + test('should increment and decrement the loading count', async () => { + let found = false; + + await renderHome({ + find: async () => { + sinon.assert.calledOnce(defaultProps.loadingCount.increment); + sinon.assert.notCalled(defaultProps.loadingCount.decrement); + found = true; + return { total: 0 }; + }, + }); + + expect(found).toBeTruthy(); + sinon.assert.calledOnce(defaultProps.loadingCount.increment); + sinon.assert.calledOnce(defaultProps.loadingCount.decrement); + }); + + test('should decrement the loading count even if loading fails', async () => { + await renderHome({ + find: async () => { + throw new Error('Shazm!'); + }, + }); + + sinon.assert.calledOnce(defaultProps.loadingCount.increment); + sinon.assert.calledOnce(defaultProps.loadingCount.decrement); + }); + }); - // Ensure all promises resolve - await new Promise(resolve => process.nextTick(resolve)); - // Ensure the state changes are reflected - component.update(); + describe('welcome', () => { + test('should show the welcome screen if enabled, and there are no index patterns defined', async () => { + defaultProps.settingsClient.get = sinon.spy(() => true); - expect(component).toMatchSnapshot(); // eslint-disable-line - }); + const component = await renderHome({ + find: () => Promise.resolve({ total: 0 }), + }); - test('should set isNewKibanaInstance to false when there are index patterns', async () => { - const component = shallow( { - return Promise.resolve({ total: 1 }); - } - } - />); + sinon.assert.calledOnce(defaultProps.settingsClient.get); - // Ensure all promises resolve - await new Promise(resolve => process.nextTick(resolve)); - // Ensure the state changes are reflected - component.update(); + expect(component).toMatchSnapshot(); + }); + + test('stores skip welcome setting if skipped', async () => { + defaultProps.settingsClient.get = sinon.spy(() => true); + + const component = await renderHome({ + find: () => Promise.resolve({ total: 0 }), + }); + + component.instance().skipWelcome(); + component.update(); + + sinon.assert.calledWith(defaultProps.settingsClient.set, 'home:welcome:show', false); + + expect(component).toMatchSnapshot(); + }); + + test('should show the normal home page if loading fails', async () => { + defaultProps.settingsClient.get = sinon.spy(() => true); + + const component = await renderHome({ + find: () => Promise.reject('Doh!'), + }); - expect(component).toMatchSnapshot(); // eslint-disable-line + expect(component).toMatchSnapshot(); + }); }); - test('should safely handle execeptions', async () => { - const component = shallow( { - throw new Error('simulated find error'); - } - } - />); + describe('isNewKibanaInstance', () => { + test('should set isNewKibanaInstance to true when there are no index patterns', async () => { + // Ensure the welcome screen does not show by disabling the setting + defaultProps.settingsClient.get = sinon.spy(() => false); - // Ensure all promises resolve - await new Promise(resolve => process.nextTick(resolve)); - // Ensure the state changes are reflected - component.update(); + const component = await renderHome({ + find: () => Promise.resolve({ total: 0 }), + }); + + expect(component).toMatchSnapshot(); + }); + + test('should set isNewKibanaInstance to false when there are index patterns', async () => { + const component = await renderHome({ + find: () => Promise.resolve({ total: 1 }), + }); + + expect(component).toMatchSnapshot(); + }); - expect(component).toMatchSnapshot(); // eslint-disable-line + test('should safely handle execeptions', async () => { + const component = await renderHome({ + find: () => { + throw new Error('simulated find error'); + }, + }); + + expect(component).toMatchSnapshot(); + }); }); }); + diff --git a/src/core_plugins/kibana/public/home/components/home_app.js b/src/core_plugins/kibana/public/home/components/home_app.js index e3b48c0e680ad..851c2446577f8 100644 --- a/src/core_plugins/kibana/public/home/components/home_app.js +++ b/src/core_plugins/kibana/public/home/components/home_app.js @@ -45,6 +45,9 @@ export function HomeApp({ const isCloudEnabled = chrome.getInjected('isCloudEnabled', false); const apmUiEnabled = chrome.getInjected('apmUiEnabled', true); const savedObjectsClient = chrome.getSavedObjectsClient(); + const loadingCount = chrome.loadingCount; + const kibanaVersion = chrome.getKibanaVersion(); + const settingsClient = chrome.getUiSettingsClient(); const renderTutorialDirectory = (props) => { return ( @@ -100,6 +103,9 @@ export function HomeApp({ apmUiEnabled={apmUiEnabled} recentlyAccessed={recentlyAccessed} find={savedObjectsClient.find} + loadingCount={loadingCount} + kibanaVersion={kibanaVersion} + settingsClient={settingsClient} /> diff --git a/src/core_plugins/kibana/public/home/components/welcome.js b/src/core_plugins/kibana/public/home/components/welcome.js index 9e7c523f26f7d..61bb868789c94 100644 --- a/src/core_plugins/kibana/public/home/components/welcome.js +++ b/src/core_plugins/kibana/public/home/components/welcome.js @@ -25,7 +25,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import chrome from 'ui/chrome'; import { EuiCard, EuiTitle, @@ -36,20 +35,6 @@ import { EuiIcon, } from '@elastic/eui'; -const ENABLE_WELCOME = 'home:welcome:show'; - -/** - * A lightweight wrapper around the 'home:welcome:show' setting. - */ -export const WelcomePreference = { - get isEnabled() { - return chrome.getUiSettingsClient().get(ENABLE_WELCOME, true); - }, - set isEnabled(val) { - return chrome.getUiSettingsClient().set(ENABLE_WELCOME, val); - }, -}; - /** * Shows a full-screen welcome page that gives helpful quick links to beginners. */ From b4c53621a5f8c91229e5b2b0b98cd6be082c4155 Mon Sep 17 00:00:00 2001 From: Christopher Davies Date: Fri, 27 Jul 2018 17:20:36 -0400 Subject: [PATCH 03/13] Fix the security logout tests to hide the welcome screen if it exists. --- .../kibana/public/home/components/welcome.js | 1 + test/functional/page_objects/home_page.js | 12 ++++++++++++ .../functional/page_objects/security_page.js | 16 ++++++++++++++-- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/core_plugins/kibana/public/home/components/welcome.js b/src/core_plugins/kibana/public/home/components/welcome.js index 61bb868789c94..ee6326221a8b2 100644 --- a/src/core_plugins/kibana/public/home/components/welcome.js +++ b/src/core_plugins/kibana/public/home/components/welcome.js @@ -92,6 +92,7 @@ export class Welcome extends React.Component { } title="I don't need help" description="Skip the tour. I know what I'm doing." diff --git a/test/functional/page_objects/home_page.js b/test/functional/page_objects/home_page.js index 9b1c3d6a5c741..77205e7bc3323 100644 --- a/test/functional/page_objects/home_page.js +++ b/test/functional/page_objects/home_page.js @@ -63,6 +63,18 @@ export function HomePageProvider({ getService }) { await testSubjects.click(`launchSampleDataSet${id}`); } + // When logging into a brand new Kibana instance, the welcome screen + // may pop up. It may not, depending on the speed of the test, so it + // pays to check for the welcome screen and hide it in any test that + // hits the Kibana home page. + isWelcomeShowing() { + return testSubjects.exists('skipWelcomeScreen'); + } + + async hideWelcomeScreen() { + await testSubjects.click('skipWelcomeScreen'); + } + async loadSavedObjects() { await retry.try(async () => { await testSubjects.click('loadSavedObjects'); diff --git a/x-pack/test/functional/page_objects/security_page.js b/x-pack/test/functional/page_objects/security_page.js index c41323f3962ec..96e30e152689f 100644 --- a/x-pack/test/functional/page_objects/security_page.js +++ b/x-pack/test/functional/page_objects/security_page.js @@ -16,7 +16,7 @@ export function SecurityPageProvider({ getService, getPageObjects }) { const testSubjects = getService('testSubjects'); const esArchiver = getService('esArchiver'); const defaultFindTimeout = config.get('timeouts.find'); - const PageObjects = getPageObjects(['common', 'header', 'settings']); + const PageObjects = getPageObjects(['common', 'header', 'settings', 'home']); class LoginPage { async login(username, password) { @@ -72,12 +72,24 @@ export function SecurityPageProvider({ getService, getPageObjects }) { async logout() { log.debug('SecurityPage.logout'); - const logoutLinkExists = await find.existsByLinkText('Logout'); + const [isWelcomeShowing, logoutLinkExists] = await Promise.all([ + PageObjects.home.isWelcomeShowing(), + find.existsByLinkText('Logout'), + ]); + if (!logoutLinkExists) { log.debug('Logout not found'); return; } + // This sometimes happens when hitting the home screen on a brand new / empty + // Kibana instance. It may not *always* happen, depending on how + // long it takes the home screen to query Elastic to see if it's a + // new Kibana instance. + if (isWelcomeShowing) { + await PageObjects.home.hideWelcomeScreen(); + } + await find.clickByLinkText('Logout'); await retry.try(async () => { From f6424733c7943c2297fa6b102fffe4d1b588cd2f Mon Sep 17 00:00:00 2001 From: Christopher Davies Date: Fri, 27 Jul 2018 18:02:24 -0400 Subject: [PATCH 04/13] Tweak home page to display instantly if welcome page has been disabled. --- src/core_plugins/kibana/public/home/components/home.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core_plugins/kibana/public/home/components/home.js b/src/core_plugins/kibana/public/home/components/home.js index 7b8cef0783f79..be63d74ea3d37 100644 --- a/src/core_plugins/kibana/public/home/components/home.js +++ b/src/core_plugins/kibana/public/home/components/home.js @@ -45,10 +45,12 @@ export class Home extends Component { constructor(props) { super(props); + const isWelcomeEnabled = props.settingsClient.get(KEY_ENABLE_WELCOME, true); + this.state = { - isLoading: true, + isLoading: isWelcomeEnabled, isNewKibanaInstance: false, - isWelcomeEnabled: props.settingsClient.get(KEY_ENABLE_WELCOME, true), + isWelcomeEnabled, }; } From 979e5919b49ee20e94f10f0cf35919fccae74dcd Mon Sep 17 00:00:00 2001 From: Christopher Davies Date: Fri, 27 Jul 2018 19:33:11 -0400 Subject: [PATCH 05/13] Make the hiding of the welcome screen a local user preference. --- .../__snapshots__/home.test.js.snap | 228 ++++++++++++++++++ .../kibana/public/home/components/home.js | 6 +- .../public/home/components/home.test.js | 32 ++- .../kibana/public/home/components/home_app.js | 1 + 4 files changed, 263 insertions(+), 4 deletions(-) diff --git a/src/core_plugins/kibana/public/home/components/__snapshots__/home.test.js.snap b/src/core_plugins/kibana/public/home/components/__snapshots__/home.test.js.snap index 7c7bb679e1790..56c6fe8a6755e 100644 --- a/src/core_plugins/kibana/public/home/components/__snapshots__/home.test.js.snap +++ b/src/core_plugins/kibana/public/home/components/__snapshots__/home.test.js.snap @@ -1080,6 +1080,234 @@ exports[`home welcome should show the normal home page if loading fails 1`] = `
`; +exports[`home welcome should show the normal home page if welcome screen is disabled locally 1`] = ` + + + + + + + + +

+ Visualize and Explore Data +

+
+ + +
+
+ + + +

+ Manage and Administer the Elastic Stack +

+
+ + +
+
+
+ + + + +

+ Didn’t find what you were looking for? +

+
+ + + View full directory of Kibana plugins + +
+
+
+
+`; + +exports[`home welcome should show the normal home page if welcome screen is disabled system wide 1`] = ` + + + + + + + + +

+ Visualize and Explore Data +

+
+ + +
+
+ + + +

+ Manage and Administer the Elastic Stack +

+
+ + +
+
+
+ + + + +

+ Didn’t find what you were looking for? +

+
+ + + View full directory of Kibana plugins + +
+
+
+
+`; + exports[`home welcome should show the welcome screen if enabled, and there are no index patterns defined 1`] = ` { - this.props.settingsClient.set(KEY_ENABLE_WELCOME, false); + this.props.localStorage.setItem(KEY_ENABLE_WELCOME, 'false'); this._isMounted && this.setState({ isWelcomeEnabled: false }); }; @@ -223,4 +224,5 @@ Home.propTypes = { loadingCount: PropTypes.object.isRequired, kibanaVersion: PropTypes.string.isRequired, settingsClient: PropTypes.object.isRequired, + localStorage: PropTypes.object.isRequired, }; diff --git a/src/core_plugins/kibana/public/home/components/home.test.js b/src/core_plugins/kibana/public/home/components/home.test.js index 6b6840492da99..5d5c8af7c54e5 100644 --- a/src/core_plugins/kibana/public/home/components/home.test.js +++ b/src/core_plugins/kibana/public/home/components/home.test.js @@ -42,6 +42,13 @@ describe('home', () => { increment: sinon.mock(), decrement: sinon.mock(), }, + localStorage: { + getItem: sinon.spy((path) => { + expect(path).toEqual('home:welcome:show'); + return null; + }), + setItem: sinon.mock(), + }, settingsClient: { get: sinon.spy((path, defaultVal) => { expect(path).toEqual('home:welcome:show'); @@ -53,7 +60,7 @@ describe('home', () => { }; }); - async function renderHome(props) { + async function renderHome(props = {}) { const component = shallow( { describe('welcome', () => { test('should show the welcome screen if enabled, and there are no index patterns defined', async () => { defaultProps.settingsClient.get = sinon.spy(() => true); + defaultProps.localStorage.getItem = sinon.spy(() => true); const component = await renderHome({ find: () => Promise.resolve({ total: 0 }), }); sinon.assert.calledOnce(defaultProps.settingsClient.get); + sinon.assert.calledOnce(defaultProps.localStorage.getItem); expect(component).toMatchSnapshot(); }); @@ -198,7 +207,8 @@ describe('home', () => { component.instance().skipWelcome(); component.update(); - sinon.assert.calledWith(defaultProps.settingsClient.set, 'home:welcome:show', false); + sinon.assert.calledWith(defaultProps.localStorage.setItem, 'home:welcome:show', 'false'); + sinon.assert.notCalled(defaultProps.settingsClient.set); expect(component).toMatchSnapshot(); }); @@ -212,6 +222,24 @@ describe('home', () => { expect(component).toMatchSnapshot(); }); + + test('should show the normal home page if welcome screen is disabled locally', async () => { + defaultProps.settingsClient.getItem = sinon.spy(() => true); + defaultProps.localStorage.getItem = sinon.spy(() => 'false'); + + const component = await renderHome(); + + expect(component).toMatchSnapshot(); + }); + + test('should show the normal home page if welcome screen is disabled system wide', async () => { + defaultProps.settingsClient.getItem = sinon.spy(() => false); + defaultProps.localStorage.getItem = sinon.spy(() => 'true'); + + const component = await renderHome(); + + expect(component).toMatchSnapshot(); + }); }); describe('isNewKibanaInstance', () => { diff --git a/src/core_plugins/kibana/public/home/components/home_app.js b/src/core_plugins/kibana/public/home/components/home_app.js index 851c2446577f8..35a866e0fe47a 100644 --- a/src/core_plugins/kibana/public/home/components/home_app.js +++ b/src/core_plugins/kibana/public/home/components/home_app.js @@ -106,6 +106,7 @@ export function HomeApp({ loadingCount={loadingCount} kibanaVersion={kibanaVersion} settingsClient={settingsClient} + localStorage={localStorage} /> From 9ae922f55020b6e2e2a32dfcc89fbdce85ef5d85 Mon Sep 17 00:00:00 2001 From: Christopher Davies Date: Mon, 30 Jul 2018 08:58:31 -0400 Subject: [PATCH 06/13] Add a bit of commenting --- .../kibana/public/home/components/home.js | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/core_plugins/kibana/public/home/components/home.js b/src/core_plugins/kibana/public/home/components/home.js index 22283b0ab8f0b..b36186d96bdb9 100644 --- a/src/core_plugins/kibana/public/home/components/home.js +++ b/src/core_plugins/kibana/public/home/components/home.js @@ -45,10 +45,15 @@ export class Home extends Component { constructor(props) { super(props); - const isWelcomeEnabled = props.localStorage.getItem(KEY_ENABLE_WELCOME) !== 'false' && + const isWelcomeEnabled = + props.localStorage.getItem(KEY_ENABLE_WELCOME) !== 'false' && props.settingsClient.get(KEY_ENABLE_WELCOME, true); this.state = { + // If welcome is enabled, we wait for loading to complete + // before rendering. This prevents an annoying flickering + // effect where home renders, and then a few ms after, the + // welcome screen fades in. isLoading: isWelcomeEnabled, isNewKibanaInstance: false, isWelcomeEnabled, @@ -68,14 +73,13 @@ export class Home extends Component { this.props.loadingCount.increment(); try { - const resp = await this.props - .find({ - type: 'index-pattern', - fields: ['title'], - search: `*`, - search_fields: ['title'], - perPage: 1, - }); + const resp = await this.props.find({ + type: 'index-pattern', + fields: ['title'], + search: `*`, + search_fields: ['title'], + perPage: 1, + }); this._isMounted && this.setState({ isNewKibanaInstance: resp.total === 0 }); } catch (err) { // An error here is relatively unimportant, as it only means we don't provide From 9be2d33924d3798bdff079bfb0a33f8dfd72164a Mon Sep 17 00:00:00 2001 From: Christopher Davies Date: Mon, 30 Jul 2018 11:15:49 -0400 Subject: [PATCH 07/13] Fix home test snapshot --- .../components/__snapshots__/home.test.js.snap | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/core_plugins/kibana/public/home/components/__snapshots__/home.test.js.snap b/src/core_plugins/kibana/public/home/components/__snapshots__/home.test.js.snap index be7cd4961c263..f08f95996e48c 100644 --- a/src/core_plugins/kibana/public/home/components/__snapshots__/home.test.js.snap +++ b/src/core_plugins/kibana/public/home/components/__snapshots__/home.test.js.snap @@ -987,7 +987,9 @@ exports[`home welcome should show the normal home page if loading fails 1`] = ` className="home" restrictWidth={false} > - + - + - + - + Date: Thu, 9 Aug 2018 20:15:36 -0400 Subject: [PATCH 08/13] Update welcome UI with new styles Add a max timeout of 250ms --- .../public/assets/bg_bottom_branded.svg | 74 ++++++++++++++++++ .../kibana/public/assets/bg_top_branded.svg | 41 ++++++++++ .../kibana/public/assets/illo_dashboard.png | Bin 0 -> 11739 bytes .../__snapshots__/home.test.js.snap | 4 +- .../kibana/public/home/components/home.js | 40 +++++++--- .../public/home/components/home.test.js | 33 +------- .../kibana/public/home/components/home_app.js | 7 +- .../kibana/public/home/components/welcome.js | 60 +++++++------- src/core_plugins/kibana/public/home/home.less | 44 +++++++++-- 9 files changed, 220 insertions(+), 83 deletions(-) create mode 100644 src/core_plugins/kibana/public/assets/bg_bottom_branded.svg create mode 100644 src/core_plugins/kibana/public/assets/bg_top_branded.svg create mode 100644 src/core_plugins/kibana/public/assets/illo_dashboard.png diff --git a/src/core_plugins/kibana/public/assets/bg_bottom_branded.svg b/src/core_plugins/kibana/public/assets/bg_bottom_branded.svg new file mode 100644 index 0000000000000..9f6114fd5c502 --- /dev/null +++ b/src/core_plugins/kibana/public/assets/bg_bottom_branded.svg @@ -0,0 +1,74 @@ + + + + E2D4A2B4-5E17-4ADE-80E4-31B9CAF520F4 + Created with sketchtool. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/core_plugins/kibana/public/assets/bg_top_branded.svg b/src/core_plugins/kibana/public/assets/bg_top_branded.svg new file mode 100644 index 0000000000000..f6e1965078462 --- /dev/null +++ b/src/core_plugins/kibana/public/assets/bg_top_branded.svg @@ -0,0 +1,41 @@ + + + + 7901612E-113D-4EE2-89F8-C5AEAD9876B6 + Created with sketchtool. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/core_plugins/kibana/public/assets/illo_dashboard.png b/src/core_plugins/kibana/public/assets/illo_dashboard.png new file mode 100644 index 0000000000000000000000000000000000000000..ef2dac5ca4144f1d5b923d62617a1328b212d852 GIT binary patch literal 11739 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 PUqcjRRHZAPnZNo!ApgyC literal 0 HcmV?d00001 diff --git a/src/core_plugins/kibana/public/home/components/__snapshots__/home.test.js.snap b/src/core_plugins/kibana/public/home/components/__snapshots__/home.test.js.snap index f08f95996e48c..d95b24d28c756 100644 --- a/src/core_plugins/kibana/public/home/components/__snapshots__/home.test.js.snap +++ b/src/core_plugins/kibana/public/home/components/__snapshots__/home.test.js.snap @@ -1332,8 +1332,8 @@ exports[`home welcome should show the normal home page if welcome screen is disa exports[`home welcome should show the welcome screen if enabled, and there are no index patterns defined 1`] = ` `; diff --git a/src/core_plugins/kibana/public/home/components/home.js b/src/core_plugins/kibana/public/home/components/home.js index b36186d96bdb9..10c0aa376d9cd 100644 --- a/src/core_plugins/kibana/public/home/components/home.js +++ b/src/core_plugins/kibana/public/home/components/home.js @@ -70,9 +70,15 @@ export class Home extends Component { } fetchIsNewKibanaInstance = async () => { - this.props.loadingCount.increment(); - try { + // Set a max-time on this query so we don't hang the page too long... + // Worst case, we don't show the welcome screen when we should. + setTimeout(() => { + if (this.state.isLoading) { + this.setState({ isWelcomeEnabled: false }); + } + }, 250); + const resp = await this.props.find({ type: 'index-pattern', fields: ['title'], @@ -80,14 +86,22 @@ export class Home extends Component { search_fields: ['title'], perPage: 1, }); - this._isMounted && this.setState({ isNewKibanaInstance: resp.total === 0 }); + + this.endLoading({ isNewKibanaInstance: resp.total === 0 }); } catch (err) { // An error here is relatively unimportant, as it only means we don't provide // some UI niceties. + this.endLoading(); } + }; - this._isMounted && this.setState({ isLoading: false }); - this.props.loadingCount.decrement(); + endLoading = (state = {}) => { + if (this._isMounted) { + this.setState({ + ...state, + isLoading: false, + }); + } }; skipWelcome = () => { @@ -183,14 +197,19 @@ export class Home extends Component { ); } - // For now, loading is just an empty page w/ the standard - // Kibana chrome.loadingCount.increment() indicator. + // For now, loading is just an empty page, as we'll show something + // in 250ms, no matter what, and a blank page prevents an odd flicker effect. renderLoading() { return ''; } renderWelcome() { - return ; + return ( + + ); } render() { @@ -225,8 +244,7 @@ Home.propTypes = { apmUiEnabled: PropTypes.bool.isRequired, recentlyAccessed: PropTypes.arrayOf(recentlyAccessedShape).isRequired, find: PropTypes.func.isRequired, - loadingCount: PropTypes.object.isRequired, - kibanaVersion: PropTypes.string.isRequired, - settingsClient: PropTypes.object.isRequired, localStorage: PropTypes.object.isRequired, + settingsClient: PropTypes.object.isRequired, + urlBasePath: PropTypes.string.isRequired, }; diff --git a/src/core_plugins/kibana/public/home/components/home.test.js b/src/core_plugins/kibana/public/home/components/home.test.js index 5d5c8af7c54e5..b47bc235105ce 100644 --- a/src/core_plugins/kibana/public/home/components/home.test.js +++ b/src/core_plugins/kibana/public/home/components/home.test.js @@ -57,6 +57,7 @@ describe('home', () => { }), set: sinon.mock(), }, + urlBasePath: 'goober', }; }); @@ -70,6 +71,8 @@ describe('home', () => { await new Promise(resolve => process.nextTick(resolve)); // Ensure the state changes are reflected component.update(); + // Ensure all promises resolve + await new Promise(resolve => process.nextTick(resolve)); return component; } @@ -152,36 +155,6 @@ describe('home', () => { }); }); - describe('loading', () => { - test('should increment and decrement the loading count', async () => { - let found = false; - - await renderHome({ - find: async () => { - sinon.assert.calledOnce(defaultProps.loadingCount.increment); - sinon.assert.notCalled(defaultProps.loadingCount.decrement); - found = true; - return { total: 0 }; - }, - }); - - expect(found).toBeTruthy(); - sinon.assert.calledOnce(defaultProps.loadingCount.increment); - sinon.assert.calledOnce(defaultProps.loadingCount.decrement); - }); - - test('should decrement the loading count even if loading fails', async () => { - await renderHome({ - find: async () => { - throw new Error('Shazm!'); - }, - }); - - sinon.assert.calledOnce(defaultProps.loadingCount.increment); - sinon.assert.calledOnce(defaultProps.loadingCount.decrement); - }); - }); - describe('welcome', () => { test('should show the welcome screen if enabled, and there are no index patterns defined', async () => { defaultProps.settingsClient.get = sinon.spy(() => true); diff --git a/src/core_plugins/kibana/public/home/components/home_app.js b/src/core_plugins/kibana/public/home/components/home_app.js index 35a866e0fe47a..565f6faec8fd7 100644 --- a/src/core_plugins/kibana/public/home/components/home_app.js +++ b/src/core_plugins/kibana/public/home/components/home_app.js @@ -45,8 +45,6 @@ export function HomeApp({ const isCloudEnabled = chrome.getInjected('isCloudEnabled', false); const apmUiEnabled = chrome.getInjected('apmUiEnabled', true); const savedObjectsClient = chrome.getSavedObjectsClient(); - const loadingCount = chrome.loadingCount; - const kibanaVersion = chrome.getKibanaVersion(); const settingsClient = chrome.getUiSettingsClient(); const renderTutorialDirectory = (props) => { @@ -103,10 +101,9 @@ export function HomeApp({ apmUiEnabled={apmUiEnabled} recentlyAccessed={recentlyAccessed} find={savedObjectsClient.find} - loadingCount={loadingCount} - kibanaVersion={kibanaVersion} - settingsClient={settingsClient} localStorage={localStorage} + settingsClient={settingsClient} + urlBasePath={chrome.getBasePath()} /> diff --git a/src/core_plugins/kibana/public/home/components/welcome.js b/src/core_plugins/kibana/public/home/components/welcome.js index ee6326221a8b2..bd61c0fd66b4e 100644 --- a/src/core_plugins/kibana/public/home/components/welcome.js +++ b/src/core_plugins/kibana/public/home/components/welcome.js @@ -33,6 +33,8 @@ import { EuiFlexItem, EuiText, EuiIcon, + EuiButton, + EuiButtonEmpty, } from '@elastic/eui'; /** @@ -41,9 +43,9 @@ import { export class Welcome extends React.Component { hideOnEsc = (e) => { if (e.key === 'Escape') { - this.props.skipWelcome(); + this.props.onSkip(); } - } + }; componentDidMount() { document.addEventListener('keydown', this.hideOnEsc); @@ -54,8 +56,7 @@ export class Welcome extends React.Component { } render() { - const { skipWelcome, kibanaVersion } = this.props; - const majorVersion = kibanaVersion.split('.')[0]; + const { urlBasePath, onSkip } = this.props; return (
@@ -66,37 +67,38 @@ export class Welcome extends React.Component { -

Welcome to Kibana {majorVersion}

+

Welcome to Kibana

- Your window into the Elastic stack + Your Window into the Elastic Stack
-
- - - Choose a way to start your journey - - -
- } - title="Play around with sample data" - description="See what Kibana is capable of without all the setup." - href="#/home/tutorial_directory/sampleData" - /> - - - } - title="I don't need help" - description="Skip the tour. I know what I'm doing." - onClick={skipWelcome} + image={`${urlBasePath}/plugins/kibana/assets/illo_dashboard.png`} + textAlign="left" + title="Let's get started" + description="We noticed that you don't have any data in your cluster. + You can try our sample data and dashboards or jump in with your own data." + footer={( +
+ + Try our sample data + + + Explore on my own + +
+ )} />
@@ -107,6 +109,6 @@ export class Welcome extends React.Component { } Welcome.propTypes = { - kibanaVersion: PropTypes.string.isRequired, - skipWelcome: PropTypes.func.isRequired, + urlBasePath: PropTypes.string.isRequired, + onSkip: PropTypes.func.isRequired, }; diff --git a/src/core_plugins/kibana/public/home/home.less b/src/core_plugins/kibana/public/home/home.less index c7fcc4014affd..1307fcb96d4cf 100644 --- a/src/core_plugins/kibana/public/home/home.less +++ b/src/core_plugins/kibana/public/home/home.less @@ -33,16 +33,30 @@ home-app { background: inherit; color: inherit; opacity: 0; + overflow: auto; animation: homeFadeIn 0.5s ease-in 0s forwards; } -.home-welcome-header { - background: #0079A5; - color: white; +.home-welcome::before { + content: url(../assets/bg_top_branded.svg); + position: absolute; + top: 0; + right: 0; + z-index: 1; } -.home-welcome-title { - color: inherit; +.home-welcome::after { + content: url(../assets/bg_bottom_branded.svg); + position: fixed; + bottom: -2px; // Hides an odd space at the bottom of the svg + left: 0; + z-index: 1; +} + +.home-welcome-header { + position: relative; + padding: 32px; + z-index: 10; } .home-welcome-logo { @@ -51,20 +65,38 @@ home-app { background-color: white; border-radius: 100%; padding: 16px; + box-shadow: 0 4px 16px -6px rgba(0, 0, 0, 0.75); +} + +.home-welcome-title { + color: inherit; + font-weight: 400; +} + +.home-welcome-footer-action { + margin-right: 8px; +} + +.welcome-subtitle { + opacity: 0.75; } .home-welcome-content { + position: relative; margin: auto; - max-width: 800px; + max-width: 512px; padding-left: 32px; padding-right: 32px; + z-index: 10; } @keyframes homeFadeIn { from { opacity: 0; + transform: translateY(200px), scale(0.75); } to { opacity: 1; + transform: translateY(0), scale(1); } } \ No newline at end of file From 2a64261fdc1c8a647cfce55300866305995201d7 Mon Sep 17 00:00:00 2001 From: Christopher Davies Date: Thu, 9 Aug 2018 20:23:16 -0400 Subject: [PATCH 09/13] Add data-test-subj back into welcome screen --- src/core_plugins/kibana/public/home/components/welcome.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core_plugins/kibana/public/home/components/welcome.js b/src/core_plugins/kibana/public/home/components/welcome.js index bd61c0fd66b4e..b127deb69916c 100644 --- a/src/core_plugins/kibana/public/home/components/welcome.js +++ b/src/core_plugins/kibana/public/home/components/welcome.js @@ -94,6 +94,7 @@ export class Welcome extends React.Component { Explore on my own From 9a72c4ac8bf5ba78d2b552135496d332ddd49701 Mon Sep 17 00:00:00 2001 From: Christopher Davies Date: Fri, 10 Aug 2018 10:30:07 -0400 Subject: [PATCH 10/13] Fix home snapshots, tweak welcome screen title --- .../home/components/__snapshots__/home.test.js.snap | 8 ++++++++ src/core_plugins/kibana/public/home/components/welcome.js | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/core_plugins/kibana/public/home/components/__snapshots__/home.test.js.snap b/src/core_plugins/kibana/public/home/components/__snapshots__/home.test.js.snap index 5dea74f1f2bbf..6c7bf794ea864 100644 --- a/src/core_plugins/kibana/public/home/components/__snapshots__/home.test.js.snap +++ b/src/core_plugins/kibana/public/home/components/__snapshots__/home.test.js.snap @@ -1044,6 +1044,7 @@ exports[`home welcome should show the normal home page if loading fails 1`] = ` @@ -1069,6 +1070,7 @@ exports[`home welcome should show the normal home page if loading fails 1`] = ` @@ -1160,6 +1162,7 @@ exports[`home welcome should show the normal home page if welcome screen is disa @@ -1185,6 +1188,7 @@ exports[`home welcome should show the normal home page if welcome screen is disa @@ -1276,6 +1280,7 @@ exports[`home welcome should show the normal home page if welcome screen is disa @@ -1301,6 +1306,7 @@ exports[`home welcome should show the normal home page if welcome screen is disa @@ -1399,6 +1405,7 @@ exports[`home welcome stores skip welcome setting if skipped 1`] = ` @@ -1424,6 +1431,7 @@ exports[`home welcome stores skip welcome setting if skipped 1`] = ` diff --git a/src/core_plugins/kibana/public/home/components/welcome.js b/src/core_plugins/kibana/public/home/components/welcome.js index b127deb69916c..aa10b551f4ca3 100644 --- a/src/core_plugins/kibana/public/home/components/welcome.js +++ b/src/core_plugins/kibana/public/home/components/welcome.js @@ -69,7 +69,7 @@ export class Welcome extends React.Component {

Welcome to Kibana

- Your Window into the Elastic Stack + Your window into the Elastic Stack
From 4af5702b23970a42e175bfa9ecfecd3d7e5dbffa Mon Sep 17 00:00:00 2001 From: Christopher Davies Date: Mon, 13 Aug 2018 08:22:05 -0400 Subject: [PATCH 11/13] Add gradient to welcome screen --- src/core_plugins/kibana/public/home/home.less | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core_plugins/kibana/public/home/home.less b/src/core_plugins/kibana/public/home/home.less index d831e2fceec74..f2c4764a2b58b 100644 --- a/src/core_plugins/kibana/public/home/home.less +++ b/src/core_plugins/kibana/public/home/home.less @@ -35,6 +35,8 @@ home-app { bottom: 0; z-index: 100000; background: inherit; + // When sassified, should pull in EUI colors: $euiColorLightestShade, $euiColorEmptyShade + background-image: linear-gradient(0deg, @globalColorLightestGray 0%, white 100%); color: inherit; opacity: 0; overflow: auto; From 4f1a60b17acb183c8d62ce3bf9f9cb716a3f4bad Mon Sep 17 00:00:00 2001 From: Christopher Davies Date: Mon, 13 Aug 2018 15:27:48 -0400 Subject: [PATCH 12/13] Bump up the welcome screen timeout to 500ms --- src/core_plugins/kibana/public/home/components/home.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core_plugins/kibana/public/home/components/home.js b/src/core_plugins/kibana/public/home/components/home.js index 10c0aa376d9cd..983fe47c29db5 100644 --- a/src/core_plugins/kibana/public/home/components/home.js +++ b/src/core_plugins/kibana/public/home/components/home.js @@ -77,7 +77,7 @@ export class Home extends Component { if (this.state.isLoading) { this.setState({ isWelcomeEnabled: false }); } - }, 250); + }, 500); const resp = await this.props.find({ type: 'index-pattern', From 0cb55fcf4e7f01ee42ac9fcab615d049a3622cae Mon Sep 17 00:00:00 2001 From: Christopher Davies Date: Tue, 14 Aug 2018 15:41:01 -0400 Subject: [PATCH 13/13] Remove welcome screen advanced settings --- .../__snapshots__/home.test.js.snap | 118 ------------------ .../kibana/public/home/components/home.js | 5 +- .../public/home/components/home.test.js | 32 +---- .../kibana/public/home/components/home_app.js | 2 - .../settings/lib/get_category_name.js | 1 - .../kibana/ui_setting_defaults.js | 7 -- 6 files changed, 5 insertions(+), 160 deletions(-) diff --git a/src/core_plugins/kibana/public/home/components/__snapshots__/home.test.js.snap b/src/core_plugins/kibana/public/home/components/__snapshots__/home.test.js.snap index 6c7bf794ea864..fca2261462277 100644 --- a/src/core_plugins/kibana/public/home/components/__snapshots__/home.test.js.snap +++ b/src/core_plugins/kibana/public/home/components/__snapshots__/home.test.js.snap @@ -1234,124 +1234,6 @@ exports[`home welcome should show the normal home page if welcome screen is disa
`; -exports[`home welcome should show the normal home page if welcome screen is disabled system wide 1`] = ` - - - - - - - - -

- Visualize and Explore Data -

-
- - -
-
- - - -

- Manage and Administer the Elastic Stack -

-
- - -
-
-
- - - - -

- Didn’t find what you were looking for? -

-
- - - View full directory of Kibana plugins - -
-
-
-
-`; - exports[`home welcome should show the welcome screen if enabled, and there are no index patterns defined 1`] = ` { localStorage: { getItem: sinon.spy((path) => { expect(path).toEqual('home:welcome:show'); - return null; + return 'false'; }), setItem: sinon.mock(), }, - settingsClient: { - get: sinon.spy((path, defaultVal) => { - expect(path).toEqual('home:welcome:show'); - expect(defaultVal).toBeTruthy(); - return true; - }), - set: sinon.mock(), - }, urlBasePath: 'goober', }; }); @@ -157,21 +149,19 @@ describe('home', () => { describe('welcome', () => { test('should show the welcome screen if enabled, and there are no index patterns defined', async () => { - defaultProps.settingsClient.get = sinon.spy(() => true); - defaultProps.localStorage.getItem = sinon.spy(() => true); + defaultProps.localStorage.getItem = sinon.spy(() => 'true'); const component = await renderHome({ find: () => Promise.resolve({ total: 0 }), }); - sinon.assert.calledOnce(defaultProps.settingsClient.get); sinon.assert.calledOnce(defaultProps.localStorage.getItem); expect(component).toMatchSnapshot(); }); test('stores skip welcome setting if skipped', async () => { - defaultProps.settingsClient.get = sinon.spy(() => true); + defaultProps.localStorage.getItem = sinon.spy(() => 'true'); const component = await renderHome({ find: () => Promise.resolve({ total: 0 }), @@ -181,13 +171,12 @@ describe('home', () => { component.update(); sinon.assert.calledWith(defaultProps.localStorage.setItem, 'home:welcome:show', 'false'); - sinon.assert.notCalled(defaultProps.settingsClient.set); expect(component).toMatchSnapshot(); }); test('should show the normal home page if loading fails', async () => { - defaultProps.settingsClient.get = sinon.spy(() => true); + defaultProps.localStorage.getItem = sinon.spy(() => 'true'); const component = await renderHome({ find: () => Promise.reject('Doh!'), @@ -197,29 +186,16 @@ describe('home', () => { }); test('should show the normal home page if welcome screen is disabled locally', async () => { - defaultProps.settingsClient.getItem = sinon.spy(() => true); defaultProps.localStorage.getItem = sinon.spy(() => 'false'); const component = await renderHome(); expect(component).toMatchSnapshot(); }); - - test('should show the normal home page if welcome screen is disabled system wide', async () => { - defaultProps.settingsClient.getItem = sinon.spy(() => false); - defaultProps.localStorage.getItem = sinon.spy(() => 'true'); - - const component = await renderHome(); - - expect(component).toMatchSnapshot(); - }); }); describe('isNewKibanaInstance', () => { test('should set isNewKibanaInstance to true when there are no index patterns', async () => { - // Ensure the welcome screen does not show by disabling the setting - defaultProps.settingsClient.get = sinon.spy(() => false); - const component = await renderHome({ find: () => Promise.resolve({ total: 0 }), }); diff --git a/src/core_plugins/kibana/public/home/components/home_app.js b/src/core_plugins/kibana/public/home/components/home_app.js index 565f6faec8fd7..d277fd542f70d 100644 --- a/src/core_plugins/kibana/public/home/components/home_app.js +++ b/src/core_plugins/kibana/public/home/components/home_app.js @@ -45,7 +45,6 @@ export function HomeApp({ const isCloudEnabled = chrome.getInjected('isCloudEnabled', false); const apmUiEnabled = chrome.getInjected('apmUiEnabled', true); const savedObjectsClient = chrome.getSavedObjectsClient(); - const settingsClient = chrome.getUiSettingsClient(); const renderTutorialDirectory = (props) => { return ( @@ -102,7 +101,6 @@ export function HomeApp({ recentlyAccessed={recentlyAccessed} find={savedObjectsClient.find} localStorage={localStorage} - settingsClient={settingsClient} urlBasePath={chrome.getBasePath()} /> diff --git a/src/core_plugins/kibana/public/management/sections/settings/lib/get_category_name.js b/src/core_plugins/kibana/public/management/sections/settings/lib/get_category_name.js index 65fd1a4dfb84b..d41c4bce089ca 100644 --- a/src/core_plugins/kibana/public/management/sections/settings/lib/get_category_name.js +++ b/src/core_plugins/kibana/public/management/sections/settings/lib/get_category_name.js @@ -28,7 +28,6 @@ const names = { dashboard: 'Dashboard', reporting: 'Reporting', search: 'Search', - home: 'Home', }; export function getCategoryName(category) { diff --git a/src/core_plugins/kibana/ui_setting_defaults.js b/src/core_plugins/kibana/ui_setting_defaults.js index 587e9a2800859..dc00edaad0b27 100644 --- a/src/core_plugins/kibana/ui_setting_defaults.js +++ b/src/core_plugins/kibana/ui_setting_defaults.js @@ -416,13 +416,6 @@ export function getUiSettingDefaults() { target="_blank" rel="noopener noreferrer">accepted formats), "display" (the title to be displayed), and "section" (which column to put the option in).` }, - 'home:welcome:show': { - name: 'Show the welcome screen', - value: true, - description: `Toggles whether or not to show the welcome screen if - this is a new installation of Kibana.`, - category: ['home'], - }, 'dashboard:defaultDarkTheme': { name: 'Dark theme', value: false,