[Lens] Mute visualization modifier badge if layer has only manual annotations (#167483)

## Summary

Fixes #167408 

This PR reduces the amount of "visualization modifiers" in the specific
case where ALL annotations in a layer are manual.
The `Ignore global filters` will still be shown if at least one
query-based annotation is defined in the layer.


### Checklist

Delete any items that are not applicable to this PR.

- [x] [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

---------

Co-authored-by: Stratoula Kalafateli <efstratia.kalafateli@elastic.co>
This commit is contained in:
Marco Liberati 2023-09-28 15:19:23 +02:00 committed by GitHub
parent 1f593f4c96
commit 911ed802b7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 104 additions and 5 deletions

View file

@ -731,12 +731,14 @@ describe('xy_visualization', () => {
},
};
});
it('when there is no date histogram annotation layer is disabled', () => {
const supportedAnnotationLayer = xyVisualization
.getSupportedLayers(exampleState())
.find((a) => a.type === 'annotations');
expect(supportedAnnotationLayer?.disabled).toBeTruthy();
});
it('for data with date histogram annotation layer is enabled and calculates initial dimensions', () => {
const supportedAnnotationLayer = xyVisualization
.getSupportedLayers(exampleState(), frame)
@ -3216,6 +3218,34 @@ describe('xy_visualization', () => {
});
describe('info', () => {
function createStateWithAnnotationProps(annotation: Partial<EventAnnotationConfig>) {
return {
layers: [
{
layerId: 'first',
layerType: layerTypes.DATA,
seriesType: 'area',
splitAccessor: undefined,
xAccessor: DATE_HISTORGRAM_COLUMN_ID,
accessors: ['b'],
},
{
layerId: 'layerId',
layerType: 'annotations',
indexPatternId: 'first',
annotations: [
{
label: 'Event',
id: '1',
type: 'query',
timeField: 'start_date',
...annotation,
},
],
},
],
} as XYState;
}
function getFrameMock() {
const datasourceMock = createMockDatasource('testDatasource');
datasourceMock.publicAPIMock.getOperationForColumnId.mockImplementation((id) =>
@ -3239,21 +3269,47 @@ describe('xy_visualization', () => {
});
}
it('should return an info message if annotation layer is ignoring the global filters', () => {
const initialState = exampleState();
it('should not return an info message if annotation layer is ignoring the global filters but contains only manual annotations', () => {
const initialState = createStateWithAnnotationProps({});
const state: State = {
...initialState,
layers: [
...initialState.layers,
// replace the existing annotation layers with a new one
...initialState.layers.filter(({ layerType }) => layerType !== layerTypes.ANNOTATIONS),
{
layerId: 'annotation',
layerType: layerTypes.ANNOTATIONS,
annotations: [exampleAnnotation2],
annotations: [exampleAnnotation2, { ...exampleAnnotation2, id: 'an3' }],
ignoreGlobalFilters: true,
indexPatternId: 'myIndexPattern',
},
],
};
expect(xyVisualization.getUserMessages!(state, { frame: getFrameMock() })).toHaveLength(0);
});
it("should return an info message if the annotation layer is ignoring filters and there's at least a query annotation", () => {
const state = createStateWithAnnotationProps({
filter: {
language: 'kuery',
query: 'agent.keyword: *',
type: 'kibana_query',
},
id: 'newColId',
key: {
type: 'point_in_time',
},
label: 'agent.keyword: *',
timeField: 'timestamp',
type: 'query',
});
const annotationLayer = state.layers.find(
({ layerType }) => layerType === layerTypes.ANNOTATIONS
)! as XYAnnotationLayerConfig;
annotationLayer.ignoreGlobalFilters = true;
annotationLayer.annotations.push(exampleAnnotation2);
expect(xyVisualization.getUserMessages!(state, { frame: getFrameMock() })).toContainEqual(
expect.objectContaining({
displayLocations: [{ id: 'embeddableBadge' }],
@ -3264,6 +3320,30 @@ describe('xy_visualization', () => {
})
);
});
it('should not return an info message if annotation layer is not ignoring the global filters', () => {
const state = createStateWithAnnotationProps({
filter: {
language: 'kuery',
query: 'agent.keyword: *',
type: 'kibana_query',
},
id: 'newColId',
key: {
type: 'point_in_time',
},
label: 'agent.keyword: *',
timeField: 'timestamp',
type: 'query',
});
const annotationLayer = state.layers.find(
({ layerType }) => layerType === layerTypes.ANNOTATIONS
)! as XYAnnotationLayerConfig;
annotationLayer.ignoreGlobalFilters = false;
annotationLayer.annotations.push(exampleAnnotation2);
expect(xyVisualization.getUserMessages!(state, { frame: getFrameMock() })).toHaveLength(0);
});
});
});

View file

@ -1149,7 +1149,10 @@ function getNotifiableFeatures(
fieldFormats: FieldFormatsStart
): UserMessage[] {
const annotationsWithIgnoreFlag = getAnnotationsLayers(state.layers).filter(
(layer) => layer.ignoreGlobalFilters
(layer) =>
layer.ignoreGlobalFilters &&
// If all annotations are manual, do not report it
layer.annotations.some((annotation) => annotation.type !== 'manual')
);
if (!annotationsWithIgnoreFlag.length) {
return [];

View file

@ -12,6 +12,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
const PageObjects = getPageObjects(['visualize', 'lens', 'common', 'header']);
const find = getService('find');
const testSubjects = getService('testSubjects');
const retry = getService('retry');
describe('lens layer actions tests', () => {
it('should allow creation of lens xy chart', async () => {
@ -239,6 +240,21 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
// by default annotations ignore global filters
await PageObjects.lens.createLayer('annotations');
await testSubjects.click('lns-layerPanel-2 > lnsXY_xAnnotationsPanel > lns-dimensionTrigger');
await testSubjects.click('lnsXY_annotation_query');
await retry.try(async () => {
if (!(await testSubjects.exists('annotation-query-based-query-input'))) {
await testSubjects.setValue('annotation-query-based-query-input', '*', {
clearWithKeyboard: true,
typeCharByChar: true,
});
}
});
await PageObjects.lens.closeDimensionEditor();
await PageObjects.lens.save('sampledVisualization', false, true, false, 'new');
// now check for the bottom-left badge