Sync saved searches that don't have local modifications on a dashboard (#14452)

* Add tests to catch error

* Fix test

* Don't store column and sort state in panel uiState unless explicitly overridden in a dashboard.

* add debug messages

* Elements can go stale between the find by and the click event so wrap in a retry

* fix bad merge with master
This commit is contained in:
Stacey Gammon 2017-11-02 16:47:40 -04:00 committed by GitHub
parent 403f966d39
commit 92964ef45f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 49 additions and 36 deletions

View file

@ -34,36 +34,34 @@ export class SearchEmbeddableHandler extends EmbeddableHandler {
searchScope.panel = panel;
container.registerPanelIndexPattern(panel.panelIndex, savedObject.searchSource.get('index'));
// This causes changes to a saved search to be hidden, but also allows
// the user to locally modify and save changes to a saved search only in a dashboard.
// See https://github.com/elastic/kibana/issues/9523 for more details.
searchScope.panel = container.updatePanel(searchScope.panel.panelIndex, {
columns: searchScope.panel.columns || searchScope.savedObj.columns,
sort: searchScope.panel.sort || searchScope.savedObj.sort
});
// If there is column or sort data on the panel, that means the original columns or sort settings have
// been overridden in a dashboard.
searchScope.columns = searchScope.panel.columns || searchScope.savedObj.columns;
searchScope.sort = searchScope.panel.sort || searchScope.savedObj.sort;
const uiState = savedObject.uiStateJSON ? JSON.parse(savedObject.uiStateJSON) : {};
searchScope.uiState = container.createChildUistate(getPersistedStateId(panel), uiState);
searchScope.setSortOrder = function setSortOrder(columnName, direction) {
searchScope.panel = container.updatePanel(searchScope.panel.panelIndex, { sort: [columnName, direction] });
searchScope.sort = searchScope.panel.sort;
};
searchScope.addColumn = function addColumn(columnName) {
savedObject.searchSource.get('index').popularizeField(columnName, 1);
columnActions.addColumn(searchScope.panel.columns, columnName);
searchScope.panel = container.updatePanel(searchScope.panel.panelIndex, { columns: searchScope.panel.columns });
columnActions.addColumn(searchScope.columns, columnName);
searchScope.panel = container.updatePanel(searchScope.panel.panelIndex, { columns: searchScope.columns });
};
searchScope.removeColumn = function removeColumn(columnName) {
savedObject.searchSource.get('index').popularizeField(columnName, 1);
columnActions.removeColumn(searchScope.panel.columns, columnName);
searchScope.panel = container.updatePanel(searchScope.panel.panelIndex, { columns: searchScope.panel.columns });
columnActions.removeColumn(searchScope.columns, columnName);
searchScope.panel = container.updatePanel(searchScope.panel.panelIndex, { columns: searchScope.columns });
};
searchScope.moveColumn = function moveColumn(columnName, newIndex) {
columnActions.moveColumn(searchScope.panel.columns, columnName, newIndex);
searchScope.panel = container.updatePanel(searchScope.panel.panelIndex, { columns: searchScope.panel.columns });
columnActions.moveColumn(searchScope.columns, columnName, newIndex);
searchScope.panel = container.updatePanel(searchScope.panel.panelIndex, { columns: searchScope.columns });
};
searchScope.filter = function (field, value, operator) {

View file

@ -1,7 +1,7 @@
<doc-table
search-source="savedObj.searchSource"
sorting="panel.sort"
columns="panel.columns"
sorting="sort"
columns="columns"
data-shared-item
data-title="{{savedObj.title}}"
data-description="{{savedObj.description}}"

View file

@ -65,22 +65,39 @@ export default function ({ getService, getPageObjects }) {
});
});
it('Saved search with column changes will not update when the saved object changes', async () => {
await PageObjects.dashboard.gotoDashboardLandingPage();
await PageObjects.dashboard.clickNewDashboard();
it('Saved search with no changes will update when the saved object changes', async () => {
await PageObjects.header.clickDiscover();
await PageObjects.dashboard.setTimepickerInDataRange();
await PageObjects.discover.clickFieldListItemAdd('bytes');
await PageObjects.discover.saveSearch('my search');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.header.clickToastOK();
await PageObjects.header.clickDashboard();
await PageObjects.dashboard.clickNewDashboard();
await PageObjects.dashboard.addSavedSearch('my search');
await PageObjects.dashboard.saveDashboard('No local edits');
await PageObjects.header.clickToastOK();
await PageObjects.header.clickDiscover();
await PageObjects.discover.clickFieldListItemAdd('bytes');
await PageObjects.discover.clickFieldListItemAdd('agent');
await PageObjects.discover.saveSearch('my search');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.header.clickToastOK();
await PageObjects.header.clickDashboard();
await PageObjects.dashboard.addSavedSearch('my search');
await PageObjects.header.waitUntilLoadingHasFinished();
const headers = await PageObjects.discover.getColumnHeaders();
expect(headers.length).to.be(3);
expect(headers[1]).to.be('bytes');
expect(headers[2]).to.be('agent');
});
it('Saved search with column changes will not update when the saved object changes', async () => {
await PageObjects.discover.removeHeaderColumn('bytes');
await PageObjects.dashboard.clickEdit();
await PageObjects.dashboard.saveDashboard('Has local edits');
await PageObjects.header.clickToastOK();

View file

@ -262,15 +262,7 @@ export function DashboardPageProvider({ getService, getPageObjects }) {
await this.clickAddVisualization();
log.debug('filter visualization (' + vizName + ')');
await this.filterVizNames(vizName);
// this second wait is usually enough to avoid the
// 'stale element reference: element is not attached to the page document'
// on the next step
await PageObjects.common.sleep(1000);
// but wrap in a try loop since it can still happen
await retry.try(() => {
log.debug('click visualization (' + vizName + ')');
return this.clickVizNameLink(vizName);
});
await this.clickVizNameLink(vizName);
await PageObjects.header.clickToastOK();
// this second click of 'Add' collapses the Add Visualization pane
await this.clickAddVisualization();

View file

@ -129,20 +129,26 @@ export function FindProvider({ getService }) {
async clickByPartialLinkText(linkText, timeout = defaultFindTimeout) {
log.debug(`clickByPartialLinkText(${linkText})`);
const element = await retry.try(async () => await this.byPartialLinkText(linkText, timeout));
await element.click();
await retry.try(async () => {
const element = await this.byPartialLinkText(linkText, timeout);
await element.click();
});
}
async clickByLinkText(linkText, timeout = defaultFindTimeout) {
log.debug(`clickByLinkText(${linkText})`);
const element = await this.byLinkText(linkText, timeout);
await element.click();
await retry.try(async () => {
const element = await this.byLinkText(linkText, timeout);
await element.click();
});
}
async clickByCssSelector(selector, timeout = defaultFindTimeout) {
log.debug(`clickByCssSelector(${selector})`);
const element = await this.byCssSelector(selector, timeout);
await element.click();
await retry.try(async () => {
const element = await this.byCssSelector(selector, timeout);
await element.click();
});
}
}