diff --git a/packages/kbn-apm-synthtrace/src/lib/apm/apm_fields.ts b/packages/kbn-apm-synthtrace/src/lib/apm/apm_fields.ts index 7736aa8e8879b2..07379b2a3002d6 100644 --- a/packages/kbn-apm-synthtrace/src/lib/apm/apm_fields.ts +++ b/packages/kbn-apm-synthtrace/src/lib/apm/apm_fields.ts @@ -58,6 +58,8 @@ export type ApmFields = Fields & 'error.grouping_key': string; 'host.name': string; 'host.hostname': string; + 'http.request.method': string; + 'http.response.status_code': number; 'kubernetes.pod.uid': string; 'kubernetes.pod.name': string; 'metricset.name': string; @@ -84,14 +86,13 @@ export type ApmFields = Fields & 'service.framework.name': string; 'service.target.name': string; 'service.target.type': string; + 'span.action': string; 'span.id': string; 'span.name': string; 'span.type': string; 'span.subtype': string; 'span.duration.us': number; - 'span.destination.service.name': string; 'span.destination.service.resource': string; - 'span.destination.service.type': string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; 'span.self_time.count': number; diff --git a/packages/kbn-apm-synthtrace/src/lib/apm/base_span.ts b/packages/kbn-apm-synthtrace/src/lib/apm/base_span.ts index f8c058592a4947..0cfe5940405a23 100644 --- a/packages/kbn-apm-synthtrace/src/lib/apm/base_span.ts +++ b/packages/kbn-apm-synthtrace/src/lib/apm/base_span.ts @@ -40,6 +40,10 @@ export class BaseSpan extends Serializable { return this; } + getChildren() { + return this._children; + } + children(...children: BaseSpan[]): this { children.forEach((child) => { child.parent(this); diff --git a/packages/kbn-apm-synthtrace/src/lib/apm/client/apm_synthtrace_apm_client.ts b/packages/kbn-apm-synthtrace/src/lib/apm/client/apm_synthtrace_apm_client.ts index da836cd8a2119f..af200a103558e2 100644 --- a/packages/kbn-apm-synthtrace/src/lib/apm/client/apm_synthtrace_apm_client.ts +++ b/packages/kbn-apm-synthtrace/src/lib/apm/client/apm_synthtrace_apm_client.ts @@ -148,9 +148,7 @@ export class ApmSynthtraceApmClient { const destination = (e.context.destination = e.context.destination ?? {}); const destinationService = (destination.service = destination.service ?? { resource: '' }); - set('span.destination.service.name', destinationService, (c, v) => (c.name = v)); set('span.destination.service.resource', destinationService, (c, v) => (c.resource = v)); - set('span.destination.service.type', destinationService, (c, v) => (c.type = v)); } if (e.kind === 'transaction') { set('transaction.name', e, (c, v) => (c.name = v)); diff --git a/packages/kbn-apm-synthtrace/src/lib/apm/instance.ts b/packages/kbn-apm-synthtrace/src/lib/apm/instance.ts index 32a81de9f307a2..f69e54b3e300b7 100644 --- a/packages/kbn-apm-synthtrace/src/lib/apm/instance.ts +++ b/packages/kbn-apm-synthtrace/src/lib/apm/instance.ts @@ -13,6 +13,12 @@ import { Span } from './span'; import { Transaction } from './transaction'; import { ApmApplicationMetricFields, ApmFields } from './apm_fields'; +export type SpanParams = { + spanName: string; + spanType: string; + spanSubtype?: string; +} & ApmFields; + export class Instance extends Entity { transaction({ transactionName, @@ -28,16 +34,7 @@ export class Instance extends Entity { }); } - span({ - spanName, - spanType, - spanSubtype, - ...apmFields - }: { - spanName: string; - spanType: string; - spanSubtype?: string; - } & ApmFields) { + span({ spanName, spanType, spanSubtype, ...apmFields }: SpanParams) { return new Span({ ...this.fields, ...apmFields, diff --git a/packages/kbn-apm-synthtrace/src/lib/apm/span.ts b/packages/kbn-apm-synthtrace/src/lib/apm/span.ts index a5795ae321478e..99e0b1053014a1 100644 --- a/packages/kbn-apm-synthtrace/src/lib/apm/span.ts +++ b/packages/kbn-apm-synthtrace/src/lib/apm/span.ts @@ -10,6 +10,7 @@ import url from 'url'; import { BaseSpan } from './base_span'; import { generateShortId } from '../utils/generate_id'; import { ApmFields } from './apm_fields'; +import { SpanParams } from './instance'; export class Span extends BaseSpan { constructor(fields: ApmFields) { @@ -25,29 +26,26 @@ export class Span extends BaseSpan { return this; } - destination(resource: string, type?: string, name?: string) { - if (!type) { - type = this.fields['span.type']; - } - - if (!name) { - name = resource; - } + destination(resource: string) { this.fields['span.destination.service.resource'] = resource; - this.fields['span.destination.service.name'] = name; - this.fields['span.destination.service.type'] = type; return this; } } +export type HttpMethod = 'GET' | 'POST' | 'DELETE' | 'PUT'; + export function httpExitSpan({ spanName, destinationUrl, + method = 'GET', + statusCode = 200, }: { spanName: string; destinationUrl: string; -}) { + method?: HttpMethod; + statusCode?: number; +}): SpanParams { // origin: 'http://opbeans-go:3000', // host: 'opbeans-go:3000', // hostname: 'opbeans-go', @@ -55,31 +53,98 @@ export function httpExitSpan({ const destination = new url.URL(destinationUrl); const spanType = 'external'; - const spanSubType = 'http'; + const spanSubtype = 'http'; return { spanName, spanType, - spanSubType, + spanSubtype, + + // http + 'span.action': method, + 'http.request.method': method, + 'http.response.status_code': statusCode, + + // destination 'destination.address': destination.hostname, 'destination.port': parseInt(destination.port, 10), 'service.target.name': destination.host, - 'span.destination.service.name': destination.origin, 'span.destination.service.resource': destination.host, - 'span.destination.service.type': 'external', }; } -export function dbExitSpan({ spanName, spanSubType }: { spanName: string; spanSubType?: string }) { +export function dbExitSpan({ spanName, spanSubtype }: { spanName: string; spanSubtype?: string }) { const spanType = 'db'; return { spanName, spanType, - spanSubType, - 'service.target.type': spanSubType, - 'span.destination.service.name': spanSubType, - 'span.destination.service.resource': spanSubType, - 'span.destination.service.type': spanType, + spanSubtype, + 'service.target.type': spanSubtype, + 'span.destination.service.resource': spanSubtype, + }; +} + +export function elasticsearchSpan(spanName: string, statement?: string): SpanParams { + const spanType = 'db'; + const spanSubtype = 'elasticsearch'; + + return { + spanName, + spanType, + spanSubtype, + + ...(statement + ? { + 'span.db.statement': statement, + 'span.db.type': 'elasticsearch', + } + : {}), + + 'service.target.type': spanSubtype, + 'destination.address': 'qwerty.us-west2.gcp.elastic-cloud.com', + 'destination.port': 443, + 'span.destination.service.resource': spanSubtype, + }; +} + +export function sqliteSpan(spanName: string, statement?: string): SpanParams { + const spanType = 'db'; + const spanSubtype = 'sqlite'; + + return { + spanName, + spanType, + spanSubtype, + + ...(statement + ? { + 'span.db.statement': statement, + 'span.db.type': 'sql', + } + : {}), + + // destination + 'service.target.type': spanSubtype, + 'destination.address': 'qwerty.us-west2.gcp.elastic-cloud.com', + 'destination.port': 443, + 'span.destination.service.resource': spanSubtype, + }; +} + +export function redisSpan(spanName: string): SpanParams { + const spanType = 'db'; + const spanSubtype = 'redis'; + + return { + spanName, + spanType, + spanSubtype, + + // destination + 'service.target.type': spanSubtype, + 'destination.address': 'qwerty.us-west2.gcp.elastic-cloud.com', + 'destination.port': 443, + 'span.destination.service.resource': spanSubtype, }; } diff --git a/packages/kbn-apm-synthtrace/src/lib/dsl/distributed_trace_client.test.ts b/packages/kbn-apm-synthtrace/src/lib/dsl/distributed_trace_client.test.ts new file mode 100644 index 00000000000000..87e508abe87db3 --- /dev/null +++ b/packages/kbn-apm-synthtrace/src/lib/dsl/distributed_trace_client.test.ts @@ -0,0 +1,221 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { apm } from '../apm'; +import { ApmFields } from '../apm/apm_fields'; +import { BaseSpan } from '../apm/base_span'; +import { DistributedTrace } from './distributed_trace_client'; + +const opbeansRum = apm + .service({ name: 'opbeans-rum', environment: 'prod', agentName: 'rum-js' }) + .instance('my-instance'); + +const opbeansNode = apm + .service({ name: 'opbeans-node', environment: 'prod', agentName: 'nodejs' }) + .instance('my-instance'); + +const opbeansGo = apm + .service({ name: 'opbeans-go', environment: 'prod', agentName: 'go' }) + .instance('my-instance'); + +describe('DistributedTrace', () => { + describe('basic scenario', () => { + it('should add latency', () => { + const dt = new DistributedTrace({ + serviceInstance: opbeansRum, + transactionName: 'Dashboard', + timestamp: 0, + children: (s) => { + s.service({ + serviceInstance: opbeansNode, + transactionName: 'GET /nodejs/products', + + children: (_) => { + _.service({ serviceInstance: opbeansGo, transactionName: 'GET /gogo' }); + _.db({ name: 'GET apm-*/_search', type: 'elasticsearch', duration: 400 }); + }, + }); + }, + }).getTransaction(); + + const traceDocs = getTraceDocs(dt); + const formattedDocs = traceDocs.map((f) => { + return { + processorEvent: f['processor.event'], + timestamp: f['@timestamp'], + duration: (f['transaction.duration.us'] ?? f['span.duration.us'])! / 1000, + name: f['transaction.name'] ?? f['span.name'], + }; + }); + + expect(formattedDocs).toMatchInlineSnapshot(` + Array [ + Object { + "duration": 400, + "name": "Dashboard", + "processorEvent": "transaction", + "timestamp": 0, + }, + Object { + "duration": 400, + "name": "GET /nodejs/products", + "processorEvent": "span", + "timestamp": 0, + }, + Object { + "duration": 400, + "name": "GET /nodejs/products", + "processorEvent": "transaction", + "timestamp": 0, + }, + Object { + "duration": 0, + "name": "GET /gogo", + "processorEvent": "span", + "timestamp": 0, + }, + Object { + "duration": 0, + "name": "GET /gogo", + "processorEvent": "transaction", + "timestamp": 0, + }, + Object { + "duration": 400, + "name": "GET apm-*/_search", + "processorEvent": "span", + "timestamp": 0, + }, + ] + `); + }); + }); + + describe('latency', () => { + it('should add latency', () => { + const traceDocs = getSimpleScenario({ latency: 500 }); + const timestamps = traceDocs.map((f) => f['@timestamp']); + expect(timestamps).toMatchInlineSnapshot(` + Array [ + 0, + 0, + 250, + 250, + 250, + 250, + ] + `); + }); + + it('should not add latency', () => { + const traceDocs = getSimpleScenario(); + const timestamps = traceDocs.map((f) => f['@timestamp']); + expect(timestamps).toMatchInlineSnapshot(` + Array [ + 0, + 0, + 0, + 0, + 0, + 0, + ] + `); + }); + }); + + describe('duration', () => { + it('should add duration', () => { + const traceDocs = getSimpleScenario({ duration: 3000 }); + const durations = traceDocs.map( + (f) => (f['transaction.duration.us'] ?? f['span.duration.us'])! / 1000 + ); + expect(durations).toMatchInlineSnapshot(` + Array [ + 3000, + 3000, + 3000, + 300, + 400, + 500, + ] + `); + }); + + it('should not add duration', () => { + const traceDocs = getSimpleScenario(); + const durations = traceDocs.map( + (f) => (f['transaction.duration.us'] ?? f['span.duration.us'])! / 1000 + ); + expect(durations).toMatchInlineSnapshot(` + Array [ + 500, + 500, + 500, + 300, + 400, + 500, + ] + `); + }); + }); + + describe('repeat', () => { + it('produces few trace documents when "repeat" is disabled', () => { + const traceDocs = getSimpleScenario({ repeat: undefined }); + expect(traceDocs.length).toBe(6); + }); + + it('produces more trace documents when "repeat" is enabled', () => { + const traceDocs = getSimpleScenario({ repeat: 20 }); + expect(traceDocs.length).toBe(101); + }); + }); +}); + +function getTraceDocs(transaction: BaseSpan): ApmFields[] { + const children = transaction.getChildren(); + if (children) { + const childFields = children.flatMap((child) => getTraceDocs(child)); + return [transaction.fields, ...childFields]; + } + + return [transaction.fields]; +} + +function getSimpleScenario({ + duration, + latency, + repeat, +}: { + duration?: number; + latency?: number; + repeat?: number; +} = {}) { + const dt = new DistributedTrace({ + serviceInstance: opbeansRum, + transactionName: 'Dashboard', + timestamp: 0, + children: (s) => { + s.service({ + serviceInstance: opbeansNode, + transactionName: 'GET /nodejs/products', + duration, + latency, + repeat, + + children: (_) => { + _.db({ name: 'GET apm-*/_search', type: 'elasticsearch', duration: 300 }); + _.db({ name: 'GET apm-*/_search', type: 'elasticsearch', duration: 400 }); + _.db({ name: 'GET apm-*/_search', type: 'elasticsearch', duration: 500 }); + }, + }); + }, + }).getTransaction(); + + return getTraceDocs(dt); +} diff --git a/packages/kbn-apm-synthtrace/src/lib/dsl/distributed_trace_client.ts b/packages/kbn-apm-synthtrace/src/lib/dsl/distributed_trace_client.ts new file mode 100644 index 00000000000000..ceeb94f871e3ac --- /dev/null +++ b/packages/kbn-apm-synthtrace/src/lib/dsl/distributed_trace_client.ts @@ -0,0 +1,183 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { times } from 'lodash'; +import { elasticsearchSpan, httpExitSpan, HttpMethod, redisSpan, sqliteSpan } from '../apm/span'; +import { BaseSpan } from '../apm/base_span'; +import { Instance, SpanParams } from '../apm/instance'; +import { Transaction } from '../apm/transaction'; + +export class DistributedTrace { + timestamp: number; + serviceInstance: Instance; + spanEndTimes: number[] = []; + childSpans: BaseSpan[] = []; + transaction: Transaction; + + constructor({ + serviceInstance, + transactionName, + timestamp, + children, + }: { + serviceInstance: Instance; + transactionName: string; + timestamp: number; + children?: (dt: DistributedTrace) => void; + }) { + this.timestamp = timestamp; + this.serviceInstance = serviceInstance; + + if (children) { + children(this); + } + + const maxEndTime = Math.max(...this.spanEndTimes); + const duration = maxEndTime - this.timestamp; + + this.transaction = serviceInstance + .transaction({ transactionName }) + .timestamp(timestamp) + .duration(duration) + .children(...this.childSpans); + + return this; + } + + getTransaction() { + return this.transaction; + } + + service({ + serviceInstance, + transactionName, + latency = 0, + repeat = 1, + timestamp = this.timestamp, + duration, + children, + }: { + serviceInstance: Instance; + transactionName: string; + repeat?: number; + timestamp?: number; + latency?: number; + duration?: number; + children?: (dt: DistributedTrace) => unknown; + }) { + const originServiceInstance = this.serviceInstance; + + times(repeat, () => { + const dt = new DistributedTrace({ + serviceInstance, + transactionName, + timestamp: timestamp + latency / 2, + children, + }); + + const maxSpanEndTime = Math.max(...dt.spanEndTimes, timestamp + (duration ?? 0)); + this.spanEndTimes.push(maxSpanEndTime + latency / 2); + + // origin service + const exitSpanStart = timestamp; + const exitSpanDuration = (duration ?? maxSpanEndTime - exitSpanStart) + latency / 2; + + // destination service + const transactionStart = timestamp + latency / 2; + const transactionDuration = duration ?? maxSpanEndTime - transactionStart; + + const span = originServiceInstance + .span( + httpExitSpan({ + spanName: transactionName, + destinationUrl: 'http://api-gateway:3000', // TODO: this should be derived from serviceInstance + }) + ) + .duration(exitSpanDuration) + .timestamp(exitSpanStart) + .children( + dt.serviceInstance + .transaction({ transactionName }) + .timestamp(transactionStart) + .duration(transactionDuration) + .children(...(dt.childSpans ?? [])) + ); + + this.childSpans.push(span); + }); + } + + external({ + name, + url, + method, + statusCode, + duration, + timestamp = this.timestamp, + }: { + name: string; + url: string; + method?: HttpMethod; + statusCode?: number; + duration: number; + timestamp?: number; + }) { + const startTime = timestamp; + const endTime = startTime + duration; + this.spanEndTimes.push(endTime); + + const span = this.serviceInstance + .span(httpExitSpan({ spanName: name, destinationUrl: url, method, statusCode })) + .timestamp(startTime) + .duration(duration) + .success(); + + this.childSpans.push(span); + } + + db({ + name, + duration, + type, + statement, + timestamp = this.timestamp, + }: { + name: string; + duration: number; + type: 'elasticsearch' | 'sqlite' | 'redis'; + statement?: string; + timestamp?: number; + }) { + const startTime = timestamp; + const endTime = startTime + duration; + this.spanEndTimes.push(endTime); + + let dbSpan: SpanParams; + switch (type) { + case 'elasticsearch': + dbSpan = elasticsearchSpan(name, statement); + break; + + case 'sqlite': + dbSpan = sqliteSpan(name, statement); + break; + + case 'redis': + dbSpan = redisSpan(name); + break; + } + + const span = this.serviceInstance + .span(dbSpan) + .timestamp(startTime) + .duration(duration) + .success(); + + this.childSpans.push(span); + } +} diff --git a/packages/kbn-apm-synthtrace/src/scenarios/distributed_trace_long.ts b/packages/kbn-apm-synthtrace/src/scenarios/distributed_trace_long.ts new file mode 100644 index 00000000000000..32542ee2c1d493 --- /dev/null +++ b/packages/kbn-apm-synthtrace/src/scenarios/distributed_trace_long.ts @@ -0,0 +1,134 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +/* eslint-disable @typescript-eslint/no-shadow */ + +import { apm, timerange } from '../..'; +import { ApmFields } from '../lib/apm/apm_fields'; +import { Scenario } from '../cli/scenario'; +import { RunOptions } from '../cli/utils/parse_run_cli_flags'; +import { getSynthtraceEnvironment } from '../lib/utils/get_synthtrace_environment'; +import { DistributedTrace } from '../lib/dsl/distributed_trace_client'; + +const ENVIRONMENT = getSynthtraceEnvironment(__filename); + +const scenario: Scenario = async (runOptions: RunOptions) => { + return { + generate: ({ from, to }) => { + const ratePerMinute = 1; + const traceDuration = 1100; + const rootTransactionName = `${ratePerMinute}rpm / ${traceDuration}ms`; + + const opbeansRum = apm + .service({ name: 'opbeans-rum', environment: ENVIRONMENT, agentName: 'rum-js' }) + .instance('my-instance'); + + const opbeansNode = apm + .service({ name: 'opbeans-node', environment: ENVIRONMENT, agentName: 'nodejs' }) + .instance('my-instance'); + + const opbeansGo = apm + .service({ name: 'opbeans-go', environment: ENVIRONMENT, agentName: 'go' }) + .instance('my-instance'); + + const opbeansDotnet = apm + .service({ name: 'opbeans-dotnet', environment: ENVIRONMENT, agentName: 'dotnet' }) + .instance('my-instance'); + + const opbeansJava = apm + .service({ name: 'opbeans-java', environment: ENVIRONMENT, agentName: 'java' }) + .instance('my-instance'); + + const traces = timerange(from, to) + .ratePerMinute(ratePerMinute) + .generator((timestamp) => { + return new DistributedTrace({ + serviceInstance: opbeansRum, + transactionName: rootTransactionName, + timestamp, + children: (_) => { + _.service({ + repeat: 10, + serviceInstance: opbeansNode, + transactionName: 'GET /nodejs/products', + latency: 100, + + children: (_) => { + _.service({ + serviceInstance: opbeansGo, + transactionName: 'GET /go', + children: (_) => { + _.service({ + repeat: 20, + serviceInstance: opbeansJava, + transactionName: 'GET /java', + children: (_) => { + _.external({ + name: 'GET telemetry.elastic.co', + url: 'https://telemetry.elastic.co/ping', + duration: 50, + }); + }, + }); + }, + }); + _.db({ name: 'GET apm-*/_search', type: 'elasticsearch', duration: 400 }); + _.db({ name: 'GET', type: 'redis', duration: 500 }); + _.db({ name: 'SELECT * FROM users', type: 'sqlite', duration: 600 }); + }, + }); + + _.service({ + serviceInstance: opbeansNode, + transactionName: 'GET /nodejs/users', + latency: 100, + repeat: 10, + children: (_) => { + _.service({ + serviceInstance: opbeansGo, + transactionName: 'GET /go/security', + latency: 50, + children: (_) => { + _.service({ + repeat: 10, + serviceInstance: opbeansDotnet, + transactionName: 'GET /dotnet/cases/4', + latency: 50, + children: (_) => + _.db({ + name: 'GET apm-*/_search', + type: 'elasticsearch', + duration: 600, + statement: JSON.stringify( + { + query: { + query_string: { + query: '(new york city) OR (big apple)', + default_field: 'content', + }, + }, + }, + null, + 2 + ), + }), + }); + }, + }); + }, + }); + }, + }).getTransaction(); + }); + + return traces; + }, + }; +}; + +export default scenario; diff --git a/packages/kbn-tinymath/README.md b/packages/kbn-tinymath/README.md index 1094c4286c851b..3db95cef9adb0b 100644 --- a/packages/kbn-tinymath/README.md +++ b/packages/kbn-tinymath/README.md @@ -66,7 +66,10 @@ parse('1 + random()') This package is rebuilt when running `yarn kbn bootstrap`, but can also be build directly using `yarn build` from the `packages/kbn-tinymath` directory. + ### Running tests -To test `@kbn/tinymath` from Kibana, run `yarn run jest --watch packages/kbn-tinymath` from +To test `@kbn/tinymath` from Kibana, run `node scripts/jest --config packages/kbn-tinymath/jest.config.js` from the top level of Kibana. + +To test grammar changes it is required to run a build task before the test suite. diff --git a/packages/kbn-tinymath/docs/functions.md b/packages/kbn-tinymath/docs/functions.md index 0c7460a8189ddb..23d267ec975f51 100644 --- a/packages/kbn-tinymath/docs/functions.md +++ b/packages/kbn-tinymath/docs/functions.md @@ -96,6 +96,143 @@ clamp(35, 10, [20, 30, 40, 50]) // returns [20, 30, 35, 35] clamp([1, 9], 3, [4, 5]) // returns [clamp([1, 3, 4]), clamp([9, 3, 5])] = [3, 5] ``` *** +## _eq(_ _a_, _b_ _)_ +Performs an equality comparison between two values. + + +| Param | Type | Description | +| --- | --- | --- | +| a | number \| Array.<number> | a number or an array of numbers | +| b | number \| Array.<number> | a number or an array of numbers | + +**Returns**: boolean - Returns true if `a` and `b` are equal, false otherwise. Returns an array with the equality comparison of each element if `a` is an array. +**Throws**: + +- `'Missing b value'` if `b` is not provided +- `'Array length mismatch'` if `args` contains arrays of different lengths + +**Example** +```js +eq(1, 1) // returns true +eq(1, 2) // returns false +eq([1, 2], 1) // returns [true, false] +eq([1, 2], [1, 2]) // returns [true, true] +``` +*** +## _gt(_ _a_, _b_ _)_ +Performs a greater than comparison between two values. + + +| Param | Type | Description | +| --- | --- | --- | +| a | number \| Array.<number> | a number or an array of numbers | +| b | number \| Array.<number> | a number or an array of numbers | + +**Returns**: boolean - Returns true if `a` is greater than `b`, false otherwise. Returns an array with the greater than comparison of each element if `a` is an array. +**Throws**: + +- `'Missing b value'` if `b` is not provided +- `'Array length mismatch'` if `args` contains arrays of different lengths + +**Example** +```js +gt(1, 1) // returns false +gt(2, 1) // returns true +gt([1, 2], 1) // returns [true, false] +gt([1, 2], [2, 1]) // returns [false, true] +``` +*** +## _gte(_ _a_, _b_ _)_ +Performs a greater than or equal comparison between two values. + + +| Param | Type | Description | +| --- | --- | --- | +| a | number \| Array.<number> | a number or an array of numbers | +| b | number \| Array.<number> | a number or an array of numbers | + +**Returns**: boolean - Returns true if `a` is greater than or equal to `b`, false otherwise. Returns an array with the greater than or equal comparison of each element if `a` is an array. +**Throws**: + +- `'Array length mismatch'` if `args` contains arrays of different lengths + +**Example** +```js +gte(1, 1) // returns true +gte(1, 2) // returns false +gte([1, 2], 2) // returns [false, true] +gte([1, 2], [1, 1]) // returns [true, true] +``` +*** +## _ifelse(_ _cond_, _a_, _b_ _)_ +Evaluates the a conditional argument and returns one of the two values based on that. + + +| Param | Type | Description | +| --- | --- | --- | +| cond | boolean | a boolean value | +| a | any \| Array.<any> | a value or an array of any values | +| b | any \| Array.<any> | a value or an array of any values | + +**Returns**: any \| Array.<any> - if the value of cond is truthy, return `a`, otherwise return `b`. +**Throws**: + +- `'Condition clause is of the wrong type'` if the `cond` provided is not of boolean type +- `'Missing a value'` if `a` is not provided +- `'Missing b value'` if `b` is not provided + +**Example** +```js +ifelse(5 > 6, 1, 0) // returns 0 +ifelse(1 == 1, [1, 2, 3], 5) // returns [1, 2, 3] +ifelse(1 < 2, [1, 2, 3], [2, 3, 4]) // returns [1, 2, 3] +``` +*** +## _lt(_ _a_, _b_ _)_ +Performs a lower than comparison between two values. + + +| Param | Type | Description | +| --- | --- | --- | +| a | number \| Array.<number> | a number or an array of numbers | +| b | number \| Array.<number> | a number or an array of numbers | + +**Returns**: boolean - Returns true if `a` is lower than `b`, false otherwise. Returns an array with the lower than comparison of each element if `a` is an array. +**Throws**: + +- `'Missing b value'` if `b` is not provided +- `'Array length mismatch'` if `args` contains arrays of different lengths + +**Example** +```js +lt(1, 1) // returns false +lt(1, 2) // returns true +lt([1, 2], 2) // returns [true, false] +lt([1, 2], [1, 2]) // returns [false, false] +``` +*** +## _lte(_ _a_, _b_ _)_ +Performs a lower than or equal comparison between two values. + + +| Param | Type | Description | +| --- | --- | --- | +| a | number \| Array.<number> | a number or an array of numbers | +| b | number \| Array.<number> | a number or an array of numbers | + +**Returns**: boolean - Returns true if `a` is lower than or equal to `b`, false otherwise. Returns an array with the lower than or equal comparison of each element if `a` is an array. +**Throws**: + +- `'Array length mismatch'` if `args` contains arrays of different lengths + +**Example** +```js +lte(1, 1) // returns true +lte(1, 2) // returns true +lte([1, 2], 2) // returns [true, true] +lte([1, 2], [1, 1]) // returns [true, false] +``` +*** ## _cos(_ _a_ _)_ Calculates the the cosine of a number. For arrays, the function will be applied index-wise to each element. diff --git a/packages/kbn-tinymath/grammar/grammar.peggy b/packages/kbn-tinymath/grammar/grammar.peggy index 414bc2fa11cb74..7eb5f6c5f82d65 100644 --- a/packages/kbn-tinymath/grammar/grammar.peggy +++ b/packages/kbn-tinymath/grammar/grammar.peggy @@ -11,6 +11,32 @@ max: location.end.offset } } + + const symbolsToFn = { + '+': 'add', '-': 'subtract', + '*': 'multiply', '/': 'divide', + '<': 'lt', '>': 'gt', '==': 'eq', + '<=': 'lte', '>=': 'gte', + } + + // Shared function for AST operations + function parseSymbol(left, rest){ + const topLevel = rest.reduce((acc, [name, right]) => ({ + type: 'function', + name: symbolsToFn[name], + args: [acc, right], + }), left); + if (typeof topLevel === 'object') { + topLevel.location = simpleLocation(location()); + topLevel.text = text(); + } + return topLevel; + } + + // op is always defined, while eq can be null for gt and lt cases + function getComparisonSymbol([op, eq]){ + return symbolsToFn[op+(eq || '')]; + } } start @@ -70,45 +96,55 @@ Variable // expressions +// An Expression can be of 3 different types: +// * a Comparison operation, which can contain recursive MathOperations inside +// * a MathOperation, which can contain other MathOperations, but not Comparison types +// * an ExpressionGroup, which is a generic Grouping that contains also Comparison operations (i.e. ( 5 > 1)) Expression + = Comparison + / MathOperation + / ExpressionGroup + +Comparison + = _ left:MathOperation op:(('>' / '<')('=')? / '=''=') right:MathOperation _ { + return { + type: 'function', + name: getComparisonSymbol(op), + args: [left, right], + location: simpleLocation(location()), + text: text() + }; + } + +MathOperation = AddSubtract + / MultiplyDivide + / Factor AddSubtract = _ left:MultiplyDivide rest:(('+' / '-') MultiplyDivide)+ _ { - const topLevel = rest.reduce((acc, curr) => ({ - type: 'function', - name: curr[0] === '+' ? 'add' : 'subtract', - args: [acc, curr[1]], - }), left); - if (typeof topLevel === 'object') { - topLevel.location = simpleLocation(location()); - topLevel.text = text(); - } - return topLevel; + return parseSymbol(left, rest, {'+': 'add', '-': 'subtract'}); } - / MultiplyDivide MultiplyDivide = _ left:Factor rest:(('*' / '/') Factor)* _ { - const topLevel = rest.reduce((acc, curr) => ({ - type: 'function', - name: curr[0] === '*' ? 'multiply' : 'divide', - args: [acc, curr[1]], - }), left); - if (typeof topLevel === 'object') { - topLevel.location = simpleLocation(location()); - topLevel.text = text(); - } - return topLevel; + return parseSymbol(left, rest, {'*': 'multiply', '/': 'divide'}); } - / Factor Factor = Group / Function / Literal +// Because of the new Comparison syntax it is required a new Group type +// the previous Group has been renamed into ExpressionGroup while +// a new Group type has been defined to exclude the Comparison type from it Group + = _ '(' _ expr:MathOperation _ ')' _ { + return expr + } + +ExpressionGroup = _ '(' _ expr:Expression _ ')' _ { return expr } diff --git a/packages/kbn-tinymath/src/functions/abs.js b/packages/kbn-tinymath/src/functions/abs.js index aa3c808d89afde..46cf65837621b5 100644 --- a/packages/kbn-tinymath/src/functions/abs.js +++ b/packages/kbn-tinymath/src/functions/abs.js @@ -17,11 +17,11 @@ * abs([-1 , -2, 3, -4]) // returns [1, 2, 3, 4] */ -module.exports = { abs }; - function abs(a) { if (Array.isArray(a)) { return a.map((a) => Math.abs(a)); } return Math.abs(a); } + +module.exports = { abs }; diff --git a/packages/kbn-tinymath/src/functions/add.js b/packages/kbn-tinymath/src/functions/add.js index 184c619c945341..b1abb23d99f6e1 100644 --- a/packages/kbn-tinymath/src/functions/add.js +++ b/packages/kbn-tinymath/src/functions/add.js @@ -17,8 +17,6 @@ * add([1, 2], 3, [4, 5], 6) // returns [(1 + 3 + 4 + 6), (2 + 3 + 5 + 6)] = [14, 16] */ -module.exports = { add }; - function add(...args) { if (args.length === 1) { if (Array.isArray(args[0])) return args[0].reduce((result, current) => result + current); @@ -35,3 +33,4 @@ function add(...args) { return result + current; }); } +module.exports = { add }; diff --git a/packages/kbn-tinymath/src/functions/cbrt.js b/packages/kbn-tinymath/src/functions/cbrt.js index 1c5f75a724b5ee..39ea7ffb33c1e7 100644 --- a/packages/kbn-tinymath/src/functions/cbrt.js +++ b/packages/kbn-tinymath/src/functions/cbrt.js @@ -17,11 +17,11 @@ * cbrt([27, 64, 125]) // returns [3, 4, 5] */ -module.exports = { cbrt }; - function cbrt(a) { if (Array.isArray(a)) { return a.map((a) => Math.cbrt(a)); } return Math.cbrt(a); } + +module.exports = { cbrt }; diff --git a/packages/kbn-tinymath/src/functions/ceil.js b/packages/kbn-tinymath/src/functions/ceil.js index fe1ca21e4aed10..3dbfbcabaa2248 100644 --- a/packages/kbn-tinymath/src/functions/ceil.js +++ b/packages/kbn-tinymath/src/functions/ceil.js @@ -17,11 +17,11 @@ * ceil([1.1, 2.2, 3.3]) // returns [2, 3, 4] */ -module.exports = { ceil }; - function ceil(a) { if (Array.isArray(a)) { return a.map((a) => Math.ceil(a)); } return Math.ceil(a); } + +module.exports = { ceil }; diff --git a/packages/kbn-tinymath/src/functions/clamp.js b/packages/kbn-tinymath/src/functions/clamp.js index 29c190aa8f9210..a8563895abec12 100644 --- a/packages/kbn-tinymath/src/functions/clamp.js +++ b/packages/kbn-tinymath/src/functions/clamp.js @@ -30,8 +30,6 @@ const findClamp = (a, min, max) => { * clamp([1, 9], 3, [4, 5]) // returns [clamp([1, 3, 4]), clamp([9, 3, 5])] = [3, 5] */ -module.exports = { clamp }; - function clamp(a, min, max) { if (max === null) throw new Error("Missing maximum value. You may want to use the 'min' function instead"); @@ -73,3 +71,5 @@ function clamp(a, min, max) { return findClamp(a, min, max); } + +module.exports = { clamp }; diff --git a/packages/kbn-tinymath/src/functions/comparison/eq.js b/packages/kbn-tinymath/src/functions/comparison/eq.js new file mode 100644 index 00000000000000..dc1e7f027c44f5 --- /dev/null +++ b/packages/kbn-tinymath/src/functions/comparison/eq.js @@ -0,0 +1,39 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +/** + * Performs an equality comparison between two values. + * @param {number|number[]} a a number or an array of numbers + * @param {number|number[]} b a number or an array of numbers + * @return {boolean} Returns true if `a` and `b` are equal, false otherwise. Returns an array with the equality comparison of each element if `a` is an array. + * @throws `'Missing b value'` if `b` is not provided + * @throws `'Array length mismatch'` if `args` contains arrays of different lengths + * @example + * eq(1, 1) // returns true + * eq(1, 2) // returns false + * eq([1, 2], 1) // returns [true, false] + * eq([1, 2], [1, 2]) // returns [true, true] + */ + +function eq(a, b) { + if (b == null) { + throw new Error('Missing b value'); + } + if (Array.isArray(a)) { + if (!Array.isArray(b)) { + return a.every((v) => v === b); + } + if (a.length !== b.length) { + throw new Error('Array length mismatch'); + } + return a.every((v, i) => v === b[i]); + } + + return a === b; +} +module.exports = { eq }; diff --git a/packages/kbn-tinymath/src/functions/comparison/gt.js b/packages/kbn-tinymath/src/functions/comparison/gt.js new file mode 100644 index 00000000000000..1fc1a0cac083a5 --- /dev/null +++ b/packages/kbn-tinymath/src/functions/comparison/gt.js @@ -0,0 +1,39 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +/** + * Performs a greater than comparison between two values. + * @param {number|number[]} a a number or an array of numbers + * @param {number|number[]} b a number or an array of numbers + * @return {boolean} Returns true if `a` is greater than `b`, false otherwise. Returns an array with the greater than comparison of each element if `a` is an array. + * @throws `'Missing b value'` if `b` is not provided + * @throws `'Array length mismatch'` if `args` contains arrays of different lengths + * @example + * gt(1, 1) // returns false + * gt(2, 1) // returns true + * gt([1, 2], 1) // returns [true, false] + * gt([1, 2], [2, 1]) // returns [false, true] + */ + +function gt(a, b) { + if (b == null) { + throw new Error('Missing b value'); + } + if (Array.isArray(a)) { + if (!Array.isArray(b)) { + return a.every((v) => v > b); + } + if (a.length !== b.length) { + throw new Error('Array length mismatch'); + } + return a.every((v, i) => v > b[i]); + } + + return a > b; +} +module.exports = { gt }; diff --git a/packages/kbn-tinymath/src/functions/comparison/gte.js b/packages/kbn-tinymath/src/functions/comparison/gte.js new file mode 100644 index 00000000000000..2d70145e90f9e1 --- /dev/null +++ b/packages/kbn-tinymath/src/functions/comparison/gte.js @@ -0,0 +1,28 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +const { eq } = require('./eq'); +const { gt } = require('./gt'); + +/** + * Performs a greater than or equal comparison between two values. + * @param {number|number[]} a a number or an array of numbers + * @param {number|number[]} b a number or an array of numbers + * @return {boolean} Returns true if `a` is greater than or equal to `b`, false otherwise. Returns an array with the greater than or equal comparison of each element if `a` is an array. + * @throws `'Array length mismatch'` if `args` contains arrays of different lengths + * @example + * gte(1, 1) // returns true + * gte(1, 2) // returns false + * gte([1, 2], 2) // returns [false, true] + * gte([1, 2], [1, 1]) // returns [true, true] + */ + +function gte(a, b) { + return eq(a, b) || gt(a, b); +} +module.exports = { gte }; diff --git a/packages/kbn-tinymath/src/functions/comparison/ifelse.js b/packages/kbn-tinymath/src/functions/comparison/ifelse.js new file mode 100644 index 00000000000000..7f9c212d6029d0 --- /dev/null +++ b/packages/kbn-tinymath/src/functions/comparison/ifelse.js @@ -0,0 +1,38 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +/** + * Evaluates the a conditional argument and returns one of the two values based on that. + * @param {(boolean)} cond a boolean value + * @param {(any|any[])} a a value or an array of any values + * @param {(any|any[])} b a value or an array of any values + * @return {(any|any[])} if the value of cond is truthy, return `a`, otherwise return `b`. + * @throws `'Condition clause is of the wrong type'` if the `cond` provided is not of boolean type + * @throws `'Missing a value'` if `a` is not provided + * @throws `'Missing b value'` if `b` is not provided + * @example + * ifelse(5 > 6, 1, 0) // returns 0 + * ifelse(1 == 1, [1, 2, 3], 5) // returns [1, 2, 3] + * ifelse(1 < 2, [1, 2, 3], [2, 3, 4]) // returns [1, 2, 3] + */ + +function ifelse(cond, a, b) { + if (typeof cond !== 'boolean') { + throw Error('Condition clause is of the wrong type'); + } + if (a == null) { + throw new Error('Missing a value'); + } + if (b == null) { + throw new Error('Missing b value'); + } + return cond ? a : b; +} + +ifelse.skipNumberValidation = true; +module.exports = { ifelse }; diff --git a/packages/kbn-tinymath/src/functions/comparison/index.js b/packages/kbn-tinymath/src/functions/comparison/index.js new file mode 100644 index 00000000000000..b20cc39014a517 --- /dev/null +++ b/packages/kbn-tinymath/src/functions/comparison/index.js @@ -0,0 +1,16 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +const { eq } = require('./eq'); +const { lt } = require('./lt'); +const { gt } = require('./gt'); +const { lte } = require('./lte'); +const { gte } = require('./gte'); +const { ifelse } = require('./ifelse'); + +module.exports = { eq, lt, gt, lte, gte, ifelse }; diff --git a/packages/kbn-tinymath/src/functions/comparison/lt.js b/packages/kbn-tinymath/src/functions/comparison/lt.js new file mode 100644 index 00000000000000..fb7a444d1af7a3 --- /dev/null +++ b/packages/kbn-tinymath/src/functions/comparison/lt.js @@ -0,0 +1,39 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +/** + * Performs a lower than comparison between two values. + * @param {number|number[]} a a number or an array of numbers + * @param {number|number[]} b a number or an array of numbers + * @return {boolean} Returns true if `a` is lower than `b`, false otherwise. Returns an array with the lower than comparison of each element if `a` is an array. + * @throws `'Missing b value'` if `b` is not provided + * @throws `'Array length mismatch'` if `args` contains arrays of different lengths + * @example + * lt(1, 1) // returns false + * lt(1, 2) // returns true + * lt([1, 2], 2) // returns [true, false] + * lt([1, 2], [1, 2]) // returns [false, false] + */ + +function lt(a, b) { + if (b == null) { + throw new Error('Missing b value'); + } + if (Array.isArray(a)) { + if (!Array.isArray(b)) { + return a.every((v) => v < b); + } + if (a.length !== b.length) { + throw new Error('Array length mismatch'); + } + return a.every((v, i) => v < b[i]); + } + + return a < b; +} +module.exports = { lt }; diff --git a/packages/kbn-tinymath/src/functions/comparison/lte.js b/packages/kbn-tinymath/src/functions/comparison/lte.js new file mode 100644 index 00000000000000..36aceb11f3bd78 --- /dev/null +++ b/packages/kbn-tinymath/src/functions/comparison/lte.js @@ -0,0 +1,28 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +const { eq } = require('./eq'); +const { lt } = require('./lt'); + +/** + * Performs a lower than or equal comparison between two values. + * @param {number|number[]} a a number or an array of numbers + * @param {number|number[]} b a number or an array of numbers + * @return {boolean} Returns true if `a` is lower than or equal to `b`, false otherwise. Returns an array with the lower than or equal comparison of each element if `a` is an array. + * @throws `'Array length mismatch'` if `args` contains arrays of different lengths + * @example + * lte(1, 1) // returns true + * lte(1, 2) // returns true + * lte([1, 2], 2) // returns [true, true] + * lte([1, 2], [1, 1]) // returns [true, false] + */ + +function lte(a, b) { + return eq(a, b) || lt(a, b); +} +module.exports = { lte }; diff --git a/packages/kbn-tinymath/src/functions/cos.js b/packages/kbn-tinymath/src/functions/cos.js index 590cc2aee06b9c..590f2bf5bd5e02 100644 --- a/packages/kbn-tinymath/src/functions/cos.js +++ b/packages/kbn-tinymath/src/functions/cos.js @@ -16,11 +16,10 @@ * cos([0, 1.5707963267948966]) // returns [1, 6.123233995736766e-17] */ -module.exports = { cos }; - function cos(a) { if (Array.isArray(a)) { return a.map((a) => Math.cos(a)); } return Math.cos(a); } +module.exports = { cos }; diff --git a/packages/kbn-tinymath/src/functions/count.js b/packages/kbn-tinymath/src/functions/count.js index aa01e1c25835a0..ecddb623180f29 100644 --- a/packages/kbn-tinymath/src/functions/count.js +++ b/packages/kbn-tinymath/src/functions/count.js @@ -19,10 +19,10 @@ const { size } = require('./size'); * count(100) // returns 1 */ -module.exports = { count }; - function count(a) { return size(a); } count.skipNumberValidation = true; + +module.exports = { count }; diff --git a/packages/kbn-tinymath/src/functions/cube.js b/packages/kbn-tinymath/src/functions/cube.js index 4d6f8cbea6374d..92fe42326f056d 100644 --- a/packages/kbn-tinymath/src/functions/cube.js +++ b/packages/kbn-tinymath/src/functions/cube.js @@ -18,8 +18,7 @@ const { pow } = require('./pow'); * cube([3, 4, 5]) // returns [27, 64, 125] */ -module.exports = { cube }; - function cube(a) { return pow(a, 3); } +module.exports = { cube }; diff --git a/packages/kbn-tinymath/src/functions/degtorad.js b/packages/kbn-tinymath/src/functions/degtorad.js index e50365b0beabc9..ce6f53ac29c27e 100644 --- a/packages/kbn-tinymath/src/functions/degtorad.js +++ b/packages/kbn-tinymath/src/functions/degtorad.js @@ -16,11 +16,10 @@ * degtorad([0, 90, 180, 360]) // returns [0, 1.5707963267948966, 3.141592653589793, 6.283185307179586] */ -module.exports = { degtorad }; - function degtorad(a) { if (Array.isArray(a)) { return a.map((a) => (a * Math.PI) / 180); } return (a * Math.PI) / 180; } +module.exports = { degtorad }; diff --git a/packages/kbn-tinymath/src/functions/divide.js b/packages/kbn-tinymath/src/functions/divide.js index 3f323944c886b5..b572217f3ce7d8 100644 --- a/packages/kbn-tinymath/src/functions/divide.js +++ b/packages/kbn-tinymath/src/functions/divide.js @@ -20,8 +20,6 @@ * divide([14, 42, 65, 108], [2, 7, 5, 12]) // returns [7, 6, 13, 9] */ -module.exports = { divide }; - function divide(a, b) { if (Array.isArray(a) && Array.isArray(b)) { if (a.length !== b.length) throw new Error('Array length mismatch'); @@ -30,8 +28,14 @@ function divide(a, b) { return val / b[i]; }); } - if (Array.isArray(b)) return b.map((b) => a / b); + if (Array.isArray(b)) { + return b.map((bi) => { + if (bi === 0) throw new Error('Cannot divide by 0'); + return a / bi; + }); + } if (b === 0) throw new Error('Cannot divide by 0'); if (Array.isArray(a)) return a.map((a) => a / b); return a / b; } +module.exports = { divide }; diff --git a/packages/kbn-tinymath/src/functions/exp.js b/packages/kbn-tinymath/src/functions/exp.js index 79669b9dcceddc..cf89785e507c1c 100644 --- a/packages/kbn-tinymath/src/functions/exp.js +++ b/packages/kbn-tinymath/src/functions/exp.js @@ -16,11 +16,10 @@ * exp([1, 2, 3]) // returns [e^1, e^2, e^3] = [2.718281828459045, 7.3890560989306495, 20.085536923187668] */ -module.exports = { exp }; - function exp(a) { if (Array.isArray(a)) { return a.map((a) => Math.exp(a)); } return Math.exp(a); } +module.exports = { exp }; diff --git a/packages/kbn-tinymath/src/functions/first.js b/packages/kbn-tinymath/src/functions/first.js index 894cb38e69f470..d7970ac0abb716 100644 --- a/packages/kbn-tinymath/src/functions/first.js +++ b/packages/kbn-tinymath/src/functions/first.js @@ -16,8 +16,6 @@ * first([1, 2, 3]) // returns 1 */ -module.exports = { first }; - function first(a) { if (Array.isArray(a)) { return a[0]; @@ -26,3 +24,5 @@ function first(a) { } first.skipNumberValidation = true; + +module.exports = { first }; diff --git a/packages/kbn-tinymath/src/functions/fix.js b/packages/kbn-tinymath/src/functions/fix.js index 1d297327fd47be..3088a949add777 100644 --- a/packages/kbn-tinymath/src/functions/fix.js +++ b/packages/kbn-tinymath/src/functions/fix.js @@ -24,11 +24,11 @@ const fixer = (a) => { * fix([1.8, 2.9, -3.7, -4.6]) // returns [1, 2, -3, -4] */ -module.exports = { fix }; - function fix(a) { if (Array.isArray(a)) { return a.map((a) => fixer(a)); } return fixer(a); } + +module.exports = { fix }; diff --git a/packages/kbn-tinymath/src/functions/floor.js b/packages/kbn-tinymath/src/functions/floor.js index 5d27228d7cdf9f..e13f64dc665aee 100644 --- a/packages/kbn-tinymath/src/functions/floor.js +++ b/packages/kbn-tinymath/src/functions/floor.js @@ -17,11 +17,11 @@ * floor([1.7, 2.8, 3.9]) // returns [1, 2, 3] */ -module.exports = { floor }; - function floor(a) { if (Array.isArray(a)) { return a.map((a) => Math.floor(a)); } return Math.floor(a); } + +module.exports = { floor }; diff --git a/packages/kbn-tinymath/src/functions/index.js b/packages/kbn-tinymath/src/functions/index.js index 37c2a13c41cf47..8f0740cb08571c 100644 --- a/packages/kbn-tinymath/src/functions/index.js +++ b/packages/kbn-tinymath/src/functions/index.js @@ -45,6 +45,7 @@ const { subtract } = require('./subtract'); const { sum } = require('./sum'); const { tan } = require('./tan'); const { unique } = require('./unique'); +const { eq, lt, gt, lte, gte, ifelse } = require('./comparison'); module.exports = { functions: { @@ -63,6 +64,7 @@ module.exports = { first, fix, floor, + ifelse, last, log, log10, @@ -87,5 +89,10 @@ module.exports = { sum, tan, unique, + eq, + lt, + gt, + lte, + gte, }, }; diff --git a/packages/kbn-tinymath/src/functions/last.js b/packages/kbn-tinymath/src/functions/last.js index 63ba3bd1cfc355..7cdd5fe9cdde6f 100644 --- a/packages/kbn-tinymath/src/functions/last.js +++ b/packages/kbn-tinymath/src/functions/last.js @@ -16,8 +16,6 @@ * last([1, 2, 3]) // returns 3 */ -module.exports = { last }; - function last(a) { if (Array.isArray(a)) { return a[a.length - 1]; @@ -26,3 +24,4 @@ function last(a) { } last.skipNumberValidation = true; +module.exports = { last }; diff --git a/packages/kbn-tinymath/src/functions/lib/transpose.js b/packages/kbn-tinymath/src/functions/lib/transpose.js index 9637971cec7cfe..9e4d673fdf57a0 100644 --- a/packages/kbn-tinymath/src/functions/lib/transpose.js +++ b/packages/kbn-tinymath/src/functions/lib/transpose.js @@ -8,6 +8,7 @@ /** * Transposes a 2D array, i.e. turns the rows into columns and vice versa. Scalar values are also included in the transpose. + * @private * @param {any[][]} args an array or an array that contains arrays * @param {number} index index of the first array element in args * @return {any[][]} transpose of args diff --git a/packages/kbn-tinymath/src/functions/log.js b/packages/kbn-tinymath/src/functions/log.js index 083c9cdef2dc02..06043eca5384cb 100644 --- a/packages/kbn-tinymath/src/functions/log.js +++ b/packages/kbn-tinymath/src/functions/log.js @@ -22,8 +22,6 @@ const changeOfBase = (a, b) => Math.log(a) / Math.log(b); * log([2, 4, 8, 16, 32], 2) // returns [1, 2, 3, 4, 5] */ -module.exports = { log }; - function log(a, b = Math.E) { if (b <= 0) throw new Error('Base out of range'); @@ -36,3 +34,4 @@ function log(a, b = Math.E) { if (a < 0) throw new Error('Must be greater than 0'); return changeOfBase(a, b); } +module.exports = { log }; diff --git a/packages/kbn-tinymath/src/functions/log10.js b/packages/kbn-tinymath/src/functions/log10.js index 68c2ffb2bbd305..09f7182e703750 100644 --- a/packages/kbn-tinymath/src/functions/log10.js +++ b/packages/kbn-tinymath/src/functions/log10.js @@ -20,8 +20,7 @@ const { log } = require('./log'); * log([10, 100, 1000, 10000, 100000]) // returns [1, 2, 3, 4, 5] */ -module.exports = { log10 }; - function log10(a) { return log(a, 10); } +module.exports = { log10 }; diff --git a/packages/kbn-tinymath/src/functions/max.js b/packages/kbn-tinymath/src/functions/max.js index 4b6bb2bd27d5ea..46e6fec0f69899 100644 --- a/packages/kbn-tinymath/src/functions/max.js +++ b/packages/kbn-tinymath/src/functions/max.js @@ -17,8 +17,6 @@ * max([1, 9], 4, [3, 5]) // returns [max([1, 4, 3]), max([9, 4, 5])] = [4, 9] */ -module.exports = { max }; - function max(...args) { if (args.length === 1) { if (Array.isArray(args[0])) @@ -36,3 +34,4 @@ function max(...args) { return Math.max(result, current); }); } +module.exports = { max }; diff --git a/packages/kbn-tinymath/src/functions/mean.js b/packages/kbn-tinymath/src/functions/mean.js index 441b90cff2ac33..995c54b3b1ea02 100644 --- a/packages/kbn-tinymath/src/functions/mean.js +++ b/packages/kbn-tinymath/src/functions/mean.js @@ -19,8 +19,6 @@ const { add } = require('./add'); * mean([1, 9], 5, [3, 4]) // returns [mean([1, 5, 3]), mean([9, 5, 4])] = [3, 6] */ -module.exports = { mean }; - function mean(...args) { if (args.length === 1) { if (Array.isArray(args[0])) return add(args[0]) / args[0].length; @@ -34,3 +32,4 @@ function mean(...args) { return sum / args.length; } +module.exports = { mean }; diff --git a/packages/kbn-tinymath/src/functions/median.js b/packages/kbn-tinymath/src/functions/median.js index 7c47158a81ddae..facac3d367750d 100644 --- a/packages/kbn-tinymath/src/functions/median.js +++ b/packages/kbn-tinymath/src/functions/median.js @@ -33,8 +33,6 @@ const findMedian = (a) => { * median([1, 9], 2, 4, [3, 5]) // returns [median([1, 2, 4, 3]), median([9, 2, 4, 5])] = [2.5, 4.5] */ -module.exports = { median }; - function median(...args) { if (args.length === 1) { if (Array.isArray(args[0])) return findMedian(args[0]); @@ -48,3 +46,4 @@ function median(...args) { } return findMedian(args); } +module.exports = { median }; diff --git a/packages/kbn-tinymath/src/functions/min.js b/packages/kbn-tinymath/src/functions/min.js index 356ccecc4b6f2d..8f9ecd7c25c280 100644 --- a/packages/kbn-tinymath/src/functions/min.js +++ b/packages/kbn-tinymath/src/functions/min.js @@ -17,8 +17,6 @@ * min([1, 9], 4, [3, 5]) // returns [min([1, 4, 3]), min([9, 4, 5])] = [1, 4] */ -module.exports = { min }; - function min(...args) { if (args.length === 1) { if (Array.isArray(args[0])) @@ -36,3 +34,4 @@ function min(...args) { return Math.min(result, current); }); } +module.exports = { min }; diff --git a/packages/kbn-tinymath/src/functions/mod.js b/packages/kbn-tinymath/src/functions/mod.js index 7f6a4fffca829a..bb945772f41c99 100644 --- a/packages/kbn-tinymath/src/functions/mod.js +++ b/packages/kbn-tinymath/src/functions/mod.js @@ -20,8 +20,6 @@ * mod([14, 42, 65, 108], [5, 4, 14, 2]) // returns [5, 2, 9, 0] */ -module.exports = { mod }; - function mod(a, b) { if (Array.isArray(a) && Array.isArray(b)) { if (a.length !== b.length) throw new Error('Array length mismatch'); @@ -35,3 +33,4 @@ function mod(a, b) { if (Array.isArray(a)) return a.map((a) => a % b); return a % b; } +module.exports = { mod }; diff --git a/packages/kbn-tinymath/src/functions/mode.js b/packages/kbn-tinymath/src/functions/mode.js index 0836c1c939f440..99f0086de0a787 100644 --- a/packages/kbn-tinymath/src/functions/mode.js +++ b/packages/kbn-tinymath/src/functions/mode.js @@ -40,8 +40,6 @@ const findMode = (a) => { * mode([1, 9], 1, 4, [3, 5]) // returns [mode([1, 1, 4, 3]), mode([9, 1, 4, 5])] = [[1], [4, 5, 9]] */ -module.exports = { mode }; - function mode(...args) { if (args.length === 1) { if (Array.isArray(args[0])) return findMode(args[0]); @@ -55,3 +53,4 @@ function mode(...args) { } return findMode(args); } +module.exports = { mode }; diff --git a/packages/kbn-tinymath/src/functions/multiply.js b/packages/kbn-tinymath/src/functions/multiply.js index d7c9c75ee36479..d9d6c751bdaf79 100644 --- a/packages/kbn-tinymath/src/functions/multiply.js +++ b/packages/kbn-tinymath/src/functions/multiply.js @@ -19,8 +19,6 @@ * multiply([1, 2, 3, 4], [2, 7, 5, 12]) // returns [2, 14, 15, 48] */ -module.exports = { multiply }; - function multiply(...args) { return args.reduce((result, current) => { if (Array.isArray(result) && Array.isArray(current)) { @@ -32,3 +30,4 @@ function multiply(...args) { return result * current; }); } +module.exports = { multiply }; diff --git a/packages/kbn-tinymath/src/functions/pi.js b/packages/kbn-tinymath/src/functions/pi.js index 9f0b74292524c7..dacb0ea5ea4ed7 100644 --- a/packages/kbn-tinymath/src/functions/pi.js +++ b/packages/kbn-tinymath/src/functions/pi.js @@ -14,8 +14,7 @@ * pi() // 3.141592653589793 */ -module.exports = { pi }; - function pi() { return Math.PI; } +module.exports = { pi }; diff --git a/packages/kbn-tinymath/src/functions/pow.js b/packages/kbn-tinymath/src/functions/pow.js index 2c600cb7f47aae..e2be268d3c623c 100644 --- a/packages/kbn-tinymath/src/functions/pow.js +++ b/packages/kbn-tinymath/src/functions/pow.js @@ -17,8 +17,6 @@ * pow([1, 2, 3], 4) // returns [1, 16, 81] */ -module.exports = { pow }; - function pow(a, b) { if (b == null) throw new Error('Missing exponent'); if (Array.isArray(a)) { @@ -26,3 +24,4 @@ function pow(a, b) { } return Math.pow(a, b); } +module.exports = { pow }; diff --git a/packages/kbn-tinymath/src/functions/radtodeg.js b/packages/kbn-tinymath/src/functions/radtodeg.js index 6cfd40841ba556..733147334a637c 100644 --- a/packages/kbn-tinymath/src/functions/radtodeg.js +++ b/packages/kbn-tinymath/src/functions/radtodeg.js @@ -16,11 +16,10 @@ * radtodeg([0, 1.5707963267948966, 3.141592653589793, 6.283185307179586]) // returns [0, 90, 180, 360] */ -module.exports = { radtodeg }; - function radtodeg(a) { if (Array.isArray(a)) { return a.map((a) => (a * 180) / Math.PI); } return (a * 180) / Math.PI; } +module.exports = { radtodeg }; diff --git a/packages/kbn-tinymath/src/functions/random.js b/packages/kbn-tinymath/src/functions/random.js index 799f6515d4ca51..be2dd2c7733221 100644 --- a/packages/kbn-tinymath/src/functions/random.js +++ b/packages/kbn-tinymath/src/functions/random.js @@ -18,8 +18,6 @@ * random(-10,10) // returns a random number between -10 (inclusive) and 10 (exclusive) */ -module.exports = { random }; - function random(a, b) { if (a == null) return Math.random(); @@ -33,3 +31,5 @@ function random(a, b) { if (a > b) throw new Error(`Min is greater than max`); return Math.random() * (b - a) + a; } + +module.exports = { random }; diff --git a/packages/kbn-tinymath/src/functions/range.js b/packages/kbn-tinymath/src/functions/range.js index 571b179b75b650..0b2a05dfb8ae48 100644 --- a/packages/kbn-tinymath/src/functions/range.js +++ b/packages/kbn-tinymath/src/functions/range.js @@ -21,8 +21,7 @@ const { subtract } = require('./subtract'); * range([1, 9], 4, [3, 5]) // returns [range([1, 4, 3]), range([9, 4, 5])] = [3, 5] */ -module.exports = { range }; - function range(...args) { return subtract(max(...args), min(...args)); } +module.exports = { range }; diff --git a/packages/kbn-tinymath/src/functions/round.js b/packages/kbn-tinymath/src/functions/round.js index 9befb64ca5d45f..88d45fda42b5f8 100644 --- a/packages/kbn-tinymath/src/functions/round.js +++ b/packages/kbn-tinymath/src/functions/round.js @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -const rounder = (a, b) => Math.round(a * Math.pow(10, b)) / Math.pow(10, b); +const rounder = (a, b = 0) => Math.round(a * Math.pow(10, b)) / Math.pow(10, b); /** * Rounds a number towards the nearest integer by default or decimal place if specified. For arrays, the function will be applied index-wise to each element. @@ -22,11 +22,10 @@ const rounder = (a, b) => Math.round(a * Math.pow(10, b)) / Math.pow(10, b); * round([2.9234, 5.1234, 3.5234, 4.49234324], 2) // returns [2.92, 5.12, 3.52, 4.49] */ -module.exports = { round }; - -function round(a, b = 0) { +function round(a, b) { if (Array.isArray(a)) { return a.map((a) => rounder(a, b)); } return rounder(a, b); } +module.exports = { round }; diff --git a/packages/kbn-tinymath/src/functions/sin.js b/packages/kbn-tinymath/src/functions/sin.js index 591c799ff3ebe7..6a2801623283eb 100644 --- a/packages/kbn-tinymath/src/functions/sin.js +++ b/packages/kbn-tinymath/src/functions/sin.js @@ -16,11 +16,10 @@ * sin([0, 1.5707963267948966]) // returns [0, 1] */ -module.exports = { sin }; - function sin(a) { if (Array.isArray(a)) { return a.map((a) => Math.sin(a)); } return Math.sin(a); } +module.exports = { sin }; diff --git a/packages/kbn-tinymath/src/functions/size.js b/packages/kbn-tinymath/src/functions/size.js index fb16bcb905f969..f862ee33ed92ac 100644 --- a/packages/kbn-tinymath/src/functions/size.js +++ b/packages/kbn-tinymath/src/functions/size.js @@ -17,11 +17,10 @@ * size(100) // returns 1 */ -module.exports = { size }; - function size(a) { if (Array.isArray(a)) return a.length; throw new Error('Must pass an array'); } size.skipNumberValidation = true; +module.exports = { size }; diff --git a/packages/kbn-tinymath/src/functions/sqrt.js b/packages/kbn-tinymath/src/functions/sqrt.js index 19aeaab964d034..fa666d6a4b0ba4 100644 --- a/packages/kbn-tinymath/src/functions/sqrt.js +++ b/packages/kbn-tinymath/src/functions/sqrt.js @@ -17,8 +17,6 @@ * sqrt([9, 16, 25]) // returns [3, 4, 5] */ -module.exports = { sqrt }; - function sqrt(a) { if (Array.isArray(a)) { return a.map((a) => { @@ -30,3 +28,4 @@ function sqrt(a) { if (a < 0) throw new Error('Unable find the square root of a negative number'); return Math.sqrt(a); } +module.exports = { sqrt }; diff --git a/packages/kbn-tinymath/src/functions/square.js b/packages/kbn-tinymath/src/functions/square.js index 5c285eaee32099..58acd1c7f5e334 100644 --- a/packages/kbn-tinymath/src/functions/square.js +++ b/packages/kbn-tinymath/src/functions/square.js @@ -18,8 +18,7 @@ const { pow } = require('./pow'); * square([3, 4, 5]) // returns [9, 16, 25] */ -module.exports = { square }; - function square(a) { return pow(a, 2); } +module.exports = { square }; diff --git a/packages/kbn-tinymath/src/functions/subtract.js b/packages/kbn-tinymath/src/functions/subtract.js index becc267ca51bb4..fe2b5ae7544565 100644 --- a/packages/kbn-tinymath/src/functions/subtract.js +++ b/packages/kbn-tinymath/src/functions/subtract.js @@ -19,8 +19,6 @@ * subtract([14, 42, 65, 108], [2, 7, 5, 12]) // returns [12, 35, 52, 96] */ -module.exports = { subtract }; - function subtract(a, b) { if (Array.isArray(a) && Array.isArray(b)) { if (a.length !== b.length) throw new Error('Array length mismatch'); @@ -30,3 +28,4 @@ function subtract(a, b) { if (Array.isArray(b)) return b.map((b) => a - b); return a - b; } +module.exports = { subtract }; diff --git a/packages/kbn-tinymath/src/functions/sum.js b/packages/kbn-tinymath/src/functions/sum.js index d9a8f4e5310107..fb5bca8abde004 100644 --- a/packages/kbn-tinymath/src/functions/sum.js +++ b/packages/kbn-tinymath/src/functions/sum.js @@ -20,8 +20,6 @@ const findSum = (total, current) => total + current; * sum([10, 20, 30, 40], 10, [1, 2, 3], 22) // returns sum(10, 20, 30, 40, 10, 1, 2, 3, 22) = 138 */ -module.exports = { sum }; - function sum(...args) { return args.reduce((total, current) => { if (Array.isArray(current)) { @@ -30,3 +28,4 @@ function sum(...args) { return total + current; }, 0); } +module.exports = { sum }; diff --git a/packages/kbn-tinymath/src/functions/tan.js b/packages/kbn-tinymath/src/functions/tan.js index 7f045acce0f384..4c980ee3fd2722 100644 --- a/packages/kbn-tinymath/src/functions/tan.js +++ b/packages/kbn-tinymath/src/functions/tan.js @@ -16,11 +16,10 @@ * tan([0, 1, -1]) // returns [0, 1.5574077246549023, -1.5574077246549023] */ -module.exports = { tan }; - function tan(a) { if (Array.isArray(a)) { return a.map((a) => Math.tan(a)); } return Math.tan(a); } +module.exports = { tan }; diff --git a/packages/kbn-tinymath/src/functions/unique.js b/packages/kbn-tinymath/src/functions/unique.js index 5220b4ad79adfd..77153c036822db 100644 --- a/packages/kbn-tinymath/src/functions/unique.js +++ b/packages/kbn-tinymath/src/functions/unique.js @@ -18,8 +18,6 @@ * unique([1, 2, 3, 4, 2, 2, 2, 3, 4, 2, 4, 5, 2, 1, 4, 2]) // returns 5 */ -module.exports = { unique }; - function unique(a) { if (Array.isArray(a)) { return a.filter((val, i) => a.indexOf(val) === i).length; @@ -28,3 +26,4 @@ function unique(a) { } unique.skipNumberValidation = true; +module.exports = { unique }; diff --git a/packages/kbn-tinymath/test/functions/comparison/eq.test.js b/packages/kbn-tinymath/test/functions/comparison/eq.test.js new file mode 100644 index 00000000000000..eb84479a3708a7 --- /dev/null +++ b/packages/kbn-tinymath/test/functions/comparison/eq.test.js @@ -0,0 +1,42 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +const { eq } = require('../../../src/functions/comparison/eq'); + +describe('Eq', () => { + it('numbers', () => { + expect(eq(-10, -10)).toBeTruthy(); + expect(eq(10, 10)).toBeTruthy(); + expect(eq(0, 0)).toBeTruthy(); + }); + + it('arrays', () => { + // Should pass + expect(eq([-1], -1)).toBeTruthy(); + expect(eq([-1], [-1])).toBeTruthy(); + expect(eq([-1, -1], -1)).toBeTruthy(); + expect(eq([-1, -1], [-1, -1])).toBeTruthy(); + + // Should not pass + expect(eq([-1], 0)).toBeFalsy(); + expect(eq([-1], [0])).toBeFalsy(); + expect(eq([-1, -1], 0)).toBeFalsy(); + expect(eq([-1, -1], [0, 0])).toBeFalsy(); + expect(eq([-1, -1], [-1, 0])).toBeFalsy(); + }); + + it('missing args', () => { + expect(() => eq()).toThrow(); + expect(() => eq(-10)).toThrow(); + expect(() => eq([])).toThrow(); + }); + + it('empty arrays', () => { + expect(eq([], [])).toBeTruthy(); + }); +}); diff --git a/packages/kbn-tinymath/test/functions/comparison/gt.test.js b/packages/kbn-tinymath/test/functions/comparison/gt.test.js new file mode 100644 index 00000000000000..a6a7173d350434 --- /dev/null +++ b/packages/kbn-tinymath/test/functions/comparison/gt.test.js @@ -0,0 +1,42 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +const { gt } = require('../../../src/functions/comparison/gt'); + +describe('Gt', () => { + it('missing args', () => { + expect(() => gt()).toThrow(); + expect(() => gt(-10)).toThrow(); + expect(() => gt([])).toThrow(); + }); + + it('empty arrays', () => { + expect(gt([], [])).toBeTruthy(); + }); + + it('numbers', () => { + expect(gt(-10, -20)).toBeTruthy(); + expect(gt(10, 0)).toBeTruthy(); + expect(gt(0, -1)).toBeTruthy(); + }); + + it('arrays', () => { + // Should pass + expect(gt([-1], -2)).toBeTruthy(); + expect(gt([-1], [-2])).toBeTruthy(); + expect(gt([-1, -1], -2)).toBeTruthy(); + expect(gt([-1, -1], [-2, -2])).toBeTruthy(); + + // Should not pass + expect(gt([-1], 2)).toBeFalsy(); + expect(gt([-1], [2])).toBeFalsy(); + expect(gt([-1, -1], 2)).toBeFalsy(); + expect(gt([-1, -1], [2, 2])).toBeFalsy(); + expect(gt([-1, -1], [-2, 2])).toBeFalsy(); + }); +}); diff --git a/packages/kbn-tinymath/test/functions/comparison/gte.test.js b/packages/kbn-tinymath/test/functions/comparison/gte.test.js new file mode 100644 index 00000000000000..fde1294a5a0fc5 --- /dev/null +++ b/packages/kbn-tinymath/test/functions/comparison/gte.test.js @@ -0,0 +1,59 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +const { gte } = require('../../../src/functions/comparison/gte'); + +describe('Gte', () => { + it('missing args', () => { + expect(() => gte()).toThrow(); + expect(() => gte(-10)).toThrow(); + expect(() => gte([])).toThrow(); + }); + + it('empty arrays', () => { + expect(gte([], [])).toBeTruthy(); + }); + + describe('eq values', () => { + it('numbers', () => { + expect(gte(-10, -10)).toBeTruthy(); + expect(gte(10, 10)).toBeTruthy(); + expect(gte(0, 0)).toBeTruthy(); + }); + + it('arrays', () => { + expect(gte([-1], -1)).toBeTruthy(); + expect(gte([-1], [-1])).toBeTruthy(); + expect(gte([-1, -1], -1)).toBeTruthy(); + expect(gte([-1, -1], [-1, -1])).toBeTruthy(); + }); + }); + + describe('gt values', () => { + it('numbers', () => { + expect(gte(-10, -20)).toBeTruthy(); + expect(gte(10, 0)).toBeTruthy(); + expect(gte(0, -1)).toBeTruthy(); + }); + + it('arrays', () => { + // Should pass + expect(gte([-1], -2)).toBeTruthy(); + expect(gte([-1], [-2])).toBeTruthy(); + expect(gte([-1, -1], -2)).toBeTruthy(); + expect(gte([-1, -1], [-2, -2])).toBeTruthy(); + + // Should not pass + expect(gte([-1], 2)).toBeFalsy(); + expect(gte([-1], [2])).toBeFalsy(); + expect(gte([-1, -1], 2)).toBeFalsy(); + expect(gte([-1, -1], [2, 2])).toBeFalsy(); + expect(gte([-1, -1], [-2, 2])).toBeFalsy(); + }); + }); +}); diff --git a/packages/kbn-tinymath/test/functions/comparison/ifelse.test.js b/packages/kbn-tinymath/test/functions/comparison/ifelse.test.js new file mode 100644 index 00000000000000..efd098e26292a1 --- /dev/null +++ b/packages/kbn-tinymath/test/functions/comparison/ifelse.test.js @@ -0,0 +1,33 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +const { ifelse } = require('../../../src/functions/comparison/ifelse'); + +describe('Ifelse', () => { + it('should basically work', () => { + expect(ifelse(true, 1, 0)).toEqual(1); + expect(ifelse(false, 1, 0)).toEqual(0); + expect(ifelse(1 > 0, 1, 0)).toEqual(1); + expect(ifelse(1 < 0, 1, 0)).toEqual(0); + }); + + it('should throw if cond is not of boolean type', () => { + expect(() => ifelse(5, 1, 0)).toThrow('Condition clause is of the wrong type'); + expect(() => ifelse(null, 1, 0)).toThrow('Condition clause is of the wrong type'); + expect(() => ifelse(undefined, 1, 0)).toThrow('Condition clause is of the wrong type'); + expect(() => ifelse(0, 1, 0)).toThrow('Condition clause is of the wrong type'); + }); + + it('missing args', () => { + expect(() => ifelse()).toThrow(); + expect(() => ifelse(-10)).toThrow(); + expect(() => ifelse([])).toThrow(); + expect(() => ifelse(true)).toThrow(); + expect(() => ifelse(true, 1)).toThrow(); + }); +}); diff --git a/packages/kbn-tinymath/test/functions/comparison/lt.test.js b/packages/kbn-tinymath/test/functions/comparison/lt.test.js new file mode 100644 index 00000000000000..cbd56a4ac674ec --- /dev/null +++ b/packages/kbn-tinymath/test/functions/comparison/lt.test.js @@ -0,0 +1,42 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +const { lt } = require('../../../src/functions/comparison/lt'); + +describe('Lt', () => { + it('missing args', () => { + expect(() => lt()).toThrow(); + expect(() => lt(-10)).toThrow(); + expect(() => lt([])).toThrow(); + }); + + it('empty arrays', () => { + expect(lt([], [])).toBeTruthy(); + }); + + it('numbers', () => { + expect(lt(-10, -2)).toBeTruthy(); + expect(lt(10, 20)).toBeTruthy(); + expect(lt(0, 1)).toBeTruthy(); + }); + + it('arrays', () => { + // Should pass + expect(lt([-1], 0)).toBeTruthy(); + expect(lt([-1], [0])).toBeTruthy(); + expect(lt([-1, -1], 0)).toBeTruthy(); + expect(lt([-1, -1], [0, 0])).toBeTruthy(); + + // Should not pass + expect(lt([-1], -2)).toBeFalsy(); + expect(lt([-1], [-2])).toBeFalsy(); + expect(lt([-1, -1], -2)).toBeFalsy(); + expect(lt([-1, -1], [-2, -2])).toBeFalsy(); + expect(lt([-1, -1], [-2, 2])).toBeFalsy(); + }); +}); diff --git a/packages/kbn-tinymath/test/functions/comparison/lte.test.js b/packages/kbn-tinymath/test/functions/comparison/lte.test.js new file mode 100644 index 00000000000000..5c6f4a4b5eaa78 --- /dev/null +++ b/packages/kbn-tinymath/test/functions/comparison/lte.test.js @@ -0,0 +1,59 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +const { lte } = require('../../../src/functions/comparison/lte'); + +describe('Lte', () => { + it('missing args', () => { + expect(() => lte()).toThrow(); + expect(() => lte(-10)).toThrow(); + expect(() => lte([])).toThrow(); + }); + + it('empty arrays', () => { + expect(lte([], [])).toBeTruthy(); + }); + + describe('eq values', () => { + it('numbers', () => { + expect(lte(-10, -10)).toBeTruthy(); + expect(lte(10, 10)).toBeTruthy(); + expect(lte(0, 0)).toBeTruthy(); + }); + + it('arrays', () => { + expect(lte([-1], -1)).toBeTruthy(); + expect(lte([-1], [-1])).toBeTruthy(); + expect(lte([-1, -1], -1)).toBeTruthy(); + expect(lte([-1, -1], [-1, -1])).toBeTruthy(); + }); + }); + + describe('lt values', () => { + it('numbers', () => { + expect(lte(-10, -2)).toBeTruthy(); + expect(lte(10, 20)).toBeTruthy(); + expect(lte(0, 1)).toBeTruthy(); + }); + + it('arrays', () => { + // Should pass + expect(lte([-1], 0)).toBeTruthy(); + expect(lte([-1], [0])).toBeTruthy(); + expect(lte([-1, -1], 0)).toBeTruthy(); + expect(lte([-1, -1], [0, 0])).toBeTruthy(); + + // Should not pass + expect(lte([-1], -2)).toBeFalsy(); + expect(lte([-1], [-2])).toBeFalsy(); + expect(lte([-1, -1], -2)).toBeFalsy(); + expect(lte([-1, -1], [-2, -2])).toBeFalsy(); + expect(lte([-1, -1], [-2, 2])).toBeFalsy(); + }); + }); +}); diff --git a/packages/kbn-tinymath/test/functions/divide.test.js b/packages/kbn-tinymath/test/functions/divide.test.js index 00af7b1430e588..85851e78df8dda 100644 --- a/packages/kbn-tinymath/test/functions/divide.test.js +++ b/packages/kbn-tinymath/test/functions/divide.test.js @@ -29,4 +29,11 @@ describe('Divide', () => { it('array length mismatch', () => { expect(() => divide([1, 2], [3])).toThrow('Array length mismatch'); }); + + it('divide by 0', () => { + expect(() => divide([1, 2], 0)).toThrow('Cannot divide by 0'); + expect(() => divide(1, 0)).toThrow('Cannot divide by 0'); + expect(() => divide([1, 2], [0, 0])).toThrow('Cannot divide by 0'); + expect(() => divide(1, [1, 0])).toThrow('Cannot divide by 0'); + }); }); diff --git a/packages/kbn-tinymath/test/library.test.js b/packages/kbn-tinymath/test/library.test.js index 9d87919c4f1acf..054d78fc60adb2 100644 --- a/packages/kbn-tinymath/test/library.test.js +++ b/packages/kbn-tinymath/test/library.test.js @@ -68,6 +68,91 @@ describe('Parser', () => { location: { min: 0, max: 13 }, }); }); + + describe('Comparison', () => { + it('should throw for non valid comparison symbols', () => { + const symbols = ['<>', '><', '===', '>>', '<<']; + for (const symbol of symbols) { + expect(() => parse(`5 ${symbol} 1`)).toThrow(); + } + }); + describe.each` + symbol | fn + ${'<'} | ${'lt'} + ${'>'} | ${'gt'} + ${'=='} | ${'eq'} + ${'>='} | ${'gte'} + ${'<='} | ${'lte'} + `('Symbol "$symbol" ( $fn )', ({ symbol, fn }) => { + it(`should parse comparison symbol: "$symbol"`, () => { + expect(parse(`5 ${symbol} 1`)).toEqual({ + name: fn, + type: 'function', + args: [5, 1], + text: `5 ${symbol} 1`, + location: { min: 0, max: 4 + symbol.length }, + }); + expect(parse(`a ${symbol} b`)).toEqual({ + name: fn, + type: 'function', + args: [variableEqual('a'), variableEqual('b')], + text: `a ${symbol} b`, + location: { min: 0, max: 4 + symbol.length }, + }); + }); + + it.each` + expression + ${`1 + (1 ${symbol} 1)`} + ${`(1 ${symbol} 1) + 1`} + ${`((1 ${symbol} 1) + 1)`} + ${`((1 ${symbol} 1) + (1 ${symbol} 1))`} + ${`((1 ${symbol} 1) + ( ${symbol} 1))`} + ${` ${symbol} 1`} + ${`1 ${symbol} `} + ${`a + (b ${symbol} c)`} + ${`(a ${symbol} b) + c`} + ${`((a ${symbol} b) + c)`} + ${`((a ${symbol} b) + (c ${symbol} d))`} + ${`((a ${symbol} b) + ( ${symbol} c))`} + ${` ${symbol} a`} + ${`a ${symbol} `} + `( + 'should throw for invalid expression with comparison arguments: $expression', + ({ expression }) => { + expect(() => parse(expression)).toThrow(); + } + ); + + it.each` + expression + ${`1 ${symbol} 1 ${symbol} 1`} + ${`(1 ${symbol} 1) ${symbol} 1`} + ${`1 ${symbol} (1 ${symbol} 1)`} + ${`a ${symbol} b ${symbol} c`} + ${`(a ${symbol} b) ${symbol} c`} + ${`a ${symbol} (b ${symbol} c)`} + `('should throw for cascading comparison operators: $expression', ({ expression }) => { + expect(() => parse(expression)).toThrow(); + }); + + it.each` + expression + ${`1 ${symbol} 1`} + ${`(1 ${symbol} 1)`} + ${`((1 ${symbol} 1))`} + ${`((1 + 1) ${symbol} 1)`} + ${`1 + 1 ${symbol} 1 * 1`} + ${`a ${symbol} b`} + ${`(a ${symbol} b)`} + ${`((a ${symbol} b))`} + ${`((a + b) ${symbol} c)`} + ${`a + b ${symbol} c * d`} + `('should parse comparison expressions: $expression', ({ expression }) => { + expect(() => parse(expression)).not.toThrow(); + }); + }); + }); }); describe('Variables', () => { diff --git a/src/core/server/integration_tests/saved_objects/migrations/check_registered_types.test.ts b/src/core/server/integration_tests/saved_objects/migrations/check_registered_types.test.ts index e7d02da09889d4..f6591cf7a77590 100644 --- a/src/core/server/integration_tests/saved_objects/migrations/check_registered_types.test.ts +++ b/src/core/server/integration_tests/saved_objects/migrations/check_registered_types.test.ts @@ -62,11 +62,11 @@ describe('checking migration metadata changes on all registered SO types', () => "app_search_telemetry": "7fc4fc08852bf0924ee29942bb394fda9aa8954d", "application_usage_daily": "6e645e0b60ef3af2e8fde80963c2a4f09a190d61", "application_usage_totals": "b2af3577dcd50bfae492b166a7804f69e2cc41dc", - "canvas-element": "5f32b99ba6ff9c1f17cc093591b975be65a27b9b", - "canvas-workpad": "b60252414fb6159a14f9febf98dbe41e5a8bf199", - "canvas-workpad-template": "c371cad0a8d61385f4782cab9a9063d3cf241ee0", + "canvas-element": "c27505dcf2970760bea8a0fe1d000253f0c40f08", + "canvas-workpad": "eb7b28a3b1c24af615edbf29becddf2e750a4bb5", + "canvas-workpad-template": "34454b811e32993eaa55c6ec85a7aecca00c4cfc", "cases": "7ff5ce930146a2d6fc8fbf536ce2ee16e9df296f", - "cases-comments": "8cfbad4ede637305eb6fb79db680f03dc0ce5ec4", + "cases-comments": "d7c4c1d24e97620cd415e27e5eb7d5b5f2c5b461", "cases-configure": "1afc414f5563a36e4612fa269193d3ed7277c7bd", "cases-connector-mappings": "4b16d440af966e5d6e0fa33368bfa15d987a4b69", "cases-telemetry": "16e261e7378a72acd0806f18df92525dd1da4f37", @@ -76,7 +76,7 @@ describe('checking migration metadata changes on all registered SO types', () => "core-usage-stats": "f40a213da2c597b0de94e364a4326a5a1baa4ca9", "csp-rule-template": "3679c5f2431da8153878db79c78a4e695357fb61", "csp_rule": "d2bb53ea5d2bdfba1a835ad8956dfcd2b2c32e19", - "dashboard": "0b0842b6aa40c125d64233fd81cee11080580dc2", + "dashboard": "742f2d9f110709fd8599b14f7766f38efc30de61", "endpoint:user-artifact": "f94c250a52b30d0a2d32635f8b4c5bdabd1e25c0", "endpoint:user-artifact-manifest": "8c14d49a385d5d1307d956aa743ec78de0b2be88", "enterprise_search_telemetry": "fafcc8318528d34f721c42d1270787c52565bad5", @@ -103,7 +103,7 @@ describe('checking migration metadata changes on all registered SO types', () => "inventory-view": "bc2bd1e7ec7c186159447ab228d269f22bd39056", "kql-telemetry": "29544cd7d3b767c5399878efae6bd724d24c03fd", "legacy-url-alias": "7172dfd54f2e0c89fe263fd7095519b2d826a930", - "lens": "08769c789ad6d1b8a4d0cffebc9d9bb08bf01ad9", + "lens": "236ecd358ed3a4ecfc03ed676d958b64acf0b697", "lens-ui-telemetry": "df2844565c9e18fed2bdb1f6cc3aadd58cf1e45b", "map": "00ca6c4cf46ae59f70f1436262eb9f457b45eb14", "maps-telemetry": "5adbde35bd50ec2b8e9ea5b96d4d9f886e31ecfb", diff --git a/src/plugins/data/common/search/aggs/agg_type.ts b/src/plugins/data/common/search/aggs/agg_type.ts index 8d01377ddf8083..4812ac6f07c5f1 100644 --- a/src/plugins/data/common/search/aggs/agg_type.ts +++ b/src/plugins/data/common/search/aggs/agg_type.ts @@ -29,7 +29,8 @@ type PostFlightRequestFn = ( searchSource: ISearchSource, inspectorRequestAdapter?: RequestAdapter, abortSignal?: AbortSignal, - searchSessionId?: string + searchSessionId?: string, + disableShardFailureWarning?: boolean ) => Promise>; export interface AggTypeConfig< diff --git a/src/plugins/data/common/search/aggs/buckets/_terms_other_bucket_helper.ts b/src/plugins/data/common/search/aggs/buckets/_terms_other_bucket_helper.ts index cc49c896bdfe5b..f695dc1b1d399f 100644 --- a/src/plugins/data/common/search/aggs/buckets/_terms_other_bucket_helper.ts +++ b/src/plugins/data/common/search/aggs/buckets/_terms_other_bucket_helper.ts @@ -333,7 +333,8 @@ export const createOtherBucketPostFlightRequest = ( searchSource, inspectorRequestAdapter, abortSignal, - searchSessionId + searchSessionId, + disableShardFailureWarning ) => { if (!resp.aggregations) return resp; const nestedSearchSource = searchSource.createChild(); @@ -347,6 +348,7 @@ export const createOtherBucketPostFlightRequest = ( nestedSearchSource.fetch$({ abortSignal, sessionId: searchSessionId, + disableShardFailureWarning, inspector: { adapter: inspectorRequestAdapter, title: i18n.translate('data.search.aggs.buckets.terms.otherBucketTitle', { diff --git a/src/plugins/data/common/search/search_source/search_source.ts b/src/plugins/data/common/search/search_source/search_source.ts index d6ec49360e95b7..497a2476686946 100644 --- a/src/plugins/data/common/search/search_source/search_source.ts +++ b/src/plugins/data/common/search/search_source/search_source.ts @@ -511,7 +511,8 @@ export class SearchSource { this, options.inspector?.adapter, options.abortSignal, - options.sessionId + options.sessionId, + options.disableShardFailureWarning ); } } diff --git a/src/plugins/vis_types/timeseries/server/lib/vis_data/response_processors/series/math.test.js b/src/plugins/vis_types/timeseries/server/lib/vis_data/response_processors/series/math.test.js index 3ff2ee0cba3536..6d2a435a20b68f 100644 --- a/src/plugins/vis_types/timeseries/server/lib/vis_data/response_processors/series/math.test.js +++ b/src/plugins/vis_types/timeseries/server/lib/vis_data/response_processors/series/math.test.js @@ -253,7 +253,7 @@ describe('math(resp, panel, series)', () => { )(await mathAgg(resp, panel, series)((results) => results))([]); } catch (e) { expect(e.message).toEqual( - 'Failed to parse expression. Expected "*", "+", "-", "/", end of input, or whitespace but "(" found.' + 'Failed to parse expression. Expected "*", "+", "-", "/", "<", "=", ">", end of input, or whitespace but "(" found.' ); } }); diff --git a/x-pack/examples/embedded_lens_example/public/app.tsx b/x-pack/examples/embedded_lens_example/public/app.tsx index 42784984a0d440..e4df914a54c3cd 100644 --- a/x-pack/examples/embedded_lens_example/public/app.tsx +++ b/x-pack/examples/embedded_lens_example/public/app.tsx @@ -100,7 +100,7 @@ function getLensAttributes( ], state: { datasourceStates: { - indexpattern: { + formBased: { layers: { layer1: dataLayer!, }, diff --git a/x-pack/examples/testing_embedded_lens/public/app.tsx b/x-pack/examples/testing_embedded_lens/public/app.tsx index cd550a92800041..2b8799c1951a3c 100644 --- a/x-pack/examples/testing_embedded_lens/public/app.tsx +++ b/x-pack/examples/testing_embedded_lens/public/app.tsx @@ -148,7 +148,7 @@ function getBaseAttributes( ], state: { datasourceStates: { - indexpattern: { + formBased: { layers: { layer1: finalDataLayer, }, diff --git a/x-pack/examples/third_party_lens_navigation_prompt/public/plugin.ts b/x-pack/examples/third_party_lens_navigation_prompt/public/plugin.ts index aca5f5d0b37b89..0538c7f5017420 100644 --- a/x-pack/examples/third_party_lens_navigation_prompt/public/plugin.ts +++ b/x-pack/examples/third_party_lens_navigation_prompt/public/plugin.ts @@ -71,7 +71,7 @@ function getLensAttributes(defaultDataView: DataView): TypedLensByValueInput['at ], state: { datasourceStates: { - indexpattern: { + formBased: { layers: { layer1: dataLayer, }, diff --git a/x-pack/examples/third_party_vis_lens_example/README.md b/x-pack/examples/third_party_vis_lens_example/README.md index f2fa563f33393d..ccb8fc69d41ae1 100644 --- a/x-pack/examples/third_party_vis_lens_example/README.md +++ b/x-pack/examples/third_party_vis_lens_example/README.md @@ -16,7 +16,7 @@ To test the migration, you can import the following ndjson file via saved object ``` {"attributes":{"fieldFormatMap":"{\"hour_of_day\":{}}","runtimeFieldMap":"{\"hour_of_day\":{\"type\":\"long\",\"script\":{\"source\":\"emit(doc['timestamp'].value.getHour());\"}}}","timeFieldName":"timestamp","title":"kibana_sample_data_logs"},"coreMigrationVersion":"8.0.0","id":"90943e30-9a47-11e8-b64d-95841ca0b247","migrationVersion":{"index-pattern":"8.0.0"},"references":[],"type":"index-pattern","updated_at":"2022-01-24T10:54:24.209Z","version":"WzQzMTQ3LDFd"} -{"attributes":{"description":"","state":{"datasourceStates":{"indexpattern":{"layers":{"f2700077-50bf-48e4-829c-f695f87e226d":{"columnOrder":["5e704cac-8490-457a-b635-01f3a5a132b7"],"columns":{"5e704cac-8490-457a-b635-01f3a5a132b7":{"dataType":"number","isBucketed":false,"label":"Count of records","operationType":"count","scale":"ratio","sourceField":"Records"}},"incompleteColumns":{}}}}},"filters":[],"query":{"language":"kuery","query":""},"visualization":{"column":"5e704cac-8490-457a-b635-01f3a5a132b7","layerId":"f2700077-50bf-48e4-829c-f695f87e226d"}},"title":"Rotating number test","visualizationType":"rotatingNumber"},"coreMigrationVersion":"8.0.0","id":"468f0be0-7e86-11ec-9739-d570ffd3fbe4","migrationVersion":{"lens":"8.0.0"},"references":[{"id":"90943e30-9a47-11e8-b64d-95841ca0b247","name":"indexpattern-datasource-current-indexpattern","type":"index-pattern"},{"id":"90943e30-9a47-11e8-b64d-95841ca0b247","name":"indexpattern-datasource-layer-f2700077-50bf-48e4-829c-f695f87e226d","type":"index-pattern"}],"type":"lens","updated_at":"2022-01-26T08:59:31.618Z","version":"WzQzNjUzLDFd"} +{"attributes":{"description":"","state":{"datasourceStates":{"formBased":{"layers":{"f2700077-50bf-48e4-829c-f695f87e226d":{"columnOrder":["5e704cac-8490-457a-b635-01f3a5a132b7"],"columns":{"5e704cac-8490-457a-b635-01f3a5a132b7":{"dataType":"number","isBucketed":false,"label":"Count of records","operationType":"count","scale":"ratio","sourceField":"Records"}},"incompleteColumns":{}}}}},"filters":[],"query":{"language":"kuery","query":""},"visualization":{"column":"5e704cac-8490-457a-b635-01f3a5a132b7","layerId":"f2700077-50bf-48e4-829c-f695f87e226d"}},"title":"Rotating number test","visualizationType":"rotatingNumber"},"coreMigrationVersion":"8.0.0","id":"468f0be0-7e86-11ec-9739-d570ffd3fbe4","migrationVersion":{"lens":"8.0.0"},"references":[{"id":"90943e30-9a47-11e8-b64d-95841ca0b247","name":"indexpattern-datasource-current-indexpattern","type":"index-pattern"},{"id":"90943e30-9a47-11e8-b64d-95841ca0b247","name":"indexpattern-datasource-layer-f2700077-50bf-48e4-829c-f695f87e226d","type":"index-pattern"}],"type":"lens","updated_at":"2022-01-26T08:59:31.618Z","version":"WzQzNjUzLDFd"} {"excludedObjects":[],"excludedObjectsCount":0,"exportedCount":2,"missingRefCount":0,"missingReferences":[]} ``` diff --git a/x-pack/examples/third_party_vis_lens_example/public/plugin.ts b/x-pack/examples/third_party_vis_lens_example/public/plugin.ts index f7a0378619b3a4..38922ae676666d 100644 --- a/x-pack/examples/third_party_vis_lens_example/public/plugin.ts +++ b/x-pack/examples/third_party_vis_lens_example/public/plugin.ts @@ -67,7 +67,7 @@ function getLensAttributes(defaultDataView: DataView): TypedLensByValueInput['at ], state: { datasourceStates: { - indexpattern: { + formBased: { layers: { layer1: dataLayer, }, diff --git a/x-pack/plugins/data_visualizer/public/application/common/components/field_data_row/action_menu/lens_utils.ts b/x-pack/plugins/data_visualizer/public/application/common/components/field_data_row/action_menu/lens_utils.ts index 034f7037fc29af..b053715090c7be 100644 --- a/x-pack/plugins/data_visualizer/public/application/common/components/field_data_row/action_menu/lens_utils.ts +++ b/x-pack/plugins/data_visualizer/public/application/common/components/field_data_row/action_menu/lens_utils.ts @@ -282,7 +282,7 @@ export function getLensAttributes( ], state: { datasourceStates: { - indexpattern: { + formBased: { layers: { layer1: { columnOrder: ['col1', 'col2'], diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/sync_jobs.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/sync_jobs.tsx index 708f8a6a772531..b6ae8bdd40fff2 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/sync_jobs.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/sync_jobs.tsx @@ -85,9 +85,9 @@ export const SyncJobs: React.FC = () => { { + onChange={({ page: { index, size } }: { page: { index: number; size: number } }) => { if (connectorId) { - fetchSyncJobs({ connectorId, page: index, size: syncJobsPagination.pageSize }); + fetchSyncJobs({ connectorId, page: index, size }); } }} pagination={{ diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/components/package_policy_input_stream.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/components/package_policy_input_stream.tsx index 5d6d6f5153360d..9b94537a73c276 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/components/package_policy_input_stream.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/components/package_policy_input_stream.tsx @@ -47,7 +47,7 @@ const ScrollAnchor = styled.div` scroll-margin-top: ${(props) => parseFloat(props.theme.eui.euiHeaderHeightCompensation) * 2}px; `; -export const PackagePolicyInputStreamConfig: React.FunctionComponent<{ +interface Props { packagePolicy: NewPackagePolicy; packageInputStream: RegistryStream & { data_stream: { dataset: string; type: string } }; packageInfo: PackageInfo; @@ -56,7 +56,9 @@ export const PackagePolicyInputStreamConfig: React.FunctionComponent<{ updatePackagePolicyInputStream: (updatedStream: Partial) => void; inputStreamValidationResults: PackagePolicyConfigValidationResults; forceShowErrors?: boolean; -}> = memo( +} + +export const PackagePolicyInputStreamConfig = memo( ({ packagePolicy, packageInputStream, @@ -193,161 +195,174 @@ export const PackagePolicyInputStreamConfig: React.FunctionComponent<{ ); })} - {/* Advanced section */} - {(isPackagePolicyEdit || !!advancedVars.length) && ( - - - + {/* Advanced section - always shown since we display experimental indexing settings here */} + + + + + setIsShowingAdvanced(!isShowingAdvanced)} + flush="left" + > + + + + {!isShowingAdvanced && hasErrors && advancedVarsWithErrorsCount ? ( - setIsShowingAdvanced(!isShowingAdvanced)} - flush="left" - > + - + - {!isShowingAdvanced && hasErrors && advancedVarsWithErrorsCount ? ( + ) : null} + + + {isShowingAdvanced ? ( + <> + {advancedVars.map((varDef) => { + if (!packagePolicyInputStream.vars) return null; + const { name: varName, type: varType } = varDef; + const value = packagePolicyInputStream.vars?.[varName]?.value; + + return ( + + { + updatePackagePolicyInputStream({ + vars: { + ...packagePolicyInputStream.vars, + [varName]: { + type: varType, + value: newValue, + }, + }, + }); + }} + errors={inputStreamValidationResults?.vars![varName]} + forceShowErrors={forceShowErrors} + /> + + ); + })} + {/* Only show datastream pipelines and mappings on edit */} + {isPackagePolicyEdit && ( + <> + + + + + + + + )} + {/* Experimental index/datastream settings e.g. synthetic source */} + + - + +
+ +
+
+
+ + + + + ), + }} /> - ) : null} -
-
- {isShowingAdvanced ? ( - <> - {advancedVars.map((varDef) => { - if (!packagePolicyInputStream.vars) return null; - const { name: varName, type: varType } = varDef; - const value = packagePolicyInputStream.vars?.[varName]?.value; - - return ( - - { - updatePackagePolicyInputStream({ - vars: { - ...packagePolicyInputStream.vars, - [varName]: { - type: varType, - value: newValue, - }, - }, - }); - }} - errors={inputStreamValidationResults?.vars![varName]} - forceShowErrors={forceShowErrors} - /> - - ); - })} - {/* Only show datastream pipelines and mappings on edit */} - {isPackagePolicyEdit && ( - <> - - - - - - - - )} - {/* Experimental index/datastream settings e.g. synthetic source */} - - - - -
- -
-
-
- - + + + + dataStream === + getRegistryDataStreamAssetBaseName( + packagePolicyInputStream.data_stream + ) && features.synthetic_source + ) ?? false + } + label={ - - - ), - }} + id="xpack.fleet.createPackagePolicy.experimentalFeatures.syntheticSourceLabel" + defaultMessage="Synthetic source" /> - - - - - - dataStream === - getRegistryDataStreamAssetBaseName( - packagePolicyInputStream.data_stream - ) && features.synthetic_source - ) ?? false - } - label={ - + } + onChange={(e) => { + if (!packagePolicy.package) { + return; } - onChange={(e) => { - if (!packagePolicy.package) { - return; - } - updatePackagePolicy({ - package: { - ...packagePolicy.package, - experimental_data_stream_features: [ - { - data_stream: getRegistryDataStreamAssetBaseName( - packagePolicyInputStream.data_stream - ), - features: { - synthetic_source: e.target.checked, - }, - }, - ], + const newExperimentalDataStreamFeatures = [ + ...(packagePolicy.package.experimental_data_stream_features ?? []), + ]; + + const dataStream = getRegistryDataStreamAssetBaseName( + packagePolicyInputStream.data_stream + ); + + const existingSettingRecord = newExperimentalDataStreamFeatures.find( + (x) => x.data_stream === dataStream + ); + + if (existingSettingRecord) { + existingSettingRecord.features.synthetic_source = e.target.checked; + } else { + newExperimentalDataStreamFeatures.push({ + data_stream: dataStream, + features: { + synthetic_source: e.target.checked, }, }); - }} - /> - -
-
- - ) : null} -
- )} + } + + updatePackagePolicy({ + package: { + ...packagePolicy.package, + experimental_data_stream_features: + newExperimentalDataStreamFeatures, + }, + }); + }} + /> +
+ + + + ) : null} +
diff --git a/x-pack/plugins/infra/public/pages/metrics/hosts/components/hosts_table.tsx b/x-pack/plugins/infra/public/pages/metrics/hosts/components/hosts_table.tsx index e92ac801e8612b..143f7fedb14204 100644 --- a/x-pack/plugins/infra/public/pages/metrics/hosts/components/hosts_table.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/hosts/components/hosts_table.tsx @@ -35,7 +35,7 @@ const getLensHostsTable = ( ], state: { datasourceStates: { - indexpattern: { + formBased: { layers: { 'cbe5d8a0-381d-49bf-b8ac-f8f312ec7129': { columns: { diff --git a/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.test.ts b/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.test.ts index 78934d09755bee..4e2e6b780dafb4 100644 --- a/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.test.ts +++ b/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.test.ts @@ -14,6 +14,8 @@ import { getGroupedESQuery, processUngroupedResults, processGroupByResults, + LogThresholdAlertFactory, + LogThresholdAlertLimit, } from './log_threshold_executor'; import { Comparator, @@ -406,9 +408,14 @@ describe('Log threshold executor', () => { }); describe('Results processors', () => { - describe('Can process ungrouped results', () => { - test('It handles the ALERT state correctly', () => { - const alertFactoryMock = jest.fn(); + describe('for ungrouped results', () => { + it('handles the ALERT state correctly', () => { + const alertFactoryMock: jest.MockedFunction = jest.fn(); + const alertLimitMock: jest.Mocked = { + getValue: jest.fn().mockReturnValue(10), + setLimitReached: jest.fn(), + }; + const ruleParams = { ...baseRuleParams, criteria: [positiveCriteria[0]], @@ -421,7 +428,7 @@ describe('Log threshold executor', () => { }, } as UngroupedSearchQueryResponse; - processUngroupedResults(results, ruleParams, alertFactoryMock); + processUngroupedResults(results, ruleParams, alertFactoryMock, alertLimitMock); // first call, fifth argument expect(alertFactoryMock.mock.calls[0][4]).toEqual([ @@ -437,11 +444,91 @@ describe('Log threshold executor', () => { }, ]); }); + + it('reports reaching a low limit when alerting', () => { + const alertFactoryMock: jest.MockedFunction = jest.fn(); + const alertLimitMock: jest.Mocked = { + getValue: jest.fn().mockReturnValue(1), + setLimitReached: jest.fn(), + }; + + const ruleParams = { + ...baseRuleParams, + criteria: [positiveCriteria[0]], + }; + const results = { + hits: { + total: { + value: 10, + }, + }, + } as UngroupedSearchQueryResponse; + + processUngroupedResults(results, ruleParams, alertFactoryMock, alertLimitMock); + + expect(alertFactoryMock).toBeCalledTimes(1); + expect(alertLimitMock.setLimitReached).toHaveBeenCalledWith(true); + }); + + it('reports not reaching a higher limit when alerting', () => { + const alertFactoryMock: jest.MockedFunction = jest.fn(); + const alertLimitMock: jest.Mocked = { + getValue: jest.fn().mockReturnValue(10), + setLimitReached: jest.fn(), + }; + + const ruleParams = { + ...baseRuleParams, + criteria: [positiveCriteria[0]], + }; + const results = { + hits: { + total: { + value: 10, + }, + }, + } as UngroupedSearchQueryResponse; + + processUngroupedResults(results, ruleParams, alertFactoryMock, alertLimitMock); + + expect(alertFactoryMock).toBeCalledTimes(1); + expect(alertLimitMock.setLimitReached).toHaveBeenCalledWith(false); + }); + + it('reports not reaching the limit without any alerts', () => { + const alertFactoryMock: jest.MockedFunction = jest.fn(); + const alertLimitMock: jest.Mocked = { + getValue: jest.fn().mockReturnValue(0), + setLimitReached: jest.fn(), + }; + + const ruleParams = { + ...baseRuleParams, + criteria: [positiveCriteria[0]], + }; + const results = { + hits: { + total: { + value: 0, + }, + }, + } as UngroupedSearchQueryResponse; + + processUngroupedResults(results, ruleParams, alertFactoryMock, alertLimitMock); + + expect(alertFactoryMock).not.toHaveBeenCalled(); + expect(alertLimitMock.setLimitReached).toHaveBeenCalledWith(false); + }); }); - describe('Can process grouped results', () => { - test('It handles the ALERT state correctly', () => { - const alertFactoryMock = jest.fn(); + describe('for grouped results', () => { + it('handles the ALERT state correctly', () => { + const alertFactoryMock: jest.MockedFunction = jest.fn(); + const alertLimitMock: jest.Mocked = { + getValue: jest.fn().mockReturnValue(2), + setLimitReached: jest.fn(), + }; + const ruleParams = { ...baseRuleParams, criteria: [positiveCriteria[0]], @@ -481,7 +568,7 @@ describe('Log threshold executor', () => { }, ] as GroupedSearchQueryResponse['aggregations']['groups']['buckets']; - processGroupByResults(results, ruleParams, alertFactoryMock); + processGroupByResults(results, ruleParams, alertFactoryMock, alertLimitMock); expect(alertFactoryMock.mock.calls.length).toBe(2); // First call, fifth argument @@ -514,6 +601,110 @@ describe('Log threshold executor', () => { }, ]); }); + + it('respects and reports reaching a low limit when alerting', () => { + const alertFactoryMock: jest.MockedFunction = jest.fn(); + const alertLimitMock: jest.Mocked = { + getValue: jest.fn().mockReturnValue(1), + setLimitReached: jest.fn(), + }; + + const ruleParams = { + ...baseRuleParams, + criteria: [positiveCriteria[0]], + groupBy: ['host.name', 'event.dataset'], + }; + // Two groups should fire, one shouldn't + const results = [ + { + key: { + 'host.name': 'i-am-a-host-name-1', + 'event.dataset': 'i-am-a-dataset-1', + }, + doc_count: 100, + filtered_results: { + doc_count: 10, + }, + }, + { + key: { + 'host.name': 'i-am-a-host-name-2', + 'event.dataset': 'i-am-a-dataset-2', + }, + doc_count: 100, + filtered_results: { + doc_count: 2, + }, + }, + { + key: { + 'host.name': 'i-am-a-host-name-3', + 'event.dataset': 'i-am-a-dataset-3', + }, + doc_count: 100, + filtered_results: { + doc_count: 20, + }, + }, + ] as GroupedSearchQueryResponse['aggregations']['groups']['buckets']; + + processGroupByResults(results, ruleParams, alertFactoryMock, alertLimitMock); + + expect(alertFactoryMock).toHaveBeenCalledTimes(1); + expect(alertLimitMock.setLimitReached).toHaveBeenCalledWith(true); + }); + + it('reports not reaching a higher limit when alerting', () => { + const alertFactoryMock: jest.MockedFunction = jest.fn(); + const alertLimitMock: jest.Mocked = { + getValue: jest.fn().mockReturnValue(10), + setLimitReached: jest.fn(), + }; + + const ruleParams = { + ...baseRuleParams, + criteria: [positiveCriteria[0]], + groupBy: ['host.name', 'event.dataset'], + }; + // Two groups should fire, one shouldn't + const results = [ + { + key: { + 'host.name': 'i-am-a-host-name-1', + 'event.dataset': 'i-am-a-dataset-1', + }, + doc_count: 100, + filtered_results: { + doc_count: 10, + }, + }, + { + key: { + 'host.name': 'i-am-a-host-name-2', + 'event.dataset': 'i-am-a-dataset-2', + }, + doc_count: 100, + filtered_results: { + doc_count: 2, + }, + }, + { + key: { + 'host.name': 'i-am-a-host-name-3', + 'event.dataset': 'i-am-a-dataset-3', + }, + doc_count: 100, + filtered_results: { + doc_count: 20, + }, + }, + ] as GroupedSearchQueryResponse['aggregations']['groups']['buckets']; + + processGroupByResults(results, ruleParams, alertFactoryMock, alertLimitMock); + + expect(alertFactoryMock).toHaveBeenCalledTimes(2); + expect(alertLimitMock.setLimitReached).toHaveBeenCalledWith(false); + }); }); }); }); diff --git a/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.ts b/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.ts index dab15eb5ca9235..a475e6beea011c 100644 --- a/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.ts +++ b/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.ts @@ -19,6 +19,7 @@ import { Alert, AlertInstanceContext as AlertContext, AlertInstanceState as AlertState, + RuleExecutorServices, RuleTypeState, } from '@kbn/alerting-plugin/server'; @@ -60,18 +61,23 @@ export type LogThresholdRuleTypeState = RuleTypeState; // no specific state used export type LogThresholdAlertState = AlertState; // no specific state used export type LogThresholdAlertContext = AlertContext; // no specific instance context used -type LogThresholdAlert = Alert< +export type LogThresholdAlert = Alert< LogThresholdAlertState, LogThresholdAlertContext, LogThresholdActionGroups >; -type LogThresholdAlertFactory = ( +export type LogThresholdAlertFactory = ( id: string, reason: string, value: number, threshold: number, actions?: Array<{ actionGroup: LogThresholdActionGroups; context: AlertContext }> ) => LogThresholdAlert; +export type LogThresholdAlertLimit = RuleExecutorServices< + LogThresholdAlertState, + LogThresholdAlertContext, + LogThresholdActionGroups +>['alertFactory']['alertLimit']; const COMPOSITE_GROUP_SIZE = 2000; @@ -96,8 +102,13 @@ export const createLogThresholdExecutor = (libs: InfraBackendLibs) => LogThresholdAlertContext, LogThresholdActionGroups >(async ({ services, params, startedAt }) => { - const { alertWithLifecycle, savedObjectsClient, scopedClusterClient, getAlertStartedDate } = - services; + const { + alertFactory: { alertLimit }, + alertWithLifecycle, + savedObjectsClient, + scopedClusterClient, + getAlertStartedDate, + } = services; const { basePath } = libs; const alertFactory: LogThresholdAlertFactory = (id, reason, value, threshold, actions) => { @@ -150,6 +161,7 @@ export const createLogThresholdExecutor = (libs: InfraBackendLibs) => runtimeMappings, scopedClusterClient.asCurrentUser, alertFactory, + alertLimit, startedAt.valueOf() ); } else { @@ -160,6 +172,7 @@ export const createLogThresholdExecutor = (libs: InfraBackendLibs) => runtimeMappings, scopedClusterClient.asCurrentUser, alertFactory, + alertLimit, startedAt.valueOf() ); } @@ -185,6 +198,7 @@ export async function executeAlert( runtimeMappings: estypes.MappingRuntimeFields, esClient: ElasticsearchClient, alertFactory: LogThresholdAlertFactory, + alertLimit: LogThresholdAlertLimit, executionTimestamp: number ) { const query = getESQuery( @@ -200,9 +214,19 @@ export async function executeAlert( } if (hasGroupBy(ruleParams)) { - processGroupByResults(await getGroupedResults(query, esClient), ruleParams, alertFactory); + processGroupByResults( + await getGroupedResults(query, esClient), + ruleParams, + alertFactory, + alertLimit + ); } else { - processUngroupedResults(await getUngroupedResults(query, esClient), ruleParams, alertFactory); + processUngroupedResults( + await getUngroupedResults(query, esClient), + ruleParams, + alertFactory, + alertLimit + ); } } @@ -213,6 +237,7 @@ export async function executeRatioAlert( runtimeMappings: estypes.MappingRuntimeFields, esClient: ElasticsearchClient, alertFactory: LogThresholdAlertFactory, + alertLimit: LogThresholdAlertLimit, executionTimestamp: number ) { // Ratio alert params are separated out into two standard sets of alert params @@ -254,7 +279,8 @@ export async function executeRatioAlert( numeratorGroupedResults, denominatorGroupedResults, ruleParams, - alertFactory + alertFactory, + alertLimit ); } else { const [numeratorUngroupedResults, denominatorUngroupedResults] = await Promise.all([ @@ -265,7 +291,8 @@ export async function executeRatioAlert( numeratorUngroupedResults, denominatorUngroupedResults, ruleParams, - alertFactory + alertFactory, + alertLimit ); } } @@ -297,7 +324,8 @@ const getESQuery = ( export const processUngroupedResults = ( results: UngroupedSearchQueryResponse, params: CountRuleParams, - alertFactory: LogThresholdAlertFactory + alertFactory: LogThresholdAlertFactory, + alertLimit: LogThresholdAlertLimit ) => { const { count, criteria, timeSize, timeUnit } = params; const documentCount = results.hits.total.value; @@ -323,6 +351,9 @@ export const processUngroupedResults = ( }, ]; alertFactory(UNGROUPED_FACTORY_KEY, reasonMessage, documentCount, count.value, actions); + alertLimit.setLimitReached(alertLimit.getValue() <= 1); + } else { + alertLimit.setLimitReached(false); } }; @@ -330,7 +361,8 @@ export const processUngroupedRatioResults = ( numeratorResults: UngroupedSearchQueryResponse, denominatorResults: UngroupedSearchQueryResponse, params: RatioRuleParams, - alertFactory: LogThresholdAlertFactory + alertFactory: LogThresholdAlertFactory, + alertLimit: LogThresholdAlertLimit ) => { const { count, criteria, timeSize, timeUnit } = params; @@ -360,6 +392,9 @@ export const processUngroupedRatioResults = ( }, ]; alertFactory(UNGROUPED_FACTORY_KEY, reasonMessage, ratio, count.value, actions); + alertLimit.setLimitReached(alertLimit.getValue() <= 1); + } else { + alertLimit.setLimitReached(false); } }; @@ -405,16 +440,24 @@ const getReducedGroupByResults = ( export const processGroupByResults = ( results: GroupedSearchQueryResponse['aggregations']['groups']['buckets'], params: CountRuleParams, - alertFactory: LogThresholdAlertFactory + alertFactory: LogThresholdAlertFactory, + alertLimit: LogThresholdAlertLimit ) => { const { count, criteria, timeSize, timeUnit } = params; const groupResults = getReducedGroupByResults(results); - groupResults.forEach((group) => { + let remainingAlertCount = alertLimit.getValue(); + + for (const group of groupResults) { + if (remainingAlertCount <= 0) { + break; + } + const documentCount = group.documentCount; if (checkValueAgainstComparatorMap[count.comparator](documentCount, count.value)) { + remainingAlertCount -= 1; const reasonMessage = getReasonMessageForGroupedCountAlert( documentCount, count.value, @@ -437,21 +480,30 @@ export const processGroupByResults = ( ]; alertFactory(group.name, reasonMessage, documentCount, count.value, actions); } - }); + } + + alertLimit.setLimitReached(remainingAlertCount <= 0); }; export const processGroupByRatioResults = ( numeratorResults: GroupedSearchQueryResponse['aggregations']['groups']['buckets'], denominatorResults: GroupedSearchQueryResponse['aggregations']['groups']['buckets'], params: RatioRuleParams, - alertFactory: LogThresholdAlertFactory + alertFactory: LogThresholdAlertFactory, + alertLimit: LogThresholdAlertLimit ) => { const { count, criteria, timeSize, timeUnit } = params; const numeratorGroupResults = getReducedGroupByResults(numeratorResults); const denominatorGroupResults = getReducedGroupByResults(denominatorResults); - numeratorGroupResults.forEach((numeratorGroup) => { + let remainingAlertCount = alertLimit.getValue(); + + for (const numeratorGroup of numeratorGroupResults) { + if (remainingAlertCount <= 0) { + break; + } + const numeratorDocumentCount = numeratorGroup.documentCount; const denominatorGroup = denominatorGroupResults.find( (_group) => _group.name === numeratorGroup.name @@ -464,6 +516,7 @@ export const processGroupByRatioResults = ( ratio !== undefined && checkValueAgainstComparatorMap[count.comparator](ratio, count.value) ) { + remainingAlertCount -= 1; const reasonMessage = getReasonMessageForGroupedRatioAlert( ratio, count.value, @@ -487,7 +540,9 @@ export const processGroupByRatioResults = ( ]; alertFactory(numeratorGroup.name, reasonMessage, ratio, count.value, actions); } - }); + } + + alertLimit.setLimitReached(remainingAlertCount <= 0); }; export const buildFiltersFromCriteria = ( diff --git a/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx b/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx index 4176e5f1e51a79..f2b4d2b3151480 100644 --- a/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx +++ b/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx @@ -644,7 +644,7 @@ export const LensTopNavMenu = ({ setIsOnTextBasedMode(true); dispatch( switchAndCleanDatasource({ - newDatasourceId: 'textBasedLanguages', + newDatasourceId: 'textBased', visualizationId: visualization?.activeId, currentIndexPatternId: currentIndexPattern?.id, }) @@ -764,7 +764,7 @@ export const LensTopNavMenu = ({ if (isOnTextBasedMode) { dispatch( switchAndCleanDatasource({ - newDatasourceId: 'indexpattern', + newDatasourceId: 'formBased', visualizationId: visualization?.activeId, currentIndexPatternId: dataView?.id, }) @@ -795,7 +795,7 @@ export const LensTopNavMenu = ({ if (isOnTextBasedMode) { dispatch( switchAndCleanDatasource({ - newDatasourceId: 'indexpattern', + newDatasourceId: 'formBased', visualizationId: visualization?.activeId, currentIndexPatternId: dataView?.id, }) @@ -838,7 +838,7 @@ export const LensTopNavMenu = ({ if (isOnTextBasedMode) { dispatch( switchAndCleanDatasource({ - newDatasourceId: 'indexpattern', + newDatasourceId: 'formBased', visualizationId: visualization?.activeId, currentIndexPatternId: newIndexPatternId, }) diff --git a/x-pack/plugins/lens/public/app_plugin/show_underlying_data.test.ts b/x-pack/plugins/lens/public/app_plugin/show_underlying_data.test.ts index bd6b7a000ecd6c..b185697021105e 100644 --- a/x-pack/plugins/lens/public/app_plugin/show_underlying_data.test.ts +++ b/x-pack/plugins/lens/public/app_plugin/show_underlying_data.test.ts @@ -93,7 +93,7 @@ describe('getLayerMetaInfo', () => { it('should return error in case of getFilters returning errors', () => { const mockDatasource = createMockDatasource('testDatasource'); const updatedPublicAPI: DatasourcePublicAPI = { - datasourceId: 'indexpattern', + datasourceId: 'formBased', getOperationForColumnId: jest.fn(), getTableSpec: jest.fn(() => [{ columnId: 'col1', fields: ['bytes'] }]), getVisualDefaults: jest.fn(), @@ -166,7 +166,7 @@ describe('getLayerMetaInfo', () => { it('should basically work collecting fields and filters in the visualization', () => { const mockDatasource = createMockDatasource('testDatasource'); const updatedPublicAPI: DatasourcePublicAPI = { - datasourceId: 'indexpattern', + datasourceId: 'formBased', getOperationForColumnId: jest.fn(), getTableSpec: jest.fn(() => [{ columnId: 'col1', fields: ['bytes'] }]), getVisualDefaults: jest.fn(), diff --git a/x-pack/plugins/lens/public/async_services.ts b/x-pack/plugins/lens/public/async_services.ts index c0ccd2a71ce2bc..1aa40cda214451 100644 --- a/x-pack/plugins/lens/public/async_services.ts +++ b/x-pack/plugins/lens/public/async_services.ts @@ -29,12 +29,12 @@ export * from './visualizations/heatmap'; export * from './visualizations/gauge/gauge_visualization'; export * from './visualizations/gauge'; -export * from './indexpattern_datasource/indexpattern'; -export { getTextBasedLanguagesDatasource } from './text_based_languages_datasource/text_based_languages'; -export { createFormulaPublicApi } from './indexpattern_datasource/operations/definitions/formula/formula_public_api'; +export * from './datasources/form_based/form_based'; +export { getTextBasedDatasource } from './datasources/text_based/text_based_languages'; +export { createFormulaPublicApi } from './datasources/form_based/operations/definitions/formula/formula_public_api'; -export * from './text_based_languages_datasource'; -export * from './indexpattern_datasource'; +export * from './datasources/text_based'; +export * from './datasources/form_based'; export * from './lens_ui_telemetry'; export * from './lens_ui_errors'; export * from './editor_frame_service/editor_frame'; diff --git a/x-pack/plugins/lens/public/data_views_service/loader.test.ts b/x-pack/plugins/lens/public/data_views_service/loader.test.ts index 340bc675bf3e75..97ded75233cdae 100644 --- a/x-pack/plugins/lens/public/data_views_service/loader.test.ts +++ b/x-pack/plugins/lens/public/data_views_service/loader.test.ts @@ -14,7 +14,7 @@ import { syncExistingFields, } from './loader'; import { sampleIndexPatterns, mockDataViewsService } from './mocks'; -import { documentField } from '../indexpattern_datasource/document_field'; +import { documentField } from '../datasources/form_based/document_field'; import { coreMock } from '@kbn/core/public/mocks'; import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; import type { DataView } from '@kbn/data-views-plugin/public'; diff --git a/x-pack/plugins/lens/public/data_views_service/loader.ts b/x-pack/plugins/lens/public/data_views_service/loader.ts index 3bb1bdf0612a75..f0184d0a11d0b2 100644 --- a/x-pack/plugins/lens/public/data_views_service/loader.ts +++ b/x-pack/plugins/lens/public/data_views_service/loader.ts @@ -12,7 +12,7 @@ import { CoreStart } from '@kbn/core/public'; import { DataPublicPluginStart } from '@kbn/data-plugin/public'; import { loadFieldExisting } from '@kbn/unified-field-list-plugin/public'; import { IndexPattern, IndexPatternField, IndexPatternMap, IndexPatternRef } from '../types'; -import { documentField } from '../indexpattern_datasource/document_field'; +import { documentField } from '../datasources/form_based/document_field'; import { DateRange } from '../../common'; import { DataViewsState } from '../state_management'; diff --git a/x-pack/plugins/lens/public/data_views_service/mocks.ts b/x-pack/plugins/lens/public/data_views_service/mocks.ts index 9b7f5cbc2a91aa..ed8d6e86e58a4e 100644 --- a/x-pack/plugins/lens/public/data_views_service/mocks.ts +++ b/x-pack/plugins/lens/public/data_views_service/mocks.ts @@ -6,11 +6,11 @@ */ import { DataViewsContract } from '@kbn/data-views-plugin/common'; -import { documentField } from '../indexpattern_datasource/document_field'; +import { documentField } from '../datasources/form_based/document_field'; import { createMockedIndexPattern, createMockedRestrictedIndexPattern, -} from '../indexpattern_datasource/mocks'; +} from '../datasources/form_based/mocks'; import { DataViewsState } from '../state_management'; import { ExistingFieldsMap, IndexPattern } from '../types'; import { getFieldByNameFactory } from './loader'; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/__mocks__/loader.ts b/x-pack/plugins/lens/public/datasources/form_based/__mocks__/loader.ts similarity index 91% rename from x-pack/plugins/lens/public/indexpattern_datasource/__mocks__/loader.ts rename to x-pack/plugins/lens/public/datasources/form_based/__mocks__/loader.ts index 1273d596576c40..47af8d816b73f6 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/__mocks__/loader.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/__mocks__/loader.ts @@ -6,11 +6,11 @@ */ import { createMockedIndexPattern, createMockedRestrictedIndexPattern } from '../mocks'; -import { IndexPatternPrivateState } from '../types'; +import { FormBasedPrivateState } from '../types'; export function loadInitialState() { const indexPattern = createMockedIndexPattern(); - const result: IndexPatternPrivateState = { + const result: FormBasedPrivateState = { currentIndexPatternId: indexPattern.id, layers: {}, }; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/__snapshots__/utils.test.tsx.snap b/x-pack/plugins/lens/public/datasources/form_based/__snapshots__/utils.test.tsx.snap similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/__snapshots__/utils.test.tsx.snap rename to x-pack/plugins/lens/public/datasources/form_based/__snapshots__/utils.test.tsx.snap diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.scss b/x-pack/plugins/lens/public/datasources/form_based/datapanel.scss similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/datapanel.scss rename to x-pack/plugins/lens/public/datasources/form_based/datapanel.scss diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/datapanel.test.tsx similarity index 93% rename from x-pack/plugins/lens/public/indexpattern_datasource/datapanel.test.tsx rename to x-pack/plugins/lens/public/datasources/form_based/datapanel.test.tsx index 7ee461aa633696..deb9642e25dc3f 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/datapanel.test.tsx @@ -13,13 +13,13 @@ import { dataViewPluginMocks, Start as DataViewPublicStart, } from '@kbn/data-views-plugin/public/mocks'; -import { InnerIndexPatternDataPanel, IndexPatternDataPanel, Props } from './datapanel'; +import { InnerFormBasedDataPanel, FormBasedDataPanel, Props } from './datapanel'; import { FieldList } from './field_list'; import { FieldItem } from './field_item'; import { NoFieldsCallout } from './no_fields_callout'; import { act } from 'react-dom/test-utils'; import { coreMock } from '@kbn/core/public/mocks'; -import { IndexPatternPrivateState } from './types'; +import { FormBasedPrivateState } from './types'; import { mountWithIntl, shallowWithIntl } from '@kbn/test-jest-helpers'; import { EuiProgress, EuiLoadingSpinner } from '@elastic/eui'; import { documentField } from './document_field'; @@ -29,12 +29,12 @@ import { indexPatternFieldEditorPluginMock } from '@kbn/data-view-field-editor-p import { getFieldByNameFactory } from './pure_helpers'; import { uiActionsPluginMock } from '@kbn/ui-actions-plugin/public/mocks'; import { TermsIndexPatternColumn } from './operations'; -import { DOCUMENT_FIELD_NAME } from '../../common'; -import { createIndexPatternServiceMock } from '../mocks/data_views_service_mock'; -import { createMockFramePublicAPI } from '../mocks'; -import { DataViewsState } from '../state_management'; -import { ExistingFieldsMap, FramePublicAPI, IndexPattern } from '../types'; -import { IndexPatternServiceProps } from '../data_views_service/service'; +import { DOCUMENT_FIELD_NAME } from '../../../common'; +import { createIndexPatternServiceMock } from '../../mocks/data_views_service_mock'; +import { createMockFramePublicAPI } from '../../mocks'; +import { DataViewsState } from '../../state_management'; +import { ExistingFieldsMap, FramePublicAPI, IndexPattern } from '../../types'; +import { IndexPatternServiceProps } from '../../data_views_service/service'; import { FieldSpec, DataView } from '@kbn/data-views-plugin/public'; import { UI_SETTINGS } from '@kbn/data-plugin/public'; @@ -174,7 +174,7 @@ function getExistingFields(indexPatterns: Record) { return existingFields; } -const initialState: IndexPatternPrivateState = { +const initialState: FormBasedPrivateState = { currentIndexPatternId: '1', layers: { first: { @@ -285,7 +285,7 @@ const dslQuery = { bool: { must: [], filter: [], should: [], must_not: [] } }; // @ts-expect-error Portal mocks are notoriously difficult to type ReactDOM.createPortal = jest.fn((element) => element); -describe('IndexPattern Data Panel', () => { +describe('FormBased Data Panel', () => { const indexPatterns = { a: { id: 'a', @@ -304,7 +304,7 @@ describe('IndexPattern Data Panel', () => { hasRestrictions: false, }, }; - let defaultProps: Parameters[0] & { + let defaultProps: Parameters[0] & { showNoDataPopover: () => void; }; let core: ReturnType; @@ -340,7 +340,7 @@ describe('IndexPattern Data Panel', () => { it('should render a warning if there are no index patterns', () => { const wrapper = shallowWithIntl( - { columns: {}, }, }, - } as IndexPatternPrivateState, + } as FormBasedPrivateState, }; } async function testExistenceLoading( props: Props, - stateChanges?: Partial, + stateChanges?: Partial, propChanges?: Partial ) { - const inst = mountWithIntl(); + const inst = mountWithIntl(); await act(async () => { inst.update(); @@ -601,7 +601,7 @@ describe('IndexPattern Data Panel', () => { it('shows a loading indicator when loading', async () => { const updateIndexPatterns = jest.fn(); const load = async () => {}; - const inst = mountWithIntl(); + const inst = mountWithIntl(); expect(inst.find(EuiProgress).length).toEqual(1); await act(load); inst.update(); @@ -629,7 +629,7 @@ describe('IndexPattern Data Panel', () => { return result; }); - const inst = mountWithIntl(); + const inst = mountWithIntl(); inst.update(); @@ -676,7 +676,7 @@ describe('IndexPattern Data Panel', () => { }); describe('displaying field list', () => { - let props: Parameters[0]; + let props: Parameters[0]; beforeEach(() => { props = { ...defaultProps, @@ -691,7 +691,7 @@ describe('IndexPattern Data Panel', () => { }; }); it('should list all supported fields in the pattern sorted alphabetically in groups', async () => { - const wrapper = mountWithIntl(); + const wrapper = mountWithIntl(); expect(wrapper.find(FieldItem).first().prop('field').displayName).toEqual('Records'); expect( wrapper @@ -715,7 +715,7 @@ describe('IndexPattern Data Panel', () => { it('should show meta fields accordion', async () => { const wrapper = mountWithIntl( - { it('should display NoFieldsCallout when all fields are empty', async () => { const wrapper = mountWithIntl( - @@ -780,7 +780,7 @@ describe('IndexPattern Data Panel', () => { it('should display spinner for available fields accordion if existing fields are not loaded yet', async () => { const wrapper = mountWithIntl( - @@ -795,7 +795,7 @@ describe('IndexPattern Data Panel', () => { it('should not allow field details when error', () => { const wrapper = mountWithIntl( - @@ -810,7 +810,7 @@ describe('IndexPattern Data Panel', () => { it('should allow field details when timeout', () => { const wrapper = mountWithIntl( - @@ -824,7 +824,7 @@ describe('IndexPattern Data Panel', () => { }); it('should filter down by name', () => { - const wrapper = mountWithIntl(); + const wrapper = mountWithIntl(); act(() => { wrapper.find('[data-test-subj="lnsIndexPatternFieldSearch"]').simulate('change', { target: { value: 'me' }, @@ -843,7 +843,7 @@ describe('IndexPattern Data Panel', () => { }); it('should announce filter in live region', () => { - const wrapper = mountWithIntl(); + const wrapper = mountWithIntl(); act(() => { wrapper.find('[data-test-subj="lnsIndexPatternFieldSearch"]').simulate('change', { target: { value: 'me' }, @@ -862,7 +862,7 @@ describe('IndexPattern Data Panel', () => { }); it('should filter down by type', () => { - const wrapper = mountWithIntl(); + const wrapper = mountWithIntl(); wrapper.find('[data-test-subj="lnsIndexPatternFiltersToggle"]').first().simulate('click'); @@ -874,7 +874,7 @@ describe('IndexPattern Data Panel', () => { }); it('should display no fields in groups when filtered by type Record', () => { - const wrapper = mountWithIntl(); + const wrapper = mountWithIntl(); wrapper.find('[data-test-subj="lnsIndexPatternFiltersToggle"]').first().simulate('click'); @@ -887,7 +887,7 @@ describe('IndexPattern Data Panel', () => { }); it('should toggle type if clicked again', () => { - const wrapper = mountWithIntl(); + const wrapper = mountWithIntl(); wrapper.find('[data-test-subj="lnsIndexPatternFiltersToggle"]').first().simulate('click'); wrapper.find('[data-test-subj="typeFilter-number"]').first().simulate('click'); @@ -903,7 +903,7 @@ describe('IndexPattern Data Panel', () => { }); it('should filter down by type and by name', () => { - const wrapper = mountWithIntl(); + const wrapper = mountWithIntl(); act(() => { wrapper.find('[data-test-subj="lnsIndexPatternFieldSearch"]').simulate('change', { target: { value: 'me' }, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx b/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx similarity index 97% rename from x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx rename to x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx index 4107cd0c14fa5e..970db62925fe64 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/datapanel.tsx @@ -39,18 +39,18 @@ import type { FramePublicAPI, IndexPattern, IndexPatternField, -} from '../types'; -import { ChildDragDropProvider, DragContextState } from '../drag_drop'; -import type { IndexPatternPrivateState } from './types'; -import { Loader } from '../loader'; -import { LensFieldIcon } from '../shared_components/field_picker/lens_field_icon'; +} from '../../types'; +import { ChildDragDropProvider, DragContextState } from '../../drag_drop'; +import type { FormBasedPrivateState } from './types'; +import { Loader } from '../../loader'; +import { LensFieldIcon } from '../../shared_components/field_picker/lens_field_icon'; import { getFieldType } from './pure_utils'; import { FieldGroups, FieldList } from './field_list'; -import { fieldContainsData, fieldExists } from '../shared_components'; -import { IndexPatternServiceAPI } from '../data_views_service/service'; +import { fieldContainsData, fieldExists } from '../../shared_components'; +import { IndexPatternServiceAPI } from '../../data_views_service/service'; export type Props = Omit< - DatasourceDataPanelProps, + DatasourceDataPanelProps, 'core' | 'onChangeIndexPattern' > & { data: DataPublicPluginStart; @@ -124,7 +124,7 @@ function buildSafeEsQuery( } } -export function IndexPatternDataPanel({ +export function FormBasedDataPanel({ state, dragDropContext, core, @@ -264,7 +264,7 @@ const defaultFieldGroups: { const htmlId = htmlIdGenerator('datapanel'); const fieldSearchDescriptionId = htmlId(); -export const InnerIndexPatternDataPanel = function InnerIndexPatternDataPanel({ +export const InnerFormBasedDataPanel = function InnerFormBasedDataPanel({ currentIndexPatternId, query, dateRange, @@ -751,4 +751,4 @@ export const InnerIndexPatternDataPanel = function InnerIndexPatternDataPanel({ ); }; -export const MemoizedDataPanel = memo(InnerIndexPatternDataPanel); +export const MemoizedDataPanel = memo(InnerFormBasedDataPanel); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dedupe_aggs.test.ts b/x-pack/plugins/lens/public/datasources/form_based/dedupe_aggs.test.ts similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/dedupe_aggs.test.ts rename to x-pack/plugins/lens/public/datasources/form_based/dedupe_aggs.test.ts diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dedupe_aggs.ts b/x-pack/plugins/lens/public/datasources/form_based/dedupe_aggs.ts similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/dedupe_aggs.ts rename to x-pack/plugins/lens/public/datasources/form_based/dedupe_aggs.ts diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/advanced_options.tsx b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/advanced_options.tsx similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/advanced_options.tsx rename to x-pack/plugins/lens/public/datasources/form_based/dimension_panel/advanced_options.tsx diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/bucket_nesting_editor.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/bucket_nesting_editor.test.tsx similarity index 98% rename from x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/bucket_nesting_editor.test.tsx rename to x-pack/plugins/lens/public/datasources/form_based/dimension_panel/bucket_nesting_editor.test.tsx index 248cc0f78756eb..6c09849df04ac4 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/bucket_nesting_editor.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/bucket_nesting_editor.test.tsx @@ -8,8 +8,8 @@ import { mount } from 'enzyme'; import React from 'react'; import { BucketNestingEditor } from './bucket_nesting_editor'; -import { GenericIndexPatternColumn } from '../indexpattern'; -import { IndexPatternField } from '../../types'; +import { GenericIndexPatternColumn } from '../form_based'; +import { IndexPatternField } from '../../../types'; const fieldMap: Record = { a: { displayName: 'a' } as IndexPatternField, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/bucket_nesting_editor.tsx b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/bucket_nesting_editor.tsx similarity index 96% rename from x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/bucket_nesting_editor.tsx rename to x-pack/plugins/lens/public/datasources/form_based/dimension_panel/bucket_nesting_editor.tsx index 31a4b91706dfac..fb062e4231467a 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/bucket_nesting_editor.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/bucket_nesting_editor.tsx @@ -8,10 +8,10 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { EuiFormRow, EuiSwitch, EuiSelect } from '@elastic/eui'; -import { IndexPatternLayer } from '../types'; +import { FormBasedLayer } from '../types'; import { hasField } from '../pure_utils'; import { GenericIndexPatternColumn } from '../operations'; -import { IndexPatternField } from '../../types'; +import { IndexPatternField } from '../../../types'; function nestColumn(columnOrder: string[], outer: string, inner: string) { const result = columnOrder.filter((c) => c !== inner); @@ -38,7 +38,7 @@ export function BucketNestingEditor({ getFieldByName, }: { columnId: string; - layer: IndexPatternLayer; + layer: FormBasedLayer; setColumns: (columns: string[]) => void; getFieldByName: (name: string) => IndexPatternField | undefined; }) { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_editor.scss b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/dimension_editor.scss similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_editor.scss rename to x-pack/plugins/lens/public/datasources/form_based/dimension_panel/dimension_editor.scss diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_editor.tsx b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/dimension_editor.tsx similarity index 97% rename from x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_editor.tsx rename to x-pack/plugins/lens/public/datasources/form_based/dimension_panel/dimension_editor.tsx index b4cad9aa73697c..330d3285b29511 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_editor.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/dimension_editor.tsx @@ -27,9 +27,9 @@ import { EuiButtonIcon, } from '@elastic/eui'; import ReactDOM from 'react-dom'; -import type { IndexPatternDimensionEditorProps } from './dimension_panel'; +import type { FormBasedDimensionEditorProps } from './dimension_panel'; import type { OperationSupportMatrix } from './operation_support'; -import { deleteColumn, GenericIndexPatternColumn } from '../indexpattern'; +import { deleteColumn, GenericIndexPatternColumn } from '../form_based'; import { operationDefinitionMap, getOperationDisplay, @@ -46,7 +46,7 @@ import { mergeLayer } from '../state_helpers'; import { getReferencedField, hasField } from '../pure_utils'; import { fieldIsInvalid } from '../utils'; import { BucketNestingEditor } from './bucket_nesting_editor'; -import type { IndexPatternLayer } from '../types'; +import type { FormBasedLayer } from '../types'; import { FormatSelector } from './format_selector'; import { ReferenceEditor } from './reference_editor'; import { TimeScaling } from './time_scaling'; @@ -54,8 +54,8 @@ import { Filtering } from './filtering'; import { ReducedTimeRange } from './reduced_time_range'; import { AdvancedOptions } from './advanced_options'; import { TimeShift } from './time_shift'; -import type { LayerType } from '../../../common'; -import { DOCUMENT_FIELD_NAME } from '../../../common'; +import type { LayerType } from '../../../../common'; +import { DOCUMENT_FIELD_NAME } from '../../../../common'; import { quickFunctionsName, staticValueOperationName, @@ -68,15 +68,15 @@ import { } from './dimensions_editor_helpers'; import type { TemporaryState } from './dimensions_editor_helpers'; import { FieldInput } from './field_input'; -import { NameInput } from '../../shared_components'; +import { NameInput } from '../../../shared_components'; import { ParamEditorProps } from '../operations/definitions'; import { WrappingHelpPopover } from '../help_popover'; import { isColumn } from '../operations/definitions/helpers'; import type { FieldChoiceWithOperationType } from './field_select'; -import type { IndexPattern, IndexPatternField } from '../../types'; +import type { IndexPattern, IndexPatternField } from '../../../types'; import { documentField } from '../document_field'; -export interface DimensionEditorProps extends IndexPatternDimensionEditorProps { +export interface DimensionEditorProps extends FormBasedDimensionEditorProps { selectedColumn?: GenericIndexPatternColumn; layerType: LayerType; operationSupportMatrix: OperationSupportMatrix; @@ -142,13 +142,13 @@ export function DimensionEditor(props: DimensionEditorProps) { const setStateWrapper = useCallback( ( setter: - | IndexPatternLayer - | ((prevLayer: IndexPatternLayer) => IndexPatternLayer) + | FormBasedLayer + | ((prevLayer: FormBasedLayer) => FormBasedLayer) | GenericIndexPatternColumn, options: { forceRender?: boolean } = {} ) => { const layer = state.layers[layerId]; - let hypotethicalLayer: IndexPatternLayer; + let hypotethicalLayer: FormBasedLayer; if (isColumn(setter)) { hypotethicalLayer = { ...layer, @@ -164,7 +164,7 @@ export function DimensionEditor(props: DimensionEditorProps) { setState( (prevState) => { - let outputLayer: IndexPatternLayer; + let outputLayer: FormBasedLayer; const prevLayer = prevState.layers[layerId]; if (isColumn(setter)) { outputLayer = { @@ -250,8 +250,8 @@ export function DimensionEditor(props: DimensionEditorProps) { // TODO: revisit this once we get rid of updateDatasourceAsync upstream const moveDefinetelyToStaticValueAndUpdate = ( setter: - | IndexPatternLayer - | ((prevLayer: IndexPatternLayer) => IndexPatternLayer) + | FormBasedLayer + | ((prevLayer: FormBasedLayer) => FormBasedLayer) | GenericIndexPatternColumn ) => { if (temporaryStaticValue) { @@ -501,7 +501,7 @@ export function DimensionEditor(props: DimensionEditorProps) { } else if (!selectedColumn || !compatibleWithCurrentField) { const possibleFields = fieldByOperation[operationType] || new Set(); - let newLayer: IndexPatternLayer; + let newLayer: FormBasedLayer; if (possibleFields.size === 1) { newLayer = insertOrReplaceColumn({ layer: props.state.layers[props.layerId], @@ -585,9 +585,7 @@ export function DimensionEditor(props: DimensionEditorProps) { const paramEditorProps: ParamEditorProps< GenericIndexPatternColumn, - | IndexPatternLayer - | ((prevLayer: IndexPatternLayer) => IndexPatternLayer) - | GenericIndexPatternColumn + FormBasedLayer | ((prevLayer: FormBasedLayer) => FormBasedLayer) | GenericIndexPatternColumn > = { layer: state.layers[layerId], layerId, @@ -769,11 +767,11 @@ export function DimensionEditor(props: DimensionEditorProps) { }} paramEditorUpdater={( setter: - | IndexPatternLayer - | ((prevLayer: IndexPatternLayer) => IndexPatternLayer) + | FormBasedLayer + | ((prevLayer: FormBasedLayer) => FormBasedLayer) | GenericIndexPatternColumn ) => { - let newLayer: IndexPatternLayer; + let newLayer: FormBasedLayer; if (typeof setter === 'function') { newLayer = setter(layer); } else if (isColumn(setter)) { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/dimension_panel.test.tsx similarity index 89% rename from x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.test.tsx rename to x-pack/plugins/lens/public/datasources/form_based/dimension_panel/dimension_panel.test.tsx index 41dd1df5bcd921..456b1537db97c5 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/dimension_panel.test.tsx @@ -21,8 +21,8 @@ import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; import { DataPublicPluginStart } from '@kbn/data-plugin/public'; import { fieldFormatsServiceMock } from '@kbn/field-formats-plugin/public/mocks'; import { - IndexPatternDimensionEditorComponent, - IndexPatternDimensionEditorProps, + FormBasedDimensionEditorComponent, + FormBasedDimensionEditorProps, } from './dimension_panel'; import { mountWithIntl as mount, shallowWithIntl as shallow } from '@kbn/test-jest-helpers'; import { @@ -32,9 +32,9 @@ import { CoreStart, } from '@kbn/core/public'; import { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; +import { generateId } from '../../../id_generator'; +import { FormBasedPrivateState } from '../types'; import { LayerTypes } from '@kbn/expression-xy-plugin/public'; -import { generateId } from '../../id_generator'; -import { IndexPatternPrivateState } from '../types'; import { FiltersIndexPatternColumn, GenericIndexPatternColumn, @@ -42,7 +42,7 @@ import { TermsIndexPatternColumn, } from '../operations'; import { documentField } from '../document_field'; -import { OperationMetadata } from '../../types'; +import { OperationMetadata } from '../../../types'; import { DateHistogramIndexPatternColumn } from '../operations/definitions/date_histogram'; import { getFieldByNameFactory } from '../pure_helpers'; import { Filtering, setFilter } from './filtering'; @@ -69,7 +69,7 @@ jest.mock('lodash', () => { debounce: (fn: unknown) => fn, }; }); -jest.mock('../../id_generator'); +jest.mock('../../../id_generator'); // Mock the Monaco Editor component jest.mock('../operations/definitions/formula/editor/formula_editor', () => { return { @@ -148,10 +148,10 @@ const bytesColumn: GenericIndexPatternColumn = { * - Dimension trigger: Not tested here * - Dimension editor component: First half of the tests */ -describe('IndexPatternDimensionEditorPanel', () => { - let state: IndexPatternPrivateState; +describe('FormBasedDimensionEditor', () => { + let state: FormBasedPrivateState; let setState: jest.Mock; - let defaultProps: IndexPatternDimensionEditorProps; + let defaultProps: FormBasedDimensionEditorProps; function getStateWithColumns(columns: Record) { return { @@ -265,14 +265,14 @@ describe('IndexPatternDimensionEditorPanel', () => { const filterOperations = jest.fn().mockReturnValue(true); wrapper = shallow( - + ); expect(filterOperations).toBeCalled(); }); it('should show field select', () => { - wrapper = mount(); + wrapper = mount(); expect( wrapper.find(EuiComboBox).filter('[data-test-subj="indexPattern-dimension-field"]') @@ -281,7 +281,7 @@ describe('IndexPatternDimensionEditorPanel', () => { it('should not show field select on fieldless operation', () => { wrapper = mount( - { it('should not show any choices if the filter returns false', () => { wrapper = mount( - false} @@ -320,7 +320,7 @@ describe('IndexPatternDimensionEditorPanel', () => { }); it('should list all field names and document as a whole in prioritized order', () => { - wrapper = mount(); + wrapper = mount(); const options = wrapper .find(EuiComboBox) @@ -348,7 +348,7 @@ describe('IndexPatternDimensionEditorPanel', () => { }, }, }; - wrapper = mount(); + wrapper = mount(); const options = wrapper .find(EuiComboBox) @@ -360,7 +360,7 @@ describe('IndexPatternDimensionEditorPanel', () => { it('should indicate fields which are incompatible for the operation of the current column', () => { wrapper = mount( - @@ -383,7 +383,7 @@ describe('IndexPatternDimensionEditorPanel', () => { it('should indicate operations which are incompatible for the field of the current column', () => { wrapper = mount( - @@ -407,7 +407,7 @@ describe('IndexPatternDimensionEditorPanel', () => { it('should indicate when a transition is invalid due to filterOperations', () => { wrapper = mount( - { }); it('should not display hidden operation types', () => { - wrapper = mount(); + wrapper = mount(); const items: EuiListGroupItemProps[] = wrapper.find(EuiListGroup).prop('listItems') || []; @@ -442,7 +442,7 @@ describe('IndexPatternDimensionEditorPanel', () => { it('should indicate that reference-based operations are not compatible when they are incomplete', () => { wrapper = mount( - { it('should indicate that reference-based operations are compatible sometimes', () => { wrapper = mount( - { }); it('should keep the operation when switching to another field compatible with this operation', () => { - const initialState: IndexPatternPrivateState = getStateWithColumns({ col1: bytesColumn }); + const initialState: FormBasedPrivateState = getStateWithColumns({ col1: bytesColumn }); - wrapper = mount( - - ); + wrapper = mount(); const comboBox = wrapper .find(EuiComboBox) @@ -562,7 +560,7 @@ describe('IndexPatternDimensionEditorPanel', () => { }); it('should switch operations when selecting a field that requires another operation', () => { - wrapper = mount(); + wrapper = mount(); const comboBox = wrapper .find(EuiComboBox) @@ -597,7 +595,7 @@ describe('IndexPatternDimensionEditorPanel', () => { it('should keep the field when switching to another operation compatible for this field', () => { wrapper = mount( - @@ -628,7 +626,7 @@ describe('IndexPatternDimensionEditorPanel', () => { }); it('should not set the state if selecting the currently active operation', () => { - wrapper = mount(); + wrapper = mount(); act(() => { wrapper @@ -640,7 +638,7 @@ describe('IndexPatternDimensionEditorPanel', () => { }); it('should update label and custom label flag on label input changes', () => { - wrapper = mount(); + wrapper = mount(); act(() => { wrapper @@ -669,7 +667,7 @@ describe('IndexPatternDimensionEditorPanel', () => { it('should not keep the label as long as it is the default label', () => { wrapper = mount( - @@ -698,7 +696,7 @@ describe('IndexPatternDimensionEditorPanel', () => { it('should keep the label on operation change if it is custom', () => { wrapper = mount( - { it('should remove customLabel flag if label is set to default', () => { wrapper = mount( - { describe('transient invalid state', () => { it('should set the state if selecting an operation incompatible with the current field', () => { - wrapper = mount(); + wrapper = mount(); act(() => { wrapper @@ -799,7 +797,7 @@ describe('IndexPatternDimensionEditorPanel', () => { }); it('should show error message in invalid state', () => { - wrapper = mount(); + wrapper = mount(); wrapper .find('button[data-test-subj="lns-indexPatternDimension-terms incompatible"]') @@ -811,7 +809,7 @@ describe('IndexPatternDimensionEditorPanel', () => { }); it('should leave error state if a compatible operation is selected', () => { - wrapper = mount(); + wrapper = mount(); wrapper .find('button[data-test-subj="lns-indexPatternDimension-terms incompatible"]') @@ -825,7 +823,7 @@ describe('IndexPatternDimensionEditorPanel', () => { }); it('should leave error state if the original operation is re-selected', () => { - wrapper = mount(); + wrapper = mount(); wrapper .find('button[data-test-subj="lns-indexPatternDimension-terms incompatible"]') @@ -841,7 +839,7 @@ describe('IndexPatternDimensionEditorPanel', () => { it('should leave error state when switching from incomplete state to fieldless operation', () => { // @ts-expect-error window['__react-beautiful-dnd-disable-dev-warnings'] = true; // issue with enzyme & react-beautiful-dnd throwing errors: https://github.com/atlassian/react-beautiful-dnd/issues/1593 - wrapper = mount(); + wrapper = mount(); wrapper .find('button[data-test-subj="lns-indexPatternDimension-terms incompatible"]') @@ -854,7 +852,7 @@ describe('IndexPatternDimensionEditorPanel', () => { it('should leave error state when re-selecting the original fieldless function', () => { wrapper = mount( - { }); it('should indicate fields compatible with selected operation', () => { - wrapper = mount(); + wrapper = mount(); wrapper .find('button[data-test-subj="lns-indexPatternDimension-terms incompatible"]') @@ -901,7 +899,7 @@ describe('IndexPatternDimensionEditorPanel', () => { }); it('should select compatible operation if field not compatible with selected operation', () => { - wrapper = mount(); + wrapper = mount(); wrapper.find('button[data-test-subj="lns-indexPatternDimension-average"]').simulate('click'); @@ -962,11 +960,7 @@ describe('IndexPatternDimensionEditorPanel', () => { }, }); wrapper = mount( - + ); // Transition to a field operation (incompatible) @@ -991,7 +985,7 @@ describe('IndexPatternDimensionEditorPanel', () => { it('should select the Records field when count is selected on non-existing column', () => { wrapper = mount( - { it('should indicate document and field compatibility with selected document operation', () => { wrapper = mount( - { }); it('should set datasource state if compatible field is selected for operation', () => { - wrapper = mount(); + wrapper = mount(); wrapper .find('button[data-test-subj="lns-indexPatternDimension-terms incompatible"]') @@ -1110,7 +1104,7 @@ describe('IndexPatternDimensionEditorPanel', () => { } it('should default to None if time scaling is not set', () => { - wrapper = mount(); + wrapper = mount(); findTestSubject(wrapper, 'indexPattern-advanced-accordion').simulate('click'); expect(wrapper.find('[data-test-subj="indexPattern-time-scaling-enable"]')).toHaveLength(1); expect( @@ -1122,7 +1116,7 @@ describe('IndexPatternDimensionEditorPanel', () => { }); it('should show current time scaling if set', () => { - wrapper = mount(); + wrapper = mount(); findTestSubject(wrapper, 'indexPattern-advanced-accordion').simulate('click'); expect( wrapper @@ -1134,7 +1128,7 @@ describe('IndexPatternDimensionEditorPanel', () => { it('should allow to set time scaling initially', () => { const props = getProps({}); - wrapper = mount(); + wrapper = mount(); findTestSubject(wrapper, 'indexPattern-advanced-accordion').simulate('click'); wrapper .find('[data-test-subj="indexPattern-time-scaling-unit"]') @@ -1167,7 +1161,7 @@ describe('IndexPatternDimensionEditorPanel', () => { operationType: 'sum', label: 'Sum of bytes per hour', }); - wrapper = mount(); + wrapper = mount(); wrapper.find('button[data-test-subj="lns-indexPatternDimension-count"]').simulate('click'); expect(setState.mock.calls[0]).toEqual([expect.any(Function), { isDimensionComplete: true }]); expect(setState.mock.calls[0][0](props.state)).toEqual({ @@ -1194,7 +1188,7 @@ describe('IndexPatternDimensionEditorPanel', () => { operationType: 'sum', label: 'Sum of bytes per hour', }); - wrapper = mount(); + wrapper = mount(); wrapper.find('button[data-test-subj="lns-indexPatternDimension-average"]').simulate('click'); expect(setState.mock.calls[0]).toEqual([expect.any(Function), { isDimensionComplete: true }]); expect(setState.mock.calls[0][0](props.state)).toEqual({ @@ -1216,7 +1210,7 @@ describe('IndexPatternDimensionEditorPanel', () => { it('should allow to change time scaling', () => { const props = getProps({ timeScale: 's', label: 'Count of records per second' }); - wrapper = mount(); + wrapper = mount(); findTestSubject(wrapper, 'indexPattern-advanced-accordion').simulate('click'); wrapper.find('[data-test-subj="indexPattern-time-scaling-unit"] select').simulate('change', { @@ -1243,7 +1237,7 @@ describe('IndexPatternDimensionEditorPanel', () => { it('should not adjust label if it is custom', () => { const props = getProps({ timeScale: 's', customLabel: true, label: 'My label' }); - wrapper = mount(); + wrapper = mount(); wrapper.find('[data-test-subj="indexPattern-time-scaling-unit"] select').simulate('change', { target: { value: 'h' }, }); @@ -1309,7 +1303,7 @@ describe('IndexPatternDimensionEditorPanel', () => { }), columnId: 'col2', }; - wrapper = mount(); + wrapper = mount(); findTestSubject(wrapper, 'indexPattern-advanced-accordion').simulate('click'); expect( wrapper.find('[data-test-subj="indexPattern-dimension-reducedTimeRange-row"]') @@ -1318,7 +1312,7 @@ describe('IndexPatternDimensionEditorPanel', () => { it('should show current reduced time range if set', () => { wrapper = mount( - + ); expect( wrapper.find(ReducedTimeRange).find(EuiComboBox).prop('selectedOptions')[0].value @@ -1327,7 +1321,7 @@ describe('IndexPatternDimensionEditorPanel', () => { it('should allow to set reduced time range initially', () => { const props = getProps({}); - wrapper = mount(); + wrapper = mount(); findTestSubject(wrapper, 'indexPattern-advanced-accordion').simulate('click'); wrapper.find(ReducedTimeRange).find(EuiComboBox).prop('onChange')!([ { value: '1h', label: '' }, @@ -1355,7 +1349,7 @@ describe('IndexPatternDimensionEditorPanel', () => { operationType: 'sum', label: 'Sum of bytes per hour', }); - wrapper = mount(); + wrapper = mount(); wrapper.find('button[data-test-subj="lns-indexPatternDimension-count"]').simulate('click'); expect((props.setState as jest.Mock).mock.calls[0][0](props.state)).toEqual({ ...props.state, @@ -1377,7 +1371,7 @@ describe('IndexPatternDimensionEditorPanel', () => { const props = getProps({ timeShift: '1d', }); - wrapper = mount(); + wrapper = mount(); wrapper.find(ReducedTimeRange).find(EuiComboBox).prop('onCreateOption')!('7m', []); expect((props.setState as jest.Mock).mock.calls[0][0](props.state)).toEqual({ ...props.state, @@ -1399,7 +1393,7 @@ describe('IndexPatternDimensionEditorPanel', () => { const props = getProps({ reducedTimeRange: '5 months', }); - wrapper = mount(); + wrapper = mount(); expect(wrapper.find(ReducedTimeRange).find(EuiComboBox).prop('isInvalid')).toBeTruthy(); @@ -1457,7 +1451,7 @@ describe('IndexPatternDimensionEditorPanel', () => { columnId: 'col2', }; wrapper = mount( - { }); it('should show custom options if time shift is available', () => { - wrapper = shallow(); + wrapper = shallow(); expect( wrapper .find(DimensionEditor) @@ -1485,7 +1479,7 @@ describe('IndexPatternDimensionEditorPanel', () => { }); it('should show current time shift if set', () => { - wrapper = mount(); + wrapper = mount(); expect(wrapper.find(TimeShift).find(EuiComboBox).prop('selectedOptions')[0].value).toEqual( '1d' ); @@ -1493,7 +1487,7 @@ describe('IndexPatternDimensionEditorPanel', () => { it('should allow to set time shift initially', () => { const props = getProps({}); - wrapper = mount(); + wrapper = mount(); findTestSubject(wrapper, 'indexPattern-advanced-accordion').simulate('click'); wrapper.find(TimeShift).find(EuiComboBox).prop('onChange')!([{ value: '1h', label: '' }]); expect((props.setState as jest.Mock).mock.calls[0][0](props.state)).toEqual({ @@ -1519,7 +1513,7 @@ describe('IndexPatternDimensionEditorPanel', () => { operationType: 'sum', label: 'Sum of bytes per hour', }); - wrapper = mount(); + wrapper = mount(); wrapper.find('button[data-test-subj="lns-indexPatternDimension-count"]').simulate('click'); expect((props.setState as jest.Mock).mock.calls[0][0](props.state)).toEqual({ ...props.state, @@ -1541,7 +1535,7 @@ describe('IndexPatternDimensionEditorPanel', () => { const props = getProps({ timeShift: '1d', }); - wrapper = mount(); + wrapper = mount(); wrapper.find(TimeShift).find(EuiComboBox).prop('onCreateOption')!('1h', []); expect((props.setState as jest.Mock).mock.calls[0][0](props.state)).toEqual({ ...props.state, @@ -1563,7 +1557,7 @@ describe('IndexPatternDimensionEditorPanel', () => { const props = getProps({ timeShift: '5 months', }); - wrapper = mount(); + wrapper = mount(); expect(wrapper.find(TimeShift).find(EuiComboBox).prop('isInvalid')).toBeTruthy(); @@ -1608,7 +1602,7 @@ describe('IndexPatternDimensionEditorPanel', () => { it('should not show custom options if time scaling is not available', () => { wrapper = mount( - { }); it('should show custom options if filtering is available', () => { - wrapper = mount(); + wrapper = mount(); findTestSubject(wrapper, 'indexPattern-advanced-accordion').simulate('click'); expect( wrapper.find('[data-test-subj="indexPattern-filter-by-enable"]').hostNodes() @@ -1635,7 +1629,7 @@ describe('IndexPatternDimensionEditorPanel', () => { it('should show current filter if set', () => { wrapper = mount( - ); @@ -1655,7 +1649,7 @@ describe('IndexPatternDimensionEditorPanel', () => { operationType: 'sum', label: 'Sum of bytes per hour', }); - wrapper = mount(); + wrapper = mount(); wrapper.find('button[data-test-subj="lns-indexPatternDimension-count"]').simulate('click'); expect(setState.mock.calls[0]).toEqual([expect.any(Function), { isDimensionComplete: true }]); expect(setState.mock.calls[0][0](props.state)).toEqual({ @@ -1679,7 +1673,7 @@ describe('IndexPatternDimensionEditorPanel', () => { filter: { language: 'kuery', query: 'a: b' }, }); - wrapper = mount(); + wrapper = mount(); act(() => { const { updateLayer, columnId, layer } = wrapper.find(Filtering).props(); @@ -1707,7 +1701,7 @@ describe('IndexPatternDimensionEditorPanel', () => { it('should render invalid field if field reference is broken', () => { wrapper = mount( - { }); it('should support selecting the operation before the field', () => { - wrapper = mount(); + wrapper = mount(); wrapper.find('button[data-test-subj="lns-indexPatternDimension-average"]').simulate('click'); @@ -1784,7 +1778,7 @@ describe('IndexPatternDimensionEditorPanel', () => { it('should select operation directly if only one field is possible', () => { wrapper = mount( - { }); it('should select operation directly if only document is possible', () => { - wrapper = mount(); + wrapper = mount(); wrapper.find('button[data-test-subj="lns-indexPatternDimension-count"]').simulate('click'); @@ -1845,7 +1839,7 @@ describe('IndexPatternDimensionEditorPanel', () => { }); it('should indicate compatible fields when selecting the operation first', () => { - wrapper = mount(); + wrapper = mount(); act(() => { wrapper.find('button[data-test-subj="lns-indexPatternDimension-average"]').simulate('click'); @@ -1871,7 +1865,7 @@ describe('IndexPatternDimensionEditorPanel', () => { it('should indicate document compatibility when document operation is selected', () => { wrapper = mount( - { }); it('should not update when selecting the current field again', () => { - wrapper = mount(); + wrapper = mount(); const comboBox = wrapper .find(EuiComboBox) @@ -1914,7 +1908,7 @@ describe('IndexPatternDimensionEditorPanel', () => { it('should show all operations that are not filtered out', () => { wrapper = mount( - !op.isBucketed && op.dataType === 'number'} /> @@ -1946,7 +1940,7 @@ describe('IndexPatternDimensionEditorPanel', () => { // Prevents field format from being loaded setState.mockImplementation(() => {}); - wrapper = mount(); + wrapper = mount(); const comboBox = wrapper .find(EuiComboBox) @@ -1981,12 +1975,10 @@ describe('IndexPatternDimensionEditorPanel', () => { }); it('should use helper function when changing the function', () => { - const initialState: IndexPatternPrivateState = getStateWithColumns({ + const initialState: FormBasedPrivateState = getStateWithColumns({ col1: bytesColumn, }); - wrapper = mount( - - ); + wrapper = mount(); act(() => { wrapper .find('button[data-test-subj="lns-indexPatternDimension-min"]') @@ -2004,7 +1996,7 @@ describe('IndexPatternDimensionEditorPanel', () => { }); it('should keep the latest valid dimension when removing the selection in field combobox', () => { - wrapper = mount(); + wrapper = mount(); act(() => { wrapper @@ -2017,7 +2009,7 @@ describe('IndexPatternDimensionEditorPanel', () => { }); it('allows custom format', () => { - const stateWithNumberCol: IndexPatternPrivateState = getStateWithColumns({ + const stateWithNumberCol: FormBasedPrivateState = getStateWithColumns({ col1: { label: 'Average of memory', dataType: 'number', @@ -2029,7 +2021,7 @@ describe('IndexPatternDimensionEditorPanel', () => { }); wrapper = mount( - + ); act(() => { @@ -2059,7 +2051,7 @@ describe('IndexPatternDimensionEditorPanel', () => { }); it('keeps decimal places while switching', () => { - const stateWithNumberCol: IndexPatternPrivateState = getStateWithColumns({ + const stateWithNumberCol: FormBasedPrivateState = getStateWithColumns({ col1: { label: 'Average of memory', dataType: 'number', @@ -2073,7 +2065,7 @@ describe('IndexPatternDimensionEditorPanel', () => { }, }); wrapper = mount( - + ); act(() => { @@ -2099,7 +2091,7 @@ describe('IndexPatternDimensionEditorPanel', () => { }); it('allows custom format with number of decimal places', () => { - const stateWithNumberCol: IndexPatternPrivateState = getStateWithColumns({ + const stateWithNumberCol: FormBasedPrivateState = getStateWithColumns({ col1: { label: 'Average of memory', dataType: 'number', @@ -2114,7 +2106,7 @@ describe('IndexPatternDimensionEditorPanel', () => { }); wrapper = mount( - + ); act(() => { @@ -2145,7 +2137,7 @@ describe('IndexPatternDimensionEditorPanel', () => { it('should hide the top level field selector when switching from non-reference to reference', () => { (generateId as jest.Mock).mockReturnValue(`second`); - wrapper = mount(); + wrapper = mount(); expect(wrapper.find('ReferenceEditor')).toHaveLength(0); @@ -2157,7 +2149,7 @@ describe('IndexPatternDimensionEditorPanel', () => { }); it('should hide the reference editors when switching from reference to non-reference', () => { - const stateWithReferences: IndexPatternPrivateState = getStateWithColumns({ + const stateWithReferences: FormBasedPrivateState = getStateWithColumns({ col1: { label: 'Differences of (incomplete)', dataType: 'number', @@ -2169,7 +2161,7 @@ describe('IndexPatternDimensionEditorPanel', () => { }); wrapper = mount( - + ); expect(wrapper.find('ReferenceEditor')).toHaveLength(1); @@ -2182,7 +2174,7 @@ describe('IndexPatternDimensionEditorPanel', () => { }); it('should show a warning when the current dimension is no longer configurable', () => { - const stateWithInvalidCol: IndexPatternPrivateState = getStateWithColumns({ + const stateWithInvalidCol: FormBasedPrivateState = getStateWithColumns({ col1: { label: 'Invalid differences', dataType: 'number', @@ -2193,7 +2185,7 @@ describe('IndexPatternDimensionEditorPanel', () => { }); wrapper = mount( - + ); expect( @@ -2205,7 +2197,7 @@ describe('IndexPatternDimensionEditorPanel', () => { }); it('should remove options to select references when there are no time fields', () => { - const stateWithoutTime: IndexPatternPrivateState = { + const stateWithoutTime: FormBasedPrivateState = { ...getStateWithColumns({ col1: { label: 'Avg', @@ -2218,7 +2210,7 @@ describe('IndexPatternDimensionEditorPanel', () => { }; wrapper = mount( - { }); it('should not show tabs when formula and static_value operations are not available', () => { - const stateWithInvalidCol: IndexPatternPrivateState = getStateWithColumns({ + const stateWithInvalidCol: FormBasedPrivateState = getStateWithColumns({ col1: { label: 'Average of memory', dataType: 'number', @@ -2279,15 +2271,13 @@ describe('IndexPatternDimensionEditorPanel', () => { }), }; - wrapper = mount( - - ); + wrapper = mount(); expect(wrapper.find('[data-test-subj="lens-dimensionTabs"]').exists()).toBeFalsy(); }); it('should show the formula tab when supported', () => { - const stateWithFormulaColumn: IndexPatternPrivateState = getStateWithColumns({ + const stateWithFormulaColumn: FormBasedPrivateState = getStateWithColumns({ col1: { label: 'Formula', dataType: 'number', @@ -2299,7 +2289,7 @@ describe('IndexPatternDimensionEditorPanel', () => { }); wrapper = mount( - + ); expect( @@ -2308,7 +2298,7 @@ describe('IndexPatternDimensionEditorPanel', () => { }); it('should not show the static_value tab when not supported', () => { - const stateWithFormulaColumn: IndexPatternPrivateState = getStateWithColumns({ + const stateWithFormulaColumn: FormBasedPrivateState = getStateWithColumns({ col1: { label: 'Formula', dataType: 'number', @@ -2320,14 +2310,14 @@ describe('IndexPatternDimensionEditorPanel', () => { }); wrapper = mount( - + ); expect(wrapper.find('[data-test-subj="lens-dimensionTabs-static_value"]').exists()).toBeFalsy(); }); it('should show the static value tab when supported', () => { - const staticWithFormulaColumn: IndexPatternPrivateState = getStateWithColumns({ + const staticWithFormulaColumn: FormBasedPrivateState = getStateWithColumns({ col1: { label: 'Formula', dataType: 'number', @@ -2339,7 +2329,7 @@ describe('IndexPatternDimensionEditorPanel', () => { }); wrapper = mount( - { }); it('should select the quick function tab by default', () => { - const stateWithNoColumn: IndexPatternPrivateState = getStateWithColumns({}); + const stateWithNoColumn: FormBasedPrivateState = getStateWithColumns({}); wrapper = mount( - + ); expect( @@ -2367,10 +2357,10 @@ describe('IndexPatternDimensionEditorPanel', () => { }); it('should select the static value tab when supported by default', () => { - const stateWithNoColumn: IndexPatternPrivateState = getStateWithColumns({}); + const stateWithNoColumn: FormBasedPrivateState = getStateWithColumns({}); wrapper = mount( - { }); it('should not show any tab when formula is in full screen mode', () => { - const stateWithFormulaColumn: IndexPatternPrivateState = getStateWithColumns({ + const stateWithFormulaColumn: FormBasedPrivateState = getStateWithColumns({ col1: { label: 'Formula', dataType: 'number', @@ -2395,7 +2385,7 @@ describe('IndexPatternDimensionEditorPanel', () => { }); wrapper = mount( - & { +export type FormBasedDimensionTriggerProps = + DatasourceDimensionTriggerProps & { uniqueLabel: string; }; -export type IndexPatternDimensionEditorProps = - DatasourceDimensionEditorProps & { +export type FormBasedDimensionEditorProps = + DatasourceDimensionEditorProps & { uiSettings: IUiSettingsClient; storage: IStorageWrapper; savedObjectsClient: SavedObjectsClientContract; @@ -49,8 +49,8 @@ function wrapOnDot(str?: string) { return str ? str.replace(/\./g, '.\u200B') : ''; } -export const IndexPatternDimensionTriggerComponent = function IndexPatternDimensionTrigger( - props: IndexPatternDimensionTriggerProps +export const FormBasedDimensionTriggerComponent = function FormBasedDimensionTrigger( + props: FormBasedDimensionTriggerProps ) { const layerId = props.layerId; const layer = props.state.layers[layerId]; @@ -80,8 +80,8 @@ export const IndexPatternDimensionTriggerComponent = function IndexPatternDimens ); }; -export const IndexPatternDimensionEditorComponent = function IndexPatternDimensionPanel( - props: IndexPatternDimensionEditorProps +export const FormBasedDimensionEditorComponent = function FormBasedDimensionPanel( + props: FormBasedDimensionEditorProps ) { const layerId = props.layerId; const currentIndexPattern = props.indexPatterns[props.state.layers[layerId]?.indexPatternId]; @@ -103,5 +103,5 @@ export const IndexPatternDimensionEditorComponent = function IndexPatternDimensi ); }; -export const IndexPatternDimensionTrigger = memo(IndexPatternDimensionTriggerComponent); -export const IndexPatternDimensionEditor = memo(IndexPatternDimensionEditorComponent); +export const FormBasedDimensionTrigger = memo(FormBasedDimensionTriggerComponent); +export const FormBasedDimensionEditor = memo(FormBasedDimensionEditorComponent); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimensions_editor_helpers.tsx b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/dimensions_editor_helpers.tsx similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimensions_editor_helpers.tsx rename to x-pack/plugins/lens/public/datasources/form_based/dimension_panel/dimensions_editor_helpers.tsx diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/droppable/get_drop_props.test.ts b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/droppable/get_drop_props.test.ts similarity index 99% rename from x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/droppable/get_drop_props.test.ts rename to x-pack/plugins/lens/public/datasources/form_based/dimension_panel/droppable/get_drop_props.test.ts index 2f4d8a0121aa11..21650cffed54aa 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/droppable/get_drop_props.test.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/droppable/get_drop_props.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { DragDropOperation, OperationMetadata } from '../../../types'; +import { DragDropOperation, OperationMetadata } from '../../../../types'; import { TermsIndexPatternColumn } from '../../operations'; import { getDropProps } from './get_drop_props'; import { @@ -15,7 +15,7 @@ import { mockedDndOperations, mockedColumns, } from './mocks'; -import { generateId } from '../../../id_generator'; +import { generateId } from '../../../../id_generator'; const getDefaultProps = () => ({ indexPatterns: mockDataViews(), @@ -27,7 +27,7 @@ const getDefaultProps = () => ({ source: mockedDndOperations.bucket, }); -describe('IndexPatternDimensionEditorPanel#getDropProps', () => { +describe('FormBasedDimensionEditorPanel#getDropProps', () => { describe('not dragging', () => { it('returns undefined if no drag is happening', () => { expect(getDropProps({ ...getDefaultProps(), source: undefined })).toBe(undefined); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/droppable/get_drop_props.ts b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/droppable/get_drop_props.ts similarity index 95% rename from x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/droppable/get_drop_props.ts rename to x-pack/plugins/lens/public/datasources/form_based/dimension_panel/droppable/get_drop_props.ts index a1f16006fd8036..a9e81bd6df668f 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/droppable/get_drop_props.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/droppable/get_drop_props.ts @@ -12,22 +12,22 @@ import { IndexPattern, IndexPatternMap, IndexPatternField, -} from '../../../types'; +} from '../../../../types'; import { getCurrentFieldsForOperation, getOperationDisplay, hasOperationSupportForMultipleFields, } from '../../operations'; -import { isDraggedDataViewField, isOperationFromTheSameGroup } from '../../../utils'; +import { isDraggedDataViewField, isOperationFromTheSameGroup } from '../../../../utils'; import { hasField } from '../../pure_utils'; -import { DragContextState } from '../../../drag_drop/providers'; -import { OperationMetadata, DraggedField } from '../../../types'; +import { DragContextState } from '../../../../drag_drop/providers'; +import { OperationMetadata, DraggedField } from '../../../../types'; import { getOperationTypesForField } from '../../operations'; -import { GenericIndexPatternColumn } from '../../indexpattern'; -import { IndexPatternPrivateState, DataViewDragDropOperation } from '../../types'; +import { GenericIndexPatternColumn } from '../../form_based'; +import { FormBasedPrivateState, DataViewDragDropOperation } from '../../types'; interface GetDropPropsArgs { - state: IndexPatternPrivateState; + state: FormBasedPrivateState; source?: DragContextState['dragging']; target: DragDropOperation; indexPatterns: IndexPatternMap; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/droppable/index.ts b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/droppable/index.ts similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/droppable/index.ts rename to x-pack/plugins/lens/public/datasources/form_based/dimension_panel/droppable/index.ts diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/droppable/mocks.ts b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/droppable/mocks.ts similarity index 97% rename from x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/droppable/mocks.ts rename to x-pack/plugins/lens/public/datasources/form_based/dimension_panel/droppable/mocks.ts index 93b63071d6642b..ceb16345f475c0 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/droppable/mocks.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/droppable/mocks.ts @@ -5,9 +5,9 @@ * 2.0. */ -import { IndexPatternLayer } from '../../types'; +import { FormBasedLayer } from '../../types'; import { documentField } from '../../document_field'; -import { IndexPatternMap, OperationMetadata } from '../../../types'; +import { IndexPatternMap, OperationMetadata } from '../../../../types'; import { DateHistogramIndexPatternColumn, GenericIndexPatternColumn, @@ -15,7 +15,7 @@ import { TermsIndexPatternColumn, } from '../../operations'; import { getFieldByNameFactory } from '../../pure_helpers'; -jest.mock('../../../id_generator'); +jest.mock('../../../../id_generator'); export const mockDataViews = (): IndexPatternMap => { const fields = [ @@ -191,7 +191,7 @@ export const mockedColumns: Record = { } as GenericIndexPatternColumn, }; -export const mockedLayers: Record IndexPatternLayer> = { +export const mockedLayers: Record FormBasedLayer> = { singleColumnLayer: (id = 'col1') => ({ indexPatternId: 'first', columnOrder: [id], diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/droppable/on_drop_handler.test.ts b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/droppable/on_drop_handler.test.ts similarity index 98% rename from x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/droppable/on_drop_handler.test.ts rename to x-pack/plugins/lens/public/datasources/form_based/dimension_panel/droppable/on_drop_handler.test.ts index 3b468181db6df7..1bff858194a368 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/droppable/on_drop_handler.test.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/droppable/on_drop_handler.test.ts @@ -6,10 +6,14 @@ */ import { onDrop } from './on_drop_handler'; -import { IndexPatternPrivateState } from '../../types'; -import { OperationMetadata, DropType, DatasourceDimensionDropHandlerProps } from '../../../types'; +import { FormBasedPrivateState } from '../../types'; +import { + OperationMetadata, + DropType, + DatasourceDimensionDropHandlerProps, +} from '../../../../types'; import { FormulaIndexPatternColumn, MedianIndexPatternColumn } from '../../operations'; -import { generateId } from '../../../id_generator'; +import { generateId } from '../../../../id_generator'; import { mockDataViews, mockedLayers, @@ -18,7 +22,7 @@ import { mockedColumns, } from './mocks'; -jest.mock('../../../id_generator'); +jest.mock('../../../../id_generator'); const dimensionGroups = [ { @@ -47,7 +51,7 @@ const dimensionGroups = [ }, ]; -function getStateWithMultiFieldColumn(state: IndexPatternPrivateState) { +function getStateWithMultiFieldColumn(state: FormBasedPrivateState) { return { ...state, layers: { @@ -62,10 +66,10 @@ function getStateWithMultiFieldColumn(state: IndexPatternPrivateState) { }; } -describe('IndexPatternDimensionEditorPanel: onDrop', () => { - let state: IndexPatternPrivateState; +describe('FormBasedDimensionEditorPanel: onDrop', () => { + let state: FormBasedPrivateState; let setState: jest.Mock; - let defaultProps: DatasourceDimensionDropHandlerProps; + let defaultProps: DatasourceDimensionDropHandlerProps; beforeEach(() => { state = { @@ -347,7 +351,7 @@ describe('IndexPatternDimensionEditorPanel: onDrop', () => { describe('dropping a dimension', () => { it('sets correct order in group for metric and bucket columns when duplicating a column in group', () => { - const testState: IndexPatternPrivateState = { + const testState: FormBasedPrivateState = { ...state, layers: { ...state.layers, @@ -439,7 +443,7 @@ describe('IndexPatternDimensionEditorPanel: onDrop', () => { it('when duplicating fullReference column, the referenced columns get duplicated too', () => { (generateId as jest.Mock).mockReturnValue(`ref1Copy`); - const testState: IndexPatternPrivateState = { + const testState: FormBasedPrivateState = { ...state, layers: { ...state.layers, @@ -501,7 +505,7 @@ describe('IndexPatternDimensionEditorPanel: onDrop', () => { it('when duplicating fullReference column, the multiple referenced columns get duplicated too', () => { (generateId as jest.Mock).mockReturnValueOnce(`ref1Copy`); (generateId as jest.Mock).mockReturnValueOnce(`ref2Copy`); - const testState: IndexPatternPrivateState = { + const testState: FormBasedPrivateState = { ...state, layers: { ...state.layers, @@ -566,7 +570,7 @@ describe('IndexPatternDimensionEditorPanel: onDrop', () => { it('when duplicating fullReference column, the referenced columns get duplicated', () => { (generateId as jest.Mock).mockReturnValueOnce(`ref1Copy`); (generateId as jest.Mock).mockReturnValueOnce(`ref2Copy`); - const testState: IndexPatternPrivateState = { + const testState: FormBasedPrivateState = { ...state, layers: { ...state.layers, @@ -854,7 +858,7 @@ describe('IndexPatternDimensionEditorPanel: onDrop', () => { }); describe('dimension group aware ordering and copying', () => { - let testState: IndexPatternPrivateState; + let testState: FormBasedPrivateState; beforeEach(() => { testState = { ...state }; testState.layers.first = { ...mockedLayers.multipleColumnsLayer() }; @@ -1541,7 +1545,7 @@ describe('IndexPatternDimensionEditorPanel: onDrop', () => { }, ]; describe('simple operations', () => { - let props: DatasourceDimensionDropHandlerProps; + let props: DatasourceDimensionDropHandlerProps; beforeEach(() => { setState = jest.fn(); @@ -2087,7 +2091,7 @@ describe('IndexPatternDimensionEditorPanel: onDrop', () => { }); }); describe('references', () => { - let props: DatasourceDimensionDropHandlerProps; + let props: DatasourceDimensionDropHandlerProps; beforeEach(() => { props = { dimensionGroups: defaultDimensionGroups, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/droppable/on_drop_handler.ts b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/droppable/on_drop_handler.ts similarity index 98% rename from x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/droppable/on_drop_handler.ts rename to x-pack/plugins/lens/public/datasources/form_based/dimension_panel/droppable/on_drop_handler.ts index 232c96610f04c7..ad575d3c53947b 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/droppable/on_drop_handler.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/droppable/on_drop_handler.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { isDraggedDataViewField } from '../../../utils'; +import { isDraggedDataViewField } from '../../../../utils'; import { DatasourceDimensionDropHandlerProps, DragDropOperation, @@ -14,7 +14,7 @@ import { StateSetter, VisualizationDimensionGroupConfig, DraggedField, -} from '../../../types'; +} from '../../../../types'; import { insertOrReplaceColumn, deleteColumn, @@ -28,12 +28,12 @@ import { } from '../../operations'; import { mergeLayer, mergeLayers } from '../../state_helpers'; import { getNewOperation, getField } from './get_drop_props'; -import { IndexPatternPrivateState, DataViewDragDropOperation } from '../../types'; +import { FormBasedPrivateState, DataViewDragDropOperation } from '../../types'; interface DropHandlerProps { - state: IndexPatternPrivateState; + state: FormBasedPrivateState; setState: StateSetter< - IndexPatternPrivateState, + FormBasedPrivateState, { isDimensionComplete?: boolean; forceRender?: boolean; @@ -46,7 +46,7 @@ interface DropHandlerProps { indexPatterns: IndexPatternMap; } -export function onDrop(props: DatasourceDimensionDropHandlerProps) { +export function onDrop(props: DatasourceDimensionDropHandlerProps) { const { target, source, dropType, state, indexPatterns } = props; if (isDraggedDataViewField(source) && isFieldDropType(dropType)) { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_input.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/field_input.test.tsx similarity index 98% rename from x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_input.test.tsx rename to x-pack/plugins/lens/public/datasources/form_based/dimension_panel/field_input.test.tsx index b7ab501f34d169..877dc18156cdf3 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_input.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/field_input.test.tsx @@ -21,7 +21,7 @@ import { import { FieldInput, getErrorMessage } from './field_input'; import { createMockedIndexPattern } from '../mocks'; import { getOperationSupportMatrix } from '.'; -import { GenericIndexPatternColumn, IndexPatternLayer, IndexPatternPrivateState } from '../types'; +import { GenericIndexPatternColumn, FormBasedLayer, FormBasedPrivateState } from '../types'; import { ReferenceBasedIndexPatternColumn } from '../operations/definitions/column_types'; jest.mock('../operations/layer_helpers', () => { @@ -30,7 +30,7 @@ jest.mock('../operations/layer_helpers', () => { return { ...original, insertOrReplaceColumn: () => { - return {} as IndexPatternLayer; + return {} as FormBasedLayer; }, }; }); @@ -113,14 +113,14 @@ function getLayer(col1: GenericIndexPatternColumn = getStringBasedOperationColum }; } function getDefaultOperationSupportMatrix( - layer: IndexPatternLayer, + layer: FormBasedLayer, columnId: string, existingFields: Record> ) { return getOperationSupportMatrix({ state: { layers: { layer1: layer }, - } as unknown as IndexPatternPrivateState, + } as unknown as FormBasedPrivateState, layerId: 'layer1', filterOperations: () => true, columnId, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_input.tsx b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/field_input.tsx similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_input.tsx rename to x-pack/plugins/lens/public/datasources/form_based/dimension_panel/field_input.tsx diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_select.scss b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/field_select.scss similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_select.scss rename to x-pack/plugins/lens/public/datasources/form_based/dimension_panel/field_select.scss diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_select.tsx b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/field_select.tsx similarity index 95% rename from x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_select.tsx rename to x-pack/plugins/lens/public/datasources/form_based/dimension_panel/field_select.tsx index af5dc76143b173..52b2c128af5954 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_select.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/field_select.tsx @@ -10,11 +10,15 @@ import { partition } from 'lodash'; import React, { useMemo } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiComboBoxOptionOption, EuiComboBoxProps } from '@elastic/eui'; -import type { OperationType } from '../indexpattern'; +import type { OperationType } from '../form_based'; import type { OperationSupportMatrix } from './operation_support'; -import { FieldOption, FieldOptionValue, FieldPicker } from '../../shared_components/field_picker'; -import { fieldContainsData } from '../../shared_components'; -import type { ExistingFieldsMap, IndexPattern } from '../../types'; +import { + FieldOption, + FieldOptionValue, + FieldPicker, +} from '../../../shared_components/field_picker'; +import { fieldContainsData } from '../../../shared_components'; +import type { ExistingFieldsMap, IndexPattern } from '../../../types'; import { getFieldType } from '../pure_utils'; export type FieldChoiceWithOperationType = FieldOptionValue & { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/filtering.tsx b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/filtering.tsx similarity index 81% rename from x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/filtering.tsx rename to x-pack/plugins/lens/public/datasources/form_based/dimension_panel/filtering.tsx index 059170d9702d86..13db26af121086 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/filtering.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/filtering.tsx @@ -8,11 +8,11 @@ import React, { useCallback } from 'react'; import { isEqual } from 'lodash'; import type { Query } from '@kbn/es-query'; import { GenericIndexPatternColumn, operationDefinitionMap } from '../operations'; -import type { IndexPatternLayer } from '../types'; -import { validateQuery, FilterQueryInput } from '../../shared_components'; -import type { IndexPattern } from '../../types'; +import type { FormBasedLayer } from '../types'; +import { validateQuery, FilterQueryInput } from '../../../shared_components'; +import type { IndexPattern } from '../../../types'; -export function setFilter(columnId: string, layer: IndexPatternLayer, query: Query | undefined) { +export function setFilter(columnId: string, layer: FormBasedLayer, query: Query | undefined) { return { ...layer, columns: { @@ -36,8 +36,8 @@ export function Filtering({ selectedColumn: GenericIndexPatternColumn; indexPattern: IndexPattern; columnId: string; - layer: IndexPatternLayer; - updateLayer: (newLayer: IndexPatternLayer) => void; + layer: FormBasedLayer; + updateLayer: (newLayer: FormBasedLayer) => void; helpMessage: string | null; }) { const inputFilter = selectedColumn.filter; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/format_selector.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/format_selector.test.tsx similarity index 98% rename from x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/format_selector.test.tsx rename to x-pack/plugins/lens/public/datasources/form_based/dimension_panel/format_selector.test.tsx index d59cb4f136fda3..6763d6337880ba 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/format_selector.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/format_selector.test.tsx @@ -9,7 +9,7 @@ import React from 'react'; import { mount, shallow } from 'enzyme'; import { FormatSelector } from './format_selector'; import { act } from 'react-dom/test-utils'; -import { GenericIndexPatternColumn } from '../..'; +import { GenericIndexPatternColumn } from '../../..'; jest.mock('lodash', () => { const original = jest.requireActual('lodash'); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/format_selector.tsx b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/format_selector.tsx similarity index 97% rename from x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/format_selector.tsx rename to x-pack/plugins/lens/public/datasources/form_based/dimension_panel/format_selector.tsx index 280829c8c1573a..62770711a62df7 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/format_selector.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/format_selector.tsx @@ -8,9 +8,9 @@ import React, { useCallback, useMemo, useState } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiFormRow, EuiComboBox, EuiSpacer, EuiRange, EuiFieldText } from '@elastic/eui'; -import { GenericIndexPatternColumn } from '../indexpattern'; +import { GenericIndexPatternColumn } from '../form_based'; import { isColumnFormatted } from '../operations/definitions/helpers'; -import { useDebouncedValue } from '../../shared_components'; +import { useDebouncedValue } from '../../../shared_components'; const supportedFormats: Record = { number: { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/index.ts b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/index.ts similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/index.ts rename to x-pack/plugins/lens/public/datasources/form_based/dimension_panel/index.ts diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/operation_support.ts b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/operation_support.ts similarity index 91% rename from x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/operation_support.ts rename to x-pack/plugins/lens/public/datasources/form_based/dimension_panel/operation_support.ts index 43d9770deb2281..5c08b98023c749 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/operation_support.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/operation_support.ts @@ -6,10 +6,10 @@ */ import memoizeOne from 'memoize-one'; -import { DatasourceDimensionDropProps, IndexPatternMap, OperationMetadata } from '../../types'; -import { OperationType } from '../indexpattern'; +import { DatasourceDimensionDropProps, IndexPatternMap, OperationMetadata } from '../../../types'; +import { OperationType } from '../form_based'; import { memoizedGetAvailableOperationsByMetadata, OperationFieldTuple } from '../operations'; -import { IndexPatternPrivateState } from '../types'; +import { FormBasedPrivateState } from '../types'; export interface OperationSupportMatrix { operationByField: Partial>>; @@ -18,9 +18,9 @@ export interface OperationSupportMatrix { } type Props = Pick< - DatasourceDimensionDropProps['target'], + DatasourceDimensionDropProps['target'], 'layerId' | 'columnId' | 'filterOperations' -> & { state: IndexPatternPrivateState; indexPatterns: IndexPatternMap }; +> & { state: FormBasedPrivateState; indexPatterns: IndexPatternMap }; function computeOperationMatrix( operationsByMetadata: Array<{ diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/reduced_time_range.tsx b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/reduced_time_range.tsx similarity index 96% rename from x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/reduced_time_range.tsx rename to x-pack/plugins/lens/public/datasources/form_based/dimension_panel/reduced_time_range.tsx index 4d160f7923e065..6f92b8dc75c178 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/reduced_time_range.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/reduced_time_range.tsx @@ -17,13 +17,13 @@ import { GenericIndexPatternColumn, operationDefinitionMap, } from '../operations'; -import type { IndexPatternLayer } from '../types'; -import type { IndexPattern } from '../../types'; +import type { FormBasedLayer } from '../types'; +import type { IndexPattern } from '../../../types'; import { reducedTimeRangeOptions } from '../reduced_time_range_utils'; export function setReducedTimeRange( columnId: string, - layer: IndexPatternLayer, + layer: FormBasedLayer, reducedTimeRange: string | undefined, skipLabelUpdate?: boolean ) { @@ -69,8 +69,8 @@ export function ReducedTimeRange({ }: { selectedColumn: GenericIndexPatternColumn; columnId: string; - layer: IndexPatternLayer; - updateLayer: (newLayer: IndexPatternLayer) => void; + layer: FormBasedLayer; + updateLayer: (newLayer: FormBasedLayer) => void; indexPattern: IndexPattern; helpMessage: string | null; skipLabelUpdate?: boolean; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/reference_editor.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/reference_editor.test.tsx similarity index 98% rename from x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/reference_editor.test.tsx rename to x-pack/plugins/lens/public/datasources/form_based/dimension_panel/reference_editor.test.tsx index 6e5c157e5b9e8f..d46dabf6c12f35 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/reference_editor.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/reference_editor.test.tsx @@ -16,7 +16,7 @@ import { fieldFormatsServiceMock } from '@kbn/field-formats-plugin/public/mocks' import type { IUiSettingsClient, SavedObjectsClientContract, HttpSetup } from '@kbn/core/public'; import { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; -import { OperationMetadata } from '../../types'; +import { OperationMetadata } from '../../../types'; import { createMockedIndexPattern, createMockedIndexPatternWithoutType } from '../mocks'; import { ReferenceEditor, ReferenceEditorProps } from './reference_editor'; import { @@ -26,7 +26,7 @@ import { TermsIndexPatternColumn, } from '../operations'; import { FieldSelect } from './field_select'; -import { IndexPatternLayer } from '../types'; +import { FormBasedLayer } from '../types'; jest.mock('../operations'); @@ -148,7 +148,7 @@ describe('reference editor', () => { sourceField: 'bytes', }, }, - } as IndexPatternLayer; + } as FormBasedLayer; wrapper = mount( { sourceField: 'dest', }, }, - } as IndexPatternLayer; + } as FormBasedLayer; wrapper = mount( { sourceField: 'bytes', }, }, - } as IndexPatternLayer; + } as FormBasedLayer; wrapper = mount( { sourceField: 'bytes', }, }, - } as IndexPatternLayer; + } as FormBasedLayer; wrapper = mount( { sourceField: 'dest', }, }, - } as IndexPatternLayer; + } as FormBasedLayer; const onChooseFunction = jest.fn(); wrapper = mount( { sourceField: 'bytes', }, }, - } as IndexPatternLayer; + } as FormBasedLayer; wrapper = mount( { incompleteColumns: { ref: { operationType: 'max' }, }, - } as IndexPatternLayer; + } as FormBasedLayer; wrapper = mount( { incompleteColumns: { ref: { sourceField: 'timestamp' }, }, - } as IndexPatternLayer; + } as FormBasedLayer; wrapper = mount( { sourceField: 'missing', }, }, - } as IndexPatternLayer; + } as FormBasedLayer; wrapper = mount( IndexPatternLayer) + | FormBasedLayer + | ((prevLayer: FormBasedLayer) => FormBasedLayer) | GenericIndexPatternColumn ) => void; onChooseField: (choice: FieldChoiceWithOperationType) => void; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/time_scaling.tsx b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/time_scaling.tsx similarity index 91% rename from x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/time_scaling.tsx rename to x-pack/plugins/lens/public/datasources/form_based/dimension_panel/time_scaling.tsx index 791d3b5846f24f..003407649622ef 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/time_scaling.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/time_scaling.tsx @@ -20,13 +20,13 @@ import { GenericIndexPatternColumn, operationDefinitionMap, } from '../operations'; -import type { TimeScaleUnit } from '../../../common/expressions'; -import { unitSuffixesLong } from '../../../common/suffix_formatter'; -import type { IndexPatternLayer } from '../types'; +import type { TimeScaleUnit } from '../../../../common/expressions'; +import { unitSuffixesLong } from '../../../../common/suffix_formatter'; +import type { FormBasedLayer } from '../types'; export function setTimeScaling( columnId: string, - layer: IndexPatternLayer, + layer: FormBasedLayer, timeScale: TimeScaleUnit | undefined ) { const currentColumn = layer.columns[columnId]; @@ -62,8 +62,8 @@ export function TimeScaling({ }: { selectedColumn: GenericIndexPatternColumn; columnId: string; - layer: IndexPatternLayer; - updateLayer: (newLayer: IndexPatternLayer) => void; + layer: FormBasedLayer; + updateLayer: (newLayer: FormBasedLayer) => void; }) { const selectedOperation = operationDefinitionMap[selectedColumn.operationType]; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/time_shift.tsx b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/time_shift.tsx similarity index 94% rename from x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/time_shift.tsx rename to x-pack/plugins/lens/public/datasources/form_based/dimension_panel/time_shift.tsx index 63696a3a2196c1..35f278cbbe988a 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/time_shift.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/time_shift.tsx @@ -15,18 +15,18 @@ import { GenericIndexPatternColumn, operationDefinitionMap, } from '../operations'; -import type { IndexPatternLayer } from '../types'; -import type { IndexPatternDimensionEditorProps } from './dimension_panel'; +import type { FormBasedLayer } from '../types'; +import type { FormBasedDimensionEditorProps } from './dimension_panel'; import { getDateHistogramInterval, getLayerTimeShiftChecks, timeShiftOptions, } from '../time_shift_utils'; -import type { IndexPattern } from '../../types'; +import type { IndexPattern } from '../../../types'; export function setTimeShift( columnId: string, - layer: IndexPatternLayer, + layer: FormBasedLayer, timeShift: string | undefined ) { const trimmedTimeShift = timeShift?.trim(); @@ -69,9 +69,9 @@ export function TimeShift({ selectedColumn: GenericIndexPatternColumn; indexPattern: IndexPattern; columnId: string; - layer: IndexPatternLayer; - updateLayer: (newLayer: IndexPatternLayer) => void; - activeData: IndexPatternDimensionEditorProps['activeData']; + layer: FormBasedLayer; + updateLayer: (newLayer: FormBasedLayer) => void; + activeData: FormBasedDimensionEditorProps['activeData']; layerId: string; }) { const [localValue, setLocalValue] = useState(selectedColumn.timeShift); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/document_field.ts b/x-pack/plugins/lens/public/datasources/form_based/document_field.ts similarity index 86% rename from x-pack/plugins/lens/public/indexpattern_datasource/document_field.ts rename to x-pack/plugins/lens/public/datasources/form_based/document_field.ts index e6ef0fcfdc0bfe..557a087d2a6e6f 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/document_field.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/document_field.ts @@ -6,8 +6,8 @@ */ import { i18n } from '@kbn/i18n'; -import { DOCUMENT_FIELD_NAME } from '../../common'; -import type { IndexPatternField } from '../types'; +import { DOCUMENT_FIELD_NAME } from '../../../common'; +import type { IndexPatternField } from '../../types'; const customLabel = i18n.translate('xpack.lens.indexPattern.records', { defaultMessage: 'Records', diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/field_item.scss b/x-pack/plugins/lens/public/datasources/form_based/field_item.scss similarity index 97% rename from x-pack/plugins/lens/public/indexpattern_datasource/field_item.scss rename to x-pack/plugins/lens/public/datasources/form_based/field_item.scss index 873f5bdcbdf52c..5af939906b25cc 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/field_item.scss +++ b/x-pack/plugins/lens/public/datasources/form_based/field_item.scss @@ -1,4 +1,4 @@ -@import '../mixins'; +@import '../../mixins'; .lnsFieldItem { width: 100%; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/field_item.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/field_item.test.tsx similarity index 99% rename from x-pack/plugins/lens/public/indexpattern_datasource/field_item.test.tsx rename to x-pack/plugins/lens/public/datasources/form_based/field_item.test.tsx index 19b3f9e313267c..a0514dafd61b07 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/field_item.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/field_item.test.tsx @@ -15,7 +15,7 @@ import { coreMock } from '@kbn/core/public/mocks'; import { mountWithIntl } from '@kbn/test-jest-helpers'; import { findTestSubject } from '@elastic/eui/lib/test'; import { fieldFormatsServiceMock } from '@kbn/field-formats-plugin/public/mocks'; -import { IndexPattern } from '../types'; +import { IndexPattern } from '../../types'; import { chartPluginMock } from '@kbn/charts-plugin/public/mocks'; import { documentField } from './document_field'; import { uiActionsPluginMock } from '@kbn/ui-actions-plugin/public/mocks'; @@ -25,9 +25,9 @@ import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; import { DataView, DataViewField } from '@kbn/data-views-plugin/common'; import { loadFieldStats } from '@kbn/unified-field-list-plugin/public/services/field_stats'; +import { DOCUMENT_FIELD_NAME } from '../../../common'; +import { LensFieldIcon } from '../../shared_components'; import { FieldStats, FieldVisualizeButton } from '@kbn/unified-field-list-plugin/public'; -import { DOCUMENT_FIELD_NAME } from '../../common'; -import { LensFieldIcon } from '../shared_components'; jest.mock('@kbn/unified-field-list-plugin/public/services/field_stats', () => ({ loadFieldStats: jest.fn().mockResolvedValue({}), diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx b/x-pack/plugins/lens/public/datasources/form_based/field_item.tsx similarity index 95% rename from x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx rename to x-pack/plugins/lens/public/datasources/form_based/field_item.tsx index 17b1ce35f38b0b..5ebfecc4cc95a2 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/field_item.tsx @@ -26,16 +26,16 @@ import { FieldPopoverVisualize, } from '@kbn/unified-field-list-plugin/public'; import { generateFilters, getEsQueryConfig } from '@kbn/data-plugin/public'; -import { APP_ID } from '../../common/constants'; -import { DragDrop } from '../drag_drop'; -import { DatasourceDataPanelProps, DataType } from '../types'; -import { DOCUMENT_FIELD_NAME } from '../../common'; -import type { IndexPattern, IndexPatternField } from '../types'; -import { LensFieldIcon } from '../shared_components/field_picker/lens_field_icon'; -import type { LensAppServices } from '../app_plugin/types'; -import { debouncedComponent } from '../debounced_component'; +import { DragDrop } from '../../drag_drop'; +import { DatasourceDataPanelProps, DataType } from '../../types'; +import { DOCUMENT_FIELD_NAME } from '../../../common'; +import type { IndexPattern, IndexPatternField } from '../../types'; +import { LensFieldIcon } from '../../shared_components/field_picker/lens_field_icon'; +import type { LensAppServices } from '../../app_plugin/types'; +import { debouncedComponent } from '../../debounced_component'; +import { APP_ID } from '../../../common/constants'; import { getFieldType } from './pure_utils'; -import { combineQueryAndFilters } from '../app_plugin/show_underlying_data'; +import { combineQueryAndFilters } from '../../app_plugin/show_underlying_data'; export interface FieldItemProps { core: DatasourceDataPanelProps['core']; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/field_list.scss b/x-pack/plugins/lens/public/datasources/form_based/field_list.scss similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/field_list.scss rename to x-pack/plugins/lens/public/datasources/form_based/field_list.scss diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/field_list.tsx b/x-pack/plugins/lens/public/datasources/form_based/field_list.tsx similarity index 99% rename from x-pack/plugins/lens/public/indexpattern_datasource/field_list.tsx rename to x-pack/plugins/lens/public/datasources/form_based/field_list.tsx index 18da8488db212f..e2226def27a9a5 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/field_list.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/field_list.tsx @@ -13,7 +13,7 @@ import { UiActionsStart } from '@kbn/ui-actions-plugin/public'; import { FieldItem } from './field_item'; import { NoFieldsCallout } from './no_fields_callout'; import { FieldItemSharedProps, FieldsAccordion } from './fields_accordion'; -import type { DatasourceDataPanelProps, IndexPatternField } from '../types'; +import type { DatasourceDataPanelProps, IndexPatternField } from '../../types'; const PAGINATION_SIZE = 50; export type FieldGroups = Record< diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/fields_accordion.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/fields_accordion.test.tsx similarity index 98% rename from x-pack/plugins/lens/public/indexpattern_datasource/fields_accordion.test.tsx rename to x-pack/plugins/lens/public/datasources/form_based/fields_accordion.test.tsx index 864ba4ac55af9a..a471f8e0fa309b 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/fields_accordion.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/fields_accordion.test.tsx @@ -10,7 +10,7 @@ import { EuiLoadingSpinner, EuiNotificationBadge } from '@elastic/eui'; import { coreMock } from '@kbn/core/public/mocks'; import { mountWithIntl, shallowWithIntl } from '@kbn/test-jest-helpers'; import { fieldFormatsServiceMock } from '@kbn/field-formats-plugin/public/mocks'; -import { IndexPattern } from '../types'; +import { IndexPattern } from '../../types'; import { FieldItem } from './field_item'; import { FieldsAccordion, FieldsAccordionProps, FieldItemSharedProps } from './fields_accordion'; import { chartPluginMock } from '@kbn/charts-plugin/public/mocks'; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/fields_accordion.tsx b/x-pack/plugins/lens/public/datasources/form_based/fields_accordion.tsx similarity index 99% rename from x-pack/plugins/lens/public/indexpattern_datasource/fields_accordion.tsx rename to x-pack/plugins/lens/public/datasources/form_based/fields_accordion.tsx index 5db910e6d3effa..105c9583e300d5 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/fields_accordion.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/fields_accordion.tsx @@ -23,7 +23,7 @@ import type { Query } from '@kbn/es-query'; import { ChartsPluginSetup } from '@kbn/charts-plugin/public'; import { UiActionsStart } from '@kbn/ui-actions-plugin/public'; import { FieldItem } from './field_item'; -import type { DatasourceDataPanelProps, IndexPattern, IndexPatternField } from '../types'; +import type { DatasourceDataPanelProps, IndexPattern, IndexPatternField } from '../../types'; export interface FieldItemSharedProps { core: DatasourceDataPanelProps['core']; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.test.ts b/x-pack/plugins/lens/public/datasources/form_based/form_based.test.ts similarity index 93% rename from x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.test.ts rename to x-pack/plugins/lens/public/datasources/form_based/form_based.test.ts index aefb4c73274637..5a30dad2631233 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.test.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/form_based.test.ts @@ -10,7 +10,7 @@ import { SavedObjectReference } from '@kbn/core/public'; import { isFragment } from 'react-is'; import { coreMock } from '@kbn/core/public/mocks'; import { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; -import { IndexPatternPersistedState, IndexPatternPrivateState } from './types'; +import { FormBasedPersistedState, FormBasedPrivateState } from './types'; import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks'; import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; @@ -20,8 +20,8 @@ import { indexPatternFieldEditorPluginMock } from '@kbn/data-view-field-editor-p import { uiActionsPluginMock } from '@kbn/ui-actions-plugin/public/mocks'; import { fieldFormatsServiceMock } from '@kbn/field-formats-plugin/public/mocks'; import { TinymathAST } from '@kbn/tinymath'; -import { getIndexPatternDatasource, GenericIndexPatternColumn } from './indexpattern'; -import { DatasourcePublicAPI, Datasource, FramePublicAPI, OperationDescriptor } from '../types'; +import { getFormBasedDatasource, GenericIndexPatternColumn } from './form_based'; +import { DatasourcePublicAPI, Datasource, FramePublicAPI, OperationDescriptor } from '../../types'; import { getFieldByNameFactory } from './pure_helpers'; import { operationDefinitionMap, @@ -42,10 +42,10 @@ import { import { createMockedFullReference } from './operations/mocks'; import { cloneDeep } from 'lodash'; import { DatatableColumn } from '@kbn/expressions-plugin/common'; -import { createMockFramePublicAPI } from '../mocks'; +import { createMockFramePublicAPI } from '../../mocks'; jest.mock('./loader'); -jest.mock('../id_generator'); +jest.mock('../../id_generator'); jest.mock('./operations'); jest.mock('./dimension_panel/reference_editor', () => ({ ReferenceEditor: () => null, @@ -178,11 +178,11 @@ const expectedIndexPatterns = { const indexPatterns = expectedIndexPatterns; describe('IndexPattern Data Source', () => { - let baseState: IndexPatternPrivateState; - let indexPatternDatasource: Datasource; + let baseState: FormBasedPrivateState; + let FormBasedDatasource: Datasource; beforeEach(() => { - indexPatternDatasource = getIndexPatternDatasource({ + FormBasedDatasource = getFormBasedDatasource({ unifiedSearch: unifiedSearchPluginMock.createStartContract(), storage: {} as IStorageWrapper, core: coreMock.createStart(), @@ -230,7 +230,7 @@ describe('IndexPattern Data Source', () => { operationType: 'count', sourceField: '___records___', }; - const map = indexPatternDatasource.uniqueLabels({ + const map = FormBasedDatasource.uniqueLabels({ layers: { a: { columnOrder: ['a', 'b'], @@ -252,7 +252,7 @@ describe('IndexPattern Data Source', () => { indexPatternId: 'foo', }, }, - } as unknown as IndexPatternPrivateState); + } as unknown as FormBasedPrivateState); expect(map).toMatchInlineSnapshot(` Object { @@ -267,7 +267,7 @@ describe('IndexPattern Data Source', () => { describe('#getPersistedState', () => { it('should persist from saved state', async () => { - expect(indexPatternDatasource.getPersistableState(baseState)).toEqual({ + expect(FormBasedDatasource.getPersistableState(baseState)).toEqual({ state: { layers: { first: { @@ -300,12 +300,12 @@ describe('IndexPattern Data Source', () => { describe('#toExpression', () => { it('should generate an empty expression when no columns are selected', async () => { - const state = indexPatternDatasource.initialize(); - expect(indexPatternDatasource.toExpression(state, 'first', indexPatterns)).toEqual(null); + const state = FormBasedDatasource.initialize(); + expect(FormBasedDatasource.toExpression(state, 'first', indexPatterns)).toEqual(null); }); it('should create a table when there is a formula without aggs', async () => { - const queryBaseState: IndexPatternPrivateState = { + const queryBaseState: FormBasedPrivateState = { currentIndexPatternId: '1', layers: { first: { @@ -324,7 +324,7 @@ describe('IndexPattern Data Source', () => { }, }, }; - expect(indexPatternDatasource.toExpression(queryBaseState, 'first', indexPatterns)).toEqual({ + expect(FormBasedDatasource.toExpression(queryBaseState, 'first', indexPatterns)).toEqual({ chain: [ { function: 'createTable', @@ -342,7 +342,7 @@ describe('IndexPattern Data Source', () => { }); it('should generate an expression for an aggregated query', async () => { - const queryBaseState: IndexPatternPrivateState = { + const queryBaseState: FormBasedPrivateState = { currentIndexPatternId: '1', layers: { first: { @@ -371,7 +371,7 @@ describe('IndexPattern Data Source', () => { }, }; - expect(indexPatternDatasource.toExpression(queryBaseState, 'first', indexPatterns)) + expect(FormBasedDatasource.toExpression(queryBaseState, 'first', indexPatterns)) .toMatchInlineSnapshot(` Object { "chain": Array [ @@ -496,7 +496,7 @@ describe('IndexPattern Data Source', () => { }); it('should put all time fields used in date_histograms to the esaggs timeFields parameter if not ignoring global time range', async () => { - const queryBaseState: IndexPatternPrivateState = { + const queryBaseState: FormBasedPrivateState = { currentIndexPatternId: '1', layers: { first: { @@ -546,16 +546,12 @@ describe('IndexPattern Data Source', () => { }, }; - const ast = indexPatternDatasource.toExpression( - queryBaseState, - 'first', - indexPatterns - ) as Ast; + const ast = FormBasedDatasource.toExpression(queryBaseState, 'first', indexPatterns) as Ast; expect(ast.chain[1].arguments.timeFields).toEqual(['timestamp', 'another_datefield']); }); it('should pass time shift parameter to metric agg functions', async () => { - const queryBaseState: IndexPatternPrivateState = { + const queryBaseState: FormBasedPrivateState = { currentIndexPatternId: '1', layers: { first: { @@ -585,11 +581,7 @@ describe('IndexPattern Data Source', () => { }, }; - const ast = indexPatternDatasource.toExpression( - queryBaseState, - 'first', - indexPatterns - ) as Ast; + const ast = FormBasedDatasource.toExpression(queryBaseState, 'first', indexPatterns) as Ast; expect((ast.chain[1].arguments.aggs[1] as Ast).chain[0].arguments.timeShift).toEqual(['1d']); }); @@ -609,7 +601,7 @@ describe('IndexPattern Data Source', () => { * The sum has its own shift and does not respected the shift from the moving average * The differences has a filter which is inherited to the median, but not the average as it has its own filter */ - const queryBaseState: IndexPatternPrivateState = { + const queryBaseState: FormBasedPrivateState = { currentIndexPatternId: '1', layers: { first: { @@ -796,11 +788,7 @@ describe('IndexPattern Data Source', () => { }, }; - const ast = indexPatternDatasource.toExpression( - queryBaseState, - 'first', - indexPatterns - ) as Ast; + const ast = FormBasedDatasource.toExpression(queryBaseState, 'first', indexPatterns) as Ast; const count = (ast.chain[1].arguments.aggs[1] as Ast).chain[0]; const sum = (ast.chain[1].arguments.aggs[2] as Ast).chain[0]; const average = (ast.chain[1].arguments.aggs[3] as Ast).chain[0]; @@ -822,7 +810,7 @@ describe('IndexPattern Data Source', () => { }); it('should wrap filtered metrics in filtered metric aggregation', async () => { - const queryBaseState: IndexPatternPrivateState = { + const queryBaseState: FormBasedPrivateState = { currentIndexPatternId: '1', layers: { first: { @@ -864,11 +852,7 @@ describe('IndexPattern Data Source', () => { }, }; - const ast = indexPatternDatasource.toExpression( - queryBaseState, - 'first', - indexPatterns - ) as Ast; + const ast = FormBasedDatasource.toExpression(queryBaseState, 'first', indexPatterns) as Ast; expect(ast.chain[1].arguments.aggs[0]).toMatchInlineSnapshot(` Object { "chain": Array [ @@ -954,7 +938,7 @@ describe('IndexPattern Data Source', () => { }); it('should add time_scale and format function if time scale is set and supported', async () => { - const queryBaseState: IndexPatternPrivateState = { + const queryBaseState: FormBasedPrivateState = { currentIndexPatternId: '1', layers: { first: { @@ -992,11 +976,7 @@ describe('IndexPattern Data Source', () => { }, }; - const ast = indexPatternDatasource.toExpression( - queryBaseState, - 'first', - indexPatterns - ) as Ast; + const ast = FormBasedDatasource.toExpression(queryBaseState, 'first', indexPatterns) as Ast; const timeScaleCalls = ast.chain.filter((fn) => fn.function === 'lens_time_scale'); const formatCalls = ast.chain.filter((fn) => fn.function === 'lens_format_column'); expect(timeScaleCalls).toHaveLength(1); @@ -1040,7 +1020,7 @@ describe('IndexPattern Data Source', () => { }); it('should not add time shift to nested count metric', async () => { - const queryBaseState: IndexPatternPrivateState = { + const queryBaseState: FormBasedPrivateState = { currentIndexPatternId: '1', layers: { first: { @@ -1061,11 +1041,7 @@ describe('IndexPattern Data Source', () => { }, }; - const ast = indexPatternDatasource.toExpression( - queryBaseState, - 'first', - indexPatterns - ) as Ast; + const ast = FormBasedDatasource.toExpression(queryBaseState, 'first', indexPatterns) as Ast; const filteredMetricAgg = (ast.chain[1].arguments.aggs[0] as Ast).chain[0].arguments; const metricAgg = (filteredMetricAgg.customMetric[0] as Ast).chain[0].arguments; const bucketAgg = (filteredMetricAgg.customBucket[0] as Ast).chain[0].arguments; @@ -1076,7 +1052,7 @@ describe('IndexPattern Data Source', () => { }); it('should put column formatters after calculated columns', async () => { - const queryBaseState: IndexPatternPrivateState = { + const queryBaseState: FormBasedPrivateState = { currentIndexPatternId: '1', layers: { first: { @@ -1116,18 +1092,14 @@ describe('IndexPattern Data Source', () => { }, }; - const ast = indexPatternDatasource.toExpression( - queryBaseState, - 'first', - indexPatterns - ) as Ast; + const ast = FormBasedDatasource.toExpression(queryBaseState, 'first', indexPatterns) as Ast; const formatIndex = ast.chain.findIndex((fn) => fn.function === 'lens_format_column'); const calculationIndex = ast.chain.findIndex((fn) => fn.function === 'moving_average'); expect(calculationIndex).toBeLessThan(formatIndex); }); it('should rename the output from esaggs when using flat query', () => { - const queryBaseState: IndexPatternPrivateState = { + const queryBaseState: FormBasedPrivateState = { currentIndexPatternId: '1', layers: { first: { @@ -1168,11 +1140,7 @@ describe('IndexPattern Data Source', () => { }, }; - const ast = indexPatternDatasource.toExpression( - queryBaseState, - 'first', - indexPatterns - ) as Ast; + const ast = FormBasedDatasource.toExpression(queryBaseState, 'first', indexPatterns) as Ast; expect(ast.chain[1].arguments.metricsAtAllLevels).toEqual([false]); expect(JSON.parse(ast.chain[2].arguments.idMap[0] as string)).toEqual({ 'col-0-0': [expect.objectContaining({ id: 'bucket1' })], @@ -1182,7 +1150,7 @@ describe('IndexPattern Data Source', () => { }); it('should not put date fields used outside date_histograms to the esaggs timeFields parameter', async () => { - const queryBaseState: IndexPatternPrivateState = { + const queryBaseState: FormBasedPrivateState = { currentIndexPatternId: '1', layers: { first: { @@ -1211,18 +1179,14 @@ describe('IndexPattern Data Source', () => { }, }; - const ast = indexPatternDatasource.toExpression( - queryBaseState, - 'first', - indexPatterns - ) as Ast; + const ast = FormBasedDatasource.toExpression(queryBaseState, 'first', indexPatterns) as Ast; expect(ast.chain[1].arguments.timeFields).toEqual(['timestamp']); expect(ast.chain[1].arguments.timeFields).not.toContain('timefield'); }); describe('optimizations', () => { it('should call optimizeEsAggs once per operation for which it is available', () => { - const queryBaseState: IndexPatternPrivateState = { + const queryBaseState: FormBasedPrivateState = { currentIndexPatternId: '1', layers: { first: { @@ -1272,7 +1236,7 @@ describe('IndexPattern Data Source', () => { const optimizeMock = jest.spyOn(operationDefinitionMap.percentile, 'optimizeEsAggs'); - indexPatternDatasource.toExpression(queryBaseState, 'first', indexPatterns); + FormBasedDatasource.toExpression(queryBaseState, 'first', indexPatterns); expect(operationDefinitionMap.percentile.optimizeEsAggs).toHaveBeenCalledTimes(1); @@ -1280,7 +1244,7 @@ describe('IndexPattern Data Source', () => { }); it('should update anticipated esAggs column IDs based on the order of the optimized agg expression builders', () => { - const queryBaseState: IndexPatternPrivateState = { + const queryBaseState: FormBasedPrivateState = { currentIndexPatternId: '1', layers: { first: { @@ -1340,11 +1304,7 @@ describe('IndexPattern Data Source', () => { return { aggs: aggs.reverse(), esAggsIdMap }; }); - const ast = indexPatternDatasource.toExpression( - queryBaseState, - 'first', - indexPatterns - ) as Ast; + const ast = FormBasedDatasource.toExpression(queryBaseState, 'first', indexPatterns) as Ast; expect(operationDefinitionMap.percentile.optimizeEsAggs).toHaveBeenCalledTimes(1); @@ -1356,7 +1316,7 @@ describe('IndexPattern Data Source', () => { }); it('should deduplicate aggs for supported operations', () => { - const queryBaseState: IndexPatternPrivateState = { + const queryBaseState: FormBasedPrivateState = { currentIndexPatternId: '1', layers: { first: { @@ -1408,11 +1368,7 @@ describe('IndexPattern Data Source', () => { }, }; - const ast = indexPatternDatasource.toExpression( - queryBaseState, - 'first', - indexPatterns - ) as Ast; + const ast = FormBasedDatasource.toExpression(queryBaseState, 'first', indexPatterns) as Ast; const idMap = JSON.parse(ast.chain[2].arguments.idMap as unknown as string); @@ -1491,7 +1447,7 @@ describe('IndexPattern Data Source', () => { }); it('should collect expression references and append them', async () => { - const queryBaseState: IndexPatternPrivateState = { + const queryBaseState: FormBasedPrivateState = { currentIndexPatternId: '1', layers: { first: { @@ -1517,18 +1473,14 @@ describe('IndexPattern Data Source', () => { }, }; - const ast = indexPatternDatasource.toExpression( - queryBaseState, - 'first', - indexPatterns - ) as Ast; + const ast = FormBasedDatasource.toExpression(queryBaseState, 'first', indexPatterns) as Ast; // @ts-expect-error we can't isolate just the reference type expect(operationDefinitionMap.testReference.toExpression).toHaveBeenCalled(); expect(ast.chain[3]).toEqual('mock'); }); it('should keep correct column mapping keys with reference columns present', async () => { - const queryBaseState: IndexPatternPrivateState = { + const queryBaseState: FormBasedPrivateState = { currentIndexPatternId: '1', layers: { first: { @@ -1554,11 +1506,7 @@ describe('IndexPattern Data Source', () => { }, }; - const ast = indexPatternDatasource.toExpression( - queryBaseState, - 'first', - indexPatterns - ) as Ast; + const ast = FormBasedDatasource.toExpression(queryBaseState, 'first', indexPatterns) as Ast; expect(JSON.parse(ast.chain[2].arguments.idMap[0] as string)).toEqual({ 'col-0-0': [ @@ -1571,7 +1519,7 @@ describe('IndexPattern Data Source', () => { it('should topologically sort references', () => { // This is a real example of count() + count() - const queryBaseState: IndexPatternPrivateState = { + const queryBaseState: FormBasedPrivateState = { currentIndexPatternId: '1', layers: { first: { @@ -1645,11 +1593,7 @@ describe('IndexPattern Data Source', () => { }, }; - const ast = indexPatternDatasource.toExpression( - queryBaseState, - 'first', - indexPatterns - ) as Ast; + const ast = FormBasedDatasource.toExpression(queryBaseState, 'first', indexPatterns) as Ast; const chainLength = ast.chain.length; expect(ast.chain[chainLength - 2].arguments.name).toEqual(['math']); expect(ast.chain[chainLength - 1].arguments.id).toEqual(['formula']); @@ -1674,7 +1618,7 @@ describe('IndexPattern Data Source', () => { }, currentIndexPatternId: '1', }; - expect(indexPatternDatasource.insertLayer(state, 'newLayer')).toEqual({ + expect(FormBasedDatasource.insertLayer(state, 'newLayer')).toEqual({ ...state, layers: { ...state.layers, @@ -1705,7 +1649,7 @@ describe('IndexPattern Data Source', () => { }, currentIndexPatternId: '1', }; - expect(indexPatternDatasource.removeLayer(state, 'first')).toEqual({ + expect(FormBasedDatasource.removeLayer(state, 'first')).toEqual({ ...state, layers: { second: { @@ -1720,7 +1664,7 @@ describe('IndexPattern Data Source', () => { describe('#createEmptyLayer', () => { it('creates state with empty layers', () => { - expect(indexPatternDatasource.createEmptyLayer('index-pattern-id')).toEqual({ + expect(FormBasedDatasource.createEmptyLayer('index-pattern-id')).toEqual({ currentIndexPatternId: 'index-pattern-id', layers: {}, }); @@ -1730,7 +1674,7 @@ describe('IndexPattern Data Source', () => { describe('#getLayers', () => { it('should list the current layers', () => { expect( - indexPatternDatasource.getLayers({ + FormBasedDatasource.getLayers({ layers: { first: { indexPatternId: '1', @@ -1753,7 +1697,7 @@ describe('IndexPattern Data Source', () => { let publicAPI: DatasourcePublicAPI; beforeEach(async () => { - publicAPI = indexPatternDatasource.getPublicAPI({ + publicAPI = FormBasedDatasource.getPublicAPI({ state: baseState, layerId: 'first', indexPatterns, @@ -1770,7 +1714,7 @@ describe('IndexPattern Data Source', () => { }); it('should skip columns that are being referenced', () => { - publicAPI = indexPatternDatasource.getPublicAPI({ + publicAPI = FormBasedDatasource.getPublicAPI({ state: { ...baseState, layers: { @@ -1808,7 +1752,7 @@ describe('IndexPattern Data Source', () => { }); it('should collect all fields (also from referenced columns)', () => { - publicAPI = indexPatternDatasource.getPublicAPI({ + publicAPI = FormBasedDatasource.getPublicAPI({ state: { ...baseState, layers: { @@ -1847,7 +1791,7 @@ describe('IndexPattern Data Source', () => { }); it('should collect and organize fields per visible column', () => { - publicAPI = indexPatternDatasource.getPublicAPI({ + publicAPI = FormBasedDatasource.getPublicAPI({ state: { ...baseState, layers: { @@ -1917,7 +1861,7 @@ describe('IndexPattern Data Source', () => { }); it('should return null for referenced columns', () => { - publicAPI = indexPatternDatasource.getPublicAPI({ + publicAPI = FormBasedDatasource.getPublicAPI({ state: { ...baseState, layers: { @@ -1962,7 +1906,7 @@ describe('IndexPattern Data Source', () => { describe('getFilters', () => { it('should return all filters in metrics, grouped by language', () => { - publicAPI = indexPatternDatasource.getPublicAPI({ + publicAPI = FormBasedDatasource.getPublicAPI({ state: { ...baseState, layers: { @@ -2004,7 +1948,7 @@ describe('IndexPattern Data Source', () => { }); }); it('should ignore empty filtered metrics', () => { - publicAPI = indexPatternDatasource.getPublicAPI({ + publicAPI = FormBasedDatasource.getPublicAPI({ state: { ...baseState, layers: { @@ -2034,7 +1978,7 @@ describe('IndexPattern Data Source', () => { }); }); it('shuold collect top values fields as kuery existence filters if no data is provided', () => { - publicAPI = indexPatternDatasource.getPublicAPI({ + publicAPI = FormBasedDatasource.getPublicAPI({ state: { ...baseState, layers: { @@ -2089,7 +2033,7 @@ describe('IndexPattern Data Source', () => { }); }); it('shuold collect top values fields and terms as kuery filters if data is provided', () => { - publicAPI = indexPatternDatasource.getPublicAPI({ + publicAPI = FormBasedDatasource.getPublicAPI({ state: { ...baseState, layers: { @@ -2160,7 +2104,7 @@ describe('IndexPattern Data Source', () => { }); }); it('shuold collect top values fields and terms and carefully handle empty string values', () => { - publicAPI = indexPatternDatasource.getPublicAPI({ + publicAPI = FormBasedDatasource.getPublicAPI({ state: { ...baseState, layers: { @@ -2231,7 +2175,7 @@ describe('IndexPattern Data Source', () => { }); }); it('should ignore top values fields if other/missing option is enabled', () => { - publicAPI = indexPatternDatasource.getPublicAPI({ + publicAPI = FormBasedDatasource.getPublicAPI({ state: { ...baseState, layers: { @@ -2278,7 +2222,7 @@ describe('IndexPattern Data Source', () => { }); }); it('should collect custom ranges as kuery filters', () => { - publicAPI = indexPatternDatasource.getPublicAPI({ + publicAPI = FormBasedDatasource.getPublicAPI({ state: { ...baseState, layers: { @@ -2333,7 +2277,7 @@ describe('IndexPattern Data Source', () => { }); }); it('should collect custom ranges as kuery filters as partial', () => { - publicAPI = indexPatternDatasource.getPublicAPI({ + publicAPI = FormBasedDatasource.getPublicAPI({ state: { ...baseState, layers: { @@ -2393,7 +2337,7 @@ describe('IndexPattern Data Source', () => { }); }); it('should collect filters within filters operation grouped by language', () => { - publicAPI = indexPatternDatasource.getPublicAPI({ + publicAPI = FormBasedDatasource.getPublicAPI({ state: { ...baseState, layers: { @@ -2464,7 +2408,7 @@ describe('IndexPattern Data Source', () => { }); }); it('should ignore filtered metrics if at least one metric is unfiltered', () => { - publicAPI = indexPatternDatasource.getPublicAPI({ + publicAPI = FormBasedDatasource.getPublicAPI({ state: { ...baseState, layers: { @@ -2502,7 +2446,7 @@ describe('IndexPattern Data Source', () => { }); }); it('should ignore filtered metrics if at least one metric is unfiltered in formula', () => { - publicAPI = indexPatternDatasource.getPublicAPI({ + publicAPI = FormBasedDatasource.getPublicAPI({ state: { ...baseState, layers: { @@ -2575,7 +2519,7 @@ describe('IndexPattern Data Source', () => { }); }); it('should support complete scenarios', () => { - publicAPI = indexPatternDatasource.getPublicAPI({ + publicAPI = FormBasedDatasource.getPublicAPI({ state: { ...baseState, layers: { @@ -2662,7 +2606,7 @@ describe('IndexPattern Data Source', () => { }); it('should avoid duplicate filters when formula has a global filter', () => { - publicAPI = indexPatternDatasource.getPublicAPI({ + publicAPI = FormBasedDatasource.getPublicAPI({ state: { ...baseState, layers: { @@ -2770,7 +2714,7 @@ describe('IndexPattern Data Source', () => { it('should use the results of getErrorMessages directly when single layer', () => { (getErrorMessages as jest.Mock).mockClear(); (getErrorMessages as jest.Mock).mockReturnValueOnce(['error 1', 'error 2']); - const state: IndexPatternPrivateState = { + const state: FormBasedPrivateState = { layers: { first: { indexPatternId: '1', @@ -2780,7 +2724,7 @@ describe('IndexPattern Data Source', () => { }, currentIndexPatternId: '1', }; - expect(indexPatternDatasource.getErrorMessages(state, indexPatterns)).toEqual([ + expect(FormBasedDatasource.getErrorMessages(state, indexPatterns)).toEqual([ { longMessage: 'error 1', shortMessage: '' }, { longMessage: 'error 2', shortMessage: '' }, ]); @@ -2790,7 +2734,7 @@ describe('IndexPattern Data Source', () => { it('should prepend each error with its layer number on multi-layer chart', () => { (getErrorMessages as jest.Mock).mockClear(); (getErrorMessages as jest.Mock).mockReturnValueOnce(['error 1', 'error 2']); - const state: IndexPatternPrivateState = { + const state: FormBasedPrivateState = { layers: { first: { indexPatternId: '1', @@ -2805,7 +2749,7 @@ describe('IndexPattern Data Source', () => { }, currentIndexPatternId: '1', }; - expect(indexPatternDatasource.getErrorMessages(state, indexPatterns)).toEqual([ + expect(FormBasedDatasource.getErrorMessages(state, indexPatterns)).toEqual([ { longMessage: 'Layer 1 error: error 1', shortMessage: '' }, { longMessage: 'Layer 1 error: error 2', shortMessage: '' }, ]); @@ -2814,7 +2758,7 @@ describe('IndexPattern Data Source', () => { }); describe('#getWarningMessages', () => { - let state: IndexPatternPrivateState; + let state: FormBasedPrivateState; let framePublicAPI: FramePublicAPI; beforeEach(() => { @@ -2948,12 +2892,7 @@ describe('IndexPattern Data Source', () => { ); it('should return mismatched time shifts', () => { - const warnings = indexPatternDatasource.getWarningMessages!( - state, - framePublicAPI, - {}, - () => {} - ); + const warnings = FormBasedDatasource.getWarningMessages!(state, framePublicAPI, {}, () => {}); expect(extractTranslationIdsFromWarnings(warnings)).toMatchInlineSnapshot(` Array [ @@ -2966,12 +2905,7 @@ describe('IndexPattern Data Source', () => { it('should show different types of warning messages', () => { framePublicAPI.activeData!.first.columns[1].meta.sourceParams!.hasPrecisionError = true; - const warnings = indexPatternDatasource.getWarningMessages!( - state, - framePublicAPI, - {}, - () => {} - ); + const warnings = FormBasedDatasource.getWarningMessages!(state, framePublicAPI, {}, () => {}); expect(extractTranslationIdsFromWarnings(warnings)).toMatchInlineSnapshot(` Array [ @@ -3002,7 +2936,7 @@ describe('IndexPattern Data Source', () => { currentIndexPatternId: '1', }; - expect(indexPatternDatasource.getErrorMessages(state, indexPatterns)).toEqual([ + expect(FormBasedDatasource.getErrorMessages(state, indexPatterns)).toEqual([ { longMessage: 'Layer 1 error: error 1', shortMessage: '' }, { longMessage: 'Layer 1 error: error 2', shortMessage: '' }, ]); @@ -3013,7 +2947,7 @@ describe('IndexPattern Data Source', () => { describe('#updateStateOnCloseDimension', () => { it('should not update when there are no incomplete columns', () => { expect( - indexPatternDatasource.updateStateOnCloseDimension!({ + FormBasedDatasource.updateStateOnCloseDimension!({ state: { layers: { first: { @@ -3055,7 +2989,7 @@ describe('IndexPattern Data Source', () => { currentIndexPatternId: '1', }; expect( - indexPatternDatasource.updateStateOnCloseDimension!({ + FormBasedDatasource.updateStateOnCloseDimension!({ state, layerId: 'first', columnId: 'col1', @@ -3127,9 +3061,9 @@ describe('IndexPattern Data Source', () => { }, }, }, - } as IndexPatternPrivateState; + } as FormBasedPrivateState; expect( - indexPatternDatasource.isTimeBased(state, { + FormBasedDatasource.isTimeBased(state, { ...indexPatterns, '1': { ...indexPatterns['1'], timeFieldName: undefined }, }) @@ -3189,9 +3123,9 @@ describe('IndexPattern Data Source', () => { }, }, }, - } as IndexPatternPrivateState; + } as FormBasedPrivateState; expect( - indexPatternDatasource.isTimeBased(state, { + FormBasedDatasource.isTimeBased(state, { ...indexPatterns, '1': { ...indexPatterns['1'], timeFieldName: undefined }, }) @@ -3215,9 +3149,9 @@ describe('IndexPattern Data Source', () => { }, }, }, - } as IndexPatternPrivateState; + } as FormBasedPrivateState; expect( - indexPatternDatasource.isTimeBased(state, { + FormBasedDatasource.isTimeBased(state, { ...indexPatterns, '1': { ...indexPatterns['1'], timeFieldName: undefined }, }) @@ -3241,8 +3175,8 @@ describe('IndexPattern Data Source', () => { }, }, }, - } as IndexPatternPrivateState; - expect(indexPatternDatasource.isTimeBased(state, indexPatterns)).toEqual(true); + } as FormBasedPrivateState; + expect(FormBasedDatasource.isTimeBased(state, indexPatterns)).toEqual(true); }); }); @@ -3265,9 +3199,9 @@ describe('IndexPattern Data Source', () => { }, }, }, - } as IndexPatternPrivateState; + } as FormBasedPrivateState; expect( - indexPatternDatasource.initializeDimension!(state, 'first', indexPatterns, { + FormBasedDatasource.initializeDimension!(state, 'first', indexPatterns, { columnId: 'newStatic', groupId: 'a', }) @@ -3292,9 +3226,9 @@ describe('IndexPattern Data Source', () => { }, }, }, - } as IndexPatternPrivateState; + } as FormBasedPrivateState; expect( - indexPatternDatasource.initializeDimension!(state, 'first', indexPatterns, { + FormBasedDatasource.initializeDimension!(state, 'first', indexPatterns, { columnId: 'newStatic', groupId: 'a', staticValue: 0, // use a falsy value to check also this corner case @@ -3329,7 +3263,7 @@ describe('IndexPattern Data Source', () => { describe('#isEqual', () => { const layerId = '8bd66b66-aba3-49fb-9ff2-4bf83f2be08e'; - const persistableState: IndexPatternPersistedState = { + const persistableState: FormBasedPersistedState = { layers: { [layerId]: { columns: { @@ -3366,7 +3300,7 @@ describe('IndexPattern Data Source', () => { it('should be false if datasource states are using different data views', () => { expect( - indexPatternDatasource.isEqual(persistableState, references1, persistableState, references2) + FormBasedDatasource.isEqual(persistableState, references1, persistableState, references2) ).toBe(false); }); @@ -3375,7 +3309,7 @@ describe('IndexPattern Data Source', () => { differentPersistableState.layers[layerId].columnOrder = ['something else']; expect( - indexPatternDatasource.isEqual( + FormBasedDatasource.isEqual( persistableState, references1, differentPersistableState, @@ -3386,7 +3320,7 @@ describe('IndexPattern Data Source', () => { it('should be true if datasource states are identical and they refer to the same data view', () => { expect( - indexPatternDatasource.isEqual(persistableState, references1, persistableState, references1) + FormBasedDatasource.isEqual(persistableState, references1, persistableState, references1) ).toBe(true); }); }); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.tsx b/x-pack/plugins/lens/public/datasources/form_based/form_based.tsx similarity index 90% rename from x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.tsx rename to x-pack/plugins/lens/public/datasources/form_based/form_based.tsx index fb31c3c1a9a713..984ce87dfefafc 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/form_based.tsx @@ -36,7 +36,7 @@ import type { IndexPatternField, IndexPattern, IndexPatternRef, -} from '../types'; +} from '../../types'; import { changeIndexPattern, changeLayerIndexPattern, @@ -49,18 +49,18 @@ import { } from './loader'; import { toExpression } from './to_expression'; import { - IndexPatternDimensionTrigger, - IndexPatternDimensionEditor, + FormBasedDimensionTrigger, + FormBasedDimensionEditor, getDropProps, onDrop, } from './dimension_panel'; -import { IndexPatternDataPanel } from './datapanel'; +import { FormBasedDataPanel } from './datapanel'; import { getDatasourceSuggestionsForField, getDatasourceSuggestionsFromCurrentState, getDatasourceSuggestionsForVisualizeField, getDatasourceSuggestionsForVisualizeCharts, -} from './indexpattern_suggestions'; +} from './form_based_suggestions'; import { getFiltersInLayer, @@ -69,7 +69,7 @@ import { isColumnInvalid, cloneLayer, } from './utils'; -import { isDraggedDataViewField } from '../utils'; +import { isDraggedDataViewField } from '../../utils'; import { normalizeOperationDataType } from './pure_utils'; import { LayerPanel } from './layerpanel'; import { @@ -81,15 +81,15 @@ import { TermsIndexPatternColumn, } from './operations'; import { getReferenceRoot } from './operations/layer_helpers'; -import { IndexPatternPrivateState, IndexPatternPersistedState } from './types'; +import { FormBasedPrivateState, FormBasedPersistedState } from './types'; import { mergeLayer } from './state_helpers'; -import { Datasource, VisualizeEditorContext } from '../types'; +import { Datasource, VisualizeEditorContext } from '../../types'; import { deleteColumn, isReferenced } from './operations'; -import { GeoFieldWorkspacePanel } from '../editor_frame_service/editor_frame/workspace_panel/geo_field_workspace_panel'; -import { DraggingIdentifier } from '../drag_drop'; +import { GeoFieldWorkspacePanel } from '../../editor_frame_service/editor_frame/workspace_panel/geo_field_workspace_panel'; +import { DraggingIdentifier } from '../../drag_drop'; import { getStateTimeShiftWarningMessages } from './time_shift_utils'; import { getPrecisionErrorWarningMessages } from './utils'; -import { DOCUMENT_FIELD_NAME } from '../../common/constants'; +import { DOCUMENT_FIELD_NAME } from '../../../common/constants'; import { isColumnOfType } from './operations/definitions/helpers'; export type { OperationType, GenericIndexPatternColumn } from './operations'; export { deleteColumn } from './operations'; @@ -119,15 +119,15 @@ export function columnToOperation( }; } -export type { FormatColumnArgs, TimeScaleArgs, CounterRateArgs } from '../../common/expressions'; +export type { FormatColumnArgs, TimeScaleArgs, CounterRateArgs } from '../../../common/expressions'; export { getSuffixFormatter, unitSuffixesLong, suffixFormatterId, -} from '../../common/suffix_formatter'; +} from '../../../common/suffix_formatter'; -export function getIndexPatternDatasource({ +export function getFormBasedDatasource({ core, storage, data, @@ -152,14 +152,14 @@ export function getIndexPatternDatasource({ }) { const uiSettings = core.uiSettings; - const DATASOURCE_ID = 'indexpattern'; + const DATASOURCE_ID = 'formBased'; // Not stateful. State is persisted to the frame - const indexPatternDatasource: Datasource = { + const formBasedDatasource: Datasource = { id: DATASOURCE_ID, initialize( - persistedState?: IndexPatternPersistedState, + persistedState?: FormBasedPersistedState, references?: SavedObjectReference[], initialContext?: VisualizeFieldContext | VisualizeEditorContext, indexPatternRefs?: IndexPatternRef[], @@ -176,11 +176,11 @@ export function getIndexPatternDatasource({ }); }, - getPersistableState(state: IndexPatternPrivateState) { + getPersistableState(state: FormBasedPrivateState) { return extractReferences(state); }, - insertLayer(state: IndexPatternPrivateState, newLayerId: string) { + insertLayer(state: FormBasedPrivateState, newLayerId: string) { return { ...state, layers: { @@ -204,7 +204,7 @@ export function getIndexPatternDatasource({ }; }, - removeLayer(state: IndexPatternPrivateState, layerId: string) { + removeLayer(state: FormBasedPrivateState, layerId: string) { const newLayers = { ...state.layers }; delete newLayers[layerId]; @@ -214,7 +214,7 @@ export function getIndexPatternDatasource({ }; }, - clearLayer(state: IndexPatternPrivateState, layerId: string) { + clearLayer(state: FormBasedPrivateState, layerId: string) { return { ...state, layers: { @@ -224,7 +224,7 @@ export function getIndexPatternDatasource({ }; }, - getLayers(state: IndexPatternPrivateState) { + getLayers(state: FormBasedPrivateState) { return Object.keys(state?.layers); }, @@ -266,10 +266,7 @@ export function getIndexPatternDatasource({ toExpression: (state, layerId, indexPatterns) => toExpression(state, layerId, indexPatterns, uiSettings), - renderDataPanel( - domElement: Element, - props: DatasourceDataPanelProps - ) { + renderDataPanel(domElement: Element, props: DatasourceDataPanelProps) { const { onChangeIndexPattern, ...otherProps } = props; render( @@ -285,7 +282,7 @@ export function getIndexPatternDatasource({ discover, }} > - ; const counts = {} as Record; @@ -342,9 +339,9 @@ export function getIndexPatternDatasource({ renderDimensionTrigger: ( domElement: Element, - props: DatasourceDimensionTriggerProps + props: DatasourceDimensionTriggerProps ) => { - const columnLabelMap = indexPatternDatasource.uniqueLabels(props.state); + const columnLabelMap = formBasedDatasource.uniqueLabels(props.state); render( @@ -361,10 +358,7 @@ export function getIndexPatternDatasource({ unifiedSearch, }} > - + , @@ -374,9 +368,9 @@ export function getIndexPatternDatasource({ renderDimensionEditor: ( domElement: Element, - props: DatasourceDimensionEditorProps + props: DatasourceDimensionEditorProps ) => { - const columnLabelMap = indexPatternDatasource.uniqueLabels(props.state); + const columnLabelMap = formBasedDatasource.uniqueLabels(props.state); render( @@ -394,7 +388,7 @@ export function getIndexPatternDatasource({ unifiedSearch, }} > - + props: DatasourceLayerPanelProps ) => { const { onChangeIndexPattern, ...otherProps } = props; render( @@ -445,7 +439,7 @@ export function getIndexPatternDatasource({ onDrop, getCustomWorkspaceRenderer: ( - state: IndexPatternPrivateState, + state: FormBasedPrivateState, dragging: DraggingIdentifier, indexPatterns: Record ) => { @@ -501,7 +495,7 @@ export function getIndexPatternDatasource({ onIndexPatternRename: (state, oldIndexPatternId, newIndexPatternId) => { return renameIndexPattern({ state, oldIndexPatternId, newIndexPatternId }); }, - getRenderEventCounters(state: IndexPatternPrivateState): string[] { + getRenderEventCounters(state: FormBasedPrivateState): string[] { const additionalEvents = { time_shift: false, filter: false, @@ -545,8 +539,8 @@ export function getIndexPatternDatasource({ }); }, - getPublicAPI({ state, layerId, indexPatterns }: PublicAPIProps) { - const columnLabelMap = indexPatternDatasource.uniqueLabels(state); + getPublicAPI({ state, layerId, indexPatterns }: PublicAPIProps) { + const columnLabelMap = formBasedDatasource.uniqueLabels(state); const layer = state.layers[layerId]; const visibleColumnIds = layer.columnOrder.filter((colId) => !isReferenced(layer, colId)); @@ -766,16 +760,16 @@ export function getIndexPatternDatasource({ ); }, isEqual: ( - persistableState1: IndexPatternPersistedState, + persistableState1: FormBasedPersistedState, references1: SavedObjectReference[], - persistableState2: IndexPatternPersistedState, + persistableState2: FormBasedPersistedState, references2: SavedObjectReference[] ) => isEqual( injectReferences(persistableState1, references1), injectReferences(persistableState2, references2) ), - getUsedDataView: (state: IndexPatternPrivateState, layerId?: string) => { + getUsedDataView: (state: FormBasedPrivateState, layerId?: string) => { if (!layerId) { return state.currentIndexPatternId; } @@ -786,7 +780,7 @@ export function getIndexPatternDatasource({ }, }; - return indexPatternDatasource; + return formBasedDatasource; } function blankLayer(indexPatternId: string) { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/form_based_suggestions.test.tsx similarity index 98% rename from x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.test.tsx rename to x-pack/plugins/lens/public/datasources/form_based/form_based_suggestions.test.tsx index 382c11bda545a7..d7a544a723e04f 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/form_based_suggestions.test.tsx @@ -12,16 +12,16 @@ import type { StaticValueColumn, CountColumn, } from '@kbn/visualizations-plugin/common/convert_to_lens'; -import { DatasourceSuggestion } from '../types'; -import { generateId } from '../id_generator'; -import type { IndexPatternPrivateState } from './types'; +import { DatasourceSuggestion } from '../../types'; +import { generateId } from '../../id_generator'; +import type { FormBasedPrivateState } from './types'; import { getDatasourceSuggestionsForField, getDatasourceSuggestionsFromCurrentState, getDatasourceSuggestionsForVisualizeField, getDatasourceSuggestionsForVisualizeCharts, IndexPatternSuggestion, -} from './indexpattern_suggestions'; +} from './form_based_suggestions'; import { documentField } from './document_field'; import { getFieldByNameFactory } from './pure_helpers'; import { isEqual } from 'lodash'; @@ -33,7 +33,7 @@ import { } from './operations/definitions'; jest.mock('./loader'); -jest.mock('../id_generator'); +jest.mock('../../id_generator'); const fieldsOne = [ { @@ -171,7 +171,7 @@ const expectedIndexPatterns = { }, }; -function testInitialState(): IndexPatternPrivateState { +function testInitialState(): FormBasedPrivateState { return { currentIndexPatternId: '1', layers: { @@ -206,7 +206,7 @@ function getSuggestionSubset( ): Array> { return suggestions.map((s) => { const newSuggestion = { ...s } as Omit & { - state?: IndexPatternPrivateState; + state?: FormBasedPrivateState; }; delete newSuggestion.state; return newSuggestion; @@ -385,7 +385,7 @@ describe('IndexPattern Data Source suggestions', () => { }); it('should make a metric suggestion for a number field if there is no time field', async () => { - const state: IndexPatternPrivateState = { + const state: FormBasedPrivateState = { currentIndexPatternId: '1', layers: { first: { @@ -628,7 +628,7 @@ describe('IndexPattern Data Source suggestions', () => { }); it('should make a metric suggestion for a number field if there is no time field', async () => { - const state: IndexPatternPrivateState = { + const state: FormBasedPrivateState = { currentIndexPatternId: '1', layers: { previousLayer: { @@ -764,7 +764,7 @@ describe('IndexPattern Data Source suggestions', () => { }); describe('suggesting extensions to non-empty tables', () => { - function stateWithNonEmptyTables(): IndexPatternPrivateState { + function stateWithNonEmptyTables(): FormBasedPrivateState { const state = testInitialState(); return { @@ -1036,7 +1036,7 @@ describe('IndexPattern Data Source suggestions', () => { it('adds a metric column on a number field if no other metrics set', () => { (generateId as jest.Mock).mockReturnValue('newid'); const initialState = stateWithNonEmptyTables(); - const modifiedState: IndexPatternPrivateState = { + const modifiedState: FormBasedPrivateState = { ...initialState, layers: { ...initialState.layers, @@ -1138,7 +1138,7 @@ describe('IndexPattern Data Source suggestions', () => { it('skips duplicates when the document-specific field is already in use', () => { const initialState = stateWithNonEmptyTables(); - const modifiedState: IndexPatternPrivateState = { + const modifiedState: FormBasedPrivateState = { ...initialState, layers: { ...initialState.layers, @@ -1170,7 +1170,7 @@ describe('IndexPattern Data Source suggestions', () => { it('hides any referenced metrics when adding new metrics', () => { (generateId as jest.Mock).mockReturnValue('newid'); const initialState = stateWithNonEmptyTables(); - const modifiedState: IndexPatternPrivateState = { + const modifiedState: FormBasedPrivateState = { ...initialState, layers: { currentLayer: { @@ -1239,7 +1239,7 @@ describe('IndexPattern Data Source suggestions', () => { it('makes a suggestion to extending from an invalid state with a new metric', () => { (generateId as jest.Mock).mockReturnValue('newid'); const initialState = stateWithNonEmptyTables(); - const modifiedState: IndexPatternPrivateState = { + const modifiedState: FormBasedPrivateState = { ...initialState, layers: { currentLayer: { @@ -1306,7 +1306,7 @@ describe('IndexPattern Data Source suggestions', () => { (generateId as jest.Mock).mockReturnValue('newid'); const initialState = stateWithNonEmptyTables(); - const modifiedState: IndexPatternPrivateState = { + const modifiedState: FormBasedPrivateState = { ...initialState, layers: { referenceLineLayer: { @@ -1394,7 +1394,7 @@ describe('IndexPattern Data Source suggestions', () => { }); describe('finding the layer that is using the current index pattern', () => { - function stateWithCurrentIndexPattern(): IndexPatternPrivateState { + function stateWithCurrentIndexPattern(): FormBasedPrivateState { const state = testInitialState(); return { @@ -2140,7 +2140,7 @@ describe('IndexPattern Data Source suggestions', () => { it('returns a single suggestion containing the current columns for each layer', async () => { const initialState = testInitialState(); - const state: IndexPatternPrivateState = { + const state: FormBasedPrivateState = { ...initialState, layers: { ...initialState.layers, @@ -2233,7 +2233,7 @@ describe('IndexPattern Data Source suggestions', () => { it('returns a metric over time for single metric tables', async () => { const initialState = testInitialState(); - const state: IndexPatternPrivateState = { + const state: FormBasedPrivateState = { ...initialState, layers: { first: { @@ -2296,7 +2296,7 @@ describe('IndexPattern Data Source suggestions', () => { it('adds date histogram over default time field for tables without time dimension', async () => { const initialState = testInitialState(); - const state: IndexPatternPrivateState = { + const state: FormBasedPrivateState = { ...initialState, layers: { first: { @@ -2385,7 +2385,7 @@ describe('IndexPattern Data Source suggestions', () => { it('adds date histogram over default time field for tables without time dimension and a referenceLine', async () => { const initialState = testInitialState(); - const state: IndexPatternPrivateState = { + const state: FormBasedPrivateState = { ...initialState, layers: { first: { @@ -2495,7 +2495,7 @@ describe('IndexPattern Data Source suggestions', () => { it('does not create an over time suggestion if tables with numeric buckets with time dimension', async () => { const initialState = testInitialState(); - const state: IndexPatternPrivateState = { + const state: FormBasedPrivateState = { ...initialState, layers: { first: { @@ -2543,7 +2543,7 @@ describe('IndexPattern Data Source suggestions', () => { it('adds date histogram over default time field for custom range intervals', async () => { const initialState = testInitialState(); - const state: IndexPatternPrivateState = { + const state: FormBasedPrivateState = { ...initialState, layers: { first: { @@ -2630,7 +2630,7 @@ describe('IndexPattern Data Source suggestions', () => { it('does not create an over time suggestion if there is no default time field', async () => { const initialState = testInitialState(); - const state: IndexPatternPrivateState = { + const state: FormBasedPrivateState = { ...initialState, layers: { first: { @@ -2667,7 +2667,7 @@ describe('IndexPattern Data Source suggestions', () => { it('should not propose an over time suggestion if there are multiple bucket dimensions', () => { const initialState = testInitialState(); - const state: IndexPatternPrivateState = { + const state: FormBasedPrivateState = { ...initialState, layers: { first: { @@ -2751,7 +2751,7 @@ describe('IndexPattern Data Source suggestions', () => { searchable: true, }, ]; - const state: IndexPatternPrivateState = { + const state: FormBasedPrivateState = { currentIndexPatternId: '1', layers: { first: { @@ -2858,7 +2858,7 @@ describe('IndexPattern Data Source suggestions', () => { it('returns an only metric version of a given table, but does not include current state as reduced', () => { const initialState = testInitialState(); - const state: IndexPatternPrivateState = { + const state: FormBasedPrivateState = { currentIndexPatternId: '1', layers: { first: { @@ -2966,7 +2966,7 @@ describe('IndexPattern Data Source suggestions', () => { it('returns an alternative metric for an only-metric table', () => { const initialState = testInitialState(); - const state: IndexPatternPrivateState = { + const state: FormBasedPrivateState = { currentIndexPatternId: '1', layers: { first: { @@ -3032,7 +3032,7 @@ describe('IndexPattern Data Source suggestions', () => { it('contains a reordering suggestion when there are exactly 2 buckets', () => { const initialState = testInitialState(); - const state: IndexPatternPrivateState = { + const state: FormBasedPrivateState = { currentIndexPatternId: '1', layers: { first: { @@ -3084,7 +3084,7 @@ describe('IndexPattern Data Source suggestions', () => { it('will generate suggestions even if there are errors from missing fields', () => { const initialState = testInitialState(); - const state: IndexPatternPrivateState = { + const state: FormBasedPrivateState = { currentIndexPatternId: '1', layers: { first: { @@ -3148,7 +3148,7 @@ describe('IndexPattern Data Source suggestions', () => { describe('references', () => { it('will extend the table with a date when starting in an invalid state', () => { const initialState = testInitialState(); - const state: IndexPatternPrivateState = { + const state: FormBasedPrivateState = { ...initialState, layers: { ...initialState.layers, @@ -3237,7 +3237,7 @@ describe('IndexPattern Data Source suggestions', () => { it('will make an unchanged suggestion including incomplete references', () => { const initialState = testInitialState(); - const state: IndexPatternPrivateState = { + const state: FormBasedPrivateState = { ...initialState, layers: { ...initialState.layers, @@ -3327,7 +3327,7 @@ describe('IndexPattern Data Source suggestions', () => { it('will create reduced suggestions with all referenced children when handling references', () => { const initialState = testInitialState(); - const state: IndexPatternPrivateState = { + const state: FormBasedPrivateState = { ...initialState, layers: { ...initialState.layers, @@ -3473,7 +3473,7 @@ describe('IndexPattern Data Source suggestions', () => { it('will leave dangling references in place', () => { const initialState = testInitialState(); - const state: IndexPatternPrivateState = { + const state: FormBasedPrivateState = { ...initialState, layers: { ...initialState.layers, @@ -3521,7 +3521,7 @@ describe('IndexPattern Data Source suggestions', () => { it('will not suggest reduced tables if there is just a referenced top level metric', () => { const initialState = testInitialState(); - const state: IndexPatternPrivateState = { + const state: FormBasedPrivateState = { ...initialState, layers: { ...initialState.layers, @@ -3566,7 +3566,7 @@ describe('IndexPattern Data Source suggestions', () => { }); function isTableWithBucketColumns( - suggestion: DatasourceSuggestion, + suggestion: DatasourceSuggestion, columnIds: string[], numBuckets: number ) { @@ -3577,7 +3577,7 @@ function isTableWithBucketColumns( } function isTableWithMetricColumns( - suggestion: DatasourceSuggestion, + suggestion: DatasourceSuggestion, columnIds: string[] ) { expect(suggestion.table.isMultiRow).toEqual(false); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts b/x-pack/plugins/lens/public/datasources/form_based/form_based_suggestions.ts similarity index 95% rename from x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts rename to x-pack/plugins/lens/public/datasources/form_based/form_based_suggestions.ts index 8503c369f4ec2e..52008f10bcdeb3 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/form_based_suggestions.ts @@ -14,7 +14,7 @@ import type { AnyColumnWithSourceField, TermsColumn, } from '@kbn/visualizations-plugin/common/convert_to_lens'; -import { generateId } from '../id_generator'; +import { generateId } from '../../id_generator'; import type { DatasourceSuggestion, IndexPattern, @@ -22,8 +22,8 @@ import type { IndexPatternMap, TableChangeType, VisualizationDimensionGroupConfig, -} from '../types'; -import { columnToOperation } from './indexpattern'; +} from '../../types'; +import { columnToOperation } from './form_based'; import { insertNewColumn, replaceColumn, @@ -41,12 +41,12 @@ import { ColumnAdvancedParams, } from './operations'; import { hasField } from './pure_utils'; -import type { IndexPatternPrivateState, IndexPatternLayer } from './types'; +import type { FormBasedPrivateState, FormBasedLayer } from './types'; import { documentField } from './document_field'; import { OperationDefinition } from './operations/definitions'; import { insertOrReplaceFormulaColumn } from './operations/definitions/formula'; -export type IndexPatternSuggestion = DatasourceSuggestion; +export type IndexPatternSuggestion = DatasourceSuggestion; interface ColumnChange { op: OperationType; @@ -67,12 +67,12 @@ function buildSuggestion({ label, changeType, }: { - state: IndexPatternPrivateState; + state: FormBasedPrivateState; layerId: string; changeType: TableChangeType; - updatedLayer?: IndexPatternLayer; + updatedLayer?: FormBasedLayer; label?: string; -}): DatasourceSuggestion { +}): DatasourceSuggestion { const updatedState = updatedLayer ? { ...state, @@ -120,7 +120,7 @@ function buildSuggestion({ } export function getDatasourceSuggestionsForField( - state: IndexPatternPrivateState, + state: FormBasedPrivateState, indexPatternId: string, field: IndexPatternField, indexPatterns: IndexPatternMap, @@ -176,7 +176,7 @@ export function getDatasourceSuggestionsForField( // Called when the user navigates from Visualize editor to Lens export function getDatasourceSuggestionsForVisualizeCharts( - state: IndexPatternPrivateState, + state: FormBasedPrivateState, contextLayers: Layer[], indexPatterns: IndexPatternMap ): IndexPatternSuggestion[] { @@ -184,7 +184,7 @@ export function getDatasourceSuggestionsForVisualizeCharts( } function getEmptyLayersSuggestionsForVisualizeCharts( - state: IndexPatternPrivateState, + state: FormBasedPrivateState, contextLayers: Layer[], indexPatterns: IndexPatternMap ): IndexPatternSuggestion[] { @@ -280,7 +280,7 @@ function convertToColumnChange(columns: Layer['columns'], indexPattern: IndexPat ) { const orderColumn = column.params.orderAgg; const operationDefinition = operationDefinitionMap[orderColumn.operationType]; - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { indexPatternId: indexPattern.id, columns: {}, columnOrder: [], @@ -311,7 +311,7 @@ function createNewLayerWithMetricAggregationFromVizEditor( layer: Layer ) { const columns = convertToColumnChange(layer.columns, indexPattern); - let newLayer: IndexPatternLayer = { + let newLayer: FormBasedLayer = { indexPatternId: indexPattern.id, columns: {}, columnOrder: [], @@ -360,7 +360,7 @@ function createNewLayerWithMetricAggregationFromVizEditor( // Called when the user navigates from Discover to Lens (Visualize button) export function getDatasourceSuggestionsForVisualizeField( - state: IndexPatternPrivateState, + state: FormBasedPrivateState, indexPatternId: string, fieldName: string, indexPatterns: IndexPatternMap @@ -400,7 +400,7 @@ function getBucketOperation(field: IndexPatternField) { } function getExistingLayerSuggestionsForField( - state: IndexPatternPrivateState, + state: FormBasedPrivateState, layerId: string, field: IndexPatternField, indexPatterns: IndexPatternMap @@ -514,14 +514,14 @@ function getExistingLayerSuggestionsForField( } function getEmptyLayerSuggestionsForField( - state: IndexPatternPrivateState, + state: FormBasedPrivateState, layerId: string, indexPatternId: string, field: IndexPatternField, indexPatterns: IndexPatternMap ): IndexPatternSuggestion[] { const indexPattern = indexPatterns[indexPatternId]; - let newLayer: IndexPatternLayer | undefined; + let newLayer: FormBasedLayer | undefined; const bucketOperation = getBucketOperation(field); if (bucketOperation) { newLayer = createNewLayerWithBucketAggregation(indexPattern, field, bucketOperation); @@ -549,7 +549,7 @@ function createNewLayerWithBucketAggregation( indexPattern: IndexPattern, field: IndexPatternField, operation: OperationType -): IndexPatternLayer { +): FormBasedLayer { return insertNewColumn({ op: operation, layer: insertNewColumn({ @@ -570,7 +570,7 @@ function createNewLayerWithBucketAggregation( function createNewLayerWithMetricAggregation( indexPattern: IndexPattern, field: IndexPatternField -): IndexPatternLayer | undefined { +): FormBasedLayer | undefined { const dateField = indexPattern.getFieldByName(indexPattern.timeFieldName!); const [metricOperation] = getMetricOperationTypes(field); if (!metricOperation) { @@ -595,10 +595,10 @@ function createNewLayerWithMetricAggregation( } export function getDatasourceSuggestionsFromCurrentState( - state: IndexPatternPrivateState, + state: FormBasedPrivateState, indexPatterns: IndexPatternMap, filterLayers: (layerId: string) => boolean = () => true -): Array> { +): Array> { const layers = Object.entries(state.layers || {}).filter(([layerId]) => filterLayers(layerId)); if (layers.length > 1) { @@ -658,7 +658,7 @@ export function getDatasourceSuggestionsFromCurrentState( buckets.length === 1 && buckets.some((columnId) => layer.columns[columnId].dataType === 'number'); - const suggestions: Array> = []; + const suggestions: Array> = []; // Always suggest an unchanged table, including during invalid states suggestions.push( @@ -708,7 +708,7 @@ export function getDatasourceSuggestionsFromCurrentState( } function createChangedNestingSuggestion( - state: IndexPatternPrivateState, + state: FormBasedPrivateState, layerId: string, indexPatterns: IndexPatternMap ) { @@ -739,7 +739,7 @@ function createChangedNestingSuggestion( function createMetricSuggestion( indexPattern: IndexPattern, layerId: string, - state: IndexPatternPrivateState, + state: FormBasedPrivateState, field: IndexPatternField ) { const [operation] = getMetricOperationTypes(field); @@ -781,10 +781,10 @@ function getNestedTitle([outerBucketLabel, innerBucketLabel]: string[]) { function createAlternativeMetricSuggestions( indexPattern: IndexPattern, layerId: string, - state: IndexPatternPrivateState + state: FormBasedPrivateState ) { const layer = state.layers[layerId]; - const suggestions: Array> = []; + const suggestions: Array> = []; const topLevelMetricColumns = layer.columnOrder.filter( (columnId) => !isReferenced(layer, columnId) ); @@ -826,7 +826,7 @@ function createAlternativeMetricSuggestions( } function createSuggestionWithDefaultDateHistogram( - state: IndexPatternPrivateState, + state: FormBasedPrivateState, layerId: string, timeField: IndexPatternField, indexPatterns: IndexPatternMap @@ -852,7 +852,7 @@ function createSuggestionWithDefaultDateHistogram( }); } -function createSimplifiedTableSuggestions(state: IndexPatternPrivateState, layerId: string) { +function createSimplifiedTableSuggestions(state: FormBasedPrivateState, layerId: string) { const layer = state.layers[layerId]; const [availableBucketedColumns, availableMetricColumns] = partition( @@ -916,7 +916,7 @@ function createSimplifiedTableSuggestions(state: IndexPatternPrivateState, layer }); } -function getMetricSuggestionTitle(layer: IndexPatternLayer, onlySimpleMetric: boolean) { +function getMetricSuggestionTitle(layer: FormBasedLayer, onlySimpleMetric: boolean) { const { operationType, label } = layer.columns[layer.columnOrder[0]]; return i18n.translate('xpack.lens.indexpattern.suggestions.overallLabel', { defaultMessage: '{operation} overall', diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/help_popover.scss b/x-pack/plugins/lens/public/datasources/form_based/help_popover.scss similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/help_popover.scss rename to x-pack/plugins/lens/public/datasources/form_based/help_popover.scss diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/help_popover.tsx b/x-pack/plugins/lens/public/datasources/form_based/help_popover.tsx similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/help_popover.tsx rename to x-pack/plugins/lens/public/datasources/form_based/help_popover.tsx diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/index.ts b/x-pack/plugins/lens/public/datasources/form_based/index.ts similarity index 84% rename from x-pack/plugins/lens/public/indexpattern_datasource/index.ts rename to x-pack/plugins/lens/public/datasources/form_based/index.ts index 6b1b052c90b148..3b1f62829fa462 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/index.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/index.ts @@ -16,11 +16,11 @@ import type { IndexPatternFieldEditorStart } from '@kbn/data-view-field-editor-p import type { DataPublicPluginSetup, DataPublicPluginStart } from '@kbn/data-plugin/public'; import type { UiActionsStart } from '@kbn/ui-actions-plugin/public'; import type { FieldFormatsStart, FieldFormatsSetup } from '@kbn/field-formats-plugin/public'; -import type { EditorFrameSetup } from '../types'; +import type { EditorFrameSetup } from '../../types'; export type { PersistedIndexPatternLayer, FormulaPublicApi } from './types'; -export interface IndexPatternDatasourceSetupPlugins { +export interface FormBasedDatasourceSetupPlugins { expressions: ExpressionsSetup; fieldFormats: FieldFormatsSetup; data: DataPublicPluginSetup; @@ -28,7 +28,7 @@ export interface IndexPatternDatasourceSetupPlugins { charts: ChartsPluginSetup; } -export interface IndexPatternDatasourceStartPlugins { +export interface FormBasedDatasourceStartPlugins { data: DataPublicPluginStart; unifiedSearch: UnifiedSearchPublicPluginStart; discover?: DiscoverStart; @@ -38,19 +38,19 @@ export interface IndexPatternDatasourceStartPlugins { uiActions: UiActionsStart; } -export class IndexPatternDatasource { +export class FormBasedDatasource { setup( - core: CoreSetup, + core: CoreSetup, { fieldFormats: fieldFormatsSetup, expressions, editorFrame, charts, - }: IndexPatternDatasourceSetupPlugins + }: FormBasedDatasourceSetupPlugins ) { editorFrame.registerDatasource(async () => { - const { getIndexPatternDatasource, getSuffixFormatter, suffixFormatterId } = await import( - '../async_services' + const { getFormBasedDatasource, getSuffixFormatter, suffixFormatterId } = await import( + '../../async_services' ); if (!fieldFormatsSetup.has(suffixFormatterId)) { @@ -67,7 +67,7 @@ export class IndexPatternDatasource { { dataViewFieldEditor, uiActions, data, fieldFormats, dataViews, unifiedSearch, discover }, ] = await core.getStartServices(); - return getIndexPatternDatasource({ + return getFormBasedDatasource({ core: coreStart, fieldFormats, storage: new Storage(localStorage), diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/layerpanel.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/layerpanel.test.tsx similarity index 95% rename from x-pack/plugins/lens/public/indexpattern_datasource/layerpanel.test.tsx rename to x-pack/plugins/lens/public/datasources/form_based/layerpanel.test.tsx index 7dde02c6c2b611..defc505f1d9e13 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/layerpanel.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/layerpanel.test.tsx @@ -6,13 +6,13 @@ */ import React, { MouseEvent } from 'react'; -import { IndexPatternPrivateState } from './types'; -import { IndexPatternLayerPanelProps, LayerPanel } from './layerpanel'; +import { FormBasedPrivateState } from './types'; +import { FormBasedLayerPanelProps, LayerPanel } from './layerpanel'; import { shallowWithIntl as shallow } from '@kbn/test-jest-helpers'; import { ShallowWrapper } from 'enzyme'; import { EuiSelectable } from '@elastic/eui'; import { DataViewsList } from '@kbn/unified-search-plugin/public'; -import { ChangeIndexPattern } from '../shared_components/dataview_picker/dataview_picker'; +import { ChangeIndexPattern } from '../../shared_components/dataview_picker/dataview_picker'; import { getFieldByNameFactory } from './pure_helpers'; import { TermsIndexPatternColumn } from './operations'; @@ -135,7 +135,7 @@ const fieldsThree = [ }, ]; -const initialState: IndexPatternPrivateState = { +const initialState: FormBasedPrivateState = { currentIndexPatternId: '1', layers: { first: { @@ -168,7 +168,7 @@ const initialState: IndexPatternPrivateState = { }, }; describe('Layer Data Panel', () => { - let defaultProps: IndexPatternLayerPanelProps; + let defaultProps: FormBasedLayerPanelProps; beforeEach(() => { defaultProps = { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/layerpanel.tsx b/x-pack/plugins/lens/public/datasources/form_based/layerpanel.tsx similarity index 78% rename from x-pack/plugins/lens/public/indexpattern_datasource/layerpanel.tsx rename to x-pack/plugins/lens/public/datasources/form_based/layerpanel.tsx index 9824f70eeddfc0..c18b79b28c58c5 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/layerpanel.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/layerpanel.tsx @@ -8,13 +8,12 @@ import React from 'react'; import { I18nProvider } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; -import { DatasourceLayerPanelProps } from '../types'; -import { IndexPatternPrivateState } from './types'; -import { ChangeIndexPattern } from '../shared_components/dataview_picker/dataview_picker'; +import { DatasourceLayerPanelProps } from '../../types'; +import { FormBasedPrivateState } from './types'; +import { ChangeIndexPattern } from '../../shared_components/dataview_picker/dataview_picker'; -export interface IndexPatternLayerPanelProps - extends DatasourceLayerPanelProps { - state: IndexPatternPrivateState; +export interface FormBasedLayerPanelProps extends DatasourceLayerPanelProps { + state: FormBasedPrivateState; onChangeIndexPattern: (newId: string) => void; } @@ -23,7 +22,7 @@ export function LayerPanel({ layerId, onChangeIndexPattern, dataViews, -}: IndexPatternLayerPanelProps) { +}: FormBasedLayerPanelProps) { const layer = state.layers[layerId]; const indexPattern = dataViews.indexPatterns[layer.indexPatternId]; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts b/x-pack/plugins/lens/public/datasources/form_based/loader.test.ts similarity index 96% rename from x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts rename to x-pack/plugins/lens/public/datasources/form_based/loader.test.ts index a3bc7a21143c42..896fbd0e6404fd 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/loader.test.ts @@ -12,9 +12,9 @@ import { extractReferences, injectReferences, } from './loader'; -import { IndexPatternPersistedState, IndexPatternPrivateState } from './types'; +import { FormBasedPersistedState, FormBasedPrivateState } from './types'; import { DateHistogramIndexPatternColumn, TermsIndexPatternColumn } from './operations'; -import { sampleIndexPatterns } from '../data_views_service/mocks'; +import { sampleIndexPatterns } from '../../data_views_service/mocks'; const createMockStorage = (lastData?: Record) => { return { @@ -141,7 +141,7 @@ describe('loader', () => { }); it('should initialize all the embeddable references without local storage', () => { - const savedState: IndexPatternPersistedState = { + const savedState: FormBasedPersistedState = { layers: { layerb: { columnOrder: ['col1', 'col2'], @@ -189,7 +189,7 @@ describe('loader', () => { }); it('should initialize from saved state', () => { - const savedState: IndexPatternPersistedState = { + const savedState: FormBasedPersistedState = { layers: { layerb: { columnOrder: ['col1', 'col2'], @@ -242,7 +242,7 @@ describe('loader', () => { }); describe('saved object references', () => { - const state: IndexPatternPrivateState = { + const state: FormBasedPrivateState = { currentIndexPatternId: 'b', layers: { a: { @@ -300,7 +300,7 @@ describe('loader', () => { describe('changeIndexPattern', () => { it('sets the given indexpattern as current', () => { - const state: IndexPatternPrivateState = { + const state: FormBasedPrivateState = { currentIndexPatternId: '2', layers: {}, }; @@ -324,7 +324,7 @@ describe('loader', () => { }); it('should update an empty layer on indexpattern change', () => { - const state: IndexPatternPrivateState = { + const state: FormBasedPrivateState = { currentIndexPatternId: '2', layers: { layerId: { columnOrder: [], columns: {}, indexPatternId: '2' } }, }; @@ -345,7 +345,7 @@ describe('loader', () => { }); it('should keep layer indexpattern on change if not empty', () => { - const state: IndexPatternPrivateState = { + const state: FormBasedPrivateState = { currentIndexPatternId: '2', layers: { layerId: { @@ -402,7 +402,7 @@ describe('loader', () => { describe('changeLayerIndexPattern', () => { it('loads the index pattern and then changes the specified layer', async () => { - const state: IndexPatternPrivateState = { + const state: FormBasedPrivateState = { currentIndexPatternId: '1', layers: { l0: { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts b/x-pack/plugins/lens/public/datasources/form_based/loader.ts similarity index 89% rename from x-pack/plugins/lens/public/indexpattern_datasource/loader.ts rename to x-pack/plugins/lens/public/datasources/form_based/loader.ts index e26231995578e1..6aa021a6f363fe 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/loader.ts @@ -17,12 +17,12 @@ import { UiActionsStart, VisualizeFieldContext, } from '@kbn/ui-actions-plugin/public'; -import type { VisualizeEditorContext } from '../types'; -import { IndexPatternPersistedState, IndexPatternPrivateState, IndexPatternLayer } from './types'; +import type { VisualizeEditorContext } from '../../types'; +import { FormBasedPersistedState, FormBasedPrivateState, FormBasedLayer } from './types'; import { memoizedGetAvailableOperationsByMetadata, updateLayerIndexPattern } from './operations'; -import { readFromStorage, writeToStorage } from '../settings_storage'; -import type { IndexPattern, IndexPatternRef } from '../types'; +import { readFromStorage, writeToStorage } from '../../settings_storage'; +import type { IndexPattern, IndexPatternRef } from '../../types'; export function onRefreshIndexPattern() { if (memoizedGetAvailableOperationsByMetadata.cache.clear) { @@ -47,9 +47,9 @@ function getLayerReferenceName(layerId: string) { return `indexpattern-datasource-layer-${layerId}`; } -export function extractReferences({ layers }: IndexPatternPrivateState) { +export function extractReferences({ layers }: FormBasedPrivateState) { const savedObjectReferences: SavedObjectReference[] = []; - const persistableState: IndexPatternPersistedState = { + const persistableState: FormBasedPersistedState = { layers: {}, }; Object.entries(layers).forEach(([layerId, { indexPatternId, ...persistableLayer }]) => { @@ -64,10 +64,10 @@ export function extractReferences({ layers }: IndexPatternPrivateState) { } export function injectReferences( - state: IndexPatternPersistedState, + state: FormBasedPersistedState, references: SavedObjectReference[] ) { - const layers: Record = {}; + const layers: Record = {}; Object.entries(state.layers).forEach(([layerId, persistedLayer]) => { layers[layerId] = { ...persistedLayer, @@ -83,7 +83,7 @@ function createStateFromPersisted({ persistedState, references, }: { - persistedState?: IndexPatternPersistedState; + persistedState?: FormBasedPersistedState; references?: SavedObjectReference[]; }) { return persistedState && references ? injectReferences(persistedState, references) : undefined; @@ -97,7 +97,7 @@ function getUsedIndexPatterns({ defaultIndexPatternId, }: { state?: { - layers: Record; + layers: Record; }; defaultIndexPatternId?: string; storage: IStorageWrapper; @@ -139,14 +139,14 @@ export function loadInitialState({ indexPatternRefs = [], indexPatterns = {}, }: { - persistedState?: IndexPatternPersistedState; + persistedState?: FormBasedPersistedState; references?: SavedObjectReference[]; defaultIndexPatternId?: string; storage: IStorageWrapper; initialContext?: VisualizeFieldContext | VisualizeEditorContext; indexPatternRefs?: IndexPatternRef[]; indexPatterns?: Record; -}): IndexPatternPrivateState { +}): FormBasedPrivateState { const state = createStateFromPersisted({ persistedState, references }); const { usedPatterns, allIndexPatternIds: indexPatternIds } = getUsedIndexPatterns({ state, @@ -186,7 +186,7 @@ export function changeIndexPattern({ indexPatterns, }: { indexPatternId: string; - state: IndexPatternPrivateState; + state: FormBasedPrivateState; storage: IStorageWrapper; indexPatterns: Record; }) { @@ -209,7 +209,7 @@ export function renameIndexPattern({ }: { oldIndexPatternId: string; newIndexPatternId: string; - state: IndexPatternPrivateState; + state: FormBasedPrivateState; }) { return { ...state, @@ -231,7 +231,7 @@ export function triggerActionOnIndexPatternChange({ }: { indexPatternId: string; layerId: string; - state: IndexPatternPrivateState; + state: FormBasedPrivateState; uiActions: UiActionsStart; }) { const fromDataView = state.layers[layerId]?.indexPatternId; @@ -260,7 +260,7 @@ export function changeLayerIndexPattern({ }: { indexPatternId: string; layerId: string; - state: IndexPatternPrivateState; + state: FormBasedPrivateState; replaceIfPossible?: boolean; storage: IStorageWrapper; indexPatterns: Record; @@ -276,7 +276,7 @@ export function changeLayerIndexPattern({ }; } -function isSingleEmptyLayer(layerMap: IndexPatternPrivateState['layers']) { +function isSingleEmptyLayer(layerMap: FormBasedPrivateState['layers']) { const layers = Object.values(layerMap); return layers.length === 1 && layers[0].columnOrder.length === 0; } diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/mocks.ts b/x-pack/plugins/lens/public/datasources/form_based/mocks.ts similarity index 97% rename from x-pack/plugins/lens/public/indexpattern_datasource/mocks.ts rename to x-pack/plugins/lens/public/datasources/form_based/mocks.ts index 7cd3639547e149..c2a85fbf0bac4d 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/mocks.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/mocks.ts @@ -5,9 +5,9 @@ * 2.0. */ -import { DragContextState } from '../drag_drop'; +import { DragContextState } from '../../drag_drop'; import { getFieldByNameFactory } from './pure_helpers'; -import type { IndexPattern, IndexPatternField } from '../types'; +import type { IndexPattern, IndexPatternField } from '../../types'; export const createMockedIndexPattern = (someProps?: Partial): IndexPattern => { const fields = [ diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/no_fields_callout.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/no_fields_callout.test.tsx similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/no_fields_callout.test.tsx rename to x-pack/plugins/lens/public/datasources/form_based/no_fields_callout.test.tsx diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/no_fields_callout.tsx b/x-pack/plugins/lens/public/datasources/form_based/no_fields_callout.tsx similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/no_fields_callout.tsx rename to x-pack/plugins/lens/public/datasources/form_based/no_fields_callout.tsx diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/__mocks__/index.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/__mocks__/index.ts similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/__mocks__/index.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/__mocks__/index.ts diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions.test.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions.test.ts similarity index 97% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions.test.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions.test.ts index c9b3ae608ec768..3dc58b7f1ef6c9 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions.test.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions.test.ts @@ -18,8 +18,8 @@ import { } from './definitions'; import { getFieldByNameFactory } from '../pure_helpers'; import { documentField } from '../document_field'; -import { IndexPatternLayer } from '../types'; -import { IndexPattern, IndexPatternField } from '../../types'; +import { FormBasedLayer } from '../types'; +import { IndexPattern, IndexPatternField } from '../../../types'; import { GenericIndexPatternColumn } from '.'; import { DateHistogramIndexPatternColumn } from './definitions/date_histogram'; @@ -83,7 +83,7 @@ const indexPattern = { const baseColumnArgs: { previousColumn: GenericIndexPatternColumn; indexPattern: IndexPattern; - layer: IndexPatternLayer; + layer: FormBasedLayer; field: IndexPatternField; } = { previousColumn: { @@ -105,7 +105,7 @@ const baseColumnArgs: { field: indexPattern.fields[2], }; -const layer: IndexPatternLayer = { +const layer: FormBasedLayer = { indexPatternId: '1', columnOrder: ['date', 'metric', 'ref'], columns: { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/counter_rate.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/calculations/counter_rate.tsx similarity index 97% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/counter_rate.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/calculations/counter_rate.tsx index f2c421946bafbb..3b89de8e94c51c 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/counter_rate.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/calculations/counter_rate.tsx @@ -7,7 +7,7 @@ import { i18n } from '@kbn/i18n'; import { FormattedIndexPatternColumn, ReferenceBasedIndexPatternColumn } from '../column_types'; -import { IndexPatternLayer } from '../../../types'; +import { FormBasedLayer } from '../../../types'; import { buildLabelFunction, getErrorsForDateReference, @@ -106,7 +106,7 @@ export const counterRateOperation: OperationDefinition< isTransferable: (column, newIndexPattern) => { return hasDateField(newIndexPattern); }, - getErrorMessage: (layer: IndexPatternLayer, columnId: string) => { + getErrorMessage: (layer: FormBasedLayer, columnId: string) => { return combineErrorMessages([ getErrorsForDateReference( layer, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/cumulative_sum.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/calculations/cumulative_sum.tsx similarity index 96% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/cumulative_sum.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/calculations/cumulative_sum.tsx index 67260672fa66dc..339f5e4bc40030 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/cumulative_sum.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/calculations/cumulative_sum.tsx @@ -7,7 +7,7 @@ import { i18n } from '@kbn/i18n'; import { FormattedIndexPatternColumn, ReferenceBasedIndexPatternColumn } from '../column_types'; -import { IndexPatternLayer } from '../../../types'; +import { FormBasedLayer } from '../../../types'; import { checkForDateHistogram, getErrorsForDateReference, @@ -19,7 +19,7 @@ import { import { OperationDefinition } from '..'; import { getFormatFromPreviousColumn, getFilter, combineErrorMessages } from '../helpers'; import { getDisallowedPreviousShiftMessage } from '../../../time_shift_utils'; -import { DOCUMENT_FIELD_NAME } from '../../../../../common'; +import { DOCUMENT_FIELD_NAME } from '../../../../../../common'; const ofName = buildLabelFunction((name?: string) => { return i18n.translate('xpack.lens.indexPattern.cumulativeSumOf', { @@ -106,7 +106,7 @@ export const cumulativeSumOperation: OperationDefinition< isTransferable: () => { return true; }, - getErrorMessage: (layer: IndexPatternLayer, columnId: string) => { + getErrorMessage: (layer: FormBasedLayer, columnId: string) => { return combineErrorMessages([ getErrorsForDateReference( layer, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/differences.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/calculations/differences.tsx similarity index 97% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/differences.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/calculations/differences.tsx index 1d76667654cb3e..f2c379b5af5c15 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/differences.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/calculations/differences.tsx @@ -7,7 +7,7 @@ import { i18n } from '@kbn/i18n'; import { FormattedIndexPatternColumn, ReferenceBasedIndexPatternColumn } from '../column_types'; -import { IndexPatternLayer } from '../../../types'; +import { FormBasedLayer } from '../../../types'; import { buildLabelFunction, checkForDateHistogram, @@ -92,7 +92,7 @@ export const derivativeOperation: OperationDefinition< isTransferable: (column, newIndexPattern) => { return hasDateField(newIndexPattern); }, - getErrorMessage: (layer: IndexPatternLayer, columnId: string) => { + getErrorMessage: (layer: FormBasedLayer, columnId: string) => { return combineErrorMessages([ getErrorsForDateReference( layer, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/index.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/calculations/index.ts similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/index.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/calculations/index.ts diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/moving_average.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/calculations/moving_average.tsx similarity index 97% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/moving_average.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/calculations/moving_average.tsx index 0fbdd96153a0f9..d7b46d09c0f1e9 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/moving_average.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/calculations/moving_average.tsx @@ -9,9 +9,9 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import React, { useState } from 'react'; import { EuiFieldNumber, EuiFormRow } from '@elastic/eui'; -import { useDebounceWithOptions } from '../../../../shared_components'; +import { useDebounceWithOptions } from '../../../../../shared_components'; import { FormattedIndexPatternColumn, ReferenceBasedIndexPatternColumn } from '../column_types'; -import { IndexPatternLayer } from '../../../types'; +import { FormBasedLayer } from '../../../types'; import { buildLabelFunction, checkForDateHistogram, @@ -114,7 +114,7 @@ export const movingAverageOperation: OperationDefinition< isTransferable: (column, newIndexPattern) => { return hasDateField(newIndexPattern); }, - getErrorMessage: (layer: IndexPatternLayer, columnId: string) => { + getErrorMessage: (layer: FormBasedLayer, columnId: string) => { return combineErrorMessages([ getErrorsForDateReference( layer, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/overall_metric.test.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/calculations/overall_metric.test.ts similarity index 93% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/overall_metric.test.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/calculations/overall_metric.test.ts index 178a98074ad8a7..901600e90f034c 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/overall_metric.test.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/calculations/overall_metric.test.ts @@ -6,7 +6,7 @@ */ import { createMockedIndexPattern } from '../../../mocks'; -import type { IndexPatternLayer } from '../../../types'; +import type { FormBasedLayer } from '../../../types'; import { overallAverageOperation, overallMaxOperation, @@ -16,7 +16,7 @@ import { describe('overall_metric', () => { const indexPattern = createMockedIndexPattern(); - let layer: IndexPatternLayer; + let layer: FormBasedLayer; beforeEach(() => { layer = { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/overall_metric.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/calculations/overall_metric.tsx similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/overall_metric.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/calculations/overall_metric.tsx diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/time_scale.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/calculations/time_scale.tsx similarity index 97% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/time_scale.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/calculations/time_scale.tsx index 68df34650794d0..59eb7fea46233a 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/time_scale.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/calculations/time_scale.tsx @@ -13,7 +13,7 @@ import type { import { getErrorsForDateReference } from './utils'; import type { OperationDefinition } from '..'; import { combineErrorMessages, getFormatFromPreviousColumn } from '../helpers'; -import { IndexPatternLayer } from '../../../types'; +import { FormBasedLayer } from '../../../types'; import { getDisallowedPreviousShiftMessage } from '../../../time_shift_utils'; type OverallMetricIndexPatternColumn = FormattedIndexPatternColumn & @@ -101,7 +101,7 @@ export const timeScaleOperation: OperationDefinition { return true; }, - getErrorMessage: (layer: IndexPatternLayer, columnId: string) => { + getErrorMessage: (layer: FormBasedLayer, columnId: string) => { return combineErrorMessages([ getErrorsForDateReference( layer, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/utils.test.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/calculations/utils.test.ts similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/utils.test.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/calculations/utils.test.ts diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/utils.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/calculations/utils.ts similarity index 90% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/utils.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/calculations/utils.ts index 5b33fb0717539a..bac4a8940c6891 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/calculations/utils.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/calculations/utils.ts @@ -9,10 +9,10 @@ import { i18n } from '@kbn/i18n'; import type { AstFunction } from '@kbn/interpreter'; import memoizeOne from 'memoize-one'; import { LayerTypes } from '@kbn/expression-xy-plugin/public'; -import type { IndexPattern } from '../../../../types'; -import type { LayerType } from '../../../../../common'; -import type { TimeScaleUnit } from '../../../../../common/expressions'; -import type { IndexPatternLayer } from '../../../types'; +import type { IndexPattern } from '../../../../../types'; +import { LayerType } from '../../../../../../common'; +import type { TimeScaleUnit } from '../../../../../../common/expressions'; +import type { FormBasedLayer } from '../../../types'; import { adjustTimeScaleLabelSuffix } from '../../time_scale_utils'; import type { ReferenceBasedIndexPatternColumn } from '../column_types'; import { getManagedColumnsFrom, isColumnValidAsReference } from '../../layer_helpers'; @@ -49,7 +49,7 @@ export function checkForDataLayerType(layerType: LayerType, name: string) { /** * Checks whether the current layer includes a date histogram and returns an error otherwise */ -export function checkForDateHistogram(layer: IndexPatternLayer, name: string) { +export function checkForDateHistogram(layer: FormBasedLayer, name: string) { const buckets = layer.columnOrder.filter((colId) => layer.columns[colId].isBucketed); const hasDateHistogram = buckets.some( (colId) => layer.columns[colId].operationType === 'date_histogram' @@ -68,7 +68,7 @@ export function checkForDateHistogram(layer: IndexPatternLayer, name: string) { ]; } -const getFullyManagedColumnIds = memoizeOne((layer: IndexPatternLayer) => { +const getFullyManagedColumnIds = memoizeOne((layer: FormBasedLayer) => { const managedColumnIds = new Set(); Object.entries(layer.columns).forEach(([id, column]) => { if ( @@ -85,7 +85,7 @@ const getFullyManagedColumnIds = memoizeOne((layer: IndexPatternLayer) => { return managedColumnIds; }); -export function checkReferences(layer: IndexPatternLayer, columnId: string) { +export function checkReferences(layer: FormBasedLayer, columnId: string) { const column = layer.columns[columnId] as ReferenceBasedIndexPatternColumn; const errors: string[] = []; @@ -128,11 +128,7 @@ export function checkReferences(layer: IndexPatternLayer, columnId: string) { return errors.length ? errors : undefined; } -export function getErrorsForDateReference( - layer: IndexPatternLayer, - columnId: string, - name: string -) { +export function getErrorsForDateReference(layer: FormBasedLayer, columnId: string, name: string) { const dateErrors = checkForDateHistogram(layer, name) ?? []; const referenceErrors = checkReferences(layer, columnId) ?? []; if (dateErrors.length || referenceErrors.length) { @@ -149,7 +145,7 @@ export function hasDateField(indexPattern: IndexPattern) { * Creates an expression ast for a date based operation (cumulative sum, derivative, moving average, counter rate) */ export function dateBasedOperationToExpression( - layer: IndexPatternLayer, + layer: FormBasedLayer, columnId: string, functionName: string, additionalArgs: Record = {} @@ -180,7 +176,7 @@ export function dateBasedOperationToExpression( * Creates an expression ast for a date based operation (cumulative sum, derivative, moving average, counter rate) */ export function optionallHistogramBasedOperationToExpression( - layer: IndexPatternLayer, + layer: FormBasedLayer, columnId: string, functionName: string, additionalArgs: Record = {} diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.test.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/cardinality.test.ts similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.test.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/cardinality.test.ts diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/cardinality.tsx similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/cardinality.tsx diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/column_types.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/column_types.ts similarity index 91% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/column_types.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/column_types.ts index 8af67468f0ac19..a0931a23f4e5ad 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/column_types.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/column_types.ts @@ -6,8 +6,8 @@ */ import type { Query } from '@kbn/es-query'; -import type { Operation } from '../../../types'; -import type { TimeScaleUnit } from '../../../../common/expressions'; +import type { Operation } from '../../../../types'; +import type { TimeScaleUnit } from '../../../../../common/expressions'; import type { OperationType } from '.'; export interface BaseIndexPatternColumn extends Operation { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.test.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/count.test.ts similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.test.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/count.test.ts diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/count.tsx similarity index 96% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/count.tsx index 1f67eebf3541ae..c05b8d415de7ed 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/count.tsx @@ -11,10 +11,10 @@ import { euiThemeVars } from '@kbn/ui-theme'; import { EuiSwitch, EuiText } from '@elastic/eui'; import { AggFunctionsMapping } from '@kbn/data-plugin/public'; import { buildExpressionFunction } from '@kbn/expressions-plugin/public'; -import type { TimeScaleUnit } from '../../../../common/expressions'; -import type { OperationDefinition, ParamEditorProps } from '.'; -import type { FieldBasedIndexPatternColumn, ValueFormatConfig } from './column_types'; -import type { IndexPatternField } from '../../../types'; +import { TimeScaleUnit } from '../../../../../common/expressions'; +import { OperationDefinition, ParamEditorProps } from '.'; +import { FieldBasedIndexPatternColumn, ValueFormatConfig } from './column_types'; +import type { IndexPatternField } from '../../../../types'; import { getInvalidFieldMessage, getFilter, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/date_histogram.test.tsx similarity index 97% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.test.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/date_histogram.test.tsx index a437cf63fd8730..c08f8703c723fa 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/date_histogram.test.tsx @@ -18,8 +18,8 @@ import type { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; import { UI_SETTINGS } from '@kbn/data-plugin/public'; import { dataPluginMock, getCalculateAutoTimeExpression } from '@kbn/data-plugin/public/mocks'; import { createMockedIndexPattern } from '../../mocks'; -import type { IndexPatternLayer } from '../../types'; -import type { IndexPattern } from '../../../types'; +import type { FormBasedLayer } from '../../types'; +import type { IndexPattern } from '../../../../types'; import { getFieldByNameFactory } from '../../pure_helpers'; import { act } from 'react-dom/test-utils'; @@ -124,7 +124,7 @@ const defaultOptions = { }; describe('date_histogram', () => { - let layer: IndexPatternLayer; + let layer: FormBasedLayer; const InlineOptions = dateHistogramOperation.paramEditor!; beforeEach(() => { @@ -160,7 +160,7 @@ describe('date_histogram', () => { }, }, }, - } as unknown as IndexPatternLayer; + } as unknown as FormBasedLayer; } describe('buildColumn', () => { @@ -339,7 +339,7 @@ describe('date_histogram', () => { it('should render current value for other index pattern', () => { const updateLayerSpy = jest.fn(); - const secondLayer: IndexPatternLayer = { + const secondLayer: FormBasedLayer = { indexPatternId: '2', columnOrder: ['col2'], columns: { @@ -374,7 +374,7 @@ describe('date_histogram', () => { }); it('should render time interval control set to auto for auto interval', () => { - const thirdLayer: IndexPatternLayer = { + const thirdLayer: FormBasedLayer = { indexPatternId: '1', columnOrder: ['col1'], columns: { @@ -409,7 +409,7 @@ describe('date_histogram', () => { }); it('should allow switching to manual interval', () => { - const thirdLayer: IndexPatternLayer = { + const thirdLayer: FormBasedLayer = { indexPatternId: '1', columnOrder: ['col1'], columns: { @@ -451,7 +451,7 @@ describe('date_histogram', () => { }); it('should allow turning off time range sync', () => { - const thirdLayer: IndexPatternLayer = { + const thirdLayer: FormBasedLayer = { indexPatternId: '1', columnOrder: ['col1'], columns: { @@ -493,7 +493,7 @@ describe('date_histogram', () => { }); it('turns off time range ignore on switching to auto interval', () => { - const thirdLayer: IndexPatternLayer = { + const thirdLayer: FormBasedLayer = { indexPatternId: '1', columnOrder: ['col1'], columns: { @@ -535,7 +535,7 @@ describe('date_histogram', () => { }); it('turns off drop partial bucket on tuning off time range ignore', () => { - const thirdLayer: IndexPatternLayer = { + const thirdLayer: FormBasedLayer = { indexPatternId: '1', columnOrder: ['col1'], columns: { @@ -735,7 +735,7 @@ describe('date_histogram', () => { }); it('should allow the drop of partial buckets', () => { - const thirdLayer: IndexPatternLayer = { + const thirdLayer: FormBasedLayer = { indexPatternId: '1', columnOrder: ['col1'], columns: { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/date_histogram.tsx similarity index 98% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/date_histogram.tsx index 8d6b201b2cc196..87261f41338d05 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/date_histogram.tsx @@ -33,8 +33,8 @@ import { updateColumnParam } from '../layer_helpers'; import { OperationDefinition, ParamEditorProps } from '.'; import { FieldBasedIndexPatternColumn } from './column_types'; import { getInvalidFieldMessage, getSafeName } from './helpers'; -import { IndexPatternLayer } from '../../types'; -import { TooltipWrapper } from '../../../shared_components'; +import { FormBasedLayer } from '../../types'; +import { TooltipWrapper } from '../../../../shared_components'; const { isValidInterval } = search.aggs; const autoInterval = 'auto'; @@ -50,7 +50,7 @@ export interface DateHistogramIndexPatternColumn extends FieldBasedIndexPatternC }; } -function getMultipleDateHistogramsErrorMessage(layer: IndexPatternLayer, columnId: string) { +function getMultipleDateHistogramsErrorMessage(layer: FormBasedLayer, columnId: string) { const usesTimeShift = Object.values(layer.columns).some( (col) => col.timeShift && col.timeShift !== '' ); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/filters/filter_popover.scss b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/filters/filter_popover.scss similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/filters/filter_popover.scss rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/filters/filter_popover.scss diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/filters/filter_popover.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/filters/filter_popover.test.tsx similarity index 98% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/filters/filter_popover.test.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/filters/filter_popover.test.tsx index 475761c94ec54b..9fbc38732806cd 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/filters/filter_popover.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/filters/filter_popover.test.tsx @@ -13,7 +13,7 @@ import { createMockedIndexPattern } from '../../../mocks'; import { FilterPopover } from './filter_popover'; import { LabelInput } from '../shared_components'; import { QueryStringInput } from '@kbn/unified-search-plugin/public'; -import { QueryInput } from '../../../../shared_components'; +import { QueryInput } from '../../../../../shared_components'; jest.mock('.', () => ({ isQueryValid: () => true, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/filters/filter_popover.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/filters/filter_popover.tsx similarity index 94% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/filters/filter_popover.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/filters/filter_popover.tsx index 17314bbc991c01..21a52f46e5c58a 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/filters/filter_popover.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/filters/filter_popover.tsx @@ -12,8 +12,8 @@ import { EuiPopover, EuiSpacer } from '@elastic/eui'; import type { Query } from '@kbn/es-query'; // Need to keep it separate to make it work Jest mocks in dimension_panel tests // import { QueryInput } from '../../../../shared_components/query_input'; -import { isQueryValid, QueryInput } from '../../../../shared_components'; -import { IndexPattern } from '../../../../types'; +import { isQueryValid, QueryInput } from '../../../../../shared_components'; +import { IndexPattern } from '../../../../../types'; import { FilterValue, defaultLabel } from '.'; import { LabelInput } from '../shared_components'; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/filters/filters.scss b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/filters/filters.scss similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/filters/filters.scss rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/filters/filters.scss diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/filters/filters.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/filters/filters.test.tsx similarity index 99% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/filters/filters.test.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/filters/filters.test.tsx index 2b227674c26e92..2264fa8f185fbb 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/filters/filters.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/filters/filters.test.tsx @@ -16,7 +16,7 @@ import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; import type { FiltersIndexPatternColumn } from '.'; import { filtersOperation } from '..'; -import type { IndexPatternLayer } from '../../../types'; +import type { FormBasedLayer } from '../../../types'; import { createMockedIndexPattern } from '../../../mocks'; import { FilterPopover } from './filter_popover'; @@ -62,7 +62,7 @@ jest.mock('@elastic/eui', () => { }); describe('filters', () => { - let layer: IndexPatternLayer; + let layer: FormBasedLayer; const InlineOptions = filtersOperation.paramEditor!; beforeEach(() => { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/filters/filters.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/filters/filters.tsx similarity index 98% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/filters/filters.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/filters/filters.tsx index 434dbb092bdb0b..67f3af575f7db3 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/filters/filters.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/filters/filters.tsx @@ -19,8 +19,8 @@ import { DraggableBucketContainer, isQueryValid, NewBucketButton, -} from '../../../../shared_components'; -import { IndexPattern } from '../../../../types'; +} from '../../../../../shared_components'; +import { IndexPattern } from '../../../../../types'; import { updateColumnParam } from '../../layer_helpers'; import type { OperationDefinition } from '..'; import type { BaseIndexPatternColumn } from '../column_types'; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/filters/index.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/filters/index.tsx similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/filters/index.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/filters/index.tsx diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/formula.scss b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/editor/formula.scss similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/formula.scss rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/editor/formula.scss diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/formula_editor.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/editor/formula_editor.tsx similarity index 99% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/formula_editor.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/editor/formula_editor.tsx index 1e9a304ffa8a26..4464b54fb8a328 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/formula_editor.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/editor/formula_editor.tsx @@ -27,7 +27,7 @@ import { monaco } from '@kbn/monaco'; import classNames from 'classnames'; import { CodeEditor } from '@kbn/kibana-react-plugin/public'; import type { CodeEditorProps } from '@kbn/kibana-react-plugin/public'; -import { TooltipWrapper, useDebounceWithOptions } from '../../../../../shared_components'; +import { TooltipWrapper, useDebounceWithOptions } from '../../../../../../shared_components'; import { ParamEditorProps } from '../..'; import { getManagedColumnsFrom } from '../../../layer_helpers'; import { ErrorWrapper, runASTValidation, tryToParse } from '../validation'; @@ -48,7 +48,7 @@ import { MemoizedFormulaHelp } from './formula_help'; import './formula.scss'; import { FormulaIndexPatternColumn } from '../formula'; import { insertOrReplaceFormulaColumn } from '../parse'; -import { filterByVisibleOperation } from '../util'; +import { filterByVisibleOperation, nonNullable } from '../util'; import { getColumnTimeShiftWarnings, getDateHistogramInterval } from '../../../../time_shift_utils'; function tableHasData( @@ -363,7 +363,7 @@ export function FormulaEditor({ } return newWarnings; }) - .filter((marker) => marker); + .filter(nonNullable); setWarnings(markers.map(({ severity, message }) => ({ severity, message }))); monaco.editor.setModelMarkers(editorModel.current, 'LENS', markers); } diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/formula_help.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/editor/formula_help.tsx similarity index 86% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/formula_help.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/editor/formula_help.tsx index 0a1cf746c19f8c..8f728bc5d15a2b 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/formula_help.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/editor/formula_help.tsx @@ -21,7 +21,8 @@ import { EuiSpacer, } from '@elastic/eui'; import { Markdown } from '@kbn/kibana-react-plugin/public'; -import type { IndexPattern } from '../../../../../types'; +import { groupBy } from 'lodash'; +import type { IndexPattern } from '../../../../../../types'; import { tinymathFunctions } from '../util'; import { getPossibleFunctions } from './math_completion'; import { hasFunctionFieldArgument } from '../validation'; @@ -193,31 +194,40 @@ max(system.network.in.bytes, reducedTimeRange="30m") items: [], }); - const availableFunctions = getPossibleFunctions(indexPattern); + const { + elasticsearch: esFunction, + calculation: calculationFunction, + math: mathOperations, + comparison: comparisonOperations, + } = useMemo( + () => + groupBy(getPossibleFunctions(indexPattern), (key) => { + if (key in operationDefinitionMap) { + return operationDefinitionMap[key].documentation?.section; + } + if (key in tinymathFunctions) { + return tinymathFunctions[key].section; + } + }), + [operationDefinitionMap, indexPattern] + ); // Es aggs helpGroups[2].items.push( - ...availableFunctions - .filter( - (key) => - key in operationDefinitionMap && - operationDefinitionMap[key].documentation?.section === 'elasticsearch' - ) - .sort() - .map((key) => ({ - label: key, - description: ( - <> -

- {key}({operationDefinitionMap[key].documentation?.signature}) -

- - {operationDefinitionMap[key].documentation?.description ? ( - - ) : null} - - ), - })) + ...esFunction.sort().map((key) => ({ + label: key, + description: ( + <> +

+ {key}({operationDefinitionMap[key].documentation?.signature}) +

+ + {operationDefinitionMap[key].documentation?.description ? ( + + ) : null} + + ), + })) ); helpGroups.push({ @@ -236,31 +246,24 @@ max(system.network.in.bytes, reducedTimeRange="30m") // Calculations aggs helpGroups[3].items.push( - ...availableFunctions - .filter( - (key) => - key in operationDefinitionMap && - operationDefinitionMap[key].documentation?.section === 'calculation' - ) - .sort() - .map((key) => ({ - label: key, - description: ( - <> -

- {key}({operationDefinitionMap[key].documentation?.signature}) -

- - {operationDefinitionMap[key].documentation?.description ? ( - - ) : null} - - ), - checked: - selectedFunction === `${key}: ${operationDefinitionMap[key].displayName}` - ? ('on' as const) - : undefined, - })) + ...calculationFunction.sort().map((key) => ({ + label: key, + description: ( + <> +

+ {key}({operationDefinitionMap[key].documentation?.signature}) +

+ + {operationDefinitionMap[key].documentation?.description ? ( + + ) : null} + + ), + checked: + selectedFunction === `${key}: ${operationDefinitionMap[key].displayName}` + ? ('on' as const) + : undefined, + })) ); helpGroups.push({ @@ -274,22 +277,55 @@ max(system.network.in.bytes, reducedTimeRange="30m") items: [], }); - const tinymathFns = useMemo(() => { - return getPossibleFunctions(indexPattern) - .filter((key) => key in tinymathFunctions) - .sort() - .map((key) => { - const [description, examples] = tinymathFunctions[key].help.split(`\`\`\``); - return { - label: key, - description: description.replace(/\n/g, '\n\n'), - examples: examples ? `\`\`\`${examples}\`\`\`` : '', - }; - }); - }, [indexPattern]); + const mathFns = useMemo(() => { + return mathOperations.sort().map((key) => { + const [description, examples] = tinymathFunctions[key].help.split(`\`\`\``); + return { + label: key, + description: description.replace(/\n/g, '\n\n'), + examples: examples ? `\`\`\`${examples}\`\`\`` : '', + }; + }); + }, [mathOperations]); helpGroups[4].items.push( - ...tinymathFns.map(({ label, description, examples }) => { + ...mathFns.map(({ label, description, examples }) => { + return { + label, + description: ( + <> +

{getFunctionSignatureLabel(label, operationDefinitionMap)}

+ + + + ), + }; + }) + ); + + helpGroups.push({ + label: i18n.translate('xpack.lens.formulaDocumentation.comparisonSection', { + defaultMessage: 'Comparison', + }), + description: i18n.translate('xpack.lens.formulaDocumentation.comparisonSectionDescription', { + defaultMessage: 'These functions are used to perform value comparison.', + }), + items: [], + }); + + const comparisonFns = useMemo(() => { + return comparisonOperations.sort().map((key) => { + const [description, examples] = tinymathFunctions[key].help.split(`\`\`\``); + return { + label: key, + description: description.replace(/\n/g, '\n\n'), + examples: examples ? `\`\`\`${examples}\`\`\`` : '', + }; + }); + }, [comparisonOperations]); + + helpGroups[5].items.push( + ...comparisonFns.map(({ label, description, examples }) => { return { label, description: ( diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/index.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/editor/index.ts similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/index.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/editor/index.ts diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/math_completion.test.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/editor/math_completion.test.ts similarity index 99% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/math_completion.test.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/editor/math_completion.test.ts index 79e77c3275ea80..76b70ba9a471c3 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/math_completion.test.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/editor/math_completion.test.ts @@ -11,7 +11,7 @@ import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; import { createMockedIndexPattern } from '../../../../mocks'; import { GenericOperationDefinition } from '../..'; -import type { IndexPatternField, OperationMetadata } from '../../../../../types'; +import type { OperationMetadata, IndexPatternField } from '../../../../../../types'; import { tinymathFunctions } from '../util'; import { getSignatureHelp, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/math_completion.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/editor/math_completion.ts similarity index 99% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/math_completion.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/editor/math_completion.ts index 94b8dcc2a96818..0dba9dc9931511 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/math_completion.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/editor/math_completion.ts @@ -22,9 +22,9 @@ import type { } from '@kbn/unified-search-plugin/public'; import type { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; import { parseTimeShift } from '@kbn/data-plugin/common'; -import type { IndexPattern } from '../../../../../types'; +import type { IndexPattern } from '../../../../../../types'; import { memoizedGetAvailableOperationsByMetadata } from '../../../operations'; -import { tinymathFunctions, groupArgsByType, unquotedStringRegex } from '../util'; +import { tinymathFunctions, groupArgsByType, unquotedStringRegex, nonNullable } from '../util'; import type { GenericOperationDefinition } from '../..'; import { getFunctionSignatureLabel, getHelpTextContent } from './formula_help'; import { hasFunctionFieldArgument } from '../validation'; @@ -78,7 +78,7 @@ export function getInfoAtZeroIndexedPosition( if (ast.type === 'function') { const [match] = ast.args .map((arg) => getInfoAtZeroIndexedPosition(arg, zeroIndexedPosition, ast)) - .filter((a) => a); + .filter(nonNullable); if (match) { return match; } else if (ast.location) { @@ -297,7 +297,7 @@ function getArgumentSuggestions( const fields = validOperation.operations .filter((op) => op.operationType === operation.type) .map((op) => ('field' in op ? op.field : undefined)) - .filter((field) => field); + .filter(nonNullable); const fieldArg = ast.args[0]; const location = typeof fieldArg !== 'string' && (fieldArg as TinymathVariable).location; let range: monaco.IRange | undefined; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/math_tokenization.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/editor/math_tokenization.tsx similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/math_tokenization.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/editor/math_tokenization.tsx diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/formula.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/formula.test.tsx similarity index 90% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/formula.test.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/formula.test.tsx index 9c5cf27e60a88d..90ece71627f421 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/formula.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/formula.test.tsx @@ -13,8 +13,8 @@ import { } from '..'; import type { FormulaIndexPatternColumn } from './formula'; import { insertOrReplaceFormulaColumn } from './parse'; -import type { IndexPatternLayer } from '../../../types'; -import { IndexPattern } from '../../../../types'; +import type { FormBasedLayer } from '../../../types'; +import { IndexPattern } from '../../../../../types'; import { tinymathFunctions } from './util'; import { TermsIndexPatternColumn } from '../terms'; import { MovingAverageIndexPatternColumn } from '../calculations'; @@ -69,7 +69,7 @@ const operationDefinitionMap: Record = { }; describe('formula', () => { - let layer: IndexPatternLayer; + let layer: FormBasedLayer; beforeEach(() => { layer = { @@ -894,7 +894,7 @@ describe('formula', () => { formula: string, isBroken = true, columnParams: Partial> = {} - ): IndexPatternLayer { + ): FormBasedLayer { return { columns: { col1: { @@ -1491,6 +1491,23 @@ invalid: " ).toEqual(undefined); }); + it('returns no error if the formula contains comparison operator within the ifelse operation', () => { + const formulas = [ + ...['lt', 'gt', 'lte', 'gte', 'eq'].map((op) => `${op}(5, 1)`), + ...['<', '>', '==', '>=', '<='].map((symbol) => `5 ${symbol} 1`), + ]; + for (const formula of formulas) { + expect( + formulaOperation.getErrorMessage!( + getNewLayerWithFormula(`ifelse(${formula}, 1, 5)`), + 'col1', + indexPattern, + operationDefinitionMap + ) + ).toEqual(undefined); + } + }); + it('returns no error if a math operation is passed to fullReference operations', () => { const formulas = [ 'derivative(7+1)', @@ -1534,6 +1551,8 @@ invalid: " { formula: 'last_value(dest)' }, { formula: 'terms(dest)' }, { formula: 'moving_average(last_value(dest), window=7)', errorFormula: 'last_value(dest)' }, + ...['lt', 'gt', 'lte', 'gte', 'eq'].map((op) => ({ formula: `${op}(5, 1)` })), + ...['<', '>', '==', '>=', '<='].map((symbol) => ({ formula: `5 ${symbol} 1` })), ]; for (const { formula, errorFormula } of formulas) { expect( @@ -1546,7 +1565,7 @@ invalid: " ).toEqual([ `The return value type of the operation ${ errorFormula ?? formula - } is not supported in Formula.`, + } is not supported in Formula`, ]); } }); @@ -1557,8 +1576,14 @@ invalid: " // * field passed // * missing argument const errors = [ - (operation: string) => - `The first argument for ${operation} should be a operation name. Found ()`, + (operation: string) => { + const required = tinymathFunctions[operation].positionalArguments.filter( + ({ optional }) => !optional + ); + return `The operation ${operation} in the Formula is missing ${ + required.length + } arguments: ${required.map(({ name }) => name).join(', ')}`; + }, (operation: string) => `The operation ${operation} has too many arguments`, (operation: string) => `The operation ${operation} does not accept any field as argument`, (operation: string) => { @@ -1573,9 +1598,11 @@ invalid: " .join(', ')}`; }, ]; + + const mathFns = Object.keys(tinymathFunctions); // we'll try to map all of these here in this test - for (const fn of Object.keys(tinymathFunctions)) { - it(`returns an error for the math functions available: ${fn}`, () => { + for (const fn of mathFns) { + it(`[${fn}] returns an error for the math functions available`, () => { const nArgs = tinymathFunctions[fn].positionalArguments; // start with the first 3 types const formulas = [ @@ -1585,14 +1612,22 @@ invalid: " `${fn}(${Array(nArgs.length).fill('bytes').join(', ')})`, ]; // add the fourth check only for those functions with more than 1 arg required + // and check that this first argument is of type number const enableFourthCheck = nArgs.filter( ({ optional, alternativeWhenMissing }) => !optional && !alternativeWhenMissing - ).length > 1; + ).length > 1 && nArgs[0]?.type === 'number'; if (enableFourthCheck) { formulas.push(`${fn}(1)`); } - formulas.forEach((formula, i) => { + const finalFormulas = formulas.map((text) => { + if (tinymathFunctions[fn].outputType !== 'boolean') { + return text; + } + // for comparison functions wrap the existing formula within the ifelse function + return `ifelse(${text}, 1, 0)`; + }); + finalFormulas.forEach((formula, i) => { expect( formulaOperation.getErrorMessage!( getNewLayerWithFormula(formula), @@ -1600,16 +1635,87 @@ invalid: " indexPattern, operationDefinitionMap ) - ).toEqual([errors[i](fn)]); + ).toContain(errors[i](fn)); }); }); } + // comparison tests + for (const fn of mathFns.filter((name) => tinymathFunctions[name].section === 'comparison')) { + if (tinymathFunctions[fn].outputType === 'boolean') { + it(`[${fn}] returns an error about unsupported return type and when partial arguments are passed`, () => { + const formulas = [`${fn}()`, `${fn}(1)`]; + formulas.forEach((formula, nArg) => { + const expectedCount = tinymathFunctions[fn].positionalArguments.length - nArg; + const expectedArgs = ['left', 'right'].slice(nArg).join(', '); + expect( + formulaOperation.getErrorMessage!( + getNewLayerWithFormula(formula), + 'col1', + indexPattern, + operationDefinitionMap + ) + ).toEqual([ + `The return value type of the operation ${formula} is not supported in Formula`, + `The operation ${fn} in the Formula is missing ${expectedCount} arguments: ${expectedArgs}`, + ]); + }); + }); + } else { + const indexReverseMap = { + cond: [0], + left: [1], + right: [2], + all: [0, 1, 2], + }; + it.each` + cond | left | right | expectedFail + ${'1'} | ${'2'} | ${'3'} | ${'cond'} + ${'1 > 1'} | ${'2 > 2'} | ${'3'} | ${'left'} + ${'1 > 1'} | ${'2'} | ${'3 > 3'} | ${'right'} + ${'1'} | ${'2 > 2'} | ${'3 > 3'} | ${'all'} + ${'count()'} | ${'average(bytes)'} | ${'average(bytes)'} | ${'cond'} + ${'count() > 1'} | ${'average(bytes) > 2'} | ${'average(bytes)'} | ${'left'} + ${'count() > 1'} | ${'average(bytes)'} | ${'average(bytes) > 3'} | ${'right'} + ${'count()'} | ${'average(bytes) > 2'} | ${'average(bytes) > 3'} | ${'all'} + `( + `[${fn}] returns an error if $expectedFail argument is/are of the wrong type: ${fn}($cond, $left, $right)`, + ({ + cond, + left, + right, + expectedFail, + }: { + cond: string; + left: string; + right: string; + expectedFail: keyof typeof indexReverseMap; + }) => { + const argsSorted = [cond, left, right]; + expect( + formulaOperation.getErrorMessage!( + getNewLayerWithFormula(`${fn}(${cond}, ${left}, ${right})`), + 'col1', + indexPattern, + operationDefinitionMap + ) + ).toEqual( + indexReverseMap[expectedFail].map((i) => { + const arg = tinymathFunctions[fn].positionalArguments[i]; + const passedValue = />/.test(argsSorted[i]) ? 'boolean' : 'number'; + return `The ${arg.name} argument for the operation ${fn} in the Formula is of the wrong type: ${passedValue} instead of ${arg.type}`; + }) + ); + } + ); + } + } + it('returns an error suggesting to use an alternative function', () => { const formulas = [`clamp(1)`, 'clamp(1, 5)']; const errorsWithSuggestions = [ - 'The operation clamp in the Formula is missing the min argument: use the pick_max operation instead.', - 'The operation clamp in the Formula is missing the max argument: use the pick_min operation instead.', + 'The operation clamp in the Formula is missing the min argument: use the pick_max operation instead', + 'The operation clamp in the Formula is missing the max argument: use the pick_min operation instead', ]; formulas.forEach((formula, i) => { expect( @@ -1648,7 +1754,7 @@ invalid: " operationDefinitionMap ) ).toEqual([ - `The Formula filter of type "lucene" is not compatible with the inner filter of type "kql" from the ${operation} operation.`, + `The Formula filter of type "lucene" is not compatible with the inner filter of type "kql" from the ${operation} operation`, ]); } }); @@ -1668,8 +1774,8 @@ invalid: " operationDefinitionMap ) ).toEqual([ - `The Formula filter of type "lucene" is not compatible with the inner filter of type "kql" from the count operation.`, - `The Formula filter of type "lucene" is not compatible with the inner filter of type "kql" from the sum operation.`, + `The Formula filter of type "lucene" is not compatible with the inner filter of type "kql" from the count operation`, + `The Formula filter of type "lucene" is not compatible with the inner filter of type "kql" from the sum operation`, ]); }); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/formula.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/formula.tsx similarity index 96% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/formula.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/formula.tsx index 2715ab96cef0cc..9746a25ebf907b 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/formula.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/formula.tsx @@ -8,12 +8,12 @@ import { i18n } from '@kbn/i18n'; import type { BaseIndexPatternColumn, OperationDefinition } from '..'; import type { ReferenceBasedIndexPatternColumn } from '../column_types'; -import type { IndexPattern } from '../../../../types'; +import type { IndexPattern } from '../../../../../types'; import { runASTValidation, tryToParse } from './validation'; import { WrappedFormulaEditor } from './editor'; import { insertOrReplaceFormulaColumn } from './parse'; import { generateFormula } from './generate'; -import { filterByVisibleOperation } from './util'; +import { filterByVisibleOperation, nonNullable } from './util'; import { getManagedColumnsFrom } from '../../layer_helpers'; import { getFilter, isColumnFormatted } from '../helpers'; @@ -77,7 +77,8 @@ export const formulaOperation: OperationDefinition message); + // remove duplicates + return Array.from(new Set(errors.map(({ message }) => message))); } const managedColumns = getManagedColumnsFrom(columnId, layer.columns); @@ -90,7 +91,7 @@ export const formulaOperation: OperationDefinition marker); + .filter(nonNullable); const hasBuckets = layer.columnOrder.some((colId) => layer.columns[colId].isBucketed); const hasOtherMetrics = layer.columnOrder.some((colId) => { const col = layer.columns[colId]; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/formula_public_api.test.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/formula_public_api.test.ts similarity index 96% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/formula_public_api.test.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/formula_public_api.test.ts index c854595757a0ce..4c1ba662d18618 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/formula_public_api.test.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/formula_public_api.test.ts @@ -10,13 +10,13 @@ import { createFormulaPublicApi, FormulaPublicApi } from './formula_public_api'; import type { DataView } from '@kbn/data-views-plugin/public'; import type { DateHistogramIndexPatternColumn, PersistedIndexPatternLayer } from '../../../types'; -import { convertDataViewIntoLensIndexPattern } from '../../../../data_views_service/loader'; +import { convertDataViewIntoLensIndexPattern } from '../../../../../data_views_service/loader'; jest.mock('./parse', () => ({ insertOrReplaceFormulaColumn: jest.fn().mockReturnValue({}), })); -jest.mock('../../../../data_views_service/loader', () => ({ +jest.mock('../../../../../data_views_service/loader', () => ({ convertDataViewIntoLensIndexPattern: jest.fn((v) => v), })); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/formula_public_api.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/formula_public_api.ts similarity index 96% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/formula_public_api.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/formula_public_api.ts index 4085ec931d3a6d..231cd82804c8f6 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/formula_public_api.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/formula_public_api.ts @@ -6,8 +6,8 @@ */ import type { DataView } from '@kbn/data-views-plugin/public'; -import { convertDataViewIntoLensIndexPattern } from '../../../../data_views_service/loader'; -import type { IndexPattern } from '../../../../types'; +import { convertDataViewIntoLensIndexPattern } from '../../../../../data_views_service/loader'; +import type { IndexPattern } from '../../../../../types'; import type { PersistedIndexPatternLayer } from '../../../types'; import { insertOrReplaceFormulaColumn } from './parse'; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/generate.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/generate.ts similarity index 97% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/generate.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/generate.ts index 189a8d342b9031..2315d6d164fc8f 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/generate.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/generate.ts @@ -6,14 +6,14 @@ */ import { isObject } from 'lodash'; -import { DOCUMENT_FIELD_NAME } from '../../../../../common'; +import { DOCUMENT_FIELD_NAME } from '../../../../../../common'; import { FieldBasedIndexPatternColumn, GenericOperationDefinition, GenericIndexPatternColumn, } from '..'; import { BaseIndexPatternColumn, ReferenceBasedIndexPatternColumn } from '../column_types'; -import { IndexPatternLayer } from '../../../types'; +import { FormBasedLayer } from '../../../types'; import { unquotedStringRegex } from './util'; import { isColumnOfType } from '../helpers'; import { StaticValueIndexPatternColumn } from '../static_value'; @@ -37,7 +37,7 @@ export function getSafeFieldName({ export function generateFormula( previousColumn: ReferenceBasedIndexPatternColumn | GenericIndexPatternColumn, - layer: IndexPatternLayer, + layer: FormBasedLayer, previousFormula: string, operationDefinitionMap: Record | undefined ) { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/index.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/index.ts similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/index.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/index.ts diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/math.test.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/math.test.ts similarity index 98% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/math.test.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/math.test.ts index fdf4cc98c59d77..60fc7d5b726322 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/math.test.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/math.test.ts @@ -6,11 +6,11 @@ */ import { TinymathAST } from '@kbn/tinymath'; -import { IndexPattern } from '../../../../types'; -import { IndexPatternLayer } from '../../../types'; +import { IndexPattern } from '../../../../../types'; +import { FormBasedLayer } from '../../../types'; import { MathIndexPatternColumn, mathOperation } from './math'; -function createLayerWithMathColumn(tinymathAst: string | TinymathAST): IndexPatternLayer { +function createLayerWithMathColumn(tinymathAst: string | TinymathAST): FormBasedLayer { return { columnOrder: ['myColumnId'], columns: { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/math.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/math.tsx similarity index 98% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/math.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/math.tsx index c4e0cbed627f2d..de197c2de81893 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/math.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/math.tsx @@ -8,7 +8,7 @@ import type { TinymathAST } from '@kbn/tinymath'; import { OperationDefinition } from '..'; import { ValueFormatConfig, ReferenceBasedIndexPatternColumn } from '../column_types'; -import { IndexPattern } from '../../../../types'; +import { IndexPattern } from '../../../../../types'; export interface MathIndexPatternColumn extends ReferenceBasedIndexPatternColumn { operationType: 'math'; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/math_examples.md b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/math_examples.md similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/math_examples.md rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/math_examples.md diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/mocks/operation_mocks.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/mocks/operation_mocks.ts similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/mocks/operation_mocks.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/mocks/operation_mocks.ts diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/parse.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/parse.ts similarity index 95% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/parse.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/parse.ts index 10789e181dcb92..ea204295500d4c 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/parse.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/parse.ts @@ -8,14 +8,14 @@ import { i18n } from '@kbn/i18n'; import { isObject } from 'lodash'; import type { TinymathAST, TinymathVariable, TinymathLocation } from '@kbn/tinymath'; -import type { IndexPattern } from '../../../../types'; +import type { IndexPattern } from '../../../../../types'; import { OperationDefinition, GenericOperationDefinition, GenericIndexPatternColumn, operationDefinitionMap, } from '..'; -import type { IndexPatternLayer } from '../../../types'; +import type { FormBasedLayer } from '../../../types'; import { mathOperation } from './math'; import { documentField } from '../../../document_field'; import { runASTValidation, shouldHaveFieldArgument, tryToParse } from './validation'; @@ -25,6 +25,7 @@ import { getOperationParams, groupArgsByType, mergeWithGlobalFilters, + nonNullable, } from './util'; import { FormulaIndexPatternColumn, isFormulaIndexPatternColumn } from './formula'; import { getColumnOrder } from '../../layer_helpers'; @@ -36,7 +37,7 @@ export function getManagedId(mainId: string, index: number) { function parseAndExtract( text: string, - layer: IndexPatternLayer, + layer: FormBasedLayer, columnId: string, indexPattern: IndexPattern, operations: Record, @@ -72,7 +73,7 @@ function extractColumns( idPrefix: string, operations: Record, ast: TinymathAST, - layer: IndexPatternLayer, + layer: FormBasedLayer, indexPattern: IndexPattern, label: string ): Array<{ column: GenericIndexPatternColumn; location?: TinymathLocation }> { @@ -89,9 +90,9 @@ function extractColumns( const nodeOperation = operations[node.name]; if (!nodeOperation) { // it's a regular math node - const consumedArgs = node.args - .map(parseNode) - .filter((n) => typeof n !== 'undefined' && n !== null) as Array; + const consumedArgs = node.args.map(parseNode).filter(nonNullable) as Array< + number | TinymathVariable + >; return { ...node, args: consumedArgs, @@ -226,7 +227,7 @@ const getEmptyColumnsWithFormulaMeta = (): { function generateFormulaColumns( id: string, column: FormulaIndexPatternColumn, - layer: IndexPatternLayer, + layer: FormBasedLayer, { indexPattern, operations = operationDefinitionMap }: ExpandColumnProperties ) { const { columns, meta } = getEmptyColumnsWithFormulaMeta(); @@ -273,7 +274,7 @@ function generateFormulaColumns( export function insertOrReplaceFormulaColumn( id: string, column: FormulaIndexPatternColumn, - baseLayer: IndexPatternLayer, + baseLayer: FormBasedLayer, params: ExpandColumnProperties ) { const layer = { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/types.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/types.ts similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/types.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/types.ts diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/util.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/util.ts similarity index 73% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/util.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/util.ts index d66bac4cc87199..4c310b5efa5d3b 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/util.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/util.ts @@ -114,12 +114,16 @@ function getTypeI18n(type: string) { if (type === 'string') { return i18n.translate('xpack.lens.formula.string', { defaultMessage: 'string' }); } + if (type === 'boolean') { + return i18n.translate('xpack.lens.formula.boolean', { defaultMessage: 'boolean' }); + } return ''; } export const tinymathFunctions: Record< string, { + section: 'math' | 'comparison'; positionalArguments: Array<{ name: string; optional?: boolean; @@ -129,9 +133,13 @@ export const tinymathFunctions: Record< }>; // Help is in Markdown format help: string; + // When omitted defaults to "number". + // Used for comparison functions return type + outputType?: string; } > = { add: { + section: 'math', positionalArguments: [ { name: i18n.translate('xpack.lens.formula.left', { defaultMessage: 'left' }), @@ -158,6 +166,7 @@ Example: Offset count by a static value }), }, subtract: { + section: 'math', positionalArguments: [ { name: i18n.translate('xpack.lens.formula.left', { defaultMessage: 'left' }), @@ -179,6 +188,7 @@ Example: Calculate the range of a field }), }, multiply: { + section: 'math', positionalArguments: [ { name: i18n.translate('xpack.lens.formula.left', { defaultMessage: 'left' }), @@ -203,6 +213,7 @@ Example: Calculate price after constant tax rate }), }, divide: { + section: 'math', positionalArguments: [ { name: i18n.translate('xpack.lens.formula.left', { defaultMessage: 'left' }), @@ -226,6 +237,7 @@ Example: \`divide(sum(bytes), 2)\` }), }, abs: { + section: 'math', positionalArguments: [ { name: i18n.translate('xpack.lens.formula.value', { defaultMessage: 'value' }), @@ -241,6 +253,7 @@ Example: Calculate average distance to sea level \`abs(average(altitude))\` }), }, cbrt: { + section: 'math', positionalArguments: [ { name: i18n.translate('xpack.lens.formula.value', { defaultMessage: 'value' }), @@ -257,6 +270,7 @@ Example: Calculate side length from volume }), }, ceil: { + section: 'math', positionalArguments: [ { name: i18n.translate('xpack.lens.formula.value', { defaultMessage: 'value' }), @@ -273,6 +287,7 @@ Example: Round up price to the next dollar }), }, clamp: { + section: 'math', positionalArguments: [ { name: i18n.translate('xpack.lens.formula.value', { defaultMessage: 'value' }), @@ -305,6 +320,7 @@ clamp( }), }, cube: { + section: 'math', positionalArguments: [ { name: i18n.translate('xpack.lens.formula.value', { defaultMessage: 'value' }), @@ -321,6 +337,7 @@ Example: Calculate volume from side length }), }, exp: { + section: 'math', positionalArguments: [ { name: i18n.translate('xpack.lens.formula.value', { defaultMessage: 'value' }), @@ -338,6 +355,7 @@ Example: Calculate the natural exponential function }), }, fix: { + section: 'math', positionalArguments: [ { name: i18n.translate('xpack.lens.formula.value', { defaultMessage: 'value' }), @@ -354,6 +372,7 @@ Example: Rounding towards zero }), }, floor: { + section: 'math', positionalArguments: [ { name: i18n.translate('xpack.lens.formula.value', { defaultMessage: 'value' }), @@ -370,6 +389,7 @@ Example: Round down a price }), }, log: { + section: 'math', positionalArguments: [ { name: i18n.translate('xpack.lens.formula.value', { defaultMessage: 'value' }), @@ -395,6 +415,7 @@ log(sum(bytes), 2) }), }, mod: { + section: 'math', positionalArguments: [ { name: i18n.translate('xpack.lens.formula.value', { defaultMessage: 'value' }), @@ -415,6 +436,7 @@ Example: Calculate last three digits of a value }), }, pow: { + section: 'math', positionalArguments: [ { name: i18n.translate('xpack.lens.formula.value', { defaultMessage: 'value' }), @@ -435,6 +457,7 @@ Example: Calculate volume based on side length }), }, round: { + section: 'math', positionalArguments: [ { name: i18n.translate('xpack.lens.formula.value', { defaultMessage: 'value' }), @@ -460,6 +483,7 @@ round(sum(bytes), 2) }), }, sqrt: { + section: 'math', positionalArguments: [ { name: i18n.translate('xpack.lens.formula.value', { defaultMessage: 'value' }), @@ -476,6 +500,7 @@ Example: Calculate side length based on area }), }, square: { + section: 'math', positionalArguments: [ { name: i18n.translate('xpack.lens.formula.value', { defaultMessage: 'value' }), @@ -492,6 +517,7 @@ Example: Calculate area based on side length }), }, pick_max: { + section: 'math', positionalArguments: [ { name: i18n.translate('xpack.lens.formula.left', { defaultMessage: 'left' }), @@ -512,6 +538,7 @@ Example: Find the maximum between two fields averages }), }, pick_min: { + section: 'math', positionalArguments: [ { name: i18n.translate('xpack.lens.formula.left', { defaultMessage: 'left' }), @@ -532,6 +559,7 @@ Example: Find the minimum between two fields averages }), }, defaults: { + section: 'math', positionalArguments: [ { name: i18n.translate('xpack.lens.formula.value', { defaultMessage: 'value' }), @@ -548,11 +576,170 @@ Returns a default numeric value when value is null. Example: Return -1 when a field has no data \`defaults(average(bytes), -1)\` +`, + }), + }, + lt: { + section: 'comparison', + positionalArguments: [ + { + name: i18n.translate('xpack.lens.formula.left', { defaultMessage: 'left' }), + type: getTypeI18n('number'), + }, + { + name: i18n.translate('xpack.lens.formula.right', { defaultMessage: 'right' }), + type: getTypeI18n('number'), + }, + ], + outputType: getTypeI18n('boolean'), + help: i18n.translate('xpack.lens.formula.ltFunction.markdown', { + defaultMessage: ` +Performs a lower than comparison between two values. +To be used as condition for \`ifelse\` comparison function. +Also works with \`<\` symbol. + +Example: Returns true if the average of bytes is lower than the average amount of memory +\`average(bytes) <= average(memory)\` + +Example: \`lt(average(bytes), 1000)\` + `, + }), + }, + gt: { + section: 'comparison', + positionalArguments: [ + { + name: i18n.translate('xpack.lens.formula.left', { defaultMessage: 'left' }), + type: getTypeI18n('number'), + }, + { + name: i18n.translate('xpack.lens.formula.right', { defaultMessage: 'right' }), + type: getTypeI18n('number'), + }, + ], + outputType: getTypeI18n('boolean'), + help: i18n.translate('xpack.lens.formula.gtFunction.markdown', { + defaultMessage: ` +Performs a greater than comparison between two values. +To be used as condition for \`ifelse\` comparison function. +Also works with \`>\` symbol. + +Example: Returns true if the average of bytes is greater than the average amount of memory +\`average(bytes) > average(memory)\` + +Example: \`gt(average(bytes), 1000)\` + `, + }), + }, + eq: { + section: 'comparison', + positionalArguments: [ + { + name: i18n.translate('xpack.lens.formula.left', { defaultMessage: 'left' }), + type: getTypeI18n('number'), + }, + { + name: i18n.translate('xpack.lens.formula.right', { defaultMessage: 'right' }), + type: getTypeI18n('number'), + }, + ], + outputType: getTypeI18n('boolean'), + help: i18n.translate('xpack.lens.formula.eqFunction.markdown', { + defaultMessage: ` +Performs an equality comparison between two values. +To be used as condition for \`ifelse\` comparison function. +Also works with \`==\` symbol. + +Example: Returns true if the average of bytes is exactly the same amount of average memory +\`average(bytes) == average(memory)\` + +Example: \`eq(sum(bytes), 1000000)\` + `, + }), + }, + lte: { + section: 'comparison', + positionalArguments: [ + { + name: i18n.translate('xpack.lens.formula.left', { defaultMessage: 'left' }), + type: getTypeI18n('number'), + }, + { + name: i18n.translate('xpack.lens.formula.right', { defaultMessage: 'right' }), + type: getTypeI18n('number'), + }, + ], + outputType: getTypeI18n('boolean'), + help: i18n.translate('xpack.lens.formula.lteFunction.markdown', { + defaultMessage: ` +Performs a lower than or equal comparison between two values. +To be used as condition for \`ifelse\` comparison function. +Also works with \`<=\` symbol. + +Example: Returns true if the average of bytes is lower than or equal to the average amount of memory +\`average(bytes) <= average(memory)\` + +Example: \`lte(average(bytes), 1000)\` + `, + }), + }, + gte: { + section: 'comparison', + positionalArguments: [ + { + name: i18n.translate('xpack.lens.formula.left', { defaultMessage: 'left' }), + type: getTypeI18n('number'), + }, + { + name: i18n.translate('xpack.lens.formula.right', { defaultMessage: 'right' }), + type: getTypeI18n('number'), + }, + ], + outputType: getTypeI18n('boolean'), + help: i18n.translate('xpack.lens.formula.gteFunction.markdown', { + defaultMessage: ` +Performs a greater than comparison between two values. +To be used as condition for \`ifelse\` comparison function. +Also works with \`>=\` symbol. + +Example: Returns true if the average of bytes is greater than or equal to the average amount of memory +\`average(bytes) >= average(memory)\` + +Example: \`gte(average(bytes), 1000)\` + `, + }), + }, + ifelse: { + section: 'comparison', + positionalArguments: [ + { + name: i18n.translate('xpack.lens.formula.condition', { defaultMessage: 'condition' }), + type: getTypeI18n('boolean'), + }, + { + name: i18n.translate('xpack.lens.formula.left', { defaultMessage: 'left' }), + type: getTypeI18n('number'), + }, + { + name: i18n.translate('xpack.lens.formula.right', { defaultMessage: 'right' }), + type: getTypeI18n('number'), + }, + ], + help: i18n.translate('xpack.lens.formula.ifElseFunction.markdown', { + defaultMessage: ` +Returns a value depending on whether the element of condition is true or false. + +Example: Average revenue per customer but in some cases customer id is not provided which counts as additional customer +\`sum(total)/(unique_count(customer_id) + ifelse( count() > count(kql='customer_id:*'), 1, 0))\` `, }), }, }; +export function nonNullable(v: T): v is NonNullable { + return v != null; +} + export function isMathNode(node: TinymathAST | string) { return isObject(node) && node.type === 'function' && tinymathFunctions[node.name]; } @@ -562,7 +749,7 @@ export function findMathNodes(root: TinymathAST | string): TinymathFunction[] { if (!isObject(node) || node.type !== 'function' || !isMathNode(node)) { return []; } - return [node, ...node.args.flatMap(flattenMathNodes)].filter(Boolean); + return [node, ...node.args.flatMap(flattenMathNodes)].filter(nonNullable); } return flattenMathNodes(root); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/validation.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/validation.ts similarity index 89% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/validation.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/validation.ts index a7ffc57a2361ef..1601e53fef33d8 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/validation.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/validation.ts @@ -19,6 +19,7 @@ import { getValueOrName, groupArgsByType, isMathNode, + nonNullable, tinymathFunctions, } from './util'; @@ -27,8 +28,8 @@ import type { GenericIndexPatternColumn, GenericOperationDefinition, } from '..'; -import type { IndexPatternLayer } from '../../../types'; -import type { IndexPattern } from '../../../../types'; +import type { FormBasedLayer } from '../../../types'; +import type { IndexPattern } from '../../../../../types'; import type { TinymathNodeTypes } from './types'; interface ValidationErrors { @@ -45,6 +46,10 @@ interface ValidationErrors { message: string; type: { operation: string; params: string }; }; + wrongTypeArgument: { + message: string; + type: { operation: string; name: string; type: string; expectedType: string }; + }; wrongFirstArgument: { message: string; type: { operation: string; type: string; argument: string | number }; @@ -109,6 +114,26 @@ export interface ErrorWrapper { severity?: 'error' | 'warning'; } +function getNodeLocation(node: TinymathFunction): TinymathLocation[] { + return [node.location].filter(nonNullable); +} + +function getArgumentType(arg: TinymathAST, operations: Record) { + if (!isObject(arg)) { + return typeof arg; + } + if (arg.type === 'function') { + if (tinymathFunctions[arg.name]) { + return tinymathFunctions[arg.name].outputType ?? 'number'; + } + // Assume it's a number for now + if (operations[arg.name]) { + return 'number'; + } + } + // leave for now other argument types +} + export function isParsingError(message: string) { return message.includes('Failed to parse expression'); } @@ -118,7 +143,7 @@ function findFunctionNodes(root: TinymathAST | string): TinymathFunction[] { if (!isObject(node) || node.type !== 'function') { return []; } - return [node, ...node.args.flatMap(flattenFunctionNodes)].filter(Boolean); + return [node, ...node.args.flatMap(flattenFunctionNodes)].filter(nonNullable); } return flattenFunctionNodes(root); @@ -132,14 +157,15 @@ export function hasInvalidOperations( return { // avoid duplicates names: Array.from(new Set(nodes.map(({ name }) => name))), - locations: nodes.map(({ location }) => location).filter((a) => a) as TinymathLocation[], + locations: nodes.map(({ location }) => location).filter(nonNullable), }; } export const getRawQueryValidationError = (text: string, operations: Record) => { // try to extract the query context here const singleLine = text.split('\n').join(''); - const allArgs = singleLine.split(',').filter((args) => /(kql|lucene)/.test(args)); + const languagesRegexp = /(kql|lucene)/; + const allArgs = singleLine.split(',').filter((args) => languagesRegexp.test(args)); // check for the presence of a valid ES operation const containsOneValidOperation = Object.keys(operations).some((operation) => singleLine.includes(operation) @@ -153,7 +179,7 @@ export const getRawQueryValidationError = (text: string, operations: Record - arg.split('count').filter((subArg) => /(kql|lucene)/.test(subArg)) + arg.split('count').filter((subArg) => languagesRegexp.test(subArg)) ); const [kqlQueries, luceneQueries] = partition(flattenArgs, (arg) => /kql/.test(arg)); const errors = []; @@ -260,6 +286,18 @@ function getMessageFromId({ values: { operation: out.operation, params: out.params }, }); break; + case 'wrongTypeArgument': + message = i18n.translate('xpack.lens.indexPattern.formulaExpressionWrongTypeArgument', { + defaultMessage: + 'The {name} argument for the operation {operation} in the Formula is of the wrong type: {type} instead of {expectedType}', + values: { + operation: out.operation, + name: out.name, + type: out.type, + expectedType: out.expectedType, + }, + }); + break; case 'duplicateArgument': message = i18n.translate('xpack.lens.indexPattern.formulaOperationDuplicateParams', { defaultMessage: @@ -332,21 +370,20 @@ function getMessageFromId({ break; case 'wrongReturnedType': message = i18n.translate('xpack.lens.indexPattern.formulaOperationWrongReturnedType', { - defaultMessage: - 'The return value type of the operation {text} is not supported in Formula.', + defaultMessage: 'The return value type of the operation {text} is not supported in Formula', values: { text: out.text }, }); break; case 'filtersTypeConflict': message = i18n.translate('xpack.lens.indexPattern.formulaOperationFiltersTypeConflicts', { defaultMessage: - 'The Formula filter of type "{outerType}" is not compatible with the inner filter of type "{innerType}" from the {operation} operation.', + 'The Formula filter of type "{outerType}" is not compatible with the inner filter of type "{innerType}" from the {operation} operation', values: { operation: out.operation, outerType: out.outerType, innerType: out.innerType }, }); break; case 'useAlternativeFunction': message = i18n.translate('xpack.lens.indexPattern.formulaUseAlternative', { - defaultMessage: `The operation {operation} in the Formula is missing the {params} argument: use the {alternativeFn} operation instead.`, + defaultMessage: `The operation {operation} in the Formula is missing the {params} argument: use the {alternativeFn} operation instead`, values: { operation: out.operation, params: out.params, alternativeFn: out.alternativeFn }, }); break; @@ -397,13 +434,14 @@ export function tryToParse( export function runASTValidation( ast: TinymathAST, - layer: IndexPatternLayer, + layer: FormBasedLayer, indexPattern: IndexPattern, operations: Record, currentColumn: GenericIndexPatternColumn ) { return [ ...checkMissingVariableOrFunctions(ast, layer, indexPattern, operations), + ...checkTopNodeReturnType(ast), ...runFullASTValidation(ast, layer, indexPattern, operations, currentColumn), ]; } @@ -426,7 +464,7 @@ function checkVariableEdgeCases(ast: TinymathAST, missingVariables: Set) function checkMissingVariableOrFunctions( ast: TinymathAST, - layer: IndexPatternLayer, + layer: FormBasedLayer, indexPattern: IndexPattern, operations: Record ): ErrorWrapper[] { @@ -548,7 +586,7 @@ function validateFiltersArguments( innerType, outerType, }, - locations: node.location ? [node.location] : [], + locations: getNodeLocation(node), }) ); } @@ -574,7 +612,7 @@ function validateNameArguments( operation: node.name, params: missingParams.map(({ name }) => name).join(', '), }, - locations: node.location ? [node.location] : [], + locations: getNodeLocation(node), }) ); } @@ -587,7 +625,7 @@ function validateNameArguments( operation: node.name, params: wrongTypeParams.map(({ name }) => name).join(', '), }, - locations: node.location ? [node.location] : [], + locations: getNodeLocation(node), }) ); } @@ -600,7 +638,7 @@ function validateNameArguments( operation: node.name, params: duplicateParams.join(', '), }, - locations: node.location ? [node.location] : [], + locations: getNodeLocation(node), }) ); } @@ -614,16 +652,37 @@ function validateNameArguments( getMessageFromId({ messageId: 'tooManyQueries', values: {}, - locations: node.location ? [node.location] : [], + locations: getNodeLocation(node), }) ); } return errors; } +const DEFAULT_RETURN_TYPE = 'number'; +function checkTopNodeReturnType(ast: TinymathAST): ErrorWrapper[] { + if ( + isObject(ast) && + ast.type === 'function' && + ast.text && + (tinymathFunctions[ast.name]?.outputType || DEFAULT_RETURN_TYPE) !== DEFAULT_RETURN_TYPE + ) { + return [ + getMessageFromId({ + messageId: 'wrongReturnedType', + values: { + text: ast.text, + }, + locations: getNodeLocation(ast), + }), + ]; + } + return []; +} + function runFullASTValidation( ast: TinymathAST, - layer: IndexPatternLayer, + layer: FormBasedLayer, indexPattern: IndexPattern, operations: Record, currentColumn?: GenericIndexPatternColumn @@ -645,7 +704,7 @@ function runFullASTValidation( const [firstArg] = node?.args || []; if (!nodeOperation) { - errors.push(...validateMathNodes(node, missingVariablesSet)); + errors.push(...validateMathNodes(node, missingVariablesSet, operations)); // carry on with the validation for all the functions within the math operation if (functions?.length) { return errors.concat(functions.flatMap((fn) => validateNode(fn))); @@ -664,7 +723,7 @@ function runFullASTValidation( }), argument: `math operation`, }, - locations: node.location ? [node.location] : [], + locations: getNodeLocation(node), }) ); } else { @@ -683,7 +742,7 @@ function runFullASTValidation( defaultMessage: 'no field', }), }, - locations: node.location ? [node.location] : [], + locations: getNodeLocation(node), }) ); } @@ -716,7 +775,7 @@ function runFullASTValidation( values: { operation: node.name, }, - locations: node.location ? [node.location] : [], + locations: getNodeLocation(node), }) ); } else { @@ -742,7 +801,8 @@ function runFullASTValidation( // In general this should be handled down the Esaggs route rather than here const isFirstArgumentNotValid = Boolean( !isArgumentValidType(firstArg, 'function') || - (isMathNode(firstArg) && validateMathNodes(firstArg, missingVariablesSet).length) + (isMathNode(firstArg) && + validateMathNodes(firstArg, missingVariablesSet, operations).length) ); // First field has a special handling if (isFirstArgumentNotValid) { @@ -760,7 +820,7 @@ function runFullASTValidation( defaultMessage: 'no operation', }), }, - locations: node.location ? [node.location] : [], + locations: getNodeLocation(node), }) ); } @@ -786,7 +846,7 @@ function runFullASTValidation( values: { operation: node.name, }, - locations: node.location ? [node.location] : [], + locations: getNodeLocation(node), }) ); } else { @@ -946,22 +1006,27 @@ export function isArgumentValidType(arg: TinymathAST | string, type: TinymathNod return isObject(arg) && arg.type === type; } -export function validateMathNodes(root: TinymathAST, missingVariableSet: Set) { +export function validateMathNodes( + root: TinymathAST, + missingVariableSet: Set, + operations: Record +) { const mathNodes = findMathNodes(root); const errors: ErrorWrapper[] = []; mathNodes.forEach((node: TinymathFunction) => { const { positionalArguments } = tinymathFunctions[node.name]; + const mandatoryArguments = positionalArguments.filter(({ optional }) => !optional); if (!node.args.length) { // we can stop here return errors.push( getMessageFromId({ - messageId: 'wrongFirstArgument', + messageId: 'missingMathArgument', values: { operation: node.name, - type: 'operation', - argument: `()`, + count: mandatoryArguments.length, + params: mandatoryArguments.map(({ name }) => name).join(', '), }, - locations: node.location ? [node.location] : [], + locations: getNodeLocation(node), }) ); } @@ -973,12 +1038,12 @@ export function validateMathNodes(root: TinymathAST, missingVariableSet: Set { const arg = node.args[index]; if (arg != null && typeof arg !== 'number') { @@ -992,12 +1057,11 @@ export function validateMathNodes(root: TinymathAST, missingVariableSet: Set !optional); // if there is only 1 mandatory arg, this is already handled by the wrongFirstArgument check if (mandatoryArguments.length > 1 && node.args.length < mandatoryArguments.length) { const missingArgs = mandatoryArguments.filter((_, i) => node.args[i] == null); @@ -1020,7 +1084,7 @@ export function validateMathNodes(root: TinymathAST, missingVariableSet: Set name).join(', '), }, - locations: node.location ? [node.location] : [], + locations: getNodeLocation(node), }) ); } @@ -1035,11 +1099,37 @@ export function validateMathNodes(root: TinymathAST, missingVariableSet: Set { + const arg = node.args[index]; + if (arg != null) { + const argType = getArgumentType(arg, operations); + if (argType && argType !== type) { + return index; + } + } + }) + .filter(nonNullable); + for (const wrongTypeArgumentIndex of wrongTypeArgumentIndexes) { + const arg = node.args[wrongTypeArgumentIndex]; + errors.push( + getMessageFromId({ + messageId: 'wrongTypeArgument', + values: { + operation: node.name, + name: positionalArguments[wrongTypeArgumentIndex].name, + type: getArgumentType(arg, operations) || 'number', + expectedType: positionalArguments[wrongTypeArgumentIndex].type || '', + }, + locations: getNodeLocation(node), + }) + ); + } }); return errors; } @@ -1073,7 +1163,7 @@ function validateFieldArguments( supported: 1, text: (fields as TinymathVariable[]).map(({ text }) => text).join(', '), }, - locations: node.location ? [node.location] : [], + locations: getNodeLocation(node), }) ); } @@ -1085,7 +1175,7 @@ function validateFieldArguments( values: { text: node.text ?? `${node.name}(${getValueOrName(firstArg)})`, }, - locations: node.location ? [node.location] : [], + locations: getNodeLocation(node), }) ); } @@ -1101,7 +1191,7 @@ function validateFieldArguments( defaultMessage: 'field', }), }, - locations: node.location ? [node.location] : [], + locations: getNodeLocation(node), }) ); } @@ -1133,7 +1223,7 @@ function validateFunctionArguments( defaultMessage: 'metric', }), }, - locations: node.location ? [node.location] : [], + locations: getNodeLocation(node), }) ); } else { @@ -1146,7 +1236,7 @@ function validateFunctionArguments( supported: requiredFunctions, text: (esOperations as TinymathFunction[]).map(({ text }) => text).join(', '), }, - locations: node.location ? [node.location] : [], + locations: getNodeLocation(node), }) ); } @@ -1164,7 +1254,7 @@ function validateFunctionArguments( type, text: (mathOperations as TinymathFunction[]).map(({ text }) => text).join(', '), }, - locations: node.location ? [node.location] : [], + locations: getNodeLocation(node), }) ); } diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/get_group_by_key.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/get_group_by_key.ts similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/get_group_by_key.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/get_group_by_key.ts diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/helpers.test.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/helpers.test.ts similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/helpers.test.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/helpers.test.ts diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/helpers.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/helpers.tsx similarity index 96% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/helpers.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/helpers.tsx index 868d5e2557e49f..32d39f9527ef4b 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/helpers.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/helpers.tsx @@ -6,14 +6,14 @@ */ import { i18n } from '@kbn/i18n'; -import type { IndexPattern, IndexPatternField } from '../../../types'; +import type { IndexPattern, IndexPatternField } from '../../../../types'; import { GenericIndexPatternColumn, operationDefinitionMap } from '.'; import { FieldBasedIndexPatternColumn, FormattedIndexPatternColumn, ReferenceBasedIndexPatternColumn, } from './column_types'; -import type { IndexPatternLayer } from '../../types'; +import type { FormBasedLayer } from '../../types'; import { hasField } from '../../pure_utils'; export function getInvalidFieldMessage( @@ -132,8 +132,8 @@ export function isColumnOfType( export const isColumn = ( setter: | GenericIndexPatternColumn - | IndexPatternLayer - | ((prevLayer: IndexPatternLayer) => IndexPatternLayer) + | FormBasedLayer + | ((prevLayer: FormBasedLayer) => FormBasedLayer) ): setter is GenericIndexPatternColumn => { return 'operationType' in setter; }; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/index.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/index.ts similarity index 95% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/index.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/index.ts index bde67ea14a4888..5253267b286cd7 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/index.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/index.ts @@ -55,17 +55,17 @@ import { IndexPatternField, OperationMetadata, ParamEditorCustomProps, -} from '../../../types'; +} from '../../../../types'; import type { BaseIndexPatternColumn, IncompleteColumn, GenericIndexPatternColumn, ReferenceBasedIndexPatternColumn, } from './column_types'; -import { DataViewDragDropOperation, IndexPatternLayer } from '../../types'; -import { DateRange, LayerType } from '../../../../common'; +import { DataViewDragDropOperation, FormBasedLayer } from '../../types'; +import { DateRange, LayerType } from '../../../../../common'; import { rangeOperation } from './ranges'; -import { IndexPatternDimensionEditorProps, OperationSupportMatrix } from '../../dimension_panel'; +import { FormBasedDimensionEditorProps, OperationSupportMatrix } from '../../dimension_panel'; import type { OriginalColumn } from '../../to_expression'; import { ReferenceEditorProps } from '../../dimension_panel/reference_editor'; @@ -174,10 +174,10 @@ export { staticValueOperation } from './static_value'; */ export interface ParamEditorProps< C, - U = IndexPatternLayer | ((prevLayer: IndexPatternLayer) => IndexPatternLayer) + U = FormBasedLayer | ((prevLayer: FormBasedLayer) => FormBasedLayer) > { currentColumn: C; - layer: IndexPatternLayer; + layer: FormBasedLayer; paramEditorUpdater: (setter: U) => void; ReferenceEditor?: (props: ReferenceEditorProps) => JSX.Element | null; toggleFullscreen: () => void; @@ -195,7 +195,7 @@ export interface ParamEditorProps< fieldFormats: FieldFormatsStart; unifiedSearch: UnifiedSearchPublicPluginStart; dataViews: DataViewsPublicPluginStart; - activeData?: IndexPatternDimensionEditorProps['activeData']; + activeData?: FormBasedDimensionEditorProps['activeData']; operationDefinitionMap: Record; paramEditorCustomProps?: ParamEditorCustomProps; existingFields: Record>; @@ -203,20 +203,18 @@ export interface ParamEditorProps< } export interface FieldInputProps { - layer: IndexPatternLayer; + layer: FormBasedLayer; selectedColumn?: C; columnId: string; indexPattern: IndexPattern; - updateLayer: ( - setter: IndexPatternLayer | ((prevLayer: IndexPatternLayer) => IndexPatternLayer) - ) => void; + updateLayer: (setter: FormBasedLayer | ((prevLayer: FormBasedLayer) => FormBasedLayer)) => void; onDeleteColumn?: () => void; currentFieldIsInvalid: boolean; incompleteField: IncompleteColumn['sourceField'] | null; incompleteOperation: IncompleteColumn['operationType']; incompleteParams: Omit; - dimensionGroups: IndexPatternDimensionEditorProps['dimensionGroups']; - groupId: IndexPatternDimensionEditorProps['groupId']; + dimensionGroups: FormBasedDimensionEditorProps['dimensionGroups']; + groupId: FormBasedDimensionEditorProps['groupId']; /** * indexPatternId -> fieldName -> boolean */ @@ -271,7 +269,7 @@ interface BaseOperationDefinitionProps< * Based on the current column and the other updated columns, this function has to * return an updated column. If not implemented, the `id` function is used instead. */ - onOtherColumnChanged?: (layer: IndexPatternLayer, thisColumnId: string) => C; + onOtherColumnChanged?: (layer: FormBasedLayer, thisColumnId: string) => C; /** * React component for operation specific settings shown in the flyout editor */ @@ -303,7 +301,7 @@ interface BaseOperationDefinitionProps< */ getDisabledStatus?: ( indexPattern: IndexPattern, - layer: IndexPatternLayer, + layer: FormBasedLayer, layerType?: LayerType ) => string | undefined; /** @@ -313,7 +311,7 @@ interface BaseOperationDefinitionProps< * - Missing references */ getErrorMessage?: ( - layer: IndexPatternLayer, + layer: FormBasedLayer, columnId: string, indexPattern: IndexPattern, operationDefinitionMap?: Record @@ -329,7 +327,7 @@ interface BaseOperationDefinitionProps< core: CoreStart, frame: FrameDatasourceAPI, layerId: string - ) => Promise; + ) => Promise; }; } > @@ -453,7 +451,7 @@ interface BaseOperationDefinitionProps< } interface BaseBuildColumnArgs { - layer: IndexPatternLayer; + layer: FormBasedLayer; indexPattern: IndexPattern; } @@ -499,7 +497,7 @@ interface FieldlessOperationDefinition column: C, columnId: string, indexPattern: IndexPattern, - layer: IndexPatternLayer, + layer: FormBasedLayer, uiSettings: IUiSettingsClient ) => ExpressionAstFunction; } @@ -556,7 +554,7 @@ interface FieldBasedOperationDefinition @@ -568,7 +566,7 @@ interface FieldBasedOperationDefinition @@ -584,7 +582,7 @@ interface FieldBasedOperationDefinition Promise; + ) => Promise; }; } > @@ -652,7 +650,7 @@ interface FullReferenceOperationDefinition { * A chain of expression functions which will transform the table */ toExpression: ( - layer: IndexPatternLayer, + layer: FormBasedLayer, columnId: string, indexPattern: IndexPattern ) => ExpressionAstFunction[]; @@ -680,7 +678,7 @@ interface ManagedReferenceOperationDefinition * A chain of expression functions which will transform the table */ toExpression: ( - layer: IndexPatternLayer, + layer: FormBasedLayer, columnId: string, indexPattern: IndexPattern ) => ExpressionAstFunction[]; @@ -689,11 +687,11 @@ interface ManagedReferenceOperationDefinition * root level */ createCopy: ( - layers: Record, + layers: Record, source: DataViewDragDropOperation, target: DataViewDragDropOperation, operationDefinitionMap: Record - ) => Record; + ) => Record; } interface OperationDefinitionMap { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/last_value.test.tsx similarity index 99% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.test.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/last_value.test.tsx index 05386492544f48..16c6f2727ea509 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/last_value.test.tsx @@ -17,8 +17,8 @@ import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; import { createMockedIndexPattern } from '../../mocks'; import { LastValueIndexPatternColumn } from './last_value'; import { lastValueOperation } from '.'; -import type { IndexPatternLayer } from '../../types'; -import type { IndexPattern } from '../../../types'; +import type { FormBasedLayer } from '../../types'; +import type { IndexPattern } from '../../../../types'; import { TermsIndexPatternColumn } from './terms'; import { EuiSwitch, EuiSwitchEvent } from '@elastic/eui'; import { buildExpression, parseExpression } from '@kbn/expressions-plugin/common'; @@ -55,7 +55,7 @@ const defaultProps = { }; describe('last_value', () => { - let layer: IndexPatternLayer; + let layer: FormBasedLayer; const InlineOptions = lastValueOperation.paramEditor!; beforeEach(() => { @@ -506,7 +506,7 @@ describe('last_value', () => { }, columnOrder: [], indexPatternId: '', - } as IndexPatternLayer; + } as FormBasedLayer; expect( lastValueOperation.buildColumn({ @@ -829,7 +829,7 @@ describe('last_value', () => { describe('getErrorMessage', () => { let indexPattern: IndexPattern; - let errorLayer: IndexPatternLayer; + let errorLayer: FormBasedLayer; beforeEach(() => { indexPattern = createMockedIndexPattern(); errorLayer = { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/last_value.tsx similarity index 99% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/last_value.tsx index 4206cd81097601..59b77cd73fc9d5 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/last_value.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/last_value.tsx @@ -20,8 +20,8 @@ import { AggFunctionsMapping } from '@kbn/data-plugin/public'; import { buildExpressionFunction } from '@kbn/expressions-plugin/public'; import { OperationDefinition } from '.'; import { FieldBasedIndexPatternColumn, ValueFormatConfig } from './column_types'; -import type { IndexPatternField, IndexPattern } from '../../../types'; -import { DataType } from '../../../types'; +import type { IndexPatternField, IndexPattern } from '../../../../types'; +import { DataType } from '../../../../types'; import { getFormatFromPreviousColumn, getInvalidFieldMessage, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.test.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/metrics.test.ts similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.test.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/metrics.test.ts diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/metrics.tsx similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/metrics.tsx diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/percentile.test.tsx similarity index 99% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.test.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/percentile.test.tsx index 77434d7ecc7ad0..e78ac9e9360da9 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/percentile.test.tsx @@ -18,7 +18,7 @@ import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; import { createMockedIndexPattern } from '../../mocks'; import { percentileOperation } from '.'; -import { IndexPatternLayer } from '../../types'; +import { FormBasedLayer } from '../../types'; import { PercentileIndexPatternColumn } from './percentile'; import { TermsIndexPatternColumn } from './terms'; import { @@ -27,7 +27,7 @@ import { ExpressionAstExpressionBuilder, } from '@kbn/expressions-plugin/public'; import type { OriginalColumn } from '../../to_expression'; -import { IndexPattern } from '../../../types'; +import { IndexPattern } from '../../../../types'; import faker from 'faker'; jest.mock('lodash', () => { @@ -71,7 +71,7 @@ const defaultProps = { }; describe('percentile', () => { - let layer: IndexPatternLayer; + let layer: FormBasedLayer; const InlineOptions = percentileOperation.paramEditor!; beforeEach(() => { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/percentile.tsx similarity index 99% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/percentile.tsx index ec4a3d569e7da0..f391e3a6f9a2f4 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/percentile.tsx @@ -28,7 +28,7 @@ import { } from './helpers'; import { FieldBasedIndexPatternColumn } from './column_types'; import { adjustTimeScaleLabelSuffix } from '../time_scale_utils'; -import { useDebouncedValue } from '../../../shared_components'; +import { useDebouncedValue } from '../../../../shared_components'; import { getDisallowedPreviousShiftMessage } from '../../time_shift_utils'; import { FormRow } from './shared_components'; import { getColumnReducedTimeRangeError } from '../../reduced_time_range_utils'; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile_ranks.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/percentile_ranks.test.tsx similarity index 98% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile_ranks.test.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/percentile_ranks.test.tsx index a0c69a7354849c..adb0d8e491fd7c 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile_ranks.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/percentile_ranks.test.tsx @@ -18,10 +18,10 @@ import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; import { createMockedIndexPattern } from '../../mocks'; import { percentileRanksOperation } from '.'; -import { IndexPatternLayer } from '../../types'; +import { FormBasedLayer } from '../../types'; import type { PercentileRanksIndexPatternColumn } from './percentile_ranks'; import { TermsIndexPatternColumn } from './terms'; -import { IndexPattern } from '../../../types'; +import { IndexPattern } from '../../../../types'; jest.mock('lodash', () => { const original = jest.requireActual('lodash'); @@ -64,7 +64,7 @@ const defaultProps = { }; describe('percentile ranks', () => { - let layer: IndexPatternLayer; + let layer: FormBasedLayer; const InlineOptions = percentileRanksOperation.paramEditor!; beforeEach(() => { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile_ranks.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/percentile_ranks.tsx similarity index 99% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile_ranks.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/percentile_ranks.tsx index 45bd05f37372fe..3d7b12802858c5 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/percentile_ranks.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/percentile_ranks.tsx @@ -22,7 +22,7 @@ import { } from './helpers'; import { FieldBasedIndexPatternColumn } from './column_types'; import { adjustTimeScaleLabelSuffix } from '../time_scale_utils'; -import { useDebouncedValue } from '../../../shared_components'; +import { useDebouncedValue } from '../../../../shared_components'; import { getDisallowedPreviousShiftMessage } from '../../time_shift_utils'; import { FormRow } from './shared_components'; import { getColumnReducedTimeRangeError } from '../../reduced_time_range_utils'; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/advanced_editor.scss b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/ranges/advanced_editor.scss similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/advanced_editor.scss rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/ranges/advanced_editor.scss diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/advanced_editor.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/ranges/advanced_editor.tsx similarity index 99% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/advanced_editor.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/ranges/advanced_editor.tsx index d3f5000646bc9c..c3212642e0064f 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/advanced_editor.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/ranges/advanced_editor.tsx @@ -28,7 +28,7 @@ import { DraggableBucketContainer, NewBucketButton, useDebounceWithOptions, -} from '../../../../shared_components'; +} from '../../../../../shared_components'; import { RangeTypeLens, isValidRange } from './ranges'; import { FROM_PLACEHOLDER, TO_PLACEHOLDER, TYPING_DEBOUNCE_TIME } from './constants'; import { LabelInput } from '../shared_components'; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/constants.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/ranges/constants.ts similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/constants.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/ranges/constants.ts diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/index.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/ranges/index.ts similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/index.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/ranges/index.ts diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/range_editor.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/ranges/range_editor.tsx similarity index 99% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/range_editor.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/ranges/range_editor.tsx index 92f0196b9cbb53..1f7565c9d31d65 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/range_editor.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/ranges/range_editor.tsx @@ -26,7 +26,7 @@ import { UI_SETTINGS } from '@kbn/data-plugin/public'; import { RangeColumnParams, UpdateParamsFnType, MODES_TYPES } from './ranges'; import { AdvancedRangeEditor } from './advanced_editor'; import { TYPING_DEBOUNCE_TIME, MODES, MIN_HISTOGRAM_BARS } from './constants'; -import { useDebounceWithOptions } from '../../../../shared_components'; +import { useDebounceWithOptions } from '../../../../../shared_components'; import { HelpPopover, HelpPopoverButton } from '../../../help_popover'; const GranularityHelpPopover = () => { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/ranges.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/ranges/ranges.test.tsx similarity index 99% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/ranges.test.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/ranges/ranges.test.tsx index 874559ae66c191..d0dd9f64586120 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/ranges.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/ranges/ranges.test.tsx @@ -15,7 +15,7 @@ import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; import { fieldFormatsServiceMock } from '@kbn/field-formats-plugin/public/mocks'; import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks'; -import type { IndexPatternLayer } from '../../../types'; +import type { FormBasedLayer } from '../../../types'; import { rangeOperation } from '..'; import { RangeIndexPatternColumn } from './ranges'; import { @@ -26,9 +26,9 @@ import { SLICES, } from './constants'; import { RangePopover } from './advanced_editor'; -import { DragDropBuckets } from '../../../../shared_components'; +import { DragDropBuckets } from '../../../../../shared_components'; import { getFieldByNameFactory } from '../../../pure_helpers'; -import { IndexPattern } from '../../../../types'; +import { IndexPattern } from '../../../../../types'; // mocking random id generator function jest.mock('@elastic/eui', () => { @@ -136,7 +136,7 @@ const defaultOptions = { }; describe('ranges', () => { - let layer: IndexPatternLayer; + let layer: FormBasedLayer; const InlineOptions = rangeOperation.paramEditor!; const MAX_HISTOGRAM_VALUE = 100; const GRANULARITY_DEFAULT_VALUE = (MAX_HISTOGRAM_VALUE - MIN_HISTOGRAM_BARS) / 2; @@ -156,7 +156,7 @@ describe('ranges', () => { column.params.type = MODES.Range; } - function getDefaultLayer(): IndexPatternLayer { + function getDefaultLayer(): FormBasedLayer { return { indexPatternId: '1', columnOrder: ['col1', 'col2'], diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/ranges.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/ranges/ranges.tsx similarity index 98% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/ranges.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/ranges/ranges.tsx index 52c9471aefe0e7..2dab571dcfc392 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/ranges.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/ranges/ranges.tsx @@ -15,9 +15,9 @@ import { RangeEditor } from './range_editor'; import { OperationDefinition } from '..'; import { FieldBasedIndexPatternColumn } from '../column_types'; import { updateColumnParam } from '../../layer_helpers'; -import { supportedFormats } from '../../../../../common/expressions/format_column/supported_formats'; +import { supportedFormats } from '../../../../../../common/expressions/format_column/supported_formats'; import { MODES, AUTO_BARS, DEFAULT_INTERVAL, MIN_HISTOGRAM_BARS, SLICES } from './constants'; -import { IndexPattern, IndexPatternField } from '../../../../types'; +import { IndexPattern, IndexPatternField } from '../../../../../types'; import { getInvalidFieldMessage, isValidNumber } from '../helpers'; type RangeType = Omit; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/shared_components/form_row.scss b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/shared_components/form_row.scss similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/shared_components/form_row.scss rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/shared_components/form_row.scss diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/shared_components/form_row.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/shared_components/form_row.tsx similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/shared_components/form_row.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/shared_components/form_row.tsx diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/shared_components/index.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/shared_components/index.tsx similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/shared_components/index.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/shared_components/index.tsx diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/shared_components/label_input.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/shared_components/label_input.tsx similarity index 96% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/shared_components/label_input.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/shared_components/label_input.tsx index 4bc461aaa319bf..9d8730d38216ad 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/shared_components/label_input.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/shared_components/label_input.tsx @@ -8,7 +8,7 @@ import React, { useRef } from 'react'; import { EuiFieldText, keys } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { useDebouncedValue } from '../../../../shared_components'; +import { useDebouncedValue } from '../../../../../shared_components'; export const LabelInput = ({ value, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/static_value.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/static_value.test.tsx similarity index 98% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/static_value.test.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/static_value.test.tsx index a93b1ece5e13fc..0ed6a60677f732 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/static_value.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/static_value.test.tsx @@ -17,8 +17,8 @@ import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; import { createMockedIndexPattern } from '../../mocks'; import { staticValueOperation } from '.'; -import { IndexPatternLayer } from '../../types'; -import { IndexPattern } from '../../../types'; +import { FormBasedLayer } from '../../types'; +import { IndexPattern } from '../../../../types'; import { StaticValueIndexPatternColumn } from './static_value'; import { TermsIndexPatternColumn } from './terms'; @@ -63,7 +63,7 @@ const defaultProps = { }; describe('static_value', () => { - let layer: IndexPatternLayer; + let layer: FormBasedLayer; beforeEach(() => { layer = { @@ -97,7 +97,7 @@ describe('static_value', () => { }; }); - function getLayerWithStaticValue(newValue: string | null | undefined): IndexPatternLayer { + function getLayerWithStaticValue(newValue: string | null | undefined): FormBasedLayer { return { ...layer, columns: { @@ -377,7 +377,7 @@ describe('static_value', () => { }, } as StaticValueIndexPatternColumn, }, - } as IndexPatternLayer; + } as FormBasedLayer; const instance = shallow( { - let layer: IndexPatternLayer; + let layer: FormBasedLayer; const InlineOptions = termsOperation.paramEditor!; const InlineFieldInput = termsOperation.renderFieldInput!; @@ -1187,7 +1187,7 @@ describe('terms', () => { return getOperationSupportMatrix({ state: { layers: { layer1: layer }, - } as unknown as IndexPatternPrivateState, + } as unknown as FormBasedPrivateState, layerId: 'layer1', filterOperations: () => true, columnId, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/types.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/terms/types.ts similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/types.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/terms/types.ts diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/values_input.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/terms/values_input.test.tsx similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/values_input.test.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/terms/values_input.test.tsx diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/values_input.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/terms/values_input.tsx similarity index 97% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/values_input.tsx rename to x-pack/plugins/lens/public/datasources/form_based/operations/definitions/terms/values_input.tsx index 9e86ea8525adc8..33dd5b72060081 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/values_input.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/terms/values_input.tsx @@ -8,7 +8,7 @@ import React, { useState } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiFieldNumber, EuiFormRow } from '@elastic/eui'; -import { useDebounceWithOptions } from '../../../../shared_components'; +import { useDebounceWithOptions } from '../../../../../shared_components'; export const ValuesInput = ({ value, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/index.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/index.ts similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/index.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/index.ts diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.test.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/layer_helpers.test.ts similarity index 97% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.test.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/layer_helpers.test.ts index 1a77cd253424fb..65b11c2605cc3f 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.test.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/layer_helpers.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { OperationMetadata } from '../../types'; +import type { OperationMetadata } from '../../../types'; import { copyColumn, insertNewColumn, @@ -23,10 +23,10 @@ import { operationDefinitionMap, OperationType } from '.'; import { TermsIndexPatternColumn } from './definitions/terms'; import { DateHistogramIndexPatternColumn } from './definitions/date_histogram'; import { AvgIndexPatternColumn } from './definitions/metrics'; -import type { IndexPatternLayer, IndexPatternPrivateState } from '../types'; +import type { FormBasedLayer, FormBasedPrivateState } from '../types'; import { documentField } from '../document_field'; import { getFieldByNameFactory } from '../pure_helpers'; -import { generateId } from '../../id_generator'; +import { generateId } from '../../../id_generator'; import { createMockedFullReference, createMockedManagedReference } from './mocks'; import { FiltersIndexPatternColumn, @@ -38,13 +38,13 @@ import { } from './definitions'; import { TinymathAST } from '@kbn/tinymath'; import { CoreStart } from '@kbn/core/public'; -import { IndexPattern } from '../../types'; +import { IndexPattern } from '../../../types'; import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; const dataMock = dataPluginMock.createStartContract(); jest.mock('.'); -jest.mock('../../id_generator'); +jest.mock('../../../id_generator'); jest.mock('../dimension_panel/reference_editor', () => ({ ReferenceEditor: () => null, })); @@ -257,7 +257,7 @@ describe('state_helpers', () => { }); it('should update order on inserting a bucketed fieldless operation', () => { - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { indexPatternId: '1', columnOrder: ['col1'], columns: { @@ -284,7 +284,7 @@ describe('state_helpers', () => { }); it('should update order on inserting a bucketed field-based operation', () => { - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { indexPatternId: '1', columnOrder: ['col1'], columns: { @@ -312,7 +312,7 @@ describe('state_helpers', () => { }); it('should insert a metric after buckets', () => { - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { indexPatternId: '1', columnOrder: ['col1'], columns: { @@ -343,7 +343,7 @@ describe('state_helpers', () => { }); it('should insert a metric after references', () => { - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { indexPatternId: '1', columnOrder: ['col1'], columns: { @@ -382,7 +382,7 @@ describe('state_helpers', () => { }); it('should insert new buckets at the end of previous buckets', () => { - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { indexPatternId: '1', columnOrder: ['col1', 'col3'], columns: { @@ -421,7 +421,7 @@ describe('state_helpers', () => { }); it('should not change order of metrics and references on inserting new buckets', () => { - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { indexPatternId: '1', columnOrder: ['col1', 'col2'], columns: { @@ -665,7 +665,7 @@ describe('state_helpers', () => { specificOperations: [], }, ]; - const layer: IndexPatternLayer = { indexPatternId: '1', columnOrder: [], columns: {} }; + const layer: FormBasedLayer = { indexPatternId: '1', columnOrder: [], columns: {} }; expect(() => { insertNewColumn({ layer, @@ -678,7 +678,7 @@ describe('state_helpers', () => { }); it('should leave the references empty if too ambiguous', () => { - const layer: IndexPatternLayer = { indexPatternId: '1', columnOrder: [], columns: {} }; + const layer: FormBasedLayer = { indexPatternId: '1', columnOrder: [], columns: {} }; const result = insertNewColumn({ layer, indexPattern, @@ -710,7 +710,7 @@ describe('state_helpers', () => { validateMetadata: () => true, }, ]; - const layer: IndexPatternLayer = { indexPatternId: '1', columnOrder: [], columns: {} }; + const layer: FormBasedLayer = { indexPatternId: '1', columnOrder: [], columns: {} }; const result = insertNewColumn({ layer, indexPattern, @@ -728,7 +728,7 @@ describe('state_helpers', () => { }); it('should create a referenced column if the ID is being used as a reference', () => { - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { indexPatternId: '1', columnOrder: ['col1'], columns: { @@ -825,7 +825,7 @@ describe('state_helpers', () => { }); it('should update order on changing the column', () => { - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { indexPatternId: '1', columnOrder: ['col1', 'col2'], columns: { @@ -1498,7 +1498,7 @@ describe('state_helpers', () => { operationType: 'count' as const, }; - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { indexPatternId: '1', columnOrder: ['col1'], columns: { col1: expectedColumn }, @@ -1526,7 +1526,7 @@ describe('state_helpers', () => { }); it('should not wrap around the previous operation as a reference if excluded by validateMetadata (case new1)', () => { - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { indexPatternId: '1', columnOrder: ['col1'], columns: { @@ -1573,7 +1573,7 @@ describe('state_helpers', () => { const testFilter = { language: 'kuery', query: '' }; - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { indexPatternId: '1', columnOrder: ['col1'], columns: { col1: { ...expectedColumn, filter: testFilter } }, @@ -1612,7 +1612,7 @@ describe('state_helpers', () => { validateMetadata: () => true, }, ]; - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { indexPatternId: '1', columnOrder: ['col1'], columns: { @@ -1653,7 +1653,7 @@ describe('state_helpers', () => { specificOperations: ['unique_count', 'sum', 'average'], // this order is ignored }, ]; - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { indexPatternId: '1', columnOrder: ['col1'], columns: { @@ -1694,7 +1694,7 @@ describe('state_helpers', () => { specificOperations: ['unique_count'], }, ]; - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { indexPatternId: '1', columnOrder: ['col1'], columns: { @@ -1734,7 +1734,7 @@ describe('state_helpers', () => { specificOperations: [], }, ]; - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { indexPatternId: '1', columnOrder: ['col1'], columns: { @@ -1804,7 +1804,7 @@ describe('state_helpers', () => { }); it('should use existing references, delete invalid, when switching from one reference to another (case ref1)', () => { - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { indexPatternId: '1', columnOrder: ['ref1', 'invalid', 'output'], columns: { @@ -1856,7 +1856,7 @@ describe('state_helpers', () => { }); it('should modify a copied object, not the original layer', () => { - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { indexPatternId: '1', columnOrder: ['ref1', 'invalid', 'output'], columns: { @@ -1907,7 +1907,7 @@ describe('state_helpers', () => { label: 'math', operationType: 'math' as const, }; - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { indexPatternId: '', columnOrder: [], columns: { @@ -1977,7 +1977,7 @@ describe('state_helpers', () => { }); it('should transition by using the field from the previous reference if nothing else works (case new5)', () => { - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { indexPatternId: '1', columnOrder: ['fieldReused', 'output'], columns: { @@ -2045,7 +2045,7 @@ describe('state_helpers', () => { ], }, }; - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { indexPatternId: '1', columnOrder: ['col1', 'col2'], columns: { @@ -2089,7 +2089,7 @@ describe('state_helpers', () => { filter: { language: 'kuery', query: 'bytes > 4000' }, timeShift: '3h', }; - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { indexPatternId: '1', columnOrder: ['col1', 'col2'], columns: { @@ -2135,7 +2135,7 @@ describe('state_helpers', () => { timeShift: '3h', }; - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { indexPatternId: '1', columnOrder: ['metric', 'ref'], columns: { @@ -2168,7 +2168,7 @@ describe('state_helpers', () => { }); it('should keep state and set incomplete column on incompatible switch', () => { - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { indexPatternId: '1', columnOrder: ['metric', 'ref'], columns: { @@ -2272,7 +2272,7 @@ describe('state_helpers', () => { }, ]; - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { indexPatternId: '1', columnOrder: ['col1', 'col2'], columns: { @@ -2439,7 +2439,7 @@ describe('state_helpers', () => { }); it('should delete the column and all of its references', () => { - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { indexPatternId: '1', columnOrder: ['col1', 'col2'], columns: { @@ -2467,7 +2467,7 @@ describe('state_helpers', () => { }); it('should update the labels when deleting columns', () => { - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { indexPatternId: '1', columnOrder: ['col1', 'col2'], columns: { @@ -2512,7 +2512,7 @@ describe('state_helpers', () => { }); it('should recursively delete references', () => { - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { indexPatternId: '1', columnOrder: ['col1', 'col2', 'col3'], columns: { @@ -2837,7 +2837,7 @@ describe('state_helpers', () => { }); it('should remove operations referencing unavailable fields', () => { - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { columnOrder: ['col1', 'col2'], columns: { col1: { @@ -2870,7 +2870,7 @@ describe('state_helpers', () => { }); it('should remove operations indirectly referencing unavailable fields', () => { - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { columnOrder: ['col1', 'col2'], columns: { col1: { @@ -2902,7 +2902,7 @@ describe('state_helpers', () => { }); it('should remove operations referencing fields with insufficient capabilities', () => { - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { columnOrder: ['col1', 'col2'], columns: { col1: { @@ -2941,7 +2941,7 @@ describe('state_helpers', () => { interval: 'w', }, })) as OperationDefinition['transfer']; - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { columnOrder: ['col1', 'col2'], columns: { col1: { @@ -2971,7 +2971,7 @@ describe('state_helpers', () => { }); it('should remove operations referencing fields with wrong field types', () => { - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { columnOrder: ['col1', 'col2'], columns: { col1: { @@ -3004,7 +3004,7 @@ describe('state_helpers', () => { }); it('should remove operations referencing fields with incompatible restrictions', () => { - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { columnOrder: ['col1', 'col2'], columns: { col1: { @@ -3078,7 +3078,7 @@ describe('state_helpers', () => { }, }, indexPattern, - {} as IndexPatternPrivateState, + {} as FormBasedPrivateState, '1', {} as CoreStart, dataMock @@ -3114,7 +3114,7 @@ describe('state_helpers', () => { }, }, indexPattern, - {} as IndexPatternPrivateState, + {} as FormBasedPrivateState, '1', {} as CoreStart, dataMock @@ -3151,7 +3151,7 @@ describe('state_helpers', () => { }, }, indexPattern, - {} as IndexPatternPrivateState, + {} as FormBasedPrivateState, '1', {} as CoreStart, dataMock @@ -3181,7 +3181,7 @@ describe('state_helpers', () => { }, }, indexPattern, - {} as IndexPatternPrivateState, + {} as FormBasedPrivateState, '1', {} as CoreStart, dataMock @@ -3209,7 +3209,7 @@ describe('state_helpers', () => { describe('hasTermsWithManyBuckets', () => { it('should return false for a bucketed non terms operation', () => { - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { columnOrder: ['col1'], columns: { col1: { @@ -3230,7 +3230,7 @@ describe('state_helpers', () => { }); it('should return false if all terms operation have a lower size', () => { - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { columnOrder: ['col1'], columns: { col1: { @@ -3256,7 +3256,7 @@ describe('state_helpers', () => { }); it('should return true if the size is high', () => { - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { columnOrder: ['col1'], columns: { col1: { @@ -3284,7 +3284,7 @@ describe('state_helpers', () => { describe('isReferenced', () => { it('should return false for top column which has references', () => { - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { indexPatternId: '1', columnOrder: [], columns: { @@ -3308,7 +3308,7 @@ describe('state_helpers', () => { }); it('should return true for referenced column', () => { - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { indexPatternId: '1', columnOrder: [], columns: { @@ -3334,7 +3334,7 @@ describe('state_helpers', () => { describe('getReferenceRoot', () => { it("should just return the column id itself if it's not a referenced column", () => { - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { indexPatternId: '1', columnOrder: [], columns: { @@ -3358,7 +3358,7 @@ describe('state_helpers', () => { }); it('should return the top column if a referenced column is passed', () => { - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { indexPatternId: '1', columnOrder: [], columns: { @@ -3389,7 +3389,7 @@ describe('state_helpers', () => { label: 'math', operationType: 'math' as const, }; - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { indexPatternId: '', columnOrder: [], columns: { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/layer_helpers.ts similarity index 95% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/layer_helpers.ts index eb0f39262874b1..db9b744cd43b22 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/layer_helpers.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/layer_helpers.ts @@ -17,7 +17,7 @@ import type { IndexPatternField, OperationMetadata, VisualizationDimensionGroupConfig, -} from '../../types'; +} from '../../../types'; import { operationDefinitionMap, operationDefinitions, @@ -27,23 +27,19 @@ import { GenericOperationDefinition, TermsIndexPatternColumn, } from './definitions'; -import type { - DataViewDragDropOperation, - IndexPatternLayer, - IndexPatternPrivateState, -} from '../types'; +import type { DataViewDragDropOperation, FormBasedLayer, FormBasedPrivateState } from '../types'; import { getSortScoreByPriorityForField } from './operations'; -import { generateId } from '../../id_generator'; +import { generateId } from '../../../id_generator'; import { GenericIndexPatternColumn, ReferenceBasedIndexPatternColumn, BaseIndexPatternColumn, } from './definitions/column_types'; import { FormulaIndexPatternColumn, insertOrReplaceFormulaColumn } from './definitions/formula'; -import type { TimeScaleUnit } from '../../../common/expressions'; +import type { TimeScaleUnit } from '../../../../common/expressions'; import { documentField } from '../document_field'; import { isColumnOfType } from './definitions/helpers'; -import type { DataType } from '../..'; +import type { DataType } from '../../..'; export interface ColumnAdvancedParams { filter?: Query | undefined; @@ -54,7 +50,7 @@ export interface ColumnAdvancedParams { interface ColumnChange { op: OperationType; - layer: IndexPatternLayer; + layer: FormBasedLayer; columnId: string; indexPattern: IndexPattern; field?: IndexPatternField; @@ -72,7 +68,7 @@ interface ColumnChange { } interface ColumnCopy { - layers: Record; + layers: Record; target: DataViewDragDropOperation; source: DataViewDragDropOperation; shouldDeleteSource?: boolean; @@ -82,7 +78,7 @@ export const deleteColumnInLayers = ({ layers, source, }: { - layers: Record; + layers: Record; source: DataViewDragDropOperation; }) => ({ ...layers, @@ -98,7 +94,7 @@ export function copyColumn({ source, target, shouldDeleteSource, -}: ColumnCopy): Record { +}: ColumnCopy): Record { const outputLayers = createCopiedColumn(layers, target, source); return shouldDeleteSource ? deleteColumnInLayers({ @@ -109,10 +105,10 @@ export function copyColumn({ } function createCopiedColumn( - layers: Record, + layers: Record, target: DataViewDragDropOperation, source: DataViewDragDropOperation -): Record { +): Record { const sourceLayer = layers[source.layerId]; const sourceColumn = sourceLayer.columns[source.columnId]; const targetLayer = layers[target.layerId]; @@ -152,7 +148,7 @@ function createCopiedColumn( }; } -export function insertOrReplaceColumn(args: ColumnChange): IndexPatternLayer { +export function insertOrReplaceColumn(args: ColumnChange): FormBasedLayer { if (args.layer.columns[args.columnId]) { return replaceColumn(args); } @@ -185,7 +181,7 @@ const insertReferences = ({ visualizationGroups, targetGroup, }: { - layer: IndexPatternLayer; + layer: FormBasedLayer; references: Exclude; requiredReferences: RequiredReference[]; indexPattern: IndexPattern; @@ -269,7 +265,7 @@ const generateNewReferences = ({ incompleteFieldName?: string; incompleteFieldOperation?: OperationType; columnParams?: Record; - layer: IndexPatternLayer; + layer: FormBasedLayer; requiredReferences: RequiredReference[]; indexPattern: IndexPattern; visualizationGroups: VisualizationDimensionGroupConfig[]; @@ -364,7 +360,7 @@ export function insertNewColumn({ initialParams, references, respectOrder, -}: ColumnChange): IndexPatternLayer { +}: ColumnChange): FormBasedLayer { const operationDefinition = operationDefinitionMap[op]; if (!operationDefinition) { @@ -541,8 +537,8 @@ function replaceFormulaColumn( }: { operationDefinition: Extract; previousDefinition: GenericOperationDefinition; - layer: IndexPatternLayer; - previousColumn: IndexPatternLayer['columns'][number]; + layer: FormBasedLayer; + previousColumn: FormBasedLayer['columns'][number]; indexPattern: IndexPattern; columnId: string; }, @@ -615,7 +611,7 @@ export function replaceColumn({ initialParams, shouldResetLabel, shouldCombineField, -}: ColumnChange): IndexPatternLayer { +}: ColumnChange): FormBasedLayer { const previousColumn = layer.columns[columnId]; if (!previousColumn) { throw new Error(`Can't replace column because there is no prior column`); @@ -901,10 +897,10 @@ function removeOrphanedColumns( | OperationDefinition | OperationDefinition, previousColumn: GenericIndexPatternColumn, - tempLayer: IndexPatternLayer, + tempLayer: FormBasedLayer, indexPattern: IndexPattern ) { - let newLayer: IndexPatternLayer = tempLayer; + let newLayer: FormBasedLayer = tempLayer; if (previousDefinition.input === 'managedReference') { const [columnId] = Object.entries(tempLayer.columns).find(([_, currColumn]) => currColumn === previousColumn) || @@ -994,13 +990,13 @@ function applyReferenceTransition({ indexPattern, visualizationGroups, }: { - layer: IndexPatternLayer; + layer: FormBasedLayer; columnId: string; previousColumn: GenericIndexPatternColumn; op: OperationType; indexPattern: IndexPattern; visualizationGroups: VisualizationDimensionGroupConfig[]; -}): IndexPatternLayer { +}): FormBasedLayer { const operationDefinition = operationDefinitionMap[op]; if (operationDefinition.input !== 'fullReference') { @@ -1218,13 +1214,13 @@ function copyCustomLabel( } function addBucket( - layer: IndexPatternLayer, + layer: FormBasedLayer, column: BaseIndexPatternColumn, addedColumnId: string, visualizationGroups: VisualizationDimensionGroupConfig[], targetGroup?: string, respectOrder?: boolean -): IndexPatternLayer { +): FormBasedLayer { const [buckets, metrics] = partition( layer.columnOrder, (colId) => layer.columns[colId].isBucketed @@ -1314,10 +1310,10 @@ export function reorderByGroups( } function addMetric( - layer: IndexPatternLayer, + layer: FormBasedLayer, column: BaseIndexPatternColumn, addedColumnId: string -): IndexPatternLayer { +): FormBasedLayer { const tempLayer = { ...resetIncomplete(layer, addedColumnId), columns: { @@ -1347,10 +1343,10 @@ export function updateColumnLabel({ columnId, customLabel, }: { - layer: IndexPatternLayer; + layer: FormBasedLayer; columnId: string; customLabel?: string; -}): IndexPatternLayer { +}): FormBasedLayer { const oldColumn = layer.columns[columnId]; return { ...layer, @@ -1371,11 +1367,11 @@ export function updateColumnParam({ paramName, value, }: { - layer: IndexPatternLayer; + layer: FormBasedLayer; columnId: string; paramName: string; value: unknown; -}): IndexPatternLayer { +}): FormBasedLayer { const currentColumn = layer.columns[columnId]; return { ...layer, @@ -1392,7 +1388,7 @@ export function updateColumnParam({ }; } -export function adjustColumnReferences(layer: IndexPatternLayer) { +export function adjustColumnReferences(layer: FormBasedLayer) { const newColumns = { ...layer.columns }; Object.keys(newColumns).forEach((currentColumnId) => { const currentColumn = newColumns[currentColumnId]; @@ -1413,7 +1409,7 @@ export function adjustColumnReferences(layer: IndexPatternLayer) { } export function adjustColumnReferencesForChangedColumn( - layer: IndexPatternLayer, + layer: FormBasedLayer, changedColumnId: string ) { const newColumns = { ...layer.columns }; @@ -1440,10 +1436,10 @@ export function deleteColumn({ columnId, indexPattern, }: { - layer: IndexPatternLayer; + layer: FormBasedLayer; columnId: string; indexPattern: IndexPattern; -}): IndexPatternLayer { +}): FormBasedLayer { const column = layer.columns[columnId]; if (!column) { const newIncomplete = { ...(layer.incompleteColumns || {}) }; @@ -1491,7 +1487,7 @@ export function deleteColumn({ // // This does NOT topologically sort references, as this would cause the order in the UI // to change. Reference order is determined before creating the pipeline in to_expression -export function getColumnOrder(layer: IndexPatternLayer): string[] { +export function getColumnOrder(layer: FormBasedLayer): string[] { const entries = Object.entries(layer.columns); entries.sort(([idA], [idB]) => { const indexA = layer.columnOrder.indexOf(idA); @@ -1511,7 +1507,7 @@ export function getColumnOrder(layer: IndexPatternLayer): string[] { } // Splits existing columnOrder into the three categories -export function getExistingColumnGroups(layer: IndexPatternLayer): [string[], string[], string[]] { +export function getExistingColumnGroups(layer: FormBasedLayer): [string[], string[], string[]] { const [direct, referenced] = partition( layer.columnOrder, (columnId) => layer.columns[columnId] && !('references' in layer.columns[columnId]) @@ -1525,7 +1521,7 @@ export function getExistingColumnGroups(layer: IndexPatternLayer): [string[], st export function isColumnTransferable( column: GenericIndexPatternColumn, newIndexPattern: IndexPattern, - layer: IndexPatternLayer + layer: FormBasedLayer ): boolean { return ( operationDefinitionMap[column.operationType].isTransferable( @@ -1541,13 +1537,13 @@ export function isColumnTransferable( } export function updateLayerIndexPattern( - layer: IndexPatternLayer, + layer: FormBasedLayer, newIndexPattern: IndexPattern -): IndexPatternLayer { - const keptColumns: IndexPatternLayer['columns'] = pickBy(layer.columns, (column) => { +): FormBasedLayer { + const keptColumns: FormBasedLayer['columns'] = pickBy(layer.columns, (column) => { return isColumnTransferable(column, newIndexPattern, layer); }); - const newColumns: IndexPatternLayer['columns'] = mapValues(keptColumns, (column) => { + const newColumns: FormBasedLayer['columns'] = mapValues(keptColumns, (column) => { const operationDefinition = operationDefinitionMap[column.operationType]; return operationDefinition.transfer ? operationDefinition.transfer(column, newIndexPattern) @@ -1573,9 +1569,9 @@ export function updateLayerIndexPattern( * - If timeshift is used, only a single date histogram can be used */ export function getErrorMessages( - layer: IndexPatternLayer, + layer: FormBasedLayer, indexPattern: IndexPattern, - state: IndexPatternPrivateState, + state: FormBasedPrivateState, layerId: string, core: CoreStart, data: DataPublicPluginStart @@ -1584,7 +1580,7 @@ export function getErrorMessages( | string | { message: string; - fixAction?: DatasourceFixAction; + fixAction?: DatasourceFixAction; } > | undefined { @@ -1632,21 +1628,21 @@ export function getErrorMessages( | string | { message: string; - fixAction?: DatasourceFixAction; + fixAction?: DatasourceFixAction; } >; return errors.length ? errors : undefined; } -export function isReferenced(layer: IndexPatternLayer, columnId: string): boolean { +export function isReferenced(layer: FormBasedLayer, columnId: string): boolean { const allReferences = Object.values(layer.columns).flatMap((col) => 'references' in col ? col.references : [] ); return allReferences.includes(columnId); } -const computeReferenceLookup = memoizeOne((layer: IndexPatternLayer): Record => { +const computeReferenceLookup = memoizeOne((layer: FormBasedLayer): Record => { // speed up things for deep chains as in formula const refLookup: Record = {}; for (const [parentId, col] of Object.entries(layer.columns)) { @@ -1666,7 +1662,7 @@ const computeReferenceLookup = memoizeOne((layer: IndexPatternLayer): Record { const column = layer.columns[columnId]; if (column) { @@ -1740,9 +1736,9 @@ export function isOperationAllowedAsReference({ // Labels need to be updated when columns are added because reference-based column labels // are sometimes copied into the parents export function updateDefaultLabels( - layer: IndexPatternLayer, + layer: FormBasedLayer, indexPattern: IndexPattern -): IndexPatternLayer { +): FormBasedLayer { const copiedColumns = { ...layer.columns }; layer.columnOrder.forEach((id) => { const col = copiedColumns[id]; @@ -1760,7 +1756,7 @@ export function updateDefaultLabels( return { ...layer, columns: copiedColumns }; } -export function resetIncomplete(layer: IndexPatternLayer, columnId: string): IndexPatternLayer { +export function resetIncomplete(layer: FormBasedLayer, columnId: string): FormBasedLayer { const incompleteColumns = { ...(layer.incompleteColumns ?? {}) }; delete incompleteColumns[columnId]; return { ...layer, incompleteColumns }; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/mocks.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/mocks.ts similarity index 97% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/mocks.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/mocks.ts index 2d7e70179fb3f7..3884bab02f2008 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/mocks.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/mocks.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { OperationMetadata } from '../../types'; +import type { OperationMetadata } from '../../../types'; import type { OperationType } from './definitions'; export const createMockedFullReference = () => { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/operations.test.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/operations.test.ts similarity index 100% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/operations.test.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/operations.test.ts diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/operations.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/operations.ts similarity index 99% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/operations.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/operations.ts index 27071e5f0ee748..b44c0a0e4cc558 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/operations.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/operations.ts @@ -6,7 +6,7 @@ */ import { memoize } from 'lodash'; -import type { IndexPattern, IndexPatternField, OperationMetadata } from '../../types'; +import type { IndexPattern, IndexPatternField, OperationMetadata } from '../../../types'; import { operationDefinitionMap, operationDefinitions, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/time_scale_utils.test.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/time_scale_utils.test.ts similarity index 98% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/time_scale_utils.test.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/time_scale_utils.test.ts index 559086cf69b844..e249be575aac2f 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/time_scale_utils.test.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/time_scale_utils.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { TimeScaleUnit } from '../../../common/expressions'; +import type { TimeScaleUnit } from '../../../../common/expressions'; import { adjustTimeScaleLabelSuffix } from './time_scale_utils'; export const DEFAULT_TIME_SCALE = 's' as TimeScaleUnit; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/time_scale_utils.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/time_scale_utils.ts similarity index 92% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/time_scale_utils.ts rename to x-pack/plugins/lens/public/datasources/form_based/operations/time_scale_utils.ts index 1ebf4ccc76a362..08dfa147bf88e6 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/time_scale_utils.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/time_scale_utils.ts @@ -6,8 +6,8 @@ */ import { i18n } from '@kbn/i18n'; -import { unitSuffixesLong } from '../../../common/suffix_formatter'; -import type { TimeScaleUnit } from '../../../common/expressions'; +import { unitSuffixesLong } from '../../../../common/suffix_formatter'; +import type { TimeScaleUnit } from '../../../../common/expressions'; export const DEFAULT_TIME_SCALE = 's' as TimeScaleUnit; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/pure_helpers.ts b/x-pack/plugins/lens/public/datasources/form_based/pure_helpers.ts similarity index 92% rename from x-pack/plugins/lens/public/indexpattern_datasource/pure_helpers.ts rename to x-pack/plugins/lens/public/datasources/form_based/pure_helpers.ts index ba3ba9bbb824f8..6355809369804d 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/pure_helpers.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/pure_helpers.ts @@ -6,7 +6,7 @@ */ import { keyBy } from 'lodash'; -import { IndexPatternField } from '../types'; +import { IndexPatternField } from '../../types'; import { documentField } from './document_field'; export function getFieldByNameFactory( diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/pure_utils.ts b/x-pack/plugins/lens/public/datasources/form_based/pure_utils.ts similarity index 95% rename from x-pack/plugins/lens/public/indexpattern_datasource/pure_utils.ts rename to x-pack/plugins/lens/public/datasources/form_based/pure_utils.ts index 39b4bcdf49229a..5d8d823c30ab40 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/pure_utils.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/pure_utils.ts @@ -5,8 +5,8 @@ * 2.0. */ -import type { DataType, IndexPattern, IndexPatternField } from '../types'; -import type { IndexPatternLayer } from './types'; +import type { DataType, IndexPattern, IndexPatternField } from '../../types'; +import type { FormBasedLayer } from './types'; import type { BaseIndexPatternColumn, FieldBasedIndexPatternColumn, @@ -36,7 +36,7 @@ export function getFieldType(field: IndexPatternField) { export function getReferencedField( column: GenericIndexPatternColumn | undefined, indexPattern: IndexPattern, - layer: IndexPatternLayer + layer: FormBasedLayer ) { if (!column) return; if (!('references' in column)) return; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/reduced_time_range_utils.tsx b/x-pack/plugins/lens/public/datasources/form_based/reduced_time_range_utils.tsx similarity index 95% rename from x-pack/plugins/lens/public/indexpattern_datasource/reduced_time_range_utils.tsx rename to x-pack/plugins/lens/public/datasources/form_based/reduced_time_range_utils.tsx index 04984a1c782bf9..69e0fb4f07a5e5 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/reduced_time_range_utils.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/reduced_time_range_utils.tsx @@ -6,8 +6,8 @@ */ import { i18n } from '@kbn/i18n'; -import type { IndexPatternLayer } from './types'; -import type { IndexPattern } from '../types'; +import type { FormBasedLayer } from './types'; +import type { IndexPattern } from '../../types'; export const reducedTimeRangeOptions = [ { @@ -53,7 +53,7 @@ export const reducedTimeRangeOptionOrder = reducedTimeRangeOptions.reduce<{ ); export function getColumnReducedTimeRangeError( - layer: IndexPatternLayer, + layer: FormBasedLayer, columnId: string, indexPattern: IndexPattern ): string[] | undefined { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/state_helpers.ts b/x-pack/plugins/lens/public/datasources/form_based/state_helpers.ts similarity index 73% rename from x-pack/plugins/lens/public/indexpattern_datasource/state_helpers.ts rename to x-pack/plugins/lens/public/datasources/form_based/state_helpers.ts index 6e16ebe5e8d538..0120c29713a836 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/state_helpers.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/state_helpers.ts @@ -5,16 +5,16 @@ * 2.0. */ -import { IndexPatternPrivateState, IndexPatternLayer } from './types'; +import { FormBasedPrivateState, FormBasedLayer } from './types'; export function mergeLayer({ state, layerId, newLayer, }: { - state: IndexPatternPrivateState; + state: FormBasedPrivateState; layerId: string; - newLayer: Partial; + newLayer: Partial; }) { return { ...state, @@ -29,8 +29,8 @@ export function mergeLayers({ state, newLayers, }: { - state: IndexPatternPrivateState; - newLayers: Record; + state: FormBasedPrivateState; + newLayers: Record; }) { return { ...state, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/time_shift_utils.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/time_shift_utils.test.tsx similarity index 96% rename from x-pack/plugins/lens/public/indexpattern_datasource/time_shift_utils.test.tsx rename to x-pack/plugins/lens/public/datasources/form_based/time_shift_utils.test.tsx index 4cb251e3820bef..a0ff29a6841507 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/time_shift_utils.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/time_shift_utils.test.tsx @@ -6,11 +6,11 @@ */ import { getDisallowedPreviousShiftMessage } from './time_shift_utils'; -import { IndexPatternLayer } from './types'; +import { FormBasedLayer } from './types'; describe('time_shift_utils', () => { describe('getDisallowedPreviousShiftMessage', () => { - const layer: IndexPatternLayer = { + const layer: FormBasedLayer = { indexPatternId: '', columnOrder: [], columns: { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/time_shift_utils.tsx b/x-pack/plugins/lens/public/datasources/form_based/time_shift_utils.tsx similarity index 97% rename from x-pack/plugins/lens/public/indexpattern_datasource/time_shift_utils.tsx rename to x-pack/plugins/lens/public/datasources/form_based/time_shift_utils.tsx index 51f389e69a4f06..6dd4b88d3422a9 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/time_shift_utils.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/time_shift_utils.tsx @@ -13,12 +13,8 @@ import type { DatatableUtilitiesService } from '@kbn/data-plugin/common'; import { Datatable } from '@kbn/expressions-plugin/common'; import { search } from '@kbn/data-plugin/public'; import { parseTimeShift } from '@kbn/data-plugin/common'; -import type { - GenericIndexPatternColumn, - IndexPatternLayer, - IndexPatternPrivateState, -} from './types'; -import type { FramePublicAPI, IndexPattern } from '../types'; +import type { GenericIndexPatternColumn, FormBasedLayer, FormBasedPrivateState } from './types'; +import type { FramePublicAPI, IndexPattern } from '../../types'; export const timeShiftOptions = [ { @@ -105,7 +101,7 @@ export const timeShiftOptionOrder = timeShiftOptions.reduce<{ [key: string]: num export function getDateHistogramInterval( datatableUtilities: DatatableUtilitiesService, - layer: IndexPatternLayer, + layer: FormBasedLayer, indexPattern: IndexPattern, activeData: Record | undefined, layerId: string @@ -163,7 +159,7 @@ export function getLayerTimeShiftChecks({ } export function getDisallowedPreviousShiftMessage( - layer: IndexPatternLayer, + layer: FormBasedLayer, columnId: string ): string[] | undefined { const currentColumn = layer.columns[columnId]; @@ -191,7 +187,7 @@ export function getDisallowedPreviousShiftMessage( export function getStateTimeShiftWarningMessages( datatableUtilities: DatatableUtilitiesService, - state: IndexPatternPrivateState, + state: FormBasedPrivateState, { activeData, dataViews }: FramePublicAPI ) { if (!state) return; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/to_expression.ts b/x-pack/plugins/lens/public/datasources/form_based/to_expression.ts similarity index 98% rename from x-pack/plugins/lens/public/indexpattern_datasource/to_expression.ts rename to x-pack/plugins/lens/public/datasources/form_based/to_expression.ts index 72cb2a2ab729eb..fc77aa6520bd0c 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/to_expression.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/to_expression.ts @@ -20,13 +20,13 @@ import { ExpressionAstExpressionBuilder, ExpressionAstFunction, } from '@kbn/expressions-plugin/public'; -import { GenericIndexPatternColumn } from './indexpattern'; +import { GenericIndexPatternColumn } from './form_based'; import { operationDefinitionMap } from './operations'; -import { IndexPatternPrivateState, IndexPatternLayer } from './types'; +import { FormBasedPrivateState, FormBasedLayer } from './types'; import { DateHistogramIndexPatternColumn, RangeIndexPatternColumn } from './operations/definitions'; import { FormattedIndexPatternColumn } from './operations/definitions/column_types'; import { isColumnFormatted, isColumnOfType } from './operations/definitions/helpers'; -import type { IndexPattern, IndexPatternMap } from '../types'; +import type { IndexPattern, IndexPatternMap } from '../../types'; import { dedupeAggs } from './dedupe_aggs'; export type OriginalColumn = { id: string } & GenericIndexPatternColumn; @@ -50,7 +50,7 @@ const updatePositionIndex = (currentId: string, newIndex: number) => { }; function getExpressionForLayer( - layer: IndexPatternLayer, + layer: FormBasedLayer, indexPattern: IndexPattern, uiSettings: IUiSettingsClient ): ExpressionAstExpression | null { @@ -438,7 +438,7 @@ function sortedReferences(columns: Array; // Each layer is tied to the index pattern that created it @@ -56,15 +55,15 @@ export interface IndexPatternLayer { incompleteColumns?: Record; } -export interface IndexPatternPersistedState { - layers: Record>; +export interface FormBasedPersistedState { + layers: Record>; } -export type PersistedIndexPatternLayer = Omit; +export type PersistedIndexPatternLayer = Omit; -export interface IndexPatternPrivateState { +export interface FormBasedPrivateState { currentIndexPatternId: string; - layers: Record; + layers: Record; isDimensionClosePrevented?: boolean; } diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/utils.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/utils.test.tsx similarity index 95% rename from x-pack/plugins/lens/public/indexpattern_datasource/utils.test.tsx rename to x-pack/plugins/lens/public/datasources/form_based/utils.test.tsx index 2d7a6334adaf6f..5349e433f3cac0 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/utils.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/utils.test.tsx @@ -9,19 +9,19 @@ import React from 'react'; import { shallow } from 'enzyme'; import { createDatatableUtilitiesMock } from '@kbn/data-plugin/common/mocks'; import { getPrecisionErrorWarningMessages, cloneLayer } from './utils'; -import type { IndexPatternPrivateState, GenericIndexPatternColumn } from './types'; -import type { FramePublicAPI } from '../types'; +import type { FormBasedPrivateState, GenericIndexPatternColumn } from './types'; +import type { FramePublicAPI } from '../../types'; import type { DocLinksStart } from '@kbn/core/public'; import { EuiButton } from '@elastic/eui'; import { TermsIndexPatternColumn } from './operations'; import { mountWithIntl } from '@kbn/test-jest-helpers'; import { FormattedMessage } from '@kbn/i18n-react'; -import { IndexPatternLayer } from './types'; +import { FormBasedLayer } from './types'; describe('indexpattern_datasource utils', () => { describe('getPrecisionErrorWarningMessages', () => { const datatableUtilitites = createDatatableUtilitiesMock(); - let state: IndexPatternPrivateState; + let state: FormBasedPrivateState; let framePublicAPI: FramePublicAPI; let docLinks: DocLinksStart; @@ -42,7 +42,7 @@ describe('indexpattern_datasource utils', () => { }, }, }, - } as unknown as IndexPatternPrivateState; + } as unknown as FormBasedPrivateState; framePublicAPI = { activeData: { id: { @@ -227,7 +227,7 @@ describe('indexpattern_datasource utils', () => { incompleteColumns: {}, indexPatternId: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f', }, - } as unknown as Record, + } as unknown as Record, 'a', 'b', (id) => id + 'C' diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/utils.tsx b/x-pack/plugins/lens/public/datasources/form_based/utils.tsx similarity index 96% rename from x-pack/plugins/lens/public/indexpattern_datasource/utils.tsx rename to x-pack/plugins/lens/public/datasources/form_based/utils.tsx index 612719967161c2..dfec3c723d189a 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/utils.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/utils.tsx @@ -17,13 +17,9 @@ import type { DatatableColumn } from '@kbn/expressions-plugin/common'; import { groupBy, escape, uniq } from 'lodash'; import type { Query } from '@kbn/data-plugin/common'; import { SearchResponseWarning } from '@kbn/data-plugin/public/search/types'; -import type { FramePublicAPI, IndexPattern, StateSetter } from '../types'; -import { renewIDs } from '../utils'; -import type { - IndexPatternLayer, - IndexPatternPersistedState, - IndexPatternPrivateState, -} from './types'; +import type { FramePublicAPI, IndexPattern, StateSetter } from '../../types'; +import { renewIDs } from '../../utils'; +import type { FormBasedLayer, FormBasedPersistedState, FormBasedPrivateState } from './types'; import type { ReferenceBasedIndexPatternColumn } from './operations/definitions/column_types'; import { @@ -44,11 +40,11 @@ import { hasField } from './pure_utils'; import { mergeLayer } from './state_helpers'; import { supportsRarityRanking } from './operations/definitions/terms'; import { DEFAULT_MAX_DOC_COUNT } from './operations/definitions/terms/constants'; -import { getOriginalId } from '../../common/expressions/datatable/transpose_helpers'; -import { isQueryValid } from '../shared_components'; +import { getOriginalId } from '../../../common/expressions/datatable/transpose_helpers'; +import { isQueryValid } from '../../shared_components'; export function isColumnInvalid( - layer: IndexPatternLayer, + layer: FormBasedLayer, columnId: string, indexPattern: IndexPattern ) { @@ -76,7 +72,7 @@ export function isColumnInvalid( } function getReferencesErrors( - layer: IndexPatternLayer, + layer: FormBasedLayer, column: ReferenceBasedIndexPatternColumn, indexPattern: IndexPattern ) { @@ -167,7 +163,7 @@ const accuracyModeEnabledWarning = (columnName: string, docLink: string) => ( ); export function getTSDBRollupWarningMessages( - state: IndexPatternPersistedState, + state: FormBasedPersistedState, warning: SearchResponseWarning ) { if (state) { @@ -208,10 +204,10 @@ export function getTSDBRollupWarningMessages( export function getPrecisionErrorWarningMessages( datatableUtilities: DatatableUtilitiesService, - state: IndexPatternPrivateState, + state: FormBasedPrivateState, { activeData, dataViews }: FramePublicAPI, docLinks: DocLinksStart, - setState: StateSetter + setState: StateSetter ) { const warningMessages: React.ReactNode[] = []; @@ -338,7 +334,7 @@ export function getPrecisionErrorWarningMessages( return warningMessages; } -export function getVisualDefaultsForLayer(layer: IndexPatternLayer) { +export function getVisualDefaultsForLayer(layer: FormBasedLayer) { return Object.keys(layer.columns).reduce>>( (memo, columnId) => { const column = layer.columns[columnId]; @@ -461,7 +457,7 @@ function shouldUseTermsFallback( * * if there's at least one unfiltered metric, then just return an empty list of filters * * otherwise get all the filters, with the only exception of those from formula (referenced columns will have it anyway) */ -function collectFiltersFromMetrics(layer: IndexPatternLayer, columnIds: string[]) { +function collectFiltersFromMetrics(layer: FormBasedLayer, columnIds: string[]) { // Isolate filtered metrics first // mind to ignore non-filterable columns and formula columns const metricColumns = Object.keys(layer.columns).filter((colId) => { @@ -506,7 +502,7 @@ function collectOnlyValidQueries( } export function getFiltersInLayer( - layer: IndexPatternLayer, + layer: FormBasedLayer, columnIds: string[], layerData: NonNullable[string] | undefined, indexPattern: IndexPattern, @@ -617,7 +613,7 @@ export function getFiltersInLayer( } export const cloneLayer = ( - layers: Record, + layers: Record, layerId: string, newLayerId: string, getNewId: (id: string) => string diff --git a/x-pack/plugins/lens/public/text_based_languages_datasource/datapanel.test.tsx b/x-pack/plugins/lens/public/datasources/text_based/datapanel.test.tsx similarity index 88% rename from x-pack/plugins/lens/public/text_based_languages_datasource/datapanel.test.tsx rename to x-pack/plugins/lens/public/datasources/text_based/datapanel.test.tsx index 51ba02c1cdc6fc..781b6547f8e159 100644 --- a/x-pack/plugins/lens/public/text_based_languages_datasource/datapanel.test.tsx +++ b/x-pack/plugins/lens/public/datasources/text_based/datapanel.test.tsx @@ -19,18 +19,18 @@ import { import type { DatatableColumn } from '@kbn/expressions-plugin/public'; import { FieldButton } from '@kbn/react-field'; -import { type TextBasedLanguagesDataPanelProps, TextBasedLanguagesDataPanel } from './datapanel'; +import { type TextBasedDataPanelProps, TextBasedDataPanel } from './datapanel'; import { coreMock } from '@kbn/core/public/mocks'; -import type { TextBasedLanguagesPrivateState } from './types'; +import type { TextBasedPrivateState } from './types'; import { mountWithIntl } from '@kbn/test-jest-helpers'; import { uiActionsPluginMock } from '@kbn/ui-actions-plugin/public/mocks'; -import { createIndexPatternServiceMock } from '../mocks/data_views_service_mock'; -import { createMockFramePublicAPI } from '../mocks'; +import { createIndexPatternServiceMock } from '../../mocks/data_views_service_mock'; +import { createMockFramePublicAPI } from '../../mocks'; import { createMockedDragDropContext } from './mocks'; -import { DataViewsState } from '../state_management'; -import { ExistingFieldsMap, IndexPattern } from '../types'; +import { DataViewsState } from '../../state_management'; +import { ExistingFieldsMap, IndexPattern } from '../../types'; const fieldsFromQuery = [ { @@ -113,7 +113,7 @@ function getExistingFields(indexPatterns: Record) { return existingFields; } -const initialState: TextBasedLanguagesPrivateState = { +const initialState: TextBasedPrivateState = { layers: { first: { index: '1', @@ -163,7 +163,7 @@ describe('TextBased Query Languages Data Panel', () => { let core: ReturnType; let dataViews: DataViewPublicStart; - let defaultProps: TextBasedLanguagesDataPanelProps; + let defaultProps: TextBasedDataPanelProps; const dataViewsMock = dataViewPluginMocks.createStartContract(); beforeEach(() => { core = coreMock.createStart(); @@ -202,12 +202,12 @@ describe('TextBased Query Languages Data Panel', () => { }); it('should render a search box', async () => { - const wrapper = mountWithIntl(); + const wrapper = mountWithIntl(); expect(wrapper.find('[data-test-subj="lnsTextBasedLangugesFieldSearch"]').length).toEqual(1); }); it('should list all supported fields in the pattern', async () => { - const wrapper = mountWithIntl(); + const wrapper = mountWithIntl(); expect( wrapper .find('[data-test-subj="lnsTextBasedLanguagesPanelFields"]') @@ -217,7 +217,7 @@ describe('TextBased Query Languages Data Panel', () => { }); it('should list all supported fields in the pattern that match the search input', async () => { - const wrapper = mountWithIntl(); + const wrapper = mountWithIntl(); const searchBox = wrapper.find('[data-test-subj="lnsTextBasedLangugesFieldSearch"]'); act(() => { diff --git a/x-pack/plugins/lens/public/text_based_languages_datasource/datapanel.tsx b/x-pack/plugins/lens/public/datasources/text_based/datapanel.tsx similarity index 90% rename from x-pack/plugins/lens/public/text_based_languages_datasource/datapanel.tsx rename to x-pack/plugins/lens/public/datasources/text_based/datapanel.tsx index 9e15db381549d1..925d92be5aa995 100644 --- a/x-pack/plugins/lens/public/text_based_languages_datasource/datapanel.tsx +++ b/x-pack/plugins/lens/public/datasources/text_based/datapanel.tsx @@ -17,23 +17,22 @@ import { isOfAggregateQueryType } from '@kbn/es-query'; import { ExpressionsStart } from '@kbn/expressions-plugin/public'; import { FieldButton } from '@kbn/react-field'; import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; -import { DatasourceDataPanelProps, DataType } from '../types'; -import type { TextBasedLanguagesPrivateState } from './types'; +import { DatasourceDataPanelProps, DataType } from '../../types'; +import type { TextBasedPrivateState } from './types'; import { getStateFromAggregateQuery } from './utils'; -import { DragDrop } from '../drag_drop'; -import { LensFieldIcon } from '../shared_components'; -import { ChildDragDropProvider } from '../drag_drop'; +import { DragDrop } from '../../drag_drop'; +import { LensFieldIcon } from '../../shared_components'; +import { ChildDragDropProvider } from '../../drag_drop'; -export type TextBasedLanguagesDataPanelProps = - DatasourceDataPanelProps & { - data: DataPublicPluginStart; - expressions: ExpressionsStart; - dataViews: DataViewsPublicPluginStart; - }; +export type TextBasedDataPanelProps = DatasourceDataPanelProps & { + data: DataPublicPluginStart; + expressions: ExpressionsStart; + dataViews: DataViewsPublicPluginStart; +}; const htmlId = htmlIdGenerator('datapanel-text-based-languages'); const fieldSearchDescriptionId = htmlId(); -export function TextBasedLanguagesDataPanel({ +export function TextBasedDataPanel({ setState, state, dragDropContext, @@ -44,7 +43,7 @@ export function TextBasedLanguagesDataPanel({ dateRange, expressions, dataViews, -}: TextBasedLanguagesDataPanelProps) { +}: TextBasedDataPanelProps) { const prevQuery = usePrevious(query); const [localState, setLocalState] = useState({ nameFilter: '' }); const clearLocalState = () => setLocalState((s) => ({ ...s, nameFilter: '' })); diff --git a/x-pack/plugins/lens/public/text_based_languages_datasource/fetch_data_from_aggregate_query.ts b/x-pack/plugins/lens/public/datasources/text_based/fetch_data_from_aggregate_query.ts similarity index 100% rename from x-pack/plugins/lens/public/text_based_languages_datasource/fetch_data_from_aggregate_query.ts rename to x-pack/plugins/lens/public/datasources/text_based/fetch_data_from_aggregate_query.ts diff --git a/x-pack/plugins/lens/public/text_based_languages_datasource/field_select.test.tsx b/x-pack/plugins/lens/public/datasources/text_based/field_select.test.tsx similarity index 96% rename from x-pack/plugins/lens/public/text_based_languages_datasource/field_select.test.tsx rename to x-pack/plugins/lens/public/datasources/text_based/field_select.test.tsx index f1051f3b8f61d4..b344131747b1b7 100644 --- a/x-pack/plugins/lens/public/text_based_languages_datasource/field_select.test.tsx +++ b/x-pack/plugins/lens/public/datasources/text_based/field_select.test.tsx @@ -8,7 +8,7 @@ import React from 'react'; import type { DatatableColumn } from '@kbn/expressions-plugin/public'; -import { FieldPicker, FieldOptionValue } from '../shared_components/field_picker'; +import { FieldPicker, FieldOptionValue } from '../../shared_components/field_picker'; import { FieldSelect, FieldSelectProps } from './field_select'; import { shallowWithIntl as shallow } from '@kbn/test-jest-helpers'; diff --git a/x-pack/plugins/lens/public/text_based_languages_datasource/field_select.tsx b/x-pack/plugins/lens/public/datasources/text_based/field_select.tsx similarity index 89% rename from x-pack/plugins/lens/public/text_based_languages_datasource/field_select.tsx rename to x-pack/plugins/lens/public/datasources/text_based/field_select.tsx index 63153bc87d59ee..e7cb5451d31ab2 100644 --- a/x-pack/plugins/lens/public/text_based_languages_datasource/field_select.tsx +++ b/x-pack/plugins/lens/public/datasources/text_based/field_select.tsx @@ -9,12 +9,12 @@ import React, { useMemo } from 'react'; import { EuiComboBoxOptionOption, EuiComboBoxProps } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import type { DatatableColumn } from '@kbn/expressions-plugin/public'; -import { FieldPicker, FieldOptionValue, FieldOption } from '../shared_components/field_picker'; -import type { TextBasedLanguagesLayerColumn } from './types'; -import type { DataType } from '../types'; +import { FieldPicker, FieldOptionValue, FieldOption } from '../../shared_components/field_picker'; +import type { TextBasedLayerColumn } from './types'; +import type { DataType } from '../../types'; export interface FieldSelectProps extends EuiComboBoxProps { - selectedField?: TextBasedLanguagesLayerColumn; + selectedField?: TextBasedLayerColumn; onChoose: (choice: FieldOptionValue) => void; existingFields: DatatableColumn[]; } diff --git a/x-pack/plugins/lens/public/text_based_languages_datasource/index.ts b/x-pack/plugins/lens/public/datasources/text_based/index.ts similarity index 71% rename from x-pack/plugins/lens/public/text_based_languages_datasource/index.ts rename to x-pack/plugins/lens/public/datasources/text_based/index.ts index b2cffc5659dbf8..1041e94eb7c614 100644 --- a/x-pack/plugins/lens/public/text_based_languages_datasource/index.ts +++ b/x-pack/plugins/lens/public/datasources/text_based/index.ts @@ -10,31 +10,28 @@ import { Storage } from '@kbn/kibana-utils-plugin/public'; import { ExpressionsStart } from '@kbn/expressions-plugin/public'; import { DataPublicPluginSetup, DataPublicPluginStart } from '@kbn/data-plugin/public'; import type { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; -import { EditorFrameSetup } from '../types'; +import { EditorFrameSetup } from '../../types'; -export interface TextBasedLanguageSetupPlugins { +export interface TextBasedSetupPlugins { data: DataPublicPluginSetup; editorFrame: EditorFrameSetup; } -export interface TextBasedLanguageStartPlugins { +export interface TextBasedStartPlugins { data: DataPublicPluginStart; dataViews: DataViewsPublicPluginStart; expressions: ExpressionsStart; } -export class TextBasedLanguagesDatasource { +export class TextBasedDatasource { constructor() {} - setup( - core: CoreSetup, - { editorFrame }: TextBasedLanguageSetupPlugins - ) { + setup(core: CoreSetup, { editorFrame }: TextBasedSetupPlugins) { editorFrame.registerDatasource(async () => { - const { getTextBasedLanguagesDatasource } = await import('../async_services'); + const { getTextBasedDatasource } = await import('../../async_services'); const [coreStart, { data, dataViews, expressions }] = await core.getStartServices(); - return getTextBasedLanguagesDatasource({ + return getTextBasedDatasource({ core: coreStart, storage: new Storage(localStorage), data, diff --git a/x-pack/plugins/lens/public/text_based_languages_datasource/layerpanel.test.tsx b/x-pack/plugins/lens/public/datasources/text_based/layerpanel.test.tsx similarity index 83% rename from x-pack/plugins/lens/public/text_based_languages_datasource/layerpanel.test.tsx rename to x-pack/plugins/lens/public/datasources/text_based/layerpanel.test.tsx index 7a3bf25b5e9e67..f0a9d147ddfd63 100644 --- a/x-pack/plugins/lens/public/text_based_languages_datasource/layerpanel.test.tsx +++ b/x-pack/plugins/lens/public/datasources/text_based/layerpanel.test.tsx @@ -7,12 +7,12 @@ import React from 'react'; import type { DatatableColumn } from '@kbn/expressions-plugin/public'; -import { TextBasedLanguagesPrivateState } from './types'; -import type { DataViewsState } from '../state_management/types'; +import { TextBasedPrivateState } from './types'; +import type { DataViewsState } from '../../state_management/types'; -import { TextBasedLanguageLayerPanelProps, LayerPanel } from './layerpanel'; +import { TextBasedLayerPanelProps, LayerPanel } from './layerpanel'; import { shallowWithIntl as shallow } from '@kbn/test-jest-helpers'; -import { ChangeIndexPattern } from '../shared_components/dataview_picker/dataview_picker'; +import { ChangeIndexPattern } from '../../shared_components/dataview_picker/dataview_picker'; const fields = [ { @@ -38,7 +38,7 @@ const fields = [ }, ] as DatatableColumn[]; -const initialState: TextBasedLanguagesPrivateState = { +const initialState: TextBasedPrivateState = { layers: { first: { index: '1', @@ -55,7 +55,7 @@ const initialState: TextBasedLanguagesPrivateState = { fieldList: fields, }; describe('Layer Data Panel', () => { - let defaultProps: TextBasedLanguageLayerPanelProps; + let defaultProps: TextBasedLayerPanelProps; beforeEach(() => { defaultProps = { diff --git a/x-pack/plugins/lens/public/text_based_languages_datasource/layerpanel.tsx b/x-pack/plugins/lens/public/datasources/text_based/layerpanel.tsx similarity index 75% rename from x-pack/plugins/lens/public/text_based_languages_datasource/layerpanel.tsx rename to x-pack/plugins/lens/public/datasources/text_based/layerpanel.tsx index 8f8e4a91242b15..879d28a607c7fc 100644 --- a/x-pack/plugins/lens/public/text_based_languages_datasource/layerpanel.tsx +++ b/x-pack/plugins/lens/public/datasources/text_based/layerpanel.tsx @@ -8,16 +8,15 @@ import React from 'react'; import { I18nProvider } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; -import { DatasourceLayerPanelProps } from '../types'; -import { TextBasedLanguagesPrivateState } from './types'; -import { ChangeIndexPattern } from '../shared_components/dataview_picker/dataview_picker'; +import { DatasourceLayerPanelProps } from '../../types'; +import { TextBasedPrivateState } from './types'; +import { ChangeIndexPattern } from '../../shared_components/dataview_picker/dataview_picker'; -export interface TextBasedLanguageLayerPanelProps - extends DatasourceLayerPanelProps { - state: TextBasedLanguagesPrivateState; +export interface TextBasedLayerPanelProps extends DatasourceLayerPanelProps { + state: TextBasedPrivateState; } -export function LayerPanel({ state, layerId, dataViews }: TextBasedLanguageLayerPanelProps) { +export function LayerPanel({ state, layerId, dataViews }: TextBasedLayerPanelProps) { const layer = state.layers[layerId]; const dataView = dataViews.indexPatternRefs.find((ref) => ref.id === layer.index); const notFoundTitleLabel = i18n.translate('xpack.lens.layerPanel.missingDataView', { diff --git a/x-pack/plugins/lens/public/text_based_languages_datasource/mocks.ts b/x-pack/plugins/lens/public/datasources/text_based/mocks.ts similarity index 92% rename from x-pack/plugins/lens/public/text_based_languages_datasource/mocks.ts rename to x-pack/plugins/lens/public/datasources/text_based/mocks.ts index adca02ab2299df..8b191b815100eb 100644 --- a/x-pack/plugins/lens/public/text_based_languages_datasource/mocks.ts +++ b/x-pack/plugins/lens/public/datasources/text_based/mocks.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { DragContextState } from '../drag_drop'; +import { DragContextState } from '../../drag_drop'; export function createMockedDragDropContext(): jest.Mocked { return { diff --git a/x-pack/plugins/lens/public/text_based_languages_datasource/text_based_languages.test.ts b/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.test.ts similarity index 88% rename from x-pack/plugins/lens/public/text_based_languages_datasource/text_based_languages.test.ts rename to x-pack/plugins/lens/public/datasources/text_based/text_based_languages.test.ts index ae7e84c61b3c53..5f4df8492c9b35 100644 --- a/x-pack/plugins/lens/public/text_based_languages_datasource/text_based_languages.test.ts +++ b/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.test.ts @@ -8,14 +8,14 @@ import { coreMock } from '@kbn/core/public/mocks'; import { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; import { expressionsPluginMock } from '@kbn/expressions-plugin/public/mocks'; -import { TextBasedLanguagesPersistedState, TextBasedLanguagesPrivateState } from './types'; +import { TextBasedPersistedState, TextBasedPrivateState } from './types'; import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; -import { getTextBasedLanguagesDatasource } from './text_based_languages'; -import { generateId } from '../id_generator'; -import { DatasourcePublicAPI, Datasource } from '../types'; +import { getTextBasedDatasource } from './text_based_languages'; +import { generateId } from '../../id_generator'; +import { DatasourcePublicAPI, Datasource } from '../../types'; -jest.mock('../id_generator'); +jest.mock('../../id_generator'); const fieldsOne = [ { @@ -78,14 +78,11 @@ const expectedIndexPatterns = { const indexPatterns = expectedIndexPatterns; describe('IndexPattern Data Source', () => { - let baseState: TextBasedLanguagesPrivateState; - let textBasedLanguagesDatasource: Datasource< - TextBasedLanguagesPrivateState, - TextBasedLanguagesPersistedState - >; + let baseState: TextBasedPrivateState; + let TextBasedDatasource: Datasource; beforeEach(() => { - textBasedLanguagesDatasource = getTextBasedLanguagesDatasource({ + TextBasedDatasource = getTextBasedDatasource({ storage: {} as IStorageWrapper, core: coreMock.createStart(), data: dataPluginMock.createStartContract(), @@ -127,12 +124,12 @@ describe('IndexPattern Data Source', () => { }, }, ], - } as unknown as TextBasedLanguagesPrivateState; + } as unknown as TextBasedPrivateState; }); describe('uniqueLabels', () => { it('appends a suffix to duplicates', () => { - const map = textBasedLanguagesDatasource.uniqueLabels({ + const map = TextBasedDatasource.uniqueLabels({ layers: { a: { columns: [ @@ -154,7 +151,7 @@ describe('IndexPattern Data Source', () => { index: 'foo', }, }, - } as unknown as TextBasedLanguagesPrivateState); + } as unknown as TextBasedPrivateState); expect(map).toMatchInlineSnapshot(` Object { @@ -167,7 +164,7 @@ describe('IndexPattern Data Source', () => { describe('#getPersistedState', () => { it('should persist from saved state', async () => { - expect(textBasedLanguagesDatasource.getPersistableState(baseState)).toEqual({ + expect(TextBasedDatasource.getPersistableState(baseState)).toEqual({ state: { layers: baseState.layers, }, @@ -180,7 +177,7 @@ describe('IndexPattern Data Source', () => { describe('#insertLayer', () => { it('should insert an empty layer into the previous state', () => { - expect(textBasedLanguagesDatasource.insertLayer(baseState, 'newLayer')).toEqual({ + expect(TextBasedDatasource.insertLayer(baseState, 'newLayer')).toEqual({ ...baseState, layers: { ...baseState.layers, @@ -205,7 +202,7 @@ describe('IndexPattern Data Source', () => { describe('#removeLayer', () => { it('should remove a layer', () => { - expect(textBasedLanguagesDatasource.removeLayer(baseState, 'a')).toEqual({ + expect(TextBasedDatasource.removeLayer(baseState, 'a')).toEqual({ ...baseState, layers: { a: { @@ -229,7 +226,7 @@ describe('IndexPattern Data Source', () => { describe('#createEmptyLayer', () => { it('creates state with empty layers', () => { - expect(textBasedLanguagesDatasource.createEmptyLayer('index-pattern-id')).toEqual({ + expect(TextBasedDatasource.createEmptyLayer('index-pattern-id')).toEqual({ fieldList: [], layers: {}, indexPatternRefs: [], @@ -240,7 +237,7 @@ describe('IndexPattern Data Source', () => { describe('#getLayers', () => { it('should list the current layers', () => { expect( - textBasedLanguagesDatasource.getLayers({ + TextBasedDatasource.getLayers({ layers: { a: { columns: [ @@ -279,7 +276,7 @@ describe('IndexPattern Data Source', () => { index: 'foo', }, }, - } as unknown as TextBasedLanguagesPrivateState) + } as unknown as TextBasedPrivateState) ).toEqual(['a']); }); }); @@ -298,8 +295,8 @@ describe('IndexPattern Data Source', () => { name: 'Foo', }, }, - } as unknown as TextBasedLanguagesPrivateState; - const suggestions = textBasedLanguagesDatasource.getDatasourceSuggestionsForVisualizeField( + } as unknown as TextBasedPrivateState; + const suggestions = TextBasedDatasource.getDatasourceSuggestionsForVisualizeField( state, '1', '', @@ -417,8 +414,8 @@ describe('IndexPattern Data Source', () => { index: 'foo', }, }, - } as unknown as TextBasedLanguagesPrivateState; - expect(textBasedLanguagesDatasource.getErrorMessages(state, indexPatterns)).toEqual([ + } as unknown as TextBasedPrivateState; + expect(TextBasedDatasource.getErrorMessages(state, indexPatterns)).toEqual([ { longMessage: 'error 1', shortMessage: 'error 1' }, { longMessage: 'error 2', shortMessage: 'error 2' }, ]); @@ -466,9 +463,9 @@ describe('IndexPattern Data Source', () => { index: '1', }, }, - } as unknown as TextBasedLanguagesPrivateState; + } as unknown as TextBasedPrivateState; expect( - textBasedLanguagesDatasource.isTimeBased(state, { + TextBasedDatasource.isTimeBased(state, { ...indexPatterns, }) ).toEqual(true); @@ -513,9 +510,9 @@ describe('IndexPattern Data Source', () => { index: '1', }, }, - } as unknown as TextBasedLanguagesPrivateState; + } as unknown as TextBasedPrivateState; expect( - textBasedLanguagesDatasource.isTimeBased(state, { + TextBasedDatasource.isTimeBased(state, { ...indexPatterns, '1': { ...indexPatterns['1'], timeFieldName: undefined }, }) @@ -525,10 +522,8 @@ describe('IndexPattern Data Source', () => { describe('#toExpression', () => { it('should generate an empty expression when no columns are selected', async () => { - const state = textBasedLanguagesDatasource.initialize(); - expect(textBasedLanguagesDatasource.toExpression(state, 'first', indexPatterns)).toEqual( - null - ); + const state = TextBasedDatasource.initialize(); + expect(TextBasedDatasource.toExpression(state, 'first', indexPatterns)).toEqual(null); }); it('should generate an expression for an SQL query', async () => { @@ -576,9 +571,9 @@ describe('IndexPattern Data Source', () => { { id: '2', title: 'my-fake-restricted-pattern' }, { id: '3', title: 'my-compatible-pattern' }, ], - } as unknown as TextBasedLanguagesPrivateState; + } as unknown as TextBasedPrivateState; - expect(textBasedLanguagesDatasource.toExpression(queryBaseState, 'a', indexPatterns)) + expect(TextBasedDatasource.toExpression(queryBaseState, 'a', indexPatterns)) .toMatchInlineSnapshot(` Object { "chain": Array [ @@ -621,7 +616,7 @@ describe('IndexPattern Data Source', () => { let publicAPI: DatasourcePublicAPI; beforeEach(async () => { - publicAPI = textBasedLanguagesDatasource.getPublicAPI({ + publicAPI = TextBasedDatasource.getPublicAPI({ state: baseState, layerId: 'a', indexPatterns, @@ -676,9 +671,9 @@ describe('IndexPattern Data Source', () => { }, }, ], - } as unknown as TextBasedLanguagesPrivateState; + } as unknown as TextBasedPrivateState; - publicAPI = textBasedLanguagesDatasource.getPublicAPI({ + publicAPI = TextBasedDatasource.getPublicAPI({ state, layerId: 'a', indexPatterns, @@ -701,9 +696,9 @@ describe('IndexPattern Data Source', () => { }, }, ], - } as unknown as TextBasedLanguagesPrivateState; + } as unknown as TextBasedPrivateState; - publicAPI = textBasedLanguagesDatasource.getPublicAPI({ + publicAPI = TextBasedDatasource.getPublicAPI({ state, layerId: 'a', indexPatterns, diff --git a/x-pack/plugins/lens/public/text_based_languages_datasource/text_based_languages.tsx b/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.tsx similarity index 89% rename from x-pack/plugins/lens/public/text_based_languages_datasource/text_based_languages.tsx rename to x-pack/plugins/lens/public/datasources/text_based/text_based_languages.tsx index 7157f643c6e8cf..d7897362e86c46 100644 --- a/x-pack/plugins/lens/public/text_based_languages_datasource/text_based_languages.tsx +++ b/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.tsx @@ -25,25 +25,25 @@ import { DataType, TableChangeType, DatasourceDimensionTriggerProps, -} from '../types'; -import { generateId } from '../id_generator'; +} from '../../types'; +import { generateId } from '../../id_generator'; import { toExpression } from './to_expression'; -import { TextBasedLanguagesDataPanel } from './datapanel'; +import { TextBasedDataPanel } from './datapanel'; import type { - TextBasedLanguagesPrivateState, - TextBasedLanguagesPersistedState, - TextBasedLanguagesLayerColumn, - TextBasedLanguageField, + TextBasedPrivateState, + TextBasedPersistedState, + TextBasedLayerColumn, + TextBasedField, } from './types'; import { FieldSelect } from './field_select'; -import type { Datasource, IndexPatternMap } from '../types'; +import type { Datasource, IndexPatternMap } from '../../types'; import { LayerPanel } from './layerpanel'; function getLayerReferenceName(layerId: string) { return `textBasedLanguages-datasource-layer-${layerId}`; } -export function getTextBasedLanguagesDatasource({ +export function getTextBasedDatasource({ core, storage, data, @@ -56,7 +56,7 @@ export function getTextBasedLanguagesDatasource({ expressions: ExpressionsStart; dataViews: DataViewsPublicPluginStart; }) { - const getSuggestionsForState = (state: TextBasedLanguagesPrivateState) => { + const getSuggestionsForState = (state: TextBasedPrivateState) => { return Object.entries(state.layers)?.map(([id, layer]) => { return { state: { @@ -83,7 +83,7 @@ export function getTextBasedLanguagesDatasource({ }); }; const getSuggestionsForVisualizeField = ( - state: TextBasedLanguagesPrivateState, + state: TextBasedPrivateState, indexPatternId: string, fieldName: string, indexPatterns: IndexPatternMap @@ -153,11 +153,8 @@ export function getTextBasedLanguagesDatasource({ return []; }; - const TextBasedLanguagesDatasource: Datasource< - TextBasedLanguagesPrivateState, - TextBasedLanguagesPersistedState - > = { - id: 'textBasedLanguages', + const TextBasedDatasource: Datasource = { + id: 'textBased', checkIntegrity: () => { return []; @@ -188,7 +185,7 @@ export function getTextBasedLanguagesDatasource({ return errors; }, initialize( - state?: TextBasedLanguagesPersistedState, + state?: TextBasedPersistedState, savedObjectReferences?, context?, indexPatternRefs?, @@ -217,7 +214,7 @@ export function getTextBasedLanguagesDatasource({ return Object.values(state.layers).map(({ index }) => index); }, - getPersistableState({ layers }: TextBasedLanguagesPrivateState) { + getPersistableState({ layers }: TextBasedPrivateState) { const savedObjectReferences: SavedObjectReference[] = []; Object.entries(layers).forEach(([layerId, { index, ...persistableLayer }]) => { if (index) { @@ -237,7 +234,7 @@ export function getTextBasedLanguagesDatasource({ if (!column || !indexPattern) return false; return true; }, - insertLayer(state: TextBasedLanguagesPrivateState, newLayerId: string) { + insertLayer(state: TextBasedPrivateState, newLayerId: string) { const layer = Object.values(state?.layers)?.[0]; const query = layer?.query; const columns = layer?.allColumns ?? []; @@ -267,7 +264,7 @@ export function getTextBasedLanguagesDatasource({ }; }, - removeLayer(state: TextBasedLanguagesPrivateState, layerId: string) { + removeLayer(state: TextBasedPrivateState, layerId: string) { const newLayers = { ...state.layers, [layerId]: { @@ -283,7 +280,7 @@ export function getTextBasedLanguagesDatasource({ }; }, - clearLayer(state: TextBasedLanguagesPrivateState, layerId: string) { + clearLayer(state: TextBasedPrivateState, layerId: string) { return { ...state, layers: { @@ -293,7 +290,7 @@ export function getTextBasedLanguagesDatasource({ }; }, - getLayers(state: TextBasedLanguagesPrivateState) { + getLayers(state: TextBasedPrivateState) { return state && state.layers ? Object.keys(state?.layers) : []; }, isTimeBased: (state, indexPatterns) => { @@ -306,7 +303,7 @@ export function getTextBasedLanguagesDatasource({ }) ); }, - getUsedDataView: (state: TextBasedLanguagesPrivateState, layerId?: string) => { + getUsedDataView: (state: TextBasedPrivateState, layerId?: string) => { if (!layerId) { const layers = Object.values(state.layers); return layers?.[0]?.index; @@ -331,13 +328,10 @@ export function getTextBasedLanguagesDatasource({ return toExpression(state, layerId); }, - renderDataPanel( - domElement: Element, - props: DatasourceDataPanelProps - ) { + renderDataPanel(domElement: Element, props: DatasourceDataPanelProps) { render( - + props: DatasourceDimensionTriggerProps ) => { - const columnLabelMap = TextBasedLanguagesDatasource.uniqueLabels(props.state); + const columnLabelMap = TextBasedDatasource.uniqueLabels(props.state); const layer = props.state.layers[props.layerId]; const selectedField = layer?.allColumns?.find((column) => column.columnId === props.columnId); let customLabel: string | undefined = columnLabelMap[props.columnId]; @@ -377,13 +371,13 @@ export function getTextBasedLanguagesDatasource({ ); }, - getRenderEventCounters(state: TextBasedLanguagesPrivateState): string[] { + getRenderEventCounters(state: TextBasedPrivateState): string[] { return []; }, renderDimensionEditor: ( domElement: Element, - props: DatasourceDimensionEditorProps + props: DatasourceDimensionEditorProps ) => { const fields = props.state.fieldList; const selectedField = props.state.layers[props.layerId]?.allColumns?.find( @@ -450,7 +444,7 @@ export function getTextBasedLanguagesDatasource({ renderLayerPanel: ( domElement: Element, - props: DatasourceLayerPanelProps + props: DatasourceLayerPanelProps ) => { render( @@ -460,7 +454,7 @@ export function getTextBasedLanguagesDatasource({ ); }, - uniqueLabels(state: TextBasedLanguagesPrivateState) { + uniqueLabels(state: TextBasedPrivateState) { const layers = state.layers; const columnLabelMap = {} as Record; const counts = {} as Record; @@ -536,9 +530,9 @@ export function getTextBasedLanguagesDatasource({ return false; }, - getPublicAPI({ state, layerId }: PublicAPIProps) { + getPublicAPI({ state, layerId }: PublicAPIProps) { return { - datasourceId: 'textBasedLanguages', + datasourceId: 'textBased', getTableSpec: () => { const columns = state.layers[layerId]?.columns.filter((c) => { @@ -555,7 +549,7 @@ export function getTextBasedLanguagesDatasource({ getOperationForColumnId: (columnId: string) => { const layer = state.layers[layerId]; const column = layer?.allColumns?.find((c) => c.columnId === columnId); - const columnLabelMap = TextBasedLanguagesDatasource.uniqueLabels(state); + const columnLabelMap = TextBasedDatasource.uniqueLabels(state); if (column) { return { @@ -591,9 +585,7 @@ export function getTextBasedLanguagesDatasource({ }; }, getDatasourceSuggestionsForField(state, draggedField) { - const field = state.fieldList.find( - (f) => f.id === (draggedField as TextBasedLanguageField).id - ); + const field = state.fieldList.find((f) => f.id === (draggedField as TextBasedField).id); if (!field) return []; return Object.entries(state.layers)?.map(([id, layer]) => { const newId = generateId(); @@ -650,14 +642,10 @@ export function getTextBasedLanguagesDatasource({ isEqual: () => true, }; - return TextBasedLanguagesDatasource; + return TextBasedDatasource; } -function blankLayer( - index: string, - query?: AggregateQuery, - columns?: TextBasedLanguagesLayerColumn[] -) { +function blankLayer(index: string, query?: AggregateQuery, columns?: TextBasedLayerColumn[]) { return { index, query, diff --git a/x-pack/plugins/lens/public/text_based_languages_datasource/to_expression.ts b/x-pack/plugins/lens/public/datasources/text_based/to_expression.ts similarity index 80% rename from x-pack/plugins/lens/public/text_based_languages_datasource/to_expression.ts rename to x-pack/plugins/lens/public/datasources/text_based/to_expression.ts index aa7a264673a3eb..dba9a93555ce27 100644 --- a/x-pack/plugins/lens/public/text_based_languages_datasource/to_expression.ts +++ b/x-pack/plugins/lens/public/datasources/text_based/to_expression.ts @@ -7,13 +7,10 @@ import { Ast } from '@kbn/interpreter'; import { textBasedQueryStateToExpressionAst } from '@kbn/data-plugin/common'; -import type { OriginalColumn } from '../../common/types'; -import { TextBasedLanguagesPrivateState, TextBasedLanguagesLayer, IndexPatternRef } from './types'; +import type { OriginalColumn } from '../../../common/types'; +import { TextBasedPrivateState, TextBasedLayer, IndexPatternRef } from './types'; -function getExpressionForLayer( - layer: TextBasedLanguagesLayer, - refs: IndexPatternRef[] -): Ast | null { +function getExpressionForLayer(layer: TextBasedLayer, refs: IndexPatternRef[]): Ast | null { if (!layer.columns || layer.columns?.length === 0) { return null; } @@ -53,7 +50,7 @@ function getExpressionForLayer( return textBasedQueryToAst; } -export function toExpression(state: TextBasedLanguagesPrivateState, layerId: string) { +export function toExpression(state: TextBasedPrivateState, layerId: string) { if (state.layers[layerId]) { return getExpressionForLayer(state.layers[layerId], state.indexPatternRefs); } diff --git a/x-pack/plugins/lens/public/text_based_languages_datasource/types.ts b/x-pack/plugins/lens/public/datasources/text_based/types.ts similarity index 65% rename from x-pack/plugins/lens/public/text_based_languages_datasource/types.ts rename to x-pack/plugins/lens/public/datasources/text_based/types.ts index 11b9612624efda..0e30e0d517054c 100644 --- a/x-pack/plugins/lens/public/text_based_languages_datasource/types.ts +++ b/x-pack/plugins/lens/public/datasources/text_based/types.ts @@ -7,33 +7,33 @@ import type { DatatableColumn } from '@kbn/expressions-plugin/public'; import type { AggregateQuery } from '@kbn/es-query'; import type { VisualizeFieldContext } from '@kbn/ui-actions-plugin/public'; -import type { VisualizeEditorContext } from '../types'; +import type { VisualizeEditorContext } from '../../types'; -export interface TextBasedLanguagesLayerColumn { +export interface TextBasedLayerColumn { columnId: string; fieldName: string; meta?: DatatableColumn['meta']; } -export interface TextBasedLanguageField { +export interface TextBasedField { id: string; field: string; } -export interface TextBasedLanguagesLayer { +export interface TextBasedLayer { index: string; query: AggregateQuery | undefined; - columns: TextBasedLanguagesLayerColumn[]; - allColumns: TextBasedLanguagesLayerColumn[]; + columns: TextBasedLayerColumn[]; + allColumns: TextBasedLayerColumn[]; timeField?: string; errors?: Error[]; } -export interface TextBasedLanguagesPersistedState { - layers: Record; +export interface TextBasedPersistedState { + layers: Record; } -export type TextBasedLanguagesPrivateState = TextBasedLanguagesPersistedState & { +export type TextBasedPrivateState = TextBasedPersistedState & { indexPatternRefs: IndexPatternRef[]; fieldList: DatatableColumn[]; initialContext?: VisualizeFieldContext | VisualizeEditorContext; diff --git a/x-pack/plugins/lens/public/text_based_languages_datasource/utils.test.ts b/x-pack/plugins/lens/public/datasources/text_based/utils.test.ts similarity index 97% rename from x-pack/plugins/lens/public/text_based_languages_datasource/utils.test.ts rename to x-pack/plugins/lens/public/datasources/text_based/utils.test.ts index 1e7096414d19ec..1698ae536f44f3 100644 --- a/x-pack/plugins/lens/public/text_based_languages_datasource/utils.test.ts +++ b/x-pack/plugins/lens/public/datasources/text_based/utils.test.ts @@ -9,14 +9,14 @@ import type { DatatableColumn } from '@kbn/expressions-plugin/public'; import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; import { expressionsPluginMock } from '@kbn/expressions-plugin/public/mocks'; import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; -import { mockDataViewsService } from '../data_views_service/mocks'; +import { mockDataViewsService } from '../../data_views_service/mocks'; import { getIndexPatternFromTextBasedQuery, loadIndexPatternRefs, getStateFromAggregateQuery, getAllColumns, } from './utils'; -import type { TextBasedLanguagesLayerColumn } from './types'; +import type { TextBasedLayerColumn } from './types'; import { type AggregateQuery } from '@kbn/es-query'; jest.mock('./fetch_data_from_aggregate_query', () => ({ @@ -92,7 +92,7 @@ describe('Text based languages utils', () => { type: 'number', }, }, - ] as TextBasedLanguagesLayerColumn[]; + ] as TextBasedLayerColumn[]; const columnsFromQuery = [ { name: 'timestamp', diff --git a/x-pack/plugins/lens/public/text_based_languages_datasource/utils.ts b/x-pack/plugins/lens/public/datasources/text_based/utils.ts similarity index 92% rename from x-pack/plugins/lens/public/text_based_languages_datasource/utils.ts rename to x-pack/plugins/lens/public/datasources/text_based/utils.ts index 5504cd39bd6a1a..5078c967ff9e82 100644 --- a/x-pack/plugins/lens/public/text_based_languages_datasource/utils.ts +++ b/x-pack/plugins/lens/public/datasources/text_based/utils.ts @@ -10,14 +10,10 @@ import type { ExpressionsStart } from '@kbn/expressions-plugin/public'; import { type AggregateQuery, getIndexPatternFromSQLQuery } from '@kbn/es-query'; import type { DatatableColumn } from '@kbn/expressions-plugin/public'; -import { generateId } from '../id_generator'; +import { generateId } from '../../id_generator'; import { fetchDataFromAggregateQuery } from './fetch_data_from_aggregate_query'; -import type { - IndexPatternRef, - TextBasedLanguagesPrivateState, - TextBasedLanguagesLayerColumn, -} from './types'; +import type { IndexPatternRef, TextBasedPrivateState, TextBasedLayerColumn } from './types'; export async function loadIndexPatternRefs( indexPatternsService: DataViewsPublicPluginStart @@ -36,7 +32,7 @@ export async function loadIndexPatternRefs( } export const getAllColumns = ( - existingColumns: TextBasedLanguagesLayerColumn[], + existingColumns: TextBasedLayerColumn[], columnsFromQuery: DatatableColumn[] ) => { // filter out columns that do not exist on the query @@ -64,7 +60,7 @@ export const getAllColumns = ( }; export async function getStateFromAggregateQuery( - state: TextBasedLanguagesPrivateState, + state: TextBasedPrivateState, query: AggregateQuery, dataViews: DataViewsPublicPluginStart, data: DataPublicPluginStart, @@ -80,7 +76,7 @@ export async function getStateFromAggregateQuery( // get the id of the dataview const index = indexPatternRefs.find((r) => r.title === indexPattern)?.id ?? ''; let columnsFromQuery: DatatableColumn[] = []; - let allColumns: TextBasedLanguagesLayerColumn[] = []; + let allColumns: TextBasedLayerColumn[] = []; let timeFieldName; try { const table = await fetchDataFromAggregateQuery(query, dataViews, data, expressions); diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.ts b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.ts index c96a022f4aed2a..81298a97f650e0 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.ts +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.ts @@ -209,7 +209,7 @@ export function getVisualizeFieldSuggestions({ // suggestions for visualizing textbased languages if (visualizeTriggerFieldContext && 'query' in visualizeTriggerFieldContext) { if (visualizeTriggerFieldContext.query) { - return suggestions.find((s) => s.datasourceId === 'textBasedLanguages'); + return suggestions.find((s) => s.datasourceId === 'textBased'); } } diff --git a/x-pack/plugins/lens/public/embeddable/embeddable_component.tsx b/x-pack/plugins/lens/public/embeddable/embeddable_component.tsx index 98c8d363a45b77..56939b54299ce1 100644 --- a/x-pack/plugins/lens/public/embeddable/embeddable_component.tsx +++ b/x-pack/plugins/lens/public/embeddable/embeddable_component.tsx @@ -22,7 +22,7 @@ import { } from '@kbn/embeddable-plugin/public'; import type { LensByReferenceInput, LensByValueInput } from './embeddable'; import type { Document } from '../persistence'; -import type { IndexPatternPersistedState } from '../indexpattern_datasource/types'; +import type { FormBasedPersistedState } from '../datasources/form_based/types'; import type { XYState } from '../visualizations/xy/types'; import type { PieVisualizationState, LegacyMetricState } from '../../common'; import type { DatatableVisualizationState } from '../visualizations/datatable/visualization'; @@ -37,7 +37,7 @@ type LensAttributes = Omit< visualizationType: TVisType; state: Omit & { datasourceStates: { - indexpattern: IndexPatternPersistedState; + formBased: FormBasedPersistedState; }; visualization: TVisState; }; diff --git a/x-pack/plugins/lens/public/index.ts b/x-pack/plugins/lens/public/index.ts index 9efe67c4283e30..54380bd7eec639 100644 --- a/x-pack/plugins/lens/public/index.ts +++ b/x-pack/plugins/lens/public/index.ts @@ -44,7 +44,7 @@ export type { DatatableVisualizationState } from './visualizations/datatable/vis export type { HeatmapVisualizationState } from './visualizations/heatmap/types'; export type { GaugeVisualizationState } from './visualizations/gauge/constants'; export type { - IndexPatternPersistedState, + FormBasedPersistedState, PersistedIndexPatternLayer, OperationType, IncompleteColumn, @@ -75,8 +75,8 @@ export type { FormulaPublicApi, StaticValueIndexPatternColumn, TimeScaleIndexPatternColumn, - IndexPatternLayer, -} from './indexpattern_datasource/types'; + FormBasedLayer, +} from './datasources/form_based/types'; export type { XYArgs, XYRender, diff --git a/x-pack/plugins/lens/public/plugin.ts b/x-pack/plugins/lens/public/plugin.ts index 6b06978befea7b..c4d4cf9bfab9f6 100644 --- a/x-pack/plugins/lens/public/plugin.ts +++ b/x-pack/plugins/lens/public/plugin.ts @@ -52,11 +52,11 @@ import type { AdvancedUiActionsSetup } from '@kbn/ui-actions-enhanced-plugin/pub import type { DocLinksStart } from '@kbn/core-doc-links-browser'; import type { EditorFrameService as EditorFrameServiceType } from './editor_frame_service'; import type { - IndexPatternDatasource as IndexPatternDatasourceType, - IndexPatternDatasourceSetupPlugins, + FormBasedDatasource as FormBasedDatasourceType, + FormBasedDatasourceSetupPlugins, FormulaPublicApi, -} from './indexpattern_datasource'; -import type { TextBasedLanguagesDatasource as TextBasedLanguagesDatasourceType } from './text_based_languages_datasource'; +} from './datasources/form_based'; +import type { TextBasedDatasource as TextBasedDatasourceType } from './datasources/text_based'; import type { XyVisualization as XyVisualizationType, @@ -231,8 +231,8 @@ export class LensPlugin { private editorFrameService: EditorFrameServiceType | undefined; private editorFrameSetup: EditorFrameSetup | undefined; private queuedVisualizations: Array Promise)> = []; - private indexpatternDatasource: IndexPatternDatasourceType | undefined; - private textBasedLanguagesDatasource: TextBasedLanguagesDatasourceType | undefined; + private FormBasedDatasource: FormBasedDatasourceType | undefined; + private TextBasedDatasource: TextBasedDatasourceType | undefined; private xyVisualization: XyVisualizationType | undefined; private legacyMetricVisualization: LegacyMetricVisualizationType | undefined; private metricVisualization: MetricVisualizationType | undefined; @@ -423,19 +423,19 @@ export class LensPlugin { const { DatatableVisualization, EditorFrameService, - IndexPatternDatasource, + FormBasedDatasource, XyVisualization, LegacyMetricVisualization, MetricVisualization, PieVisualization, HeatmapVisualization, GaugeVisualization, - TextBasedLanguagesDatasource, + TextBasedDatasource, } = await import('./async_services'); this.datatableVisualization = new DatatableVisualization(); this.editorFrameService = new EditorFrameService(); - this.indexpatternDatasource = new IndexPatternDatasource(); - this.textBasedLanguagesDatasource = new TextBasedLanguagesDatasource(); + this.FormBasedDatasource = new FormBasedDatasource(); + this.TextBasedDatasource = new TextBasedDatasource(); this.xyVisualization = new XyVisualization(); this.legacyMetricVisualization = new LegacyMetricVisualization(); this.metricVisualization = new MetricVisualization(); @@ -445,7 +445,7 @@ export class LensPlugin { const editorFrameSetupInterface = this.editorFrameService.setup(); - const dependencies: IndexPatternDatasourceSetupPlugins & + const dependencies: FormBasedDatasourceSetupPlugins & XyVisualizationPluginSetupPlugins & DatatableVisualizationPluginSetupPlugins & LegacyMetricVisualizationPluginSetupPlugins & @@ -458,8 +458,8 @@ export class LensPlugin { formatFactory, eventAnnotation, }; - this.indexpatternDatasource.setup(core, dependencies); - this.textBasedLanguagesDatasource.setup(core, dependencies); + this.FormBasedDatasource.setup(core, dependencies); + this.TextBasedDatasource.setup(core, dependencies); this.xyVisualization.setup(core, dependencies); this.datatableVisualization.setup(core, dependencies); this.legacyMetricVisualization.setup(core, dependencies); diff --git a/x-pack/plugins/lens/public/shared_components/field_picker/lens_field_icon.tsx b/x-pack/plugins/lens/public/shared_components/field_picker/lens_field_icon.tsx index fabb8cab6fd0e3..e3be012647e8cc 100644 --- a/x-pack/plugins/lens/public/shared_components/field_picker/lens_field_icon.tsx +++ b/x-pack/plugins/lens/public/shared_components/field_picker/lens_field_icon.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { FieldIcon, FieldIconProps } from '@kbn/react-field'; import { DataType } from '../../types'; -import { normalizeOperationDataType } from '../../indexpattern_datasource/pure_utils'; +import { normalizeOperationDataType } from '../../datasources/form_based/pure_utils'; export function LensFieldIcon({ type, ...rest }: FieldIconProps & { type: DataType }) { return ( diff --git a/x-pack/plugins/lens/public/state_management/init_middleware/load_initial.ts b/x-pack/plugins/lens/public/state_management/init_middleware/load_initial.ts index 5b942eff4a6833..69e93f7a763a32 100644 --- a/x-pack/plugins/lens/public/state_management/init_middleware/load_initial.ts +++ b/x-pack/plugins/lens/public/state_management/init_middleware/load_initial.ts @@ -117,7 +117,7 @@ export function loadInitial( let activeDatasourceId: string | undefined; if (initialContext && 'query' in initialContext) { - activeDatasourceId = 'textBasedLanguages'; + activeDatasourceId = 'textBased'; } if ( diff --git a/x-pack/plugins/lens/public/types.ts b/x-pack/plugins/lens/public/types.ts index 29aff3d4286902..bed1acfad574f9 100644 --- a/x-pack/plugins/lens/public/types.ts +++ b/x-pack/plugins/lens/public/types.ts @@ -47,7 +47,7 @@ import { LENS_EDIT_PAGESIZE_ACTION, } from './visualizations/datatable/components/constants'; import type { LensInspector } from './lens_inspector_service'; -import type { FormatSelectorOptions } from './indexpattern_datasource/dimension_panel/format_selector'; +import type { FormatSelectorOptions } from './datasources/form_based/dimension_panel/format_selector'; import type { DataViewsState } from './state_management/types'; import type { IndexPatternServiceAPI } from './data_views_service/service'; import type { Document } from './persistence/saved_object_store'; diff --git a/x-pack/plugins/lens/public/visualizations/datatable/visualization.tsx b/x-pack/plugins/lens/public/visualizations/datatable/visualization.tsx index ad5e8118c5226c..27ac3d5b092b9c 100644 --- a/x-pack/plugins/lens/public/visualizations/datatable/visualization.tsx +++ b/x-pack/plugins/lens/public/visualizations/datatable/visualization.tsx @@ -29,7 +29,7 @@ import type { LayerType } from '../../../common'; import { getDefaultSummaryLabel } from '../../../common/expressions/datatable/summary'; import type { ColumnState, SortingState, PagingState } from '../../../common/expressions'; import { DataTableToolbar } from './components/toolbar'; -import type { IndexPatternLayer } from '../../indexpattern_datasource/types'; +import type { FormBasedLayer } from '../../datasources/form_based/types'; export interface DatatableVisualizationState { columns: ColumnState[]; @@ -45,7 +45,7 @@ export interface DatatableVisualizationState { interface DatatableDatasourceState { [prop: string]: unknown; - layers: IndexPatternLayer[]; + layers: FormBasedLayer[]; } export interface DatatableSuggestion extends Suggestion { diff --git a/x-pack/plugins/lens/public/visualizations/gauge/visualization.tsx b/x-pack/plugins/lens/public/visualizations/gauge/visualization.tsx index 99120c90942d42..f78529a17c8f48 100644 --- a/x-pack/plugins/lens/public/visualizations/gauge/visualization.tsx +++ b/x-pack/plugins/lens/public/visualizations/gauge/visualization.tsx @@ -37,7 +37,7 @@ import { applyPaletteParams } from '../../shared_components'; import { GaugeDimensionEditor } from './dimension_editor'; import { generateId } from '../../id_generator'; import { getAccessorsFromState } from './utils'; -import { IndexPatternLayer } from '../..'; +import { FormBasedLayer } from '../..'; const groupLabelForGauge = i18n.translate('xpack.lens.metric.groupLabel', { defaultMessage: 'Goal and single value', @@ -50,7 +50,7 @@ interface GaugeVisualizationDeps { interface GaugeDatasourceState { [prop: string]: unknown; - layers: IndexPatternLayer[]; + layers: FormBasedLayer[]; } export interface GaugeSuggestion extends Suggestion { diff --git a/x-pack/plugins/lens/public/visualizations/metric/visualization.tsx b/x-pack/plugins/lens/public/visualizations/metric/visualization.tsx index e3b42fedc45e44..5fe14fb58cc21a 100644 --- a/x-pack/plugins/lens/public/visualizations/metric/visualization.tsx +++ b/x-pack/plugins/lens/public/visualizations/metric/visualization.tsx @@ -31,8 +31,8 @@ import { GROUP_ID, LENS_METRIC_ID } from './constants'; import { DimensionEditor } from './dimension_editor'; import { Toolbar } from './toolbar'; import { generateId } from '../../id_generator'; -import { FormatSelectorOptions } from '../../indexpattern_datasource/dimension_panel/format_selector'; -import { IndexPatternLayer } from '../../indexpattern_datasource/types'; +import { FormatSelectorOptions } from '../../datasources/form_based/dimension_panel/format_selector'; +import { FormBasedLayer } from '../../datasources/form_based/types'; export const DEFAULT_MAX_COLUMNS = 3; @@ -59,7 +59,7 @@ export interface MetricVisualizationState { interface MetricDatasourceState { [prop: string]: unknown; - layers: IndexPatternLayer[]; + layers: FormBasedLayer[]; } export interface MetricSuggestion extends Suggestion { diff --git a/x-pack/plugins/lens/public/visualizations/partition/visualization.tsx b/x-pack/plugins/lens/public/visualizations/partition/visualization.tsx index 49a485debcf276..cf30fbcc1ceffd 100644 --- a/x-pack/plugins/lens/public/visualizations/partition/visualization.tsx +++ b/x-pack/plugins/lens/public/visualizations/partition/visualization.tsx @@ -37,11 +37,11 @@ import { suggestions } from './suggestions'; import { PartitionChartsMeta } from './partition_charts_meta'; import { DimensionEditor, PieToolbar } from './toolbar'; import { checkTableForContainsSmallValues } from './render_helpers'; -import type { IndexPatternLayer } from '../..'; +import type { FormBasedLayer } from '../..'; interface DatatableDatasourceState { [prop: string]: unknown; - layers: IndexPatternLayer[]; + layers: FormBasedLayer[]; } export interface PartitionSuggestion extends Suggestion { diff --git a/x-pack/plugins/lens/public/visualizations/xy/visualization.test.ts b/x-pack/plugins/lens/public/visualizations/xy/visualization.test.ts index 6c2d61d7bb8694..8c6da8bf95a6be 100644 --- a/x-pack/plugins/lens/public/visualizations/xy/visualization.test.ts +++ b/x-pack/plugins/lens/public/visualizations/xy/visualization.test.ts @@ -28,7 +28,7 @@ import { EventAnnotationConfig } from '@kbn/event-annotation-plugin/common'; import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; import { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; import { DataViewsState } from '../../state_management'; -import { createMockedIndexPattern } from '../../indexpattern_datasource/mocks'; +import { createMockedIndexPattern } from '../../datasources/form_based/mocks'; import { createMockDataViewsState } from '../../data_views_service/mocks'; import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks'; diff --git a/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/annotations_config_panel/index.test.tsx b/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/annotations_config_panel/index.test.tsx index 7d581d50d0859b..185a73c64d4e6e 100644 --- a/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/annotations_config_panel/index.test.tsx +++ b/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/annotations_config_panel/index.test.tsx @@ -18,7 +18,7 @@ import { chartPluginMock } from '@kbn/charts-plugin/public/mocks'; import moment from 'moment'; import { EventAnnotationConfig } from '@kbn/event-annotation-plugin/common'; import { createMockDataViewsState } from '../../../../data_views_service/mocks'; -import { createMockedIndexPattern } from '../../../../indexpattern_datasource/mocks'; +import { createMockedIndexPattern } from '../../../../datasources/form_based/mocks'; import { act } from 'react-dom/test-utils'; import { EuiButtonGroup } from '@elastic/eui'; diff --git a/x-pack/plugins/lens/readme.md b/x-pack/plugins/lens/readme.md index d8b80e864be582..d276a45eb00ac0 100644 --- a/x-pack/plugins/lens/readme.md +++ b/x-pack/plugins/lens/readme.md @@ -82,7 +82,7 @@ References (`references`) are regular saved object references forming a graph of ### Datasource state -The data source state (`state.datasourceStates.indexPattern.layers`) contains the configuration state of the data fetching and processing part of Lens. It's not specific to a certain representation (xy, pie, gauge, ...), but instead it defines a data table per layer made out of columns with various properties. This data table is passed over to the visualization state which maps it to various dimensions of the specific visualization. Layer and columns have unique ids which are shared amongst visualization and datasource - it's important to make sure they are always in sync. The keys of the `state.datasourceStates.indexPattern.layers` object are the layer ids. Lens editor chooses uuids for these, but when programmatically generating Lens attributes, any string can be used for them. The `layers[].columns` object is constructed in a similar way (keys represent the column ids). The `operationType` property defines the type of the column, other properties depend on the specific operation. Types for individual parts of the datasource state are provided (check the `lens/public` export, e.g. there's the `MaxIndexPatternColumn` for a column of operation type `max`) +The data source state (`state.datasourceStates.formBased.layers`) contains the configuration state of the data fetching and processing part of Lens. It's not specific to a certain representation (xy, pie, gauge, ...), but instead it defines a data table per layer made out of columns with various properties. This data table is passed over to the visualization state which maps it to various dimensions of the specific visualization. Layer and columns have unique ids which are shared amongst visualization and datasource - it's important to make sure they are always in sync. The keys of the `state.datasourceStates.formBased.layers` object are the layer ids. Lens editor chooses uuids for these, but when programmatically generating Lens attributes, any string can be used for them. The `layers[].columns` object is constructed in a similar way (keys represent the column ids). The `operationType` property defines the type of the column, other properties depend on the specific operation. Types for individual parts of the datasource state are provided (check the `lens/public` export, e.g. there's the `MaxIndexPatternColumn` for a column of operation type `max`) ### Visualization state diff --git a/x-pack/plugins/lens/server/embeddable/make_lens_embeddable_factory.ts b/x-pack/plugins/lens/server/embeddable/make_lens_embeddable_factory.ts index 8b977fbce5742a..42846e84377dd3 100644 --- a/x-pack/plugins/lens/server/embeddable/make_lens_embeddable_factory.ts +++ b/x-pack/plugins/lens/server/embeddable/make_lens_embeddable_factory.ts @@ -7,6 +7,7 @@ import { EmbeddableRegistryDefinition } from '@kbn/embeddable-plugin/server'; import type { SerializableRecord } from '@kbn/utility-types'; +import type { SavedObject } from '@kbn/core-saved-objects-common'; import { mergeMigrationFunctionMaps, MigrateFunctionsObject, @@ -31,6 +32,7 @@ import { getLensDataViewMigrations, commonMigrateMetricIds, commonMigratePartitionChartGroups, + commonMigrateIndexPatternDatasource, } from '../migrations/common_migrations'; import { CustomVisualizationMigrations, @@ -155,6 +157,15 @@ export const makeLensEmbeddableFactory = attributes: migratedLensState, } as unknown as SerializableRecord; }, + '8.6.0': (state) => { + const lensState = state as unknown as SavedObject>; + + const migratedLensState = commonMigrateIndexPatternDatasource(lensState.attributes); + return { + ...lensState, + attributes: migratedLensState, + } as unknown as SerializableRecord; + }, }), getLensCustomVisualizationMigrations(customVisualizationMigrations) ), diff --git a/x-pack/plugins/lens/server/migrations/common_migrations.ts b/x-pack/plugins/lens/server/migrations/common_migrations.ts index 4afe60729920fa..b56f4b691911b3 100644 --- a/x-pack/plugins/lens/server/migrations/common_migrations.ts +++ b/x-pack/plugins/lens/server/migrations/common_migrations.ts @@ -34,6 +34,7 @@ import { XYVisStatePre850, VisState850, LensDocShape850, + LensDocShape860, } from './types'; import { DOCUMENT_FIELD_NAME, LegacyMetricState } from '../../common'; import { isPartitionShape } from '../../common/visualizations'; @@ -477,6 +478,22 @@ export const commonMigrateMetricIds = ( return newAttributes; }; +export const commonMigrateIndexPatternDatasource = ( + attributes: LensDocShape850 +): LensDocShape860 => { + const newAttrs = { + ...attributes, + state: { + ...attributes.state, + datasourceStates: { + formBased: attributes.state.datasourceStates.indexpattern, + }, + }, + }; + + return newAttrs; +}; + export const commonMigratePartitionChartGroups = ( attributes: LensDocShape850<{ shape: string; diff --git a/x-pack/plugins/lens/server/migrations/saved_object_migrations.test.ts b/x-pack/plugins/lens/server/migrations/saved_object_migrations.test.ts index fcb1e2a5722f1f..54504b9201f67b 100644 --- a/x-pack/plugins/lens/server/migrations/saved_object_migrations.test.ts +++ b/x-pack/plugins/lens/server/migrations/saved_object_migrations.test.ts @@ -2363,4 +2363,100 @@ describe('Lens migrations', () => { expect(result.attributes.visualizationType).toBe('lnsMetric'); }); }); + + describe('8.6.0 migrates indexpattern datasource', () => { + const context = { log: { warn: () => {} } } as unknown as SavedObjectMigrationContext; + const example = { + type: 'lens', + id: 'mock-saved-object-id', + attributes: { + state: { + datasourceMetaData: { + filterableIndexPatterns: [ + { + id: 'logstash-*', + title: 'logstash-*', + }, + ], + }, + datasourceStates: { + indexpattern: { + currentIndexPatternId: 'logstash-*', + layers: { + 'c61a8afb-a185-4fae-a064-fb3846f6c451': { + columnOrder: ['2cd09808-3915-49f4-b3b0-82767eba23f7'], + columns: { + '2cd09808-3915-49f4-b3b0-82767eba23f7': { + dataType: 'number', + isBucketed: false, + label: 'Maximum of bytes', + operationType: 'max', + scale: 'ratio', + sourceField: 'bytes', + }, + 'd3e62a7a-c259-4fff-a2fc-eebf20b7008a': { + dataType: 'number', + isBucketed: false, + label: 'Minimum of bytes', + operationType: 'min', + scale: 'ratio', + sourceField: 'bytes', + }, + 'd6e40cea-6299-43b4-9c9d-b4ee305a2ce8': { + dataType: 'date', + isBucketed: true, + label: 'Date Histogram of @timestamp', + operationType: 'date_histogram', + params: { + interval: 'auto', + }, + scale: 'interval', + sourceField: '@timestamp', + }, + }, + indexPatternId: 'logstash-*', + }, + }, + }, + }, + filters: [], + query: { + language: 'kuery', + query: '', + }, + visualization: { + accessor: '2cd09808-3915-49f4-b3b0-82767eba23f7', + isHorizontal: false, + layerId: 'c61a8afb-a185-4fae-a064-fb3846f6c451', + layers: [ + { + accessors: [ + 'd3e62a7a-c259-4fff-a2fc-eebf20b7008a', + '26ef70a9-c837-444c-886e-6bd905ee7335', + ], + layerId: 'c61a8afb-a185-4fae-a064-fb3846f6c451', + seriesType: 'area', + splitAccessor: '54cd64ed-2a44-4591-af84-b2624504569a', + xAccessor: 'd6e40cea-6299-43b4-9c9d-b4ee305a2ce8', + }, + ], + legend: { + isVisible: true, + position: 'right', + }, + preferredSeriesType: 'area', + }, + }, + title: 'Artistpreviouslyknownaslens', + visualizationType: 'lnsXY', + }, + }; + + it('migrates the indexpattern datasource to formBased', () => { + const result = migrations['8.6.0'](example, context); + expect(result.attributes.state.datasourceStates.formBased).toBe( + example.attributes.state.datasourceStates.indexpattern + ); + }); + }); }); diff --git a/x-pack/plugins/lens/server/migrations/saved_object_migrations.ts b/x-pack/plugins/lens/server/migrations/saved_object_migrations.ts index 2f02ca358fcc00..8e4914b94fe838 100644 --- a/x-pack/plugins/lens/server/migrations/saved_object_migrations.ts +++ b/x-pack/plugins/lens/server/migrations/saved_object_migrations.ts @@ -38,6 +38,7 @@ import { LensDocShape850, LensDocShape840, VisState850, + LensDocShape860, } from './types'; import { commonRenameOperationsForFormula, @@ -59,6 +60,7 @@ import { getLensDataViewMigrations, commonMigrateMetricIds, commonMigratePartitionChartGroups, + commonMigrateIndexPatternDatasource, } from './common_migrations'; interface LensDocShapePre710 { @@ -533,6 +535,13 @@ const migrateMetricIds: SavedObjectMigrationFn attributes: commonMigrateMetricIds(doc.attributes), }); +const migrateIndexPatternDatasource: SavedObjectMigrationFn = ( + doc +) => ({ + ...doc, + attributes: commonMigrateIndexPatternDatasource(doc.attributes), +}); + const migratePartitionChartGroups: SavedObjectMigrationFn = ( doc ) => ({ @@ -566,6 +575,7 @@ const lensMigrations: SavedObjectMigrationMap = { ), '8.3.0': flow(lockOldMetricVisSettings, preserveOldLegendSizeDefault, fixValueLabelsInXY), '8.5.0': flow(migrateMetricIds, enrichAnnotationLayers, migratePartitionChartGroups), + '8.6.0': flow(migrateIndexPatternDatasource), }; export const getAllMigrations = ( diff --git a/x-pack/plugins/lens/server/migrations/types.ts b/x-pack/plugins/lens/server/migrations/types.ts index 87c993a712e017..061ba113f734ac 100644 --- a/x-pack/plugins/lens/server/migrations/types.ts +++ b/x-pack/plugins/lens/server/migrations/types.ts @@ -303,3 +303,24 @@ export type VisState840 = VisState830; export type LensDocShape840 = LensDocShape830; export type LensDocShape850 = LensDocShape840; + +export type LensDocShape860 = Omit< + LensDocShape850, + 'state' +> & { + state: Omit['state'], 'datasourceStates'> & { + datasourceStates: { + // This is hardcoded as our only datasource + formBased: { + currentIndexPatternId: string; + layers: Record< + string, + { + columnOrder: string[]; + columns: Record>; + } + >; + }; + }; + }; +}; diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/job_from_lens/visualization_extractor.ts b/x-pack/plugins/ml/public/application/jobs/new_job/job_from_lens/visualization_extractor.ts index d3fe88a390c1ed..31cec1635968f6 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/job_from_lens/visualization_extractor.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/job_from_lens/visualization_extractor.ts @@ -14,8 +14,8 @@ import type { LensSavedObjectAttributes, FieldBasedIndexPatternColumn, XYDataLayerConfig, - IndexPatternPersistedState, - IndexPatternLayer, + FormBasedPersistedState, + FormBasedLayer, XYLayerConfig, } from '@kbn/lens-plugin/public'; import { layerTypes } from '@kbn/lens-plugin/public'; @@ -68,7 +68,7 @@ export class VisualizationExtractor { ); } - const indexpattern = vis.state.datasourceStates.indexpattern as IndexPatternPersistedState; + const indexpattern = vis.state.datasourceStates.formBased as FormBasedPersistedState; const compatibleIndexPatternLayer = Object.entries(indexpattern.layers).find( ([id]) => layer.layerId === id ); @@ -192,10 +192,7 @@ export class VisualizationExtractor { } } -function getColumns( - { columns }: Omit, - layer: XYDataLayerConfig -) { +function getColumns({ columns }: Omit, layer: XYDataLayerConfig) { layer.accessors.forEach((a) => { const col = columns[a]; // fail early if any of the cols being used as accessors 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 8f2953a45834e0..a21684bd0d08c0 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 @@ -118,7 +118,7 @@ describe('Lens Attribute', () => { ReportTypes.KPI ); - expect(lnsAttrKpi.getJSON().state.datasourceStates.indexpattern.layers.layer0.columns).toEqual({ + expect(lnsAttrKpi.getJSON().state.datasourceStates.formBased.layers.layer0.columns).toEqual({ 'x-axis-column-layer0': { dataType: 'date', isBucketed: true, @@ -352,7 +352,7 @@ describe('Lens Attribute', () => { }); it('should return first layer', function () { - expect(lnsAttr.getLayers()).toEqual(sampleAttribute.state.datasourceStates.indexpattern.layers); + expect(lnsAttr.getLayers()).toEqual(sampleAttribute.state.datasourceStates.formBased.layers); }); it('should return expected XYState', function () { 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 3c8c2e5d4bffb7..50701e12f94bee 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 @@ -1100,7 +1100,7 @@ export class LensAttributes { references: this.getReferences(), state: { datasourceStates: { - indexpattern: { + formBased: { layers: this.layers, }, }, diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes/sample_formula_metric_attribute.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes/sample_formula_metric_attribute.ts index d6f572fcacde67..c70d0ee0314517 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes/sample_formula_metric_attribute.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes/sample_formula_metric_attribute.ts @@ -21,7 +21,7 @@ export const sampleMetricFormulaAttribute = { ], state: { datasourceStates: { - indexpattern: { + formBased: { layers: { layer0: { columnOrder: [ diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes/single_metric_attributes.test.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes/single_metric_attributes.test.ts index 2f06db3ae144a7..d6c5bfea5f1d63 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes/single_metric_attributes.test.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes/single_metric_attributes.test.ts @@ -74,7 +74,7 @@ describe('SingleMetricAttributes', () => { ], state: { datasourceStates: { - indexpattern: { + formBased: { layers: { layer0: { columnOrder: ['layer-0-column-1'], @@ -136,7 +136,7 @@ describe('SingleMetricAttributes', () => { ], state: { datasourceStates: { - indexpattern: { + formBased: { layers: { layer0: { columnOrder: ['layer-0-column-1'], diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes/single_metric_attributes.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes/single_metric_attributes.ts index 4dbc2dd86740a9..f674ab1f9914f2 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes/single_metric_attributes.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes/single_metric_attributes.ts @@ -188,7 +188,7 @@ export class SingleMetricLensAttributes extends LensAttributes { state: { visualization, datasourceStates: { - indexpattern: { + formBased: { layers: this.layers, }, }, diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/mobile_test_attribute.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/mobile_test_attribute.ts index 02678ad91ba128..874d6e45b22341 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/mobile_test_attribute.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/mobile_test_attribute.ts @@ -23,7 +23,7 @@ export const testMobileKPIAttr = { visualizationType: 'lnsXY', state: { datasourceStates: { - indexpattern: { + formBased: { layers: { layer0: { columnOrder: ['x-axis-column-layer0', 'y-axis-column-layer0'], diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/sample_attribute.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/sample_attribute.ts index dcc2775a54871a..5302078d372ce7 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/sample_attribute.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/sample_attribute.ts @@ -27,7 +27,7 @@ export const sampleAttribute = { ], state: { datasourceStates: { - indexpattern: { + formBased: { layers: { layer0: { columnOrder: [ diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/sample_attribute_cwv.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/sample_attribute_cwv.ts index a688962459a247..108112e43ae357 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/sample_attribute_cwv.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/sample_attribute_cwv.ts @@ -22,7 +22,7 @@ export const sampleAttributeCoreWebVital = { ], state: { datasourceStates: { - indexpattern: { + formBased: { layers: { layer0: { columnOrder: [ 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 index c5b62ce3f14b45..c1bd53c85b760b 100644 --- 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 @@ -22,7 +22,7 @@ export const sampleAttributeKpi = { ], state: { datasourceStates: { - indexpattern: { + formBased: { layers: { layer0: { columnOrder: ['x-axis-column-layer0', 'y-axis-column-layer0'], diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/sample_attribute_with_reference_lines.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/sample_attribute_with_reference_lines.ts index 32d3d480e777dd..2cf6cdc8a6054c 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/sample_attribute_with_reference_lines.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/sample_attribute_with_reference_lines.ts @@ -27,7 +27,7 @@ export const sampleAttributeWithReferenceLines = { ], state: { datasourceStates: { - indexpattern: { + formBased: { layers: { layer0: { columnOrder: [ diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/embeddable/embeddable.test.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/embeddable/embeddable.test.tsx index fecb9e7172cc67..a6c3cd1777ec56 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/embeddable/embeddable.test.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/embeddable/embeddable.test.tsx @@ -32,7 +32,7 @@ const mockLensAttrs = { }, filters: [], datasourceStates: { - indexpattern: { + formBased: { layers: { '416b6fad-1923-4f6a-a2df-b223bb287e30': { columnOrder: ['b00c65ea-32be-4163-bfc8-f795b1ef9d06'], diff --git a/x-pack/plugins/osquery/public/lens/view_results_in_lens.tsx b/x-pack/plugins/osquery/public/lens/view_results_in_lens.tsx index 080c078f6a290a..a61e986fd12012 100644 --- a/x-pack/plugins/osquery/public/lens/view_results_in_lens.tsx +++ b/x-pack/plugins/osquery/public/lens/view_results_in_lens.tsx @@ -174,7 +174,7 @@ function getLensAttributes( ], state: { datasourceStates: { - indexpattern: { + formBased: { layers: { layer1: dataLayer, }, diff --git a/x-pack/plugins/osquery/public/packs/pack_queries_status_table.tsx b/x-pack/plugins/osquery/public/packs/pack_queries_status_table.tsx index 2ba4a76c48515b..df08fa6d1bf9bb 100644 --- a/x-pack/plugins/osquery/public/packs/pack_queries_status_table.tsx +++ b/x-pack/plugins/osquery/public/packs/pack_queries_status_table.tsx @@ -151,7 +151,7 @@ function getLensAttributes( ], state: { datasourceStates: { - indexpattern: { + formBased: { layers: { layer1: dataLayer, }, diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/__snapshots__/authentication.test.ts.snap b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/__snapshots__/authentication.test.ts.snap index 747487203066ba..f683d2828bae3a 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/__snapshots__/authentication.test.ts.snap +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/__snapshots__/authentication.test.ts.snap @@ -27,7 +27,7 @@ Object { ], "state": Object { "datasourceStates": Object { - "indexpattern": Object { + "formBased": Object { "layers": Object { "3fd0c5d5-f762-4a27-8c56-14eee0223e13": Object { "columnOrder": Array [ diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/__snapshots__/external_alert.test.ts.snap b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/__snapshots__/external_alert.test.ts.snap index ac42b228012fe0..425f545129ee61 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/__snapshots__/external_alert.test.ts.snap +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/__snapshots__/external_alert.test.ts.snap @@ -27,7 +27,7 @@ Object { ], "state": Object { "datasourceStates": Object { - "indexpattern": Object { + "formBased": Object { "layers": Object { "a3c54471-615f-4ff9-9fda-69b5b2ea3eef": Object { "columnOrder": Array [ diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/authentication.ts b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/authentication.ts index 15d7f029ae6120..4e69bac6287ecb 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/authentication.ts +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/authentication.ts @@ -98,7 +98,7 @@ export const authenticationLensAttributes: LensAttributes = { }, ], datasourceStates: { - indexpattern: { + formBased: { layers: { '3fd0c5d5-f762-4a27-8c56-14eee0223e13': { columns: { diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/external_alert.ts b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/external_alert.ts index a815d442b043e6..f5a664b98161bb 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/external_alert.ts +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/common/external_alert.ts @@ -71,7 +71,7 @@ export const getExternalAlertLensAttributes: GetLensAttributes = ( }, ], datasourceStates: { - indexpattern: { + formBased: { layers: { 'a3c54471-615f-4ff9-9fda-69b5b2ea3eef': { columns: { diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/event.test.ts.snap b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/event.test.ts.snap index 7f3fdb6c661070..129a82aa1692c8 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/event.test.ts.snap +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/event.test.ts.snap @@ -17,7 +17,7 @@ Object { ], "state": Object { "datasourceStates": Object { - "indexpattern": Object { + "formBased": Object { "layers": Object { "0039eb0c-9a1a-4687-ae54-0f4e239bec75": Object { "columnOrder": Array [ diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/kpi_host_area.test.ts.snap b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/kpi_host_area.test.ts.snap index c5e4e272ec9c4b..b9165ea5c38a8f 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/kpi_host_area.test.ts.snap +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/kpi_host_area.test.ts.snap @@ -17,7 +17,7 @@ Object { ], "state": Object { "datasourceStates": Object { - "indexpattern": Object { + "formBased": Object { "layers": Object { "416b6fad-1923-4f6a-a2df-b223bb287e30": Object { "columnOrder": Array [ diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/kpi_host_metric.test.ts.snap b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/kpi_host_metric.test.ts.snap index 3669de2d301094..ea37bec0d1976d 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/kpi_host_metric.test.ts.snap +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/kpi_host_metric.test.ts.snap @@ -17,7 +17,7 @@ Object { ], "state": Object { "datasourceStates": Object { - "indexpattern": Object { + "formBased": Object { "layers": Object { "416b6fad-1923-4f6a-a2df-b223bb287e30": Object { "columnOrder": Array [ diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/kpi_unique_ips_area.test.ts.snap b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/kpi_unique_ips_area.test.ts.snap index acaf78556269f7..f45cd86c70ed2e 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/kpi_unique_ips_area.test.ts.snap +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/kpi_unique_ips_area.test.ts.snap @@ -22,7 +22,7 @@ Object { ], "state": Object { "datasourceStates": Object { - "indexpattern": Object { + "formBased": Object { "layers": Object { "8be0156b-d423-4a39-adf1-f54d4c9f2e69": Object { "columnOrder": Array [ diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/kpi_unique_ips_bar.test.ts.snap b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/kpi_unique_ips_bar.test.ts.snap index 9f702ecb064129..0a66d46f9a7dbb 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/kpi_unique_ips_bar.test.ts.snap +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/kpi_unique_ips_bar.test.ts.snap @@ -22,7 +22,7 @@ Object { ], "state": Object { "datasourceStates": Object { - "indexpattern": Object { + "formBased": Object { "layers": Object { "8be0156b-d423-4a39-adf1-f54d4c9f2e69": Object { "columnOrder": Array [ diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/kpi_unique_ips_destination_metric.test.ts.snap b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/kpi_unique_ips_destination_metric.test.ts.snap index ebeb85e27a44f1..3ca56d9f020b22 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/kpi_unique_ips_destination_metric.test.ts.snap +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/kpi_unique_ips_destination_metric.test.ts.snap @@ -17,7 +17,7 @@ Object { ], "state": Object { "datasourceStates": Object { - "indexpattern": Object { + "formBased": Object { "layers": Object { "8be0156b-d423-4a39-adf1-f54d4c9f2e69": Object { "columnOrder": Array [ diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/kpi_unique_ips_source_metric.test.ts.snap b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/kpi_unique_ips_source_metric.test.ts.snap index f8ec7bb8c70d7b..2972842a6f419f 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/kpi_unique_ips_source_metric.test.ts.snap +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/__snapshots__/kpi_unique_ips_source_metric.test.ts.snap @@ -17,7 +17,7 @@ Object { ], "state": Object { "datasourceStates": Object { - "indexpattern": Object { + "formBased": Object { "layers": Object { "8be0156b-d423-4a39-adf1-f54d4c9f2e69": Object { "columnOrder": Array [ diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/events.ts b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/events.ts index da244d40565fb9..f07716f8c4bd7b 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/events.ts +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/events.ts @@ -53,7 +53,7 @@ export const getEventsHistogramLensAttributes: GetLensAttributes = ( }, filters: [], datasourceStates: { - indexpattern: { + formBased: { layers: { '0039eb0c-9a1a-4687-ae54-0f4e239bec75': { columns: { diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_host_area.ts b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_host_area.ts index 64f62133e9406d..6eb400734ebe04 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_host_area.ts +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_host_area.ts @@ -12,7 +12,7 @@ export const kpiHostAreaLensAttributes: LensAttributes = { description: '', state: { datasourceStates: { - indexpattern: { + formBased: { layers: { '416b6fad-1923-4f6a-a2df-b223bb287e30': { columnOrder: [ diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_host_metric.ts b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_host_metric.ts index 00ab0239acb406..66b6b63a693218 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_host_metric.ts +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_host_metric.ts @@ -11,7 +11,7 @@ export const kpiHostMetricLensAttributes: LensAttributes = { description: '', state: { datasourceStates: { - indexpattern: { + formBased: { layers: { '416b6fad-1923-4f6a-a2df-b223bb287e30': { columnOrder: ['b00c65ea-32be-4163-bfc8-f795b1ef9d06'], diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_area.ts b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_area.ts index ac0d102a5f03c0..79539f40390afa 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_area.ts +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_area.ts @@ -12,7 +12,7 @@ export const kpiUniqueIpsAreaLensAttributes: LensAttributes = { description: '', state: { datasourceStates: { - indexpattern: { + formBased: { layers: { '8be0156b-d423-4a39-adf1-f54d4c9f2e69': { columnOrder: [ diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_bar.ts b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_bar.ts index cf7dbf21913b5e..862eb64b44eeb3 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_bar.ts +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_bar.ts @@ -12,7 +12,7 @@ export const kpiUniqueIpsBarLensAttributes: LensAttributes = { description: '', state: { datasourceStates: { - indexpattern: { + formBased: { layers: { '8be0156b-d423-4a39-adf1-f54d4c9f2e69': { columnOrder: [ diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_destination_metric.ts b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_destination_metric.ts index 5c4aa31f658335..094bc189f1ac73 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_destination_metric.ts +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_destination_metric.ts @@ -11,7 +11,7 @@ export const kpiUniqueIpsDestinationMetricLensAttributes: LensAttributes = { description: '', state: { datasourceStates: { - indexpattern: { + formBased: { layers: { '8be0156b-d423-4a39-adf1-f54d4c9f2e69': { columnOrder: ['d9a6eb6b-8b78-439e-98e7-a718f8ffbebe'], diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_source_metric.ts b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_source_metric.ts index 4d308b95d796d7..388f5ef53b3014 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_source_metric.ts +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/hosts/kpi_unique_ips_source_metric.ts @@ -11,7 +11,7 @@ export const kpiUniqueIpsSourceMetricLensAttributes: LensAttributes = { description: '', state: { datasourceStates: { - indexpattern: { + formBased: { layers: { '8be0156b-d423-4a39-adf1-f54d4c9f2e69': { columnOrder: ['d9a6eb6b-8b78-439e-98e7-a718f8ffbebe'], diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/dns_top_domains.test.ts.snap b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/dns_top_domains.test.ts.snap index 6e0f9c2bbd516c..392d68b512b41a 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/dns_top_domains.test.ts.snap +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/dns_top_domains.test.ts.snap @@ -22,7 +22,7 @@ Object { ], "state": Object { "datasourceStates": Object { - "indexpattern": Object { + "formBased": Object { "layers": Object { "b1c3efc6-c886-4fba-978f-3b6bb5e7948a": Object { "columnOrder": Array [ diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_dns_queries.test.ts.snap b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_dns_queries.test.ts.snap index 39f16779abaf4f..173a1229e1282f 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_dns_queries.test.ts.snap +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_dns_queries.test.ts.snap @@ -22,7 +22,7 @@ Object { ], "state": Object { "datasourceStates": Object { - "indexpattern": Object { + "formBased": Object { "layers": Object { "cea37c70-8f91-43bf-b9fe-72d8c049f6a3": Object { "columnOrder": Array [ diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_network_events.test.ts.snap b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_network_events.test.ts.snap index 03bacfac49ad71..c9b0441a25a4b0 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_network_events.test.ts.snap +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_network_events.test.ts.snap @@ -27,7 +27,7 @@ Object { ], "state": Object { "datasourceStates": Object { - "indexpattern": Object { + "formBased": Object { "layers": Object { "eaadfec7-deaa-4aeb-a403-3b4e516416d2": Object { "columnOrder": Array [ diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_tls_handshakes.test.ts.snap b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_tls_handshakes.test.ts.snap index 6e695484fdc0f0..532d81001ab062 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_tls_handshakes.test.ts.snap +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_tls_handshakes.test.ts.snap @@ -17,7 +17,7 @@ Object { ], "state": Object { "datasourceStates": Object { - "indexpattern": Object { + "formBased": Object { "layers": Object { "1f48a633-8eee-45ae-9471-861227e9ca03": Object { "columnOrder": Array [ diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_unique_flow_ids.test.ts.snap b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_unique_flow_ids.test.ts.snap index 1e3f1f63c40c8a..60a52f4f5b4a9f 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_unique_flow_ids.test.ts.snap +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_unique_flow_ids.test.ts.snap @@ -17,7 +17,7 @@ Object { ], "state": Object { "datasourceStates": Object { - "indexpattern": Object { + "formBased": Object { "layers": Object { "5d46d48f-6ce8-46be-a797-17ad50642564": Object { "columnOrder": Array [ diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_unique_private_ips_area.test.ts.snap b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_unique_private_ips_area.test.ts.snap index 2415dcc6c750c5..11e3f62d0cd4cc 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_unique_private_ips_area.test.ts.snap +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_unique_private_ips_area.test.ts.snap @@ -22,7 +22,7 @@ Object { ], "state": Object { "datasourceStates": Object { - "indexpattern": Object { + "formBased": Object { "layers": Object { "38aa6532-6bf9-4c8f-b2a6-da8d32f7d0d7": Object { "columnOrder": Array [ diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_unique_private_ips_bar.test.ts.snap b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_unique_private_ips_bar.test.ts.snap index 2ea658869183c8..2a702bb87f3fda 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_unique_private_ips_bar.test.ts.snap +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_unique_private_ips_bar.test.ts.snap @@ -22,7 +22,7 @@ Object { ], "state": Object { "datasourceStates": Object { - "indexpattern": Object { + "formBased": Object { "layers": Object { "38aa6532-6bf9-4c8f-b2a6-da8d32f7d0d7": Object { "columnOrder": Array [ diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_unique_private_ips_destination_metric.test.ts.snap b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_unique_private_ips_destination_metric.test.ts.snap index 37311a980c6b48..9f205c5c23c070 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_unique_private_ips_destination_metric.test.ts.snap +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_unique_private_ips_destination_metric.test.ts.snap @@ -17,7 +17,7 @@ Object { ], "state": Object { "datasourceStates": Object { - "indexpattern": Object { + "formBased": Object { "layers": Object { "cea37c70-8f91-43bf-b9fe-72d8c049f6a3": Object { "columnOrder": Array [ diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_unique_private_ips_source_metric.test.ts.snap b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_unique_private_ips_source_metric.test.ts.snap index 2f7ba7d2997b1c..b7e25a6ceb8f42 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_unique_private_ips_source_metric.test.ts.snap +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/kpi_unique_private_ips_source_metric.test.ts.snap @@ -17,7 +17,7 @@ Object { ], "state": Object { "datasourceStates": Object { - "indexpattern": Object { + "formBased": Object { "layers": Object { "cea37c70-8f91-43bf-b9fe-72d8c049f6a3": Object { "columnOrder": Array [ diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/dns_top_domains.ts b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/dns_top_domains.ts index ef75bea77c3e09..0f195bdeaa8d4e 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/dns_top_domains.ts +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/dns_top_domains.ts @@ -89,7 +89,7 @@ export const dnsTopDomainsLensAttributes: LensAttributes = { }, ], datasourceStates: { - indexpattern: { + formBased: { layers: { 'b1c3efc6-c886-4fba-978f-3b6bb5e7948a': { columns: { diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_dns_queries.ts b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_dns_queries.ts index 681cd278214b1a..c4691a4797b5b6 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_dns_queries.ts +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_dns_queries.ts @@ -64,7 +64,7 @@ export const kpiDnsQueriesLensAttributes: LensAttributes = { }, ], datasourceStates: { - indexpattern: { + formBased: { layers: { 'cea37c70-8f91-43bf-b9fe-72d8c049f6a3': { columns: { diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_network_events.ts b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_network_events.ts index 534ffeb2024e65..bb88ceb732c663 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_network_events.ts +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_network_events.ts @@ -62,7 +62,7 @@ export const kpiNetworkEventsLensAttributes: LensAttributes = { }, ], datasourceStates: { - indexpattern: { + formBased: { layers: { 'eaadfec7-deaa-4aeb-a403-3b4e516416d2': { columns: { diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_tls_handshakes.ts b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_tls_handshakes.ts index 367fe6fd40f6f9..b7b651bf56362f 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_tls_handshakes.ts +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_tls_handshakes.ts @@ -93,7 +93,7 @@ export const kpiTlsHandshakesLensAttributes: LensAttributes = { }, ], datasourceStates: { - indexpattern: { + formBased: { layers: { '1f48a633-8eee-45ae-9471-861227e9ca03': { columns: { diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_unique_flow_ids.ts b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_unique_flow_ids.ts index 5f31645c75ecae..3660f2ff6ad06b 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_unique_flow_ids.ts +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_unique_flow_ids.ts @@ -56,7 +56,7 @@ export const kpiUniqueFlowIdsLensAttributes: LensAttributes = { }, ], datasourceStates: { - indexpattern: { + formBased: { layers: { '5d46d48f-6ce8-46be-a797-17ad50642564': { columns: { diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_area.ts b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_area.ts index 394bc227e871c4..86e9f21d7ffef3 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_area.ts +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_area.ts @@ -82,7 +82,7 @@ export const kpiUniquePrivateIpsAreaLensAttributes: LensAttributes = { }, filters: [], datasourceStates: { - indexpattern: { + formBased: { layers: { '38aa6532-6bf9-4c8f-b2a6-da8d32f7d0d7': { columns: { diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_bar.ts b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_bar.ts index fe4a698aedf5ef..07a81a273e2b52 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_bar.ts +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_bar.ts @@ -85,7 +85,7 @@ export const kpiUniquePrivateIpsBarLensAttributes: LensAttributes = { }, filters: [], datasourceStates: { - indexpattern: { + formBased: { layers: { 'e406bf4f-942b-41ac-b516-edb5cef06ec8': { columns: { diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_destination_metric.ts b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_destination_metric.ts index 6e3d440619e768..bcdd7d377b82b0 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_destination_metric.ts +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_destination_metric.ts @@ -11,7 +11,7 @@ export const kpiUniquePrivateIpsDestinationMetricLensAttributes: LensAttributes description: '', state: { datasourceStates: { - indexpattern: { + formBased: { layers: { 'cea37c70-8f91-43bf-b9fe-72d8c049f6a3': { columnOrder: ['bd17c23e-4f83-4108-8005-2669170d064b'], diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_source_metric.ts b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_source_metric.ts index 3f1110d7063003..411dd90828a7bc 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_source_metric.ts +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/kpi_unique_private_ips_source_metric.ts @@ -10,7 +10,7 @@ export const kpiUniquePrivateIpsSourceMetricLensAttributes: LensAttributes = { description: '', state: { datasourceStates: { - indexpattern: { + formBased: { layers: { 'cea37c70-8f91-43bf-b9fe-72d8c049f6a3': { columnOrder: ['bd17c23e-4f83-4108-8005-2669170d064b'], diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/__snapshots__/kpi_total_users_area.test.ts.snap b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/__snapshots__/kpi_total_users_area.test.ts.snap index 11df964f2eca14..f474a4c9d6e101 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/__snapshots__/kpi_total_users_area.test.ts.snap +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/__snapshots__/kpi_total_users_area.test.ts.snap @@ -17,7 +17,7 @@ Object { ], "state": Object { "datasourceStates": Object { - "indexpattern": Object { + "formBased": Object { "layers": Object { "416b6fad-1923-4f6a-a2df-b223bb287e30": Object { "columnOrder": Array [ diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/__snapshots__/kpi_total_users_metric.test.ts.snap b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/__snapshots__/kpi_total_users_metric.test.ts.snap index b53e1bd24d3038..eef74c94537d43 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/__snapshots__/kpi_total_users_metric.test.ts.snap +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/__snapshots__/kpi_total_users_metric.test.ts.snap @@ -17,7 +17,7 @@ Object { ], "state": Object { "datasourceStates": Object { - "indexpattern": Object { + "formBased": Object { "layers": Object { "416b6fad-1923-4f6a-a2df-b223bb287e30": Object { "columnOrder": Array [ diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/__snapshots__/kpi_user_authentication_metric_failure.test.ts.snap b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/__snapshots__/kpi_user_authentication_metric_failure.test.ts.snap index 37c20b7e802656..b87fad1faa0550 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/__snapshots__/kpi_user_authentication_metric_failure.test.ts.snap +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/__snapshots__/kpi_user_authentication_metric_failure.test.ts.snap @@ -17,7 +17,7 @@ Object { ], "state": Object { "datasourceStates": Object { - "indexpattern": Object { + "formBased": Object { "layers": Object { "4590dafb-4ac7-45aa-8641-47a3ff0b817c": Object { "columnOrder": Array [ diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/__snapshots__/kpi_user_authentications_area.test.ts.snap b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/__snapshots__/kpi_user_authentications_area.test.ts.snap index 1954bccfaffbe1..1dcaab239de8e8 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/__snapshots__/kpi_user_authentications_area.test.ts.snap +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/__snapshots__/kpi_user_authentications_area.test.ts.snap @@ -22,7 +22,7 @@ Object { ], "state": Object { "datasourceStates": Object { - "indexpattern": Object { + "formBased": Object { "layers": Object { "31213ae3-905b-4e88-b987-0cccb1f3209f": Object { "columnOrder": Array [ diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/__snapshots__/kpi_user_authentications_bar.test.ts.snap b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/__snapshots__/kpi_user_authentications_bar.test.ts.snap index 5335dca6057a63..ac7c883ca71b71 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/__snapshots__/kpi_user_authentications_bar.test.ts.snap +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/__snapshots__/kpi_user_authentications_bar.test.ts.snap @@ -22,7 +22,7 @@ Object { ], "state": Object { "datasourceStates": Object { - "indexpattern": Object { + "formBased": Object { "layers": Object { "31213ae3-905b-4e88-b987-0cccb1f3209f": Object { "columnOrder": Array [ diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/__snapshots__/kpi_user_authentications_metric_success.test.ts.snap b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/__snapshots__/kpi_user_authentications_metric_success.test.ts.snap index 4cadcaf19e91ec..0b652257864c0d 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/__snapshots__/kpi_user_authentications_metric_success.test.ts.snap +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/__snapshots__/kpi_user_authentications_metric_success.test.ts.snap @@ -17,7 +17,7 @@ Object { ], "state": Object { "datasourceStates": Object { - "indexpattern": Object { + "formBased": Object { "layers": Object { "4590dafb-4ac7-45aa-8641-47a3ff0b817c": Object { "columnOrder": Array [ diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_total_users_area.ts b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_total_users_area.ts index c97748077a6be0..c241d03266cc34 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_total_users_area.ts +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_total_users_area.ts @@ -12,7 +12,7 @@ export const kpiTotalUsersAreaLensAttributes: LensAttributes = { description: '', state: { datasourceStates: { - indexpattern: { + formBased: { layers: { '416b6fad-1923-4f6a-a2df-b223bb287e30': { columnOrder: [ diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_total_users_metric.ts b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_total_users_metric.ts index faa6b62e18b651..08cfed0cb91f70 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_total_users_metric.ts +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_total_users_metric.ts @@ -11,7 +11,7 @@ export const kpiTotalUsersMetricLensAttributes: LensAttributes = { description: '', state: { datasourceStates: { - indexpattern: { + formBased: { layers: { '416b6fad-1923-4f6a-a2df-b223bb287e30': { columnOrder: ['3e51b035-872c-4b44-824b-fe069c222e91'], diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_user_authentication_metric_failure.ts b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_user_authentication_metric_failure.ts index 3f421f8a1c30a1..238a8b95e35d95 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_user_authentication_metric_failure.ts +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_user_authentication_metric_failure.ts @@ -49,7 +49,7 @@ export const kpiUserAuthenticationsMetricFailureLensAttributes: LensAttributes = }, ], datasourceStates: { - indexpattern: { + formBased: { layers: { '4590dafb-4ac7-45aa-8641-47a3ff0b817c': { columnOrder: ['0eb97c09-a351-4280-97da-944e4bd30dd7'], diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_user_authentications_area.ts b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_user_authentications_area.ts index d96ea21489bb25..da6bdf139a1ca7 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_user_authentications_area.ts +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_user_authentications_area.ts @@ -109,7 +109,7 @@ export const kpiUserAuthenticationsAreaLensAttributes: LensAttributes = { }, ], datasourceStates: { - indexpattern: { + formBased: { layers: { '31213ae3-905b-4e88-b987-0cccb1f3209f': { columnOrder: [ diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_user_authentications_bar.ts b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_user_authentications_bar.ts index 4727c6010b7518..a4a1629e360de4 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_user_authentications_bar.ts +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_user_authentications_bar.ts @@ -104,7 +104,7 @@ export const kpiUserAuthenticationsBarLensAttributes: LensAttributes = { }, ], datasourceStates: { - indexpattern: { + formBased: { layers: { '31213ae3-905b-4e88-b987-0cccb1f3209f': { columnOrder: [ diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_user_authentications_metric_success.ts b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_user_authentications_metric_success.ts index 3af6f5734d458d..58ee89ac81b42f 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_user_authentications_metric_success.ts +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/users/kpi_user_authentications_metric_success.ts @@ -49,7 +49,7 @@ export const kpiUserAuthenticationsMetricSuccessLensAttributes: LensAttributes = }, ], datasourceStates: { - indexpattern: { + formBased: { layers: { '4590dafb-4ac7-45aa-8641-47a3ff0b817c': { columnOrder: ['0eb97c09-a351-4280-97da-944e4bd30dd7'], diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/index.tsx b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/index.tsx index 2d8491879d0602..d88ad343eab3cc 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/anomalies/index.tsx @@ -37,6 +37,8 @@ const TABLE_SORTING = { }, } as const; +export const ENTITY_ANALYTICS_ANOMALIES_PANEL = 'entity_analytics_anomalies'; + export const EntityAnalyticsAnomalies = () => { const { services: { ml, http }, @@ -86,7 +88,7 @@ export const EntityAnalyticsAnomalies = () => { }, [getSecuritySolutionLinkProps]); return ( - + eui.euiColorDanger}; @@ -74,10 +73,6 @@ export const EntityAnalyticsHeader = () => { const getSecuritySolutionLinkProps = useGetSecuritySolutionLinkProps(); const isPlatinumOrTrialLicense = useMlCapabilities().isPlatinumOrTrialLicense; - const { - services: { ml, http }, - } = useKibana(); - const [goToHostRiskTabFilteredByCritical, hostRiskTabUrl] = useMemo(() => { const { onClick, href } = getSecuritySolutionLinkProps({ deepLinkId: SecurityPageName.hosts, @@ -151,9 +146,14 @@ export const EntityAnalyticsHeader = () => { [data, areJobsEnabled] ); - const jobsUrl = useMlHref(ml, http.basePath.get(), { - page: ML_PAGES.ANOMALY_DETECTION_JOBS_MANAGE, - }); + const scrollToAnomalies = useCallback(() => { + const element = document.querySelector( + `[data-test-subj="${ENTITY_ANALYTICS_ANOMALIES_PANEL}"]` + ); + if (element) { + element.scrollIntoView({ behavior: 'smooth' }); + } + }, []); return ( @@ -211,9 +211,9 @@ export const EntityAnalyticsHeader = () => { - + {i18n.ANOMALIES} - + diff --git a/x-pack/plugins/synthetics/e2e/journeys/data_view_permissions.ts b/x-pack/plugins/synthetics/e2e/journeys/data_view_permissions.ts index e5714234de690c..5aa7ee96f25b1a 100644 --- a/x-pack/plugins/synthetics/e2e/journeys/data_view_permissions.ts +++ b/x-pack/plugins/synthetics/e2e/journeys/data_view_permissions.ts @@ -6,8 +6,12 @@ */ import { journey, step, expect, before } from '@elastic/synthetics'; +import { + byTestId, + TIMEOUT_60_SEC, + waitForLoadingToFinish, +} from '@kbn/observability-plugin/e2e/utils'; import { callKibana } from '@kbn/apm-plugin/server/test_helpers/create_apm_users/helpers/call_kibana'; -import { byTestId, waitForLoadingToFinish } from '@kbn/observability-plugin/e2e/utils'; import { loginPageProvider } from '../page_objects/login'; journey('DataViewPermissions', async ({ page, params }) => { @@ -44,7 +48,7 @@ journey('DataViewPermissions', async ({ page, params }) => { step('Click explore data button', async () => { await page.click(byTestId('uptimeExploreDataButton')); await waitForLoadingToFinish({ page }); - await page.waitForSelector(`text=${permissionError}`); + await page.waitForSelector(`text=${permissionError}`, TIMEOUT_60_SEC); expect(await page.$(`text=${permissionError}`)).toBeTruthy(); }); }); diff --git a/x-pack/plugins/synthetics/e2e/journeys/index.ts b/x-pack/plugins/synthetics/e2e/journeys/index.ts index a33a5185fcac2a..5651b092544ded 100644 --- a/x-pack/plugins/synthetics/e2e/journeys/index.ts +++ b/x-pack/plugins/synthetics/e2e/journeys/index.ts @@ -5,9 +5,9 @@ * 2.0. */ +export * from './data_view_permissions'; export * from './synthetics'; export * from './alerts'; -export * from './data_view_permissions'; export * from './uptime.journey'; export * from './step_duration.journey'; export * from './read_only_user'; diff --git a/x-pack/plugins/synthetics/e2e/journeys/synthetics/index.ts b/x-pack/plugins/synthetics/e2e/journeys/synthetics/index.ts index 3c8869fab85a8e..1b74aa6a05b42e 100644 --- a/x-pack/plugins/synthetics/e2e/journeys/synthetics/index.ts +++ b/x-pack/plugins/synthetics/e2e/journeys/synthetics/index.ts @@ -7,3 +7,4 @@ export * from './getting_started.journey'; export * from './add_monitor.journey'; +export * from './monitor_selector.journey'; diff --git a/x-pack/plugins/synthetics/e2e/journeys/synthetics/monitor_selector.journey.ts b/x-pack/plugins/synthetics/e2e/journeys/synthetics/monitor_selector.journey.ts new file mode 100644 index 00000000000000..866df48d97e781 --- /dev/null +++ b/x-pack/plugins/synthetics/e2e/journeys/synthetics/monitor_selector.journey.ts @@ -0,0 +1,62 @@ +/* + * 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 { journey, step, expect, before } from '@elastic/synthetics'; +import { + addTestMonitor, + cleanTestMonitors, + enableMonitorManagedViaApi, +} from './services/add_monitor'; +import { syntheticsAppPageProvider } from '../../page_objects/synthetics_app'; + +journey(`MonitorSelector`, async ({ page, params }) => { + const syntheticsApp = syntheticsAppPageProvider({ page, kibanaUrl: params.kibanaUrl }); + const testMonitor1 = 'Test monitor 1'; + const testMonitor2 = 'Test monitor 2'; + const testMonitor3 = 'Test monitor 3'; + + before(async () => { + await enableMonitorManagedViaApi(params.kibanaUrl); + await cleanTestMonitors(params); + + await addTestMonitor(params.kibanaUrl, testMonitor1); + await addTestMonitor(params.kibanaUrl, testMonitor2); + await addTestMonitor(params.kibanaUrl, testMonitor3); + }); + + step('Go to monitor-management', async () => { + await syntheticsApp.navigateToMonitorManagement(); + }); + + step('login to Kibana', async () => { + await syntheticsApp.loginToKibana(); + const invalid = await page.locator(`text=Username or password is incorrect. Please try again.`); + expect(await invalid.isVisible()).toBeFalsy(); + }); + + step('go to monitor', async () => { + await page.click('text=' + testMonitor1); + }); + + step('shows recently viewed monitors', async () => { + await page.click('text=' + testMonitor1); + await page.click('[aria-label="Select a different monitor to view its details"]'); + await page.click('text=' + testMonitor2); + + await page.click('[aria-label="Select a different monitor to view its details"]'); + await page.click('text=Recently viewed'); + await page.click('text=Other monitors'); + await page.click('text=' + testMonitor3); + + await page.click('[aria-label="Select a different monitor to view its details"]'); + await page.click('[placeholder="Monitor name or tag"]'); + await page.fill('[placeholder="Monitor name or tag"]', '2'); + await page.click('text=' + testMonitor2); + + await page.click('[aria-label="Select a different monitor to view its details"]'); + }); +}); diff --git a/x-pack/plugins/synthetics/e2e/journeys/synthetics/services/add_monitor.ts b/x-pack/plugins/synthetics/e2e/journeys/synthetics/services/add_monitor.ts new file mode 100644 index 00000000000000..37078cb3c06766 --- /dev/null +++ b/x-pack/plugins/synthetics/e2e/journeys/synthetics/services/add_monitor.ts @@ -0,0 +1,96 @@ +/* + * 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 axios from 'axios'; + +export const enableMonitorManagedViaApi = async (kibanaUrl: string) => { + try { + await axios.post(kibanaUrl + '/internal/uptime/service/enablement', undefined, { + auth: { username: 'elastic', password: 'changeme' }, + headers: { 'kbn-xsrf': 'true' }, + }); + } catch (e) { + // eslint-disable-next-line no-console + console.log(e); + } +}; + +export const addTestMonitor = async (kibanaUrl: string, name: string) => { + data.name = name; + + try { + await axios.post(kibanaUrl + '/internal/uptime/service/monitors', data, { + auth: { username: 'elastic', password: 'changeme' }, + headers: { 'kbn-xsrf': 'true' }, + }); + } catch (e) { + // eslint-disable-next-line no-console + console.log(e); + } +}; + +export const cleanTestMonitors = async (params: Record) => { + const getService = params.getService; + const server = getService('kibanaServer'); + + try { + await server.savedObjects.clean({ types: ['synthetics-monitor'] }); + } catch (e) { + // eslint-disable-next-line no-console + console.log(e); + } +}; + +const data = { + type: 'browser', + form_monitor_type: 'single', + enabled: true, + schedule: { unit: 'm', number: '10' }, + 'service.name': '', + config_id: '', + tags: [], + timeout: '16', + name: 'Monitor 2', + locations: [{ id: 'us_central', isServiceManaged: true }], + namespace: 'default', + origin: 'ui', + journey_id: '', + project_id: '', + playwright_options: '', + __ui: { + script_source: { is_generated_script: false, file_name: '' }, + is_zip_url_tls_enabled: false, + }, + params: '', + 'url.port': null, + 'source.inline.script': + "step('Go to https://www.google.com', async () => {\n await page.goto('https://www.google.com');\n expect(await page.isVisible('text=Data')).toBeTruthy();\n });", + 'source.project.content': '', + 'source.zip_url.url': '', + 'source.zip_url.username': '', + 'source.zip_url.password': '', + 'source.zip_url.folder': '', + 'source.zip_url.proxy_url': '', + playwright_text_assertion: 'Data', + urls: 'https://www.google.com', + screenshots: 'on', + synthetics_args: [], + 'filter_journeys.match': '', + 'filter_journeys.tags': [], + ignore_https_errors: false, + 'throttling.is_enabled': true, + 'throttling.download_speed': '5', + 'throttling.upload_speed': '3', + 'throttling.latency': '20', + 'throttling.config': '5d/3u/20l', + 'ssl.certificate_authorities': '', + 'ssl.certificate': '', + 'ssl.key': '', + 'ssl.key_passphrase': '', + 'ssl.verification_mode': 'full', + 'ssl.supported_protocols': ['TLSv1.1', 'TLSv1.2', 'TLSv1.3'], +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/links/add_monitor.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/links/add_monitor.tsx new file mode 100644 index 00000000000000..41cf49f5703f4d --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/links/add_monitor.tsx @@ -0,0 +1,25 @@ +/* + * 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 { EuiButtonEmpty } from '@elastic/eui'; +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { useSyntheticsSettingsContext } from '../../../contexts'; + +export const AddMonitorLink = () => { + const { basePath } = useSyntheticsSettingsContext(); + + return ( + + {CREATE_NEW_MONITOR} + + ); +}; + +const CREATE_NEW_MONITOR = i18n.translate('xpack.synthetics.monitorSummary.createNewMonitor', { + defaultMessage: 'Create monitor', +}); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_details_page_title.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_details_page_title.tsx index b0ea152e1626bb..abe1a496df1a6d 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_details_page_title.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_details_page_title.tsx @@ -6,9 +6,19 @@ */ import React from 'react'; +import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { MonitorSelector } from './monitor_selector/monitor_selector'; import { useSelectedMonitor } from './hooks/use_selected_monitor'; export const MonitorDetailsPageTitle = () => { const { monitor } = useSelectedMonitor(); - return <>{monitor ? monitor.name : null}; + + return ( + + {monitor?.name} + + + + + ); }; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_selector/monitor_selector.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_selector/monitor_selector.tsx new file mode 100644 index 00000000000000..3fb4ff71aaf744 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_selector/monitor_selector.tsx @@ -0,0 +1,160 @@ +/* + * 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 React, { Fragment, useEffect, useState } from 'react'; +import { + EuiPopover, + EuiPopoverTitle, + EuiSelectable, + EuiButtonIcon, + EuiSelectableOption, + EuiHighlight, + EuiLink, + EuiText, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { useHistory } from 'react-router-dom'; +import { AddMonitorLink } from '../../common/links/add_monitor'; +import { useRecentlyViewedMonitors } from './use_recently_viewed_monitors'; +import { useSyntheticsSettingsContext } from '../../../contexts'; +import { useMonitorName } from './use_monitor_name'; +import { useSelectedLocation } from '../hooks/use_selected_location'; + +export const MonitorSelector = () => { + const history = useHistory(); + + const [options, setOptions] = useState([]); + const [searchValue, setSearchValue] = useState(''); + const [isPopoverOpen, setIsPopoverOpen] = useState(false); + + const selectedLocation = useSelectedLocation(); + + const { basePath } = useSyntheticsSettingsContext(); + + const { values, loading } = useMonitorName({ search: searchValue }); + + const recentlyViewed = useRecentlyViewedMonitors(); + + useEffect(() => { + const newOptions: EuiSelectableOption[] = []; + if (recentlyViewed.length > 0 && !searchValue) { + const otherMonitors = values.filter((value) => + recentlyViewed.every((recent) => recent.key !== value.key) + ); + + if (otherMonitors.length > 0) { + newOptions.push({ key: 'monitors', label: OTHER_MONITORS, isGroupLabel: true }); + } + + setOptions([...recentlyViewed, ...newOptions, ...otherMonitors]); + } else { + setOptions(values); + } + }, [recentlyViewed, searchValue, values]); + + const onButtonClick = () => { + setIsPopoverOpen(!isPopoverOpen); + }; + + const closePopover = () => { + setIsPopoverOpen(false); + }; + + const button = ( + + ); + + return ( + + + {GO_TO_MONITOR} + setSearchValue(val), + autoFocus: true, + }} + options={options} + onChange={(selectedOptions) => { + setOptions(selectedOptions); + const option = selectedOptions.find((opt) => opt.checked === 'on'); + if (option) { + history.push(`/monitor/${option.key}?locationId=${selectedLocation?.id}`); + } + closePopover(); + }} + singleSelection={true} + listProps={{ + showIcons: false, + }} + renderOption={(option, search) => ( + + {option.label} + + )} + noMatchesMessage={NO_RESULT_FOUND} + emptyMessage={} + loadingMessage={LOADING_MONITORS} + > + {(list, search) => ( +
+ + {options.length > 0 || searchValue ? ( + search + ) : ( + + {NO_OTHER_MONITORS_EXISTS} + + )} + + {list} +
+ )} +
+
+
+ ); +}; + +const GO_TO_MONITOR = i18n.translate('xpack.synthetics.monitorSummary.goToMonitor', { + defaultMessage: 'Go to monitor', +}); + +const NO_RESULT_FOUND = i18n.translate('xpack.synthetics.monitorSummary.noResultsFound', { + defaultMessage: 'No monitors found. Try modifying your query.', +}); + +const PLACEHOLDER = i18n.translate('xpack.synthetics.monitorSummary.placeholderSearch', { + defaultMessage: 'Monitor name or tag', +}); + +const SELECT_MONITOR = i18n.translate('xpack.synthetics.monitorSummary.selectMonitor', { + defaultMessage: 'Select a different monitor to view its details', +}); + +const OTHER_MONITORS = i18n.translate('xpack.synthetics.monitorSummary.otherMonitors', { + defaultMessage: 'Other monitors', +}); + +const LOADING_MONITORS = i18n.translate('xpack.synthetics.monitorSummary.loadingMonitors', { + defaultMessage: 'Loading monitors', +}); + +const NO_OTHER_MONITORS_EXISTS = i18n.translate('xpack.synthetics.monitorSummary.noOtherMonitors', { + defaultMessage: 'No other monitors exist.', +}); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_selector/use_monitor_name.ts b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_selector/use_monitor_name.ts new file mode 100644 index 00000000000000..cb097b0f993425 --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_selector/use_monitor_name.ts @@ -0,0 +1,35 @@ +/* + * 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 { useMemo } from 'react'; +import { useFetcher } from '@kbn/observability-plugin/public'; +import { useParams } from 'react-router-dom'; +import { fetchMonitorManagementList } from '../../../state'; + +export const useMonitorName = ({ search = '' }: { search?: string }) => { + const { data, loading } = useFetcher(() => { + return fetchMonitorManagementList({ + pageSize: 100, + pageIndex: 0, + sortField: 'name.keyword', + sortOrder: 'asc', + query: search, + }); + }, [search]); + + const { monitorId } = useParams<{ monitorId: string }>(); + + return useMemo(() => { + const { monitors = [] } = data ?? {}; + const values = monitors.map((monitor) => ({ + label: monitor.attributes.name as string, + key: monitor.id, + })); + + return { values: values.filter((val) => val.key !== monitorId), loading }; + }, [data, loading, monitorId]); +}; diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_selector/use_recently_viewed_monitors.test.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_selector/use_recently_viewed_monitors.test.tsx new file mode 100644 index 00000000000000..8c5922f4acc7ab --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_selector/use_recently_viewed_monitors.test.tsx @@ -0,0 +1,83 @@ +/* + * 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 React from 'react'; +import { renderHook } from '@testing-library/react-hooks'; +import { useRecentlyViewedMonitors } from './use_recently_viewed_monitors'; +import { mockCore, WrappedHelper } from '../../../utils/testing'; +import { syntheticsMonitorType } from '../../../../../../common/types/saved_objects'; +import { MONITOR_ROUTE } from '../../../../../../common/constants'; + +const resultData = { + resolved_objects: [ + { + saved_object: { + id: 'c9322230-2a11-11ed-962b-d3e7eeedf9d1', + + attributes: { + name: 'Test Monitor', + }, + }, + }, + ], +}; + +describe('useRecentlyViewedMonitors', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('returns expected result', () => { + const WrapperWithState = ({ children }: { children: React.ReactElement }) => { + return ( + + {children} + + ); + }; + + const { result } = renderHook(() => useRecentlyViewedMonitors(), { wrapper: WrapperWithState }); + expect(result.current).toEqual([]); + }); + + it('returns the result when found', async () => { + const core = mockCore(); + + core.savedObjects!.client.bulkResolve = jest.fn().mockResolvedValue(resultData); + + const WrapperWithState = ({ children }: { children: React.ReactElement }) => { + return ( + + {children} + + ); + }; + + const { result, waitForNextUpdate } = renderHook(() => useRecentlyViewedMonitors(), { + wrapper: WrapperWithState, + }); + expect(result.current).toEqual([]); + + expect(core.savedObjects?.client.bulkResolve).toHaveBeenCalledTimes(1); + expect(core.savedObjects?.client.bulkResolve).toHaveBeenLastCalledWith([ + { id: '1', type: syntheticsMonitorType }, + ]); + + await waitForNextUpdate(); + + expect(result.current).toEqual([ + { + isGroupLabel: true, + key: 'recently_viewed', + label: 'Recently viewed', + }, + { + key: 'c9322230-2a11-11ed-962b-d3e7eeedf9d1', + label: 'Test Monitor', + }, + ]); + }); +}); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_selector/use_recently_viewed_monitors.ts b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_selector/use_recently_viewed_monitors.ts new file mode 100644 index 00000000000000..64f7a60c28c7aa --- /dev/null +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitor_details/monitor_selector/use_recently_viewed_monitors.ts @@ -0,0 +1,80 @@ +/* + * 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 useLocalStorage from 'react-use/lib/useLocalStorage'; +import { i18n } from '@kbn/i18n'; +import { useParams } from 'react-router-dom'; +import { useEffect, useMemo } from 'react'; +import { useKibana } from '@kbn/kibana-react-plugin/public'; +import { useFetcher } from '@kbn/observability-plugin/public'; +import { MonitorFields } from '../../../../../../common/runtime_types'; +import { syntheticsMonitorType } from '../../../../../../common/types/saved_objects'; + +export const useRecentlyViewedMonitors = () => { + const [recentlyViewed, setRecentlyViewed] = useLocalStorage( + 'xpack.synthetics.recentlyViewedMonitors', + [] + ); + const { monitorId } = useParams<{ monitorId: string }>(); + + const { savedObjects } = useKibana().services; + + useEffect(() => { + const newRecentlyViewed = [ + ...new Set([...(monitorId ? [monitorId] : []), ...(recentlyViewed ?? [])]), + ].slice(0, 5); + + if ( + newRecentlyViewed?.[0] !== recentlyViewed?.[0] || + newRecentlyViewed.length !== recentlyViewed?.length + ) { + setRecentlyViewed(newRecentlyViewed); + } + }, [monitorId, recentlyViewed, setRecentlyViewed]); + + const { data } = useFetcher(async () => { + const monitorsList = recentlyViewed ?? []; + + const { resolved_objects: monitorObjects } = await savedObjects!.client.bulkResolve( + monitorsList.map((monId) => ({ + type: syntheticsMonitorType, + id: monId, + })) + ); + + const missingMonitors = monitorObjects + .filter((mon) => mon.saved_object.error?.statusCode === 404) + .map((mon) => mon.saved_object.id); + + if (missingMonitors.length > 0) { + setRecentlyViewed(monitorsList.filter((monId) => !missingMonitors.includes(monId))); + } + + return monitorObjects + .filter( + ({ saved_object: monitor }) => Boolean(monitor.attributes) && monitor.id !== monitorId + ) + .map(({ saved_object: monitor }) => ({ + key: monitor.id, + label: (monitor.attributes as MonitorFields).name, + })); + }, [monitorId, recentlyViewed]); + + return useMemo(() => { + if ((data ?? []).length === 0) { + return []; + } + return [ + { key: 'recently_viewed', label: RECENTLY_VIEWED, isGroupLabel: true }, + ...(data ?? []), + ]; + }, [data]); +}; + +const RECENTLY_VIEWED = i18n.translate('xpack.synthetics.monitorSummary.recentlyViewed', { + defaultMessage: 'Recently viewed', +}); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/utils/testing/rtl_helpers.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/utils/testing/rtl_helpers.tsx index 1e0a277d2c6541..55ae549a032b34 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/utils/testing/rtl_helpers.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/utils/testing/rtl_helpers.tsx @@ -226,6 +226,10 @@ export function WrappedHelper({ }: RenderRouterOptions & { children: ReactElement; useRealStore?: boolean }) { const testState: AppState = merge({}, mockState, state); + if (url) { + history = getHistoryFromUrl(url); + } + return ( diff --git a/x-pack/plugins/ux/public/components/app/rum_dashboard/charts/__snapshots__/visitor_breakdown_chart.test.tsx.snap b/x-pack/plugins/ux/public/components/app/rum_dashboard/charts/__snapshots__/visitor_breakdown_chart.test.tsx.snap index 0ff461bc8ff771..1e7d3ca13e43c2 100644 --- a/x-pack/plugins/ux/public/components/app/rum_dashboard/charts/__snapshots__/visitor_breakdown_chart.test.tsx.snap +++ b/x-pack/plugins/ux/public/components/app/rum_dashboard/charts/__snapshots__/visitor_breakdown_chart.test.tsx.snap @@ -10,7 +10,7 @@ Object { }, }, "datasourceStates": Object { - "indexpattern": Object { + "formBased": Object { "layers": Object { "layer1": Object { "columnOrder": Array [ diff --git a/x-pack/plugins/ux/public/components/app/rum_dashboard/charts/visitor_breakdown_chart.tsx b/x-pack/plugins/ux/public/components/app/rum_dashboard/charts/visitor_breakdown_chart.tsx index 9b3ee489c934c0..e20e9b1f89f7e8 100644 --- a/x-pack/plugins/ux/public/components/app/rum_dashboard/charts/visitor_breakdown_chart.tsx +++ b/x-pack/plugins/ux/public/components/app/rum_dashboard/charts/visitor_breakdown_chart.tsx @@ -188,7 +188,7 @@ export function getVisitorBreakdownLensAttributes({ [localDataView.id]: localDataView, }, datasourceStates: { - indexpattern: { + formBased: { layers: { layer1: dataLayer, }, diff --git a/x-pack/test/api_integration/apis/logs_ui/log_threshold_alert.ts b/x-pack/test/api_integration/apis/logs_ui/log_threshold_alert.ts index 43699de65e524e..2ada34d4dcd5fc 100644 --- a/x-pack/test/api_integration/apis/logs_ui/log_threshold_alert.ts +++ b/x-pack/test/api_integration/apis/logs_ui/log_threshold_alert.ts @@ -10,6 +10,8 @@ import sinon from 'sinon'; import { executeAlert, executeRatioAlert, + LogThresholdAlertFactory, + LogThresholdAlertLimit, } from '@kbn/infra-plugin/server/lib/alerting/log_threshold/log_threshold_executor'; import { Comparator, @@ -28,9 +30,13 @@ export default function ({ getService }: FtrProviderContext) { after(() => esArchiver.unload('x-pack/test/functional/es_archives/infra/alerts_test_data')); describe('without group by', () => { - it('should work', async () => { + it('should trigger alerts below the alert limit', async () => { const timestamp = new Date(DATES['alert-test-data'].gauge.max); - const alertFactory = sinon.fake(); + const alertFactory = sinon.fake() as SinonSpyOf; + const alertLimit = { + getValue: sinon.fake.returns(10), + setLimitReached: sinon.fake(), + } as SinonSpiesOf; const ruleParams = { count: { comparator: Comparator.GT_OR_EQ, @@ -46,6 +52,7 @@ export default function ({ getService }: FtrProviderContext) { }, ], }; + await executeAlert( ruleParams, '@timestamp', @@ -53,8 +60,10 @@ export default function ({ getService }: FtrProviderContext) { {}, esClient, alertFactory, + alertLimit, timestamp.valueOf() ); + expect(alertFactory.callCount).to.equal(1); expect(alertFactory.getCall(0).args).to.eql([ '*', @@ -74,13 +83,18 @@ export default function ({ getService }: FtrProviderContext) { }, ], ]); + expect(alertLimit.setLimitReached.calledOnceWith(false)).to.be(true); }); }); describe('with group by', () => { - it('should work', async () => { + it('should trigger alerts up to the alert limit', async () => { const timestamp = new Date(DATES['alert-test-data'].gauge.max); - const alertFactory = sinon.fake(); + const alertFactory = sinon.fake() as SinonSpyOf; + const alertLimit = { + getValue: sinon.fake.returns(2), + setLimitReached: sinon.fake(), + } as SinonSpiesOf; const ruleParams = { count: { comparator: Comparator.GT_OR_EQ, @@ -97,6 +111,7 @@ export default function ({ getService }: FtrProviderContext) { }, ], }; + await executeAlert( ruleParams, '@timestamp', @@ -104,8 +119,10 @@ export default function ({ getService }: FtrProviderContext) { {}, esClient, alertFactory, + alertLimit, timestamp.valueOf() ); + expect(alertFactory.callCount).to.equal(2); expect(alertFactory.getCall(0).args).to.eql([ 'dev', @@ -125,6 +142,64 @@ export default function ({ getService }: FtrProviderContext) { }, ], ]); + expect(alertLimit.setLimitReached.calledOnceWith(true)).to.be(true); + }); + + it('should limit alerts to the alert limit', async () => { + const timestamp = new Date(DATES['alert-test-data'].gauge.max); + const alertFactory = sinon.fake() as SinonSpyOf; + const alertLimit = { + getValue: sinon.fake.returns(1), + setLimitReached: sinon.fake(), + } as SinonSpiesOf; + const ruleParams = { + count: { + comparator: Comparator.GT_OR_EQ, + value: 1, + }, + timeUnit: 'm' as TimeUnit, + timeSize: 5, + groupBy: ['env'], + criteria: [ + { + field: 'env', + comparator: Comparator.NOT_EQ, + value: 'test', + }, + ], + }; + + await executeAlert( + ruleParams, + '@timestamp', + 'alerts-test-data', + {}, + esClient, + alertFactory, + alertLimit, + timestamp.valueOf() + ); + + expect(alertFactory.callCount).to.equal(1); + expect(alertFactory.getCall(0).args).to.eql([ + 'dev', + '2 log entries in the last 5 mins for dev. Alert when ≥ 1.', + 2, + 1, + [ + { + actionGroup: 'logs.threshold.fired', + context: { + conditions: 'env does not equal test', + group: 'dev', + isRatio: false, + matchingDocuments: 2, + reason: '2 log entries in the last 5 mins for dev. Alert when ≥ 1.', + }, + }, + ], + ]); + expect(alertLimit.setLimitReached.calledOnceWith(true)).to.be(true); }); }); }); @@ -134,9 +209,13 @@ export default function ({ getService }: FtrProviderContext) { after(() => esArchiver.unload('x-pack/test/functional/es_archives/infra/ten_thousand_plus')); describe('without group by', () => { - it('should work', async () => { + it('should trigger alerts below the alert limit', async () => { const timestamp = new Date(DATES.ten_thousand_plus.max); - const alertFactory = sinon.fake(); + const alertFactory = sinon.fake() as SinonSpyOf; + const alertLimit = { + getValue: sinon.fake.returns(2), + setLimitReached: sinon.fake(), + } as SinonSpiesOf; const ruleParams = { count: { comparator: Comparator.GT_OR_EQ, @@ -156,6 +235,7 @@ export default function ({ getService }: FtrProviderContext) { {}, esClient, alertFactory, + alertLimit, timestamp.valueOf() ); expect(alertFactory.callCount).to.equal(1); @@ -179,13 +259,18 @@ export default function ({ getService }: FtrProviderContext) { }, ], ]); + expect(alertLimit.setLimitReached.calledOnceWith(false)).to.be(true); }); }); describe('with group by', () => { - it('should work', async () => { + it('should trigger alerts below the alert limit', async () => { const timestamp = new Date(DATES.ten_thousand_plus.max); - const alertFactory = sinon.fake(); + const alertFactory = sinon.fake() as SinonSpyOf; + const alertLimit = { + getValue: sinon.fake.returns(2), + setLimitReached: sinon.fake(), + } as SinonSpiesOf; const ruleParams = { count: { comparator: Comparator.GT_OR_EQ, @@ -206,6 +291,7 @@ export default function ({ getService }: FtrProviderContext) { {}, esClient, alertFactory, + alertLimit, timestamp.valueOf() ); expect(alertFactory.callCount).to.equal(1); @@ -229,8 +315,18 @@ export default function ({ getService }: FtrProviderContext) { }, ], ]); + expect(alertLimit.setLimitReached.calledOnceWith(false)).to.be(true); }); }); }); }); } + +type SinonSpyOf any> = sinon.SinonSpy< + Parameters, + ReturnType +>; + +type SinonSpiesOf any>> = { + [Key in keyof SpyTarget]: SinonSpyOf; +}; diff --git a/x-pack/test/functional_with_es_ssl/apps/cases/attachment_framework.ts b/x-pack/test/functional_with_es_ssl/apps/cases/attachment_framework.ts index f9bcd5946d400e..2d16926b476602 100644 --- a/x-pack/test/functional_with_es_ssl/apps/cases/attachment_framework.ts +++ b/x-pack/test/functional_with_es_ssl/apps/cases/attachment_framework.ts @@ -145,7 +145,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { query: { query: '', language: 'kuery' }, filters: [], datasourceStates: { - indexpattern: { + formBased: { layers: { '85863a23-73a0-4e11-9774-70f77b9a5898': { columns: {