mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
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:
parent
403f966d39
commit
92964ef45f
5 changed files with 49 additions and 36 deletions
|
@ -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) {
|
||||
|
|
|
@ -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}}"
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue