diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/apm/service_latency_config.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/apm/service_latency_config.ts deleted file mode 100644 index 7c3abba3e5b0..000000000000 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/apm/service_latency_config.ts +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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 { ConfigProps, DataSeries } from '../../types'; -import { FieldLabels } from '../constants'; -import { buildPhraseFilter } from '../utils'; -import { TRANSACTION_DURATION } from '../constants/elasticsearch_fieldnames'; - -export function getServiceLatencyLensConfig({ indexPattern }: ConfigProps): DataSeries { - return { - reportType: 'kpi-over-time', - defaultSeriesType: 'line', - seriesTypes: ['line', 'bar'], - xAxisColumn: { - sourceField: '@timestamp', - }, - yAxisColumns: [ - { - operationType: 'average', - sourceField: 'transaction.duration.us', - label: 'Latency', - }, - ], - hasOperationType: true, - defaultFilters: [ - 'user_agent.name', - 'user_agent.os.name', - 'client.geo.country_name', - 'user_agent.device.name', - ], - breakdowns: [ - 'user_agent.name', - 'user_agent.os.name', - 'client.geo.country_name', - 'user_agent.device.name', - ], - filters: buildPhraseFilter('transaction.type', 'request', indexPattern), - labels: { ...FieldLabels, [TRANSACTION_DURATION]: 'Latency' }, - reportDefinitions: [ - { - field: 'service.name', - required: true, - }, - { - field: 'service.environment', - }, - ], - }; -} diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts index 01e8d023ae96..52faa2dccaea 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/constants.ts @@ -96,3 +96,5 @@ export const USE_BREAK_DOWN_COLUMN = 'USE_BREAK_DOWN_COLUMN'; export const FILTER_RECORDS = 'FILTER_RECORDS'; export const TERMS_COLUMN = 'TERMS_COLUMN'; export const OPERATION_COLUMN = 'operation'; + +export const REPORT_METRIC_FIELD = 'REPORT_METRIC_FIELD'; diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/url_constants.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/url_constants.ts index b5a5169216b7..6f990015fbc6 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/url_constants.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/constants/url_constants.ts @@ -13,4 +13,5 @@ export enum URL_KEYS { BREAK_DOWN = 'bd', FILTERS = 'ft', REPORT_DEFINITIONS = 'rdf', + SELECTED_METRIC = 'mt', } diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.test.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.test.ts index 5189a529bda8..72b4bd7919c3 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.test.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.test.ts @@ -9,8 +9,14 @@ import { LayerConfig, LensAttributes } from './lens_attributes'; import { mockAppIndexPattern, mockIndexPattern } from '../rtl_helpers'; import { getDefaultConfigs } from './default_configs'; import { sampleAttribute } from './test_data/sample_attribute'; -import { LCP_FIELD, USER_AGENT_NAME } from './constants/elasticsearch_fieldnames'; +import { + LCP_FIELD, + TRANSACTION_DURATION, + USER_AGENT_NAME, +} from './constants/elasticsearch_fieldnames'; import { buildExistsFilter, buildPhrasesFilter } from './utils'; +import { sampleAttributeKpi } from './test_data/sample_attribute_kpi'; +import { REPORT_METRIC_FIELD } from './constants'; describe('Lens Attribute', () => { mockAppIndexPattern(); @@ -21,12 +27,12 @@ describe('Lens Attribute', () => { indexPattern: mockIndexPattern, }); - reportViewConfig.filters?.push(...buildExistsFilter('transaction.type', mockIndexPattern)); + reportViewConfig.baseFilters?.push(...buildExistsFilter('transaction.type', mockIndexPattern)); let lnsAttr: LensAttributes; const layerConfig: LayerConfig = { - reportConfig: reportViewConfig, + seriesConfig: reportViewConfig, seriesType: 'line', operationType: 'count', indexPattern: mockIndexPattern, @@ -42,6 +48,27 @@ describe('Lens Attribute', () => { expect(lnsAttr.getJSON()).toEqual(sampleAttribute); }); + it('should return expected json for kpi report type', function () { + const seriesConfigKpi = getDefaultConfigs({ + reportType: 'kpi-over-time', + dataType: 'ux', + indexPattern: mockIndexPattern, + }); + + const lnsAttrKpi = new LensAttributes([ + { + seriesConfig: seriesConfigKpi, + seriesType: 'line', + operationType: 'count', + indexPattern: mockIndexPattern, + reportDefinitions: { 'service.name': ['elastic-co'] }, + time: { from: 'now-15m', to: 'now' }, + }, + ]); + + expect(lnsAttrKpi.getJSON()).toEqual(sampleAttributeKpi); + }); + it('should return main y axis', function () { expect(lnsAttr.getMainYAxis(layerConfig)).toEqual({ dataType: 'number', @@ -72,7 +99,7 @@ describe('Lens Attribute', () => { }); it('should return expected field type for custom field with default value', function () { - expect(JSON.stringify(lnsAttr.getFieldMeta('performance.metric', layerConfig))).toEqual( + expect(JSON.stringify(lnsAttr.getFieldMeta(REPORT_METRIC_FIELD, layerConfig))).toEqual( JSON.stringify({ fieldMeta: { count: 0, @@ -92,7 +119,7 @@ describe('Lens Attribute', () => { it('should return expected field type for custom field with passed value', function () { const layerConfig1: LayerConfig = { - reportConfig: reportViewConfig, + seriesConfig: reportViewConfig, seriesType: 'line', operationType: 'count', indexPattern: mockIndexPattern, @@ -102,20 +129,20 @@ describe('Lens Attribute', () => { lnsAttr = new LensAttributes([layerConfig1]); - expect(JSON.stringify(lnsAttr.getFieldMeta('performance.metric', layerConfig1))).toEqual( + expect(JSON.stringify(lnsAttr.getFieldMeta(REPORT_METRIC_FIELD, layerConfig1))).toEqual( JSON.stringify({ fieldMeta: { count: 0, - name: LCP_FIELD, + name: TRANSACTION_DURATION, type: 'number', - esTypes: ['scaled_float'], + esTypes: ['long'], scripted: false, searchable: true, aggregatable: true, readFromDocValues: true, }, - fieldName: LCP_FIELD, - columnLabel: 'Largest contentful paint', + fieldName: TRANSACTION_DURATION, + columnLabel: 'Page load time', }) ); }); @@ -269,7 +296,7 @@ describe('Lens Attribute', () => { describe('Layer breakdowns', function () { it('should return breakdown column', function () { const layerConfig1: LayerConfig = { - reportConfig: reportViewConfig, + seriesConfig: reportViewConfig, seriesType: 'line', operationType: 'count', indexPattern: mockIndexPattern, @@ -322,7 +349,7 @@ describe('Lens Attribute', () => { 'x-axis-column-layer0': { dataType: 'number', isBucketed: true, - label: 'Largest contentful paint', + label: 'Page load time', operationType: 'range', params: { maxBars: 'auto', @@ -330,7 +357,7 @@ describe('Lens Attribute', () => { type: 'histogram', }, scale: 'interval', - sourceField: 'transaction.marks.agent.largestContentfulPaint', + sourceField: 'transaction.duration.us', }, 'y-axis-column-layer0': { dataType: 'number', @@ -353,12 +380,12 @@ describe('Lens Attribute', () => { describe('Layer Filters', function () { it('should return expected filters', function () { - reportViewConfig.filters?.push( + reportViewConfig.baseFilters?.push( ...buildPhrasesFilter('service.name', ['elastic', 'kibana'], mockIndexPattern) ); const layerConfig1: LayerConfig = { - reportConfig: reportViewConfig, + seriesConfig: reportViewConfig, seriesType: 'line', operationType: 'count', indexPattern: mockIndexPattern, diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.ts index 208e8d8ba43c..eaf9c1c884a9 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.ts @@ -29,8 +29,14 @@ import { } from '../../../../../../lens/public'; import { urlFiltersToKueryString } from '../utils/stringify_kueries'; import { ExistsFilter, IndexPattern } from '../../../../../../../../src/plugins/data/common'; -import { FieldLabels, FILTER_RECORDS, USE_BREAK_DOWN_COLUMN, TERMS_COLUMN } from './constants'; -import { ColumnFilter, DataSeries, UrlFilter, URLReportDefinition } from '../types'; +import { + FieldLabels, + FILTER_RECORDS, + USE_BREAK_DOWN_COLUMN, + TERMS_COLUMN, + REPORT_METRIC_FIELD, +} from './constants'; +import { ColumnFilter, SeriesConfig, UrlFilter, URLReportDefinition } from '../types'; import { PersistableFilter } from '../../../../../../lens/common'; import { parseAbsoluteDate } from '../series_date_picker/date_range_picker'; @@ -47,54 +53,47 @@ function buildNumberColumn(sourceField: string) { }; } -export const parseCustomFieldName = ( - sourceField: string, - reportViewConfig: DataSeries, - selectedDefinitions: URLReportDefinition -) => { - let fieldName = sourceField; +export const parseCustomFieldName = (seriesConfig: SeriesConfig, selectedMetricField?: string) => { let columnType; let columnFilters; let timeScale; let columnLabel; - const rdf = reportViewConfig.reportDefinitions ?? []; + const metricOptions = seriesConfig.metricOptions ?? []; - const customField = rdf.find(({ field }) => field === fieldName); - - if (customField) { - if (selectedDefinitions[fieldName]) { - fieldName = selectedDefinitions[fieldName][0]; - if (customField?.options) { - const currField = customField?.options?.find( - ({ field, id }) => field === fieldName || id === fieldName - ); - columnType = currField?.columnType; - columnFilters = currField?.columnFilters; - timeScale = currField?.timeScale; - columnLabel = currField?.label; - } - } else if (customField.options?.[0].field || customField.options?.[0].id) { - fieldName = customField.options?.[0].field || customField.options?.[0].id; - columnType = customField.options?.[0].columnType; - columnFilters = customField.options?.[0].columnFilters; - timeScale = customField.options?.[0].timeScale; - columnLabel = customField.options?.[0].label; + if (selectedMetricField) { + if (metricOptions) { + const currField = metricOptions.find( + ({ field, id }) => field === selectedMetricField || id === selectedMetricField + ); + columnType = currField?.columnType; + columnFilters = currField?.columnFilters; + timeScale = currField?.timeScale; + columnLabel = currField?.label; } + } else if (metricOptions?.[0].field || metricOptions?.[0].id) { + const firstMetricOption = metricOptions?.[0]; + + selectedMetricField = firstMetricOption.field || firstMetricOption.id; + columnType = firstMetricOption.columnType; + columnFilters = firstMetricOption.columnFilters; + timeScale = firstMetricOption.timeScale; + columnLabel = firstMetricOption.label; } - return { fieldName, columnType, columnFilters, timeScale, columnLabel }; + return { fieldName: selectedMetricField!, columnType, columnFilters, timeScale, columnLabel }; }; export interface LayerConfig { filters?: UrlFilter[]; - reportConfig: DataSeries; + seriesConfig: SeriesConfig; breakdown?: string; seriesType?: SeriesType; operationType?: OperationType; reportDefinitions: URLReportDefinition; time: { to: string; from: string }; indexPattern: IndexPattern; + selectedMetricField?: string; } export class LensAttributes { @@ -105,9 +104,9 @@ export class LensAttributes { constructor(layerConfigs: LayerConfig[]) { this.layers = {}; - layerConfigs.forEach(({ reportConfig, operationType }) => { + layerConfigs.forEach(({ seriesConfig, operationType }) => { if (operationType) { - reportConfig.yAxisColumns.forEach((yAxisColumn) => { + seriesConfig.yAxisColumns.forEach((yAxisColumn) => { if (typeof yAxisColumn.operationType !== undefined) { yAxisColumn.operationType = operationType as FieldBasedIndexPatternColumn['operationType']; } @@ -150,12 +149,12 @@ export class LensAttributes { getNumberRangeColumn( sourceField: string, - reportViewConfig: DataSeries, + seriesConfig: SeriesConfig, label?: string ): RangeIndexPatternColumn { return { sourceField, - label: reportViewConfig.labels[sourceField] ?? label, + label: seriesConfig.labels[sourceField] ?? label, dataType: 'number', operationType: 'range', isBucketed: true, @@ -171,22 +170,22 @@ export class LensAttributes { getCardinalityColumn({ sourceField, label, - reportViewConfig, + seriesConfig, }: { sourceField: string; label?: string; - reportViewConfig: DataSeries; + seriesConfig: SeriesConfig; }) { return this.getNumberOperationColumn({ sourceField, operationType: 'unique_count', label, - reportViewConfig, + seriesConfig, }); } getNumberColumn({ - reportViewConfig, + seriesConfig, label, sourceField, columnType, @@ -196,7 +195,7 @@ export class LensAttributes { columnType?: string; operationType?: string; label?: string; - reportViewConfig: DataSeries; + seriesConfig: SeriesConfig; }) { if (columnType === 'operation' || operationType) { if ( @@ -209,26 +208,26 @@ export class LensAttributes { sourceField, operationType, label, - reportViewConfig, + seriesConfig, }); } if (operationType?.includes('th')) { - return this.getPercentileNumberColumn(sourceField, operationType, reportViewConfig!); + return this.getPercentileNumberColumn(sourceField, operationType, seriesConfig!); } } - return this.getNumberRangeColumn(sourceField, reportViewConfig!, label); + return this.getNumberRangeColumn(sourceField, seriesConfig!, label); } getNumberOperationColumn({ sourceField, label, - reportViewConfig, + seriesConfig, operationType, }: { sourceField: string; operationType: 'average' | 'median' | 'sum' | 'unique_count'; label?: string; - reportViewConfig: DataSeries; + seriesConfig: SeriesConfig; }): | AvgIndexPatternColumn | MedianIndexPatternColumn @@ -239,7 +238,7 @@ export class LensAttributes { label: i18n.translate('xpack.observability.expView.columns.operation.label', { defaultMessage: '{operationType} of {sourceField}', values: { - sourceField: label || reportViewConfig.labels[sourceField], + sourceField: label || seriesConfig.labels[sourceField], operationType: capitalize(operationType), }, }), @@ -250,13 +249,13 @@ export class LensAttributes { getPercentileNumberColumn( sourceField: string, percentileValue: string, - reportViewConfig: DataSeries + seriesConfig: SeriesConfig ): PercentileIndexPatternColumn { return { ...buildNumberColumn(sourceField), label: i18n.translate('xpack.observability.expView.columns.label', { defaultMessage: '{percentileValue} percentile of {sourceField}', - values: { sourceField: reportViewConfig.labels[sourceField], percentileValue }, + values: { sourceField: seriesConfig.labels[sourceField], percentileValue }, }), operationType: 'percentile', params: { percentile: Number(percentileValue.split('th')[0]) }, @@ -295,13 +294,13 @@ export class LensAttributes { } getXAxis(layerConfig: LayerConfig, layerId: string) { - const { xAxisColumn } = layerConfig.reportConfig; + const { xAxisColumn } = layerConfig.seriesConfig; if (xAxisColumn?.sourceField === USE_BREAK_DOWN_COLUMN) { return this.getBreakdownColumn({ layerId, indexPattern: layerConfig.indexPattern, - sourceField: layerConfig.breakdown || layerConfig.reportConfig.breakdowns[0], + sourceField: layerConfig.breakdown || layerConfig.seriesConfig.breakdownFields[0], }); } @@ -333,6 +332,7 @@ export class LensAttributes { timeScale, columnFilters, } = this.getFieldMeta(sourceField, layerConfig); + const { type: fieldType } = fieldMeta ?? {}; if (columnType === TERMS_COLUMN) { @@ -356,14 +356,14 @@ export class LensAttributes { columnType, operationType, label: columnLabel || label, - reportViewConfig: layerConfig.reportConfig, + seriesConfig: layerConfig.seriesConfig, }); } if (operationType === 'unique_count') { return this.getCardinalityColumn({ sourceField: fieldName, label: columnLabel || label, - reportViewConfig: layerConfig.reportConfig, + seriesConfig: layerConfig.seriesConfig, }); } @@ -378,32 +378,26 @@ export class LensAttributes { sourceField: string; layerConfig: LayerConfig; }) { - return parseCustomFieldName( - sourceField, - layerConfig.reportConfig, - layerConfig.reportDefinitions - ); + return parseCustomFieldName(layerConfig.seriesConfig, sourceField); } getFieldMeta(sourceField: string, layerConfig: LayerConfig) { - const { - fieldName, - columnType, - columnLabel, - columnFilters, - timeScale, - } = this.getCustomFieldName({ - sourceField, - layerConfig, - }); + if (sourceField === REPORT_METRIC_FIELD) { + const { fieldName, columnType, columnLabel, columnFilters, timeScale } = parseCustomFieldName( + layerConfig.seriesConfig, + layerConfig.selectedMetricField + ); + const fieldMeta = layerConfig.indexPattern.getFieldByName(fieldName!); + return { fieldMeta, fieldName, columnType, columnLabel, columnFilters, timeScale }; + } else { + const fieldMeta = layerConfig.indexPattern.getFieldByName(sourceField); - const fieldMeta = layerConfig.indexPattern.getFieldByName(fieldName); - - return { fieldMeta, fieldName, columnType, columnLabel, columnFilters, timeScale }; + return { fieldMeta, fieldName: sourceField }; + } } getMainYAxis(layerConfig: LayerConfig) { - const { sourceField, operationType, label } = layerConfig.reportConfig.yAxisColumns[0]; + const { sourceField, operationType, label } = layerConfig.seriesConfig.yAxisColumns[0]; if (sourceField === 'Records' || !sourceField) { return this.getRecordsColumn(label); @@ -420,7 +414,7 @@ export class LensAttributes { getChildYAxises(layerConfig: LayerConfig) { const lensColumns: Record = {}; - const yAxisColumns = layerConfig.reportConfig.yAxisColumns; + const yAxisColumns = layerConfig.seriesConfig.yAxisColumns; // 1 means there is only main y axis if (yAxisColumns.length === 1) { return lensColumns; @@ -460,7 +454,7 @@ export class LensAttributes { const { filters, time: { from, to }, - reportConfig: { filters: layerFilters, reportType }, + seriesConfig: { baseFilters: layerFilters, reportType }, } = layerConfig; let baseFilters = ''; if (reportType !== 'kpi-over-time' && totalLayers > 1) { @@ -522,7 +516,7 @@ export class LensAttributes { } getTimeShift(mainLayerConfig: LayerConfig, layerConfig: LayerConfig, index: number) { - if (index === 0 || mainLayerConfig.reportConfig.reportType !== 'kpi-over-time') { + if (index === 0 || mainLayerConfig.seriesConfig.reportType !== 'kpi-over-time') { return null; } @@ -603,16 +597,16 @@ export class LensAttributes { ...Object.keys(this.getChildYAxises(layerConfig)), ], layerId: `layer${index}`, - seriesType: layerConfig.seriesType || layerConfig.reportConfig.defaultSeriesType, - palette: layerConfig.reportConfig.palette, - yConfig: layerConfig.reportConfig.yConfig || [ + seriesType: layerConfig.seriesType || layerConfig.seriesConfig.defaultSeriesType, + palette: layerConfig.seriesConfig.palette, + yConfig: layerConfig.seriesConfig.yConfig || [ { forAccessor: `y-axis-column-layer${index}` }, ], xAccessor: `x-axis-column-layer${index}`, ...(layerConfig.breakdown ? { splitAccessor: `breakdown-column-layer${index}` } : {}), })), - ...(this.layerConfigs[0].reportConfig.yTitle - ? { yTitle: this.layerConfigs[0].reportConfig.yTitle } + ...(this.layerConfigs[0].seriesConfig.yTitle + ? { yTitle: this.layerConfigs[0].seriesConfig.yTitle } : {}), }; } diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/metrics/cpu_usage_config.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/metrics/cpu_usage_config.ts deleted file mode 100644 index 2d44e122af82..000000000000 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/metrics/cpu_usage_config.ts +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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 { DataSeries, ConfigProps } from '../../types'; -import { FieldLabels } from '../constants'; - -export function getCPUUsageLensConfig({}: ConfigProps): DataSeries { - return { - reportType: 'kpi-over-time', - defaultSeriesType: 'line', - seriesTypes: ['line', 'bar'], - xAxisColumn: { - sourceField: '@timestamp', - }, - yAxisColumns: [ - { - operationType: 'average', - sourceField: 'system.cpu.user.pct', - label: 'CPU Usage %', - }, - ], - hasOperationType: true, - defaultFilters: [], - breakdowns: ['host.hostname'], - filters: [], - labels: { ...FieldLabels, 'host.hostname': 'Host name' }, - reportDefinitions: [ - { - field: 'agent.hostname', - required: true, - }, - ], - }; -} diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/metrics/memory_usage_config.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/metrics/memory_usage_config.ts deleted file mode 100644 index deaa551dce65..000000000000 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/metrics/memory_usage_config.ts +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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 { DataSeries, ConfigProps } from '../../types'; -import { FieldLabels } from '../constants'; - -export function getMemoryUsageLensConfig({}: ConfigProps): DataSeries { - return { - reportType: 'kpi-over-time', - defaultSeriesType: 'line', - seriesTypes: ['line', 'bar'], - xAxisColumn: { - sourceField: '@timestamp', - }, - yAxisColumns: [ - { - operationType: 'average', - sourceField: 'system.memory.used.pct', - label: 'Memory Usage %', - }, - ], - hasOperationType: true, - defaultFilters: [], - breakdowns: ['host.hostname'], - filters: [], - labels: { ...FieldLabels, 'host.hostname': 'Host name' }, - reportDefinitions: [ - { - field: 'host.hostname', - required: true, - }, - ], - }; -} diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/metrics/network_activity_config.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/metrics/network_activity_config.ts deleted file mode 100644 index d27cdba207d6..000000000000 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/metrics/network_activity_config.ts +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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 { DataSeries, ConfigProps } from '../../types'; -import { FieldLabels } from '../constants'; - -export function getNetworkActivityLensConfig({}: ConfigProps): DataSeries { - return { - reportType: 'kpi-over-time', - defaultSeriesType: 'line', - seriesTypes: ['line', 'bar'], - xAxisColumn: { - sourceField: '@timestamp', - }, - yAxisColumns: [ - { - operationType: 'average', - sourceField: 'system.memory.used.pct', - }, - ], - hasOperationType: true, - defaultFilters: [], - breakdowns: ['host.hostname'], - filters: [], - labels: { ...FieldLabels, 'host.hostname': 'Host name' }, - reportDefinitions: [ - { - field: 'host.hostname', - required: true, - }, - ], - }; -} diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/device_distribution_config.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/device_distribution_config.ts index e1cb5a0370fb..98979b9922a8 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/device_distribution_config.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/device_distribution_config.ts @@ -5,14 +5,14 @@ * 2.0. */ -import { ConfigProps, DataSeries } from '../../types'; +import { ConfigProps, SeriesConfig } from '../../types'; import { FieldLabels, USE_BREAK_DOWN_COLUMN } from '../constants'; import { buildPhraseFilter } from '../utils'; import { SERVICE_NAME } from '../constants/elasticsearch_fieldnames'; import { MOBILE_APP, NUMBER_OF_DEVICES } from '../constants/labels'; import { MobileFields } from './mobile_fields'; -export function getMobileDeviceDistributionConfig({ indexPattern }: ConfigProps): DataSeries { +export function getMobileDeviceDistributionConfig({ indexPattern }: ConfigProps): SeriesConfig { return { reportType: 'device-data-distribution', defaultSeriesType: 'bar', @@ -28,9 +28,9 @@ export function getMobileDeviceDistributionConfig({ indexPattern }: ConfigProps) }, ], hasOperationType: false, - defaultFilters: Object.keys(MobileFields), - breakdowns: Object.keys(MobileFields), - filters: [ + filterFields: Object.keys(MobileFields), + breakdownFields: Object.keys(MobileFields), + baseFilters: [ ...buildPhraseFilter('agent.name', 'iOS/swift', indexPattern), ...buildPhraseFilter('processor.event', 'transaction', indexPattern), ], @@ -39,11 +39,6 @@ export function getMobileDeviceDistributionConfig({ indexPattern }: ConfigProps) ...MobileFields, [SERVICE_NAME]: MOBILE_APP, }, - reportDefinitions: [ - { - field: SERVICE_NAME, - required: true, - }, - ], + definitionFields: [SERVICE_NAME], }; } diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/distribution_config.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/distribution_config.ts index 62dd38e55a32..b9894347d96c 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/distribution_config.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/distribution_config.ts @@ -5,8 +5,8 @@ * 2.0. */ -import { ConfigProps, DataSeries } from '../../types'; -import { FieldLabels, OPERATION_COLUMN, RECORDS_FIELD } from '../constants'; +import { ConfigProps, SeriesConfig } from '../../types'; +import { FieldLabels, OPERATION_COLUMN, RECORDS_FIELD, REPORT_METRIC_FIELD } from '../constants'; import { buildPhrasesFilter } from '../utils'; import { METRIC_SYSTEM_CPU_USAGE, @@ -19,13 +19,13 @@ import { import { CPU_USAGE, MEMORY_USAGE, MOBILE_APP, RESPONSE_LATENCY } from '../constants/labels'; import { MobileFields } from './mobile_fields'; -export function getMobileKPIDistributionConfig({ indexPattern }: ConfigProps): DataSeries { +export function getMobileKPIDistributionConfig({ indexPattern }: ConfigProps): SeriesConfig { return { reportType: 'data-distribution', defaultSeriesType: 'bar', seriesTypes: ['line', 'bar'], xAxisColumn: { - sourceField: 'performance.metric', + sourceField: REPORT_METRIC_FIELD, }, yAxisColumns: [ { @@ -33,9 +33,9 @@ export function getMobileKPIDistributionConfig({ indexPattern }: ConfigProps): D }, ], hasOperationType: false, - defaultFilters: Object.keys(MobileFields), - breakdowns: Object.keys(MobileFields), - filters: [ + filterFields: Object.keys(MobileFields), + breakdownFields: Object.keys(MobileFields), + baseFilters: [ ...buildPhrasesFilter('agent.name', ['iOS/swift', 'open-telemetry/swift'], indexPattern), ], labels: { @@ -43,38 +43,25 @@ export function getMobileKPIDistributionConfig({ indexPattern }: ConfigProps): D ...MobileFields, [SERVICE_NAME]: MOBILE_APP, }, - reportDefinitions: [ + definitionFields: [SERVICE_NAME, SERVICE_ENVIRONMENT], + metricOptions: [ { - field: SERVICE_NAME, - required: true, + label: RESPONSE_LATENCY, + field: TRANSACTION_DURATION, + id: TRANSACTION_DURATION, + columnType: OPERATION_COLUMN, }, { - field: SERVICE_ENVIRONMENT, - required: true, + label: MEMORY_USAGE, + field: METRIC_SYSTEM_MEMORY_USAGE, + id: METRIC_SYSTEM_MEMORY_USAGE, + columnType: OPERATION_COLUMN, }, { - field: 'performance.metric', - custom: true, - options: [ - { - label: RESPONSE_LATENCY, - field: TRANSACTION_DURATION, - id: TRANSACTION_DURATION, - columnType: OPERATION_COLUMN, - }, - { - label: MEMORY_USAGE, - field: METRIC_SYSTEM_MEMORY_USAGE, - id: METRIC_SYSTEM_MEMORY_USAGE, - columnType: OPERATION_COLUMN, - }, - { - label: CPU_USAGE, - field: METRIC_SYSTEM_CPU_USAGE, - id: METRIC_SYSTEM_CPU_USAGE, - columnType: OPERATION_COLUMN, - }, - ], + label: CPU_USAGE, + field: METRIC_SYSTEM_CPU_USAGE, + id: METRIC_SYSTEM_CPU_USAGE, + columnType: OPERATION_COLUMN, }, ], }; diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/kpi_over_time_config.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/kpi_over_time_config.ts index 9a2e86a8f796..945a631078a3 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/kpi_over_time_config.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/mobile/kpi_over_time_config.ts @@ -5,8 +5,8 @@ * 2.0. */ -import { ConfigProps, DataSeries } from '../../types'; -import { FieldLabels, OPERATION_COLUMN, RECORDS_FIELD } from '../constants'; +import { ConfigProps, SeriesConfig } from '../../types'; +import { FieldLabels, OPERATION_COLUMN, RECORDS_FIELD, REPORT_METRIC_FIELD } from '../constants'; import { buildPhrasesFilter } from '../utils'; import { METRIC_SYSTEM_CPU_USAGE, @@ -24,7 +24,7 @@ import { } from '../constants/labels'; import { MobileFields } from './mobile_fields'; -export function getMobileKPIConfig({ indexPattern }: ConfigProps): DataSeries { +export function getMobileKPIConfig({ indexPattern }: ConfigProps): SeriesConfig { return { reportType: 'kpi-over-time', defaultSeriesType: 'line', @@ -34,14 +34,14 @@ export function getMobileKPIConfig({ indexPattern }: ConfigProps): DataSeries { }, yAxisColumns: [ { - sourceField: 'business.kpi', + sourceField: REPORT_METRIC_FIELD, operationType: 'median', }, ], hasOperationType: true, - defaultFilters: Object.keys(MobileFields), - breakdowns: Object.keys(MobileFields), - filters: [ + filterFields: Object.keys(MobileFields), + breakdownFields: Object.keys(MobileFields), + baseFilters: [ ...buildPhrasesFilter('agent.name', ['iOS/swift', 'open-telemetry/swift'], indexPattern), ], labels: { @@ -52,50 +52,37 @@ export function getMobileKPIConfig({ indexPattern }: ConfigProps): DataSeries { [METRIC_SYSTEM_MEMORY_USAGE]: MEMORY_USAGE, [METRIC_SYSTEM_CPU_USAGE]: CPU_USAGE, }, - reportDefinitions: [ + definitionFields: [SERVICE_NAME, SERVICE_ENVIRONMENT], + metricOptions: [ { - field: SERVICE_NAME, - required: true, + label: RESPONSE_LATENCY, + field: TRANSACTION_DURATION, + id: TRANSACTION_DURATION, + columnType: OPERATION_COLUMN, }, { - field: SERVICE_ENVIRONMENT, - required: true, - }, - { - field: 'business.kpi', - custom: true, - options: [ + field: RECORDS_FIELD, + id: RECORDS_FIELD, + label: TRANSACTIONS_PER_MINUTE, + columnFilters: [ { - label: RESPONSE_LATENCY, - field: TRANSACTION_DURATION, - id: TRANSACTION_DURATION, - columnType: OPERATION_COLUMN, - }, - { - field: RECORDS_FIELD, - id: RECORDS_FIELD, - label: TRANSACTIONS_PER_MINUTE, - columnFilters: [ - { - language: 'kuery', - query: `processor.event: transaction`, - }, - ], - timeScale: 'm', - }, - { - label: MEMORY_USAGE, - field: METRIC_SYSTEM_MEMORY_USAGE, - id: METRIC_SYSTEM_MEMORY_USAGE, - columnType: OPERATION_COLUMN, - }, - { - label: CPU_USAGE, - field: METRIC_SYSTEM_CPU_USAGE, - id: METRIC_SYSTEM_CPU_USAGE, - columnType: OPERATION_COLUMN, + language: 'kuery', + query: `processor.event: transaction`, }, ], + timeScale: 'm', + }, + { + label: MEMORY_USAGE, + field: METRIC_SYSTEM_MEMORY_USAGE, + id: METRIC_SYSTEM_MEMORY_USAGE, + columnType: OPERATION_COLUMN, + }, + { + label: CPU_USAGE, + field: METRIC_SYSTEM_CPU_USAGE, + id: METRIC_SYSTEM_CPU_USAGE, + columnType: OPERATION_COLUMN, }, ], }; diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/rum/core_web_vitals_config.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/rum/core_web_vitals_config.ts index e34d8b0dcfdd..1d04a9b38950 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/rum/core_web_vitals_config.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/rum/core_web_vitals_config.ts @@ -6,8 +6,13 @@ */ import { euiPaletteForStatus } from '@elastic/eui'; -import { ConfigProps, DataSeries } from '../../types'; -import { FieldLabels, FILTER_RECORDS, USE_BREAK_DOWN_COLUMN } from '../constants'; +import { ConfigProps, SeriesConfig } from '../../types'; +import { + FieldLabels, + FILTER_RECORDS, + REPORT_METRIC_FIELD, + USE_BREAK_DOWN_COLUMN, +} from '../constants'; import { buildPhraseFilter } from '../utils'; import { CLIENT_GEO_COUNTRY_NAME, @@ -27,7 +32,7 @@ import { SERVICE_ENVIRONMENT, } from '../constants/elasticsearch_fieldnames'; -export function getCoreWebVitalsConfig({ indexPattern }: ConfigProps): DataSeries { +export function getCoreWebVitalsConfig({ indexPattern }: ConfigProps): SeriesConfig { const statusPallete = euiPaletteForStatus(3); return { @@ -39,20 +44,20 @@ export function getCoreWebVitalsConfig({ indexPattern }: ConfigProps): DataSerie }, yAxisColumns: [ { - sourceField: 'core.web.vitals', + sourceField: REPORT_METRIC_FIELD, label: 'Good', }, { - sourceField: 'core.web.vitals', + sourceField: REPORT_METRIC_FIELD, label: 'Average', }, { - sourceField: 'core.web.vitals', + sourceField: REPORT_METRIC_FIELD, label: 'Poor', }, ], hasOperationType: false, - defaultFilters: [ + filterFields: [ { field: TRANSACTION_URL, isNegated: false, @@ -69,7 +74,7 @@ export function getCoreWebVitalsConfig({ indexPattern }: ConfigProps): DataSerie nested: USER_AGENT_VERSION, }, ], - breakdowns: [ + breakdownFields: [ SERVICE_NAME, USER_AGENT_NAME, USER_AGENT_OS, @@ -77,79 +82,67 @@ export function getCoreWebVitalsConfig({ indexPattern }: ConfigProps): DataSerie USER_AGENT_DEVICE, URL_FULL, ], - filters: [ + baseFilters: [ ...buildPhraseFilter(TRANSACTION_TYPE, 'page-load', indexPattern), ...buildPhraseFilter(PROCESSOR_EVENT, 'transaction', indexPattern), ], labels: { ...FieldLabels, [SERVICE_NAME]: 'Web Application' }, - reportDefinitions: [ + definitionFields: [SERVICE_NAME, SERVICE_ENVIRONMENT], + metricOptions: [ { - field: SERVICE_NAME, - required: true, - }, - { - field: SERVICE_ENVIRONMENT, - }, - { - field: 'core.web.vitals', - custom: true, - options: [ + id: LCP_FIELD, + label: 'Largest contentful paint', + columnType: FILTER_RECORDS, + columnFilters: [ { - id: LCP_FIELD, - label: 'Largest contentful paint', - columnType: FILTER_RECORDS, - columnFilters: [ - { - language: 'kuery', - query: `${LCP_FIELD} < 2500`, - }, - { - language: 'kuery', - query: `${LCP_FIELD} > 2500 and ${LCP_FIELD} < 4000`, - }, - { - language: 'kuery', - query: `${LCP_FIELD} > 4000`, - }, - ], + language: 'kuery', + query: `${LCP_FIELD} < 2500`, }, { - label: 'First input delay', - id: FID_FIELD, - columnType: FILTER_RECORDS, - columnFilters: [ - { - language: 'kuery', - query: `${FID_FIELD} < 100`, - }, - { - language: 'kuery', - query: `${FID_FIELD} > 100 and ${FID_FIELD} < 300`, - }, - { - language: 'kuery', - query: `${FID_FIELD} > 300`, - }, - ], + language: 'kuery', + query: `${LCP_FIELD} > 2500 and ${LCP_FIELD} < 4000`, }, { - label: 'Cumulative layout shift', - id: CLS_FIELD, - columnType: FILTER_RECORDS, - columnFilters: [ - { - language: 'kuery', - query: `${CLS_FIELD} < 0.1`, - }, - { - language: 'kuery', - query: `${CLS_FIELD} > 0.1 and ${CLS_FIELD} < 0.25`, - }, - { - language: 'kuery', - query: `${CLS_FIELD} > 0.25`, - }, - ], + language: 'kuery', + query: `${LCP_FIELD} > 4000`, + }, + ], + }, + { + label: 'First input delay', + id: FID_FIELD, + columnType: FILTER_RECORDS, + columnFilters: [ + { + language: 'kuery', + query: `${FID_FIELD} < 100`, + }, + { + language: 'kuery', + query: `${FID_FIELD} > 100 and ${FID_FIELD} < 300`, + }, + { + language: 'kuery', + query: `${FID_FIELD} > 300`, + }, + ], + }, + { + label: 'Cumulative layout shift', + id: CLS_FIELD, + columnType: FILTER_RECORDS, + columnFilters: [ + { + language: 'kuery', + query: `${CLS_FIELD} < 0.1`, + }, + { + language: 'kuery', + query: `${CLS_FIELD} > 0.1 and ${CLS_FIELD} < 0.25`, + }, + { + language: 'kuery', + query: `${CLS_FIELD} > 0.25`, }, ], }, diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/rum/data_distribution_config.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/rum/data_distribution_config.ts index 812f1b2e4cf3..b171edf2901d 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/rum/data_distribution_config.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/rum/data_distribution_config.ts @@ -5,8 +5,8 @@ * 2.0. */ -import { ConfigProps, DataSeries } from '../../types'; -import { FieldLabels, RECORDS_FIELD } from '../constants'; +import { ConfigProps, SeriesConfig } from '../../types'; +import { FieldLabels, RECORDS_FIELD, REPORT_METRIC_FIELD } from '../constants'; import { buildPhraseFilter } from '../utils'; import { CLIENT_GEO_COUNTRY_NAME, @@ -39,13 +39,13 @@ import { WEB_APPLICATION_LABEL, } from '../constants/labels'; -export function getRumDistributionConfig({ indexPattern }: ConfigProps): DataSeries { +export function getRumDistributionConfig({ indexPattern }: ConfigProps): SeriesConfig { return { reportType: 'data-distribution', defaultSeriesType: 'line', seriesTypes: [], xAxisColumn: { - sourceField: 'performance.metric', + sourceField: REPORT_METRIC_FIELD, }, yAxisColumns: [ { @@ -54,7 +54,7 @@ export function getRumDistributionConfig({ indexPattern }: ConfigProps): DataSer }, ], hasOperationType: false, - defaultFilters: [ + filterFields: [ { field: TRANSACTION_URL, isNegated: false, @@ -67,34 +67,22 @@ export function getRumDistributionConfig({ indexPattern }: ConfigProps): DataSer nested: USER_AGENT_VERSION, }, ], - breakdowns: [USER_AGENT_NAME, USER_AGENT_OS, CLIENT_GEO_COUNTRY_NAME, USER_AGENT_DEVICE], - reportDefinitions: [ + breakdownFields: [USER_AGENT_NAME, USER_AGENT_OS, CLIENT_GEO_COUNTRY_NAME, USER_AGENT_DEVICE], + definitionFields: [SERVICE_NAME, SERVICE_ENVIRONMENT], + metricOptions: [ + { label: PAGE_LOAD_TIME_LABEL, id: TRANSACTION_DURATION, field: TRANSACTION_DURATION }, { - field: SERVICE_NAME, - required: true, - }, - { - field: SERVICE_ENVIRONMENT, - }, - { - field: 'performance.metric', - custom: true, - options: [ - { label: PAGE_LOAD_TIME_LABEL, id: TRANSACTION_DURATION, field: TRANSACTION_DURATION }, - { - label: BACKEND_TIME_LABEL, - id: TRANSACTION_TIME_TO_FIRST_BYTE, - field: TRANSACTION_TIME_TO_FIRST_BYTE, - }, - { label: FCP_LABEL, id: FCP_FIELD, field: FCP_FIELD }, - { label: TBT_LABEL, id: TBT_FIELD, field: TBT_FIELD }, - { label: LCP_LABEL, id: LCP_FIELD, field: LCP_FIELD }, - { label: FID_LABEL, id: FID_FIELD, field: FID_FIELD }, - { label: CLS_LABEL, id: CLS_FIELD, field: CLS_FIELD }, - ], + label: BACKEND_TIME_LABEL, + id: TRANSACTION_TIME_TO_FIRST_BYTE, + field: TRANSACTION_TIME_TO_FIRST_BYTE, }, + { label: FCP_LABEL, id: FCP_FIELD, field: FCP_FIELD }, + { label: TBT_LABEL, id: TBT_FIELD, field: TBT_FIELD }, + { label: LCP_LABEL, id: LCP_FIELD, field: LCP_FIELD }, + { label: FID_LABEL, id: FID_FIELD, field: FID_FIELD }, + { label: CLS_LABEL, id: CLS_FIELD, field: CLS_FIELD }, ], - filters: [ + baseFilters: [ ...buildPhraseFilter(TRANSACTION_TYPE, 'page-load', indexPattern), ...buildPhraseFilter(PROCESSOR_EVENT, 'transaction', indexPattern), ], diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/rum/kpi_over_time_config.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/rum/kpi_over_time_config.ts index 12d66c55c7d0..5899b16d12b4 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/rum/kpi_over_time_config.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/rum/kpi_over_time_config.ts @@ -5,8 +5,8 @@ * 2.0. */ -import { ConfigProps, DataSeries } from '../../types'; -import { FieldLabels, OPERATION_COLUMN, RECORDS_FIELD } from '../constants'; +import { ConfigProps, SeriesConfig } from '../../types'; +import { FieldLabels, OPERATION_COLUMN, RECORDS_FIELD, REPORT_METRIC_FIELD } from '../constants'; import { buildPhraseFilter } from '../utils'; import { CLIENT_GEO_COUNTRY_NAME, @@ -39,7 +39,7 @@ import { WEB_APPLICATION_LABEL, } from '../constants/labels'; -export function getKPITrendsLensConfig({ indexPattern }: ConfigProps): DataSeries { +export function getKPITrendsLensConfig({ indexPattern }: ConfigProps): SeriesConfig { return { defaultSeriesType: 'bar_stacked', seriesTypes: [], @@ -49,12 +49,12 @@ export function getKPITrendsLensConfig({ indexPattern }: ConfigProps): DataSerie }, yAxisColumns: [ { - sourceField: 'business.kpi', + sourceField: REPORT_METRIC_FIELD, operationType: 'median', }, ], hasOperationType: false, - defaultFilters: [ + filterFields: [ { field: TRANSACTION_URL, isNegated: false, @@ -67,44 +67,32 @@ export function getKPITrendsLensConfig({ indexPattern }: ConfigProps): DataSerie nested: USER_AGENT_VERSION, }, ], - breakdowns: [USER_AGENT_NAME, USER_AGENT_OS, CLIENT_GEO_COUNTRY_NAME, USER_AGENT_DEVICE], - filters: [ + breakdownFields: [USER_AGENT_NAME, USER_AGENT_OS, CLIENT_GEO_COUNTRY_NAME, USER_AGENT_DEVICE], + baseFilters: [ ...buildPhraseFilter(TRANSACTION_TYPE, 'page-load', indexPattern), ...buildPhraseFilter(PROCESSOR_EVENT, 'transaction', indexPattern), ], labels: { ...FieldLabels, [SERVICE_NAME]: WEB_APPLICATION_LABEL }, - reportDefinitions: [ + definitionFields: [SERVICE_NAME, SERVICE_ENVIRONMENT], + metricOptions: [ + { field: RECORDS_FIELD, id: RECORDS_FIELD, label: PAGE_VIEWS_LABEL }, { - field: SERVICE_NAME, - required: true, + label: PAGE_LOAD_TIME_LABEL, + field: TRANSACTION_DURATION, + id: TRANSACTION_DURATION, + columnType: OPERATION_COLUMN, }, { - field: SERVICE_ENVIRONMENT, - }, - { - field: 'business.kpi', - custom: true, - options: [ - { field: RECORDS_FIELD, id: RECORDS_FIELD, label: PAGE_VIEWS_LABEL }, - { - label: PAGE_LOAD_TIME_LABEL, - field: TRANSACTION_DURATION, - id: TRANSACTION_DURATION, - columnType: OPERATION_COLUMN, - }, - { - label: BACKEND_TIME_LABEL, - field: TRANSACTION_TIME_TO_FIRST_BYTE, - id: TRANSACTION_TIME_TO_FIRST_BYTE, - columnType: OPERATION_COLUMN, - }, - { label: FCP_LABEL, field: FCP_FIELD, id: FCP_FIELD, columnType: OPERATION_COLUMN }, - { label: TBT_LABEL, field: TBT_FIELD, id: TBT_FIELD, columnType: OPERATION_COLUMN }, - { label: LCP_LABEL, field: LCP_FIELD, id: LCP_FIELD, columnType: OPERATION_COLUMN }, - { label: FID_LABEL, field: FID_FIELD, id: FID_FIELD, columnType: OPERATION_COLUMN }, - { label: CLS_LABEL, field: CLS_FIELD, id: CLS_FIELD, columnType: OPERATION_COLUMN }, - ], + label: BACKEND_TIME_LABEL, + field: TRANSACTION_TIME_TO_FIRST_BYTE, + id: TRANSACTION_TIME_TO_FIRST_BYTE, + columnType: OPERATION_COLUMN, }, + { label: FCP_LABEL, field: FCP_FIELD, id: FCP_FIELD, columnType: OPERATION_COLUMN }, + { label: TBT_LABEL, field: TBT_FIELD, id: TBT_FIELD, columnType: OPERATION_COLUMN }, + { label: LCP_LABEL, field: LCP_FIELD, id: LCP_FIELD, columnType: OPERATION_COLUMN }, + { label: FID_LABEL, field: FID_FIELD, id: FID_FIELD, columnType: OPERATION_COLUMN }, + { label: CLS_LABEL, field: CLS_FIELD, id: CLS_FIELD, columnType: OPERATION_COLUMN }, ], }; } diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/synthetics/data_distribution_config.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/synthetics/data_distribution_config.ts index b958c0dd7152..9783f63f5b90 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/synthetics/data_distribution_config.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/synthetics/data_distribution_config.ts @@ -5,18 +5,21 @@ * 2.0. */ -import { ConfigProps, DataSeries } from '../../types'; -import { FieldLabels, RECORDS_FIELD } from '../constants'; +import { ConfigProps, SeriesConfig } from '../../types'; +import { FieldLabels, RECORDS_FIELD, REPORT_METRIC_FIELD } from '../constants'; import { buildExistsFilter } from '../utils'; import { MONITORS_DURATION_LABEL, PINGS_LABEL } from '../constants/labels'; -export function getSyntheticsDistributionConfig({ series, indexPattern }: ConfigProps): DataSeries { +export function getSyntheticsDistributionConfig({ + series, + indexPattern, +}: ConfigProps): SeriesConfig { return { reportType: 'data-distribution', defaultSeriesType: series?.seriesType || 'line', seriesTypes: [], xAxisColumn: { - sourceField: 'performance.metric', + sourceField: REPORT_METRIC_FIELD, }, yAxisColumns: [ { @@ -25,8 +28,8 @@ export function getSyntheticsDistributionConfig({ series, indexPattern }: Config }, ], hasOperationType: false, - defaultFilters: ['monitor.type', 'observer.geo.name', 'tags'], - breakdowns: [ + filterFields: ['monitor.type', 'observer.geo.name', 'tags'], + breakdownFields: [ 'observer.geo.name', 'monitor.name', 'monitor.id', @@ -34,21 +37,10 @@ export function getSyntheticsDistributionConfig({ series, indexPattern }: Config 'tags', 'url.port', ], - filters: [...buildExistsFilter('summary.up', indexPattern)], - reportDefinitions: [ - { - field: 'monitor.name', - }, - { - field: 'url.full', - }, - { - field: 'performance.metric', - custom: true, - options: [ - { label: 'Monitor duration', id: 'monitor.duration.us', field: 'monitor.duration.us' }, - ], - }, + baseFilters: [...buildExistsFilter('summary.up', indexPattern)], + definitionFields: ['monitor.name', 'url.full'], + metricOptions: [ + { label: 'Monitor duration', id: 'monitor.duration.us', field: 'monitor.duration.us' }, ], labels: { ...FieldLabels, 'monitor.duration.us': MONITORS_DURATION_LABEL }, }; diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/synthetics/kpi_over_time_config.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/synthetics/kpi_over_time_config.ts index 3e9284543636..6bf280e93eb1 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/synthetics/kpi_over_time_config.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/synthetics/kpi_over_time_config.ts @@ -5,15 +5,15 @@ * 2.0. */ -import { ConfigProps, DataSeries } from '../../types'; -import { FieldLabels, OPERATION_COLUMN } from '../constants'; +import { ConfigProps, SeriesConfig } from '../../types'; +import { FieldLabels, OPERATION_COLUMN, REPORT_METRIC_FIELD } from '../constants'; import { buildExistsFilter } from '../utils'; import { DOWN_LABEL, MONITORS_DURATION_LABEL, UP_LABEL } from '../constants/labels'; import { MONITOR_DURATION_US } from '../constants/field_names/synthetics'; const SUMMARY_UP = 'summary.up'; const SUMMARY_DOWN = 'summary.down'; -export function getSyntheticsKPIConfig({ indexPattern }: ConfigProps): DataSeries { +export function getSyntheticsKPIConfig({ indexPattern }: ConfigProps): SeriesConfig { return { reportType: 'kpi-over-time', defaultSeriesType: 'bar_stacked', @@ -23,45 +23,34 @@ export function getSyntheticsKPIConfig({ indexPattern }: ConfigProps): DataSerie }, yAxisColumns: [ { - sourceField: 'business.kpi', + sourceField: REPORT_METRIC_FIELD, operationType: 'median', }, ], hasOperationType: false, - defaultFilters: ['observer.geo.name', 'monitor.type', 'tags'], - breakdowns: ['observer.geo.name', 'monitor.type'], - filters: [...buildExistsFilter('summary.up', indexPattern)], + filterFields: ['observer.geo.name', 'monitor.type', 'tags'], + breakdownFields: ['observer.geo.name', 'monitor.type'], + baseFilters: [...buildExistsFilter('summary.up', indexPattern)], palette: { type: 'palette', name: 'status' }, - reportDefinitions: [ + definitionFields: ['monitor.name', 'url.full'], + metricOptions: [ { - field: 'monitor.name', + label: MONITORS_DURATION_LABEL, + field: MONITOR_DURATION_US, + id: MONITOR_DURATION_US, + columnType: OPERATION_COLUMN, }, { - field: 'url.full', + field: SUMMARY_UP, + id: SUMMARY_UP, + label: UP_LABEL, + columnType: OPERATION_COLUMN, }, { - field: 'business.kpi', - custom: true, - options: [ - { - label: MONITORS_DURATION_LABEL, - field: MONITOR_DURATION_US, - id: MONITOR_DURATION_US, - columnType: OPERATION_COLUMN, - }, - { - field: SUMMARY_UP, - id: SUMMARY_UP, - label: UP_LABEL, - columnType: OPERATION_COLUMN, - }, - { - field: SUMMARY_DOWN, - id: SUMMARY_DOWN, - label: DOWN_LABEL, - columnType: OPERATION_COLUMN, - }, - ], + field: SUMMARY_DOWN, + id: SUMMARY_DOWN, + label: DOWN_LABEL, + columnType: OPERATION_COLUMN, }, ], labels: { ...FieldLabels }, diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/sample_attribute_kpi.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/sample_attribute_kpi.ts new file mode 100644 index 000000000000..7f066caf66bf --- /dev/null +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/sample_attribute_kpi.ts @@ -0,0 +1,71 @@ +/* + * 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. + */ +export const sampleAttributeKpi = { + title: 'Prefilled from exploratory view app', + description: '', + visualizationType: 'lnsXY', + references: [ + { id: 'apm-*', name: 'indexpattern-datasource-current-indexpattern', type: 'index-pattern' }, + { id: 'apm-*', name: 'indexpattern-datasource-layer-layer0', type: 'index-pattern' }, + ], + state: { + datasourceStates: { + indexpattern: { + layers: { + layer0: { + columnOrder: ['x-axis-column-layer0', 'y-axis-column-layer0'], + columns: { + 'x-axis-column-layer0': { + sourceField: '@timestamp', + dataType: 'date', + isBucketed: true, + label: '@timestamp', + operationType: 'date_histogram', + params: { interval: 'auto' }, + scale: 'interval', + }, + 'y-axis-column-layer0': { + dataType: 'number', + isBucketed: false, + label: 'Page views', + operationType: 'count', + scale: 'ratio', + sourceField: 'Records', + filter: { + query: 'transaction.type: page-load and processor.event: transaction', + language: 'kuery', + }, + }, + }, + incompleteColumns: {}, + }, + }, + }, + }, + visualization: { + legend: { isVisible: true, position: 'right' }, + valueLabels: 'hide', + fittingFunction: 'Linear', + curveType: 'CURVE_MONOTONE_X', + axisTitlesVisibilitySettings: { x: true, yLeft: true, yRight: true }, + tickLabelsVisibilitySettings: { x: true, yLeft: true, yRight: true }, + gridlinesVisibilitySettings: { x: true, yLeft: true, yRight: true }, + preferredSeriesType: 'line', + layers: [ + { + accessors: ['y-axis-column-layer0'], + layerId: 'layer0', + seriesType: 'line', + yConfig: [{ forAccessor: 'y-axis-column-layer0' }], + xAccessor: 'x-axis-column-layer0', + }, + ], + }, + query: { query: '', language: 'kuery' }, + filters: [], + }, +}; diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/utils.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/utils.ts index 9b1e7ec141ca..f7df2939d990 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/utils.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/utils.ts @@ -21,6 +21,7 @@ export function convertToShortUrl(series: SeriesUrl) { filters, reportDefinitions, dataType, + selectedMetricField, ...restSeries } = series; @@ -32,6 +33,7 @@ export function convertToShortUrl(series: SeriesUrl) { [URL_KEYS.FILTERS]: filters, [URL_KEYS.REPORT_DEFINITIONS]: reportDefinitions, [URL_KEYS.DATA_TYPE]: dataType, + [URL_KEYS.SELECTED_METRIC]: selectedMetricField, ...restSeries, }; } diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_lens_attributes.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_lens_attributes.ts index 11487afe28e9..d14a26d13d92 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_lens_attributes.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_lens_attributes.ts @@ -12,25 +12,16 @@ import { LayerConfig, LensAttributes } from '../configurations/lens_attributes'; import { useSeriesStorage } from './use_series_storage'; import { getDefaultConfigs } from '../configurations/default_configs'; -import { DataSeries, SeriesUrl, UrlFilter } from '../types'; +import { SeriesUrl, UrlFilter } from '../types'; import { useAppIndexPatternContext } from './use_app_index_pattern'; -export const getFiltersFromDefs = ( - reportDefinitions: SeriesUrl['reportDefinitions'], - dataViewConfig: DataSeries -) => { - const rdfFilters = Object.entries(reportDefinitions ?? {}).map(([field, value]) => { +export const getFiltersFromDefs = (reportDefinitions: SeriesUrl['reportDefinitions']) => { + return Object.entries(reportDefinitions ?? {}).map(([field, value]) => { return { field, values: value, }; }) as UrlFilter[]; - - // let's filter out custom fields - return rdfFilters.filter(({ field }) => { - const rdf = dataViewConfig.reportDefinitions.find(({ field: fd }) => field === fd); - return !rdf?.custom; - }); }; export const useLensAttributes = (): TypedLensByValueInput['attributes'] | null => { @@ -49,25 +40,26 @@ export const useLensAttributes = (): TypedLensByValueInput['attributes'] | null const seriesT = allSeries[seriesIdT]; const indexPattern = indexPatterns?.[seriesT?.dataType]; if (indexPattern && seriesT.reportType && !isEmpty(seriesT.reportDefinitions)) { - const reportViewConfig = getDefaultConfigs({ + const seriesConfig = getDefaultConfigs({ reportType: seriesT.reportType, dataType: seriesT.dataType, indexPattern, }); const filters: UrlFilter[] = (seriesT.filters ?? []).concat( - getFiltersFromDefs(seriesT.reportDefinitions, reportViewConfig) + getFiltersFromDefs(seriesT.reportDefinitions) ); layerConfigs.push({ filters, indexPattern, - reportConfig: reportViewConfig, - breakdown: seriesT.breakdown, - operationType: seriesT.operationType, - seriesType: seriesT.seriesType, - reportDefinitions: seriesT.reportDefinitions ?? {}, + seriesConfig, time: seriesT.time, + breakdown: seriesT.breakdown, + seriesType: seriesT.seriesType, + operationType: seriesT.operationType, + reportDefinitions: seriesT.reportDefinitions ?? {}, + selectedMetricField: seriesT.selectedMetricField, }); } }); diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_series_storage.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_series_storage.tsx index e9ae43950d47..7e9b69a276d0 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_series_storage.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_series_storage.tsx @@ -110,7 +110,7 @@ export function useSeriesStorage() { } function convertFromShortUrl(newValue: ShortUrlSeries): SeriesUrl { - const { dt, op, st, rt, bd, ft, time, rdf, ...restSeries } = newValue; + const { dt, op, st, rt, bd, ft, time, rdf, mt, ...restSeries } = newValue; return { operationType: op, reportType: rt!, @@ -120,6 +120,7 @@ function convertFromShortUrl(newValue: ShortUrlSeries): SeriesUrl { time: time!, reportDefinitions: rdf, dataType: dt!, + selectedMetricField: mt, ...restSeries, }; } @@ -132,6 +133,7 @@ interface ShortUrlSeries { [URL_KEYS.BREAK_DOWN]?: string; [URL_KEYS.FILTERS]?: UrlFilter[]; [URL_KEYS.REPORT_DEFINITIONS]?: URLReportDefinition; + [URL_KEYS.SELECTED_METRIC]?: string; time?: { to: string; from: string; diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_breakdowns.test.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_breakdowns.test.tsx index 203382afc162..a5e5ad3900de 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_breakdowns.test.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_breakdowns.test.tsx @@ -21,7 +21,7 @@ describe('Series Builder ReportBreakdowns', function () { }); it('should render properly', function () { - render(); + render(); screen.getByText('Select an option: , is selected'); screen.getAllByText('Browser family'); @@ -29,7 +29,7 @@ describe('Series Builder ReportBreakdowns', function () { it('should set new series breakdown on change', function () { const { setSeries } = render( - + ); const btn = screen.getByRole('button', { @@ -51,7 +51,7 @@ describe('Series Builder ReportBreakdowns', function () { }); it('should set undefined on new series on no select breakdown', function () { const { setSeries } = render( - + ); const btn = screen.getByRole('button', { diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_breakdowns.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_breakdowns.tsx index e95cd894df5f..fa2d01691ce1 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_breakdowns.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_breakdowns.tsx @@ -7,19 +7,19 @@ import React from 'react'; import { Breakdowns } from '../../series_editor/columns/breakdowns'; -import { DataSeries } from '../../types'; +import { SeriesConfig } from '../../types'; export function ReportBreakdowns({ seriesId, - dataViewSeries, + seriesConfig, }: { - dataViewSeries: DataSeries; + seriesConfig: SeriesConfig; seriesId: string; }) { return ( ); diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_definition_col.test.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_definition_col.test.tsx index 2e5c674b9fad..cac1eccada31 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_definition_col.test.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_definition_col.test.tsx @@ -21,7 +21,7 @@ describe('Series Builder ReportDefinitionCol', function () { mockAppIndexPattern(); const seriesId = 'test-series-id'; - const dataViewSeries = getDefaultConfigs({ + const seriesConfig = getDefaultConfigs({ reportType: 'data-distribution', indexPattern: mockIndexPattern, dataType: 'ux', @@ -41,7 +41,7 @@ describe('Series Builder ReportDefinitionCol', function () { mockUseValuesList([{ label: 'elastic-co', count: 10 }]); it('should render properly', async function () { - render(, { + render(, { initSeries, }); @@ -52,7 +52,7 @@ describe('Series Builder ReportDefinitionCol', function () { }); it('should render selected report definitions', async function () { - render(, { + render(, { initSeries, }); @@ -63,7 +63,7 @@ describe('Series Builder ReportDefinitionCol', function () { it('should be able to remove selected definition', async function () { const { setSeries } = render( - , + , { initSeries } ); diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_definition_col.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_definition_col.tsx index 47962af0d4bc..0c620abf56e8 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_definition_col.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_definition_col.tsx @@ -9,39 +9,40 @@ import React from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiHorizontalRule } from '@elastic/eui'; import styled from 'styled-components'; import { useSeriesStorage } from '../../hooks/use_series_storage'; -import { CustomReportField } from '../custom_report_field'; -import { DataSeries, URLReportDefinition } from '../../types'; +import { ReportMetricOptions } from '../report_metric_options'; +import { SeriesConfig } from '../../types'; import { SeriesChartTypesSelect } from './chart_types'; import { OperationTypeSelect } from './operation_type_select'; import { DatePickerCol } from './date_picker_col'; import { parseCustomFieldName } from '../../configurations/lens_attributes'; import { ReportDefinitionField } from './report_definition_field'; -function getColumnType(dataView: DataSeries, selectedDefinition: URLReportDefinition) { - const { reportDefinitions } = dataView; - const customColumn = reportDefinitions.find((item) => item.custom); - if (customColumn?.field && selectedDefinition[customColumn?.field]) { - const { columnType } = parseCustomFieldName(customColumn.field, dataView, selectedDefinition); +function getColumnType(seriesConfig: SeriesConfig, selectedMetricField?: string) { + const { columnType } = parseCustomFieldName(seriesConfig, selectedMetricField); - return columnType; - } - return null; + return columnType; } export function ReportDefinitionCol({ - dataViewSeries, + seriesConfig, seriesId, }: { - dataViewSeries: DataSeries; + seriesConfig: SeriesConfig; seriesId: string; }) { const { getSeries, setSeries } = useSeriesStorage(); const series = getSeries(seriesId); - const { reportDefinitions: selectedReportDefinitions = {} } = series ?? {}; + const { reportDefinitions: selectedReportDefinitions = {}, selectedMetricField } = series ?? {}; - const { reportDefinitions, defaultSeriesType, hasOperationType, yAxisColumns } = dataViewSeries; + const { + definitionFields, + defaultSeriesType, + hasOperationType, + yAxisColumns, + metricOptions, + } = seriesConfig; const onChange = (field: string, value?: string[]) => { if (!value?.[0]) { @@ -58,7 +59,7 @@ export function ReportDefinitionCol({ } }; - const columnType = getColumnType(dataViewSeries, selectedReportDefinitions); + const columnType = getColumnType(seriesConfig, selectedMetricField); return ( @@ -66,20 +67,21 @@ export function ReportDefinitionCol({ - {reportDefinitions.map(({ field, custom, options }) => ( + {definitionFields.map((field) => ( - {!custom ? ( - - ) : ( - - )} + ))} + {metricOptions && ( + + + + )} {(hasOperationType || columnType === 'operation') && ( diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_definition_field.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_definition_field.tsx index 51f4edaae93d..61f6f85dbeaf 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_definition_field.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_definition_field.tsx @@ -15,16 +15,16 @@ import { ESFilter } from '../../../../../../../../../src/core/types/elasticsearc import { PersistableFilter } from '../../../../../../../lens/common'; import { ExistsFilter } from '../../../../../../../../../src/plugins/data/common/es_query/filters'; import { buildPhrasesFilter } from '../../configurations/utils'; -import { DataSeries } from '../../types'; +import { SeriesConfig } from '../../types'; interface Props { seriesId: string; field: string; - dataSeries: DataSeries; + seriesConfig: SeriesConfig; onChange: (field: string, value?: string[]) => void; } -export function ReportDefinitionField({ seriesId, field, dataSeries, onChange }: Props) { +export function ReportDefinitionField({ seriesId, field, seriesConfig, onChange }: Props) { const { getSeries } = useSeriesStorage(); const series = getSeries(seriesId); @@ -33,11 +33,11 @@ export function ReportDefinitionField({ seriesId, field, dataSeries, onChange }: const { reportDefinitions: selectedReportDefinitions = {} } = series; - const { labels, filters, reportDefinitions } = dataSeries; + const { labels, baseFilters, definitionFields } = seriesConfig; const queryFilters = useMemo(() => { const filtersN: ESFilter[] = []; - (filters ?? []).forEach((qFilter: PersistableFilter | ExistsFilter) => { + (baseFilters ?? []).forEach((qFilter: PersistableFilter | ExistsFilter) => { if (qFilter.query) { filtersN.push(qFilter.query); } @@ -48,8 +48,8 @@ export function ReportDefinitionField({ seriesId, field, dataSeries, onChange }: }); if (!isEmpty(selectedReportDefinitions)) { - reportDefinitions.forEach(({ field: fieldT, custom }) => { - if (!custom && indexPattern && selectedReportDefinitions?.[fieldT] && fieldT !== field) { + definitionFields.forEach((fieldT) => { + if (indexPattern && selectedReportDefinitions?.[fieldT] && fieldT !== field) { const values = selectedReportDefinitions?.[fieldT]; const valueFilter = buildPhrasesFilter(fieldT, values, indexPattern)[0]; filtersN.push(valueFilter.query); @@ -59,7 +59,7 @@ export function ReportDefinitionField({ seriesId, field, dataSeries, onChange }: return filtersN; // eslint-disable-next-line react-hooks/exhaustive-deps - }, [JSON.stringify(selectedReportDefinitions), JSON.stringify(filters)]); + }, [JSON.stringify(selectedReportDefinitions), JSON.stringify(baseFilters)]); return ( diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_filters.test.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_filters.test.tsx index f35639388aac..0b183b5f20c0 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_filters.test.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_filters.test.tsx @@ -21,7 +21,7 @@ describe('Series Builder ReportFilters', function () { }); it('should render properly', function () { - render(); + render(); screen.getByText('Add filter'); }); diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_filters.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_filters.tsx index 4571ecfe252e..d5938c5387e8 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_filters.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_filters.tsx @@ -7,23 +7,23 @@ import React from 'react'; import { SeriesFilter } from '../../series_editor/columns/series_filter'; -import { DataSeries } from '../../types'; +import { SeriesConfig } from '../../types'; export function ReportFilters({ - dataViewSeries, + seriesConfig, seriesId, }: { - dataViewSeries: DataSeries; + seriesConfig: SeriesConfig; seriesId: string; }) { return ( ); } diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_types_col.test.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_types_col.test.tsx index f7cfe06c0d92..07048d47b2bc 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_types_col.test.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_types_col.test.tsx @@ -38,7 +38,7 @@ describe('ReportTypesCol', function () { expect(setSeries).toHaveBeenCalledWith(seriesId, { breakdown: 'user_agent.name', dataType: 'ux', - reportDefinitions: {}, + selectedMetricField: undefined, reportType: 'kpi-over-time', time: { from: 'now-15m', to: 'now' }, }); diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_types_col.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_types_col.tsx index 64c7b48c668b..396f8c4f1deb 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_types_col.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/columns/report_types_col.tsx @@ -15,7 +15,7 @@ import { ReportViewType, SeriesUrl } from '../../types'; import { useSeriesStorage } from '../../hooks/use_series_storage'; import { DEFAULT_TIME } from '../../configurations/constants'; import { useAppIndexPatternContext } from '../../hooks/use_app_index_pattern'; -import { ReportTypeItem, SELECT_DATA_TYPE } from '../series_builder'; +import { ReportTypeItem } from '../series_builder'; interface Props { seriesId: string; @@ -30,7 +30,12 @@ export function ReportTypesCol({ seriesId, reportTypes }: Props) { const { loading, hasData } = useAppIndexPatternContext(restSeries.dataType); if (!restSeries.dataType) { - return {SELECT_DATA_TYPE}; + return ( + + ); } if (!loading && !hasData) { @@ -72,8 +77,7 @@ export function ReportTypesCol({ seriesId, reportTypes }: Props) { setSeries(seriesId, { ...restSeries, reportType, - operationType: undefined, - reportDefinitions: {}, + selectedMetricField: undefined, time: restSeries?.time ?? DEFAULT_TIME, }); } diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/custom_report_field.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/report_metric_options.tsx similarity index 66% rename from x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/custom_report_field.tsx rename to x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/report_metric_options.tsx index 201df9628e13..a2a3e34c2183 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/custom_report_field.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/report_metric_options.tsx @@ -8,28 +8,26 @@ import React from 'react'; import { EuiSuperSelect } from '@elastic/eui'; import { useSeriesStorage } from '../hooks/use_series_storage'; -import { ReportDefinition } from '../types'; +import { SeriesConfig } from '../types'; interface Props { - field: string; seriesId: string; defaultValue?: string; - options: ReportDefinition['options']; + options: SeriesConfig['metricOptions']; } -export function CustomReportField({ field, seriesId, options: opts }: Props) { +export function ReportMetricOptions({ seriesId, options: opts }: Props) { const { getSeries, setSeries } = useSeriesStorage(); const series = getSeries(seriesId); - const { reportDefinitions: rtd = {} } = series; - const onChange = (value: string) => { - setSeries(seriesId, { ...series, reportDefinitions: { ...rtd, [field]: [value] } }); + setSeries(seriesId, { + ...series, + selectedMetricField: value, + }); }; - const { reportDefinitions } = series; - const options = opts ?? []; return ( @@ -41,7 +39,7 @@ export function CustomReportField({ field, seriesId, options: opts }: Props) { value: fd || id, inputDisplay: label, }))} - valueOfSelected={reportDefinitions?.[field]?.[0] || options?.[0].field || options?.[0].id} + valueOfSelected={series.selectedMetricField || options?.[0].field || options?.[0].id} onChange={(value) => onChange(value)} /> ); diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/series_builder.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/series_builder.tsx index e596eb6be354..684cf3a210a5 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/series_builder.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_builder/series_builder.tsx @@ -17,7 +17,7 @@ import { EuiSwitch, } from '@elastic/eui'; import { rgba } from 'polished'; -import { AppDataType, DataSeries, ReportViewType, SeriesUrl } from '../types'; +import { AppDataType, SeriesConfig, ReportViewType, SeriesUrl } from '../types'; import { DataTypesCol } from './columns/data_types_col'; import { ReportTypesCol } from './columns/report_types_col'; import { ReportDefinitionCol } from './columns/report_definition_col'; @@ -66,7 +66,7 @@ export const ReportTypes: Record = { interface BuilderItem { id: string; series: SeriesUrl; - seriesConfig?: DataSeries; + seriesConfig?: SeriesConfig; } export function SeriesBuilder({ @@ -142,7 +142,7 @@ export function SeriesBuilder({ return loading ? ( LOADING_VIEW ) : reportType ? ( - + ) : ( SELECT_REPORT_TYPE ); @@ -159,7 +159,7 @@ export function SeriesBuilder({ field: 'id', render: (seriesId: string, { series: { reportType }, seriesConfig }: BuilderItem) => reportType && seriesConfig ? ( - + ) : null, }, { @@ -170,7 +170,7 @@ export function SeriesBuilder({ field: 'id', render: (seriesId: string, { series: { reportType }, seriesConfig }: BuilderItem) => reportType && seriesConfig ? ( - + ) : null, }, ...(multiSeries @@ -301,10 +301,3 @@ export const SELECT_REPORT_TYPE = i18n.translate( defaultMessage: 'No report type selected', } ); - -export const SELECT_DATA_TYPE = i18n.translate( - 'xpack.observability.expView.seriesBuilder.selectDataType', - { - defaultMessage: 'No data type selected', - } -); diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/chart_edit_options.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/chart_edit_options.tsx index a0d2fd86482a..207a53e13f1a 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/chart_edit_options.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/chart_edit_options.tsx @@ -8,22 +8,22 @@ import React from 'react'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { Breakdowns } from './columns/breakdowns'; -import { DataSeries } from '../types'; +import { SeriesConfig } from '../types'; import { ChartOptions } from './columns/chart_options'; interface Props { - series: DataSeries; + seriesConfig: SeriesConfig; seriesId: string; - breakdowns: string[]; + breakdownFields: string[]; } -export function ChartEditOptions({ series, seriesId, breakdowns }: Props) { +export function ChartEditOptions({ seriesConfig, seriesId, breakdownFields }: Props) { return ( - + - + ); diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/columns/breakdowns.test.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/columns/breakdowns.test.tsx index d180bf4529c2..84568e1c5068 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/columns/breakdowns.test.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/columns/breakdowns.test.tsx @@ -23,8 +23,8 @@ describe('Breakdowns', function () { render( ); @@ -37,8 +37,8 @@ describe('Breakdowns', function () { const { setSeries } = render( , { initSeries } ); diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/columns/breakdowns.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/columns/breakdowns.tsx index cf24cb31951b..2237935d466a 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/columns/breakdowns.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/columns/breakdowns.tsx @@ -10,15 +10,15 @@ import { EuiSuperSelect } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { useSeriesStorage } from '../../hooks/use_series_storage'; import { USE_BREAK_DOWN_COLUMN } from '../../configurations/constants'; -import { DataSeries } from '../../types'; +import { SeriesConfig } from '../../types'; interface Props { seriesId: string; breakdowns: string[]; - reportViewConfig: DataSeries; + seriesConfig: SeriesConfig; } -export function Breakdowns({ reportViewConfig, seriesId, breakdowns = [] }: Props) { +export function Breakdowns({ seriesConfig, seriesId, breakdowns = [] }: Props) { const { setSeries, getSeries } = useSeriesStorage(); const series = getSeries(seriesId); @@ -40,11 +40,11 @@ export function Breakdowns({ reportViewConfig, seriesId, breakdowns = [] }: Prop } }; - const hasUseBreakdownColumn = reportViewConfig.xAxisColumn.sourceField === USE_BREAK_DOWN_COLUMN; + const hasUseBreakdownColumn = seriesConfig.xAxisColumn.sourceField === USE_BREAK_DOWN_COLUMN; const items = breakdowns.map((breakdown) => ({ id: breakdown, - label: reportViewConfig.labels[breakdown], + label: seriesConfig.labels[breakdown], })); if (!hasUseBreakdownColumn) { diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/columns/chart_options.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/columns/chart_options.tsx index 08664ac75eb8..f2a6377fd9b7 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/columns/chart_options.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/columns/chart_options.tsx @@ -7,22 +7,25 @@ import React from 'react'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -import { DataSeries } from '../../types'; +import { SeriesConfig } from '../../types'; import { OperationTypeSelect } from '../../series_builder/columns/operation_type_select'; import { SeriesChartTypesSelect } from '../../series_builder/columns/chart_types'; interface Props { - series: DataSeries; + seriesConfig: SeriesConfig; seriesId: string; } -export function ChartOptions({ series, seriesId }: Props) { +export function ChartOptions({ seriesConfig, seriesId }: Props) { return ( - + - {series.hasOperationType && ( + {seriesConfig.hasOperationType && ( diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/columns/filter_expanded.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/columns/filter_expanded.tsx index 0f0cec0fbfcf..6f9d8efdc068 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/columns/filter_expanded.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/columns/filter_expanded.tsx @@ -14,7 +14,7 @@ import { QueryDslQueryContainer } from '@elastic/elasticsearch/api/types'; import { map } from 'lodash'; import { useAppIndexPatternContext } from '../../hooks/use_app_index_pattern'; import { useSeriesStorage } from '../../hooks/use_series_storage'; -import { DataSeries, UrlFilter } from '../../types'; +import { SeriesConfig, UrlFilter } from '../../types'; import { FilterValueButton } from './filter_value_btn'; import { useValuesList } from '../../../../../hooks/use_values_list'; import { euiStyled } from '../../../../../../../../../src/plugins/kibana_react/common'; @@ -29,7 +29,7 @@ interface Props { isNegated?: boolean; goBack: () => void; nestedField?: string; - filters: DataSeries['filters']; + filters: SeriesConfig['baseFilters']; } export function FilterExpanded({ diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/columns/series_filter.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/columns/series_filter.tsx index b7e20b341b57..02144c6929b3 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/columns/series_filter.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/columns/series_filter.tsx @@ -16,16 +16,16 @@ import { EuiFlexGroup, } from '@elastic/eui'; import { FilterExpanded } from './filter_expanded'; -import { DataSeries } from '../../types'; +import { SeriesConfig } from '../../types'; import { FieldLabels } from '../../configurations/constants/constants'; import { SelectedFilters } from '../selected_filters'; import { useSeriesStorage } from '../../hooks/use_series_storage'; interface Props { seriesId: string; - defaultFilters: DataSeries['defaultFilters']; - filters: DataSeries['filters']; - series: DataSeries; + filterFields: SeriesConfig['filterFields']; + baseFilters: SeriesConfig['baseFilters']; + seriesConfig: SeriesConfig; isNew?: boolean; labels?: Record; } @@ -38,18 +38,18 @@ export interface Field { } export function SeriesFilter({ - series, + seriesConfig, isNew, seriesId, - defaultFilters = [], - filters, + filterFields = [], + baseFilters, labels, }: Props) { const [isPopoverVisible, setIsPopoverVisible] = useState(false); const [selectedField, setSelectedField] = useState(); - const options: Field[] = defaultFilters.map((field) => { + const options: Field[] = filterFields.map((field) => { if (typeof field === 'string') { return { label: labels?.[field] ?? FieldLabels[field], field }; } @@ -111,7 +111,7 @@ export function SeriesFilter({ goBack={() => { setSelectedField(undefined); }} - filters={filters} + filters={baseFilters} /> ) : null; @@ -122,7 +122,7 @@ export function SeriesFilter({ return ( - + , { initSeries }); + render(, { + initSeries, + }); await waitFor(() => { screen.getByText('Chrome'); diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/selected_filters.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/selected_filters.tsx index 33496e617a3a..5d2ce6ba8495 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/selected_filters.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/selected_filters.tsx @@ -9,28 +9,28 @@ import React, { Fragment } from 'react'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { useSeriesStorage } from '../hooks/use_series_storage'; import { FilterLabel } from '../components/filter_label'; -import { DataSeries, UrlFilter } from '../types'; +import { SeriesConfig, UrlFilter } from '../types'; import { useAppIndexPatternContext } from '../hooks/use_app_index_pattern'; import { useSeriesFilters } from '../hooks/use_series_filters'; import { getFiltersFromDefs } from '../hooks/use_lens_attributes'; interface Props { seriesId: string; - series: DataSeries; + seriesConfig: SeriesConfig; isNew?: boolean; } -export function SelectedFilters({ seriesId, isNew, series: dataSeries }: Props) { +export function SelectedFilters({ seriesId, isNew, seriesConfig }: Props) { const { getSeries } = useSeriesStorage(); const series = getSeries(seriesId); const { reportDefinitions = {} } = series; - const { labels } = dataSeries; + const { labels } = seriesConfig; const filters: UrlFilter[] = series.filters ?? []; - let definitionFilters: UrlFilter[] = getFiltersFromDefs(reportDefinitions, dataSeries); + let definitionFilters: UrlFilter[] = getFiltersFromDefs(reportDefinitions); // we don't want to display report definition filters in new series view if (isNew) { diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/series_editor.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/series_editor.tsx index bcceeb204a31..c3cc8484d175 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/series_editor.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/series_editor/series_editor.tsx @@ -10,7 +10,7 @@ import { i18n } from '@kbn/i18n'; import { EuiBasicTable, EuiIcon, EuiSpacer, EuiText } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { SeriesFilter } from './columns/series_filter'; -import { DataSeries } from '../types'; +import { SeriesConfig } from '../types'; import { NEW_SERIES_KEY, useSeriesStorage } from '../hooks/use_series_storage'; import { getDefaultConfigs } from '../configurations/default_configs'; import { DatePickerCol } from './columns/date_picker_col'; @@ -19,7 +19,7 @@ import { SeriesActions } from './columns/series_actions'; import { ChartEditOptions } from './chart_edit_options'; interface EditItem { - seriesConfig: DataSeries; + seriesConfig: SeriesConfig; id: string; } @@ -48,10 +48,10 @@ export function SeriesEditor() { width: '15%', render: (seriesId: string, { seriesConfig, id }: EditItem) => ( ), }, @@ -64,8 +64,8 @@ export function SeriesEditor() { render: (seriesId: string, { seriesConfig, id }: EditItem) => ( ), }, @@ -123,7 +123,7 @@ export function SeriesEditor() { rowHeader="firstName" columns={columns} noItemsMessage={i18n.translate('xpack.observability.expView.seriesEditor.seriesNotFound', { - defaultMessage: 'No series found, please add a series.', + defaultMessage: 'No series found. Please add a series.', })} cellProps={{ style: { diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/types.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/types.ts index e8fccc5baab3..ad7c654c9a16 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/types.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/types.ts @@ -37,31 +37,27 @@ export interface ColumnFilter { query: string; } -export interface ReportDefinition { - field: string; - required?: boolean; - custom?: boolean; - options?: Array<{ - id: string; - field?: string; - label: string; - description?: string; - columnType?: 'range' | 'operation' | 'FILTER_RECORDS' | 'TERMS_COLUMN'; - columnFilters?: ColumnFilter[]; - timeScale?: string; - }>; +export interface MetricOption { + id: string; + field?: string; + label: string; + description?: string; + columnType?: 'range' | 'operation' | 'FILTER_RECORDS' | 'TERMS_COLUMN'; + columnFilters?: ColumnFilter[]; + timeScale?: string; } -export interface DataSeries { +export interface SeriesConfig { reportType: ReportViewType; xAxisColumn: Partial | Partial; yAxisColumns: Array>; - breakdowns: string[]; + breakdownFields: string[]; defaultSeriesType: SeriesType; - defaultFilters: Array; + filterFields: Array; seriesTypes: SeriesType[]; - filters?: PersistableFilter[] | ExistsFilter[]; - reportDefinitions: ReportDefinition[]; + baseFilters?: PersistableFilter[] | ExistsFilter[]; + definitionFields: string[]; + metricOptions?: MetricOption[]; labels: Record; hasOperationType: boolean; palette?: PaletteOutput; @@ -83,6 +79,7 @@ export interface SeriesUrl { operationType?: OperationType; dataType: AppDataType; reportDefinitions?: URLReportDefinition; + selectedMetricField?: string; isNew?: boolean; }