[8.11] [Saved Search] [Embeddable] Fix issue where Dashboard panel targeting deleted saved search can't be removed (#169896) (#169944)

# Backport

This will backport the following commits from `main` to `8.11`:
- [[Saved Search] [Embeddable] Fix issue where Dashboard panel targeting
deleted saved search can't be removed
(#169896)](https://github.com/elastic/kibana/pull/169896)

<!--- Backport version: 8.9.7 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Davis
McPhee","email":"davis.mcphee@elastic.co"},"sourceCommit":{"committedDate":"2023-10-26T14:05:19Z","message":"[Saved
Search] [Embeddable] Fix issue where Dashboard panel targeting deleted
saved search can't be removed (#169896)\n\n## Summary\r\n\r\nThis PR
fixes an issue where an undefined reference error makes it so\r\nthat
Dashboard panels targeting deleted saved searches cannot
be\r\nremoved.\r\n\r\nThe bug was likely introduced in 8.10 with
embeddable changes in\r\n#146849.\r\n\r\nFixes #169829.\r\n\r\n###
Checklist\r\n\r\n- [ ] Any text added follows [EUI's
writing\r\nguidelines](https://elastic.github.io/eui/#/guidelines/writing),
uses\r\nsentence case text and includes
[i18n\r\nsupport](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)\r\n-
[
]\r\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\r\nwas
added for features that require explanation or tutorials\r\n- [x] [Unit
or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common scenarios\r\n- [ ] Any UI
touched in this PR is usable by keyboard only (learn more\r\nabout
[keyboard accessibility](https://webaim.org/techniques/keyboard/))\r\n-
[ ] Any UI touched in this PR does not create any new axe
failures\r\n(run axe in
browser:\r\n[FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/),\r\n[Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))\r\n-
[ ] If a plugin configuration key changed, check if it needs to
be\r\nallowlisted in the cloud and added to the
[docker\r\nlist](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)\r\n-
[ ] This renders correctly on smaller devices using a
responsive\r\nlayout. (You can test this [in
your\r\nbrowser](https://www.browserstack.com/guide/responsive-testing-on-local-server))\r\n-
[ ] This was checked for
[cross-browser\r\ncompatibility](https://www.elastic.co/support/matrix#matrix_browsers)\r\n\r\n###
For maintainers\r\n\r\n- [ ] This was checked for breaking API changes
and was
[labeled\r\nappropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)","sha":"8c93e5c6ff31621c380aaa947e579b3cb196b613","branchLabelMapping":{"^v8.12.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:fix","Team:DataDiscovery","backport:prev-minor","v8.12.0"],"number":169896,"url":"https://github.com/elastic/kibana/pull/169896","mergeCommit":{"message":"[Saved
Search] [Embeddable] Fix issue where Dashboard panel targeting deleted
saved search can't be removed (#169896)\n\n## Summary\r\n\r\nThis PR
fixes an issue where an undefined reference error makes it so\r\nthat
Dashboard panels targeting deleted saved searches cannot
be\r\nremoved.\r\n\r\nThe bug was likely introduced in 8.10 with
embeddable changes in\r\n#146849.\r\n\r\nFixes #169829.\r\n\r\n###
Checklist\r\n\r\n- [ ] Any text added follows [EUI's
writing\r\nguidelines](https://elastic.github.io/eui/#/guidelines/writing),
uses\r\nsentence case text and includes
[i18n\r\nsupport](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)\r\n-
[
]\r\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\r\nwas
added for features that require explanation or tutorials\r\n- [x] [Unit
or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common scenarios\r\n- [ ] Any UI
touched in this PR is usable by keyboard only (learn more\r\nabout
[keyboard accessibility](https://webaim.org/techniques/keyboard/))\r\n-
[ ] Any UI touched in this PR does not create any new axe
failures\r\n(run axe in
browser:\r\n[FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/),\r\n[Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))\r\n-
[ ] If a plugin configuration key changed, check if it needs to
be\r\nallowlisted in the cloud and added to the
[docker\r\nlist](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)\r\n-
[ ] This renders correctly on smaller devices using a
responsive\r\nlayout. (You can test this [in
your\r\nbrowser](https://www.browserstack.com/guide/responsive-testing-on-local-server))\r\n-
[ ] This was checked for
[cross-browser\r\ncompatibility](https://www.elastic.co/support/matrix#matrix_browsers)\r\n\r\n###
For maintainers\r\n\r\n- [ ] This was checked for breaking API changes
and was
[labeled\r\nappropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)","sha":"8c93e5c6ff31621c380aaa947e579b3cb196b613"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v8.12.0","labelRegex":"^v8.12.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/169896","number":169896,"mergeCommit":{"message":"[Saved
Search] [Embeddable] Fix issue where Dashboard panel targeting deleted
saved search can't be removed (#169896)\n\n## Summary\r\n\r\nThis PR
fixes an issue where an undefined reference error makes it so\r\nthat
Dashboard panels targeting deleted saved searches cannot
be\r\nremoved.\r\n\r\nThe bug was likely introduced in 8.10 with
embeddable changes in\r\n#146849.\r\n\r\nFixes #169829.\r\n\r\n###
Checklist\r\n\r\n- [ ] Any text added follows [EUI's
writing\r\nguidelines](https://elastic.github.io/eui/#/guidelines/writing),
uses\r\nsentence case text and includes
[i18n\r\nsupport](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)\r\n-
[
]\r\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\r\nwas
added for features that require explanation or tutorials\r\n- [x] [Unit
or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common scenarios\r\n- [ ] Any UI
touched in this PR is usable by keyboard only (learn more\r\nabout
[keyboard accessibility](https://webaim.org/techniques/keyboard/))\r\n-
[ ] Any UI touched in this PR does not create any new axe
failures\r\n(run axe in
browser:\r\n[FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/),\r\n[Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))\r\n-
[ ] If a plugin configuration key changed, check if it needs to
be\r\nallowlisted in the cloud and added to the
[docker\r\nlist](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)\r\n-
[ ] This renders correctly on smaller devices using a
responsive\r\nlayout. (You can test this [in
your\r\nbrowser](https://www.browserstack.com/guide/responsive-testing-on-local-server))\r\n-
[ ] This was checked for
[cross-browser\r\ncompatibility](https://www.elastic.co/support/matrix#matrix_browsers)\r\n\r\n###
For maintainers\r\n\r\n- [ ] This was checked for breaking API changes
and was
[labeled\r\nappropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)","sha":"8c93e5c6ff31621c380aaa947e579b3cb196b613"}}]}]
BACKPORT-->

Co-authored-by: Davis McPhee <davis.mcphee@elastic.co>
This commit is contained in:
Kibana Machine 2023-10-26 12:10:24 -04:00 committed by GitHub
parent 95a1c0babc
commit 1638e2bd95
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 122 additions and 11 deletions

View file

@ -732,11 +732,7 @@ export class SavedSearchEmbeddable
}
}
public getSavedSearch(): SavedSearch {
if (!this.savedSearch) {
throw new Error('Saved search not defined');
}
public getSavedSearch(): SavedSearch | undefined {
return this.savedSearch;
}

View file

@ -22,7 +22,7 @@ export interface SearchOutput extends EmbeddableOutput {
}
export interface ISearchEmbeddable extends IEmbeddable<SearchInput, SearchOutput> {
getSavedSearch(): SavedSearch;
getSavedSearch(): SavedSearch | undefined;
hasTimeRange(): boolean;
}

View file

@ -82,7 +82,7 @@ describe('view saved search action', () => {
expect(discoverServiceMock.locator.navigate).toHaveBeenCalledWith(
getDiscoverLocatorParams({
input: embeddable.getInput(),
savedSearch: embeddable.getSavedSearch(),
savedSearch: embeddable.getSavedSearch()!,
})
);
});

View file

@ -33,9 +33,13 @@ export class ViewSavedSearchAction implements Action<ViewSearchContext> {
async execute(context: ActionExecutionContext<ViewSearchContext>): Promise<void> {
const embeddable = context.embeddable as SavedSearchEmbeddable;
const savedSearch = embeddable.getSavedSearch();
if (!savedSearch) {
return;
}
const locatorParams = getDiscoverLocatorParams({
input: embeddable.getInput(),
savedSearch: embeddable.getSavedSearch(),
savedSearch,
});
await this.locator.navigate(locatorParams);
}

View file

@ -104,7 +104,7 @@ export class ReportingCsvPanelAction implements ActionDefinition<ActionContext>
}
const savedSearch = embeddable.getSavedSearch();
const query = savedSearch.searchSource.getField('query');
const query = savedSearch?.searchSource.getField('query');
// using isOfAggregateQueryType(query) added increased the bundle size over the configured limit of 55.7KB
if (query && Boolean(query && 'sql' in query)) {
@ -121,11 +121,12 @@ export class ReportingCsvPanelAction implements ActionDefinition<ActionContext>
throw new IncompatibleActionError();
}
if (this.isDownloading) {
const savedSearch = embeddable.getSavedSearch();
if (!savedSearch || this.isDownloading) {
return;
}
const savedSearch = embeddable.getSavedSearch();
const { columns, getSearchSource } = await this.getSharingData(savedSearch);
const immediateJobParams = this.apiClient.getDecoratedJobParams({

View file

@ -19,5 +19,6 @@ export default function ({ loadTestFile }: FtrProviderContext) {
loadTestFile(require.resolve('./visualize_field'));
loadTestFile(require.resolve('./value_suggestions'));
loadTestFile(require.resolve('./value_suggestions_non_timebased'));
loadTestFile(require.resolve('./saved_search_embeddable'));
});
}

View file

@ -0,0 +1,109 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import expect from '@kbn/expect';
import { FtrProviderContext } from '../../ftr_provider_context';
export default function ({ getService, getPageObjects }: FtrProviderContext) {
const browser = getService('browser');
const dataGrid = getService('dataGrid');
const dashboardAddPanel = getService('dashboardAddPanel');
const dashboardPanelActions = getService('dashboardPanelActions');
const filterBar = getService('filterBar');
const esArchiver = getService('esArchiver');
const kibanaServer = getService('kibanaServer');
const testSubjects = getService('testSubjects');
const PageObjects = getPageObjects(['common', 'dashboard', 'header', 'timePicker', 'discover']);
describe('discover saved search embeddable', () => {
before(async () => {
await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional');
await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/dashboard/current/data');
await kibanaServer.savedObjects.cleanStandardList();
await kibanaServer.importExport.load(
'test/functional/fixtures/kbn_archiver/dashboard/current/kibana'
);
await kibanaServer.uiSettings.replace({
defaultIndex: '0bf35f60-3dc9-11e8-8660-4d65aa086b3c',
});
await PageObjects.common.setTime({
from: 'Sep 22, 2015 @ 00:00:00.000',
to: 'Sep 23, 2015 @ 00:00:00.000',
});
});
after(async () => {
await kibanaServer.savedObjects.cleanStandardList();
await PageObjects.common.unsetTime();
});
beforeEach(async () => {
await PageObjects.dashboard.navigateToApp();
await filterBar.ensureFieldEditorModalIsClosed();
await PageObjects.dashboard.gotoDashboardLandingPage();
await PageObjects.dashboard.clickNewDashboard();
});
const addSearchEmbeddableToDashboard = async (title = 'Rendering-Test:-saved-search') => {
await dashboardAddPanel.addSavedSearch(title);
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.dashboard.waitForRenderComplete();
const rows = await dataGrid.getDocTableRows();
expect(rows.length).to.be.above(0);
};
const refreshDashboardPage = async (requireRenderComplete = false) => {
await browser.refresh();
await PageObjects.header.waitUntilLoadingHasFinished();
if (requireRenderComplete) {
await PageObjects.dashboard.waitForRenderComplete();
}
};
it('should allow removing the dashboard panel after the underlying saved search has been deleted', async () => {
const searchTitle = 'TempSearch';
const searchId = '90943e30-9a47-11e8-b64d-95841ca0b247';
await kibanaServer.savedObjects.create({
type: 'search',
id: searchId,
overwrite: false,
attributes: {
title: searchTitle,
description: '',
columns: ['agent', 'bytes', 'clientip'],
sort: [['@timestamp', 'desc']],
kibanaSavedObjectMeta: {
searchSourceJSON:
'{"highlightAll":true,"version":true,"query":{"language":"lucene","query":""},"filter":[],"indexRefName":"kibanaSavedObjectMeta.searchSourceJSON.index"}',
},
},
references: [
{
id: '0bf35f60-3dc9-11e8-8660-4d65aa086b3c',
name: 'kibanaSavedObjectMeta.searchSourceJSON.index',
type: 'index-pattern',
},
],
});
await addSearchEmbeddableToDashboard(searchTitle);
await PageObjects.dashboard.saveDashboard('Dashboard with deleted saved search', {
waitDialogIsClosed: true,
exitFromEditMode: false,
});
await kibanaServer.savedObjects.delete({
type: 'search',
id: searchId,
});
await refreshDashboardPage();
await testSubjects.existOrFail('embeddableError');
const panels = await PageObjects.dashboard.getDashboardPanels();
await dashboardPanelActions.removePanel(panels[0]);
await PageObjects.header.waitUntilLoadingHasFinished();
await testSubjects.missingOrFail('embeddableError');
});
});
}