mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Exploratory view] Use index patterns for formatting (#96280)
This commit is contained in:
parent
93965343e5
commit
391e92ead3
65 changed files with 470 additions and 123 deletions
1
.github/CODEOWNERS
vendored
1
.github/CODEOWNERS
vendored
|
@ -79,6 +79,7 @@
|
|||
|
||||
# Uptime
|
||||
/x-pack/plugins/uptime @elastic/uptime
|
||||
/x-pack/plugins/observability/public/components/shared/exploratory_view @elastic/uptime
|
||||
/x-pack/test/functional_with_es_ssl/apps/uptime @elastic/uptime
|
||||
/x-pack/test/functional/apps/uptime @elastic/uptime
|
||||
/x-pack/test/api_integration/apis/uptime @elastic/uptime
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
import sinon from 'sinon';
|
||||
|
||||
import { CoreSetup } from 'src/core/public';
|
||||
import { SerializedFieldFormat } from 'src/plugins/expressions/public';
|
||||
import { IFieldType, FieldSpec } from '../../common/index_patterns';
|
||||
import { IndexPattern, indexPatterns, KBN_FIELD_TYPES, fieldList } from '../';
|
||||
import { getFieldFormatsRegistry } from '../test_utils';
|
||||
|
@ -51,6 +52,7 @@ export class StubIndexPattern {
|
|||
_reindexFields: Function;
|
||||
stubSetFieldFormat: Function;
|
||||
fields?: FieldSpec[];
|
||||
setFieldFormat: (fieldName: string, format: SerializedFieldFormat) => void;
|
||||
|
||||
constructor(
|
||||
pattern: string,
|
||||
|
@ -74,6 +76,10 @@ export class StubIndexPattern {
|
|||
this.metaFields = ['_id', '_type', '_source'];
|
||||
this.fieldFormatMap = {};
|
||||
|
||||
this.setFieldFormat = (fieldName: string, format: SerializedFieldFormat) => {
|
||||
this.fieldFormatMap[fieldName] = format;
|
||||
};
|
||||
|
||||
this.getComputedFields = IndexPattern.prototype.getComputedFields.bind(this);
|
||||
this.flattenHit = indexPatterns.flattenHitWrapper(
|
||||
(this as unknown) as IndexPattern,
|
||||
|
|
|
@ -543,6 +543,7 @@ exports[`discover sidebar field details footer renders properly 1`] = `
|
|||
"_source",
|
||||
],
|
||||
"popularizeField": [Function],
|
||||
"setFieldFormat": [Function],
|
||||
"stubSetFieldFormat": [Function],
|
||||
"timeFieldName": "time",
|
||||
"title": "logstash-*",
|
||||
|
|
|
@ -21,7 +21,7 @@ export type {
|
|||
YAxisMode,
|
||||
XYCurveType,
|
||||
} from './xy_visualization/types';
|
||||
export type { DataType } from './types';
|
||||
export type { DataType, OperationMetadata } from './types';
|
||||
export type {
|
||||
PieVisualizationState,
|
||||
PieLayerState,
|
||||
|
|
|
@ -18,7 +18,7 @@ const createStartContract = (): Start => {
|
|||
}),
|
||||
canUseEditor: jest.fn(() => true),
|
||||
navigateToPrefilledEditor: jest.fn(),
|
||||
getXyVisTypes: jest.fn().mockReturnValue(new Promise(() => visualizationTypes)),
|
||||
getXyVisTypes: jest.fn().mockReturnValue(new Promise((resolve) => resolve(visualizationTypes))),
|
||||
};
|
||||
return startContract;
|
||||
};
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { ConfigProps, DataSeries } from '../types';
|
||||
import { FieldLabels } from './constants';
|
||||
import { buildPhraseFilter } from './utils';
|
||||
import { OperationType } from '../../../../../../lens/public';
|
||||
import { ConfigProps, DataSeries } from '../../types';
|
||||
import { FieldLabels } from '../constants';
|
||||
import { buildPhraseFilter } from '../utils';
|
||||
import { OperationType } from '../../../../../../../lens/public';
|
||||
|
||||
export function getServiceLatencyLensConfig({ seriesId, indexPattern }: ConfigProps): DataSeries {
|
||||
return {
|
||||
|
@ -20,7 +20,7 @@ export function getServiceLatencyLensConfig({ seriesId, indexPattern }: ConfigPr
|
|||
sourceField: '@timestamp',
|
||||
},
|
||||
yAxisColumn: {
|
||||
operationType: 'avg' as OperationType,
|
||||
operationType: 'average' as OperationType,
|
||||
sourceField: 'transaction.duration.us',
|
||||
label: 'Latency',
|
||||
},
|
|
@ -5,10 +5,10 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { ConfigProps, DataSeries } from '../types';
|
||||
import { FieldLabels } from './constants';
|
||||
import { buildPhraseFilter } from './utils';
|
||||
import { OperationType } from '../../../../../../lens/public';
|
||||
import { ConfigProps, DataSeries } from '../../types';
|
||||
import { FieldLabels } from '../constants/constants';
|
||||
import { buildPhraseFilter } from '../utils';
|
||||
import { OperationType } from '../../../../../../../lens/public';
|
||||
|
||||
export function getServiceThroughputLensConfig({
|
||||
seriesId,
|
||||
|
@ -23,7 +23,7 @@ export function getServiceThroughputLensConfig({
|
|||
sourceField: '@timestamp',
|
||||
},
|
||||
yAxisColumn: {
|
||||
operationType: 'avg' as OperationType,
|
||||
operationType: 'average' as OperationType,
|
||||
sourceField: 'transaction.duration.us',
|
||||
label: 'Throughput',
|
||||
},
|
|
@ -5,14 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { AppDataType, ReportViewTypeId } from '../types';
|
||||
import {
|
||||
CLS_FIELD,
|
||||
FCP_FIELD,
|
||||
FID_FIELD,
|
||||
LCP_FIELD,
|
||||
TBT_FIELD,
|
||||
} from './data/elasticsearch_fieldnames';
|
||||
import { AppDataType, ReportViewTypeId } from '../../types';
|
||||
import { CLS_FIELD, FCP_FIELD, FID_FIELD, LCP_FIELD, TBT_FIELD } from './elasticsearch_fieldnames';
|
||||
|
||||
export const FieldLabels: Record<string, string> = {
|
||||
'user_agent.name': 'Browser family',
|
||||
|
@ -24,10 +18,10 @@ export const FieldLabels: Record<string, string> = {
|
|||
'service.name': 'Service Name',
|
||||
'service.environment': 'Environment',
|
||||
|
||||
[LCP_FIELD]: 'Largest contentful paint',
|
||||
[FCP_FIELD]: 'First contentful paint',
|
||||
[TBT_FIELD]: 'Total blocking time',
|
||||
[FID_FIELD]: 'First input delay',
|
||||
[LCP_FIELD]: 'Largest contentful paint (Seconds)',
|
||||
[FCP_FIELD]: 'First contentful paint (Seconds)',
|
||||
[TBT_FIELD]: 'Total blocking time (Seconds)',
|
||||
[FID_FIELD]: 'First input delay (Seconds)',
|
||||
[CLS_FIELD]: 'Cumulative layout shift',
|
||||
|
||||
'monitor.id': 'Monitor Id',
|
||||
|
@ -38,6 +32,7 @@ export const FieldLabels: Record<string, string> = {
|
|||
'monitor.name': 'Monitor name',
|
||||
'monitor.type': 'Monitor Type',
|
||||
'url.port': 'Port',
|
||||
'url.full': 'Url',
|
||||
tags: 'Tags',
|
||||
|
||||
// custom
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* 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 * from './constants';
|
|
@ -6,16 +6,16 @@
|
|||
*/
|
||||
|
||||
import { ReportViewTypes } from '../types';
|
||||
import { getPerformanceDistLensConfig } from './performance_dist_config';
|
||||
import { getMonitorDurationConfig } from './monitor_duration_config';
|
||||
import { getServiceLatencyLensConfig } from './service_latency_config';
|
||||
import { getMonitorPingsConfig } from './monitor_pings_config';
|
||||
import { getServiceThroughputLensConfig } from './service_throughput_config';
|
||||
import { getKPITrendsLensConfig } from './kpi_trends_config';
|
||||
import { getCPUUsageLensConfig } from './cpu_usage_config';
|
||||
import { getMemoryUsageLensConfig } from './memory_usage_config';
|
||||
import { getNetworkActivityLensConfig } from './network_activity_config';
|
||||
import { getLogsFrequencyLensConfig } from './logs_frequency_config';
|
||||
import { getPerformanceDistLensConfig } from './rum/performance_dist_config';
|
||||
import { getMonitorDurationConfig } from './synthetics/monitor_duration_config';
|
||||
import { getServiceLatencyLensConfig } from './apm/service_latency_config';
|
||||
import { getMonitorPingsConfig } from './synthetics/monitor_pings_config';
|
||||
import { getServiceThroughputLensConfig } from './apm/service_throughput_config';
|
||||
import { getKPITrendsLensConfig } from './rum/kpi_trends_config';
|
||||
import { getCPUUsageLensConfig } from './metrics/cpu_usage_config';
|
||||
import { getMemoryUsageLensConfig } from './metrics/memory_usage_config';
|
||||
import { getNetworkActivityLensConfig } from './metrics/network_activity_config';
|
||||
import { getLogsFrequencyLensConfig } from './logs/logs_frequency_config';
|
||||
import { IIndexPattern } from '../../../../../../../../src/plugins/data/common/index_patterns';
|
||||
|
||||
interface Props {
|
||||
|
|
|
@ -8,9 +8,8 @@
|
|||
import { LensAttributes } from './lens_attributes';
|
||||
import { mockIndexPattern } from '../rtl_helpers';
|
||||
import { getDefaultConfigs } from './default_configs';
|
||||
import { sampleAttribute } from './data/sample_attribute';
|
||||
import { LCP_FIELD, SERVICE_NAME } from './data/elasticsearch_fieldnames';
|
||||
import { USER_AGENT_NAME } from './data/elasticsearch_fieldnames';
|
||||
import { sampleAttribute } from './test_data/sample_attribute';
|
||||
import { LCP_FIELD, SERVICE_NAME, USER_AGENT_NAME } from './constants/elasticsearch_fieldnames';
|
||||
|
||||
describe('Lens Attribute', () => {
|
||||
const reportViewConfig = getDefaultConfigs({
|
||||
|
@ -93,7 +92,7 @@ describe('Lens Attribute', () => {
|
|||
expect(lnsAttr.getNumberColumn('transaction.duration.us')).toEqual({
|
||||
dataType: 'number',
|
||||
isBucketed: true,
|
||||
label: 'Page load time',
|
||||
label: 'Page load time (Seconds)',
|
||||
operationType: 'range',
|
||||
params: {
|
||||
maxBars: 'auto',
|
||||
|
@ -129,7 +128,7 @@ describe('Lens Attribute', () => {
|
|||
expect(lnsAttr.getXAxis()).toEqual({
|
||||
dataType: 'number',
|
||||
isBucketed: true,
|
||||
label: 'Page load time',
|
||||
label: 'Page load time (Seconds)',
|
||||
operationType: 'range',
|
||||
params: {
|
||||
maxBars: 'auto',
|
||||
|
@ -154,7 +153,7 @@ describe('Lens Attribute', () => {
|
|||
'x-axis-column': {
|
||||
dataType: 'number',
|
||||
isBucketed: true,
|
||||
label: 'Page load time',
|
||||
label: 'Page load time (Seconds)',
|
||||
operationType: 'range',
|
||||
params: {
|
||||
maxBars: 'auto',
|
||||
|
@ -318,7 +317,7 @@ describe('Lens Attribute', () => {
|
|||
'x-axis-column': {
|
||||
dataType: 'number',
|
||||
isBucketed: true,
|
||||
label: 'Page load time',
|
||||
label: 'Page load time (Seconds)',
|
||||
operationType: 'range',
|
||||
params: {
|
||||
maxBars: 'auto',
|
||||
|
@ -363,7 +362,7 @@ describe('Lens Attribute', () => {
|
|||
'x-axis-column': {
|
||||
dataType: 'number',
|
||||
isBucketed: true,
|
||||
label: 'Page load time',
|
||||
label: 'Page load time (Seconds)',
|
||||
operationType: 'range',
|
||||
params: {
|
||||
maxBars: 'auto',
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { DataSeries } from '../types';
|
||||
import { FieldLabels } from './constants';
|
||||
import { DataSeries } from '../../types';
|
||||
import { FieldLabels } from '../constants';
|
||||
|
||||
interface Props {
|
||||
seriesId: string;
|
|
@ -5,9 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { DataSeries } from '../types';
|
||||
import { FieldLabels } from './constants';
|
||||
import { OperationType } from '../../../../../../lens/public';
|
||||
import { DataSeries } from '../../types';
|
||||
import { FieldLabels } from '../constants';
|
||||
import { OperationType } from '../../../../../../../lens/public';
|
||||
|
||||
interface Props {
|
||||
seriesId: string;
|
||||
|
@ -23,7 +23,7 @@ export function getCPUUsageLensConfig({ seriesId }: Props): DataSeries {
|
|||
sourceField: '@timestamp',
|
||||
},
|
||||
yAxisColumn: {
|
||||
operationType: 'avg' as OperationType,
|
||||
operationType: 'average' as OperationType,
|
||||
sourceField: 'system.cpu.user.pct',
|
||||
label: 'CPU Usage %',
|
||||
},
|
|
@ -5,9 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { DataSeries } from '../types';
|
||||
import { FieldLabels } from './constants';
|
||||
import { OperationType } from '../../../../../../lens/public';
|
||||
import { DataSeries } from '../../types';
|
||||
import { FieldLabels } from '../constants';
|
||||
import { OperationType } from '../../../../../../../lens/public';
|
||||
|
||||
interface Props {
|
||||
seriesId: string;
|
||||
|
@ -23,7 +23,7 @@ export function getMemoryUsageLensConfig({ seriesId }: Props): DataSeries {
|
|||
sourceField: '@timestamp',
|
||||
},
|
||||
yAxisColumn: {
|
||||
operationType: 'avg' as OperationType,
|
||||
operationType: 'average' as OperationType,
|
||||
sourceField: 'system.memory.used.pct',
|
||||
label: 'Memory Usage %',
|
||||
},
|
|
@ -5,9 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { DataSeries } from '../types';
|
||||
import { FieldLabels } from './constants';
|
||||
import { OperationType } from '../../../../../../lens/public';
|
||||
import { DataSeries } from '../../types';
|
||||
import { FieldLabels } from '../constants';
|
||||
import { OperationType } from '../../../../../../../lens/public';
|
||||
|
||||
interface Props {
|
||||
seriesId: string;
|
||||
|
@ -23,7 +23,7 @@ export function getNetworkActivityLensConfig({ seriesId }: Props): DataSeries {
|
|||
sourceField: '@timestamp',
|
||||
},
|
||||
yAxisColumn: {
|
||||
operationType: 'avg' as OperationType,
|
||||
operationType: 'average' as OperationType,
|
||||
sourceField: 'system.memory.used.pct',
|
||||
},
|
||||
hasMetricType: true,
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* 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 { FieldFormat } from '../../types';
|
||||
import {
|
||||
FCP_FIELD,
|
||||
FID_FIELD,
|
||||
LCP_FIELD,
|
||||
TBT_FIELD,
|
||||
TRANSACTION_DURATION,
|
||||
} from '../constants/elasticsearch_fieldnames';
|
||||
|
||||
export const rumFieldFormats: FieldFormat[] = [
|
||||
{
|
||||
field: TRANSACTION_DURATION,
|
||||
format: {
|
||||
id: 'duration',
|
||||
params: {
|
||||
inputFormat: 'microseconds',
|
||||
outputFormat: 'asSeconds',
|
||||
showSuffix: true,
|
||||
outputPrecision: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: FCP_FIELD,
|
||||
format: {
|
||||
id: 'duration',
|
||||
params: {
|
||||
inputFormat: 'milliseconds',
|
||||
outputFormat: 'asSeconds',
|
||||
showSuffix: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: LCP_FIELD,
|
||||
format: {
|
||||
id: 'duration',
|
||||
params: {
|
||||
inputFormat: 'milliseconds',
|
||||
outputFormat: 'asSeconds',
|
||||
showSuffix: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: TBT_FIELD,
|
||||
format: {
|
||||
id: 'duration',
|
||||
params: {
|
||||
inputFormat: 'milliseconds',
|
||||
outputFormat: 'asSeconds',
|
||||
showSuffix: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: FID_FIELD,
|
||||
format: {
|
||||
id: 'duration',
|
||||
params: {
|
||||
inputFormat: 'milliseconds',
|
||||
outputFormat: 'asSeconds',
|
||||
showSuffix: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
|
@ -5,9 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { ConfigProps, DataSeries } from '../types';
|
||||
import { FieldLabels } from './constants';
|
||||
import { buildPhraseFilter } from './utils';
|
||||
import { ConfigProps, DataSeries } from '../../types';
|
||||
import { FieldLabels } from '../constants';
|
||||
import { buildPhraseFilter } from '../utils';
|
||||
import {
|
||||
CLIENT_GEO_COUNTRY_NAME,
|
||||
PROCESSOR_EVENT,
|
||||
|
@ -18,7 +18,7 @@ import {
|
|||
USER_AGENT_NAME,
|
||||
USER_AGENT_OS,
|
||||
USER_AGENT_VERSION,
|
||||
} from './data/elasticsearch_fieldnames';
|
||||
} from '../constants/elasticsearch_fieldnames';
|
||||
|
||||
export function getKPITrendsLensConfig({ seriesId, indexPattern }: ConfigProps): DataSeries {
|
||||
return {
|
|
@ -5,9 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { ConfigProps, DataSeries } from '../types';
|
||||
import { FieldLabels } from './constants';
|
||||
import { buildPhraseFilter } from './utils';
|
||||
import { ConfigProps, DataSeries } from '../../types';
|
||||
import { FieldLabels } from '../constants';
|
||||
import { buildPhraseFilter } from '../utils';
|
||||
import {
|
||||
CLIENT_GEO_COUNTRY_NAME,
|
||||
CLS_FIELD,
|
||||
|
@ -24,7 +24,7 @@ import {
|
|||
USER_AGENT_NAME,
|
||||
USER_AGENT_OS,
|
||||
USER_AGENT_VERSION,
|
||||
} from './data/elasticsearch_fieldnames';
|
||||
} from '../constants/elasticsearch_fieldnames';
|
||||
|
||||
export function getPerformanceDistLensConfig({ seriesId, indexPattern }: ConfigProps): DataSeries {
|
||||
return {
|
||||
|
@ -80,7 +80,7 @@ export function getPerformanceDistLensConfig({ seriesId, indexPattern }: ConfigP
|
|||
labels: {
|
||||
...FieldLabels,
|
||||
[SERVICE_NAME]: 'Web Application',
|
||||
[TRANSACTION_DURATION]: 'Page load time',
|
||||
[TRANSACTION_DURATION]: 'Page load time (Seconds)',
|
||||
},
|
||||
};
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* 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 { FieldFormat } from '../../types';
|
||||
|
||||
export const syntheticsFieldFormats: FieldFormat[] = [
|
||||
{
|
||||
field: 'monitor.duration.us',
|
||||
format: {
|
||||
id: 'duration',
|
||||
params: {
|
||||
inputFormat: 'microseconds',
|
||||
outputFormat: 'asMilliseconds',
|
||||
outputPrecision: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
|
@ -5,9 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { DataSeries } from '../types';
|
||||
import { FieldLabels } from './constants';
|
||||
import { OperationType } from '../../../../../../lens/public';
|
||||
import { DataSeries } from '../../types';
|
||||
import { FieldLabels } from '../constants/constants';
|
||||
import { OperationType } from '../../../../../../../lens/public';
|
||||
|
||||
interface Props {
|
||||
seriesId: string;
|
||||
|
@ -23,7 +23,7 @@ export function getMonitorDurationConfig({ seriesId }: Props): DataSeries {
|
|||
sourceField: '@timestamp',
|
||||
},
|
||||
yAxisColumn: {
|
||||
operationType: 'avg' as OperationType,
|
||||
operationType: 'average' as OperationType,
|
||||
sourceField: 'monitor.duration.us',
|
||||
label: 'Monitor duration (ms)',
|
||||
},
|
|
@ -5,8 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { DataSeries } from '../types';
|
||||
import { FieldLabels } from './constants';
|
||||
import { DataSeries } from '../../types';
|
||||
import { FieldLabels } from '../constants';
|
||||
|
||||
interface Props {
|
||||
seriesId: string;
|
|
@ -21,7 +21,7 @@ export const sampleAttribute = {
|
|||
columns: {
|
||||
'x-axis-column': {
|
||||
sourceField: 'transaction.duration.us',
|
||||
label: 'Page load time',
|
||||
label: 'Page load time (Seconds)',
|
||||
dataType: 'number',
|
||||
operationType: 'range',
|
||||
isBucketed: true,
|
|
@ -5,11 +5,11 @@
|
|||
* 2.0.
|
||||
*/
|
||||
import rison, { RisonValue } from 'rison-node';
|
||||
import type { AllSeries, AllShortSeries } from '../hooks/use_url_strorage';
|
||||
import type { AllSeries, AllShortSeries } from '../hooks/use_url_storage';
|
||||
import type { SeriesUrl } from '../types';
|
||||
import { IIndexPattern } from '../../../../../../../../src/plugins/data/common/index_patterns';
|
||||
import { esFilters } from '../../../../../../../../src/plugins/data/public';
|
||||
import { URL_KEYS } from './url_constants';
|
||||
import { URL_KEYS } from './constants/url_constants';
|
||||
|
||||
export function convertToShortUrl(series: SeriesUrl) {
|
||||
const {
|
||||
|
|
|
@ -10,7 +10,7 @@ import { fireEvent, screen, waitFor } from '@testing-library/dom';
|
|||
import { render, mockUrlStorage, mockCore } from './rtl_helpers';
|
||||
import { ExploratoryView } from './exploratory_view';
|
||||
import { getStubIndexPattern } from '../../../../../../../src/plugins/data/public/test_utils';
|
||||
import * as obsvInd from '../../../utils/observability_index_patterns';
|
||||
import * as obsvInd from './utils/observability_index_patterns';
|
||||
|
||||
describe('ExploratoryView', () => {
|
||||
beforeEach(() => {
|
||||
|
|
|
@ -12,7 +12,7 @@ import { useKibana } from '../../../../../../../src/plugins/kibana_react/public'
|
|||
import { ObservabilityPublicPluginsStart } from '../../../plugin';
|
||||
import { ExploratoryViewHeader } from './header/header';
|
||||
import { SeriesEditor } from './series_editor/series_editor';
|
||||
import { useUrlStorage } from './hooks/use_url_strorage';
|
||||
import { useUrlStorage } from './hooks/use_url_storage';
|
||||
import { useLensAttributes } from './hooks/use_lens_attributes';
|
||||
import { EmptyView } from './components/empty_view';
|
||||
import { useIndexPatternContext } from './hooks/use_default_index_pattern';
|
||||
|
|
|
@ -12,7 +12,7 @@ import { TypedLensByValueInput } from '../../../../../../lens/public';
|
|||
import { useKibana } from '../../../../../../../../src/plugins/kibana_react/public';
|
||||
import { ObservabilityPublicPluginsStart } from '../../../../plugin';
|
||||
import { DataViewLabels } from '../configurations/constants';
|
||||
import { useUrlStorage } from '../hooks/use_url_strorage';
|
||||
import { useUrlStorage } from '../hooks/use_url_storage';
|
||||
|
||||
interface Props {
|
||||
seriesId: string;
|
||||
|
|
|
@ -10,7 +10,7 @@ import { IndexPattern } from '../../../../../../../../src/plugins/data/common';
|
|||
import { AppDataType } from '../types';
|
||||
import { useKibana } from '../../../../../../../../src/plugins/kibana_react/public';
|
||||
import { ObservabilityPublicPluginsStart } from '../../../../plugin';
|
||||
import { ObservabilityIndexPatterns } from '../../../../utils/observability_index_patterns';
|
||||
import { ObservabilityIndexPatterns } from '../utils/observability_index_patterns';
|
||||
|
||||
export interface IIndexPatternContext {
|
||||
indexPattern: IndexPattern;
|
||||
|
|
|
@ -8,12 +8,9 @@ import { useFetcher } from '../../../..';
|
|||
import { IKbnUrlStateStorage } from '../../../../../../../../src/plugins/kibana_utils/public';
|
||||
import { useKibana } from '../../../../../../../../src/plugins/kibana_react/public';
|
||||
import { ObservabilityPublicPluginsStart } from '../../../../plugin';
|
||||
import { AllShortSeries } from './use_url_strorage';
|
||||
import { AllShortSeries } from './use_url_storage';
|
||||
import { ReportToDataTypeMap } from '../configurations/constants';
|
||||
import {
|
||||
DataType,
|
||||
ObservabilityIndexPatterns,
|
||||
} from '../../../../utils/observability_index_patterns';
|
||||
import { DataType, ObservabilityIndexPatterns } from '../utils/observability_index_patterns';
|
||||
|
||||
export const useInitExploratoryView = (storage: IKbnUrlStateStorage) => {
|
||||
const {
|
||||
|
@ -30,7 +27,7 @@ export const useInitExploratoryView = (storage: IKbnUrlStateStorage) => {
|
|||
|
||||
const firstSeries = allSeries[firstSeriesId];
|
||||
|
||||
const { data: indexPattern } = useFetcher(() => {
|
||||
const { data: indexPattern, error } = useFetcher(() => {
|
||||
const obsvIndexP = new ObservabilityIndexPatterns(data);
|
||||
let reportType: DataType = 'apm';
|
||||
if (firstSeries?.rt) {
|
||||
|
@ -40,5 +37,9 @@ export const useInitExploratoryView = (storage: IKbnUrlStateStorage) => {
|
|||
return obsvIndexP.getIndexPattern(reportType);
|
||||
}, [firstSeries?.rt, data]);
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return indexPattern;
|
||||
};
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import { useMemo } from 'react';
|
||||
import { TypedLensByValueInput } from '../../../../../../lens/public';
|
||||
import { LensAttributes } from '../configurations/lens_attributes';
|
||||
import { useUrlStorage } from './use_url_strorage';
|
||||
import { useUrlStorage } from './use_url_storage';
|
||||
import { getDefaultConfigs } from '../configurations/default_configs';
|
||||
|
||||
import { IndexPattern } from '../../../../../../../../src/plugins/data/common';
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { useUrlStorage } from './use_url_strorage';
|
||||
import { useUrlStorage } from './use_url_storage';
|
||||
import { UrlFilter } from '../types';
|
||||
|
||||
export interface UpdateFilter {
|
||||
|
|
|
@ -10,7 +10,7 @@ import { IKbnUrlStateStorage } from '../../../../../../../../src/plugins/kibana_
|
|||
import type { AppDataType, ReportViewTypeId, SeriesUrl, UrlFilter } from '../types';
|
||||
import { convertToShortUrl } from '../configurations/utils';
|
||||
import { OperationType, SeriesType } from '../../../../../../lens/public';
|
||||
import { URL_KEYS } from '../configurations/url_constants';
|
||||
import { URL_KEYS } from '../configurations/constants/url_constants';
|
||||
|
||||
export const UrlStorageContext = createContext<IKbnUrlStateStorage | null>(null);
|
||||
|
|
@ -18,7 +18,7 @@ import {
|
|||
createKbnUrlStateStorage,
|
||||
withNotifyOnErrors,
|
||||
} from '../../../../../../../src/plugins/kibana_utils/public/';
|
||||
import { UrlStorageContextProvider } from './hooks/use_url_strorage';
|
||||
import { UrlStorageContextProvider } from './hooks/use_url_storage';
|
||||
import { useInitExploratoryView } from './hooks/use_init_exploratory_view';
|
||||
import { WithHeaderLayout } from '../../app/layout/with_header';
|
||||
|
||||
|
|
|
@ -23,20 +23,20 @@ import { ObservabilityPublicPluginsStart } from '../../../plugin';
|
|||
import { EuiThemeProvider } from '../../../../../../../src/plugins/kibana_react/common';
|
||||
import { lensPluginMock } from '../../../../../lens/public/mocks';
|
||||
import { IndexPatternContextProvider } from './hooks/use_default_index_pattern';
|
||||
import { AllSeries, UrlStorageContextProvider } from './hooks/use_url_strorage';
|
||||
import { AllSeries, UrlStorageContextProvider } from './hooks/use_url_storage';
|
||||
import {
|
||||
withNotifyOnErrors,
|
||||
createKbnUrlStateStorage,
|
||||
} from '../../../../../../../src/plugins/kibana_utils/public';
|
||||
import * as fetcherHook from '../../../hooks/use_fetcher';
|
||||
import * as useUrlHook from './hooks/use_url_strorage';
|
||||
import * as useUrlHook from './hooks/use_url_storage';
|
||||
import * as useSeriesFilterHook from './hooks/use_series_filters';
|
||||
import * as useHasDataHook from '../../../hooks/use_has_data';
|
||||
import * as useValuesListHook from '../../../hooks/use_values_list';
|
||||
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { getStubIndexPattern } from '../../../../../../../src/plugins/data/public/index_patterns/index_pattern.stub';
|
||||
import indexPatternData from './configurations/data/test_index_pattern.json';
|
||||
import indexPatternData from './configurations/test_data/test_index_pattern.json';
|
||||
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { setIndexPatterns } from '../../../../../../../src/plugins/data/public/services';
|
||||
|
|
|
@ -9,7 +9,7 @@ import React from 'react';
|
|||
import { fireEvent, screen } from '@testing-library/react';
|
||||
import { mockUrlStorage, render } from '../../rtl_helpers';
|
||||
import { dataTypes, DataTypesCol } from './data_types_col';
|
||||
import { NEW_SERIES_KEY } from '../../hooks/use_url_strorage';
|
||||
import { NEW_SERIES_KEY } from '../../hooks/use_url_storage';
|
||||
|
||||
describe('DataTypesCol', function () {
|
||||
it('should render properly', function () {
|
||||
|
|
|
@ -9,7 +9,7 @@ import React from 'react';
|
|||
import { EuiButton, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
|
||||
import { AppDataType } from '../../types';
|
||||
import { useIndexPatternContext } from '../../hooks/use_default_index_pattern';
|
||||
import { NEW_SERIES_KEY, useUrlStorage } from '../../hooks/use_url_strorage';
|
||||
import { NEW_SERIES_KEY, useUrlStorage } from '../../hooks/use_url_storage';
|
||||
|
||||
export const dataTypes: Array<{ id: AppDataType; label: string }> = [
|
||||
{ id: 'synthetics', label: 'Synthetic Monitoring' },
|
||||
|
|
|
@ -10,9 +10,9 @@ import { fireEvent, screen } from '@testing-library/react';
|
|||
import { render } from '../../../../../utils/test_helper';
|
||||
import { getDefaultConfigs } from '../../configurations/default_configs';
|
||||
import { mockIndexPattern, mockUrlStorage } from '../../rtl_helpers';
|
||||
import { NEW_SERIES_KEY } from '../../hooks/use_url_strorage';
|
||||
import { NEW_SERIES_KEY } from '../../hooks/use_url_storage';
|
||||
import { ReportBreakdowns } from './report_breakdowns';
|
||||
import { USER_AGENT_OS } from '../../configurations/data/elasticsearch_fieldnames';
|
||||
import { USER_AGENT_OS } from '../../configurations/constants/elasticsearch_fieldnames';
|
||||
|
||||
describe('Series Builder ReportBreakdowns', function () {
|
||||
const dataViewSeries = getDefaultConfigs({
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import React from 'react';
|
||||
import { Breakdowns } from '../../series_editor/columns/breakdowns';
|
||||
import { NEW_SERIES_KEY } from '../../hooks/use_url_strorage';
|
||||
import { NEW_SERIES_KEY } from '../../hooks/use_url_storage';
|
||||
import { DataSeries } from '../../types';
|
||||
|
||||
export function ReportBreakdowns({ dataViewSeries }: { dataViewSeries: DataSeries }) {
|
||||
|
|
|
@ -9,9 +9,9 @@ import React from 'react';
|
|||
import { fireEvent, screen } from '@testing-library/react';
|
||||
import { getDefaultConfigs } from '../../configurations/default_configs';
|
||||
import { mockIndexPattern, mockUrlStorage, mockUseValuesList, render } from '../../rtl_helpers';
|
||||
import { NEW_SERIES_KEY } from '../../hooks/use_url_strorage';
|
||||
import { NEW_SERIES_KEY } from '../../hooks/use_url_storage';
|
||||
import { ReportDefinitionCol } from './report_definition_col';
|
||||
import { SERVICE_NAME } from '../../configurations/data/elasticsearch_fieldnames';
|
||||
import { SERVICE_NAME } from '../../configurations/constants/elasticsearch_fieldnames';
|
||||
|
||||
describe('Series Builder ReportDefinitionCol', function () {
|
||||
const dataViewSeries = getDefaultConfigs({
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import React from 'react';
|
||||
import { EuiBadge, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
|
||||
import { useIndexPatternContext } from '../../hooks/use_default_index_pattern';
|
||||
import { NEW_SERIES_KEY, useUrlStorage } from '../../hooks/use_url_strorage';
|
||||
import { NEW_SERIES_KEY, useUrlStorage } from '../../hooks/use_url_storage';
|
||||
import { CustomReportField } from '../custom_report_field';
|
||||
import FieldValueSuggestions from '../../../field_value_suggestions';
|
||||
import { DataSeries } from '../../types';
|
||||
|
@ -67,6 +67,7 @@ export function ReportDefinitionCol({ dataViewSeries }: { dataViewSeries: DataSe
|
|||
{rtd?.[field] && (
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiBadge
|
||||
className="globalFilterItem"
|
||||
iconSide="right"
|
||||
iconType="cross"
|
||||
color="hollow"
|
||||
|
|
|
@ -11,7 +11,7 @@ import { render } from '../../../../../utils/test_helper';
|
|||
import { ReportFilters } from './report_filters';
|
||||
import { getDefaultConfigs } from '../../configurations/default_configs';
|
||||
import { mockIndexPattern, mockUrlStorage } from '../../rtl_helpers';
|
||||
import { NEW_SERIES_KEY } from '../../hooks/use_url_strorage';
|
||||
import { NEW_SERIES_KEY } from '../../hooks/use_url_storage';
|
||||
|
||||
describe('Series Builder ReportFilters', function () {
|
||||
const dataViewSeries = getDefaultConfigs({
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import React from 'react';
|
||||
import { SeriesFilter } from '../../series_editor/columns/series_filter';
|
||||
import { NEW_SERIES_KEY } from '../../hooks/use_url_strorage';
|
||||
import { NEW_SERIES_KEY } from '../../hooks/use_url_storage';
|
||||
import { DataSeries } from '../../types';
|
||||
|
||||
export function ReportFilters({ dataViewSeries }: { dataViewSeries: DataSeries }) {
|
||||
|
|
|
@ -9,7 +9,7 @@ import React from 'react';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui';
|
||||
import { ReportViewTypeId, SeriesUrl } from '../../types';
|
||||
import { NEW_SERIES_KEY, useUrlStorage } from '../../hooks/use_url_strorage';
|
||||
import { NEW_SERIES_KEY, useUrlStorage } from '../../hooks/use_url_storage';
|
||||
|
||||
interface Props {
|
||||
reportTypes: Array<{ id: ReportViewTypeId; label: string }>;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import React from 'react';
|
||||
import { EuiSuperSelect } from '@elastic/eui';
|
||||
import { useUrlStorage } from '../hooks/use_url_strorage';
|
||||
import { useUrlStorage } from '../hooks/use_url_storage';
|
||||
import { ReportDefinition } from '../types';
|
||||
|
||||
interface Props {
|
||||
|
|
|
@ -16,7 +16,7 @@ import { ReportTypesCol } from './columns/report_types_col';
|
|||
import { ReportDefinitionCol } from './columns/report_definition_col';
|
||||
import { ReportFilters } from './columns/report_filters';
|
||||
import { ReportBreakdowns } from './columns/report_breakdowns';
|
||||
import { NEW_SERIES_KEY, useUrlStorage } from '../hooks/use_url_strorage';
|
||||
import { NEW_SERIES_KEY, useUrlStorage } from '../hooks/use_url_storage';
|
||||
import { useIndexPatternContext } from '../hooks/use_default_index_pattern';
|
||||
import { getDefaultConfigs } from '../configurations/default_configs';
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import { EuiSuperDatePicker } from '@elastic/eui';
|
||||
import React, { useEffect } from 'react';
|
||||
import { useHasData } from '../../../../hooks/use_has_data';
|
||||
import { useUrlStorage } from '../hooks/use_url_strorage';
|
||||
import { useUrlStorage } from '../hooks/use_url_storage';
|
||||
import { useQuickTimeRanges } from '../../../../hooks/use_quick_time_ranges';
|
||||
|
||||
export interface TimePickerTime {
|
||||
|
|
|
@ -9,9 +9,9 @@ import React from 'react';
|
|||
import { fireEvent, screen } from '@testing-library/react';
|
||||
import { Breakdowns } from './breakdowns';
|
||||
import { mockIndexPattern, mockUrlStorage, render } from '../../rtl_helpers';
|
||||
import { NEW_SERIES_KEY } from '../../hooks/use_url_strorage';
|
||||
import { NEW_SERIES_KEY } from '../../hooks/use_url_storage';
|
||||
import { getDefaultConfigs } from '../../configurations/default_configs';
|
||||
import { USER_AGENT_OS } from '../../configurations/data/elasticsearch_fieldnames';
|
||||
import { USER_AGENT_OS } from '../../configurations/constants/elasticsearch_fieldnames';
|
||||
|
||||
describe('Breakdowns', function () {
|
||||
const dataViewSeries = getDefaultConfigs({
|
||||
|
|
|
@ -9,7 +9,7 @@ import React from 'react';
|
|||
import { EuiSuperSelect } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FieldLabels } from '../../configurations/constants';
|
||||
import { useUrlStorage } from '../../hooks/use_url_strorage';
|
||||
import { useUrlStorage } from '../../hooks/use_url_storage';
|
||||
|
||||
interface Props {
|
||||
seriesId: string;
|
||||
|
|
|
@ -19,7 +19,7 @@ import styled from 'styled-components';
|
|||
import { useKibana } from '../../../../../../../../../src/plugins/kibana_react/public';
|
||||
import { ObservabilityPublicPluginsStart } from '../../../../../plugin';
|
||||
import { useFetcher } from '../../../../..';
|
||||
import { useUrlStorage } from '../../hooks/use_url_strorage';
|
||||
import { useUrlStorage } from '../../hooks/use_url_storage';
|
||||
import { SeriesType } from '../../../../../../../lens/public';
|
||||
|
||||
export function SeriesChartTypes({
|
||||
|
|
|
@ -9,7 +9,7 @@ import React from 'react';
|
|||
import { fireEvent, screen } from '@testing-library/react';
|
||||
import { FilterExpanded } from './filter_expanded';
|
||||
import { mockUrlStorage, mockUseValuesList, render } from '../../rtl_helpers';
|
||||
import { USER_AGENT_NAME } from '../../configurations/data/elasticsearch_fieldnames';
|
||||
import { USER_AGENT_NAME } from '../../configurations/constants/elasticsearch_fieldnames';
|
||||
|
||||
describe('FilterExpanded', function () {
|
||||
it('should render properly', async function () {
|
||||
|
|
|
@ -14,7 +14,7 @@ import {
|
|||
EuiFilterGroup,
|
||||
} from '@elastic/eui';
|
||||
import { useIndexPatternContext } from '../../hooks/use_default_index_pattern';
|
||||
import { useUrlStorage } from '../../hooks/use_url_strorage';
|
||||
import { useUrlStorage } from '../../hooks/use_url_storage';
|
||||
import { UrlFilter } from '../../types';
|
||||
import { FilterValueButton } from './filter_value_btn';
|
||||
import { useValuesList } from '../../../../../hooks/use_values_list';
|
||||
|
|
|
@ -12,7 +12,7 @@ import { mockUrlStorage, mockUseSeriesFilter, mockUseValuesList, render } from '
|
|||
import {
|
||||
USER_AGENT_NAME,
|
||||
USER_AGENT_VERSION,
|
||||
} from '../../configurations/data/elasticsearch_fieldnames';
|
||||
} from '../../configurations/constants/elasticsearch_fieldnames';
|
||||
|
||||
describe('FilterValueButton', function () {
|
||||
it('should render properly', async function () {
|
||||
|
|
|
@ -8,7 +8,7 @@ import { i18n } from '@kbn/i18n';
|
|||
import React, { useMemo } from 'react';
|
||||
import { EuiFilterButton, hexToRgb } from '@elastic/eui';
|
||||
import { useIndexPatternContext } from '../../hooks/use_default_index_pattern';
|
||||
import { useUrlStorage } from '../../hooks/use_url_strorage';
|
||||
import { useUrlStorage } from '../../hooks/use_url_storage';
|
||||
import { useSeriesFilters } from '../../hooks/use_series_filters';
|
||||
import { euiStyled } from '../../../../../../../../../src/plugins/kibana_react/common';
|
||||
import FieldValueSuggestions from '../../../field_value_suggestions';
|
||||
|
|
|
@ -8,12 +8,12 @@
|
|||
import React, { useState } from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { EuiButton, EuiButtonGroup, EuiPopover } from '@elastic/eui';
|
||||
import { useUrlStorage } from '../../hooks/use_url_strorage';
|
||||
import { useUrlStorage } from '../../hooks/use_url_storage';
|
||||
import { OperationType } from '../../../../../../../lens/public';
|
||||
|
||||
const toggleButtons = [
|
||||
{
|
||||
id: `avg`,
|
||||
id: `average`,
|
||||
label: i18n.translate('xpack.observability.expView.metricsSelect.average', {
|
||||
defaultMessage: 'Average',
|
||||
}),
|
||||
|
@ -49,7 +49,7 @@ export function MetricSelection({
|
|||
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
const [toggleIdSelected, setToggleIdSelected] = useState(series?.metric ?? 'avg');
|
||||
const [toggleIdSelected, setToggleIdSelected] = useState(series?.metric ?? 'average');
|
||||
|
||||
const onChange = (optionId: OperationType) => {
|
||||
setToggleIdSelected(optionId);
|
||||
|
|
|
@ -9,7 +9,7 @@ import { i18n } from '@kbn/i18n';
|
|||
import React from 'react';
|
||||
import { EuiButtonIcon } from '@elastic/eui';
|
||||
import { DataSeries } from '../../types';
|
||||
import { useUrlStorage } from '../../hooks/use_url_strorage';
|
||||
import { useUrlStorage } from '../../hooks/use_url_storage';
|
||||
|
||||
interface Props {
|
||||
series: DataSeries;
|
||||
|
|
|
@ -17,9 +17,9 @@ import {
|
|||
} from '@elastic/eui';
|
||||
import { FilterExpanded } from './filter_expanded';
|
||||
import { DataSeries } from '../../types';
|
||||
import { FieldLabels } from '../../configurations/constants';
|
||||
import { FieldLabels } from '../../configurations/constants/constants';
|
||||
import { SelectedFilters } from '../selected_filters';
|
||||
import { NEW_SERIES_KEY, useUrlStorage } from '../../hooks/use_url_strorage';
|
||||
import { NEW_SERIES_KEY, useUrlStorage } from '../../hooks/use_url_storage';
|
||||
|
||||
interface Props {
|
||||
seriesId: string;
|
||||
|
|
|
@ -10,8 +10,8 @@ import { screen, waitFor } from '@testing-library/react';
|
|||
import { mockIndexPattern, mockUrlStorage, render } from '../rtl_helpers';
|
||||
import { SelectedFilters } from './selected_filters';
|
||||
import { getDefaultConfigs } from '../configurations/default_configs';
|
||||
import { NEW_SERIES_KEY } from '../hooks/use_url_strorage';
|
||||
import { USER_AGENT_NAME } from '../configurations/data/elasticsearch_fieldnames';
|
||||
import { NEW_SERIES_KEY } from '../hooks/use_url_storage';
|
||||
import { USER_AGENT_NAME } from '../configurations/constants/elasticsearch_fieldnames';
|
||||
|
||||
describe('SelectedFilters', function () {
|
||||
const dataViewSeries = getDefaultConfigs({
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import React, { Fragment } from 'react';
|
||||
import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
|
||||
import { NEW_SERIES_KEY, useUrlStorage } from '../hooks/use_url_strorage';
|
||||
import { NEW_SERIES_KEY, useUrlStorage } from '../hooks/use_url_storage';
|
||||
import { FilterLabel } from '../components/filter_label';
|
||||
import { DataSeries, UrlFilter } from '../types';
|
||||
import { useIndexPatternContext } from '../hooks/use_default_index_pattern';
|
||||
|
|
|
@ -13,7 +13,7 @@ import { ActionsCol } from './columns/actions_col';
|
|||
import { Breakdowns } from './columns/breakdowns';
|
||||
import { DataSeries } from '../types';
|
||||
import { SeriesBuilder } from '../series_builder/series_builder';
|
||||
import { NEW_SERIES_KEY, useUrlStorage } from '../hooks/use_url_strorage';
|
||||
import { NEW_SERIES_KEY, useUrlStorage } from '../hooks/use_url_storage';
|
||||
import { getDefaultConfigs } from '../configurations/default_configs';
|
||||
import { DatePickerCol } from './columns/date_picker_col';
|
||||
import { RemoveSeries } from './columns/remove_series';
|
||||
|
|
|
@ -87,3 +87,22 @@ export interface ConfigProps {
|
|||
}
|
||||
|
||||
export type AppDataType = 'synthetics' | 'rum' | 'logs' | 'metrics' | 'apm';
|
||||
|
||||
type FormatType = 'duration' | 'number';
|
||||
type InputFormat = 'microseconds' | 'milliseconds' | 'seconds';
|
||||
type OutputFormat = 'asSeconds' | 'asMilliseconds' | 'humanize';
|
||||
|
||||
export interface FieldFormatParams {
|
||||
inputFormat: InputFormat;
|
||||
outputFormat: OutputFormat;
|
||||
outputPrecision?: number;
|
||||
showSuffix?: boolean;
|
||||
}
|
||||
|
||||
export interface FieldFormat {
|
||||
field: string;
|
||||
format: {
|
||||
id: FormatType;
|
||||
params: FieldFormatParams;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* 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 { indexPatternList, ObservabilityIndexPatterns } from './observability_index_patterns';
|
||||
import { mockCore, mockIndexPattern } from '../rtl_helpers';
|
||||
import { SavedObjectNotFound } from '../../../../../../../../src/plugins/kibana_utils/public';
|
||||
|
||||
const fieldFormats = {
|
||||
'transaction.duration.us': {
|
||||
id: 'duration',
|
||||
params: {
|
||||
inputFormat: 'microseconds',
|
||||
outputFormat: 'asSeconds',
|
||||
outputPrecision: 1,
|
||||
showSuffix: true,
|
||||
},
|
||||
},
|
||||
'transaction.experience.fid': {
|
||||
id: 'duration',
|
||||
params: { inputFormat: 'milliseconds', outputFormat: 'asSeconds', showSuffix: true },
|
||||
},
|
||||
'transaction.experience.tbt': {
|
||||
id: 'duration',
|
||||
params: { inputFormat: 'milliseconds', outputFormat: 'asSeconds', showSuffix: true },
|
||||
},
|
||||
'transaction.marks.agent.firstContentfulPaint': {
|
||||
id: 'duration',
|
||||
params: { inputFormat: 'milliseconds', outputFormat: 'asSeconds', showSuffix: true },
|
||||
},
|
||||
'transaction.marks.agent.largestContentfulPaint': {
|
||||
id: 'duration',
|
||||
params: { inputFormat: 'milliseconds', outputFormat: 'asSeconds', showSuffix: true },
|
||||
},
|
||||
};
|
||||
|
||||
describe('ObservabilityIndexPatterns', function () {
|
||||
const { data } = mockCore();
|
||||
data!.indexPatterns.get = jest.fn().mockReturnValue({ title: 'index-*' });
|
||||
data!.indexPatterns.createAndSave = jest.fn().mockReturnValue({ id: indexPatternList.rum });
|
||||
data!.indexPatterns.updateSavedObject = jest.fn();
|
||||
|
||||
it('should return index pattern for app', async function () {
|
||||
const obsv = new ObservabilityIndexPatterns(data!);
|
||||
|
||||
const indexP = await obsv.getIndexPattern('rum');
|
||||
|
||||
expect(indexP).toEqual({ title: 'index-*' });
|
||||
|
||||
expect(data?.indexPatterns.get).toHaveBeenCalledWith(indexPatternList.rum);
|
||||
expect(data?.indexPatterns.get).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should creates missing index pattern', async function () {
|
||||
data!.indexPatterns.get = jest.fn().mockImplementation(() => {
|
||||
throw new SavedObjectNotFound('index_pattern');
|
||||
});
|
||||
|
||||
const obsv = new ObservabilityIndexPatterns(data!);
|
||||
|
||||
const indexP = await obsv.getIndexPattern('rum');
|
||||
|
||||
expect(indexP).toEqual({ id: indexPatternList.rum });
|
||||
|
||||
expect(data?.indexPatterns.createAndSave).toHaveBeenCalledWith({
|
||||
fieldFormats,
|
||||
id: 'rum_static_index_pattern_id',
|
||||
timeFieldName: '@timestamp',
|
||||
title: '(rum-data-view)*,apm-*',
|
||||
});
|
||||
expect(data?.indexPatterns.createAndSave).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should return getFieldFormats', function () {
|
||||
const obsv = new ObservabilityIndexPatterns(data!);
|
||||
|
||||
expect(obsv.getFieldFormats('rum')).toEqual(fieldFormats);
|
||||
});
|
||||
|
||||
it('should validate field formats', async function () {
|
||||
mockIndexPattern.getFormatterForField = jest.fn().mockReturnValue({ params: () => {} });
|
||||
|
||||
const obsv = new ObservabilityIndexPatterns(data!);
|
||||
|
||||
await obsv.validateFieldFormats('rum', mockIndexPattern);
|
||||
|
||||
expect(data?.indexPatterns.updateSavedObject).toHaveBeenCalledTimes(1);
|
||||
expect(data?.indexPatterns.updateSavedObject).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ fieldFormatMap: fieldFormats })
|
||||
);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* 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 { SavedObjectNotFound } from '../../../../../../../../src/plugins/kibana_utils/public';
|
||||
import {
|
||||
DataPublicPluginStart,
|
||||
IndexPattern,
|
||||
FieldFormat as IFieldFormat,
|
||||
IndexPatternSpec,
|
||||
} from '../../../../../../../../src/plugins/data/public';
|
||||
import { rumFieldFormats } from '../configurations/rum/field_formats';
|
||||
import { syntheticsFieldFormats } from '../configurations/synthetics/field_formats';
|
||||
import { FieldFormat, FieldFormatParams } from '../types';
|
||||
|
||||
const appFieldFormats: Record<DataType, FieldFormat[] | null> = {
|
||||
rum: rumFieldFormats,
|
||||
apm: null,
|
||||
logs: null,
|
||||
metrics: null,
|
||||
synthetics: syntheticsFieldFormats,
|
||||
};
|
||||
|
||||
function getFieldFormatsForApp(app: DataType) {
|
||||
return appFieldFormats[app];
|
||||
}
|
||||
|
||||
export type DataType = 'synthetics' | 'apm' | 'logs' | 'metrics' | 'rum';
|
||||
|
||||
export const indexPatternList: Record<DataType, string> = {
|
||||
synthetics: 'synthetics_static_index_pattern_id',
|
||||
apm: 'apm_static_index_pattern_id',
|
||||
rum: 'rum_static_index_pattern_id',
|
||||
logs: 'logs_static_index_pattern_id',
|
||||
metrics: 'metrics_static_index_pattern_id',
|
||||
};
|
||||
|
||||
const appToPatternMap: Record<DataType, string> = {
|
||||
synthetics: '(synthetics-data-view)*,heartbeat-*,synthetics-*',
|
||||
apm: 'apm-*',
|
||||
rum: '(rum-data-view)*,apm-*',
|
||||
logs: 'logs-*,filebeat-*',
|
||||
metrics: 'metrics-*,metricbeat-*',
|
||||
};
|
||||
|
||||
export function isParamsSame(param1: IFieldFormat['_params'], param2: FieldFormatParams) {
|
||||
return (
|
||||
param1?.inputFormat === param2?.inputFormat &&
|
||||
param1?.outputFormat === param2?.outputFormat &&
|
||||
param1?.showSuffix === param2?.showSuffix &&
|
||||
param2?.outputPrecision === param1?.outputPrecision
|
||||
);
|
||||
}
|
||||
|
||||
export class ObservabilityIndexPatterns {
|
||||
data?: DataPublicPluginStart;
|
||||
|
||||
constructor(data: DataPublicPluginStart) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
async createIndexPattern(app: DataType) {
|
||||
if (!this.data) {
|
||||
throw new Error('data is not defined');
|
||||
}
|
||||
|
||||
const pattern = appToPatternMap[app];
|
||||
|
||||
return await this.data.indexPatterns.createAndSave({
|
||||
title: pattern,
|
||||
id: indexPatternList[app],
|
||||
timeFieldName: '@timestamp',
|
||||
fieldFormats: this.getFieldFormats(app),
|
||||
});
|
||||
}
|
||||
// we want to make sure field formats remain same
|
||||
async validateFieldFormats(app: DataType, indexPattern: IndexPattern) {
|
||||
const defaultFieldFormats = getFieldFormatsForApp(app);
|
||||
if (defaultFieldFormats && defaultFieldFormats.length > 0) {
|
||||
let isParamsDifferent = false;
|
||||
defaultFieldFormats.forEach(({ field, format }) => {
|
||||
const fieldFormat = indexPattern.getFormatterForField(indexPattern.getFieldByName(field)!);
|
||||
const params = fieldFormat.params();
|
||||
if (!isParamsSame(params, format.params)) {
|
||||
indexPattern.setFieldFormat(field, format);
|
||||
isParamsDifferent = true;
|
||||
}
|
||||
});
|
||||
if (isParamsDifferent) {
|
||||
await this.data?.indexPatterns.updateSavedObject(indexPattern);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getFieldFormats(app: DataType) {
|
||||
const fieldFormatMap: IndexPatternSpec['fieldFormats'] = {};
|
||||
|
||||
(appFieldFormats?.[app] ?? []).forEach(({ field, format }) => {
|
||||
fieldFormatMap[field] = format;
|
||||
});
|
||||
|
||||
return fieldFormatMap;
|
||||
}
|
||||
|
||||
async getIndexPattern(app: DataType): Promise<IndexPattern | undefined> {
|
||||
if (!this.data) {
|
||||
throw new Error('data is not defined');
|
||||
}
|
||||
try {
|
||||
const indexPattern = await this.data?.indexPatterns.get(indexPatternList[app]);
|
||||
|
||||
// this is intentional a non blocking call, so no await clause
|
||||
this.validateFieldFormats(app, indexPattern);
|
||||
return indexPattern;
|
||||
} catch (e: unknown) {
|
||||
if (e instanceof SavedObjectNotFound) {
|
||||
return await this.createIndexPattern(app || 'apm');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -76,6 +76,7 @@ export function FieldValueSelection({
|
|||
<EuiButton
|
||||
style={width ? { width } : {}}
|
||||
size="s"
|
||||
color="text"
|
||||
iconType="arrowDown"
|
||||
iconSide="right"
|
||||
onClick={onButtonClick}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue