Skip to content

Commit

Permalink
[ES|QL] Do not allow saving in library action on text based panels (#…
Browse files Browse the repository at this point in the history
…167111)

## Summary

Save to library action should not be present in ES|QL panels. For now we
only allow by value embeddables and we don't want them to be
edited/created in Lens editor

<img width="915" alt="image"
src="https://github.com/elastic/kibana/assets/17003240/d6e5e8a7-459f-4b1d-8461-2863b45db882">


### Checklist
- [ ] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
  • Loading branch information
stratoula authored Sep 27, 2023
1 parent 7013a9b commit 93fc807
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 4 deletions.
5 changes: 5 additions & 0 deletions packages/kbn-es-query/src/es_query/es_aggregate_query.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ describe('sql query helpers', () => {
expect(flag).toBe(false);
});

it('should return false for an undefined query', () => {
const flag = isOfAggregateQueryType(undefined);
expect(flag).toBe(false);
});

it('should return true for an Aggregate type query', () => {
const flag = isOfAggregateQueryType({ sql: 'SELECT * FROM foo' });
expect(flag).toBe(true);
Expand Down
2 changes: 1 addition & 1 deletion packages/kbn-es-query/src/es_query/es_aggregate_query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export function isOfQueryType(arg?: Query | AggregateQuery): arg is Query {
// currently only supports the sql query type
// should be enhanced to support other query types
export function isOfAggregateQueryType(
query: AggregateQuery | Query | { [key: string]: any }
query?: AggregateQuery | Query | { [key: string]: any }
): query is AggregateQuery {
return Boolean(query && ('sql' in query || 'esql' in query));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
CONTACT_CARD_EMBEDDABLE,
} from '@kbn/embeddable-plugin/public/lib/test_samples/embeddables';
import { embeddablePluginMock } from '@kbn/embeddable-plugin/public/mocks';
import { type Query, type AggregateQuery, Filter } from '@kbn/es-query';

import { buildMockDashboard } from '../mocks';
import { pluginServices } from '../services/plugin_services';
Expand Down Expand Up @@ -82,6 +83,18 @@ test('Add to library is incompatible with Error Embeddables', async () => {
expect(await action.isCompatible({ embeddable: errorEmbeddable })).toBe(false);
});

test('Add to library is incompatible with ES|QL Embeddables', async () => {
const action = new AddToLibraryAction();
const mockGetFilters = jest.fn(async () => [] as Filter[]);
const mockGetQuery = jest.fn(async () => undefined as Query | AggregateQuery | undefined);
const filterableEmbeddable = embeddablePluginMock.mockFilterableEmbeddable(embeddable, {
getFilters: () => mockGetFilters(),
getQuery: () => mockGetQuery(),
});
mockGetQuery.mockResolvedValue({ esql: 'from logstash-* | limit 10' } as AggregateQuery);
expect(await action.isCompatible({ embeddable: filterableEmbeddable })).toBe(false);
});

test('Add to library is incompatible on visualize embeddable without visualize save permissions', async () => {
pluginServices.getServices().application.capabilities = {
...defaultCapabilities,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ import {
PanelNotFoundError,
type EmbeddableInput,
isReferenceOrValueEmbeddable,
isFilterableEmbeddable,
} from '@kbn/embeddable-plugin/public';
import { Action, IncompatibleActionError } from '@kbn/ui-actions-plugin/public';

import { type AggregateQuery } from '@kbn/es-query';
import { DashboardPanelState } from '../../common';
import { pluginServices } from '../services/plugin_services';
import { dashboardAddToLibraryActionStrings } from './_dashboard_actions_strings';
Expand Down Expand Up @@ -61,7 +62,10 @@ export class AddToLibraryAction implements Action<AddToLibraryActionContext> {
// TODO: Fix this, potentially by adding a 'canSave' function to embeddable interface
const { maps, visualize } = this.applicationCapabilities;
const canSave = embeddable.type === 'map' ? maps.save : visualize.save;

const { isOfAggregateQueryType } = await import('@kbn/es-query');
const query = isFilterableEmbeddable(embeddable) && (await embeddable.getQuery());
// Textbased panels (i.e. ES|QL, SQL) should not save to library
const isTextBasedEmbeddable = isOfAggregateQueryType(query as AggregateQuery);
return Boolean(
canSave &&
!isErrorEmbeddable(embeddable) &&
Expand All @@ -70,7 +74,8 @@ export class AddToLibraryAction implements Action<AddToLibraryActionContext> {
embeddable.getRoot().isContainer &&
embeddable.getRoot().type === DASHBOARD_CONTAINER_TYPE &&
isReferenceOrValueEmbeddable(embeddable) &&
!embeddable.inputIsRefType(embeddable.getInput())
!embeddable.inputIsRefType(embeddable.getInput()) &&
!isTextBasedEmbeddable
);
}

Expand Down

0 comments on commit 93fc807

Please sign in to comment.