From a30db6c7290a081b2c1fdef6e3e0e1f2c3c70a9c Mon Sep 17 00:00:00 2001 From: Maja Grubic Date: Tue, 10 Dec 2019 19:13:24 +0000 Subject: [PATCH 1/4] [Dashboard] Add visualization from dasbhoard empty screen --- .../dashboard_empty_screen.test.tsx.snap | 80 ++- .../__tests__/dashboard_empty_screen.test.tsx | 11 + .../dashboard/dashboard_app_controller.tsx | 34 +- .../dashboard/dashboard_empty_screen.tsx | 23 +- .../__snapshots__/new_vis_modal.test.tsx.snap | 628 +++++++++++++++++- .../visualize/wizard/new_vis_modal.test.tsx | 30 + .../public/visualize/wizard/new_vis_modal.tsx | 6 +- .../embeddable/grid/_dashboard_grid.scss | 2 +- .../viewport/_dashboard_viewport.scss | 1 - .../apps/dashboard/empty_dashboard.js | 8 + .../services/dashboard/visualizations.js | 8 +- 11 files changed, 766 insertions(+), 65 deletions(-) diff --git a/src/legacy/core_plugins/kibana/public/dashboard/__tests__/__snapshots__/dashboard_empty_screen.test.tsx.snap b/src/legacy/core_plugins/kibana/public/dashboard/__tests__/__snapshots__/dashboard_empty_screen.test.tsx.snap index 8410040a0100d..6b022fe943dc1 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/__tests__/__snapshots__/dashboard_empty_screen.test.tsx.snap +++ b/src/legacy/core_plugins/kibana/public/dashboard/__tests__/__snapshots__/dashboard_empty_screen.test.tsx.snap @@ -306,40 +306,62 @@ exports[`DashboardEmptyScreen renders correctly with visualize paragraph 1`] = ` className="euiSpacer euiSpacer--m" /> - -
-

- - visit the Visualize app - , - } - } +

-
+ + + + + Create new + + + + + +

diff --git a/src/legacy/core_plugins/kibana/public/dashboard/__tests__/dashboard_empty_screen.test.tsx b/src/legacy/core_plugins/kibana/public/dashboard/__tests__/dashboard_empty_screen.test.tsx index 69bdcf59bb227..653e7d4215eef 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/__tests__/dashboard_empty_screen.test.tsx +++ b/src/legacy/core_plugins/kibana/public/dashboard/__tests__/dashboard_empty_screen.test.tsx @@ -47,4 +47,15 @@ describe('DashboardEmptyScreen', () => { const paragraph = findTestSubject(component, 'linkToVisualizeParagraph'); expect(paragraph.length).toBe(0); }); + + test('when specified, prop onVisualizeClick is called correctly', () => { + const onVisualizeClick = jest.fn(); + const component = mountComponent({ + ...defaultProps, + ...{ showLinkToVisualize: true, onVisualizeClick }, + }); + const button = findTestSubject(component, 'addVisualizationButton'); + button.simulate('click'); + expect(onVisualizeClick).toHaveBeenCalled(); + }); }); diff --git a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app_controller.tsx b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app_controller.tsx index 3b336ebfc11fe..057c1eb12c5ae 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app_controller.tsx +++ b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app_controller.tsx @@ -21,7 +21,7 @@ import _ from 'lodash'; import { i18n } from '@kbn/i18n'; import React from 'react'; import angular from 'angular'; -import { uniq, noop } from 'lodash'; +import { uniq } from 'lodash'; import { Subscription } from 'rxjs'; import { DashboardEmptyScreen, DashboardEmptyScreenProps } from './dashboard_empty_screen'; @@ -53,7 +53,7 @@ import { isErrorEmbeddable, ErrorEmbeddable, ViewMode, - openAddPanelFlyout, + openAddPanelFlyout, EmbeddableFactoryNotFoundError, } from '../../../embeddable_api/public/np_ready/public'; import { DashboardAppState, NavAction, ConfirmModalFn, SavedDashboardPanel } from './types'; @@ -142,16 +142,20 @@ export class DashboardAppController { } $scope.showSaveQuery = dashboardCapabilities.saveQuery as boolean; - $scope.getShouldShowEditHelp = () => + const getShouldShowEditHelp = () => !dashboardStateManager.getPanels().length && dashboardStateManager.getIsEditMode() && !dashboardConfig.getHideWriteControls(); - $scope.getShouldShowViewHelp = () => + const getShouldShowViewHelp = () => !dashboardStateManager.getPanels().length && dashboardStateManager.getIsViewMode() && !dashboardConfig.getHideWriteControls(); + const addVisualization = () => { + navActions[TopNavIds.VISUALIZE](); + }; + const updateIndexPatterns = (container?: DashboardContainer) => { if (!container || isErrorEmbeddable(container)) { return; @@ -186,7 +190,7 @@ export class DashboardAppController { showLinkToVisualize: shouldShowEditHelp, }; if (shouldShowEditHelp) { - emptyScreenProps.onVisualizeClick = noop; + emptyScreenProps.onVisualizeClick = addVisualization; } return emptyScreenProps; }; @@ -202,8 +206,8 @@ export class DashboardAppController { if (dashboardContainer && !isErrorEmbeddable(dashboardContainer)) { expandedPanelId = dashboardContainer.getInput().expandedPanelId; } - const shouldShowEditHelp = $scope.getShouldShowEditHelp(); - const shouldShowViewHelp = $scope.getShouldShowViewHelp(); + const shouldShowEditHelp = getShouldShowEditHelp(); + const shouldShowViewHelp = getShouldShowViewHelp(); return { id: dashboardStateManager.savedDashboard.id || '', filters: queryFilter.getFilters(), @@ -258,8 +262,8 @@ export class DashboardAppController { dashboardContainer = container; dashboardContainer.renderEmpty = () => { - const shouldShowEditHelp = $scope.getShouldShowEditHelp(); - const shouldShowViewHelp = $scope.getShouldShowViewHelp(); + const shouldShowEditHelp = getShouldShowEditHelp(); + const shouldShowViewHelp = getShouldShowViewHelp(); const isEmptyState = shouldShowEditHelp || shouldShowViewHelp; return isEmptyState ? ( @@ -752,7 +756,17 @@ export class DashboardAppController { } }; - navActions[TopNavIds.VISUALIZE] = async () => {}; + navActions[TopNavIds.VISUALIZE] = async () => { + const type = 'visualization'; + const factory = embeddables.getEmbeddableFactory(type); + if (!factory) { + throw new EmbeddableFactoryNotFoundError(type); + } + const explicitInput = await factory.getExplicitInput(); + if (dashboardContainer) { + await dashboardContainer.addNewEmbeddable(type, explicitInput); + } + }; navActions[TopNavIds.OPTIONS] = anchorElement => { showOptionsPopover({ diff --git a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_empty_screen.tsx b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_empty_screen.tsx index 234228ba4166a..af077a06c70ee 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_empty_screen.tsx +++ b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_empty_screen.tsx @@ -26,6 +26,7 @@ import { EuiPageBody, EuiPage, EuiText, + EuiButton, } from '@elastic/eui'; import * as constants from './dashboard_empty_screen_constants'; @@ -38,23 +39,17 @@ export interface DashboardEmptyScreenProps { export function DashboardEmptyScreen({ showLinkToVisualize, onLinkClick, + onVisualizeClick, }: DashboardEmptyScreenProps) { const linkToVisualizeParagraph = ( - -

+

+ - {constants.visualizeAppLinkTest} - - ), - }} + id="embeddableApi.addPanel.createNewDefaultOption" + defaultMessage="Create new" /> -

-
+ +

); const paragraph = ( description1: string, @@ -96,7 +91,7 @@ export function DashboardEmptyScreen({ ); return ( - + diff --git a/src/legacy/core_plugins/kibana/public/visualize/wizard/__snapshots__/new_vis_modal.test.tsx.snap b/src/legacy/core_plugins/kibana/public/visualize/wizard/__snapshots__/new_vis_modal.test.tsx.snap index 5be5f58994887..d0b19a9ce9ee3 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/wizard/__snapshots__/new_vis_modal.test.tsx.snap +++ b/src/legacy/core_plugins/kibana/public/visualize/wizard/__snapshots__/new_vis_modal.test.tsx.snap @@ -241,13 +241,70 @@ exports[`NewVisModal filter for visualization types should render as expected 1` aria-live="polite" class="euiScreenReaderOnly" > - 1 type found + 2 types found + + + + + Vis with alias Url + + } + onBlur={[Function]} + onClick={[Function]} + onFocus={[Function]} + onMouseEnter={[Function]} + onMouseLeave={[Function]} + role="menuitem" + > + + ({ import { NewVisModal } from './new_vis_modal'; describe('NewVisModal', () => { + const { location } = window; const defaultVisTypeParams = { hidden: false, visualization: class Controller { @@ -50,6 +51,12 @@ describe('NewVisModal', () => { stage: 'production', ...defaultVisTypeParams, }, + { + name: 'visWithAliasUrl', + title: 'Vis with alias Url', + stage: 'production', + aliasUrl: '/aliasUrl', + }, ]; const visTypes: TypesStart = { get: (id: string) => { @@ -68,6 +75,10 @@ describe('NewVisModal', () => { jest.clearAllMocks(); }); + afterAll(() => { + window.location = location; + }); + it('should render as expected', () => { const wrapper = mountWithIntl( { visButton.simulate('click'); expect(window.location.assign).toBeCalledWith('#/visualize/create?type=vis&foo=true&bar=42'); }); + + it('closes if visualization with aliasUrl and addToDashboard in editorParams', () => { + const onClose = jest.fn(); + window.location.assign = jest.fn(); + const wrapper = mountWithIntl( + + ); + const visButton = wrapper.find('button[data-test-subj="visType-visWithAliasUrl"]'); + visButton.simulate('click'); + expect(window.location.assign).toBeCalledWith('testbasepath/aliasUrl'); + expect(onClose).toHaveBeenCalled(); + }); }); describe('filter for visualization types', () => { diff --git a/src/legacy/core_plugins/kibana/public/visualize/wizard/new_vis_modal.tsx b/src/legacy/core_plugins/kibana/public/visualize/wizard/new_vis_modal.tsx index 0b46b562f2146..37b827fc947f9 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/wizard/new_vis_modal.tsx +++ b/src/legacy/core_plugins/kibana/public/visualize/wizard/new_vis_modal.tsx @@ -126,8 +126,10 @@ class NewVisModal extends React.Component { @@ -54,6 +56,12 @@ export default function ({ getService, getPageObjects }) { expect(isAddPanelOpen).to.be(true); }); + it('should add new visualization from dashboard', async () => { + await testSubjects.click('addVisualizationButton'); + await dashboardVisualizations.createAndAddMarkdown({ name: 'Dashboard Test Markdown', markdown: 'Markdown text' }, false); + await PageObjects.dashboard.waitForRenderComplete(); + await dashboardExpect.markdownWithValuesExists(['Markdown text']); + }); }); } diff --git a/test/functional/services/dashboard/visualizations.js b/test/functional/services/dashboard/visualizations.js index 8cde98861ca88..97433a1e4923c 100644 --- a/test/functional/services/dashboard/visualizations.js +++ b/test/functional/services/dashboard/visualizations.js @@ -73,14 +73,16 @@ export function DashboardVisualizationProvider({ getService, getPageObjects }) { await dashboardAddPanel.addSavedSearch(name); } - async createAndAddMarkdown({ name, markdown }) { + async createAndAddMarkdown({ name, markdown }, checkForAddPanel = true) { log.debug(`createAndAddMarkdown(${markdown})`); const inViewMode = await PageObjects.dashboard.getIsInViewMode(); if (inViewMode) { await PageObjects.dashboard.switchToEditMode(); } - await dashboardAddPanel.ensureAddPanelIsShowing(); - await dashboardAddPanel.clickAddNewEmbeddableLink('visualization'); + if (checkForAddPanel) { + await dashboardAddPanel.ensureAddPanelIsShowing(); + await dashboardAddPanel.clickAddNewEmbeddableLink('visualization'); + } await PageObjects.visualize.clickMarkdownWidget(); await PageObjects.visualize.setMarkdownTxt(markdown); await PageObjects.visualize.clickGo(); From d089ad0d0b548a1cefbe5e880ba39b39b20d7680 Mon Sep 17 00:00:00 2001 From: Maja Grubic Date: Tue, 10 Dec 2019 19:20:36 +0000 Subject: [PATCH 2/4] Fixing linting errors --- .../kibana/public/dashboard/dashboard_app_controller.tsx | 3 ++- .../kibana/public/dashboard/dashboard_empty_screen.tsx | 8 +++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app_controller.tsx b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app_controller.tsx index 057c1eb12c5ae..87f97de307c88 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app_controller.tsx +++ b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app_controller.tsx @@ -53,7 +53,8 @@ import { isErrorEmbeddable, ErrorEmbeddable, ViewMode, - openAddPanelFlyout, EmbeddableFactoryNotFoundError, + openAddPanelFlyout, + EmbeddableFactoryNotFoundError, } from '../../../embeddable_api/public/np_ready/public'; import { DashboardAppState, NavAction, ConfirmModalFn, SavedDashboardPanel } from './types'; diff --git a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_empty_screen.tsx b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_empty_screen.tsx index af077a06c70ee..787229e2527c2 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_empty_screen.tsx +++ b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_empty_screen.tsx @@ -43,7 +43,13 @@ export function DashboardEmptyScreen({ }: DashboardEmptyScreenProps) { const linkToVisualizeParagraph = (

- + Date: Wed, 11 Dec 2019 09:13:03 +0000 Subject: [PATCH 3/4] Fixing i18n error --- .../__snapshots__/dashboard_empty_screen.test.tsx.snap | 8 +------- .../kibana/public/dashboard/dashboard_empty_screen.tsx | 7 ++----- .../public/dashboard/dashboard_empty_screen_constants.tsx | 6 ++++++ 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/legacy/core_plugins/kibana/public/dashboard/__tests__/__snapshots__/dashboard_empty_screen.test.tsx.snap b/src/legacy/core_plugins/kibana/public/dashboard/__tests__/__snapshots__/dashboard_empty_screen.test.tsx.snap index 6b022fe943dc1..4ea658bcd03ef 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/__tests__/__snapshots__/dashboard_empty_screen.test.tsx.snap +++ b/src/legacy/core_plugins/kibana/public/dashboard/__tests__/__snapshots__/dashboard_empty_screen.test.tsx.snap @@ -350,13 +350,7 @@ exports[`DashboardEmptyScreen renders correctly with visualize paragraph 1`] = ` - - Create new - + Create new diff --git a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_empty_screen.tsx b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_empty_screen.tsx index 787229e2527c2..2fc78d64d0a0c 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_empty_screen.tsx +++ b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_empty_screen.tsx @@ -17,7 +17,7 @@ * under the License. */ import React from 'react'; -import { I18nProvider, FormattedMessage } from '@kbn/i18n/react'; +import { I18nProvider } from '@kbn/i18n/react'; import { EuiIcon, EuiLink, @@ -50,10 +50,7 @@ export function DashboardEmptyScreen({ onClick={onVisualizeClick} data-test-subj="addVisualizationButton" > - + {constants.createNewVisualizationButton}

); diff --git a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_empty_screen_constants.tsx b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_empty_screen_constants.tsx index 0f510375aaf59..03004f6270fef 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_empty_screen_constants.tsx +++ b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_empty_screen_constants.tsx @@ -76,3 +76,9 @@ export const visualizeAppLinkTest: string = i18n.translate( defaultMessage: 'visit the Visualize app', } ); +export const createNewVisualizationButton: string = i18n.translate( + 'kbn.dashboard.createNewVisualizationButton', + { + defaultMessage: 'Create new', + } +); From ff865d68838ed5cb4cf7207d98cd4a24b5fa7080 Mon Sep 17 00:00:00 2001 From: Maja Grubic Date: Wed, 11 Dec 2019 19:33:10 +0000 Subject: [PATCH 4/4] Fixing unit test that was causing typecheck failure --- .../kibana/public/visualize/wizard/new_vis_modal.test.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/legacy/core_plugins/kibana/public/visualize/wizard/new_vis_modal.test.tsx b/src/legacy/core_plugins/kibana/public/visualize/wizard/new_vis_modal.test.tsx index 1d257df077071..79799d09caec3 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/wizard/new_vis_modal.test.tsx +++ b/src/legacy/core_plugins/kibana/public/visualize/wizard/new_vis_modal.test.tsx @@ -155,6 +155,7 @@ describe('NewVisModal', () => { editorParams={['foo=true', 'bar=42', 'addToDashboard']} addBasePath={addBasePath} uiSettings={uiSettings} + savedObjects={{} as SavedObjectsStart} /> ); const visButton = wrapper.find('button[data-test-subj="visType-visWithAliasUrl"]');