[Dashboard] Redesign clone experience (#159752)

## Summary

Closes #154500. 
Closes https://github.com/elastic/kibana/issues/114206.

This updates the UX around cloning dashboards. I removed the clone
confirm model, so cloning a dashboard is just a one click action now.
This aligns with how other apps like ML handle cloning. I've also made
the dashboard title breadcrumb a button in edit mode that opens the
dashboard settings flyout for better discoverability.


4f5ea117-a5e4-4ec5-9113-8b09fd8c84a1

I also changed the pattern for cloned dashboard title from `Dashboard
Title Copy` to `Dashboard Title (#)`.
<img width="1226" alt="Screenshot 2023-06-30 at 1 03 35 PM"
src="b50ba5c6-dc95-4aab-a320-b1a78b74c1b6">
This commit is contained in:
Catherine Liu 2023-06-30 20:45:39 -07:00 committed by GitHub
parent a25506c842
commit 938716e58a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 100 additions and 507 deletions

View file

@ -17,7 +17,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
describe('dashboard clone', function describeIndexTests() {
const dashboardName = 'Dashboard Clone Test';
const clonedDashboardName = dashboardName + ' Copy';
const clonedDashboardName = dashboardName + ' (1)';
before(async function () {
return PageObjects.dashboard.initTests();
@ -31,7 +31,6 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.dashboard.saveDashboard(dashboardName);
await PageObjects.dashboard.clickClone();
await PageObjects.dashboard.confirmClone();
await PageObjects.dashboard.gotoDashboardLandingPage();
await listingTable.searchAndExpectItemsCount('dashboard', clonedDashboardName, 1);
});
@ -43,38 +42,5 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
expect(panelTitles).to.eql(PageObjects.dashboard.getTestVisualizationNames());
});
});
it('clone appends Copy to the dashboard title name', async () => {
await PageObjects.dashboard.loadSavedDashboard(dashboardName);
await PageObjects.dashboard.clickClone();
const title = await PageObjects.dashboard.getCloneTitle();
expect(title).to.be(clonedDashboardName);
});
it('and warns on duplicate name', async function () {
await PageObjects.dashboard.confirmClone();
await PageObjects.dashboard.expectDuplicateTitleWarningDisplayed({ displayed: true });
});
it("and doesn't save", async () => {
await PageObjects.dashboard.cancelClone();
await PageObjects.dashboard.gotoDashboardLandingPage();
await listingTable.searchAndExpectItemsCount('dashboard', dashboardName, 1);
});
it('Clones on confirm duplicate title warning', async function () {
await PageObjects.dashboard.loadSavedDashboard(dashboardName);
await PageObjects.dashboard.clickClone();
await PageObjects.dashboard.confirmClone();
await PageObjects.dashboard.expectDuplicateTitleWarningDisplayed({ displayed: true });
await PageObjects.dashboard.confirmClone();
await PageObjects.dashboard.waitForRenderComplete();
await PageObjects.dashboard.gotoDashboardLandingPage();
await listingTable.searchAndExpectItemsCount('dashboard', dashboardName + ' Copy', 2);
});
});
}

View file

@ -212,24 +212,6 @@ export class DashboardPageObject extends FtrService {
await this.testSubjects.click('dashboardClone');
}
public async getCloneTitle() {
return await this.testSubjects.getAttribute('clonedDashboardTitle', 'value');
}
public async confirmClone() {
this.log.debug('Confirming clone');
await this.testSubjects.click('cloneConfirmButton');
}
public async cancelClone() {
this.log.debug('Canceling clone');
await this.testSubjects.click('cloneCancelButton');
}
public async setClonedDashboardTitle(title: string) {
await this.testSubjects.setValue('clonedDashboardTitle', title);
}
/**
* Asserts that the duplicate title warning is either displayed or not displayed.
* @param { displayed: boolean }