= {};
+
+ for (let i = 0; i < sampleDataset.dataIndices.length; i++) {
+ const dataIndex = sampleDataset.dataIndices[i];
+ const indexName = createIndexName(sampleDataset.id, dataIndex.id);
+ // clean up any old installation of dataset
+ await this.uninstallDataIndex(sampleDataset, dataIndex);
+ await this.installDataIndex(sampleDataset, dataIndex);
+
+ const injectedCount = await insertDataIntoIndex({
+ index: indexName,
+ nowReference,
+ logger: this.logger,
+ esClient: this.esClient,
+ dataIndexConfig: dataIndex,
+ });
+ createdDocsPerIndex[indexName] = injectedCount;
+ }
+
+ const createdSavedObjects = await this.importSavedObjects(sampleDataset);
+
+ return {
+ createdDocsPerIndex,
+ createdSavedObjects,
+ };
+ }
+
+ async uninstall(datasetId: string) {
+ const sampleDataset = this.sampleDatasets.find(({ id }) => id === datasetId);
+ if (!sampleDataset) {
+ throw new SampleDataInstallError(`Sample dataset ${datasetId} not found`, 404);
+ }
+
+ for (let i = 0; i < sampleDataset.dataIndices.length; i++) {
+ const dataIndex = sampleDataset.dataIndices[i];
+ await this.uninstallDataIndex(sampleDataset, dataIndex);
+ }
+ const deletedObjects = await this.deleteSavedObjects(sampleDataset);
+
+ return {
+ deletedSavedObjects: deletedObjects,
+ };
+ }
+
+ private async uninstallDataIndex(dataset: SampleDatasetSchema, dataIndex: DataIndexSchema) {
+ let index = createIndexName(dataset.id, dataIndex.id);
+
+ try {
+ // if the sample data was reindexed using UA, the index name is actually an alias pointing to the reindexed
+ // index. In that case, we need to get rid of the alias and to delete the underlying index
+ const { body: response } = await this.esClient.asCurrentUser.indices.getAlias({
+ name: index,
+ });
+ const aliasName = index;
+ index = Object.keys(response)[0];
+ await this.esClient.asCurrentUser.indices.deleteAlias({ name: aliasName, index });
+ } catch (err) {
+ // ignore errors from missing alias
+ }
+
+ try {
+ await this.esClient.asCurrentUser.indices.delete({
+ index,
+ });
+ } catch (err) {
+ // ignore delete errors
+ }
+ }
+
+ private async installDataIndex(dataset: SampleDatasetSchema, dataIndex: DataIndexSchema) {
+ const index = createIndexName(dataset.id, dataIndex.id);
+ try {
+ await this.esClient.asCurrentUser.indices.create({
+ index,
+ body: {
+ settings: { index: { number_of_shards: 1, auto_expand_replicas: '0-1' } },
+ mappings: { properties: dataIndex.fields },
+ },
+ });
+ } catch (err) {
+ const errMsg = `Unable to create sample data index "${index}", error: ${err.message}`;
+ this.logger.warn(errMsg);
+ throw new SampleDataInstallError(errMsg, err.status);
+ }
+ }
+
+ private async importSavedObjects(dataset: SampleDatasetSchema) {
+ const savedObjects = dataset.savedObjects.map(({ version, ...obj }) => obj);
+ const readStream = Readable.from(savedObjects);
+
+ const { errors = [] } = await this.soImporter.import({
+ readStream,
+ overwrite: true,
+ createNewCopies: false,
+ });
+ if (errors.length > 0) {
+ const errMsg = `sample_data install errors while loading saved objects. Errors: ${JSON.stringify(
+ errors.map(({ type, id, error }) => ({ type, id, error })) // discard other fields
+ )}`;
+ this.logger.warn(errMsg);
+ throw new SampleDataInstallError(errMsg, 500);
+ }
+ return savedObjects.length;
+ }
+
+ private async deleteSavedObjects(dataset: SampleDatasetSchema) {
+ const objects = dataset.savedObjects.map(({ type, id }) => ({ type, id }));
+ const findSampleObjectsResult = await findSampleObjects({
+ client: this.soClient,
+ logger: this.logger,
+ objects,
+ });
+ const objectsToDelete = findSampleObjectsResult.filter(({ foundObjectId }) => foundObjectId);
+ const deletePromises = objectsToDelete.map(({ type, foundObjectId }) =>
+ this.soClient.delete(type, foundObjectId!).catch((err) => {
+ // if the object doesn't exist, ignore the error and proceed
+ if (isBoom(err) && err.output.statusCode === 404) {
+ return;
+ }
+ throw err;
+ })
+ );
+ try {
+ await Promise.all(deletePromises);
+ } catch (err) {
+ throw new SampleDataInstallError(
+ `Unable to delete sample dataset saved objects, error: ${
+ err.body?.error?.type ?? err.message
+ }`,
+ err.body?.status ?? 500
+ );
+ }
+ return objectsToDelete.length;
+ }
+}
diff --git a/src/plugins/kibana_utils/common/persistable_state/types.ts b/src/plugins/kibana_utils/common/persistable_state/types.ts
index f5aa73e9fe205..db757ac662686 100644
--- a/src/plugins/kibana_utils/common/persistable_state/types.ts
+++ b/src/plugins/kibana_utils/common/persistable_state/types.ts
@@ -92,8 +92,8 @@ export interface PersistableState };
export type MigrateFunction<
- FromVersion extends SerializableRecord = SerializableRecord,
- ToVersion extends SerializableRecord = SerializableRecord
+ FromVersion extends Serializable = SerializableRecord,
+ ToVersion extends Serializable = SerializableRecord
> = (state: FromVersion) => ToVersion;
/**
diff --git a/src/plugins/presentation_util/public/components/solution_toolbar/solution_toolbar.tsx b/src/plugins/presentation_util/public/components/solution_toolbar/solution_toolbar.tsx
index 15edd85d6754a..fa678dbdaae89 100644
--- a/src/plugins/presentation_util/public/components/solution_toolbar/solution_toolbar.tsx
+++ b/src/plugins/presentation_util/public/components/solution_toolbar/solution_toolbar.tsx
@@ -57,9 +57,15 @@ export const SolutionToolbar = ({ isDarkModeEnabled, children }: Props) => {
gutterSize="s"
>
{primaryActionButton}
- {quickButtonGroup ? {quickButtonGroup} : null}
- {extra}
- {addFromLibraryButton ? {addFromLibraryButton} : null}
+
+
+ {quickButtonGroup ? {quickButtonGroup} : null}
+ {extra}
+ {addFromLibraryButton ? (
+ {addFromLibraryButton}
+ ) : null}
+
+
);
};
diff --git a/src/plugins/presentation_util/public/services/create/dependency_manager.test.ts b/src/plugins/presentation_util/public/services/create/dependency_manager.test.ts
new file mode 100644
index 0000000000000..29702c3356865
--- /dev/null
+++ b/src/plugins/presentation_util/public/services/create/dependency_manager.test.ts
@@ -0,0 +1,55 @@
+/*
+ * 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 { DependencyManager } from './dependency_manager';
+
+describe('DependencyManager', () => {
+ it('orderDependencies. Should sort topology by dependencies', () => {
+ const graph = {
+ N: [],
+ R: [],
+ A: ['B', 'C'],
+ B: ['D'],
+ C: ['F', 'B'],
+ F: ['E'],
+ E: ['D'],
+ D: ['L'],
+ };
+ const sortedTopology = ['N', 'R', 'L', 'D', 'B', 'E', 'F', 'C', 'A'];
+ expect(DependencyManager.orderDependencies(graph)).toEqual(sortedTopology);
+ });
+
+ it('orderDependencies. Should return base topology if no depended vertices', () => {
+ const graph = {
+ N: [],
+ R: [],
+ D: undefined,
+ };
+ const sortedTopology = ['N', 'R', 'D'];
+ expect(DependencyManager.orderDependencies(graph)).toEqual(sortedTopology);
+ });
+
+ it('orderDependencies. Should detect circular dependencies and throw error with path', () => {
+ const graph = {
+ N: ['R'],
+ R: ['A'],
+ A: ['B'],
+ B: ['C'],
+ C: ['D'],
+ D: ['E'],
+ E: ['F'],
+ F: ['L'],
+ L: ['G'],
+ G: ['N'],
+ };
+ const circularPath = ['N', 'R', 'A', 'B', 'C', 'D', 'E', 'F', 'L', 'G', 'N'].join(' -> ');
+ const errorMessage = `Circular dependency detected while setting up services: ${circularPath}`;
+
+ expect(() => DependencyManager.orderDependencies(graph)).toThrowError(errorMessage);
+ });
+});
diff --git a/src/plugins/presentation_util/public/services/create/dependency_manager.ts b/src/plugins/presentation_util/public/services/create/dependency_manager.ts
new file mode 100644
index 0000000000000..de30b180607fe
--- /dev/null
+++ b/src/plugins/presentation_util/public/services/create/dependency_manager.ts
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+
+type GraphVertex = string | number | symbol;
+type Graph = Record;
+type BreadCrumbs = Record;
+
+interface CycleDetectionResult {
+ hasCycle: boolean;
+ path: T[];
+}
+
+export class DependencyManager {
+ static orderDependencies(graph: Graph) {
+ const cycleInfo = DependencyManager.getSortedDependencies(graph);
+ if (cycleInfo.hasCycle) {
+ const error = DependencyManager.getCyclePathError(cycleInfo.path);
+ DependencyManager.throwCyclicPathError(error);
+ }
+
+ return cycleInfo.path;
+ }
+
+ /**
+ * DFS algorithm for checking if graph is a DAG (Directed Acyclic Graph)
+ * and sorting topogy (dependencies) if graph is DAG.
+ * @param {Graph} graph - graph of dependencies.
+ */
+ private static getSortedDependencies(
+ graph: Graph = {} as Graph
+ ): CycleDetectionResult {
+ const sortedVertices: Set = new Set();
+ const vertices = Object.keys(graph) as T[];
+ return vertices.reduce>((cycleInfo, srcVertex) => {
+ if (cycleInfo.hasCycle) {
+ return cycleInfo;
+ }
+
+ return DependencyManager.sortVerticesFrom(srcVertex, graph, sortedVertices, {}, {});
+ }, DependencyManager.createCycleInfo());
+ }
+
+ /**
+ * Modified DFS algorithm for topological sort.
+ * @param {T extends GraphVertex} srcVertex - a source vertex - the start point of dependencies ordering.
+ * @param {Graph} graph - graph of dependencies, represented in the adjacency list form.
+ * @param {Set} sortedVertices - ordered dependencies path from the free to the dependent vertex.
+ * @param {BreadCrumbs} visited - record of visited vertices.
+ * @param {BreadCrumbs} inpath - record of vertices, which was met in the path. Is used for detecting cycles.
+ */
+ private static sortVerticesFrom(
+ srcVertex: T,
+ graph: Graph,
+ sortedVertices: Set,
+ visited: BreadCrumbs = {},
+ inpath: BreadCrumbs = {}
+ ): CycleDetectionResult {
+ visited[srcVertex] = true;
+ inpath[srcVertex] = true;
+ const cycleInfo = graph[srcVertex]?.reduce | undefined>(
+ (info, vertex) => {
+ if (inpath[vertex]) {
+ const path = (Object.keys(inpath) as T[]).filter(
+ (visitedVertex) => inpath[visitedVertex]
+ );
+ return DependencyManager.createCycleInfo([...path, vertex], true);
+ } else if (!visited[vertex]) {
+ return DependencyManager.sortVerticesFrom(vertex, graph, sortedVertices, visited, inpath);
+ }
+ return info;
+ },
+ undefined
+ );
+
+ inpath[srcVertex] = false;
+
+ if (!sortedVertices.has(srcVertex)) {
+ sortedVertices.add(srcVertex);
+ }
+
+ return cycleInfo ?? DependencyManager.createCycleInfo([...sortedVertices]);
+ }
+
+ private static createCycleInfo(
+ path: T[] = [],
+ hasCycle: boolean = false
+ ): CycleDetectionResult {
+ return { hasCycle, path };
+ }
+
+ private static getCyclePathError(
+ cyclePath: CycleDetectionResult['path']
+ ) {
+ const cycleString = cyclePath.join(' -> ');
+ return `Circular dependency detected while setting up services: ${cycleString}`;
+ }
+
+ private static throwCyclicPathError(error: string) {
+ throw new Error(error);
+ }
+}
diff --git a/src/plugins/presentation_util/public/services/create/factory.ts b/src/plugins/presentation_util/public/services/create/factory.ts
index ddc2e5845b037..49ed5ef8aaf8d 100644
--- a/src/plugins/presentation_util/public/services/create/factory.ts
+++ b/src/plugins/presentation_util/public/services/create/factory.ts
@@ -16,7 +16,10 @@ import { CoreStart, AppUpdater, PluginInitializerContext } from 'src/core/public
* The `StartParameters` generic determines what parameters are expected to
* create the service.
*/
-export type PluginServiceFactory = (params: Parameters) => Service;
+export type PluginServiceFactory = (
+ params: Parameters,
+ requiredServices: RequiredServices
+) => Service;
/**
* Parameters necessary to create a Kibana-based service, (e.g. during Plugin
@@ -38,6 +41,7 @@ export interface KibanaPluginServiceParams {
* The `Setup` generic refers to the specific Plugin `TPluginsSetup`.
* The `Start` generic refers to the specific Plugin `TPluginsStart`.
*/
-export type KibanaPluginServiceFactory = (
- params: KibanaPluginServiceParams
+export type KibanaPluginServiceFactory = (
+ params: KibanaPluginServiceParams,
+ requiredServices: RequiredServices
) => Service;
diff --git a/src/plugins/presentation_util/public/services/create/provider.tsx b/src/plugins/presentation_util/public/services/create/provider.tsx
index 06590bcfbb3d0..3271dc52fd9d0 100644
--- a/src/plugins/presentation_util/public/services/create/provider.tsx
+++ b/src/plugins/presentation_util/public/services/create/provider.tsx
@@ -17,7 +17,25 @@ import { PluginServiceFactory } from './factory';
* start the service.
*/
export type PluginServiceProviders = {
- [K in keyof Services]: PluginServiceProvider;
+ [K in keyof Services]: PluginServiceProvider<
+ Services[K],
+ StartParameters,
+ Services,
+ Array
+ >;
+};
+
+type ElementOfArray = ArrayType extends Array<
+ infer ElementType
+>
+ ? ElementType
+ : never;
+
+export type PluginServiceRequiredServices<
+ RequiredServices extends Array,
+ AvailableServices
+> = {
+ [K in ElementOfArray]: AvailableServices[K];
};
/**
@@ -27,16 +45,34 @@ export type PluginServiceProviders = {
* The `StartParameters` generic determines what parameters are expected to
* start the service.
*/
-export class PluginServiceProvider {
- private factory: PluginServiceFactory;
+export class PluginServiceProvider<
+ Service extends {},
+ StartParameters = {},
+ Services = {},
+ RequiredServices extends Array = []
+> {
+ private factory: PluginServiceFactory<
+ Service,
+ StartParameters,
+ PluginServiceRequiredServices
+ >;
+ private _requiredServices?: RequiredServices;
private context = createContext(null);
private pluginService: Service | null = null;
public readonly Provider: React.FC = ({ children }) => {
return {children};
};
- constructor(factory: PluginServiceFactory) {
+ constructor(
+ factory: PluginServiceFactory<
+ Service,
+ StartParameters,
+ PluginServiceRequiredServices
+ >,
+ requiredServices?: RequiredServices
+ ) {
this.factory = factory;
+ this._requiredServices = requiredServices;
this.context.displayName = 'PluginServiceContext';
}
@@ -55,8 +91,11 @@ export class PluginServiceProvider {
*
* @param params Parameters used to start the service.
*/
- start(params: StartParameters) {
- this.pluginService = this.factory(params);
+ start(
+ params: StartParameters,
+ requiredServices: PluginServiceRequiredServices
+ ) {
+ this.pluginService = this.factory(params, requiredServices);
}
/**
@@ -80,4 +119,8 @@ export class PluginServiceProvider {
stop() {
this.pluginService = null;
}
+
+ public get requiredServices() {
+ return this._requiredServices ?? [];
+ }
}
diff --git a/src/plugins/presentation_util/public/services/create/providers_mediator.ts b/src/plugins/presentation_util/public/services/create/providers_mediator.ts
new file mode 100644
index 0000000000000..dd5937149850c
--- /dev/null
+++ b/src/plugins/presentation_util/public/services/create/providers_mediator.ts
@@ -0,0 +1,55 @@
+/*
+ * 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 { DependencyManager } from './dependency_manager';
+import { PluginServiceProviders, PluginServiceRequiredServices } from './provider';
+
+export class PluginServiceProvidersMediator {
+ constructor(private readonly providers: PluginServiceProviders) {}
+
+ start(params: StartParameters) {
+ this.getOrderedDependencies().forEach((service) => {
+ this.providers[service].start(params, this.getServiceDependencies(service));
+ });
+ }
+
+ stop() {
+ this.getOrderedDependencies().forEach((service) => this.providers[service].stop());
+ }
+
+ private getOrderedDependencies() {
+ const dependenciesGraph = this.getGraphOfDependencies();
+ return DependencyManager.orderDependencies(dependenciesGraph);
+ }
+
+ private getGraphOfDependencies() {
+ return this.getProvidersNames().reduce>>(
+ (graph, vertex) => ({ ...graph, [vertex]: this.providers[vertex].requiredServices ?? [] }),
+ {} as Record>
+ );
+ }
+
+ private getProvidersNames() {
+ return Object.keys(this.providers) as Array;
+ }
+
+ private getServiceDependencies(service: keyof Services) {
+ const requiredServices = this.providers[service].requiredServices ?? [];
+ return this.getServicesByDeps(requiredServices);
+ }
+
+ private getServicesByDeps(deps: Array) {
+ return deps.reduce, Services>>(
+ (services, dependency) => ({
+ ...services,
+ [dependency]: this.providers[dependency].getService(),
+ }),
+ {} as PluginServiceRequiredServices, Services>
+ );
+ }
+}
diff --git a/src/plugins/presentation_util/public/services/create/registry.tsx b/src/plugins/presentation_util/public/services/create/registry.tsx
index e8f85666bcac4..8369815a042af 100644
--- a/src/plugins/presentation_util/public/services/create/registry.tsx
+++ b/src/plugins/presentation_util/public/services/create/registry.tsx
@@ -8,6 +8,7 @@
import React from 'react';
import { PluginServiceProvider, PluginServiceProviders } from './provider';
+import { PluginServiceProvidersMediator } from './providers_mediator';
/**
* A `PluginServiceRegistry` maintains a set of service providers which can be collectively
@@ -19,10 +20,12 @@ import { PluginServiceProvider, PluginServiceProviders } from './provider';
*/
export class PluginServiceRegistry {
private providers: PluginServiceProviders;
+ private providersMediator: PluginServiceProvidersMediator;
private _isStarted = false;
constructor(providers: PluginServiceProviders) {
this.providers = providers;
+ this.providersMediator = new PluginServiceProvidersMediator(providers);
}
/**
@@ -69,8 +72,7 @@ export class PluginServiceRegistry {
* @param params Parameters used to start the registry.
*/
start(params: StartParameters) {
- const providerNames = Object.keys(this.providers) as Array;
- providerNames.forEach((providerName) => this.providers[providerName].start(params));
+ this.providersMediator.start(params);
this._isStarted = true;
return this;
}
@@ -79,8 +81,7 @@ export class PluginServiceRegistry {
* Stop the registry.
*/
stop() {
- const providerNames = Object.keys(this.providers) as Array;
- providerNames.forEach((providerName) => this.providers[providerName].stop());
+ this.providersMediator.stop();
this._isStarted = false;
return this;
}
diff --git a/src/plugins/share/public/plugin.ts b/src/plugins/share/public/plugin.ts
index fd8a5fd7541a6..684d29caeb312 100644
--- a/src/plugins/share/public/plugin.ts
+++ b/src/plugins/share/public/plugin.ts
@@ -86,7 +86,7 @@ export class SharePlugin implements Plugin {
const { basePath } = http;
this.url = new UrlService({
- baseUrl: basePath.publicBaseUrl || basePath.serverBasePath,
+ baseUrl: basePath.get(),
version: this.initializerContext.env.packageInfo.version,
navigate: async ({ app, path, state }, { replace = false } = {}) => {
const [start] = await core.getStartServices();
diff --git a/src/plugins/vis_types/timelion/public/components/timelion_vis_component.tsx b/src/plugins/vis_types/timelion/public/components/timelion_vis_component.tsx
index cb2ba498a0664..063f60b82927e 100644
--- a/src/plugins/vis_types/timelion/public/components/timelion_vis_component.tsx
+++ b/src/plugins/vis_types/timelion/public/components/timelion_vis_component.tsx
@@ -18,6 +18,7 @@ import {
LayoutDirection,
} from '@elastic/charts';
import { EuiTitle } from '@elastic/eui';
+import { RangeFilterParams } from '@kbn/es-query';
import { useKibana } from '../../../../kibana_react/public';
import { useActiveCursor } from '../../../../charts/public';
@@ -38,7 +39,6 @@ import { getCharts } from '../helpers/plugin_services';
import type { Sheet } from '../helpers/timelion_request_handler';
import type { IInterpreterRenderHandlers } from '../../../../expressions';
import type { TimelionVisDependencies } from '../plugin';
-import type { RangeFilterParams } from '../../../../data/public';
import type { Series } from '../helpers/timelion_request_handler';
import './timelion_vis.scss';
diff --git a/src/plugins/vis_types/timelion/public/legacy/timelion_vis_component.tsx b/src/plugins/vis_types/timelion/public/legacy/timelion_vis_component.tsx
index 136544ac068a3..edb250dfe1200 100644
--- a/src/plugins/vis_types/timelion/public/legacy/timelion_vis_component.tsx
+++ b/src/plugins/vis_types/timelion/public/legacy/timelion_vis_component.tsx
@@ -11,6 +11,7 @@ import $ from 'jquery';
import moment from 'moment-timezone';
import { debounce, compact, get, each, cloneDeep, last, map } from 'lodash';
import { useResizeObserver } from '@elastic/eui';
+import { RangeFilterParams } from '@kbn/es-query';
import { IInterpreterRenderHandlers } from 'src/plugins/expressions';
import { useKibana } from '../../../../kibana_react/public';
@@ -31,7 +32,6 @@ import { tickFormatters } from './tick_formatters';
import { generateTicksProvider } from '../helpers/tick_generator';
import type { TimelionVisDependencies } from '../plugin';
-import type { RangeFilterParams } from '../../../../data/common';
import './timelion_vis.scss';
diff --git a/src/plugins/vis_types/timelion/public/timelion_vis_renderer.tsx b/src/plugins/vis_types/timelion/public/timelion_vis_renderer.tsx
index 3c9fb1b1b268f..6b799d3e34946 100644
--- a/src/plugins/vis_types/timelion/public/timelion_vis_renderer.tsx
+++ b/src/plugins/vis_types/timelion/public/timelion_vis_renderer.tsx
@@ -10,12 +10,12 @@ import React, { lazy } from 'react';
import { render, unmountComponentAtNode } from 'react-dom';
import { ExpressionRenderDefinition } from 'src/plugins/expressions';
+import { RangeFilterParams } from '@kbn/es-query';
import { KibanaContextProvider, KibanaThemeProvider } from '../../../kibana_react/public';
import { VisualizationContainer } from '../../../visualizations/public';
import { TimelionVisDependencies } from './plugin';
import { TimelionRenderValue } from './timelion_vis_fn';
import { UI_SETTINGS } from '../common/constants';
-import { RangeFilterParams } from '../../../data/public';
const LazyTimelionVisComponent = lazy(() =>
import('./async_services').then(({ TimelionVisComponent }) => ({ default: TimelionVisComponent }))
diff --git a/src/plugins/vis_types/timeseries/public/application/visualizations/views/gauge.js b/src/plugins/vis_types/timeseries/public/application/visualizations/views/gauge.js
index 0e4322a7ba82c..0976d8f9cf47e 100644
--- a/src/plugins/vis_types/timeseries/public/application/visualizations/views/gauge.js
+++ b/src/plugins/vis_types/timeseries/public/application/visualizations/views/gauge.js
@@ -9,6 +9,7 @@
import _ from 'lodash';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
+import { EuiResizeObserver } from '@elastic/eui';
import classNames from 'classnames';
import { isBackgroundInverted, isBackgroundDark } from '../../lib/set_is_reversed';
import { getLastValue } from '../../../../common/last_value_utils';
@@ -29,19 +30,12 @@ export class Gauge extends Component {
};
this.handleResize = this.handleResize.bind(this);
- }
-
- UNSAFE_componentWillMount() {
- const check = () => {
- this.timeout = setTimeout(() => {
- const newState = calculateCoordinates(this.inner, this.resize, this.state);
- if (newState && this.state && !_.isEqual(newState, this.state)) {
- this.handleResize();
- }
- check();
- }, 500);
- };
- check();
+ this.checkResizeThrottled = _.throttle(() => {
+ const newState = calculateCoordinates(this.inner, this.resize, this.state);
+ if (newState && this.state && !_.isEqual(newState, this.state)) {
+ this.handleResize();
+ }
+ }, 200);
}
componentWillUnmount() {
@@ -155,16 +149,20 @@ export class Gauge extends Component {
});
return (
-
-
(this.resize = el)}
- className={`tvbVisGauge__resize`}
- data-test-subj="tvbVisGaugeContainer"
- >
- {metrics}
-
-
-
+
+ {(resizeRef) => (
+
+
(this.resize = el)}
+ className={`tvbVisGauge__resize`}
+ data-test-subj="tvbVisGaugeContainer"
+ >
+ {metrics}
+
+
+
+ )}
+
);
}
}
diff --git a/src/plugins/vis_types/timeseries/public/application/visualizations/views/gauge_vis.js b/src/plugins/vis_types/timeseries/public/application/visualizations/views/gauge_vis.js
index 165f5080af93a..0cc96ba3c74da 100644
--- a/src/plugins/vis_types/timeseries/public/application/visualizations/views/gauge_vis.js
+++ b/src/plugins/vis_types/timeseries/public/application/visualizations/views/gauge_vis.js
@@ -9,6 +9,7 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import _ from 'lodash';
+import { EuiResizeObserver } from '@elastic/eui';
import reactcss from 'reactcss';
import { calculateCoordinates } from '../lib/calculate_coordinates';
import { COLORS } from '../constants/chart';
@@ -25,19 +26,12 @@ export class GaugeVis extends Component {
translateY: 1,
};
this.handleResize = this.handleResize.bind(this);
- }
-
- UNSAFE_componentWillMount() {
- const check = () => {
- this.timeout = setTimeout(() => {
- const newState = calculateCoordinates(this.inner, this.resize, this.state);
- if (newState && this.state && !_.isEqual(newState, this.state)) {
- this.handleResize();
- }
- check();
- }, 500);
- };
- check();
+ this.checkResizeThrottled = _.throttle(() => {
+ const newState = calculateCoordinates(this.inner, this.resize, this.state);
+ if (newState && this.state && !_.isEqual(newState, this.state)) {
+ this.handleResize();
+ }
+ }, 200);
}
componentWillUnmount() {
@@ -148,11 +142,21 @@ export class GaugeVis extends Component {
);
}
return (
- (this.resize = el)} style={styles.resize}>
-
(this.inner = el)}>
- {svg}
-
-
+
+ {(resizeRef) => (
+ {
+ this.resize = el;
+ resizeRef(el);
+ }}
+ style={styles.resize}
+ >
+
(this.inner = el)}>
+ {svg}
+
+
+ )}
+
);
}
}
diff --git a/src/plugins/vis_types/timeseries/public/application/visualizations/views/metric.js b/src/plugins/vis_types/timeseries/public/application/visualizations/views/metric.js
index 0ceb2daa831be..6c9cc942b362f 100644
--- a/src/plugins/vis_types/timeseries/public/application/visualizations/views/metric.js
+++ b/src/plugins/vis_types/timeseries/public/application/visualizations/views/metric.js
@@ -9,6 +9,7 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import _ from 'lodash';
+import { EuiResizeObserver } from '@elastic/eui';
import reactcss from 'reactcss';
import { getLastValue } from '../../../../common/last_value_utils';
@@ -25,19 +26,12 @@ export class Metric extends Component {
translateY: 1,
};
this.handleResize = this.handleResize.bind(this);
- }
-
- UNSAFE_componentWillMount() {
- const check = () => {
- this.timeout = setTimeout(() => {
- const newState = calculateCoordinates(this.inner, this.resize, this.state);
- if (newState && this.state && !_.isEqual(newState, this.state)) {
- this.handleResize();
- }
- check();
- }, 500);
- };
- check();
+ this.checkResizeThrottled = _.throttle(() => {
+ const newState = calculateCoordinates(this.inner, this.resize, this.state);
+ if (newState && this.state && !_.isEqual(newState, this.state)) {
+ this.handleResize();
+ }
+ }, 200);
}
componentWillUnmount() {
@@ -123,25 +117,33 @@ export class Metric extends Component {
className += ' tvbVisMetric--reversed';
}
return (
-
-
(this.resize = el)} className="tvbVisMetric__resize">
-
(this.inner = el)} className="tvbVisMetric__inner" style={styles.inner}>
-
- {primaryLabel}
+
+ {(resizeRef) => (
+
+
(this.resize = el)} className="tvbVisMetric__resize">
(this.inner = el)}
+ className="tvbVisMetric__inner"
+ style={styles.inner}
>
- {/* eslint-disable-next-line react/no-danger */}
-
+
+ {primaryLabel}
+
+ {/* eslint-disable-next-line react/no-danger */}
+
+
+
+ {secondarySnippet}
+ {additionalLabel}
- {secondarySnippet}
- {additionalLabel}
-
-
+ )}
+
);
}
}
diff --git a/src/plugins/vis_types/timeseries/server/lib/vis_data/request_processors/table/types.ts b/src/plugins/vis_types/timeseries/server/lib/vis_data/request_processors/table/types.ts
index b84aee949471b..6ab50858fe98b 100644
--- a/src/plugins/vis_types/timeseries/server/lib/vis_data/request_processors/table/types.ts
+++ b/src/plugins/vis_types/timeseries/server/lib/vis_data/request_processors/table/types.ts
@@ -7,8 +7,8 @@
*/
import type { IUiSettingsClient } from 'kibana/server';
+import { EsQueryConfig } from '@kbn/es-query';
import type { FetchedIndexPattern, Panel } from '../../../../../common/types';
-import type { EsQueryConfig } from '../../../../../../../data/common';
import type { SearchCapabilities } from '../../../search_strategies';
import type { VisTypeTimeseriesVisDataRequest } from '../../../../types';
diff --git a/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx b/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx
index b52a3f3a6040e..9c328a175c10b 100644
--- a/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx
+++ b/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx
@@ -12,14 +12,13 @@ import { i18n } from '@kbn/i18n';
import React from 'react';
import { render } from 'react-dom';
import { EuiLoadingChart } from '@elastic/eui';
-import { Filter } from '@kbn/es-query';
+import { Filter, onlyDisabledFiltersChanged } from '@kbn/es-query';
import { KibanaThemeProvider } from '../../../kibana_react/public';
import { VISUALIZE_EMBEDDABLE_TYPE } from './constants';
import {
IndexPattern,
TimeRange,
Query,
- esFilters,
TimefilterContract,
} from '../../../../plugins/data/public';
import {
@@ -239,7 +238,7 @@ export class VisualizeEmbeddable
}
// Check if filters has changed
- if (!esFilters.onlyDisabledFiltersChanged(this.input.filters, this.filters)) {
+ if (!onlyDisabledFiltersChanged(this.input.filters, this.filters)) {
this.filters = this.input.filters;
dirty = true;
}
diff --git a/src/plugins/visualizations/public/plugin.ts b/src/plugins/visualizations/public/plugin.ts
index 59d7c25c6f41d..eae4f704b7c3c 100644
--- a/src/plugins/visualizations/public/plugin.ts
+++ b/src/plugins/visualizations/public/plugin.ts
@@ -57,7 +57,6 @@ import {
import { VisualizeLocatorDefinition } from '../common/locator';
import { showNewVisModal } from './wizard';
import { createVisEditorsRegistry, VisEditorsRegistry } from './vis_editors_registry';
-import { esFilters } from '../../../plugins/data/public';
import { FeatureCatalogueCategory } from '../../home/public';
import type { VisualizeServices } from './visualize_app/types';
@@ -189,7 +188,7 @@ export class VisualizationsPlugin
),
map(({ state }) => ({
...state,
- filters: state.filters?.filter(esFilters.isFilterPinned),
+ filters: data.query.filterManager.getGlobalFilters(),
}))
),
},
diff --git a/src/plugins/visualizations/public/visualize_app/utils/get_visualize_list_item_link.test.ts b/src/plugins/visualizations/public/visualize_app/utils/get_visualize_list_item_link.test.ts
index e138acf2e9e85..7fe571b25f98c 100644
--- a/src/plugins/visualizations/public/visualize_app/utils/get_visualize_list_item_link.test.ts
+++ b/src/plugins/visualizations/public/visualize_app/utils/get_visualize_list_item_link.test.ts
@@ -9,8 +9,8 @@
import { getVisualizeListItemLink } from './get_visualize_list_item_link';
import { ApplicationStart } from 'kibana/public';
import { createHashHistory } from 'history';
+import { FilterStateStore } from '@kbn/es-query';
import { createKbnUrlStateStorage } from '../../../../kibana_utils/public';
-import { esFilters } from '../../../../data/public';
import { GLOBAL_STATE_STORAGE_KEY } from '../../../common/constants';
jest.mock('../../services', () => {
@@ -104,7 +104,7 @@ describe('listing item link is correct for each app', () => {
},
query: { query: 'q1' },
$state: {
- store: esFilters.FilterStateStore.GLOBAL_STATE,
+ store: FilterStateStore.GLOBAL_STATE,
},
},
];
diff --git a/src/plugins/visualizations/public/visualize_app/utils/use/use_visualize_app_state.tsx b/src/plugins/visualizations/public/visualize_app/utils/use/use_visualize_app_state.tsx
index 661717f99ed88..c6e8f9efdd035 100644
--- a/src/plugins/visualizations/public/visualize_app/utils/use/use_visualize_app_state.tsx
+++ b/src/plugins/visualizations/public/visualize_app/utils/use/use_visualize_app_state.tsx
@@ -11,6 +11,7 @@ import { cloneDeep, isEqual } from 'lodash';
import { map } from 'rxjs/operators';
import { EventEmitter } from 'events';
import { i18n } from '@kbn/i18n';
+import { FilterStateStore } from '@kbn/es-query';
import {
KibanaThemeProvider,
@@ -18,7 +19,7 @@ import {
toMountPoint,
} from '../../../../../kibana_react/public';
import { migrateLegacyQuery } from '../migrate_legacy_query';
-import { esFilters, connectToQueryState } from '../../../../../data/public';
+import { connectToQueryState } from '../../../../../data/public';
import {
VisualizeServices,
VisualizeAppStateContainer,
@@ -87,7 +88,7 @@ export const useVisualizeAppState = (
),
},
{
- filters: esFilters.FilterStateStore.APP_STATE,
+ filters: FilterStateStore.APP_STATE,
query: true,
}
);
diff --git a/test/api_integration/apis/home/sample_data.ts b/test/api_integration/apis/home/sample_data.ts
index 1a324ef844e2e..6636a490118b4 100644
--- a/test/api_integration/apis/home/sample_data.ts
+++ b/test/api_integration/apis/home/sample_data.ts
@@ -21,8 +21,7 @@ export default function ({ getService }: FtrProviderContext) {
const FLIGHTS_CANVAS_APPLINK_PATH =
'/app/canvas#/workpad/workpad-a474e74b-aedc-47c3-894a-db77e62c41e0'; // includes default ID of the flights canvas applink path
- // Failing: See https://github.com/elastic/kibana/issues/121051
- describe.skip('sample data apis', () => {
+ describe('sample data apis', () => {
before(async () => {
await esArchiver.emptyKibanaIndex();
});
@@ -63,22 +62,23 @@ export default function ({ getService }: FtrProviderContext) {
});
});
- it('should load elasticsearch index containing sample data with dates relative to current time', async () => {
- const resp = await es.search<{ timestamp: string }>({
- index: 'kibana_sample_data_flights',
- body: {
- sort: [{ timestamp: { order: 'desc' } }],
- },
- });
+ // Failing: See https://github.com/elastic/kibana/issues/121051
+ describe.skip('dates', () => {
+ it('should load elasticsearch index containing sample data with dates relative to current time', async () => {
+ const resp = await es.search<{ timestamp: string }>({
+ index: 'kibana_sample_data_flights',
+ body: {
+ sort: [{ timestamp: { order: 'desc' } }],
+ },
+ });
- const doc = resp.hits.hits[0];
- const docMilliseconds = Date.parse(doc._source!.timestamp);
- const nowMilliseconds = Date.now();
- const delta = Math.abs(nowMilliseconds - docMilliseconds);
- expect(delta).to.be.lessThan(MILLISECOND_IN_WEEK * 5);
- });
+ const doc = resp.hits.hits[0];
+ const docMilliseconds = Date.parse(doc._source!.timestamp);
+ const nowMilliseconds = Date.now();
+ const delta = Math.abs(nowMilliseconds - docMilliseconds);
+ expect(delta).to.be.lessThan(MILLISECOND_IN_WEEK * 5);
+ });
- describe('parameters', () => {
it('should load elasticsearch index containing sample data with dates relative to now parameter', async () => {
const nowString = `2000-01-01T00:00:00`;
await supertest.post(`${apiPath}/flights?now=${nowString}`).set('kbn-xsrf', 'kibana');
diff --git a/test/functional/apps/discover/_context_encoded_url_param.ts b/test/functional/apps/discover/_context_encoded_url_param.ts
new file mode 100644
index 0000000000000..83ac63afd915f
--- /dev/null
+++ b/test/functional/apps/discover/_context_encoded_url_param.ts
@@ -0,0 +1,55 @@
+/*
+ * 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 expect from '@kbn/expect';
+import { FtrProviderContext } from '../../ftr_provider_context';
+
+export default function ({ getService, getPageObjects }: FtrProviderContext) {
+ const dataGrid = getService('dataGrid');
+ const kibanaServer = getService('kibanaServer');
+ const PageObjects = getPageObjects(['common', 'discover', 'timePicker', 'settings', 'header']);
+ const testSubjects = getService('testSubjects');
+ const es = getService('es');
+
+ describe('context encoded id param', () => {
+ before(async function () {
+ await PageObjects.common.navigateToApp('settings');
+ await es.transport.request({
+ path: '/includes-plus-symbol-doc-id/_doc/1+1=2',
+ method: 'PUT',
+ body: {
+ username: 'Dmitry',
+ '@timestamp': '2015-09-21T09:30:23',
+ },
+ });
+ await PageObjects.settings.createIndexPattern('includes-plus-symbol-doc-id');
+
+ await kibanaServer.uiSettings.update({ 'doc_table:legacy': false });
+ await PageObjects.timePicker.setDefaultAbsoluteRangeViaUiSettings();
+ await PageObjects.common.navigateToApp('discover');
+ });
+
+ it('should navigate to context page correctly', async () => {
+ await PageObjects.discover.selectIndexPattern('includes-plus-symbol-doc-id');
+ await PageObjects.header.waitUntilLoadingHasFinished();
+
+ // navigate to the context view
+ await dataGrid.clickRowToggle({ rowIndex: 0 });
+ const [, surroundingActionEl] = await dataGrid.getRowActions({
+ isAnchorRow: false,
+ rowIndex: 0,
+ });
+ await surroundingActionEl.click();
+ await PageObjects.header.waitUntilLoadingHasFinished();
+
+ const headerElement = await testSubjects.find('contextDocumentSurroundingHeader');
+
+ expect(await headerElement.getVisibleText()).to.be('Documents surrounding #1+1=2');
+ });
+ });
+}
diff --git a/test/functional/apps/discover/_doc_table.ts b/test/functional/apps/discover/_doc_table.ts
index f6f60d4fd6393..794204b923b72 100644
--- a/test/functional/apps/discover/_doc_table.ts
+++ b/test/functional/apps/discover/_doc_table.ts
@@ -120,14 +120,19 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.discover.backToTop();
});
- it('should go the end of the table when using the accessible Skip button', async function () {
+ it('should go the end and back to top of the classic table when using the accessible buttons', async function () {
// click the Skip to the end of the table
await PageObjects.discover.skipToEndOfDocTable();
// now check the footer text content
const footer = await PageObjects.discover.getDocTableFooter();
- log.debug(await footer.getVisibleText());
expect(await footer.getVisibleText()).to.have.string(rowsHardLimit);
await PageObjects.discover.backToTop();
+ // check that the skip to end of the table button now has focus
+ const skipButton = await testSubjects.find('discoverSkipTableButton');
+ const activeElement = await find.activeElement();
+ const activeElementText = await activeElement.getVisibleText();
+ const skipButtonText = await skipButton.getVisibleText();
+ expect(skipButtonText === activeElementText).to.be(true);
});
describe('expand a document row', function () {
diff --git a/test/functional/apps/discover/_runtime_fields_editor.ts b/test/functional/apps/discover/_runtime_fields_editor.ts
index 4757807cb7ac1..2e21b2e1f8ec6 100644
--- a/test/functional/apps/discover/_runtime_fields_editor.ts
+++ b/test/functional/apps/discover/_runtime_fields_editor.ts
@@ -31,8 +31,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await fieldEditor.save();
};
- // Failing: https://github.com/elastic/kibana/issues/111922
- describe.skip('discover integration with runtime fields editor', function describeIndexTests() {
+ describe('discover integration with runtime fields editor', function describeIndexTests() {
before(async function () {
await security.testUser.setRoles(['kibana_admin', 'test_logstash_reader']);
await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional');
@@ -63,7 +62,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('allows creation of a new field', async function () {
await createRuntimeField('runtimefield');
await PageObjects.header.waitUntilLoadingHasFinished();
- await retry.waitFor('fieldNames to include runtimefield', async () => {
+ await retry.waitForWithTimeout('fieldNames to include runtimefield', 5000, async () => {
const fieldNames = await PageObjects.discover.getAllFieldNames();
return fieldNames.includes('runtimefield');
});
@@ -76,7 +75,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await fieldEditor.confirmSave();
await PageObjects.header.waitUntilLoadingHasFinished();
- await retry.waitFor('fieldNames to include edits', async () => {
+ await retry.waitForWithTimeout('fieldNames to include edits', 5000, async () => {
const fieldNames = await PageObjects.discover.getAllFieldNames();
return fieldNames.includes('runtimefield edited');
});
@@ -105,7 +104,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await PageObjects.discover.removeField('delete');
await fieldEditor.confirmDelete();
await PageObjects.header.waitUntilLoadingHasFinished();
- await retry.waitFor('fieldNames to include edits', async () => {
+ await retry.waitForWithTimeout('fieldNames to include edits', 5000, async () => {
const fieldNames = await PageObjects.discover.getAllFieldNames();
return !fieldNames.includes('delete');
});
@@ -127,16 +126,22 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await rowActions[idxToClick].click();
});
- await retry.waitFor('doc viewer is displayed with runtime field', async () => {
- const hasDocHit = await testSubjects.exists('doc-hit');
- if (!hasDocHit) {
- // Maybe loading has not completed
- throw new Error('test subject doc-hit is not yet displayed');
+ await retry.waitForWithTimeout(
+ 'doc viewer is displayed with runtime field',
+ 5000,
+ async () => {
+ const hasDocHit = await testSubjects.exists('doc-hit');
+ if (!hasDocHit) {
+ // Maybe loading has not completed
+ throw new Error('test subject doc-hit is not yet displayed');
+ }
+ const runtimeFieldsRow = await testSubjects.exists(
+ 'tableDocViewRow-discover runtimefield'
+ );
+
+ return hasDocHit && runtimeFieldsRow;
}
- const runtimeFieldsRow = await testSubjects.exists('tableDocViewRow-discover runtimefield');
-
- return hasDocHit && runtimeFieldsRow;
- });
+ );
});
});
}
diff --git a/test/functional/apps/discover/index.ts b/test/functional/apps/discover/index.ts
index 13658215e9e59..1241b0e892e9c 100644
--- a/test/functional/apps/discover/index.ts
+++ b/test/functional/apps/discover/index.ts
@@ -53,5 +53,6 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) {
loadTestFile(require.resolve('./_date_nested'));
loadTestFile(require.resolve('./_search_on_page_load'));
loadTestFile(require.resolve('./_chart_hidden'));
+ loadTestFile(require.resolve('./_context_encoded_url_param'));
});
}
diff --git a/test/functional/services/lib/compare_pngs.ts b/test/functional/services/lib/compare_pngs.ts
index 521781c5a6d2b..5fb0c4d6ad1dc 100644
--- a/test/functional/services/lib/compare_pngs.ts
+++ b/test/functional/services/lib/compare_pngs.ts
@@ -9,6 +9,8 @@
import { parse, join } from 'path';
import Jimp from 'jimp';
import { ToolingLog } from '@kbn/dev-utils';
+import { promises as fs } from 'fs';
+import path from 'path';
interface PngDescriptor {
path: string;
@@ -102,3 +104,53 @@ export async function comparePngs(
}
return percent;
}
+
+export async function checkIfPngsMatch(
+ actualpngPath: string,
+ baselinepngPath: string,
+ screenshotsDirectory: string,
+ log: any
+) {
+ log.debug(`checkIfpngsMatch: ${actualpngPath} vs ${baselinepngPath}`);
+ // Copy the pngs into the screenshot session directory, as that's where the generated pngs will automatically be
+ // stored.
+ const sessionDirectoryPath = path.resolve(screenshotsDirectory, 'session');
+ const failureDirectoryPath = path.resolve(screenshotsDirectory, 'failure');
+
+ await fs.mkdir(sessionDirectoryPath, { recursive: true });
+ await fs.mkdir(failureDirectoryPath, { recursive: true });
+
+ const actualpngFileName = path.basename(actualpngPath, '.png');
+ const baselinepngFileName = path.basename(baselinepngPath, '.png');
+
+ const baselineCopyPath = path.resolve(
+ sessionDirectoryPath,
+ `${baselinepngFileName}_baseline.png`
+ );
+ const actualCopyPath = path.resolve(sessionDirectoryPath, `${actualpngFileName}_actual.png`);
+
+ // Don't cause a test failure if the baseline snapshot doesn't exist - we don't have all OS's covered and we
+ // don't want to start causing failures for other devs working on OS's which are lacking snapshots. We have
+ // mac and linux covered which is better than nothing for now.
+ try {
+ log.debug(`writeFile: ${baselineCopyPath}`);
+ await fs.writeFile(baselineCopyPath, await fs.readFile(baselinepngPath));
+ } catch (error) {
+ throw new Error(`No baseline png found at ${baselinepngPath}`);
+ }
+ log.debug(`writeFile: ${actualCopyPath}`);
+ await fs.writeFile(actualCopyPath, await fs.readFile(actualpngPath));
+
+ let diffTotal = 0;
+
+ const diffPngPath = path.resolve(failureDirectoryPath, `${baselinepngFileName}-${1}.png`);
+ diffTotal += await comparePngs(
+ actualCopyPath,
+ baselineCopyPath,
+ diffPngPath,
+ sessionDirectoryPath,
+ log
+ );
+
+ return diffTotal;
+}
diff --git a/test/functional/services/remote/network_profiles.ts b/test/functional/services/remote/network_profiles.ts
index c27bafa4f8dcb..cb4076686270c 100644
--- a/test/functional/services/remote/network_profiles.ts
+++ b/test/functional/services/remote/network_profiles.ts
@@ -12,23 +12,11 @@ interface NetworkOptions {
LATENCY: number;
}
-const sec = 1_000;
-const kB = 1024;
+const sec = 10 ** 3;
+const MBps = 10 ** 6 / 8; // megabyte per second (MB/s) (can be abbreviated as MBps)
-// Download (kb/s) Upload (kb/s) Latency (ms)
-// https://gist.github.com/theodorosploumis/fd4086ee58369b68aea6b0782dc96a2e
+// Selenium uses B/s (bytes) for network throttling
+// Download (B/s) Upload (B/s) Latency (ms)
export const NETWORK_PROFILES: { [key: string]: NetworkOptions } = {
- DEFAULT: { DOWNLOAD: 5 * kB * sec, UPLOAD: 1 * kB * sec, LATENCY: 0.1 * sec },
- GPRS: { DOWNLOAD: 0.05 * kB * sec, UPLOAD: 0.02 * kB * sec, LATENCY: 0.5 * sec },
- MOBILE_EDGE: { DOWNLOAD: 0.24 * kB * sec, UPLOAD: 0.2 * kB * sec, LATENCY: 0.84 * sec },
- '2G_REGULAR': { DOWNLOAD: 0.25 * kB * sec, UPLOAD: 0.05 * kB * sec, LATENCY: 0.3 * sec },
- '2G_GOOD': { DOWNLOAD: 0.45 * kB * sec, UPLOAD: 0.15 * kB * sec, LATENCY: 0.15 * sec },
- '3G_SLOW': { DOWNLOAD: 0.78 * kB * sec, UPLOAD: 0.33 * kB * sec, LATENCY: 0.2 * sec },
- '3G_REGULAR': { DOWNLOAD: 0.75 * kB * sec, UPLOAD: 0.25 * kB * sec, LATENCY: 0.1 * sec },
- '3G_GOOD': { DOWNLOAD: 1.5 * kB * sec, UPLOAD: 0.75 * kB * sec, LATENCY: 0.04 * sec },
- '4G_REGULAR': { DOWNLOAD: 4 * kB * sec, UPLOAD: 3 * kB * sec, LATENCY: 0.02 * sec },
- DSL: { DOWNLOAD: 2 * kB * sec, UPLOAD: 1 * kB * sec, LATENCY: 0.005 * sec },
- CABLE_5MBPS: { DOWNLOAD: 5 * kB * sec, UPLOAD: 1 * kB * sec, LATENCY: 0.28 * sec },
- CABLE_8MBPS: { DOWNLOAD: 8 * kB * sec, UPLOAD: 2 * kB * sec, LATENCY: 0.1 * sec },
- WIFI: { DOWNLOAD: 30 * kB * sec, UPLOAD: 15 * kB * sec, LATENCY: 0.002 * sec },
+ CLOUD_USER: { DOWNLOAD: 6 * MBps, UPLOAD: 6 * MBps, LATENCY: 0.1 * sec },
};
diff --git a/test/functional/services/remote/webdriver.ts b/test/functional/services/remote/webdriver.ts
index 84dfdf3c845f7..d4e20a617a602 100644
--- a/test/functional/services/remote/webdriver.ts
+++ b/test/functional/services/remote/webdriver.ts
@@ -39,6 +39,7 @@ const headlessBrowser: string = process.env.TEST_BROWSER_HEADLESS as string;
const browserBinaryPath: string = process.env.TEST_BROWSER_BINARY_PATH as string;
const remoteDebug: string = process.env.TEST_REMOTE_DEBUG as string;
const certValidation: string = process.env.NODE_TLS_REJECT_UNAUTHORIZED as string;
+const noCache: string = process.env.TEST_DISABLE_CACHE as string;
const SECOND = 1000;
const MINUTE = 60 * SECOND;
const NO_QUEUE_COMMANDS = ['getLog', 'getStatus', 'newSession', 'quit'];
@@ -118,6 +119,11 @@ function initChromiumOptions(browserType: Browsers, acceptInsecureCerts: boolean
options.setChromeBinaryPath(browserBinaryPath);
}
+ if (noCache === '1') {
+ options.addArguments('disk-cache-size', '0');
+ options.addArguments('disk-cache-dir', '/dev/null');
+ }
+
const prefs = new logging.Preferences();
prefs.setLevel(logging.Type.BROWSER, logging.Level.ALL);
options.setUserPreferences(chromiumUserPrefs);
@@ -291,12 +297,12 @@ async function attemptToCreateCommand(
const { session, consoleLog$ } = await buildDriverInstance();
if (throttleOption === '1' && browserType === 'chrome') {
- const { KBN_NETWORK_TEST_PROFILE = 'DEFAULT' } = process.env;
+ const { KBN_NETWORK_TEST_PROFILE = 'CLOUD_USER' } = process.env;
const profile =
KBN_NETWORK_TEST_PROFILE in Object.keys(NETWORK_PROFILES)
? KBN_NETWORK_TEST_PROFILE
- : 'DEFAULT';
+ : 'CLOUD_USER';
const {
DOWNLOAD: downloadThroughput,
@@ -306,9 +312,16 @@ async function attemptToCreateCommand(
// Only chrome supports this option.
log.debug(
- `NETWORK THROTTLED with profile ${profile}: ${downloadThroughput}kbps down, ${uploadThroughput}kbps up, ${latency} ms latency.`
+ `NETWORK THROTTLED with profile ${profile}: ${downloadThroughput} B/s down, ${uploadThroughput} B/s up, ${latency} ms latency.`
);
+ if (noCache) {
+ // @ts-expect-error
+ await session.sendDevToolsCommand('Network.setCacheDisabled', {
+ cacheDisabled: true,
+ });
+ }
+
// @ts-expect-error
session.setNetworkConditions({
offline: false,
diff --git a/test/plugin_functional/test_suites/saved_objects_management/hidden_types.ts b/test/plugin_functional/test_suites/saved_objects_management/hidden_types.ts
index 8e7adb504ebee..439ece04e615f 100644
--- a/test/plugin_functional/test_suites/saved_objects_management/hidden_types.ts
+++ b/test/plugin_functional/test_suites/saved_objects_management/hidden_types.ts
@@ -21,7 +21,8 @@ export default function ({ getService, getPageObjects }: PluginFunctionalProvide
const esArchiver = getService('esArchiver');
const testSubjects = getService('testSubjects');
- describe('saved objects management with hidden types', () => {
+ // Failing: See https://github.com/elastic/kibana/issues/116059
+ describe.skip('saved objects management with hidden types', () => {
before(async () => {
await esArchiver.load(
'test/functional/fixtures/es_archiver/saved_objects_management/hidden_types'
diff --git a/x-pack/examples/embedded_lens_example/public/app.tsx b/x-pack/examples/embedded_lens_example/public/app.tsx
index f1b683f2430f7..510d9469c7878 100644
--- a/x-pack/examples/embedded_lens_example/public/app.tsx
+++ b/x-pack/examples/embedded_lens_example/public/app.tsx
@@ -17,37 +17,32 @@ import {
EuiPageHeader,
EuiPageHeaderSection,
EuiTitle,
- EuiCallOut,
} from '@elastic/eui';
-import { IndexPattern } from 'src/plugins/data/public';
-import { CoreStart } from 'kibana/public';
-import { ViewMode } from '../../../../src/plugins/embeddable/public';
-import {
+
+import type { DataView } from 'src/plugins/data_views/public';
+import type { CoreStart } from 'kibana/public';
+import type { StartDependencies } from './plugin';
+import type {
TypedLensByValueInput,
PersistedIndexPatternLayer,
XYState,
LensEmbeddableInput,
+ FormulaPublicApi,
DateHistogramIndexPatternColumn,
} from '../../../plugins/lens/public';
-import { StartDependencies } from './plugin';
+
+import { ViewMode } from '../../../../src/plugins/embeddable/public';
// Generate a Lens state based on some app-specific input parameters.
// `TypedLensByValueInput` can be used for type-safety - it uses the same interfaces as Lens-internal code.
function getLensAttributes(
- defaultIndexPattern: IndexPattern,
- color: string
+ color: string,
+ dataView: DataView,
+ formula: FormulaPublicApi
): TypedLensByValueInput['attributes'] {
- const dataLayer: PersistedIndexPatternLayer = {
- columnOrder: ['col1', 'col2'],
+ const baseLayer: PersistedIndexPatternLayer = {
+ columnOrder: ['col1'],
columns: {
- col2: {
- dataType: 'number',
- isBucketed: false,
- label: 'Count of records',
- operationType: 'count',
- scale: 'ratio',
- sourceField: 'Records',
- },
col1: {
dataType: 'date',
isBucketed: true,
@@ -55,11 +50,18 @@ function getLensAttributes(
operationType: 'date_histogram',
params: { interval: 'auto' },
scale: 'interval',
- sourceField: defaultIndexPattern.timeFieldName!,
+ sourceField: dataView.timeFieldName!,
} as DateHistogramIndexPatternColumn,
},
};
+ const dataLayer = formula.insertOrReplaceFormulaColumn(
+ 'col2',
+ { formula: 'count()' },
+ baseLayer,
+ dataView
+ );
+
const xyConfig: XYState = {
axisTitlesVisibilitySettings: { x: true, yLeft: true, yRight: true },
fittingFunction: 'None',
@@ -85,12 +87,12 @@ function getLensAttributes(
title: 'Prefilled from example app',
references: [
{
- id: defaultIndexPattern.id!,
+ id: dataView.id!,
name: 'indexpattern-datasource-current-indexpattern',
type: 'index-pattern',
},
{
- id: defaultIndexPattern.id!,
+ id: dataView.id!,
name: 'indexpattern-datasource-layer-layer1',
type: 'index-pattern',
},
@@ -99,7 +101,7 @@ function getLensAttributes(
datasourceStates: {
indexpattern: {
layers: {
- layer1: dataLayer,
+ layer1: dataLayer!,
},
},
},
@@ -113,19 +115,22 @@ function getLensAttributes(
export const App = (props: {
core: CoreStart;
plugins: StartDependencies;
- defaultIndexPattern: IndexPattern | null;
+ defaultDataView: DataView;
+ formula: FormulaPublicApi;
}) => {
const [color, setColor] = useState('green');
const [isLoading, setIsLoading] = useState(false);
const [isSaveModalVisible, setIsSaveModalVisible] = useState(false);
- const LensComponent = props.plugins.lens.EmbeddableComponent;
- const LensSaveModalComponent = props.plugins.lens.SaveModalComponent;
-
const [time, setTime] = useState({
from: 'now-5d',
to: 'now',
});
+ const LensComponent = props.plugins.lens.EmbeddableComponent;
+ const LensSaveModalComponent = props.plugins.lens.SaveModalComponent;
+
+ const attributes = getLensAttributes(color, props.defaultDataView, props.formula);
+
return (
@@ -147,138 +152,122 @@ export const App = (props: {
the series which causes Lens to re-render. The Edit button will take the current
configuration and navigate to a prefilled editor.
- {props.defaultIndexPattern && props.defaultIndexPattern.isTimeBased() ? (
- <>
-
-
- {
- // eslint-disable-next-line no-bitwise
- const newColor = '#' + ((Math.random() * 0xffffff) << 0).toString(16);
- setColor(newColor);
- }}
- >
- Change color
-
-
-
- {
- props.plugins.lens.navigateToPrefilledEditor(
- {
- id: '',
- timeRange: time,
- attributes: getLensAttributes(props.defaultIndexPattern!, color),
- },
- {
- openInNewTab: true,
- }
- );
- // eslint-disable-next-line no-bitwise
- const newColor = '#' + ((Math.random() * 0xffffff) << 0).toString(16);
- setColor(newColor);
- }}
- >
- Edit in Lens (new tab)
-
-
-
- {
- props.plugins.lens.navigateToPrefilledEditor(
- {
- id: '',
- timeRange: time,
- attributes: getLensAttributes(props.defaultIndexPattern!, color),
- },
- {
- openInNewTab: false,
- }
- );
- }}
- >
- Edit in Lens (same tab)
-
-
-
- {
- setIsSaveModalVisible(true);
- }}
- >
- Save Visualization
-
-
-
- {
- setTime({
- from: '2015-09-18T06:31:44.000Z',
- to: '2015-09-23T18:31:44.000Z',
- });
- }}
- >
- Change time range
-
-
-
- {
- setIsLoading(val);
+
+
+
+ {
+ // eslint-disable-next-line no-bitwise
+ const newColor = '#' + ((Math.random() * 0xffffff) << 0).toString(16);
+ setColor(newColor);
}}
- onBrushEnd={({ range }) => {
- setTime({
- from: new Date(range[0]).toISOString(),
- to: new Date(range[1]).toISOString(),
- });
+ >
+ Change color
+
+
+
+ {
+ props.plugins.lens.navigateToPrefilledEditor(
+ {
+ id: '',
+ timeRange: time,
+ attributes,
+ },
+ {
+ openInNewTab: true,
+ }
+ );
+ // eslint-disable-next-line no-bitwise
+ const newColor = '#' + ((Math.random() * 0xffffff) << 0).toString(16);
+ setColor(newColor);
+ }}
+ >
+ Edit in Lens (new tab)
+
+
+
+ {
+ props.plugins.lens.navigateToPrefilledEditor(
+ {
+ id: '',
+ timeRange: time,
+ attributes,
+ },
+ {
+ openInNewTab: false,
+ }
+ );
}}
- onFilter={(_data) => {
- // call back event for on filter event
+ >
+ Edit in Lens (same tab)
+
+
+
+ {
+ setIsSaveModalVisible(true);
}}
- onTableRowClick={(_data) => {
- // call back event for on table row click event
+ >
+ Save Visualization
+
+
+
+ {
+ setTime({
+ from: '2015-09-18T06:31:44.000Z',
+ to: '2015-09-23T18:31:44.000Z',
+ });
}}
- viewMode={ViewMode.VIEW}
- />
- {isSaveModalVisible && (
- {}}
- onClose={() => setIsSaveModalVisible(false)}
- />
- )}
- >
- ) : (
-
- This demo only works if your default index pattern is set and time based
-
+ >
+ Change time range
+
+
+
+ {
+ setIsLoading(val);
+ }}
+ onBrushEnd={({ range }) => {
+ setTime({
+ from: new Date(range[0]).toISOString(),
+ to: new Date(range[1]).toISOString(),
+ });
+ }}
+ onFilter={(_data) => {
+ // call back event for on filter event
+ }}
+ onTableRowClick={(_data) => {
+ // call back event for on table row click event
+ }}
+ viewMode={ViewMode.VIEW}
+ />
+ {isSaveModalVisible && (
+ {}}
+ onClose={() => setIsSaveModalVisible(false)}
+ />
)}
diff --git a/x-pack/examples/embedded_lens_example/public/mount.tsx b/x-pack/examples/embedded_lens_example/public/mount.tsx
index 58ec363223270..e438b6946b8b6 100644
--- a/x-pack/examples/embedded_lens_example/public/mount.tsx
+++ b/x-pack/examples/embedded_lens_example/public/mount.tsx
@@ -7,8 +7,10 @@
import * as React from 'react';
import { render, unmountComponentAtNode } from 'react-dom';
-import { CoreSetup, AppMountParameters } from 'kibana/public';
-import { StartDependencies } from './plugin';
+import { EuiCallOut } from '@elastic/eui';
+
+import type { CoreSetup, AppMountParameters } from 'kibana/public';
+import type { StartDependencies } from './plugin';
export const mount =
(coreSetup: CoreSetup) =>
@@ -16,20 +18,27 @@ export const mount =
const [core, plugins] = await coreSetup.getStartServices();
const { App } = await import('./app');
- const deps = {
- core,
- plugins,
- };
-
- const defaultIndexPattern = await plugins.data.indexPatterns.getDefault();
+ const defaultDataView = await plugins.data.indexPatterns.getDefault();
+ const { formula } = await plugins.lens.stateHelperApi();
const i18nCore = core.i18n;
const reactElement = (
-
+ {defaultDataView && defaultDataView.isTimeBased() ? (
+
+ ) : (
+
+ This demo only works if your default index pattern is set and time based
+
+ )}
);
+
render(reactElement, element);
return () => unmountComponentAtNode(element);
};
diff --git a/x-pack/plugins/apm/dev_docs/routing_and_linking.md b/x-pack/plugins/apm/dev_docs/routing_and_linking.md
index 562af3d01ef77..d5c1d6c630635 100644
--- a/x-pack/plugins/apm/dev_docs/routing_and_linking.md
+++ b/x-pack/plugins/apm/dev_docs/routing_and_linking.md
@@ -46,7 +46,7 @@ To be able to use the parameters, you can use `useApmParams`, which will automat
```ts
const {
path: { serviceName }, // string
- query: { transactionType } // string | undefined
+ query: { transactionType }, // string | undefined
} = useApmParams('/services/:serviceName');
```
@@ -64,13 +64,16 @@ For links that stay inside APM, the preferred way of linking is to call the `use
```ts
const apmRouter = useApmRouter();
-const serviceOverviewLink = apmRouter.link('/services/:serviceName', { path: { serviceName: 'opbeans-java' }, query: { transactionType: 'request' }});
+const serviceOverviewLink = apmRouter.link('/services/:serviceName', {
+ path: { serviceName: 'opbeans-java' },
+ query: { transactionType: 'request' },
+});
```
- If you're not in React context, you can also import `apmRouter` directly and call its `link` function - but you have to prepend the basePath manually in that case.
+If you're not in React context, you can also import `apmRouter` directly and call its `link` function - but you have to prepend the basePath manually in that case.
-We also have the [`getLegacyApmHref` function and `APMLink` component](../public/components/shared/Links/apm/APMLink.tsx), but we should consider them deprecated, in favor of `router.link`. Other components inside that directory contain other functions and components that provide the same functionality for linking to more specific sections inside the APM plugin.
+We also have the [`getLegacyApmHref` function and `APMLink` component](../public/components/shared/links/apm/APMLink.tsx), but we should consider them deprecated, in favor of `router.link`. Other components inside that directory contain other functions and components that provide the same functionality for linking to more specific sections inside the APM plugin.
### Cross-app linking
-Other helpers and components in [the Links directory](../public/components/shared/Links) allow linking to other Kibana apps.
+Other helpers and components in [the Links directory](../public/components/shared/links) allow linking to other Kibana apps.
diff --git a/x-pack/plugins/apm/public/application/application.test.tsx b/x-pack/plugins/apm/public/application/application.test.tsx
index 12170ac20b7df..396e853ca54a7 100644
--- a/x-pack/plugins/apm/public/application/application.test.tsx
+++ b/x-pack/plugins/apm/public/application/application.test.tsx
@@ -20,13 +20,13 @@ import { disableConsoleWarning } from '../utils/testHelpers';
import { dataPluginMock } from 'src/plugins/data/public/mocks';
import { embeddablePluginMock } from 'src/plugins/embeddable/public/mocks';
import { ApmPluginSetupDeps, ApmPluginStartDeps } from '../plugin';
-import { RumHome } from '../components/app/RumDashboard/RumHome';
+import { RumHome } from '../components/app/rum_dashboard/rum_home';
jest.mock('../services/rest/data_view', () => ({
createStaticDataView: () => Promise.resolve(undefined),
}));
-jest.mock('../components/app/RumDashboard/RumHome', () => ({
+jest.mock('../components/app/rum_dashboard/rum_home', () => ({
RumHome: () => Home Mock
,
}));
diff --git a/x-pack/plugins/apm/public/application/uxApp.tsx b/x-pack/plugins/apm/public/application/uxApp.tsx
index cfb1a5c354c2d..dde7cfe5399d3 100644
--- a/x-pack/plugins/apm/public/application/uxApp.tsx
+++ b/x-pack/plugins/apm/public/application/uxApp.tsx
@@ -21,18 +21,18 @@ import {
useUiSetting$,
} from '../../../../../src/plugins/kibana_react/public';
import { APMRouteDefinition } from '../application/routes';
-import { ScrollToTopOnPathChange } from '../components/app/Main/ScrollToTopOnPathChange';
+import { ScrollToTopOnPathChange } from '../components/app/main/ScrollToTopOnPathChange';
import {
RumHome,
DASHBOARD_LABEL,
-} from '../components/app/RumDashboard/RumHome';
+} from '../components/app/rum_dashboard/rum_home';
import { ApmPluginContext } from '../context/apm_plugin/apm_plugin_context';
import { UrlParamsProvider } from '../context/url_params_context/url_params_context';
import { ConfigSchema } from '../index';
import { ApmPluginSetupDeps, ApmPluginStartDeps } from '../plugin';
import { createCallApmApi } from '../services/rest/createCallApmApi';
import { createStaticDataView } from '../services/rest/data_view';
-import { UXActionMenu } from '../components/app/RumDashboard/ActionMenu';
+import { UXActionMenu } from '../components/app/rum_dashboard/action_menu';
import { redirectTo } from '../components/routing/redirect_to';
import {
InspectorContextProvider,
diff --git a/x-pack/plugins/apm/public/components/app/Settings/agent_configurations/AgentConfigurationCreateEdit/ServicePage/FormRowSelect.tsx b/x-pack/plugins/apm/public/components/app/Settings/agent_configurations/AgentConfigurationCreateEdit/ServicePage/FormRowSelect.tsx
index 45c8ddaf2f4df..b45a513bf9d64 100644
--- a/x-pack/plugins/apm/public/components/app/Settings/agent_configurations/AgentConfigurationCreateEdit/ServicePage/FormRowSelect.tsx
+++ b/x-pack/plugins/apm/public/components/app/Settings/agent_configurations/AgentConfigurationCreateEdit/ServicePage/FormRowSelect.tsx
@@ -11,7 +11,7 @@ import {
EuiSelectOption,
EuiFormRow,
} from '@elastic/eui';
-import { SelectWithPlaceholder } from '../../../../../shared/SelectWithPlaceholder';
+import { SelectWithPlaceholder } from '../../../../../shared/select_with_placeholder';
interface Props {
title: string;
diff --git a/x-pack/plugins/apm/public/components/app/Settings/agent_configurations/AgentConfigurationCreateEdit/ServicePage/ServicePage.tsx b/x-pack/plugins/apm/public/components/app/Settings/agent_configurations/AgentConfigurationCreateEdit/ServicePage/ServicePage.tsx
index d71751805ce41..50f4e34a1c6b4 100644
--- a/x-pack/plugins/apm/public/components/app/Settings/agent_configurations/AgentConfigurationCreateEdit/ServicePage/ServicePage.tsx
+++ b/x-pack/plugins/apm/public/components/app/Settings/agent_configurations/AgentConfigurationCreateEdit/ServicePage/ServicePage.tsx
@@ -17,7 +17,7 @@ import {
} from '../../../../../../../common/agent_configuration/all_option';
import { useFetcher, FETCH_STATUS } from '../../../../../../hooks/use_fetcher';
import { FormRowSelect } from './FormRowSelect';
-import { APMLink } from '../../../../../shared/Links/apm/APMLink';
+import { APMLink } from '../../../../../shared/links/apm/apm_link';
interface Props {
newConfig: AgentConfigurationIntake;
diff --git a/x-pack/plugins/apm/public/components/app/Settings/agent_configurations/AgentConfigurationCreateEdit/SettingsPage/SettingFormRow.tsx b/x-pack/plugins/apm/public/components/app/Settings/agent_configurations/AgentConfigurationCreateEdit/SettingsPage/SettingFormRow.tsx
index cee38e4186454..ccc483182d772 100644
--- a/x-pack/plugins/apm/public/components/app/Settings/agent_configurations/AgentConfigurationCreateEdit/SettingsPage/SettingFormRow.tsx
+++ b/x-pack/plugins/apm/public/components/app/Settings/agent_configurations/AgentConfigurationCreateEdit/SettingsPage/SettingFormRow.tsx
@@ -24,7 +24,7 @@ import {
amountAndUnitToString,
amountAndUnitToObject,
} from '../../../../../../../common/agent_configuration/amount_and_unit';
-import { SelectWithPlaceholder } from '../../../../../shared/SelectWithPlaceholder';
+import { SelectWithPlaceholder } from '../../../../../shared/select_with_placeholder';
function FormRow({
setting,
diff --git a/x-pack/plugins/apm/public/components/app/Settings/agent_configurations/AgentConfigurationCreateEdit/index.tsx b/x-pack/plugins/apm/public/components/app/Settings/agent_configurations/AgentConfigurationCreateEdit/index.tsx
index a0ca7daf82610..eaf7bb711e54e 100644
--- a/x-pack/plugins/apm/public/components/app/Settings/agent_configurations/AgentConfigurationCreateEdit/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/Settings/agent_configurations/AgentConfigurationCreateEdit/index.tsx
@@ -16,7 +16,7 @@ import {
AgentConfigurationIntake,
} from '../../../../../../common/agent_configuration/configuration_types';
import { FetcherResult } from '../../../../../hooks/use_fetcher';
-import { fromQuery, toQuery } from '../../../../shared/Links/url_helpers';
+import { fromQuery, toQuery } from '../../../../shared/links/url_helpers';
import { ServicePage } from './ServicePage/ServicePage';
import { SettingsPage } from './SettingsPage/SettingsPage';
diff --git a/x-pack/plugins/apm/public/components/app/Settings/agent_configurations/List/index.tsx b/x-pack/plugins/apm/public/components/app/Settings/agent_configurations/List/index.tsx
index 4804e52b16d4f..15efd28756b0b 100644
--- a/x-pack/plugins/apm/public/components/app/Settings/agent_configurations/List/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/Settings/agent_configurations/List/index.tsx
@@ -23,9 +23,9 @@ import { getOptionLabel } from '../../../../../../common/agent_configuration/all
import { useApmPluginContext } from '../../../../../context/apm_plugin/use_apm_plugin_context';
import { FETCH_STATUS } from '../../../../../hooks/use_fetcher';
import { useTheme } from '../../../../../hooks/use_theme';
-import { LoadingStatePrompt } from '../../../../shared/LoadingStatePrompt';
+import { LoadingStatePrompt } from '../../../../shared/loading_state_prompt';
import { ITableColumn, ManagedTable } from '../../../../shared/managed_table';
-import { TimestampTooltip } from '../../../../shared/TimestampTooltip';
+import { TimestampTooltip } from '../../../../shared/timestamp_tooltip';
import { ConfirmDeleteModal } from './ConfirmDeleteModal';
type Config =
diff --git a/x-pack/plugins/apm/public/components/app/Settings/agent_keys/agent_keys_table.tsx b/x-pack/plugins/apm/public/components/app/Settings/agent_keys/agent_keys_table.tsx
index ccd409f1798a5..e1ced3fabcd77 100644
--- a/x-pack/plugins/apm/public/components/app/Settings/agent_keys/agent_keys_table.tsx
+++ b/x-pack/plugins/apm/public/components/app/Settings/agent_keys/agent_keys_table.tsx
@@ -12,7 +12,7 @@ import {
EuiBasicTableColumn,
EuiInMemoryTableProps,
} from '@elastic/eui';
-import { TimestampTooltip } from '../../../shared/TimestampTooltip';
+import { TimestampTooltip } from '../../../shared/timestamp_tooltip';
import { ApiKey } from '../../../../../../security/common/model';
import { ConfirmDeleteModal } from './confirm_delete_modal';
diff --git a/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/jobs_list.tsx b/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/jobs_list.tsx
index 1faab4092361d..15b2d393a97a0 100644
--- a/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/jobs_list.tsx
+++ b/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/jobs_list.tsx
@@ -27,9 +27,9 @@ import { useApmPluginContext } from '../../../../context/apm_plugin/use_apm_plug
import { FETCH_STATUS } from '../../../../hooks/use_fetcher';
import { useMlManageJobsHref } from '../../../../hooks/use_ml_manage_jobs_href';
import { callApmApi } from '../../../../services/rest/createCallApmApi';
-import { MLExplorerLink } from '../../../shared/Links/MachineLearningLinks/MLExplorerLink';
-import { MLManageJobsLink } from '../../../shared/Links/MachineLearningLinks/MLManageJobsLink';
-import { LoadingStatePrompt } from '../../../shared/LoadingStatePrompt';
+import { MLExplorerLink } from '../../../shared/links/machine_learning_links/mlexplorer_link';
+import { MLManageJobsLink } from '../../../shared/links/machine_learning_links/mlmanage_jobs_link';
+import { LoadingStatePrompt } from '../../../shared/loading_state_prompt';
import { ITableColumn, ManagedTable } from '../../../shared/managed_table';
import { MLCallout, shouldDisplayMlCallout } from '../../../shared/ml_callout';
import { AnomalyDetectionApiResponse } from './index';
diff --git a/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/jobs_list_status.tsx b/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/jobs_list_status.tsx
index 6145e9f9ca7da..1df6dc0332b2a 100644
--- a/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/jobs_list_status.tsx
+++ b/x-pack/plugins/apm/public/components/app/Settings/anomaly_detection/jobs_list_status.tsx
@@ -8,7 +8,7 @@ import { EuiBadge, EuiFlexGroup, EuiFlexItem, EuiToolTip } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import { DATAFEED_STATE, JOB_STATE } from '../../../../../../ml/common';
-import { MLManageJobsLink } from '../../../shared/Links/MachineLearningLinks/MLManageJobsLink';
+import { MLManageJobsLink } from '../../../shared/links/machine_learning_links/mlmanage_jobs_link';
export function JobsListStatus({
jobId,
diff --git a/x-pack/plugins/apm/public/components/app/Settings/custom_link/custom_link_table.tsx b/x-pack/plugins/apm/public/components/app/Settings/custom_link/custom_link_table.tsx
index b6f344751b59b..5ce98f8b10884 100644
--- a/x-pack/plugins/apm/public/components/app/Settings/custom_link/custom_link_table.tsx
+++ b/x-pack/plugins/apm/public/components/app/Settings/custom_link/custom_link_table.tsx
@@ -18,9 +18,9 @@ import { isEmpty } from 'lodash';
import React, { useState } from 'react';
import { CustomLink } from '../../../../../common/custom_link/custom_link_types';
import { useApmPluginContext } from '../../../../context/apm_plugin/use_apm_plugin_context';
-import { LoadingStatePrompt } from '../../../shared/LoadingStatePrompt';
+import { LoadingStatePrompt } from '../../../shared/loading_state_prompt';
import { ITableColumn, ManagedTable } from '../../../shared/managed_table';
-import { TimestampTooltip } from '../../../shared/TimestampTooltip';
+import { TimestampTooltip } from '../../../shared/timestamp_tooltip';
interface Props {
items: CustomLink[];
diff --git a/x-pack/plugins/apm/public/components/app/Settings/schema/confirm_switch_modal.tsx b/x-pack/plugins/apm/public/components/app/Settings/schema/confirm_switch_modal.tsx
index 1847ea90bd7fa..375a4b5ac1156 100644
--- a/x-pack/plugins/apm/public/components/app/Settings/schema/confirm_switch_modal.tsx
+++ b/x-pack/plugins/apm/public/components/app/Settings/schema/confirm_switch_modal.tsx
@@ -16,7 +16,7 @@ import {
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { useUiTracker } from '../../../../../../observability/public';
-import { ElasticDocsLink } from '../../../shared/Links/ElasticDocsLink';
+import { ElasticDocsLink } from '../../../shared/links/elastic_docs_link';
interface Props {
onConfirm: () => void;
diff --git a/x-pack/plugins/apm/public/components/app/Settings/schema/migrated/card_footer_content.tsx b/x-pack/plugins/apm/public/components/app/Settings/schema/migrated/card_footer_content.tsx
index 62b4b242b1b68..6017d16ba2dad 100644
--- a/x-pack/plugins/apm/public/components/app/Settings/schema/migrated/card_footer_content.tsx
+++ b/x-pack/plugins/apm/public/components/app/Settings/schema/migrated/card_footer_content.tsx
@@ -9,8 +9,8 @@ import { EuiButton, EuiSpacer, EuiText } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import React from 'react';
-import { APMLink } from '../../../../shared/Links/apm/APMLink';
-import { useFleetCloudAgentPolicyHref } from '../../../../shared/Links/kibana';
+import { APMLink } from '../../../../shared/links/apm/apm_link';
+import { useFleetCloudAgentPolicyHref } from '../../../../shared/links/kibana';
export function CardFooterContent() {
const fleetCloudAgentPolicyHref = useFleetCloudAgentPolicyHref();
diff --git a/x-pack/plugins/apm/public/components/app/Settings/schema/migrated/upgrade_available_card.tsx b/x-pack/plugins/apm/public/components/app/Settings/schema/migrated/upgrade_available_card.tsx
index eee8ca66dd08f..8741cd7667698 100644
--- a/x-pack/plugins/apm/public/components/app/Settings/schema/migrated/upgrade_available_card.tsx
+++ b/x-pack/plugins/apm/public/components/app/Settings/schema/migrated/upgrade_available_card.tsx
@@ -9,7 +9,7 @@ import { EuiCard, EuiIcon, EuiLink } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import React from 'react';
-import { useUpgradeApmPackagePolicyHref } from '../../../../shared/Links/kibana';
+import { useUpgradeApmPackagePolicyHref } from '../../../../shared/links/kibana';
import { CardFooterContent } from './card_footer_content';
export function UpgradeAvailableCard({
diff --git a/x-pack/plugins/apm/public/components/app/Settings/schema/schema_overview.tsx b/x-pack/plugins/apm/public/components/app/Settings/schema/schema_overview.tsx
index d9540115d0d70..4c50b47a4b9a6 100644
--- a/x-pack/plugins/apm/public/components/app/Settings/schema/schema_overview.tsx
+++ b/x-pack/plugins/apm/public/components/app/Settings/schema/schema_overview.tsx
@@ -22,7 +22,7 @@ import React from 'react';
import semverLt from 'semver/functions/lt';
import { SUPPORTED_APM_PACKAGE_VERSION } from '../../../../../common/fleet';
import { PackagePolicy } from '../../../../../../fleet/common/types';
-import { ElasticDocsLink } from '../../../shared/Links/ElasticDocsLink';
+import { ElasticDocsLink } from '../../../shared/links/elastic_docs_link';
import rocketLaunchGraphic from './blog-rocket-720x420.png';
import { MigrationInProgressPanel } from './migration_in_progress_panel';
import { UpgradeAvailableCard } from './migrated/upgrade_available_card';
diff --git a/x-pack/plugins/apm/public/components/app/correlations/failed_transactions_correlations.tsx b/x-pack/plugins/apm/public/components/app/correlations/failed_transactions_correlations.tsx
index c642ca7bd577f..2d09abc15f854 100644
--- a/x-pack/plugins/apm/public/components/app/correlations/failed_transactions_correlations.tsx
+++ b/x-pack/plugins/apm/public/components/app/correlations/failed_transactions_correlations.tsx
@@ -38,8 +38,8 @@ import { useLocalStorage } from '../../../hooks/useLocalStorage';
import { FETCH_STATUS } from '../../../hooks/use_fetcher';
import { useTheme } from '../../../hooks/use_theme';
-import { ImpactBar } from '../../shared/ImpactBar';
-import { push } from '../../shared/Links/url_helpers';
+import { ImpactBar } from '../../shared/impact_bar';
+import { push } from '../../shared/links/url_helpers';
import { CorrelationsTable } from './correlations_table';
import { FailedTransactionsCorrelationsHelpPopover } from './failed_transactions_correlations_help_popover';
diff --git a/x-pack/plugins/apm/public/components/app/correlations/latency_correlations.test.tsx b/x-pack/plugins/apm/public/components/app/correlations/latency_correlations.test.tsx
index 0656ab045efc2..5bf7e30a3df5d 100644
--- a/x-pack/plugins/apm/public/components/app/correlations/latency_correlations.test.tsx
+++ b/x-pack/plugins/apm/public/components/app/correlations/latency_correlations.test.tsx
@@ -25,7 +25,7 @@ import {
mockApmPluginContextValue,
MockApmPluginContextWrapper,
} from '../../../context/apm_plugin/mock_apm_plugin_context';
-import { fromQuery } from '../../shared/Links/url_helpers';
+import { fromQuery } from '../../shared/links/url_helpers';
import { LatencyCorrelations } from './latency_correlations';
diff --git a/x-pack/plugins/apm/public/components/app/correlations/latency_correlations.tsx b/x-pack/plugins/apm/public/components/app/correlations/latency_correlations.tsx
index f79e955595717..5b37a14b4e4e5 100644
--- a/x-pack/plugins/apm/public/components/app/correlations/latency_correlations.tsx
+++ b/x-pack/plugins/apm/public/components/app/correlations/latency_correlations.tsx
@@ -33,7 +33,7 @@ import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_
import { FETCH_STATUS } from '../../../hooks/use_fetcher';
import { TransactionDistributionChart } from '../../shared/charts/transaction_distribution_chart';
-import { push } from '../../shared/Links/url_helpers';
+import { push } from '../../shared/links/url_helpers';
import { CorrelationsTable } from './correlations_table';
import { LatencyCorrelationsHelpPopover } from './latency_correlations_help_popover';
diff --git a/x-pack/plugins/apm/public/components/app/correlations/use_failed_transactions_correlations.test.tsx b/x-pack/plugins/apm/public/components/app/correlations/use_failed_transactions_correlations.test.tsx
index 929cc4f7f4cd3..d68c11f981a0f 100644
--- a/x-pack/plugins/apm/public/components/app/correlations/use_failed_transactions_correlations.test.tsx
+++ b/x-pack/plugins/apm/public/components/app/correlations/use_failed_transactions_correlations.test.tsx
@@ -17,7 +17,7 @@ import {
} from '../../../context/apm_plugin/mock_apm_plugin_context';
import { delay } from '../../../utils/testHelpers';
-import { fromQuery } from '../../shared/Links/url_helpers';
+import { fromQuery } from '../../shared/links/url_helpers';
import { useFailedTransactionsCorrelations } from './use_failed_transactions_correlations';
diff --git a/x-pack/plugins/apm/public/components/app/correlations/use_latency_correlations.test.tsx b/x-pack/plugins/apm/public/components/app/correlations/use_latency_correlations.test.tsx
index 90d976c389c58..c2c5a63a2ab03 100644
--- a/x-pack/plugins/apm/public/components/app/correlations/use_latency_correlations.test.tsx
+++ b/x-pack/plugins/apm/public/components/app/correlations/use_latency_correlations.test.tsx
@@ -17,7 +17,7 @@ import {
} from '../../../context/apm_plugin/mock_apm_plugin_context';
import { delay } from '../../../utils/testHelpers';
-import { fromQuery } from '../../shared/Links/url_helpers';
+import { fromQuery } from '../../shared/links/url_helpers';
import { useLatencyCorrelations } from './use_latency_correlations';
diff --git a/x-pack/plugins/apm/public/components/app/error_group_details/detail_view/exception_stacktrace.tsx b/x-pack/plugins/apm/public/components/app/error_group_details/detail_view/exception_stacktrace.tsx
index 77d54e0dad698..85ad5c5336c8c 100644
--- a/x-pack/plugins/apm/public/components/app/error_group_details/detail_view/exception_stacktrace.tsx
+++ b/x-pack/plugins/apm/public/components/app/error_group_details/detail_view/exception_stacktrace.tsx
@@ -8,8 +8,8 @@
import { EuiTitle } from '@elastic/eui';
import React from 'react';
import { Exception } from '../../../../../typings/es_schemas/raw/error_raw';
-import { Stacktrace } from '../../../shared/Stacktrace';
-import { CauseStacktrace } from '../../../shared/Stacktrace/cause_stacktrace';
+import { Stacktrace } from '../../../shared/stacktrace';
+import { CauseStacktrace } from '../../../shared/stacktrace/cause_stacktrace';
interface ExceptionStacktraceProps {
codeLanguage?: string;
diff --git a/x-pack/plugins/apm/public/components/app/error_group_details/detail_view/index.tsx b/x-pack/plugins/apm/public/components/app/error_group_details/detail_view/index.tsx
index 5438fce7c4881..af7283af8c526 100644
--- a/x-pack/plugins/apm/public/components/app/error_group_details/detail_view/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/error_group_details/detail_view/index.tsx
@@ -23,15 +23,15 @@ import { euiStyled } from '../../../../../../../../src/plugins/kibana_react/comm
import type { APIReturnType } from '../../../../services/rest/createCallApmApi';
import type { APMError } from '../../../../../typings/es_schemas/ui/apm_error';
import type { ApmUrlParams } from '../../../../context/url_params_context/types';
-import { TransactionDetailLink } from '../../../shared/Links/apm/transaction_detail_link';
-import { DiscoverErrorLink } from '../../../shared/Links/DiscoverLinks/DiscoverErrorLink';
-import { fromQuery, toQuery } from '../../../shared/Links/url_helpers';
-import { ErrorMetadata } from '../../../shared/MetadataTable/ErrorMetadata';
-import { Stacktrace } from '../../../shared/Stacktrace';
-import { Summary } from '../../../shared/Summary';
-import { HttpInfoSummaryItem } from '../../../shared/Summary/http_info_summary_item';
-import { UserAgentSummaryItem } from '../../../shared/Summary/UserAgentSummaryItem';
-import { TimestampTooltip } from '../../../shared/TimestampTooltip';
+import { TransactionDetailLink } from '../../../shared/links/apm/transaction_detail_link';
+import { DiscoverErrorLink } from '../../../shared/links/discover_links/discover_error_link';
+import { fromQuery, toQuery } from '../../../shared/links/url_helpers';
+import { ErrorMetadata } from '../../../shared/metadata_table/error_metadata';
+import { Stacktrace } from '../../../shared/stacktrace';
+import { Summary } from '../../../shared/summary';
+import { HttpInfoSummaryItem } from '../../../shared/summary/http_info_summary_item';
+import { UserAgentSummaryItem } from '../../../shared/summary/user_agent_summary_item';
+import { TimestampTooltip } from '../../../shared/timestamp_tooltip';
import {
ErrorTab,
exceptionStacktraceTab,
diff --git a/x-pack/plugins/apm/public/components/app/error_group_overview/error_group_list/index.tsx b/x-pack/plugins/apm/public/components/app/error_group_overview/error_group_list/index.tsx
index e252eba15ade1..65681a398d8e6 100644
--- a/x-pack/plugins/apm/public/components/app/error_group_overview/error_group_list/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/error_group_overview/error_group_list/index.tsx
@@ -19,11 +19,11 @@ import { NOT_AVAILABLE_LABEL } from '../../../../../common/i18n';
import { useLegacyUrlParams } from '../../../../context/url_params_context/use_url_params';
import { APIReturnType } from '../../../../services/rest/createCallApmApi';
import { truncate, unit } from '../../../../utils/style';
-import { ErrorDetailLink } from '../../../shared/Links/apm/ErrorDetailLink';
-import { ErrorOverviewLink } from '../../../shared/Links/apm/ErrorOverviewLink';
-import { APMQueryParams } from '../../../shared/Links/url_helpers';
+import { ErrorDetailLink } from '../../../shared/links/apm/error_detail_link';
+import { ErrorOverviewLink } from '../../../shared/links/apm/error_overview_link';
+import { APMQueryParams } from '../../../shared/links/url_helpers';
import { ITableColumn, ManagedTable } from '../../../shared/managed_table';
-import { TimestampTooltip } from '../../../shared/TimestampTooltip';
+import { TimestampTooltip } from '../../../shared/timestamp_tooltip';
import { SparkPlot } from '../../../shared/charts/spark_plot';
const GroupIdLink = euiStyled(ErrorDetailLink)`
diff --git a/x-pack/plugins/apm/public/components/app/infra_overview/index.tsx b/x-pack/plugins/apm/public/components/app/infra_overview/index.tsx
new file mode 100644
index 0000000000000..c1360ba3b13ad
--- /dev/null
+++ b/x-pack/plugins/apm/public/components/app/infra_overview/index.tsx
@@ -0,0 +1,24 @@
+/*
+ * 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 { EuiEmptyPrompt, EuiLoadingLogo } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+import React from 'react';
+
+export function InfraOverview() {
+ return (
+ }
+ title={
+
+ {i18n.translate('xpack.apm.infra.announcement', {
+ defaultMessage: 'Infrastructure data coming soon',
+ })}
+
+ }
+ />
+ );
+}
diff --git a/x-pack/plugins/apm/public/components/app/Main/ScrollToTopOnPathChange.tsx b/x-pack/plugins/apm/public/components/app/main/ScrollToTopOnPathChange.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/Main/ScrollToTopOnPathChange.tsx
rename to x-pack/plugins/apm/public/components/app/main/ScrollToTopOnPathChange.tsx
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/ActionMenu/index.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/action_menu/index.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/ActionMenu/index.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/action_menu/index.tsx
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/ActionMenu/inpector_link.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/action_menu/inpector_link.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/ActionMenu/inpector_link.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/action_menu/inpector_link.tsx
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/Breakdowns/BreakdownFilter.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/breakdowns/breakdown_filter.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/Breakdowns/BreakdownFilter.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/breakdowns/breakdown_filter.tsx
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/ChartWrapper/index.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/chart_wrapper/index.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/ChartWrapper/index.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/chart_wrapper/index.tsx
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/Charts/PageLoadDistChart.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/charts/page_load_dist_chart.tsx
similarity index 93%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/Charts/PageLoadDistChart.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/charts/page_load_dist_chart.tsx
index 51349ff22a962..8b34ad8980774 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/Charts/PageLoadDistChart.tsx
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/charts/page_load_dist_chart.tsx
@@ -28,13 +28,13 @@ import {
EUI_CHARTS_THEME_LIGHT,
} from '@elastic/eui/dist/eui_charts_theme';
import styled from 'styled-components';
-import { PercentileAnnotations } from '../PageLoadDistribution/PercentileAnnotations';
+import { PercentileAnnotations } from '../page_load_distribution/percentile_annotations';
import { I18LABELS } from '../translations';
-import { ChartWrapper } from '../ChartWrapper';
-import { PercentileRange } from '../PageLoadDistribution';
+import { ChartWrapper } from '../chart_wrapper';
+import { PercentileRange } from '../page_load_distribution';
import { BreakdownItem } from '../../../../../typings/ui_filters';
import { useUiSetting$ } from '../../../../../../../../src/plugins/kibana_react/public';
-import { BreakdownSeries } from '../PageLoadDistribution/BreakdownSeries';
+import { BreakdownSeries } from '../page_load_distribution/breakdown_series';
interface PageLoadData {
pageLoadDistribution: Array<{ x: number; y: number }>;
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/Charts/PageViewsChart.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/charts/page_views_chart.tsx
similarity index 97%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/Charts/PageViewsChart.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/charts/page_views_chart.tsx
index e5ee427e16677..059feb0915fdb 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/Charts/PageViewsChart.tsx
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/charts/page_views_chart.tsx
@@ -29,8 +29,8 @@ import React from 'react';
import { useHistory } from 'react-router-dom';
import { useUiSetting$ } from '../../../../../../../../src/plugins/kibana_react/public';
import { useLegacyUrlParams } from '../../../../context/url_params_context/use_url_params';
-import { fromQuery, toQuery } from '../../../shared/Links/url_helpers';
-import { ChartWrapper } from '../ChartWrapper';
+import { fromQuery, toQuery } from '../../../shared/links/url_helpers';
+import { ChartWrapper } from '../chart_wrapper';
import { I18LABELS } from '../translations';
interface Props {
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/Charts/VisitorBreakdownChart.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/charts/visitor_breakdown_chart.tsx
similarity index 98%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/Charts/VisitorBreakdownChart.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/charts/visitor_breakdown_chart.tsx
index 149e9b8ee763a..89f49a9669b45 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/Charts/VisitorBreakdownChart.tsx
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/charts/visitor_breakdown_chart.tsx
@@ -22,7 +22,7 @@ import {
EUI_CHARTS_THEME_LIGHT,
} from '@elastic/eui/dist/eui_charts_theme';
import { useUiSetting$ } from '../../../../../../../../src/plugins/kibana_react/public';
-import { ChartWrapper } from '../ChartWrapper';
+import { ChartWrapper } from '../chart_wrapper';
import { I18LABELS } from '../translations';
const StyleChart = styled.div`
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/ClientMetrics/index.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/client_metrics/index.tsx
similarity index 91%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/ClientMetrics/index.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/client_metrics/index.tsx
index 7c48531d21990..a017d1b5304e3 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/ClientMetrics/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/client_metrics/index.tsx
@@ -14,9 +14,9 @@ import {
EuiSpacer,
} from '@elastic/eui';
import { I18LABELS } from '../translations';
-import { getPercentileLabel } from '../UXMetrics/translations';
+import { getPercentileLabel } from '../ux_metrics/translations';
import { useLegacyUrlParams } from '../../../../context/url_params_context/use_url_params';
-import { Metrics } from './Metrics';
+import { Metrics } from './metrics';
export function ClientMetrics() {
const {
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/ClientMetrics/Metrics.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/client_metrics/metrics.tsx
similarity index 95%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/ClientMetrics/Metrics.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/client_metrics/metrics.tsx
index ded242e2ce558..82dac9cc8f016 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/ClientMetrics/Metrics.tsx
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/client_metrics/metrics.tsx
@@ -18,9 +18,9 @@ import {
} from '@elastic/eui';
import { useFetcher } from '../../../../hooks/use_fetcher';
import { I18LABELS } from '../translations';
-import { useUxQuery } from '../hooks/useUxQuery';
-import { formatToSec } from '../UXMetrics/KeyUXMetrics';
-import { CsmSharedContext } from '../CsmSharedContext';
+import { useUxQuery } from '../hooks/use_ux_query';
+import { formatToSec } from '../ux_metrics/key_ux_metrics';
+import { CsmSharedContext } from '../csm_shared_context';
const ClFlexGroup = styled(EuiFlexGroup)`
flex-direction: row;
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/CsmSharedContext/index.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/csm_shared_context/index.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/CsmSharedContext/index.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/csm_shared_context/index.tsx
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/empty_state_loading.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/empty_state_loading.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/empty_state_loading.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/empty_state_loading.tsx
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/hooks/use_call_api.ts b/x-pack/plugins/apm/public/components/app/rum_dashboard/hooks/use_call_api.ts
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/hooks/use_call_api.ts
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/hooks/use_call_api.ts
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/hooks/useHasRumData.ts b/x-pack/plugins/apm/public/components/app/rum_dashboard/hooks/use_has_rum_data.ts
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/hooks/useHasRumData.ts
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/hooks/use_has_rum_data.ts
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/hooks/useLocalUIFilters.ts b/x-pack/plugins/apm/public/components/app/rum_dashboard/hooks/use_local_ui_filters.ts
similarity index 95%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/hooks/useLocalUIFilters.ts
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/hooks/use_local_ui_filters.ts
index 8045e4947dcb0..5c0bc7fdfd462 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/hooks/useLocalUIFilters.ts
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/hooks/use_local_ui_filters.ts
@@ -15,10 +15,10 @@ import {
import {
fromQuery,
toQuery,
-} from '../../../../components/shared/Links/url_helpers';
+} from '../../../../components/shared/links/url_helpers';
import { removeUndefinedProps } from '../../../../context/url_params_context/helpers';
import { useLegacyUrlParams } from '../../../../context/url_params_context/use_url_params';
-import { getExcludedName } from '../LocalUIFilters';
+import { getExcludedName } from '../local_ui_filters';
export type FiltersUIHook = ReturnType;
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/hooks/useUxQuery.ts b/x-pack/plugins/apm/public/components/app/rum_dashboard/hooks/use_ux_query.ts
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/hooks/useUxQuery.ts
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/hooks/use_ux_query.ts
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/ImpactfulMetrics/index.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/impactful_metrics/index.tsx
similarity index 94%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/ImpactfulMetrics/index.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/impactful_metrics/index.tsx
index b696a46f59bd1..640ab0b0daad2 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/ImpactfulMetrics/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/impactful_metrics/index.tsx
@@ -7,7 +7,7 @@
import React from 'react';
import { EuiFlexItem, EuiPanel, EuiFlexGroup, EuiSpacer } from '@elastic/eui';
-import { JSErrors } from './JSErrors';
+import { JSErrors } from './js_errors';
export function ImpactfulMetrics() {
return (
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/ImpactfulMetrics/JSErrors.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/impactful_metrics/js_errors.tsx
similarity index 96%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/ImpactfulMetrics/JSErrors.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/impactful_metrics/js_errors.tsx
index 96ec397f5f94f..9f7ad5d053fa4 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/ImpactfulMetrics/JSErrors.tsx
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/impactful_metrics/js_errors.tsx
@@ -21,8 +21,8 @@ import { FormattedMessage } from '@kbn/i18n-react';
import { useLegacyUrlParams } from '../../../../context/url_params_context/use_url_params';
import { FETCH_STATUS, useFetcher } from '../../../../hooks/use_fetcher';
import { I18LABELS } from '../translations';
-import { CsmSharedContext } from '../CsmSharedContext';
-import { ErrorDetailLink } from '../../../shared/Links/apm/ErrorDetailLink';
+import { CsmSharedContext } from '../csm_shared_context';
+import { ErrorDetailLink } from '../../../shared/links/apm/error_detail_link';
interface JSErrorItem {
errorMessage: string;
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/index.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/index.tsx
similarity index 86%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/index.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/index.tsx
index ee11c301441b6..d3eadeaf016c0 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/index.tsx
@@ -8,8 +8,8 @@
import { EuiSpacer } from '@elastic/eui';
import React from 'react';
import { useTrackPageview } from '../../../../../observability/public';
-import { LocalUIFilters } from './LocalUIFilters';
-import { RumDashboard } from './RumDashboard';
+import { LocalUIFilters } from './local_ui_filters';
+import { RumDashboard } from './rum_dashboard';
export function RumOverview() {
useTrackPageview({ app: 'ux', path: 'home' });
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/index.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/local_ui_filters/index.tsx
similarity index 96%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/index.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/local_ui_filters/index.tsx
index 655bf93e4fb93..1c54713125c7e 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/local_ui_filters/index.tsx
@@ -16,7 +16,7 @@ import {
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { ESFilter } from 'src/core/types/elasticsearch';
-import { useLocalUIFilters } from '../hooks/useLocalUIFilters';
+import { useLocalUIFilters } from '../hooks/use_local_ui_filters';
import {
uxFiltersByName,
UxLocalUIFilterName,
@@ -24,8 +24,8 @@ import {
} from '../../../../../common/ux_ui_filter';
import { useBreakpoints } from '../../../../hooks/use_breakpoints';
import { FieldValueSuggestions } from '../../../../../../observability/public';
-import { URLFilter } from '../URLFilter';
-import { SelectedFilters } from './SelectedFilters';
+import { URLFilter } from '../url_filter';
+import { SelectedFilters } from './selected_filters';
import {
SERVICE_NAME,
TRANSACTION_TYPE,
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/queries.ts b/x-pack/plugins/apm/public/components/app/rum_dashboard/local_ui_filters/queries.ts
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/queries.ts
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/local_ui_filters/queries.ts
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/SelectedFilters.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/local_ui_filters/selected_filters.tsx
similarity index 98%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/SelectedFilters.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/local_ui_filters/selected_filters.tsx
index d9f9154c5c100..787bcd88266e2 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/SelectedFilters.tsx
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/local_ui_filters/selected_filters.tsx
@@ -11,7 +11,7 @@ import { i18n } from '@kbn/i18n';
import styled from 'styled-components';
import { useLegacyUrlParams } from '../../../../context/url_params_context/use_url_params';
import { FilterValueLabel } from '../../../../../../observability/public';
-import { FiltersUIHook } from '../hooks/useLocalUIFilters';
+import { FiltersUIHook } from '../hooks/use_local_ui_filters';
import { UxLocalUIFilterName } from '../../../../../common/ux_ui_filter';
import { IndexPattern } from '../../../../../../../../src/plugins/data/common';
import { SelectedWildcards } from './selected_wildcards';
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/selected_wildcards.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/local_ui_filters/selected_wildcards.tsx
similarity index 96%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/selected_wildcards.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/local_ui_filters/selected_wildcards.tsx
index 6a9dfd1fddd11..d18381cee77af 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/selected_wildcards.tsx
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/local_ui_filters/selected_wildcards.tsx
@@ -10,7 +10,7 @@ import { useCallback } from 'react';
import { useHistory } from 'react-router-dom';
import { FilterValueLabel } from '../../../../../../observability/public';
import { useLegacyUrlParams } from '../../../../context/url_params_context/use_url_params';
-import { fromQuery, toQuery } from '../../../shared/Links/url_helpers';
+import { fromQuery, toQuery } from '../../../shared/links/url_helpers';
import { TRANSACTION_URL } from '../../../../../common/elasticsearch_fieldnames';
import { IndexPattern } from '../../../../../../../../src/plugins/data_views/common';
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/use_data_view.test.js b/x-pack/plugins/apm/public/components/app/rum_dashboard/local_ui_filters/use_data_view.test.js
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/use_data_view.test.js
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/local_ui_filters/use_data_view.test.js
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/use_data_view.ts b/x-pack/plugins/apm/public/components/app/rum_dashboard/local_ui_filters/use_data_view.ts
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/use_data_view.ts
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/local_ui_filters/use_data_view.ts
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/PageLoadDistribution/BreakdownSeries.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/page_load_distribution/breakdown_series.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/PageLoadDistribution/BreakdownSeries.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/page_load_distribution/breakdown_series.tsx
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/PageLoadDistribution/index.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/page_load_distribution/index.tsx
similarity index 95%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/PageLoadDistribution/index.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/page_load_distribution/index.tsx
index 0daf620dc5009..e8e24c121ea6d 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/PageLoadDistribution/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/page_load_distribution/index.tsx
@@ -17,10 +17,10 @@ import { FormattedMessage } from '@kbn/i18n-react';
import { useLegacyUrlParams } from '../../../../context/url_params_context/use_url_params';
import { useFetcher } from '../../../../hooks/use_fetcher';
import { I18LABELS } from '../translations';
-import { BreakdownFilter } from '../Breakdowns/BreakdownFilter';
-import { PageLoadDistChart } from '../Charts/PageLoadDistChart';
+import { BreakdownFilter } from '../breakdowns/breakdown_filter';
+import { PageLoadDistChart } from '../charts/page_load_dist_chart';
import { BreakdownItem } from '../../../../../typings/ui_filters';
-import { ResetPercentileZoom } from './ResetPercentileZoom';
+import { ResetPercentileZoom } from './reset_percentile_zoom';
import { createExploratoryViewUrl } from '../../../../../../observability/public';
import { useKibana } from '../../../../../../../../src/plugins/kibana_react/public';
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/PageLoadDistribution/PercentileAnnotations.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/page_load_distribution/percentile_annotations.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/PageLoadDistribution/PercentileAnnotations.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/page_load_distribution/percentile_annotations.tsx
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/PageLoadDistribution/ResetPercentileZoom.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/page_load_distribution/reset_percentile_zoom.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/PageLoadDistribution/ResetPercentileZoom.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/page_load_distribution/reset_percentile_zoom.tsx
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/PageLoadDistribution/use_breakdowns.ts b/x-pack/plugins/apm/public/components/app/rum_dashboard/page_load_distribution/use_breakdowns.ts
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/PageLoadDistribution/use_breakdowns.ts
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/page_load_distribution/use_breakdowns.ts
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/PageViewsTrend/index.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/page_views_trend/index.tsx
similarity index 96%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/PageViewsTrend/index.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/page_views_trend/index.tsx
index a334c1e23892a..2510420d3eac4 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/PageViewsTrend/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/page_views_trend/index.tsx
@@ -17,8 +17,8 @@ import { FormattedMessage } from '@kbn/i18n-react';
import { useLegacyUrlParams } from '../../../../context/url_params_context/use_url_params';
import { useFetcher } from '../../../../hooks/use_fetcher';
import { I18LABELS } from '../translations';
-import { BreakdownFilter } from '../Breakdowns/BreakdownFilter';
-import { PageViewsChart } from '../Charts/PageViewsChart';
+import { BreakdownFilter } from '../breakdowns/breakdown_filter';
+import { PageViewsChart } from '../charts/page_views_chart';
import { BreakdownItem } from '../../../../../typings/ui_filters';
import { createExploratoryViewUrl } from '../../../../../../observability/public';
import { useKibana } from '../../../../../../../../src/plugins/kibana_react/public';
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/Panels/PageLoadAndViews.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/panels/page_load_and_views.tsx
similarity index 86%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/Panels/PageLoadAndViews.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/panels/page_load_and_views.tsx
index 9dd83fd1c8fd1..1d6a65317122c 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/Panels/PageLoadAndViews.tsx
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/panels/page_load_and_views.tsx
@@ -7,8 +7,8 @@
import React from 'react';
import { EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui';
-import { PageLoadDistribution } from '../PageLoadDistribution';
-import { PageViewsTrend } from '../PageViewsTrend';
+import { PageLoadDistribution } from '../page_load_distribution';
+import { PageViewsTrend } from '../page_views_trend';
export function PageLoadAndViews() {
return (
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/Panels/VisitorBreakdowns.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/panels/visitor_breakdowns.tsx
similarity index 86%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/Panels/VisitorBreakdowns.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/panels/visitor_breakdowns.tsx
index ff79feaa924f3..04127ec702262 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/Panels/VisitorBreakdowns.tsx
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/panels/visitor_breakdowns.tsx
@@ -7,8 +7,8 @@
import React from 'react';
import { EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui';
-import { VisitorBreakdown } from '../VisitorBreakdown';
-import { VisitorBreakdownMap } from '../VisitorBreakdownMap';
+import { VisitorBreakdown } from '../visitor_breakdown';
+import { VisitorBreakdownMap } from '../visitor_breakdown_map';
export function VisitorBreakdownsPanel() {
return (
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/Panels/WebApplicationSelect.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/panels/web_application_select.tsx
similarity index 94%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/Panels/WebApplicationSelect.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/panels/web_application_select.tsx
index ecba89b2651ac..9c5494c1ea533 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/Panels/WebApplicationSelect.tsx
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/panels/web_application_select.tsx
@@ -6,7 +6,7 @@
*/
import React from 'react';
-import { ServiceNameFilter } from '../URLFilter/ServiceNameFilter';
+import { ServiceNameFilter } from '../url_filter/service_name_filter';
import { useFetcher } from '../../../../hooks/use_fetcher';
import { RUM_AGENT_NAMES } from '../../../../../common/agent_name';
import { useLegacyUrlParams } from '../../../../context/url_params_context/use_url_params';
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/RumDashboard.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/rum_dashboard.tsx
similarity index 76%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/RumDashboard.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/rum_dashboard.tsx
index 4ed011441c81b..d6b454bd948f7 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/RumDashboard.tsx
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/rum_dashboard.tsx
@@ -7,12 +7,12 @@
import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import React from 'react';
-import { UXMetrics } from './UXMetrics';
-import { ImpactfulMetrics } from './ImpactfulMetrics';
-import { PageLoadAndViews } from './Panels/PageLoadAndViews';
-import { VisitorBreakdownsPanel } from './Panels/VisitorBreakdowns';
+import { UXMetrics } from './ux_metrics';
+import { ImpactfulMetrics } from './impactful_metrics';
+import { PageLoadAndViews } from './panels/page_load_and_views';
+import { VisitorBreakdownsPanel } from './panels/visitor_breakdowns';
import { useBreakpoints } from '../../../hooks/use_breakpoints';
-import { ClientMetrics } from './ClientMetrics';
+import { ClientMetrics } from './client_metrics';
export function RumDashboard() {
const { isSmall } = useBreakpoints();
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/rum_datepicker/index.test.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/rum_datepicker/index.test.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/rum_datepicker/index.test.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/rum_datepicker/index.test.tsx
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/rum_datepicker/index.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/rum_datepicker/index.tsx
similarity index 94%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/rum_datepicker/index.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/rum_datepicker/index.tsx
index 9bc18d772a4a1..4e39ad4397b41 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/rum_datepicker/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/rum_datepicker/index.tsx
@@ -7,7 +7,7 @@
import React from 'react';
import { useUxUrlParams } from '../../../../context/url_params_context/use_ux_url_params';
import { useDateRangeRedirect } from '../../../../hooks/use_date_range_redirect';
-import { DatePicker } from '../../../shared/DatePicker';
+import { DatePicker } from '../../../shared/date_picker';
export function RumDatePicker() {
const {
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/RumHome.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/rum_home.tsx
similarity index 90%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/RumHome.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/rum_home.tsx
index 54c34121ea0cb..bb0427d462d54 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/RumHome.tsx
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/rum_home.tsx
@@ -8,15 +8,15 @@
import React, { Fragment } from 'react';
import { i18n } from '@kbn/i18n';
import { EuiFlexGroup, EuiTitle, EuiFlexItem } from '@elastic/eui';
-import { RumOverview } from '../RumDashboard';
-import { CsmSharedContextProvider } from './CsmSharedContext';
-import { WebApplicationSelect } from './Panels/WebApplicationSelect';
+import { RumOverview } from '../rum_dashboard';
+import { CsmSharedContextProvider } from './csm_shared_context';
+import { WebApplicationSelect } from './panels/web_application_select';
import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_context';
-import { UxEnvironmentFilter } from '../../shared/EnvironmentFilter';
-import { UserPercentile } from './UserPercentile';
+import { UxEnvironmentFilter } from '../../shared/environment_filter';
+import { UserPercentile } from './user_percentile';
import { useBreakpoints } from '../../../hooks/use_breakpoints';
import { KibanaPageTemplateProps } from '../../../../../../../src/plugins/kibana_react/public';
-import { useHasRumData } from './hooks/useHasRumData';
+import { useHasRumData } from './hooks/use_has_rum_data';
import { RumDatePicker } from './rum_datepicker';
import { EmptyStateLoading } from './empty_state_loading';
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/translations.ts b/x-pack/plugins/apm/public/components/app/rum_dashboard/translations.ts
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/translations.ts
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/translations.ts
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/URLFilter/index.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/url_filter/index.tsx
similarity index 94%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/URLFilter/index.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/url_filter/index.tsx
index cac899665d98b..558092db4a458 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/URLFilter/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/url_filter/index.tsx
@@ -8,8 +8,8 @@
import React, { useCallback } from 'react';
import { useHistory } from 'react-router-dom';
import { omit } from 'lodash';
-import { URLSearch } from './URLSearch';
-import { fromQuery, toQuery } from '../../../shared/Links/url_helpers';
+import { URLSearch } from './url_search';
+import { fromQuery, toQuery } from '../../../shared/links/url_helpers';
import { removeUndefinedProps } from '../../../../context/url_params_context/helpers';
export function URLFilter() {
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/URLFilter/ServiceNameFilter/index.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/url_filter/service_name_filter/index.tsx
similarity index 97%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/URLFilter/ServiceNameFilter/index.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/url_filter/service_name_filter/index.tsx
index f6891a5d8fb67..b3560f0ebc97b 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/URLFilter/ServiceNameFilter/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/url_filter/service_name_filter/index.tsx
@@ -10,7 +10,7 @@ import { i18n } from '@kbn/i18n';
import React, { useEffect, useCallback } from 'react';
import { useHistory } from 'react-router-dom';
import { useLegacyUrlParams } from '../../../../../context/url_params_context/use_url_params';
-import { fromQuery, toQuery } from '../../../../shared/Links/url_helpers';
+import { fromQuery, toQuery } from '../../../../shared/links/url_helpers';
interface Props {
serviceNames: string[];
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/URLFilter/URLSearch/index.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/url_filter/url_search/index.tsx
similarity index 97%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/URLFilter/URLSearch/index.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/url_filter/url_search/index.tsx
index e34270f963599..9ecb2f31112ea 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/URLFilter/URLSearch/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/url_filter/url_search/index.tsx
@@ -10,8 +10,8 @@ import { isEqual, map } from 'lodash';
import { i18n } from '@kbn/i18n';
import { useLegacyUrlParams } from '../../../../../context/url_params_context/use_url_params';
import { I18LABELS } from '../../translations';
-import { formatToSec } from '../../UXMetrics/KeyUXMetrics';
-import { getPercentileLabel } from '../../UXMetrics/translations';
+import { formatToSec } from '../../ux_metrics/key_ux_metrics';
+import { getPercentileLabel } from '../../ux_metrics/translations';
import { SelectableUrlList } from '../../../../../../../observability/public';
import { selectableRenderOptions, UrlOption } from './render_option';
import { useUrlSearch } from './use_url_search';
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/URLFilter/URLSearch/render_option.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/url_filter/url_search/render_option.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/URLFilter/URLSearch/render_option.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/url_filter/url_search/render_option.tsx
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/URLFilter/URLSearch/use_url_search.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/url_filter/url_search/use_url_search.tsx
similarity index 96%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/URLFilter/URLSearch/use_url_search.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/url_filter/url_search/use_url_search.tsx
index 8228ab4c6e83e..e7a025985fca7 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/URLFilter/URLSearch/use_url_search.tsx
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/url_filter/url_search/use_url_search.tsx
@@ -8,7 +8,7 @@
import useDebounce from 'react-use/lib/useDebounce';
import { useState } from 'react';
import { useFetcher } from '../../../../../hooks/use_fetcher';
-import { useUxQuery } from '../../hooks/useUxQuery';
+import { useUxQuery } from '../../hooks/use_ux_query';
import { useLegacyUrlParams } from '../../../../../context/url_params_context/use_url_params';
interface Props {
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/UserPercentile/index.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/user_percentile/index.tsx
similarity index 97%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/UserPercentile/index.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/user_percentile/index.tsx
index 7d05b188e9bbe..a1e70f4f25d21 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/UserPercentile/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/user_percentile/index.tsx
@@ -10,7 +10,7 @@ import React, { useCallback, useEffect } from 'react';
import { EuiSelect } from '@elastic/eui';
import { useHistory } from 'react-router-dom';
import { useLegacyUrlParams } from '../../../../context/url_params_context/use_url_params';
-import { fromQuery, toQuery } from '../../../shared/Links/url_helpers';
+import { fromQuery, toQuery } from '../../../shared/links/url_helpers';
import { I18LABELS } from '../translations';
const DEFAULT_P = 50;
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/utils/test_helper.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/utils/test_helper.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/utils/test_helper.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/utils/test_helper.tsx
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/FormatToSec.test.ts b/x-pack/plugins/apm/public/components/app/rum_dashboard/ux_metrics/format_to_sec.test.ts
similarity index 94%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/FormatToSec.test.ts
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/ux_metrics/format_to_sec.test.ts
index ca29bb4ce2944..3bb1e8bd923f1 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/FormatToSec.test.ts
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/ux_metrics/format_to_sec.test.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import { formatToSec } from './KeyUXMetrics';
+import { formatToSec } from './key_ux_metrics';
describe('FormatToSec', () => {
test('it returns the expected value', () => {
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/index.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/ux_metrics/index.tsx
similarity index 93%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/index.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/ux_metrics/index.tsx
index ab6843f94ee43..cc1223de7b177 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/ux_metrics/index.tsx
@@ -15,11 +15,11 @@ import {
EuiTitle,
} from '@elastic/eui';
import { I18LABELS } from '../translations';
-import { KeyUXMetrics } from './KeyUXMetrics';
+import { KeyUXMetrics } from './key_ux_metrics';
import { useFetcher } from '../../../../hooks/use_fetcher';
-import { useUxQuery } from '../hooks/useUxQuery';
+import { useUxQuery } from '../hooks/use_ux_query';
import { getCoreVitalsComponent } from '../../../../../../observability/public';
-import { CsmSharedContext } from '../CsmSharedContext';
+import { CsmSharedContext } from '../csm_shared_context';
import { useLegacyUrlParams } from '../../../../context/url_params_context/use_url_params';
import { getPercentileLabel } from './translations';
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/KeyUXMetrics.test.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/ux_metrics/key_ux_metrics.test.tsx
similarity index 97%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/KeyUXMetrics.test.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/ux_metrics/key_ux_metrics.test.tsx
index e1253b41a45f5..2f92e5efedf42 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/KeyUXMetrics.test.tsx
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/ux_metrics/key_ux_metrics.test.tsx
@@ -8,7 +8,7 @@
import React from 'react';
import { render } from '@testing-library/react';
import * as fetcherHook from '../../../../hooks/use_fetcher';
-import { KeyUXMetrics } from './KeyUXMetrics';
+import { KeyUXMetrics } from './key_ux_metrics';
describe('KeyUXMetrics', () => {
it('renders metrics with correct formats', () => {
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/KeyUXMetrics.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/ux_metrics/key_ux_metrics.tsx
similarity index 98%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/KeyUXMetrics.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/ux_metrics/key_ux_metrics.tsx
index 4eaf0dccc3225..3e1c64c484edb 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/KeyUXMetrics.tsx
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/ux_metrics/key_ux_metrics.tsx
@@ -22,7 +22,7 @@ import {
TBT_TOOLTIP,
} from './translations';
import { useFetcher } from '../../../../hooks/use_fetcher';
-import { useUxQuery } from '../hooks/useUxQuery';
+import { useUxQuery } from '../hooks/use_ux_query';
import { UXMetrics } from '../../../../../../observability/public';
export function formatToSec(
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/translations.ts b/x-pack/plugins/apm/public/components/app/rum_dashboard/ux_metrics/translations.ts
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/translations.ts
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/ux_metrics/translations.ts
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/ux_overview_fetchers.ts b/x-pack/plugins/apm/public/components/app/rum_dashboard/ux_overview_fetchers.ts
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/ux_overview_fetchers.ts
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/ux_overview_fetchers.ts
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdown/index.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/visitor_breakdown/index.tsx
similarity index 96%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdown/index.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/visitor_breakdown/index.tsx
index 7a19690a4582e..822cb0f591bce 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdown/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/visitor_breakdown/index.tsx
@@ -7,7 +7,7 @@
import React from 'react';
import { EuiFlexGroup, EuiFlexItem, EuiTitle, EuiSpacer } from '@elastic/eui';
-import { VisitorBreakdownChart } from '../Charts/VisitorBreakdownChart';
+import { VisitorBreakdownChart } from '../charts/visitor_breakdown_chart';
import { I18LABELS, VisitorBreakdownLabel } from '../translations';
import { useFetcher } from '../../../../hooks/use_fetcher';
import { useLegacyUrlParams } from '../../../../context/url_params_context/use_url_params';
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdownMap/__mocks__/regions_layer.mock.ts b/x-pack/plugins/apm/public/components/app/rum_dashboard/visitor_breakdown_map/__mocks__/regions_layer.mock.ts
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdownMap/__mocks__/regions_layer.mock.ts
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/visitor_breakdown_map/__mocks__/regions_layer.mock.ts
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdownMap/__snapshots__/EmbeddedMap.test.tsx.snap b/x-pack/plugins/apm/public/components/app/rum_dashboard/visitor_breakdown_map/__snapshots__/embedded_map.test.tsx.snap
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdownMap/__snapshots__/EmbeddedMap.test.tsx.snap
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/visitor_breakdown_map/__snapshots__/embedded_map.test.tsx.snap
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdownMap/__snapshots__/MapToolTip.test.tsx.snap b/x-pack/plugins/apm/public/components/app/rum_dashboard/visitor_breakdown_map/__snapshots__/map_tooltip.test.tsx.snap
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdownMap/__snapshots__/MapToolTip.test.tsx.snap
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/visitor_breakdown_map/__snapshots__/map_tooltip.test.tsx.snap
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdownMap/__stories__/MapTooltip.stories.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/visitor_breakdown_map/__stories__/MapTooltip.stories.tsx
similarity index 92%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdownMap/__stories__/MapTooltip.stories.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/visitor_breakdown_map/__stories__/MapTooltip.stories.tsx
index 8263db648cd39..da4aad4102195 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdownMap/__stories__/MapTooltip.stories.tsx
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/visitor_breakdown_map/__stories__/MapTooltip.stories.tsx
@@ -7,10 +7,10 @@
import { storiesOf } from '@storybook/react';
import React from 'react';
-import { MapToolTip } from '../MapToolTip';
-import { COUNTRY_NAME, TRANSACTION_DURATION_COUNTRY } from '../useLayerList';
+import { MapToolTip } from '../map_tooltip';
+import { COUNTRY_NAME, TRANSACTION_DURATION_COUNTRY } from '../use_layer_list';
-storiesOf('app/RumDashboard/VisitorsRegionMap', module).add(
+storiesOf('app/rum_dashboard/VisitorsRegionMap', module).add(
'Tooltip',
() => {
const loadFeatureProps = async () => {
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdownMap/EmbeddedMap.test.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/visitor_breakdown_map/embedded_map.test.tsx
similarity index 96%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdownMap/EmbeddedMap.test.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/visitor_breakdown_map/embedded_map.test.tsx
index f286f963b4fa0..572661dc8cea4 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdownMap/EmbeddedMap.test.tsx
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/visitor_breakdown_map/embedded_map.test.tsx
@@ -8,7 +8,7 @@
import { render } from 'enzyme';
import React from 'react';
-import { EmbeddedMap } from './EmbeddedMap';
+import { EmbeddedMap } from './embedded_map';
import { KibanaContextProvider } from '../../../../../../../../src/plugins/kibana_react/public';
import { embeddablePluginMock } from '../../../../../../../../src/plugins/embeddable/public/mocks';
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdownMap/EmbeddedMap.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/visitor_breakdown_map/embedded_map.tsx
similarity index 97%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdownMap/EmbeddedMap.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/visitor_breakdown_map/embedded_map.tsx
index 17a380f4d5e35..32dcf3d5d3439 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdownMap/EmbeddedMap.tsx
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/visitor_breakdown_map/embedded_map.tsx
@@ -20,12 +20,12 @@ import {
ViewMode,
isErrorEmbeddable,
} from '../../../../../../../../src/plugins/embeddable/public';
-import { useLayerList } from './useLayerList';
+import { useLayerList } from './use_layer_list';
import { useLegacyUrlParams } from '../../../../context/url_params_context/use_url_params';
import { useApmPluginContext } from '../../../../context/apm_plugin/use_apm_plugin_context';
import type { RenderTooltipContentParams } from '../../../../../../maps/public';
-import { MapToolTip } from './MapToolTip';
-import { useMapFilters } from './useMapFilters';
+import { MapToolTip } from './map_tooltip';
+import { useMapFilters } from './use_map_filters';
import { EmbeddableStart } from '../../../../../../../../src/plugins/embeddable/public';
const EmbeddedPanel = styled.div`
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdownMap/index.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/visitor_breakdown_map/index.tsx
similarity index 93%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdownMap/index.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/visitor_breakdown_map/index.tsx
index 142337ef3e160..253f989b389a8 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdownMap/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/visitor_breakdown_map/index.tsx
@@ -7,7 +7,7 @@
import React from 'react';
import { EuiTitle, EuiSpacer } from '@elastic/eui';
-import { EmbeddedMap } from './EmbeddedMap';
+import { EmbeddedMap } from './embedded_map';
import { I18LABELS } from '../translations';
export function VisitorBreakdownMap() {
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdownMap/MapToolTip.test.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/visitor_breakdown_map/map_tooltip.test.tsx
similarity index 93%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdownMap/MapToolTip.test.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/visitor_breakdown_map/map_tooltip.test.tsx
index be3b28f07cdaf..6d59b15876d20 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdownMap/MapToolTip.test.tsx
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/visitor_breakdown_map/map_tooltip.test.tsx
@@ -8,7 +8,7 @@
import { render, shallow } from 'enzyme';
import React from 'react';
-import { MapToolTip } from './MapToolTip';
+import { MapToolTip } from './map_tooltip';
describe('Map Tooltip', () => {
test('it shallow renders', () => {
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdownMap/MapToolTip.tsx b/x-pack/plugins/apm/public/components/app/rum_dashboard/visitor_breakdown_map/map_tooltip.tsx
similarity index 99%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdownMap/MapToolTip.tsx
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/visitor_breakdown_map/map_tooltip.tsx
index e923795fad95f..56f1ae2014473 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdownMap/MapToolTip.tsx
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/visitor_breakdown_map/map_tooltip.tsx
@@ -19,7 +19,7 @@ import {
REGION_NAME,
TRANSACTION_DURATION_COUNTRY,
TRANSACTION_DURATION_REGION,
-} from './useLayerList';
+} from './use_layer_list';
import type { RenderTooltipContentParams } from '../../../../../../maps/public';
import { I18LABELS } from '../translations';
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdownMap/useLayerList.test.ts b/x-pack/plugins/apm/public/components/app/rum_dashboard/visitor_breakdown_map/use_layer_list.test.ts
similarity index 92%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdownMap/useLayerList.test.ts
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/visitor_breakdown_map/use_layer_list.test.ts
index 254d15f025c1b..7c0cbf694aed7 100644
--- a/x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdownMap/useLayerList.test.ts
+++ b/x-pack/plugins/apm/public/components/app/rum_dashboard/visitor_breakdown_map/use_layer_list.test.ts
@@ -7,7 +7,7 @@
import { renderHook } from '@testing-library/react-hooks';
import { mockLayerList } from './__mocks__/regions_layer.mock';
-import { useLayerList } from './useLayerList';
+import { useLayerList } from './use_layer_list';
describe('useLayerList', () => {
test('it returns the region layer', () => {
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdownMap/useLayerList.ts b/x-pack/plugins/apm/public/components/app/rum_dashboard/visitor_breakdown_map/use_layer_list.ts
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdownMap/useLayerList.ts
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/visitor_breakdown_map/use_layer_list.ts
diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdownMap/useMapFilters.ts b/x-pack/plugins/apm/public/components/app/rum_dashboard/visitor_breakdown_map/use_map_filters.ts
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/RumDashboard/VisitorBreakdownMap/useMapFilters.ts
rename to x-pack/plugins/apm/public/components/app/rum_dashboard/visitor_breakdown_map/use_map_filters.ts
diff --git a/x-pack/plugins/apm/public/components/app/service_inventory/index.tsx b/x-pack/plugins/apm/public/components/app/service_inventory/index.tsx
index 163082cf044cd..549ccc8e69259 100644
--- a/x-pack/plugins/apm/public/components/app/service_inventory/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/service_inventory/index.tsx
@@ -22,7 +22,7 @@ import { useLocalStorage } from '../../../hooks/useLocalStorage';
import { useAnyOfApmParams } from '../../../hooks/use_apm_params';
import { FETCH_STATUS, useFetcher } from '../../../hooks/use_fetcher';
import { useTimeRange } from '../../../hooks/use_time_range';
-import { useUpgradeAssistantHref } from '../../shared/Links/kibana';
+import { useUpgradeAssistantHref } from '../../shared/links/kibana';
import { SearchBar } from '../../shared/search_bar';
import { getTimeRangeComparison } from '../../shared/time_comparison/get_time_range_comparison';
import { ServiceList } from './service_list';
diff --git a/x-pack/plugins/apm/public/components/app/service_inventory/service_list/index.tsx b/x-pack/plugins/apm/public/components/app/service_inventory/service_list/index.tsx
index fe91b14e64e8a..2d83f1f46bd38 100644
--- a/x-pack/plugins/apm/public/components/app/service_inventory/service_list/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/service_inventory/service_list/index.tsx
@@ -36,7 +36,7 @@ import { APIReturnType } from '../../../../services/rest/createCallApmApi';
import { unit } from '../../../../utils/style';
import { ApmRoutes } from '../../../routing/apm_route_config';
import { AggregatedTransactionsBadge } from '../../../shared/aggregated_transactions_badge';
-import { EnvironmentBadge } from '../../../shared/EnvironmentBadge';
+import { EnvironmentBadge } from '../../../shared/environment_badge';
import { ListMetric } from '../../../shared/list_metric';
import { ITableColumn, ManagedTable } from '../../../shared/managed_table';
import { ServiceLink } from '../../../shared/service_link';
diff --git a/x-pack/plugins/apm/public/components/app/service_map/Controls.tsx b/x-pack/plugins/apm/public/components/app/service_map/Controls.tsx
index a48fb77b45585..9236d9c21a6c6 100644
--- a/x-pack/plugins/apm/public/components/app/service_map/Controls.tsx
+++ b/x-pack/plugins/apm/public/components/app/service_map/Controls.tsx
@@ -11,9 +11,9 @@ import React, { useContext, useEffect, useState } from 'react';
import { euiStyled } from '../../../../../../../src/plugins/kibana_react/common';
import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_context';
import { useTheme } from '../../../hooks/use_theme';
-import { getLegacyApmHref } from '../../shared/Links/apm/APMLink';
+import { getLegacyApmHref } from '../../shared/links/apm/apm_link';
import { useLegacyUrlParams } from '../../../context/url_params_context/use_url_params';
-import { APMQueryParams } from '../../shared/Links/url_helpers';
+import { APMQueryParams } from '../../shared/links/url_helpers';
import { CytoscapeContext } from './Cytoscape';
import { getAnimationOptions, getNodeHeight } from './cytoscape_options';
import { useAnyOfApmParams } from '../../../hooks/use_apm_params';
diff --git a/x-pack/plugins/apm/public/components/app/service_map/Popover/anomaly_detection.tsx b/x-pack/plugins/apm/public/components/app/service_map/Popover/anomaly_detection.tsx
index 1ceb90ff838ad..dd728be30c71a 100644
--- a/x-pack/plugins/apm/public/components/app/service_map/Popover/anomaly_detection.tsx
+++ b/x-pack/plugins/apm/public/components/app/service_map/Popover/anomaly_detection.tsx
@@ -26,7 +26,7 @@ import {
import { TRANSACTION_REQUEST } from '../../../../../common/transaction_types';
import { asDuration, asInteger } from '../../../../../common/utils/formatters';
import { useTheme } from '../../../../hooks/use_theme';
-import { MLSingleMetricLink } from '../../../shared/Links/MachineLearningLinks/MLSingleMetricLink';
+import { MLSingleMetricLink } from '../../../shared/links/machine_learning_links/mlsingle_metric_link';
import { popoverWidth } from '../cytoscape_options';
const HealthStatusTitle = euiStyled(EuiTitle)`
diff --git a/x-pack/plugins/apm/public/components/app/service_map/empty_prompt.tsx b/x-pack/plugins/apm/public/components/app/service_map/empty_prompt.tsx
index 6c7a8718dee58..ce9dbe7ce417f 100644
--- a/x-pack/plugins/apm/public/components/app/service_map/empty_prompt.tsx
+++ b/x-pack/plugins/apm/public/components/app/service_map/empty_prompt.tsx
@@ -8,7 +8,7 @@
import { EuiEmptyPrompt } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
-import { SetupInstructionsLink } from '../../shared/Links/SetupInstructionsLink';
+import { SetupInstructionsLink } from '../../shared/links/setup_instructions_link';
export function EmptyPrompt() {
return (
diff --git a/x-pack/plugins/apm/public/components/app/service_node_overview/index.tsx b/x-pack/plugins/apm/public/components/app/service_node_overview/index.tsx
index 04bb578b0c434..0436c27cdd6b7 100644
--- a/x-pack/plugins/apm/public/components/app/service_node_overview/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/service_node_overview/index.tsx
@@ -22,7 +22,7 @@ import { useApmParams } from '../../../hooks/use_apm_params';
import { useFetcher, FETCH_STATUS } from '../../../hooks/use_fetcher';
import { useTimeRange } from '../../../hooks/use_time_range';
import { truncate, unit } from '../../../utils/style';
-import { ServiceNodeMetricOverviewLink } from '../../shared/Links/apm/ServiceNodeMetricOverviewLink';
+import { ServiceNodeMetricOverviewLink } from '../../shared/links/apm/service_node_metric_overview_link';
import { ITableColumn, ManagedTable } from '../../shared/managed_table';
const INITIAL_PAGE_SIZE = 25;
diff --git a/x-pack/plugins/apm/public/components/app/service_overview/index.tsx b/x-pack/plugins/apm/public/components/app/service_overview/index.tsx
index 6f3b5c71af810..9e5508a5810df 100644
--- a/x-pack/plugins/apm/public/components/app/service_overview/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/service_overview/index.tsx
@@ -26,7 +26,7 @@ import { useApmParams } from '../../../hooks/use_apm_params';
import { AggregatedTransactionsBadge } from '../../shared/aggregated_transactions_badge';
import { useApmRouter } from '../../../hooks/use_apm_router';
import { useTimeRange } from '../../../hooks/use_time_range';
-import { replace } from '../../shared/Links/url_helpers';
+import { replace } from '../../shared/links/url_helpers';
/**
* The height a chart should be if it's next to a table with 5 rows and a title.
diff --git a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/get_columns.tsx b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/get_columns.tsx
index aba1073bfe9c2..fea48dee5d6c0 100644
--- a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/get_columns.tsx
+++ b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/get_columns.tsx
@@ -11,8 +11,8 @@ import React from 'react';
import { asInteger } from '../../../../../common/utils/formatters';
import { APIReturnType } from '../../../../services/rest/createCallApmApi';
import { SparkPlot } from '../../../shared/charts/spark_plot';
-import { ErrorDetailLink } from '../../../shared/Links/apm/ErrorDetailLink';
-import { TimestampTooltip } from '../../../shared/TimestampTooltip';
+import { ErrorDetailLink } from '../../../shared/links/apm/error_detail_link';
+import { TimestampTooltip } from '../../../shared/timestamp_tooltip';
import { TruncateWithTooltip } from '../../../shared/truncate_with_tooltip';
type ErrorGroupMainStatistics =
diff --git a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/index.tsx b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/index.tsx
index 28824b3b8a399..d9658f9d5e047 100644
--- a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/index.tsx
@@ -19,7 +19,7 @@ import { useApmServiceContext } from '../../../../context/apm_service/use_apm_se
import { useLegacyUrlParams } from '../../../../context/url_params_context/use_url_params';
import { FETCH_STATUS, useFetcher } from '../../../../hooks/use_fetcher';
import { APIReturnType } from '../../../../services/rest/createCallApmApi';
-import { ErrorOverviewLink } from '../../../shared/Links/apm/ErrorOverviewLink';
+import { ErrorOverviewLink } from '../../../shared/links/apm/error_overview_link';
import { getTimeRangeComparison } from '../../../shared/time_comparison/get_time_range_comparison';
import { OverviewTableContainer } from '../../../shared/overview_table_container';
import { getColumns } from './get_columns';
diff --git a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_table/get_columns.tsx b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_table/get_columns.tsx
index 853ea37112ad8..ae543adf2b852 100644
--- a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_table/get_columns.tsx
+++ b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_table/get_columns.tsx
@@ -25,8 +25,8 @@ import {
asTransactionRate,
} from '../../../../../common/utils/formatters';
import { APIReturnType } from '../../../../services/rest/createCallApmApi';
-import { MetricOverviewLink } from '../../../shared/Links/apm/MetricOverviewLink';
-import { ServiceNodeMetricOverviewLink } from '../../../shared/Links/apm/ServiceNodeMetricOverviewLink';
+import { MetricOverviewLink } from '../../../shared/links/apm/metric_overview_link';
+import { ServiceNodeMetricOverviewLink } from '../../../shared/links/apm/service_node_metric_overview_link';
import { ListMetric } from '../../../shared/list_metric';
import { getLatencyColumnLabel } from '../../../shared/transactions_table/get_latency_column_label';
import { TruncateWithTooltip } from '../../../shared/truncate_with_tooltip';
diff --git a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_table/instance_actions_menu/index.tsx b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_table/instance_actions_menu/index.tsx
index e5e460e3b2812..932f2f5d215e7 100644
--- a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_table/instance_actions_menu/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_table/instance_actions_menu/index.tsx
@@ -20,8 +20,8 @@ import { SERVICE_NODE_NAME } from '../../../../../../common/elasticsearch_fieldn
import { useApmPluginContext } from '../../../../../context/apm_plugin/use_apm_plugin_context';
import { FETCH_STATUS } from '../../../../../hooks/use_fetcher';
import { pushNewItemToKueryBar } from '../../../../shared/kuery_bar/utils';
-import { useMetricOverviewHref } from '../../../../shared/Links/apm/MetricOverviewLink';
-import { useServiceNodeMetricOverviewHref } from '../../../../shared/Links/apm/ServiceNodeMetricOverviewLink';
+import { useMetricOverviewHref } from '../../../../shared/links/apm/metric_overview_link';
+import { useServiceNodeMetricOverviewHref } from '../../../../shared/links/apm/service_node_metric_overview_link';
import { useInstanceDetailsFetcher } from '../use_instance_details_fetcher';
import { getMenuSections } from './menu_sections';
diff --git a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_table/instance_actions_menu/menu_sections.ts b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_table/instance_actions_menu/menu_sections.ts
index 7e7f30065c958..7a537125203ea 100644
--- a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_table/instance_actions_menu/menu_sections.ts
+++ b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_table/instance_actions_menu/menu_sections.ts
@@ -9,7 +9,7 @@ import { i18n } from '@kbn/i18n';
import { IBasePath } from 'kibana/public';
import moment from 'moment';
import { APIReturnType } from '../../../../../services/rest/createCallApmApi';
-import { getInfraHref } from '../../../../shared/Links/InfraLink';
+import { getInfraHref } from '../../../../shared/links/infra_link';
import {
Action,
getNonEmptySections,
diff --git a/x-pack/plugins/apm/public/components/app/trace_overview/trace_list.tsx b/x-pack/plugins/apm/public/components/app/trace_overview/trace_list.tsx
index 40283ae192947..e5f3c7bcbee4e 100644
--- a/x-pack/plugins/apm/public/components/app/trace_overview/trace_list.tsx
+++ b/x-pack/plugins/apm/public/components/app/trace_overview/trace_list.tsx
@@ -18,9 +18,9 @@ import {
import { useApmParams } from '../../../hooks/use_apm_params';
import { APIReturnType } from '../../../services/rest/createCallApmApi';
import { truncate } from '../../../utils/style';
-import { EmptyMessage } from '../../shared/EmptyMessage';
-import { ImpactBar } from '../../shared/ImpactBar';
-import { TransactionDetailLink } from '../../shared/Links/apm/transaction_detail_link';
+import { EmptyMessage } from '../../shared/empty_message';
+import { ImpactBar } from '../../shared/impact_bar';
+import { TransactionDetailLink } from '../../shared/links/apm/transaction_detail_link';
import { ITableColumn, ManagedTable } from '../../shared/managed_table';
import { ServiceLink } from '../../shared/service_link';
import { TruncateWithTooltip } from '../../shared/truncate_with_tooltip';
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/distribution/index.test.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/distribution/index.test.tsx
index 8430e620f59ab..1e4d1816bf84a 100644
--- a/x-pack/plugins/apm/public/components/app/transaction_details/distribution/index.test.tsx
+++ b/x-pack/plugins/apm/public/components/app/transaction_details/distribution/index.test.tsx
@@ -21,7 +21,7 @@ import {
MockApmPluginContextWrapper,
} from '../../../../context/apm_plugin/mock_apm_plugin_context';
import * as useFetcherModule from '../../../../hooks/use_fetcher';
-import { fromQuery } from '../../../shared/Links/url_helpers';
+import { fromQuery } from '../../../shared/links/url_helpers';
import { getFormattedSelection, TransactionDistribution } from './index';
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/distribution/index.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/distribution/index.tsx
index a2f6fd493313f..7d387a39f9334 100644
--- a/x-pack/plugins/apm/public/components/app/transaction_details/distribution/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/transaction_details/distribution/index.tsx
@@ -33,7 +33,7 @@ import { useWaterfallFetcher } from '../use_waterfall_fetcher';
import { WaterfallWithSummary } from '../waterfall_with_summary';
import { useTransactionDistributionChartData } from './use_transaction_distribution_chart_data';
-import { HeightRetainer } from '../../../shared/HeightRetainer';
+import { HeightRetainer } from '../../../shared/height_retainer';
import { ChartTitleToolTip } from '../../correlations/chart_title_tool_tip';
// Enforce min height so it's consistent across all tabs on the same level
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/index.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/index.tsx
index cf8d69410d26b..45c9d30419e85 100644
--- a/x-pack/plugins/apm/public/components/app/transaction_details/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/transaction_details/index.tsx
@@ -16,7 +16,7 @@ import { useApmRouter } from '../../../hooks/use_apm_router';
import { useTimeRange } from '../../../hooks/use_time_range';
import { AggregatedTransactionsBadge } from '../../shared/aggregated_transactions_badge';
import { TransactionCharts } from '../../shared/charts/transaction_charts';
-import { replace } from '../../shared/Links/url_helpers';
+import { replace } from '../../shared/links/url_helpers';
import { TransactionDetailsTabs } from './transaction_details_tabs';
export function TransactionDetails() {
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/transaction_details_tabs.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/transaction_details_tabs.tsx
index 9f7d2977dfa84..5e9f1f8149d9d 100644
--- a/x-pack/plugins/apm/public/components/app/transaction_details/transaction_details_tabs.tsx
+++ b/x-pack/plugins/apm/public/components/app/transaction_details/transaction_details_tabs.tsx
@@ -18,7 +18,7 @@ import { useApmParams } from '../../../hooks/use_apm_params';
import { useTransactionTraceSamplesFetcher } from '../../../hooks/use_transaction_trace_samples_fetcher';
import { maybe } from '../../../../common/utils/maybe';
-import { fromQuery, push, toQuery } from '../../shared/Links/url_helpers';
+import { fromQuery, push, toQuery } from '../../shared/links/url_helpers';
import { failedTransactionsCorrelationsTab } from './failed_transactions_correlations_tab';
import { latencyCorrelationsTab } from './latency_correlations_tab';
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/use_waterfall_fetcher.ts b/x-pack/plugins/apm/public/components/app/transaction_details/use_waterfall_fetcher.ts
index 4f26a5875347c..c35de9d510951 100644
--- a/x-pack/plugins/apm/public/components/app/transaction_details/use_waterfall_fetcher.ts
+++ b/x-pack/plugins/apm/public/components/app/transaction_details/use_waterfall_fetcher.ts
@@ -10,7 +10,7 @@ import { useLegacyUrlParams } from '../../../context/url_params_context/use_url_
import { useApmParams } from '../../../hooks/use_apm_params';
import { useFetcher } from '../../../hooks/use_fetcher';
import { useTimeRange } from '../../../hooks/use_time_range';
-import { getWaterfall } from './waterfall_with_summary/waterfall_container/Waterfall/waterfall_helpers/waterfall_helpers';
+import { getWaterfall } from './waterfall_with_summary/waterfall_container/waterfall/waterfall_helpers/waterfall_helpers';
const INITIAL_DATA = {
errorDocs: [],
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/index.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/index.tsx
index 1c421032ac7d3..f528ce17c02f0 100644
--- a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/index.tsx
@@ -17,14 +17,14 @@ import { i18n } from '@kbn/i18n';
import React, { useEffect, useState } from 'react';
import { useHistory } from 'react-router-dom';
import type { ApmUrlParams } from '../../../../context/url_params_context/types';
-import { fromQuery, toQuery } from '../../../shared/Links/url_helpers';
-import { LoadingStatePrompt } from '../../../shared/LoadingStatePrompt';
-import { TransactionSummary } from '../../../shared/Summary/TransactionSummary';
-import { TransactionActionMenu } from '../../../shared/transaction_action_menu/TransactionActionMenu';
+import { fromQuery, toQuery } from '../../../shared/links/url_helpers';
+import { LoadingStatePrompt } from '../../../shared/loading_state_prompt';
+import { TransactionSummary } from '../../../shared/summary/transaction_summary';
+import { TransactionActionMenu } from '../../../shared/transaction_action_menu/transaction_action_menu';
import type { TraceSample } from '../../../../hooks/use_transaction_trace_samples_fetcher';
-import { MaybeViewTraceLink } from './MaybeViewTraceLink';
-import { TransactionTabs } from './TransactionTabs';
-import { IWaterfall } from './waterfall_container/Waterfall/waterfall_helpers/waterfall_helpers';
+import { MaybeViewTraceLink } from './maybe_view_trace_link';
+import { TransactionTabs } from './transaction_tabs';
+import { IWaterfall } from './waterfall_container/waterfall/waterfall_helpers/waterfall_helpers';
import { useApmParams } from '../../../../hooks/use_apm_params';
interface Props {
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/MaybeViewTraceLink.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/maybe_view_trace_link.tsx
similarity index 96%
rename from x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/MaybeViewTraceLink.tsx
rename to x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/maybe_view_trace_link.tsx
index b146afae53907..dfc89f78e4b3b 100644
--- a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/MaybeViewTraceLink.tsx
+++ b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/maybe_view_trace_link.tsx
@@ -11,8 +11,8 @@ import React from 'react';
import { getNextEnvironmentUrlParam } from '../../../../../common/environment_filter_values';
import { useLegacyUrlParams } from '../../../../context/url_params_context/use_url_params';
import { Transaction as ITransaction } from '../../../../../typings/es_schemas/ui/transaction';
-import { TransactionDetailLink } from '../../../shared/Links/apm/transaction_detail_link';
-import { IWaterfall } from './waterfall_container/Waterfall/waterfall_helpers/waterfall_helpers';
+import { TransactionDetailLink } from '../../../shared/links/apm/transaction_detail_link';
+import { IWaterfall } from './waterfall_container/waterfall/waterfall_helpers/waterfall_helpers';
import { Environment } from '../../../../../common/environment_rt';
export function MaybeViewTraceLink({
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/PercentOfParent.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/percent_of_parent.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/PercentOfParent.tsx
rename to x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/percent_of_parent.tsx
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/TransactionTabs.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/transaction_tabs.tsx
similarity index 94%
rename from x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/TransactionTabs.tsx
rename to x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/transaction_tabs.tsx
index 0e01c44b3fb5a..c5001e25b0801 100644
--- a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/TransactionTabs.tsx
+++ b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/transaction_tabs.tsx
@@ -12,10 +12,10 @@ import { useHistory } from 'react-router-dom';
import { LogStream } from '../../../../../../infra/public';
import { Transaction } from '../../../../../typings/es_schemas/ui/transaction';
import type { ApmUrlParams } from '../../../../context/url_params_context/types';
-import { fromQuery, toQuery } from '../../../shared/Links/url_helpers';
-import { TransactionMetadata } from '../../../shared/MetadataTable/TransactionMetadata';
+import { fromQuery, toQuery } from '../../../shared/links/url_helpers';
+import { TransactionMetadata } from '../../../shared/metadata_table/transaction_metadata';
import { WaterfallContainer } from './waterfall_container';
-import { IWaterfall } from './waterfall_container/Waterfall/waterfall_helpers/waterfall_helpers';
+import { IWaterfall } from './waterfall_container/waterfall/waterfall_helpers/waterfall_helpers';
interface Props {
transaction: Transaction;
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/index.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/index.tsx
index 6ef7651a1e404..71e4b6a6f1aad 100644
--- a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/index.tsx
@@ -11,9 +11,9 @@ import type { ApmUrlParams } from '../../../../../context/url_params_context/typ
import {
IWaterfall,
WaterfallLegendType,
-} from './Waterfall/waterfall_helpers/waterfall_helpers';
-import { Waterfall } from './Waterfall';
-import { WaterfallLegends } from './WaterfallLegends';
+} from './waterfall/waterfall_helpers/waterfall_helpers';
+import { Waterfall } from './waterfall';
+import { WaterfallLegends } from './waterfall_legends';
import { useApmServiceContext } from '../../../../../context/apm_service/use_apm_service_context';
interface Props {
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Marks/get_agent_marks.test.ts b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/marks/get_agent_marks.test.ts
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Marks/get_agent_marks.test.ts
rename to x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/marks/get_agent_marks.test.ts
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Marks/get_agent_marks.ts b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/marks/get_agent_marks.ts
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Marks/get_agent_marks.ts
rename to x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/marks/get_agent_marks.ts
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Marks/get_error_marks.test.ts b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/marks/get_error_marks.test.ts
similarity index 97%
rename from x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Marks/get_error_marks.test.ts
rename to x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/marks/get_error_marks.test.ts
index 62507efc64401..5331ae1ae3d36 100644
--- a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Marks/get_error_marks.test.ts
+++ b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/marks/get_error_marks.test.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import { IWaterfallError } from '../Waterfall/waterfall_helpers/waterfall_helpers';
+import { IWaterfallError } from '../waterfall/waterfall_helpers/waterfall_helpers';
import { getErrorMarks } from './get_error_marks';
describe('getErrorMarks', () => {
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Marks/get_error_marks.ts b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/marks/get_error_marks.ts
similarity index 93%
rename from x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Marks/get_error_marks.ts
rename to x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/marks/get_error_marks.ts
index 1012c3dfa6fd1..25baf42572d06 100644
--- a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Marks/get_error_marks.ts
+++ b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/marks/get_error_marks.ts
@@ -7,7 +7,7 @@
import { isEmpty } from 'lodash';
import { ErrorRaw } from '../../../../../../../typings/es_schemas/raw/error_raw';
-import { IWaterfallError } from '../Waterfall/waterfall_helpers/waterfall_helpers';
+import { IWaterfallError } from '../waterfall/waterfall_helpers/waterfall_helpers';
import { Mark } from '.';
export interface ErrorMark extends Mark {
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Marks/index.ts b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/marks/index.ts
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Marks/index.ts
rename to x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/marks/index.ts
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/accordion_waterfall.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/accordion_waterfall.tsx
similarity index 98%
rename from x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/accordion_waterfall.tsx
rename to x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/accordion_waterfall.tsx
index 25b306723b2d2..6ca1a78db28b1 100644
--- a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/accordion_waterfall.tsx
+++ b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/accordion_waterfall.tsx
@@ -15,7 +15,7 @@ import {
} from '@elastic/eui';
import React, { Dispatch, SetStateAction, useState } from 'react';
import { euiStyled } from '../../../../../../../../../../src/plugins/kibana_react/common';
-import { Margins } from '../../../../../shared/charts/Timeline';
+import { Margins } from '../../../../../shared/charts/timeline';
import {
IWaterfall,
IWaterfallSpanOrTransaction,
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/failure_badge.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/failure_badge.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/failure_badge.tsx
rename to x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/failure_badge.tsx
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/FlyoutTopLevelProperties.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/flyout_top_level_properties.tsx
similarity index 97%
rename from x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/FlyoutTopLevelProperties.tsx
rename to x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/flyout_top_level_properties.tsx
index c81dfb6283c94..20e278000266a 100644
--- a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/FlyoutTopLevelProperties.tsx
+++ b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/flyout_top_level_properties.tsx
@@ -15,7 +15,7 @@ import { getNextEnvironmentUrlParam } from '../../../../../../../common/environm
import { Transaction } from '../../../../../../../typings/es_schemas/ui/transaction';
import { useLegacyUrlParams } from '../../../../../../context/url_params_context/use_url_params';
import { useApmParams } from '../../../../../../hooks/use_apm_params';
-import { TransactionDetailLink } from '../../../../../shared/Links/apm/transaction_detail_link';
+import { TransactionDetailLink } from '../../../../../shared/links/apm/transaction_detail_link';
import { ServiceLink } from '../../../../../shared/service_link';
import { StickyProperties } from '../../../../../shared/sticky_properties';
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/index.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/index.tsx
similarity index 94%
rename from x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/index.tsx
rename to x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/index.tsx
index 50ec934961e1a..c64a121c91882 100644
--- a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/index.tsx
@@ -11,10 +11,10 @@ import { History } from 'history';
import React, { useState } from 'react';
import { useHistory } from 'react-router-dom';
import { euiStyled } from '../../../../../../../../../../src/plugins/kibana_react/common';
-import { Timeline } from '../../../../../shared/charts/Timeline';
-import { fromQuery, toQuery } from '../../../../../shared/Links/url_helpers';
-import { getAgentMarks } from '../Marks/get_agent_marks';
-import { getErrorMarks } from '../Marks/get_error_marks';
+import { Timeline } from '../../../../../shared/charts/timeline';
+import { fromQuery, toQuery } from '../../../../../shared/links/url_helpers';
+import { getAgentMarks } from '../marks/get_agent_marks';
+import { getErrorMarks } from '../marks/get_error_marks';
import { AccordionWaterfall } from './accordion_waterfall';
import { WaterfallFlyout } from './waterfall_flyout';
import {
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/ResponsiveFlyout.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/responsive_flyout.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/ResponsiveFlyout.tsx
rename to x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/responsive_flyout.tsx
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/span_flyout/index.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/span_flyout/index.tsx
similarity index 92%
rename from x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/span_flyout/index.tsx
rename to x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/span_flyout/index.tsx
index 457daef851bcf..57bfc2b61fc53 100644
--- a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/span_flyout/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/span_flyout/index.tsx
@@ -22,18 +22,18 @@ import {
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React, { Fragment } from 'react';
-import { CompositeSpanDurationSummaryItem } from '../../../../../../shared/Summary/CompositeSpanDurationSummaryItem';
+import { CompositeSpanDurationSummaryItem } from '../../../../../../shared/summary/composite_span_duration_summary_item';
import { euiStyled } from '../../../../../../../../../../../src/plugins/kibana_react/common';
import { Span } from '../../../../../../../../typings/es_schemas/ui/span';
import { Transaction } from '../../../../../../../../typings/es_schemas/ui/transaction';
-import { DiscoverSpanLink } from '../../../../../../shared/Links/DiscoverLinks/DiscoverSpanLink';
-import { SpanMetadata } from '../../../../../../shared/MetadataTable/SpanMetadata';
-import { Stacktrace } from '../../../../../../shared/Stacktrace';
-import { Summary } from '../../../../../../shared/Summary';
-import { DurationSummaryItem } from '../../../../../../shared/Summary/DurationSummaryItem';
-import { HttpInfoSummaryItem } from '../../../../../../shared/Summary/http_info_summary_item';
-import { TimestampTooltip } from '../../../../../../shared/TimestampTooltip';
-import { ResponsiveFlyout } from '../ResponsiveFlyout';
+import { DiscoverSpanLink } from '../../../../../../shared/links/discover_links/discover_span_link';
+import { SpanMetadata } from '../../../../../../shared/metadata_table/span_metadata';
+import { Stacktrace } from '../../../../../../shared/stacktrace';
+import { Summary } from '../../../../../../shared/summary';
+import { DurationSummaryItem } from '../../../../../../shared/summary/duration_summary_item';
+import { HttpInfoSummaryItem } from '../../../../../../shared/summary/http_info_summary_item';
+import { TimestampTooltip } from '../../../../../../shared/timestamp_tooltip';
+import { ResponsiveFlyout } from '../responsive_flyout';
import { SyncBadge } from '../sync_badge';
import { SpanDatabase } from './span_db';
import { StickySpanProperties } from './sticky_span_properties';
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/span_flyout/span_db.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/span_flyout/span_db.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/span_flyout/span_db.tsx
rename to x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/span_flyout/span_db.tsx
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/span_flyout/span_flyout.stories.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/span_flyout/span_flyout.stories.tsx
similarity index 99%
rename from x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/span_flyout/span_flyout.stories.tsx
rename to x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/span_flyout/span_flyout.stories.tsx
index 33a0069e19ef1..f87967f762f25 100644
--- a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/span_flyout/span_flyout.stories.tsx
+++ b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/span_flyout/span_flyout.stories.tsx
@@ -14,7 +14,7 @@ import { SpanFlyout } from './';
type Args = ComponentProps;
export default {
- title: 'app/TransactionDetails/Waterfall/SpanFlyout',
+ title: 'app/TransactionDetails/waterfall/SpanFlyout',
component: SpanFlyout,
decorators: [
(StoryComponent: ComponentType) => {
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/span_flyout/sticky_span_properties.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/span_flyout/sticky_span_properties.tsx
similarity index 99%
rename from x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/span_flyout/sticky_span_properties.tsx
rename to x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/span_flyout/sticky_span_properties.tsx
index 9e7a32a6808ec..3067b335f4861 100644
--- a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/span_flyout/sticky_span_properties.tsx
+++ b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/span_flyout/sticky_span_properties.tsx
@@ -23,7 +23,7 @@ import { Span } from '../../../../../../../../typings/es_schemas/ui/span';
import { Transaction } from '../../../../../../../../typings/es_schemas/ui/transaction';
import { useApmParams } from '../../../../../../../hooks/use_apm_params';
import { BackendLink } from '../../../../../../shared/backend_link';
-import { TransactionDetailLink } from '../../../../../../shared/Links/apm/transaction_detail_link';
+import { TransactionDetailLink } from '../../../../../../shared/links/apm/transaction_detail_link';
import { ServiceLink } from '../../../../../../shared/service_link';
import { StickyProperties } from '../../../../../../shared/sticky_properties';
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/span_flyout/truncate_height_section.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/span_flyout/truncate_height_section.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/span_flyout/truncate_height_section.tsx
rename to x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/span_flyout/truncate_height_section.tsx
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/sync_badge.stories.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/sync_badge.stories.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/sync_badge.stories.tsx
rename to x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/sync_badge.stories.tsx
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/sync_badge.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/sync_badge.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/sync_badge.tsx
rename to x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/sync_badge.tsx
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/transaction_flyout/DroppedSpansWarning.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/transaction_flyout/dropped_spans_warning.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/transaction_flyout/DroppedSpansWarning.tsx
rename to x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/transaction_flyout/dropped_spans_warning.tsx
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/transaction_flyout/index.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/transaction_flyout/index.tsx
similarity index 85%
rename from x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/transaction_flyout/index.tsx
rename to x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/transaction_flyout/index.tsx
index 6468e6ed1e2c8..5f1e0cacd8483 100644
--- a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/transaction_flyout/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/transaction_flyout/index.tsx
@@ -18,12 +18,12 @@ import {
import { i18n } from '@kbn/i18n';
import React from 'react';
import { Transaction } from '../../../../../../../../typings/es_schemas/ui/transaction';
-import { TransactionActionMenu } from '../../../../../../shared/transaction_action_menu/TransactionActionMenu';
-import { TransactionSummary } from '../../../../../../shared/Summary/TransactionSummary';
-import { FlyoutTopLevelProperties } from '../FlyoutTopLevelProperties';
-import { ResponsiveFlyout } from '../ResponsiveFlyout';
-import { TransactionMetadata } from '../../../../../../shared/MetadataTable/TransactionMetadata';
-import { DroppedSpansWarning } from './DroppedSpansWarning';
+import { TransactionActionMenu } from '../../../../../../shared/transaction_action_menu/transaction_action_menu';
+import { TransactionSummary } from '../../../../../../shared/summary/transaction_summary';
+import { FlyoutTopLevelProperties } from '../flyout_top_level_properties';
+import { ResponsiveFlyout } from '../responsive_flyout';
+import { TransactionMetadata } from '../../../../../../shared/metadata_table/transaction_metadata';
+import { DroppedSpansWarning } from './dropped_spans_warning';
interface Props {
onClose: () => void;
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/transaction_flyout/transaction_flyout.stories.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/transaction_flyout/transaction_flyout.stories.tsx
similarity index 98%
rename from x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/transaction_flyout/transaction_flyout.stories.tsx
rename to x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/transaction_flyout/transaction_flyout.stories.tsx
index 33f1de91b61cc..7f8fbf62130b3 100644
--- a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/transaction_flyout/transaction_flyout.stories.tsx
+++ b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/transaction_flyout/transaction_flyout.stories.tsx
@@ -14,7 +14,7 @@ import { TransactionFlyout } from './';
type Args = ComponentProps;
export default {
- title: 'app/TransactionDetails/Waterfall/TransactionFlyout',
+ title: 'app/TransactionDetails/waterfall/TransactionFlyout',
component: TransactionFlyout,
decorators: [
(StoryComponent: ComponentType) => {
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/waterfall_flyout.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/waterfall_flyout.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/waterfall_flyout.tsx
rename to x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/waterfall_flyout.tsx
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/waterfall_helpers/__snapshots__/waterfall_helpers.test.ts.snap b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/waterfall_helpers/__snapshots__/waterfall_helpers.test.ts.snap
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/waterfall_helpers/__snapshots__/waterfall_helpers.test.ts.snap
rename to x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/waterfall_helpers/__snapshots__/waterfall_helpers.test.ts.snap
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/waterfall_helpers/mock_responses/spans.json b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/waterfall_helpers/mock_responses/spans.json
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/waterfall_helpers/mock_responses/spans.json
rename to x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/waterfall_helpers/mock_responses/spans.json
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/waterfall_helpers/mock_responses/transaction.json b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/waterfall_helpers/mock_responses/transaction.json
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/waterfall_helpers/mock_responses/transaction.json
rename to x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/waterfall_helpers/mock_responses/transaction.json
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/waterfall_helpers/waterfall_helpers.test.ts b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/waterfall_helpers/waterfall_helpers.test.ts
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/waterfall_helpers/waterfall_helpers.test.ts
rename to x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/waterfall_helpers/waterfall_helpers.test.ts
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/waterfall_helpers/waterfall_helpers.ts b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/waterfall_helpers/waterfall_helpers.ts
similarity index 100%
rename from x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/waterfall_helpers/waterfall_helpers.ts
rename to x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/waterfall_helpers/waterfall_helpers.ts
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/waterfall_item.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/waterfall_item.tsx
similarity index 99%
rename from x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/waterfall_item.tsx
rename to x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/waterfall_item.tsx
index c9e6e08ac759f..056a2847c68bf 100644
--- a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/Waterfall/waterfall_item.tsx
+++ b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/waterfall_item.tsx
@@ -16,7 +16,7 @@ import {
TRANSACTION_ID,
} from '../../../../../../../common/elasticsearch_fieldnames';
import { asDuration } from '../../../../../../../common/utils/formatters';
-import { Margins } from '../../../../../shared/charts/Timeline';
+import { Margins } from '../../../../../shared/charts/timeline';
import { TruncateWithTooltip } from '../../../../../shared/truncate_with_tooltip';
import { SyncBadge } from './sync_badge';
import { IWaterfallSpanOrTransaction } from './waterfall_helpers/waterfall_helpers';
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall_container.stories.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall_container.stories.tsx
index 895b83136a097..312412a8cf827 100644
--- a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall_container.stories.tsx
+++ b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall_container.stories.tsx
@@ -10,7 +10,7 @@ import React, { ComponentProps } from 'react';
import { MemoryRouter } from 'react-router-dom';
import { MockApmPluginContextWrapper } from '../../../../../context/apm_plugin/mock_apm_plugin_context';
import { WaterfallContainer } from './index';
-import { getWaterfall } from './Waterfall/waterfall_helpers/waterfall_helpers';
+import { getWaterfall } from './waterfall/waterfall_helpers/waterfall_helpers';
import {
inferredSpans,
manyChildrenWithSameLength,
@@ -23,7 +23,7 @@ import {
type Args = ComponentProps;
const stories: Meta = {
- title: 'app/TransactionDetails/Waterfall',
+ title: 'app/TransactionDetails/waterfall',
component: WaterfallContainer,
decorators: [
(StoryComponent) => (
diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/WaterfallLegends.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall_legends.tsx
similarity index 92%
rename from x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/WaterfallLegends.tsx
rename to x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall_legends.tsx
index aaa9b3e45ee22..30d4b0049d1bd 100644
--- a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/WaterfallLegends.tsx
+++ b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall_legends.tsx
@@ -10,11 +10,11 @@ import { EuiFlexItem } from '@elastic/eui';
import { EuiTitle } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
-import { Legend } from '../../../../shared/charts/Timeline/legend';
+import { Legend } from '../../../../shared/charts/timeline/legend';
import {
IWaterfallLegend,
WaterfallLegendType,
-} from './Waterfall/waterfall_helpers/waterfall_helpers';
+} from './waterfall/waterfall_helpers/waterfall_helpers';
interface Props {
legends: IWaterfallLegend[];
diff --git a/x-pack/plugins/apm/public/components/app/transaction_overview/index.tsx b/x-pack/plugins/apm/public/components/app/transaction_overview/index.tsx
index e1d6fb65bbc56..39d522ca088fc 100644
--- a/x-pack/plugins/apm/public/components/app/transaction_overview/index.tsx
+++ b/x-pack/plugins/apm/public/components/app/transaction_overview/index.tsx
@@ -13,7 +13,7 @@ import { useApmParams } from '../../../hooks/use_apm_params';
import { useTimeRange } from '../../../hooks/use_time_range';
import { AggregatedTransactionsBadge } from '../../shared/aggregated_transactions_badge';
import { TransactionCharts } from '../../shared/charts/transaction_charts';
-import { replace } from '../../shared/Links/url_helpers';
+import { replace } from '../../shared/links/url_helpers';
import { TransactionsTable } from '../../shared/transactions_table';
export function TransactionOverview() {
diff --git a/x-pack/plugins/apm/public/components/app/transaction_overview/transaction_overview.test.tsx b/x-pack/plugins/apm/public/components/app/transaction_overview/transaction_overview.test.tsx
index a1b24fc516664..ede47a65d7ea5 100644
--- a/x-pack/plugins/apm/public/components/app/transaction_overview/transaction_overview.test.tsx
+++ b/x-pack/plugins/apm/public/components/app/transaction_overview/transaction_overview.test.tsx
@@ -21,7 +21,7 @@ import {
disableConsoleWarning,
renderWithTheme,
} from '../../../utils/testHelpers';
-import { fromQuery } from '../../shared/Links/url_helpers';
+import { fromQuery } from '../../shared/links/url_helpers';
import { TransactionOverview } from './';
const KibanaReactContext = createKibanaReactContext({
diff --git a/x-pack/plugins/apm/public/components/routing/app_root.tsx b/x-pack/plugins/apm/public/components/routing/app_root.tsx
index 5750146bef722..c7b98743c6bea 100644
--- a/x-pack/plugins/apm/public/components/routing/app_root.tsx
+++ b/x-pack/plugins/apm/public/components/routing/app_root.tsx
@@ -20,7 +20,7 @@ import {
HeaderMenuPortal,
InspectorContextProvider,
} from '../../../../observability/public';
-import { ScrollToTopOnPathChange } from '../../components/app/Main/ScrollToTopOnPathChange';
+import { ScrollToTopOnPathChange } from '../../components/app/main/ScrollToTopOnPathChange';
import { AnomalyDetectionJobsContextProvider } from '../../context/anomaly_detection_jobs/anomaly_detection_jobs_context';
import {
ApmPluginContext,
diff --git a/x-pack/plugins/apm/public/components/routing/service_detail/index.tsx b/x-pack/plugins/apm/public/components/routing/service_detail/index.tsx
index d8a996d2163bc..713292c633891 100644
--- a/x-pack/plugins/apm/public/components/routing/service_detail/index.tsx
+++ b/x-pack/plugins/apm/public/components/routing/service_detail/index.tsx
@@ -27,6 +27,7 @@ import { TransactionDetails } from '../../app/transaction_details';
import { ServiceProfiling } from '../../app/service_profiling';
import { ServiceDependencies } from '../../app/service_dependencies';
import { ServiceLogs } from '../../app/service_logs';
+import { InfraOverview } from '../../app/infra_overview';
function page({
path,
@@ -265,6 +266,17 @@ export const serviceDetail = {
}),
element: ,
}),
+ page({
+ path: '/services/{serviceName}/infra',
+ tab: 'infra',
+ title: i18n.translate('xpack.apm.views.infra.title', {
+ defaultMessage: 'Infrastructure',
+ }),
+ element: ,
+ searchBarOptions: {
+ hidden: true,
+ },
+ }),
{
path: '/services/{serviceName}/',
element: ,
diff --git a/x-pack/plugins/apm/public/components/routing/templates/apm_main_template.tsx b/x-pack/plugins/apm/public/components/routing/templates/apm_main_template.tsx
index 710b4b6f71a35..fcc69c5055bad 100644
--- a/x-pack/plugins/apm/public/components/routing/templates/apm_main_template.tsx
+++ b/x-pack/plugins/apm/public/components/routing/templates/apm_main_template.tsx
@@ -15,7 +15,7 @@ import {
import { EnvironmentsContextProvider } from '../../../context/environments_context/environments_context';
import { useFetcher } from '../../../hooks/use_fetcher';
import { ApmPluginStartDeps } from '../../../plugin';
-import { ApmEnvironmentFilter } from '../../shared/EnvironmentFilter';
+import { ApmEnvironmentFilter } from '../../shared/environment_filter';
import { getNoDataConfig } from './no_data_config';
// Paths that must skip the no data screen
diff --git a/x-pack/plugins/apm/public/components/routing/templates/apm_service_template/index.tsx b/x-pack/plugins/apm/public/components/routing/templates/apm_service_template/index.tsx
index 0b97301b4e7c5..962fbb4eb6be6 100644
--- a/x-pack/plugins/apm/public/components/routing/templates/apm_service_template/index.tsx
+++ b/x-pack/plugins/apm/public/components/routing/templates/apm_service_template/index.tsx
@@ -42,6 +42,7 @@ type Tab = NonNullable[0] & {
| 'errors'
| 'metrics'
| 'nodes'
+ | 'infra'
| 'service-map'
| 'logs'
| 'profiling';
@@ -240,6 +241,16 @@ function useTabs({ selectedTab }: { selectedTab: Tab['key'] }) {
}),
hidden: isJVMsTabHidden({ agentName, runtimeName }),
},
+ {
+ key: 'infra',
+ href: router.link('/services/{serviceName}/infra', {
+ path: { serviceName },
+ query,
+ }),
+ label: i18n.translate('xpack.apm.home.infraTabLabel', {
+ defaultMessage: 'Infrastructure',
+ }),
+ },
{
key: 'service-map',
href: router.link('/services/{serviceName}/service-map', {
diff --git a/x-pack/plugins/apm/public/components/routing/templates/settings_template.tsx b/x-pack/plugins/apm/public/components/routing/templates/settings_template.tsx
index fc87b24579695..43a865c0584c9 100644
--- a/x-pack/plugins/apm/public/components/routing/templates/settings_template.tsx
+++ b/x-pack/plugins/apm/public/components/routing/templates/settings_template.tsx
@@ -13,7 +13,7 @@ import { useHistory } from 'react-router-dom';
import { CoreStart } from 'kibana/public';
import { ApmMainTemplate } from './apm_main_template';
import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_context';
-import { getLegacyApmHref } from '../../shared/Links/apm/APMLink';
+import { getLegacyApmHref } from '../../shared/links/apm/apm_link';
type Tab = NonNullable[0] & {
key:
diff --git a/x-pack/plugins/apm/public/components/shared/apm_header_action_menu/anomaly_detection_setup_link.tsx b/x-pack/plugins/apm/public/components/shared/apm_header_action_menu/anomaly_detection_setup_link.tsx
index e1bda5475acc4..40335f0cab61d 100644
--- a/x-pack/plugins/apm/public/components/shared/apm_header_action_menu/anomaly_detection_setup_link.tsx
+++ b/x-pack/plugins/apm/public/components/shared/apm_header_action_menu/anomaly_detection_setup_link.tsx
@@ -19,7 +19,7 @@ import { useAnomalyDetectionJobsContext } from '../../../context/anomaly_detecti
import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_context';
import { useApmParams } from '../../../hooks/use_apm_params';
import { useTheme } from '../../../hooks/use_theme';
-import { getLegacyApmHref } from '../Links/apm/APMLink';
+import { getLegacyApmHref } from '../links/apm/apm_link';
export function AnomalyDetectionSetupLink() {
const { query } = useApmParams('/*');
diff --git a/x-pack/plugins/apm/public/components/shared/apm_header_action_menu/index.tsx b/x-pack/plugins/apm/public/components/shared/apm_header_action_menu/index.tsx
index 655fc2da2b097..158705970640c 100644
--- a/x-pack/plugins/apm/public/components/shared/apm_header_action_menu/index.tsx
+++ b/x-pack/plugins/apm/public/components/shared/apm_header_action_menu/index.tsx
@@ -9,7 +9,7 @@ import { EuiHeaderLink, EuiHeaderLinks } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import { getAlertingCapabilities } from '../../alerting/get_alerting_capabilities';
-import { getLegacyApmHref } from '../Links/apm/APMLink';
+import { getLegacyApmHref } from '../links/apm/apm_link';
import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_context';
import { AlertingPopoverAndFlyout } from './alerting_popover_flyout';
import { AnomalyDetectionSetupLink } from './anomaly_detection_setup_link';
diff --git a/x-pack/plugins/apm/public/components/shared/charts/helper/helper.ts b/x-pack/plugins/apm/public/components/shared/charts/helper/helper.ts
index 9dccddd509387..d203bd8cfe022 100644
--- a/x-pack/plugins/apm/public/components/shared/charts/helper/helper.ts
+++ b/x-pack/plugins/apm/public/components/shared/charts/helper/helper.ts
@@ -8,7 +8,7 @@
import { XYBrushEvent } from '@elastic/charts';
import { History } from 'history';
import { Coordinate, TimeSeries } from '../../../../../typings/timeseries';
-import { fromQuery, toQuery } from '../../Links/url_helpers';
+import { fromQuery, toQuery } from '../../links/url_helpers';
export const onBrushEnd = ({
x,
diff --git a/x-pack/plugins/apm/public/components/shared/charts/instances_latency_distribution_chart/index.tsx b/x-pack/plugins/apm/public/components/shared/charts/instances_latency_distribution_chart/index.tsx
index 30bf5908ef376..0e9ad84864863 100644
--- a/x-pack/plugins/apm/public/components/shared/charts/instances_latency_distribution_chart/index.tsx
+++ b/x-pack/plugins/apm/public/components/shared/charts/instances_latency_distribution_chart/index.tsx
@@ -31,7 +31,7 @@ import {
import { FETCH_STATUS } from '../../../../hooks/use_fetcher';
import { useTheme } from '../../../../hooks/use_theme';
import { APIReturnType } from '../../../../services/rest/createCallApmApi';
-import * as urlHelpers from '../../Links/url_helpers';
+import * as urlHelpers from '../../links/url_helpers';
import { ChartContainer } from '../chart_container';
import { getResponseTimeTickFormatter } from '../transaction_charts/helper';
import { CustomTooltip } from './custom_tooltip';
diff --git a/x-pack/plugins/apm/public/components/shared/charts/latency_chart/index.tsx b/x-pack/plugins/apm/public/components/shared/charts/latency_chart/index.tsx
index 0b4eca8b9373c..d654cb9c0f5d3 100644
--- a/x-pack/plugins/apm/public/components/shared/charts/latency_chart/index.tsx
+++ b/x-pack/plugins/apm/public/components/shared/charts/latency_chart/index.tsx
@@ -24,7 +24,7 @@ import {
getResponseTimeTickFormatter,
} from '../../../shared/charts/transaction_charts/helper';
import { MLHeader } from '../../../shared/charts/transaction_charts/ml_header';
-import * as urlHelpers from '../../../shared/Links/url_helpers';
+import * as urlHelpers from '../../../shared/links/url_helpers';
import { getComparisonChartTheme } from '../../time_comparison/get_time_range_comparison';
import { useEnvironmentsContext } from '../../../../context/environments_context/use_environments_context';
import { ApmMlDetectorType } from '../../../../../common/anomaly_detection/apm_ml_detectors';
diff --git a/x-pack/plugins/apm/public/components/shared/charts/Timeline/Timeline.test.tsx b/x-pack/plugins/apm/public/components/shared/charts/timeline/Timeline.test.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/charts/Timeline/Timeline.test.tsx
rename to x-pack/plugins/apm/public/components/shared/charts/timeline/Timeline.test.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/charts/Timeline/__snapshots__/Timeline.test.tsx.snap b/x-pack/plugins/apm/public/components/shared/charts/timeline/__snapshots__/Timeline.test.tsx.snap
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/charts/Timeline/__snapshots__/Timeline.test.tsx.snap
rename to x-pack/plugins/apm/public/components/shared/charts/timeline/__snapshots__/Timeline.test.tsx.snap
diff --git a/x-pack/plugins/apm/public/components/shared/charts/Timeline/index.tsx b/x-pack/plugins/apm/public/components/shared/charts/timeline/index.tsx
similarity index 89%
rename from x-pack/plugins/apm/public/components/shared/charts/Timeline/index.tsx
rename to x-pack/plugins/apm/public/components/shared/charts/timeline/index.tsx
index 6c7cb7a067d2e..4a56f1a28e4be 100644
--- a/x-pack/plugins/apm/public/components/shared/charts/Timeline/index.tsx
+++ b/x-pack/plugins/apm/public/components/shared/charts/timeline/index.tsx
@@ -8,11 +8,11 @@
import PropTypes from 'prop-types';
import React, { PureComponent, ReactNode } from 'react';
import { makeWidthFlexible } from 'react-vis';
-import { AgentMark } from '../../../app/transaction_details/waterfall_with_summary/waterfall_container/Marks/get_agent_marks';
-import { ErrorMark } from '../../../app/transaction_details/waterfall_with_summary/waterfall_container/Marks/get_error_marks';
-import { getPlotValues } from './plotUtils';
+import { AgentMark } from '../../../app/transaction_details/waterfall_with_summary/waterfall_container/marks/get_agent_marks';
+import { ErrorMark } from '../../../app/transaction_details/waterfall_with_summary/waterfall_container/marks/get_error_marks';
+import { getPlotValues } from './plot_utils';
import { TimelineAxis } from './timeline_axis';
-import { VerticalLines } from './VerticalLines';
+import { VerticalLines } from './vertical_lines';
export type Mark = AgentMark | ErrorMark;
diff --git a/x-pack/plugins/apm/public/components/shared/charts/Timeline/LastTickValue.tsx b/x-pack/plugins/apm/public/components/shared/charts/timeline/last_tick_value.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/charts/Timeline/LastTickValue.tsx
rename to x-pack/plugins/apm/public/components/shared/charts/timeline/last_tick_value.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/charts/Timeline/legend.tsx b/x-pack/plugins/apm/public/components/shared/charts/timeline/legend.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/charts/Timeline/legend.tsx
rename to x-pack/plugins/apm/public/components/shared/charts/timeline/legend.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/charts/Timeline/Marker/__snapshots__/agent_marker.test.tsx.snap b/x-pack/plugins/apm/public/components/shared/charts/timeline/marker/__snapshots__/agent_marker.test.tsx.snap
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/charts/Timeline/Marker/__snapshots__/agent_marker.test.tsx.snap
rename to x-pack/plugins/apm/public/components/shared/charts/timeline/marker/__snapshots__/agent_marker.test.tsx.snap
diff --git a/x-pack/plugins/apm/public/components/shared/charts/Timeline/Marker/__snapshots__/index.test.tsx.snap b/x-pack/plugins/apm/public/components/shared/charts/timeline/marker/__snapshots__/index.test.tsx.snap
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/charts/Timeline/Marker/__snapshots__/index.test.tsx.snap
rename to x-pack/plugins/apm/public/components/shared/charts/timeline/marker/__snapshots__/index.test.tsx.snap
diff --git a/x-pack/plugins/apm/public/components/shared/charts/Timeline/Marker/agent_marker.test.tsx b/x-pack/plugins/apm/public/components/shared/charts/timeline/marker/agent_marker.test.tsx
similarity index 93%
rename from x-pack/plugins/apm/public/components/shared/charts/Timeline/Marker/agent_marker.test.tsx
rename to x-pack/plugins/apm/public/components/shared/charts/timeline/marker/agent_marker.test.tsx
index 0b7e405ae5d95..e421190d6793c 100644
--- a/x-pack/plugins/apm/public/components/shared/charts/Timeline/Marker/agent_marker.test.tsx
+++ b/x-pack/plugins/apm/public/components/shared/charts/timeline/marker/agent_marker.test.tsx
@@ -8,7 +8,7 @@
import { shallow } from 'enzyme';
import React from 'react';
import { EuiThemeProvider } from '../../../../../../../../../src/plugins/kibana_react/common';
-import { AgentMark } from '../../../../app/transaction_details/waterfall_with_summary/waterfall_container/Marks/get_agent_marks';
+import { AgentMark } from '../../../../app/transaction_details/waterfall_with_summary/waterfall_container/marks/get_agent_marks';
import { AgentMarker } from './agent_marker';
describe('AgentMarker', () => {
diff --git a/x-pack/plugins/apm/public/components/shared/charts/Timeline/Marker/agent_marker.tsx b/x-pack/plugins/apm/public/components/shared/charts/timeline/marker/agent_marker.tsx
similarity index 95%
rename from x-pack/plugins/apm/public/components/shared/charts/Timeline/Marker/agent_marker.tsx
rename to x-pack/plugins/apm/public/components/shared/charts/timeline/marker/agent_marker.tsx
index 947c7a93f38b1..9e97129b199db 100644
--- a/x-pack/plugins/apm/public/components/shared/charts/Timeline/Marker/agent_marker.tsx
+++ b/x-pack/plugins/apm/public/components/shared/charts/timeline/marker/agent_marker.tsx
@@ -10,7 +10,7 @@ import React from 'react';
import { euiStyled } from '../../../../../../../../../src/plugins/kibana_react/common';
import { asDuration } from '../../../../../../common/utils/formatters';
import { useTheme } from '../../../../../hooks/use_theme';
-import { AgentMark } from '../../../../app/transaction_details/waterfall_with_summary/waterfall_container/Marks/get_agent_marks';
+import { AgentMark } from '../../../../app/transaction_details/waterfall_with_summary/waterfall_container/marks/get_agent_marks';
import { Legend } from '../legend';
const NameContainer = euiStyled.div`
diff --git a/x-pack/plugins/apm/public/components/shared/charts/Timeline/Marker/error_marker.test.tsx b/x-pack/plugins/apm/public/components/shared/charts/timeline/marker/error_marker.test.tsx
similarity index 98%
rename from x-pack/plugins/apm/public/components/shared/charts/Timeline/Marker/error_marker.test.tsx
rename to x-pack/plugins/apm/public/components/shared/charts/timeline/marker/error_marker.test.tsx
index cef97c46fd2e2..d3b378ab5cb0b 100644
--- a/x-pack/plugins/apm/public/components/shared/charts/Timeline/Marker/error_marker.test.tsx
+++ b/x-pack/plugins/apm/public/components/shared/charts/timeline/marker/error_marker.test.tsx
@@ -14,7 +14,7 @@ import {
expectTextsInDocument,
renderWithTheme,
} from '../../../../../utils/testHelpers';
-import { ErrorMark } from '../../../../app/transaction_details/waterfall_with_summary/waterfall_container/Marks/get_error_marks';
+import { ErrorMark } from '../../../../app/transaction_details/waterfall_with_summary/waterfall_container/marks/get_error_marks';
import { ErrorMarker } from './error_marker';
function Wrapper({ children }: { children?: ReactNode }) {
diff --git a/x-pack/plugins/apm/public/components/shared/charts/Timeline/Marker/error_marker.tsx b/x-pack/plugins/apm/public/components/shared/charts/timeline/marker/error_marker.tsx
similarity index 96%
rename from x-pack/plugins/apm/public/components/shared/charts/Timeline/Marker/error_marker.tsx
rename to x-pack/plugins/apm/public/components/shared/charts/timeline/marker/error_marker.tsx
index a1e3f42cb5684..3f27ddbf78af4 100644
--- a/x-pack/plugins/apm/public/components/shared/charts/Timeline/Marker/error_marker.tsx
+++ b/x-pack/plugins/apm/public/components/shared/charts/timeline/marker/error_marker.tsx
@@ -15,8 +15,8 @@ import {
import { asDuration } from '../../../../../../common/utils/formatters';
import { useLegacyUrlParams } from '../../../../../context/url_params_context/use_url_params';
import { useTheme } from '../../../../../hooks/use_theme';
-import { ErrorMark } from '../../../../app/transaction_details/waterfall_with_summary/waterfall_container/Marks/get_error_marks';
-import { ErrorDetailLink } from '../../../Links/apm/ErrorDetailLink';
+import { ErrorMark } from '../../../../app/transaction_details/waterfall_with_summary/waterfall_container/marks/get_error_marks';
+import { ErrorDetailLink } from '../../../links/apm/error_detail_link';
import { Legend, Shape } from '../legend';
interface Props {
diff --git a/x-pack/plugins/apm/public/components/shared/charts/Timeline/Marker/index.test.tsx b/x-pack/plugins/apm/public/components/shared/charts/timeline/marker/index.test.tsx
similarity index 90%
rename from x-pack/plugins/apm/public/components/shared/charts/Timeline/Marker/index.test.tsx
rename to x-pack/plugins/apm/public/components/shared/charts/timeline/marker/index.test.tsx
index f2c8f9e3b318d..698801b5a8d37 100644
--- a/x-pack/plugins/apm/public/components/shared/charts/Timeline/Marker/index.test.tsx
+++ b/x-pack/plugins/apm/public/components/shared/charts/timeline/marker/index.test.tsx
@@ -8,8 +8,8 @@
import { shallow } from 'enzyme';
import React from 'react';
import { Marker } from './';
-import { AgentMark } from '../../../../app/transaction_details/waterfall_with_summary/waterfall_container/Marks/get_agent_marks';
-import { ErrorMark } from '../../../../app/transaction_details/waterfall_with_summary/waterfall_container/Marks/get_error_marks';
+import { AgentMark } from '../../../../app/transaction_details/waterfall_with_summary/waterfall_container/marks/get_agent_marks';
+import { ErrorMark } from '../../../../app/transaction_details/waterfall_with_summary/waterfall_container/marks/get_error_marks';
describe('Marker', () => {
it('renders agent marker', () => {
diff --git a/x-pack/plugins/apm/public/components/shared/charts/Timeline/Marker/index.tsx b/x-pack/plugins/apm/public/components/shared/charts/timeline/marker/index.tsx
similarity index 89%
rename from x-pack/plugins/apm/public/components/shared/charts/Timeline/Marker/index.tsx
rename to x-pack/plugins/apm/public/components/shared/charts/timeline/marker/index.tsx
index 88318eb0e0c2d..e4e26ce637bfe 100644
--- a/x-pack/plugins/apm/public/components/shared/charts/Timeline/Marker/index.tsx
+++ b/x-pack/plugins/apm/public/components/shared/charts/timeline/marker/index.tsx
@@ -7,8 +7,8 @@
import React from 'react';
import { euiStyled } from '../../../../../../../../../src/plugins/kibana_react/common';
-import { AgentMark } from '../../../../app/transaction_details/waterfall_with_summary/waterfall_container/Marks/get_agent_marks';
-import { ErrorMark } from '../../../../app/transaction_details/waterfall_with_summary/waterfall_container/Marks/get_error_marks';
+import { AgentMark } from '../../../../app/transaction_details/waterfall_with_summary/waterfall_container/marks/get_agent_marks';
+import { ErrorMark } from '../../../../app/transaction_details/waterfall_with_summary/waterfall_container/marks/get_error_marks';
import { AgentMarker } from './agent_marker';
import { ErrorMarker } from './error_marker';
diff --git a/x-pack/plugins/apm/public/components/shared/charts/Timeline/plotUtils.ts b/x-pack/plugins/apm/public/components/shared/charts/timeline/plot_utils.ts
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/charts/Timeline/plotUtils.ts
rename to x-pack/plugins/apm/public/components/shared/charts/timeline/plot_utils.ts
diff --git a/x-pack/plugins/apm/public/components/shared/charts/Timeline/timeline_axis.tsx b/x-pack/plugins/apm/public/components/shared/charts/timeline/timeline_axis.tsx
similarity index 95%
rename from x-pack/plugins/apm/public/components/shared/charts/Timeline/timeline_axis.tsx
rename to x-pack/plugins/apm/public/components/shared/charts/timeline/timeline_axis.tsx
index cf942ebb75776..4dddb4bee226d 100644
--- a/x-pack/plugins/apm/public/components/shared/charts/Timeline/timeline_axis.tsx
+++ b/x-pack/plugins/apm/public/components/shared/charts/timeline/timeline_axis.tsx
@@ -11,9 +11,9 @@ import { XAxis, XYPlot } from 'react-vis';
import { getDurationFormatter } from '../../../../../common/utils/formatters';
import { useTheme } from '../../../../hooks/use_theme';
import { Mark } from './';
-import { LastTickValue } from './LastTickValue';
-import { Marker } from './Marker';
-import { PlotValues } from './plotUtils';
+import { LastTickValue } from './last_tick_value';
+import { Marker } from './marker';
+import { PlotValues } from './plot_utils';
// Remove any tick that is too close to topTraceDuration
const getXAxisTickValues = (
diff --git a/x-pack/plugins/apm/public/components/shared/charts/Timeline/VerticalLines.tsx b/x-pack/plugins/apm/public/components/shared/charts/timeline/vertical_lines.tsx
similarity index 95%
rename from x-pack/plugins/apm/public/components/shared/charts/Timeline/VerticalLines.tsx
rename to x-pack/plugins/apm/public/components/shared/charts/timeline/vertical_lines.tsx
index 2dcc969f661b8..6f07efeed7c46 100644
--- a/x-pack/plugins/apm/public/components/shared/charts/Timeline/VerticalLines.tsx
+++ b/x-pack/plugins/apm/public/components/shared/charts/timeline/vertical_lines.tsx
@@ -8,8 +8,8 @@
import React from 'react';
import { VerticalGridLines, XYPlot } from 'react-vis';
import { useTheme } from '../../../../hooks/use_theme';
-import { Mark } from '../../../app/transaction_details/waterfall_with_summary/waterfall_container/Marks';
-import { PlotValues } from './plotUtils';
+import { Mark } from '../../../app/transaction_details/waterfall_with_summary/waterfall_container/marks';
+import { PlotValues } from './plot_utils';
interface VerticalLinesProps {
marks?: Mark[];
diff --git a/x-pack/plugins/apm/public/components/shared/charts/transaction_charts/ml_header.tsx b/x-pack/plugins/apm/public/components/shared/charts/transaction_charts/ml_header.tsx
index 76e85b1d9998d..0ae6fc00b2804 100644
--- a/x-pack/plugins/apm/public/components/shared/charts/transaction_charts/ml_header.tsx
+++ b/x-pack/plugins/apm/public/components/shared/charts/transaction_charts/ml_header.tsx
@@ -12,7 +12,7 @@ import React from 'react';
import { euiStyled } from '../../../../../../../../src/plugins/kibana_react/common';
import { useApmServiceContext } from '../../../../context/apm_service/use_apm_service_context';
import { useApmParams } from '../../../../hooks/use_apm_params';
-import { MLSingleMetricLink } from '../../Links/MachineLearningLinks/MLSingleMetricLink';
+import { MLSingleMetricLink } from '../../links/machine_learning_links/mlsingle_metric_link';
interface Props {
hasValidMlLicense?: boolean;
diff --git a/x-pack/plugins/apm/public/components/shared/DatePicker/date_picker.test.tsx b/x-pack/plugins/apm/public/components/shared/date_picker/date_picker.test.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/DatePicker/date_picker.test.tsx
rename to x-pack/plugins/apm/public/components/shared/date_picker/date_picker.test.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/DatePicker/index.tsx b/x-pack/plugins/apm/public/components/shared/date_picker/index.tsx
similarity index 98%
rename from x-pack/plugins/apm/public/components/shared/DatePicker/index.tsx
rename to x-pack/plugins/apm/public/components/shared/date_picker/index.tsx
index 12cc137d62142..c792c4ae9b426 100644
--- a/x-pack/plugins/apm/public/components/shared/DatePicker/index.tsx
+++ b/x-pack/plugins/apm/public/components/shared/date_picker/index.tsx
@@ -11,7 +11,7 @@ import { useHistory, useLocation } from 'react-router-dom';
import { UI_SETTINGS } from '../../../../../../../src/plugins/data/common';
import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_context';
import { clearCache } from '../../../services/rest/callApi';
-import { fromQuery, toQuery } from '../Links/url_helpers';
+import { fromQuery, toQuery } from '../links/url_helpers';
import { TimePickerQuickRange } from './typings';
export function DatePicker({
diff --git a/x-pack/plugins/apm/public/components/shared/DatePicker/typings.ts b/x-pack/plugins/apm/public/components/shared/date_picker/typings.ts
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/DatePicker/typings.ts
rename to x-pack/plugins/apm/public/components/shared/date_picker/typings.ts
diff --git a/x-pack/plugins/apm/public/components/shared/dependencies_table/index.tsx b/x-pack/plugins/apm/public/components/shared/dependencies_table/index.tsx
index 8791075158c95..7c2bc722ac1e6 100644
--- a/x-pack/plugins/apm/public/components/shared/dependencies_table/index.tsx
+++ b/x-pack/plugins/apm/public/components/shared/dependencies_table/index.tsx
@@ -21,8 +21,8 @@ import {
} from '../../../../common/utils/formatters';
import { useBreakpoints } from '../../../hooks/use_breakpoints';
import { FETCH_STATUS } from '../../../hooks/use_fetcher';
-import { EmptyMessage } from '../EmptyMessage';
-import { ImpactBar } from '../ImpactBar';
+import { EmptyMessage } from '../empty_message';
+import { ImpactBar } from '../impact_bar';
import { ListMetric } from '../list_metric';
import { ITableColumn, ManagedTable } from '../managed_table';
import { OverviewTableContainer } from '../overview_table_container';
diff --git a/x-pack/plugins/apm/public/components/shared/EmptyMessage.tsx b/x-pack/plugins/apm/public/components/shared/empty_message.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/EmptyMessage.tsx
rename to x-pack/plugins/apm/public/components/shared/empty_message.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/EnvironmentBadge/index.tsx b/x-pack/plugins/apm/public/components/shared/environment_badge/index.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/EnvironmentBadge/index.tsx
rename to x-pack/plugins/apm/public/components/shared/environment_badge/index.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/EnvironmentFilter/index.tsx b/x-pack/plugins/apm/public/components/shared/environment_filter/index.tsx
similarity index 98%
rename from x-pack/plugins/apm/public/components/shared/EnvironmentFilter/index.tsx
rename to x-pack/plugins/apm/public/components/shared/environment_filter/index.tsx
index 4344ed3a80f64..a7a8c90c31c16 100644
--- a/x-pack/plugins/apm/public/components/shared/EnvironmentFilter/index.tsx
+++ b/x-pack/plugins/apm/public/components/shared/environment_filter/index.tsx
@@ -15,7 +15,7 @@ import {
ENVIRONMENT_NOT_DEFINED,
} from '../../../../common/environment_filter_values';
import { useEnvironmentsFetcher } from '../../../hooks/use_environments_fetcher';
-import { fromQuery, toQuery } from '../Links/url_helpers';
+import { fromQuery, toQuery } from '../links/url_helpers';
import { useUxUrlParams } from '../../../context/url_params_context/use_ux_url_params';
import { FETCH_STATUS } from '../../../hooks/use_fetcher';
import { Environment } from '../../../../common/environment_rt';
diff --git a/x-pack/plugins/apm/public/components/shared/ErrorStatePrompt.tsx b/x-pack/plugins/apm/public/components/shared/error_state_prompt.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/ErrorStatePrompt.tsx
rename to x-pack/plugins/apm/public/components/shared/error_state_prompt.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/HeightRetainer/index.tsx b/x-pack/plugins/apm/public/components/shared/height_retainer/index.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/HeightRetainer/index.tsx
rename to x-pack/plugins/apm/public/components/shared/height_retainer/index.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/ImpactBar/__snapshots__/ImpactBar.test.js.snap b/x-pack/plugins/apm/public/components/shared/impact_bar/__snapshots__/impact_bar.test.js.snap
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/ImpactBar/__snapshots__/ImpactBar.test.js.snap
rename to x-pack/plugins/apm/public/components/shared/impact_bar/__snapshots__/impact_bar.test.js.snap
diff --git a/x-pack/plugins/apm/public/components/shared/ImpactBar/ImpactBar.test.js b/x-pack/plugins/apm/public/components/shared/impact_bar/impact_bar.test.js
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/ImpactBar/ImpactBar.test.js
rename to x-pack/plugins/apm/public/components/shared/impact_bar/impact_bar.test.js
diff --git a/x-pack/plugins/apm/public/components/shared/ImpactBar/index.tsx b/x-pack/plugins/apm/public/components/shared/impact_bar/index.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/ImpactBar/index.tsx
rename to x-pack/plugins/apm/public/components/shared/impact_bar/index.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/KeyValueTable/FormattedValue.tsx b/x-pack/plugins/apm/public/components/shared/key_value_table/formatted_value.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/KeyValueTable/FormattedValue.tsx
rename to x-pack/plugins/apm/public/components/shared/key_value_table/formatted_value.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/KeyValueTable/index.tsx b/x-pack/plugins/apm/public/components/shared/key_value_table/index.tsx
similarity index 96%
rename from x-pack/plugins/apm/public/components/shared/KeyValueTable/index.tsx
rename to x-pack/plugins/apm/public/components/shared/key_value_table/index.tsx
index e9525728bc3c5..8b5595a67fa78 100644
--- a/x-pack/plugins/apm/public/components/shared/KeyValueTable/index.tsx
+++ b/x-pack/plugins/apm/public/components/shared/key_value_table/index.tsx
@@ -13,7 +13,7 @@ import {
EuiTableRow,
EuiTableRowCell,
} from '@elastic/eui';
-import { FormattedValue } from './FormattedValue';
+import { FormattedValue } from './formatted_value';
import { KeyValuePair } from '../../../utils/flattenObject';
export function KeyValueTable({
diff --git a/x-pack/plugins/apm/public/components/shared/KeyValueTable/KeyValueTable.test.tsx b/x-pack/plugins/apm/public/components/shared/key_value_table/key_value_table.test.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/KeyValueTable/KeyValueTable.test.tsx
rename to x-pack/plugins/apm/public/components/shared/key_value_table/key_value_table.test.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/kuery_bar/index.tsx b/x-pack/plugins/apm/public/components/shared/kuery_bar/index.tsx
index 20484e691d50b..a04d3218f9fff 100644
--- a/x-pack/plugins/apm/public/components/shared/kuery_bar/index.tsx
+++ b/x-pack/plugins/apm/public/components/shared/kuery_bar/index.tsx
@@ -19,10 +19,10 @@ import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_
import { useLegacyUrlParams } from '../../../context/url_params_context/use_url_params';
import { useApmParams } from '../../../hooks/use_apm_params';
import { useDynamicDataViewFetcher } from '../../../hooks/use_dynamic_data_view';
-import { fromQuery, toQuery } from '../Links/url_helpers';
+import { fromQuery, toQuery } from '../links/url_helpers';
import { getBoolFilter } from './get_bool_filter';
// @ts-expect-error
-import { Typeahead } from './Typeahead';
+import { Typeahead } from './typeahead';
import { useProcessorEvent } from './use_processor_event';
interface State {
diff --git a/x-pack/plugins/apm/public/components/shared/kuery_bar/Typeahead/ClickOutside.js b/x-pack/plugins/apm/public/components/shared/kuery_bar/typeahead/click_outside.js
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/kuery_bar/Typeahead/ClickOutside.js
rename to x-pack/plugins/apm/public/components/shared/kuery_bar/typeahead/click_outside.js
diff --git a/x-pack/plugins/apm/public/components/shared/kuery_bar/Typeahead/index.js b/x-pack/plugins/apm/public/components/shared/kuery_bar/typeahead/index.js
similarity index 98%
rename from x-pack/plugins/apm/public/components/shared/kuery_bar/Typeahead/index.js
rename to x-pack/plugins/apm/public/components/shared/kuery_bar/typeahead/index.js
index f8f51679a5192..d06bfcceab984 100644
--- a/x-pack/plugins/apm/public/components/shared/kuery_bar/Typeahead/index.js
+++ b/x-pack/plugins/apm/public/components/shared/kuery_bar/typeahead/index.js
@@ -7,8 +7,8 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
-import Suggestions from './Suggestions';
-import ClickOutside from './ClickOutside';
+import Suggestions from './suggestions';
+import ClickOutside from './click_outside';
import { EuiFieldSearch, EuiProgress } from '@elastic/eui';
const KEY_CODES = {
diff --git a/x-pack/plugins/apm/public/components/shared/kuery_bar/Typeahead/Suggestion.js b/x-pack/plugins/apm/public/components/shared/kuery_bar/typeahead/suggestion.js
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/kuery_bar/Typeahead/Suggestion.js
rename to x-pack/plugins/apm/public/components/shared/kuery_bar/typeahead/suggestion.js
diff --git a/x-pack/plugins/apm/public/components/shared/kuery_bar/Typeahead/Suggestions.js b/x-pack/plugins/apm/public/components/shared/kuery_bar/typeahead/suggestions.js
similarity index 98%
rename from x-pack/plugins/apm/public/components/shared/kuery_bar/Typeahead/Suggestions.js
rename to x-pack/plugins/apm/public/components/shared/kuery_bar/typeahead/suggestions.js
index 386eb7e1e0d7d..e6f482e88afc0 100644
--- a/x-pack/plugins/apm/public/components/shared/kuery_bar/Typeahead/Suggestions.js
+++ b/x-pack/plugins/apm/public/components/shared/kuery_bar/typeahead/suggestions.js
@@ -11,7 +11,7 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { euiStyled } from '../../../../../../../../src/plugins/kibana_react/common';
import { unit } from '../../../../utils/style';
-import Suggestion from './Suggestion';
+import Suggestion from './suggestion';
const List = euiStyled.ul`
width: 100%;
diff --git a/x-pack/plugins/apm/public/components/shared/kuery_bar/utils.ts b/x-pack/plugins/apm/public/components/shared/kuery_bar/utils.ts
index 1d4dd04ce9df4..805e162c67fe6 100644
--- a/x-pack/plugins/apm/public/components/shared/kuery_bar/utils.ts
+++ b/x-pack/plugins/apm/public/components/shared/kuery_bar/utils.ts
@@ -7,7 +7,7 @@
import { History } from 'history';
import { isEmpty } from 'lodash';
-import { push } from '../Links/url_helpers';
+import { push } from '../links/url_helpers';
export function pushNewItemToKueryBar({
kuery,
diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/APMLink.test.tsx b/x-pack/plugins/apm/public/components/shared/links/apm/APMLink.test.tsx
similarity index 98%
rename from x-pack/plugins/apm/public/components/shared/Links/apm/APMLink.test.tsx
rename to x-pack/plugins/apm/public/components/shared/links/apm/APMLink.test.tsx
index c422b78d661e4..ea10852c7d668 100644
--- a/x-pack/plugins/apm/public/components/shared/Links/apm/APMLink.test.tsx
+++ b/x-pack/plugins/apm/public/components/shared/links/apm/APMLink.test.tsx
@@ -8,7 +8,7 @@
import { Location } from 'history';
import React from 'react';
import { getRenderedHref } from '../../../../utils/testHelpers';
-import { APMLink } from './APMLink';
+import { APMLink } from './apm_link';
describe('APMLink', () => {
test('APMLink should produce the correct URL', async () => {
diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/agentConfigurationLinks.tsx b/x-pack/plugins/apm/public/components/shared/links/apm/agent_configuration_links.tsx
similarity index 95%
rename from x-pack/plugins/apm/public/components/shared/Links/apm/agentConfigurationLinks.tsx
rename to x-pack/plugins/apm/public/components/shared/links/apm/agent_configuration_links.tsx
index c45ab22682ef4..366003c101789 100644
--- a/x-pack/plugins/apm/public/components/shared/Links/apm/agentConfigurationLinks.tsx
+++ b/x-pack/plugins/apm/public/components/shared/links/apm/agent_configuration_links.tsx
@@ -7,7 +7,7 @@
import { IBasePath } from 'kibana/public';
import { AgentConfigurationIntake } from '../../../../../common/agent_configuration/configuration_types';
-import { getLegacyApmHref } from './APMLink';
+import { getLegacyApmHref } from './apm_link';
export function editAgentConfigurationHref(
configService: AgentConfigurationIntake['service'],
diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/APMLink.tsx b/x-pack/plugins/apm/public/components/shared/links/apm/apm_link.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Links/apm/APMLink.tsx
rename to x-pack/plugins/apm/public/components/shared/links/apm/apm_link.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/ErrorDetailLink.tsx b/x-pack/plugins/apm/public/components/shared/links/apm/error_detail_link.tsx
similarity index 91%
rename from x-pack/plugins/apm/public/components/shared/Links/apm/ErrorDetailLink.tsx
rename to x-pack/plugins/apm/public/components/shared/links/apm/error_detail_link.tsx
index 75fd8ba1a5f11..4bf744e29c1ee 100644
--- a/x-pack/plugins/apm/public/components/shared/Links/apm/ErrorDetailLink.tsx
+++ b/x-pack/plugins/apm/public/components/shared/links/apm/error_detail_link.tsx
@@ -6,7 +6,7 @@
*/
import React from 'react';
-import { APMLink, APMLinkExtendProps } from './APMLink';
+import { APMLink, APMLinkExtendProps } from './apm_link';
interface Props extends APMLinkExtendProps {
serviceName: string;
diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/ErrorOverviewLink.tsx b/x-pack/plugins/apm/public/components/shared/links/apm/error_overview_link.tsx
similarity index 94%
rename from x-pack/plugins/apm/public/components/shared/Links/apm/ErrorOverviewLink.tsx
rename to x-pack/plugins/apm/public/components/shared/links/apm/error_overview_link.tsx
index ccd9bdff960b6..b517a39c1004d 100644
--- a/x-pack/plugins/apm/public/components/shared/Links/apm/ErrorOverviewLink.tsx
+++ b/x-pack/plugins/apm/public/components/shared/links/apm/error_overview_link.tsx
@@ -9,7 +9,7 @@ import React from 'react';
import { pickKeys } from '../../../../../common/utils/pick_keys';
import { useLegacyUrlParams } from '../../../../context/url_params_context/use_url_params';
import { APMQueryParams } from '../url_helpers';
-import { APMLink, APMLinkExtendProps } from './APMLink';
+import { APMLink, APMLinkExtendProps } from './apm_link';
const persistedFilters: Array = [
'host',
diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/HomeLink.tsx b/x-pack/plugins/apm/public/components/shared/links/apm/home_link.tsx
similarity index 87%
rename from x-pack/plugins/apm/public/components/shared/Links/apm/HomeLink.tsx
rename to x-pack/plugins/apm/public/components/shared/links/apm/home_link.tsx
index 66fdb7913b5d5..5337f1a2f16b9 100644
--- a/x-pack/plugins/apm/public/components/shared/Links/apm/HomeLink.tsx
+++ b/x-pack/plugins/apm/public/components/shared/links/apm/home_link.tsx
@@ -6,7 +6,7 @@
*/
import React from 'react';
-import { APMLink, APMLinkExtendProps } from './APMLink';
+import { APMLink, APMLinkExtendProps } from './apm_link';
function HomeLink(props: APMLinkExtendProps) {
return ;
diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/MetricOverviewLink.tsx b/x-pack/plugins/apm/public/components/shared/links/apm/metric_overview_link.tsx
similarity index 92%
rename from x-pack/plugins/apm/public/components/shared/Links/apm/MetricOverviewLink.tsx
rename to x-pack/plugins/apm/public/components/shared/links/apm/metric_overview_link.tsx
index c3d418b63426b..9d9a013d1c439 100644
--- a/x-pack/plugins/apm/public/components/shared/Links/apm/MetricOverviewLink.tsx
+++ b/x-pack/plugins/apm/public/components/shared/links/apm/metric_overview_link.tsx
@@ -7,7 +7,7 @@
import React from 'react';
import { APMQueryParams } from '../url_helpers';
-import { APMLink, APMLinkExtendProps, useAPMHref } from './APMLink';
+import { APMLink, APMLinkExtendProps, useAPMHref } from './apm_link';
const persistedFilters: Array = [
'host',
diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/service_inventory_link.tsx b/x-pack/plugins/apm/public/components/shared/links/apm/service_inventory_link.tsx
similarity index 92%
rename from x-pack/plugins/apm/public/components/shared/Links/apm/service_inventory_link.tsx
rename to x-pack/plugins/apm/public/components/shared/links/apm/service_inventory_link.tsx
index 0a51cb4cacd0b..c4a589dca3ad8 100644
--- a/x-pack/plugins/apm/public/components/shared/Links/apm/service_inventory_link.tsx
+++ b/x-pack/plugins/apm/public/components/shared/links/apm/service_inventory_link.tsx
@@ -6,7 +6,7 @@
*/
import { APMQueryParams } from '../url_helpers';
-import { useAPMHref } from './APMLink';
+import { useAPMHref } from './apm_link';
const persistedFilters: Array = ['host', 'agentName'];
diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/ServiceMapLink.tsx b/x-pack/plugins/apm/public/components/shared/links/apm/service_map_link.tsx
similarity index 92%
rename from x-pack/plugins/apm/public/components/shared/Links/apm/ServiceMapLink.tsx
rename to x-pack/plugins/apm/public/components/shared/links/apm/service_map_link.tsx
index 2c4dec9f4bcba..84eff7eb444bd 100644
--- a/x-pack/plugins/apm/public/components/shared/Links/apm/ServiceMapLink.tsx
+++ b/x-pack/plugins/apm/public/components/shared/links/apm/service_map_link.tsx
@@ -7,7 +7,7 @@
import { EuiLink } from '@elastic/eui';
import React from 'react';
-import { APMLinkExtendProps, useAPMHref } from './APMLink';
+import { APMLinkExtendProps, useAPMHref } from './apm_link';
export function useServiceMapHref(serviceName?: string) {
const path = serviceName
diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/ServiceNodeMetricOverviewLink.tsx b/x-pack/plugins/apm/public/components/shared/links/apm/service_node_metric_overview_link.tsx
similarity index 94%
rename from x-pack/plugins/apm/public/components/shared/Links/apm/ServiceNodeMetricOverviewLink.tsx
rename to x-pack/plugins/apm/public/components/shared/links/apm/service_node_metric_overview_link.tsx
index aad5756b70e7e..b8f0a0c53cb7d 100644
--- a/x-pack/plugins/apm/public/components/shared/Links/apm/ServiceNodeMetricOverviewLink.tsx
+++ b/x-pack/plugins/apm/public/components/shared/links/apm/service_node_metric_overview_link.tsx
@@ -8,7 +8,7 @@
import { EuiLink } from '@elastic/eui';
import React from 'react';
import { APMQueryParams } from '../url_helpers';
-import { APMLinkExtendProps, useAPMHref } from './APMLink';
+import { APMLinkExtendProps, useAPMHref } from './apm_link';
interface Props extends APMLinkExtendProps {
serviceName: string;
diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/ServiceNodeOverviewLink.tsx b/x-pack/plugins/apm/public/components/shared/links/apm/service_node_overview_link.tsx
similarity index 93%
rename from x-pack/plugins/apm/public/components/shared/Links/apm/ServiceNodeOverviewLink.tsx
rename to x-pack/plugins/apm/public/components/shared/links/apm/service_node_overview_link.tsx
index b76c468ae2153..e13a38143ef25 100644
--- a/x-pack/plugins/apm/public/components/shared/Links/apm/ServiceNodeOverviewLink.tsx
+++ b/x-pack/plugins/apm/public/components/shared/links/apm/service_node_overview_link.tsx
@@ -6,7 +6,7 @@
*/
import { APMQueryParams } from '../url_helpers';
-import { useAPMHref } from './APMLink';
+import { useAPMHref } from './apm_link';
const persistedFilters: Array = [
'host',
diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/service_profiling_link.tsx b/x-pack/plugins/apm/public/components/shared/links/apm/service_profiling_link.tsx
similarity index 93%
rename from x-pack/plugins/apm/public/components/shared/Links/apm/service_profiling_link.tsx
rename to x-pack/plugins/apm/public/components/shared/links/apm/service_profiling_link.tsx
index ab3b085e4e255..01e23cba48e04 100644
--- a/x-pack/plugins/apm/public/components/shared/Links/apm/service_profiling_link.tsx
+++ b/x-pack/plugins/apm/public/components/shared/links/apm/service_profiling_link.tsx
@@ -7,7 +7,7 @@
import { EuiLink } from '@elastic/eui';
import React from 'react';
-import { APMLinkExtendProps, useAPMHref } from './APMLink';
+import { APMLinkExtendProps, useAPMHref } from './apm_link';
interface ServiceProfilingLinkProps extends APMLinkExtendProps {
serviceName: string;
diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/service_transactions_overview_link.test.tsx b/x-pack/plugins/apm/public/components/shared/links/apm/service_transactions_overview_link.test.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Links/apm/service_transactions_overview_link.test.tsx
rename to x-pack/plugins/apm/public/components/shared/links/apm/service_transactions_overview_link.test.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/service_transactions_overview_link.tsx b/x-pack/plugins/apm/public/components/shared/links/apm/service_transactions_overview_link.tsx
similarity index 95%
rename from x-pack/plugins/apm/public/components/shared/Links/apm/service_transactions_overview_link.tsx
rename to x-pack/plugins/apm/public/components/shared/links/apm/service_transactions_overview_link.tsx
index 982d25802e202..b33f22cd9faf9 100644
--- a/x-pack/plugins/apm/public/components/shared/Links/apm/service_transactions_overview_link.tsx
+++ b/x-pack/plugins/apm/public/components/shared/links/apm/service_transactions_overview_link.tsx
@@ -8,7 +8,7 @@
import { EuiLink } from '@elastic/eui';
import React from 'react';
import { APMQueryParams } from '../url_helpers';
-import { APMLinkExtendProps, useAPMHref } from './APMLink';
+import { APMLinkExtendProps, useAPMHref } from './apm_link';
import { removeUndefinedProps } from '../../../../context/url_params_context/helpers';
const persistedFilters: Array = [
diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/TraceOverviewLink.tsx b/x-pack/plugins/apm/public/components/shared/links/apm/trace_overview_link.tsx
similarity index 92%
rename from x-pack/plugins/apm/public/components/shared/Links/apm/TraceOverviewLink.tsx
rename to x-pack/plugins/apm/public/components/shared/links/apm/trace_overview_link.tsx
index 92682a88efb17..9353de8162b08 100644
--- a/x-pack/plugins/apm/public/components/shared/Links/apm/TraceOverviewLink.tsx
+++ b/x-pack/plugins/apm/public/components/shared/links/apm/trace_overview_link.tsx
@@ -6,7 +6,7 @@
*/
import { APMQueryParams } from '../url_helpers';
-import { useAPMHref } from './APMLink';
+import { useAPMHref } from './apm_link';
const persistedFilters: Array = [
'transactionResult',
diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/transaction_detail_link.tsx b/x-pack/plugins/apm/public/components/shared/links/apm/transaction_detail_link.tsx
similarity index 97%
rename from x-pack/plugins/apm/public/components/shared/Links/apm/transaction_detail_link.tsx
rename to x-pack/plugins/apm/public/components/shared/links/apm/transaction_detail_link.tsx
index 9df035515b040..af299c6095e59 100644
--- a/x-pack/plugins/apm/public/components/shared/Links/apm/transaction_detail_link.tsx
+++ b/x-pack/plugins/apm/public/components/shared/links/apm/transaction_detail_link.tsx
@@ -9,7 +9,7 @@ import React from 'react';
import { useLocation } from 'react-router-dom';
import { EuiLink } from '@elastic/eui';
import { pickBy, identity } from 'lodash';
-import { getLegacyApmHref, APMLinkExtendProps } from './APMLink';
+import { getLegacyApmHref, APMLinkExtendProps } from './apm_link';
import { useLegacyUrlParams } from '../../../../context/url_params_context/use_url_params';
import { pickKeys } from '../../../../../common/utils/pick_keys';
import { APMQueryParams } from '../url_helpers';
diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/transaction_overview_link.test.tsx b/x-pack/plugins/apm/public/components/shared/links/apm/transaction_overview_link.test.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Links/apm/transaction_overview_link.test.tsx
rename to x-pack/plugins/apm/public/components/shared/links/apm/transaction_overview_link.test.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/transaction_overview_link.tsx b/x-pack/plugins/apm/public/components/shared/links/apm/transaction_overview_link.tsx
similarity index 95%
rename from x-pack/plugins/apm/public/components/shared/Links/apm/transaction_overview_link.tsx
rename to x-pack/plugins/apm/public/components/shared/links/apm/transaction_overview_link.tsx
index d3e40aebc1daf..bd0ac78b855f0 100644
--- a/x-pack/plugins/apm/public/components/shared/Links/apm/transaction_overview_link.tsx
+++ b/x-pack/plugins/apm/public/components/shared/links/apm/transaction_overview_link.tsx
@@ -10,7 +10,7 @@ import React from 'react';
import { useLocation } from 'react-router-dom';
import { removeUndefinedProps } from '../../../../context/url_params_context/helpers';
import { useApmPluginContext } from '../../../../context/apm_plugin/use_apm_plugin_context';
-import { APMLinkExtendProps, getLegacyApmHref } from './APMLink';
+import { APMLinkExtendProps, getLegacyApmHref } from './apm_link';
interface Props extends APMLinkExtendProps {
serviceName: string;
diff --git a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/__fixtures__/mock_transaction.json b/x-pack/plugins/apm/public/components/shared/links/discover_links/__fixtures__/mock_transaction.json
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/__fixtures__/mock_transaction.json
rename to x-pack/plugins/apm/public/components/shared/links/discover_links/__fixtures__/mock_transaction.json
diff --git a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/__snapshots__/DiscoverErrorButton.test.tsx.snap b/x-pack/plugins/apm/public/components/shared/links/discover_links/__snapshots__/discover_error_button.test.tsx.snap
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/__snapshots__/DiscoverErrorButton.test.tsx.snap
rename to x-pack/plugins/apm/public/components/shared/links/discover_links/__snapshots__/discover_error_button.test.tsx.snap
diff --git a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/__snapshots__/DiscoverErrorLink.test.tsx.snap b/x-pack/plugins/apm/public/components/shared/links/discover_links/__snapshots__/discover_error_link.test.tsx.snap
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/__snapshots__/DiscoverErrorLink.test.tsx.snap
rename to x-pack/plugins/apm/public/components/shared/links/discover_links/__snapshots__/discover_error_link.test.tsx.snap
diff --git a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/__snapshots__/discover_transaction_button.test.tsx.snap b/x-pack/plugins/apm/public/components/shared/links/discover_links/__snapshots__/discover_transaction_button.test.tsx.snap
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/__snapshots__/discover_transaction_button.test.tsx.snap
rename to x-pack/plugins/apm/public/components/shared/links/discover_links/__snapshots__/discover_transaction_button.test.tsx.snap
diff --git a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/__snapshots__/DiscoverTransactionLink.test.tsx.snap b/x-pack/plugins/apm/public/components/shared/links/discover_links/__snapshots__/discover_transaction_link.test.tsx.snap
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/__snapshots__/DiscoverTransactionLink.test.tsx.snap
rename to x-pack/plugins/apm/public/components/shared/links/discover_links/__snapshots__/discover_transaction_link.test.tsx.snap
diff --git a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverErrorButton.test.tsx b/x-pack/plugins/apm/public/components/shared/links/discover_links/discover_error_button.test.tsx
similarity index 96%
rename from x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverErrorButton.test.tsx
rename to x-pack/plugins/apm/public/components/shared/links/discover_links/discover_error_button.test.tsx
index 3d70653d58d19..3cbe8d7e31632 100644
--- a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverErrorButton.test.tsx
+++ b/x-pack/plugins/apm/public/components/shared/links/discover_links/discover_error_button.test.tsx
@@ -8,7 +8,7 @@
import { shallow, ShallowWrapper } from 'enzyme';
import React from 'react';
import { APMError } from '../../../../../typings/es_schemas/ui/apm_error';
-import { DiscoverErrorLink } from './DiscoverErrorLink';
+import { DiscoverErrorLink } from './discover_error_link';
describe('DiscoverErrorLink without kuery', () => {
let wrapper: ShallowWrapper;
diff --git a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverErrorLink.test.tsx b/x-pack/plugins/apm/public/components/shared/links/discover_links/discover_error_link.test.tsx
similarity index 96%
rename from x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverErrorLink.test.tsx
rename to x-pack/plugins/apm/public/components/shared/links/discover_links/discover_error_link.test.tsx
index 3d70653d58d19..3cbe8d7e31632 100644
--- a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverErrorLink.test.tsx
+++ b/x-pack/plugins/apm/public/components/shared/links/discover_links/discover_error_link.test.tsx
@@ -8,7 +8,7 @@
import { shallow, ShallowWrapper } from 'enzyme';
import React from 'react';
import { APMError } from '../../../../../typings/es_schemas/ui/apm_error';
-import { DiscoverErrorLink } from './DiscoverErrorLink';
+import { DiscoverErrorLink } from './discover_error_link';
describe('DiscoverErrorLink without kuery', () => {
let wrapper: ShallowWrapper;
diff --git a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverErrorLink.tsx b/x-pack/plugins/apm/public/components/shared/links/discover_links/discover_error_link.tsx
similarity index 96%
rename from x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverErrorLink.tsx
rename to x-pack/plugins/apm/public/components/shared/links/discover_links/discover_error_link.tsx
index 467a6d604ee60..c7d35e7c983e8 100644
--- a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverErrorLink.tsx
+++ b/x-pack/plugins/apm/public/components/shared/links/discover_links/discover_error_link.tsx
@@ -11,7 +11,7 @@ import {
SERVICE_NAME,
} from '../../../../../common/elasticsearch_fieldnames';
import { APMError } from '../../../../../typings/es_schemas/ui/apm_error';
-import { DiscoverLink } from './DiscoverLink';
+import { DiscoverLink } from './discover_link';
function getDiscoverQuery(error: APMError, kuery?: string) {
const serviceName = error.service.name;
diff --git a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverLink.tsx b/x-pack/plugins/apm/public/components/shared/links/discover_links/discover_link.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverLink.tsx
rename to x-pack/plugins/apm/public/components/shared/links/discover_links/discover_link.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverLinks.integration.test.tsx b/x-pack/plugins/apm/public/components/shared/links/discover_links/discover_links.integration.test.tsx
similarity index 95%
rename from x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverLinks.integration.test.tsx
rename to x-pack/plugins/apm/public/components/shared/links/discover_links/discover_links.integration.test.tsx
index 53ea5735c8b22..4e47a1d4217de 100644
--- a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverLinks.integration.test.tsx
+++ b/x-pack/plugins/apm/public/components/shared/links/discover_links/discover_links.integration.test.tsx
@@ -11,9 +11,9 @@ import { APMError } from '../../../../../typings/es_schemas/ui/apm_error';
import { Span } from '../../../../../typings/es_schemas/ui/span';
import { Transaction } from '../../../../../typings/es_schemas/ui/transaction';
import { getRenderedHref } from '../../../../utils/testHelpers';
-import { DiscoverErrorLink } from './DiscoverErrorLink';
-import { DiscoverSpanLink } from './DiscoverSpanLink';
-import { DiscoverTransactionLink } from './DiscoverTransactionLink';
+import { DiscoverErrorLink } from './discover_error_link';
+import { DiscoverSpanLink } from './discover_span_link';
+import { DiscoverTransactionLink } from './discover_transaction_link';
describe('DiscoverLinks', () => {
it('produces the correct URL for a transaction', async () => {
diff --git a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverSpanLink.tsx b/x-pack/plugins/apm/public/components/shared/links/discover_links/discover_span_link.tsx
similarity index 94%
rename from x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverSpanLink.tsx
rename to x-pack/plugins/apm/public/components/shared/links/discover_links/discover_span_link.tsx
index 631ac6e2129f0..f943e6fb49985 100644
--- a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverSpanLink.tsx
+++ b/x-pack/plugins/apm/public/components/shared/links/discover_links/discover_span_link.tsx
@@ -8,7 +8,7 @@
import React, { ReactNode } from 'react';
import { SPAN_ID } from '../../../../../common/elasticsearch_fieldnames';
import { Span } from '../../../../../typings/es_schemas/ui/span';
-import { DiscoverLink } from './DiscoverLink';
+import { DiscoverLink } from './discover_link';
function getDiscoverQuery(span: Span) {
const query = `${SPAN_ID}:"${span.span.id}"`;
diff --git a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/discover_transaction_button.test.tsx b/x-pack/plugins/apm/public/components/shared/links/discover_links/discover_transaction_button.test.tsx
similarity index 96%
rename from x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/discover_transaction_button.test.tsx
rename to x-pack/plugins/apm/public/components/shared/links/discover_links/discover_transaction_button.test.tsx
index b8278f3d285f4..5505036087dbf 100644
--- a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/discover_transaction_button.test.tsx
+++ b/x-pack/plugins/apm/public/components/shared/links/discover_links/discover_transaction_button.test.tsx
@@ -11,7 +11,7 @@ import { Transaction } from '../../../../../typings/es_schemas/ui/transaction';
import {
DiscoverTransactionLink,
getDiscoverQuery,
-} from './DiscoverTransactionLink';
+} from './discover_transaction_link';
import mockTransaction from './__fixtures__/mock_transaction.json';
describe('DiscoverTransactionLink component', () => {
diff --git a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverTransactionLink.test.tsx b/x-pack/plugins/apm/public/components/shared/links/discover_links/discover_transaction_link.test.tsx
similarity index 93%
rename from x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverTransactionLink.test.tsx
rename to x-pack/plugins/apm/public/components/shared/links/discover_links/discover_transaction_link.test.tsx
index a73f569827aa5..498a7fd26c138 100644
--- a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverTransactionLink.test.tsx
+++ b/x-pack/plugins/apm/public/components/shared/links/discover_links/discover_transaction_link.test.tsx
@@ -8,7 +8,7 @@
import { Transaction } from '../../../../../typings/es_schemas/ui/transaction';
// @ts-expect-error
import configureStore from '../../../../../store/config/configureStore';
-import { getDiscoverQuery } from './DiscoverTransactionLink';
+import { getDiscoverQuery } from './discover_transaction_link';
function getMockTransaction() {
return {
diff --git a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverTransactionLink.tsx b/x-pack/plugins/apm/public/components/shared/links/discover_links/discover_transaction_link.tsx
similarity index 96%
rename from x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverTransactionLink.tsx
rename to x-pack/plugins/apm/public/components/shared/links/discover_links/discover_transaction_link.tsx
index 21e7a1e45263f..d776572cc9e32 100644
--- a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/DiscoverTransactionLink.tsx
+++ b/x-pack/plugins/apm/public/components/shared/links/discover_links/discover_transaction_link.tsx
@@ -12,7 +12,7 @@ import {
TRANSACTION_ID,
} from '../../../../../common/elasticsearch_fieldnames';
import { Transaction } from '../../../../../typings/es_schemas/ui/transaction';
-import { DiscoverLink } from './DiscoverLink';
+import { DiscoverLink } from './discover_link';
export function getDiscoverQuery(transaction: Transaction) {
const transactionId = transaction.transaction.id;
diff --git a/x-pack/plugins/apm/public/components/shared/Links/ElasticDocsLink.tsx b/x-pack/plugins/apm/public/components/shared/links/elastic_docs_link.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Links/ElasticDocsLink.tsx
rename to x-pack/plugins/apm/public/components/shared/links/elastic_docs_link.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/Links/InfraLink.test.tsx b/x-pack/plugins/apm/public/components/shared/links/infra_link.test.tsx
similarity index 94%
rename from x-pack/plugins/apm/public/components/shared/Links/InfraLink.test.tsx
rename to x-pack/plugins/apm/public/components/shared/links/infra_link.test.tsx
index c5a8c3299daa5..8301bd844b5cb 100644
--- a/x-pack/plugins/apm/public/components/shared/Links/InfraLink.test.tsx
+++ b/x-pack/plugins/apm/public/components/shared/links/infra_link.test.tsx
@@ -8,7 +8,7 @@
import { Location } from 'history';
import React from 'react';
import { getRenderedHref } from '../../../utils/testHelpers';
-import { InfraLink } from './InfraLink';
+import { InfraLink } from './infra_link';
test('InfraLink produces the correct URL', async () => {
const href = await getRenderedHref(
diff --git a/x-pack/plugins/apm/public/components/shared/Links/InfraLink.tsx b/x-pack/plugins/apm/public/components/shared/links/infra_link.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Links/InfraLink.tsx
rename to x-pack/plugins/apm/public/components/shared/links/infra_link.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/Links/kibana.ts b/x-pack/plugins/apm/public/components/shared/links/kibana.ts
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Links/kibana.ts
rename to x-pack/plugins/apm/public/components/shared/links/kibana.ts
diff --git a/x-pack/plugins/apm/public/components/shared/Links/MachineLearningLinks/MLExplorerLink.test.tsx b/x-pack/plugins/apm/public/components/shared/links/machine_learning_links/mlexplorer_link.test.tsx
similarity index 97%
rename from x-pack/plugins/apm/public/components/shared/Links/MachineLearningLinks/MLExplorerLink.test.tsx
rename to x-pack/plugins/apm/public/components/shared/links/machine_learning_links/mlexplorer_link.test.tsx
index 44e33e6bf419d..9a8f2bd98106b 100644
--- a/x-pack/plugins/apm/public/components/shared/Links/MachineLearningLinks/MLExplorerLink.test.tsx
+++ b/x-pack/plugins/apm/public/components/shared/links/machine_learning_links/mlexplorer_link.test.tsx
@@ -8,7 +8,7 @@
import { Location } from 'history';
import React from 'react';
import { getRenderedHref } from '../../../../utils/testHelpers';
-import { MLExplorerLink } from './MLExplorerLink';
+import { MLExplorerLink } from './mlexplorer_link';
describe('MLExplorerLink', () => {
it('should produce the correct URL with jobId', async () => {
diff --git a/x-pack/plugins/apm/public/components/shared/Links/MachineLearningLinks/MLExplorerLink.tsx b/x-pack/plugins/apm/public/components/shared/links/machine_learning_links/mlexplorer_link.tsx
similarity index 96%
rename from x-pack/plugins/apm/public/components/shared/Links/MachineLearningLinks/MLExplorerLink.tsx
rename to x-pack/plugins/apm/public/components/shared/links/machine_learning_links/mlexplorer_link.tsx
index 72a29a079bc67..541b00f8291b0 100644
--- a/x-pack/plugins/apm/public/components/shared/Links/MachineLearningLinks/MLExplorerLink.tsx
+++ b/x-pack/plugins/apm/public/components/shared/links/machine_learning_links/mlexplorer_link.tsx
@@ -11,7 +11,7 @@ import { UI_SETTINGS } from '../../../../../../../../src/plugins/data/common';
import { useApmPluginContext } from '../../../../context/apm_plugin/use_apm_plugin_context';
import { useMlHref, ML_PAGES } from '../../../../../../ml/public';
import { useLegacyUrlParams } from '../../../../context/url_params_context/use_url_params';
-import { TimePickerRefreshInterval } from '../../DatePicker/typings';
+import { TimePickerRefreshInterval } from '../../date_picker/typings';
interface Props {
children?: ReactNode;
diff --git a/x-pack/plugins/apm/public/components/shared/Links/MachineLearningLinks/MLManageJobsLink.test.tsx b/x-pack/plugins/apm/public/components/shared/links/machine_learning_links/mlmanage_jobs_link.test.tsx
similarity index 93%
rename from x-pack/plugins/apm/public/components/shared/Links/MachineLearningLinks/MLManageJobsLink.test.tsx
rename to x-pack/plugins/apm/public/components/shared/links/machine_learning_links/mlmanage_jobs_link.test.tsx
index edea1f916eb18..8f7ff4f11ab22 100644
--- a/x-pack/plugins/apm/public/components/shared/Links/MachineLearningLinks/MLManageJobsLink.test.tsx
+++ b/x-pack/plugins/apm/public/components/shared/links/machine_learning_links/mlmanage_jobs_link.test.tsx
@@ -8,7 +8,7 @@
import { Location } from 'history';
import React from 'react';
import { getRenderedHref } from '../../../../utils/testHelpers';
-import { MLManageJobsLink } from './MLManageJobsLink';
+import { MLManageJobsLink } from './mlmanage_jobs_link';
test('MLManageJobsLink', async () => {
const href = await getRenderedHref(() => , {
diff --git a/x-pack/plugins/apm/public/components/shared/Links/MachineLearningLinks/MLManageJobsLink.tsx b/x-pack/plugins/apm/public/components/shared/links/machine_learning_links/mlmanage_jobs_link.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Links/MachineLearningLinks/MLManageJobsLink.tsx
rename to x-pack/plugins/apm/public/components/shared/links/machine_learning_links/mlmanage_jobs_link.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/Links/MachineLearningLinks/MLSingleMetricLink.test.tsx b/x-pack/plugins/apm/public/components/shared/links/machine_learning_links/mlsingle_metric_link.test.tsx
similarity index 97%
rename from x-pack/plugins/apm/public/components/shared/Links/MachineLearningLinks/MLSingleMetricLink.test.tsx
rename to x-pack/plugins/apm/public/components/shared/links/machine_learning_links/mlsingle_metric_link.test.tsx
index cbafbd3fde2fa..ddcd5503853fe 100644
--- a/x-pack/plugins/apm/public/components/shared/Links/MachineLearningLinks/MLSingleMetricLink.test.tsx
+++ b/x-pack/plugins/apm/public/components/shared/links/machine_learning_links/mlsingle_metric_link.test.tsx
@@ -8,7 +8,7 @@
import { Location } from 'history';
import React from 'react';
import { getRenderedHref } from '../../../../utils/testHelpers';
-import { MLSingleMetricLink } from './MLSingleMetricLink';
+import { MLSingleMetricLink } from './mlsingle_metric_link';
describe('MLSingleMetricLink', () => {
it('should produce the correct URL with jobId', async () => {
diff --git a/x-pack/plugins/apm/public/components/shared/Links/MachineLearningLinks/MLSingleMetricLink.tsx b/x-pack/plugins/apm/public/components/shared/links/machine_learning_links/mlsingle_metric_link.tsx
similarity index 97%
rename from x-pack/plugins/apm/public/components/shared/Links/MachineLearningLinks/MLSingleMetricLink.tsx
rename to x-pack/plugins/apm/public/components/shared/links/machine_learning_links/mlsingle_metric_link.tsx
index 2964a8e2578c7..ef92691336c34 100644
--- a/x-pack/plugins/apm/public/components/shared/Links/MachineLearningLinks/MLSingleMetricLink.tsx
+++ b/x-pack/plugins/apm/public/components/shared/links/machine_learning_links/mlsingle_metric_link.tsx
@@ -11,7 +11,7 @@ import { UI_SETTINGS } from '../../../../../../../../src/plugins/data/common';
import { useApmPluginContext } from '../../../../context/apm_plugin/use_apm_plugin_context';
import { useMlHref, ML_PAGES } from '../../../../../../ml/public';
import { useLegacyUrlParams } from '../../../../context/url_params_context/use_url_params';
-import { TimePickerRefreshInterval } from '../../DatePicker/typings';
+import { TimePickerRefreshInterval } from '../../date_picker/typings';
interface Props {
children?: ReactNode;
diff --git a/x-pack/plugins/apm/public/components/shared/Links/rison_helpers.test.ts b/x-pack/plugins/apm/public/components/shared/links/rison_helpers.test.ts
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Links/rison_helpers.test.ts
rename to x-pack/plugins/apm/public/components/shared/links/rison_helpers.test.ts
diff --git a/x-pack/plugins/apm/public/components/shared/Links/rison_helpers.ts b/x-pack/plugins/apm/public/components/shared/links/rison_helpers.ts
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Links/rison_helpers.ts
rename to x-pack/plugins/apm/public/components/shared/links/rison_helpers.ts
diff --git a/x-pack/plugins/apm/public/components/shared/Links/SetupInstructionsLink.tsx b/x-pack/plugins/apm/public/components/shared/links/setup_instructions_link.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Links/SetupInstructionsLink.tsx
rename to x-pack/plugins/apm/public/components/shared/links/setup_instructions_link.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/Links/url_helpers.test.tsx b/x-pack/plugins/apm/public/components/shared/links/url_helpers.test.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Links/url_helpers.test.tsx
rename to x-pack/plugins/apm/public/components/shared/links/url_helpers.test.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/Links/url_helpers.ts b/x-pack/plugins/apm/public/components/shared/links/url_helpers.ts
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Links/url_helpers.ts
rename to x-pack/plugins/apm/public/components/shared/links/url_helpers.ts
diff --git a/x-pack/plugins/apm/public/components/shared/LoadingStatePrompt.tsx b/x-pack/plugins/apm/public/components/shared/loading_state_prompt.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/LoadingStatePrompt.tsx
rename to x-pack/plugins/apm/public/components/shared/loading_state_prompt.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/managed_table/index.tsx b/x-pack/plugins/apm/public/components/shared/managed_table/index.tsx
index 03ae13c06c613..16ab8cb1d9202 100644
--- a/x-pack/plugins/apm/public/components/shared/managed_table/index.tsx
+++ b/x-pack/plugins/apm/public/components/shared/managed_table/index.tsx
@@ -11,7 +11,7 @@ import { orderBy } from 'lodash';
import React, { ReactNode, useCallback, useMemo } from 'react';
import { useHistory } from 'react-router-dom';
import { useLegacyUrlParams } from '../../../context/url_params_context/use_url_params';
-import { fromQuery, toQuery } from '../Links/url_helpers';
+import { fromQuery, toQuery } from '../links/url_helpers';
// TODO: this should really be imported from EUI
export interface ITableColumn {
diff --git a/x-pack/plugins/apm/public/components/shared/MetadataTable/ErrorMetadata/index.tsx b/x-pack/plugins/apm/public/components/shared/metadata_table/error_metadata/index.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/MetadataTable/ErrorMetadata/index.tsx
rename to x-pack/plugins/apm/public/components/shared/metadata_table/error_metadata/index.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/MetadataTable/helper.test.ts b/x-pack/plugins/apm/public/components/shared/metadata_table/helper.test.ts
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/MetadataTable/helper.test.ts
rename to x-pack/plugins/apm/public/components/shared/metadata_table/helper.test.ts
diff --git a/x-pack/plugins/apm/public/components/shared/MetadataTable/helper.ts b/x-pack/plugins/apm/public/components/shared/metadata_table/helper.ts
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/MetadataTable/helper.ts
rename to x-pack/plugins/apm/public/components/shared/metadata_table/helper.ts
diff --git a/x-pack/plugins/apm/public/components/shared/MetadataTable/index.tsx b/x-pack/plugins/apm/public/components/shared/metadata_table/index.tsx
similarity index 96%
rename from x-pack/plugins/apm/public/components/shared/MetadataTable/index.tsx
rename to x-pack/plugins/apm/public/components/shared/metadata_table/index.tsx
index 5e2c180bcfd55..ab6c132c61e13 100644
--- a/x-pack/plugins/apm/public/components/shared/MetadataTable/index.tsx
+++ b/x-pack/plugins/apm/public/components/shared/metadata_table/index.tsx
@@ -21,10 +21,10 @@ import React, { useCallback } from 'react';
import { useHistory, useLocation } from 'react-router-dom';
import { EuiLoadingSpinner } from '@elastic/eui';
import { useLegacyUrlParams } from '../../../context/url_params_context/use_url_params';
-import { HeightRetainer } from '../HeightRetainer';
-import { fromQuery, toQuery } from '../Links/url_helpers';
+import { HeightRetainer } from '../height_retainer';
+import { fromQuery, toQuery } from '../links/url_helpers';
import { filterSectionsByTerm } from './helper';
-import { Section } from './Section';
+import { Section } from './section';
import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_context';
import { SectionDescriptor } from './types';
diff --git a/x-pack/plugins/apm/public/components/shared/MetadataTable/MetadataTable.test.tsx b/x-pack/plugins/apm/public/components/shared/metadata_table/metadata_table.test.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/MetadataTable/MetadataTable.test.tsx
rename to x-pack/plugins/apm/public/components/shared/metadata_table/metadata_table.test.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/MetadataTable/Section.test.tsx b/x-pack/plugins/apm/public/components/shared/metadata_table/section.test.tsx
similarity index 94%
rename from x-pack/plugins/apm/public/components/shared/MetadataTable/Section.test.tsx
rename to x-pack/plugins/apm/public/components/shared/metadata_table/section.test.tsx
index ed816b1c7a337..1d14d04a2be65 100644
--- a/x-pack/plugins/apm/public/components/shared/MetadataTable/Section.test.tsx
+++ b/x-pack/plugins/apm/public/components/shared/metadata_table/section.test.tsx
@@ -7,7 +7,7 @@
import React from 'react';
import { render } from '@testing-library/react';
-import { Section } from './Section';
+import { Section } from './section';
import { expectTextsInDocument } from '../../../utils/testHelpers';
describe('Section', () => {
diff --git a/x-pack/plugins/apm/public/components/shared/MetadataTable/Section.tsx b/x-pack/plugins/apm/public/components/shared/metadata_table/section.tsx
similarity index 94%
rename from x-pack/plugins/apm/public/components/shared/MetadataTable/Section.tsx
rename to x-pack/plugins/apm/public/components/shared/metadata_table/section.tsx
index 03ae237f470c3..4093d8128c7ca 100644
--- a/x-pack/plugins/apm/public/components/shared/MetadataTable/Section.tsx
+++ b/x-pack/plugins/apm/public/components/shared/metadata_table/section.tsx
@@ -9,7 +9,7 @@ import React from 'react';
import { isEmpty } from 'lodash';
import { i18n } from '@kbn/i18n';
import { EuiText } from '@elastic/eui';
-import { KeyValueTable } from '../KeyValueTable';
+import { KeyValueTable } from '../key_value_table';
interface Props {
properties: Array<{ field: string; value: string[] | number[] }>;
diff --git a/x-pack/plugins/apm/public/components/shared/MetadataTable/SpanMetadata/index.tsx b/x-pack/plugins/apm/public/components/shared/metadata_table/span_metadata/index.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/MetadataTable/SpanMetadata/index.tsx
rename to x-pack/plugins/apm/public/components/shared/metadata_table/span_metadata/index.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/MetadataTable/TransactionMetadata/index.tsx b/x-pack/plugins/apm/public/components/shared/metadata_table/transaction_metadata/index.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/MetadataTable/TransactionMetadata/index.tsx
rename to x-pack/plugins/apm/public/components/shared/metadata_table/transaction_metadata/index.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/MetadataTable/types.ts b/x-pack/plugins/apm/public/components/shared/metadata_table/types.ts
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/MetadataTable/types.ts
rename to x-pack/plugins/apm/public/components/shared/metadata_table/types.ts
diff --git a/x-pack/plugins/apm/public/components/shared/ml_callout/index.tsx b/x-pack/plugins/apm/public/components/shared/ml_callout/index.tsx
index 926be5ef93cf7..9fa8bb5f04960 100644
--- a/x-pack/plugins/apm/public/components/shared/ml_callout/index.tsx
+++ b/x-pack/plugins/apm/public/components/shared/ml_callout/index.tsx
@@ -16,7 +16,7 @@ import { i18n } from '@kbn/i18n';
import React, { useState } from 'react';
import { AnomalyDetectionSetupState } from '../../../../common/anomaly_detection/get_anomaly_detection_setup_state';
import { useMlManageJobsHref } from '../../../hooks/use_ml_manage_jobs_href';
-import { APMLink } from '../Links/apm/APMLink';
+import { APMLink } from '../links/apm/apm_link';
export function shouldDisplayMlCallout(
anomalyDetectionSetupState: AnomalyDetectionSetupState
diff --git a/x-pack/plugins/apm/public/components/shared/search_bar.test.tsx b/x-pack/plugins/apm/public/components/shared/search_bar.test.tsx
index db30e73c86dc7..d91af5b11c49b 100644
--- a/x-pack/plugins/apm/public/components/shared/search_bar.test.tsx
+++ b/x-pack/plugins/apm/public/components/shared/search_bar.test.tsx
@@ -17,7 +17,7 @@ import type { ApmUrlParams } from '../../context/url_params_context/types';
import * as useFetcherHook from '../../hooks/use_fetcher';
import * as useServiceTransactionTypesHook from '../../context/apm_service/use_service_transaction_types_fetcher';
import { renderWithTheme } from '../../utils/testHelpers';
-import { fromQuery } from './Links/url_helpers';
+import { fromQuery } from './links/url_helpers';
import { CoreStart } from 'kibana/public';
import { SearchBar } from './search_bar';
diff --git a/x-pack/plugins/apm/public/components/shared/search_bar.tsx b/x-pack/plugins/apm/public/components/shared/search_bar.tsx
index 1a6e9a803d735..f1d82e2e307e1 100644
--- a/x-pack/plugins/apm/public/components/shared/search_bar.tsx
+++ b/x-pack/plugins/apm/public/components/shared/search_bar.tsx
@@ -17,7 +17,7 @@ import { useTimeRangeId } from '../../context/time_range_id/use_time_range_id';
import { toBoolean, toNumber } from '../../context/url_params_context/helpers';
import { useApmParams } from '../../hooks/use_apm_params';
import { useBreakpoints } from '../../hooks/use_breakpoints';
-import { DatePicker } from './DatePicker';
+import { DatePicker } from './date_picker';
import { KueryBar } from './kuery_bar';
import { TimeComparison } from './time_comparison';
import { TransactionTypeSelect } from './transaction_type_select';
diff --git a/x-pack/plugins/apm/public/components/shared/SelectWithPlaceholder/index.tsx b/x-pack/plugins/apm/public/components/shared/select_with_placeholder/index.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/SelectWithPlaceholder/index.tsx
rename to x-pack/plugins/apm/public/components/shared/select_with_placeholder/index.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/Stacktrace/Context.tsx b/x-pack/plugins/apm/public/components/shared/stacktrace/Context.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Stacktrace/Context.tsx
rename to x-pack/plugins/apm/public/components/shared/stacktrace/Context.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/Stacktrace/Stackframe.test.tsx b/x-pack/plugins/apm/public/components/shared/stacktrace/Stackframe.test.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Stacktrace/Stackframe.test.tsx
rename to x-pack/plugins/apm/public/components/shared/stacktrace/Stackframe.test.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/Stacktrace/Stackframe.tsx b/x-pack/plugins/apm/public/components/shared/stacktrace/Stackframe.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Stacktrace/Stackframe.tsx
rename to x-pack/plugins/apm/public/components/shared/stacktrace/Stackframe.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/Stacktrace/Variables.tsx b/x-pack/plugins/apm/public/components/shared/stacktrace/Variables.tsx
similarity index 96%
rename from x-pack/plugins/apm/public/components/shared/Stacktrace/Variables.tsx
rename to x-pack/plugins/apm/public/components/shared/stacktrace/Variables.tsx
index a43cd26e7f94a..3d92f3c584f45 100644
--- a/x-pack/plugins/apm/public/components/shared/Stacktrace/Variables.tsx
+++ b/x-pack/plugins/apm/public/components/shared/stacktrace/Variables.tsx
@@ -10,7 +10,7 @@ import { i18n } from '@kbn/i18n';
import React from 'react';
import { euiStyled } from '../../../../../../../src/plugins/kibana_react/common';
import { Stackframe } from '../../../../typings/es_schemas/raw/fields/stackframe';
-import { KeyValueTable } from '../KeyValueTable';
+import { KeyValueTable } from '../key_value_table';
import { flattenObject } from '../../../utils/flattenObject';
const VariablesContainer = euiStyled.div`
diff --git a/x-pack/plugins/apm/public/components/shared/Stacktrace/__fixtures__/stacktraces.json b/x-pack/plugins/apm/public/components/shared/stacktrace/__fixtures__/stacktraces.json
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Stacktrace/__fixtures__/stacktraces.json
rename to x-pack/plugins/apm/public/components/shared/stacktrace/__fixtures__/stacktraces.json
diff --git a/x-pack/plugins/apm/public/components/shared/Stacktrace/cause_stacktrace.test.tsx b/x-pack/plugins/apm/public/components/shared/stacktrace/cause_stacktrace.test.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Stacktrace/cause_stacktrace.test.tsx
rename to x-pack/plugins/apm/public/components/shared/stacktrace/cause_stacktrace.test.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/Stacktrace/cause_stacktrace.tsx b/x-pack/plugins/apm/public/components/shared/stacktrace/cause_stacktrace.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Stacktrace/cause_stacktrace.tsx
rename to x-pack/plugins/apm/public/components/shared/stacktrace/cause_stacktrace.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/Stacktrace/frame_heading.test.tsx b/x-pack/plugins/apm/public/components/shared/stacktrace/frame_heading.test.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Stacktrace/frame_heading.test.tsx
rename to x-pack/plugins/apm/public/components/shared/stacktrace/frame_heading.test.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/Stacktrace/frame_heading.tsx b/x-pack/plugins/apm/public/components/shared/stacktrace/frame_heading.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Stacktrace/frame_heading.tsx
rename to x-pack/plugins/apm/public/components/shared/stacktrace/frame_heading.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/Stacktrace/frame_heading_renderers/c_sharp_frame_heading_renderer.tsx b/x-pack/plugins/apm/public/components/shared/stacktrace/frame_heading_renderers/c_sharp_frame_heading_renderer.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Stacktrace/frame_heading_renderers/c_sharp_frame_heading_renderer.tsx
rename to x-pack/plugins/apm/public/components/shared/stacktrace/frame_heading_renderers/c_sharp_frame_heading_renderer.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/Stacktrace/frame_heading_renderers/default_frame_heading_renderer.tsx b/x-pack/plugins/apm/public/components/shared/stacktrace/frame_heading_renderers/default_frame_heading_renderer.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Stacktrace/frame_heading_renderers/default_frame_heading_renderer.tsx
rename to x-pack/plugins/apm/public/components/shared/stacktrace/frame_heading_renderers/default_frame_heading_renderer.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/Stacktrace/frame_heading_renderers/index.ts b/x-pack/plugins/apm/public/components/shared/stacktrace/frame_heading_renderers/index.ts
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Stacktrace/frame_heading_renderers/index.ts
rename to x-pack/plugins/apm/public/components/shared/stacktrace/frame_heading_renderers/index.ts
diff --git a/x-pack/plugins/apm/public/components/shared/Stacktrace/frame_heading_renderers/java_frame_heading_renderer.tsx b/x-pack/plugins/apm/public/components/shared/stacktrace/frame_heading_renderers/java_frame_heading_renderer.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Stacktrace/frame_heading_renderers/java_frame_heading_renderer.tsx
rename to x-pack/plugins/apm/public/components/shared/stacktrace/frame_heading_renderers/java_frame_heading_renderer.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/Stacktrace/frame_heading_renderers/java_script_frame_heading_renderer.tsx b/x-pack/plugins/apm/public/components/shared/stacktrace/frame_heading_renderers/java_script_frame_heading_renderer.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Stacktrace/frame_heading_renderers/java_script_frame_heading_renderer.tsx
rename to x-pack/plugins/apm/public/components/shared/stacktrace/frame_heading_renderers/java_script_frame_heading_renderer.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/Stacktrace/frame_heading_renderers/ruby_frame_heading_renderer.tsx b/x-pack/plugins/apm/public/components/shared/stacktrace/frame_heading_renderers/ruby_frame_heading_renderer.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Stacktrace/frame_heading_renderers/ruby_frame_heading_renderer.tsx
rename to x-pack/plugins/apm/public/components/shared/stacktrace/frame_heading_renderers/ruby_frame_heading_renderer.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/Stacktrace/index.tsx b/x-pack/plugins/apm/public/components/shared/stacktrace/index.tsx
similarity index 97%
rename from x-pack/plugins/apm/public/components/shared/Stacktrace/index.tsx
rename to x-pack/plugins/apm/public/components/shared/stacktrace/index.tsx
index 3395b22988e8c..de24482c06d50 100644
--- a/x-pack/plugins/apm/public/components/shared/Stacktrace/index.tsx
+++ b/x-pack/plugins/apm/public/components/shared/stacktrace/index.tsx
@@ -9,7 +9,7 @@ import { i18n } from '@kbn/i18n';
import { isEmpty, last } from 'lodash';
import React, { Fragment } from 'react';
import { Stackframe } from '../../../../typings/es_schemas/raw/fields/stackframe';
-import { EmptyMessage } from '../../shared/EmptyMessage';
+import { EmptyMessage } from '../../shared/empty_message';
import { LibraryStacktrace } from './library_stacktrace';
import { Stackframe as StackframeComponent } from './Stackframe';
diff --git a/x-pack/plugins/apm/public/components/shared/Stacktrace/library_stacktrace.test.tsx b/x-pack/plugins/apm/public/components/shared/stacktrace/library_stacktrace.test.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Stacktrace/library_stacktrace.test.tsx
rename to x-pack/plugins/apm/public/components/shared/stacktrace/library_stacktrace.test.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/Stacktrace/library_stacktrace.tsx b/x-pack/plugins/apm/public/components/shared/stacktrace/library_stacktrace.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Stacktrace/library_stacktrace.tsx
rename to x-pack/plugins/apm/public/components/shared/stacktrace/library_stacktrace.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/Stacktrace/stacktrace.test.ts b/x-pack/plugins/apm/public/components/shared/stacktrace/stacktrace.test.ts
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Stacktrace/stacktrace.test.ts
rename to x-pack/plugins/apm/public/components/shared/stacktrace/stacktrace.test.ts
diff --git a/x-pack/plugins/apm/public/components/shared/Summary/__fixtures__/transactions.ts b/x-pack/plugins/apm/public/components/shared/summary/__fixtures__/transactions.ts
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Summary/__fixtures__/transactions.ts
rename to x-pack/plugins/apm/public/components/shared/summary/__fixtures__/transactions.ts
diff --git a/x-pack/plugins/apm/public/components/shared/Summary/CompositeSpanDurationSummaryItem.tsx b/x-pack/plugins/apm/public/components/shared/summary/composite_span_duration_summary_item.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Summary/CompositeSpanDurationSummaryItem.tsx
rename to x-pack/plugins/apm/public/components/shared/summary/composite_span_duration_summary_item.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/Summary/DurationSummaryItem.tsx b/x-pack/plugins/apm/public/components/shared/summary/duration_summary_item.tsx
similarity index 96%
rename from x-pack/plugins/apm/public/components/shared/Summary/DurationSummaryItem.tsx
rename to x-pack/plugins/apm/public/components/shared/summary/duration_summary_item.tsx
index e0710556096c9..9993fd27b6172 100644
--- a/x-pack/plugins/apm/public/components/shared/Summary/DurationSummaryItem.tsx
+++ b/x-pack/plugins/apm/public/components/shared/summary/duration_summary_item.tsx
@@ -9,7 +9,7 @@ import React from 'react';
import { i18n } from '@kbn/i18n';
import { EuiToolTip, EuiText } from '@elastic/eui';
import { asDuration } from '../../../../common/utils/formatters';
-import { PercentOfParent } from '../../app/transaction_details/waterfall_with_summary/PercentOfParent';
+import { PercentOfParent } from '../../app/transaction_details/waterfall_with_summary/percent_of_parent';
interface Props {
duration: number;
diff --git a/x-pack/plugins/apm/public/components/shared/Summary/error_count_summary_item_badge.test.tsx b/x-pack/plugins/apm/public/components/shared/summary/error_count_summary_item_badge.test.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Summary/error_count_summary_item_badge.test.tsx
rename to x-pack/plugins/apm/public/components/shared/summary/error_count_summary_item_badge.test.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/Summary/error_count_summary_item_badge.tsx b/x-pack/plugins/apm/public/components/shared/summary/error_count_summary_item_badge.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Summary/error_count_summary_item_badge.tsx
rename to x-pack/plugins/apm/public/components/shared/summary/error_count_summary_item_badge.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/Summary/http_info_summary_item/http_info_summary_item.test.tsx b/x-pack/plugins/apm/public/components/shared/summary/http_info_summary_item/http_info_summary_item.test.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Summary/http_info_summary_item/http_info_summary_item.test.tsx
rename to x-pack/plugins/apm/public/components/shared/summary/http_info_summary_item/http_info_summary_item.test.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/Summary/http_info_summary_item/index.tsx b/x-pack/plugins/apm/public/components/shared/summary/http_info_summary_item/index.tsx
similarity index 96%
rename from x-pack/plugins/apm/public/components/shared/Summary/http_info_summary_item/index.tsx
rename to x-pack/plugins/apm/public/components/shared/summary/http_info_summary_item/index.tsx
index d10d15f8240a1..51e574324dfa6 100644
--- a/x-pack/plugins/apm/public/components/shared/Summary/http_info_summary_item/index.tsx
+++ b/x-pack/plugins/apm/public/components/shared/summary/http_info_summary_item/index.tsx
@@ -10,7 +10,7 @@ import { i18n } from '@kbn/i18n';
import React from 'react';
import { euiStyled } from '../../../../../../../../src/plugins/kibana_react/common';
import { truncate, unit } from '../../../../utils/style';
-import { HttpStatusBadge } from '../HttpStatusBadge';
+import { HttpStatusBadge } from '../http_status_badge';
const HttpInfoBadge = euiStyled(EuiBadge)`
margin-right: ${({ theme }) => theme.eui.euiSizeXS};
diff --git a/x-pack/plugins/apm/public/components/shared/Summary/HttpStatusBadge/HttpStatusBadge.test.tsx b/x-pack/plugins/apm/public/components/shared/summary/http_status_badge/http_status_badge.test.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Summary/HttpStatusBadge/HttpStatusBadge.test.tsx
rename to x-pack/plugins/apm/public/components/shared/summary/http_status_badge/http_status_badge.test.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/Summary/HttpStatusBadge/index.tsx b/x-pack/plugins/apm/public/components/shared/summary/http_status_badge/index.tsx
similarity index 95%
rename from x-pack/plugins/apm/public/components/shared/Summary/HttpStatusBadge/index.tsx
rename to x-pack/plugins/apm/public/components/shared/summary/http_status_badge/index.tsx
index 41983a9185b8f..4ef9634fe0279 100644
--- a/x-pack/plugins/apm/public/components/shared/Summary/HttpStatusBadge/index.tsx
+++ b/x-pack/plugins/apm/public/components/shared/summary/http_status_badge/index.tsx
@@ -8,7 +8,7 @@
import React from 'react';
import { i18n } from '@kbn/i18n';
import { EuiToolTip, EuiBadge } from '@elastic/eui';
-import { statusCodes } from './statusCodes';
+import { statusCodes } from './status_codes';
import { httpStatusCodeToColor } from '../../../../utils/httpStatusCodeToColor';
interface HttpStatusBadgeProps {
diff --git a/x-pack/plugins/apm/public/components/shared/Summary/HttpStatusBadge/statusCodes.ts b/x-pack/plugins/apm/public/components/shared/summary/http_status_badge/status_codes.ts
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Summary/HttpStatusBadge/statusCodes.ts
rename to x-pack/plugins/apm/public/components/shared/summary/http_status_badge/status_codes.ts
diff --git a/x-pack/plugins/apm/public/components/shared/Summary/index.tsx b/x-pack/plugins/apm/public/components/shared/summary/index.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Summary/index.tsx
rename to x-pack/plugins/apm/public/components/shared/summary/index.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/Summary/TransactionResultSummaryItem.tsx b/x-pack/plugins/apm/public/components/shared/summary/transaction_result_summary_item.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Summary/TransactionResultSummaryItem.tsx
rename to x-pack/plugins/apm/public/components/shared/summary/transaction_result_summary_item.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/Summary/TransactionSummary.test.tsx b/x-pack/plugins/apm/public/components/shared/summary/transaction_summary.test.tsx
similarity index 94%
rename from x-pack/plugins/apm/public/components/shared/Summary/TransactionSummary.test.tsx
rename to x-pack/plugins/apm/public/components/shared/summary/transaction_summary.test.tsx
index 5c2b8383ee3b6..a1ce5e99333d2 100644
--- a/x-pack/plugins/apm/public/components/shared/Summary/TransactionSummary.test.tsx
+++ b/x-pack/plugins/apm/public/components/shared/summary/transaction_summary.test.tsx
@@ -7,7 +7,7 @@
import { shallow } from 'enzyme';
import React from 'react';
-import { TransactionSummary } from './TransactionSummary';
+import { TransactionSummary } from './transaction_summary';
import * as exampleTransactions from './__fixtures__/transactions';
describe('TransactionSummary', () => {
diff --git a/x-pack/plugins/apm/public/components/shared/Summary/TransactionSummary.tsx b/x-pack/plugins/apm/public/components/shared/summary/transaction_summary.tsx
similarity index 86%
rename from x-pack/plugins/apm/public/components/shared/Summary/TransactionSummary.tsx
rename to x-pack/plugins/apm/public/components/shared/summary/transaction_summary.tsx
index dc1a62e591b17..399121b710ce9 100644
--- a/x-pack/plugins/apm/public/components/shared/Summary/TransactionSummary.tsx
+++ b/x-pack/plugins/apm/public/components/shared/summary/transaction_summary.tsx
@@ -8,12 +8,12 @@
import React from 'react';
import { Transaction } from '../../../../typings/es_schemas/ui/transaction';
import { Summary } from './';
-import { TimestampTooltip } from '../TimestampTooltip';
-import { DurationSummaryItem } from './DurationSummaryItem';
+import { TimestampTooltip } from '../timestamp_tooltip';
+import { DurationSummaryItem } from './duration_summary_item';
import { ErrorCountSummaryItemBadge } from './error_count_summary_item_badge';
import { HttpInfoSummaryItem } from './http_info_summary_item';
-import { TransactionResultSummaryItem } from './TransactionResultSummaryItem';
-import { UserAgentSummaryItem } from './UserAgentSummaryItem';
+import { TransactionResultSummaryItem } from './transaction_result_summary_item';
+import { UserAgentSummaryItem } from './user_agent_summary_item';
interface Props {
transaction: Transaction;
diff --git a/x-pack/plugins/apm/public/components/shared/Summary/UserAgentSummaryItem.test.tsx b/x-pack/plugins/apm/public/components/shared/summary/user_agent_summary_item.test.tsx
similarity index 92%
rename from x-pack/plugins/apm/public/components/shared/Summary/UserAgentSummaryItem.test.tsx
rename to x-pack/plugins/apm/public/components/shared/summary/user_agent_summary_item.test.tsx
index 8884020f0364d..9d68c5912f513 100644
--- a/x-pack/plugins/apm/public/components/shared/Summary/UserAgentSummaryItem.test.tsx
+++ b/x-pack/plugins/apm/public/components/shared/summary/user_agent_summary_item.test.tsx
@@ -6,7 +6,7 @@
*/
import React from 'react';
-import { UserAgentSummaryItem } from './UserAgentSummaryItem';
+import { UserAgentSummaryItem } from './user_agent_summary_item';
import { mountWithTheme } from '../../../utils/testHelpers';
describe('UserAgentSummaryItem', () => {
diff --git a/x-pack/plugins/apm/public/components/shared/Summary/UserAgentSummaryItem.tsx b/x-pack/plugins/apm/public/components/shared/summary/user_agent_summary_item.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/Summary/UserAgentSummaryItem.tsx
rename to x-pack/plugins/apm/public/components/shared/summary/user_agent_summary_item.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/time_comparison/index.test.tsx b/x-pack/plugins/apm/public/components/shared/time_comparison/index.test.tsx
index e20a6df12ad46..d3c3369f6a72a 100644
--- a/x-pack/plugins/apm/public/components/shared/time_comparison/index.test.tsx
+++ b/x-pack/plugins/apm/public/components/shared/time_comparison/index.test.tsx
@@ -14,7 +14,7 @@ import {
expectTextsNotInDocument,
} from '../../../utils/testHelpers';
import { getSelectOptions, TimeComparison } from './';
-import * as urlHelpers from '../../shared/Links/url_helpers';
+import * as urlHelpers from '../../shared/links/url_helpers';
import moment from 'moment';
import { getComparisonTypes } from './get_comparison_types';
import { MockApmPluginContextWrapper } from '../../../context/apm_plugin/mock_apm_plugin_context';
diff --git a/x-pack/plugins/apm/public/components/shared/time_comparison/index.tsx b/x-pack/plugins/apm/public/components/shared/time_comparison/index.tsx
index 2cb4e0964686f..e61ffbbbc5bab 100644
--- a/x-pack/plugins/apm/public/components/shared/time_comparison/index.tsx
+++ b/x-pack/plugins/apm/public/components/shared/time_comparison/index.tsx
@@ -18,7 +18,7 @@ import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_
import { useAnyOfApmParams } from '../../../hooks/use_apm_params';
import { useBreakpoints } from '../../../hooks/use_breakpoints';
import { useTimeRange } from '../../../hooks/use_time_range';
-import * as urlHelpers from '../../shared/Links/url_helpers';
+import * as urlHelpers from '../../shared/links/url_helpers';
import { getComparisonEnabled } from './get_comparison_enabled';
import { getComparisonTypes } from './get_comparison_types';
import { getTimeRangeComparison } from './get_time_range_comparison';
diff --git a/x-pack/plugins/apm/public/components/shared/TimestampTooltip/index.test.tsx b/x-pack/plugins/apm/public/components/shared/timestamp_tooltip/index.test.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/TimestampTooltip/index.test.tsx
rename to x-pack/plugins/apm/public/components/shared/timestamp_tooltip/index.test.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/TimestampTooltip/index.tsx b/x-pack/plugins/apm/public/components/shared/timestamp_tooltip/index.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/TimestampTooltip/index.tsx
rename to x-pack/plugins/apm/public/components/shared/timestamp_tooltip/index.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/transaction_action_menu/__snapshots__/TransactionActionMenu.test.tsx.snap b/x-pack/plugins/apm/public/components/shared/transaction_action_menu/__snapshots__/transaction_action_menu.test.tsx.snap
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/transaction_action_menu/__snapshots__/TransactionActionMenu.test.tsx.snap
rename to x-pack/plugins/apm/public/components/shared/transaction_action_menu/__snapshots__/transaction_action_menu.test.tsx.snap
diff --git a/x-pack/plugins/apm/public/components/shared/transaction_action_menu/custom_link_menu_section/CustomLinkToolbar.test.tsx b/x-pack/plugins/apm/public/components/shared/transaction_action_menu/custom_link_menu_section/custom_link_toolbar.test.tsx
similarity index 97%
rename from x-pack/plugins/apm/public/components/shared/transaction_action_menu/custom_link_menu_section/CustomLinkToolbar.test.tsx
rename to x-pack/plugins/apm/public/components/shared/transaction_action_menu/custom_link_menu_section/custom_link_toolbar.test.tsx
index ecef563e72948..300b0ec345f42 100644
--- a/x-pack/plugins/apm/public/components/shared/transaction_action_menu/custom_link_menu_section/CustomLinkToolbar.test.tsx
+++ b/x-pack/plugins/apm/public/components/shared/transaction_action_menu/custom_link_menu_section/custom_link_toolbar.test.tsx
@@ -17,7 +17,7 @@ import {
expectTextsInDocument,
expectTextsNotInDocument,
} from '../../../../utils/testHelpers';
-import { CustomLinkToolbar } from './CustomLinkToolbar';
+import { CustomLinkToolbar } from './custom_link_toolbar';
function getMockAPMContext({ canSave }: { canSave: boolean }) {
return {
diff --git a/x-pack/plugins/apm/public/components/shared/transaction_action_menu/custom_link_menu_section/CustomLinkToolbar.tsx b/x-pack/plugins/apm/public/components/shared/transaction_action_menu/custom_link_menu_section/custom_link_toolbar.tsx
similarity index 97%
rename from x-pack/plugins/apm/public/components/shared/transaction_action_menu/custom_link_menu_section/CustomLinkToolbar.tsx
rename to x-pack/plugins/apm/public/components/shared/transaction_action_menu/custom_link_menu_section/custom_link_toolbar.tsx
index 0818c8915d622..935939761a496 100644
--- a/x-pack/plugins/apm/public/components/shared/transaction_action_menu/custom_link_menu_section/CustomLinkToolbar.tsx
+++ b/x-pack/plugins/apm/public/components/shared/transaction_action_menu/custom_link_menu_section/custom_link_toolbar.tsx
@@ -16,7 +16,7 @@ import {
import { i18n } from '@kbn/i18n';
import { NO_PERMISSION_LABEL } from '../../../../../common/custom_link';
import { useApmPluginContext } from '../../../../context/apm_plugin/use_apm_plugin_context';
-import { APMLink } from '../../Links/apm/APMLink';
+import { APMLink } from '../../links/apm/apm_link';
export function CustomLinkToolbar({
onClickCreate,
diff --git a/x-pack/plugins/apm/public/components/shared/transaction_action_menu/custom_link_menu_section/index.tsx b/x-pack/plugins/apm/public/components/shared/transaction_action_menu/custom_link_menu_section/index.tsx
index 187f82963ad60..7e377f2a756ee 100644
--- a/x-pack/plugins/apm/public/components/shared/transaction_action_menu/custom_link_menu_section/index.tsx
+++ b/x-pack/plugins/apm/public/components/shared/transaction_action_menu/custom_link_menu_section/index.tsx
@@ -32,8 +32,8 @@ import { useApmPluginContext } from '../../../../context/apm_plugin/use_apm_plug
import { FETCH_STATUS, useFetcher } from '../../../../hooks/use_fetcher';
import { CreateEditCustomLinkFlyout } from '../../../app/Settings/custom_link/create_edit_custom_link_flyout';
import { convertFiltersToQuery } from '../../../app/Settings/custom_link/create_edit_custom_link_flyout/helper';
-import { LoadingStatePrompt } from '../../LoadingStatePrompt';
-import { CustomLinkToolbar } from './CustomLinkToolbar';
+import { LoadingStatePrompt } from '../../loading_state_prompt';
+import { CustomLinkToolbar } from './custom_link_toolbar';
import { CustomLinkList } from './custom_link_list';
const DEFAULT_LINKS_TO_SHOW = 3;
diff --git a/x-pack/plugins/apm/public/components/shared/transaction_action_menu/sections.ts b/x-pack/plugins/apm/public/components/shared/transaction_action_menu/sections.ts
index 3095c44d54e78..daf5cb0833b61 100644
--- a/x-pack/plugins/apm/public/components/shared/transaction_action_menu/sections.ts
+++ b/x-pack/plugins/apm/public/components/shared/transaction_action_menu/sections.ts
@@ -13,10 +13,10 @@ import moment from 'moment';
import url from 'url';
import type { Transaction } from '../../../../typings/es_schemas/ui/transaction';
import type { ApmUrlParams } from '../../../context/url_params_context/types';
-import { getDiscoverHref } from '../Links/DiscoverLinks/DiscoverLink';
-import { getDiscoverQuery } from '../Links/DiscoverLinks/DiscoverTransactionLink';
-import { getInfraHref } from '../Links/InfraLink';
-import { fromQuery } from '../Links/url_helpers';
+import { getDiscoverHref } from '../links/discover_links/discover_link';
+import { getDiscoverQuery } from '../links/discover_links/discover_transaction_link';
+import { getInfraHref } from '../links/infra_link';
+import { fromQuery } from '../links/url_helpers';
import { SectionRecord, getNonEmptySections, Action } from './sections_helper';
function getInfraMetricsQuery(transaction: Transaction) {
diff --git a/x-pack/plugins/apm/public/components/shared/transaction_action_menu/TransactionActionMenu.test.tsx b/x-pack/plugins/apm/public/components/shared/transaction_action_menu/transaction_action_menu.test.tsx
similarity index 99%
rename from x-pack/plugins/apm/public/components/shared/transaction_action_menu/TransactionActionMenu.test.tsx
rename to x-pack/plugins/apm/public/components/shared/transaction_action_menu/transaction_action_menu.test.tsx
index fa2d3700eaf8c..be91fb8adfe6c 100644
--- a/x-pack/plugins/apm/public/components/shared/transaction_action_menu/TransactionActionMenu.test.tsx
+++ b/x-pack/plugins/apm/public/components/shared/transaction_action_menu/transaction_action_menu.test.tsx
@@ -22,7 +22,7 @@ import {
expectTextsInDocument,
expectTextsNotInDocument,
} from '../../../utils/testHelpers';
-import { TransactionActionMenu } from './TransactionActionMenu';
+import { TransactionActionMenu } from './transaction_action_menu';
import * as Transactions from './__fixtures__/mockData';
function getMockAPMContext({ canSave }: { canSave: boolean }) {
diff --git a/x-pack/plugins/apm/public/components/shared/transaction_action_menu/TransactionActionMenu.tsx b/x-pack/plugins/apm/public/components/shared/transaction_action_menu/transaction_action_menu.tsx
similarity index 100%
rename from x-pack/plugins/apm/public/components/shared/transaction_action_menu/TransactionActionMenu.tsx
rename to x-pack/plugins/apm/public/components/shared/transaction_action_menu/transaction_action_menu.tsx
diff --git a/x-pack/plugins/apm/public/components/shared/transaction_type_select.tsx b/x-pack/plugins/apm/public/components/shared/transaction_type_select.tsx
index 84f3b1e45d4a1..292aaaed816af 100644
--- a/x-pack/plugins/apm/public/components/shared/transaction_type_select.tsx
+++ b/x-pack/plugins/apm/public/components/shared/transaction_type_select.tsx
@@ -11,7 +11,7 @@ import { useHistory } from 'react-router-dom';
import styled from 'styled-components';
import { useApmServiceContext } from '../../context/apm_service/use_apm_service_context';
import { useBreakpoints } from '../../hooks/use_breakpoints';
-import * as urlHelpers from './Links/url_helpers';
+import * as urlHelpers from './links/url_helpers';
// The default transaction type (for non-RUM services) is "request". Set the
// min-width on here to the width when "request" is loaded so it doesn't start
diff --git a/x-pack/plugins/apm/public/components/shared/transactions_table/get_columns.tsx b/x-pack/plugins/apm/public/components/shared/transactions_table/get_columns.tsx
index c44fbb8b7f87a..b6e02b1b08c3c 100644
--- a/x-pack/plugins/apm/public/components/shared/transactions_table/get_columns.tsx
+++ b/x-pack/plugins/apm/public/components/shared/transactions_table/get_columns.tsx
@@ -22,8 +22,8 @@ import {
asTransactionRate,
} from '../../../../common/utils/formatters';
import { APIReturnType } from '../../../services/rest/createCallApmApi';
-import { ImpactBar } from '../ImpactBar';
-import { TransactionDetailLink } from '../Links/apm/transaction_detail_link';
+import { ImpactBar } from '../impact_bar';
+import { TransactionDetailLink } from '../links/apm/transaction_detail_link';
import { ListMetric } from '../list_metric';
import { TruncateWithTooltip } from '../truncate_with_tooltip';
import { getLatencyColumnLabel } from './get_latency_column_label';
diff --git a/x-pack/plugins/apm/public/components/shared/transactions_table/index.tsx b/x-pack/plugins/apm/public/components/shared/transactions_table/index.tsx
index d2abd9dc4c15a..f943cf4da4b05 100644
--- a/x-pack/plugins/apm/public/components/shared/transactions_table/index.tsx
+++ b/x-pack/plugins/apm/public/components/shared/transactions_table/index.tsx
@@ -22,11 +22,11 @@ import { APIReturnType } from '../../../services/rest/createCallApmApi';
import { useApmServiceContext } from '../../../context/apm_service/use_apm_service_context';
import { useLegacyUrlParams } from '../../../context/url_params_context/use_url_params';
import { FETCH_STATUS, useFetcher } from '../../../hooks/use_fetcher';
-import { TransactionOverviewLink } from '../Links/apm/transaction_overview_link';
+import { TransactionOverviewLink } from '../links/apm/transaction_overview_link';
import { getTimeRangeComparison } from '../time_comparison/get_time_range_comparison';
import { OverviewTableContainer } from '../overview_table_container';
import { getColumns } from './get_columns';
-import { ElasticDocsLink } from '../Links/ElasticDocsLink';
+import { ElasticDocsLink } from '../links/elastic_docs_link';
import { useBreakpoints } from '../../../hooks/use_breakpoints';
type ApiResponse =
diff --git a/x-pack/plugins/apm/public/context/url_params_context/resolve_url_params.ts b/x-pack/plugins/apm/public/context/url_params_context/resolve_url_params.ts
index c37d83983a00b..4311a9c75de85 100644
--- a/x-pack/plugins/apm/public/context/url_params_context/resolve_url_params.ts
+++ b/x-pack/plugins/apm/public/context/url_params_context/resolve_url_params.ts
@@ -11,7 +11,7 @@ import { uxLocalUIFilterNames } from '../../../common/ux_ui_filter';
import { ENVIRONMENT_ALL } from '../../../common/environment_filter_values';
import { LatencyAggregationType } from '../../../common/latency_aggregation_types';
import { pickKeys } from '../../../common/utils/pick_keys';
-import { toQuery } from '../../components/shared/Links/url_helpers';
+import { toQuery } from '../../components/shared/links/url_helpers';
import {
getDateRange,
removeUndefinedProps,
diff --git a/x-pack/plugins/apm/public/hooks/use_date_range_redirect.ts b/x-pack/plugins/apm/public/hooks/use_date_range_redirect.ts
index 0446b35872045..a0b06c241a28c 100644
--- a/x-pack/plugins/apm/public/hooks/use_date_range_redirect.ts
+++ b/x-pack/plugins/apm/public/hooks/use_date_range_redirect.ts
@@ -7,7 +7,7 @@
import qs from 'query-string';
import { useHistory, useLocation } from 'react-router-dom';
import { UI_SETTINGS } from '../../../../../src/plugins/data/public';
-import { TimePickerTimeDefaults } from '../components/shared/DatePicker/typings';
+import { TimePickerTimeDefaults } from '../components/shared/date_picker/typings';
import { useApmPluginContext } from '../context/apm_plugin/use_apm_plugin_context';
export function useDateRangeRedirect() {
diff --git a/x-pack/plugins/apm/public/hooks/use_ml_manage_jobs_href.ts b/x-pack/plugins/apm/public/hooks/use_ml_manage_jobs_href.ts
index cc187c6cf619a..d289c29b60b37 100644
--- a/x-pack/plugins/apm/public/hooks/use_ml_manage_jobs_href.ts
+++ b/x-pack/plugins/apm/public/hooks/use_ml_manage_jobs_href.ts
@@ -7,7 +7,7 @@
import { UI_SETTINGS } from '../../../../../src/plugins/data/public';
import { ML_PAGES, useMlHref } from '../../../ml/public';
-import { TimePickerRefreshInterval } from '../components/shared/DatePicker/typings';
+import { TimePickerRefreshInterval } from '../components/shared/date_picker/typings';
import { useApmPluginContext } from '../context/apm_plugin/use_apm_plugin_context';
import { useLegacyUrlParams } from '../context/url_params_context/use_url_params';
diff --git a/x-pack/plugins/apm/public/plugin.ts b/x-pack/plugins/apm/public/plugin.ts
index 77c52e1afeec3..2d00080201709 100644
--- a/x-pack/plugins/apm/public/plugin.ts
+++ b/x-pack/plugins/apm/public/plugin.ts
@@ -238,7 +238,7 @@ export class ApmPlugin implements Plugin {
const getUxDataHelper = async () => {
const { fetchUxOverviewDate, hasRumData } = await import(
- './components/app/RumDashboard/ux_overview_fetchers'
+ './components/app/rum_dashboard/ux_overview_fetchers'
);
const { createCallApmApi } = await import(
'./services/rest/createCallApmApi'
diff --git a/x-pack/plugins/apm/public/setHelpExtension.ts b/x-pack/plugins/apm/public/setHelpExtension.ts
index e70d9aecf9a9c..9015a28822a75 100644
--- a/x-pack/plugins/apm/public/setHelpExtension.ts
+++ b/x-pack/plugins/apm/public/setHelpExtension.ts
@@ -7,7 +7,7 @@
import { i18n } from '@kbn/i18n';
import { CoreStart } from 'kibana/public';
-import { getUpgradeAssistantHref } from './components/shared/Links/kibana';
+import { getUpgradeAssistantHref } from './components/shared/links/kibana';
export function setHelpExtension({ chrome, http }: CoreStart) {
chrome.setHelpExtension({
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/elements/area_chart/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/elements/area_chart/index.ts
index 38dfd2261da00..3a91039d81c7a 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/elements/area_chart/index.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/elements/area_chart/index.ts
@@ -13,9 +13,10 @@ export const areaChart: ElementFactory = () => ({
help: 'A line chart with a filled body',
type: 'chart',
icon: 'visArea',
- expression: `filters
- | demodata
- | pointseries x="time" y="mean(price)"
- | plot defaultStyle={seriesStyle lines=1 fill=1}
- | render`,
+ expression: `kibana
+| selectFilter
+| demodata
+| pointseries x="time" y="mean(price)"
+| plot defaultStyle={seriesStyle lines=1 fill=1}
+| render`,
});
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/elements/bubble_chart/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/elements/bubble_chart/index.ts
index c3f07ae601db9..b1b657bb37ff5 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/elements/bubble_chart/index.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/elements/bubble_chart/index.ts
@@ -15,7 +15,8 @@ export const bubbleChart: ElementFactory = () => ({
width: 700,
height: 300,
icon: 'heatmap',
- expression: `filters
+ expression: `kibana
+| selectFilter
| demodata
| pointseries x="project" y="sum(price)" color="state" size="size(username)"
| plot defaultStyle={seriesStyle points=5 fill=1}
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/elements/filter_debug/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/elements/filter_debug/index.ts
index d4bf6ef6f569b..c6db5ff4e3309 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/elements/filter_debug/index.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/elements/filter_debug/index.ts
@@ -12,6 +12,7 @@ export const filterDebug: ElementFactory = () => ({
displayName: 'Debug filter',
help: 'Shows the underlying global filters in a workpad',
icon: 'bug',
- expression: `filters
+ expression: `kibana
+| selectFilter
| render as=debug`,
});
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/elements/horizontal_bar_chart/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/elements/horizontal_bar_chart/index.ts
index c15ca14572606..9c01259c6d9e8 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/elements/horizontal_bar_chart/index.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/elements/horizontal_bar_chart/index.ts
@@ -13,7 +13,8 @@ export const horizontalBarChart: ElementFactory = () => ({
type: 'chart',
help: 'A customizable horizontal bar chart',
icon: 'visBarHorizontal',
- expression: `filters
+ expression: `kibana
+| selectFilter
| demodata
| pointseries x="size(cost)" y="project" color="project"
| plot defaultStyle={seriesStyle bars=0.75 horizontalBars=true} legend=false
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/elements/horizontal_progress_bar/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/elements/horizontal_progress_bar/index.ts
index f4aabba4ca216..ef278fbea3411 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/elements/horizontal_progress_bar/index.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/elements/horizontal_progress_bar/index.ts
@@ -15,7 +15,8 @@ export const horizontalProgressBar: ElementFactory = () => ({
help: 'Displays progress as a portion of a horizontal bar',
width: 400,
height: 30,
- expression: `filters
+ expression: `kibana
+| selectFilter
| demodata
| math "mean(percent_uptime)"
| progress shape="horizontalBar" label={formatnumber 0%} font={font size=24 family="${openSans.value}" color="#000000" align=center}
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/elements/horizontal_progress_pill/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/elements/horizontal_progress_pill/index.ts
index d1d723a176b45..1675c2c78cdcb 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/elements/horizontal_progress_pill/index.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/elements/horizontal_progress_pill/index.ts
@@ -15,7 +15,8 @@ export const horizontalProgressPill: ElementFactory = () => ({
help: 'Displays progress as a portion of a horizontal pill',
width: 400,
height: 30,
- expression: `filters
+ expression: `kibana
+| selectFilter
| demodata
| math "mean(percent_uptime)"
| progress shape="horizontalPill" label={formatnumber 0%} font={font size=24 family="${openSans.value}" color="#000000" align=center}
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/elements/line_chart/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/elements/line_chart/index.ts
index 84a3aee434141..cdcb9bb584b5d 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/elements/line_chart/index.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/elements/line_chart/index.ts
@@ -13,7 +13,8 @@ export const lineChart: ElementFactory = () => ({
type: 'chart',
help: 'A customizable line chart',
icon: 'visLine',
- expression: `filters
+ expression: `kibana
+| selectFilter
| demodata
| pointseries x="time" y="mean(price)"
| plot defaultStyle={seriesStyle lines=3}
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/elements/markdown/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/elements/markdown/index.ts
index 6d8edd21c7e73..7bffff4fe95cd 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/elements/markdown/index.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/elements/markdown/index.ts
@@ -12,7 +12,8 @@ export const markdown: ElementFactory = () => ({
type: 'text',
help: 'Add text using Markdown',
icon: 'visText',
- expression: `filters
+ expression: `kibana
+| selectFilter
| demodata
| markdown "### Welcome to the Markdown element
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/elements/metric/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/elements/metric/index.ts
index 76176f6ba2133..aa18e235f5fd9 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/elements/metric/index.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/elements/metric/index.ts
@@ -19,13 +19,14 @@ export const metricElementInitializer: SetupInitializer = (core,
width: 200,
height: 100,
icon: 'visMetric',
- expression: `filters
- | demodata
- | math "unique(country)"
- | metric "Countries"
- metricFont={font size=48 family="${openSans.value}" color="#000000" align="center" lHeight=48}
- labelFont={font size=14 family="${openSans.value}" color="#000000" align="center"}
- metricFormat="${core.uiSettings.get(FORMATS_UI_SETTINGS.FORMAT_NUMBER_DEFAULT_PATTERN)}"
- | render`,
+ expression: `kibana
+| selectFilter
+| demodata
+| math "unique(country)"
+| metric "Countries"
+ metricFont={font size=48 family="${openSans.value}" color="#000000" align="center" lHeight=48}
+ labelFont={font size=14 family="${openSans.value}" color="#000000" align="center"}
+ metricFormat="${core.uiSettings.get(FORMATS_UI_SETTINGS.FORMAT_NUMBER_DEFAULT_PATTERN)}"
+| render`,
});
};
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/elements/metric_vis/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/elements/metric_vis/index.ts
index 3f01a8ccb3e73..3c5a4c16565c6 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/elements/metric_vis/index.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/elements/metric_vis/index.ts
@@ -12,9 +12,10 @@ export const metricVis: ElementFactory = () => ({
type: 'chart',
help: 'Metric visualization',
icon: 'visMetric',
- expression: `filters
- | demodata
- | head 1
- | metricVis metric={visdimension "percent_uptime"} colorMode="Labels"
- | render`,
+ expression: `kibana
+| selectFilter
+| demodata
+| head 1
+| metricVis metric={visdimension "percent_uptime"} colorMode="Labels"
+| render`,
});
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/elements/pie/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/elements/pie/index.ts
index 2094af748ab16..4739e6ca16474 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/elements/pie/index.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/elements/pie/index.ts
@@ -14,7 +14,8 @@ export const pie: ElementFactory = () => ({
height: 300,
help: 'A simple pie chart',
icon: 'visPie',
- expression: `filters
+ expression: `kibana
+| selectFilter
| demodata
| pointseries color="state" size="max(price)"
| pie
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/elements/plot/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/elements/plot/index.ts
index 3e879b7fb58db..c0ebfa60708d4 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/elements/plot/index.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/elements/plot/index.ts
@@ -12,7 +12,8 @@ export const plot: ElementFactory = () => ({
displayName: 'Coordinate plot',
type: 'chart',
help: 'Mixed line, bar or dot charts',
- expression: `filters
+ expression: `kibana
+| selectFilter
| demodata
| pointseries x="time" y="sum(price)" color="state"
| plot defaultStyle={seriesStyle points=5}
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/elements/progress_gauge/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/elements/progress_gauge/index.ts
index e07a848263f50..85f853cea759b 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/elements/progress_gauge/index.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/elements/progress_gauge/index.ts
@@ -16,7 +16,8 @@ export const progressGauge: ElementFactory = () => ({
width: 200,
height: 200,
icon: 'visGoal',
- expression: `filters
+ expression: `kibana
+| selectFilter
| demodata
| math "mean(percent_uptime)"
| progress shape="gauge" label={formatnumber 0%} font={font size=24 family="${openSans.value}" color="#000000" align=center}
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/elements/progress_semicircle/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/elements/progress_semicircle/index.ts
index 6c61ab24d13b2..100f5c65eb94a 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/elements/progress_semicircle/index.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/elements/progress_semicircle/index.ts
@@ -15,7 +15,8 @@ export const progressSemicircle: ElementFactory = () => ({
help: 'Displays progress as a portion of a semicircle',
width: 200,
height: 100,
- expression: `filters
+ expression: `kibana
+| selectFilter
| demodata
| math "mean(percent_uptime)"
| progress shape="semicircle" label={formatnumber 0%} font={font size=24 family="${openSans.value}" color="#000000" align=center}
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/elements/progress_wheel/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/elements/progress_wheel/index.ts
index 15fec0d3b6390..1d9ffde49ff8b 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/elements/progress_wheel/index.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/elements/progress_wheel/index.ts
@@ -15,7 +15,8 @@ export const progressWheel: ElementFactory = () => ({
help: 'Displays progress as a portion of a wheel',
width: 200,
height: 200,
- expression: `filters
+ expression: `kibana
+| selectFilter
| demodata
| math "mean(percent_uptime)"
| progress shape="wheel" label={formatnumber 0%} font={font size=24 family="${openSans.value}" color="#000000" align=center}
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/elements/repeat_image/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/elements/repeat_image/index.ts
index 783b17e7d9362..6a064ffd297ec 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/elements/repeat_image/index.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/elements/repeat_image/index.ts
@@ -12,7 +12,8 @@ export const repeatImage: ElementFactory = () => ({
displayName: 'Image repeat',
type: 'image',
help: 'Repeats an image N times',
- expression: `filters
+ expression: `kibana
+| selectFilter
| demodata
| math "mean(cost)"
| repeatImage image=null
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/elements/reveal_image/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/elements/reveal_image/index.ts
index b2b4ea4a942a3..b78e0d1d5cf24 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/elements/reveal_image/index.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/elements/reveal_image/index.ts
@@ -12,7 +12,8 @@ export const revealImage: ElementFactory = () => ({
displayName: 'Image reveal',
type: 'image',
help: 'Reveals a percentage of an image',
- expression: `filters
+ expression: `kibana
+| selectFilter
| demodata
| math "mean(percent_uptime)"
| revealImage origin=bottom image=null
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/elements/table/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/elements/table/index.ts
index 710f595ba7179..417fe09fbc586 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/elements/table/index.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/elements/table/index.ts
@@ -13,7 +13,8 @@ export const table: ElementFactory = () => ({
type: 'chart',
help: 'A scrollable grid for displaying data in a tabular format',
icon: 'visTable',
- expression: `filters
+ expression: `kibana
+| selectFilter
| demodata
| table
| render`,
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/elements/tag_cloud/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/elements/tag_cloud/index.ts
index b3543d532b9be..698468ab2e150 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/elements/tag_cloud/index.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/elements/tag_cloud/index.ts
@@ -12,10 +12,11 @@ export const tagCloud: ElementFactory = () => ({
type: 'chart',
help: 'Tagcloud visualization',
icon: 'visTagCloud',
- expression: `filters
- | demodata
- | ply by="country" fn={math "count(country)" | as "Count"}
- | filterrows fn={getCell "Count" | gte 10}
- | tagcloud metric={visdimension "Count"} bucket={visdimension "country"}
- | render`,
+ expression: `kibana
+| selectFilter
+| demodata
+| ply by="country" fn={math "count(country)" | as "Count"}
+| filterrows fn={getCell "Count" | gte 10}
+| tagcloud metric={visdimension "Count"} bucket={visdimension "country"}
+| render`,
});
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/elements/vert_bar_chart/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/elements/vert_bar_chart/index.ts
index de573166c8e9a..a90f79aa995c5 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/elements/vert_bar_chart/index.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/elements/vert_bar_chart/index.ts
@@ -13,7 +13,8 @@ export const verticalBarChart: ElementFactory = () => ({
type: 'chart',
help: 'A customizable vertical bar chart',
icon: 'visBarVertical',
- expression: `filters
+ expression: `kibana
+| selectFilter
| demodata
| pointseries x="project" y="size(cost)" color="project"
| plot defaultStyle={seriesStyle bars=0.75} legend=false
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/elements/vertical_progress_bar/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/elements/vertical_progress_bar/index.ts
index 04ee9c8cb7db2..89ffc18766bcd 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/elements/vertical_progress_bar/index.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/elements/vertical_progress_bar/index.ts
@@ -15,7 +15,8 @@ export const verticalProgressBar: ElementFactory = () => ({
help: 'Displays progress as a portion of a vertical bar',
width: 80,
height: 400,
- expression: `filters
+ expression: `kibana
+| selectFilter
| demodata
| math "mean(percent_uptime)"
| progress shape="verticalBar" label={formatnumber 0%} font={font size=24 family="${openSans.value}" color="#000000" align=center}
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/elements/vertical_progress_pill/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/elements/vertical_progress_pill/index.ts
index 7bbf3874f175f..b3a977c1d795a 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/elements/vertical_progress_pill/index.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/elements/vertical_progress_pill/index.ts
@@ -15,7 +15,8 @@ export const verticalProgressPill: ElementFactory = () => ({
help: 'Displays progress as a portion of a vertical pill',
width: 80,
height: 400,
- expression: `filters
+ expression: `kibana
+| selectFilter
| demodata
| math "mean(percent_uptime)"
| progress shape="verticalPill" label={formatnumber 0%} font={font size=24 family="${openSans.value}" color="#000000" align=center}
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/exactly.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/exactly.ts
index c0ed25849ac97..66553b6fda6c0 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/exactly.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/exactly.ts
@@ -47,13 +47,14 @@ export function exactly(): ExpressionFunctionDefinition<
},
},
fn: (input, args) => {
- const { value, column } = args;
+ const { value, column, filterGroup } = args;
const filter: ExpressionValueFilter = {
type: 'filter',
filterType: 'exactly',
value,
column,
+ filterGroup,
and: [],
};
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/timefilter.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/timefilter.ts
index e4a6a102844a9..b61e03319b916 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/timefilter.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/timefilter.ts
@@ -58,11 +58,12 @@ export function timefilter(): ExpressionFunctionDefinition<
return input;
}
- const { from, to, column } = args;
+ const { from, to, column, filterGroup } = args;
const filter: ExpressionValueFilter = {
type: 'filter',
filterType: 'time',
column,
+ filterGroup,
and: [],
};
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/server/filters.test.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/server/filters.test.ts
new file mode 100644
index 0000000000000..75bd97421e58e
--- /dev/null
+++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/server/filters.test.ts
@@ -0,0 +1,26 @@
+/*
+ * 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 { fromExpression } from '@kbn/interpreter';
+import { filters } from './filters';
+
+const { migrations } = filters();
+
+describe('filters migrations', () => {
+ const expression = 'filters group="1" group="3" ungrouped=true';
+ const ast = fromExpression(expression);
+ it('8.1.0. Should migrate `filters` expression to `kibana | selectFilter`', () => {
+ const migratedAst = migrations?.['8.1.0'](ast.chain[0]);
+ expect(migratedAst !== null && typeof migratedAst === 'object').toBeTruthy();
+ expect(migratedAst.type).toBe('expression');
+ expect(Array.isArray(migratedAst.chain)).toBeTruthy();
+ expect(migratedAst.chain[0].function === 'kibana').toBeTruthy();
+ expect(migratedAst.chain[0].arguments).toEqual({});
+ expect(migratedAst.chain[1].function === 'selectFilter').toBeTruthy();
+ expect(migratedAst.chain[1].arguments).toEqual(ast.chain[0].arguments);
+ });
+});
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/server/filters.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/server/filters.ts
new file mode 100644
index 0000000000000..8b46e818209f3
--- /dev/null
+++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/server/filters.ts
@@ -0,0 +1,43 @@
+/*
+ * 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 {
+ ExpressionValueFilter,
+ ExpressionAstExpression,
+ ExpressionAstFunction,
+} from 'src/plugins/expressions';
+import { fromExpression } from '@kbn/interpreter';
+import { buildFiltersFunction } from '../../../common/functions';
+import type { FiltersFunction } from '../../../common/functions';
+
+/*
+ Expression function `filters` can't be used on the server, because it is tightly coupled with the redux store.
+ It is replaced with `kibana | selectFilter`.
+
+ Current filters function definition is used only for the purpose of enabling migrations.
+ The function has to be registered on the server while the plugin's setup, to be able to run its migration.
+*/
+const filtersFn = (): ExpressionValueFilter => ({
+ type: 'filter',
+ and: [],
+});
+
+const migrations: FiltersFunction['migrations'] = {
+ '8.1.0': (ast: ExpressionAstFunction): ExpressionAstFunction | ExpressionAstExpression => {
+ const SELECT_FILTERS = 'selectFilter';
+ const newExpression = `kibana | ${SELECT_FILTERS}`;
+ const newAst: ExpressionAstExpression = fromExpression(newExpression);
+ const selectFiltersAstIndex = newAst.chain.findIndex(
+ ({ function: fnName }) => fnName === SELECT_FILTERS
+ );
+ const selectFilterAst = newAst.chain[selectFiltersAstIndex];
+ newAst.chain.splice(selectFiltersAstIndex, 1, { ...selectFilterAst, arguments: ast.arguments });
+ return newAst;
+ },
+};
+
+export const filters = buildFiltersFunction(filtersFn, migrations);
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/server/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/server/index.ts
index ae3778366651c..388db9e6e5960 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/functions/server/index.ts
+++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/server/index.ts
@@ -7,5 +7,6 @@
import { demodata } from './demodata';
import { pointseries } from './pointseries';
+import { filters } from './filters';
-export const functions = [demodata, pointseries];
+export const functions = [filters, demodata, pointseries];
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/__stories__/render.tsx b/x-pack/plugins/canvas/canvas_plugin_src/renderers/__stories__/render.tsx
index 643d7cdedc50d..38d1d502704e2 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/__stories__/render.tsx
+++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/__stories__/render.tsx
@@ -21,7 +21,6 @@ export const defaultHandlers: RendererHandlers = {
onEmbeddableInputChange: action('onEmbeddableInputChange'),
onResize: action('onResize'),
resize: action('resize'),
- setFilter: action('setFilter'),
done: action('done'),
onDestroy: action('onDestroy'),
reload: action('reload'),
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/filters/advanced_filter/index.tsx b/x-pack/plugins/canvas/canvas_plugin_src/renderers/filters/advanced_filter/index.tsx
index b831c9aa70e49..a31021cba4c10 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/filters/advanced_filter/index.tsx
+++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/filters/advanced_filter/index.tsx
@@ -25,7 +25,10 @@ export const advancedFilterFactory: StartInitializer> =
render(domNode, _, handlers) {
ReactDOM.render(
-
+ handlers.event({ name: 'applyFilterAction', data: filter })}
+ value={handlers.getFilter()}
+ />
,
domNode,
() => handlers.done()
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/filters/dropdown_filter/index.tsx b/x-pack/plugins/canvas/canvas_plugin_src/renderers/filters/dropdown_filter/index.tsx
index 372bcbb5642cb..5e4ea42990e47 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/filters/dropdown_filter/index.tsx
+++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/filters/dropdown_filter/index.tsx
@@ -55,20 +55,19 @@ export const dropdownFilterFactory: StartInitializer> =
(filterExpression === undefined || !filterExpression.includes('exactly'))
) {
filterExpression = '';
- handlers.setFilter(filterExpression);
+ handlers.event({ name: 'applyFilterAction', data: filterExpression });
} else if (filterExpression !== '') {
// NOTE: setFilter() will cause a data refresh, avoid calling unless required
// compare expression and filter, update filter if needed
const { changed, newAst } = syncFilterExpression(config, filterExpression, ['filterGroup']);
if (changed) {
- handlers.setFilter(toExpression(newAst));
+ handlers.event({ name: 'applyFilterAction', data: toExpression(newAst) });
}
}
-
const commit = (commitValue: string) => {
if (commitValue === '%%CANVAS_MATCH_ALL%%') {
- handlers.setFilter('');
+ handlers.event({ name: 'applyFilterAction', data: '' });
} else {
const newFilterAST: Ast = {
type: 'expression',
@@ -86,18 +85,19 @@ export const dropdownFilterFactory: StartInitializer> =
};
const newFilter = toExpression(newFilterAST);
- handlers.setFilter(newFilter);
+ handlers.event({ name: 'applyFilterAction', data: newFilter });
}
};
+ const filter = (
+
+ );
ReactDOM.render(
-
-
- ,
+ {filter},
domNode,
() => handlers.done()
);
diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/filters/time_filter/index.tsx b/x-pack/plugins/canvas/canvas_plugin_src/renderers/filters/time_filter/index.tsx
index e81ca2cc1f057..f7e9d333f8683 100644
--- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/filters/time_filter/index.tsx
+++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/filters/time_filter/index.tsx
@@ -45,7 +45,7 @@ export const timeFilterFactory: StartInitializer> = (
if (filterExpression === undefined || filterExpression.indexOf('timefilter') !== 0) {
filterExpression = defaultTimeFilterExpression;
- handlers.setFilter(filterExpression);
+ handlers.event({ name: 'applyFilterAction', data: filterExpression });
} else if (filterExpression !== '') {
// NOTE: setFilter() will cause a data refresh, avoid calling unless required
// compare expression and filter, update filter if needed
@@ -55,14 +55,14 @@ export const timeFilterFactory: StartInitializer> = (
]);
if (changed) {
- handlers.setFilter(toExpression(newAst));
+ handlers.event({ name: 'applyFilterAction', data: toExpression(newAst) });
}
}
ReactDOM.render(
handlers.event({ name: 'applyFilterAction', data: filter })}
filter={filterExpression}
commonlyUsedRanges={customQuickRanges}
dateFormat={customDateFormat}
diff --git a/x-pack/plugins/canvas/common/functions/filters.ts b/x-pack/plugins/canvas/common/functions/filters.ts
new file mode 100644
index 0000000000000..5c48fbd10862a
--- /dev/null
+++ b/x-pack/plugins/canvas/common/functions/filters.ts
@@ -0,0 +1,56 @@
+/*
+ * 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 { ExpressionFunctionDefinition } from 'src/plugins/expressions/public';
+import { ExpressionValueFilter } from '../../types';
+import { getFunctionHelp } from '../../i18n';
+
+export interface Arguments {
+ group: string[];
+ ungrouped: boolean;
+}
+
+export type FiltersFunction = ExpressionFunctionDefinition<
+ 'filters',
+ null,
+ Arguments,
+ ExpressionValueFilter
+>;
+
+export function buildFiltersFunction(
+ fn: FiltersFunction['fn'],
+ migrations?: FiltersFunction['migrations']
+) {
+ return function filters(): FiltersFunction {
+ const { help, args: argHelp } = getFunctionHelp().filters;
+
+ return {
+ name: 'filters',
+ type: 'filter',
+ help,
+ context: {
+ types: ['null'],
+ },
+ args: {
+ group: {
+ aliases: ['_'],
+ types: ['string'],
+ help: argHelp.group,
+ multi: true,
+ },
+ ungrouped: {
+ aliases: ['nogroup', 'nogroups'],
+ types: ['boolean'],
+ help: argHelp.ungrouped,
+ default: false,
+ },
+ },
+ fn,
+ migrations,
+ };
+ };
+}
diff --git a/x-pack/plugins/canvas/common/functions/index.ts b/x-pack/plugins/canvas/common/functions/index.ts
new file mode 100644
index 0000000000000..08d9391f81c13
--- /dev/null
+++ b/x-pack/plugins/canvas/common/functions/index.ts
@@ -0,0 +1,9 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export type { FiltersFunction } from './filters';
+export { buildFiltersFunction } from './filters';
diff --git a/x-pack/plugins/canvas/common/lib/build_embeddable_filters.ts b/x-pack/plugins/canvas/common/lib/build_embeddable_filters.ts
index 57fdc7d7309ce..c98d2f080452a 100644
--- a/x-pack/plugins/canvas/common/lib/build_embeddable_filters.ts
+++ b/x-pack/plugins/canvas/common/lib/build_embeddable_filters.ts
@@ -6,6 +6,8 @@
*/
import { buildQueryFilter, Filter } from '@kbn/es-query';
+import dateMath from '@elastic/datemath';
+import { maxBy, minBy } from 'lodash';
import { ExpressionValueFilter } from '../../types';
// @ts-expect-error untyped local
import { buildBoolArray } from './build_bool_array';
@@ -16,24 +18,45 @@ export interface EmbeddableFilterInput {
timeRange?: TimeRange;
}
+type ESFilter = Record;
+
const TimeFilterType = 'time';
+const formatTime = (str: string | undefined, roundUp: boolean = false) => {
+ if (!str) {
+ return null;
+ }
+ const moment = dateMath.parse(str, { roundUp });
+ return !moment || !moment.isValid() ? null : moment.valueOf();
+};
+
function getTimeRangeFromFilters(filters: ExpressionValueFilter[]): TimeRange | undefined {
- const timeFilter = filters.find(
- (filter) => filter.filterType !== undefined && filter.filterType === TimeFilterType
+ const timeFilters = filters.filter(
+ (filter) =>
+ filter.filterType !== undefined &&
+ filter.filterType === TimeFilterType &&
+ filter.from !== undefined &&
+ filter.to !== undefined
);
- return timeFilter !== undefined && timeFilter.from !== undefined && timeFilter.to !== undefined
- ? {
- from: timeFilter.from,
- to: timeFilter.to,
- }
+ const validatedTimeFilters = timeFilters.filter(
+ (filter) => formatTime(filter.from) !== null && formatTime(filter.to, true) !== null
+ );
+
+ const minFromFilter = minBy(validatedTimeFilters, (filter) => formatTime(filter.from));
+ const maxToFilter = maxBy(validatedTimeFilters, (filter) => formatTime(filter.to, true));
+
+ return minFromFilter?.from && maxToFilter?.to
+ ? { from: minFromFilter.from, to: maxToFilter.to }
: undefined;
}
export function getQueryFilters(filters: ExpressionValueFilter[]): Filter[] {
const dataFilters = filters.map((filter) => ({ ...filter, type: filter.filterType }));
- return buildBoolArray(dataFilters).map(buildQueryFilter);
+ return buildBoolArray(dataFilters).map((filter: ESFilter, index: number) => {
+ const { group, ...restFilter } = filter;
+ return buildQueryFilter(restFilter, index.toString(), '', { group });
+ });
}
export function buildEmbeddableFilters(filters: ExpressionValueFilter[]): EmbeddableFilterInput {
diff --git a/x-pack/plugins/canvas/common/lib/constants.ts b/x-pack/plugins/canvas/common/lib/constants.ts
index 6a61ec595acb7..fa938f2c07c74 100644
--- a/x-pack/plugins/canvas/common/lib/constants.ts
+++ b/x-pack/plugins/canvas/common/lib/constants.ts
@@ -16,6 +16,8 @@ export const APP_ROUTE = '/app/canvas';
export const APP_ROUTE_WORKPAD = `${APP_ROUTE}#/workpad`;
export const API_ROUTE = '/api/canvas';
export const API_ROUTE_WORKPAD = `${API_ROUTE}/workpad`;
+export const API_ROUTE_WORKPAD_EXPORT = `${API_ROUTE_WORKPAD}/export`;
+export const API_ROUTE_WORKPAD_IMPORT = `${API_ROUTE_WORKPAD}/import`;
export const API_ROUTE_WORKPAD_ASSETS = `${API_ROUTE}/workpad-assets`;
export const API_ROUTE_WORKPAD_STRUCTURES = `${API_ROUTE}/workpad-structures`;
export const API_ROUTE_CUSTOM_ELEMENT = `${API_ROUTE}/custom-element`;
diff --git a/x-pack/plugins/canvas/common/lib/filters.js b/x-pack/plugins/canvas/common/lib/filters.js
index 08caded52aa26..f43e2dd3b4606 100644
--- a/x-pack/plugins/canvas/common/lib/filters.js
+++ b/x-pack/plugins/canvas/common/lib/filters.js
@@ -13,15 +13,16 @@ export function time(filter) {
if (!filter.column) {
throw new Error('column is required for Elasticsearch range filters');
}
+ const { from, to, column, filterGroup: group } = filter;
return {
- range: {
- [filter.column]: { gte: filter.from, lte: filter.to },
- },
+ group,
+ range: { [column]: { gte: from, lte: to } },
};
}
export function luceneQueryString(filter) {
return {
+ group: filter.filterGroup,
query_string: {
query: filter.query || '*',
},
@@ -30,6 +31,7 @@ export function luceneQueryString(filter) {
export function exactly(filter) {
return {
+ group: filter.filterGroup,
term: {
[filter.column]: {
value: filter.value,
diff --git a/x-pack/plugins/canvas/public/components/datasource/datasource_preview/index.js b/x-pack/plugins/canvas/public/components/datasource/datasource_preview/index.js
index 89faef29a3b02..1ca674bfb6f9d 100644
--- a/x-pack/plugins/canvas/public/components/datasource/datasource_preview/index.js
+++ b/x-pack/plugins/canvas/public/components/datasource/datasource_preview/index.js
@@ -7,16 +7,19 @@
import React, { useState, useEffect } from 'react';
import { PropTypes } from 'prop-types';
-import { interpretAst } from '../../../lib/run_interpreter';
import { Loading } from '../../loading';
+import { useExpressionsService } from '../../../services';
import { DatasourcePreview as Component } from './datasource_preview';
export const DatasourcePreview = (props) => {
const [datatable, setDatatable] = useState();
+ const expressionsService = useExpressionsService();
useEffect(() => {
- interpretAst({ type: 'expression', chain: [props.function] }, {}).then(setDatatable);
- }, [props.function, setDatatable]);
+ expressionsService
+ .interpretAst({ type: 'expression', chain: [props.function] }, {})
+ .then(setDatatable);
+ }, [expressionsService, props.function, setDatatable]);
if (!datatable) {
return ;
diff --git a/x-pack/plugins/canvas/public/components/function_form_list/index.js b/x-pack/plugins/canvas/public/components/function_form_list/index.js
index 6048ac360386c..31db3366ce3b5 100644
--- a/x-pack/plugins/canvas/public/components/function_form_list/index.js
+++ b/x-pack/plugins/canvas/public/components/function_form_list/index.js
@@ -8,7 +8,7 @@
import { compose, withProps } from 'recompose';
import { get } from 'lodash';
import { toExpression } from '@kbn/interpreter';
-import { interpretAst } from '../../lib/run_interpreter';
+import { pluginServices } from '../../services';
import { getArgTypeDef } from '../../lib/args';
import { FunctionFormList as Component } from './function_form_list';
@@ -77,24 +77,27 @@ const componentFactory = ({
path,
parentPath,
removable,
-}) => ({
- args,
- nestedFunctionsArgs: argsWithExprFunctions,
- argType: argType.function,
- argTypeDef: Object.assign(argTypeDef, {
- args: argumentsView,
- name: argUiConfig?.name ?? argTypeDef.name,
- displayName: argUiConfig?.displayName ?? argTypeDef.displayName,
- help: argUiConfig?.help ?? argTypeDef.name,
- }),
- argResolver: (argAst) => interpretAst(argAst, prevContext),
- contextExpression: getExpression(prevContext),
- expressionIndex, // preserve the index in the AST
- nextArgType: nextArg && nextArg.function,
- path,
- parentPath,
- removable,
-});
+}) => {
+ const { expressions } = pluginServices.getServices();
+ return {
+ args,
+ nestedFunctionsArgs: argsWithExprFunctions,
+ argType: argType.function,
+ argTypeDef: Object.assign(argTypeDef, {
+ args: argumentsView,
+ name: argUiConfig?.name ?? argTypeDef.name,
+ displayName: argUiConfig?.displayName ?? argTypeDef.displayName,
+ help: argUiConfig?.help ?? argTypeDef.name,
+ }),
+ argResolver: (argAst) => expressions.interpretAst(argAst, prevContext),
+ contextExpression: getExpression(prevContext),
+ expressionIndex, // preserve the index in the AST
+ nextArgType: nextArg && nextArg.function,
+ path,
+ parentPath,
+ removable,
+ };
+};
/**
* Converts expression functions at the arguments for the expression, to the array of UI component configurations.
diff --git a/x-pack/plugins/canvas/public/components/function_reference_generator/function_examples.ts b/x-pack/plugins/canvas/public/components/function_reference_generator/function_examples.ts
index a8409270752ad..785f183b193f1 100644
--- a/x-pack/plugins/canvas/public/components/function_reference_generator/function_examples.ts
+++ b/x-pack/plugins/canvas/public/components/function_reference_generator/function_examples.ts
@@ -22,7 +22,8 @@ export const getFunctionExamples = (): FunctionExampleDict => ({
syntax: `all {neq "foo"} {neq "bar"} {neq "fizz"}
all condition={gt 10} condition={lt 20}`,
usage: {
- expression: `filters
+ expression: `kibana
+| selectFilter
| demodata
| math "mean(percent_uptime)"
| formatnumber "0.0%"
@@ -42,7 +43,8 @@ all condition={gt 10} condition={lt 20}`,
syntax: `alterColumn "cost" type="string"
alterColumn column="@timestamp" name="foo"`,
usage: {
- expression: `filters
+ expression: `kibana
+| selectFilter
| demodata
| alterColumn "time" name="time_in_ms" type="number"
| table
@@ -54,7 +56,8 @@ alterColumn column="@timestamp" name="foo"`,
syntax: `any {eq "foo"} {eq "bar"} {eq "fizz"}
any condition={lte 10} condition={gt 30}`,
usage: {
- expression: `filters
+ expression: `kibana
+| selectFilter
| demodata
| filterrows {
getCell "project" | any {eq "elasticsearch"} {eq "kibana"} {eq "x-pack"}
@@ -70,7 +73,8 @@ any condition={lte 10} condition={gt 30}`,
as "foo"
as name="bar"`,
usage: {
- expression: `filters
+ expression: `kibana
+| selectFilter
| demodata
| ply by="project" fn={math "count(username)" | as "num_users"} fn={math "mean(price)" | as "price"}
| pointseries x="project" y="num_users" size="price" color="project"
@@ -94,7 +98,8 @@ asset id="asset-498f7429-4d56-42a2-a7e4-8bf08d98d114"`,
syntax: `axisConfig show=false
axisConfig position="right" min=0 max=10 tickSize=1`,
usage: {
- expression: `filters
+ expression: `kibana
+| selectFilter
| demodata
| pointseries x="size(cost)" y="project" color="project"
| plot defaultStyle={seriesStyle bars=0.75 horizontalBars=true}
@@ -133,7 +138,8 @@ case if={lte 50} then="green"`,
syntax: `columns include="@timestamp, projects, cost"
columns exclude="username, country, age"`,
usage: {
- expression: `filters
+ expression: `kibana
+| selectFilter
| demodata
| columns include="price, cost, state, project"
| table
@@ -145,7 +151,8 @@ columns exclude="username, country, age"`,
syntax: `compare "neq" to="elasticsearch"
compare op="lte" to=100`,
usage: {
- expression: `filters
+ expression: `kibana
+| selectFilter
| demodata
| mapColumn project
fn={getCell project |
@@ -229,7 +236,8 @@ date "01/31/2019" format="MM/DD/YYYY"`,
demodata "ci"
demodata type="shirts"`,
usage: {
- expression: `filters
+ expression: `kibana
+| selectFilter
| demodata
| table
| render`,
@@ -252,7 +260,8 @@ eq null
eq 10
eq "foo"`,
usage: {
- expression: `filters
+ expression: `kibana
+| selectFilter
| demodata
| mapColumn project
fn={getCell project |
@@ -272,7 +281,8 @@ eq "foo"`,
escount "currency:\"EUR\"" index="kibana_sample_data_ecommerce"
escount query="response:404" index="kibana_sample_data_logs"`,
usage: {
- expression: `filters
+ expression: `kibana
+| selectFilter
| escount "Cancelled:true" index="kibana_sample_data_flights"
| math "value"
| progress shape="semicircle"
@@ -290,7 +300,8 @@ esdocs query="response:404" index="kibana_sample_data_logs"
esdocs index="kibana_sample_data_flights" count=100
esdocs index="kibana_sample_data_flights" sort="AvgTicketPrice, asc"`,
usage: {
- expression: `filters
+ expression: `kibana
+| selectFilter
| esdocs index="kibana_sample_data_ecommerce"
fields="customer_gender, taxful_total_price, order_date"
sort="order_date, asc"
@@ -309,7 +320,8 @@ esdocs index="kibana_sample_data_flights" sort="AvgTicketPrice, asc"`,
syntax: `essql query="SELECT * FROM \"logstash*\""
essql "SELECT * FROM \"apm*\"" count=10000`,
usage: {
- expression: `filters
+ expression: `kibana
+| selectFilter
| essql query="SELECT Carrier, FlightDelayMin, AvgTicketPrice FROM \"kibana_sample_data_flights\""
| table
| render`,
@@ -321,7 +333,8 @@ essql "SELECT * FROM \"apm*\"" count=10000`,
exactly "age" value=50 filterGroup="group2"
exactly column="project" value="beats"`,
usage: {
- expression: `filters
+ expression: `kibana
+| selectFilter
| exactly column=project value=elasticsearch
| demodata
| pointseries x=project y="mean(age)"
@@ -334,7 +347,8 @@ exactly column="project" value="beats"`,
syntax: `filterrows {getCell "project" | eq "kibana"}
filterrows fn={getCell "age" | gt 50}`,
usage: {
- expression: `filters
+ expression: `kibana
+| selectFilter
| demodata
| filterrows {getCell "country" | any {eq "IN"} {eq "US"} {eq "CN"}}
| mapColumn "@timestamp"
@@ -379,7 +393,8 @@ font underline=true
font italic=false
font lHeight=32`,
usage: {
- expression: `filters
+ expression: `kibana
+| selectFilter
| demodata
| pointseries x="project" y="size(cost)" color="project"
| plot defaultStyle={seriesStyle bars=0.75} legend=false
@@ -399,7 +414,8 @@ font lHeight=32`,
syntax: `formatdate format="YYYY-MM-DD"
formatdate "MM/DD/YYYY"`,
usage: {
- expression: `filters
+ expression: `kibana
+| selectFilter
| demodata
| mapColumn "time" fn={getCell time | formatdate "MMM 'YY"}
| pointseries x="time" y="sum(price)" color="state"
@@ -412,7 +428,8 @@ formatdate "MM/DD/YYYY"`,
syntax: `formatnumber format="$0,0.00"
formatnumber "0.0a"`,
usage: {
- expression: `filters
+ expression: `kibana
+| selectFilter
| demodata
| math "mean(percent_uptime)"
| progress shape="gauge"
diff --git a/x-pack/plugins/canvas/public/components/home/hooks/use_create_workpad.ts b/x-pack/plugins/canvas/public/components/home/hooks/use_create_workpad.ts
index eb87f4720deec..3290bc8227a29 100644
--- a/x-pack/plugins/canvas/public/components/home/hooks/use_create_workpad.ts
+++ b/x-pack/plugins/canvas/public/components/home/hooks/use_create_workpad.ts
@@ -29,7 +29,7 @@ export const useCreateWorkpad = () => {
history.push(`/workpad/${workpad.id}/page/1`);
} catch (err) {
notifyService.error(err, {
- title: errors.getUploadFailureErrorMessage(),
+ title: errors.getCreateFailureErrorMessage(),
});
}
return;
@@ -39,8 +39,8 @@ export const useCreateWorkpad = () => {
};
const errors = {
- getUploadFailureErrorMessage: () =>
- i18n.translate('xpack.canvas.error.useCreateWorkpad.uploadFailureErrorMessage', {
- defaultMessage: `Couldn't upload workpad`,
+ getCreateFailureErrorMessage: () =>
+ i18n.translate('xpack.canvas.error.useCreateWorkpad.createFailureErrorMessage', {
+ defaultMessage: `Couldn't create workpad`,
}),
};
diff --git a/x-pack/plugins/canvas/public/components/home/hooks/use_import_workpad.ts b/x-pack/plugins/canvas/public/components/home/hooks/use_import_workpad.ts
new file mode 100644
index 0000000000000..8c8d2e26d8a22
--- /dev/null
+++ b/x-pack/plugins/canvas/public/components/home/hooks/use_import_workpad.ts
@@ -0,0 +1,44 @@
+/*
+ * 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 { useCallback } from 'react';
+import { useHistory } from 'react-router-dom';
+import { i18n } from '@kbn/i18n';
+
+// @ts-expect-error
+import { getDefaultWorkpad } from '../../../state/defaults';
+import { useNotifyService, useWorkpadService } from '../../../services';
+
+import type { CanvasWorkpad } from '../../../../types';
+
+export const useImportWorkpad = () => {
+ const workpadService = useWorkpadService();
+ const notifyService = useNotifyService();
+ const history = useHistory();
+
+ return useCallback(
+ async (workpad: CanvasWorkpad) => {
+ try {
+ const importedWorkpad = await workpadService.import(workpad);
+ history.push(`/workpad/${importedWorkpad.id}/page/1`);
+ } catch (err) {
+ notifyService.error(err, {
+ title: errors.getUploadFailureErrorMessage(),
+ });
+ }
+ return;
+ },
+ [notifyService, history, workpadService]
+ );
+};
+
+const errors = {
+ getUploadFailureErrorMessage: () =>
+ i18n.translate('xpack.canvas.error.useUploadWorkpad.uploadFailureErrorMessage', {
+ defaultMessage: `Couldn't upload workpad`,
+ }),
+};
diff --git a/x-pack/plugins/canvas/public/components/home/hooks/use_upload_workpad.ts b/x-pack/plugins/canvas/public/components/home/hooks/use_upload_workpad.ts
index caec30e083d40..045ff8b52e259 100644
--- a/x-pack/plugins/canvas/public/components/home/hooks/use_upload_workpad.ts
+++ b/x-pack/plugins/canvas/public/components/home/hooks/use_upload_workpad.ts
@@ -9,19 +9,25 @@ import { useCallback } from 'react';
import { get } from 'lodash';
import { i18n } from '@kbn/i18n';
+import { SavedObject } from 'kibana/public';
import { CANVAS, JSON as JSONString } from '../../../../i18n/constants';
import { useNotifyService } from '../../../services';
import { getId } from '../../../lib/get_id';
-
-import { useCreateWorkpad } from './use_create_workpad';
+import { useImportWorkpad as useImportWorkpadHook } from './use_import_workpad';
import type { CanvasWorkpad } from '../../../../types';
+const isInvalidWorkpad = (workpad: CanvasWorkpad) =>
+ !Array.isArray(workpad.pages) || workpad.pages.length === 0 || !workpad.assets;
+
export const useImportWorkpad = () => {
const notifyService = useNotifyService();
- const createWorkpad = useCreateWorkpad();
+ const importWorkpad = useImportWorkpadHook();
return useCallback(
- (file?: File, onComplete: (workpad?: CanvasWorkpad) => void = () => {}) => {
+ (
+ file?: File,
+ onComplete: (workpad?: CanvasWorkpad | SavedObject) => void = () => {}
+ ) => {
if (!file) {
onComplete();
return;
@@ -42,16 +48,17 @@ export const useImportWorkpad = () => {
// handle reading the uploaded file
reader.onload = async () => {
try {
- const workpad = JSON.parse(reader.result as string); // Type-casting because we catch below.
+ const workpad: CanvasWorkpad = JSON.parse(reader.result as string); // Type-casting because we catch below.
+
workpad.id = getId('workpad');
// sanity check for workpad object
- if (!Array.isArray(workpad.pages) || workpad.pages.length === 0 || !workpad.assets) {
+ if (isInvalidWorkpad(workpad)) {
onComplete();
throw new Error(errors.getMissingPropertiesErrorMessage());
}
- await createWorkpad(workpad);
+ await importWorkpad(workpad);
onComplete(workpad);
} catch (e) {
notifyService.error(e, {
@@ -66,7 +73,7 @@ export const useImportWorkpad = () => {
// read the uploaded file
reader.readAsText(file);
},
- [notifyService, createWorkpad]
+ [notifyService, importWorkpad]
);
};
diff --git a/x-pack/plugins/canvas/public/components/workpad_filters/hooks/use_canvas_filters.ts b/x-pack/plugins/canvas/public/components/workpad_filters/hooks/use_canvas_filters.ts
index 85b195214d44b..21bcc89304b3c 100644
--- a/x-pack/plugins/canvas/public/components/workpad_filters/hooks/use_canvas_filters.ts
+++ b/x-pack/plugins/canvas/public/components/workpad_filters/hooks/use_canvas_filters.ts
@@ -5,19 +5,22 @@
* 2.0.
*/
-import { fromExpression } from '@kbn/interpreter';
+import { ExpressionFunctionAST, fromExpression } from '@kbn/interpreter';
import { shallowEqual, useSelector } from 'react-redux';
import { State } from '../../../../types';
-import { getFiltersByGroups } from '../../../lib/filter';
+import { getFiltersByFilterExpressions } from '../../../lib/filter';
import { adaptCanvasFilter } from '../../../lib/filter_adapters';
-import { getGlobalFilters } from '../../../state/selectors/workpad';
+import { useFiltersService } from '../../../services';
-const extractExpressionAST = (filtersExpressions: string[]) =>
- fromExpression(filtersExpressions.join(' | '));
+const extractExpressionAST = (filters: string[]) => fromExpression(filters.join(' | '));
-export function useCanvasFilters(groups: string[] = [], ungrouped: boolean = false) {
- const filterExpressions = useSelector((state: State) => getGlobalFilters(state), shallowEqual);
- const filtersByGroups = getFiltersByGroups(filterExpressions, groups, ungrouped);
+export function useCanvasFilters(filterExprsToGroupBy: ExpressionFunctionAST[] = []) {
+ const filtersService = useFiltersService();
+ const filterExpressions = useSelector(
+ (state: State) => filtersService.getFilters(state),
+ shallowEqual
+ );
+ const filtersByGroups = getFiltersByFilterExpressions(filterExpressions, filterExprsToGroupBy);
const expression = extractExpressionAST(filtersByGroups);
const filters = expression.chain.map(adaptCanvasFilter);
diff --git a/x-pack/plugins/canvas/public/components/workpad_filters/workpad_filters.tsx b/x-pack/plugins/canvas/public/components/workpad_filters/workpad_filters.tsx
index 610e6e56af350..20ec56706480d 100644
--- a/x-pack/plugins/canvas/public/components/workpad_filters/workpad_filters.tsx
+++ b/x-pack/plugins/canvas/public/components/workpad_filters/workpad_filters.tsx
@@ -8,11 +8,7 @@
import React, { FC, useCallback } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { State, FilterField, PositionedElement } from '../../../types';
-import {
- extractGroupsFromElementsFilters,
- groupFiltersBy,
- extractUngroupedFromElementsFilters,
-} from '../../lib/filter';
+import { groupFiltersBy, getFiltersExprsFromExpression } from '../../lib/filter';
import { setGroupFiltersByOption } from '../../state/actions/sidebar';
import { getGroupFiltersByOption } from '../../state/selectors/sidebar';
import { useCanvasFilters } from './hooks';
@@ -35,11 +31,8 @@ export const WorkpadFilters: FC = ({ element }) => {
},
[dispatch]
);
-
- const groups = element ? extractGroupsFromElementsFilters(element.expression) : undefined;
- const ungrouped = element ? extractUngroupedFromElementsFilters(element.expression) : false;
-
- const canvasFilters = useCanvasFilters(groups, ungrouped);
+ const filterExprs = element ? getFiltersExprsFromExpression(element.expression) : [];
+ const canvasFilters = useCanvasFilters(filterExprs);
const filtersGroups = groupFiltersByField
? groupFiltersBy(canvasFilters, groupFiltersByField)
diff --git a/x-pack/plugins/canvas/public/components/workpad_header/element_menu/__stories__/element_menu.stories.tsx b/x-pack/plugins/canvas/public/components/workpad_header/element_menu/__stories__/element_menu.stories.tsx
index 9d37873bcae0a..62d070dbf00f5 100644
--- a/x-pack/plugins/canvas/public/components/workpad_header/element_menu/__stories__/element_menu.stories.tsx
+++ b/x-pack/plugins/canvas/public/components/workpad_header/element_menu/__stories__/element_menu.stories.tsx
@@ -17,7 +17,8 @@ const testElements: { [key: string]: ElementSpec } = {
displayName: 'Area chart',
help: 'A line chart with a filled body',
type: 'chart',
- expression: `filters
+ expression: `kibana
+ | selectFilter
| demodata
| pointseries x="time" y="mean(price)"
| plot defaultStyle={seriesStyle lines=1 fill=1}
@@ -47,7 +48,8 @@ const testElements: { [key: string]: ElementSpec } = {
displayName: 'Debug filter',
help: 'Shows the underlying global filters in a workpad',
icon: 'bug',
- expression: `filters
+ expression: `kibana
+ | selectFilter
| render as=debug`,
},
image: {
@@ -64,7 +66,8 @@ const testElements: { [key: string]: ElementSpec } = {
type: 'text',
help: 'Add text using Markdown',
icon: 'visText',
- expression: `filters
+ expression: `kibana
+| selectFilter
| demodata
| markdown "### Welcome to the Markdown element
@@ -89,7 +92,8 @@ You can use standard Markdown in here, but you can also access your piped-in dat
width: 200,
height: 200,
icon: 'visGoal',
- expression: `filters
+ expression: `kibana
+ | selectFilter
| demodata
| math "mean(percent_uptime)"
| progress shape="gauge" label={formatnumber 0%} font={font size=24 family="Helvetica" color="#000000" align=center}
@@ -111,7 +115,8 @@ You can use standard Markdown in here, but you can also access your piped-in dat
displayName: 'Data table',
type: 'chart',
help: 'A scrollable grid for displaying data in a tabular format',
- expression: `filters
+ expression: `kibana
+ | selectFilter
| demodata
| table
| render`,
diff --git a/x-pack/plugins/canvas/public/functions/filters.ts b/x-pack/plugins/canvas/public/functions/filters.ts
index 2634d76297b58..a168020b6eef8 100644
--- a/x-pack/plugins/canvas/public/functions/filters.ts
+++ b/x-pack/plugins/canvas/public/functions/filters.ts
@@ -7,15 +7,10 @@
import { fromExpression } from '@kbn/interpreter';
import { get } from 'lodash';
-import { ExpressionFunctionDefinition } from 'src/plugins/expressions/public';
-import { interpretAst } from '../lib/run_interpreter';
-// @ts-expect-error untyped local
-import { getState } from '../state/store';
-import { getGlobalFilters, getWorkpadVariablesAsObject } from '../state/selectors/workpad';
-import { ExpressionValueFilter } from '../../types';
-import { getFunctionHelp } from '../../i18n';
+import { pluginServices } from '../services';
+import type { FiltersFunction } from '../../common/functions';
+import { buildFiltersFunction } from '../../common/functions';
import { InitializeArguments } from '.';
-import { getFiltersByGroups } from '../lib/filter';
export interface Arguments {
group: string[];
@@ -31,58 +26,34 @@ function getFiltersByGroup(allFilters: string[], groups?: string[], ungrouped =
// remove all allFilters that belong to a group
return allFilters.filter((filter: string) => {
const ast = fromExpression(filter);
- const expGroups = get(ast, 'chain[0].arguments.filterGroup', []);
+ const expGroups: string[] = get(ast, 'chain[0].arguments.filterGroup', []);
return expGroups.length === 0;
});
}
- return getFiltersByGroups(allFilters, groups);
+ return allFilters.filter((filter: string) => {
+ const ast = fromExpression(filter);
+ const expGroups: string[] = get(ast, 'chain[0].arguments.filterGroup', []);
+ return expGroups.length > 0 && expGroups.every((expGroup) => groups.includes(expGroup));
+ });
}
-type FiltersFunction = ExpressionFunctionDefinition<
- 'filters',
- null,
- Arguments,
- ExpressionValueFilter
->;
-
export function filtersFunctionFactory(initialize: InitializeArguments): () => FiltersFunction {
- return function filters(): FiltersFunction {
- const { help, args: argHelp } = getFunctionHelp().filters;
-
- return {
- name: 'filters',
- type: 'filter',
- help,
- context: {
- types: ['null'],
- },
- args: {
- group: {
- aliases: ['_'],
- types: ['string'],
- help: argHelp.group,
- multi: true,
- },
- ungrouped: {
- aliases: ['nogroup', 'nogroups'],
- types: ['boolean'],
- help: argHelp.ungrouped,
- default: false,
- },
- },
- fn: (input, { group, ungrouped }) => {
- const filterList = getFiltersByGroup(getGlobalFilters(getState()), group, ungrouped);
-
- if (filterList && filterList.length) {
- const filterExpression = filterList.join(' | ');
- const filterAST = fromExpression(filterExpression);
- return interpretAst(filterAST, getWorkpadVariablesAsObject(getState()));
- } else {
- const filterType = initialize.types.filter;
- return filterType?.from(null, {});
- }
- },
- };
+ const fn: FiltersFunction['fn'] = (input, { group, ungrouped }) => {
+ const { expressions, filters: filtersService } = pluginServices.getServices();
+
+ const filterList = getFiltersByGroup(filtersService.getFilters(), group, ungrouped);
+
+ if (filterList && filterList.length) {
+ const filterExpression = filterList.join(' | ');
+ const filterAST = fromExpression(filterExpression);
+ const { variables } = filtersService.getFiltersContext();
+ return expressions.interpretAst(filterAST, variables);
+ } else {
+ const filterType = initialize.types.filter;
+ return filterType?.from(null, {});
+ }
};
+
+ return buildFiltersFunction(fn);
}
diff --git a/x-pack/plugins/canvas/public/lib/create_handlers.ts b/x-pack/plugins/canvas/public/lib/create_handlers.ts
index 3734b1bf53051..3536bed0f92b3 100644
--- a/x-pack/plugins/canvas/public/lib/create_handlers.ts
+++ b/x-pack/plugins/canvas/public/lib/create_handlers.ts
@@ -10,10 +10,9 @@ import {
ExpressionRendererEvent,
IInterpreterRenderHandlers,
} from 'src/plugins/expressions/public';
-// @ts-expect-error untyped local
-import { setFilter } from '../state/actions/elements';
import { updateEmbeddableExpression, fetchEmbeddableRenderable } from '../state/actions/embeddable';
import { RendererHandlers, CanvasElement } from '../../types';
+import { pluginServices } from '../services';
import { clearValue } from '../state/actions/resolved_args';
// This class creates stub handlers to ensure every element and renderer fulfills the contract.
@@ -58,7 +57,6 @@ export const createHandlers = (baseHandlers = createBaseHandlers()): RendererHan
},
resize(_size: { height: number; width: number }) {},
- setFilter() {},
});
export const assignHandlers = (handlers: Partial = {}): RendererHandlers =>
@@ -79,6 +77,8 @@ export const createDispatchedHandlerFactory = (
oldElement = element;
}
+ const { filters } = pluginServices.getServices();
+
const handlers: RendererHandlers & {
event: IInterpreterRenderHandlers['event'];
done: IInterpreterRenderHandlers['done'];
@@ -89,8 +89,8 @@ export const createDispatchedHandlerFactory = (
case 'embeddableInputChange':
this.onEmbeddableInputChange(event.data);
break;
- case 'setFilter':
- this.setFilter(event.data);
+ case 'applyFilterAction':
+ filters.updateFilter(element.id, event.data);
break;
case 'onComplete':
this.onComplete(event.data);
@@ -106,10 +106,6 @@ export const createDispatchedHandlerFactory = (
break;
}
},
- setFilter(text: string) {
- dispatch(setFilter(text, element.id, true));
- },
-
getFilter() {
return element.filter || '';
},
diff --git a/x-pack/plugins/canvas/public/lib/filter.test.ts b/x-pack/plugins/canvas/public/lib/filter.test.ts
index bf19bd6ecf4b8..9aef71f33f609 100644
--- a/x-pack/plugins/canvas/public/lib/filter.test.ts
+++ b/x-pack/plugins/canvas/public/lib/filter.test.ts
@@ -5,6 +5,7 @@
* 2.0.
*/
+import { fromExpression } from '@kbn/interpreter';
import { FC } from 'react';
import {
Filter as FilterType,
@@ -18,9 +19,8 @@ import {
flattenFilterView,
createFilledFilterView,
groupFiltersBy,
- getFiltersByGroups,
- extractGroupsFromElementsFilters,
- extractUngroupedFromElementsFilters,
+ getFiltersExprsFromExpression,
+ getFiltersByFilterExpressions,
isExpressionWithFilters,
} from './filter';
@@ -285,7 +285,7 @@ describe('groupFiltersBy', () => {
});
});
-describe('getFiltersByGroups', () => {
+describe('getFiltersByFilterExpressions', () => {
const group1 = 'Group 1';
const group2 = 'Group 2';
@@ -296,66 +296,106 @@ describe('getFiltersByGroups', () => {
`exactly value="kibana" column="project2" filterGroup="${group2}"`,
];
- it('returns all filters related to a specified groups', () => {
- expect(getFiltersByGroups(filters, [group1, group2])).toEqual([
- filters[0],
- filters[1],
- filters[3],
- ]);
+ const filtersExprWithGroup = `filters group="${group2}"`;
+
+ const kibanaExpr = 'kibana';
+ const selectFilterExprEmpty = 'selectFilter';
+ const selectFilterExprWithGroup = `${selectFilterExprEmpty} group="${group2}"`;
+ const selectFilterExprWithGroups = `${selectFilterExprEmpty} group="${group2}" group="${group1}"`;
+ const selectFilterExprWithUngrouped = `${selectFilterExprEmpty} ungrouped=true`;
+ const selectFilterExprWithGroupAndUngrouped = `${selectFilterExprEmpty} group="${group2}" ungrouped=true`;
+
+ const removeFilterExprEmpty = 'removeFilter';
+ const removeFilterExprWithGroup = `${removeFilterExprEmpty} group="${group2}"`;
+ const removeFilterExprWithUngrouped = `${removeFilterExprEmpty} ungrouped=true`;
+ const removeFilterExprWithGroupAndUngrouped = `${removeFilterExprEmpty} group="${group2}" ungrouped=true`;
+
+ const getFiltersAsts = (filtersExprs: string[]) => {
+ const ast = fromExpression(filtersExprs.join(' | '));
+ return ast.chain;
+ };
- expect(getFiltersByGroups(filters, [group2])).toEqual([filters[1], filters[3]]);
+ it('returns all filters if no arguments specified to selectFilter expression', () => {
+ const filtersExprs = getFiltersAsts([kibanaExpr, selectFilterExprEmpty]);
+ const matchedFilters = getFiltersByFilterExpressions(filters, filtersExprs);
+ expect(matchedFilters).toEqual(filters);
});
- it('returns filters without group if ungrouped is true', () => {
- expect(getFiltersByGroups(filters, [], true)).toEqual([filters[2]]);
+ it('returns filters with group, specified to selectFilter expression', () => {
+ const filtersExprs = getFiltersAsts([kibanaExpr, selectFilterExprWithGroups]);
+ const matchedFilters = getFiltersByFilterExpressions(filters, filtersExprs);
+ expect(matchedFilters).toEqual([filters[0], filters[1], filters[3]]);
});
- it('returns filters with group if ungrouped is true and groups are not empty', () => {
- expect(getFiltersByGroups(filters, [group1], true)).toEqual([filters[0]]);
+ it('returns filters without group if ungrouped is true at selectFilter expression', () => {
+ const filtersExprs = getFiltersAsts([kibanaExpr, selectFilterExprWithUngrouped]);
+ const matchedFilters = getFiltersByFilterExpressions(filters, filtersExprs);
+ expect(matchedFilters).toEqual([filters[2]]);
});
- it('returns empty array if not found any filter with a specified group', () => {
- expect(getFiltersByGroups(filters, ['absent group'])).toEqual([]);
+ it('returns filters with group if ungrouped is true and groups are not empty at selectFilter expression', () => {
+ const filtersExprs = getFiltersAsts([kibanaExpr, selectFilterExprWithGroupAndUngrouped]);
+ const matchedFilters = getFiltersByFilterExpressions(filters, filtersExprs);
+ expect(matchedFilters).toEqual([filters[1], filters[2], filters[3]]);
});
- it('returns empty array if not groups specified', () => {
- expect(getFiltersByGroups(filters, [])).toEqual(filters);
+ it('returns no filters if no arguments, specified to removeFilter expression', () => {
+ const filtersExprs = getFiltersAsts([kibanaExpr, removeFilterExprEmpty]);
+ const matchedFilters = getFiltersByFilterExpressions(filters, filtersExprs);
+ expect(matchedFilters).toEqual([]);
+ });
+
+ it('returns filters without group, specified to removeFilter expression', () => {
+ const filtersExprs = getFiltersAsts([kibanaExpr, removeFilterExprWithGroup]);
+ const matchedFilters = getFiltersByFilterExpressions(filters, filtersExprs);
+ expect(matchedFilters).toEqual([filters[0], filters[2]]);
});
-});
-describe('extractGroupsFromElementsFilters', () => {
- const exprFilters = 'filters';
- const exprRest = 'demodata | plot | render';
-
- it('returns groups which are specified at filters expression', () => {
- const groups = ['group 1', 'group 2', 'group 3', 'group 4'];
- const additionalGroups = [...groups, 'group 5'];
- const groupsExpr = groups.map((group) => `group="${group}"`).join(' ');
- const additionalGroupsExpr = additionalGroups.map((group) => `group="${group}"`).join(' ');
-
- expect(
- extractGroupsFromElementsFilters(
- `${exprFilters} ${groupsExpr} | ${exprFilters} ${additionalGroupsExpr} | ${exprRest}`
- )
- ).toEqual(additionalGroups);
+ it('returns filters without group if ungrouped is true at removeFilter expression', () => {
+ const filtersExprs = getFiltersAsts([kibanaExpr, removeFilterExprWithUngrouped]);
+ const matchedFilters = getFiltersByFilterExpressions(filters, filtersExprs);
+ expect(matchedFilters).toEqual([filters[0], filters[1], filters[3]]);
});
- it('returns empty array if no groups were specified at filters expression', () => {
- expect(extractGroupsFromElementsFilters(`${exprFilters} | ${exprRest}`)).toEqual([]);
+ it('remove filters without group and with specified group if ungrouped is true and groups are not empty at removeFilter expression', () => {
+ const filtersExprs = getFiltersAsts([kibanaExpr, removeFilterExprWithGroupAndUngrouped]);
+ const matchedFilters = getFiltersByFilterExpressions(filters, filtersExprs);
+ expect(matchedFilters).toEqual([filters[0]]);
+ });
+
+ it('should include/exclude filters iteratively', () => {
+ const filtersExprs = getFiltersAsts([
+ kibanaExpr,
+ selectFilterExprWithGroup,
+ removeFilterExprWithGroup,
+ selectFilterExprEmpty,
+ ]);
+ const matchedFilters = getFiltersByFilterExpressions(filters, filtersExprs);
+ expect(matchedFilters).toEqual([]);
+ });
+
+ it('should include/exclude filters from global filters if `filters` expression is specified', () => {
+ const filtersExprs = getFiltersAsts([
+ kibanaExpr,
+ selectFilterExprWithGroup,
+ removeFilterExprWithGroup,
+ selectFilterExprEmpty,
+ filtersExprWithGroup,
+ ]);
+ const matchedFilters = getFiltersByFilterExpressions(filters, filtersExprs);
+ expect(matchedFilters).toEqual([filters[1], filters[3]]);
});
});
-describe('extractUngroupedFromElementsFilters', () => {
- it('checks if ungrouped filters expression exist at the element', () => {
- const expression =
- 'filters group="10" group="11" | filters group="15" ungrouped=true | demodata | plot | render';
- const isUngrouped = extractUngroupedFromElementsFilters(expression);
- expect(isUngrouped).toBeTruthy();
+describe('getFiltersExprsFromExpression', () => {
+ it('returns list of filters expressions asts', () => {
+ const filter1 = 'selectFilter';
+ const filter2 = 'filters group="15" ungrouped=true';
+ const filter3 = 'removeFilter';
+ const expression = `kibana | ${filter1} | ${filter2} | ${filter3} | demodata | plot | render`;
+ const filtersAsts = getFiltersExprsFromExpression(expression);
- const nextExpression =
- 'filters group="10" group="11" | filters group="15" | demodata | plot | render';
- const nextIsUngrouped = extractUngroupedFromElementsFilters(nextExpression);
- expect(nextIsUngrouped).toBeFalsy();
+ expect(filtersAsts).toEqual([filter1, filter2, filter3].map((f) => fromExpression(f).chain[0]));
});
});
diff --git a/x-pack/plugins/canvas/public/lib/filter.ts b/x-pack/plugins/canvas/public/lib/filter.ts
index 6e9db1757ccc7..2554ae11220eb 100644
--- a/x-pack/plugins/canvas/public/lib/filter.ts
+++ b/x-pack/plugins/canvas/public/lib/filter.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import { fromExpression } from '@kbn/interpreter';
+import { Ast, ExpressionFunctionAST, fromExpression, toExpression } from '@kbn/interpreter';
import { flowRight, get, groupBy } from 'lodash';
import {
Filter as FilterType,
@@ -14,6 +14,14 @@ import {
FlattenFilterViewInstance,
} from '../../types/filters';
+const SELECT_FILTER = 'selectFilter';
+const FILTERS = 'filters';
+const REMOVE_FILTER = 'removeFilter';
+
+const includeFiltersExpressions = [FILTERS, SELECT_FILTER];
+const excludeFiltersExpressions = [REMOVE_FILTER];
+const filtersExpressions = [...includeFiltersExpressions, ...excludeFiltersExpressions];
+
export const defaultFormatter = (value: unknown) => (value || null ? `${value}` : '-');
export const formatFilterView =
@@ -55,41 +63,73 @@ export const groupFiltersBy = (filters: FilterType[], groupByField: FilterField)
}));
};
-export const getFiltersByGroups = (
- filters: string[],
- groups: string[],
- ungrouped: boolean = false
-) =>
- filters.filter((filter: string) => {
- const ast = fromExpression(filter);
- const expGroups: string[] = get(ast, 'chain[0].arguments.filterGroup', []);
- if (!groups?.length && ungrouped) {
- return expGroups.length === 0;
- }
+const excludeFiltersByGroups = (filters: Ast[], filterExprAst: ExpressionFunctionAST) => {
+ const groupsToExclude = filterExprAst.arguments.group ?? [];
+ const removeUngrouped = filterExprAst.arguments.ungrouped?.[0] ?? false;
+ return filters.filter((filter) => {
+ const groups: string[] = get(filter, 'chain[0].arguments.filterGroup', []).filter(
+ (group: string) => group !== ''
+ );
+ const noNeedToExcludeByGroup = !(
+ groups.length &&
+ groupsToExclude.length &&
+ groupsToExclude.includes(groups[0])
+ );
+
+ const noNeedToExcludeByUngrouped = (removeUngrouped && groups.length) || !removeUngrouped;
+ const excludeAllFilters = !groupsToExclude.length && !removeUngrouped;
- return (
- !groups.length ||
- (expGroups.length > 0 && expGroups.every((expGroup) => groups.includes(expGroup)))
+ return !excludeAllFilters && noNeedToExcludeByUngrouped && noNeedToExcludeByGroup;
+ });
+};
+
+const includeFiltersByGroups = (
+ filters: Ast[],
+ filterExprAst: ExpressionFunctionAST,
+ ignoreUngroupedIfGroups: boolean = false
+) => {
+ const groupsToInclude = filterExprAst.arguments.group ?? [];
+ const includeOnlyUngrouped = filterExprAst.arguments.ungrouped?.[0] ?? false;
+ return filters.filter((filter) => {
+ const groups: string[] = get(filter, 'chain[0].arguments.filterGroup', []).filter(
+ (group: string) => group !== ''
);
+ const needToIncludeByGroup =
+ groups.length && groupsToInclude.length && groupsToInclude.includes(groups[0]);
+
+ const needToIncludeByUngrouped =
+ includeOnlyUngrouped &&
+ !groups.length &&
+ (ignoreUngroupedIfGroups ? !groupsToInclude.length : true);
+
+ const allowAll = !groupsToInclude.length && !includeOnlyUngrouped;
+ return needToIncludeByUngrouped || needToIncludeByGroup || allowAll;
});
+};
-export const extractGroupsFromElementsFilters = (expr: string) => {
- const ast = fromExpression(expr);
- const filtersFns = ast.chain.filter((expression) => expression.function === 'filters');
- const groups = filtersFns.reduce((foundGroups, filterFn) => {
- const filterGroups = filterFn?.arguments.group?.map((g) => g.toString()) ?? [];
- return [...foundGroups, ...filterGroups];
- }, []);
- return [...new Set(groups)];
+export const getFiltersByFilterExpressions = (
+ filters: string[],
+ filterExprsAsts: ExpressionFunctionAST[]
+) => {
+ const filtersAst = filters.map((filter) => fromExpression(filter));
+ const matchedFiltersAst = filterExprsAsts.reduce((includedFilters, filter) => {
+ if (excludeFiltersExpressions.includes(filter.function)) {
+ return excludeFiltersByGroups(includedFilters, filter);
+ }
+ const isFiltersExpr = filter.function === FILTERS;
+ const filtersToInclude = isFiltersExpr ? filtersAst : includedFilters;
+ return includeFiltersByGroups(filtersToInclude, filter, isFiltersExpr);
+ }, filtersAst);
+
+ return matchedFiltersAst.map((ast) => toExpression(ast));
};
-export const extractUngroupedFromElementsFilters = (expr: string) => {
+export const getFiltersExprsFromExpression = (expr: string) => {
const ast = fromExpression(expr);
- const filtersFns = ast.chain.filter((expression) => expression.function === 'filters');
- return filtersFns.some((filterFn) => filterFn?.arguments.ungrouped?.[0]);
+ return ast.chain.filter((expression) => filtersExpressions.includes(expression.function));
};
export const isExpressionWithFilters = (expr: string) => {
const ast = fromExpression(expr);
- return ast.chain.some((expression) => expression.function === 'filters');
+ return ast.chain.some((expression) => filtersExpressions.includes(expression.function));
};
diff --git a/x-pack/plugins/canvas/public/lib/run_interpreter.ts b/x-pack/plugins/canvas/public/lib/run_interpreter.ts
deleted file mode 100644
index 77c31b11924c0..0000000000000
--- a/x-pack/plugins/canvas/public/lib/run_interpreter.ts
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-
-import { fromExpression, getType } from '@kbn/interpreter';
-import { pluck } from 'rxjs/operators';
-import { ExpressionValue, ExpressionAstExpression } from 'src/plugins/expressions/public';
-import { pluginServices } from '../services';
-
-interface Options {
- castToRender?: boolean;
-}
-
-/**
- * Meant to be a replacement for plugins/interpreter/interpretAST
- */
-export async function interpretAst(
- ast: ExpressionAstExpression,
- variables: Record,
- input: ExpressionValue = null
-): Promise {
- const context = { variables };
- const { execute } = pluginServices.getServices().expressions;
-
- return await execute(ast, input, context).getData().pipe(pluck('result')).toPromise();
-}
-
-/**
- * Runs interpreter, usually in the browser
- *
- * @param {object} ast - Executable AST
- * @param {any} input - Initial input for AST execution
- * @param {object} variables - Variables to pass in to the intrepreter context
- * @param {object} options
- * @param {boolean} options.castToRender - try to cast to a type: render object?
- * @returns {promise}
- */
-export async function runInterpreter(
- ast: ExpressionAstExpression,
- input: ExpressionValue,
- variables: Record,
- options: Options = {}
-): Promise {
- const context = { variables };
- try {
- const { execute } = pluginServices.getServices().expressions;
-
- const renderable = await execute(ast, input, context)
- .getData()
- .pipe(pluck('result'))
- .toPromise();
-
- if (getType(renderable) === 'render') {
- return renderable;
- }
-
- if (options.castToRender) {
- return runInterpreter(fromExpression('render'), renderable, variables, {
- castToRender: false,
- });
- }
-
- throw new Error(`Ack! I don't know how to render a '${getType(renderable)}'`);
- } catch (err) {
- const { error: displayError } = pluginServices.getServices().notify;
- displayError(err);
- throw err;
- }
-}
diff --git a/x-pack/plugins/canvas/public/plugin.tsx b/x-pack/plugins/canvas/public/plugin.tsx
index 8cdc695ebaaba..1c2ce763f42e2 100644
--- a/x-pack/plugins/canvas/public/plugin.tsx
+++ b/x-pack/plugins/canvas/public/plugin.tsx
@@ -36,7 +36,6 @@ import { BfetchPublicSetup } from '../../../../src/plugins/bfetch/public';
import { PresentationUtilPluginStart } from '../../../../src/plugins/presentation_util/public';
import { getPluginApi, CanvasApi } from './plugin_api';
import { setupExpressions } from './setup_expressions';
-import { pluginServiceRegistry } from './services/kibana';
export type { CoreStart, CoreSetup };
@@ -123,6 +122,8 @@ export class CanvasPlugin
srcPlugin.start(coreStart, startPlugins);
const { pluginServices } = await import('./services');
+ const { pluginServiceRegistry } = await import('./services/kibana');
+
pluginServices.setRegistry(
pluginServiceRegistry.start({
coreStart,
diff --git a/x-pack/plugins/canvas/public/services/expressions.ts b/x-pack/plugins/canvas/public/services/expressions.ts
index 01bb0adb17711..456a1314bdfff 100644
--- a/x-pack/plugins/canvas/public/services/expressions.ts
+++ b/x-pack/plugins/canvas/public/services/expressions.ts
@@ -5,6 +5,4 @@
* 2.0.
*/
-import { ExpressionsServiceStart } from '../../../../../src/plugins/expressions/public';
-
-export type CanvasExpressionsService = ExpressionsServiceStart;
+export type { CanvasExpressionsService } from './kibana/expressions';
diff --git a/x-pack/plugins/cases/public/components/user_action_tree/constants.ts b/x-pack/plugins/canvas/public/services/filters.ts
similarity index 78%
rename from x-pack/plugins/cases/public/components/user_action_tree/constants.ts
rename to x-pack/plugins/canvas/public/services/filters.ts
index 584194be65f50..1ced3d15f6e10 100644
--- a/x-pack/plugins/cases/public/components/user_action_tree/constants.ts
+++ b/x-pack/plugins/canvas/public/services/filters.ts
@@ -5,4 +5,4 @@
* 2.0.
*/
-export const DRAFT_COMMENT_STORAGE_ID = 'xpack.cases.commentDraft';
+export type { CanvasFiltersService } from './kibana/filters';
diff --git a/x-pack/plugins/canvas/public/services/index.ts b/x-pack/plugins/canvas/public/services/index.ts
index ed55f919e4c76..4bf025c274859 100644
--- a/x-pack/plugins/canvas/public/services/index.ts
+++ b/x-pack/plugins/canvas/public/services/index.ts
@@ -12,6 +12,7 @@ import { PluginServices } from '../../../../../src/plugins/presentation_util/pub
import { CanvasCustomElementService } from './custom_element';
import { CanvasEmbeddablesService } from './embeddables';
import { CanvasExpressionsService } from './expressions';
+import { CanvasFiltersService } from './filters';
import { CanvasLabsService } from './labs';
import { CanvasNavLinkService } from './nav_link';
import { CanvasNotifyService } from './notify';
@@ -24,6 +25,7 @@ export interface CanvasPluginServices {
customElement: CanvasCustomElementService;
embeddables: CanvasEmbeddablesService;
expressions: CanvasExpressionsService;
+ filters: CanvasFiltersService;
labs: CanvasLabsService;
navLink: CanvasNavLinkService;
notify: CanvasNotifyService;
@@ -41,6 +43,7 @@ export const useEmbeddablesService = () =>
(() => pluginServices.getHooks().embeddables.useService())();
export const useExpressionsService = () =>
(() => pluginServices.getHooks().expressions.useService())();
+export const useFiltersService = () => (() => pluginServices.getHooks().filters.useService())();
export const useLabsService = () => (() => pluginServices.getHooks().labs.useService())();
export const useNavLinkService = () => (() => pluginServices.getHooks().navLink.useService())();
export const useNotifyService = () => (() => pluginServices.getHooks().notify.useService())();
diff --git a/x-pack/plugins/canvas/public/services/kibana/expressions.ts b/x-pack/plugins/canvas/public/services/kibana/expressions.ts
index 780de5309d97e..ea329b63863f8 100644
--- a/x-pack/plugins/canvas/public/services/kibana/expressions.ts
+++ b/x-pack/plugins/canvas/public/services/kibana/expressions.ts
@@ -4,16 +4,137 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
-
+import { fromExpression, getType } from '@kbn/interpreter';
+import {
+ ExpressionAstExpression,
+ ExpressionExecutionParams,
+ ExpressionValue,
+} from 'src/plugins/expressions';
+import { pluck } from 'rxjs/operators';
+import { buildEmbeddableFilters } from '../../../common/lib/build_embeddable_filters';
+import { ExpressionsServiceStart } from '../../../../../../src/plugins/expressions/public';
import { KibanaPluginServiceFactory } from '../../../../../../src/plugins/presentation_util/public';
-
import { CanvasStartDeps } from '../../plugin';
-import { CanvasExpressionsService } from '../expressions';
+import { CanvasFiltersService } from './filters';
+import { CanvasNotifyService } from '../notify';
+
+interface Options {
+ castToRender?: boolean;
+}
+
+export class ExpressionsService {
+ private filters: CanvasFiltersService;
+ private notify: CanvasNotifyService;
+
+ constructor(
+ private readonly expressions: ExpressionsServiceStart,
+ { filters, notify }: CanvasExpressionsServiceRequiredServices
+ ) {
+ this.filters = filters;
+ this.notify = notify;
+ }
+
+ async interpretAst(
+ ast: ExpressionAstExpression,
+ variables: Record,
+ input: ExpressionValue = null
+ ) {
+ const context = await this.getGlobalContext();
+ return await this.interpretAstWithContext(ast, input, {
+ ...(context ?? {}),
+ variables,
+ });
+ }
+
+ async interpretAstWithContext(
+ ast: ExpressionAstExpression,
+ input: ExpressionValue = null,
+ context?: ExpressionExecutionParams
+ ): Promise {
+ return await this.expressions
+ .execute(ast, input, context)
+ .getData()
+ .pipe(pluck('result'))
+ .toPromise();
+ }
+
+ /**
+ * Runs interpreter, usually in the browser
+ *
+ * @param {object} ast - Executable AST
+ * @param {any} input - Initial input for AST execution
+ * @param {object} variables - Variables to pass in to the intrepreter context
+ * @param {object} options
+ * @param {boolean} options.castToRender - try to cast to a type: render object?
+ * @returns {Promise}
+ */
+ async runInterpreter(
+ ast: ExpressionAstExpression,
+ input: ExpressionValue,
+ variables: Record,
+ options: Options = {}
+ ): Promise {
+ const context = await this.getGlobalContext();
+ const fullContext = { ...(context ?? {}), variables };
+
+ try {
+ const renderable = await this.interpretAstWithContext(ast, input, fullContext);
+
+ if (getType(renderable) === 'render') {
+ return renderable;
+ }
+
+ if (options.castToRender) {
+ return this.runInterpreter(fromExpression('render'), renderable, fullContext, {
+ castToRender: false,
+ });
+ }
+
+ throw new Error(`Ack! I don't know how to render a '${getType(renderable)}'`);
+ } catch (err) {
+ this.notify.error(err);
+ throw err;
+ }
+ }
+
+ getRenderer(name: string) {
+ return this.expressions.getRenderer(name);
+ }
+
+ getFunctions() {
+ return this.expressions.getFunctions();
+ }
+
+ private async getFilters() {
+ const filtersList = this.filters.getFilters();
+ const context = this.filters.getFiltersContext();
+ const filterExpression = filtersList.join(' | ');
+ const filterAST = fromExpression(filterExpression);
+ return await this.interpretAstWithContext(filterAST, null, context);
+ }
+
+ private async getGlobalContext() {
+ const canvasFilters = await this.getFilters();
+ const kibanaFilters = buildEmbeddableFilters(canvasFilters ? canvasFilters.and : []);
+ return {
+ searchContext: { ...kibanaFilters },
+ };
+ }
+}
+
+export type CanvasExpressionsService = ExpressionsService;
+export interface CanvasExpressionsServiceRequiredServices {
+ notify: CanvasNotifyService;
+ filters: CanvasFiltersService;
+}
export type CanvasExpressionsServiceFactory = KibanaPluginServiceFactory<
CanvasExpressionsService,
- CanvasStartDeps
+ CanvasStartDeps,
+ CanvasExpressionsServiceRequiredServices
>;
-export const expressionsServiceFactory: CanvasExpressionsServiceFactory = ({ startPlugins }) =>
- startPlugins.expressions;
+export const expressionsServiceFactory: CanvasExpressionsServiceFactory = (
+ { startPlugins },
+ requiredServices
+) => new ExpressionsService(startPlugins.expressions, requiredServices);
diff --git a/x-pack/plugins/canvas/public/services/kibana/filters.ts b/x-pack/plugins/canvas/public/services/kibana/filters.ts
new file mode 100644
index 0000000000000..872b6759b389b
--- /dev/null
+++ b/x-pack/plugins/canvas/public/services/kibana/filters.ts
@@ -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; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { KibanaPluginServiceFactory } from '../../../../../../src/plugins/presentation_util/public';
+// @ts-expect-error untyped local
+import { getState, getStore } from '../../state/store';
+import { State } from '../../../types';
+import { getGlobalFilters, getWorkpadVariablesAsObject } from '../../state/selectors/workpad';
+import { CanvasStartDeps } from '../../plugin';
+// @ts-expect-error untyped local
+import { setFilter } from '../../state/actions/elements';
+
+export class FiltersService {
+ constructor() {}
+
+ getFilters(state: State = getState()) {
+ return getGlobalFilters(state);
+ }
+
+ updateFilter(filterId: string, filterExpression: string) {
+ const { dispatch } = getStore();
+ dispatch(setFilter(filterExpression, filterId, true));
+ }
+
+ getFiltersContext(state: State = getState()) {
+ const variables = getWorkpadVariablesAsObject(state);
+ return { variables };
+ }
+}
+
+export type CanvasFiltersService = FiltersService;
+
+export type CanvasFiltersServiceFactory = KibanaPluginServiceFactory<
+ CanvasFiltersService,
+ CanvasStartDeps
+>;
+
+export const filtersServiceFactory: CanvasFiltersServiceFactory = () => new FiltersService();
diff --git a/x-pack/plugins/canvas/public/services/kibana/index.ts b/x-pack/plugins/canvas/public/services/kibana/index.ts
index 91767947bc0a6..c1ceb531657d0 100644
--- a/x-pack/plugins/canvas/public/services/kibana/index.ts
+++ b/x-pack/plugins/canvas/public/services/kibana/index.ts
@@ -24,10 +24,12 @@ import { platformServiceFactory } from './platform';
import { reportingServiceFactory } from './reporting';
import { visualizationsServiceFactory } from './visualizations';
import { workpadServiceFactory } from './workpad';
+import { filtersServiceFactory } from './filters';
export { customElementServiceFactory } from './custom_element';
export { embeddablesServiceFactory } from './embeddables';
export { expressionsServiceFactory } from './expressions';
+export { filtersServiceFactory } from './filters';
export { labsServiceFactory } from './labs';
export { notifyServiceFactory } from './notify';
export { platformServiceFactory } from './platform';
@@ -41,7 +43,8 @@ export const pluginServiceProviders: PluginServiceProviders<
> = {
customElement: new PluginServiceProvider(customElementServiceFactory),
embeddables: new PluginServiceProvider(embeddablesServiceFactory),
- expressions: new PluginServiceProvider(expressionsServiceFactory),
+ expressions: new PluginServiceProvider(expressionsServiceFactory, ['filters', 'notify']),
+ filters: new PluginServiceProvider(filtersServiceFactory),
labs: new PluginServiceProvider(labsServiceFactory),
navLink: new PluginServiceProvider(navLinkServiceFactory),
notify: new PluginServiceProvider(notifyServiceFactory),
diff --git a/x-pack/plugins/canvas/public/services/kibana/workpad.ts b/x-pack/plugins/canvas/public/services/kibana/workpad.ts
index 9f69d5096237c..c0ef1097555a6 100644
--- a/x-pack/plugins/canvas/public/services/kibana/workpad.ts
+++ b/x-pack/plugins/canvas/public/services/kibana/workpad.ts
@@ -5,6 +5,7 @@
* 2.0.
*/
+import { SavedObject } from 'kibana/public';
import { KibanaPluginServiceFactory } from '../../../../../../src/plugins/presentation_util/public';
import { CanvasStartDeps } from '../../plugin';
@@ -67,6 +68,21 @@ export const workpadServiceFactory: CanvasWorkpadServiceFactory = ({ coreStart,
return { css: DEFAULT_WORKPAD_CSS, variables: [], ...workpad };
},
+ export: async (id: string) => {
+ const workpad = await coreStart.http.get>(
+ `${getApiPath()}/export/${id}`
+ );
+ const { attributes } = workpad;
+
+ return {
+ ...workpad,
+ attributes: {
+ ...attributes,
+ css: attributes.css ?? DEFAULT_WORKPAD_CSS,
+ variables: attributes.variables ?? [],
+ },
+ };
+ },
resolve: async (id: string) => {
const { workpad, outcome, aliasId } = await coreStart.http.get(
`${getApiPath()}/resolve/${id}`
@@ -93,6 +109,14 @@ export const workpadServiceFactory: CanvasWorkpadServiceFactory = ({ coreStart,
}),
});
},
+ import: (workpad: CanvasWorkpad) =>
+ coreStart.http.post(`${getApiPath()}/import`, {
+ body: JSON.stringify({
+ ...sanitizeWorkpad({ ...workpad }),
+ assets: workpad.assets || {},
+ variables: workpad.variables || [],
+ }),
+ }),
createFromTemplate: (templateId: string) => {
return coreStart.http.post(getApiPath(), {
body: JSON.stringify({ templateId }),
diff --git a/x-pack/plugins/canvas/public/services/storybook/workpad.ts b/x-pack/plugins/canvas/public/services/storybook/workpad.ts
index 6c77bdb1adeac..5dd40997900c6 100644
--- a/x-pack/plugins/canvas/public/services/storybook/workpad.ts
+++ b/x-pack/plugins/canvas/public/services/storybook/workpad.ts
@@ -31,7 +31,7 @@ type CanvasWorkpadServiceFactory = PluginServiceFactory () => new Promise((resolve) => setTimeout(resolve, time));
-const { findNoTemplates, findNoWorkpads, findSomeTemplates } = stubs;
+const { findNoTemplates, findNoWorkpads, findSomeTemplates, importWorkpad } = stubs;
const getRandomName = () => {
const lorem =
@@ -85,6 +85,10 @@ export const workpadServiceFactory: CanvasWorkpadServiceFactory = ({
action('workpadService.findTemplates')();
return (hasTemplates ? findSomeTemplates() : findNoTemplates())();
},
+ import: (workpad) => {
+ action('workpadService.import')(workpad);
+ return importWorkpad(workpad);
+ },
create: (workpad) => {
action('workpadService.create')(workpad);
return Promise.resolve(workpad);
diff --git a/x-pack/plugins/canvas/public/services/stubs/expressions.ts b/x-pack/plugins/canvas/public/services/stubs/expressions.ts
index 6660c1c6efb35..405f2ebe0ba91 100644
--- a/x-pack/plugins/canvas/public/services/stubs/expressions.ts
+++ b/x-pack/plugins/canvas/public/services/stubs/expressions.ts
@@ -10,11 +10,22 @@ import { plugin } from '../../../../../../src/plugins/expressions/public';
import { functions as functionDefinitions } from '../../../canvas_plugin_src/functions/common';
import { renderFunctions } from '../../../canvas_plugin_src/renderers/core';
import { PluginServiceFactory } from '../../../../../../src/plugins/presentation_util/public';
-import { CanvasExpressionsService } from '../expressions';
+import {
+ CanvasExpressionsService,
+ CanvasExpressionsServiceRequiredServices,
+ ExpressionsService,
+} from '../kibana/expressions';
-type CanvasExpressionsServiceFactory = PluginServiceFactory;
+type CanvasExpressionsServiceFactory = PluginServiceFactory<
+ CanvasExpressionsService,
+ {},
+ CanvasExpressionsServiceRequiredServices
+>;
-export const expressionsServiceFactory: CanvasExpressionsServiceFactory = () => {
+export const expressionsServiceFactory: CanvasExpressionsServiceFactory = (
+ params,
+ requiredServices
+) => {
const placeholder = {} as any;
const expressionsPlugin = plugin(placeholder);
const setup = expressionsPlugin.setup(placeholder);
@@ -25,5 +36,5 @@ export const expressionsServiceFactory: CanvasExpressionsServiceFactory = () =>
expressionsService.registerRenderer(fn as unknown as AnyExpressionRenderDefinition);
});
- return expressionsService;
+ return new ExpressionsService(expressionsService, requiredServices);
};
diff --git a/x-pack/plugins/canvas/public/services/stubs/filters.ts b/x-pack/plugins/canvas/public/services/stubs/filters.ts
new file mode 100644
index 0000000000000..972dbfd6dc0e4
--- /dev/null
+++ b/x-pack/plugins/canvas/public/services/stubs/filters.ts
@@ -0,0 +1,23 @@
+/*
+ * 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 { PluginServiceFactory } from '../../../../../../src/plugins/presentation_util/public';
+import { CanvasFiltersService } from '../filters';
+
+export type CanvasFiltersServiceFactory = PluginServiceFactory;
+
+const noop = (..._args: any[]): any => {};
+
+export const filtersServiceFactory: CanvasFiltersServiceFactory = () => ({
+ getFilters: () => [
+ 'exactly value="machine-learning" column="project1" filterGroup="Group 1"',
+ 'exactly value="kibana" column="project2" filterGroup="Group 1"',
+ 'time column="@timestamp1" from="2021-11-02 17:13:18" to="2021-11-09 17:13:18" filterGroup="Some group"',
+ ],
+ updateFilter: noop,
+ getFiltersContext: () => ({ variables: {} }),
+});
diff --git a/x-pack/plugins/canvas/public/services/stubs/index.ts b/x-pack/plugins/canvas/public/services/stubs/index.ts
index 2216013a29c12..d90b1a3c92201 100644
--- a/x-pack/plugins/canvas/public/services/stubs/index.ts
+++ b/x-pack/plugins/canvas/public/services/stubs/index.ts
@@ -24,9 +24,11 @@ import { platformServiceFactory } from './platform';
import { reportingServiceFactory } from './reporting';
import { visualizationsServiceFactory } from './visualizations';
import { workpadServiceFactory } from './workpad';
+import { filtersServiceFactory } from './filters';
export { customElementServiceFactory } from './custom_element';
export { expressionsServiceFactory } from './expressions';
+export { filtersServiceFactory } from './filters';
export { labsServiceFactory } from './labs';
export { navLinkServiceFactory } from './nav_link';
export { notifyServiceFactory } from './notify';
@@ -38,7 +40,8 @@ export { workpadServiceFactory } from './workpad';
export const pluginServiceProviders: PluginServiceProviders = {
customElement: new PluginServiceProvider(customElementServiceFactory),
embeddables: new PluginServiceProvider(embeddablesServiceFactory),
- expressions: new PluginServiceProvider(expressionsServiceFactory),
+ expressions: new PluginServiceProvider(expressionsServiceFactory, ['filters', 'notify']),
+ filters: new PluginServiceProvider(filtersServiceFactory),
labs: new PluginServiceProvider(labsServiceFactory),
navLink: new PluginServiceProvider(navLinkServiceFactory),
notify: new PluginServiceProvider(notifyServiceFactory),
diff --git a/x-pack/plugins/canvas/public/services/stubs/workpad.ts b/x-pack/plugins/canvas/public/services/stubs/workpad.ts
index c10244038750d..6268fa128df0f 100644
--- a/x-pack/plugins/canvas/public/services/stubs/workpad.ts
+++ b/x-pack/plugins/canvas/public/services/stubs/workpad.ts
@@ -6,13 +6,12 @@
*/
import moment from 'moment';
-
import { PluginServiceFactory } from '../../../../../../src/plugins/presentation_util/public';
// @ts-expect-error
-import { getDefaultWorkpad } from '../../state/defaults';
+import { getDefaultWorkpad, getExportedWorkpad } from '../../state/defaults';
import { CanvasWorkpadService } from '../workpad';
-import { CanvasTemplate } from '../../../types';
+import { CanvasTemplate, CanvasWorkpad } from '../../../types';
type CanvasWorkpadServiceFactory = PluginServiceFactory;
@@ -94,6 +93,7 @@ export const findNoTemplates =
.then(() => getNoTemplates());
};
+export const importWorkpad = (workpad: CanvasWorkpad) => Promise.resolve(workpad);
export const getNoTemplates = () => ({ templates: [] });
export const getSomeTemplates = () => ({ templates });
@@ -103,6 +103,7 @@ export const workpadServiceFactory: CanvasWorkpadServiceFactory = () => ({
Promise.resolve({ outcome: 'exactMatch', workpad: { ...getDefaultWorkpad(), id } }),
findTemplates: findNoTemplates(),
create: (workpad) => Promise.resolve(workpad),
+ import: (workpad) => importWorkpad(workpad),
createFromTemplate: (_templateId: string) => Promise.resolve(getDefaultWorkpad()),
find: findNoWorkpads(),
remove: (_id: string) => Promise.resolve(),
diff --git a/x-pack/plugins/canvas/public/services/workpad.ts b/x-pack/plugins/canvas/public/services/workpad.ts
index 8e77ab3f321ef..233b1a70ff7f6 100644
--- a/x-pack/plugins/canvas/public/services/workpad.ts
+++ b/x-pack/plugins/canvas/public/services/workpad.ts
@@ -25,10 +25,12 @@ export interface ResolveWorkpadResponse {
outcome: SavedObjectsResolveResponse['outcome'];
aliasId?: SavedObjectsResolveResponse['alias_target_id'];
}
+
export interface CanvasWorkpadService {
get: (id: string) => Promise;
resolve: (id: string) => Promise;
create: (workpad: CanvasWorkpad) => Promise;
+ import: (workpad: CanvasWorkpad) => Promise;
createFromTemplate: (templateId: string) => Promise;
find: (term: string) => Promise;
remove: (id: string) => Promise;
diff --git a/x-pack/plugins/canvas/public/state/actions/elements.js b/x-pack/plugins/canvas/public/state/actions/elements.js
index bcc02c3cbc2cd..72186abd38c94 100644
--- a/x-pack/plugins/canvas/public/state/actions/elements.js
+++ b/x-pack/plugins/canvas/public/state/actions/elements.js
@@ -20,7 +20,6 @@ import {
import { getValue as getResolvedArgsValue } from '../selectors/resolved_args';
import { getDefaultElement } from '../defaults';
import { ErrorStrings } from '../../../i18n';
-import { runInterpreter, interpretAst } from '../../lib/run_interpreter';
import { subMultitree } from '../../lib/aeroelastic/functional';
import { pluginServices } from '../../services';
import { selectToplevelNodes } from './transient';
@@ -101,11 +100,16 @@ export const fetchContext = createThunk(
});
const variables = getWorkpadVariablesAsObject(getState());
+
+ const { expressions } = pluginServices.getServices();
const elementWithNewAst = set(element, pathToTarget, astChain);
+
// get context data from a partial AST
- return interpretAst(elementWithNewAst.ast, variables, prevContextValue).then((value) => {
- dispatch(args.setValue({ path: contextPath, value }));
- });
+ return expressions
+ .interpretAst(elementWithNewAst.ast, variables, prevContextValue)
+ .then((value) => {
+ dispatch(args.setValue({ path: contextPath, value }));
+ });
}
);
@@ -124,14 +128,14 @@ const fetchRenderableWithContextFn = ({ dispatch, getState }, element, ast, cont
});
const variables = getWorkpadVariablesAsObject(getState());
-
- return runInterpreter(ast, context, variables, { castToRender: true })
+ const { expressions, notify } = pluginServices.getServices();
+ return expressions
+ .runInterpreter(ast, context, variables, { castToRender: true })
.then((renderable) => {
dispatch(getAction(renderable));
})
.catch((err) => {
- const notifyService = pluginServices.getServices().notify;
- notifyService.error(err);
+ notify.error(err);
dispatch(getAction(err));
});
};
@@ -171,12 +175,13 @@ export const fetchAllRenderables = createThunk(
const argumentPath = [element.id, 'expressionRenderable'];
const variables = getWorkpadVariablesAsObject(getState());
+ const { expressions, notify } = pluginServices.getServices();
- return runInterpreter(ast, null, variables, { castToRender: true })
+ return expressions
+ .runInterpreter(ast, null, variables, { castToRender: true })
.then((renderable) => ({ path: argumentPath, value: renderable }))
.catch((err) => {
- const notifyService = pluginServices.getServices().notify;
- notifyService.error(err);
+ notify.error(err);
return { path: argumentPath, value: err };
});
});
diff --git a/x-pack/plugins/canvas/public/state/defaults.js b/x-pack/plugins/canvas/public/state/defaults.js
index 40e8425c98ff0..a4a38d50388d5 100644
--- a/x-pack/plugins/canvas/public/state/defaults.js
+++ b/x-pack/plugins/canvas/public/state/defaults.js
@@ -87,6 +87,14 @@ export const getDefaultWorkpad = () => {
};
};
+export const getExportedWorkpad = () => {
+ const workpad = getDefaultWorkpad();
+ return {
+ id: workpad.id,
+ attributes: workpad,
+ };
+};
+
export const getDefaultSidebar = () => ({
groupFiltersByOption: DEFAULT_GROUP_BY_FIELD,
});
diff --git a/x-pack/plugins/canvas/public/state/selectors/workpad.ts b/x-pack/plugins/canvas/public/state/selectors/workpad.ts
index ac94ccc562e88..557a6b8acc4e7 100644
--- a/x-pack/plugins/canvas/public/state/selectors/workpad.ts
+++ b/x-pack/plugins/canvas/public/state/selectors/workpad.ts
@@ -27,6 +27,7 @@ import {
ExpressionAstFunction,
ExpressionAstExpression,
} from '../../../types';
+import { isExpressionWithFilters } from '../../lib/filter';
type Modify = Pick> & R;
type WorkpadInfo = Modify;
@@ -248,7 +249,7 @@ function extractFilterGroups(
// TODO: we always get a function here, right?
const { function: fn, arguments: args } = item;
- if (fn === 'filters') {
+ if (isExpressionWithFilters(fn)) {
// we have a filter function, extract groups from args
return groups.concat(
buildGroupValues(args, (argValue) => {
diff --git a/x-pack/plugins/canvas/server/mocks/workpad_route_context.ts b/x-pack/plugins/canvas/server/mocks/workpad_route_context.ts
index 216cdc0970dc4..13e4e34b20b66 100644
--- a/x-pack/plugins/canvas/server/mocks/workpad_route_context.ts
+++ b/x-pack/plugins/canvas/server/mocks/workpad_route_context.ts
@@ -12,6 +12,7 @@ export interface MockWorkpadRouteContext extends CanvasRouteHandlerContext {
workpad: {
create: jest.Mock;
get: jest.Mock;
+ import: jest.Mock;
update: jest.Mock;
resolve: jest.Mock;
};
@@ -23,6 +24,7 @@ export const workpadRouteContextMock = {
workpad: {
create: jest.fn(),
get: jest.fn(),
+ import: jest.fn(),
update: jest.fn(),
resolve: jest.fn(),
},
diff --git a/x-pack/plugins/canvas/server/plugin.ts b/x-pack/plugins/canvas/server/plugin.ts
index ebe43ba76a46a..27b6186216b69 100644
--- a/x-pack/plugins/canvas/server/plugin.ts
+++ b/x-pack/plugins/canvas/server/plugin.ts
@@ -23,7 +23,8 @@ import { initRoutes } from './routes';
import { registerCanvasUsageCollector } from './collectors';
import { loadSampleData } from './sample_data';
import { setupInterpreter } from './setup_interpreter';
-import { customElementType, workpadType, workpadTemplateType } from './saved_objects';
+import { customElementType, workpadTypeFactory, workpadTemplateType } from './saved_objects';
+import type { CanvasSavedObjectTypeMigrationsDeps } from './saved_objects/migrations';
import { initializeTemplates } from './templates';
import { essqlSearchStrategyProvider } from './lib/essql_strategy';
import { getUISettings } from './ui_settings';
@@ -53,10 +54,18 @@ export class CanvasPlugin implements Plugin {
public setup(coreSetup: CoreSetup, plugins: PluginsSetup) {
const expressionsFork = plugins.expressions.fork();
+ setupInterpreter(expressionsFork, {
+ embeddablePersistableStateService: {
+ extract: plugins.embeddable.extract,
+ inject: plugins.embeddable.inject,
+ },
+ });
+
+ const deps: CanvasSavedObjectTypeMigrationsDeps = { expressions: expressionsFork };
coreSetup.uiSettings.register(getUISettings());
- coreSetup.savedObjects.registerType(customElementType);
- coreSetup.savedObjects.registerType(workpadType);
- coreSetup.savedObjects.registerType(workpadTemplateType);
+ coreSetup.savedObjects.registerType(customElementType(deps));
+ coreSetup.savedObjects.registerType(workpadTypeFactory(deps));
+ coreSetup.savedObjects.registerType(workpadTemplateType(deps));
plugins.features.registerKibanaFeature(getCanvasFeature(plugins));
@@ -84,13 +93,6 @@ export class CanvasPlugin implements Plugin {
const kibanaIndex = coreSetup.savedObjects.getKibanaIndex();
registerCanvasUsageCollector(plugins.usageCollection, kibanaIndex);
- setupInterpreter(expressionsFork, {
- embeddablePersistableStateService: {
- extract: plugins.embeddable.extract,
- inject: plugins.embeddable.inject,
- },
- });
-
coreSetup.getStartServices().then(([_, depsStart]) => {
const strategy = essqlSearchStrategyProvider();
plugins.data.search.registerSearchStrategy(ESSQL_SEARCH_STRATEGY, strategy);
diff --git a/x-pack/plugins/canvas/server/routes/workpad/import.ts b/x-pack/plugins/canvas/server/routes/workpad/import.ts
new file mode 100644
index 0000000000000..35d362f43becc
--- /dev/null
+++ b/x-pack/plugins/canvas/server/routes/workpad/import.ts
@@ -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; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { RouteInitializerDeps } from '../';
+import { API_ROUTE_WORKPAD_IMPORT } from '../../../common/lib/constants';
+import { ImportedCanvasWorkpad } from '../../../types';
+import { ImportedWorkpadSchema } from './workpad_schema';
+import { okResponse } from '../ok_response';
+import { catchErrorHandler } from '../catch_error_handler';
+
+const createRequestBodySchema = ImportedWorkpadSchema;
+
+export function initializeImportWorkpadRoute(deps: RouteInitializerDeps) {
+ const { router } = deps;
+ router.post(
+ {
+ path: `${API_ROUTE_WORKPAD_IMPORT}`,
+ validate: {
+ body: createRequestBodySchema,
+ },
+ options: {
+ body: {
+ maxBytes: 26214400,
+ accepts: ['application/json'],
+ },
+ },
+ },
+ catchErrorHandler(async (context, request, response) => {
+ const workpad = request.body as ImportedCanvasWorkpad;
+
+ const createdObject = await context.canvas.workpad.import(workpad);
+
+ return response.ok({
+ body: { ...okResponse, id: createdObject.id },
+ });
+ })
+ );
+}
diff --git a/x-pack/plugins/canvas/server/routes/workpad/index.ts b/x-pack/plugins/canvas/server/routes/workpad/index.ts
index 8483642e59c5a..b97d58ee232f1 100644
--- a/x-pack/plugins/canvas/server/routes/workpad/index.ts
+++ b/x-pack/plugins/canvas/server/routes/workpad/index.ts
@@ -9,6 +9,7 @@ import { RouteInitializerDeps } from '../';
import { initializeFindWorkpadsRoute } from './find';
import { initializeGetWorkpadRoute } from './get';
import { initializeCreateWorkpadRoute } from './create';
+import { initializeImportWorkpadRoute } from './import';
import { initializeUpdateWorkpadRoute, initializeUpdateWorkpadAssetsRoute } from './update';
import { initializeDeleteWorkpadRoute } from './delete';
import { initializeResolveWorkpadRoute } from './resolve';
@@ -18,6 +19,7 @@ export function initWorkpadRoutes(deps: RouteInitializerDeps) {
initializeResolveWorkpadRoute(deps);
initializeGetWorkpadRoute(deps);
initializeCreateWorkpadRoute(deps);
+ initializeImportWorkpadRoute(deps);
initializeUpdateWorkpadRoute(deps);
initializeUpdateWorkpadAssetsRoute(deps);
initializeDeleteWorkpadRoute(deps);
diff --git a/x-pack/plugins/canvas/server/routes/workpad/workpad_schema.ts b/x-pack/plugins/canvas/server/routes/workpad/workpad_schema.ts
index 9bde26298185b..473b46d470265 100644
--- a/x-pack/plugins/canvas/server/routes/workpad/workpad_schema.ts
+++ b/x-pack/plugins/canvas/server/routes/workpad/workpad_schema.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import { schema } from '@kbn/config-schema';
+import { TypeOf, schema } from '@kbn/config-schema';
export const PositionSchema = schema.object({
angle: schema.number(),
@@ -18,30 +18,30 @@ export const PositionSchema = schema.object({
export const WorkpadElementSchema = schema.object({
expression: schema.string(),
- filter: schema.maybe(schema.nullable(schema.string())),
+ filter: schema.nullable(schema.string({ defaultValue: '' })),
id: schema.string(),
position: PositionSchema,
});
export const WorkpadPageSchema = schema.object({
elements: schema.arrayOf(WorkpadElementSchema),
- groups: schema.maybe(
- schema.arrayOf(
- schema.object({
- id: schema.string(),
- position: PositionSchema,
- })
- )
+ groups: schema.arrayOf(
+ schema.object({
+ id: schema.string(),
+ position: PositionSchema,
+ }),
+ { defaultValue: [] }
),
id: schema.string(),
style: schema.recordOf(schema.string(), schema.string()),
- transition: schema.maybe(
- schema.oneOf([
- schema.object({}),
+ transition: schema.oneOf(
+ [
+ schema.object({}, { defaultValue: {} }),
schema.object({
name: schema.string(),
}),
- ])
+ ],
+ { defaultValue: {} }
),
});
@@ -55,44 +55,71 @@ export const WorkpadAssetSchema = schema.object({
export const WorkpadVariable = schema.object({
name: schema.string(),
value: schema.oneOf([schema.string(), schema.number(), schema.boolean()]),
- type: schema.string(),
+ type: schema.string({
+ validate: (type) => {
+ const validTypes = ['string', 'number', 'boolean'];
+ if (type && !validTypes.includes(type)) {
+ return `${type} is invalid type for a variable. Valid types: ${validTypes.join(', ')}.`;
+ }
+ },
+ }),
});
-export const WorkpadSchema = schema.object(
- {
- '@created': schema.maybe(schema.string()),
- '@timestamp': schema.maybe(schema.string()),
- assets: schema.maybe(schema.recordOf(schema.string(), WorkpadAssetSchema)),
- colors: schema.arrayOf(schema.string()),
- css: schema.string(),
- variables: schema.arrayOf(WorkpadVariable),
- height: schema.number(),
- id: schema.string(),
- isWriteable: schema.maybe(schema.boolean()),
- name: schema.string(),
- page: schema.number(),
- pages: schema.arrayOf(WorkpadPageSchema),
- width: schema.number(),
- },
- {
- validate: (workpad) => {
- // Validate unique page ids
- const pageIdsArray = workpad.pages.map((page) => page.id);
- const pageIdsSet = new Set(pageIdsArray);
+const commonWorkpadFields = {
+ '@created': schema.maybe(schema.string()),
+ '@timestamp': schema.maybe(schema.string()),
+ colors: schema.arrayOf(schema.string()),
+ css: schema.string(),
+ variables: schema.arrayOf(WorkpadVariable),
+ height: schema.number(),
+ id: schema.maybe(schema.string()),
+ isWriteable: schema.maybe(schema.boolean()),
+ name: schema.string(),
+ page: schema.number(),
+ pages: schema.arrayOf(WorkpadPageSchema),
+ width: schema.number(),
+};
- if (pageIdsArray.length !== pageIdsSet.size) {
- return 'Page Ids are not unique';
- }
+const WorkpadSchemaWithoutValidation = schema.object({
+ assets: schema.maybe(schema.recordOf(schema.string(), WorkpadAssetSchema)),
+ ...commonWorkpadFields,
+});
- // Validate unique element ids
- const elementIdsArray = workpad.pages
- .map((page) => page.elements.map((element) => element.id))
- .flat();
- const elementIdsSet = new Set(elementIdsArray);
+const ImportedWorkpadSchemaWithoutValidation = schema.object({
+ assets: schema.recordOf(schema.string(), WorkpadAssetSchema),
+ ...commonWorkpadFields,
+});
- if (elementIdsArray.length !== elementIdsSet.size) {
- return 'Element Ids are not unique';
- }
- },
+const validate = (workpad: TypeOf) => {
+ // Validate unique page ids
+ const pageIdsArray = workpad.pages.map((page) => page.id);
+ const pageIdsSet = new Set(pageIdsArray);
+
+ if (pageIdsArray.length !== pageIdsSet.size) {
+ return 'Page Ids are not unique';
+ }
+
+ // Validate unique element ids
+ const elementIdsArray = workpad.pages
+ .map((page) => page.elements.map((element) => element.id))
+ .flat();
+ const elementIdsSet = new Set(elementIdsArray);
+
+ if (elementIdsArray.length !== elementIdsSet.size) {
+ return 'Element Ids are not unique';
+ }
+};
+
+export const WorkpadSchema = WorkpadSchemaWithoutValidation.extends(
+ {},
+ {
+ validate,
+ }
+);
+
+export const ImportedWorkpadSchema = ImportedWorkpadSchemaWithoutValidation.extends(
+ {},
+ {
+ validate,
}
);
diff --git a/x-pack/plugins/canvas/server/saved_objects/custom_element.ts b/x-pack/plugins/canvas/server/saved_objects/custom_element.ts
index d62642f5619ea..82305b2fdd95f 100644
--- a/x-pack/plugins/canvas/server/saved_objects/custom_element.ts
+++ b/x-pack/plugins/canvas/server/saved_objects/custom_element.ts
@@ -7,8 +7,9 @@
import { SavedObjectsType } from 'src/core/server';
import { CUSTOM_ELEMENT_TYPE } from '../../common/lib/constants';
+import { customElementMigrationsFactory, CanvasSavedObjectTypeMigrationsDeps } from './migrations';
-export const customElementType: SavedObjectsType = {
+export const customElementType = (deps: CanvasSavedObjectTypeMigrationsDeps): SavedObjectsType => ({
name: CUSTOM_ELEMENT_TYPE,
hidden: false,
namespaceType: 'multiple-isolated',
@@ -31,7 +32,7 @@ export const customElementType: SavedObjectsType = {
'@created': { type: 'date' },
},
},
- migrations: {},
+ migrations: customElementMigrationsFactory(deps),
management: {
icon: 'canvasApp',
defaultSearchField: 'name',
@@ -40,4 +41,4 @@ export const customElementType: SavedObjectsType = {
return obj.attributes.displayName;
},
},
-};
+});
diff --git a/x-pack/plugins/canvas/server/saved_objects/index.ts b/x-pack/plugins/canvas/server/saved_objects/index.ts
index dfc27c4b6fa66..9e7cd8644c7c7 100644
--- a/x-pack/plugins/canvas/server/saved_objects/index.ts
+++ b/x-pack/plugins/canvas/server/saved_objects/index.ts
@@ -5,8 +5,8 @@
* 2.0.
*/
-import { workpadType } from './workpad';
+import { workpadTypeFactory } from './workpad';
import { customElementType } from './custom_element';
import { workpadTemplateType } from './workpad_template';
-export { customElementType, workpadType, workpadTemplateType };
+export { customElementType, workpadTypeFactory, workpadTemplateType };
diff --git a/x-pack/plugins/canvas/server/saved_objects/migrations/expressions.ts b/x-pack/plugins/canvas/server/saved_objects/migrations/expressions.ts
new file mode 100644
index 0000000000000..20eba14c5cff0
--- /dev/null
+++ b/x-pack/plugins/canvas/server/saved_objects/migrations/expressions.ts
@@ -0,0 +1,145 @@
+/*
+ * 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 { Ast, fromExpression, toExpression } from '@kbn/interpreter';
+import { Serializable } from '@kbn/utility-types';
+import { SavedObjectMigrationFn, SavedObjectUnsanitizedDoc } from 'kibana/server';
+import { flowRight, mapValues } from 'lodash';
+import {
+ CanvasElement,
+ CanvasTemplateElement,
+ CanvasTemplate,
+ CustomElement,
+ CustomElementContent,
+ CustomElementNode,
+} from '../../../types';
+import {
+ MigrateFunction,
+ MigrateFunctionsObject,
+} from '../../../../../../src/plugins/kibana_utils/common';
+import { WorkpadAttributes } from '../../routes/workpad/workpad_attributes';
+import { CanvasSavedObjectTypeMigrationsDeps } from './types';
+
+type ToSerializable = {
+ [K in keyof Type]: Type[K] extends unknown[]
+ ? ToSerializable
+ : Type[K] extends {}
+ ? ToSerializable
+ : Serializable;
+};
+
+type ExprAst = ToSerializable;
+
+interface CommonPage {
+ elements?: T[];
+}
+interface CommonWorkpad, U> {
+ pages?: T[];
+}
+
+type MigrationFn = (
+ migrate: MigrateFunction,
+ version: string
+) => SavedObjectMigrationFn;
+
+const toAst = (expression: string): ExprAst => fromExpression(expression);
+const fromAst = (ast: Ast): string => toExpression(ast);
+
+const migrateExpr = (expr: string, migrateFn: MigrateFunction) =>
+ flowRight(fromAst, migrateFn, toAst)(expr);
+
+const migrateWorkpadElement =
+ (migrate: MigrateFunction) =>
+ ({ filter, expression, ...element }: CanvasElement | CustomElementNode) => ({
+ ...element,
+ filter: filter ? migrateExpr(filter, migrate) : filter,
+ expression: expression ? migrateExpr(expression, migrate) : expression,
+ });
+
+const migrateTemplateElement =
+ (migrate: MigrateFunction) =>
+ ({ expression, ...element }: CanvasTemplateElement) => ({
+ ...element,
+ expression: expression ? migrateExpr(expression, migrate) : expression,
+ });
+
+const migrateWorkpadElements = , U>(
+ doc: SavedObjectUnsanitizedDoc | undefined>,
+ migrateElementFn: any
+) => {
+ if (
+ typeof doc.attributes !== 'object' ||
+ doc.attributes === null ||
+ doc.attributes === undefined
+ ) {
+ return doc;
+ }
+
+ const { pages } = doc.attributes;
+
+ const newPages = pages?.map((page) => {
+ const { elements } = page;
+ const newElements = elements?.map(migrateElementFn);
+ return { ...page, elements: newElements };
+ });
+
+ return { ...doc, attributes: { ...doc.attributes, pages: newPages } };
+};
+
+const migrateTemplateWorkpadExpressions: MigrationFn =
+ (migrate) => (doc) =>
+ migrateWorkpadElements(doc, migrateTemplateElement(migrate));
+
+const migrateWorkpadExpressionsAndFilters: MigrationFn = (migrate) => (doc) =>
+ migrateWorkpadElements(doc, migrateWorkpadElement(migrate));
+
+const migrateCustomElementExpressionsAndFilters: MigrationFn =
+ (migrate) => (doc) => {
+ if (
+ typeof doc.attributes !== 'object' ||
+ doc.attributes === null ||
+ doc.attributes === undefined
+ ) {
+ return doc;
+ }
+
+ const { content } = doc.attributes;
+ const { selectedNodes = [] }: CustomElementContent = content
+ ? JSON.parse(content)
+ : { selectedNodes: [] };
+
+ const newSelectedNodes = selectedNodes.map((element) => {
+ const newElement = migrateWorkpadElement(migrate)(element);
+ return { ...element, ...newElement, ast: toAst(newElement.expression) };
+ });
+
+ const newContent = JSON.stringify({ selectedNodes: newSelectedNodes });
+ return { ...doc, attributes: { ...doc.attributes, content: newContent } };
+ };
+
+export const workpadExpressionsMigrationsFactory = ({
+ expressions,
+}: CanvasSavedObjectTypeMigrationsDeps) =>
+ mapValues>(
+ expressions.getAllMigrations(),
+ migrateWorkpadExpressionsAndFilters
+ ) as MigrateFunctionsObject;
+
+export const templateWorkpadExpressionsMigrationsFactory = ({
+ expressions,
+}: CanvasSavedObjectTypeMigrationsDeps) =>
+ mapValues>(
+ expressions.getAllMigrations(),
+ migrateTemplateWorkpadExpressions
+ ) as MigrateFunctionsObject;
+
+export const customElementExpressionsMigrationsFactory = ({
+ expressions,
+}: CanvasSavedObjectTypeMigrationsDeps) =>
+ mapValues