{
+ if (input) {
+ this.inputRef = input;
+ }
+ }}
+ style={{ minWidth: '300px' }}
+ placeholder={i18n.translate('xpack.ml.timeSeriesExplorer.enterValuePlaceholder', {
+ defaultMessage: 'Enter value',
+ })}
+ singleSelection={{ asPlainText: true }}
+ options={options}
+ selectedOptions={selectedOptions}
+ onChange={this.onChange}
+ onSearchChange={this.onSearchChange}
+ isClearable={false}
+ />
+ );
+
+ const selectMessage = (
+
+ );
+
+ return (
+
+
+
+ {control}
+
+
+
+ );
+ }
+}
diff --git a/x-pack/legacy/plugins/ml/public/application/timeseriesexplorer/components/entity_control/index.js b/x-pack/legacy/plugins/ml/public/application/timeseriesexplorer/components/entity_control/index.ts
similarity index 100%
rename from x-pack/legacy/plugins/ml/public/application/timeseriesexplorer/components/entity_control/index.js
rename to x-pack/legacy/plugins/ml/public/application/timeseriesexplorer/components/entity_control/index.ts
diff --git a/x-pack/legacy/plugins/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart.js b/x-pack/legacy/plugins/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart.js
index 2e0fc44a158ead..9db6f8f0a1c35b 100644
--- a/x-pack/legacy/plugins/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart.js
+++ b/x-pack/legacy/plugins/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart.js
@@ -445,8 +445,6 @@ const TimeseriesChartIntl = injectI18n(
};
this.selectedBounds = newSelectedBounds;
} else {
- // Don't set the brush if the selection is the full context chart domain.
- this.setBrushVisibility(false);
const contextXScaleDomain = this.contextXScale.domain();
const newSelectedBounds = {
min: moment(new Date(contextXScaleDomain[0])),
diff --git a/x-pack/legacy/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js b/x-pack/legacy/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js
index 0f9ef2b54fdc23..202448340f526d 100644
--- a/x-pack/legacy/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js
+++ b/x-pack/legacy/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js
@@ -8,7 +8,7 @@
* React component for rendering Single Metric Viewer.
*/
-import { chain, difference, each, find, first, get, has, isEqual, without } from 'lodash';
+import { debounce, difference, each, find, first, get, has, isEqual, without } from 'lodash';
import moment from 'moment-timezone';
import { Subject, Subscription, forkJoin } from 'rxjs';
import { map, debounceTime, switchMap, tap, withLatestFrom } from 'rxjs/operators';
@@ -362,6 +362,12 @@ export class TimeSeriesExplorer extends React.Component {
});
};
+ entityFieldSearchChanged = debounce((entity, queryTerm) => {
+ this.loadEntityValues({
+ [entity.fieldType]: queryTerm,
+ });
+ }, 500);
+
loadAnomaliesTableData = (earliestMs, latestMs) => {
const { dateFormatTz } = this.props;
const { selectedJob } = this.state;
@@ -419,58 +425,56 @@ export class TimeSeriesExplorer extends React.Component {
);
};
- loadEntityValues = (callback = () => {}) => {
+ /**
+ * Loads available entity values.
+ * @param {Object} searchTerm - Search term for partition, e.g. { partition_field: 'partition' }
+ * @param callback - Callback to execute after component state update.
+ */
+ loadEntityValues = async (searchTerm = {}, callback = () => {}) => {
const { timefilter } = this.props;
const { detectorId, entities, selectedJob } = this.state;
- // Populate the entity input datalists with the values from the top records by score
- // for the selected detector across the full time range. No need to pass through finish().
+ // Populate the entity input datalists with aggregated values. No need to pass through finish().
const bounds = timefilter.getActiveBounds();
const detectorIndex = +detectorId;
- mlResultsService
- .getRecordsForCriteria(
- [selectedJob.job_id],
- [{ fieldName: 'detector_index', fieldValue: detectorIndex }],
- 0,
+ const {
+ partition_field: partitionField,
+ over_field: overField,
+ by_field: byField,
+ } = await mlResultsService
+ .fetchPartitionFieldsValues(
+ selectedJob.job_id,
+ searchTerm,
+ [
+ {
+ fieldName: 'detector_index',
+ fieldValue: detectorIndex,
+ },
+ ],
bounds.min.valueOf(),
- bounds.max.valueOf(),
- ANOMALIES_TABLE_DEFAULT_QUERY_SIZE
+ bounds.max.valueOf()
)
- .toPromise()
- .then(resp => {
- if (resp.records && resp.records.length > 0) {
- const firstRec = resp.records[0];
+ .toPromise();
- this.setState(
- {
- entities: entities.map(entity => {
- const newEntity = { ...entity };
- if (firstRec.partition_field_name === newEntity.fieldName) {
- newEntity.fieldValues = chain(resp.records)
- .pluck('partition_field_value')
- .uniq()
- .value();
- }
- if (firstRec.over_field_name === newEntity.fieldName) {
- newEntity.fieldValues = chain(resp.records)
- .pluck('over_field_value')
- .uniq()
- .value();
- }
- if (firstRec.by_field_name === newEntity.fieldName) {
- newEntity.fieldValues = chain(resp.records)
- .pluck('by_field_value')
- .uniq()
- .value();
- }
- return newEntity;
- }),
- },
- callback
- );
- }
- });
+ this.setState(
+ {
+ entities: entities.map(entity => {
+ const newEntity = { ...entity };
+ if (partitionField?.name === entity.fieldName) {
+ newEntity.fieldValues = partitionField.values;
+ }
+ if (overField?.name === entity.fieldName) {
+ newEntity.fieldValues = overField.values;
+ }
+ if (byField?.name === entity.fieldName) {
+ newEntity.fieldValues = byField.values;
+ }
+ return newEntity;
+ }),
+ },
+ callback
+ );
};
loadForForecastId = forecastId => {
@@ -796,11 +800,19 @@ export class TimeSeriesExplorer extends React.Component {
const byFieldName = get(detector, 'by_field_name');
if (partitionFieldName !== undefined) {
const partitionFieldValue = get(entitiesState, partitionFieldName, '');
- entities.push({ fieldName: partitionFieldName, fieldValue: partitionFieldValue });
+ entities.push({
+ fieldType: 'partition_field',
+ fieldName: partitionFieldName,
+ fieldValue: partitionFieldValue,
+ });
}
if (overFieldName !== undefined) {
const overFieldValue = get(entitiesState, overFieldName, '');
- entities.push({ fieldName: overFieldName, fieldValue: overFieldValue });
+ entities.push({
+ fieldType: 'over_field',
+ fieldName: overFieldName,
+ fieldValue: overFieldValue,
+ });
}
// For jobs with by and over fields, don't add the 'by' field as this
@@ -810,7 +822,7 @@ export class TimeSeriesExplorer extends React.Component {
// from filter for the anomaly records.
if (byFieldName !== undefined && overFieldName === undefined) {
const byFieldValue = get(entitiesState, byFieldName, '');
- entities.push({ fieldName: byFieldName, fieldValue: byFieldValue });
+ entities.push({ fieldType: 'by_field', fieldName: byFieldName, fieldValue: byFieldValue });
}
this.updateCriteriaFields(detectorIndex, entities);
@@ -1338,6 +1350,7 @@ export class TimeSeriesExplorer extends React.Component {
diff --git a/x-pack/legacy/plugins/ml/server/client/elasticsearch_ml.js b/x-pack/legacy/plugins/ml/server/client/elasticsearch_ml.js
index 5d38de4a6ba87c..2ca21efb0bd6ae 100644
--- a/x-pack/legacy/plugins/ml/server/client/elasticsearch_ml.js
+++ b/x-pack/legacy/plugins/ml/server/client/elasticsearch_ml.js
@@ -168,7 +168,7 @@ export const elasticsearchJsPlugin = (Client, config, components) => {
method: 'POST',
});
- ml.estimateDataFrameAnalyticsMemoryUsage = ca({
+ ml.explainDataFrameAnalytics = ca({
urls: [
{
fmt: '/_ml/data_frame/analytics/_explain',
diff --git a/x-pack/legacy/plugins/ml/server/models/job_validation/messages.js b/x-pack/legacy/plugins/ml/server/models/job_validation/messages.js
index 4cd6dbc787d280..2c0c218bf86b51 100644
--- a/x-pack/legacy/plugins/ml/server/models/job_validation/messages.js
+++ b/x-pack/legacy/plugins/ml/server/models/job_validation/messages.js
@@ -14,7 +14,7 @@ export const getMessages = () => {
return messages;
}
- const createJobsDocsUrl = `https://www.elastic.co/guide/en/elastic-stack-overview/{{version}}/create-jobs.html`;
+ const createJobsDocsUrl = `https://www.elastic.co/guide/en/machine-learning/{{version}}/create-jobs.html`;
return (messages = {
field_not_aggregatable: {
@@ -26,7 +26,7 @@ export const getMessages = () => {
},
}),
url:
- 'https://www.elastic.co/guide/en/elastic-stack-overview/{{version}}/ml-configuring-aggregation.html',
+ 'https://www.elastic.co/guide/en/machine-learning/{{version}}/ml-configuring-aggregation.html',
},
fields_not_aggregatable: {
status: 'ERROR',
@@ -34,7 +34,7 @@ export const getMessages = () => {
defaultMessage: 'One of the detector fields is not an aggregatable field.',
}),
url:
- 'https://www.elastic.co/guide/en/elastic-stack-overview/{{version}}/ml-configuring-aggregation.html',
+ 'https://www.elastic.co/guide/en/machine-learning/{{version}}/ml-configuring-aggregation.html',
},
cardinality_by_field: {
status: 'WARNING',
@@ -112,7 +112,7 @@ export const getMessages = () => {
}
),
url:
- 'https://www.elastic.co/guide/en/elastic-stack-overview/{{version}}/ml-configuring-categories.html',
+ 'https://www.elastic.co/guide/en/machine-learning/{{version}}/ml-configuring-categories.html',
},
categorization_filters_invalid: {
status: 'ERROR',
diff --git a/x-pack/legacy/plugins/ml/server/models/results_service/get_partition_fields_values.ts b/x-pack/legacy/plugins/ml/server/models/results_service/get_partition_fields_values.ts
new file mode 100644
index 00000000000000..00e3002a7fc71e
--- /dev/null
+++ b/x-pack/legacy/plugins/ml/server/models/results_service/get_partition_fields_values.ts
@@ -0,0 +1,161 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import Boom from 'boom';
+import { ML_RESULTS_INDEX_PATTERN } from '../../../common/constants/index_patterns';
+import { callWithRequestType } from '../../../common/types/kibana';
+
+interface CriteriaField {
+ fieldName: string;
+ fieldValue: any;
+}
+
+const PARTITION_FIELDS = ['partition_field', 'over_field', 'by_field'] as const;
+
+type PartitionFieldsType = typeof PARTITION_FIELDS[number];
+
+type SearchTerm =
+ | {
+ [key in PartitionFieldsType]?: string;
+ }
+ | undefined;
+
+/**
+ * Gets an object for aggregation query to retrieve field name and values.
+ * @param fieldType - Field type
+ * @param query - Optional query string for partition value
+ * @returns {Object}
+ */
+function getFieldAgg(fieldType: PartitionFieldsType, query?: string) {
+ const AGG_SIZE = 100;
+
+ const fieldNameKey = `${fieldType}_name`;
+ const fieldValueKey = `${fieldType}_value`;
+
+ return {
+ [fieldNameKey]: {
+ terms: {
+ field: fieldNameKey,
+ },
+ },
+ [fieldValueKey]: {
+ filter: {
+ wildcard: {
+ [fieldValueKey]: {
+ value: query ? `*${query}*` : '*',
+ },
+ },
+ },
+ aggs: {
+ values: {
+ terms: {
+ size: AGG_SIZE,
+ field: fieldValueKey,
+ },
+ },
+ },
+ },
+ };
+}
+
+/**
+ * Gets formatted result for particular field from aggregation response.
+ * @param fieldType - Field type
+ * @param aggs - Aggregation response
+ */
+function getFieldObject(fieldType: PartitionFieldsType, aggs: any) {
+ const fieldNameKey = `${fieldType}_name`;
+ const fieldValueKey = `${fieldType}_value`;
+
+ return aggs[fieldNameKey].buckets.length > 0
+ ? {
+ [fieldType]: {
+ name: aggs[fieldNameKey].buckets[0].key,
+ values: aggs[fieldValueKey].values.buckets.map(({ key }: any) => key),
+ },
+ }
+ : {};
+}
+
+export const getPartitionFieldsValuesFactory = (callWithRequest: callWithRequestType) =>
+ /**
+ * Gets the record of partition fields with possible values that fit the provided queries.
+ * @param jobId - Job ID
+ * @param searchTerm - object of queries for partition fields, e.g. { partition_field: 'query' }
+ * @param criteriaFields - key - value pairs of the term field, e.g. { detector_index: 0 }
+ * @param earliestMs
+ * @param latestMs
+ */
+ async function getPartitionFieldsValues(
+ jobId: string,
+ searchTerm: SearchTerm = {},
+ criteriaFields: CriteriaField[],
+ earliestMs: number,
+ latestMs: number
+ ) {
+ const jobsResponse = await callWithRequest('ml.jobs', { jobId: [jobId] });
+ if (jobsResponse.count === 0 || jobsResponse.jobs === undefined) {
+ throw Boom.notFound(`Job with the id "${jobId}" not found`);
+ }
+
+ const job = jobsResponse.jobs[0];
+
+ const isModelPlotEnabled = job?.model_plot_config?.enabled;
+
+ const resp = await callWithRequest('search', {
+ index: ML_RESULTS_INDEX_PATTERN,
+ size: 0,
+ body: {
+ query: {
+ bool: {
+ filter: [
+ ...criteriaFields.map(({ fieldName, fieldValue }) => {
+ return {
+ term: {
+ [fieldName]: fieldValue,
+ },
+ };
+ }),
+ {
+ term: {
+ job_id: jobId,
+ },
+ },
+ {
+ range: {
+ timestamp: {
+ gte: earliestMs,
+ lte: latestMs,
+ format: 'epoch_millis',
+ },
+ },
+ },
+ {
+ term: {
+ result_type: isModelPlotEnabled ? 'model_plot' : 'record',
+ },
+ },
+ ],
+ },
+ },
+ aggs: {
+ ...PARTITION_FIELDS.reduce((acc, key) => {
+ return {
+ ...acc,
+ ...getFieldAgg(key, searchTerm[key]),
+ };
+ }, {}),
+ },
+ },
+ });
+
+ return PARTITION_FIELDS.reduce((acc, key) => {
+ return {
+ ...acc,
+ ...getFieldObject(key, resp.aggregations),
+ };
+ }, {});
+ };
diff --git a/x-pack/legacy/plugins/ml/server/models/results_service/results_service.js b/x-pack/legacy/plugins/ml/server/models/results_service/results_service.js
index c779664978f630..3ee5d04186ff10 100644
--- a/x-pack/legacy/plugins/ml/server/models/results_service/results_service.js
+++ b/x-pack/legacy/plugins/ml/server/models/results_service/results_service.js
@@ -10,6 +10,7 @@ import moment from 'moment';
import { buildAnomalyTableItems } from './build_anomaly_table_items';
import { ML_RESULTS_INDEX_PATTERN } from '../../../common/constants/index_patterns';
import { ANOMALIES_TABLE_DEFAULT_QUERY_SIZE } from '../../../common/constants/search';
+import { getPartitionFieldsValuesFactory } from './get_partition_fields_values';
// Service for carrying out Elasticsearch queries to obtain data for the
// ML Results dashboards.
@@ -408,5 +409,6 @@ export function resultsServiceProvider(callWithRequest) {
getCategoryExamples,
getLatestBucketTimestampByJob,
getMaxAnomalyScore,
+ getPartitionFieldsValues: getPartitionFieldsValuesFactory(callWithRequest),
};
}
diff --git a/x-pack/legacy/plugins/ml/server/routes/data_frame_analytics.ts b/x-pack/legacy/plugins/ml/server/routes/data_frame_analytics.ts
index 2f8db45d9739e4..7b855e5f87cbf6 100644
--- a/x-pack/legacy/plugins/ml/server/routes/data_frame_analytics.ts
+++ b/x-pack/legacy/plugins/ml/server/routes/data_frame_analytics.ts
@@ -164,7 +164,7 @@ export function dataFrameAnalyticsRoutes({ xpackMainPlugin, router }: RouteIniti
licensePreRoutingFactory(xpackMainPlugin, async (context, request, response) => {
try {
const results = await context.ml!.mlClient.callAsCurrentUser(
- 'ml.estimateDataFrameAnalyticsMemoryUsage',
+ 'ml.explainDataFrameAnalytics',
{
body: request.body,
}
diff --git a/x-pack/legacy/plugins/ml/server/routes/results_service.js b/x-pack/legacy/plugins/ml/server/routes/results_service.js
index 6d456e6a0412ea..a658729e850831 100644
--- a/x-pack/legacy/plugins/ml/server/routes/results_service.js
+++ b/x-pack/legacy/plugins/ml/server/routes/results_service.js
@@ -55,6 +55,12 @@ function getMaxAnomalyScore(callWithRequest, payload) {
return rs.getMaxAnomalyScore(jobIds, earliestMs, latestMs);
}
+function getPartitionFieldsValues(callWithRequest, payload) {
+ const rs = resultsServiceProvider(callWithRequest);
+ const { jobId, searchTerm, criteriaFields, earliestMs, latestMs } = payload;
+ return rs.getPartitionFieldsValues(jobId, searchTerm, criteriaFields, earliestMs, latestMs);
+}
+
export function resultsServiceRoutes({ commonRouteConfig, elasticsearchPlugin, route }) {
route({
method: 'POST',
@@ -103,4 +109,18 @@ export function resultsServiceRoutes({ commonRouteConfig, elasticsearchPlugin, r
...commonRouteConfig,
},
});
+
+ route({
+ method: 'POST',
+ path: '/api/ml/results/partition_fields_values',
+ handler(request) {
+ const callWithRequest = callWithRequestFactory(elasticsearchPlugin, request);
+ return getPartitionFieldsValues(callWithRequest, request.payload).catch(resp =>
+ wrapError(resp)
+ );
+ },
+ config: {
+ ...commonRouteConfig,
+ },
+ });
}
diff --git a/x-pack/legacy/plugins/monitoring/index.js b/x-pack/legacy/plugins/monitoring/index.js
index 3d98b11c2045b1..8e0201bea710bc 100644
--- a/x-pack/legacy/plugins/monitoring/index.js
+++ b/x-pack/legacy/plugins/monitoring/index.js
@@ -22,7 +22,7 @@ export const monitoring = kibana =>
id: 'monitoring',
configPrefix: 'xpack.monitoring',
publicDir: resolve(__dirname, 'public'),
- init(server, _options) {
+ init(server) {
const configs = [
'xpack.monitoring.ui.enabled',
'xpack.monitoring.kibana.collection.enabled',
diff --git a/x-pack/legacy/plugins/monitoring/public/components/chart/chart_target.js b/x-pack/legacy/plugins/monitoring/public/components/chart/chart_target.js
index c3ca241c73cc02..5c9cddf9c29022 100644
--- a/x-pack/legacy/plugins/monitoring/public/components/chart/chart_target.js
+++ b/x-pack/legacy/plugins/monitoring/public/components/chart/chart_target.js
@@ -46,7 +46,7 @@ export class ChartTarget extends React.Component {
return seriesToShow.some(id => id.toLowerCase() === metric.id.toLowerCase());
};
}
- return _metric => true;
+ return () => true;
}
UNSAFE_componentWillReceiveProps(newProps) {
diff --git a/x-pack/legacy/plugins/monitoring/public/components/chart/chart_target.test.js b/x-pack/legacy/plugins/monitoring/public/components/chart/chart_target.test.js
index bf0d5fdd248792..56eb52fa862350 100644
--- a/x-pack/legacy/plugins/monitoring/public/components/chart/chart_target.test.js
+++ b/x-pack/legacy/plugins/monitoring/public/components/chart/chart_target.test.js
@@ -38,8 +38,8 @@ const props = {
max: 1562962539851,
},
hasLegend: true,
- onBrush: _ => void 0,
- tickFormatter: _ => void 0,
+ onBrush: () => void 0,
+ tickFormatter: () => void 0,
updateLegend: () => void 0,
};
diff --git a/x-pack/legacy/plugins/monitoring/public/components/elasticsearch/shard_allocation/components/assigned.js b/x-pack/legacy/plugins/monitoring/public/components/elasticsearch/shard_allocation/components/assigned.js
index 012bc81135e341..897c20edc3f74a 100644
--- a/x-pack/legacy/plugins/monitoring/public/components/elasticsearch/shard_allocation/components/assigned.js
+++ b/x-pack/legacy/plugins/monitoring/public/components/elasticsearch/shard_allocation/components/assigned.js
@@ -46,6 +46,8 @@ export class Assigned extends React.Component {
// TODO: redesign for shard allocation, possibly giving shard display the
// ability to use the euiLink CSS class (blue link text instead of white link text)
+ // Disabling eslint because EuiKeyboardAccessible does it for us
+ /* eslint-disable jsx-a11y/click-events-have-key-events */
const name = (
@@ -53,6 +55,7 @@ export class Assigned extends React.Component {
);
+ /* eslint-enable jsx-a11y/click-events-have-key-events */
const master =
data.node_type === 'master' ? : null;
const shards = sortBy(data.children, 'shard').map(this.createShard);
diff --git a/x-pack/legacy/plugins/monitoring/public/components/logstash/pipeline_viewer/views/detail_drawer.js b/x-pack/legacy/plugins/monitoring/public/components/logstash/pipeline_viewer/views/detail_drawer.js
index cd9fe5229b6408..73faa81af7b55c 100644
--- a/x-pack/legacy/plugins/monitoring/public/components/logstash/pipeline_viewer/views/detail_drawer.js
+++ b/x-pack/legacy/plugins/monitoring/public/components/logstash/pipeline_viewer/views/detail_drawer.js
@@ -164,7 +164,7 @@ function renderPluginBasicStats(vertex, timeseriesTooltipXValueFormatter) {
);
}
-function renderIfBasicStats(_vertex) {
+function renderIfBasicStats() {
return (
{
+ _api; // to fix eslint
const $http = $injector.get('$http');
const globalState = $injector.get('globalState');
const timeBounds = timefilter.getBounds();
diff --git a/x-pack/legacy/plugins/monitoring/public/views/logstash/node/pipelines/index.js b/x-pack/legacy/plugins/monitoring/public/views/logstash/node/pipelines/index.js
index bc5ac75931fce5..7bfcddf8f283a6 100644
--- a/x-pack/legacy/plugins/monitoring/public/views/logstash/node/pipelines/index.js
+++ b/x-pack/legacy/plugins/monitoring/public/views/logstash/node/pipelines/index.js
@@ -23,6 +23,7 @@ import { DetailStatus } from '../../../../components/logstash/detail_status';
import { CODE_PATH_LOGSTASH } from '../../../../../common/constants';
const getPageData = ($injector, _api = undefined, routeOptions = {}) => {
+ _api; // fixing eslint
const $route = $injector.get('$route');
const $http = $injector.get('$http');
const globalState = $injector.get('globalState');
diff --git a/x-pack/legacy/plugins/monitoring/public/views/logstash/pipelines/index.js b/x-pack/legacy/plugins/monitoring/public/views/logstash/pipelines/index.js
index ce49fc2fac97bf..03cf7383d1d023 100644
--- a/x-pack/legacy/plugins/monitoring/public/views/logstash/pipelines/index.js
+++ b/x-pack/legacy/plugins/monitoring/public/views/logstash/pipelines/index.js
@@ -23,6 +23,7 @@ import { CODE_PATH_LOGSTASH } from '../../../../common/constants';
*/
const getPageData = ($injector, _api = undefined, routeOptions = {}) => {
+ _api; // to fix eslint
const $http = $injector.get('$http');
const globalState = $injector.get('globalState');
const Private = $injector.get('Private');
diff --git a/x-pack/legacy/plugins/monitoring/server/cloud/cloud_service.js b/x-pack/legacy/plugins/monitoring/server/cloud/cloud_service.js
index dcc8ad8fc8b64d..2a408f5295aef8 100644
--- a/x-pack/legacy/plugins/monitoring/server/cloud/cloud_service.js
+++ b/x-pack/legacy/plugins/monitoring/server/cloud/cloud_service.js
@@ -48,7 +48,7 @@ export class CloudService {
* @param {Object} _request 'request' HTTP handler.
* @return {Promise} Never {@code null} {@code CloudServiceResponse}.
*/
- _checkIfService(_request) {
+ _checkIfService() {
return Promise.reject(new Error('not implemented'));
}
diff --git a/x-pack/legacy/plugins/monitoring/server/lib/metrics/elasticsearch/classes.js b/x-pack/legacy/plugins/monitoring/server/lib/metrics/elasticsearch/classes.js
index 755b89a0409d02..d3a43ed6518278 100644
--- a/x-pack/legacy/plugins/monitoring/server/lib/metrics/elasticsearch/classes.js
+++ b/x-pack/legacy/plugins/monitoring/server/lib/metrics/elasticsearch/classes.js
@@ -116,7 +116,7 @@ export class LatencyMetric extends ElasticsearchMetric {
},
};
- this.calculation = (bucket, _key, _metric, _bucketSizeInSeconds) => {
+ this.calculation = bucket => {
const timeInMillisDeriv = _.get(bucket, 'event_time_in_millis_deriv.normalized_value', null);
const totalEventsDeriv = _.get(bucket, 'event_total_deriv.normalized_value', null);
diff --git a/x-pack/legacy/plugins/monitoring/server/lib/metrics/logstash/classes.js b/x-pack/legacy/plugins/monitoring/server/lib/metrics/logstash/classes.js
index c76edf90613963..eddcfabe83b1be 100644
--- a/x-pack/legacy/plugins/monitoring/server/lib/metrics/logstash/classes.js
+++ b/x-pack/legacy/plugins/monitoring/server/lib/metrics/logstash/classes.js
@@ -90,7 +90,7 @@ export class LogstashEventsLatencyClusterMetric extends LogstashClusterMetric {
},
};
- this.calculation = (bucket, _key, _metric, _bucketSizeInSeconds) => {
+ this.calculation = bucket => {
const timeInMillisDeriv = _.get(bucket, 'events_time_in_millis_deriv.normalized_value', null);
const totalEventsDeriv = _.get(bucket, 'events_total_deriv.normalized_value', null);
@@ -189,7 +189,7 @@ export class LogstashEventsLatencyMetric extends LogstashMetric {
},
};
- this.calculation = (bucket, _key, _metric, _bucketSizeInSeconds) => {
+ this.calculation = bucket => {
const timeInMillisDeriv = _.get(bucket, 'events_time_in_millis_deriv.normalized_value', null);
const totalEventsDeriv = _.get(bucket, 'events_total_deriv.normalized_value', null);
diff --git a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/decrypt_job_headers.test.ts b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/decrypt_job_headers.test.ts
index 9ba7cfbcac1d89..1b7ba3c90bab1b 100644
--- a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/decrypt_job_headers.test.ts
+++ b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/decrypt_job_headers.test.ts
@@ -43,7 +43,7 @@ describe('headers', () => {
};
const encryptedHeaders = await encryptHeaders(headers);
- const { decryptedHeaders } = await decryptJobHeaders({
+ const decryptedHeaders = await decryptJobHeaders({
job: {
title: 'cool-job-bro',
type: 'csv',
diff --git a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/decrypt_job_headers.ts b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/decrypt_job_headers.ts
index 486181117bbfbd..436b2c2dab1ad5 100644
--- a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/decrypt_job_headers.ts
+++ b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/decrypt_job_headers.ts
@@ -17,22 +17,18 @@ export const decryptJobHeaders = async <
JobParamsType,
JobDocPayloadType extends HasEncryptedHeaders
>({
- job,
server,
+ job,
logger,
}: {
- job: JobDocPayloadType;
server: ServerFacade;
- logger: Logger;
-}): Promise<{
job: JobDocPayloadType;
- server: ServerFacade;
- decryptedHeaders: Record;
-}> => {
+ logger: Logger;
+}): Promise> => {
const crypto: CryptoFactory = cryptoFactory(server);
try {
const decryptedHeaders: Record = await crypto.decrypt(job.headers);
- return { job, decryptedHeaders, server };
+ return decryptedHeaders;
} catch (err) {
logger.error(err);
diff --git a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_conditional_headers.test.ts b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_conditional_headers.test.ts
index 66990c1f37df4f..070bdb4314af9c 100644
--- a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_conditional_headers.test.ts
+++ b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_conditional_headers.test.ts
@@ -27,7 +27,7 @@ describe('conditions', () => {
baz: 'quix',
};
- const { conditionalHeaders } = await getConditionalHeaders({
+ const conditionalHeaders = await getConditionalHeaders({
job: {} as JobDocPayload,
filteredHeaders: permittedHeaders,
server: mockServer,
@@ -44,7 +44,7 @@ describe('conditions', () => {
baz: 'quix',
};
- const { conditionalHeaders } = await getConditionalHeaders({
+ const conditionalHeaders = await getConditionalHeaders({
job: {} as JobDocPayload,
filteredHeaders: permittedHeaders,
server: mockServer,
@@ -65,7 +65,7 @@ describe('conditions', () => {
baz: 'quix',
};
- const { conditionalHeaders } = await getConditionalHeaders({
+ const conditionalHeaders = await getConditionalHeaders({
job: {} as JobDocPayload,
filteredHeaders: permittedHeaders,
server: mockServer,
@@ -82,7 +82,7 @@ describe('conditions', () => {
baz: 'quix',
};
- const { conditionalHeaders } = await getConditionalHeaders({
+ const conditionalHeaders = await getConditionalHeaders({
job: {} as JobDocPayload,
filteredHeaders: permittedHeaders,
server: mockServer,
@@ -97,7 +97,7 @@ describe('conditions', () => {
baz: 'quix',
};
- const { conditionalHeaders } = await getConditionalHeaders({
+ const conditionalHeaders = await getConditionalHeaders({
job: {} as JobDocPayload,
filteredHeaders: permittedHeaders,
server: mockServer,
@@ -120,7 +120,7 @@ describe('conditions', () => {
baz: 'quix',
};
- const { conditionalHeaders } = await getConditionalHeaders({
+ const conditionalHeaders = await getConditionalHeaders({
job: {} as JobDocPayload,
filteredHeaders: permittedHeaders,
server: mockServer,
@@ -137,7 +137,7 @@ describe('conditions', () => {
baz: 'quix',
};
- const { conditionalHeaders } = await getConditionalHeaders({
+ const conditionalHeaders = await getConditionalHeaders({
job: {} as JobDocPayload,
filteredHeaders: permittedHeaders,
server: mockServer,
@@ -153,7 +153,7 @@ test('uses basePath from job when creating saved object service', async () => {
baz: 'quix',
};
- const { conditionalHeaders } = await getConditionalHeaders({
+ const conditionalHeaders = await getConditionalHeaders({
job: {} as JobDocPayload,
filteredHeaders: permittedHeaders,
server: mockServer,
@@ -180,7 +180,7 @@ test(`uses basePath from server if job doesn't have a basePath when creating sav
baz: 'quix',
};
- const { conditionalHeaders } = await getConditionalHeaders({
+ const conditionalHeaders = await getConditionalHeaders({
job: {} as JobDocPayload,
filteredHeaders: permittedHeaders,
server: mockServer,
@@ -203,7 +203,7 @@ test(`uses basePath from server if job doesn't have a basePath when creating sav
describe('config formatting', () => {
test(`lowercases server.host`, async () => {
mockServer = createMockServer({ settings: { 'server.host': 'COOL-HOSTNAME' } });
- const { conditionalHeaders } = await getConditionalHeaders({
+ const conditionalHeaders = await getConditionalHeaders({
job: {} as JobDocPayload,
filteredHeaders: {},
server: mockServer,
@@ -215,7 +215,7 @@ describe('config formatting', () => {
mockServer = createMockServer({
settings: { 'xpack.reporting.kibanaServer.hostname': 'GREAT-HOSTNAME' },
});
- const { conditionalHeaders } = await getConditionalHeaders({
+ const conditionalHeaders = await getConditionalHeaders({
job: {
title: 'cool-job-bro',
type: 'csv',
diff --git a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_conditional_headers.ts b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_conditional_headers.ts
index 14c092ccfb4a68..975060a8052f07 100644
--- a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_conditional_headers.ts
+++ b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_conditional_headers.ts
@@ -6,13 +6,13 @@
import { ConditionalHeaders, ServerFacade } from '../../../types';
export const getConditionalHeaders = ({
+ server,
job,
filteredHeaders,
- server,
}: {
+ server: ServerFacade;
job: JobDocPayloadType;
filteredHeaders: Record;
- server: ServerFacade;
}) => {
const config = server.config();
const [hostname, port, basePath, protocol] = [
@@ -32,5 +32,5 @@ export const getConditionalHeaders = ({
},
};
- return { job, conditionalHeaders, server };
+ return conditionalHeaders;
};
diff --git a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_custom_logo.test.ts b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_custom_logo.test.ts
index 4fca05337ea0c7..ff2c44026315dc 100644
--- a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_custom_logo.test.ts
+++ b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_custom_logo.test.ts
@@ -19,7 +19,7 @@ test(`gets logo from uiSettings`, async () => {
baz: 'quix',
};
- const { conditionalHeaders } = await getConditionalHeaders({
+ const conditionalHeaders = await getConditionalHeaders({
job: {} as JobDocPayloadPDF,
filteredHeaders: permittedHeaders,
server: mockServer,
diff --git a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_custom_logo.ts b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_custom_logo.ts
index 9b64e896dad18d..0059276f6df718 100644
--- a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_custom_logo.ts
+++ b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_custom_logo.ts
@@ -9,13 +9,13 @@ import { ConditionalHeaders, ServerFacade } from '../../../types';
import { JobDocPayloadPDF } from '../../printable_pdf/types'; // Logo is PDF only
export const getCustomLogo = async ({
+ server,
job,
conditionalHeaders,
- server,
}: {
+ server: ServerFacade;
job: JobDocPayloadPDF;
conditionalHeaders: ConditionalHeaders;
- server: ServerFacade;
}) => {
const serverBasePath: string = server.config().get('server.basePath');
@@ -38,12 +38,8 @@ export const getCustomLogo = async ({
};
const savedObjects = server.savedObjects;
-
const savedObjectsClient = savedObjects.getScopedSavedObjectsClient(fakeRequest);
-
const uiSettings = server.uiSettingsServiceFactory({ savedObjectsClient });
-
- const logo = await uiSettings.get(UI_SETTINGS_CUSTOM_PDF_LOGO);
-
- return { job, conditionalHeaders, logo, server };
+ const logo: string = await uiSettings.get(UI_SETTINGS_CUSTOM_PDF_LOGO);
+ return { conditionalHeaders, logo };
};
diff --git a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_full_urls.test.ts b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_full_urls.test.ts
index 60735b4abd4463..9b2a065427f70b 100644
--- a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_full_urls.test.ts
+++ b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_full_urls.test.ts
@@ -22,29 +22,26 @@ beforeEach(() => {
});
test(`fails if no URL is passed`, async () => {
- await expect(
+ const fn = () =>
getFullUrls({
job: {},
server: mockServer,
- } as FullUrlsOpts)
- ).rejects.toMatchInlineSnapshot(
- `[Error: No valid URL fields found in Job Params! Expected \`job.relativeUrl\` or \`job.objects[{ relativeUrl }]\`]`
+ } as FullUrlsOpts);
+ expect(fn).toThrowErrorMatchingInlineSnapshot(
+ `"No valid URL fields found in Job Params! Expected \`job.relativeUrl: string\` or \`job.relativeUrls: string[]\`"`
);
});
test(`fails if URLs are file-protocols for PNGs`, async () => {
const forceNow = '2000-01-01T00:00:00.000Z';
const relativeUrl = 'file://etc/passwd/#/something';
- await expect(
+ const fn = () =>
getFullUrls({
- job: {
- relativeUrl,
- forceNow,
- },
+ job: { relativeUrl, forceNow },
server: mockServer,
- } as FullUrlsOpts)
- ).rejects.toMatchInlineSnapshot(
- `[Error: Found invalid URL(s), all URLs must be relative: ${relativeUrl}]`
+ } as FullUrlsOpts);
+ expect(fn).toThrowErrorMatchingInlineSnapshot(
+ `"Found invalid URL(s), all URLs must be relative: file://etc/passwd/#/something"`
);
});
@@ -52,36 +49,29 @@ test(`fails if URLs are absolute for PNGs`, async () => {
const forceNow = '2000-01-01T00:00:00.000Z';
const relativeUrl =
'http://169.254.169.254/latest/meta-data/iam/security-credentials/profileName/#/something';
- await expect(
+ const fn = () =>
getFullUrls({
- job: {
- relativeUrl,
- forceNow,
- },
+ job: { relativeUrl, forceNow },
server: mockServer,
- } as FullUrlsOpts)
- ).rejects.toMatchInlineSnapshot(
- `[Error: Found invalid URL(s), all URLs must be relative: ${relativeUrl}]`
+ } as FullUrlsOpts);
+ expect(fn).toThrowErrorMatchingInlineSnapshot(
+ `"Found invalid URL(s), all URLs must be relative: http://169.254.169.254/latest/meta-data/iam/security-credentials/profileName/#/something"`
);
});
test(`fails if URLs are file-protocols for PDF`, async () => {
const forceNow = '2000-01-01T00:00:00.000Z';
const relativeUrl = 'file://etc/passwd/#/something';
- await expect(
+ const fn = () =>
getFullUrls({
job: {
- objects: [
- {
- relativeUrl,
- },
- ],
+ relativeUrls: [relativeUrl],
forceNow,
},
server: mockServer,
- } as FullUrlsOpts)
- ).rejects.toMatchInlineSnapshot(
- `[Error: Found invalid URL(s), all URLs must be relative: ${relativeUrl}]`
+ } as FullUrlsOpts);
+ expect(fn).toThrowErrorMatchingInlineSnapshot(
+ `"Found invalid URL(s), all URLs must be relative: file://etc/passwd/#/something"`
);
});
@@ -89,70 +79,52 @@ test(`fails if URLs are absolute for PDF`, async () => {
const forceNow = '2000-01-01T00:00:00.000Z';
const relativeUrl =
'http://169.254.169.254/latest/meta-data/iam/security-credentials/profileName/#/something';
- await expect(
+ const fn = () =>
getFullUrls({
job: {
- objects: [
- {
- relativeUrl,
- },
- ],
+ relativeUrls: [relativeUrl],
forceNow,
},
server: mockServer,
- } as FullUrlsOpts)
- ).rejects.toMatchInlineSnapshot(
- `[Error: Found invalid URL(s), all URLs must be relative: ${relativeUrl}]`
+ } as FullUrlsOpts);
+ expect(fn).toThrowErrorMatchingInlineSnapshot(
+ `"Found invalid URL(s), all URLs must be relative: http://169.254.169.254/latest/meta-data/iam/security-credentials/profileName/#/something"`
);
});
test(`fails if any URLs are absolute or file's for PDF`, async () => {
const forceNow = '2000-01-01T00:00:00.000Z';
- const objects = [
- {
- relativeUrl: '/app/kibana#/something_aaa',
- },
- {
- relativeUrl:
- 'http://169.254.169.254/latest/meta-data/iam/security-credentials/profileName/#/something',
- },
- {
- relativeUrl: 'file://etc/passwd/#/something',
- },
+ const relativeUrls = [
+ '/app/kibana#/something_aaa',
+ 'http://169.254.169.254/latest/meta-data/iam/security-credentials/profileName/#/something',
+ 'file://etc/passwd/#/something',
];
- await expect(
+
+ const fn = () =>
getFullUrls({
- job: {
- objects,
- forceNow,
- },
+ job: { relativeUrls, forceNow },
server: mockServer,
- } as FullUrlsOpts)
- ).rejects.toMatchInlineSnapshot(
- `[Error: Found invalid URL(s), all URLs must be relative: ${objects[1].relativeUrl} ${objects[2].relativeUrl}]`
+ } as FullUrlsOpts);
+ expect(fn).toThrowErrorMatchingInlineSnapshot(
+ `"Found invalid URL(s), all URLs must be relative: http://169.254.169.254/latest/meta-data/iam/security-credentials/profileName/#/something file://etc/passwd/#/something"`
);
});
test(`fails if URL does not route to a visualization`, async () => {
- await expect(
+ const fn = () =>
getFullUrls({
- job: {
- relativeUrl: '/app/phoney',
- },
+ job: { relativeUrl: '/app/phoney' },
server: mockServer,
- } as FullUrlsOpts)
- ).rejects.toMatchInlineSnapshot(
- `[Error: No valid hash in the URL! A hash is expected for the application to route to the intended visualization.]`
+ } as FullUrlsOpts);
+ expect(fn).toThrowErrorMatchingInlineSnapshot(
+ `"No valid hash in the URL! A hash is expected for the application to route to the intended visualization."`
);
});
test(`adds forceNow to hash's query, if it exists`, async () => {
const forceNow = '2000-01-01T00:00:00.000Z';
- const { urls } = await getFullUrls({
- job: {
- relativeUrl: '/app/kibana#/something',
- forceNow,
- },
+ const urls = await getFullUrls({
+ job: { relativeUrl: '/app/kibana#/something', forceNow },
server: mockServer,
} as FullUrlsOpts);
@@ -164,11 +136,8 @@ test(`adds forceNow to hash's query, if it exists`, async () => {
test(`appends forceNow to hash's query, if it exists`, async () => {
const forceNow = '2000-01-01T00:00:00.000Z';
- const { urls } = await getFullUrls({
- job: {
- relativeUrl: '/app/kibana#/something?_g=something',
- forceNow,
- },
+ const urls = await getFullUrls({
+ job: { relativeUrl: '/app/kibana#/something?_g=something', forceNow },
server: mockServer,
} as FullUrlsOpts);
@@ -178,10 +147,8 @@ test(`appends forceNow to hash's query, if it exists`, async () => {
});
test(`doesn't append forceNow query to url, if it doesn't exists`, async () => {
- const { urls } = await getFullUrls({
- job: {
- relativeUrl: '/app/kibana#/something',
- },
+ const urls = await getFullUrls({
+ job: { relativeUrl: '/app/kibana#/something' },
server: mockServer,
} as FullUrlsOpts);
@@ -190,13 +157,13 @@ test(`doesn't append forceNow query to url, if it doesn't exists`, async () => {
test(`adds forceNow to each of multiple urls`, async () => {
const forceNow = '2000-01-01T00:00:00.000Z';
- const { urls } = await getFullUrls({
+ const urls = await getFullUrls({
job: {
- objects: [
- { relativeUrl: '/app/kibana#/something_aaa' },
- { relativeUrl: '/app/kibana#/something_bbb' },
- { relativeUrl: '/app/kibana#/something_ccc' },
- { relativeUrl: '/app/kibana#/something_ddd' },
+ relativeUrls: [
+ '/app/kibana#/something_aaa',
+ '/app/kibana#/something_bbb',
+ '/app/kibana#/something_ccc',
+ '/app/kibana#/something_ddd',
],
forceNow,
},
diff --git a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_full_urls.ts b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_full_urls.ts
index 59c748aba96627..ca64d8632dbfeb 100644
--- a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_full_urls.ts
+++ b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/get_full_urls.ts
@@ -12,7 +12,7 @@ import {
} from 'url';
import { getAbsoluteUrlFactory } from '../../../common/get_absolute_url';
import { validateUrls } from '../../../common/validate_urls';
-import { ServerFacade, ConditionalHeaders } from '../../../types';
+import { ServerFacade } from '../../../types';
import { JobDocPayloadPNG } from '../../png/types';
import { JobDocPayloadPDF } from '../../printable_pdf/types';
@@ -20,18 +20,15 @@ function isPngJob(job: JobDocPayloadPNG | JobDocPayloadPDF): job is JobDocPayloa
return (job as JobDocPayloadPNG).relativeUrl !== undefined;
}
function isPdfJob(job: JobDocPayloadPNG | JobDocPayloadPDF): job is JobDocPayloadPDF {
- return (job as JobDocPayloadPDF).objects !== undefined;
+ return (job as JobDocPayloadPDF).relativeUrls !== undefined;
}
-export async function getFullUrls({
- job,
+export function getFullUrls({
server,
- ...mergeValues // pass-throughs
+ job,
}: {
- job: JobDocPayloadPDF | JobDocPayloadPNG;
server: ServerFacade;
- conditionalHeaders: ConditionalHeaders;
- logo?: string;
+ job: JobDocPayloadPDF | JobDocPayloadPNG;
}) {
const config = server.config();
@@ -48,10 +45,10 @@ export async function getFullUrls({
if (isPngJob(job)) {
relativeUrls = [job.relativeUrl];
} else if (isPdfJob(job)) {
- relativeUrls = job.objects.map(obj => obj.relativeUrl);
+ relativeUrls = job.relativeUrls;
} else {
throw new Error(
- `No valid URL fields found in Job Params! Expected \`job.relativeUrl\` or \`job.objects[{ relativeUrl }]\``
+ `No valid URL fields found in Job Params! Expected \`job.relativeUrl: string\` or \`job.relativeUrls: string[]\``
);
}
@@ -96,5 +93,5 @@ export async function getFullUrls({
});
});
- return { job, server, urls, ...mergeValues };
+ return urls;
}
diff --git a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/omit_blacklisted_headers.test.ts b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/omit_blacklisted_headers.test.ts
index 4d4b0c8ade3f69..f446369fec78ce 100644
--- a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/omit_blacklisted_headers.test.ts
+++ b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/omit_blacklisted_headers.test.ts
@@ -4,14 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { createMockServer } from '../../../test_helpers/create_mock_server';
import { omitBlacklistedHeaders } from './index';
-let mockServer: any;
-beforeEach(() => {
- mockServer = createMockServer('');
-});
-
test(`omits blacklisted headers`, async () => {
const permittedHeaders = {
foo: 'bar',
@@ -27,7 +21,7 @@ test(`omits blacklisted headers`, async () => {
'transfer-encoding': '',
};
- const { filteredHeaders } = await omitBlacklistedHeaders({
+ const filteredHeaders = await omitBlacklistedHeaders({
job: {
title: 'cool-job-bro',
type: 'csv',
@@ -41,7 +35,6 @@ test(`omits blacklisted headers`, async () => {
...permittedHeaders,
...blacklistedHeaders,
},
- server: mockServer,
});
expect(filteredHeaders).toEqual(permittedHeaders);
diff --git a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/omit_blacklisted_headers.ts b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/omit_blacklisted_headers.ts
index 1bd52a0f1b2d2a..cbebd6bc21b0e6 100644
--- a/x-pack/legacy/plugins/reporting/export_types/common/execute_job/omit_blacklisted_headers.ts
+++ b/x-pack/legacy/plugins/reporting/export_types/common/execute_job/omit_blacklisted_headers.ts
@@ -5,20 +5,17 @@
*/
import { omit } from 'lodash';
import { KBN_SCREENSHOT_HEADER_BLACKLIST } from '../../../common/constants';
-import { ServerFacade } from '../../../types';
export const omitBlacklistedHeaders = ({
job,
decryptedHeaders,
- server,
}: {
job: JobDocPayloadType;
decryptedHeaders: Record;
- server: ServerFacade;
}) => {
const filteredHeaders: Record = omit(
decryptedHeaders,
KBN_SCREENSHOT_HEADER_BLACKLIST
);
- return { job, filteredHeaders, server };
+ return filteredHeaders;
};
diff --git a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/index.ts b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/index.ts
index 152ef32e331b98..b83021d5e38dd8 100644
--- a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/index.ts
+++ b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/index.ts
@@ -5,21 +5,9 @@
*/
import * as Rx from 'rxjs';
-import { first, mergeMap } from 'rxjs/operators';
-import {
- ServerFacade,
- CaptureConfig,
- HeadlessChromiumDriverFactory,
- HeadlessChromiumDriver as HeadlessBrowser,
-} from '../../../../types';
-import {
- ElementsPositionAndAttribute,
- ScreenshotResults,
- ScreenshotObservableOpts,
- TimeRange,
-} from './types';
-
-import { checkForToastMessage } from './check_for_toast';
+import { first, mergeMap, toArray } from 'rxjs/operators';
+import { ServerFacade, CaptureConfig, HeadlessChromiumDriverFactory } from '../../../../types';
+import { ScreenshotResults, ScreenshotObservableOpts } from './types';
import { injectCustomCss } from './inject_css';
import { openUrl } from './open_url';
import { waitForRenderComplete } from './wait_for_render';
@@ -28,6 +16,7 @@ import { waitForElementsToBeInDOM } from './wait_for_dom_elements';
import { getTimeRange } from './get_time_range';
import { getElementPositionAndAttributes } from './get_element_position_data';
import { getScreenshots } from './get_screenshots';
+import { scanPage } from './scan_page';
import { skipTelemetry } from './skip_telemetry';
export function screenshotsObservableFactory(
@@ -39,108 +28,68 @@ export function screenshotsObservableFactory(
return function screenshotsObservable({
logger,
- url,
+ urls,
conditionalHeaders,
layout,
browserTimezone,
- }: ScreenshotObservableOpts): Rx.Observable {
- const create$ = browserDriverFactory.create({
- viewport: layout.getBrowserViewport(),
- browserTimezone,
- });
+ }: ScreenshotObservableOpts): Rx.Observable {
+ const create$ = browserDriverFactory.createPage(
+ { viewport: layout.getBrowserViewport(), browserTimezone },
+ logger
+ );
- // @ts-ignore this needs to be refactored to use less random type declaration and instead rely on structures that work with inference TODO
- return create$.pipe(
- mergeMap(({ driver$, exit$ }) => {
- const screenshot$ = driver$.pipe(
- mergeMap(
- (browser: HeadlessBrowser) => openUrl(browser, url, conditionalHeaders, logger),
- browser => browser
- ),
- mergeMap(
- (browser: HeadlessBrowser) => skipTelemetry(browser, logger),
- browser => browser
- ),
- mergeMap(
- (browser: HeadlessBrowser) => {
- logger.debug(
- 'waiting for elements or items count attribute; or not found to interrupt'
- );
+ return Rx.from(urls).pipe(
+ mergeMap(url => {
+ return create$.pipe(
+ mergeMap(({ driver, exit$ }) => {
+ const screenshot$ = Rx.of(driver).pipe(
+ mergeMap(() => openUrl(driver, url, conditionalHeaders, logger)),
+ mergeMap(() => skipTelemetry(driver, logger)),
+ mergeMap(() => scanPage(driver, layout, logger)),
+ mergeMap(() => getNumberOfItems(driver, layout, logger)),
+ mergeMap(async itemsCount => {
+ const viewport = layout.getViewport(itemsCount);
+ await Promise.all([
+ driver.setViewport(viewport, logger),
+ waitForElementsToBeInDOM(driver, itemsCount, layout, logger),
+ ]);
+ }),
+ mergeMap(async () => {
+ // Waiting till _after_ elements have rendered before injecting our CSS
+ // allows for them to be displayed properly in many cases
+ await injectCustomCss(driver, layout, logger);
- // the dashboard is using the `itemsCountAttribute` attribute to let us
- // know how many items to expect since gridster incrementally adds panels
- // we have to use this hint to wait for all of them
- const renderSuccess = browser.waitForSelector(
- `${layout.selectors.renderComplete},[${layout.selectors.itemsCountAttribute}]`,
- {},
- logger
- );
- const renderError = checkForToastMessage(browser, layout, logger);
- return Rx.race(Rx.from(renderSuccess), Rx.from(renderError));
- },
- browser => browser
- ),
- mergeMap(
- (browser: HeadlessBrowser) => getNumberOfItems(browser, layout, logger),
- (browser, itemsCount: number) => ({ browser, itemsCount })
- ),
- mergeMap(
- async ({ browser, itemsCount }) => {
- logger.debug('setting viewport');
- const viewport = layout.getViewport(itemsCount);
- return await browser.setViewport(viewport, logger);
- },
- ({ browser, itemsCount }) => ({ browser, itemsCount })
- ),
- mergeMap(
- ({ browser, itemsCount }) =>
- waitForElementsToBeInDOM(browser, itemsCount, layout, logger),
- ({ browser }) => browser
- ),
- mergeMap(
- browser => {
- // Waiting till _after_ elements have rendered before injecting our CSS
- // allows for them to be displayed properly in many cases
- return injectCustomCss(browser, layout, logger);
- },
- browser => browser
- ),
- mergeMap(
- async browser => {
- if (layout.positionElements) {
- // position panel elements for print layout
- return await layout.positionElements(browser, logger);
- }
- },
- browser => browser
- ),
- mergeMap(
- (browser: HeadlessBrowser) => {
- return waitForRenderComplete(captureConfig, browser, layout, logger);
- },
- browser => browser
- ),
- mergeMap(
- browser => getTimeRange(browser, layout, logger),
- (browser, timeRange: TimeRange | null) => ({ browser, timeRange })
- ),
- mergeMap(
- ({ browser }) => getElementPositionAndAttributes(browser, layout),
- ({ browser, timeRange }, elementsPositionAndAttributes: ElementsPositionAndAttribute[]) => {
- return { browser, timeRange, elementsPositionAndAttributes };
- } // prettier-ignore
- ),
- mergeMap(
- ({ browser, elementsPositionAndAttributes }) => {
- return getScreenshots({ browser, elementsPositionAndAttributes, logger });
- },
- ({ timeRange }, screenshots) => ({ timeRange, screenshots })
- )
- );
+ if (layout.positionElements) {
+ // position panel elements for print layout
+ await layout.positionElements(driver, logger);
+ }
- return Rx.race(screenshot$, exit$);
+ await waitForRenderComplete(captureConfig, driver, layout, logger);
+ }),
+ mergeMap(() => getTimeRange(driver, layout, logger)),
+ mergeMap(
+ async (timeRange): Promise => {
+ const elementsPositionAndAttributes = await getElementPositionAndAttributes(
+ driver,
+ layout
+ );
+ const screenshots = await getScreenshots({
+ browser: driver,
+ elementsPositionAndAttributes,
+ logger,
+ });
+
+ return { timeRange, screenshots };
+ }
+ )
+ );
+
+ return Rx.race(screenshot$, exit$);
+ })
+ );
}),
- first()
+ first(),
+ toArray()
);
};
}
diff --git a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/scan_page.ts b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/scan_page.ts
new file mode 100644
index 00000000000000..81ff01bb204b86
--- /dev/null
+++ b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/scan_page.ts
@@ -0,0 +1,30 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import * as Rx from 'rxjs';
+import { HeadlessChromiumDriver } from '../../../../server/browsers/chromium/driver';
+import { LevelLogger } from '../../../../server/lib';
+import { LayoutInstance } from '../../layouts/layout';
+import { checkForToastMessage } from './check_for_toast';
+
+export function scanPage(
+ browser: HeadlessChromiumDriver,
+ layout: LayoutInstance,
+ logger: LevelLogger
+) {
+ logger.debug('waiting for elements or items count attribute; or not found to interrupt');
+
+ // the dashboard is using the `itemsCountAttribute` attribute to let us
+ // know how many items to expect since gridster incrementally adds panels
+ // we have to use this hint to wait for all of them
+ const renderSuccess = browser.waitForSelector(
+ `${layout.selectors.renderComplete},[${layout.selectors.itemsCountAttribute}]`,
+ {},
+ logger
+ );
+ const renderError = checkForToastMessage(browser, layout, logger);
+ return Rx.race(Rx.from(renderSuccess), Rx.from(renderError));
+}
diff --git a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/types.ts b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/types.ts
index 4f461ef4ec5f98..78cd42f0cae2fd 100644
--- a/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/types.ts
+++ b/x-pack/legacy/plugins/reporting/export_types/common/lib/screenshots/types.ts
@@ -10,7 +10,7 @@ import { LayoutInstance } from '../../layouts/layout';
export interface ScreenshotObservableOpts {
logger: LevelLogger;
- url: string;
+ urls: string[];
conditionalHeaders: ConditionalHeaders;
layout: LayoutInstance;
browserTimezone: string;
@@ -36,6 +36,6 @@ export interface Screenshot {
}
export interface ScreenshotResults {
- timeRange: TimeRange;
+ timeRange: TimeRange | null;
screenshots: Screenshot[];
}
diff --git a/x-pack/legacy/plugins/reporting/export_types/png/server/execute_job/index.test.js b/x-pack/legacy/plugins/reporting/export_types/png/server/execute_job/index.test.js
index 0888d287af07c6..1be65722fa668b 100644
--- a/x-pack/legacy/plugins/reporting/export_types/png/server/execute_job/index.test.js
+++ b/x-pack/legacy/plugins/reporting/export_types/png/server/execute_job/index.test.js
@@ -27,7 +27,7 @@ beforeEach(() => {
'server.port': 5601,
};
mockServer = {
- expose: () => {},
+ expose: () => {}, // NOTE: this is for oncePerServer
config: memoize(() => ({ get: jest.fn() })),
info: {
protocol: 'http',
diff --git a/x-pack/legacy/plugins/reporting/export_types/png/server/execute_job/index.ts b/x-pack/legacy/plugins/reporting/export_types/png/server/execute_job/index.ts
index b289ae45dde678..c2fda05fbe3e93 100644
--- a/x-pack/legacy/plugins/reporting/export_types/png/server/execute_job/index.ts
+++ b/x-pack/legacy/plugins/reporting/export_types/png/server/execute_job/index.ts
@@ -5,7 +5,7 @@
*/
import * as Rx from 'rxjs';
-import { mergeMap, catchError, map, takeUntil } from 'rxjs/operators';
+import { catchError, map, mergeMap, takeUntil } from 'rxjs/operators';
import { PLUGIN_ID, PNG_JOB_TYPE } from '../../../../common/constants';
import {
ServerFacade,
@@ -32,18 +32,14 @@ export const executeJobFactory: QueuedPngExecutorFactory = function executeJobFa
const generatePngObservable = generatePngObservableFactory(server, browserDriverFactory);
const logger = LevelLogger.createForServer(server, [PLUGIN_ID, PNG_JOB_TYPE, 'execute']);
- return function executeJob(
- jobId: string,
- jobToExecute: JobDocPayloadPNG,
- cancellationToken: any
- ) {
+ return function executeJob(jobId: string, job: JobDocPayloadPNG, cancellationToken: any) {
const jobLogger = logger.clone([jobId]);
- const process$ = Rx.of({ job: jobToExecute, server, logger }).pipe(
- mergeMap(decryptJobHeaders),
- map(omitBlacklistedHeaders),
- map(getConditionalHeaders),
- mergeMap(getFullUrls),
- mergeMap(({ job, conditionalHeaders, urls }) => {
+ const process$ = Rx.of(1).pipe(
+ mergeMap(() => decryptJobHeaders({ server, job, logger })),
+ map(decryptedHeaders => omitBlacklistedHeaders({ job, decryptedHeaders })),
+ map(filteredHeaders => getConditionalHeaders({ server, job, filteredHeaders })),
+ mergeMap(conditionalHeaders => {
+ const urls = getFullUrls({ server, job });
const hashUrl = urls[0];
return generatePngObservable(
jobLogger,
diff --git a/x-pack/legacy/plugins/reporting/export_types/png/server/lib/generate_png.ts b/x-pack/legacy/plugins/reporting/export_types/png/server/lib/generate_png.ts
index e2b1474515786e..600762c451a791 100644
--- a/x-pack/legacy/plugins/reporting/export_types/png/server/lib/generate_png.ts
+++ b/x-pack/legacy/plugins/reporting/export_types/png/server/lib/generate_png.ts
@@ -32,19 +32,17 @@ export function generatePngObservableFactory(
const layout = new PreserveLayout(layoutParams.dimensions);
const screenshots$ = screenshotsObservable({
logger,
- url,
+ urls: [url],
conditionalHeaders,
layout,
browserTimezone,
}).pipe(
- map(urlScreenshots => {
- if (urlScreenshots.screenshots.length !== 1) {
- throw new Error(
- `Expected there to be 1 screenshot, but there are ${urlScreenshots.screenshots.length}`
- );
+ map(([{ screenshots }]) => {
+ if (screenshots.length !== 1) {
+ throw new Error(`Expected there to be 1 screenshot, but there are ${screenshots.length}`);
}
- return urlScreenshots.screenshots[0].base64EncodedData;
+ return screenshots[0].base64EncodedData;
})
);
diff --git a/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/create_job/compatibility_shim.js b/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/create_job/compatibility_shim.js
deleted file mode 100644
index a3afd070603b0f..00000000000000
--- a/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/create_job/compatibility_shim.js
+++ /dev/null
@@ -1,126 +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;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { uriEncode } from '../lib/uri_encode';
-
-/*
- * TODO: Kibana 8.0:
- * Remove support for parsing Saved Object details from objectType / savedObjectId
- * Including support for determining the Report title from objectType / savedObjectId
- *
- * - `objectType` is optional, but helps differentiate the type of report in the job listing
- * - `title` must be explicitly passed
- * - `relativeUrls` array OR `relativeUrl` string must be passed
- */
-
-const getSavedObjectTitle = async (objectType, savedObjectId, savedObjectsClient) => {
- const savedObject = await savedObjectsClient.get(objectType, savedObjectId);
- return savedObject.attributes.title;
-};
-
-const getSavedObjectRelativeUrl = (objectType, savedObjectId, queryString) => {
- const appPrefixes = {
- dashboard: '/dashboard/',
- visualization: '/visualize/edit/',
- search: '/discover/',
- };
-
- const appPrefix = appPrefixes[objectType];
- if (!appPrefix) throw new Error('Unexpected app type: ' + objectType);
-
- const hash = appPrefix + uriEncode.string(savedObjectId, true);
-
- return `/app/kibana#${hash}?${queryString || ''}`;
-};
-
-export function compatibilityShimFactory(server, logger) {
- return function compatibilityShimFactory(createJobFn) {
- return async function(
- {
- savedObjectId, // deprecating
- queryString, // deprecating
- browserTimezone,
- objectType,
- title,
- relativeUrls,
- layout,
- },
- headers,
- request
- ) {
- // input validation and deprecation logging
- if (savedObjectId) {
- if (typeof savedObjectId !== 'string') {
- throw new Error('Invalid savedObjectId (deprecated). String is expected.');
- }
- if (relativeUrls) {
- throw new Error(`savedObjectId should not be provided if relativeUrls are provided`);
- }
- } else {
- if (!relativeUrls) {
- throw new Error(`Either relativeUrls or savedObjectId must be provided`);
- }
- if (!Array.isArray(relativeUrls)) {
- throw new Error('Invalid relativeUrls. String[] is expected.');
- }
- relativeUrls.forEach(url => {
- if (typeof url !== 'string') {
- throw new Error('Invalid Relative URL in relativeUrls. String is expected.');
- }
- });
- }
-
- let kibanaRelativeUrls;
- if (relativeUrls) {
- kibanaRelativeUrls = relativeUrls;
- } else {
- kibanaRelativeUrls = [getSavedObjectRelativeUrl(objectType, savedObjectId, queryString)];
- logger.warning(
- `The relativeUrls have been derived from saved object parameters. ` +
- `This functionality will be removed with the next major version.`
- );
- }
-
- let reportTitle;
- try {
- if (title) {
- reportTitle = title;
- } else {
- if (objectType && savedObjectId) {
- reportTitle = await getSavedObjectTitle(
- objectType,
- savedObjectId,
- request.getSavedObjectsClient()
- );
- logger.warning(
- `The title has been derived from saved object parameters. This ` +
- `functionality will be removed with the next major version.`
- );
- } else {
- logger.warning(
- `A title parameter should be provided with the job generation ` +
- `request. Please use Kibana to regenerate your POST URL to have a ` +
- `title included in the PDF.`
- );
- }
- }
- } catch (err) {
- logger.error(err); // 404 for the savedObjectId, etc
- throw err;
- }
-
- const transformedJobParams = {
- objectType,
- title: reportTitle,
- relativeUrls: kibanaRelativeUrls,
- browserTimezone,
- layout,
- };
-
- return await createJobFn(transformedJobParams, headers, request);
- };
- };
-}
diff --git a/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/create_job/compatibility_shim.test.js b/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/create_job/compatibility_shim.test.js
deleted file mode 100644
index b3b8bca1d89555..00000000000000
--- a/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/create_job/compatibility_shim.test.js
+++ /dev/null
@@ -1,297 +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;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { once } from 'lodash';
-import { compatibilityShimFactory } from './compatibility_shim';
-
-const createMockServer = () => {
- return {
- expose: jest.fn(), //fool once_per_server
- log: jest.fn(),
- };
-};
-
-const createMockLogger = () => ({
- warning: jest.fn(),
- error: jest.fn(),
-});
-
-const createMockRequest = () => {
- return {
- getSavedObjectsClient: once(function() {
- return {
- get: jest.fn(),
- };
- }),
- };
-};
-
-test(`passes title through if provided`, async () => {
- const mockLogger = createMockLogger();
- const compatibilityShim = compatibilityShimFactory(createMockServer(), mockLogger);
- const title = 'test title';
-
- const createJobMock = jest.fn();
- await compatibilityShim(createJobMock)(
- { title, relativeUrls: ['/something'] },
- null,
- createMockRequest()
- );
-
- expect(mockLogger.warning.mock.calls.length).toBe(0);
- expect(mockLogger.error.mock.calls.length).toBe(0);
-
- expect(createJobMock.mock.calls.length).toBe(1);
- expect(createJobMock.mock.calls[0][0].title).toBe(title);
-});
-
-test(`gets the title from the savedObject`, async () => {
- const mockLogger = createMockLogger();
- const compatibilityShim = compatibilityShimFactory(createMockServer(), mockLogger);
-
- const createJobMock = jest.fn();
- const mockRequest = createMockRequest();
- const title = 'savedTitle';
- mockRequest.getSavedObjectsClient().get.mockReturnValue({
- attributes: {
- title,
- },
- });
-
- await compatibilityShim(createJobMock)(
- { objectType: 'search', savedObjectId: 'abc' },
- null,
- mockRequest
- );
-
- expect(mockLogger.warning.mock.calls.length).toBe(2);
- expect(mockLogger.warning.mock.calls[0][0]).toEqual(
- 'The relativeUrls have been derived from saved object parameters. This functionality will be removed with the next major version.'
- );
- expect(mockLogger.error.mock.calls.length).toBe(0);
-
- expect(createJobMock.mock.calls.length).toBe(1);
- expect(createJobMock.mock.calls[0][0].title).toBe(title);
-});
-
-test(`passes the objectType and savedObjectId to the savedObjectsClient`, async () => {
- const mockLogger = createMockLogger();
- const compatibilityShim = compatibilityShimFactory(createMockServer(), mockLogger);
-
- const createJobMock = jest.fn();
- const mockRequest = createMockRequest();
- mockRequest.getSavedObjectsClient().get.mockReturnValue({
- attributes: {
- title: '',
- },
- });
-
- const objectType = 'search';
- const savedObjectId = 'abc';
- await compatibilityShim(createJobMock)({ objectType, savedObjectId }, null, mockRequest);
-
- expect(mockLogger.warning.mock.calls.length).toBe(2);
- expect(mockLogger.warning.mock.calls[0][0]).toEqual(
- 'The relativeUrls have been derived from saved object parameters. This functionality will be removed with the next major version.'
- );
- expect(mockLogger.warning.mock.calls[1][0]).toEqual(
- 'The title has been derived from saved object parameters. This functionality will be removed with the next major version.'
- );
- expect(mockLogger.error.mock.calls.length).toBe(0);
-
- const getMock = mockRequest.getSavedObjectsClient().get.mock;
- expect(getMock.calls.length).toBe(1);
- expect(getMock.calls[0][0]).toBe(objectType);
- expect(getMock.calls[0][1]).toBe(savedObjectId);
-});
-
-test(`logs no warnings when title and relativeUrls is passed`, async () => {
- const mockLogger = createMockLogger();
- const compatibilityShim = compatibilityShimFactory(createMockServer(), mockLogger);
-
- const createJobMock = jest.fn();
- const mockRequest = createMockRequest();
-
- await compatibilityShim(createJobMock)(
- { title: 'Phenomenal Dashboard', relativeUrls: ['/abc', '/def'] },
- null,
- mockRequest
- );
-
- expect(mockLogger.warning.mock.calls.length).toBe(0);
- expect(mockLogger.error.mock.calls.length).toBe(0);
-});
-
-test(`logs warning if title can not be provided`, async () => {
- const mockLogger = createMockLogger();
- const compatibilityShim = compatibilityShimFactory(createMockServer(), mockLogger);
-
- const createJobMock = jest.fn();
- const mockRequest = createMockRequest();
- await compatibilityShim(createJobMock)({ relativeUrls: ['/abc'] }, null, mockRequest);
-
- expect(mockLogger.warning.mock.calls.length).toBe(1);
- expect(mockLogger.warning.mock.calls[0][0]).toEqual(
- `A title parameter should be provided with the job generation request. Please ` +
- `use Kibana to regenerate your POST URL to have a title included in the PDF.`
- );
-});
-
-test(`logs deprecations when generating the title/relativeUrl using the savedObject`, async () => {
- const mockLogger = createMockLogger();
- const compatibilityShim = compatibilityShimFactory(createMockServer(), mockLogger);
-
- const createJobMock = jest.fn();
- const mockRequest = createMockRequest();
- mockRequest.getSavedObjectsClient().get.mockReturnValue({
- attributes: {
- title: '',
- },
- });
-
- await compatibilityShim(createJobMock)(
- { objectType: 'search', savedObjectId: 'abc' },
- null,
- mockRequest
- );
-
- expect(mockLogger.warning.mock.calls.length).toBe(2);
- expect(mockLogger.warning.mock.calls[0][0]).toEqual(
- 'The relativeUrls have been derived from saved object parameters. This functionality will be removed with the next major version.'
- );
- expect(mockLogger.warning.mock.calls[1][0]).toEqual(
- 'The title has been derived from saved object parameters. This functionality will be removed with the next major version.'
- );
-});
-
-test(`passes objectType through`, async () => {
- const mockLogger = createMockLogger();
- const compatibilityShim = compatibilityShimFactory(createMockServer(), mockLogger);
-
- const createJobMock = jest.fn();
- const mockRequest = createMockRequest();
-
- const objectType = 'foo';
- await compatibilityShim(createJobMock)(
- { title: 'test', relativeUrls: ['/something'], objectType },
- null,
- mockRequest
- );
-
- expect(mockLogger.warning.mock.calls.length).toBe(0);
- expect(mockLogger.error.mock.calls.length).toBe(0);
-
- expect(createJobMock.mock.calls.length).toBe(1);
- expect(createJobMock.mock.calls[0][0].objectType).toBe(objectType);
-});
-
-test(`passes the relativeUrls through`, async () => {
- const mockLogger = createMockLogger();
- const compatibilityShim = compatibilityShimFactory(createMockServer(), mockLogger);
-
- const createJobMock = jest.fn();
-
- const relativeUrls = ['/app/kibana#something', '/app/kibana#something-else'];
- await compatibilityShim(createJobMock)({ title: 'test', relativeUrls }, null, null);
-
- expect(mockLogger.warning.mock.calls.length).toBe(0);
- expect(mockLogger.error.mock.calls.length).toBe(0);
-
- expect(createJobMock.mock.calls.length).toBe(1);
- expect(createJobMock.mock.calls[0][0].relativeUrls).toBe(relativeUrls);
-});
-
-const testSavedObjectRelativeUrl = (objectType, expectedUrl) => {
- test(`generates the saved object relativeUrl for ${objectType}`, async () => {
- const mockLogger = createMockLogger();
- const compatibilityShim = compatibilityShimFactory(createMockServer(), mockLogger);
- const createJobMock = jest.fn();
-
- await compatibilityShim(createJobMock)(
- { title: 'test', objectType, savedObjectId: 'abc' },
- null,
- null
- );
-
- expect(mockLogger.warning.mock.calls.length).toBe(1);
- expect(mockLogger.warning.mock.calls[0][0]).toEqual(
- 'The relativeUrls have been derived from saved object parameters. This functionality will be removed with the next major version.'
- );
- expect(mockLogger.error.mock.calls.length).toBe(0);
-
- expect(createJobMock.mock.calls.length).toBe(1);
- expect(createJobMock.mock.calls[0][0].relativeUrls).toEqual([expectedUrl]);
- });
-};
-
-testSavedObjectRelativeUrl('search', '/app/kibana#/discover/abc?');
-testSavedObjectRelativeUrl('visualization', '/app/kibana#/visualize/edit/abc?');
-testSavedObjectRelativeUrl('dashboard', '/app/kibana#/dashboard/abc?');
-
-test(`appends the queryString to the relativeUrl when generating from the savedObject`, async () => {
- const mockLogger = createMockLogger();
- const compatibilityShim = compatibilityShimFactory(createMockServer(), mockLogger);
- const createJobMock = jest.fn();
-
- await compatibilityShim(createJobMock)(
- { title: 'test', objectType: 'search', savedObjectId: 'abc', queryString: 'foo=bar' },
- null,
- null
- );
-
- expect(mockLogger.warning.mock.calls.length).toBe(1);
- expect(mockLogger.warning.mock.calls[0][0]).toEqual(
- 'The relativeUrls have been derived from saved object parameters. This functionality will be removed with the next major version.'
- );
- expect(mockLogger.error.mock.calls.length).toBe(0);
-
- expect(createJobMock.mock.calls.length).toBe(1);
- expect(createJobMock.mock.calls[0][0].relativeUrls).toEqual([
- '/app/kibana#/discover/abc?foo=bar',
- ]);
-});
-
-test(`throw an Error if the objectType, savedObjectId and relativeUrls are provided`, async () => {
- const mockLogger = createMockLogger();
- const compatibilityShim = compatibilityShimFactory(createMockServer(), mockLogger);
- const createJobMock = jest.fn();
-
- const promise = compatibilityShim(createJobMock)(
- {
- title: 'test',
- objectType: 'something',
- relativeUrls: ['/something'],
- savedObjectId: 'abc',
- },
- null,
- null
- );
-
- await expect(promise).rejects.toBeDefined();
-});
-
-test(`passes headers and request through`, async () => {
- const mockLogger = createMockLogger();
- const compatibilityShim = compatibilityShimFactory(createMockServer(), mockLogger);
-
- const createJobMock = jest.fn();
-
- const headers = {};
- const request = createMockRequest();
-
- await compatibilityShim(createJobMock)(
- { title: 'test', relativeUrls: ['/something'] },
- headers,
- request
- );
-
- expect(mockLogger.warning.mock.calls.length).toBe(0);
- expect(mockLogger.error.mock.calls.length).toBe(0);
-
- expect(createJobMock.mock.calls.length).toBe(1);
- expect(createJobMock.mock.calls[0][1]).toBe(headers);
- expect(createJobMock.mock.calls[0][2]).toBe(request);
-});
diff --git a/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/create_job/index.ts b/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/create_job/index.ts
index d17713057abc1e..a8cc71175cffeb 100644
--- a/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/create_job/index.ts
+++ b/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/create_job/index.ts
@@ -4,7 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { PLUGIN_ID, PDF_JOB_TYPE } from '../../../../common/constants';
import {
CreateJobFactory,
ESQueueCreateJobFn,
@@ -13,29 +12,16 @@ import {
ConditionalHeaders,
} from '../../../../types';
import { validateUrls } from '../../../../common/validate_urls';
-import { LevelLogger } from '../../../../server/lib';
import { cryptoFactory } from '../../../../server/lib/crypto';
import { JobParamsPDF } from '../../types';
-// @ts-ignore untyped module
-import { compatibilityShimFactory } from './compatibility_shim';
-
-interface CreateJobFnOpts {
- objectType: any;
- title: string;
- relativeUrls: string[];
- browserTimezone: string;
- layout: any;
-}
export const createJobFactory: CreateJobFactory> = function createJobFactoryFn(server: ServerFacade) {
- const logger = LevelLogger.createForServer(server, [PLUGIN_ID, PDF_JOB_TYPE, 'create']);
- const compatibilityShim = compatibilityShimFactory(server, logger);
const crypto = cryptoFactory(server);
- return compatibilityShim(async function createJobFn(
- { objectType, title, relativeUrls, browserTimezone, layout }: CreateJobFnOpts,
+ return async function createJobFn(
+ { title, relativeUrls, browserTimezone, layout, objectType }: JobParamsPDF,
headers: ConditionalHeaders['headers'],
request: RequestFacade
) {
@@ -44,14 +30,14 @@ export const createJobFactory: CreateJobFactory ({ relativeUrl: u })),
- headers: serializedEncryptedHeaders,
- browserTimezone,
- layout,
basePath: request.getBasePath(),
+ browserTimezone,
forceNow: new Date().toISOString(),
+ headers: serializedEncryptedHeaders,
+ layout,
+ relativeUrls,
+ title,
+ objectType,
};
- });
+ };
};
diff --git a/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/execute_job/index.test.js b/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/execute_job/index.test.js
index db7b599a1aaabb..ddbee6e9d54a46 100644
--- a/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/execute_job/index.test.js
+++ b/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/execute_job/index.test.js
@@ -27,7 +27,8 @@ beforeEach(() => {
'server.port': 5601,
};
mockServer = {
- expose: () => {},
+ expose: jest.fn(),
+ log: jest.fn(),
config: memoize(() => ({ get: jest.fn() })),
info: {
protocol: 'http',
@@ -71,7 +72,7 @@ test(`passes browserTimezone to generatePdf`, async () => {
const browserTimezone = 'UTC';
await executeJob(
'pdfJobId',
- { objects: [], browserTimezone, headers: encryptedHeaders },
+ { relativeUrls: [], browserTimezone, headers: encryptedHeaders },
cancellationToken
);
@@ -96,7 +97,7 @@ test(`returns content_type of application/pdf`, async () => {
const { content_type: contentType } = await executeJob(
'pdfJobId',
- { objects: [], timeRange: {}, headers: encryptedHeaders },
+ { relativeUrls: [], timeRange: {}, headers: encryptedHeaders },
cancellationToken
);
expect(contentType).toBe('application/pdf');
@@ -112,7 +113,7 @@ test(`returns content of generatePdf getBuffer base64 encoded`, async () => {
const encryptedHeaders = await encryptHeaders({});
const { content } = await executeJob(
'pdfJobId',
- { objects: [], timeRange: {}, headers: encryptedHeaders },
+ { relativeUrls: [], timeRange: {}, headers: encryptedHeaders },
cancellationToken
);
diff --git a/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/execute_job/index.ts b/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/execute_job/index.ts
index e2b3183464cf24..d85207e6712125 100644
--- a/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/execute_job/index.ts
+++ b/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/execute_job/index.ts
@@ -5,7 +5,7 @@
*/
import * as Rx from 'rxjs';
-import { mergeMap, catchError, map, takeUntil } from 'rxjs/operators';
+import { catchError, map, mergeMap, takeUntil } from 'rxjs/operators';
import {
ServerFacade,
ExecuteJobFactory,
@@ -33,33 +33,28 @@ export const executeJobFactory: QueuedPdfExecutorFactory = function executeJobFa
const generatePdfObservable = generatePdfObservableFactory(server, browserDriverFactory);
const logger = LevelLogger.createForServer(server, [PLUGIN_ID, PDF_JOB_TYPE, 'execute']);
- return function executeJob(
- jobId: string,
- jobToExecute: JobDocPayloadPDF,
- cancellationToken: any
- ) {
+ return function executeJob(jobId: string, job: JobDocPayloadPDF, cancellationToken: any) {
const jobLogger = logger.clone([jobId]);
- const process$ = Rx.of({ job: jobToExecute, server, logger }).pipe(
- mergeMap(decryptJobHeaders),
- map(omitBlacklistedHeaders),
- map(getConditionalHeaders),
- mergeMap(getCustomLogo),
- mergeMap(getFullUrls),
- mergeMap(
- ({ job, conditionalHeaders, logo, urls }): Rx.Observable => {
- const { browserTimezone, layout } = jobToExecute;
- return generatePdfObservable(
- jobLogger,
- job.title,
- urls,
- browserTimezone,
- conditionalHeaders,
- layout,
- logo
- );
- }
- ),
+ const process$ = Rx.of(1).pipe(
+ mergeMap(() => decryptJobHeaders({ server, job, logger })),
+ map(decryptedHeaders => omitBlacklistedHeaders({ job, decryptedHeaders })),
+ map(filteredHeaders => getConditionalHeaders({ server, job, filteredHeaders })),
+ mergeMap(conditionalHeaders => getCustomLogo({ server, job, conditionalHeaders })),
+ mergeMap(({ logo, conditionalHeaders }) => {
+ const urls = getFullUrls({ server, job });
+
+ const { browserTimezone, layout, title } = job;
+ return generatePdfObservable(
+ jobLogger,
+ title,
+ urls,
+ browserTimezone,
+ conditionalHeaders,
+ layout,
+ logo
+ );
+ }),
map((buffer: Buffer) => ({
content_type: 'application/pdf',
content: buffer.toString('base64'),
@@ -72,7 +67,6 @@ export const executeJobFactory: QueuedPdfExecutorFactory = function executeJobFa
);
const stop$ = Rx.fromEventPattern(cancellationToken.on);
-
return process$.pipe(takeUntil(stop$)).toPromise();
};
};
diff --git a/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/lib/generate_pdf.ts b/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/lib/generate_pdf.ts
index 898a13a2dfe805..9a8db308bea794 100644
--- a/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/lib/generate_pdf.ts
+++ b/x-pack/legacy/plugins/reporting/export_types/printable_pdf/server/lib/generate_pdf.ts
@@ -5,7 +5,7 @@
*/
import * as Rx from 'rxjs';
-import { toArray, mergeMap } from 'rxjs/operators';
+import { mergeMap } from 'rxjs/operators';
import { groupBy } from 'lodash';
import { LevelLogger } from '../../../../server/lib';
import { ServerFacade, HeadlessChromiumDriverFactory, ConditionalHeaders } from '../../../../types';
@@ -31,7 +31,6 @@ export function generatePdfObservableFactory(
browserDriverFactory: HeadlessChromiumDriverFactory
) {
const screenshotsObservable = screenshotsObservableFactory(server, browserDriverFactory);
- const captureConcurrency = 1;
return function generatePdfObservable(
logger: LevelLogger,
@@ -41,15 +40,16 @@ export function generatePdfObservableFactory(
conditionalHeaders: ConditionalHeaders,
layoutParams: LayoutParams,
logo?: string
- ) {
+ ): Rx.Observable {
const layout = createLayout(server, layoutParams) as LayoutInstance;
- const screenshots$ = Rx.from(urls).pipe(
- mergeMap(
- url => screenshotsObservable({ logger, url, conditionalHeaders, layout, browserTimezone }),
- captureConcurrency
- ),
- toArray(),
- mergeMap(async (urlScreenshots: ScreenshotResults[]) => {
+ const screenshots$ = screenshotsObservable({
+ logger,
+ urls,
+ conditionalHeaders,
+ layout,
+ browserTimezone,
+ }).pipe(
+ mergeMap(async urlScreenshots => {
const pdfOutput = pdf.create(layout, logo);
if (title) {
@@ -68,8 +68,7 @@ export function generatePdfObservableFactory(
});
pdfOutput.generate();
- const buffer = await pdfOutput.getBuffer();
- return buffer;
+ return await pdfOutput.getBuffer();
})
);
diff --git a/x-pack/legacy/plugins/reporting/export_types/printable_pdf/types.d.ts b/x-pack/legacy/plugins/reporting/export_types/printable_pdf/types.d.ts
index b51a2d4d5711c8..0a9dcfe986ca63 100644
--- a/x-pack/legacy/plugins/reporting/export_types/printable_pdf/types.d.ts
+++ b/x-pack/legacy/plugins/reporting/export_types/printable_pdf/types.d.ts
@@ -9,7 +9,7 @@ import { JobDocPayload, ServerFacade, RequestFacade } from '../../types';
// Job params: structure of incoming user request data, after being parsed from RISON
export interface JobParamsPDF {
- objectType: string;
+ objectType: string; // visualization, dashboard, etc. Used for job info & telemetry
title: string;
relativeUrls: string[];
browserTimezone: string;
@@ -22,7 +22,5 @@ export interface JobDocPayloadPDF extends JobDocPayload {
browserTimezone: string;
forceNow?: string;
layout: LayoutParams;
- objects: Array<{
- relativeUrl: string;
- }>;
+ relativeUrls: string[];
}
diff --git a/x-pack/legacy/plugins/reporting/index.test.js b/x-pack/legacy/plugins/reporting/index.test.js
index f1b471071153c1..0d9a717bd7d816 100644
--- a/x-pack/legacy/plugins/reporting/index.test.js
+++ b/x-pack/legacy/plugins/reporting/index.test.js
@@ -16,6 +16,7 @@ jest.mock('os', () => {
return os;
});
+// eslint-disable-next-line jest/valid-describe
const describeWithContext = describe.each([
[{ dev: false, dist: false }],
[{ dev: true, dist: false }],
diff --git a/x-pack/legacy/plugins/reporting/index.ts b/x-pack/legacy/plugins/reporting/index.ts
index c0c9e458132f05..faa27bfb2d6eae 100644
--- a/x-pack/legacy/plugins/reporting/index.ts
+++ b/x-pack/legacy/plugins/reporting/index.ts
@@ -94,7 +94,7 @@ export const reporting = (kibana: any) => {
const { xpack_main: xpackMainPlugin } = server.plugins;
mirrorPluginStatus(xpackMainPlugin, this);
const checkLicense = checkLicenseFactory(exportTypesRegistry);
- xpackMainPlugin.status.once('green', () => {
+ (xpackMainPlugin as any).status.once('green', () => {
// Register a function that is called whenever the xpack info changes,
// to re-compute the license check results for this plugin
xpackMainPlugin.info.feature(this.id).registerLicenseCheckResultsGenerator(checkLicense);
diff --git a/x-pack/legacy/plugins/reporting/public/components/report_listing.tsx b/x-pack/legacy/plugins/reporting/public/components/report_listing.tsx
index 9783372aa29c4b..320f6220aa9968 100644
--- a/x-pack/legacy/plugins/reporting/public/components/report_listing.tsx
+++ b/x-pack/legacy/plugins/reporting/public/components/report_listing.tsx
@@ -425,7 +425,7 @@ class ReportListingUi extends Component {
return {
id: job._id,
type: source.jobtype,
- object_type: source.payload.type,
+ object_type: source.payload.objectType,
object_title: source.payload.title,
created_by: source.created_by,
created_at: source.created_at,
diff --git a/x-pack/legacy/plugins/reporting/server/browsers/chromium/driver_factory/index.ts b/x-pack/legacy/plugins/reporting/server/browsers/chromium/driver_factory/index.ts
index daa7df343f8aa7..6fa46b893de8ce 100644
--- a/x-pack/legacy/plugins/reporting/server/browsers/chromium/driver_factory/index.ts
+++ b/x-pack/legacy/plugins/reporting/server/browsers/chromium/driver_factory/index.ts
@@ -31,10 +31,11 @@ type queueTimeout = number;
export class HeadlessChromiumDriverFactory {
private binaryPath: binaryPath;
- private logger: Logger;
private browserConfig: BrowserConfig;
private queueTimeout: queueTimeout;
private networkPolicy: NetworkPolicy;
+ private userDataDir: string;
+ private getChromiumArgs: (viewport: BrowserConfig['viewport']) => string[];
constructor(
binaryPath: binaryPath,
@@ -46,23 +47,30 @@ export class HeadlessChromiumDriverFactory {
this.binaryPath = binaryPath;
this.browserConfig = browserConfig;
this.queueTimeout = queueTimeout;
- this.logger = logger;
this.networkPolicy = networkPolicy;
+
+ this.userDataDir = fs.mkdtempSync(path.join(os.tmpdir(), 'chromium-'));
+ this.getChromiumArgs = (viewport: BrowserConfig['viewport']) =>
+ args({
+ userDataDir: this.userDataDir,
+ viewport,
+ disableSandbox: this.browserConfig.disableSandbox,
+ proxy: this.browserConfig.proxy,
+ });
}
type = 'chromium';
- test({ viewport }: { viewport: BrowserConfig['viewport'] }, logger: Logger) {
- const userDataDir = fs.mkdtempSync(path.join(os.tmpdir(), 'chromium-'));
+ test(logger: Logger) {
const chromiumArgs = args({
- userDataDir,
- viewport,
+ userDataDir: this.userDataDir,
+ viewport: { width: 800, height: 600 },
disableSandbox: this.browserConfig.disableSandbox,
proxy: this.browserConfig.proxy,
});
return puppeteerLaunch({
- userDataDir,
+ userDataDir: this.userDataDir,
executablePath: this.binaryPath,
ignoreHTTPSErrors: true,
args: chromiumArgs,
@@ -76,33 +84,25 @@ export class HeadlessChromiumDriverFactory {
});
}
- create({
- viewport,
- browserTimezone,
- }: {
- viewport: BrowserConfig['viewport'];
- browserTimezone: string;
- }): Rx.Observable<{
- driver$: Rx.Observable;
- exit$: Rx.Observable;
- }> {
+ /*
+ * Return an observable to objects which will drive screenshot capture for a page
+ */
+ createPage(
+ { viewport, browserTimezone }: { viewport: BrowserConfig['viewport']; browserTimezone: string },
+ pLogger: Logger
+ ): Rx.Observable<{ driver: HeadlessChromiumDriver; exit$: Rx.Observable }> {
return Rx.Observable.create(async (observer: InnerSubscriber) => {
- this.logger.debug(`Creating browser driver factory`);
+ const logger = pLogger.clone(['browser-driver']);
+ logger.info(`Creating browser page driver`);
- const userDataDir = fs.mkdtempSync(path.join(os.tmpdir(), 'chromium-'));
- const chromiumArgs = args({
- userDataDir,
- viewport,
- disableSandbox: this.browserConfig.disableSandbox,
- proxy: this.browserConfig.proxy,
- });
+ const chromiumArgs = this.getChromiumArgs(viewport);
let browser: Browser;
let page: Page;
try {
browser = await puppeteerLaunch({
pipe: !this.browserConfig.inspect,
- userDataDir,
+ userDataDir: this.userDataDir,
executablePath: this.binaryPath,
ignoreHTTPSErrors: true,
args: chromiumArgs,
@@ -119,7 +119,7 @@ export class HeadlessChromiumDriverFactory {
// "TimeoutError: waiting for selector ".application" failed: timeout 30000ms exceeded"
page.setDefaultTimeout(this.queueTimeout);
- this.logger.debug(`Browser driver factory created`);
+ logger.debug(`Browser page driver created`);
} catch (err) {
observer.error(new Error(`Error spawning Chromium browser: [${err}]`));
throw err;
@@ -130,12 +130,12 @@ export class HeadlessChromiumDriverFactory {
await browser.close();
},
};
- const { terminate$ } = safeChildProcess(this.logger, childProcess);
+ const { terminate$ } = safeChildProcess(logger, childProcess);
// this is adding unsubscribe logic to our observer
// so that if our observer unsubscribes, we terminate our child-process
observer.add(() => {
- this.logger.debug(`The browser process observer has unsubscribed. Closing the browser...`);
+ logger.debug(`The browser process observer has unsubscribed. Closing the browser...`);
childProcess.kill(); // ignore async
});
@@ -144,7 +144,7 @@ export class HeadlessChromiumDriverFactory {
terminate$
.pipe(
tap(signal => {
- this.logger.debug(`Termination signal received: ${signal}`);
+ logger.debug(`Termination signal received: ${signal}`);
}),
ignoreElements()
)
@@ -152,33 +152,40 @@ export class HeadlessChromiumDriverFactory {
);
// taps the browser log streams and combine them to Kibana logs
- this.getBrowserLogger(page).subscribe();
- this.getProcessLogger(browser).subscribe();
+ this.getBrowserLogger(page, logger).subscribe();
+ this.getProcessLogger(browser, logger).subscribe();
+
+ // HeadlessChromiumDriver: object to "drive" a browser page
+ const driver = new HeadlessChromiumDriver(page, {
+ inspect: this.browserConfig.inspect,
+ networkPolicy: this.networkPolicy,
+ });
- const driver$ = Rx.of(new HeadlessChromiumDriver(page, { inspect: this.browserConfig.inspect, networkPolicy: this.networkPolicy })); // prettier-ignore
+ // Rx.Observable: stream to interrupt page capture
const exit$ = this.getPageExit(browser, page);
- observer.next({ driver$, exit$ });
+ observer.next({ driver, exit$ });
// unsubscribe logic makes a best-effort attempt to delete the user data directory used by chromium
observer.add(() => {
- this.logger.debug(`deleting chromium user data directory at [${userDataDir}]`);
+ const userDataDir = this.userDataDir;
+ logger.debug(`deleting chromium user data directory at [${userDataDir}]`);
// the unsubscribe function isn't `async` so we're going to make our best effort at
// deleting the userDataDir and if it fails log an error.
del(userDataDir).catch(error => {
- this.logger.error(`error deleting user data directory at [${userDataDir}]: [${error}]`);
+ logger.error(`error deleting user data directory at [${userDataDir}]: [${error}]`);
});
});
});
}
- getBrowserLogger(page: Page): Rx.Observable {
+ getBrowserLogger(page: Page, logger: Logger): Rx.Observable {
const consoleMessages$ = Rx.fromEvent(page, 'console').pipe(
map(line => {
if (line.type() === 'error') {
- this.logger.error(line.text(), ['headless-browser-console']);
+ logger.error(line.text(), ['headless-browser-console']);
} else {
- this.logger.debug(line.text(), [`headless-browser-console:${line.type()}`]);
+ logger.debug(line.text(), [`headless-browser-console:${line.type()}`]);
}
})
);
@@ -187,7 +194,7 @@ export class HeadlessChromiumDriverFactory {
map(req => {
const failure = req.failure && req.failure();
if (failure) {
- this.logger.warning(
+ logger.warning(
`Request to [${req.url()}] failed! [${failure.errorText}]. This error will be ignored.`
);
}
@@ -197,7 +204,7 @@ export class HeadlessChromiumDriverFactory {
return Rx.merge(consoleMessages$, pageRequestFailed$);
}
- getProcessLogger(browser: Browser) {
+ getProcessLogger(browser: Browser, logger: Logger): Rx.Observable {
const childProcess = browser.process();
// NOTE: The browser driver can not observe stdout and stderr of the child process
// Puppeteer doesn't give a handle to the original ChildProcess object
@@ -206,7 +213,7 @@ export class HeadlessChromiumDriverFactory {
// just log closing of the process
const processClose$ = Rx.fromEvent(childProcess, 'close').pipe(
tap(() => {
- this.logger.debug('child process closed', ['headless-browser-process']);
+ logger.debug('child process closed', ['headless-browser-process']);
})
);
diff --git a/x-pack/legacy/plugins/reporting/server/browsers/index.ts b/x-pack/legacy/plugins/reporting/server/browsers/index.ts
index a5ecc405bf9c59..402fabea56c842 100644
--- a/x-pack/legacy/plugins/reporting/server/browsers/index.ts
+++ b/x-pack/legacy/plugins/reporting/server/browsers/index.ts
@@ -3,6 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
+
import * as chromiumDefinition from './chromium';
export { ensureAllBrowsersDownloaded } from './download';
diff --git a/x-pack/legacy/plugins/reporting/server/lib/check_license.js b/x-pack/legacy/plugins/reporting/server/lib/check_license.ts
similarity index 69%
rename from x-pack/legacy/plugins/reporting/server/lib/check_license.js
rename to x-pack/legacy/plugins/reporting/server/lib/check_license.ts
index 5a784f9913352c..02e1196f1d00db 100644
--- a/x-pack/legacy/plugins/reporting/server/lib/check_license.js
+++ b/x-pack/legacy/plugins/reporting/server/lib/check_license.ts
@@ -4,19 +4,31 @@
* you may not use this file except in compliance with the Elastic License.
*/
+import { XPackInfo } from '../../../xpack_main/server/lib/xpack_info';
+import { XPackInfoLicense } from '../../../xpack_main/server/lib/xpack_info_license';
+import { ExportTypesRegistry, ExportTypeDefinition } from '../../types';
+
+interface LicenseCheckResult {
+ showLinks: boolean;
+ enableLinks: boolean;
+ message?: string;
+}
+
const messages = {
getUnavailable: () => {
return 'You cannot use Reporting because license information is not available at this time.';
},
- getExpired: license => {
+ getExpired: (license: XPackInfoLicense) => {
return `You cannot use Reporting because your ${license.getType()} license has expired.`;
},
};
-const makeManagementFeature = exportTypes => {
+const makeManagementFeature = (
+ exportTypes: Array>
+) => {
return {
id: 'management',
- checkLicense: license => {
+ checkLicense: (license: XPackInfoLicense | null) => {
if (!license) {
return {
showLinks: true,
@@ -46,10 +58,12 @@ const makeManagementFeature = exportTypes => {
};
};
-const makeExportTypeFeature = exportType => {
+const makeExportTypeFeature = (
+ exportType: ExportTypeDefinition
+) => {
return {
id: exportType.id,
- checkLicense: license => {
+ checkLicense: (license: XPackInfoLicense | null) => {
if (!license) {
return {
showLinks: true,
@@ -84,13 +98,9 @@ const makeExportTypeFeature = exportType => {
};
};
-export function checkLicenseFactory(exportTypesRegistry) {
- return function checkLicense(xpackLicenseInfo) {
- const license =
- xpackLicenseInfo === null || !xpackLicenseInfo.isAvailable()
- ? null
- : xpackLicenseInfo.license;
-
+export function checkLicenseFactory(exportTypesRegistry: ExportTypesRegistry) {
+ return function checkLicense(xpackInfo: XPackInfo) {
+ const license = xpackInfo === null || !xpackInfo.isAvailable() ? null : xpackInfo.license;
const exportTypes = Array.from(exportTypesRegistry.getAll());
const reportingFeatures = [
...exportTypes.map(makeExportTypeFeature),
@@ -100,6 +110,6 @@ export function checkLicenseFactory(exportTypesRegistry) {
return reportingFeatures.reduce((result, feature) => {
result[feature.id] = feature.checkLicense(license);
return result;
- }, {});
+ }, {} as Record);
};
}
diff --git a/x-pack/legacy/plugins/reporting/server/lib/esqueue/helpers/create_index.js b/x-pack/legacy/plugins/reporting/server/lib/esqueue/helpers/create_index.js
index 9e00f0447e99e4..670c2907fb8322 100644
--- a/x-pack/legacy/plugins/reporting/server/lib/esqueue/helpers/create_index.js
+++ b/x-pack/legacy/plugins/reporting/server/lib/esqueue/helpers/create_index.js
@@ -15,7 +15,7 @@ const schema = {
properties: {
/**
* Type of object that is triggering this report. Should be either search, visualization or dashboard.
- * Used for phone home stats only.
+ * Used for job listing and telemetry stats only.
*/
objectType: {
type: 'text',
diff --git a/x-pack/legacy/plugins/reporting/server/lib/esqueue/job.js b/x-pack/legacy/plugins/reporting/server/lib/esqueue/job.js
index cded6d2ce89a8c..a7d8f4df3fd541 100644
--- a/x-pack/legacy/plugins/reporting/server/lib/esqueue/job.js
+++ b/x-pack/legacy/plugins/reporting/server/lib/esqueue/job.js
@@ -57,7 +57,7 @@ export class Job extends events.EventEmitter {
meta: {
// We are copying these values out of payload because these fields are indexed and can be aggregated on
// for tracking stats, while payload contents are not.
- objectType: payload.type,
+ objectType: payload.objectType,
layout: payload.layout ? payload.layout.id : 'none',
},
payload: this.payload,
diff --git a/x-pack/legacy/plugins/reporting/server/lib/index.ts b/x-pack/legacy/plugins/reporting/server/lib/index.ts
index 50d1a276b6b5d0..0a2db749cb954a 100644
--- a/x-pack/legacy/plugins/reporting/server/lib/index.ts
+++ b/x-pack/legacy/plugins/reporting/server/lib/index.ts
@@ -5,7 +5,6 @@
*/
export { getExportTypesRegistry } from './export_types_registry';
-// @ts-ignore untyped module
export { checkLicenseFactory } from './check_license';
export { LevelLogger } from './level_logger';
export { cryptoFactory } from './crypto';
diff --git a/x-pack/legacy/plugins/reporting/server/lib/validate/validate_browser.ts b/x-pack/legacy/plugins/reporting/server/lib/validate/validate_browser.ts
index 031709c85284cb..89c49123e85bf2 100644
--- a/x-pack/legacy/plugins/reporting/server/lib/validate/validate_browser.ts
+++ b/x-pack/legacy/plugins/reporting/server/lib/validate/validate_browser.ts
@@ -18,14 +18,12 @@ export const validateBrowser = async (
logger: Logger
) => {
if (browserFactory.type === BROWSER_TYPE) {
- return browserFactory
- .test({ viewport: { width: 800, height: 600 } }, logger)
- .then((browser: Browser | null) => {
- if (browser && browser.close) {
- browser.close();
- } else {
- throw new Error('Could not close browser client handle!');
- }
- });
+ return browserFactory.test(logger).then((browser: Browser | null) => {
+ if (browser && browser.close) {
+ browser.close();
+ } else {
+ throw new Error('Could not close browser client handle!');
+ }
+ });
}
};
diff --git a/x-pack/legacy/plugins/reporting/server/routes/generation.ts b/x-pack/legacy/plugins/reporting/server/routes/generation.ts
index 7bed7bc5773e45..73450b7641c8e4 100644
--- a/x-pack/legacy/plugins/reporting/server/routes/generation.ts
+++ b/x-pack/legacy/plugins/reporting/server/routes/generation.ts
@@ -17,7 +17,6 @@ import {
import { registerGenerateFromJobParams } from './generate_from_jobparams';
import { registerGenerateCsvFromSavedObject } from './generate_from_savedobject';
import { registerGenerateCsvFromSavedObjectImmediate } from './generate_from_savedobject_immediate';
-import { registerLegacy } from './legacy';
import { createQueueFactory, enqueueJobFactory } from '../lib';
export function registerJobGenerationRoutes(
@@ -73,7 +72,6 @@ export function registerJobGenerationRoutes(
}
registerGenerateFromJobParams(server, handler, handleError);
- registerLegacy(server, handler, handleError);
// Register beta panel-action download-related API's
if (config.get('xpack.reporting.csv.enablePanelActionDownload')) {
diff --git a/x-pack/legacy/plugins/reporting/server/routes/legacy.ts b/x-pack/legacy/plugins/reporting/server/routes/legacy.ts
deleted file mode 100644
index 011ac4a02bbf9e..00000000000000
--- a/x-pack/legacy/plugins/reporting/server/routes/legacy.ts
+++ /dev/null
@@ -1,73 +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;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import querystring from 'querystring';
-import { API_BASE_URL } from '../../common/constants';
-import { ServerFacade, RequestFacade, ReportingResponseToolkit } from '../../types';
-import {
- getRouteConfigFactoryReportingPre,
- GetRouteConfigFactoryFn,
-} from './lib/route_config_factories';
-import { HandlerErrorFunction, HandlerFunction } from './types';
-
-const getStaticFeatureConfig = (getRouteConfig: GetRouteConfigFactoryFn, featureId: string) =>
- getRouteConfig(() => featureId);
-
-const BASE_GENERATE = `${API_BASE_URL}/generate`;
-
-export function registerLegacy(
- server: ServerFacade,
- handler: HandlerFunction,
- handleError: HandlerErrorFunction
-) {
- const getRouteConfig = getRouteConfigFactoryReportingPre(server);
-
- function createLegacyPdfRoute({ path, objectType }: { path: string; objectType: string }) {
- const exportTypeId = 'printablePdf';
- server.route({
- path,
- method: 'POST',
- options: getStaticFeatureConfig(getRouteConfig, exportTypeId),
- handler: async (request: RequestFacade, h: ReportingResponseToolkit) => {
- const message = `The following URL is deprecated and will stop working in the next major version: ${request.url.path}`;
- server.log(['warning', 'reporting', 'deprecation'], message);
-
- try {
- const savedObjectId = request.params.savedId;
- const queryString = querystring.stringify(request.query);
-
- return await handler(
- exportTypeId,
- {
- objectType,
- savedObjectId,
- queryString,
- },
- request,
- h
- );
- } catch (err) {
- throw handleError(exportTypeId, err);
- }
- },
- });
- }
-
- createLegacyPdfRoute({
- path: `${BASE_GENERATE}/visualization/{savedId}`,
- objectType: 'visualization',
- });
-
- createLegacyPdfRoute({
- path: `${BASE_GENERATE}/search/{savedId}`,
- objectType: 'search',
- });
-
- createLegacyPdfRoute({
- path: `${BASE_GENERATE}/dashboard/{savedId}`,
- objectType: 'dashboard',
- });
-}
diff --git a/x-pack/legacy/plugins/security/public/views/management/edit_role/components/privileges/kibana/space_aware_privilege_section/privilege_matrix.tsx b/x-pack/legacy/plugins/security/public/views/management/edit_role/components/privileges/kibana/space_aware_privilege_section/privilege_matrix.tsx
index 92dace65d466c4..962487312c83df 100644
--- a/x-pack/legacy/plugins/security/public/views/management/edit_role/components/privileges/kibana/space_aware_privilege_section/privilege_matrix.tsx
+++ b/x-pack/legacy/plugins/security/public/views/management/edit_role/components/privileges/kibana/space_aware_privilege_section/privilege_matrix.tsx
@@ -23,7 +23,7 @@ import {
import { FormattedMessage, InjectedIntl } from '@kbn/i18n/react';
import React, { Component, Fragment } from 'react';
import { Space } from '../../../../../../../../../spaces/common/model/space';
-import { SpaceAvatar } from '../../../../../../../../../spaces/public/components';
+import { SpaceAvatar } from '../../../../../../../../../spaces/public/space_avatar';
import { Feature } from '../../../../../../../../../../../plugins/features/public';
import { FeaturesPrivileges, Role } from '../../../../../../../../common/model';
import { CalculatedPrivilege } from '../../../../../../../lib/kibana_privilege_calculator';
diff --git a/x-pack/legacy/plugins/security/public/views/management/edit_role/components/privileges/kibana/space_aware_privilege_section/privilege_space_table.tsx b/x-pack/legacy/plugins/security/public/views/management/edit_role/components/privileges/kibana/space_aware_privilege_section/privilege_space_table.tsx
index e54b5ff9c45da7..65a3df9fb47a1a 100644
--- a/x-pack/legacy/plugins/security/public/views/management/edit_role/components/privileges/kibana/space_aware_privilege_section/privilege_space_table.tsx
+++ b/x-pack/legacy/plugins/security/public/views/management/edit_role/components/privileges/kibana/space_aware_privilege_section/privilege_space_table.tsx
@@ -14,7 +14,7 @@ import {
import { FormattedMessage, InjectedIntl } from '@kbn/i18n/react';
import _ from 'lodash';
import React, { Component } from 'react';
-import { getSpaceColor } from '../../../../../../../../../spaces/public/lib/space_attributes';
+import { getSpaceColor } from '../../../../../../../../../spaces/public/space_avatar';
import { Space } from '../../../../../../../../../spaces/common/model/space';
import {
FeaturesPrivileges,
diff --git a/x-pack/legacy/plugins/security/public/views/management/edit_role/components/privileges/kibana/space_aware_privilege_section/space_selector.tsx b/x-pack/legacy/plugins/security/public/views/management/edit_role/components/privileges/kibana/space_aware_privilege_section/space_selector.tsx
index e6e206e5fc7f46..0eb9cf0b0ee9d7 100644
--- a/x-pack/legacy/plugins/security/public/views/management/edit_role/components/privileges/kibana/space_aware_privilege_section/space_selector.tsx
+++ b/x-pack/legacy/plugins/security/public/views/management/edit_role/components/privileges/kibana/space_aware_privilege_section/space_selector.tsx
@@ -8,7 +8,7 @@ import { EuiComboBox, EuiComboBoxOptionProps, EuiHealth, EuiHighlight } from '@e
import { InjectedIntl } from '@kbn/i18n/react';
import React, { Component } from 'react';
import { Space } from '../../../../../../../../../spaces/common/model/space';
-import { getSpaceColor } from '../../../../../../../../../spaces/public/lib/space_attributes';
+import { getSpaceColor } from '../../../../../../../../../spaces/public/space_avatar';
const spaceToOption = (space?: Space, currentSelection?: 'global' | 'spaces') => {
if (!space) {
diff --git a/x-pack/legacy/plugins/security/public/views/management/edit_role/components/spaces_popover_list/spaces_popover_list.tsx b/x-pack/legacy/plugins/security/public/views/management/edit_role/components/spaces_popover_list/spaces_popover_list.tsx
index 1ab2a27220eeea..a99e389044eaad 100644
--- a/x-pack/legacy/plugins/security/public/views/management/edit_role/components/spaces_popover_list/spaces_popover_list.tsx
+++ b/x-pack/legacy/plugins/security/public/views/management/edit_role/components/spaces_popover_list/spaces_popover_list.tsx
@@ -14,9 +14,9 @@ import {
} from '@elastic/eui';
import { FormattedMessage, InjectedIntl } from '@kbn/i18n/react';
import React, { Component } from 'react';
-import { SPACE_SEARCH_COUNT_THRESHOLD } from '../../../../../../../spaces/common/constants';
-import { Space } from '../../../../../../../spaces/common/model/space';
-import { SpaceAvatar } from '../../../../../../../spaces/public/components';
+import { SpaceAvatar } from '../../../../../../../spaces/public/space_avatar';
+import { SPACE_SEARCH_COUNT_THRESHOLD } from '../../../../../../../../../plugins/spaces/common/constants';
+import { Space } from '../../../../../../../../../plugins/spaces/common/model/space';
interface Props {
spaces: Space[];
diff --git a/x-pack/legacy/plugins/siem/common/constants.ts b/x-pack/legacy/plugins/siem/common/constants.ts
index 4383329fea0723..5116416b527a5e 100644
--- a/x-pack/legacy/plugins/siem/common/constants.ts
+++ b/x-pack/legacy/plugins/siem/common/constants.ts
@@ -27,8 +27,6 @@ export const DEFAULT_SEARCH_AFTER_PAGE_SIZE = 100;
export const DEFAULT_ANOMALY_SCORE = 'siem:defaultAnomalyScore';
export const DEFAULT_MAX_TABLE_QUERY_SIZE = 10000;
export const DEFAULT_SCALE_DATE_FORMAT = 'dateFormat:scaled';
-export const DEFAULT_KBN_VERSION = 'kbnVersion';
-export const DEFAULT_TIMEZONE_BROWSER = 'timezoneBrowser';
export const DEFAULT_FROM = 'now-24h';
export const DEFAULT_TO = 'now';
export const DEFAULT_INTERVAL_PAUSE = true;
diff --git a/x-pack/legacy/plugins/siem/cypress/integration/lib/logout/index.ts b/x-pack/legacy/plugins/siem/cypress/integration/lib/logout/index.ts
deleted file mode 100644
index 7a6c7f71bc98c2..00000000000000
--- a/x-pack/legacy/plugins/siem/cypress/integration/lib/logout/index.ts
+++ /dev/null
@@ -1,15 +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;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-export const logout = (): null => {
- cy.request({
- method: 'GET',
- url: `${Cypress.config().baseUrl}/logout`,
- }).then(response => {
- expect(response.status).to.eq(200);
- });
- return null;
-};
diff --git a/x-pack/legacy/plugins/siem/cypress/integration/lib/logout/selectors.ts b/x-pack/legacy/plugins/siem/cypress/integration/lib/logout/selectors.ts
deleted file mode 100644
index 8cf015619f4c1f..00000000000000
--- a/x-pack/legacy/plugins/siem/cypress/integration/lib/logout/selectors.ts
+++ /dev/null
@@ -1,11 +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;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-/** The avatar / button that represents the logged-in Kibana user */
-export const USER_MENU = '[data-test-subj="userMenuButton"]';
-
-/** Clicking this link logs out the currently logged-in Kibana user */
-export const LOGOUT_LINK = '[data-test-subj="logoutLink"]';
diff --git a/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/events_viewer/events_viewer.spec.ts b/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/events_viewer/events_viewer.spec.ts
index 85878d82256096..79169d3769a781 100644
--- a/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/events_viewer/events_viewer.spec.ts
+++ b/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/events_viewer/events_viewer.spec.ts
@@ -10,7 +10,6 @@ import {
FIELDS_BROWSER_SELECTED_CATEGORY_TITLE,
FIELDS_BROWSER_TITLE,
} from '../../lib/fields_browser/selectors';
-import { logout } from '../../lib/logout';
import { HOSTS_PAGE } from '../../lib/urls';
import { loginAndWaitForPage, DEFAULT_TIMEOUT } from '../../lib/util/helpers';
import {
@@ -46,10 +45,6 @@ describe('Events Viewer', () => {
clickEventsTab();
});
- afterEach(() => {
- return logout();
- });
-
it('renders the fields browser with the expected title when the Events Viewer Fields Browser button is clicked', () => {
openEventsViewerFieldsBrowser();
diff --git a/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/fields_browser/fields_browser.spec.ts b/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/fields_browser/fields_browser.spec.ts
index dfc5e10893ebbc..95df907893fc7b 100644
--- a/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/fields_browser/fields_browser.spec.ts
+++ b/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/fields_browser/fields_browser.spec.ts
@@ -22,7 +22,6 @@ import {
FIELDS_BROWSER_SYSTEM_CATEGORIES_COUNT,
FIELDS_BROWSER_TITLE,
} from '../../lib/fields_browser/selectors';
-import { logout } from '../../lib/logout';
import { HOSTS_PAGE } from '../../lib/urls';
import { loginAndWaitForPage, DEFAULT_TIMEOUT } from '../../lib/util/helpers';
@@ -42,10 +41,6 @@ describe('Fields Browser', () => {
loginAndWaitForPage(HOSTS_PAGE);
});
- afterEach(() => {
- return logout();
- });
-
it('renders the fields browser with the expected title when the Fields button is clicked', () => {
populateTimeline();
diff --git a/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/inspect/inspect.spec.ts b/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/inspect/inspect.spec.ts
index 54207966fd36f2..ee25705a83989d 100644
--- a/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/inspect/inspect.spec.ts
+++ b/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/inspect/inspect.spec.ts
@@ -4,7 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { logout } from '../../lib/logout';
import { HOSTS_PAGE } from '../../lib/urls';
import {
INSPECT_BUTTON_ICON,
@@ -18,9 +17,6 @@ import { executeKQL, hostExistsQuery, toggleTimelineVisibility } from '../../lib
describe('Inspect', () => {
describe('Hosts and network stats and tables', () => {
- afterEach(() => {
- return logout();
- });
INSPECT_BUTTONS_IN_SIEM.map(table =>
it(`inspects the ${table.title}`, () => {
loginAndWaitForPage(table.url);
@@ -36,10 +32,6 @@ describe('Inspect', () => {
});
describe('Timeline', () => {
- afterEach(() => {
- return logout();
- });
-
it('inspects the timeline', () => {
loginAndWaitForPage(HOSTS_PAGE);
toggleTimelineVisibility();
diff --git a/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/ml_conditional_links/ml_conditional_links.spec.ts b/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/ml_conditional_links/ml_conditional_links.spec.ts
index 4c29c081b3e69e..afeb8c3c13a4fd 100644
--- a/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/ml_conditional_links/ml_conditional_links.spec.ts
+++ b/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/ml_conditional_links/ml_conditional_links.spec.ts
@@ -4,7 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { logout } from '../../lib/logout';
import {
mlNetworkSingleIpNullKqlQuery,
mlNetworkSingleIpKqlQuery,
@@ -24,10 +23,6 @@ import { loginAndWaitForPage } from '../../lib/util/helpers';
import { KQL_INPUT } from '../../lib/url_state';
describe('ml conditional links', () => {
- afterEach(() => {
- return logout();
- });
-
it('sets the KQL from a single IP with a value for the query', () => {
loginAndWaitForPage(mlNetworkSingleIpKqlQuery);
cy.get(KQL_INPUT, { timeout: 5000 }).should(
diff --git a/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/navigation/navigation.spec.ts b/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/navigation/navigation.spec.ts
index f4beba7cbb72d8..bb1a0379ce0eaf 100644
--- a/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/navigation/navigation.spec.ts
+++ b/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/navigation/navigation.spec.ts
@@ -4,7 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { logout } from '../../lib/logout';
import { OVERVIEW_PAGE, TIMELINES_PAGE } from '../../lib/urls';
import {
NAVIGATION_HOSTS,
@@ -15,10 +14,6 @@ import {
import { loginAndWaitForPage } from '../../lib/util/helpers';
describe('top-level navigation common to all pages in the SIEM app', () => {
- afterEach(() => {
- return logout();
- });
-
it('navigates to the Overview page', () => {
loginAndWaitForPage(TIMELINES_PAGE);
diff --git a/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/overview/overview.spec.ts b/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/overview/overview.spec.ts
index 2ea8b5e8bc5ce7..4ef3eb67cafc9c 100644
--- a/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/overview/overview.spec.ts
+++ b/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/overview/overview.spec.ts
@@ -4,7 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { logout } from '../../lib/logout';
import { OVERVIEW_PAGE } from '../../lib/urls';
import { clearFetch, stubApi } from '../../lib/fixtures/helpers';
import { HOST_STATS, NETWORK_STATS, STAT_AUDITD } from '../../lib/overview/selectors';
@@ -17,10 +16,6 @@ describe('Overview Page', () => {
loginAndWaitForPage(OVERVIEW_PAGE);
});
- afterEach(() => {
- return logout();
- });
-
it('Host and Network stats render with correct values', () => {
cy.get(STAT_AUDITD.domId);
diff --git a/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/pagination/pagination.spec.ts b/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/pagination/pagination.spec.ts
index ebd0ad0125efb6..73711f1434d5ff 100644
--- a/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/pagination/pagination.spec.ts
+++ b/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/pagination/pagination.spec.ts
@@ -4,7 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { logout } from '../../lib/logout';
import { HOSTS_PAGE_TAB_URLS } from '../../lib/urls';
import {
AUTHENTICATIONS_TABLE,
@@ -19,10 +18,6 @@ import {
import { DEFAULT_TIMEOUT, loginAndWaitForPage, waitForTableLoad } from '../../lib/util/helpers';
describe('Pagination', () => {
- afterEach(() => {
- return logout();
- });
-
it('pagination updates results and page number', () => {
loginAndWaitForPage(HOSTS_PAGE_TAB_URLS.uncommonProcesses);
waitForTableLoad(UNCOMMON_PROCCESSES_TABLE);
diff --git a/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/timeline/data_providers.spec.ts b/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/timeline/data_providers.spec.ts
index 236d5a53481b7f..824e4031852383 100644
--- a/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/timeline/data_providers.spec.ts
+++ b/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/timeline/data_providers.spec.ts
@@ -4,7 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { logout } from '../../lib/logout';
import {
TIMELINE_DATA_PROVIDERS,
TIMELINE_DROPPED_DATA_PROVIDERS,
@@ -22,10 +21,6 @@ describe('timeline data providers', () => {
loginAndWaitForPage(HOSTS_PAGE);
});
- afterEach(() => {
- return logout();
- });
-
it('renders the data provider of a host dragged from the All Hosts widget on the hosts page', () => {
waitForAllHostsWidget();
diff --git a/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/timeline/flyout_button.spec.ts b/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/timeline/flyout_button.spec.ts
index c1c35e497d0815..5b0ac03ae87dc0 100644
--- a/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/timeline/flyout_button.spec.ts
+++ b/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/timeline/flyout_button.spec.ts
@@ -4,7 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { logout } from '../../lib/logout';
import {
TIMELINE_FLYOUT_BODY,
TIMELINE_NOT_READY_TO_DROP_BUTTON,
@@ -21,10 +20,6 @@ describe('timeline flyout button', () => {
loginAndWaitForPage(HOSTS_PAGE);
});
- afterEach(() => {
- return logout();
- });
-
it('toggles open the timeline', () => {
toggleTimelineVisibility();
diff --git a/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/timeline/search_or_filter.spec.ts b/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/timeline/search_or_filter.spec.ts
index 0c9aed33d47ad6..9f21b4e3d53a11 100644
--- a/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/timeline/search_or_filter.spec.ts
+++ b/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/timeline/search_or_filter.spec.ts
@@ -4,7 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { logout } from '../../lib/logout';
import {
assertAtLeastOneEventMatchesSearch,
executeKQL,
@@ -19,10 +18,6 @@ describe('timeline search or filter KQL bar', () => {
loginAndWaitForPage(HOSTS_PAGE);
});
- afterEach(() => {
- return logout();
- });
-
it('executes a KQL query', () => {
toggleTimelineVisibility();
diff --git a/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/timeline/toggle_column.spec.ts b/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/timeline/toggle_column.spec.ts
index 8197f77db9a081..9a915b0e77d440 100644
--- a/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/timeline/toggle_column.spec.ts
+++ b/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/timeline/toggle_column.spec.ts
@@ -6,7 +6,6 @@
import { drag, drop } from '../../lib/drag_n_drop/helpers';
import { populateTimeline } from '../../lib/fields_browser/helpers';
-import { logout } from '../../lib/logout';
import { toggleFirstTimelineEventDetails } from '../../lib/timeline/helpers';
import { HOSTS_PAGE } from '../../lib/urls';
import { loginAndWaitForPage, DEFAULT_TIMEOUT } from '../../lib/util/helpers';
@@ -16,10 +15,6 @@ describe('toggle column in timeline', () => {
loginAndWaitForPage(HOSTS_PAGE);
});
- afterEach(() => {
- return logout();
- });
-
const timestampField = '@timestamp';
const idField = '_id';
diff --git a/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/url_state/url_state.spec.ts b/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/url_state/url_state.spec.ts
index dba5099a93c5a1..33ee2cb1cb302f 100644
--- a/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/url_state/url_state.spec.ts
+++ b/x-pack/legacy/plugins/siem/cypress/integration/smoke_tests/url_state/url_state.spec.ts
@@ -4,7 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { logout } from '../../lib/logout';
import {
ABSOLUTE_DATE_RANGE,
DATE_PICKER_ABSOLUTE_INPUT,
@@ -33,10 +32,6 @@ import { waitForAllHostsWidget } from '../../lib/hosts/helpers';
import { NAVIGATION_HOSTS_ALL_HOSTS, NAVIGATION_HOSTS_ANOMALIES } from '../../lib/hosts/selectors';
describe('url state', () => {
- afterEach(() => {
- return logout();
- });
-
it('sets the global start and end dates from the url', () => {
loginAndWaitForPage(ABSOLUTE_DATE_RANGE.url);
cy.get(DATE_PICKER_START_DATE_POPOVER_BUTTON).should(
diff --git a/x-pack/legacy/plugins/siem/dev_tools/circular_deps/run_check_circular_deps_cli.js b/x-pack/legacy/plugins/siem/dev_tools/circular_deps/run_check_circular_deps_cli.js
index a4a9532f0e8e49..7d76b1dd921aaf 100644
--- a/x-pack/legacy/plugins/siem/dev_tools/circular_deps/run_check_circular_deps_cli.js
+++ b/x-pack/legacy/plugins/siem/dev_tools/circular_deps/run_check_circular_deps_cli.js
@@ -24,9 +24,7 @@ run(
// We can only care about SIEM code, we should not be penalyze for others
if (circularFound.filter(cf => cf.includes('siem')).length !== 0) {
throw createFailError(
- 'SIEM circular dependencies of imports has been found:' +
- '\n - ' +
- circularFound.join('\n - ')
+ `SIEM circular dependencies of imports has been found:\n - ${circularFound.join('\n - ')}`
);
} else {
log.success('No circular deps 👍');
diff --git a/x-pack/legacy/plugins/siem/index.ts b/x-pack/legacy/plugins/siem/index.ts
index cf9fffc6a14558..c5038626fdfc20 100644
--- a/x-pack/legacy/plugins/siem/index.ts
+++ b/x-pack/legacy/plugins/siem/index.ts
@@ -9,7 +9,7 @@ import { resolve } from 'path';
import { Server } from 'hapi';
import { Root } from 'joi';
-import { PluginInitializerContext } from 'src/core/server';
+import { PluginInitializerContext } from '../../../../src/core/server';
import { plugin } from './server';
import { savedObjectMappings } from './server/saved_objects';
@@ -43,7 +43,7 @@ export const siem = (kibana: any) => {
description: i18n.translate('xpack.siem.securityDescription', {
defaultMessage: 'Explore your SIEM App',
}),
- main: 'plugins/siem/app',
+ main: 'plugins/siem/legacy',
euiIconType: 'securityAnalyticsApp',
title: APP_NAME,
listed: false,
diff --git a/x-pack/legacy/plugins/siem/package.json b/x-pack/legacy/plugins/siem/package.json
index bf5d6d3a3089cb..558ac013e5963b 100644
--- a/x-pack/legacy/plugins/siem/package.json
+++ b/x-pack/legacy/plugins/siem/package.json
@@ -13,7 +13,7 @@
"devDependencies": {
"@types/lodash": "^4.14.110",
"@types/js-yaml": "^3.12.1",
- "@types/react-beautiful-dnd": "^11.0.3"
+ "@types/react-beautiful-dnd": "^11.0.4"
},
"dependencies": {
"lodash": "^4.17.15",
diff --git a/x-pack/legacy/plugins/siem/public/app/app.tsx b/x-pack/legacy/plugins/siem/public/app/app.tsx
new file mode 100644
index 00000000000000..5f9199735d8c04
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/app/app.tsx
@@ -0,0 +1,110 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { createHashHistory, History } from 'history';
+import React, { memo, useMemo, FC } from 'react';
+import { ApolloProvider } from 'react-apollo';
+import { Store } from 'redux';
+import { Provider as ReduxStoreProvider } from 'react-redux';
+import { ThemeProvider } from 'styled-components';
+
+import { EuiErrorBoundary } from '@elastic/eui';
+import euiDarkVars from '@elastic/eui/dist/eui_theme_dark.json';
+import euiLightVars from '@elastic/eui/dist/eui_theme_light.json';
+import { BehaviorSubject } from 'rxjs';
+import { pluck } from 'rxjs/operators';
+import { I18nContext } from 'ui/i18n';
+
+import { KibanaContextProvider, useUiSetting$ } from '../lib/kibana';
+import { Storage } from '../../../../../../src/plugins/kibana_utils/public';
+
+import { DEFAULT_DARK_MODE } from '../../common/constants';
+import { ErrorToastDispatcher } from '../components/error_toast_dispatcher';
+import { compose } from '../lib/compose/kibana_compose';
+import { AppFrontendLibs, AppApolloClient } from '../lib/lib';
+import { CoreStart, StartPlugins } from '../plugin';
+import { PageRouter } from '../routes';
+import { createStore } from '../store';
+import { GlobalToaster, ManageGlobalToaster } from '../components/toasters';
+import { MlCapabilitiesProvider } from '../components/ml/permissions/ml_capabilities_provider';
+
+import { ApolloClientContext } from '../utils/apollo_context';
+
+interface AppPluginRootComponentProps {
+ apolloClient: AppApolloClient;
+ history: History;
+ store: Store;
+ theme: any; // eslint-disable-line @typescript-eslint/no-explicit-any
+}
+
+const AppPluginRootComponent: React.FC = ({
+ theme,
+ store,
+ apolloClient,
+ history,
+}) => (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+);
+
+const AppPluginRoot = memo(AppPluginRootComponent);
+
+const StartAppComponent: FC = libs => {
+ const history = createHashHistory();
+ const libs$ = new BehaviorSubject(libs);
+ const store = createStore(undefined, libs$.pipe(pluck('apolloClient')));
+ const [darkMode] = useUiSetting$(DEFAULT_DARK_MODE);
+ const theme = useMemo(
+ () => ({
+ eui: darkMode ? euiDarkVars : euiLightVars,
+ darkMode,
+ }),
+ [darkMode]
+ );
+
+ return (
+
+ );
+};
+
+const StartApp = memo(StartAppComponent);
+
+interface SiemAppComponentProps {
+ core: CoreStart;
+ plugins: StartPlugins;
+}
+
+const SiemAppComponent: React.FC = ({ core, plugins }) => (
+
+
+
+);
+
+export const SiemApp = memo(SiemAppComponent);
diff --git a/x-pack/legacy/plugins/siem/public/app/index.tsx b/x-pack/legacy/plugins/siem/public/app/index.tsx
new file mode 100644
index 00000000000000..01175a98d1e44e
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/app/index.tsx
@@ -0,0 +1,20 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React from 'react';
+import { render, unmountComponentAtNode } from 'react-dom';
+
+import { CoreStart, StartPlugins, AppMountParameters } from '../plugin';
+import { SiemApp } from './app';
+
+export const renderApp = (
+ core: CoreStart,
+ plugins: StartPlugins,
+ { element }: AppMountParameters
+) => {
+ render(, element);
+ return () => unmountComponentAtNode(element);
+};
diff --git a/x-pack/legacy/plugins/siem/public/apps/index.ts b/x-pack/legacy/plugins/siem/public/apps/index.ts
deleted file mode 100644
index 0cc5c5584e1b76..00000000000000
--- a/x-pack/legacy/plugins/siem/public/apps/index.ts
+++ /dev/null
@@ -1,18 +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;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import chrome from 'ui/chrome';
-import { npStart } from 'ui/new_platform';
-import { Plugin } from './plugin';
-
-const { data, embeddable, inspector, uiActions } = npStart.plugins;
-const startPlugins = { data, embeddable, inspector, uiActions };
-
-new Plugin(
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- { opaqueId: Symbol('siem'), env: {} as any, config: { get: () => ({} as any) } },
- chrome
-).start(npStart.core, startPlugins);
diff --git a/x-pack/legacy/plugins/siem/public/apps/plugin.tsx b/x-pack/legacy/plugins/siem/public/apps/plugin.tsx
deleted file mode 100644
index aa42504e07635f..00000000000000
--- a/x-pack/legacy/plugins/siem/public/apps/plugin.tsx
+++ /dev/null
@@ -1,59 +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;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import React from 'react';
-import { render } from 'react-dom';
-import { LegacyCoreStart, PluginInitializerContext } from 'src/core/public';
-import { PluginsStart } from 'ui/new_platform/new_platform';
-import { Chrome } from 'ui/chrome';
-
-import { DEFAULT_KBN_VERSION, DEFAULT_TIMEZONE_BROWSER } from '../../common/constants';
-import { SiemApp } from './start_app';
-import template from './template.html';
-
-export const ROOT_ELEMENT_ID = 'react-siem-root';
-
-export type StartCore = LegacyCoreStart;
-export type StartPlugins = Required<
- Pick
->;
-export type StartServices = StartCore & StartPlugins;
-
-export class Plugin {
- constructor(
- // @ts-ignore this is added to satisfy the New Platform typing constraint,
- // but we're not leveraging any of its functionality yet.
- private readonly initializerContext: PluginInitializerContext,
- private readonly chrome: Chrome
- ) {
- this.chrome = chrome;
- }
-
- public start(core: StartCore, plugins: StartPlugins) {
- // TODO(rylnd): These are unknown by uiSettings by default
- core.uiSettings.set(DEFAULT_KBN_VERSION, '8.0.0');
- core.uiSettings.set(DEFAULT_TIMEZONE_BROWSER, 'UTC');
-
- // @ts-ignore improper type description
- this.chrome.setRootTemplate(template);
- const checkForRoot = () => {
- return new Promise(resolve => {
- const ready = !!document.getElementById(ROOT_ELEMENT_ID);
- if (ready) {
- resolve();
- } else {
- setTimeout(() => resolve(checkForRoot()), 10);
- }
- });
- };
- checkForRoot().then(() => {
- const node = document.getElementById(ROOT_ELEMENT_ID);
- if (node) {
- render(, node);
- }
- });
- }
-}
diff --git a/x-pack/legacy/plugins/siem/public/apps/start_app.tsx b/x-pack/legacy/plugins/siem/public/apps/start_app.tsx
deleted file mode 100644
index 54180b51fe0398..00000000000000
--- a/x-pack/legacy/plugins/siem/public/apps/start_app.tsx
+++ /dev/null
@@ -1,87 +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;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { createHashHistory } from 'history';
-import React, { memo, FC } from 'react';
-import { ApolloProvider } from 'react-apollo';
-import { Provider as ReduxStoreProvider } from 'react-redux';
-import { ThemeProvider } from 'styled-components';
-
-import { EuiErrorBoundary } from '@elastic/eui';
-import euiDarkVars from '@elastic/eui/dist/eui_theme_dark.json';
-import euiLightVars from '@elastic/eui/dist/eui_theme_light.json';
-import { BehaviorSubject } from 'rxjs';
-import { pluck } from 'rxjs/operators';
-import { I18nContext } from 'ui/i18n';
-
-import { KibanaContextProvider, useUiSetting$ } from '../lib/kibana';
-import { Storage } from '../../../../../../src/plugins/kibana_utils/public';
-
-import { DEFAULT_DARK_MODE } from '../../common/constants';
-import { ErrorToastDispatcher } from '../components/error_toast_dispatcher';
-import { compose } from '../lib/compose/kibana_compose';
-import { AppFrontendLibs } from '../lib/lib';
-import { StartCore, StartPlugins } from './plugin';
-import { PageRouter } from '../routes';
-import { createStore } from '../store';
-import { GlobalToaster, ManageGlobalToaster } from '../components/toasters';
-import { MlCapabilitiesProvider } from '../components/ml/permissions/ml_capabilities_provider';
-
-import { ApolloClientContext } from '../utils/apollo_context';
-
-const StartApp: FC = memo(libs => {
- const history = createHashHistory();
-
- const libs$ = new BehaviorSubject(libs);
-
- const store = createStore(undefined, libs$.pipe(pluck('apolloClient')));
-
- const AppPluginRoot = memo(() => {
- const [darkMode] = useUiSetting$(DEFAULT_DARK_MODE);
- return (
-
-
-
-
-
-
- ({
- eui: darkMode ? euiDarkVars : euiLightVars,
- darkMode,
- })}
- >
-
-
-
-
-
-
-
-
-
-
-
-
- );
- });
- return ;
-});
-
-export const ROOT_ELEMENT_ID = 'react-siem-root';
-
-export const SiemApp = memo<{ core: StartCore; plugins: StartPlugins }>(({ core, plugins }) => (
-
-
-
-));
diff --git a/x-pack/legacy/plugins/siem/public/apps/template.html b/x-pack/legacy/plugins/siem/public/apps/template.html
deleted file mode 100644
index 9f757b25ccecb6..00000000000000
--- a/x-pack/legacy/plugins/siem/public/apps/template.html
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/x-pack/legacy/plugins/siem/public/components/alerts_viewer/alerts_table.tsx b/x-pack/legacy/plugins/siem/public/components/alerts_viewer/alerts_table.tsx
index 8fa4f3625c34f7..179474ee6e9d4a 100644
--- a/x-pack/legacy/plugins/siem/public/components/alerts_viewer/alerts_table.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/alerts_viewer/alerts_table.tsx
@@ -51,33 +51,31 @@ const defaultAlertsFilters: esFilters.Filter[] = [
},
];
-export const AlertsTable = React.memo(
- ({
- endDate,
- startDate,
- pageFilters = [],
- }: {
- endDate: number;
- startDate: number;
- pageFilters?: esFilters.Filter[];
- }) => {
- const alertsFilter = useMemo(() => [...defaultAlertsFilters, ...pageFilters], [pageFilters]);
- return (
- ({
- documentType: i18n.ALERTS_DOCUMENT_TYPE,
- footerText: i18n.TOTAL_COUNT_OF_ALERTS,
- title: i18n.ALERTS_TABLE_TITLE,
- }),
- []
- )}
- />
- );
- }
-);
+interface Props {
+ endDate: number;
+ startDate: number;
+ pageFilters?: esFilters.Filter[];
+}
+
+const AlertsTableComponent: React.FC = ({ endDate, startDate, pageFilters = [] }) => {
+ const alertsFilter = useMemo(() => [...defaultAlertsFilters, ...pageFilters], [pageFilters]);
+ return (
+ ({
+ documentType: i18n.ALERTS_DOCUMENT_TYPE,
+ footerText: i18n.TOTAL_COUNT_OF_ALERTS,
+ title: i18n.ALERTS_TABLE_TITLE,
+ }),
+ []
+ )}
+ />
+ );
+};
+
+export const AlertsTable = React.memo(AlertsTableComponent);
diff --git a/x-pack/legacy/plugins/siem/public/components/and_or_badge/index.tsx b/x-pack/legacy/plugins/siem/public/components/and_or_badge/index.tsx
index be449e3d422d97..2fb270c2840005 100644
--- a/x-pack/legacy/plugins/siem/public/components/and_or_badge/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/and_or_badge/index.tsx
@@ -5,7 +5,7 @@
*/
import { EuiBadge } from '@elastic/eui';
-import * as React from 'react';
+import React from 'react';
import styled from 'styled-components';
import * as i18n from './translations';
diff --git a/x-pack/legacy/plugins/siem/public/components/arrows/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/arrows/index.test.tsx
index 10d3c899562e8c..5404a1ac43844f 100644
--- a/x-pack/legacy/plugins/siem/public/components/arrows/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/arrows/index.test.tsx
@@ -5,8 +5,7 @@
*/
import { mount } from 'enzyme';
-import toJson from 'enzyme-to-json';
-import * as React from 'react';
+import React from 'react';
import { TestProviders } from '../../mock';
@@ -20,7 +19,7 @@ describe('arrows', () => {
);
- expect(toJson(wrapper.find('ArrowBody'))).toMatchSnapshot();
+ expect(wrapper.find('ArrowBody')).toMatchSnapshot();
});
});
diff --git a/x-pack/legacy/plugins/siem/public/components/arrows/index.tsx b/x-pack/legacy/plugins/siem/public/components/arrows/index.tsx
index dfc7645c564d26..97b5eb04ac7bbb 100644
--- a/x-pack/legacy/plugins/siem/public/components/arrows/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/arrows/index.tsx
@@ -5,7 +5,7 @@
*/
import { EuiIcon } from '@elastic/eui';
-import * as React from 'react';
+import React from 'react';
import styled from 'styled-components';
/** Renders the body (non-pointy part) of an arrow */
diff --git a/x-pack/legacy/plugins/siem/public/components/autocomplete_field/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/autocomplete_field/index.test.tsx
index 77a7296e368cfe..27e87d25e286f5 100644
--- a/x-pack/legacy/plugins/siem/public/components/autocomplete_field/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/autocomplete_field/index.test.tsx
@@ -7,9 +7,8 @@
import { EuiFieldSearch } from '@elastic/eui';
import euiDarkVars from '@elastic/eui/dist/eui_theme_dark.json';
import { mount, shallow } from 'enzyme';
-import toJson from 'enzyme-to-json';
import { noop } from 'lodash/fp';
-import * as React from 'react';
+import React from 'react';
import { ThemeProvider } from 'styled-components';
import { AutocompleteSuggestion } from '../../../../../../../src/plugins/data/public';
@@ -117,7 +116,7 @@ describe('Autocomplete', () => {
value={''}
/>
);
- expect(toJson(wrapper)).toMatchSnapshot();
+ expect(wrapper).toMatchSnapshot();
});
test('it is rendering with placeholder', () => {
diff --git a/x-pack/legacy/plugins/siem/public/components/bytes/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/bytes/index.test.tsx
index 6816bff24f1cd2..d99a909efad102 100644
--- a/x-pack/legacy/plugins/siem/public/components/bytes/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/bytes/index.test.tsx
@@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import * as React from 'react';
+import React from 'react';
import { TestProviders } from '../../mock';
import { PreferenceFormattedBytes } from '../formatted_bytes';
diff --git a/x-pack/legacy/plugins/siem/public/components/bytes/index.tsx b/x-pack/legacy/plugins/siem/public/components/bytes/index.tsx
index fbe83623211b1a..94c6ecba68be52 100644
--- a/x-pack/legacy/plugins/siem/public/components/bytes/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/bytes/index.tsx
@@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import * as React from 'react';
+import React from 'react';
import { DefaultDraggable } from '../draggables';
import { PreferenceFormattedBytes } from '../formatted_bytes';
diff --git a/x-pack/legacy/plugins/siem/public/components/certificate_fingerprint/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/certificate_fingerprint/index.test.tsx
index b0c165fedfffc1..9cd0af062c54a6 100644
--- a/x-pack/legacy/plugins/siem/public/components/certificate_fingerprint/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/certificate_fingerprint/index.test.tsx
@@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import * as React from 'react';
+import React from 'react';
import { TestProviders } from '../../mock';
import { useMountAppended } from '../../utils/use_mount_appended';
diff --git a/x-pack/legacy/plugins/siem/public/components/certificate_fingerprint/index.tsx b/x-pack/legacy/plugins/siem/public/components/certificate_fingerprint/index.tsx
index f8db7d754aab15..181d92dce06f99 100644
--- a/x-pack/legacy/plugins/siem/public/components/certificate_fingerprint/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/certificate_fingerprint/index.tsx
@@ -5,7 +5,7 @@
*/
import { EuiText } from '@elastic/eui';
-import * as React from 'react';
+import React from 'react';
import styled from 'styled-components';
import { DraggableBadge } from '../draggables';
diff --git a/x-pack/legacy/plugins/siem/public/components/charts/areachart.test.tsx b/x-pack/legacy/plugins/siem/public/components/charts/areachart.test.tsx
index 2b99efc05fd8cb..ac283790671d3a 100644
--- a/x-pack/legacy/plugins/siem/public/components/charts/areachart.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/charts/areachart.test.tsx
@@ -5,7 +5,7 @@
*/
import { ShallowWrapper, shallow } from 'enzyme';
-import * as React from 'react';
+import React from 'react';
import { AreaChartBaseComponent, AreaChartComponent } from './areachart';
import { ChartSeriesData } from './common';
diff --git a/x-pack/legacy/plugins/siem/public/components/charts/areachart.tsx b/x-pack/legacy/plugins/siem/public/components/charts/areachart.tsx
index ba07a3f3436d93..71f22efadc6ed2 100644
--- a/x-pack/legacy/plugins/siem/public/components/charts/areachart.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/charts/areachart.tsx
@@ -18,6 +18,7 @@ import {
import { getOr, get, isNull, isNumber } from 'lodash/fp';
import { AutoSizer } from '../auto_sizer';
import { ChartPlaceHolder } from './chart_place_holder';
+import { useTimeZone } from '../../hooks';
import {
chartDefaultSettings,
ChartSeriesConfigs,
@@ -26,7 +27,6 @@ import {
getChartWidth,
WrappedByAutoSizer,
useTheme,
- useBrowserTimeZone,
} from './common';
// custom series styles: https://ela.st/areachart-styling
@@ -71,7 +71,7 @@ export const AreaChartBaseComponent = ({
configs?: ChartSeriesConfigs | undefined;
}) => {
const theme = useTheme();
- const timeZone = useBrowserTimeZone();
+ const timeZone = useTimeZone();
const xTickFormatter = get('configs.axis.xTickFormatter', chartConfigs);
const yTickFormatter = get('configs.axis.yTickFormatter', chartConfigs);
const xAxisId = `group-${data[0].key}-x`;
diff --git a/x-pack/legacy/plugins/siem/public/components/charts/barchart.test.tsx b/x-pack/legacy/plugins/siem/public/components/charts/barchart.test.tsx
index 506b1ceb5ed830..ac9c4d591232a6 100644
--- a/x-pack/legacy/plugins/siem/public/components/charts/barchart.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/charts/barchart.test.tsx
@@ -5,7 +5,7 @@
*/
import { shallow, ShallowWrapper } from 'enzyme';
-import * as React from 'react';
+import React from 'react';
import { BarChartBaseComponent, BarChartComponent } from './barchart';
import { ChartSeriesData } from './common';
diff --git a/x-pack/legacy/plugins/siem/public/components/charts/barchart.tsx b/x-pack/legacy/plugins/siem/public/components/charts/barchart.tsx
index db84d7dbd2c18f..415cbeb7c24409 100644
--- a/x-pack/legacy/plugins/siem/public/components/charts/barchart.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/charts/barchart.tsx
@@ -7,6 +7,7 @@
import React from 'react';
import { Chart, BarSeries, Axis, Position, ScaleType, Settings } from '@elastic/charts';
import { getOr, get, isNumber } from 'lodash/fp';
+import { useTimeZone } from '../../hooks';
import { AutoSizer } from '../auto_sizer';
import { ChartPlaceHolder } from './chart_place_holder';
import {
@@ -17,7 +18,6 @@ import {
getChartHeight,
getChartWidth,
WrappedByAutoSizer,
- useBrowserTimeZone,
useTheme,
} from './common';
@@ -44,7 +44,7 @@ export const BarChartBaseComponent = ({
configs?: ChartSeriesConfigs | undefined;
}) => {
const theme = useTheme();
- const timeZone = useBrowserTimeZone();
+ const timeZone = useTimeZone();
const xTickFormatter = get('configs.axis.xTickFormatter', chartConfigs);
const yTickFormatter = get('configs.axis.yTickFormatter', chartConfigs);
const tickSize = getOr(0, 'configs.axis.tickSize', chartConfigs);
diff --git a/x-pack/legacy/plugins/siem/public/components/charts/common.tsx b/x-pack/legacy/plugins/siem/public/components/charts/common.tsx
index a4be390019916d..78cce72f0a0d39 100644
--- a/x-pack/legacy/plugins/siem/public/components/charts/common.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/charts/common.tsx
@@ -15,10 +15,9 @@ import {
SettingsSpecProps,
TickFormatter,
} from '@elastic/charts';
-import moment from 'moment-timezone';
import styled from 'styled-components';
import { useUiSetting } from '../../lib/kibana';
-import { DEFAULT_DATE_FORMAT_TZ, DEFAULT_DARK_MODE } from '../../../common/constants';
+import { DEFAULT_DARK_MODE } from '../../../common/constants';
export const defaultChartHeight = '100%';
export const defaultChartWidth = '100%';
@@ -108,11 +107,6 @@ export const chartDefaultSettings = {
debug: false,
};
-export const useBrowserTimeZone = () => {
- const kibanaTimezone = useUiSetting(DEFAULT_DATE_FORMAT_TZ);
- return kibanaTimezone === 'Browser' ? moment.tz.guess() : kibanaTimezone;
-};
-
export const getChartHeight = (customHeight?: number, autoSizerHeight?: number): string => {
const height = customHeight || autoSizerHeight;
return height ? `${height}px` : defaultChartHeight;
diff --git a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar.test.tsx b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar.test.tsx
index a5eac381f92150..eae0fc4ff422b8 100644
--- a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar.test.tsx
@@ -6,7 +6,6 @@
import euiDarkVars from '@elastic/eui/dist/eui_theme_dark.json';
import { mount, shallow } from 'enzyme';
-import toJson from 'enzyme-to-json';
import React from 'react';
import { TestProviders } from '../../../mock';
@@ -44,7 +43,7 @@ describe('UtilityBar', () => {
);
- expect(toJson(wrapper.find('UtilityBar'))).toMatchSnapshot();
+ expect(wrapper.find('UtilityBar')).toMatchSnapshot();
});
test('it applies border styles when border is true', () => {
diff --git a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_action.test.tsx b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_action.test.tsx
index 2610fb44532f59..2a8a71955a986a 100644
--- a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_action.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_action.test.tsx
@@ -5,7 +5,6 @@
*/
import { mount, shallow } from 'enzyme';
-import toJson from 'enzyme-to-json';
import React from 'react';
import { TestProviders } from '../../../mock';
@@ -19,7 +18,7 @@ describe('UtilityBarAction', () => {
);
- expect(toJson(wrapper.find('UtilityBarAction'))).toMatchSnapshot();
+ expect(wrapper.find('UtilityBarAction')).toMatchSnapshot();
});
test('it renders a popover', () => {
diff --git a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_group.test.tsx b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_group.test.tsx
index 59ef7021d40493..e18e7d5e0b524f 100644
--- a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_group.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_group.test.tsx
@@ -5,7 +5,6 @@
*/
import { shallow } from 'enzyme';
-import toJson from 'enzyme-to-json';
import React from 'react';
import { TestProviders } from '../../../mock';
@@ -21,6 +20,6 @@ describe('UtilityBarGroup', () => {
);
- expect(toJson(wrapper.find('UtilityBarGroup'))).toMatchSnapshot();
+ expect(wrapper.find('UtilityBarGroup')).toMatchSnapshot();
});
});
diff --git a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_section.test.tsx b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_section.test.tsx
index baa4331ced8f88..f849fa4b4ee46d 100644
--- a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_section.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_section.test.tsx
@@ -5,7 +5,6 @@
*/
import { shallow } from 'enzyme';
-import toJson from 'enzyme-to-json';
import React from 'react';
import { TestProviders } from '../../../mock';
@@ -23,6 +22,6 @@ describe('UtilityBarSection', () => {
);
- expect(toJson(wrapper.find('UtilityBarSection'))).toMatchSnapshot();
+ expect(wrapper.find('UtilityBarSection')).toMatchSnapshot();
});
});
diff --git a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_text.test.tsx b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_text.test.tsx
index 794f207fd88e36..230dd80b1a86b7 100644
--- a/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_text.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/detection_engine/utility_bar/utility_bar_text.test.tsx
@@ -5,7 +5,6 @@
*/
import { shallow } from 'enzyme';
-import toJson from 'enzyme-to-json';
import React from 'react';
import { TestProviders } from '../../../mock';
@@ -19,6 +18,6 @@ describe('UtilityBarText', () => {
);
- expect(toJson(wrapper.find('UtilityBarText'))).toMatchSnapshot();
+ expect(wrapper.find('UtilityBarText')).toMatchSnapshot();
});
});
diff --git a/x-pack/legacy/plugins/siem/public/components/direction/index.tsx b/x-pack/legacy/plugins/siem/public/components/direction/index.tsx
index 9295e055f918d7..ad1e63dbd7e6a1 100644
--- a/x-pack/legacy/plugins/siem/public/components/direction/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/direction/index.tsx
@@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import * as React from 'react';
+import React from 'react';
import { NetworkDirectionEcs } from '../../graphql/types';
import { DraggableBadge } from '../draggables';
diff --git a/x-pack/legacy/plugins/siem/public/components/drag_and_drop/drag_drop_context_wrapper.test.tsx b/x-pack/legacy/plugins/siem/public/components/drag_and_drop/drag_drop_context_wrapper.test.tsx
index 1a8af9d99193a6..9e8bde8d9ff92c 100644
--- a/x-pack/legacy/plugins/siem/public/components/drag_and_drop/drag_drop_context_wrapper.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/drag_and_drop/drag_drop_context_wrapper.test.tsx
@@ -5,8 +5,7 @@
*/
import { mount, shallow } from 'enzyme';
-import toJson from 'enzyme-to-json';
-import * as React from 'react';
+import React from 'react';
import { MockedProvider } from 'react-apollo/test-utils';
import { mockBrowserFields, mocksSource } from '../../containers/source/mock';
@@ -28,7 +27,7 @@ describe('DragDropContextWrapper', () => {
);
- expect(toJson(wrapper.find('DragDropContextWrapper'))).toMatchSnapshot();
+ expect(wrapper.find('DragDropContextWrapper')).toMatchSnapshot();
});
test('it renders the children', () => {
diff --git a/x-pack/legacy/plugins/siem/public/components/drag_and_drop/draggable_wrapper.test.tsx b/x-pack/legacy/plugins/siem/public/components/drag_and_drop/draggable_wrapper.test.tsx
index 4b546bca1f72eb..e846c923c5cbe3 100644
--- a/x-pack/legacy/plugins/siem/public/components/drag_and_drop/draggable_wrapper.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/drag_and_drop/draggable_wrapper.test.tsx
@@ -5,8 +5,7 @@
*/
import { shallow } from 'enzyme';
-import toJson from 'enzyme-to-json';
-import * as React from 'react';
+import React from 'react';
import { MockedProvider } from 'react-apollo/test-utils';
import { mockBrowserFields, mocksSource } from '../../containers/source/mock';
@@ -33,7 +32,7 @@ describe('DraggableWrapper', () => {
);
- expect(toJson(wrapper.find('DraggableWrapper'))).toMatchSnapshot();
+ expect(wrapper.find('DraggableWrapper')).toMatchSnapshot();
});
test('it renders the children passed to the render prop', () => {
diff --git a/x-pack/legacy/plugins/siem/public/components/drag_and_drop/draggable_wrapper.tsx b/x-pack/legacy/plugins/siem/public/components/drag_and_drop/draggable_wrapper.tsx
index 4faf02ead3fe18..9672097713a9b2 100644
--- a/x-pack/legacy/plugins/siem/public/components/drag_and_drop/draggable_wrapper.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/drag_and_drop/draggable_wrapper.tsx
@@ -13,15 +13,15 @@ import {
Droppable,
} from 'react-beautiful-dnd';
import { connect } from 'react-redux';
-import styled, { css } from 'styled-components';
+import styled from 'styled-components';
import { ActionCreator } from 'typescript-fsa';
import { EuiPortal } from '@elastic/eui';
import { dragAndDropActions } from '../../store/drag_and_drop';
import { DataProvider } from '../timeline/data_providers/data_provider';
-import { STATEFUL_EVENT_CSS_CLASS_NAME } from '../timeline/helpers';
import { TruncatableText } from '../truncatable_text';
import { getDraggableId, getDroppableId } from './helpers';
+import { ProviderContainer } from './provider_container';
// As right now, we do not know what we want there, we will keep it as a placeholder
export const DragEffects = styled.div``;
@@ -42,143 +42,12 @@ const Wrapper = styled.div`
Wrapper.displayName = 'Wrapper';
-const ProviderContainer = styled.div<{ isDragging: boolean }>`
- &,
- &::before,
- &::after {
- transition: background ${({ theme }) => theme.eui.euiAnimSpeedFast} ease,
- color ${({ theme }) => theme.eui.euiAnimSpeedFast} ease;
+const ProviderContentWrapper = styled.span`
+ > span.euiToolTipAnchor {
+ display: block; /* allow EuiTooltip content to be truncatable */
}
-
- ${({ isDragging }) =>
- !isDragging &&
- css`
- & {
- border-radius: 2px;
- padding: 0 4px 0 8px;
- position: relative;
- z-index: ${({ theme }) => theme.eui.euiZLevel0} !important;
-
- &::before {
- background-image: linear-gradient(
- 135deg,
- ${({ theme }) => theme.eui.euiColorMediumShade} 25%,
- transparent 25%
- ),
- linear-gradient(
- -135deg,
- ${({ theme }) => theme.eui.euiColorMediumShade} 25%,
- transparent 25%
- ),
- linear-gradient(
- 135deg,
- transparent 75%,
- ${({ theme }) => theme.eui.euiColorMediumShade} 75%
- ),
- linear-gradient(
- -135deg,
- transparent 75%,
- ${({ theme }) => theme.eui.euiColorMediumShade} 75%
- );
- background-position: 0 0, 1px 0, 1px -1px, 0px 1px;
- background-size: 2px 2px;
- bottom: 2px;
- content: '';
- display: block;
- left: 2px;
- position: absolute;
- top: 2px;
- width: 4px;
- }
- }
-
- &:hover {
- &,
- & .euiBadge,
- & .euiBadge__text {
- cursor: move; /* Fallback for IE11 */
- cursor: grab;
- }
- }
-
- .${STATEFUL_EVENT_CSS_CLASS_NAME}:hover &,
- tr:hover & {
- background-color: ${({ theme }) => theme.eui.euiColorLightShade};
-
- &::before {
- background-image: linear-gradient(
- 135deg,
- ${({ theme }) => theme.eui.euiColorDarkShade} 25%,
- transparent 25%
- ),
- linear-gradient(
- -135deg,
- ${({ theme }) => theme.eui.euiColorDarkShade} 25%,
- transparent 25%
- ),
- linear-gradient(
- 135deg,
- transparent 75%,
- ${({ theme }) => theme.eui.euiColorDarkShade} 75%
- ),
- linear-gradient(
- -135deg,
- transparent 75%,
- ${({ theme }) => theme.eui.euiColorDarkShade} 75%
- );
- }
- }
-
- &:hover,
- &:focus,
- .${STATEFUL_EVENT_CSS_CLASS_NAME}:hover &:hover,
- .${STATEFUL_EVENT_CSS_CLASS_NAME}:focus &:focus,
- tr:hover &:hover,
- tr:hover &:focus {
- background-color: ${({ theme }) => theme.eui.euiColorPrimary};
-
- &,
- & a,
- & a:hover {
- color: ${({ theme }) => theme.eui.euiColorEmptyShade};
- }
-
- &::before {
- background-image: linear-gradient(
- 135deg,
- ${({ theme }) => theme.eui.euiColorEmptyShade} 25%,
- transparent 25%
- ),
- linear-gradient(
- -135deg,
- ${({ theme }) => theme.eui.euiColorEmptyShade} 25%,
- transparent 25%
- ),
- linear-gradient(
- 135deg,
- transparent 75%,
- ${({ theme }) => theme.eui.euiColorEmptyShade} 75%
- ),
- linear-gradient(
- -135deg,
- transparent 75%,
- ${({ theme }) => theme.eui.euiColorEmptyShade} 75%
- );
- }
- }
- `}
-
- ${({ isDragging }) =>
- isDragging &&
- css`
- & {
- z-index: 9999 !important;
- }
- `}
`;
-ProviderContainer.displayName = 'ProviderContainer';
-
interface OwnProps {
dataProvider: DataProvider;
inline?: boolean;
@@ -244,9 +113,11 @@ const DraggableWrapperComponent = React.memo(
{render(dataProvider, provided, snapshot)}
) : (
-
+
{render(dataProvider, provided, snapshot)}
-
+
)}
diff --git a/x-pack/legacy/plugins/siem/public/components/drag_and_drop/droppable_wrapper.test.tsx b/x-pack/legacy/plugins/siem/public/components/drag_and_drop/droppable_wrapper.test.tsx
index 056669673bb9e2..bd2f01721290fb 100644
--- a/x-pack/legacy/plugins/siem/public/components/drag_and_drop/droppable_wrapper.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/drag_and_drop/droppable_wrapper.test.tsx
@@ -5,8 +5,7 @@
*/
import { shallow } from 'enzyme';
-import toJson from 'enzyme-to-json';
-import * as React from 'react';
+import React from 'react';
import { MockedProvider } from 'react-apollo/test-utils';
import { mockBrowserFields, mocksSource } from '../../containers/source/mock';
@@ -33,7 +32,7 @@ describe('DroppableWrapper', () => {
);
- expect(toJson(wrapper.find('DroppableWrapper'))).toMatchSnapshot();
+ expect(wrapper.find('DroppableWrapper')).toMatchSnapshot();
});
test('it renders the children when a render prop is not provided', () => {
diff --git a/x-pack/legacy/plugins/siem/public/components/drag_and_drop/droppable_wrapper.tsx b/x-pack/legacy/plugins/siem/public/components/drag_and_drop/droppable_wrapper.tsx
index c660ac6adaa71d..821ef9be10e8d0 100644
--- a/x-pack/legacy/plugins/siem/public/components/drag_and_drop/droppable_wrapper.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/drag_and_drop/droppable_wrapper.tsx
@@ -5,7 +5,7 @@
*/
import { rgba } from 'polished';
-import * as React from 'react';
+import React from 'react';
import { Droppable } from 'react-beautiful-dnd';
import styled from 'styled-components';
diff --git a/x-pack/legacy/plugins/siem/public/components/drag_and_drop/provider_container.tsx b/x-pack/legacy/plugins/siem/public/components/drag_and_drop/provider_container.tsx
new file mode 100644
index 00000000000000..c1f029086aa350
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/components/drag_and_drop/provider_container.tsx
@@ -0,0 +1,154 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React from 'react';
+import styled, { css } from 'styled-components';
+import { STATEFUL_EVENT_CSS_CLASS_NAME } from '../timeline/helpers';
+
+interface ProviderContainerProps {
+ isDragging: boolean;
+}
+
+const ProviderContainerComponent = styled.div`
+ &,
+ &::before,
+ &::after {
+ transition: background ${({ theme }) => theme.eui.euiAnimSpeedFast} ease,
+ color ${({ theme }) => theme.eui.euiAnimSpeedFast} ease;
+ }
+
+ ${({ isDragging }) =>
+ !isDragging &&
+ css`
+ & {
+ border-radius: 2px;
+ padding: 0 4px 0 8px;
+ position: relative;
+ z-index: ${({ theme }) => theme.eui.euiZLevel0} !important;
+
+ &::before {
+ background-image: linear-gradient(
+ 135deg,
+ ${({ theme }) => theme.eui.euiColorMediumShade} 25%,
+ transparent 25%
+ ),
+ linear-gradient(
+ -135deg,
+ ${({ theme }) => theme.eui.euiColorMediumShade} 25%,
+ transparent 25%
+ ),
+ linear-gradient(
+ 135deg,
+ transparent 75%,
+ ${({ theme }) => theme.eui.euiColorMediumShade} 75%
+ ),
+ linear-gradient(
+ -135deg,
+ transparent 75%,
+ ${({ theme }) => theme.eui.euiColorMediumShade} 75%
+ );
+ background-position: 0 0, 1px 0, 1px -1px, 0px 1px;
+ background-size: 2px 2px;
+ bottom: 2px;
+ content: '';
+ display: block;
+ left: 2px;
+ position: absolute;
+ top: 2px;
+ width: 4px;
+ }
+ }
+
+ &:hover {
+ &,
+ & .euiBadge,
+ & .euiBadge__text {
+ cursor: move; /* Fallback for IE11 */
+ cursor: grab;
+ }
+ }
+
+ .${STATEFUL_EVENT_CSS_CLASS_NAME}:hover &,
+ tr:hover & {
+ background-color: ${({ theme }) => theme.eui.euiColorLightShade};
+
+ &::before {
+ background-image: linear-gradient(
+ 135deg,
+ ${({ theme }) => theme.eui.euiColorDarkShade} 25%,
+ transparent 25%
+ ),
+ linear-gradient(
+ -135deg,
+ ${({ theme }) => theme.eui.euiColorDarkShade} 25%,
+ transparent 25%
+ ),
+ linear-gradient(
+ 135deg,
+ transparent 75%,
+ ${({ theme }) => theme.eui.euiColorDarkShade} 75%
+ ),
+ linear-gradient(
+ -135deg,
+ transparent 75%,
+ ${({ theme }) => theme.eui.euiColorDarkShade} 75%
+ );
+ }
+ }
+
+ &:hover,
+ &:focus,
+ .${STATEFUL_EVENT_CSS_CLASS_NAME}:hover &:hover,
+ .${STATEFUL_EVENT_CSS_CLASS_NAME}:focus &:focus,
+ tr:hover &:hover,
+ tr:hover &:focus {
+ background-color: ${({ theme }) => theme.eui.euiColorPrimary};
+
+ &,
+ & a,
+ & a:hover {
+ color: ${({ theme }) => theme.eui.euiColorEmptyShade};
+ }
+
+ &::before {
+ background-image: linear-gradient(
+ 135deg,
+ ${({ theme }) => theme.eui.euiColorEmptyShade} 25%,
+ transparent 25%
+ ),
+ linear-gradient(
+ -135deg,
+ ${({ theme }) => theme.eui.euiColorEmptyShade} 25%,
+ transparent 25%
+ ),
+ linear-gradient(
+ 135deg,
+ transparent 75%,
+ ${({ theme }) => theme.eui.euiColorEmptyShade} 75%
+ ),
+ linear-gradient(
+ -135deg,
+ transparent 75%,
+ ${({ theme }) => theme.eui.euiColorEmptyShade} 75%
+ );
+ }
+ }
+ `}
+
+ ${({ isDragging }) =>
+ isDragging &&
+ css`
+ & {
+ z-index: 9999 !important;
+ }
+ `}
+`;
+
+ProviderContainerComponent.displayName = 'ProviderContainerComponent';
+
+export const ProviderContainer = React.memo(ProviderContainerComponent);
+
+ProviderContainer.displayName = 'ProviderContainer';
diff --git a/x-pack/legacy/plugins/siem/public/components/draggables/field_badge/index.tsx b/x-pack/legacy/plugins/siem/public/components/draggables/field_badge/index.tsx
index 90d8ad463b476e..ba0d53210bace5 100644
--- a/x-pack/legacy/plugins/siem/public/components/draggables/field_badge/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/draggables/field_badge/index.tsx
@@ -5,7 +5,7 @@
*/
import { rgba } from 'polished';
-import * as React from 'react';
+import React from 'react';
import styled from 'styled-components';
const Field = styled.div`
diff --git a/x-pack/legacy/plugins/siem/public/components/draggables/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/draggables/index.test.tsx
index f1ed533bef545f..76335e3c723061 100644
--- a/x-pack/legacy/plugins/siem/public/components/draggables/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/draggables/index.test.tsx
@@ -5,8 +5,7 @@
*/
import { shallow } from 'enzyme';
-import toJson from 'enzyme-to-json';
-import * as React from 'react';
+import React from 'react';
import { TestProviders } from '../../mock';
import { getEmptyString } from '../empty_value';
@@ -34,7 +33,7 @@ describe('draggables', () => {
{'A child of this'}
);
- expect(toJson(wrapper)).toMatchSnapshot();
+ expect(wrapper).toMatchSnapshot();
});
test('it renders the default Badge', () => {
@@ -50,7 +49,7 @@ describe('draggables', () => {
{'A child of this'}
);
- expect(toJson(wrapper)).toMatchSnapshot();
+ expect(wrapper).toMatchSnapshot();
});
});
diff --git a/x-pack/legacy/plugins/siem/public/components/draggables/index.tsx b/x-pack/legacy/plugins/siem/public/components/draggables/index.tsx
index 5b219dad9c8412..57f047416ec1ca 100644
--- a/x-pack/legacy/plugins/siem/public/components/draggables/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/draggables/index.tsx
@@ -5,7 +5,7 @@
*/
import { EuiBadge, EuiBadgeProps, EuiToolTip, IconType } from '@elastic/eui';
-import * as React from 'react';
+import React from 'react';
import { Omit } from '../../../common/utility_types';
import { DragEffects, DraggableWrapper } from '../drag_and_drop/draggable_wrapper';
@@ -105,12 +105,9 @@ export const DefaultDraggable = React.memo(
) : (
-
+
+ {children}
+
)
}
/>
diff --git a/x-pack/legacy/plugins/siem/public/components/duration/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/duration/index.test.tsx
index 140a625bc53fee..0dbc60ad9ae523 100644
--- a/x-pack/legacy/plugins/siem/public/components/duration/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/duration/index.test.tsx
@@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import * as React from 'react';
+import React from 'react';
import { TestProviders } from '../../mock';
import { ONE_MILLISECOND_AS_NANOSECONDS } from '../formatted_duration/helpers';
diff --git a/x-pack/legacy/plugins/siem/public/components/duration/index.tsx b/x-pack/legacy/plugins/siem/public/components/duration/index.tsx
index 15e6246f1f1ad8..76712b789ffbe5 100644
--- a/x-pack/legacy/plugins/siem/public/components/duration/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/duration/index.tsx
@@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import * as React from 'react';
+import React from 'react';
import { DefaultDraggable } from '../draggables';
import { FormattedDuration } from '../formatted_duration';
diff --git a/x-pack/legacy/plugins/siem/public/components/edit_data_provider/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/edit_data_provider/index.test.tsx
index 7c515862b0d921..1786905a4bb48a 100644
--- a/x-pack/legacy/plugins/siem/public/components/edit_data_provider/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/edit_data_provider/index.test.tsx
@@ -5,7 +5,7 @@
*/
import { mount } from 'enzyme';
-import * as React from 'react';
+import React from 'react';
import { mockBrowserFields } from '../../containers/source/mock';
import { TestProviders } from '../../mock';
diff --git a/x-pack/legacy/plugins/siem/public/components/embeddables/embeddable.test.tsx b/x-pack/legacy/plugins/siem/public/components/embeddables/embeddable.test.tsx
index 884d5bc348d6f3..2dc3d8828675f8 100644
--- a/x-pack/legacy/plugins/siem/public/components/embeddables/embeddable.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/embeddables/embeddable.test.tsx
@@ -5,7 +5,6 @@
*/
import { shallow } from 'enzyme';
-import toJson from 'enzyme-to-json';
import React from 'react';
import { Embeddable } from './embeddable';
@@ -18,6 +17,6 @@ describe('Embeddable', () => {
);
- expect(toJson(wrapper)).toMatchSnapshot();
+ expect(wrapper).toMatchSnapshot();
});
});
diff --git a/x-pack/legacy/plugins/siem/public/components/embeddables/embeddable_header.test.tsx b/x-pack/legacy/plugins/siem/public/components/embeddables/embeddable_header.test.tsx
index aa247b69eb4eb2..3b8e137618ab0c 100644
--- a/x-pack/legacy/plugins/siem/public/components/embeddables/embeddable_header.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/embeddables/embeddable_header.test.tsx
@@ -5,7 +5,6 @@
*/
import { mount, shallow } from 'enzyme';
-import toJson from 'enzyme-to-json';
import React from 'react';
import { TestProviders } from '../../mock';
@@ -15,7 +14,7 @@ describe('EmbeddableHeader', () => {
test('it renders', () => {
const wrapper = shallow();
- expect(toJson(wrapper)).toMatchSnapshot();
+ expect(wrapper).toMatchSnapshot();
});
test('it renders the title', () => {
diff --git a/x-pack/legacy/plugins/siem/public/components/embeddables/embedded_map.test.tsx b/x-pack/legacy/plugins/siem/public/components/embeddables/embedded_map.test.tsx
index 007916595fd6ad..c752273777d2f0 100644
--- a/x-pack/legacy/plugins/siem/public/components/embeddables/embedded_map.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/embeddables/embedded_map.test.tsx
@@ -5,8 +5,7 @@
*/
import { shallow } from 'enzyme';
-import toJson from 'enzyme-to-json';
-import * as React from 'react';
+import React from 'react';
import { useIndexPatterns } from '../../hooks/use_index_patterns';
import { EmbeddedMapComponent } from './embedded_map';
@@ -41,6 +40,6 @@ describe('EmbeddedMapComponent', () => {
startDate={new Date('2019-08-28T05:50:47.877Z').getTime()}
/>
);
- expect(toJson(wrapper)).toMatchSnapshot();
+ expect(wrapper).toMatchSnapshot();
});
});
diff --git a/x-pack/legacy/plugins/siem/public/components/embeddables/index_patterns_missing_prompt.test.tsx b/x-pack/legacy/plugins/siem/public/components/embeddables/index_patterns_missing_prompt.test.tsx
index d04329edff4756..4f617644a1fe14 100644
--- a/x-pack/legacy/plugins/siem/public/components/embeddables/index_patterns_missing_prompt.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/embeddables/index_patterns_missing_prompt.test.tsx
@@ -5,8 +5,7 @@
*/
import { shallow } from 'enzyme';
-import toJson from 'enzyme-to-json';
-import * as React from 'react';
+import React from 'react';
import { IndexPatternsMissingPromptComponent } from './index_patterns_missing_prompt';
@@ -15,6 +14,6 @@ jest.mock('../../lib/kibana');
describe('IndexPatternsMissingPrompt', () => {
test('renders correctly against snapshot', () => {
const wrapper = shallow();
- expect(toJson(wrapper)).toMatchSnapshot();
+ expect(wrapper).toMatchSnapshot();
});
});
diff --git a/x-pack/legacy/plugins/siem/public/components/embeddables/index_patterns_missing_prompt.tsx b/x-pack/legacy/plugins/siem/public/components/embeddables/index_patterns_missing_prompt.tsx
index 798e3d2c10f97f..a4f95d2e299adc 100644
--- a/x-pack/legacy/plugins/siem/public/components/embeddables/index_patterns_missing_prompt.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/embeddables/index_patterns_missing_prompt.tsx
@@ -6,7 +6,7 @@
import { EuiButton, EuiCode, EuiEmptyPrompt } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
-import * as React from 'react';
+import React from 'react';
import chrome from 'ui/chrome';
import { useKibana } from '../../lib/kibana';
diff --git a/x-pack/legacy/plugins/siem/public/components/embeddables/map_tool_tip/line_tool_tip_content.test.tsx b/x-pack/legacy/plugins/siem/public/components/embeddables/map_tool_tip/line_tool_tip_content.test.tsx
index c43ab1ff4a036f..824c717427763c 100644
--- a/x-pack/legacy/plugins/siem/public/components/embeddables/map_tool_tip/line_tool_tip_content.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/embeddables/map_tool_tip/line_tool_tip_content.test.tsx
@@ -5,8 +5,7 @@
*/
import { shallow } from 'enzyme';
-import toJson from 'enzyme-to-json';
-import * as React from 'react';
+import React from 'react';
import { LineToolTipContentComponent } from './line_tool_tip_content';
import { FeatureProperty } from '../types';
import { SUM_OF_DESTINATION_BYTES, SUM_OF_SOURCE_BYTES } from '../map_config';
@@ -27,6 +26,6 @@ describe('LineToolTipContent', () => {
const wrapper = shallow(
);
- expect(toJson(wrapper)).toMatchSnapshot();
+ expect(wrapper).toMatchSnapshot();
});
});
diff --git a/x-pack/legacy/plugins/siem/public/components/embeddables/map_tool_tip/map_tool_tip.test.tsx b/x-pack/legacy/plugins/siem/public/components/embeddables/map_tool_tip/map_tool_tip.test.tsx
index 13eefb252fb04b..2daaeb53e45f2c 100644
--- a/x-pack/legacy/plugins/siem/public/components/embeddables/map_tool_tip/map_tool_tip.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/embeddables/map_tool_tip/map_tool_tip.test.tsx
@@ -5,8 +5,7 @@
*/
import { shallow } from 'enzyme';
-import toJson from 'enzyme-to-json';
-import * as React from 'react';
+import React from 'react';
import { MapToolTipComponent } from './map_tool_tip';
import { MapFeature } from '../types';
@@ -19,7 +18,7 @@ jest.mock('../../search_bar', () => ({
describe('MapToolTip', () => {
test('placeholder component renders correctly against snapshot', () => {
const wrapper = shallow();
- expect(toJson(wrapper)).toMatchSnapshot();
+ expect(wrapper).toMatchSnapshot();
});
test('full component renders correctly against snapshot', () => {
@@ -46,6 +45,6 @@ describe('MapToolTip', () => {
loadFeatureGeometry={loadFeatureGeometry}
/>
);
- expect(toJson(wrapper)).toMatchSnapshot();
+ expect(wrapper).toMatchSnapshot();
});
});
diff --git a/x-pack/legacy/plugins/siem/public/components/embeddables/map_tool_tip/point_tool_tip_content.test.tsx b/x-pack/legacy/plugins/siem/public/components/embeddables/map_tool_tip/point_tool_tip_content.test.tsx
index 929b4983b5fd76..8741cfaa26ca6d 100644
--- a/x-pack/legacy/plugins/siem/public/components/embeddables/map_tool_tip/point_tool_tip_content.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/embeddables/map_tool_tip/point_tool_tip_content.test.tsx
@@ -5,8 +5,7 @@
*/
import { shallow } from 'enzyme';
-import toJson from 'enzyme-to-json';
-import * as React from 'react';
+import React from 'react';
import { FeatureProperty } from '../types';
import { getRenderedFieldValue, PointToolTipContentComponent } from './point_tool_tip_content';
import { TestProviders } from '../../../mock';
@@ -49,7 +48,7 @@ describe('PointToolTipContent', () => {
/>
);
- expect(toJson(wrapper.find('PointToolTipContentComponent'))).toMatchSnapshot();
+ expect(wrapper.find('PointToolTipContentComponent')).toMatchSnapshot();
});
test('renders array filter correctly', () => {
diff --git a/x-pack/legacy/plugins/siem/public/components/embeddables/map_tool_tip/tooltip_footer.test.tsx b/x-pack/legacy/plugins/siem/public/components/embeddables/map_tool_tip/tooltip_footer.test.tsx
index 4c77570cfbc9f2..7351ea0a183c36 100644
--- a/x-pack/legacy/plugins/siem/public/components/embeddables/map_tool_tip/tooltip_footer.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/embeddables/map_tool_tip/tooltip_footer.test.tsx
@@ -5,8 +5,7 @@
*/
import { mount, shallow } from 'enzyme';
-import toJson from 'enzyme-to-json';
-import * as React from 'react';
+import React from 'react';
import { ToolTipFooterComponent } from './tooltip_footer';
describe('ToolTipFilter', () => {
@@ -27,7 +26,7 @@ describe('ToolTipFilter', () => {
totalFeatures={100}
/>
);
- expect(toJson(wrapper)).toMatchSnapshot();
+ expect(wrapper).toMatchSnapshot();
});
describe('Lower bounds', () => {
diff --git a/x-pack/legacy/plugins/siem/public/components/empty_page/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/empty_page/index.test.tsx
index 67b0c5ea64b515..6a14c12cee0f85 100644
--- a/x-pack/legacy/plugins/siem/public/components/empty_page/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/empty_page/index.test.tsx
@@ -5,7 +5,6 @@
*/
import { shallow } from 'enzyme';
-import toJson from 'enzyme-to-json';
import React from 'react';
import { EmptyPage } from './index';
@@ -18,5 +17,5 @@ test('renders correctly', () => {
title="My Super Title"
/>
);
- expect(toJson(EmptyComponent)).toMatchSnapshot();
+ expect(EmptyComponent).toMatchSnapshot();
});
diff --git a/x-pack/legacy/plugins/siem/public/components/empty_value/empty_value.test.tsx b/x-pack/legacy/plugins/siem/public/components/empty_value/empty_value.test.tsx
index bd056c04acc894..fc1d30907ab092 100644
--- a/x-pack/legacy/plugins/siem/public/components/empty_value/empty_value.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/empty_value/empty_value.test.tsx
@@ -6,7 +6,6 @@
import euiDarkVars from '@elastic/eui/dist/eui_theme_dark.json';
import { mount, shallow } from 'enzyme';
-import toJson from 'enzyme-to-json';
import React from 'react';
import { ThemeProvider } from 'styled-components';
import { mountWithIntl } from 'test_utils/enzyme_helpers';
@@ -25,7 +24,7 @@ describe('EmptyValue', () => {
test('it renders against snapshot', () => {
const wrapper = shallow({getEmptyString()}
);
- expect(toJson(wrapper)).toMatchSnapshot();
+ expect(wrapper).toMatchSnapshot();
});
describe('#getEmptyValue', () => {
diff --git a/x-pack/legacy/plugins/siem/public/components/error_toast_dispatcher/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/error_toast_dispatcher/index.test.tsx
index 6233fcfe7c823c..6b90d9ccd08c48 100644
--- a/x-pack/legacy/plugins/siem/public/components/error_toast_dispatcher/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/error_toast_dispatcher/index.test.tsx
@@ -5,8 +5,7 @@
*/
import { shallow } from 'enzyme';
-import toJson from 'enzyme-to-json';
-import * as React from 'react';
+import React from 'react';
import { Provider } from 'react-redux';
import { apolloClientObservable, mockGlobalState } from '../../mock';
@@ -30,7 +29,7 @@ describe('Error Toast Dispatcher', () => {
);
- expect(toJson(wrapper.find('Connect(ErrorToastDispatcherComponent)'))).toMatchSnapshot();
+ expect(wrapper.find('Connect(ErrorToastDispatcherComponent)')).toMatchSnapshot();
});
});
});
diff --git a/x-pack/legacy/plugins/siem/public/components/event_details/columns.tsx b/x-pack/legacy/plugins/siem/public/components/event_details/columns.tsx
index d835d2c6219312..1962850425baac 100644
--- a/x-pack/legacy/plugins/siem/public/components/event_details/columns.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/event_details/columns.tsx
@@ -4,6 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/
+/* eslint-disable react/display-name */
+
import {
EuiCheckbox,
EuiFlexGroup,
@@ -13,7 +15,7 @@ import {
EuiText,
EuiToolTip,
} from '@elastic/eui';
-import * as React from 'react';
+import React from 'react';
import { Draggable } from 'react-beautiful-dnd';
import styled from 'styled-components';
@@ -23,16 +25,14 @@ import { WithCopyToClipboard } from '../../lib/clipboard/with_copy_to_clipboard'
import { DragEffects } from '../drag_and_drop/draggable_wrapper';
import { DroppableWrapper } from '../drag_and_drop/droppable_wrapper';
import { getDroppableId, getDraggableFieldId, DRAG_TYPE_FIELD } from '../drag_and_drop/helpers';
-import { DefaultDraggable } from '../draggables';
import { DraggableFieldBadge } from '../draggables/field_badge';
-import { EVENT_DURATION_FIELD_NAME } from '../duration';
import { FieldName } from '../fields_browser/field_name';
import { SelectableText } from '../selectable_text';
import { OverflowField } from '../tables/helpers';
import { ColumnHeader } from '../timeline/body/column_headers/column_header';
import { defaultColumnHeaderType } from '../timeline/body/column_headers/default_headers';
import { DEFAULT_COLUMN_MIN_WIDTH } from '../timeline/body/helpers';
-import { DATE_FIELD_TYPE, MESSAGE_FIELD_NAME } from '../timeline/body/renderers/constants';
+import { MESSAGE_FIELD_NAME } from '../timeline/body/renderers/constants';
import { FormattedFieldValue } from '../timeline/body/renderers/formatted_field';
import { OnUpdateColumns } from '../timeline/events';
import { WithHoverActions } from '../with_hover_actions';
@@ -180,28 +180,14 @@ export const getColumns = ({
data.field === MESSAGE_FIELD_NAME ? (
) : (
-
-
-
-
-
+ />
)
}
/>
diff --git a/x-pack/legacy/plugins/siem/public/components/event_details/event_details.test.tsx b/x-pack/legacy/plugins/siem/public/components/event_details/event_details.test.tsx
index d97da7797bb451..162fc8fd8bb343 100644
--- a/x-pack/legacy/plugins/siem/public/components/event_details/event_details.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/event_details/event_details.test.tsx
@@ -5,8 +5,7 @@
*/
import { shallow } from 'enzyme';
-import toJson from 'enzyme-to-json';
-import * as React from 'react';
+import React from 'react';
import { mockDetailItemData, mockDetailItemDataId } from '../../mock/mock_detail_item';
import { TestProviders } from '../../mock/test_providers';
@@ -34,7 +33,7 @@ describe('EventDetails', () => {
toggleColumn={jest.fn()}
/>
);
- expect(toJson(wrapper)).toMatchSnapshot();
+ expect(wrapper).toMatchSnapshot();
});
});
diff --git a/x-pack/legacy/plugins/siem/public/components/event_details/event_fields_browser.test.tsx b/x-pack/legacy/plugins/siem/public/components/event_details/event_fields_browser.test.tsx
index 25f95bfa1d383f..5b18e2d9b1fbce 100644
--- a/x-pack/legacy/plugins/siem/public/components/event_details/event_fields_browser.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/event_details/event_fields_browser.test.tsx
@@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import * as React from 'react';
+import React from 'react';
import { mockDetailItemData, mockDetailItemDataId } from '../../mock/mock_detail_item';
import { TestProviders } from '../../mock/test_providers';
@@ -14,8 +14,6 @@ import { mockBrowserFields } from '../../containers/source/mock';
import { defaultHeaders } from '../../mock/header';
import { useMountAppended } from '../../utils/use_mount_appended';
-jest.mock('../../lib/kibana');
-
describe('EventFieldsBrowser', () => {
const mount = useMountAppended();
diff --git a/x-pack/legacy/plugins/siem/public/components/event_details/event_fields_browser.tsx b/x-pack/legacy/plugins/siem/public/components/event_details/event_fields_browser.tsx
index cec8ddff1a7c94..f4e9a2b789d71b 100644
--- a/x-pack/legacy/plugins/siem/public/components/event_details/event_fields_browser.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/event_details/event_fields_browser.tsx
@@ -6,7 +6,7 @@
import { sortBy } from 'lodash';
import { EuiInMemoryTable } from '@elastic/eui';
-import * as React from 'react';
+import React, { useMemo } from 'react';
import { ColumnHeader } from '../timeline/body/column_headers/column_header';
import { BrowserFields, getAllFieldsByName } from '../../containers/source';
@@ -29,26 +29,35 @@ interface Props {
/** Renders a table view or JSON view of the `ECS` `data` */
export const EventFieldsBrowser = React.memo(
({ browserFields, columnHeaders, data, eventId, onUpdateColumns, timelineId, toggleColumn }) => {
- const fieldsByName = getAllFieldsByName(browserFields);
+ const fieldsByName = useMemo(() => getAllFieldsByName(browserFields), [browserFields]);
+ const items = useMemo(
+ () =>
+ sortBy(data, ['field']).map(item => ({
+ ...item,
+ ...fieldsByName[item.field],
+ valuesConcatenated: item.values != null ? item.values.join() : '',
+ })),
+ [data, fieldsByName]
+ );
+ const columns = useMemo(
+ () =>
+ getColumns({
+ browserFields,
+ columnHeaders,
+ eventId,
+ onUpdateColumns,
+ contextId: timelineId,
+ toggleColumn,
+ }),
+ [browserFields, columnHeaders, eventId, onUpdateColumns, timelineId, toggleColumn]
+ );
+
return (
, column `render` callbacks expect complete BrowserField
- items={sortBy(data, ['field']).map(item => {
- return {
- ...item,
- ...fieldsByName[item.field],
- valuesConcatenated: item.values != null ? item.values.join() : '',
- };
- })}
- columns={getColumns({
- browserFields,
- columnHeaders,
- eventId,
- onUpdateColumns,
- contextId: timelineId,
- toggleColumn,
- })}
+ items={items}
+ columns={columns}
pagination={false}
search={search}
sorting={true}
diff --git a/x-pack/legacy/plugins/siem/public/components/event_details/json_view.test.tsx b/x-pack/legacy/plugins/siem/public/components/event_details/json_view.test.tsx
index 429fc94b2f2d32..0cf158c8ea90bf 100644
--- a/x-pack/legacy/plugins/siem/public/components/event_details/json_view.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/event_details/json_view.test.tsx
@@ -5,8 +5,7 @@
*/
import { shallow } from 'enzyme';
-import toJson from 'enzyme-to-json';
-import * as React from 'react';
+import React from 'react';
import { mockDetailItemData } from '../../mock';
@@ -16,7 +15,7 @@ describe('JSON View', () => {
describe('rendering', () => {
test('should match snapshot', () => {
const wrapper = shallow();
- expect(toJson(wrapper)).toMatchSnapshot();
+ expect(wrapper).toMatchSnapshot();
});
});
diff --git a/x-pack/legacy/plugins/siem/public/components/event_details/json_view.tsx b/x-pack/legacy/plugins/siem/public/components/event_details/json_view.tsx
index 519f56adff2d20..9897e319e0487b 100644
--- a/x-pack/legacy/plugins/siem/public/components/event_details/json_view.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/event_details/json_view.tsx
@@ -6,7 +6,7 @@
import { EuiCodeEditor } from '@elastic/eui';
import { set } from 'lodash/fp';
-import * as React from 'react';
+import React from 'react';
import styled from 'styled-components';
import { DetailItem } from '../../graphql/types';
diff --git a/x-pack/legacy/plugins/siem/public/components/events_viewer/events_viewer.test.tsx b/x-pack/legacy/plugins/siem/public/components/events_viewer/events_viewer.test.tsx
index b44d83c27a60d3..3cef3e98c2f0a7 100644
--- a/x-pack/legacy/plugins/siem/public/components/events_viewer/events_viewer.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/events_viewer/events_viewer.test.tsx
@@ -18,8 +18,6 @@ import { mockBrowserFields } from '../../containers/source/mock';
import { eventsDefaultModel } from './default_model';
import { useMountAppended } from '../../utils/use_mount_appended';
-jest.mock('../../lib/kibana');
-
const mockUseFetchIndexPatterns: jest.Mock = useFetchIndexPatterns as jest.Mock;
jest.mock('../../containers/detection_engine/rules/fetch_index_patterns');
mockUseFetchIndexPatterns.mockImplementation(() => [
diff --git a/x-pack/legacy/plugins/siem/public/components/events_viewer/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/events_viewer/index.test.tsx
index 27c3abf7f6824c..1e225dabb25410 100644
--- a/x-pack/legacy/plugins/siem/public/components/events_viewer/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/events_viewer/index.test.tsx
@@ -17,8 +17,6 @@ import { useFetchIndexPatterns } from '../../containers/detection_engine/rules/f
import { mockBrowserFields } from '../../containers/source/mock';
import { eventsDefaultModel } from './default_model';
-jest.mock('../../lib/kibana');
-
const mockUseFetchIndexPatterns: jest.Mock = useFetchIndexPatterns as jest.Mock;
jest.mock('../../containers/detection_engine/rules/fetch_index_patterns');
mockUseFetchIndexPatterns.mockImplementation(() => [
diff --git a/x-pack/legacy/plugins/siem/public/components/external_link_icon/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/external_link_icon/index.test.tsx
index 01317e754ad35c..24118ace6796f2 100644
--- a/x-pack/legacy/plugins/siem/public/components/external_link_icon/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/external_link_icon/index.test.tsx
@@ -5,7 +5,7 @@
*/
import { mount } from 'enzyme';
-import * as React from 'react';
+import React from 'react';
import { TestProviders } from '../../mock';
diff --git a/x-pack/legacy/plugins/siem/public/components/external_link_icon/index.tsx b/x-pack/legacy/plugins/siem/public/components/external_link_icon/index.tsx
index bba32e72abc371..147d2e2d541f52 100644
--- a/x-pack/legacy/plugins/siem/public/components/external_link_icon/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/external_link_icon/index.tsx
@@ -5,7 +5,7 @@
*/
import { EuiIcon } from '@elastic/eui';
-import * as React from 'react';
+import React from 'react';
import styled from 'styled-components';
const LinkIcon = styled(EuiIcon)`
diff --git a/x-pack/legacy/plugins/siem/public/components/field_renderers/field_renderers.test.tsx b/x-pack/legacy/plugins/siem/public/components/field_renderers/field_renderers.test.tsx
index e45f5dacb36a26..88d03d8db67611 100644
--- a/x-pack/legacy/plugins/siem/public/components/field_renderers/field_renderers.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/field_renderers/field_renderers.test.tsx
@@ -5,8 +5,7 @@
*/
import { shallow } from 'enzyme';
-import toJson from 'enzyme-to-json';
-import * as React from 'react';
+import React from 'react';
import { FlowTarget, GetIpOverviewQuery, HostEcsFields } from '../../graphql/types';
import { TestProviders } from '../../mock';
@@ -37,7 +36,7 @@ describe('Field Renderers', () => {
locationRenderer(['source.geo.city_name', 'source.geo.region_name'], mockData.complete)
);
- expect(toJson(wrapper)).toMatchSnapshot();
+ expect(wrapper).toMatchSnapshot();
});
test('it renders emptyTagValue when no fields provided', () => {
@@ -61,7 +60,7 @@ describe('Field Renderers', () => {
test('it renders correctly against snapshot', () => {
const wrapper = shallow(dateRenderer(mockData.complete.source!.firstSeen));
- expect(toJson(wrapper)).toMatchSnapshot();
+ expect(wrapper).toMatchSnapshot();
});
test('it renders emptyTagValue when invalid field provided', () => {
@@ -79,7 +78,7 @@ describe('Field Renderers', () => {
autonomousSystemRenderer(mockData.complete.source!.autonomousSystem!, FlowTarget.source)
);
- expect(toJson(wrapper)).toMatchSnapshot();
+ expect(wrapper).toMatchSnapshot();
});
test('it renders emptyTagValue when non-string field provided', () => {
@@ -111,7 +110,7 @@ describe('Field Renderers', () => {
test('it renders correctly against snapshot', () => {
const wrapper = shallow(hostNameRenderer(mockData.complete.host, '10.10.10.10'));
- expect(toJson(wrapper)).toMatchSnapshot();
+ expect(wrapper).toMatchSnapshot();
});
test('it renders emptyTagValue when non-matching IP is provided', () => {
@@ -154,7 +153,7 @@ describe('Field Renderers', () => {
test('it renders correctly against snapshot', () => {
const wrapper = shallow(hostNameRenderer(mockData.complete.host, '10.10.10.10'));
- expect(toJson(wrapper)).toMatchSnapshot();
+ expect(wrapper).toMatchSnapshot();
});
test('it renders emptyTagValue when non-matching IP is provided', () => {
@@ -188,7 +187,7 @@ describe('Field Renderers', () => {
test('it renders correctly against snapshot', () => {
const wrapper = shallow(whoisRenderer('10.10.10.10'));
- expect(toJson(wrapper)).toMatchSnapshot();
+ expect(wrapper).toMatchSnapshot();
});
});
@@ -196,7 +195,7 @@ describe('Field Renderers', () => {
test('it renders correctly against snapshot', () => {
const wrapper = shallow({reputationRenderer('10.10.10.10')});
- expect(toJson(wrapper.find('DragDropContext'))).toMatchSnapshot();
+ expect(wrapper.find('DragDropContext')).toMatchSnapshot();
});
});
diff --git a/x-pack/legacy/plugins/siem/public/components/fields_browser/categories_pane.test.tsx b/x-pack/legacy/plugins/siem/public/components/fields_browser/categories_pane.test.tsx
index 2d3accbcb55c86..361a0789135e41 100644
--- a/x-pack/legacy/plugins/siem/public/components/fields_browser/categories_pane.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/fields_browser/categories_pane.test.tsx
@@ -5,7 +5,7 @@
*/
import { mount } from 'enzyme';
-import * as React from 'react';
+import React from 'react';
import { ThemeProvider } from 'styled-components';
import euiDarkVars from '@elastic/eui/dist/eui_theme_dark.json';
diff --git a/x-pack/legacy/plugins/siem/public/components/fields_browser/categories_pane.tsx b/x-pack/legacy/plugins/siem/public/components/fields_browser/categories_pane.tsx
index 3165580f435a2b..d6972625821cf3 100644
--- a/x-pack/legacy/plugins/siem/public/components/fields_browser/categories_pane.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/fields_browser/categories_pane.tsx
@@ -5,7 +5,7 @@
*/
import { EuiInMemoryTable, EuiTitle } from '@elastic/eui';
-import * as React from 'react';
+import React from 'react';
import styled from 'styled-components';
import { BrowserFields } from '../../containers/source';
diff --git a/x-pack/legacy/plugins/siem/public/components/fields_browser/category.test.tsx b/x-pack/legacy/plugins/siem/public/components/fields_browser/category.test.tsx
index 4e16997ba92f6c..38eaf43977fa21 100644
--- a/x-pack/legacy/plugins/siem/public/components/fields_browser/category.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/fields_browser/category.test.tsx
@@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import * as React from 'react';
+import React from 'react';
import { mockBrowserFields } from '../../containers/source/mock';
diff --git a/x-pack/legacy/plugins/siem/public/components/fields_browser/category.tsx b/x-pack/legacy/plugins/siem/public/components/fields_browser/category.tsx
index 7b8451db2212f1..9d2a7da9b2d00f 100644
--- a/x-pack/legacy/plugins/siem/public/components/fields_browser/category.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/fields_browser/category.tsx
@@ -5,7 +5,7 @@
*/
import { EuiInMemoryTable } from '@elastic/eui';
-import * as React from 'react';
+import React from 'react';
import styled from 'styled-components';
import { BrowserFields } from '../../containers/source';
diff --git a/x-pack/legacy/plugins/siem/public/components/fields_browser/category_columns.test.tsx b/x-pack/legacy/plugins/siem/public/components/fields_browser/category_columns.test.tsx
index ce66a2d8d79195..cbead878f525db 100644
--- a/x-pack/legacy/plugins/siem/public/components/fields_browser/category_columns.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/fields_browser/category_columns.test.tsx
@@ -5,7 +5,7 @@
*/
import { mount } from 'enzyme';
-import * as React from 'react';
+import React from 'react';
import { mockBrowserFields } from '../../containers/source/mock';
diff --git a/x-pack/legacy/plugins/siem/public/components/fields_browser/category_columns.tsx b/x-pack/legacy/plugins/siem/public/components/fields_browser/category_columns.tsx
index a4a53a5a51435c..0c7dd7e908ce33 100644
--- a/x-pack/legacy/plugins/siem/public/components/fields_browser/category_columns.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/fields_browser/category_columns.tsx
@@ -4,6 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/
+/* eslint-disable react/display-name */
+
import {
EuiIcon,
EuiFlexGroup,
diff --git a/x-pack/legacy/plugins/siem/public/components/fields_browser/category_title.test.tsx b/x-pack/legacy/plugins/siem/public/components/fields_browser/category_title.test.tsx
index e0628a410921e5..792e0342a6d592 100644
--- a/x-pack/legacy/plugins/siem/public/components/fields_browser/category_title.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/fields_browser/category_title.test.tsx
@@ -5,7 +5,7 @@
*/
import { mount } from 'enzyme';
-import * as React from 'react';
+import React from 'react';
import { mockBrowserFields } from '../../containers/source/mock';
diff --git a/x-pack/legacy/plugins/siem/public/components/fields_browser/category_title.tsx b/x-pack/legacy/plugins/siem/public/components/fields_browser/category_title.tsx
index 49255abc83dd58..cd14cef328a7e6 100644
--- a/x-pack/legacy/plugins/siem/public/components/fields_browser/category_title.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/fields_browser/category_title.tsx
@@ -5,7 +5,7 @@
*/
import { EuiFlexGroup, EuiFlexItem, EuiTitle } from '@elastic/eui';
-import * as React from 'react';
+import React from 'react';
import styled from 'styled-components';
import { BrowserFields } from '../../containers/source';
diff --git a/x-pack/legacy/plugins/siem/public/components/fields_browser/field_browser.test.tsx b/x-pack/legacy/plugins/siem/public/components/fields_browser/field_browser.test.tsx
index c43d5833fe1da2..9214fd5f2540ce 100644
--- a/x-pack/legacy/plugins/siem/public/components/fields_browser/field_browser.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/fields_browser/field_browser.test.tsx
@@ -5,7 +5,7 @@
*/
import { mount } from 'enzyme';
-import * as React from 'react';
+import React from 'react';
import { mockBrowserFields } from '../../containers/source/mock';
import { TestProviders } from '../../mock';
diff --git a/x-pack/legacy/plugins/siem/public/components/fields_browser/field_browser.tsx b/x-pack/legacy/plugins/siem/public/components/fields_browser/field_browser.tsx
index c23908c396386a..c8a0eb9da688b0 100644
--- a/x-pack/legacy/plugins/siem/public/components/fields_browser/field_browser.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/fields_browser/field_browser.tsx
@@ -102,138 +102,138 @@ type Props = Pick<
* This component has no internal state, but it uses lifecycle methods to
* set focus to the search input, scroll to the selected category, etc
*/
-export const FieldsBrowser = React.memo(
- ({
- browserFields,
- columnHeaders,
- filteredBrowserFields,
- isEventViewer,
- isSearching,
- onCategorySelected,
- onFieldSelected,
- onHideFieldBrowser,
- onSearchInputChange,
- onOutsideClick,
- onUpdateColumns,
- searchInput,
- selectedCategoryId,
- timelineId,
- toggleColumn,
- width,
- }) => {
- /** Focuses the input that filters the field browser */
- const focusInput = () => {
- const elements = document.getElementsByClassName(
- getFieldBrowserSearchInputClassName(timelineId)
- );
+const FieldsBrowserComponent: React.FC = ({
+ browserFields,
+ columnHeaders,
+ filteredBrowserFields,
+ isEventViewer,
+ isSearching,
+ onCategorySelected,
+ onFieldSelected,
+ onHideFieldBrowser,
+ onSearchInputChange,
+ onOutsideClick,
+ onUpdateColumns,
+ searchInput,
+ selectedCategoryId,
+ timelineId,
+ toggleColumn,
+ width,
+}) => {
+ /** Focuses the input that filters the field browser */
+ const focusInput = () => {
+ const elements = document.getElementsByClassName(
+ getFieldBrowserSearchInputClassName(timelineId)
+ );
- if (elements.length > 0) {
- (elements[0] as HTMLElement).focus(); // this cast is required because focus() does not exist on every `Element` returned by `getElementsByClassName`
+ if (elements.length > 0) {
+ (elements[0] as HTMLElement).focus(); // this cast is required because focus() does not exist on every `Element` returned by `getElementsByClassName`
+ }
+ };
+
+ /** Invoked when the user types in the input to filter the field browser */
+ const onInputChange = useCallback(
+ (event: React.ChangeEvent) => {
+ onSearchInputChange(event.target.value);
+ },
+ [onSearchInputChange]
+ );
+
+ const selectFieldAndHide = useCallback(
+ (fieldId: string) => {
+ if (onFieldSelected != null) {
+ onFieldSelected(fieldId);
}
- };
-
- /** Invoked when the user types in the input to filter the field browser */
- const onInputChange = useCallback(
- (event: React.ChangeEvent) => {
- onSearchInputChange(event.target.value);
- },
- [onSearchInputChange]
- );
- const selectFieldAndHide = useCallback(
- (fieldId: string) => {
- if (onFieldSelected != null) {
- onFieldSelected(fieldId);
- }
+ onHideFieldBrowser();
+ },
+ [onFieldSelected, onHideFieldBrowser]
+ );
+
+ const scrollViews = () => {
+ if (selectedCategoryId !== '') {
+ const categoryPaneTitles = document.getElementsByClassName(
+ getCategoryPaneCategoryClassName({
+ categoryId: selectedCategoryId,
+ timelineId,
+ })
+ );
- onHideFieldBrowser();
- },
- [onFieldSelected, onHideFieldBrowser]
- );
+ if (categoryPaneTitles.length > 0) {
+ categoryPaneTitles[0].scrollIntoView();
+ }
+
+ const fieldPaneTitles = document.getElementsByClassName(
+ getFieldBrowserCategoryTitleClassName({
+ categoryId: selectedCategoryId,
+ timelineId,
+ })
+ );
- const scrollViews = () => {
- if (selectedCategoryId !== '') {
- const categoryPaneTitles = document.getElementsByClassName(
- getCategoryPaneCategoryClassName({
- categoryId: selectedCategoryId,
- timelineId,
- })
- );
-
- if (categoryPaneTitles.length > 0) {
- categoryPaneTitles[0].scrollIntoView();
- }
-
- const fieldPaneTitles = document.getElementsByClassName(
- getFieldBrowserCategoryTitleClassName({
- categoryId: selectedCategoryId,
- timelineId,
- })
- );
-
- if (fieldPaneTitles.length > 0) {
- fieldPaneTitles[0].scrollIntoView();
- }
+ if (fieldPaneTitles.length > 0) {
+ fieldPaneTitles[0].scrollIntoView();
}
+ }
+
+ focusInput(); // always re-focus the input to enable additional filtering
+ };
+
+ useEffect(() => {
+ scrollViews();
+ }, [selectedCategoryId, timelineId]);
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
- focusInput(); // always re-focus the input to enable additional filtering
- };
-
- useEffect(() => {
- scrollViews();
- }, [selectedCategoryId, timelineId]);
-
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
- }
-);
+export const FieldsBrowser = React.memo(FieldsBrowserComponent);
diff --git a/x-pack/legacy/plugins/siem/public/components/fields_browser/field_items.test.tsx b/x-pack/legacy/plugins/siem/public/components/fields_browser/field_items.test.tsx
index 6034f5a4764432..4d0c707c469105 100644
--- a/x-pack/legacy/plugins/siem/public/components/fields_browser/field_items.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/fields_browser/field_items.test.tsx
@@ -5,7 +5,7 @@
*/
import { omit } from 'lodash/fp';
-import * as React from 'react';
+import React from 'react';
import { mockBrowserFields } from '../../containers/source/mock';
import { TestProviders } from '../../mock';
diff --git a/x-pack/legacy/plugins/siem/public/components/fields_browser/field_items.tsx b/x-pack/legacy/plugins/siem/public/components/fields_browser/field_items.tsx
index dc902b792d6013..778e9d3d3c7449 100644
--- a/x-pack/legacy/plugins/siem/public/components/fields_browser/field_items.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/fields_browser/field_items.tsx
@@ -4,9 +4,11 @@
* you may not use this file except in compliance with the Elastic License.
*/
+/* eslint-disable react/display-name */
+
import { EuiCheckbox, EuiIcon, EuiToolTip, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { uniqBy } from 'lodash/fp';
-import * as React from 'react';
+import React from 'react';
import { Draggable } from 'react-beautiful-dnd';
import styled from 'styled-components';
diff --git a/x-pack/legacy/plugins/siem/public/components/fields_browser/field_name.test.tsx b/x-pack/legacy/plugins/siem/public/components/fields_browser/field_name.test.tsx
index 59ee2efa1f0061..1437af7a30adb7 100644
--- a/x-pack/legacy/plugins/siem/public/components/fields_browser/field_name.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/fields_browser/field_name.test.tsx
@@ -5,7 +5,7 @@
*/
import { mount } from 'enzyme';
-import * as React from 'react';
+import React from 'react';
import { mockBrowserFields } from '../../containers/source/mock';
import { TestProviders } from '../../mock';
diff --git a/x-pack/legacy/plugins/siem/public/components/fields_browser/fields_pane.test.tsx b/x-pack/legacy/plugins/siem/public/components/fields_browser/fields_pane.test.tsx
index 68ba2e2774314e..f3ec87a96d46b6 100644
--- a/x-pack/legacy/plugins/siem/public/components/fields_browser/fields_pane.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/fields_browser/fields_pane.test.tsx
@@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import * as React from 'react';
+import React from 'react';
import { mockBrowserFields } from '../../containers/source/mock';
import { TestProviders } from '../../mock';
diff --git a/x-pack/legacy/plugins/siem/public/components/fields_browser/fields_pane.tsx b/x-pack/legacy/plugins/siem/public/components/fields_browser/fields_pane.tsx
index 170cf324ca6d8a..fba6e22e4b21f5 100644
--- a/x-pack/legacy/plugins/siem/public/components/fields_browser/fields_pane.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/fields_browser/fields_pane.tsx
@@ -5,7 +5,7 @@
*/
import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
-import * as React from 'react';
+import React from 'react';
import styled from 'styled-components';
import { BrowserFields } from '../../containers/source';
diff --git a/x-pack/legacy/plugins/siem/public/components/fields_browser/header.test.tsx b/x-pack/legacy/plugins/siem/public/components/fields_browser/header.test.tsx
index 7e36a028961c48..42689065354d00 100644
--- a/x-pack/legacy/plugins/siem/public/components/fields_browser/header.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/fields_browser/header.test.tsx
@@ -5,7 +5,7 @@
*/
import { mount } from 'enzyme';
-import * as React from 'react';
+import React from 'react';
import { mockBrowserFields } from '../../containers/source/mock';
import { TestProviders } from '../../mock';
diff --git a/x-pack/legacy/plugins/siem/public/components/fields_browser/header.tsx b/x-pack/legacy/plugins/siem/public/components/fields_browser/header.tsx
index 8acb19970c268c..45b331f133e85e 100644
--- a/x-pack/legacy/plugins/siem/public/components/fields_browser/header.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/fields_browser/header.tsx
@@ -12,7 +12,7 @@ import {
EuiText,
EuiTitle,
} from '@elastic/eui';
-import * as React from 'react';
+import React from 'react';
import styled from 'styled-components';
import { BrowserFields } from '../../containers/source';
diff --git a/x-pack/legacy/plugins/siem/public/components/fields_browser/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/fields_browser/index.test.tsx
index 8a01a01b1daae8..24e4cd77b20d3f 100644
--- a/x-pack/legacy/plugins/siem/public/components/fields_browser/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/fields_browser/index.test.tsx
@@ -5,7 +5,7 @@
*/
import { mount } from 'enzyme';
-import * as React from 'react';
+import React from 'react';
import { mockBrowserFields } from '../../containers/source/mock';
import { TestProviders } from '../../mock';
diff --git a/x-pack/legacy/plugins/siem/public/components/fields_browser/index.tsx b/x-pack/legacy/plugins/siem/public/components/fields_browser/index.tsx
index 3958cd463d56ef..c8cde5fa02a519 100644
--- a/x-pack/legacy/plugins/siem/public/components/fields_browser/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/fields_browser/index.tsx
@@ -212,9 +212,7 @@ export const StatefulFieldsBrowserComponent = React.memo {
);
- expect(toJson(wrapper)).toMatchSnapshot();
+ expect(wrapper).toMatchSnapshot();
});
});
diff --git a/x-pack/legacy/plugins/siem/public/components/filters_global/filters_global.tsx b/x-pack/legacy/plugins/siem/public/components/filters_global/filters_global.tsx
index edf6f7f01ab2e9..b4d8c790002b2f 100644
--- a/x-pack/legacy/plugins/siem/public/components/filters_global/filters_global.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/filters_global/filters_global.tsx
@@ -13,7 +13,7 @@ import { gutterTimeline } from '../../lib/helpers';
const offsetChrome = 49;
-const disableSticky = 'screen and (max-width: ' + euiLightVars.euiBreakpoints.s + ')';
+const disableSticky = `screen and (max-width: ${euiLightVars.euiBreakpoints.s})`;
const disableStickyMq = window.matchMedia(disableSticky);
const Wrapper = styled.aside<{ isSticky?: boolean }>`
diff --git a/x-pack/legacy/plugins/siem/public/components/flow_controls/flow_direction_select.test.tsx b/x-pack/legacy/plugins/siem/public/components/flow_controls/flow_direction_select.test.tsx
index 47f0aef4b48060..f984b534c188d7 100644
--- a/x-pack/legacy/plugins/siem/public/components/flow_controls/flow_direction_select.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/flow_controls/flow_direction_select.test.tsx
@@ -5,8 +5,7 @@
*/
import { mount, shallow } from 'enzyme';
-import toJson from 'enzyme-to-json';
-import * as React from 'react';
+import React from 'react';
import { FlowDirection } from '../../graphql/types';
@@ -25,7 +24,7 @@ describe('Select Flow Direction', () => {
/>
);
- expect(toJson(wrapper)).toMatchSnapshot();
+ expect(wrapper).toMatchSnapshot();
});
});
diff --git a/x-pack/legacy/plugins/siem/public/components/flow_controls/flow_target_select.test.tsx b/x-pack/legacy/plugins/siem/public/components/flow_controls/flow_target_select.test.tsx
index b1f757841e54b1..373cc3cdc4a92d 100644
--- a/x-pack/legacy/plugins/siem/public/components/flow_controls/flow_target_select.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/flow_controls/flow_target_select.test.tsx
@@ -5,9 +5,8 @@
*/
import { mount, shallow } from 'enzyme';
-import toJson from 'enzyme-to-json';
import { clone } from 'lodash/fp';
-import * as React from 'react';
+import React from 'react';
import { ActionCreator } from 'typescript-fsa';
import { FlowDirection, FlowTarget } from '../../graphql/types';
@@ -31,7 +30,7 @@ describe('FlowTargetSelect Component', () => {
test('it renders the FlowTargetSelect', () => {
const wrapper = shallow();
- expect(toJson(wrapper)).toMatchSnapshot();
+ expect(wrapper).toMatchSnapshot();
});
});
diff --git a/x-pack/legacy/plugins/siem/public/components/flyout/button/index.tsx b/x-pack/legacy/plugins/siem/public/components/flyout/button/index.tsx
index fee4f25f9e2559..6ec5912872467f 100644
--- a/x-pack/legacy/plugins/siem/public/components/flyout/button/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/flyout/button/index.tsx
@@ -6,7 +6,7 @@
import { EuiNotificationBadge, EuiIcon, EuiButton } from '@elastic/eui';
import { rgba } from 'polished';
-import * as React from 'react';
+import React from 'react';
import styled from 'styled-components';
import { DroppableWrapper } from '../../drag_and_drop/droppable_wrapper';
diff --git a/x-pack/legacy/plugins/siem/public/components/flyout/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/flyout/index.test.tsx
index be7e8fac70bf53..83b842956e10ea 100644
--- a/x-pack/legacy/plugins/siem/public/components/flyout/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/flyout/index.test.tsx
@@ -5,9 +5,8 @@
*/
import { mount, shallow } from 'enzyme';
-import toJson from 'enzyme-to-json';
import { set } from 'lodash/fp';
-import * as React from 'react';
+import React from 'react';
import { ActionCreator } from 'typescript-fsa';
import { apolloClientObservable, mockGlobalState, TestProviders } from '../../mock';
@@ -35,7 +34,7 @@ describe('Flyout', () => {
/>
);
- expect(toJson(wrapper.find('Flyout'))).toMatchSnapshot();
+ expect(wrapper.find('Flyout')).toMatchSnapshot();
});
test('it renders the default flyout state as a button', () => {
diff --git a/x-pack/legacy/plugins/siem/public/components/flyout/index.tsx b/x-pack/legacy/plugins/siem/public/components/flyout/index.tsx
index 2d347830d5b1b5..528f02f0a845b7 100644
--- a/x-pack/legacy/plugins/siem/public/components/flyout/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/flyout/index.tsx
@@ -6,7 +6,7 @@
import { EuiBadge } from '@elastic/eui';
import { defaultTo, getOr } from 'lodash/fp';
-import * as React from 'react';
+import React from 'react';
import { connect } from 'react-redux';
import styled from 'styled-components';
import { ActionCreator } from 'typescript-fsa';
diff --git a/x-pack/legacy/plugins/siem/public/components/flyout/pane/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/flyout/pane/index.test.tsx
index 246261035508bd..365f99c6667b8f 100644
--- a/x-pack/legacy/plugins/siem/public/components/flyout/pane/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/flyout/pane/index.test.tsx
@@ -5,8 +5,7 @@
*/
import { mount, shallow } from 'enzyme';
-import toJson from 'enzyme-to-json';
-import * as React from 'react';
+import React from 'react';
import { TestProviders } from '../../../mock';
import { flyoutHeaderHeight } from '..';
@@ -16,8 +15,6 @@ const testFlyoutHeight = 980;
const testWidth = 640;
const usersViewing = ['elastic'];
-jest.mock('../../../lib/kibana');
-
describe('Pane', () => {
test('renders correctly against snapshot', () => {
const EmptyComponent = shallow(
@@ -34,7 +31,7 @@ describe('Pane', () => {
);
- expect(toJson(EmptyComponent.find('Pane'))).toMatchSnapshot();
+ expect(EmptyComponent.find('Pane')).toMatchSnapshot();
});
test('it should NOT let the flyout expand to take up the full width of the element that contains it', () => {
@@ -53,7 +50,7 @@ describe('Pane', () => {
);
- expect(wrapper.find('[data-test-subj="eui-flyout"]').get(0).props.maxWidth).toEqual('95%');
+ expect(wrapper.find('Resizable').get(0).props.maxWidth).toEqual('95vw');
});
test('it applies timeline styles to the EuiFlyout', () => {
diff --git a/x-pack/legacy/plugins/siem/public/components/flyout/pane/index.tsx b/x-pack/legacy/plugins/siem/public/components/flyout/pane/index.tsx
index f2f0cf4f980f33..00ac15092a6ec1 100644
--- a/x-pack/legacy/plugins/siem/public/components/flyout/pane/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/components/flyout/pane/index.tsx
@@ -5,13 +5,14 @@
*/
import { EuiButtonIcon, EuiFlyout, EuiFlyoutBody, EuiFlyoutHeader, EuiToolTip } from '@elastic/eui';
-import React, { useCallback } from 'react';
+import React, { useCallback, useState } from 'react';
import { connect } from 'react-redux';
import styled from 'styled-components';
import { ActionCreator } from 'typescript-fsa';
+import { Resizable, ResizeCallback } from 're-resizable';
+import { throttle } from 'lodash/fp';
-import { OnResize, Resizeable } from '../../resize_handle';
-import { TimelineResizeHandle } from '../../resize_handle/styled_handles';
+import { TimelineResizeHandle } from './timeline_resize_handle';
import { FlyoutHeader } from '../header';
import * as i18n from './translations';
@@ -41,10 +42,10 @@ interface DispatchProps {
type Props = OwnProps & DispatchProps;
-const EuiFlyoutContainer = styled.div<{ headerHeight: number; width: number }>`
+const EuiFlyoutContainer = styled.div<{ headerHeight: number }>`
.timeline-flyout {
min-width: 150px;
- width: ${({ width }) => `${width}px`};
+ width: auto;
}
.timeline-flyout-header {
align-items: center;
@@ -65,8 +66,6 @@ const EuiFlyoutContainer = styled.div<{ headerHeight: number; width: number }>`
}
`;
-EuiFlyoutContainer.displayName = 'EuiFlyoutContainer';
-
const FlyoutHeaderContainer = styled.div`
align-items: center;
display: flex;
@@ -75,88 +74,95 @@ const FlyoutHeaderContainer = styled.div`
width: 100%;
`;
-FlyoutHeaderContainer.displayName = 'FlyoutHeaderContainer';
-
// manually wrap the close button because EuiButtonIcon can't be a wrapped `styled`
const WrappedCloseButton = styled.div`
margin-right: 5px;
`;
-WrappedCloseButton.displayName = 'WrappedCloseButton';
-
-const FlyoutHeaderWithCloseButton = React.memo<{
+const FlyoutHeaderWithCloseButtonComponent: React.FC<{
onClose: () => void;
timelineId: string;
usersViewing: string[];
-}>(
- ({ onClose, timelineId, usersViewing }) => (
-
-
-
-
-
-
-
-
- ),
+}> = ({ onClose, timelineId, usersViewing }) => (
+
+
+
+
+
+
+
+
+);
+
+const FlyoutHeaderWithCloseButton = React.memo(
+ FlyoutHeaderWithCloseButtonComponent,
(prevProps, nextProps) =>
prevProps.timelineId === nextProps.timelineId &&
prevProps.usersViewing === nextProps.usersViewing
);
-FlyoutHeaderWithCloseButton.displayName = 'FlyoutHeaderWithCloseButton';
-
-const FlyoutPaneComponent = React.memo(
- ({
- applyDeltaToWidth,
- children,
- flyoutHeight,
- headerHeight,
- onClose,
- timelineId,
- usersViewing,
- width,
- }) => {
- const renderFlyout = useCallback(() => <>>, []);
-
- const onResize: OnResize = useCallback(
- ({ delta, id }) => {
- const bodyClientWidthPixels = document.body.clientWidth;
-
+const FlyoutPaneComponent: React.FC = ({
+ applyDeltaToWidth,
+ children,
+ flyoutHeight,
+ headerHeight,
+ onClose,
+ timelineId,
+ usersViewing,
+ width,
+}) => {
+ const [lastDelta, setLastDelta] = useState(0);
+ const onResizeStop: ResizeCallback = useCallback(
+ (e, direction, ref, delta) => {
+ const bodyClientWidthPixels = document.body.clientWidth;
+
+ if (delta.width) {
applyDeltaToWidth({
bodyClientWidthPixels,
- delta,
- id,
+ delta: -(delta.width - lastDelta),
+ id: timelineId,
maxWidthPercent,
minWidthPixels,
});
- },
- [applyDeltaToWidth, maxWidthPercent, minWidthPixels]
- );
- return (
-
-
- setLastDelta(0), [setLastDelta]);
+ const throttledResize = throttle(100, onResizeStop);
+
+ return (
+
+
+