/>
}
color="warning"
- data-test-subj="titleDupicateWarnMsg"
+ data-test-subj="titleDuplicateWarnMsg"
id={duplicateWarningId}
>
diff --git a/src/plugins/saved_objects/public/save_modal/show_saved_object_save_modal.tsx b/src/plugins/saved_objects/public/save_modal/show_saved_object_save_modal.tsx
index 5d04e5b10ed85..9013cec29997a 100644
--- a/src/plugins/saved_objects/public/save_modal/show_saved_object_save_modal.tsx
+++ b/src/plugins/saved_objects/public/save_modal/show_saved_object_save_modal.tsx
@@ -7,9 +7,8 @@
*/
import React, { FC, PropsWithChildren } from 'react';
-import ReactDOM from 'react-dom';
-import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render';
+import { toMountPoint } from '@kbn/react-kibana-mount';
import { getAnalytics, getI18n, getTheme } from '../kibana_services';
/**
@@ -34,34 +33,42 @@ export function showSaveModal(
saveModal: React.ReactElement,
Wrapper?: FC>
) {
- const container = document.createElement('div');
- const closeModal = () => {
- ReactDOM.unmountComponentAtNode(container);
- document.body.removeChild(container);
- saveModal.props.onClose?.();
- };
+ // initialize variable that will hold reference for unmount
+ // eslint-disable-next-line prefer-const
+ let unmount: ReturnType>;
- const onSave = saveModal.props.onSave;
+ const mount = toMountPoint(
+ React.createElement(function createSavedObjectModal() {
+ const closeModal = () => {
+ unmount();
+ // revert control back to caller after cleaning up modal
+ setTimeout(() => {
+ saveModal.props.onClose?.();
+ }, 0);
+ };
- const onSaveConfirmed: MinimalSaveModalProps['onSave'] = async (...args) => {
- const response = await onSave(...args);
- // close modal if we either hit an error or the saved object got an id
- if (Boolean(isSuccess(response) ? response.id : response.error)) {
- closeModal();
- }
- return response;
- };
- document.body.appendChild(container);
- const element = React.cloneElement(saveModal, {
- onSave: onSaveConfirmed,
- onClose: closeModal,
- });
+ const onSave = saveModal.props.onSave;
- const I18nContext = getI18n().Context;
- ReactDOM.render(
-
- {Wrapper ? {element} : element}
- ,
- container
+ const onSaveConfirmed: MinimalSaveModalProps['onSave'] = async (...args) => {
+ const response = await onSave(...args);
+ // close modal if we either hit an error or the saved object got an id
+ if (Boolean(isSuccess(response) ? response.id : response.error)) {
+ closeModal();
+ }
+ return response;
+ };
+
+ const augmentedElement = React.cloneElement(saveModal, {
+ onSave: onSaveConfirmed,
+ onClose: closeModal,
+ });
+
+ return React.createElement(Wrapper ?? React.Fragment, {
+ children: augmentedElement,
+ });
+ }),
+ { analytics: getAnalytics(), theme: getTheme(), i18n: getI18n() }
);
+
+ unmount = mount(document.createElement('div'));
}
diff --git a/src/plugins/saved_objects/tsconfig.json b/src/plugins/saved_objects/tsconfig.json
index 39557cef8c5b1..4119011216816 100644
--- a/src/plugins/saved_objects/tsconfig.json
+++ b/src/plugins/saved_objects/tsconfig.json
@@ -13,7 +13,6 @@
"@kbn/i18n-react",
"@kbn/utility-types",
"@kbn/ui-theme",
- "@kbn/react-kibana-context-render",
"@kbn/react-kibana-mount",
],
"exclude": [
diff --git a/test/accessibility/apps/dashboard.ts b/test/accessibility/apps/dashboard.ts
index 32d198c7d5e02..268bf06bc4b17 100644
--- a/test/accessibility/apps/dashboard.ts
+++ b/test/accessibility/apps/dashboard.ts
@@ -57,7 +57,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
it('save the dashboard', async () => {
- await PageObjects.dashboard.saveDashboard(dashboardName);
+ await PageObjects.dashboard.saveDashboard(dashboardName, { saveAsNew: false });
await a11y.testAppSnapshot();
});
@@ -128,7 +128,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
it('Make a clone of the dashboard', async () => {
- await PageObjects.dashboard.clickClone();
+ await PageObjects.dashboard.duplicateDashboard();
await a11y.testAppSnapshot();
});
diff --git a/test/functional/apps/dashboard/group1/embeddable_rendering.ts b/test/functional/apps/dashboard/group1/embeddable_rendering.ts
index 45408a8846c17..3ebef1fda00cc 100644
--- a/test/functional/apps/dashboard/group1/embeddable_rendering.ts
+++ b/test/functional/apps/dashboard/group1/embeddable_rendering.ts
@@ -154,6 +154,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.dashboard.waitForRenderComplete();
await PageObjects.dashboard.saveDashboard('embeddable rendering test', {
+ saveAsNew: true,
storeTimeWithDashboard: true,
});
});
diff --git a/test/functional/apps/dashboard/group2/dashboard_filter_bar.ts b/test/functional/apps/dashboard/group2/dashboard_filter_bar.ts
index 276a3f29e8fd5..c580d69fa0453 100644
--- a/test/functional/apps/dashboard/group2/dashboard_filter_bar.ts
+++ b/test/functional/apps/dashboard/group2/dashboard_filter_bar.ts
@@ -167,9 +167,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
const filterKey = 'bytes';
await filterBar.toggleFilterPinned(filterKey);
await PageObjects.dashboard.switchToEditMode();
- await PageObjects.dashboard.saveDashboard('saved with pinned filters', {
- saveAsNew: true,
- });
+ await PageObjects.dashboard.saveDashboard('saved with pinned filters');
expect(await filterBar.isFilterPinned(filterKey)).to.be(true);
await pieChart.expectPieSliceCount(1);
});
diff --git a/test/functional/apps/dashboard/group3/bwc_shared_urls.ts b/test/functional/apps/dashboard/group3/bwc_shared_urls.ts
index 8f89ed302c67c..fece4367abf04 100644
--- a/test/functional/apps/dashboard/group3/bwc_shared_urls.ts
+++ b/test/functional/apps/dashboard/group3/bwc_shared_urls.ts
@@ -103,6 +103,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('loads a saved dashboard', async function () {
await PageObjects.dashboard.saveDashboard('saved with colors', {
+ saveAsNew: true,
storeTimeWithDashboard: true,
});
diff --git a/test/functional/apps/dashboard/group3/dashboard_state.ts b/test/functional/apps/dashboard/group3/dashboard_state.ts
index 423adf781835c..df80d35ce2a64 100644
--- a/test/functional/apps/dashboard/group3/dashboard_state.ts
+++ b/test/functional/apps/dashboard/group3/dashboard_state.ts
@@ -102,7 +102,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
const overwriteColor = '#d36086';
await PageObjects.visChart.selectNewLegendColorChoice(overwriteColor);
- await PageObjects.dashboard.saveDashboard(dashboardName);
+ await PageObjects.dashboard.saveDashboard(dashboardName, { saveAsNew: false });
await PageObjects.dashboard.gotoDashboardLandingPage();
await PageObjects.dashboard.loadSavedDashboard(dashboardName);
diff --git a/test/functional/apps/dashboard/group4/dashboard_clone.ts b/test/functional/apps/dashboard/group4/dashboard_clone.ts
index c62c1a4195900..438f01061dda8 100644
--- a/test/functional/apps/dashboard/group4/dashboard_clone.ts
+++ b/test/functional/apps/dashboard/group4/dashboard_clone.ts
@@ -30,7 +30,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
);
await PageObjects.dashboard.saveDashboard(dashboardName);
- await PageObjects.dashboard.clickClone();
+ await PageObjects.dashboard.duplicateDashboard();
await PageObjects.dashboard.gotoDashboardLandingPage();
await listingTable.searchAndExpectItemsCount('dashboard', clonedDashboardName, 1);
});
diff --git a/test/functional/apps/dashboard/group4/dashboard_listing.ts b/test/functional/apps/dashboard/group4/dashboard_listing.ts
index ed8cc60cb5884..36e99d0e5c8c1 100644
--- a/test/functional/apps/dashboard/group4/dashboard_listing.ts
+++ b/test/functional/apps/dashboard/group4/dashboard_listing.ts
@@ -164,7 +164,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('stays on listing page if title matches two dashboards', async function () {
await PageObjects.dashboard.clickNewDashboard();
- await PageObjects.dashboard.saveDashboard('two words', { needsConfirm: true });
+ await PageObjects.dashboard.saveDashboard('two words', {
+ saveAsNew: true,
+ needsConfirm: true,
+ });
await PageObjects.dashboard.gotoDashboardLandingPage();
const currentUrl = await browser.getCurrentUrl();
const newUrl = currentUrl + '&title=two%20words';
diff --git a/test/functional/apps/dashboard/group4/dashboard_save.ts b/test/functional/apps/dashboard/group4/dashboard_save.ts
index 4bbf697974953..9b7bcc77406c9 100644
--- a/test/functional/apps/dashboard/group4/dashboard_save.ts
+++ b/test/functional/apps/dashboard/group4/dashboard_save.ts
@@ -25,126 +25,144 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.dashboard.initTests();
});
- it('warns on duplicate name for new dashboard', async function () {
- await PageObjects.dashboard.clickNewDashboard();
- await PageObjects.dashboard.saveDashboard(dashboardName);
+ describe('create new', () => {
+ it('warns on duplicate name for new dashboard', async function () {
+ await PageObjects.dashboard.clickNewDashboard();
+ await PageObjects.dashboard.saveDashboard(dashboardName);
+
+ await PageObjects.dashboard.expectDuplicateTitleWarningDisplayed({ displayed: false });
+
+ await PageObjects.dashboard.gotoDashboardLandingPage();
+ await PageObjects.dashboard.clickNewDashboard();
+ await PageObjects.dashboard.enterDashboardSaveModalApplyUpdatesAndClickSave(dashboardName, {
+ waitDialogIsClosed: false,
+ });
+ await PageObjects.dashboard.expectDuplicateTitleWarningDisplayed({ displayed: true });
+ });
- await PageObjects.dashboard.expectDuplicateTitleWarningDisplayed({ displayed: false });
+ it('does not save on reject confirmation', async function () {
+ await PageObjects.dashboard.cancelSave();
+ await PageObjects.dashboard.gotoDashboardLandingPage();
- await PageObjects.dashboard.gotoDashboardLandingPage();
- await PageObjects.dashboard.clickNewDashboard();
- await PageObjects.dashboard.enterDashboardTitleAndClickSave(dashboardName, {
- waitDialogIsClosed: false,
+ await listingTable.searchAndExpectItemsCount('dashboard', dashboardName, 1);
});
- await PageObjects.dashboard.expectDuplicateTitleWarningDisplayed({ displayed: true });
- });
- it('does not save on reject confirmation', async function () {
- await PageObjects.dashboard.cancelSave();
- await PageObjects.dashboard.gotoDashboardLandingPage();
+ it('Saves on confirm duplicate title warning', async function () {
+ await PageObjects.dashboard.gotoDashboardLandingPage();
+ await PageObjects.dashboard.clickNewDashboard();
+ await PageObjects.dashboard.enterDashboardSaveModalApplyUpdatesAndClickSave(dashboardName, {
+ waitDialogIsClosed: false,
+ });
- await listingTable.searchAndExpectItemsCount('dashboard', dashboardName, 1);
- });
+ await PageObjects.dashboard.ensureDuplicateTitleCallout();
+ await PageObjects.dashboard.clickSave();
- it('Saves on confirm duplicate title warning', async function () {
- await PageObjects.dashboard.gotoDashboardLandingPage();
- await PageObjects.dashboard.clickNewDashboard();
- await PageObjects.dashboard.enterDashboardTitleAndClickSave(dashboardName, {
- waitDialogIsClosed: false,
- });
+ // This is important since saving a new dashboard will cause a refresh of the page. We have to
+ // wait till it finishes reloading or it might reload the url after simulating the
+ // dashboard landing page click.
+ await PageObjects.header.waitUntilLoadingHasFinished();
- await PageObjects.dashboard.ensureDuplicateTitleCallout();
- await PageObjects.dashboard.clickSave();
+ // after saving a new dashboard, the app state must be removed
+ await await PageObjects.dashboard.expectAppStateRemovedFromURL();
- // This is important since saving a new dashboard will cause a refresh of the page. We have to
- // wait till it finishes reloading or it might reload the url after simulating the
- // dashboard landing page click.
- await PageObjects.header.waitUntilLoadingHasFinished();
+ await PageObjects.dashboard.gotoDashboardLandingPage();
- // after saving a new dashboard, the app state must be removed
- await await PageObjects.dashboard.expectAppStateRemovedFromURL();
+ await listingTable.searchAndExpectItemsCount('dashboard', dashboardName, 2);
+ });
- await PageObjects.dashboard.gotoDashboardLandingPage();
+ it('Saves new Dashboard using the Enter key', async function () {
+ await PageObjects.dashboard.gotoDashboardLandingPage();
+ await PageObjects.dashboard.clickNewDashboard();
+ await PageObjects.dashboard.enterDashboardTitleAndPressEnter(dashboardNameEnterKey);
- await listingTable.searchAndExpectItemsCount('dashboard', dashboardName, 2);
- });
+ // This is important since saving a new dashboard will cause a refresh of the page. We have to
+ // wait till it finishes reloading or it might reload the url after simulating the
+ // dashboard landing page click.
+ await PageObjects.header.waitUntilLoadingHasFinished();
+ await PageObjects.dashboard.gotoDashboardLandingPage();
- it('Does not warn when you save an existing dashboard with the title it already has, and that title is a duplicate', async function () {
- await listingTable.clickItemLink('dashboard', dashboardName);
- await PageObjects.header.awaitGlobalLoadingIndicatorHidden();
- await PageObjects.dashboard.switchToEditMode();
- await PageObjects.dashboard.saveDashboard(dashboardName);
-
- await PageObjects.dashboard.expectDuplicateTitleWarningDisplayed({ displayed: false });
+ await listingTable.searchAndExpectItemsCount('dashboard', dashboardNameEnterKey, 1);
+ });
});
- it('Warns you when you Save as New Dashboard, and the title is a duplicate', async function () {
- await PageObjects.dashboard.switchToEditMode();
- await PageObjects.dashboard.enterDashboardTitleAndClickSave(dashboardName, {
- saveAsNew: true,
+ describe('quick save', () => {
+ it('Does not show quick save menu item on a new dashboard', async function () {
+ await PageObjects.dashboard.gotoDashboardLandingPage();
+ await PageObjects.dashboard.clickNewDashboard();
+ await PageObjects.dashboard.expectMissingQuickSaveOption();
});
- await PageObjects.dashboard.expectDuplicateTitleWarningDisplayed({ displayed: true });
+ it('Does not show dashboard save modal when on quick save', async function () {
+ await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional');
+ await PageObjects.dashboard.gotoDashboardLandingPage();
+ await PageObjects.dashboard.clickNewDashboard();
+ await PageObjects.dashboard.saveDashboard('test quick save');
- await PageObjects.dashboard.cancelSave();
- });
+ await PageObjects.dashboard.switchToEditMode();
+ await PageObjects.dashboard.expectExistsQuickSaveOption();
+ await dashboardAddPanel.clickMarkdownQuickButton();
+ await PageObjects.visualize.saveVisualizationAndReturn();
+ await PageObjects.dashboard.waitForRenderComplete();
+ await PageObjects.dashboard.clickQuickSave();
- it('Does not warn when only the prefix matches', async function () {
- await PageObjects.dashboard.saveDashboard(dashboardName.split(' ')[0]);
+ await testSubjects.existOrFail('saveDashboardSuccess');
+ });
- await PageObjects.dashboard.expectDuplicateTitleWarningDisplayed({ displayed: false });
+ it('Stays in edit mode after performing a quick save', async function () {
+ await PageObjects.header.waitUntilLoadingHasFinished();
+ await testSubjects.existOrFail('dashboardQuickSaveMenuItem');
+ });
});
- it('Warns when case is different', async function () {
- await PageObjects.dashboard.switchToEditMode();
- await PageObjects.dashboard.enterDashboardTitleAndClickSave(dashboardName.toUpperCase(), {
- waitDialogIsClosed: false,
+ describe('duplication (edit mode)', () => {
+ it('Warns you when you Save as New Dashboard, and the title is a duplicate', async function () {
+ await PageObjects.dashboard.switchToEditMode();
+ await PageObjects.dashboard.enterDashboardSaveModalApplyUpdatesAndClickSave(dashboardName, {
+ waitDialogIsClosed: false,
+ });
+
+ await PageObjects.dashboard.expectDuplicateTitleWarningDisplayed({ displayed: true });
+
+ await PageObjects.dashboard.cancelSave();
});
- await PageObjects.dashboard.expectDuplicateTitleWarningDisplayed({ displayed: true });
+ it('Does not warn when only the prefix matches', async function () {
+ await PageObjects.dashboard.saveDashboard(dashboardName.split(' ')[0]);
- await PageObjects.dashboard.cancelSave();
- });
+ await PageObjects.dashboard.expectDuplicateTitleWarningDisplayed({ displayed: false });
+ });
- it('Saves new Dashboard using the Enter key', async function () {
- await PageObjects.dashboard.gotoDashboardLandingPage();
- await PageObjects.dashboard.clickNewDashboard();
- await PageObjects.dashboard.enterDashboardTitleAndPressEnter(dashboardNameEnterKey);
+ it('Warns when case is different', async function () {
+ await PageObjects.dashboard.switchToEditMode();
+ await PageObjects.dashboard.enterDashboardSaveModalApplyUpdatesAndClickSave(
+ dashboardName.toUpperCase(),
+ {
+ waitDialogIsClosed: false,
+ }
+ );
- // This is important since saving a new dashboard will cause a refresh of the page. We have to
- // wait till it finishes reloading or it might reload the url after simulating the
- // dashboard landing page click.
- await PageObjects.header.waitUntilLoadingHasFinished();
- await PageObjects.dashboard.gotoDashboardLandingPage();
+ await PageObjects.dashboard.expectDuplicateTitleWarningDisplayed({ displayed: true });
- await listingTable.searchAndExpectItemsCount('dashboard', dashboardNameEnterKey, 1);
+ await PageObjects.dashboard.cancelSave();
+ });
});
- it('Does not show quick save menu item on a new dashboard', async function () {
- await PageObjects.dashboard.gotoDashboardLandingPage();
- await PageObjects.dashboard.clickNewDashboard();
- await PageObjects.dashboard.expectMissingQuickSaveOption();
- });
+ describe('flyout settings', () => {
+ const dashboardNameFlyout = 'Dashboard Save Test with Flyout';
- it('Does not show dashboard save modal when on quick save', async function () {
- await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional');
- await PageObjects.dashboard.gotoDashboardLandingPage();
- await PageObjects.dashboard.clickNewDashboard();
- await PageObjects.dashboard.saveDashboard('test quick save');
-
- await PageObjects.dashboard.switchToEditMode();
- await PageObjects.dashboard.expectExistsQuickSaveOption();
- await dashboardAddPanel.clickMarkdownQuickButton();
- await PageObjects.visualize.saveVisualizationAndReturn();
- await PageObjects.dashboard.waitForRenderComplete();
- await PageObjects.dashboard.clickQuickSave();
-
- await testSubjects.existOrFail('saveDashboardSuccess');
- });
+ it('Does not warn when you save an existing dashboard with the title it already has', async function () {
+ await PageObjects.dashboard.gotoDashboardLandingPage();
+ await PageObjects.dashboard.clickNewDashboard();
+ await PageObjects.dashboard.enterDashboardTitleAndPressEnter(dashboardNameFlyout);
- it('Stays in edit mode after performing a quick save', async function () {
- await PageObjects.header.waitUntilLoadingHasFinished();
- await testSubjects.existOrFail('dashboardQuickSaveMenuItem');
+ // This is important since saving a new dashboard will cause a refresh of the page. We have to
+ // wait till it finishes reloading or it might reload the url after simulating the
+ // dashboard landing page click.
+ await PageObjects.header.waitUntilLoadingHasFinished();
+
+ await PageObjects.dashboard.switchToEditMode();
+ await PageObjects.dashboard.modifyExistingDashboardDetails(dashboardNameFlyout);
+ });
});
});
}
diff --git a/test/functional/apps/dashboard/group4/dashboard_time.ts b/test/functional/apps/dashboard/group4/dashboard_time.ts
index 2b35c5e78f331..eb689353bde41 100644
--- a/test/functional/apps/dashboard/group4/dashboard_time.ts
+++ b/test/functional/apps/dashboard/group4/dashboard_time.ts
@@ -33,7 +33,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.dashboard.addVisualizations([
PageObjects.dashboard.getTestVisualizationNames()[0],
]);
- await PageObjects.dashboard.saveDashboard(dashboardName, { storeTimeWithDashboard: false });
+ await PageObjects.dashboard.saveDashboard(dashboardName, {
+ storeTimeWithDashboard: false,
+ saveAsNew: true,
+ });
});
it('Does not set the time picker on open', async () => {
@@ -51,7 +54,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('is saved with time', async function () {
await PageObjects.dashboard.switchToEditMode();
await PageObjects.timePicker.setDefaultAbsoluteRange();
- await PageObjects.dashboard.saveDashboard(dashboardName, { storeTimeWithDashboard: true });
+ await PageObjects.dashboard.saveDashboard(dashboardName, {
+ storeTimeWithDashboard: true,
+ saveAsNew: false,
+ });
});
it('sets time on open', async function () {
diff --git a/test/functional/apps/dashboard/group5/legacy_urls.ts b/test/functional/apps/dashboard/group5/legacy_urls.ts
index 03dabfe87ba2f..0d09ba7a7ca79 100644
--- a/test/functional/apps/dashboard/group5/legacy_urls.ts
+++ b/test/functional/apps/dashboard/group5/legacy_urls.ts
@@ -41,7 +41,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.dashboard.navigateToApp();
await PageObjects.dashboard.clickNewDashboard();
await dashboardAddPanel.addVisualization('Rendering-Test:-animal-sounds-pie');
- await PageObjects.dashboard.saveDashboard('legacyTest', { waitDialogIsClosed: true });
+ await PageObjects.dashboard.saveDashboard('legacyTest', {
+ waitDialogIsClosed: true,
+ saveAsNew: true,
+ });
await PageObjects.header.waitUntilLoadingHasFinished();
const currentUrl = await browser.getCurrentUrl();
await log.debug(`Current url is ${currentUrl}`);
diff --git a/test/functional/apps/dashboard/group6/view_edit.ts b/test/functional/apps/dashboard/group6/view_edit.ts
index 1d4f2482cc9c0..93748e07e2536 100644
--- a/test/functional/apps/dashboard/group6/view_edit.ts
+++ b/test/functional/apps/dashboard/group6/view_edit.ts
@@ -63,12 +63,24 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
expect(isInViewMode).to.be(false);
});
+ describe('save as new', () => {
+ it('keeps duplicated dashboard in edit mode', async () => {
+ await PageObjects.dashboard.gotoDashboardEditMode(dashboardName);
+ await PageObjects.dashboard.duplicateDashboard('edit');
+ const isViewMode = await PageObjects.dashboard.getIsInViewMode();
+ expect(isViewMode).to.equal(false);
+ });
+ });
+
describe('save', function () {
- it('auto exits out of edit mode', async function () {
+ it('keeps dashboard in edit mode', async function () {
await PageObjects.dashboard.gotoDashboardEditMode(dashboardName);
- await PageObjects.dashboard.saveDashboard(dashboardName);
+ await PageObjects.dashboard.saveDashboard(dashboardName, {
+ storeTimeWithDashboard: true,
+ saveAsNew: false,
+ });
const isViewMode = await PageObjects.dashboard.getIsInViewMode();
- expect(isViewMode).to.equal(true);
+ expect(isViewMode).to.equal(false);
});
});
@@ -85,6 +97,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.dashboard.saveDashboard(dashboardName, {
storeTimeWithDashboard: true,
+ saveAsNew: false,
});
await PageObjects.timePicker.setAbsoluteRange(
@@ -170,7 +183,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
'Sep 19, 2013 @ 06:31:44.000',
'Sep 19, 2013 @ 06:31:44.000'
);
- await PageObjects.dashboard.saveDashboard(dashboardName);
+ await PageObjects.dashboard.saveDashboard(dashboardName, { saveAsNew: false });
await PageObjects.dashboard.switchToEditMode();
await PageObjects.timePicker.setAbsoluteRange(
'Sep 19, 2015 @ 06:31:44.000',
@@ -180,6 +193,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.common.clickCancelOnModal();
await PageObjects.dashboard.saveDashboard(dashboardName, {
+ saveAsNew: false,
storeTimeWithDashboard: true,
});
@@ -197,8 +211,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('when time changed is stored with dashboard', async function () {
await PageObjects.dashboard.gotoDashboardEditMode(dashboardName);
await PageObjects.timePicker.setDefaultDataRange();
- await PageObjects.dashboard.saveDashboard(dashboardName);
- await PageObjects.dashboard.switchToEditMode();
+ await PageObjects.dashboard.saveDashboard(dashboardName, { saveAsNew: false });
await PageObjects.timePicker.setAbsoluteRange(
'Sep 19, 2013 @ 06:31:44.000',
'Sep 19, 2013 @ 06:31:44.000'
@@ -208,7 +221,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.dashboard.clickCancelOutOfEditMode(false);
await PageObjects.common.clickCancelOnModal();
- await PageObjects.dashboard.saveDashboard(dashboardName, { storeTimeWithDashboard: true });
+ await PageObjects.dashboard.saveDashboard(dashboardName, {
+ storeTimeWithDashboard: true,
+ saveAsNew: false,
+ });
await PageObjects.dashboard.loadSavedDashboard(dashboardName);
@@ -222,7 +238,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
describe('Does not show lose changes warning', function () {
it('when time changed is not stored with dashboard', async function () {
await PageObjects.dashboard.gotoDashboardEditMode(dashboardName);
- await PageObjects.dashboard.saveDashboard(dashboardName, { storeTimeWithDashboard: false });
+ await PageObjects.dashboard.saveDashboard(dashboardName, {
+ storeTimeWithDashboard: false,
+ saveAsNew: false,
+ });
await PageObjects.timePicker.setAbsoluteRange(
'Oct 19, 2014 @ 06:31:44.000',
'Dec 19, 2014 @ 06:31:44.000'
diff --git a/test/functional/apps/dashboard_elements/controls/common/control_group_apply_button.ts b/test/functional/apps/dashboard_elements/controls/common/control_group_apply_button.ts
index 40e75ac70ff09..9f5862c5fbbcd 100644
--- a/test/functional/apps/dashboard_elements/controls/common/control_group_apply_button.ts
+++ b/test/functional/apps/dashboard_elements/controls/common/control_group_apply_button.ts
@@ -37,7 +37,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await dashboardAddPanel.addVisualization('Rendering-Test:-animal-sounds-pie');
// save the dashboard before adding controls
- await dashboard.saveDashboard('Test Control Group Apply Button', { exitFromEditMode: false });
+ await dashboard.saveDashboard('Test Control Group Apply Button', {
+ exitFromEditMode: false,
+ saveAsNew: true,
+ });
await header.waitUntilLoadingHasFinished();
await dashboard.waitForRenderComplete();
await dashboard.expectMissingUnsavedChangesBadge();
diff --git a/test/functional/apps/dashboard_elements/controls/common/range_slider.ts b/test/functional/apps/dashboard_elements/controls/common/range_slider.ts
index 8819f143a3dc7..06e67b9d8df91 100644
--- a/test/functional/apps/dashboard_elements/controls/common/range_slider.ts
+++ b/test/functional/apps/dashboard_elements/controls/common/range_slider.ts
@@ -57,7 +57,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await dashboard.preserveCrossAppState();
await dashboard.gotoDashboardLandingPage();
await dashboard.clickNewDashboard();
- await dashboard.saveDashboard(DASHBOARD_NAME, { exitFromEditMode: false });
+ await dashboard.saveDashboard(DASHBOARD_NAME, {
+ exitFromEditMode: false,
+ saveAsNew: true,
+ });
});
after(async () => {
diff --git a/test/functional/apps/dashboard_elements/controls/common/replace_controls.ts b/test/functional/apps/dashboard_elements/controls/common/replace_controls.ts
index 974f5e942d42a..e29b53c95d4d0 100644
--- a/test/functional/apps/dashboard_elements/controls/common/replace_controls.ts
+++ b/test/functional/apps/dashboard_elements/controls/common/replace_controls.ts
@@ -56,7 +56,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await dashboard.gotoDashboardLandingPage();
await dashboard.clickNewDashboard();
await timePicker.setDefaultDataRange();
- await dashboard.saveDashboard(DASHBOARD_NAME, { exitFromEditMode: false });
+ await dashboard.saveDashboard(DASHBOARD_NAME, {
+ exitFromEditMode: false,
+ saveAsNew: true,
+ });
});
after(async () => {
diff --git a/test/functional/apps/dashboard_elements/controls/common/time_slider.ts b/test/functional/apps/dashboard_elements/controls/common/time_slider.ts
index c860af183d64e..32f6e39e6b3c2 100644
--- a/test/functional/apps/dashboard_elements/controls/common/time_slider.ts
+++ b/test/functional/apps/dashboard_elements/controls/common/time_slider.ts
@@ -62,7 +62,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
'Oct 22, 2018 @ 00:00:00.000',
'Dec 3, 2018 @ 00:00:00.000'
);
- await dashboard.saveDashboard('test time slider control', { exitFromEditMode: false });
+ await dashboard.saveDashboard('test time slider control', {
+ exitFromEditMode: false,
+ saveAsNew: true,
+ });
});
it('can create a new time slider control from a blank state', async () => {
diff --git a/test/functional/apps/dashboard_elements/controls/options_list/index.ts b/test/functional/apps/dashboard_elements/controls/options_list/index.ts
index 966dbd91b7705..5f589129ed279 100644
--- a/test/functional/apps/dashboard_elements/controls/options_list/index.ts
+++ b/test/functional/apps/dashboard_elements/controls/options_list/index.ts
@@ -35,6 +35,7 @@ export default function ({ loadTestFile, getService, getPageObjects }: FtrProvid
await timePicker.setDefaultDataRange();
await elasticChart.setNewChartUiDebugFlag();
await dashboard.saveDashboard(OPTIONS_LIST_DASHBOARD_NAME, {
+ saveAsNew: true,
exitFromEditMode: false,
storeTimeWithDashboard: true,
});
diff --git a/test/functional/apps/dashboard_elements/links/links_create_edit.ts b/test/functional/apps/dashboard_elements/links/links_create_edit.ts
index ac68b2c00be8c..97e78ca2fb0a4 100644
--- a/test/functional/apps/dashboard_elements/links/links_create_edit.ts
+++ b/test/functional/apps/dashboard_elements/links/links_create_edit.ts
@@ -44,7 +44,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await dashboard.preserveCrossAppState();
await dashboard.gotoDashboardLandingPage();
await dashboard.clickNewDashboard();
- await dashboard.saveDashboard(DASHBOARD_NAME, { exitFromEditMode: false });
+ await dashboard.saveDashboard(DASHBOARD_NAME, {
+ exitFromEditMode: false,
+ saveAsNew: true,
+ });
await dashboard.loadSavedDashboard(DASHBOARD_NAME);
await dashboard.switchToEditMode();
});
diff --git a/test/functional/apps/discover/embeddable/_saved_search_embeddable.ts b/test/functional/apps/discover/embeddable/_saved_search_embeddable.ts
index b370141f69728..befce148bdf81 100644
--- a/test/functional/apps/discover/embeddable/_saved_search_embeddable.ts
+++ b/test/functional/apps/discover/embeddable/_saved_search_embeddable.ts
@@ -68,6 +68,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await dataGrid.checkCurrentRowsPerPageToBe(100);
await PageObjects.dashboard.saveDashboard(dashboardName, {
+ saveAsNew: true,
waitDialogIsClosed: true,
exitFromEditMode: false,
});
@@ -78,7 +79,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await dataGrid.changeRowsPerPageTo(10);
- await PageObjects.dashboard.saveDashboard(dashboardName);
+ await PageObjects.dashboard.saveDashboard(dashboardName, { saveAsNew: false });
await refreshDashboardPage();
await dataGrid.checkCurrentRowsPerPageToBe(10);
diff --git a/test/functional/page_objects/dashboard_page.ts b/test/functional/page_objects/dashboard_page.ts
index 66ce19c3d6d4f..408054a5c6114 100644
--- a/test/functional/page_objects/dashboard_page.ts
+++ b/test/functional/page_objects/dashboard_page.ts
@@ -229,9 +229,20 @@ export class DashboardPageObject extends FtrService {
await this.expectExistsDashboardLandingPage();
}
- public async clickClone() {
- this.log.debug('Clicking clone');
- await this.testSubjects.click('dashboardClone');
+ public async duplicateDashboard(dashboardNameOverride?: string) {
+ this.log.debug('Clicking duplicate');
+
+ await this.testSubjects.click('dashboardInteractiveSaveMenuItem');
+
+ if (dashboardNameOverride) {
+ this.log.debug('entering dashboard duplicate override title');
+ await this.testSubjects.setValue('savedObjectTitle', dashboardNameOverride);
+ }
+
+ await this.clickSave();
+
+ // Confirm that the Dashboard has actually been saved
+ await this.testSubjects.existOrFail('saveDashboardSuccess');
}
/**
@@ -240,9 +251,9 @@ export class DashboardPageObject extends FtrService {
*/
public async expectDuplicateTitleWarningDisplayed({ displayed = true }) {
if (displayed) {
- await this.testSubjects.existOrFail('titleDupicateWarnMsg');
+ await this.testSubjects.existOrFail('titleDuplicateWarnMsg');
} else {
- await this.testSubjects.missingOrFail('titleDupicateWarnMsg');
+ await this.testSubjects.missingOrFail('titleDuplicateWarnMsg');
}
}
@@ -460,19 +471,62 @@ export class DashboardPageObject extends FtrService {
}
/**
- * Save the current dashboard with the specified name and options and
+ * @description opens the dashboard settings flyout to modify an existing dashboard
+ */
+ public async modifyExistingDashboardDetails(
+ dashboard: string,
+ saveOptions: Pick = {}
+ ) {
+ await this.openSettingsFlyout();
+
+ await this.retry.try(async () => {
+ this.log.debug('entering new title');
+ await this.testSubjects.setValue('dashboardTitleInput', dashboard);
+
+ if (saveOptions.storeTimeWithDashboard !== undefined) {
+ await this.setStoreTimeWithDashboard(saveOptions.storeTimeWithDashboard);
+ }
+
+ if (saveOptions.tags) {
+ const tagsComboBox = await this.testSubjects.find('comboBoxInput');
+ for (const tagName of saveOptions.tags) {
+ await this.comboBox.setElement(tagsComboBox, tagName);
+ }
+ }
+
+ this.log.debug('DashboardPage.applyCustomization');
+ await this.testSubjects.click('applyCustomizeDashboardButton');
+
+ if (saveOptions.needsConfirm) {
+ await this.ensureDuplicateTitleCallout();
+ await this.testSubjects.click('applyCustomizeDashboardButton');
+ }
+
+ this.log.debug('isCustomizeDashboardLoadingIndicatorVisible');
+ return await this.testSubjects.exists('dashboardUnsavedChangesBadge', { timeout: 1500 });
+ });
+ }
+
+ /**
+ * @description Save the current dashboard with the specified name and options and
* verify that the save was successful, close the toast and return the
* toast message
- *
- * @param dashboardName {String}
- * @param saveOptions {{storeTimeWithDashboard: boolean, saveAsNew: boolean, needsConfirm: false, waitDialogIsClosed: boolean }}
*/
public async saveDashboard(
dashboardName: string,
- saveOptions: SaveDashboardOptions = { waitDialogIsClosed: true, exitFromEditMode: true }
+ saveOptions: SaveDashboardOptions = {
+ waitDialogIsClosed: true,
+ exitFromEditMode: true,
+ saveAsNew: true,
+ }
) {
await this.retry.try(async () => {
- await this.enterDashboardTitleAndClickSave(dashboardName, saveOptions);
+ if (saveOptions.saveAsNew) {
+ await this.enterDashboardSaveModalApplyUpdatesAndClickSave(dashboardName, saveOptions);
+ } else {
+ await this.modifyExistingDashboardDetails(dashboardName, saveOptions);
+ await this.clickQuickSave();
+ }
if (saveOptions.needsConfirm) {
await this.ensureDuplicateTitleCallout();
@@ -482,9 +536,14 @@ export class DashboardPageObject extends FtrService {
// Confirm that the Dashboard has actually been saved
await this.testSubjects.existOrFail('saveDashboardSuccess');
});
- const message = await this.toasts.getTitleAndDismiss();
- await this.header.waitUntilLoadingHasFinished();
- await this.common.waitForSaveModalToClose();
+
+ let message;
+
+ if (saveOptions.saveAsNew) {
+ message = await this.toasts.getTitleAndDismiss();
+ await this.header.waitUntilLoadingHasFinished();
+ await this.common.waitForSaveModalToClose();
+ }
const isInViewMode = await this.testSubjects.exists('dashboardEditMode');
if (saveOptions.exitFromEditMode && !isInViewMode) {
@@ -506,20 +565,20 @@ export class DashboardPageObject extends FtrService {
}
/**
- *
- * @param dashboardTitle {String}
- * @param saveOptions {{storeTimeWithDashboard: boolean, saveAsNew: boolean, waitDialogIsClosed: boolean}}
+ * @description populates the duplicate dashboard modal
*/
- public async enterDashboardTitleAndClickSave(
+ public async enterDashboardSaveModalApplyUpdatesAndClickSave(
dashboardTitle: string,
- saveOptions: SaveDashboardOptions = { waitDialogIsClosed: true }
+ saveOptions: Omit = { waitDialogIsClosed: true }
) {
const isSaveModalOpen = await this.testSubjects.exists('savedObjectSaveModal', {
timeout: 2000,
});
+
if (!isSaveModalOpen) {
- await this.testSubjects.click('dashboardSaveMenuItem');
+ await this.testSubjects.click('dashboardInteractiveSaveMenuItem');
}
+
const modalDialog = await this.testSubjects.find('savedObjectSaveModal');
this.log.debug('entering new title');
@@ -529,11 +588,6 @@ export class DashboardPageObject extends FtrService {
await this.setStoreTimeWithDashboard(saveOptions.storeTimeWithDashboard);
}
- const saveAsNewCheckboxExists = await this.testSubjects.exists('saveAsNewCheckbox');
- if (saveAsNewCheckboxExists) {
- await this.setSaveAsNewCheckBox(Boolean(saveOptions.saveAsNew));
- }
-
if (saveOptions.tags) {
await this.selectDashboardTags(saveOptions.tags);
}
@@ -545,7 +599,7 @@ export class DashboardPageObject extends FtrService {
}
public async ensureDuplicateTitleCallout() {
- await this.testSubjects.existOrFail('titleDupicateWarnMsg');
+ await this.testSubjects.existOrFail('titleDuplicateWarnMsg');
}
public async selectDashboardTags(tagNames: string[]) {
@@ -560,7 +614,7 @@ export class DashboardPageObject extends FtrService {
* @param dashboardTitle {String}
*/
public async enterDashboardTitleAndPressEnter(dashboardTitle: string) {
- await this.testSubjects.click('dashboardSaveMenuItem');
+ await this.testSubjects.click('dashboardInteractiveSaveMenuItem');
const modalDialog = await this.testSubjects.find('savedObjectSaveModal');
this.log.debug('entering new title');
@@ -745,7 +799,7 @@ export class DashboardPageObject extends FtrService {
}
public async expectMissingSaveOption() {
- await this.testSubjects.missingOrFail('dashboardSaveMenuItem');
+ await this.testSubjects.missingOrFail('dashboardInteractiveSaveMenuItem');
}
public async expectMissingQuickSaveOption() {
diff --git a/x-pack/performance/journeys_e2e/dashboard_listing_page.ts b/x-pack/performance/journeys_e2e/dashboard_listing_page.ts
index bad94790b2805..34e9d8a34927a 100644
--- a/x-pack/performance/journeys_e2e/dashboard_listing_page.ts
+++ b/x-pack/performance/journeys_e2e/dashboard_listing_page.ts
@@ -36,9 +36,9 @@ export const journey = new Journey({
await kibanaPage.waitForListViewTable();
await deletedDashboard.waitFor({ state: 'detached' });
})
- .step('Add dashboard', async ({ page, inputDelays }) => {
+ .step('Add dashboard', async ({ page, inputDelays }) => {
await page.click(subj('newItemButton'));
- await page.click(subj('dashboardSaveMenuItem'));
+ await page.click(subj('dashboardInteractiveSaveMenuItem'));
await page.type(subj('savedObjectTitle'), `foobar dashboard ${uuidv4()}`, {
delay: inputDelays.TYPING,
});
diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json
index f68a59f484638..8c5b395bdd3f3 100644
--- a/x-pack/plugins/translations/translations/fr-FR.json
+++ b/x-pack/plugins/translations/translations/fr-FR.json
@@ -1313,16 +1313,16 @@
"dashboard.topNav.saveModal.storeTimeWithDashboardFormRowHelpText": "Le filtre temporel est défini sur l’option sélectionnée chaque fois que ce tableau de bord est chargé.",
"dashboard.topNav.saveModal.storeTimeWithDashboardFormRowLabel": "Enregistrer la plage temporelle avec le tableau de bord",
"dashboard.topNave.cancelButtonAriaLabel": "Basculer en mode Affichage",
- "dashboard.topNave.cloneButtonAriaLabel": "cloner",
- "dashboard.topNave.cloneConfigDescription": "Créer une copie du tableau de bord",
+ "dashboard.topNave.viewModeInteractiveSaveButtonAriaLabel": "cloner",
+ "dashboard.topNave.viewModeInteractiveSaveConfigDescription": "Créer une copie du tableau de bord",
"dashboard.topNave.editButtonAriaLabel": "modifier",
"dashboard.topNave.editConfigDescription": "Basculer en mode Édition",
"dashboard.topNave.fullScreenButtonAriaLabel": "plein écran",
"dashboard.topNave.fullScreenConfigDescription": "Mode Plein écran",
"dashboard.topNave.resetChangesButtonAriaLabel": "Réinitialiser",
"dashboard.topNave.resetChangesConfigDescription": "Réinitialiser les modifications apportées au tableau de bord",
- "dashboard.topNave.saveAsButtonAriaLabel": "enregistrer sous",
- "dashboard.topNave.saveAsConfigDescription": "Enregistrer en tant que nouveau tableau de bord",
+ "dashboard.topNave.editModeInteractiveSaveButtonAriaLabel": "enregistrer sous",
+ "dashboard.topNave.editModeInteractiveSaveConfigDescription": "Enregistrer en tant que nouveau tableau de bord",
"dashboard.topNave.saveButtonAriaLabel": "enregistrer",
"dashboard.topNave.saveConfigDescription": "Enregistrer le tableau de bord sans invite de confirmation",
"dashboard.topNave.settingsButtonAriaLabel": "les paramètres d'index suivants déclassés ?",
diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json
index e7d393cd5595c..48a3eefcb30ec 100644
--- a/x-pack/plugins/translations/translations/ja-JP.json
+++ b/x-pack/plugins/translations/translations/ja-JP.json
@@ -1313,16 +1313,16 @@
"dashboard.topNav.saveModal.storeTimeWithDashboardFormRowHelpText": "有効化すると、ダッシュボードが読み込まれるごとに現在選択された時刻の時間フィルターが変更されます。",
"dashboard.topNav.saveModal.storeTimeWithDashboardFormRowLabel": "ダッシュボードに時刻を保存",
"dashboard.topNave.cancelButtonAriaLabel": "表示モードに切り替える",
- "dashboard.topNave.cloneButtonAriaLabel": "クローンを作成",
- "dashboard.topNave.cloneConfigDescription": "ダッシュボードのコピーを作成します",
+ "dashboard.topNave.viewModeInteractiveSaveButtonAriaLabel": "クローンを作成",
+ "dashboard.topNave.viewModeInteractiveSaveConfigDescription": "ダッシュボードのコピーを作成します",
"dashboard.topNave.editButtonAriaLabel": "編集",
"dashboard.topNave.editConfigDescription": "編集モードに切り替えます",
"dashboard.topNave.fullScreenButtonAriaLabel": "全画面",
"dashboard.topNave.fullScreenConfigDescription": "全画面モード",
"dashboard.topNave.resetChangesButtonAriaLabel": "リセット",
"dashboard.topNave.resetChangesConfigDescription": "ダッシュボードの変更をリセット",
- "dashboard.topNave.saveAsButtonAriaLabel": "名前を付けて保存",
- "dashboard.topNave.saveAsConfigDescription": "新しいダッシュボードとして保存",
+ "dashboard.topNave.editModeInteractiveSaveButtonAriaLabel": "名前を付けて保存",
+ "dashboard.topNave.editModeInteractiveSaveConfigDescription": "新しいダッシュボードとして保存",
"dashboard.topNave.saveButtonAriaLabel": "保存",
"dashboard.topNave.saveConfigDescription": "プロンプトを表示せずにダッシュボードをクイック保存",
"dashboard.topNave.settingsButtonAriaLabel": "設定",
diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json
index 10435bf1bdfc8..abaaacf435a14 100644
--- a/x-pack/plugins/translations/translations/zh-CN.json
+++ b/x-pack/plugins/translations/translations/zh-CN.json
@@ -1315,16 +1315,16 @@
"dashboard.topNav.saveModal.storeTimeWithDashboardFormRowHelpText": "每次加载此仪表板时,都会将时间筛选更改为当前选定的时间。",
"dashboard.topNav.saveModal.storeTimeWithDashboardFormRowLabel": "将时间随仪表板保存",
"dashboard.topNave.cancelButtonAriaLabel": "切换到查看模式",
- "dashboard.topNave.cloneButtonAriaLabel": "克隆",
- "dashboard.topNave.cloneConfigDescription": "创建仪表板的副本",
+ "dashboard.topNave.viewModeInteractiveSaveButtonAriaLabel": "克隆",
+ "dashboard.topNave.viewModeInteractiveSaveConfigDescription": "创建仪表板的副本",
"dashboard.topNave.editButtonAriaLabel": "编辑",
"dashboard.topNave.editConfigDescription": "切换到编辑模式",
"dashboard.topNave.fullScreenButtonAriaLabel": "全屏",
"dashboard.topNave.fullScreenConfigDescription": "全屏模式",
"dashboard.topNave.resetChangesButtonAriaLabel": "重置",
"dashboard.topNave.resetChangesConfigDescription": "重置对仪表板所做的更改",
- "dashboard.topNave.saveAsButtonAriaLabel": "另存为",
- "dashboard.topNave.saveAsConfigDescription": "另存为新仪表板",
+ "dashboard.topNave.editModeInteractiveSaveButtonAriaLabel": "另存为",
+ "dashboard.topNave.editModeInteractiveSaveConfigDescription": "另存为新仪表板",
"dashboard.topNave.saveButtonAriaLabel": "保存",
"dashboard.topNave.saveConfigDescription": "没有任何提示,快速保存您的仪表板",
"dashboard.topNave.settingsButtonAriaLabel": "设置",
diff --git a/x-pack/test/accessibility/apps/group1/dashboard_links.ts b/x-pack/test/accessibility/apps/group1/dashboard_links.ts
index 5e5d00dd34b94..3ec6df1b880ca 100644
--- a/x-pack/test/accessibility/apps/group1/dashboard_links.ts
+++ b/x-pack/test/accessibility/apps/group1/dashboard_links.ts
@@ -32,7 +32,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await common.navigateToApp('dashboard');
await dashboard.gotoDashboardLandingPage();
await dashboard.clickNewDashboard();
- await dashboard.saveDashboard(DASHBOARD_NAME, { exitFromEditMode: false });
+ await dashboard.saveDashboard(DASHBOARD_NAME, {
+ exitFromEditMode: false,
+ saveAsNew: true,
+ });
});
after(async () => {
diff --git a/x-pack/test/functional/apps/dashboard/group1/created_by.ts b/x-pack/test/functional/apps/dashboard/group1/created_by.ts
index 00c280f28f96d..ed3798e1b8809 100644
--- a/x-pack/test/functional/apps/dashboard/group1/created_by.ts
+++ b/x-pack/test/functional/apps/dashboard/group1/created_by.ts
@@ -76,6 +76,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
await PageObjects.dashboard.preserveCrossAppState();
await PageObjects.dashboard.clickNewDashboard();
await PageObjects.dashboard.saveDashboard(DASHBOARD_NAME, {
+ saveAsNew: true,
waitDialogIsClosed: false,
exitFromEditMode: false,
});
diff --git a/x-pack/test/functional/apps/dashboard/group3/drilldowns/explore_data_panel_action.ts b/x-pack/test/functional/apps/dashboard/group3/drilldowns/explore_data_panel_action.ts
index ccf738af3825d..cb73963a68e97 100644
--- a/x-pack/test/functional/apps/dashboard/group3/drilldowns/explore_data_panel_action.ts
+++ b/x-pack/test/functional/apps/dashboard/group3/drilldowns/explore_data_panel_action.ts
@@ -48,7 +48,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await panelActions.customizePanel();
await dashboardCustomizePanel.disableCustomTimeRange();
await dashboardCustomizePanel.clickSaveButton();
- await dashboard.saveDashboard('Dashboard with Pie Chart');
+ await dashboard.saveDashboard('Dashboard with Pie Chart', {
+ saveAsNew: false,
+ exitFromEditMode: true,
+ });
});
it('action exists in panel context menu', async () => {
@@ -85,7 +88,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await dashboardCustomizePanel.clickCommonlyUsedTimeRange('Last_90 days');
await dashboardCustomizePanel.clickSaveButton();
- await dashboard.saveDashboard('Dashboard with Pie Chart');
+ await dashboard.saveDashboard('Dashboard with Pie Chart', {
+ saveAsNew: false,
+ exitFromEditMode: true,
+ });
await panelActions.openContextMenu();
await testSubjects.clickWhenNotDisabledWithoutRetry(ACTION_TEST_SUBJ);
diff --git a/x-pack/test/functional/apps/discover/saved_search_embeddable.ts b/x-pack/test/functional/apps/discover/saved_search_embeddable.ts
index fd546315a1fd9..3f3f58dcdaf16 100644
--- a/x-pack/test/functional/apps/discover/saved_search_embeddable.ts
+++ b/x-pack/test/functional/apps/discover/saved_search_embeddable.ts
@@ -93,6 +93,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.dashboard.saveDashboard('Dashboard with deleted saved search', {
waitDialogIsClosed: true,
exitFromEditMode: false,
+ saveAsNew: true,
});
await kibanaServer.savedObjects.delete({
type: 'search',
diff --git a/x-pack/test/functional/apps/lens/group4/show_underlying_data_dashboard.ts b/x-pack/test/functional/apps/lens/group4/show_underlying_data_dashboard.ts
index 761278e69025c..965474919e6fa 100644
--- a/x-pack/test/functional/apps/lens/group4/show_underlying_data_dashboard.ts
+++ b/x-pack/test/functional/apps/lens/group4/show_underlying_data_dashboard.ts
@@ -36,6 +36,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.lens.save('Embedded Visualization', true, false, false, 'new');
await PageObjects.dashboard.saveDashboard(`Open in Discover Testing ${uuidv4()}`, {
+ saveAsNew: true,
exitFromEditMode: true,
});
@@ -68,6 +69,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.lens.save('Embedded Visualization', false);
await PageObjects.dashboard.saveDashboard(`Open in Discover Testing ${uuidv4()}`, {
+ saveAsNew: false,
exitFromEditMode: true,
});
diff --git a/x-pack/test/functional/apps/managed_content/managed_content.ts b/x-pack/test/functional/apps/managed_content/managed_content.ts
index 8f2ff247709cd..1bee3acd761bb 100644
--- a/x-pack/test/functional/apps/managed_content/managed_content.ts
+++ b/x-pack/test/functional/apps/managed_content/managed_content.ts
@@ -159,7 +159,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
await PageObjects.dashboard.waitForRenderComplete();
- await PageObjects.dashboard.clickClone();
+ await PageObjects.dashboard.duplicateDashboard();
await PageObjects.dashboard.waitForRenderComplete();
diff --git a/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_grid_in_dashboard.ts b/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_grid_in_dashboard.ts
index 3f7e726543485..76f1f0fcd5584 100644
--- a/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_grid_in_dashboard.ts
+++ b/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_grid_in_dashboard.ts
@@ -106,7 +106,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.assertFieldStatsTableNotExists();
- await PageObjects.dashboard.saveDashboard(dashboardTitle);
+ await PageObjects.dashboard.saveDashboard(dashboardTitle, { saveAsNew: false });
});
});
}
diff --git a/x-pack/test/saved_object_tagging/functional/tests/dashboard_integration.ts b/x-pack/test/saved_object_tagging/functional/tests/dashboard_integration.ts
index 18be683db1d05..5a4a71c6abb2d 100644
--- a/x-pack/test/saved_object_tagging/functional/tests/dashboard_integration.ts
+++ b/x-pack/test/saved_object_tagging/functional/tests/dashboard_integration.ts
@@ -85,6 +85,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
await PageObjects.dashboard.clickNewDashboard();
await PageObjects.dashboard.saveDashboard('my-new-dashboard', {
+ saveAsNew: true,
waitDialogIsClosed: true,
tags: ['tag-1', 'tag-3'],
});
@@ -102,7 +103,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
await PageObjects.dashboard.clickNewDashboard();
- await testSubjects.click('dashboardSaveMenuItem');
+ await testSubjects.click('dashboardInteractiveSaveMenuItem');
await testSubjects.setValue('savedObjectTitle', 'dashboard-with-new-tag');
await testSubjects.click('savedObjectTagSelector');
@@ -148,6 +149,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
await PageObjects.dashboard.switchToEditMode();
await PageObjects.dashboard.saveDashboard('dashboard 4 with real data (tag-1)', {
+ saveAsNew: false,
waitDialogIsClosed: true,
tags: ['tag-3'],
});
diff --git a/x-pack/test_serverless/functional/test_suites/common/discover/embeddable/_saved_search_embeddable.ts b/x-pack/test_serverless/functional/test_suites/common/discover/embeddable/_saved_search_embeddable.ts
index 2cd16b00feb6a..84d67386a7555 100644
--- a/x-pack/test_serverless/functional/test_suites/common/discover/embeddable/_saved_search_embeddable.ts
+++ b/x-pack/test_serverless/functional/test_suites/common/discover/embeddable/_saved_search_embeddable.ts
@@ -81,6 +81,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.dashboard.saveDashboard(dashboardName, {
waitDialogIsClosed: true,
exitFromEditMode: false,
+ saveAsNew: true,
});
await refreshDashboardPage();
@@ -89,7 +90,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await dataGrid.changeRowsPerPageTo(10);
- await PageObjects.dashboard.saveDashboard(dashboardName);
+ await PageObjects.dashboard.saveDashboard(dashboardName, { saveAsNew: false });
await refreshDashboardPage();
await dataGrid.checkCurrentRowsPerPageToBe(10);