diff --git a/src/legacy/core_plugins/kibana/public/dashboard/np_ready/dashboard_app_controller.tsx b/src/legacy/core_plugins/kibana/public/dashboard/np_ready/dashboard_app_controller.tsx
index d1e4c9d2d2a0c..f1e1f20de1ce6 100644
--- a/src/legacy/core_plugins/kibana/public/dashboard/np_ready/dashboard_app_controller.tsx
+++ b/src/legacy/core_plugins/kibana/public/dashboard/np_ready/dashboard_app_controller.tsx
@@ -754,7 +754,7 @@ export class DashboardAppController {
* When de-angularizing this code, please call the underlaying action function
* directly and not via the top nav object.
**/
- navActions[TopNavIds.ADD]();
+ navActions[TopNavIds.ADD_EXISTING]();
};
$scope.enterEditMode = () => {
dashboardStateManager.setFullScreenMode(false);
@@ -847,7 +847,8 @@ export class DashboardAppController {
showCloneModal(onClone, currentTitle);
};
- navActions[TopNavIds.ADD] = () => {
+
+ navActions[TopNavIds.ADD_EXISTING] = () => {
if (dashboardContainer && !isErrorEmbeddable(dashboardContainer)) {
openAddPanelFlyout({
embeddable: dashboardContainer,
diff --git a/src/legacy/core_plugins/kibana/public/dashboard/np_ready/top_nav/get_top_nav_config.ts b/src/legacy/core_plugins/kibana/public/dashboard/np_ready/top_nav/get_top_nav_config.ts
index 7188fab19d6f2..7a3cb4b7dad56 100644
--- a/src/legacy/core_plugins/kibana/public/dashboard/np_ready/top_nav/get_top_nav_config.ts
+++ b/src/legacy/core_plugins/kibana/public/dashboard/np_ready/top_nav/get_top_nav_config.ts
@@ -48,9 +48,10 @@ export function getTopNavConfig(
];
case ViewMode.EDIT:
return [
+ getCreateNewConfig(actions[TopNavIds.VISUALIZE]),
getSaveConfig(actions[TopNavIds.SAVE]),
getViewConfig(actions[TopNavIds.EXIT_EDIT_MODE]),
- getAddConfig(actions[TopNavIds.ADD]),
+ getAddConfig(actions[TopNavIds.ADD_EXISTING]),
getOptionsConfig(actions[TopNavIds.OPTIONS]),
getShareConfig(actions[TopNavIds.SHARE]),
];
@@ -161,6 +162,25 @@ function getAddConfig(action: NavAction) {
};
}
+/**
+ * @returns {kbnTopNavConfig}
+ */
+function getCreateNewConfig(action: NavAction) {
+ return {
+ emphasize: true,
+ iconType: 'plusInCircle',
+ id: 'addNew',
+ label: i18n.translate('kbn.dashboard.topNave.addNewButtonAriaLabel', {
+ defaultMessage: 'Create new',
+ }),
+ description: i18n.translate('kbn.dashboard.topNave.addNewConfigDescription', {
+ defaultMessage: 'Create a new panel on this dashboard',
+ }),
+ testId: 'dashboardAddNewPanelButton',
+ run: action,
+ };
+}
+
/**
* @returns {kbnTopNavConfig}
*/
diff --git a/src/legacy/core_plugins/kibana/public/dashboard/np_ready/top_nav/top_nav_ids.ts b/src/legacy/core_plugins/kibana/public/dashboard/np_ready/top_nav/top_nav_ids.ts
index c67d6891c18e7..748bfaaab6141 100644
--- a/src/legacy/core_plugins/kibana/public/dashboard/np_ready/top_nav/top_nav_ids.ts
+++ b/src/legacy/core_plugins/kibana/public/dashboard/np_ready/top_nav/top_nav_ids.ts
@@ -18,7 +18,6 @@
*/
export const TopNavIds = {
- ADD: 'add',
SHARE: 'share',
OPTIONS: 'options',
SAVE: 'save',
@@ -27,4 +26,5 @@ export const TopNavIds = {
CLONE: 'clone',
FULL_SCREEN: 'fullScreenMode',
VISUALIZE: 'visualize',
+ ADD_EXISTING: 'addExisting',
};
diff --git a/src/plugins/navigation/public/top_nav_menu/__snapshots__/top_nav_menu_item.test.tsx.snap b/src/plugins/navigation/public/top_nav_menu/__snapshots__/top_nav_menu_item.test.tsx.snap
new file mode 100644
index 0000000000000..0d54d5d3e9c4a
--- /dev/null
+++ b/src/plugins/navigation/public/top_nav_menu/__snapshots__/top_nav_menu_item.test.tsx.snap
@@ -0,0 +1,19 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`TopNavMenu Should render emphasized item which should be clickable 1`] = `
+
+ Test
+
+`;
diff --git a/src/plugins/navigation/public/top_nav_menu/_index.scss b/src/plugins/navigation/public/top_nav_menu/_index.scss
index 4a0e6af3f7f70..5befe4789dd6c 100644
--- a/src/plugins/navigation/public/top_nav_menu/_index.scss
+++ b/src/plugins/navigation/public/top_nav_menu/_index.scss
@@ -1,7 +1,11 @@
.kbnTopNavMenu__wrapper {
z-index: 5;
- .kbnTopNavMenu {
- padding: $euiSizeS 0px $euiSizeXS;
+ .kbnTopNavMenu {
+ padding: $euiSizeS 0;
+
+ .kbnTopNavItemEmphasized {
+ padding: 0 $euiSizeS;
+ }
}
}
diff --git a/src/plugins/navigation/public/top_nav_menu/top_nav_menu.tsx b/src/plugins/navigation/public/top_nav_menu/top_nav_menu.tsx
index 80d1a53cd417f..14ad40f13e388 100644
--- a/src/plugins/navigation/public/top_nav_menu/top_nav_menu.tsx
+++ b/src/plugins/navigation/public/top_nav_menu/top_nav_menu.tsx
@@ -46,7 +46,11 @@ export function TopNavMenu(props: TopNavMenuProps) {
if (!config) return;
return config.map((menuItem: TopNavMenuData, i: number) => {
return (
-
+
);
@@ -66,6 +70,7 @@ export function TopNavMenu(props: TopNavMenuProps) {
void;
export interface TopNavMenuData {
@@ -28,6 +30,9 @@ export interface TopNavMenuData {
className?: string;
disableButton?: boolean | (() => boolean);
tooltip?: string | (() => string);
+ emphasize?: boolean;
+ iconType?: string;
+ iconSide?: ButtonIconSide;
}
export interface RegisteredTopNavMenuData extends TopNavMenuData {
diff --git a/src/plugins/navigation/public/top_nav_menu/top_nav_menu_item.test.tsx b/src/plugins/navigation/public/top_nav_menu/top_nav_menu_item.test.tsx
index 4816ef3c95869..9ba58379c5ce1 100644
--- a/src/plugins/navigation/public/top_nav_menu/top_nav_menu_item.test.tsx
+++ b/src/plugins/navigation/public/top_nav_menu/top_nav_menu_item.test.tsx
@@ -23,6 +23,15 @@ import { TopNavMenuData } from './top_nav_menu_data';
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
describe('TopNavMenu', () => {
+ const ensureMenuItemDisabled = (data: TopNavMenuData) => {
+ const component = shallowWithIntl();
+ expect(component.prop('isDisabled')).toEqual(true);
+
+ const event = { currentTarget: { value: 'a' } };
+ component.simulate('click', event);
+ expect(data.run).toHaveBeenCalledTimes(0);
+ };
+
it('Should render and click an item', () => {
const data: TopNavMenuData = {
id: 'test',
@@ -60,35 +69,62 @@ describe('TopNavMenu', () => {
expect(data.run).toHaveBeenCalled();
});
- it('Should render disabled item and it shouldnt be clickable', () => {
+ it('Should render emphasized item which should be clickable', () => {
const data: TopNavMenuData = {
id: 'test',
label: 'test',
- disableButton: true,
+ iconType: 'beaker',
+ iconSide: 'right',
+ emphasize: true,
run: jest.fn(),
};
const component = shallowWithIntl();
- expect(component.prop('isDisabled')).toEqual(true);
-
const event = { currentTarget: { value: 'a' } };
component.simulate('click', event);
- expect(data.run).toHaveBeenCalledTimes(0);
+ expect(data.run).toHaveBeenCalledTimes(1);
+ expect(component).toMatchSnapshot();
+ });
+
+ it('Should render disabled item and it shouldnt be clickable', () => {
+ ensureMenuItemDisabled({
+ id: 'test',
+ label: 'test',
+ disableButton: true,
+ run: jest.fn(),
+ });
});
it('Should render item with disable function and it shouldnt be clickable', () => {
- const data: TopNavMenuData = {
+ ensureMenuItemDisabled({
id: 'test',
label: 'test',
disableButton: () => true,
run: jest.fn(),
- };
+ });
+ });
- const component = shallowWithIntl();
- expect(component.prop('isDisabled')).toEqual(true);
+ it('Should render disabled emphasized item which shouldnt be clickable', () => {
+ ensureMenuItemDisabled({
+ id: 'test',
+ label: 'test',
+ iconType: 'beaker',
+ iconSide: 'right',
+ emphasize: true,
+ disableButton: true,
+ run: jest.fn(),
+ });
+ });
- const event = { currentTarget: { value: 'a' } };
- component.simulate('click', event);
- expect(data.run).toHaveBeenCalledTimes(0);
+ it('Should render emphasized item with disable function and it shouldnt be clickable', () => {
+ ensureMenuItemDisabled({
+ id: 'test',
+ label: 'test',
+ iconType: 'beaker',
+ iconSide: 'right',
+ emphasize: true,
+ disableButton: () => true,
+ run: jest.fn(),
+ });
});
});
diff --git a/src/plugins/navigation/public/top_nav_menu/top_nav_menu_item.tsx b/src/plugins/navigation/public/top_nav_menu/top_nav_menu_item.tsx
index 4d3b72bae6411..92e267f17d08e 100644
--- a/src/plugins/navigation/public/top_nav_menu/top_nav_menu_item.tsx
+++ b/src/plugins/navigation/public/top_nav_menu/top_nav_menu_item.tsx
@@ -21,6 +21,7 @@ import { capitalize, isFunction } from 'lodash';
import React, { MouseEvent } from 'react';
import { EuiButtonEmpty, EuiToolTip } from '@elastic/eui';
+import { EuiButton } from '@elastic/eui';
import { TopNavMenuData } from './top_nav_menu_data';
export function TopNavMenuItem(props: TopNavMenuData) {
@@ -39,14 +40,20 @@ export function TopNavMenuItem(props: TopNavMenuData) {
props.run(e.currentTarget);
}
- const btn = (
-
+ const commonButtonProps = {
+ isDisabled: isDisabled(),
+ onClick: handleClick,
+ iconType: props.iconType,
+ iconSide: props.iconSide,
+ 'data-test-subj': props.testId,
+ };
+
+ const btn = props.emphasize ? (
+
+ {capitalize(props.label || props.id!)}
+
+ ) : (
+
{capitalize(props.label || props.id!)}
);
@@ -54,9 +61,8 @@ export function TopNavMenuItem(props: TopNavMenuData) {
const tooltip = getTooltip();
if (tooltip) {
return {btn};
- } else {
- return btn;
}
+ return btn;
}
TopNavMenuItem.defaultProps = {
diff --git a/test/functional/apps/dashboard/create_and_add_embeddables.js b/test/functional/apps/dashboard/create_and_add_embeddables.js
index 5ebb9fdf6330f..3ce8e353e61fc 100644
--- a/test/functional/apps/dashboard/create_and_add_embeddables.js
+++ b/test/functional/apps/dashboard/create_and_add_embeddables.js
@@ -41,9 +41,24 @@ export default function({ getService, getPageObjects }) {
});
describe('add new visualization link', () => {
- it('adds a new visualization', async () => {
+ it('adds new visualiztion via the top nav link', async () => {
const originalPanelCount = await PageObjects.dashboard.getPanelCount();
await PageObjects.dashboard.switchToEditMode();
+ await dashboardAddPanel.clickCreateNewLink();
+ await PageObjects.visualize.clickAreaChart();
+ await PageObjects.visualize.clickNewSearch();
+ await PageObjects.visualize.saveVisualizationExpectSuccess(
+ 'visualization from top nav add new panel'
+ );
+ await retry.try(async () => {
+ const panelCount = await PageObjects.dashboard.getPanelCount();
+ expect(panelCount).to.eql(originalPanelCount + 1);
+ });
+ await PageObjects.dashboard.waitForRenderComplete();
+ });
+
+ it('adds a new visualization', async () => {
+ const originalPanelCount = await PageObjects.dashboard.getPanelCount();
await dashboardAddPanel.ensureAddPanelIsShowing();
await dashboardAddPanel.clickAddNewEmbeddableLink('visualization');
await PageObjects.visualize.clickAreaChart();
diff --git a/test/functional/services/dashboard/add_panel.js b/test/functional/services/dashboard/add_panel.js
index 91e7c15c4f1d9..6259203982161 100644
--- a/test/functional/services/dashboard/add_panel.js
+++ b/test/functional/services/dashboard/add_panel.js
@@ -32,6 +32,13 @@ export function DashboardAddPanelProvider({ getService, getPageObjects }) {
await PageObjects.common.sleep(500);
}
+ async clickCreateNewLink() {
+ log.debug('DashboardAddPanel.clickAddNewPanelButton');
+ await testSubjects.click('dashboardAddNewPanelButton');
+ // Give some time for the animation to complete
+ await PageObjects.common.sleep(500);
+ }
+
async clickAddNewEmbeddableLink(type) {
await testSubjects.click('createNew');
await testSubjects.click(`createNew-${type}`);