;
-
-export interface PipedField {
- actionType: string;
- key: string;
- pipes: string[];
- value: string;
-}
-export interface PrepareFieldsForTransformArgs {
- defaultPipes: string[];
- mappings: ConnectorMappingsAttributes[];
- params: ServiceConnectorCaseParams;
-}
-export interface EntityInformation {
- createdAt: string;
- createdBy: ElasticUser;
- updatedAt: string | null;
- updatedBy: ElasticUser | null;
-}
-export interface TransformerArgs {
- date?: string;
- previousValue?: string;
- user?: string;
- value: string;
-}
-
-export type Transformer = (args: TransformerArgs) => TransformerArgs;
-export interface TransformFieldsArgs {
- currentIncident?: S;
- fields: PipedField[];
- params: P;
-}
-
-export const ServiceConnectorUserParams = rt.type({
- fullName: rt.union([rt.string, rt.null]),
- username: rt.string,
-});
-
-export const ServiceConnectorCommentParamsRt = rt.type({
- commentId: rt.string,
- comment: rt.string,
- createdAt: rt.string,
- createdBy: ServiceConnectorUserParams,
- updatedAt: rt.union([rt.string, rt.null]),
- updatedBy: rt.union([ServiceConnectorUserParams, rt.null]),
-});
-export const ServiceConnectorBasicCaseParamsRt = rt.type({
- comments: rt.union([rt.array(ServiceConnectorCommentParamsRt), rt.null]),
- createdAt: rt.string,
- createdBy: ServiceConnectorUserParams,
- description: rt.union([rt.string, rt.null]),
- externalId: rt.union([rt.string, rt.null]),
- savedObjectId: rt.string,
- title: rt.string,
- updatedAt: rt.union([rt.string, rt.null]),
- updatedBy: rt.union([ServiceConnectorUserParams, rt.null]),
-});
-
-export const ConnectorPartialFieldsRt = rt.partial({
- ...JiraFieldsRT.props,
- ...ResilientFieldsRT.props,
- ...ServiceNowFieldsRT.props,
-});
-
-export const ServiceConnectorCaseParamsRt = rt.intersection([
- ServiceConnectorBasicCaseParamsRt,
- ConnectorPartialFieldsRt,
-]);
-export const ServiceConnectorCaseResponseRt = rt.intersection([
- rt.type({
- title: rt.string,
- id: rt.string,
- pushedDate: rt.string,
- url: rt.string,
- }),
- rt.partial({
- comments: rt.array(
- rt.intersection([
- rt.type({
- commentId: rt.string,
- pushedDate: rt.string,
- }),
- rt.partial({ externalCommentId: rt.string }),
- ])
- ),
- }),
-]);
-export type ServiceConnectorBasicCaseParams = rt.TypeOf;
-export type ServiceConnectorCaseParams = rt.TypeOf;
-export type ServiceConnectorCaseResponse = rt.TypeOf;
-export type ServiceConnectorCommentParams = rt.TypeOf;
-
-export const PostPushRequestRt = rt.type({
- connector_type: rt.string,
- params: ServiceConnectorCaseParamsRt,
-});
-
-export type PostPushRequest = rt.TypeOf;
-
-export interface SimpleComment {
- comment: string;
- commentId: string;
-}
-
-export interface MapIncident {
- incident: ExternalServiceParams;
- comments: SimpleComment[];
-}
+export type GetFieldsResponse = rt.TypeOf;
diff --git a/x-pack/plugins/case/common/api/connectors/servicenow.ts b/x-pack/plugins/case/common/api/connectors/servicenow_itsm.ts
similarity index 76%
rename from x-pack/plugins/case/common/api/connectors/servicenow.ts
rename to x-pack/plugins/case/common/api/connectors/servicenow_itsm.ts
index fc4e8f9aa09a3..2e86a26971aaa 100644
--- a/x-pack/plugins/case/common/api/connectors/servicenow.ts
+++ b/x-pack/plugins/case/common/api/connectors/servicenow_itsm.ts
@@ -7,10 +7,10 @@
import * as rt from 'io-ts';
-export const ServiceNowFieldsRT = rt.type({
+export const ServiceNowITSMFieldsRT = rt.type({
impact: rt.union([rt.string, rt.null]),
severity: rt.union([rt.string, rt.null]),
urgency: rt.union([rt.string, rt.null]),
});
-export type ServiceNowFieldsType = rt.TypeOf;
+export type ServiceNowITSMFieldsType = rt.TypeOf;
diff --git a/x-pack/plugins/case/common/api/connectors/servicenow_sir.ts b/x-pack/plugins/case/common/api/connectors/servicenow_sir.ts
new file mode 100644
index 0000000000000..749abdea87437
--- /dev/null
+++ b/x-pack/plugins/case/common/api/connectors/servicenow_sir.ts
@@ -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
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import * as rt from 'io-ts';
+
+export const ServiceNowSIRFieldsRT = rt.type({
+ category: rt.union([rt.string, rt.null]),
+ destIp: rt.union([rt.boolean, rt.null]),
+ malwareHash: rt.union([rt.boolean, rt.null]),
+ malwareUrl: rt.union([rt.boolean, rt.null]),
+ priority: rt.union([rt.string, rt.null]),
+ sourceIp: rt.union([rt.boolean, rt.null]),
+ subcategory: rt.union([rt.string, rt.null]),
+});
+
+export type ServiceNowSIRFieldsType = rt.TypeOf;
diff --git a/x-pack/plugins/case/common/api/helpers.ts b/x-pack/plugins/case/common/api/helpers.ts
index f9de74f45de46..24c4756a1596b 100644
--- a/x-pack/plugins/case/common/api/helpers.ts
+++ b/x-pack/plugins/case/common/api/helpers.ts
@@ -10,7 +10,7 @@ import {
CASE_COMMENTS_URL,
CASE_USER_ACTIONS_URL,
CASE_COMMENT_DETAILS_URL,
- CASE_CONFIGURE_PUSH_URL,
+ CASE_PUSH_URL,
} from '../constants';
export const getCaseDetailsUrl = (id: string): string => {
@@ -28,6 +28,6 @@ export const getCaseCommentDetailsUrl = (caseId: string, commentId: string): str
export const getCaseUserActionUrl = (id: string): string => {
return CASE_USER_ACTIONS_URL.replace('{case_id}', id);
};
-export const getCaseConfigurePushUrl = (id: string): string => {
- return CASE_CONFIGURE_PUSH_URL.replace('{connector_id}', id);
+export const getCasePushUrl = (caseId: string, connectorId: string): string => {
+ return CASE_PUSH_URL.replace('{case_id}', caseId).replace('{connector_id}', connectorId);
};
diff --git a/x-pack/plugins/case/common/constants.ts b/x-pack/plugins/case/common/constants.ts
index 231ff9ef2dc4d..92dd2312f1ecf 100644
--- a/x-pack/plugins/case/common/constants.ts
+++ b/x-pack/plugins/case/common/constants.ts
@@ -15,10 +15,9 @@ export const CASES_URL = '/api/cases';
export const CASE_DETAILS_URL = `${CASES_URL}/{case_id}`;
export const CASE_CONFIGURE_URL = `${CASES_URL}/configure`;
export const CASE_CONFIGURE_CONNECTORS_URL = `${CASE_CONFIGURE_URL}/connectors`;
-export const CASE_CONFIGURE_CONNECTOR_DETAILS_URL = `${CASE_CONFIGURE_CONNECTORS_URL}/{connector_id}`;
-export const CASE_CONFIGURE_PUSH_URL = `${CASE_CONFIGURE_CONNECTOR_DETAILS_URL}/push`;
export const CASE_COMMENTS_URL = `${CASE_DETAILS_URL}/comments`;
export const CASE_COMMENT_DETAILS_URL = `${CASE_DETAILS_URL}/comments/{comment_id}`;
+export const CASE_PUSH_URL = `${CASE_DETAILS_URL}/connector/{connector_id}/_push`;
export const CASE_REPORTERS_URL = `${CASES_URL}/reporters`;
export const CASE_STATUS_URL = `${CASES_URL}/status`;
export const CASE_TAGS_URL = `${CASES_URL}/tags`;
@@ -30,12 +29,14 @@ export const CASE_USER_ACTIONS_URL = `${CASE_DETAILS_URL}/user_actions`;
export const ACTION_URL = '/api/actions';
export const ACTION_TYPES_URL = '/api/actions/list_action_types';
-export const SERVICENOW_ACTION_TYPE_ID = '.servicenow';
+export const SERVICENOW_ITSM_ACTION_TYPE_ID = '.servicenow';
+export const SERVICENOW_SIR_ACTION_TYPE_ID = '.servicenow-sir';
export const JIRA_ACTION_TYPE_ID = '.jira';
export const RESILIENT_ACTION_TYPE_ID = '.resilient';
export const SUPPORTED_CONNECTORS = [
- SERVICENOW_ACTION_TYPE_ID,
+ SERVICENOW_ITSM_ACTION_TYPE_ID,
+ SERVICENOW_SIR_ACTION_TYPE_ID,
JIRA_ACTION_TYPE_ID,
RESILIENT_ACTION_TYPE_ID,
];
diff --git a/x-pack/plugins/case/server/client/alerts/get.ts b/x-pack/plugins/case/server/client/alerts/get.ts
new file mode 100644
index 0000000000000..718dd327aa08c
--- /dev/null
+++ b/x-pack/plugins/case/server/client/alerts/get.ts
@@ -0,0 +1,31 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import Boom from '@hapi/boom';
+import { CaseClientGetAlerts, CaseClientFactoryArguments } from '../types';
+import { CaseClientGetAlertsResponse } from './types';
+
+export const get = ({ alertsService, request, context }: CaseClientFactoryArguments) => async ({
+ ids,
+}: CaseClientGetAlerts): Promise => {
+ const securitySolutionClient = context?.securitySolution?.getAppClient();
+ if (securitySolutionClient == null) {
+ throw Boom.notFound('securitySolutionClient client have not been found');
+ }
+
+ if (ids.length === 0) {
+ return [];
+ }
+
+ const index = securitySolutionClient.getSignalsIndex();
+ const alerts = await alertsService.getAlerts({ ids, index, request });
+ return alerts.hits.hits.map((alert) => ({
+ id: alert._id,
+ index: alert._index,
+ ...alert._source,
+ }));
+};
diff --git a/x-pack/plugins/maps_file_upload/server/index.js b/x-pack/plugins/case/server/client/alerts/types.ts
similarity index 59%
rename from x-pack/plugins/maps_file_upload/server/index.js
rename to x-pack/plugins/case/server/client/alerts/types.ts
index 4bf4e931c7eaa..7b9d4a8856f48 100644
--- a/x-pack/plugins/maps_file_upload/server/index.js
+++ b/x-pack/plugins/case/server/client/alerts/types.ts
@@ -5,8 +5,15 @@
* 2.0.
*/
-import { FileUploadPlugin } from './plugin';
+interface Alert {
+ id: string;
+ index: string;
+ destination?: {
+ ip: string;
+ };
+ source?: {
+ ip: string;
+ };
+}
-export * from './plugin';
-
-export const plugin = () => new FileUploadPlugin();
+export type CaseClientGetAlertsResponse = Alert[];
diff --git a/x-pack/plugins/case/server/client/cases/get.ts b/x-pack/plugins/case/server/client/cases/get.ts
new file mode 100644
index 0000000000000..c1901ccaae511
--- /dev/null
+++ b/x-pack/plugins/case/server/client/cases/get.ts
@@ -0,0 +1,45 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { flattenCaseSavedObject } from '../../routes/api/utils';
+import { CaseResponseRt, CaseResponse } from '../../../common/api';
+import { CaseClientGet, CaseClientFactoryArguments } from '../types';
+
+export const get = ({ savedObjectsClient, caseService }: CaseClientFactoryArguments) => async ({
+ id,
+ includeComments = false,
+}: CaseClientGet): Promise => {
+ const theCase = await caseService.getCase({
+ client: savedObjectsClient,
+ caseId: id,
+ });
+
+ if (!includeComments) {
+ return CaseResponseRt.encode(
+ flattenCaseSavedObject({
+ savedObject: theCase,
+ })
+ );
+ }
+
+ const theComments = await caseService.getAllCaseComments({
+ client: savedObjectsClient,
+ caseId: id,
+ options: {
+ sortField: 'created_at',
+ sortOrder: 'asc',
+ },
+ });
+
+ return CaseResponseRt.encode(
+ flattenCaseSavedObject({
+ savedObject: theCase,
+ comments: theComments.saved_objects,
+ totalComment: theComments.total,
+ })
+ );
+};
diff --git a/x-pack/plugins/case/server/client/cases/mock.ts b/x-pack/plugins/case/server/client/cases/mock.ts
new file mode 100644
index 0000000000000..57e2d4373a52b
--- /dev/null
+++ b/x-pack/plugins/case/server/client/cases/mock.ts
@@ -0,0 +1,191 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import {
+ CommentResponse,
+ CommentType,
+ ConnectorMappingsAttributes,
+ CaseUserActionsResponse,
+} from '../../../common/api';
+
+import { BasicParams } from './types';
+
+export const updateUser = {
+ updated_at: '2020-03-13T08:34:53.450Z',
+ updated_by: { full_name: 'Another User', username: 'another', email: 'elastic@elastic.co' },
+};
+
+const entity = {
+ createdAt: '2020-03-13T08:34:53.450Z',
+ createdBy: { full_name: 'Elastic User', username: 'elastic', email: 'elastic@elastic.co' },
+ updatedAt: null,
+ updatedBy: null,
+};
+
+export const comment: CommentResponse = {
+ id: 'mock-comment-1',
+ comment: 'Wow, good luck catching that bad meanie!',
+ type: CommentType.user as const,
+ created_at: '2019-11-25T21:55:00.177Z',
+ created_by: {
+ full_name: 'elastic',
+ email: 'testemail@elastic.co',
+ username: 'elastic',
+ },
+ pushed_at: null,
+ pushed_by: null,
+ updated_at: '2019-11-25T21:55:00.177Z',
+ updated_by: {
+ full_name: 'elastic',
+ email: 'testemail@elastic.co',
+ username: 'elastic',
+ },
+ version: 'WzEsMV0=',
+};
+
+export const commentAlert: CommentResponse = {
+ id: 'mock-comment-1',
+ alertId: 'alert-id-1',
+ index: 'alert-index-1',
+ type: CommentType.alert as const,
+ created_at: '2019-11-25T21:55:00.177Z',
+ created_by: {
+ full_name: 'elastic',
+ email: 'testemail@elastic.co',
+ username: 'elastic',
+ },
+ pushed_at: null,
+ pushed_by: null,
+ updated_at: '2019-11-25T21:55:00.177Z',
+ updated_by: {
+ full_name: 'elastic',
+ email: 'testemail@elastic.co',
+ username: 'elastic',
+ },
+ version: 'WzEsMV0=',
+};
+
+export const defaultPipes = ['informationCreated'];
+export const basicParams: BasicParams = {
+ description: 'a description',
+ title: 'a title',
+ ...entity,
+};
+
+export const mappings: ConnectorMappingsAttributes[] = [
+ {
+ source: 'title',
+ target: 'short_description',
+ action_type: 'overwrite',
+ },
+ {
+ source: 'description',
+ target: 'description',
+ action_type: 'append',
+ },
+ {
+ source: 'comments',
+ target: 'comments',
+ action_type: 'append',
+ },
+];
+
+export const userActions: CaseUserActionsResponse = [
+ {
+ action_field: ['description', 'status', 'tags', 'title', 'connector', 'settings'],
+ action: 'create',
+ action_at: '2021-02-03T17:41:03.771Z',
+ action_by: {
+ email: 'elastic@elastic.co',
+ full_name: 'Elastic',
+ username: 'elastic',
+ },
+ new_value:
+ '{"title":"Case SIR","tags":["sir"],"description":"testing sir","connector":{"id":"456","name":"ServiceNow SN","type":".servicenow-sir","fields":{"category":"Denial of Service","destIp":true,"malwareHash":true,"malwareUrl":true,"priority":"2","sourceIp":true,"subcategory":"45"}},"settings":{"syncAlerts":true}}',
+ old_value: null,
+ action_id: 'fd830c60-6646-11eb-a291-51bf6b175a53',
+ case_id: 'fcdedd20-6646-11eb-a291-51bf6b175a53',
+ comment_id: null,
+ },
+ {
+ action_field: ['pushed'],
+ action: 'push-to-service',
+ action_at: '2021-02-03T17:41:26.108Z',
+ action_by: {
+ email: 'elastic@elastic.co',
+ full_name: 'Elastic',
+ username: 'elastic',
+ },
+ new_value:
+ '{"pushed_at":"2021-02-03T17:41:26.108Z","pushed_by":{"username":"elastic","full_name":"Elastic","email":"elastic@elastic.co"},"connector_id":"456","connector_name":"ServiceNow SN","external_id":"external-id","external_title":"SIR0010037","external_url":"https://dev92273.service-now.com/nav_to.do?uri=sn_si_incident.do?sys_id=external-id"}',
+ old_value: null,
+ action_id: '0a801750-6647-11eb-a291-51bf6b175a53',
+ case_id: 'fcdedd20-6646-11eb-a291-51bf6b175a53',
+ comment_id: null,
+ },
+ {
+ action_field: ['comment'],
+ action: 'create',
+ action_at: '2021-02-03T17:44:21.067Z',
+ action_by: {
+ email: 'elastic@elastic.co',
+ full_name: 'Elastic',
+ username: 'elastic',
+ },
+ new_value: '{"type":"alert","alertId":"alert-id-1","index":".siem-signals-default-000008"}',
+ old_value: null,
+ action_id: '7373eb60-6647-11eb-a291-51bf6b175a53',
+ case_id: 'fcdedd20-6646-11eb-a291-51bf6b175a53',
+ comment_id: 'comment-alert-1',
+ },
+ {
+ action_field: ['comment'],
+ action: 'create',
+ action_at: '2021-02-03T17:44:33.078Z',
+ action_by: {
+ email: 'elastic@elastic.co',
+ full_name: 'Elastic',
+ username: 'elastic',
+ },
+ new_value: '{"type":"alert","alertId":"alert-id-2","index":".siem-signals-default-000008"}',
+ old_value: null,
+ action_id: '7abc6410-6647-11eb-a291-51bf6b175a53',
+ case_id: 'fcdedd20-6646-11eb-a291-51bf6b175a53',
+ comment_id: 'comment-alert-2',
+ },
+ {
+ action_field: ['pushed'],
+ action: 'push-to-service',
+ action_at: '2021-02-03T17:45:29.400Z',
+ action_by: {
+ email: 'elastic@elastic.co',
+ full_name: 'Elastic',
+ username: 'elastic',
+ },
+ new_value:
+ '{"pushed_at":"2021-02-03T17:45:29.400Z","pushed_by":{"username":"elastic","full_name":"Elastic","email":"elastic@elastic.co"},"connector_id":"456","connector_name":"ServiceNow SN","external_id":"external-id","external_title":"SIR0010037","external_url":"https://dev92273.service-now.com/nav_to.do?uri=sn_si_incident.do?sys_id=external-id"}',
+ old_value: null,
+ action_id: '9b91d8f0-6647-11eb-a291-51bf6b175a53',
+ case_id: 'fcdedd20-6646-11eb-a291-51bf6b175a53',
+ comment_id: null,
+ },
+ {
+ action_field: ['comment'],
+ action: 'create',
+ action_at: '2021-02-03T17:48:30.616Z',
+ action_by: {
+ email: 'elastic@elastic.co',
+ full_name: 'Elastic',
+ username: 'elastic',
+ },
+ new_value: '{"comment":"a comment!","type":"user"}',
+ old_value: null,
+ action_id: '0818e5e0-6648-11eb-a291-51bf6b175a53',
+ case_id: 'fcdedd20-6646-11eb-a291-51bf6b175a53',
+ comment_id: 'comment-user-1',
+ },
+];
diff --git a/x-pack/plugins/case/server/client/cases/push.ts b/x-pack/plugins/case/server/client/cases/push.ts
new file mode 100644
index 0000000000000..f329fb4d00d07
--- /dev/null
+++ b/x-pack/plugins/case/server/client/cases/push.ts
@@ -0,0 +1,266 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import Boom, { isBoom, Boom as BoomType } from '@hapi/boom';
+
+import { SavedObjectsBulkUpdateResponse, SavedObjectsUpdateResponse } from 'kibana/server';
+import { flattenCaseSavedObject } from '../../routes/api/utils';
+
+import {
+ ActionConnector,
+ CaseResponseRt,
+ CaseResponse,
+ CaseStatuses,
+ ExternalServiceResponse,
+ ESCaseAttributes,
+ CommentAttributes,
+} from '../../../common/api';
+import { buildCaseUserActionItem } from '../../services/user_actions/helpers';
+
+import { CaseClientPush, CaseClientFactoryArguments } from '../types';
+import { createIncident, getCommentContextFromAttributes, isCommentAlertType } from './utils';
+
+const createError = (e: Error | BoomType, message: string): Error | BoomType => {
+ if (isBoom(e)) {
+ e.message = message;
+ e.output.payload.message = message;
+ return e;
+ }
+
+ return Error(message);
+};
+
+export const push = ({
+ savedObjectsClient,
+ caseService,
+ caseConfigureService,
+ userActionService,
+ request,
+ response,
+}: CaseClientFactoryArguments) => async ({
+ actionsClient,
+ caseClient,
+ caseId,
+ connectorId,
+}: CaseClientPush): Promise => {
+ /* Start of push to external service */
+ let theCase;
+ let connector;
+ let userActions;
+ let alerts;
+ let connectorMappings;
+ let externalServiceIncident;
+
+ try {
+ [theCase, connector, userActions] = await Promise.all([
+ caseClient.get({ id: caseId, includeComments: true }),
+ actionsClient.get({ id: connectorId }),
+ caseClient.getUserActions({ caseId }),
+ ]);
+ } catch (e) {
+ const message = `Error getting case and/or connector and/or user actions: ${e.message}`;
+ throw createError(e, message);
+ }
+
+ // We need to change the logic when we support subcases
+ if (theCase?.status === CaseStatuses.closed) {
+ throw Boom.conflict(
+ `This case ${theCase.title} is closed. You can not pushed if the case is closed.`
+ );
+ }
+
+ try {
+ alerts = await caseClient.getAlerts({
+ ids: theCase?.comments?.filter(isCommentAlertType).map((comment) => comment.alertId) ?? [],
+ });
+ } catch (e) {
+ throw new Error(`Error getting alerts for case with id ${theCase.id}: ${e.message}`);
+ }
+
+ try {
+ connectorMappings = await caseClient.getMappings({
+ actionsClient,
+ caseClient,
+ connectorId: connector.id,
+ connectorType: connector.actionTypeId,
+ });
+ } catch (e) {
+ const message = `Error getting mapping for connector with id ${connector.id}: ${e.message}`;
+ throw createError(e, message);
+ }
+
+ try {
+ externalServiceIncident = await createIncident({
+ actionsClient,
+ theCase,
+ userActions,
+ connector: connector as ActionConnector,
+ mappings: connectorMappings,
+ alerts,
+ });
+ } catch (e) {
+ const message = `Error creating incident for case with id ${theCase.id}: ${e.message}`;
+ throw createError(e, message);
+ }
+
+ const pushRes = await actionsClient.execute({
+ actionId: connector?.id ?? '',
+ params: {
+ subAction: 'pushToService',
+ subActionParams: externalServiceIncident,
+ },
+ });
+
+ if (pushRes.status === 'error') {
+ throw Boom.failedDependency(
+ pushRes.serviceMessage ?? pushRes.message ?? 'Error pushing to service'
+ );
+ }
+
+ /* End of push to external service */
+
+ /* Start of update case with push information */
+ let user;
+ let myCase;
+ let myCaseConfigure;
+ let comments;
+
+ try {
+ [user, myCase, myCaseConfigure, comments] = await Promise.all([
+ caseService.getUser({ request, response }),
+ caseService.getCase({
+ client: savedObjectsClient,
+ caseId,
+ }),
+ caseConfigureService.find({ client: savedObjectsClient }),
+ caseService.getAllCaseComments({
+ client: savedObjectsClient,
+ caseId,
+ options: {
+ fields: [],
+ page: 1,
+ perPage: theCase?.totalComment ?? 0,
+ },
+ }),
+ ]);
+ } catch (e) {
+ const message = `Error getting user and/or case and/or case configuration and/or case comments: ${e.message}`;
+ throw createError(e, message);
+ }
+
+ // eslint-disable-next-line @typescript-eslint/naming-convention
+ const { username, full_name, email } = user;
+ const pushedDate = new Date().toISOString();
+ const externalServiceResponse = pushRes.data as ExternalServiceResponse;
+
+ const externalService = {
+ pushed_at: pushedDate,
+ pushed_by: { username, full_name, email },
+ connector_id: connector.id,
+ connector_name: connector.name,
+ external_id: externalServiceResponse.id,
+ external_title: externalServiceResponse.title,
+ external_url: externalServiceResponse.url,
+ };
+
+ let updatedCase: SavedObjectsUpdateResponse;
+ let updatedComments: SavedObjectsBulkUpdateResponse;
+
+ try {
+ [updatedCase, updatedComments] = await Promise.all([
+ caseService.patchCase({
+ client: savedObjectsClient,
+ caseId,
+ updatedAttributes: {
+ ...(myCaseConfigure.total > 0 &&
+ myCaseConfigure.saved_objects[0].attributes.closure_type === 'close-by-pushing'
+ ? {
+ status: CaseStatuses.closed,
+ closed_at: pushedDate,
+ closed_by: { email, full_name, username },
+ }
+ : {}),
+ external_service: externalService,
+ updated_at: pushedDate,
+ updated_by: { username, full_name, email },
+ },
+ version: myCase.version,
+ }),
+
+ caseService.patchComments({
+ client: savedObjectsClient,
+ comments: comments.saved_objects
+ .filter((comment) => comment.attributes.pushed_at == null)
+ .map((comment) => ({
+ commentId: comment.id,
+ updatedAttributes: {
+ pushed_at: pushedDate,
+ pushed_by: { username, full_name, email },
+ },
+ version: comment.version,
+ })),
+ }),
+
+ userActionService.postUserActions({
+ client: savedObjectsClient,
+ actions: [
+ ...(myCaseConfigure.total > 0 &&
+ myCaseConfigure.saved_objects[0].attributes.closure_type === 'close-by-pushing'
+ ? [
+ buildCaseUserActionItem({
+ action: 'update',
+ actionAt: pushedDate,
+ actionBy: { username, full_name, email },
+ caseId,
+ fields: ['status'],
+ newValue: CaseStatuses.closed,
+ oldValue: myCase.attributes.status,
+ }),
+ ]
+ : []),
+ buildCaseUserActionItem({
+ action: 'push-to-service',
+ actionAt: pushedDate,
+ actionBy: { username, full_name, email },
+ caseId,
+ fields: ['pushed'],
+ newValue: JSON.stringify(externalService),
+ }),
+ ],
+ }),
+ ]);
+ } catch (e) {
+ const message = `Error updating case and/or comments and/or creating user action: ${e.message}`;
+ throw createError(e, message);
+ }
+ /* End of update case with push information */
+
+ return CaseResponseRt.encode(
+ flattenCaseSavedObject({
+ savedObject: {
+ ...myCase,
+ ...updatedCase,
+ attributes: { ...myCase.attributes, ...updatedCase?.attributes },
+ references: myCase.references,
+ },
+ comments: comments.saved_objects.map((origComment) => {
+ const updatedComment = updatedComments.saved_objects.find((c) => c.id === origComment.id);
+ return {
+ ...origComment,
+ ...updatedComment,
+ attributes: {
+ ...origComment.attributes,
+ ...updatedComment?.attributes,
+ ...getCommentContextFromAttributes(origComment.attributes),
+ },
+ version: updatedComment?.version ?? origComment.version,
+ references: origComment?.references ?? [],
+ };
+ }),
+ })
+ );
+};
diff --git a/x-pack/plugins/case/server/client/cases/types.ts b/x-pack/plugins/case/server/client/cases/types.ts
new file mode 100644
index 0000000000000..f1d56e7132bd1
--- /dev/null
+++ b/x-pack/plugins/case/server/client/cases/types.ts
@@ -0,0 +1,81 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+/* eslint-disable @kbn/eslint/no-restricted-paths */
+import {
+ PushToServiceApiParams as JiraPushToServiceApiParams,
+ Incident as JiraIncident,
+} from '../../../../actions/server/builtin_action_types/jira/types';
+import {
+ PushToServiceApiParams as ResilientPushToServiceApiParams,
+ Incident as ResilientIncident,
+} from '../../../../actions/server/builtin_action_types/resilient/types';
+import {
+ PushToServiceApiParamsITSM as ServiceNowITSMPushToServiceApiParams,
+ PushToServiceApiParamsSIR as ServiceNowSIRPushToServiceApiParams,
+ ServiceNowITSMIncident,
+} from '../../../../actions/server/builtin_action_types/servicenow/types';
+import { CaseResponse, ConnectorMappingsAttributes } from '../../../common/api';
+
+export type Incident = JiraIncident | ResilientIncident | ServiceNowITSMIncident;
+export type PushToServiceApiParams =
+ | JiraPushToServiceApiParams
+ | ResilientPushToServiceApiParams
+ | ServiceNowITSMPushToServiceApiParams
+ | ServiceNowSIRPushToServiceApiParams;
+
+export type ExternalServiceParams = Record;
+
+export interface BasicParams {
+ title: CaseResponse['title'];
+ description: CaseResponse['description'];
+ createdAt: CaseResponse['created_at'];
+ createdBy: CaseResponse['created_by'];
+ updatedAt: CaseResponse['updated_at'];
+ updatedBy: CaseResponse['updated_by'];
+}
+
+export interface PipedField {
+ actionType: string;
+ key: string;
+ pipes: string[];
+ value: string;
+}
+export interface PrepareFieldsForTransformArgs {
+ defaultPipes: string[];
+ mappings: ConnectorMappingsAttributes[];
+ params: { title: string; description: string };
+}
+export interface EntityInformation {
+ createdAt: CaseResponse['created_at'];
+ createdBy: CaseResponse['created_by'];
+ updatedAt: CaseResponse['updated_at'];
+ updatedBy: CaseResponse['updated_by'];
+}
+export interface TransformerArgs {
+ date?: string;
+ previousValue?: string;
+ user?: string;
+ value: string;
+}
+
+export type Transformer = (args: TransformerArgs) => TransformerArgs;
+export interface TransformFieldsArgs {
+ currentIncident?: S;
+ fields: PipedField[];
+ params: P;
+}
+
+export interface ExternalServiceComment {
+ comment: string;
+ commentId: string;
+}
+
+export interface MapIncident {
+ incident: ExternalServiceParams;
+ comments: ExternalServiceComment[];
+}
diff --git a/x-pack/plugins/case/server/routes/api/cases/configure/utils.test.ts b/x-pack/plugins/case/server/client/cases/utils.test.ts
similarity index 52%
rename from x-pack/plugins/case/server/routes/api/cases/configure/utils.test.ts
rename to x-pack/plugins/case/server/client/cases/utils.test.ts
index 5114703c60963..dca2c34602678 100644
--- a/x-pack/plugins/case/server/routes/api/cases/configure/utils.test.ts
+++ b/x-pack/plugins/case/server/client/cases/utils.test.ts
@@ -5,34 +5,45 @@
* 2.0.
*/
+import { actionsClientMock } from '../../../../actions/server/actions_client.mock';
+import { flattenCaseSavedObject } from '../../routes/api/utils';
+import { mockCases } from '../../routes/api/__fixtures__';
+
+import { BasicParams, ExternalServiceParams, Incident } from './types';
+import {
+ comment as commentObj,
+ mappings,
+ defaultPipes,
+ basicParams,
+ userActions,
+ commentAlert,
+} from './mock';
+
import {
- mapIncident,
+ createIncident,
+ getLatestPushInfo,
prepareFieldsForTransformation,
- serviceFormatter,
transformComments,
transformers,
transformFields,
} from './utils';
-import { comment as commentObj, mappings, defaultPipes, params, updateUser } from './mock';
-import {
- ConnectorTypes,
- ExternalServiceParams,
- Incident,
- ServiceConnectorCaseParams,
-} from '../../../../../common/api/connectors';
-import { actionsClientMock } from '../../../../../../actions/server/actions_client.mock';
-import { mappings as mappingsMock } from '../../../../client/configure/mock';
-const formatComment = { commentId: commentObj.commentId, comment: commentObj.comment };
-const serviceNowParams = params[ConnectorTypes.servicenow] as ServiceConnectorCaseParams;
-describe('api/cases/configure/utils', () => {
+const formatComment = {
+ commentId: commentObj.id,
+ comment: 'Wow, good luck catching that bad meanie!',
+};
+
+const params = { ...basicParams };
+
+describe('utils', () => {
describe('prepareFieldsForTransformation', () => {
test('prepare fields with defaults', () => {
const res = prepareFieldsForTransformation({
defaultPipes,
- params: serviceNowParams,
+ params,
mappings,
});
+
expect(res).toEqual([
{
actionType: 'overwrite',
@@ -53,8 +64,9 @@ describe('api/cases/configure/utils', () => {
const res = prepareFieldsForTransformation({
defaultPipes: ['myTestPipe'],
mappings,
- params: serviceNowParams,
+ params,
});
+
expect(res).toEqual([
{
actionType: 'overwrite',
@@ -71,16 +83,17 @@ describe('api/cases/configure/utils', () => {
]);
});
});
+
describe('transformFields', () => {
test('transform fields for creation correctly', () => {
const fields = prepareFieldsForTransformation({
defaultPipes,
mappings,
- params: serviceNowParams,
+ params,
});
- const res = transformFields({
- params: serviceNowParams,
+ const res = transformFields({
+ params,
fields,
});
@@ -92,18 +105,19 @@ describe('api/cases/configure/utils', () => {
test('transform fields for update correctly', () => {
const fields = prepareFieldsForTransformation({
- params: serviceNowParams,
+ params,
mappings,
defaultPipes: ['informationUpdated'],
});
- const res = transformFields({
+ const res = transformFields({
params: {
- ...serviceNowParams,
+ ...params,
updatedAt: '2020-03-15T08:34:53.450Z',
updatedBy: {
username: 'anotherUser',
- fullName: 'Another User',
+ full_name: 'Another User',
+ email: 'elastic@elastic.co',
},
},
fields,
@@ -112,6 +126,7 @@ describe('api/cases/configure/utils', () => {
description: 'first description (created at 2020-03-13T08:34:53.450Z by Elastic User)',
},
});
+
expect(res).toEqual({
short_description: 'a title (updated at 2020-03-15T08:34:53.450Z by Another User)',
description:
@@ -121,13 +136,13 @@ describe('api/cases/configure/utils', () => {
test('add newline character to description', () => {
const fields = prepareFieldsForTransformation({
- params: serviceNowParams,
+ params,
mappings,
defaultPipes: ['informationUpdated'],
});
- const res = transformFields({
- params: serviceNowParams,
+ const res = transformFields({
+ params,
fields,
currentIncident: {
short_description: 'first title',
@@ -141,13 +156,13 @@ describe('api/cases/configure/utils', () => {
const fields = prepareFieldsForTransformation({
defaultPipes,
mappings,
- params: serviceNowParams,
+ params,
});
- const res = transformFields({
+ const res = transformFields({
params: {
- ...serviceNowParams,
- createdBy: { fullName: '', username: 'elastic' },
+ ...params,
+ createdBy: { full_name: '', username: 'elastic', email: 'elastic@elastic.co' },
},
fields,
});
@@ -162,14 +177,14 @@ describe('api/cases/configure/utils', () => {
const fields = prepareFieldsForTransformation({
defaultPipes: ['informationUpdated'],
mappings,
- params: serviceNowParams,
+ params,
});
- const res = transformFields({
+ const res = transformFields({
params: {
- ...serviceNowParams,
+ ...params,
updatedAt: '2020-03-15T08:34:53.450Z',
- updatedBy: { username: 'anotherUser', fullName: '' },
+ updatedBy: { username: 'anotherUser', full_name: '', email: 'elastic@elastic.co' },
},
fields,
});
@@ -180,6 +195,7 @@ describe('api/cases/configure/utils', () => {
});
});
});
+
describe('transformComments', () => {
test('transform creation comments', () => {
const comments = [commentObj];
@@ -187,7 +203,7 @@ describe('api/cases/configure/utils', () => {
expect(res).toEqual([
{
...formatComment,
- comment: `${formatComment.comment} (created at ${comments[0].createdAt} by ${comments[0].createdBy.fullName})`,
+ comment: `${formatComment.comment} (created at ${comments[0].created_at} by ${comments[0].created_by.full_name})`,
},
]);
});
@@ -196,14 +212,19 @@ describe('api/cases/configure/utils', () => {
const comments = [
{
...commentObj,
- ...updateUser,
+ updated_at: '2020-03-13T08:34:53.450Z',
+ updated_by: {
+ full_name: 'Another User',
+ username: 'another',
+ email: 'elastic@elastic.co',
+ },
},
];
const res = transformComments(comments, ['informationUpdated']);
expect(res).toEqual([
{
...formatComment,
- comment: `${formatComment.comment} (updated at ${updateUser.updatedAt} by ${updateUser.updatedBy.fullName})`,
+ comment: `${formatComment.comment} (updated at ${comments[0].updated_at} by ${comments[0].updated_by.full_name})`,
},
]);
});
@@ -214,19 +235,19 @@ describe('api/cases/configure/utils', () => {
expect(res).toEqual([
{
...formatComment,
- comment: `${formatComment.comment} (added at ${comments[0].createdAt} by ${comments[0].createdBy.fullName})`,
+ comment: `${formatComment.comment} (added at ${comments[0].created_at} by ${comments[0].created_by.full_name})`,
},
]);
});
test('transform comments without fullname', () => {
- const comments = [{ ...commentObj, createdBy: { username: commentObj.createdBy.username } }];
- // @ts-ignore testing no fullName
+ const comments = [{ ...commentObj, createdBy: { username: commentObj.created_by.username } }];
+ // @ts-ignore testing no full_name
const res = transformComments(comments, ['informationAdded']);
expect(res).toEqual([
{
...formatComment,
- comment: `${formatComment.comment} (added at ${comments[0].createdAt} by ${comments[0].createdBy.username})`,
+ comment: `${formatComment.comment} (added at ${comments[0].created_at} by ${comments[0].created_by.username})`,
},
]);
});
@@ -235,15 +256,15 @@ describe('api/cases/configure/utils', () => {
const comments = [
{
...commentObj,
- updatedAt: '2020-04-13T08:34:53.450Z',
- updatedBy: { fullName: 'Elastic2', username: 'elastic' },
+ updated_at: '2020-04-13T08:34:53.450Z',
+ updated_by: { full_name: 'Elastic2', username: 'elastic', email: 'elastic@elastic.co' },
},
];
const res = transformComments(comments, ['informationAdded']);
expect(res).toEqual([
{
...formatComment,
- comment: `${formatComment.comment} (added at ${comments[0].updatedAt} by ${comments[0].updatedBy.fullName})`,
+ comment: `${formatComment.comment} (added at ${comments[0].updated_at} by ${comments[0].updated_by.full_name})`,
},
]);
});
@@ -252,19 +273,20 @@ describe('api/cases/configure/utils', () => {
const comments = [
{
...commentObj,
- updatedAt: '2020-04-13T08:34:53.450Z',
- updatedBy: { fullName: '', username: 'elastic2' },
+ updated_at: '2020-04-13T08:34:53.450Z',
+ updated_by: { full_name: '', username: 'elastic2', email: 'elastic@elastic.co' },
},
];
const res = transformComments(comments, ['informationAdded']);
expect(res).toEqual([
{
...formatComment,
- comment: `${formatComment.comment} (added at ${comments[0].updatedAt} by ${comments[0].updatedBy.username})`,
+ comment: `${formatComment.comment} (added at ${comments[0].updated_at} by ${comments[0].updated_by.username})`,
},
]);
});
});
+
describe('transformers', () => {
const { informationCreated, informationUpdated, informationAdded, append } = transformers;
describe('informationCreated', () => {
@@ -389,142 +411,291 @@ describe('api/cases/configure/utils', () => {
});
});
});
- describe('mapIncident', () => {
+
+ describe('createIncident', () => {
let actionsMock = actionsClientMock.create();
- it('maps an external incident', async () => {
- const res = await mapIncident(
- actionsMock,
- '123',
- ConnectorTypes.servicenow,
- mappingsMock[ConnectorTypes.servicenow],
- serviceNowParams
- );
+ const theCase = {
+ ...flattenCaseSavedObject({
+ savedObject: mockCases[0],
+ }),
+ comments: [commentObj],
+ totalComments: 1,
+ };
+
+ const connector = {
+ id: '456',
+ actionTypeId: '.jira',
+ name: 'Connector without isCaseOwned',
+ config: {
+ apiUrl: 'https://elastic.jira.com',
+ },
+ isPreconfigured: false,
+ };
+
+ it('creates an external incident', async () => {
+ const res = await createIncident({
+ actionsClient: actionsMock,
+ theCase,
+ userActions: [],
+ connector,
+ mappings,
+ alerts: [],
+ });
+
expect(res).toEqual({
incident: {
- description: 'a description (created at 2020-03-13T08:34:53.450Z by Elastic User)',
+ priority: null,
+ labels: ['defacement'],
+ issueType: null,
+ parent: null,
+ short_description:
+ 'Super Bad Security Issue (created at 2019-11-25T21:54:48.952Z by elastic)',
+ description:
+ 'This is a brand new case of a bad meanie defacing data (created at 2019-11-25T21:54:48.952Z by elastic)',
externalId: null,
- impact: '3',
- severity: '1',
- short_description: 'a title (created at 2020-03-13T08:34:53.450Z by Elastic User)',
- urgency: '2',
},
- comments: [
+ comments: [],
+ });
+ });
+
+ it('it creates comments correctly', async () => {
+ const res = await createIncident({
+ actionsClient: actionsMock,
+ theCase: {
+ ...theCase,
+ comments: [{ ...commentObj, id: 'comment-user-1' }],
+ },
+ userActions,
+ connector,
+ mappings,
+ alerts: [],
+ });
+
+ expect(res.comments).toEqual([
+ {
+ comment:
+ 'Wow, good luck catching that bad meanie! (added at 2019-11-25T21:55:00.177Z by elastic)',
+ commentId: 'comment-user-1',
+ },
+ ]);
+ });
+
+ it('it does NOT creates comments when mapping is nothing', async () => {
+ const res = await createIncident({
+ actionsClient: actionsMock,
+ theCase: {
+ ...theCase,
+ comments: [{ ...commentObj, id: 'comment-user-1' }],
+ },
+ userActions,
+ connector,
+ mappings: [
+ mappings[0],
+ mappings[1],
{
- comment: 'first comment (added at 2020-03-13T08:34:53.450Z by Elastic User)',
- commentId: 'b5b4c4d0-574e-11ea-9e2e-21b90f8a9631',
+ source: 'comments',
+ target: 'comments',
+ action_type: 'nothing',
},
],
+ alerts: [],
});
+
+ expect(res.comments).toEqual([]);
});
- it('throws error if invalid service', async () => {
- await mapIncident(
- actionsMock,
- '123',
- 'invalid',
- mappingsMock[ConnectorTypes.servicenow],
- serviceNowParams
- ).catch((e) => {
- expect(e).not.toBeNull();
- expect(e).toEqual(new Error(`Invalid service`));
+
+ it('it creates comments of type alert correctly', async () => {
+ const res = await createIncident({
+ actionsClient: actionsMock,
+ theCase: {
+ ...theCase,
+ comments: [
+ { ...commentObj, id: 'comment-user-1' },
+ { ...commentAlert, id: 'comment-alert-1' },
+ { ...commentAlert, id: 'comment-alert-2' },
+ ],
+ },
+ // Remove second push
+ userActions: userActions.filter((item, index) => index !== 4),
+ connector,
+ mappings: [
+ ...mappings,
+ {
+ source: 'comments',
+ target: 'comments',
+ action_type: 'nothing',
+ },
+ ],
+ alerts: [],
});
+
+ expect(res.comments).toEqual([
+ {
+ comment:
+ 'Wow, good luck catching that bad meanie! (added at 2019-11-25T21:55:00.177Z by elastic)',
+ commentId: 'comment-user-1',
+ },
+ {
+ comment:
+ 'Alert with id alert-id-1 added to case (added at 2019-11-25T21:55:00.177Z by elastic)',
+ commentId: 'comment-alert-1',
+ },
+ {
+ comment:
+ 'Alert with id alert-id-1 added to case (added at 2019-11-25T21:55:00.177Z by elastic)',
+ commentId: 'comment-alert-2',
+ },
+ ]);
});
+
it('updates an existing incident', async () => {
const existingIncidentData = {
- description: 'fun description',
- impact: '3',
- severity: '3',
+ priority: null,
+ issueType: null,
+ parent: null,
short_description: 'fun title',
- urgency: '3',
+ description: 'fun description',
};
+
const execute = jest.fn().mockReturnValue(existingIncidentData);
actionsMock = { ...actionsMock, execute };
- const res = await mapIncident(
- actionsMock,
- '123',
- ConnectorTypes.servicenow,
- mappingsMock[ConnectorTypes.servicenow],
- { ...serviceNowParams, externalId: '123' }
- );
+
+ const res = await createIncident({
+ actionsClient: actionsMock,
+ theCase,
+ userActions,
+ connector,
+ mappings,
+ alerts: [],
+ });
+
expect(res).toEqual({
incident: {
- description: 'a description (updated at 2020-03-13T08:34:53.450Z by Elastic User)',
- externalId: '123',
- impact: '3',
- severity: '1',
- short_description: 'a title (updated at 2020-03-13T08:34:53.450Z by Elastic User)',
- urgency: '2',
+ priority: null,
+ labels: ['defacement'],
+ issueType: null,
+ parent: null,
+ description:
+ 'fun description \r\nThis is a brand new case of a bad meanie defacing data (updated at 2019-11-25T21:54:48.952Z by elastic)',
+ externalId: 'external-id',
+ short_description:
+ 'Super Bad Security Issue (updated at 2019-11-25T21:54:48.952Z by elastic)',
},
- comments: [
- {
- comment: 'first comment (added at 2020-03-13T08:34:53.450Z by Elastic User)',
- commentId: 'b5b4c4d0-574e-11ea-9e2e-21b90f8a9631',
- },
- ],
+ comments: [],
});
});
+
it('throws error when existing incident throws', async () => {
+ expect.assertions(2);
const execute = jest.fn().mockImplementation(() => {
throw new Error('exception');
});
+
actionsMock = { ...actionsMock, execute };
- await mapIncident(
- actionsMock,
- '123',
- ConnectorTypes.servicenow,
- mappingsMock[ConnectorTypes.servicenow],
- { ...serviceNowParams, externalId: '123' }
- ).catch((e) => {
+ createIncident({
+ actionsClient: actionsMock,
+ theCase,
+ userActions,
+ connector,
+ mappings,
+ alerts: [],
+ }).catch((e) => {
expect(e).not.toBeNull();
expect(e).toEqual(
new Error(
- `Retrieving Incident by id 123 from ServiceNow failed with exception: Error: exception`
+ `Retrieving Incident by id external-id from .jira failed with exception: Error: exception`
)
);
});
});
- });
- const connectors = [
- {
- name: ConnectorTypes.jira,
- result: {
- incident: {
- issueType: '10003',
- parent: '5002',
- priority: 'Highest',
- },
- thirdPartyName: 'Jira',
- },
- },
- {
- name: ConnectorTypes.resilient,
- result: {
- incident: {
- incidentTypes: ['10003'],
- severityCode: '1',
- },
- thirdPartyName: 'Resilient',
- },
- },
- {
- name: ConnectorTypes.servicenow,
- result: {
- incident: {
- impact: '3',
- severity: '1',
- urgency: '2',
- },
- thirdPartyName: 'ServiceNow',
- },
- },
- ];
- describe('serviceFormatter', () => {
- connectors.forEach((c) =>
- it(`formats ${c.name}`, () => {
- const caseParams = params[c.name] as ServiceConnectorCaseParams;
- const res = serviceFormatter(c.name, caseParams);
- expect(res).toEqual(c.result);
- })
- );
+ it('throws error if connector is not supported', async () => {
+ expect.assertions(2);
+ createIncident({
+ actionsClient: actionsMock,
+ theCase,
+ userActions,
+ connector: { ...connector, actionTypeId: 'not-supported' },
+ mappings,
+ alerts: [],
+ }).catch((e) => {
+ expect(e).not.toBeNull();
+ expect(e).toEqual(new Error('Invalid external service'));
+ });
+ });
+
+ describe('getLatestPushInfo', () => {
+ it('it returns the latest push information correctly', async () => {
+ const res = getLatestPushInfo('456', userActions);
+ expect(res).toEqual({
+ index: 4,
+ pushedInfo: {
+ connector_id: '456',
+ connector_name: 'ServiceNow SN',
+ external_id: 'external-id',
+ external_title: 'SIR0010037',
+ external_url:
+ 'https://dev92273.service-now.com/nav_to.do?uri=sn_si_incident.do?sys_id=external-id',
+ pushed_at: '2021-02-03T17:45:29.400Z',
+ pushed_by: {
+ email: 'elastic@elastic.co',
+ full_name: 'Elastic',
+ username: 'elastic',
+ },
+ },
+ });
+ });
+
+ it('it returns null when there are not actions', async () => {
+ const res = getLatestPushInfo('456', []);
+ expect(res).toBe(null);
+ });
+
+ it('it returns null when there are no push user action', async () => {
+ const res = getLatestPushInfo('456', [userActions[0]]);
+ expect(res).toBe(null);
+ });
+
+ it('it returns the correct push information when with multiple push on different connectors', async () => {
+ const res = getLatestPushInfo('456', [
+ ...userActions.slice(0, 3),
+ {
+ action_field: ['pushed'],
+ action: 'push-to-service',
+ action_at: '2021-02-03T17:45:29.400Z',
+ action_by: {
+ email: 'elastic@elastic.co',
+ full_name: 'Elastic',
+ username: 'elastic',
+ },
+ new_value:
+ // The connector id is 123
+ '{"pushed_at":"2021-02-03T17:45:29.400Z","pushed_by":{"username":"elastic","full_name":"Elastic","email":"elastic@elastic.co"},"connector_id":"123","connector_name":"ServiceNow SN","external_id":"external-id","external_title":"SIR0010037","external_url":"https://dev92273.service-now.com/nav_to.do?uri=sn_si_incident.do?sys_id=external-id"}',
+ old_value: null,
+ action_id: '9b91d8f0-6647-11eb-a291-51bf6b175a53',
+ case_id: 'fcdedd20-6646-11eb-a291-51bf6b175a53',
+ comment_id: null,
+ },
+ ]);
+
+ expect(res).toEqual({
+ index: 1,
+ pushedInfo: {
+ connector_id: '456',
+ connector_name: 'ServiceNow SN',
+ external_id: 'external-id',
+ external_title: 'SIR0010037',
+ external_url:
+ 'https://dev92273.service-now.com/nav_to.do?uri=sn_si_incident.do?sys_id=external-id',
+ pushed_at: '2021-02-03T17:41:26.108Z',
+ pushed_by: {
+ email: 'elastic@elastic.co',
+ full_name: 'Elastic',
+ username: 'elastic',
+ },
+ },
+ });
+ });
+ });
});
});
diff --git a/x-pack/plugins/case/server/routes/api/cases/configure/utils.ts b/x-pack/plugins/case/server/client/cases/utils.ts
similarity index 50%
rename from x-pack/plugins/case/server/routes/api/cases/configure/utils.ts
rename to x-pack/plugins/case/server/client/cases/utils.ts
index 01a1a580bd78f..6974fd4ffa288 100644
--- a/x-pack/plugins/case/server/routes/api/cases/configure/utils.ts
+++ b/x-pack/plugins/case/server/client/cases/utils.ts
@@ -8,46 +8,118 @@
import { i18n } from '@kbn/i18n';
import { flow } from 'lodash';
import {
- ServiceConnectorCaseParams,
- ServiceConnectorCommentParams,
+ ActionConnector,
+ CaseResponse,
+ CaseFullExternalService,
+ CaseUserActionsResponse,
+ CommentResponse,
+ CommentResponseAlertsType,
+ CommentType,
ConnectorMappingsAttributes,
ConnectorTypes,
+ CommentAttributes,
+ CommentRequestUserType,
+ CommentRequestAlertType,
+} from '../../../common/api';
+import { ActionsClient } from '../../../../actions/server';
+import { externalServiceFormatters, FormatterConnectorTypes } from '../../connectors';
+import { CaseClientGetAlertsResponse } from '../../client/alerts/types';
+import {
+ BasicParams,
EntityInformation,
ExternalServiceParams,
+ ExternalServiceComment,
Incident,
- JiraPushToServiceApiParams,
MapIncident,
PipedField,
PrepareFieldsForTransformArgs,
PushToServiceApiParams,
- ResilientPushToServiceApiParams,
- ServiceNowITSMPushToServiceApiParams,
- SimpleComment,
Transformer,
TransformerArgs,
TransformFieldsArgs,
-} from '../../../../../common/api';
-import { ActionsClient } from '../../../../../../actions/server';
-export const mapIncident = async (
- actionsClient: ActionsClient,
+} from './types';
+
+export const getLatestPushInfo = (
connectorId: string,
- connectorType: string,
- mappings: ConnectorMappingsAttributes[],
- params: ServiceConnectorCaseParams
-): Promise => {
- const { comments: caseComments, externalId } = params;
+ userActions: CaseUserActionsResponse
+): { index: number; pushedInfo: CaseFullExternalService } | null => {
+ for (const [index, action] of [...userActions].reverse().entries()) {
+ if (action.action === 'push-to-service' && action.new_value)
+ try {
+ const pushedInfo = JSON.parse(action.new_value);
+ if (pushedInfo.connector_id === connectorId) {
+ // We returned the index of the element in the userActions array.
+ // As we traverse the userActions in reverse we need to calculate the index of a normal traversal
+ return { index: userActions.length - index - 1, pushedInfo };
+ }
+ } catch (e) {
+ // Silence JSON parse errors
+ }
+ }
+
+ return null;
+};
+
+const isConnectorSupported = (connectorId: string): connectorId is FormatterConnectorTypes =>
+ Object.values(ConnectorTypes).includes(connectorId as ConnectorTypes);
+
+const getCommentContent = (comment: CommentResponse): string => {
+ if (comment.type === CommentType.user) {
+ return comment.comment;
+ } else if (comment.type === CommentType.alert) {
+ return `Alert with id ${comment.alertId} added to case`;
+ }
+
+ return '';
+};
+
+interface CreateIncidentArgs {
+ actionsClient: ActionsClient;
+ theCase: CaseResponse;
+ userActions: CaseUserActionsResponse;
+ connector: ActionConnector;
+ mappings: ConnectorMappingsAttributes[];
+ alerts: CaseClientGetAlertsResponse;
+}
+
+export const createIncident = async ({
+ actionsClient,
+ theCase,
+ userActions,
+ connector,
+ mappings,
+ alerts,
+}: CreateIncidentArgs): Promise => {
+ const {
+ comments: caseComments,
+ title,
+ description,
+ created_at: createdAt,
+ created_by: createdBy,
+ updated_at: updatedAt,
+ updated_by: updatedBy,
+ } = theCase;
+
+ if (!isConnectorSupported(connector.actionTypeId)) {
+ throw new Error('Invalid external service');
+ }
+
+ const params = { title, description, createdAt, createdBy, updatedAt, updatedBy };
+ const latestPushInfo = getLatestPushInfo(connector.id, userActions);
+ const externalId = latestPushInfo?.pushedInfo?.external_id ?? null;
const defaultPipes = externalId ? ['informationUpdated'] : ['informationCreated'];
let currentIncident: ExternalServiceParams | undefined;
- const service = serviceFormatter(connectorType, params);
- if (service == null) {
- throw new Error(`Invalid service`);
- }
- const thirdPartyName = service.thirdPartyName;
- let incident: Partial = service.incident;
+
+ const externalServiceFields = externalServiceFormatters[connector.actionTypeId].format(
+ theCase,
+ alerts
+ );
+ let incident: Partial = { ...externalServiceFields };
+
if (externalId) {
try {
currentIncident = ((await actionsClient.execute({
- actionId: connectorId,
+ actionId: connector.id,
params: {
subAction: 'getIncident',
subActionParams: { externalId },
@@ -55,80 +127,56 @@ export const mapIncident = async (
})) as unknown) as ExternalServiceParams | undefined;
} catch (ex) {
throw new Error(
- `Retrieving Incident by id ${externalId} from ${thirdPartyName} failed with exception: ${ex}`
+ `Retrieving Incident by id ${externalId} from ${connector.actionTypeId} failed with exception: ${ex}`
);
}
}
+
const fields = prepareFieldsForTransformation({
defaultPipes,
mappings,
params,
});
- const transformedFields = transformFields<
- ServiceConnectorCaseParams,
- ExternalServiceParams,
- Incident
- >({
+
+ const transformedFields = transformFields({
params,
fields,
currentIncident,
});
+
incident = { ...incident, ...transformedFields, externalId };
- let comments: SimpleComment[] = [];
- if (caseComments && Array.isArray(caseComments) && caseComments.length > 0) {
+
+ const commentsIdsToBeUpdated = new Set(
+ userActions
+ .slice(latestPushInfo?.index ?? 0)
+ .filter(
+ (action, index) =>
+ Array.isArray(action.action_field) && action.action_field[0] === 'comment'
+ )
+ .map((action) => action.comment_id)
+ );
+ const commentsToBeUpdated = caseComments?.filter((comment) =>
+ commentsIdsToBeUpdated.has(comment.id)
+ );
+
+ let comments: ExternalServiceComment[] = [];
+ if (commentsToBeUpdated && Array.isArray(commentsToBeUpdated) && commentsToBeUpdated.length > 0) {
const commentsMapping = mappings.find((m) => m.source === 'comments');
if (commentsMapping?.action_type !== 'nothing') {
- comments = transformComments(caseComments, ['informationAdded']);
+ comments = transformComments(commentsToBeUpdated, ['informationAdded']);
}
}
return { incident, comments };
};
-export const serviceFormatter = (
- connectorType: string,
- params: unknown
-): { thirdPartyName: string; incident: Partial } | null => {
- switch (connectorType) {
- case ConnectorTypes.jira:
- const {
- priority,
- labels,
- issueType,
- parent,
- } = params as JiraPushToServiceApiParams['incident'];
- return {
- incident: { priority, labels, issueType, parent },
- thirdPartyName: 'Jira',
- };
- case ConnectorTypes.resilient:
- const { incidentTypes, severityCode } = params as ResilientPushToServiceApiParams['incident'];
- return {
- incident: { incidentTypes, severityCode },
- thirdPartyName: 'Resilient',
- };
- case ConnectorTypes.servicenow:
- const {
- severity,
- urgency,
- impact,
- } = params as ServiceNowITSMPushToServiceApiParams['incident'];
- return {
- incident: { severity, urgency, impact },
- thirdPartyName: 'ServiceNow',
- };
- default:
- return null;
- }
-};
-
export const getEntity = (entity: EntityInformation): string =>
(entity.updatedBy != null
- ? entity.updatedBy.fullName
- ? entity.updatedBy.fullName
+ ? entity.updatedBy.full_name
+ ? entity.updatedBy.full_name
: entity.updatedBy.username
: entity.createdBy != null
- ? entity.createdBy.fullName
- ? entity.createdBy.fullName
+ ? entity.createdBy.full_name
+ ? entity.createdBy.full_name
: entity.createdBy.username
: '') ?? '';
@@ -160,6 +208,7 @@ export const FIELD_INFORMATION = (
});
}
};
+
export const transformers: Record = {
informationCreated: ({ value, date, user, ...rest }: TransformerArgs): TransformerArgs => ({
value: `${value} ${FIELD_INFORMATION('create', date, user)}`,
@@ -178,6 +227,7 @@ export const transformers: Record = {
...rest,
}),
};
+
export const prepareFieldsForTransformation = ({
defaultPipes,
mappings,
@@ -226,14 +276,46 @@ export const transformFields = <
};
export const transformComments = (
- comments: ServiceConnectorCommentParams[],
+ comments: CaseResponse['comments'] = [],
pipes: string[]
-): SimpleComment[] =>
+): ExternalServiceComment[] =>
comments.map((c) => ({
comment: flow(...pipes.map((p) => transformers[p]))({
- value: c.comment,
- date: c.updatedAt ?? c.createdAt,
- user: getEntity(c),
+ value: getCommentContent(c),
+ date: c.updated_at ?? c.created_at,
+ user: getEntity({
+ createdAt: c.created_at,
+ createdBy: c.created_by,
+ updatedAt: c.updated_at,
+ updatedBy: c.updated_by,
+ }),
}).value,
- commentId: c.commentId,
+ commentId: c.id,
}));
+
+export const isCommentAlertType = (
+ comment: CommentResponse
+): comment is CommentResponseAlertsType => comment.type === CommentType.alert;
+
+export const getCommentContextFromAttributes = (
+ attributes: CommentAttributes
+): CommentRequestUserType | CommentRequestAlertType => {
+ switch (attributes.type) {
+ case CommentType.user:
+ return {
+ type: CommentType.user,
+ comment: attributes.comment,
+ };
+ case CommentType.alert:
+ return {
+ type: CommentType.alert,
+ alertId: attributes.alertId,
+ index: attributes.index,
+ };
+ default:
+ return {
+ type: CommentType.user,
+ comment: '',
+ };
+ }
+};
diff --git a/x-pack/plugins/case/server/client/configure/mock.ts b/x-pack/plugins/case/server/client/configure/mock.ts
index 46df0a7ac6756..4d0c384e23e27 100644
--- a/x-pack/plugins/case/server/client/configure/mock.ts
+++ b/x-pack/plugins/case/server/client/configure/mock.ts
@@ -70,7 +70,7 @@ export const mappings: TestMappings = {
action_type: 'append',
},
],
- [ConnectorTypes.servicenow]: [
+ [ConnectorTypes.serviceNowITSM]: [
{
source: 'title',
target: 'short_description',
@@ -611,7 +611,7 @@ export const formatFieldsTestData: FormatFieldsTestData[] = [
{ id: 'upon_reject', name: 'Upon reject', required: false, type: 'text' },
],
fields: serviceNowFields,
- type: ConnectorTypes.servicenow,
+ type: ConnectorTypes.serviceNowITSM,
},
];
export const mockGetFieldsResponse = {
diff --git a/x-pack/plugins/case/server/client/configure/utils.ts b/x-pack/plugins/case/server/client/configure/utils.ts
index 2fc9e3d17801c..7e91c2ae5a4d7 100644
--- a/x-pack/plugins/case/server/client/configure/utils.ts
+++ b/x-pack/plugins/case/server/client/configure/utils.ts
@@ -70,7 +70,9 @@ export const formatFields = (theData: unknown, theType: string): ConnectorField[
return normalizeJiraFields(theData as JiraGetFieldsResponse);
case ConnectorTypes.resilient:
return normalizeResilientFields(theData as ResilientGetFieldsResponse);
- case ConnectorTypes.servicenow:
+ case ConnectorTypes.serviceNowITSM:
+ return normalizeServiceNowFields(theData as ServiceNowGetFieldsResponse);
+ case ConnectorTypes.serviceNowSIR:
return normalizeServiceNowFields(theData as ServiceNowGetFieldsResponse);
default:
return [];
@@ -97,10 +99,14 @@ const getPreferredFields = (theType: string) => {
} else if (theType === ConnectorTypes.resilient) {
title = 'name';
description = 'description';
- } else if (theType === ConnectorTypes.servicenow) {
+ } else if (
+ theType === ConnectorTypes.serviceNowITSM ||
+ theType === ConnectorTypes.serviceNowSIR
+ ) {
title = 'short_description';
description = 'description';
}
+
return { title, description };
};
diff --git a/x-pack/plugins/case/server/client/index.test.ts b/x-pack/plugins/case/server/client/index.test.ts
index 095dc5102b720..4daa4d1c0bd8b 100644
--- a/x-pack/plugins/case/server/client/index.test.ts
+++ b/x-pack/plugins/case/server/client/index.test.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import { KibanaRequest } from 'kibana/server';
+import { KibanaRequest, kibanaResponseFactory } from '../../../../../src/core/server';
import { savedObjectsClientMock } from '../../../../../src/core/server/mocks';
import { createCaseClient } from '.';
import {
@@ -17,29 +17,48 @@ import {
} from '../services/mocks';
import { create } from './cases/create';
+import { get } from './cases/get';
import { update } from './cases/update';
+import { push } from './cases/push';
import { addComment } from './comments/add';
+import { getFields } from './configure/get_fields';
+import { getMappings } from './configure/get_mappings';
import { updateAlertsStatus } from './alerts/update_status';
+import { get as getUserActions } from './user_actions/get';
+import { get as getAlerts } from './alerts/get';
import type { CasesRequestHandlerContext } from '../types';
jest.mock('./cases/create');
jest.mock('./cases/update');
+jest.mock('./cases/get');
+jest.mock('./cases/push');
jest.mock('./comments/add');
jest.mock('./alerts/update_status');
+jest.mock('./alerts/get');
+jest.mock('./user_actions/get');
+jest.mock('./configure/get_fields');
+jest.mock('./configure/get_mappings');
const caseConfigureService = createConfigureServiceMock();
const alertsService = createAlertServiceMock();
const caseService = createCaseServiceMock();
const connectorMappingsService = connectorMappingsServiceMock();
const request = {} as KibanaRequest;
+const response = kibanaResponseFactory;
const savedObjectsClient = savedObjectsClientMock.create();
const userActionService = createUserActionServiceMock();
const context = {} as CasesRequestHandlerContext;
const createMock = create as jest.Mock;
+const getMock = get as jest.Mock;
const updateMock = update as jest.Mock;
+const pushMock = push as jest.Mock;
const addCommentMock = addComment as jest.Mock;
const updateAlertsStatusMock = updateAlertsStatus as jest.Mock;
+const getAlertsStatusMock = getAlerts as jest.Mock;
+const getFieldsMock = getFields as jest.Mock;
+const getMappingsMock = getMappings as jest.Mock;
+const getUserActionsMock = getUserActions as jest.Mock;
describe('createCaseClient()', () => {
test('it creates the client correctly', async () => {
@@ -50,49 +69,34 @@ describe('createCaseClient()', () => {
connectorMappingsService,
context,
request,
+ response,
savedObjectsClient,
userActionService,
});
- expect(createMock).toHaveBeenCalledWith({
- alertsService,
- caseConfigureService,
- caseService,
- connectorMappingsService,
- request,
- savedObjectsClient,
- userActionService,
- });
-
- expect(updateMock).toHaveBeenCalledWith({
- alertsService,
- caseConfigureService,
- caseService,
- connectorMappingsService,
- request,
- savedObjectsClient,
- userActionService,
- });
-
- expect(addCommentMock).toHaveBeenCalledWith({
- alertsService,
- caseConfigureService,
- caseService,
- connectorMappingsService,
- request,
- savedObjectsClient,
- userActionService,
- });
-
- expect(updateAlertsStatusMock).toHaveBeenCalledWith({
- alertsService,
- caseConfigureService,
- caseService,
- connectorMappingsService,
- context,
- request,
- savedObjectsClient,
- userActionService,
- });
+ [
+ createMock,
+ getMock,
+ updateMock,
+ pushMock,
+ addCommentMock,
+ updateAlertsStatusMock,
+ getAlertsStatusMock,
+ getFieldsMock,
+ getMappingsMock,
+ getUserActionsMock,
+ ].forEach((method) =>
+ expect(method).toHaveBeenCalledWith({
+ caseConfigureService,
+ caseService,
+ connectorMappingsService,
+ request,
+ response,
+ savedObjectsClient,
+ userActionService,
+ alertsService,
+ context,
+ })
+ );
});
});
diff --git a/x-pack/plugins/case/server/client/index.ts b/x-pack/plugins/case/server/client/index.ts
index 1b9d3ce7ecb08..e15b9fc766562 100644
--- a/x-pack/plugins/case/server/client/index.ts
+++ b/x-pack/plugins/case/server/client/index.ts
@@ -5,73 +5,41 @@
* 2.0.
*/
-import { CaseClientFactoryArguments, CaseClient } from './types';
+import {
+ CaseClientFactoryArguments,
+ CaseClient,
+ CaseClientFactoryMethods,
+ CaseClientMethods,
+} from './types';
import { create } from './cases/create';
+import { get } from './cases/get';
import { update } from './cases/update';
+import { push } from './cases/push';
import { addComment } from './comments/add';
import { getFields } from './configure/get_fields';
import { getMappings } from './configure/get_mappings';
import { updateAlertsStatus } from './alerts/update_status';
+import { get as getUserActions } from './user_actions/get';
+import { get as getAlerts } from './alerts/get';
export { CaseClient } from './types';
-export const createCaseClient = ({
- caseConfigureService,
- caseService,
- connectorMappingsService,
- request,
- savedObjectsClient,
- userActionService,
- alertsService,
- context,
-}: CaseClientFactoryArguments): CaseClient => {
- return {
- create: create({
- alertsService,
- caseConfigureService,
- caseService,
- connectorMappingsService,
- request,
- savedObjectsClient,
- userActionService,
- }),
- update: update({
- alertsService,
- caseConfigureService,
- caseService,
- connectorMappingsService,
- request,
- savedObjectsClient,
- userActionService,
- }),
- addComment: addComment({
- alertsService,
- caseConfigureService,
- caseService,
- connectorMappingsService,
- request,
- savedObjectsClient,
- userActionService,
- }),
- getFields: getFields(),
- getMappings: getMappings({
- alertsService,
- caseConfigureService,
- caseService,
- connectorMappingsService,
- request,
- savedObjectsClient,
- userActionService,
- }),
- updateAlertsStatus: updateAlertsStatus({
- alertsService,
- caseConfigureService,
- caseService,
- connectorMappingsService,
- context,
- request,
- savedObjectsClient,
- userActionService,
- }),
+export const createCaseClient = (args: CaseClientFactoryArguments): CaseClient => {
+ const methods: CaseClientFactoryMethods = {
+ create,
+ get,
+ update,
+ push,
+ addComment,
+ getAlerts,
+ getFields,
+ getMappings,
+ getUserActions,
+ updateAlertsStatus,
};
+
+ return (Object.keys(methods) as CaseClientMethods[]).reduce((client, method) => {
+ client[method] = methods[method](args);
+ return client;
+ }, {} as CaseClient);
};
diff --git a/x-pack/plugins/case/server/client/mocks.ts b/x-pack/plugins/case/server/client/mocks.ts
index 0d7f3972e58e7..b2a07e36b3aed 100644
--- a/x-pack/plugins/case/server/client/mocks.ts
+++ b/x-pack/plugins/case/server/client/mocks.ts
@@ -6,9 +6,9 @@
*/
import { omit } from 'lodash/fp';
-import { KibanaRequest } from 'kibana/server';
+// eslint-disable-next-line @kbn/eslint/no-restricted-paths
+import { KibanaRequest, kibanaResponseFactory } from '../../../../../src/core/server/http';
import { loggingSystemMock } from '../../../../../src/core/server/mocks';
-import { actionsClientMock } from '../../../actions/server/mocks';
import {
AlertServiceContract,
CaseConfigureService,
@@ -17,17 +17,20 @@ import {
ConnectorMappingsService,
} from '../services';
import { CaseClient } from './types';
-import { authenticationMock } from '../routes/api/__fixtures__';
+import { authenticationMock, createActionsClient } from '../routes/api/__fixtures__';
import { createCaseClient } from '.';
-import { getActions } from '../routes/api/__mocks__/request_responses';
import type { CasesRequestHandlerContext } from '../types';
export type CaseClientMock = jest.Mocked;
export const createCaseClientMock = (): CaseClientMock => ({
addComment: jest.fn(),
create: jest.fn(),
+ get: jest.fn(),
+ push: jest.fn(),
+ getAlerts: jest.fn(),
getFields: jest.fn(),
getMappings: jest.fn(),
+ getUserActions: jest.fn(),
update: jest.fn(),
updateAlertsStatus: jest.fn(),
});
@@ -47,10 +50,10 @@ export const createCaseClientWithMockSavedObjectsClient = async ({
alertsService: jest.Mocked;
};
}> => {
- const actionsMock = actionsClientMock.create();
- actionsMock.getAll.mockImplementation(() => Promise.resolve(getActions()));
+ const actionsMock = createActionsClient();
const log = loggingSystemMock.create().get('case');
const request = {} as KibanaRequest;
+ const response = kibanaResponseFactory;
const caseServicePlugin = new CaseService(log);
const caseConfigureServicePlugin = new CaseConfigureService(log);
@@ -63,11 +66,15 @@ export const createCaseClientWithMockSavedObjectsClient = async ({
const connectorMappingsService = await connectorMappingsServicePlugin.setup();
const userActionService = {
- postUserActions: jest.fn(),
getUserActions: jest.fn(),
+ postUserActions: jest.fn(),
};
- const alertsService = { initialize: jest.fn(), updateAlertsStatus: jest.fn() };
+ const alertsService = {
+ initialize: jest.fn(),
+ updateAlertsStatus: jest.fn(),
+ getAlerts: jest.fn(),
+ };
const context = {
core: {
@@ -89,6 +96,7 @@ export const createCaseClientWithMockSavedObjectsClient = async ({
const caseClient = createCaseClient({
savedObjectsClient,
request,
+ response,
caseService,
caseConfigureService,
connectorMappingsService,
diff --git a/x-pack/plugins/case/server/client/types.ts b/x-pack/plugins/case/server/client/types.ts
index a3466e26294f8..8778aa46a2d24 100644
--- a/x-pack/plugins/case/server/client/types.ts
+++ b/x-pack/plugins/case/server/client/types.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import { KibanaRequest, SavedObjectsClientContract } from 'kibana/server';
+import { KibanaRequest, KibanaResponseFactory, SavedObjectsClientContract } from 'kibana/server';
import { ActionsClient } from '../../../actions/server';
import {
CasePostRequest,
@@ -16,6 +16,7 @@ import {
CommentRequest,
ConnectorMappingsAttributes,
GetFieldsResponse,
+ CaseUserActionsResponse,
} from '../../common/api';
import {
CaseConfigureServiceSetup,
@@ -25,6 +26,7 @@ import {
} from '../services';
import { ConnectorMappingsServiceSetup } from '../services/connector_mappings';
import type { CasesRequestHandlerContext } from '../types';
+import { CaseClientGetAlertsResponse } from './alerts/types';
export interface CaseClientCreate {
theCase: CasePostRequest;
@@ -35,6 +37,18 @@ export interface CaseClientUpdate {
cases: CasesPatchRequest;
}
+export interface CaseClientGet {
+ id: string;
+ includeComments?: boolean;
+}
+
+export interface CaseClientPush {
+ actionsClient: ActionsClient;
+ caseClient: CaseClient;
+ caseId: string;
+ connectorId: string;
+}
+
export interface CaseClientAddComment {
caseClient: CaseClient;
caseId: string;
@@ -46,11 +60,27 @@ export interface CaseClientUpdateAlertsStatus {
status: CaseStatuses;
}
+export interface CaseClientGetAlerts {
+ ids: string[];
+}
+
+export interface CaseClientGetUserActions {
+ caseId: string;
+}
+
+export interface MappingsClient {
+ actionsClient: ActionsClient;
+ caseClient: CaseClient;
+ connectorId: string;
+ connectorType: string;
+}
+
export interface CaseClientFactoryArguments {
caseConfigureService: CaseConfigureServiceSetup;
caseService: CaseServiceSetup;
connectorMappingsService: ConnectorMappingsServiceSetup;
request: KibanaRequest;
+ response: KibanaResponseFactory;
savedObjectsClient: SavedObjectsClientContract;
userActionService: CaseUserActionServiceSetup;
alertsService: AlertServiceContract;
@@ -65,15 +95,22 @@ export interface ConfigureFields {
export interface CaseClient {
addComment: (args: CaseClientAddComment) => Promise;
create: (args: CaseClientCreate) => Promise;
+ get: (args: CaseClientGet) => Promise;
+ getAlerts: (args: CaseClientGetAlerts) => Promise;
getFields: (args: ConfigureFields) => Promise;
getMappings: (args: MappingsClient) => Promise;
+ getUserActions: (args: CaseClientGetUserActions) => Promise;
+ push: (args: CaseClientPush) => Promise;
update: (args: CaseClientUpdate) => Promise;
updateAlertsStatus: (args: CaseClientUpdateAlertsStatus) => Promise;
}
-export interface MappingsClient {
- actionsClient: ActionsClient;
- caseClient: CaseClient;
- connectorId: string;
- connectorType: string;
-}
+export type CaseClientFactoryMethod = (
+ factoryArgs: CaseClientFactoryArguments
+) => (methodArgs: any) => Promise;
+
+export type CaseClientMethods = keyof CaseClient;
+
+export type CaseClientFactoryMethods = {
+ [K in CaseClientMethods]: CaseClientFactoryMethod;
+};
diff --git a/x-pack/plugins/case/server/client/user_actions/get.ts b/x-pack/plugins/case/server/client/user_actions/get.ts
new file mode 100644
index 0000000000000..e83a9e3484262
--- /dev/null
+++ b/x-pack/plugins/case/server/client/user_actions/get.ts
@@ -0,0 +1,31 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { CASE_SAVED_OBJECT, CASE_COMMENT_SAVED_OBJECT } from '../../saved_object_types';
+import { CaseUserActionsResponseRt, CaseUserActionsResponse } from '../../../common/api';
+import { CaseClientGetUserActions, CaseClientFactoryArguments } from '../types';
+
+export const get = ({
+ savedObjectsClient,
+ userActionService,
+}: CaseClientFactoryArguments) => async ({
+ caseId,
+}: CaseClientGetUserActions): Promise => {
+ const userActions = await userActionService.getUserActions({
+ client: savedObjectsClient,
+ caseId,
+ });
+
+ return CaseUserActionsResponseRt.encode(
+ userActions.saved_objects.map((ua) => ({
+ ...ua.attributes,
+ action_id: ua.id,
+ case_id: ua.references.find((r) => r.type === CASE_SAVED_OBJECT)?.id ?? '',
+ comment_id: ua.references.find((r) => r.type === CASE_COMMENT_SAVED_OBJECT)?.id ?? null,
+ }))
+ );
+};
diff --git a/x-pack/plugins/case/server/connectors/case/index.ts b/x-pack/plugins/case/server/connectors/case/index.ts
index 01446942c33c6..9907aa5b3cd3a 100644
--- a/x-pack/plugins/case/server/connectors/case/index.ts
+++ b/x-pack/plugins/case/server/connectors/case/index.ts
@@ -7,7 +7,7 @@
import { curry } from 'lodash';
-import { KibanaRequest } from 'kibana/server';
+import { KibanaRequest, kibanaResponseFactory } from '../../../../../../src/core/server';
import { ActionTypeExecutorResult } from '../../../../actions/common';
import { CasePatchRequest, CasePostRequest } from '../../../common/api';
import { createCaseClient } from '../../client';
@@ -73,6 +73,7 @@ async function executor(
const caseClient = createCaseClient({
savedObjectsClient,
request: {} as KibanaRequest,
+ response: kibanaResponseFactory,
caseService,
caseConfigureService,
connectorMappingsService,
diff --git a/x-pack/plugins/case/server/connectors/index.ts b/x-pack/plugins/case/server/connectors/index.ts
index 100511e271b02..00809d81ca5f2 100644
--- a/x-pack/plugins/case/server/connectors/index.ts
+++ b/x-pack/plugins/case/server/connectors/index.ts
@@ -5,43 +5,14 @@
* 2.0.
*/
-import { Logger } from 'kibana/server';
-import {
- ActionTypeConfig,
- ActionTypeSecrets,
- ActionTypeParams,
- ActionType,
- // eslint-disable-next-line @kbn/eslint/no-restricted-paths
-} from '../../../actions/server/types';
-import {
- CaseServiceSetup,
- CaseConfigureServiceSetup,
- CaseUserActionServiceSetup,
- ConnectorMappingsServiceSetup,
- AlertServiceContract,
-} from '../services';
-
+import { RegisterConnectorsArgs, ExternalServiceFormatterMapper } from './types';
import { getActionType as getCaseConnector } from './case';
+import { serviceNowITSMExternalServiceFormatter } from './servicenow/itsm_formatter';
+import { serviceNowSIRExternalServiceFormatter } from './servicenow/sir_formatter';
+import { jiraExternalServiceFormatter } from './jira/external_service_formatter';
+import { resilientExternalServiceFormatter } from './resilient/external_service_formatter';
-export interface GetActionTypeParams {
- logger: Logger;
- caseService: CaseServiceSetup;
- caseConfigureService: CaseConfigureServiceSetup;
- connectorMappingsService: ConnectorMappingsServiceSetup;
- userActionService: CaseUserActionServiceSetup;
- alertsService: AlertServiceContract;
-}
-
-export interface RegisterConnectorsArgs extends GetActionTypeParams {
- actionsRegisterType<
- Config extends ActionTypeConfig = ActionTypeConfig,
- Secrets extends ActionTypeSecrets = ActionTypeSecrets,
- Params extends ActionTypeParams = ActionTypeParams,
- ExecutorResultData = void
- >(
- actionType: ActionType
- ): void;
-}
+export * from './types';
export const registerConnectors = ({
actionsRegisterType,
@@ -63,3 +34,10 @@ export const registerConnectors = ({
})
);
};
+
+export const externalServiceFormatters: ExternalServiceFormatterMapper = {
+ '.servicenow': serviceNowITSMExternalServiceFormatter,
+ '.servicenow-sir': serviceNowSIRExternalServiceFormatter,
+ '.jira': jiraExternalServiceFormatter,
+ '.resilient': resilientExternalServiceFormatter,
+};
diff --git a/x-pack/plugins/case/server/connectors/jira/external_service_formatter.test.ts b/x-pack/plugins/case/server/connectors/jira/external_service_formatter.test.ts
new file mode 100644
index 0000000000000..0bfaf7cdbd9e3
--- /dev/null
+++ b/x-pack/plugins/case/server/connectors/jira/external_service_formatter.test.ts
@@ -0,0 +1,35 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { CaseResponse } from '../../../common/api';
+import { jiraExternalServiceFormatter } from './external_service_formatter';
+
+describe('Jira formatter', () => {
+ const theCase = {
+ tags: ['tag'],
+ connector: { fields: { priority: 'High', issueType: 'Task', parent: null } },
+ } as CaseResponse;
+
+ it('it formats correctly', async () => {
+ const res = await jiraExternalServiceFormatter.format(theCase, []);
+ expect(res).toEqual({ ...theCase.connector.fields, labels: theCase.tags });
+ });
+
+ it('it formats correctly when fields do not exist ', async () => {
+ const invalidFields = { tags: ['tag'], connector: { fields: null } } as CaseResponse;
+ const res = await jiraExternalServiceFormatter.format(invalidFields, []);
+ expect(res).toEqual({ priority: null, issueType: null, parent: null, labels: theCase.tags });
+ });
+
+ it('it replace white spaces with hyphens on tags', async () => {
+ const res = await jiraExternalServiceFormatter.format(
+ { ...theCase, tags: ['a tag with spaces'] },
+ []
+ );
+ expect(res).toEqual({ ...theCase.connector.fields, labels: ['a-tag-with-spaces'] });
+ });
+});
diff --git a/x-pack/plugins/case/server/connectors/jira/external_service_formatter.ts b/x-pack/plugins/case/server/connectors/jira/external_service_formatter.ts
new file mode 100644
index 0000000000000..74376d295fea5
--- /dev/null
+++ b/x-pack/plugins/case/server/connectors/jira/external_service_formatter.ts
@@ -0,0 +1,29 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { JiraFieldsType, ConnectorJiraTypeFields } from '../../../common/api';
+import { ExternalServiceFormatter } from '../types';
+
+interface ExternalServiceParams extends JiraFieldsType {
+ labels: string[];
+}
+
+const format: ExternalServiceFormatter['format'] = (theCase) => {
+ const { priority = null, issueType = null, parent = null } =
+ (theCase.connector.fields as ConnectorJiraTypeFields['fields']) ?? {};
+ return {
+ priority,
+ // Jira do not allows empty spaces on labels. We replace white spaces with hyphens
+ labels: theCase.tags.map((tag) => tag.replace(/\s+/g, '-')),
+ issueType,
+ parent,
+ };
+};
+
+export const jiraExternalServiceFormatter: ExternalServiceFormatter = {
+ format,
+};
diff --git a/x-pack/plugins/case/server/connectors/resilient/external_service_formatter.test.ts b/x-pack/plugins/case/server/connectors/resilient/external_service_formatter.test.ts
new file mode 100644
index 0000000000000..01280e9692b5e
--- /dev/null
+++ b/x-pack/plugins/case/server/connectors/resilient/external_service_formatter.test.ts
@@ -0,0 +1,26 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { CaseResponse } from '../../../common/api';
+import { resilientExternalServiceFormatter } from './external_service_formatter';
+
+describe('IBM Resilient formatter', () => {
+ const theCase = {
+ connector: { fields: { incidentTypes: ['2'], severityCode: '2' } },
+ } as CaseResponse;
+
+ it('it formats correctly', async () => {
+ const res = await resilientExternalServiceFormatter.format(theCase, []);
+ expect(res).toEqual({ ...theCase.connector.fields });
+ });
+
+ it('it formats correctly when fields do not exist ', async () => {
+ const invalidFields = { tags: ['a tag'], connector: { fields: null } } as CaseResponse;
+ const res = await resilientExternalServiceFormatter.format(invalidFields, []);
+ expect(res).toEqual({ incidentTypes: null, severityCode: null });
+ });
+});
diff --git a/x-pack/plugins/case/server/connectors/resilient/external_service_formatter.ts b/x-pack/plugins/case/server/connectors/resilient/external_service_formatter.ts
new file mode 100644
index 0000000000000..76554dce32797
--- /dev/null
+++ b/x-pack/plugins/case/server/connectors/resilient/external_service_formatter.ts
@@ -0,0 +1,19 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { ResilientFieldsType, ConnectorResillientTypeFields } from '../../../common/api';
+import { ExternalServiceFormatter } from '../types';
+
+const format: ExternalServiceFormatter['format'] = (theCase) => {
+ const { incidentTypes = null, severityCode = null } =
+ (theCase.connector.fields as ConnectorResillientTypeFields['fields']) ?? {};
+ return { incidentTypes, severityCode };
+};
+
+export const resilientExternalServiceFormatter: ExternalServiceFormatter = {
+ format,
+};
diff --git a/x-pack/plugins/case/server/connectors/servicenow/itsm_formatter.ts b/x-pack/plugins/case/server/connectors/servicenow/itsm_formatter.ts
new file mode 100644
index 0000000000000..60faa82a9e3fa
--- /dev/null
+++ b/x-pack/plugins/case/server/connectors/servicenow/itsm_formatter.ts
@@ -0,0 +1,19 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { ServiceNowITSMFieldsType, ConnectorServiceNowITSMTypeFields } from '../../../common/api';
+import { ExternalServiceFormatter } from '../types';
+
+const format: ExternalServiceFormatter['format'] = (theCase) => {
+ const { severity = null, urgency = null, impact = null } =
+ (theCase.connector.fields as ConnectorServiceNowITSMTypeFields['fields']) ?? {};
+ return { severity, urgency, impact };
+};
+
+export const serviceNowITSMExternalServiceFormatter: ExternalServiceFormatter = {
+ format,
+};
diff --git a/x-pack/plugins/case/server/connectors/servicenow/itsm_formmater.test.ts b/x-pack/plugins/case/server/connectors/servicenow/itsm_formmater.test.ts
new file mode 100644
index 0000000000000..033f184c7e751
--- /dev/null
+++ b/x-pack/plugins/case/server/connectors/servicenow/itsm_formmater.test.ts
@@ -0,0 +1,26 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { CaseResponse } from '../../../common/api';
+import { serviceNowITSMExternalServiceFormatter } from './itsm_formatter';
+
+describe('ITSM formatter', () => {
+ const theCase = {
+ connector: { fields: { severity: '2', urgency: '2', impact: '2' } },
+ } as CaseResponse;
+
+ it('it formats correctly', async () => {
+ const res = await serviceNowITSMExternalServiceFormatter.format(theCase, []);
+ expect(res).toEqual(theCase.connector.fields);
+ });
+
+ it('it formats correctly when fields do not exist ', async () => {
+ const invalidFields = { connector: { fields: null } } as CaseResponse;
+ const res = await serviceNowITSMExternalServiceFormatter.format(invalidFields, []);
+ expect(res).toEqual({ severity: null, urgency: null, impact: null });
+ });
+});
diff --git a/x-pack/plugins/case/server/connectors/servicenow/sir_formatter.test.ts b/x-pack/plugins/case/server/connectors/servicenow/sir_formatter.test.ts
new file mode 100644
index 0000000000000..4faca62c6e706
--- /dev/null
+++ b/x-pack/plugins/case/server/connectors/servicenow/sir_formatter.test.ts
@@ -0,0 +1,164 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { CaseResponse } from '../../../common/api';
+import { serviceNowSIRExternalServiceFormatter } from './sir_formatter';
+
+describe('ITSM formatter', () => {
+ const theCase = {
+ connector: {
+ fields: {
+ destIp: true,
+ sourceIp: true,
+ category: 'Denial of Service',
+ subcategory: 'Inbound DDos',
+ malwareHash: true,
+ malwareUrl: true,
+ priority: '2 - High',
+ },
+ },
+ } as CaseResponse;
+
+ it('it formats correctly without alerts', async () => {
+ const res = await serviceNowSIRExternalServiceFormatter.format(theCase, []);
+ expect(res).toEqual({
+ dest_ip: null,
+ source_ip: null,
+ category: 'Denial of Service',
+ subcategory: 'Inbound DDos',
+ malware_hash: null,
+ malware_url: null,
+ priority: '2 - High',
+ });
+ });
+
+ it('it formats correctly when fields do not exist ', async () => {
+ const invalidFields = { connector: { fields: null } } as CaseResponse;
+ const res = await serviceNowSIRExternalServiceFormatter.format(invalidFields, []);
+ expect(res).toEqual({
+ dest_ip: null,
+ source_ip: null,
+ category: null,
+ subcategory: null,
+ malware_hash: null,
+ malware_url: null,
+ priority: null,
+ });
+ });
+
+ it('it formats correctly with alerts', async () => {
+ const alerts = [
+ {
+ id: 'alert-1',
+ index: 'index-1',
+ destination: { ip: '192.168.1.1' },
+ source: { ip: '192.168.1.2' },
+ file: {
+ hash: { sha256: '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08' },
+ },
+ url: { full: 'https://attack.com' },
+ },
+ {
+ id: 'alert-2',
+ index: 'index-2',
+ destination: { ip: '192.168.1.4' },
+ source: { ip: '192.168.1.3' },
+ file: {
+ hash: { sha256: '60303ae22b998861bce3b28f33eec1be758a213c86c93c076dbe9f558c11c752' },
+ },
+ url: { full: 'https://attack.com/api' },
+ },
+ ];
+ const res = await serviceNowSIRExternalServiceFormatter.format(theCase, alerts);
+ expect(res).toEqual({
+ dest_ip: '192.168.1.1,192.168.1.4',
+ source_ip: '192.168.1.2,192.168.1.3',
+ category: 'Denial of Service',
+ subcategory: 'Inbound DDos',
+ malware_hash:
+ '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08,60303ae22b998861bce3b28f33eec1be758a213c86c93c076dbe9f558c11c752',
+ malware_url: 'https://attack.com,https://attack.com/api',
+ priority: '2 - High',
+ });
+ });
+
+ it('it handles duplicates correctly', async () => {
+ const alerts = [
+ {
+ id: 'alert-1',
+ index: 'index-1',
+ destination: { ip: '192.168.1.1' },
+ source: { ip: '192.168.1.2' },
+ file: {
+ hash: { sha256: '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08' },
+ },
+ url: { full: 'https://attack.com' },
+ },
+ {
+ id: 'alert-2',
+ index: 'index-2',
+ destination: { ip: '192.168.1.1' },
+ source: { ip: '192.168.1.3' },
+ file: {
+ hash: { sha256: '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08' },
+ },
+ url: { full: 'https://attack.com/api' },
+ },
+ ];
+ const res = await serviceNowSIRExternalServiceFormatter.format(theCase, alerts);
+ expect(res).toEqual({
+ dest_ip: '192.168.1.1',
+ source_ip: '192.168.1.2,192.168.1.3',
+ category: 'Denial of Service',
+ subcategory: 'Inbound DDos',
+ malware_hash: '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08',
+ malware_url: 'https://attack.com,https://attack.com/api',
+ priority: '2 - High',
+ });
+ });
+
+ it('it formats correctly when field is not selected', async () => {
+ const alerts = [
+ {
+ id: 'alert-1',
+ index: 'index-1',
+ destination: { ip: '192.168.1.1' },
+ source: { ip: '192.168.1.2' },
+ file: {
+ hash: { sha256: '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08' },
+ },
+ url: { full: 'https://attack.com' },
+ },
+ {
+ id: 'alert-2',
+ index: 'index-2',
+ destination: { ip: '192.168.1.1' },
+ source: { ip: '192.168.1.3' },
+ file: {
+ hash: { sha256: '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08' },
+ },
+ url: { full: 'https://attack.com/api' },
+ },
+ ];
+
+ const newCase = {
+ ...theCase,
+ connector: { fields: { ...theCase.connector.fields, destIp: false, malwareHash: false } },
+ } as CaseResponse;
+
+ const res = await serviceNowSIRExternalServiceFormatter.format(newCase, alerts);
+ expect(res).toEqual({
+ dest_ip: null,
+ source_ip: '192.168.1.2,192.168.1.3',
+ category: 'Denial of Service',
+ subcategory: 'Inbound DDos',
+ malware_hash: null,
+ malware_url: 'https://attack.com,https://attack.com/api',
+ priority: '2 - High',
+ });
+ });
+});
diff --git a/x-pack/plugins/case/server/connectors/servicenow/sir_formatter.ts b/x-pack/plugins/case/server/connectors/servicenow/sir_formatter.ts
new file mode 100644
index 0000000000000..d2458e6c7ae53
--- /dev/null
+++ b/x-pack/plugins/case/server/connectors/servicenow/sir_formatter.ts
@@ -0,0 +1,88 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import { get } from 'lodash/fp';
+import { ConnectorServiceNowSIRTypeFields } from '../../../common/api';
+import { ExternalServiceFormatter } from '../types';
+interface ExternalServiceParams {
+ dest_ip: string | null;
+ source_ip: string | null;
+ category: string | null;
+ subcategory: string | null;
+ malware_hash: string | null;
+ malware_url: string | null;
+ priority: string | null;
+}
+type SirFieldKey = 'dest_ip' | 'source_ip' | 'malware_hash' | 'malware_url';
+type AlertFieldMappingAndValues = Record<
+ string,
+ { alertPath: string; sirFieldKey: SirFieldKey; add: boolean }
+>;
+const format: ExternalServiceFormatter['format'] = (theCase, alerts) => {
+ const {
+ destIp = null,
+ sourceIp = null,
+ category = null,
+ subcategory = null,
+ malwareHash = null,
+ malwareUrl = null,
+ priority = null,
+ } = (theCase.connector.fields as ConnectorServiceNowSIRTypeFields['fields']) ?? {};
+ const alertFieldMapping: AlertFieldMappingAndValues = {
+ destIp: { alertPath: 'destination.ip', sirFieldKey: 'dest_ip', add: !!destIp },
+ sourceIp: { alertPath: 'source.ip', sirFieldKey: 'source_ip', add: !!sourceIp },
+ malwareHash: { alertPath: 'file.hash.sha256', sirFieldKey: 'malware_hash', add: !!malwareHash },
+ malwareUrl: { alertPath: 'url.full', sirFieldKey: 'malware_url', add: !!malwareUrl },
+ };
+
+ const manageDuplicate: Record> = {
+ dest_ip: new Set(),
+ source_ip: new Set(),
+ malware_hash: new Set(),
+ malware_url: new Set(),
+ };
+
+ let sirFields: Record = {
+ dest_ip: null,
+ source_ip: null,
+ malware_hash: null,
+ malware_url: null,
+ };
+
+ const fieldsToAdd = (Object.keys(alertFieldMapping) as SirFieldKey[]).filter(
+ (key) => alertFieldMapping[key].add
+ );
+
+ if (fieldsToAdd.length > 0) {
+ sirFields = alerts.reduce>((acc, alert) => {
+ fieldsToAdd.forEach((alertField) => {
+ const field = get(alertFieldMapping[alertField].alertPath, alert);
+ if (field && !manageDuplicate[alertFieldMapping[alertField].sirFieldKey].has(field)) {
+ manageDuplicate[alertFieldMapping[alertField].sirFieldKey].add(field);
+ acc = {
+ ...acc,
+ [alertFieldMapping[alertField].sirFieldKey]: `${
+ acc[alertFieldMapping[alertField].sirFieldKey] != null
+ ? `${acc[alertFieldMapping[alertField].sirFieldKey]},${field}`
+ : field
+ }`,
+ };
+ }
+ });
+ return acc;
+ }, sirFields);
+ }
+
+ return {
+ ...sirFields,
+ category,
+ subcategory,
+ priority,
+ };
+};
+export const serviceNowSIRExternalServiceFormatter: ExternalServiceFormatter = {
+ format,
+};
diff --git a/x-pack/plugins/case/server/connectors/types.ts b/x-pack/plugins/case/server/connectors/types.ts
new file mode 100644
index 0000000000000..8e7eb91ad2dc6
--- /dev/null
+++ b/x-pack/plugins/case/server/connectors/types.ts
@@ -0,0 +1,54 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { Logger } from 'kibana/server';
+import {
+ ActionTypeConfig,
+ ActionTypeSecrets,
+ ActionTypeParams,
+ ActionType,
+ // eslint-disable-next-line @kbn/eslint/no-restricted-paths
+} from '../../../actions/server/types';
+import { CaseResponse, ConnectorTypes } from '../../common/api';
+import { CaseClientGetAlertsResponse } from '../client/alerts/types';
+import {
+ CaseServiceSetup,
+ CaseConfigureServiceSetup,
+ CaseUserActionServiceSetup,
+ ConnectorMappingsServiceSetup,
+ AlertServiceContract,
+} from '../services';
+
+export interface GetActionTypeParams {
+ logger: Logger;
+ caseService: CaseServiceSetup;
+ caseConfigureService: CaseConfigureServiceSetup;
+ connectorMappingsService: ConnectorMappingsServiceSetup;
+ userActionService: CaseUserActionServiceSetup;
+ alertsService: AlertServiceContract;
+}
+
+export interface RegisterConnectorsArgs extends GetActionTypeParams {
+ actionsRegisterType<
+ Config extends ActionTypeConfig = ActionTypeConfig,
+ Secrets extends ActionTypeSecrets = ActionTypeSecrets,
+ Params extends ActionTypeParams = ActionTypeParams,
+ ExecutorResultData = void
+ >(
+ actionType: ActionType
+ ): void;
+}
+
+export type FormatterConnectorTypes = Exclude;
+
+export interface ExternalServiceFormatter {
+ format: (theCase: CaseResponse, alerts: CaseClientGetAlertsResponse) => TExternalServiceParams;
+}
+
+export type ExternalServiceFormatterMapper = {
+ [x in FormatterConnectorTypes]: ExternalServiceFormatter;
+};
diff --git a/x-pack/plugins/case/server/plugin.ts b/x-pack/plugins/case/server/plugin.ts
index 8b4fdc73dab44..5d05db165f637 100644
--- a/x-pack/plugins/case/server/plugin.ts
+++ b/x-pack/plugins/case/server/plugin.ts
@@ -5,7 +5,13 @@
* 2.0.
*/
-import { IContextProvider, KibanaRequest, Logger, PluginInitializerContext } from 'kibana/server';
+import {
+ IContextProvider,
+ KibanaRequest,
+ KibanaResponseFactory,
+ Logger,
+ PluginInitializerContext,
+} from 'kibana/server';
import { CoreSetup, CoreStart } from 'src/core/server';
import { SecurityPluginSetup } from '../../security/server';
@@ -123,11 +129,13 @@ export class CasePlugin {
const getCaseClientWithRequestAndContext = async (
context: CasesRequestHandlerContext,
- request: KibanaRequest
+ request: KibanaRequest,
+ response: KibanaResponseFactory
) => {
return createCaseClient({
savedObjectsClient: core.savedObjects.getScopedClient(request),
request,
+ response,
caseService: this.caseService!,
caseConfigureService: this.caseConfigureService!,
connectorMappingsService: this.connectorMappingsService!,
@@ -161,7 +169,7 @@ export class CasePlugin {
userActionService: CaseUserActionServiceSetup;
alertsService: AlertServiceContract;
}): IContextProvider => {
- return async (context, request) => {
+ return async (context, request, response) => {
const [{ savedObjects }] = await core.getStartServices();
return {
getCaseClient: () => {
@@ -172,8 +180,9 @@ export class CasePlugin {
connectorMappingsService,
userActionService,
alertsService,
- request,
context,
+ request,
+ response,
});
},
};
diff --git a/x-pack/plugins/case/server/routes/api/__fixtures__/create_mock_so_repository.ts b/x-pack/plugins/case/server/routes/api/__fixtures__/create_mock_so_repository.ts
index 8dc970d235fea..18730effdf55a 100644
--- a/x-pack/plugins/case/server/routes/api/__fixtures__/create_mock_so_repository.ts
+++ b/x-pack/plugins/case/server/routes/api/__fixtures__/create_mock_so_repository.ts
@@ -17,6 +17,7 @@ import {
CASE_SAVED_OBJECT,
CASE_CONFIGURE_SAVED_OBJECT,
CASE_CONNECTOR_MAPPINGS_SAVED_OBJECT,
+ CASE_USER_ACTION_SAVED_OBJECT,
} from '../../../saved_object_types';
export const createMockSavedObjectsRepository = ({
@@ -24,11 +25,13 @@ export const createMockSavedObjectsRepository = ({
caseCommentSavedObject = [],
caseConfigureSavedObject = [],
caseMappingsSavedObject = [],
+ caseUserActionsSavedObject = [],
}: {
caseSavedObject?: any[];
caseCommentSavedObject?: any[];
caseConfigureSavedObject?: any[];
caseMappingsSavedObject?: any[];
+ caseUserActionsSavedObject?: any[];
} = {}) => {
const mockSavedObjectsClientContract = ({
bulkGet: jest.fn((objects: SavedObjectsBulkGetObject[]) => {
@@ -57,6 +60,7 @@ export const createMockSavedObjectsRepository = ({
}),
};
}),
+ bulkCreate: jest.fn(),
bulkUpdate: jest.fn((objects: Array>) => {
return {
saved_objects: objects.map(({ id, type, attributes }) => {
@@ -136,6 +140,16 @@ export const createMockSavedObjectsRepository = ({
saved_objects: caseCommentSavedObject,
};
}
+
+ if (findArgs.type === CASE_USER_ACTION_SAVED_OBJECT) {
+ return {
+ page: 1,
+ per_page: 5,
+ total: caseUserActionsSavedObject.length,
+ saved_objects: caseUserActionsSavedObject,
+ };
+ }
+
return {
page: 1,
per_page: 5,
diff --git a/x-pack/plugins/case/server/routes/api/__fixtures__/index.ts b/x-pack/plugins/case/server/routes/api/__fixtures__/index.ts
index 5e2c29f29a3e7..1abd44aec1552 100644
--- a/x-pack/plugins/case/server/routes/api/__fixtures__/index.ts
+++ b/x-pack/plugins/case/server/routes/api/__fixtures__/index.ts
@@ -10,3 +10,4 @@ export { createMockSavedObjectsRepository } from './create_mock_so_repository';
export { createRouteContext } from './route_contexts';
export { authenticationMock } from './authc_mock';
export { createRoute } from './mock_router';
+export { createActionsClient } from './mock_actions_client';
diff --git a/x-pack/plugins/case/server/routes/api/__fixtures__/mock_actions_client.ts b/x-pack/plugins/case/server/routes/api/__fixtures__/mock_actions_client.ts
new file mode 100644
index 0000000000000..d153c328cbb91
--- /dev/null
+++ b/x-pack/plugins/case/server/routes/api/__fixtures__/mock_actions_client.ts
@@ -0,0 +1,34 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { SavedObjectsErrorHelpers } from 'src/core/server';
+import { actionsClientMock } from '../../../../../actions/server/mocks';
+import {
+ getActions,
+ getActionTypes,
+ getActionExecuteResults,
+} from '../__mocks__/request_responses';
+
+export const createActionsClient = () => {
+ const actionsMock = actionsClientMock.create();
+ actionsMock.getAll.mockImplementation(() => Promise.resolve(getActions()));
+ actionsMock.listTypes.mockImplementation(() => Promise.resolve(getActionTypes()));
+ actionsMock.get.mockImplementation(({ id }) => {
+ const actions = getActions();
+ const action = actions.find((a) => a.id === id);
+ if (action) {
+ return Promise.resolve(action);
+ } else {
+ return Promise.reject(SavedObjectsErrorHelpers.createGenericNotFoundError('action', id));
+ }
+ });
+ actionsMock.execute.mockImplementation(({ actionId }) =>
+ Promise.resolve(getActionExecuteResults(actionId))
+ );
+
+ return actionsMock;
+};
diff --git a/x-pack/plugins/case/server/routes/api/__fixtures__/mock_saved_objects.ts b/x-pack/plugins/case/server/routes/api/__fixtures__/mock_saved_objects.ts
index 4ac5004eb3dfd..514f77a8f953d 100644
--- a/x-pack/plugins/case/server/routes/api/__fixtures__/mock_saved_objects.ts
+++ b/x-pack/plugins/case/server/routes/api/__fixtures__/mock_saved_objects.ts
@@ -8,6 +8,7 @@
import { SavedObject } from 'kibana/server';
import {
CaseStatuses,
+ CaseUserActionAttributes,
CommentAttributes,
CommentType,
ConnectorMappings,
@@ -15,7 +16,10 @@ import {
ESCaseAttributes,
ESCasesConfigureAttributes,
} from '../../../../common/api';
-import { CASE_CONNECTOR_MAPPINGS_SAVED_OBJECT } from '../../../saved_object_types';
+import {
+ CASE_CONNECTOR_MAPPINGS_SAVED_OBJECT,
+ CASE_USER_ACTION_SAVED_OBJECT,
+} from '../../../saved_object_types';
import { mappings } from '../../../client/configure/mock';
export const mockCases: Array> = [
@@ -424,3 +428,44 @@ export const mockCaseMappings: Array> = [
references: [],
},
];
+
+export const mockUserActions: Array> = [
+ {
+ type: CASE_USER_ACTION_SAVED_OBJECT,
+ id: 'mock-user-actions-1',
+ attributes: {
+ action_field: ['description', 'status', 'tags', 'title', 'connector', 'settings'],
+ action: 'create',
+ action_at: '2021-02-03T17:41:03.771Z',
+ action_by: {
+ email: 'elastic@elastic.co',
+ full_name: 'Elastic',
+ username: 'elastic',
+ },
+ new_value:
+ '{"title":"A case","tags":["case"],"description":"Yeah!","connector":{"id":"connector-od","name":"My Connector","type":".servicenow-sir","fields":{"category":"Denial of Service","destIp":true,"malwareHash":true,"malwareUrl":true,"priority":"2","sourceIp":true,"subcategory":"45"}},"settings":{"syncAlerts":true}}',
+ old_value: null,
+ },
+ version: 'WzYsMV0=',
+ references: [],
+ },
+ {
+ type: CASE_USER_ACTION_SAVED_OBJECT,
+ id: 'mock-user-actions-2',
+ attributes: {
+ action_field: ['comment'],
+ action: 'create',
+ action_at: '2021-02-03T17:44:21.067Z',
+ action_by: {
+ email: 'elastic@elastic.co',
+ full_name: 'Elastic',
+ username: 'elastic',
+ },
+ new_value:
+ '{"type":"alert","alertId":"cec3da90fb37a44407145adf1593f3b0d5ad94c4654201f773d63b5d4706128e","index":".siem-signals-default-000008"}',
+ old_value: null,
+ },
+ version: 'WzYsMV0=',
+ references: [],
+ },
+];
diff --git a/x-pack/plugins/case/server/routes/api/__fixtures__/route_contexts.ts b/x-pack/plugins/case/server/routes/api/__fixtures__/route_contexts.ts
index 9f7258fc7edaf..74665ffdc5b16 100644
--- a/x-pack/plugins/case/server/routes/api/__fixtures__/route_contexts.ts
+++ b/x-pack/plugins/case/server/routes/api/__fixtures__/route_contexts.ts
@@ -5,24 +5,25 @@
* 2.0.
*/
-import { KibanaRequest } from 'src/core/server';
-import { loggingSystemMock, elasticsearchServiceMock } from 'src/core/server/mocks';
-import { actionsClientMock } from '../../../../../actions/server/mocks';
+import { KibanaRequest, kibanaResponseFactory } from '../../../../../../../src/core/server';
+import {
+ loggingSystemMock,
+ elasticsearchServiceMock,
+} from '../../../../../../../src/core/server/mocks';
import { createCaseClient } from '../../../client';
import {
AlertService,
CaseService,
CaseConfigureService,
ConnectorMappingsService,
+ CaseUserActionService,
} from '../../../services';
-import { getActions, getActionTypes } from '../__mocks__/request_responses';
import { authenticationMock } from '../__fixtures__';
import type { CasesRequestHandlerContext } from '../../../types';
+import { createActionsClient } from './mock_actions_client';
export const createRouteContext = async (client: any, badAuth = false) => {
- const actionsMock = actionsClientMock.create();
- actionsMock.getAll.mockImplementation(() => Promise.resolve(getActions()));
- actionsMock.listTypes.mockImplementation(() => Promise.resolve(getActionTypes()));
+ const actionsMock = createActionsClient();
const log = loggingSystemMock.create().get('case');
const esClientMock = elasticsearchServiceMock.createClusterClient();
@@ -30,11 +31,13 @@ export const createRouteContext = async (client: any, badAuth = false) => {
const caseServicePlugin = new CaseService(log);
const caseConfigureServicePlugin = new CaseConfigureService(log);
const connectorMappingsServicePlugin = new ConnectorMappingsService(log);
+ const caseUserActionsServicePlugin = new CaseUserActionService(log);
const caseService = await caseServicePlugin.setup({
authentication: badAuth ? authenticationMock.createInvalid() : authenticationMock.create(),
});
const caseConfigureService = await caseConfigureServicePlugin.setup();
+ const userActionService = await caseUserActionsServicePlugin.setup();
const alertsService = new AlertService();
alertsService.initialize(esClientMock);
@@ -59,16 +62,14 @@ export const createRouteContext = async (client: any, badAuth = false) => {
const caseClient = createCaseClient({
savedObjectsClient: client,
request: {} as KibanaRequest,
+ response: kibanaResponseFactory,
caseService,
caseConfigureService,
connectorMappingsService,
- userActionService: {
- postUserActions: jest.fn(),
- getUserActions: jest.fn(),
- },
+ userActionService,
alertsService,
context,
});
- return context;
+ return { context, services: { userActionService } };
};
diff --git a/x-pack/plugins/case/server/routes/api/__mocks__/request_responses.ts b/x-pack/plugins/case/server/routes/api/__mocks__/request_responses.ts
index f2109167527c7..ae14b44e7dffe 100644
--- a/x-pack/plugins/case/server/routes/api/__mocks__/request_responses.ts
+++ b/x-pack/plugins/case/server/routes/api/__mocks__/request_responses.ts
@@ -10,11 +10,9 @@ import {
CasePostRequest,
CasesConfigureRequest,
ConnectorTypes,
- PostPushRequest,
} from '../../../../common/api';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { FindActionResult } from '../../../../../actions/server/types';
-import { params } from '../cases/configure/mock';
export const newCase: CasePostRequest = {
title: 'My new case',
@@ -74,6 +72,16 @@ export const getActions = (): FindActionResult[] => [
isPreconfigured: false,
referencedByCount: 0,
},
+ {
+ id: 'for-mock-case-id-3',
+ actionTypeId: '.jira',
+ name: 'For mock case id 3',
+ config: {
+ apiUrl: 'https://elastic.jira.com',
+ },
+ isPreconfigured: false,
+ referencedByCount: 0,
+ },
];
export const getActionTypes = (): ActionTypeConnector[] => [
@@ -119,6 +127,18 @@ export const getActionTypes = (): ActionTypeConnector[] => [
},
];
+export const getActionExecuteResults = (actionId = '123') => ({
+ status: 'ok' as const,
+ data: {
+ title: 'RJ2-200',
+ id: '10663',
+ pushedDate: '2020-12-17T00:32:40.738Z',
+ url: 'https://siem-kibana.atlassian.net/browse/RJ2-200',
+ comments: [],
+ },
+ actionId,
+});
+
export const newConfiguration: CasesConfigureRequest = {
connector: {
id: '456',
@@ -129,11 +149,6 @@ export const newConfiguration: CasesConfigureRequest = {
closure_type: 'close-by-pushing',
};
-export const newPostPushRequest: PostPushRequest = {
- params: params[ConnectorTypes.jira],
- connector_type: ConnectorTypes.jira,
-};
-
export const executePushResponse = {
status: 'ok',
data: {
diff --git a/x-pack/plugins/case/server/routes/api/cases/comments/delete_comment.test.ts b/x-pack/plugins/case/server/routes/api/cases/comments/delete_comment.test.ts
index 9454f582e50c6..dcbcd7b9e246d 100644
--- a/x-pack/plugins/case/server/routes/api/cases/comments/delete_comment.test.ts
+++ b/x-pack/plugins/case/server/routes/api/cases/comments/delete_comment.test.ts
@@ -33,14 +33,14 @@ describe('DELETE comment', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
caseCommentSavedObject: mockCaseComments,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(204);
});
it(`returns an error when thrown from deleteComment service`, async () => {
@@ -53,14 +53,14 @@ describe('DELETE comment', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
caseCommentSavedObject: mockCaseComments,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(404);
});
});
diff --git a/x-pack/plugins/case/server/routes/api/cases/comments/get_comment.test.ts b/x-pack/plugins/case/server/routes/api/cases/comments/get_comment.test.ts
index a1f4b8c2583cf..8ee43eaba8a82 100644
--- a/x-pack/plugins/case/server/routes/api/cases/comments/get_comment.test.ts
+++ b/x-pack/plugins/case/server/routes/api/cases/comments/get_comment.test.ts
@@ -34,14 +34,14 @@ describe('GET comment', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
caseCommentSavedObject: mockCaseComments,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(200);
const myPayload = mockCaseComments.find((s) => s.id === 'mock-comment-1');
expect(myPayload).not.toBeUndefined();
@@ -59,13 +59,13 @@ describe('GET comment', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseCommentSavedObject: mockCaseComments,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(404);
});
});
diff --git a/x-pack/plugins/case/server/routes/api/cases/comments/patch_comment.test.ts b/x-pack/plugins/case/server/routes/api/cases/comments/patch_comment.test.ts
index 3bd8a688e1bba..33dc24d776c70 100644
--- a/x-pack/plugins/case/server/routes/api/cases/comments/patch_comment.test.ts
+++ b/x-pack/plugins/case/server/routes/api/cases/comments/patch_comment.test.ts
@@ -41,14 +41,14 @@ describe('PATCH comment', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
caseCommentSavedObject: mockCaseComments,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(200);
expect(response.payload.comments[response.payload.comments.length - 1].comment).toEqual(
'Update my comment'
@@ -71,14 +71,14 @@ describe('PATCH comment', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
caseCommentSavedObject: mockCaseComments,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(200);
expect(response.payload.comments[response.payload.comments.length - 1].alertId).toEqual(
'new-id'
@@ -102,14 +102,14 @@ describe('PATCH comment', () => {
body: requestAttributes,
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
caseCommentSavedObject: mockCaseComments,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(400);
expect(response.payload.isBoom).toEqual(true);
}
@@ -130,14 +130,14 @@ describe('PATCH comment', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
caseCommentSavedObject: mockCaseComments,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(400);
expect(response.payload.isBoom).toEqual(true);
}
@@ -161,14 +161,14 @@ describe('PATCH comment', () => {
body: requestAttributes,
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
caseCommentSavedObject: mockCaseComments,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(400);
expect(response.payload.isBoom).toEqual(true);
}
@@ -190,14 +190,14 @@ describe('PATCH comment', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
caseCommentSavedObject: mockCaseComments,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(400);
expect(response.payload.isBoom).toEqual(true);
}
@@ -219,14 +219,14 @@ describe('PATCH comment', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
caseCommentSavedObject: mockCaseComments,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(400);
expect(response.payload.isBoom).toEqual(true);
expect(response.payload.message).toEqual('You cannot change the type of the comment.');
@@ -247,14 +247,14 @@ describe('PATCH comment', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
caseCommentSavedObject: mockCaseComments,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(409);
});
@@ -273,14 +273,14 @@ describe('PATCH comment', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
caseCommentSavedObject: mockCaseComments,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(404);
expect(response.payload.isBoom).toEqual(true);
});
diff --git a/x-pack/plugins/case/server/routes/api/cases/comments/post_comment.test.ts b/x-pack/plugins/case/server/routes/api/cases/comments/post_comment.test.ts
index 54699415cd984..0ab038a62ac77 100644
--- a/x-pack/plugins/case/server/routes/api/cases/comments/post_comment.test.ts
+++ b/x-pack/plugins/case/server/routes/api/cases/comments/post_comment.test.ts
@@ -43,14 +43,14 @@ describe('POST comment', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
caseCommentSavedObject: mockCaseComments,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(200);
expect(response.payload.comments[response.payload.comments.length - 1].id).toEqual(
'mock-comment'
@@ -71,14 +71,14 @@ describe('POST comment', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
caseCommentSavedObject: mockCaseComments,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(200);
expect(response.payload.comments[response.payload.comments.length - 1].id).toEqual(
'mock-comment'
@@ -95,14 +95,14 @@ describe('POST comment', () => {
body: {},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
caseCommentSavedObject: mockCaseComments,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(400);
expect(response.payload.isBoom).toEqual(true);
});
@@ -124,14 +124,14 @@ describe('POST comment', () => {
body: requestAttributes,
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
caseCommentSavedObject: mockCaseComments,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(400);
expect(response.payload.isBoom).toEqual(true);
}
@@ -152,14 +152,14 @@ describe('POST comment', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
caseCommentSavedObject: mockCaseComments,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(400);
expect(response.payload.isBoom).toEqual(true);
}
@@ -183,14 +183,14 @@ describe('POST comment', () => {
body: requestAttributes,
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
caseCommentSavedObject: mockCaseComments,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(400);
expect(response.payload.isBoom).toEqual(true);
}
@@ -212,14 +212,14 @@ describe('POST comment', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
caseCommentSavedObject: mockCaseComments,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(400);
expect(response.payload.isBoom).toEqual(true);
}
@@ -238,14 +238,14 @@ describe('POST comment', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
caseCommentSavedObject: mockCaseComments,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(404);
expect(response.payload.isBoom).toEqual(true);
});
@@ -262,14 +262,14 @@ describe('POST comment', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
caseCommentSavedObject: mockCaseComments,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(400);
expect(response.payload.isBoom).toEqual(true);
});
@@ -289,7 +289,7 @@ describe('POST comment', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
caseCommentSavedObject: mockCaseComments,
@@ -297,7 +297,7 @@ describe('POST comment', () => {
true
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(200);
expect(response.payload.comments[response.payload.comments.length - 1]).toEqual({
comment: 'Wow, good luck catching that bad meanie!',
diff --git a/x-pack/plugins/case/server/routes/api/cases/configure/get_configure.test.ts b/x-pack/plugins/case/server/routes/api/cases/configure/get_configure.test.ts
index ddcbb3522f986..ff4216a05ae58 100644
--- a/x-pack/plugins/case/server/routes/api/cases/configure/get_configure.test.ts
+++ b/x-pack/plugins/case/server/routes/api/cases/configure/get_configure.test.ts
@@ -34,7 +34,7 @@ describe('GET configuration', () => {
method: 'get',
});
- const context = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseConfigureSavedObject: mockCaseConfigure,
caseMappingsSavedObject: mockCaseMappings,
@@ -57,7 +57,7 @@ describe('GET configuration', () => {
method: 'get',
});
- const context = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseConfigureSavedObject: [{ ...mockCaseConfigure[0], version: undefined }],
caseMappingsSavedObject: mockCaseMappings,
@@ -98,7 +98,7 @@ describe('GET configuration', () => {
method: 'get',
});
- const context = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseConfigureSavedObject: [],
})
@@ -116,7 +116,7 @@ describe('GET configuration', () => {
method: 'get',
});
- const context = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseConfigureSavedObject: [{ ...mockCaseConfigure[0], id: 'throw-error-find' }],
})
@@ -133,7 +133,7 @@ describe('GET configuration', () => {
method: 'get',
});
- const context = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseConfigureSavedObject: mockCaseConfigure,
caseMappingsSavedObject: [],
diff --git a/x-pack/plugins/case/server/routes/api/cases/configure/get_configure.ts b/x-pack/plugins/case/server/routes/api/cases/configure/get_configure.ts
index 0f74b7291dd81..17972e129a825 100644
--- a/x-pack/plugins/case/server/routes/api/cases/configure/get_configure.ts
+++ b/x-pack/plugins/case/server/routes/api/cases/configure/get_configure.ts
@@ -33,9 +33,9 @@ export function initGetCaseConfigure({ caseConfigureService, router }: RouteDeps
throw Boom.badRequest('RouteHandlerContext is not registered for cases');
}
const caseClient = context.case.getCaseClient();
- const actionsClient = await context.actions?.getActionsClient();
+ const actionsClient = context.actions?.getActionsClient();
if (actionsClient == null) {
- throw Boom.notFound('Action client have not been found');
+ throw Boom.notFound('Action client not found');
}
try {
mappings = await caseClient.getMappings({
diff --git a/x-pack/plugins/case/server/routes/api/cases/configure/get_connectors.test.ts b/x-pack/plugins/case/server/routes/api/cases/configure/get_connectors.test.ts
index 1e37918d7766a..3fa0fe2f83f79 100644
--- a/x-pack/plugins/case/server/routes/api/cases/configure/get_connectors.test.ts
+++ b/x-pack/plugins/case/server/routes/api/cases/configure/get_connectors.test.ts
@@ -32,7 +32,7 @@ describe('GET connectors', () => {
method: 'get',
});
- const context = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseConfigureSavedObject: mockCaseConfigure,
caseMappingsSavedObject: mockCaseMappings,
@@ -54,7 +54,7 @@ describe('GET connectors', () => {
method: 'get',
});
- const context = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseConfigureSavedObject: mockCaseConfigure,
caseMappingsSavedObject: mockCaseMappings,
@@ -106,6 +106,16 @@ describe('GET connectors', () => {
isPreconfigured: false,
referencedByCount: 0,
},
+ {
+ id: 'for-mock-case-id-3',
+ actionTypeId: '.jira',
+ name: 'For mock case id 3',
+ config: {
+ apiUrl: 'https://elastic.jira.com',
+ },
+ isPreconfigured: false,
+ referencedByCount: 0,
+ },
]);
});
@@ -115,7 +125,7 @@ describe('GET connectors', () => {
method: 'get',
});
- const context = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseConfigureSavedObject: mockCaseConfigure,
caseMappingsSavedObject: mockCaseMappings,
diff --git a/x-pack/plugins/case/server/routes/api/cases/configure/get_connectors.ts b/x-pack/plugins/case/server/routes/api/cases/configure/get_connectors.ts
index fb0595f858d4e..0a368e0276bb5 100644
--- a/x-pack/plugins/case/server/routes/api/cases/configure/get_connectors.ts
+++ b/x-pack/plugins/case/server/routes/api/cases/configure/get_connectors.ts
@@ -14,18 +14,15 @@ import { FindActionResult } from '../../../../../../actions/server/types';
import {
CASE_CONFIGURE_CONNECTORS_URL,
- SERVICENOW_ACTION_TYPE_ID,
- JIRA_ACTION_TYPE_ID,
- RESILIENT_ACTION_TYPE_ID,
+ SUPPORTED_CONNECTORS,
} from '../../../../../common/constants';
const isConnectorSupported = (
action: FindActionResult,
actionTypes: Record
): boolean =>
- [SERVICENOW_ACTION_TYPE_ID, JIRA_ACTION_TYPE_ID, RESILIENT_ACTION_TYPE_ID].includes(
- action.actionTypeId
- ) && actionTypes[action.actionTypeId]?.enabledInLicense;
+ SUPPORTED_CONNECTORS.includes(action.actionTypeId) &&
+ actionTypes[action.actionTypeId]?.enabledInLicense;
/*
* Be aware that this api will only return 20 connectors
@@ -39,10 +36,10 @@ export function initCaseConfigureGetActionConnector({ router }: RouteDeps) {
},
async (context, request, response) => {
try {
- const actionsClient = await context.actions?.getActionsClient();
+ const actionsClient = context.actions?.getActionsClient();
if (actionsClient == null) {
- throw Boom.notFound('Action client have not been found');
+ throw Boom.notFound('Action client not found');
}
const actionTypes = (await actionsClient.listTypes()).reduce(
diff --git a/x-pack/plugins/case/server/routes/api/cases/configure/mock.ts b/x-pack/plugins/case/server/routes/api/cases/configure/mock.ts
deleted file mode 100644
index 9959a3e4acee6..0000000000000
--- a/x-pack/plugins/case/server/routes/api/cases/configure/mock.ts
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-
-import {
- ServiceConnectorCaseParams,
- ServiceConnectorCommentParams,
- ConnectorMappingsAttributes,
- ConnectorTypes,
-} from '../../../../../common/api/connectors';
-export const updateUser = {
- updatedAt: '2020-03-13T08:34:53.450Z',
- updatedBy: { fullName: 'Another User', username: 'another' },
-};
-const entity = {
- createdAt: '2020-03-13T08:34:53.450Z',
- createdBy: { fullName: 'Elastic User', username: 'elastic' },
- updatedAt: null,
- updatedBy: null,
-};
-export const comment: ServiceConnectorCommentParams = {
- comment: 'first comment',
- commentId: 'b5b4c4d0-574e-11ea-9e2e-21b90f8a9631',
- ...entity,
-};
-export const defaultPipes = ['informationCreated'];
-const basicParams = {
- comments: [comment],
- description: 'a description',
- title: 'a title',
- savedObjectId: '1231231231232',
- externalId: null,
-};
-export const params = {
- [ConnectorTypes.jira]: {
- ...basicParams,
- issueType: '10003',
- priority: 'Highest',
- parent: '5002',
- ...entity,
- } as ServiceConnectorCaseParams,
- [ConnectorTypes.resilient]: {
- ...basicParams,
- incidentTypes: ['10003'],
- severityCode: '1',
- ...entity,
- } as ServiceConnectorCaseParams,
- [ConnectorTypes.servicenow]: {
- ...basicParams,
- impact: '3',
- severity: '1',
- urgency: '2',
- ...entity,
- } as ServiceConnectorCaseParams,
- [ConnectorTypes.none]: {},
-};
-export const mappings: ConnectorMappingsAttributes[] = [
- {
- source: 'title',
- target: 'short_description',
- action_type: 'overwrite',
- },
- {
- source: 'description',
- target: 'description',
- action_type: 'append',
- },
- {
- source: 'comments',
- target: 'comments',
- action_type: 'append',
- },
-];
diff --git a/x-pack/plugins/case/server/routes/api/cases/configure/patch_configure.test.ts b/x-pack/plugins/case/server/routes/api/cases/configure/patch_configure.test.ts
index c67a1c064a82f..f43f561e30e10 100644
--- a/x-pack/plugins/case/server/routes/api/cases/configure/patch_configure.test.ts
+++ b/x-pack/plugins/case/server/routes/api/cases/configure/patch_configure.test.ts
@@ -42,7 +42,7 @@ describe('PATCH configuration', () => {
},
});
- const context = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseConfigureSavedObject: mockCaseConfigure,
caseMappingsSavedObject: mockCaseMappings,
@@ -76,7 +76,7 @@ describe('PATCH configuration', () => {
},
});
- const context = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseConfigureSavedObject: mockCaseConfigure,
caseMappingsSavedObject: mockCaseMappings,
@@ -115,7 +115,7 @@ describe('PATCH configuration', () => {
},
});
- const context = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseConfigureSavedObject: mockCaseConfigure,
caseMappingsSavedObject: mockCaseMappings,
@@ -153,7 +153,7 @@ describe('PATCH configuration', () => {
},
});
- const context = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseConfigureSavedObject: mockCaseConfigure,
caseMappingsSavedObject: [],
@@ -193,7 +193,7 @@ describe('PATCH configuration', () => {
},
});
- const context = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseConfigureSavedObject: [],
})
@@ -215,7 +215,7 @@ describe('PATCH configuration', () => {
},
});
- const context = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseConfigureSavedObject: mockCaseConfigure,
caseMappingsSavedObject: mockCaseMappings,
@@ -243,7 +243,7 @@ describe('PATCH configuration', () => {
},
});
- const context = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseConfigureSavedObject: mockCaseConfigure,
caseMappingsSavedObject: mockCaseMappings,
diff --git a/x-pack/plugins/case/server/routes/api/cases/configure/patch_configure.ts b/x-pack/plugins/case/server/routes/api/cases/configure/patch_configure.ts
index f847c4f776bf0..6925f116136b3 100644
--- a/x-pack/plugins/case/server/routes/api/cases/configure/patch_configure.ts
+++ b/x-pack/plugins/case/server/routes/api/cases/configure/patch_configure.ts
@@ -66,7 +66,7 @@ export function initPatchCaseConfigure({ caseConfigureService, caseService, rout
throw Boom.badRequest('RouteHandlerContext is not registered for cases');
}
const caseClient = context.case.getCaseClient();
- const actionsClient = await context.actions?.getActionsClient();
+ const actionsClient = context.actions?.getActionsClient();
if (actionsClient == null) {
throw Boom.notFound('Action client have not been found');
}
diff --git a/x-pack/plugins/case/server/routes/api/cases/configure/post_configure.test.ts b/x-pack/plugins/case/server/routes/api/cases/configure/post_configure.test.ts
index 0a7f3ef488fce..7dcb7d1fa12ca 100644
--- a/x-pack/plugins/case/server/routes/api/cases/configure/post_configure.test.ts
+++ b/x-pack/plugins/case/server/routes/api/cases/configure/post_configure.test.ts
@@ -40,7 +40,7 @@ describe('POST configuration', () => {
body: newConfiguration,
});
- const context = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseConfigureSavedObject: mockCaseConfigure,
caseMappingsSavedObject: mockCaseMappings,
@@ -73,7 +73,7 @@ describe('POST configuration', () => {
body: newConfiguration,
});
- const context = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseConfigureSavedObject: mockCaseConfigure,
caseMappingsSavedObject: [],
@@ -113,7 +113,7 @@ describe('POST configuration', () => {
body: newConfiguration,
});
- const context = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseConfigureSavedObject: mockCaseConfigure,
caseMappingsSavedObject: mockCaseMappings,
@@ -154,7 +154,7 @@ describe('POST configuration', () => {
},
});
- const context = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseConfigureSavedObject: mockCaseConfigure,
caseMappingsSavedObject: mockCaseMappings,
@@ -180,7 +180,7 @@ describe('POST configuration', () => {
},
});
- const context = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseConfigureSavedObject: mockCaseConfigure,
caseMappingsSavedObject: mockCaseMappings,
@@ -206,7 +206,7 @@ describe('POST configuration', () => {
},
});
- const context = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseConfigureSavedObject: mockCaseConfigure,
caseMappingsSavedObject: mockCaseMappings,
@@ -232,7 +232,7 @@ describe('POST configuration', () => {
},
});
- const context = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseConfigureSavedObject: mockCaseConfigure,
caseMappingsSavedObject: mockCaseMappings,
@@ -258,7 +258,7 @@ describe('POST configuration', () => {
},
});
- const context = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseConfigureSavedObject: mockCaseConfigure,
caseMappingsSavedObject: mockCaseMappings,
@@ -282,7 +282,7 @@ describe('POST configuration', () => {
caseMappingsSavedObject: mockCaseMappings,
});
- const context = await createRouteContext(savedObjectRepository);
+ const { context } = await createRouteContext(savedObjectRepository);
const res = await routeHandler(context, req, kibanaResponseFactory);
@@ -302,7 +302,7 @@ describe('POST configuration', () => {
caseMappingsSavedObject: mockCaseMappings,
});
- const context = await createRouteContext(savedObjectRepository);
+ const { context } = await createRouteContext(savedObjectRepository);
const res = await routeHandler(context, req, kibanaResponseFactory);
@@ -325,7 +325,7 @@ describe('POST configuration', () => {
caseMappingsSavedObject: mockCaseMappings,
});
- const context = await createRouteContext(savedObjectRepository);
+ const { context } = await createRouteContext(savedObjectRepository);
const res = await routeHandler(context, req, kibanaResponseFactory);
@@ -341,7 +341,7 @@ describe('POST configuration', () => {
body: newConfiguration,
});
- const context = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseConfigureSavedObject: [{ ...mockCaseConfigure[0], id: 'throw-error-find' }],
})
@@ -359,7 +359,7 @@ describe('POST configuration', () => {
body: newConfiguration,
});
- const context = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseConfigureSavedObject: [{ ...mockCaseConfigure[0], id: 'throw-error-delete' }],
})
@@ -384,7 +384,7 @@ describe('POST configuration', () => {
},
});
- const context = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseConfigureSavedObject: mockCaseConfigure,
caseMappingsSavedObject: mockCaseMappings,
@@ -411,7 +411,7 @@ describe('POST configuration', () => {
},
});
- const context = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseConfigureSavedObject: mockCaseConfigure,
caseMappingsSavedObject: mockCaseMappings,
@@ -437,7 +437,7 @@ describe('POST configuration', () => {
},
});
- const context = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseConfigureSavedObject: mockCaseConfigure,
caseMappingsSavedObject: mockCaseMappings,
@@ -459,7 +459,7 @@ describe('POST configuration', () => {
},
});
- const context = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseConfigureSavedObject: mockCaseConfigure,
caseMappingsSavedObject: mockCaseMappings,
diff --git a/x-pack/plugins/case/server/routes/api/cases/configure/post_configure.ts b/x-pack/plugins/case/server/routes/api/cases/configure/post_configure.ts
index 8e5fd95facc3d..0bcf2ac18740f 100644
--- a/x-pack/plugins/case/server/routes/api/cases/configure/post_configure.ts
+++ b/x-pack/plugins/case/server/routes/api/cases/configure/post_configure.ts
@@ -39,9 +39,9 @@ export function initPostCaseConfigure({ caseConfigureService, caseService, route
throw Boom.badRequest('RouteHandlerContext is not registered for cases');
}
const caseClient = context.case.getCaseClient();
- const actionsClient = await context.actions?.getActionsClient();
+ const actionsClient = context.actions?.getActionsClient();
if (actionsClient == null) {
- throw Boom.notFound('Action client have not been found');
+ throw Boom.notFound('Action client not found');
}
const client = context.core.savedObjects.client;
const query = pipe(
diff --git a/x-pack/plugins/case/server/routes/api/cases/configure/post_push_to_service.test.ts b/x-pack/plugins/case/server/routes/api/cases/configure/post_push_to_service.test.ts
deleted file mode 100644
index e382813dbf0c5..0000000000000
--- a/x-pack/plugins/case/server/routes/api/cases/configure/post_push_to_service.test.ts
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-
-import { kibanaResponseFactory, RequestHandler } from 'src/core/server';
-import { httpServerMock } from 'src/core/server/mocks';
-
-import {
- createMockSavedObjectsRepository,
- createRoute,
- createRouteContext,
- mockCaseMappings,
-} from '../../__fixtures__';
-
-import { initPostPushToService } from './post_push_to_service';
-import { executePushResponse, newPostPushRequest } from '../../__mocks__/request_responses';
-import { CASE_CONFIGURE_PUSH_URL } from '../../../../../common/constants';
-import type { CasesRequestHandlerContext } from '../../../../types';
-
-describe('Post push to service', () => {
- let routeHandler: RequestHandler;
- const req = httpServerMock.createKibanaRequest({
- path: `${CASE_CONFIGURE_PUSH_URL}`,
- method: 'post',
- params: {
- connector_id: '666',
- },
- body: newPostPushRequest,
- });
- let context: CasesRequestHandlerContext;
- beforeAll(async () => {
- routeHandler = await createRoute(initPostPushToService, 'post');
- const spyOnDate = jest.spyOn(global, 'Date') as jest.SpyInstance<{}, []>;
- spyOnDate.mockImplementation(() => ({
- toISOString: jest.fn().mockReturnValue('2020-04-09T09:43:51.778Z'),
- }));
- context = await createRouteContext(
- createMockSavedObjectsRepository({
- caseMappingsSavedObject: mockCaseMappings,
- })
- );
- });
-
- it('Happy path - posts success', async () => {
- const betterContext = ({
- ...context,
- actions: {
- ...context.actions,
- getActionsClient: () => {
- const actions = context!.actions!.getActionsClient();
- return {
- ...actions,
- execute: jest.fn().mockImplementation(({ actionId }) => {
- return {
- status: 'ok',
- data: {
- title: 'RJ2-200',
- id: '10663',
- pushedDate: '2020-12-17T00:32:40.738Z',
- url: 'https://siem-kibana.atlassian.net/browse/RJ2-200',
- comments: [],
- },
- actionId,
- };
- }),
- };
- },
- },
- } as unknown) as CasesRequestHandlerContext;
-
- const res = await routeHandler(betterContext, req, kibanaResponseFactory);
-
- expect(res.status).toEqual(200);
- expect(res.payload).toEqual({
- ...executePushResponse,
- actionId: '666',
- });
- });
- it('Unhappy path - context case missing', async () => {
- const betterContext = ({
- ...context,
- case: null,
- } as unknown) as CasesRequestHandlerContext;
-
- const res = await routeHandler(betterContext, req, kibanaResponseFactory);
- expect(res.status).toEqual(400);
- expect(res.payload.isBoom).toBeTruthy();
- expect(res.payload.output.payload.message).toEqual(
- 'RouteHandlerContext is not registered for cases'
- );
- });
- it('Unhappy path - context actions missing', async () => {
- const betterContext = ({
- ...context,
- actions: null,
- } as unknown) as CasesRequestHandlerContext;
-
- const res = await routeHandler(betterContext, req, kibanaResponseFactory);
- expect(res.status).toEqual(404);
- expect(res.payload.isBoom).toBeTruthy();
- expect(res.payload.output.payload.message).toEqual('Action client have not been found');
- });
-});
diff --git a/x-pack/plugins/case/server/routes/api/cases/configure/post_push_to_service.ts b/x-pack/plugins/case/server/routes/api/cases/configure/post_push_to_service.ts
deleted file mode 100644
index b8ba1a9ccb6ef..0000000000000
--- a/x-pack/plugins/case/server/routes/api/cases/configure/post_push_to_service.ts
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-
-import { pipe } from 'fp-ts/lib/pipeable';
-import { fold } from 'fp-ts/lib/Either';
-import { identity } from 'fp-ts/lib/function';
-import Boom from '@hapi/boom';
-import { RouteDeps } from '../../types';
-import { escapeHatch, wrapError } from '../../utils';
-
-import { CASE_CONFIGURE_PUSH_URL } from '../../../../../common/constants';
-import {
- ConnectorRequestParamsRt,
- PostPushRequestRt,
- throwErrors,
-} from '../../../../../common/api';
-import { mapIncident } from './utils';
-
-export function initPostPushToService({ router }: RouteDeps) {
- router.post(
- {
- path: CASE_CONFIGURE_PUSH_URL,
- validate: {
- params: escapeHatch,
- body: escapeHatch,
- },
- },
- async (context, request, response) => {
- try {
- if (!context.case) {
- throw Boom.badRequest('RouteHandlerContext is not registered for cases');
- }
- const caseClient = context.case.getCaseClient();
- const actionsClient = await context.actions?.getActionsClient();
- if (actionsClient == null) {
- throw Boom.notFound('Action client have not been found');
- }
- const params = pipe(
- ConnectorRequestParamsRt.decode(request.params),
- fold(throwErrors(Boom.badRequest), identity)
- );
- const body = pipe(
- PostPushRequestRt.decode(request.body),
- fold(throwErrors(Boom.badRequest), identity)
- );
-
- const myConnectorMappings = await caseClient.getMappings({
- actionsClient,
- caseClient,
- connectorId: params.connector_id,
- connectorType: body.connector_type,
- });
-
- const res = await mapIncident(
- actionsClient,
- params.connector_id,
- body.connector_type,
- myConnectorMappings,
- body.params
- );
- const pushRes = await actionsClient.execute({
- actionId: params.connector_id,
- params: {
- subAction: 'pushToService',
- subActionParams: res,
- },
- });
-
- return response.ok({
- body: pushRes,
- });
- } catch (error) {
- return response.customError(wrapError(error));
- }
- }
- );
-}
diff --git a/x-pack/plugins/case/server/routes/api/cases/delete_cases.test.ts b/x-pack/plugins/case/server/routes/api/cases/delete_cases.test.ts
index 84e452ea8e871..d588950bec9aa 100644
--- a/x-pack/plugins/case/server/routes/api/cases/delete_cases.test.ts
+++ b/x-pack/plugins/case/server/routes/api/cases/delete_cases.test.ts
@@ -33,14 +33,14 @@ describe('DELETE case', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
caseCommentSavedObject: mockCaseComments,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(204);
});
it(`returns an error when thrown from deleteCase service`, async () => {
@@ -52,14 +52,14 @@ describe('DELETE case', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
caseCommentSavedObject: mockCaseComments,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(404);
});
it(`returns an error when thrown from getAllCaseComments service`, async () => {
@@ -71,14 +71,14 @@ describe('DELETE case', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCasesErrorTriggerData,
caseCommentSavedObject: mockCaseComments,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(400);
});
it(`returns an error when thrown from deleteComment service`, async () => {
@@ -90,14 +90,14 @@ describe('DELETE case', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCasesErrorTriggerData,
caseCommentSavedObject: mockCasesErrorTriggerData,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(400);
});
});
diff --git a/x-pack/plugins/case/server/routes/api/cases/find_cases.test.ts b/x-pack/plugins/case/server/routes/api/cases/find_cases.test.ts
index acd7de1e8643e..ca9f731ca5010 100644
--- a/x-pack/plugins/case/server/routes/api/cases/find_cases.test.ts
+++ b/x-pack/plugins/case/server/routes/api/cases/find_cases.test.ts
@@ -30,13 +30,13 @@ describe('FIND all cases', () => {
method: 'get',
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(200);
expect(response.payload.cases).toHaveLength(4);
// mockSavedObjectsRepository do not support filters and returns all cases every time.
@@ -51,13 +51,13 @@ describe('FIND all cases', () => {
method: 'get',
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(200);
expect(response.payload.cases[2].connector.id).toEqual('123');
});
@@ -68,13 +68,13 @@ describe('FIND all cases', () => {
method: 'get',
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: [mockCaseNoConnectorId],
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(200);
expect(response.payload.cases[0].connector.id).toEqual('none');
});
@@ -85,14 +85,14 @@ describe('FIND all cases', () => {
method: 'get',
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: [mockCaseNoConnectorId],
caseConfigureSavedObject: mockCaseConfigure,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(200);
expect(response.payload.cases[0].connector.id).toEqual('none');
});
diff --git a/x-pack/plugins/case/server/routes/api/cases/get_case.test.ts b/x-pack/plugins/case/server/routes/api/cases/get_case.test.ts
index 7aa6f110a0079..968dd0424fe3f 100644
--- a/x-pack/plugins/case/server/routes/api/cases/get_case.test.ts
+++ b/x-pack/plugins/case/server/routes/api/cases/get_case.test.ts
@@ -40,13 +40,13 @@ describe('GET case', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
const savedObject = (mockCases.find(
(s) => s.id === 'mock-id-1'
) as unknown) as SavedObject;
@@ -71,13 +71,13 @@ describe('GET case', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(404);
expect(response.payload.isBoom).toEqual(true);
@@ -95,14 +95,14 @@ describe('GET case', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
caseCommentSavedObject: mockCaseComments,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(200);
expect(response.payload.comments).toHaveLength(5);
@@ -120,13 +120,13 @@ describe('GET case', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCasesErrorTriggerData,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(400);
});
@@ -143,13 +143,13 @@ describe('GET case', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: [mockCaseNoConnectorId],
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(200);
expect(response.payload.connector).toEqual({
@@ -172,14 +172,14 @@ describe('GET case', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: [mockCaseNoConnectorId],
caseConfigureSavedObject: mockCaseConfigure,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(200);
expect(response.payload.connector).toEqual({
@@ -202,14 +202,14 @@ describe('GET case', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
caseConfigureSavedObject: mockCaseConfigure,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(200);
expect(response.payload.connector).toEqual({
diff --git a/x-pack/plugins/case/server/routes/api/cases/get_case.ts b/x-pack/plugins/case/server/routes/api/cases/get_case.ts
index f563fc274b18b..55377d93e528d 100644
--- a/x-pack/plugins/case/server/routes/api/cases/get_case.ts
+++ b/x-pack/plugins/case/server/routes/api/cases/get_case.ts
@@ -7,9 +7,8 @@
import { schema } from '@kbn/config-schema';
-import { CaseResponseRt } from '../../../../common/api';
import { RouteDeps } from '../types';
-import { flattenCaseSavedObject, wrapError } from '../utils';
+import { wrapError } from '../utils';
import { CASE_DETAILS_URL } from '../../../../common/constants';
export function initGetCaseApi({ caseConfigureService, caseService, router }: RouteDeps) {
@@ -26,44 +25,17 @@ export function initGetCaseApi({ caseConfigureService, caseService, router }: Ro
},
},
async (context, request, response) => {
- try {
- const client = context.core.savedObjects.client;
- const includeComments = JSON.parse(request.query.includeComments);
-
- const [theCase] = await Promise.all([
- caseService.getCase({
- client,
- caseId: request.params.case_id,
- }),
- ]);
-
- if (!includeComments) {
- return response.ok({
- body: CaseResponseRt.encode(
- flattenCaseSavedObject({
- savedObject: theCase,
- })
- ),
- });
- }
+ if (!context.case) {
+ return response.badRequest({ body: 'RouteHandlerContext is not registered for cases' });
+ }
- const theComments = await caseService.getAllCaseComments({
- client,
- caseId: request.params.case_id,
- options: {
- sortField: 'created_at',
- sortOrder: 'asc',
- },
- });
+ const caseClient = context.case.getCaseClient();
+ const includeComments = JSON.parse(request.query.includeComments);
+ const id = request.params.case_id;
+ try {
return response.ok({
- body: CaseResponseRt.encode(
- flattenCaseSavedObject({
- savedObject: theCase,
- comments: theComments.saved_objects,
- totalComment: theComments.total,
- })
- ),
+ body: await caseClient.get({ id, includeComments }),
});
} catch (error) {
return response.customError(wrapError(error));
diff --git a/x-pack/plugins/case/server/routes/api/cases/patch_cases.test.ts b/x-pack/plugins/case/server/routes/api/cases/patch_cases.test.ts
index 95f7e5bb19a01..6d1134b15b65e 100644
--- a/x-pack/plugins/case/server/routes/api/cases/patch_cases.test.ts
+++ b/x-pack/plugins/case/server/routes/api/cases/patch_cases.test.ts
@@ -44,13 +44,13 @@ describe('PATCH cases', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(200);
expect(response.payload).toEqual([
{
@@ -97,14 +97,14 @@ describe('PATCH cases', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
caseConfigureSavedObject: mockCaseConfigure,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(200);
expect(response.payload).toEqual([
{
@@ -151,13 +151,13 @@ describe('PATCH cases', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(200);
expect(response.payload).toEqual([
{
@@ -204,13 +204,13 @@ describe('PATCH cases', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: [mockCaseNoConnectorId],
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(200);
expect(response.payload[0].connector.id).toEqual('none');
});
@@ -230,13 +230,13 @@ describe('PATCH cases', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(200);
expect(response.payload[0].connector.id).toEqual('123');
});
@@ -261,13 +261,13 @@ describe('PATCH cases', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(200);
expect(response.payload[0].connector).toEqual({
id: '456',
@@ -292,13 +292,13 @@ describe('PATCH cases', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(409);
});
@@ -317,14 +317,14 @@ describe('PATCH cases', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
caseCommentSavedObject: mockCaseComments,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(406);
});
@@ -343,13 +343,13 @@ describe('PATCH cases', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(404);
expect(response.payload.isBoom).toEqual(true);
});
diff --git a/x-pack/plugins/case/server/routes/api/cases/post_case.test.ts b/x-pack/plugins/case/server/routes/api/cases/post_case.test.ts
index 997516d2e30b6..292e2c6775a80 100644
--- a/x-pack/plugins/case/server/routes/api/cases/post_case.test.ts
+++ b/x-pack/plugins/case/server/routes/api/cases/post_case.test.ts
@@ -49,13 +49,13 @@ describe('POST cases', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(200);
expect(response.payload.id).toEqual('mock-it');
expect(response.payload.status).toEqual('open');
@@ -88,14 +88,14 @@ describe('POST cases', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
caseConfigureSavedObject: mockCaseConfigure,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(200);
expect(response.payload.connector).toEqual({
id: '123',
@@ -121,13 +121,13 @@ describe('POST cases', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(400);
});
@@ -146,13 +146,13 @@ describe('POST cases', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(400);
expect(response.payload.isBoom).toEqual(true);
});
@@ -179,7 +179,7 @@ describe('POST cases', () => {
},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
caseConfigureSavedObject: mockCaseConfigure,
@@ -187,7 +187,7 @@ describe('POST cases', () => {
true
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(200);
expect(response.payload).toEqual({
closed_at: null,
diff --git a/x-pack/plugins/case/server/routes/api/cases/push_case.test.ts b/x-pack/plugins/case/server/routes/api/cases/push_case.test.ts
index 549195966b2a7..49801ea4e2f3e 100644
--- a/x-pack/plugins/case/server/routes/api/cases/push_case.test.ts
+++ b/x-pack/plugins/case/server/routes/api/cases/push_case.test.ts
@@ -13,63 +13,187 @@ import {
createRoute,
createRouteContext,
mockCases,
+ mockCaseConfigure,
+ mockCaseMappings,
+ mockUserActions,
+ mockCaseComments,
} from '../__fixtures__';
-import { initPushCaseUserActionApi } from './push_case';
-import { CASE_DETAILS_URL } from '../../../../common/constants';
-import { mockCaseConfigure } from '../__fixtures__/mock_saved_objects';
+import { initPushCaseApi } from './push_case';
+import { CasesRequestHandlerContext } from '../../../types';
+import { getCasePushUrl } from '../../../../common/api/helpers';
describe('Push case', () => {
let routeHandler: RequestHandler;
const mockDate = '2019-11-25T21:54:48.952Z';
- const caseExternalServiceRequestBody = {
- connector_id: 'connector_id',
- connector_name: 'connector_name',
- external_id: 'external_id',
- external_title: 'external_title',
- external_url: 'external_url',
- };
+ const caseId = 'mock-id-3';
+ const connectorId = '123';
+ const path = getCasePushUrl(caseId, connectorId);
+
beforeAll(async () => {
- routeHandler = await createRoute(initPushCaseUserActionApi, 'post');
+ routeHandler = await createRoute(initPushCaseApi, 'post');
const spyOnDate = jest.spyOn(global, 'Date') as jest.SpyInstance<{}, []>;
spyOnDate.mockImplementation(() => ({
toISOString: jest.fn().mockReturnValue(mockDate),
}));
});
+
it(`Pushes a case`, async () => {
const request = httpServerMock.createKibanaRequest({
- path: `${CASE_DETAILS_URL}/_push`,
+ path,
+ method: 'post',
+ params: {
+ case_id: caseId,
+ connector_id: connectorId,
+ },
+ body: {},
+ });
+
+ const { context } = await createRouteContext(
+ createMockSavedObjectsRepository({
+ caseSavedObject: mockCases,
+ caseMappingsSavedObject: mockCaseMappings,
+ caseConfigureSavedObject: mockCaseConfigure,
+ caseUserActionsSavedObject: mockUserActions,
+ })
+ );
+
+ const response = await routeHandler(context, request, kibanaResponseFactory);
+ expect(response.status).toEqual(200);
+ expect(response.payload.external_service).toEqual({
+ connector_id: connectorId,
+ connector_name: 'ServiceNow',
+ external_id: '10663',
+ external_title: 'RJ2-200',
+ external_url: 'https://siem-kibana.atlassian.net/browse/RJ2-200',
+ pushed_at: mockDate,
+ pushed_by: {
+ email: 'd00d@awesome.com',
+ full_name: 'Awesome D00d',
+ username: 'awesome',
+ },
+ });
+ });
+
+ it(`Pushes a case with comments`, async () => {
+ const request = httpServerMock.createKibanaRequest({
+ path,
+ method: 'post',
+ params: {
+ case_id: caseId,
+ connector_id: connectorId,
+ },
+ body: {},
+ });
+
+ const { context } = await createRouteContext(
+ createMockSavedObjectsRepository({
+ caseSavedObject: mockCases,
+ caseMappingsSavedObject: mockCaseMappings,
+ caseConfigureSavedObject: mockCaseConfigure,
+ caseUserActionsSavedObject: mockUserActions,
+ caseCommentSavedObject: [mockCaseComments[0]],
+ })
+ );
+
+ const response = await routeHandler(context, request, kibanaResponseFactory);
+ expect(response.status).toEqual(200);
+ expect(response.payload.comments[0].pushed_at).toEqual(mockDate);
+ expect(response.payload.comments[0].pushed_by).toEqual({
+ email: 'd00d@awesome.com',
+ full_name: 'Awesome D00d',
+ username: 'awesome',
+ });
+ });
+
+ it(`Filters comments with type alert correctly`, async () => {
+ const request = httpServerMock.createKibanaRequest({
+ path,
method: 'post',
params: {
- case_id: 'mock-id-3',
+ case_id: caseId,
+ connector_id: connectorId,
},
- body: caseExternalServiceRequestBody,
+ body: {},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
+ caseMappingsSavedObject: mockCaseMappings,
+ caseConfigureSavedObject: mockCaseConfigure,
+ caseUserActionsSavedObject: mockUserActions,
+ caseCommentSavedObject: [mockCaseComments[0], mockCaseComments[3]],
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const caseClient = context.case.getCaseClient();
+ caseClient.getAlerts = jest.fn().mockResolvedValue([]);
+
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(200);
- expect(response.payload.external_service.pushed_at).toEqual(mockDate);
- expect(response.payload.external_service.connector_id).toEqual('connector_id');
- expect(response.payload.closed_at).toEqual(null);
+ expect(caseClient.getAlerts).toHaveBeenCalledWith({ ids: ['test-id'] });
+ });
+
+ it(`Calls execute with correct arguments`, async () => {
+ const request = httpServerMock.createKibanaRequest({
+ path,
+ method: 'post',
+ params: {
+ case_id: caseId,
+ connector_id: 'for-mock-case-id-3',
+ },
+ body: {},
+ });
+
+ const { context } = await createRouteContext(
+ createMockSavedObjectsRepository({
+ caseSavedObject: mockCases,
+ caseMappingsSavedObject: mockCaseMappings,
+ caseConfigureSavedObject: mockCaseConfigure,
+ caseUserActionsSavedObject: mockUserActions,
+ })
+ );
+
+ const actionsClient = context.actions.getActionsClient();
+
+ await routeHandler(context, request, kibanaResponseFactory);
+ expect(actionsClient.execute).toHaveBeenCalledWith({
+ actionId: 'for-mock-case-id-3',
+ params: {
+ subAction: 'pushToService',
+ subActionParams: {
+ incident: {
+ issueType: 'Task',
+ parent: null,
+ priority: 'High',
+ labels: ['LOLBins'],
+ summary: 'Another bad one (created at 2019-11-25T22:32:17.947Z by elastic)',
+ description:
+ 'Oh no, a bad meanie going LOLBins all over the place! (created at 2019-11-25T22:32:17.947Z by elastic)',
+ externalId: null,
+ },
+ comments: [],
+ },
+ },
+ });
});
+
it(`Pushes a case and closes when closure_type: 'close-by-pushing'`, async () => {
const request = httpServerMock.createKibanaRequest({
- path: `${CASE_DETAILS_URL}/_push`,
+ path,
method: 'post',
params: {
- case_id: 'mock-id-3',
+ case_id: caseId,
+ connector_id: connectorId,
},
- body: caseExternalServiceRequestBody,
+ body: {},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
+ caseMappingsSavedObject: mockCaseMappings,
+ caseUserActionsSavedObject: mockUserActions,
caseConfigureSavedObject: [
{
...mockCaseConfigure[0],
@@ -82,30 +206,259 @@ describe('Push case', () => {
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(200);
- expect(response.payload.external_service.pushed_at).toEqual(mockDate);
- expect(response.payload.external_service.connector_id).toEqual('connector_id');
expect(response.payload.closed_at).toEqual(mockDate);
});
- it(`Returns an error if pushCaseUserAction throws`, async () => {
+ it(`post the correct user action`, async () => {
+ const request = httpServerMock.createKibanaRequest({
+ path,
+ method: 'post',
+ params: {
+ case_id: caseId,
+ connector_id: connectorId,
+ },
+ body: {},
+ });
+
+ const { context, services } = await createRouteContext(
+ createMockSavedObjectsRepository({
+ caseSavedObject: mockCases,
+ caseMappingsSavedObject: mockCaseMappings,
+ caseConfigureSavedObject: mockCaseConfigure,
+ caseUserActionsSavedObject: mockUserActions,
+ })
+ );
+
+ services.userActionService.postUserActions = jest.fn();
+ const postUserActions = services.userActionService.postUserActions as jest.Mock;
+
+ const response = await routeHandler(context, request, kibanaResponseFactory);
+ expect(response.status).toEqual(200);
+ expect(postUserActions.mock.calls[0][0].actions[0].attributes).toEqual({
+ action: 'push-to-service',
+ action_at: '2019-11-25T21:54:48.952Z',
+ action_by: {
+ email: 'd00d@awesome.com',
+ full_name: 'Awesome D00d',
+ username: 'awesome',
+ },
+ action_field: ['pushed'],
+ new_value:
+ '{"pushed_at":"2019-11-25T21:54:48.952Z","pushed_by":{"username":"awesome","full_name":"Awesome D00d","email":"d00d@awesome.com"},"connector_id":"123","connector_name":"ServiceNow","external_id":"10663","external_title":"RJ2-200","external_url":"https://siem-kibana.atlassian.net/browse/RJ2-200"}',
+ old_value: null,
+ });
+ });
+
+ it('Unhappy path - case id is missing', async () => {
const request = httpServerMock.createKibanaRequest({
- path: `${CASE_DETAILS_URL}/_push`,
+ path,
method: 'post',
- body: {
- notagoodbody: 'Throw an error',
+ params: {
+ connector_id: connectorId,
+ },
+ body: {},
+ });
+
+ const { context } = await createRouteContext(
+ createMockSavedObjectsRepository({
+ caseSavedObject: mockCases,
+ caseMappingsSavedObject: mockCaseMappings,
+ caseConfigureSavedObject: mockCaseConfigure,
+ caseUserActionsSavedObject: mockUserActions,
+ })
+ );
+
+ const res = await routeHandler(context, request, kibanaResponseFactory);
+ expect(res.status).toEqual(400);
+ });
+
+ it('Unhappy path - connector id is missing', async () => {
+ const request = httpServerMock.createKibanaRequest({
+ path,
+ method: 'post',
+ params: {
+ case_id: caseId,
},
+ body: {},
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
+ caseMappingsSavedObject: mockCaseMappings,
+ caseConfigureSavedObject: mockCaseConfigure,
+ caseUserActionsSavedObject: mockUserActions,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
- expect(response.status).toEqual(400);
- expect(response.payload.isBoom).toEqual(true);
+ const res = await routeHandler(context, request, kibanaResponseFactory);
+ expect(res.status).toEqual(400);
+ });
+
+ it('Unhappy path - case does not exists', async () => {
+ const request = httpServerMock.createKibanaRequest({
+ path,
+ method: 'post',
+ params: {
+ case_id: 'not-exist',
+ connector_id: connectorId,
+ },
+ body: {},
+ });
+
+ const { context } = await createRouteContext(
+ createMockSavedObjectsRepository({
+ caseSavedObject: mockCases,
+ caseMappingsSavedObject: mockCaseMappings,
+ caseConfigureSavedObject: mockCaseConfigure,
+ caseUserActionsSavedObject: mockUserActions,
+ })
+ );
+
+ const res = await routeHandler(context, request, kibanaResponseFactory);
+ expect(res.status).toEqual(404);
+ });
+
+ it('Unhappy path - connector does not exists', async () => {
+ const request = httpServerMock.createKibanaRequest({
+ path,
+ method: 'post',
+ params: {
+ case_id: caseId,
+ connector_id: 'not-exists',
+ },
+ body: {},
+ });
+
+ const { context } = await createRouteContext(
+ createMockSavedObjectsRepository({
+ caseSavedObject: mockCases,
+ caseMappingsSavedObject: mockCaseMappings,
+ caseConfigureSavedObject: mockCaseConfigure,
+ caseUserActionsSavedObject: mockUserActions,
+ })
+ );
+
+ const res = await routeHandler(context, request, kibanaResponseFactory);
+ expect(res.status).toEqual(404);
+ });
+
+ it('Unhappy path - cannot push to a closed case', async () => {
+ const request = httpServerMock.createKibanaRequest({
+ path,
+ method: 'post',
+ params: {
+ case_id: 'mock-id-4',
+ connector_id: connectorId,
+ },
+ body: {},
+ });
+
+ const { context } = await createRouteContext(
+ createMockSavedObjectsRepository({
+ caseSavedObject: mockCases,
+ caseMappingsSavedObject: mockCaseMappings,
+ caseConfigureSavedObject: mockCaseConfigure,
+ caseUserActionsSavedObject: mockUserActions,
+ })
+ );
+
+ const res = await routeHandler(context, request, kibanaResponseFactory);
+ expect(res.status).toEqual(409);
+ expect(res.payload.output.payload.message).toBe(
+ 'This case Another bad one is closed. You can not pushed if the case is closed.'
+ );
+ });
+
+ it('Unhappy path - throws when external service returns an error', async () => {
+ const request = httpServerMock.createKibanaRequest({
+ path,
+ method: 'post',
+ params: {
+ case_id: caseId,
+ connector_id: connectorId,
+ },
+ body: {},
+ });
+
+ const { context } = await createRouteContext(
+ createMockSavedObjectsRepository({
+ caseSavedObject: mockCases,
+ caseMappingsSavedObject: mockCaseMappings,
+ caseConfigureSavedObject: mockCaseConfigure,
+ caseUserActionsSavedObject: mockUserActions,
+ })
+ );
+
+ const actionsClient = context.actions.getActionsClient();
+ (actionsClient.execute as jest.Mock).mockResolvedValue({
+ status: 'error',
+ });
+
+ const res = await routeHandler(context, request, kibanaResponseFactory);
+ expect(res.status).toEqual(424);
+ expect(res.payload.output.payload.message).toBe('Error pushing to service');
+ });
+
+ it('Unhappy path - context case missing', async () => {
+ const request = httpServerMock.createKibanaRequest({
+ path,
+ method: 'post',
+ params: {
+ case_id: caseId,
+ connector_id: connectorId,
+ },
+ body: {},
+ });
+
+ const { context } = await createRouteContext(
+ createMockSavedObjectsRepository({
+ caseSavedObject: mockCases,
+ caseMappingsSavedObject: mockCaseMappings,
+ caseConfigureSavedObject: mockCaseConfigure,
+ caseUserActionsSavedObject: mockUserActions,
+ })
+ );
+
+ const betterContext = ({
+ ...context,
+ case: null,
+ } as unknown) as CasesRequestHandlerContext;
+
+ const res = await routeHandler(betterContext, request, kibanaResponseFactory);
+ expect(res.status).toEqual(400);
+ expect(res.payload).toEqual('RouteHandlerContext is not registered for cases');
+ });
+
+ it('Unhappy path - context actions missing', async () => {
+ const request = httpServerMock.createKibanaRequest({
+ path,
+ method: 'post',
+ params: {
+ case_id: caseId,
+ connector_id: connectorId,
+ },
+ body: {},
+ });
+
+ const { context } = await createRouteContext(
+ createMockSavedObjectsRepository({
+ caseSavedObject: mockCases,
+ caseMappingsSavedObject: mockCaseMappings,
+ caseConfigureSavedObject: mockCaseConfigure,
+ caseUserActionsSavedObject: mockUserActions,
+ })
+ );
+
+ const betterContext = ({
+ ...context,
+ actions: null,
+ } as unknown) as CasesRequestHandlerContext;
+
+ const res = await routeHandler(betterContext, request, kibanaResponseFactory);
+ expect(res.status).toEqual(400);
+ expect(res.payload).toEqual('Action client not found');
});
});
diff --git a/x-pack/plugins/case/server/routes/api/cases/push_case.ts b/x-pack/plugins/case/server/routes/api/cases/push_case.ts
index 218b1f16b9aab..6d670c38bbf85 100644
--- a/x-pack/plugins/case/server/routes/api/cases/push_case.ts
+++ b/x-pack/plugins/case/server/routes/api/cases/push_case.ts
@@ -5,204 +5,51 @@
* 2.0.
*/
-import { schema } from '@kbn/config-schema';
import Boom from '@hapi/boom';
-import isEmpty from 'lodash/isEmpty';
import { pipe } from 'fp-ts/lib/pipeable';
import { fold } from 'fp-ts/lib/Either';
import { identity } from 'fp-ts/lib/function';
-import {
- flattenCaseSavedObject,
- wrapError,
- escapeHatch,
- getCommentContextFromAttributes,
-} from '../utils';
+import { wrapError, escapeHatch } from '../utils';
-import {
- CaseExternalServiceRequestRt,
- CaseResponseRt,
- throwErrors,
- CaseStatuses,
-} from '../../../../common/api';
-import { buildCaseUserActionItem } from '../../../services/user_actions/helpers';
+import { throwErrors, CasePushRequestParamsRt } from '../../../../common/api';
import { RouteDeps } from '../types';
-import { CASE_DETAILS_URL } from '../../../../common/constants';
+import { CASE_PUSH_URL } from '../../../../common/constants';
-export function initPushCaseUserActionApi({
- caseConfigureService,
- caseService,
- router,
- userActionService,
-}: RouteDeps) {
+export function initPushCaseApi({ router }: RouteDeps) {
router.post(
{
- path: `${CASE_DETAILS_URL}/_push`,
+ path: CASE_PUSH_URL,
validate: {
- params: schema.object({
- case_id: schema.string(),
- }),
+ params: escapeHatch,
body: escapeHatch,
},
},
async (context, request, response) => {
- try {
- const client = context.core.savedObjects.client;
- const actionsClient = await context.actions?.getActionsClient();
-
- const caseId = request.params.case_id;
- const query = pipe(
- CaseExternalServiceRequestRt.decode(request.body),
- fold(throwErrors(Boom.badRequest), identity)
- );
-
- if (actionsClient == null) {
- throw Boom.notFound('Action client have not been found');
- }
-
- // eslint-disable-next-line @typescript-eslint/naming-convention
- const { username, full_name, email } = await caseService.getUser({ request, response });
-
- const pushedDate = new Date().toISOString();
-
- const [myCase, myCaseConfigure, totalCommentsFindByCases, connectors] = await Promise.all([
- caseService.getCase({
- client,
- caseId: request.params.case_id,
- }),
- caseConfigureService.find({ client }),
- caseService.getAllCaseComments({
- client,
- caseId,
- options: {
- fields: [],
- page: 1,
- perPage: 1,
- },
- }),
- actionsClient.getAll(),
- ]);
-
- if (myCase.attributes.status === CaseStatuses.closed) {
- throw Boom.conflict(
- `This case ${myCase.attributes.title} is closed. You can not pushed if the case is closed.`
- );
- }
-
- const comments = await caseService.getAllCaseComments({
- client,
- caseId,
- options: {
- fields: [],
- page: 1,
- perPage: totalCommentsFindByCases.total,
- },
- });
-
- const externalService = {
- pushed_at: pushedDate,
- pushed_by: { username, full_name, email },
- ...query,
- };
+ if (!context.case) {
+ return response.badRequest({ body: 'RouteHandlerContext is not registered for cases' });
+ }
- const updateConnector = myCase.attributes.connector;
+ const caseClient = context.case.getCaseClient();
+ const actionsClient = context.actions?.getActionsClient();
- if (
- isEmpty(updateConnector) ||
- (updateConnector != null && updateConnector.id === 'none') ||
- !connectors.some((connector) => connector.id === updateConnector.id)
- ) {
- throw Boom.notFound('Connector not found or set to none');
- }
+ if (actionsClient == null) {
+ return response.badRequest({ body: 'Action client not found' });
+ }
- const [updatedCase, updatedComments] = await Promise.all([
- caseService.patchCase({
- client,
- caseId,
- updatedAttributes: {
- ...(myCaseConfigure.total > 0 &&
- myCaseConfigure.saved_objects[0].attributes.closure_type === 'close-by-pushing'
- ? {
- status: CaseStatuses.closed,
- closed_at: pushedDate,
- closed_by: { email, full_name, username },
- }
- : {}),
- external_service: externalService,
- updated_at: pushedDate,
- updated_by: { username, full_name, email },
- },
- version: myCase.version,
- }),
- caseService.patchComments({
- client,
- comments: comments.saved_objects
- .filter((comment) => comment.attributes.pushed_at == null)
- .map((comment) => ({
- commentId: comment.id,
- updatedAttributes: {
- pushed_at: pushedDate,
- pushed_by: { username, full_name, email },
- },
- version: comment.version,
- })),
- }),
- userActionService.postUserActions({
- client,
- actions: [
- ...(myCaseConfigure.total > 0 &&
- myCaseConfigure.saved_objects[0].attributes.closure_type === 'close-by-pushing'
- ? [
- buildCaseUserActionItem({
- action: 'update',
- actionAt: pushedDate,
- actionBy: { username, full_name, email },
- caseId,
- fields: ['status'],
- newValue: CaseStatuses.closed,
- oldValue: myCase.attributes.status,
- }),
- ]
- : []),
- buildCaseUserActionItem({
- action: 'push-to-service',
- actionAt: pushedDate,
- actionBy: { username, full_name, email },
- caseId,
- fields: ['pushed'],
- newValue: JSON.stringify(externalService),
- }),
- ],
- }),
- ]);
+ try {
+ const params = pipe(
+ CasePushRequestParamsRt.decode(request.params),
+ fold(throwErrors(Boom.badRequest), identity)
+ );
return response.ok({
- body: CaseResponseRt.encode(
- flattenCaseSavedObject({
- savedObject: {
- ...myCase,
- ...updatedCase,
- attributes: { ...myCase.attributes, ...updatedCase?.attributes },
- references: myCase.references,
- },
- comments: comments.saved_objects.map((origComment) => {
- const updatedComment = updatedComments.saved_objects.find(
- (c) => c.id === origComment.id
- );
- return {
- ...origComment,
- ...updatedComment,
- attributes: {
- ...origComment.attributes,
- ...updatedComment?.attributes,
- ...getCommentContextFromAttributes(origComment.attributes),
- },
- version: updatedComment?.version ?? origComment.version,
- references: origComment?.references ?? [],
- };
- }),
- })
- ),
+ body: await caseClient.push({
+ caseClient,
+ actionsClient,
+ caseId: params.case_id,
+ connectorId: params.connector_id,
+ }),
});
} catch (error) {
return response.customError(wrapError(error));
diff --git a/x-pack/plugins/case/server/routes/api/cases/status/get_status.test.ts b/x-pack/plugins/case/server/routes/api/cases/status/get_status.test.ts
index e8761ad69dcca..9644162629f24 100644
--- a/x-pack/plugins/case/server/routes/api/cases/status/get_status.test.ts
+++ b/x-pack/plugins/case/server/routes/api/cases/status/get_status.test.ts
@@ -36,24 +36,24 @@ describe('GET status', () => {
method: 'get',
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: mockCases,
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
- expect(theContext.core.savedObjects.client.find).toHaveBeenNthCalledWith(1, {
+ const response = await routeHandler(context, request, kibanaResponseFactory);
+ expect(context.core.savedObjects.client.find).toHaveBeenNthCalledWith(1, {
...findArgs,
filter: 'cases.attributes.status: open',
});
- expect(theContext.core.savedObjects.client.find).toHaveBeenNthCalledWith(2, {
+ expect(context.core.savedObjects.client.find).toHaveBeenNthCalledWith(2, {
...findArgs,
filter: 'cases.attributes.status: in-progress',
});
- expect(theContext.core.savedObjects.client.find).toHaveBeenNthCalledWith(3, {
+ expect(context.core.savedObjects.client.find).toHaveBeenNthCalledWith(3, {
...findArgs,
filter: 'cases.attributes.status: closed',
});
@@ -71,13 +71,13 @@ describe('GET status', () => {
method: 'get',
});
- const theContext = await createRouteContext(
+ const { context } = await createRouteContext(
createMockSavedObjectsRepository({
caseSavedObject: [{ ...mockCases[0], id: 'throw-error-find' }],
})
);
- const response = await routeHandler(theContext, request, kibanaResponseFactory);
+ const response = await routeHandler(context, request, kibanaResponseFactory);
expect(response.status).toEqual(404);
});
});
diff --git a/x-pack/plugins/case/server/routes/api/cases/user_actions/get_all_user_actions.ts b/x-pack/plugins/case/server/routes/api/cases/user_actions/get_all_user_actions.ts
index 346eec3dde752..06e929cc40e6b 100644
--- a/x-pack/plugins/case/server/routes/api/cases/user_actions/get_all_user_actions.ts
+++ b/x-pack/plugins/case/server/routes/api/cases/user_actions/get_all_user_actions.ts
@@ -7,13 +7,11 @@
import { schema } from '@kbn/config-schema';
-import { CaseUserActionsResponseRt } from '../../../../../common/api';
-import { CASE_SAVED_OBJECT, CASE_COMMENT_SAVED_OBJECT } from '../../../../saved_object_types';
import { RouteDeps } from '../../types';
import { wrapError } from '../../utils';
import { CASE_USER_ACTIONS_URL } from '../../../../../common/constants';
-export function initGetAllUserActionsApi({ userActionService, router }: RouteDeps) {
+export function initGetAllUserActionsApi({ router }: RouteDeps) {
router.get(
{
path: CASE_USER_ACTIONS_URL,
@@ -24,22 +22,16 @@ export function initGetAllUserActionsApi({ userActionService, router }: RouteDep
},
},
async (context, request, response) => {
+ if (!context.case) {
+ return response.badRequest({ body: 'RouteHandlerContext is not registered for cases' });
+ }
+
+ const caseClient = context.case.getCaseClient();
+ const caseId = request.params.case_id;
+
try {
- const client = context.core.savedObjects.client;
- const userActions = await userActionService.getUserActions({
- client,
- caseId: request.params.case_id,
- });
return response.ok({
- body: CaseUserActionsResponseRt.encode(
- userActions.saved_objects.map((ua) => ({
- ...ua.attributes,
- action_id: ua.id,
- case_id: ua.references.find((r) => r.type === CASE_SAVED_OBJECT)?.id ?? '',
- comment_id:
- ua.references.find((r) => r.type === CASE_COMMENT_SAVED_OBJECT)?.id ?? null,
- }))
- ),
+ body: await caseClient.getUserActions({ caseId }),
});
} catch (error) {
return response.customError(wrapError(error));
diff --git a/x-pack/plugins/case/server/routes/api/index.ts b/x-pack/plugins/case/server/routes/api/index.ts
index c399364ea35ec..00660e08bbd83 100644
--- a/x-pack/plugins/case/server/routes/api/index.ts
+++ b/x-pack/plugins/case/server/routes/api/index.ts
@@ -10,7 +10,7 @@ import { initFindCasesApi } from '././cases/find_cases';
import { initGetCaseApi } from './cases/get_case';
import { initPatchCasesApi } from './cases/patch_cases';
import { initPostCaseApi } from './cases/post_case';
-import { initPushCaseUserActionApi } from './cases/push_case';
+import { initPushCaseApi } from './cases/push_case';
import { initGetReportersApi } from './cases/reporters/get_reporters';
import { initGetCasesStatusApi } from './cases/status/get_status';
import { initGetTagsApi } from './cases/tags/get_tags';
@@ -28,7 +28,6 @@ import { initCaseConfigureGetActionConnector } from './cases/configure/get_conne
import { initGetCaseConfigure } from './cases/configure/get_configure';
import { initPatchCaseConfigure } from './cases/configure/patch_configure';
import { initPostCaseConfigure } from './cases/configure/post_configure';
-import { initPostPushToService } from './cases/configure/post_push_to_service';
import { RouteDeps } from './types';
@@ -39,7 +38,7 @@ export function initCaseApi(deps: RouteDeps) {
initGetCaseApi(deps);
initPatchCasesApi(deps);
initPostCaseApi(deps);
- initPushCaseUserActionApi(deps);
+ initPushCaseApi(deps);
initGetAllUserActionsApi(deps);
// Comments
initDeleteCommentApi(deps);
@@ -54,7 +53,6 @@ export function initCaseApi(deps: RouteDeps) {
initGetCaseConfigure(deps);
initPatchCaseConfigure(deps);
initPostCaseConfigure(deps);
- initPostPushToService(deps);
// Reporters
initGetReportersApi(deps);
// Status
diff --git a/x-pack/plugins/case/server/routes/api/utils.ts b/x-pack/plugins/case/server/routes/api/utils.ts
index b7e556daffbd9..e2751c05d880a 100644
--- a/x-pack/plugins/case/server/routes/api/utils.ts
+++ b/x-pack/plugins/case/server/routes/api/utils.ts
@@ -191,11 +191,11 @@ export const sortToSnake = (sortField: string): SortFieldCase => {
export const escapeHatch = schema.object({}, { unknowns: 'allow' });
-const isUserContext = (context: CommentRequest): context is CommentRequestUserType => {
+export const isUserContext = (context: CommentRequest): context is CommentRequestUserType => {
return context.type === CommentType.user;
};
-const isAlertContext = (context: CommentRequest): context is CommentRequestAlertType => {
+export const isAlertContext = (context: CommentRequest): context is CommentRequestAlertType => {
return context.type === CommentType.alert;
};
@@ -206,17 +206,3 @@ export const decodeComment = (comment: CommentRequest) => {
pipe(excess(ContextTypeAlertRt).decode(comment), fold(throwErrors(badRequest), identity));
}
};
-
-export const getCommentContextFromAttributes = (
- attributes: CommentAttributes
-): CommentRequestUserType | CommentRequestAlertType =>
- isUserContext(attributes)
- ? {
- type: CommentType.user,
- comment: attributes.comment,
- }
- : {
- type: CommentType.alert,
- alertId: attributes.alertId,
- index: attributes.index,
- };
diff --git a/x-pack/plugins/case/server/services/alerts/index.ts b/x-pack/plugins/case/server/services/alerts/index.ts
index 4f0d415f23b50..2776d6b40761e 100644
--- a/x-pack/plugins/case/server/services/alerts/index.ts
+++ b/x-pack/plugins/case/server/services/alerts/index.ts
@@ -19,6 +19,24 @@ interface UpdateAlertsStatusArgs {
index: string;
}
+interface GetAlertsArgs {
+ request: KibanaRequest;
+ ids: string[];
+ index: string;
+}
+
+interface Alert {
+ _id: string;
+ _index: string;
+ _source: Record;
+}
+
+interface AlertsResponse {
+ hits: {
+ hits: Alert[];
+ };
+}
+
export class AlertService {
private isInitialized = false;
private esClient?: IClusterClient;
@@ -55,4 +73,30 @@ export class AlertService {
return result;
}
+
+ public async getAlerts({ request, ids, index }: GetAlertsArgs): Promise {
+ if (!this.isInitialized) {
+ throw new Error('AlertService not initialized');
+ }
+
+ // The above check makes sure that esClient is defined.
+ const result = await this.esClient!.asScoped(request).asCurrentUser.search({
+ index,
+ body: {
+ query: {
+ bool: {
+ filter: {
+ bool: {
+ should: ids.map((_id) => ({ match: { _id } })),
+ minimum_should_match: 1,
+ },
+ },
+ },
+ },
+ },
+ ignore_unavailable: true,
+ });
+
+ return result.body;
+ }
}
diff --git a/x-pack/plugins/case/server/services/mocks.ts b/x-pack/plugins/case/server/services/mocks.ts
index 7c8b44b297362..0b3615793ef85 100644
--- a/x-pack/plugins/case/server/services/mocks.ts
+++ b/x-pack/plugins/case/server/services/mocks.ts
@@ -59,4 +59,5 @@ export const createUserActionServiceMock = (): CaseUserActionServiceMock => ({
export const createAlertServiceMock = (): AlertServiceMock => ({
initialize: jest.fn(),
updateAlertsStatus: jest.fn(),
+ getAlerts: jest.fn(),
});
diff --git a/x-pack/plugins/cross_cluster_replication/tsconfig.json b/x-pack/plugins/cross_cluster_replication/tsconfig.json
new file mode 100644
index 0000000000000..9c7590b9c2553
--- /dev/null
+++ b/x-pack/plugins/cross_cluster_replication/tsconfig.json
@@ -0,0 +1,31 @@
+{
+ "extends": "../../../tsconfig.base.json",
+ "compilerOptions": {
+ "composite": true,
+ "outDir": "./target/types",
+ "emitDeclarationOnly": true,
+ "declaration": true,
+ "declarationMap": true
+ },
+ "include": [
+ "common/**/*",
+ "public/**/*",
+ "server/**/*",
+ ],
+ "references": [
+ { "path": "../../../src/core/tsconfig.json" },
+ // required plugins
+ { "path": "../../../src/plugins/home/tsconfig.json" },
+ { "path": "../licensing/tsconfig.json" },
+ { "path": "../../../src/plugins/management/tsconfig.json" },
+ { "path": "../remote_clusters/tsconfig.json" },
+ { "path": "../index_management/tsconfig.json" },
+ { "path": "../features/tsconfig.json" },
+ // optional plugins
+ { "path": "../../../src/plugins/usage_collection/tsconfig.json" },
+ // required bundles
+ { "path": "../../../src/plugins/kibana_react/tsconfig.json" },
+ { "path": "../../../src/plugins/es_ui_shared/tsconfig.json" },
+ { "path": "../../../src/plugins/data/tsconfig.json" },
+ ]
+}
diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/extend_button.tsx b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/extend_button.tsx
index 1e2678912ce99..381c44b1bf7be 100644
--- a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/extend_button.tsx
+++ b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/extend_button.tsx
@@ -38,7 +38,7 @@ const ExtendConfirm = ({
defaultMessage: 'Extend search session expiration',
});
const confirm = i18n.translate('xpack.data.mgmt.searchSessions.extendModal.extendButton', {
- defaultMessage: 'Extend',
+ defaultMessage: 'Extend expiration',
});
const extend = i18n.translate('xpack.data.mgmt.searchSessions.extendModal.dontExtendButton', {
defaultMessage: 'Cancel',
@@ -58,7 +58,9 @@ const ExtendConfirm = ({
onCancel={onConfirmDismiss}
onConfirm={async () => {
setIsLoading(true);
- await api.sendExtend(id, `${extendByDuration.asMilliseconds()}ms`);
+ await api.sendExtend(id, `${newExpiration.toISOString()}`);
+ setIsLoading(false);
+ onConfirmDismiss();
onActionComplete();
}}
confirmButtonText={confirm}
diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/get_action.tsx b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/get_action.tsx
index edc5037f1dbec..1a2b2cfb4ecec 100644
--- a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/get_action.tsx
+++ b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/get_action.tsx
@@ -12,15 +12,24 @@ import { SearchSessionsMgmtAPI } from '../../lib/api';
import { UISession } from '../../types';
import { DeleteButton } from './delete_button';
import { ExtendButton } from './extend_button';
+import { InspectButton } from './inspect_button';
import { ACTION, OnActionComplete } from './types';
export const getAction = (
api: SearchSessionsMgmtAPI,
actionType: string,
- { id, name, expires }: UISession,
+ uiSession: UISession,
onActionComplete: OnActionComplete
): IClickActionDescriptor | null => {
+ const { id, name, expires } = uiSession;
switch (actionType) {
+ case ACTION.INSPECT:
+ return {
+ iconType: 'document',
+ textColor: 'default',
+ label: ,
+ };
+
case ACTION.DELETE:
return {
iconType: 'crossInACircleFilled',
diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/inspect_button.scss b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/inspect_button.scss
new file mode 100644
index 0000000000000..a43bb65927ed4
--- /dev/null
+++ b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/inspect_button.scss
@@ -0,0 +1,6 @@
+.searchSessionsFlyout .euiFlyoutBody__overflowContent {
+ height: 100%;
+ > div {
+ height: 100%;
+ }
+}
\ No newline at end of file
diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/inspect_button.tsx b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/inspect_button.tsx
new file mode 100644
index 0000000000000..86dca64909b55
--- /dev/null
+++ b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/inspect_button.tsx
@@ -0,0 +1,134 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import {
+ EuiFlyout,
+ EuiFlyoutBody,
+ EuiFlyoutHeader,
+ EuiPortal,
+ EuiSpacer,
+ EuiText,
+ EuiTitle,
+} from '@elastic/eui';
+import { FormattedMessage } from '@kbn/i18n/react';
+import React, { Component, Fragment } from 'react';
+import { UISession } from '../../types';
+import { TableText } from '..';
+import { CodeEditor } from '../../../../../../../../src/plugins/kibana_react/public';
+import './inspect_button.scss';
+
+interface Props {
+ searchSession: UISession;
+}
+
+interface State {
+ isFlyoutVisible: boolean;
+}
+
+export class InspectButton extends Component {
+ constructor(props: Props) {
+ super(props);
+
+ this.state = {
+ isFlyoutVisible: false,
+ };
+
+ this.closeFlyout = this.closeFlyout.bind(this);
+ this.showFlyout = this.showFlyout.bind(this);
+ }
+
+ public renderInfo() {
+ return (
+
+ {}}
+ options={{
+ readOnly: true,
+ lineNumbers: 'off',
+ fontSize: 12,
+ minimap: {
+ enabled: false,
+ },
+ scrollBeyondLastLine: false,
+ wordWrap: 'on',
+ wrappingIndent: 'indent',
+ automaticLayout: true,
+ }}
+ />
+
+ );
+ }
+
+ public render() {
+ let flyout;
+
+ if (this.state.isFlyoutVisible) {
+ flyout = (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {this.renderInfo()}
+
+
+
+
+ );
+ }
+
+ return (
+
+
+
+
+ {flyout}
+
+ );
+ }
+
+ private closeFlyout = () => {
+ this.setState({
+ isFlyoutVisible: false,
+ });
+ };
+
+ private showFlyout = () => {
+ this.setState({ isFlyoutVisible: true });
+ };
+}
diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/types.ts b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/types.ts
index 5f82f16adcbb6..c94b6aa8495c7 100644
--- a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/types.ts
+++ b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/actions/types.ts
@@ -8,6 +8,7 @@
export type OnActionComplete = () => void;
export enum ACTION {
+ INSPECT = 'inspect',
EXTEND = 'extend',
DELETE = 'delete',
}
diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/status.test.tsx b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/status.test.tsx
index 3d92f349fd2d6..f1d4f2ab379a0 100644
--- a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/status.test.tsx
+++ b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/components/status.test.tsx
@@ -31,6 +31,8 @@ describe('Background Search Session management status labels', () => {
status: SearchSessionStatus.IN_PROGRESS,
created: '2020-12-02T00:19:32Z',
expires: '2020-12-07T00:19:32Z',
+ initialState: {},
+ restoreState: {},
};
});
diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/api.test.ts b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/api.test.ts
index 86acbcdb53001..10b2ac3ec1d4c 100644
--- a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/api.test.ts
+++ b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/api.test.ts
@@ -46,7 +46,13 @@ describe('Search Sessions Management API', () => {
saved_objects: [
{
id: 'hello-pizza-123',
- attributes: { name: 'Veggie', appId: 'pizza', status: 'complete' },
+ attributes: {
+ name: 'Veggie',
+ appId: 'pizza',
+ status: 'complete',
+ initialState: {},
+ restoreState: {},
+ },
},
],
} as SavedObjectsFindResponse;
@@ -61,6 +67,7 @@ describe('Search Sessions Management API', () => {
Array [
Object {
"actions": Array [
+ "inspect",
"extend",
"delete",
],
@@ -68,8 +75,10 @@ describe('Search Sessions Management API', () => {
"created": undefined,
"expires": undefined,
"id": "hello-pizza-123",
+ "initialState": Object {},
"name": "Veggie",
"reloadUrl": "hello-cool-undefined-url",
+ "restoreState": Object {},
"restoreUrl": "hello-cool-undefined-url",
"status": "complete",
},
@@ -168,7 +177,7 @@ describe('Search Sessions Management API', () => {
describe('extend', () => {
beforeEach(() => {
- sessionsClient.find = jest.fn().mockImplementation(async () => {
+ sessionsClient.extend = jest.fn().mockImplementation(async () => {
return {
saved_objects: [
{
@@ -188,6 +197,20 @@ describe('Search Sessions Management API', () => {
});
await api.sendExtend('my-id', '5d');
+ expect(sessionsClient.extend).toHaveBeenCalledTimes(1);
+ expect(mockCoreStart.notifications.toasts.addSuccess).toHaveBeenCalled();
+ });
+
+ test('displays error on reject', async () => {
+ sessionsClient.extend = jest.fn().mockRejectedValue({});
+ const api = new SearchSessionsMgmtAPI(sessionsClient, mockConfig, {
+ urls: mockUrls,
+ notifications: mockCoreStart.notifications,
+ application: mockCoreStart.application,
+ });
+ await api.sendExtend('my-id', '5d');
+
+ expect(sessionsClient.extend).toHaveBeenCalledTimes(1);
expect(mockCoreStart.notifications.toasts.addError).toHaveBeenCalled();
});
});
diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/api.ts b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/api.ts
index 264556f91cc37..39da58cb76918 100644
--- a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/api.ts
+++ b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/api.ts
@@ -21,6 +21,7 @@ type UrlGeneratorsStart = SharePluginStart['urlGenerators'];
function getActions(status: SearchSessionStatus) {
const actions: ACTION[] = [];
+ actions.push(ACTION.INSPECT);
if (status === SearchSessionStatus.IN_PROGRESS || status === SearchSessionStatus.COMPLETE) {
actions.push(ACTION.EXTEND);
actions.push(ACTION.DELETE);
@@ -78,6 +79,8 @@ const mapToUISession = (urls: UrlGeneratorsStart, config: SessionsConfigSchema)
actions,
restoreUrl,
reloadUrl,
+ initialState,
+ restoreState,
};
};
@@ -166,9 +169,6 @@ export class SearchSessionsMgmtAPI {
}),
});
} catch (err) {
- // eslint-disable-next-line no-console
- console.error(err);
-
this.deps.notifications.toasts.addError(err, {
title: i18n.translate('xpack.data.mgmt.searchSessions.api.deletedError', {
defaultMessage: 'Failed to delete the search session!',
@@ -178,11 +178,21 @@ export class SearchSessionsMgmtAPI {
}
// Extend
- public async sendExtend(id: string, ttl: string): Promise {
- this.deps.notifications.toasts.addError(new Error('Not implemented'), {
- title: i18n.translate('xpack.data.mgmt.searchSessions.api.extendError', {
- defaultMessage: 'Failed to extend the session expiration!',
- }),
- });
+ public async sendExtend(id: string, expires: string): Promise {
+ try {
+ await this.sessionsClient.extend(id, expires);
+
+ this.deps.notifications.toasts.addSuccess({
+ title: i18n.translate('xpack.data.mgmt.searchSessions.api.extended', {
+ defaultMessage: 'The search session was extended.',
+ }),
+ });
+ } catch (err) {
+ this.deps.notifications.toasts.addError(err, {
+ title: i18n.translate('xpack.data.mgmt.searchSessions.api.extendError', {
+ defaultMessage: 'Failed to extend the search session!',
+ }),
+ });
+ }
}
}
diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/get_columns.test.tsx b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/get_columns.test.tsx
index 2aab35e34a2d0..fc0a8849006d3 100644
--- a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/get_columns.test.tsx
+++ b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/lib/get_columns.test.tsx
@@ -66,6 +66,8 @@ describe('Search Sessions Management table column factory', () => {
status: SearchSessionStatus.IN_PROGRESS,
created: '2020-12-02T00:19:32Z',
expires: '2020-12-07T00:19:32Z',
+ initialState: {},
+ restoreState: {},
};
});
diff --git a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/types.ts b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/types.ts
index d9aea4ddae93e..e7b48f319a8a8 100644
--- a/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/types.ts
+++ b/x-pack/plugins/data_enhanced/public/search/sessions_mgmt/types.ts
@@ -32,4 +32,6 @@ export interface UISession {
actions?: ACTION[];
reloadUrl: string;
restoreUrl: string;
+ initialState: Record;
+ restoreState: Record;
}
diff --git a/x-pack/plugins/encrypted_saved_objects/server/config.test.ts b/x-pack/plugins/encrypted_saved_objects/server/config.test.ts
index 3633dae824a2b..1cc5f7974cb13 100644
--- a/x-pack/plugins/encrypted_saved_objects/server/config.test.ts
+++ b/x-pack/plugins/encrypted_saved_objects/server/config.test.ts
@@ -5,10 +5,7 @@
* 2.0.
*/
-jest.mock('crypto', () => ({ randomBytes: jest.fn() }));
-
-import { loggingSystemMock } from 'src/core/server/mocks';
-import { createConfig, ConfigSchema } from './config';
+import { ConfigSchema } from './config';
describe('config schema', () => {
it('generates proper defaults', () => {
@@ -32,6 +29,17 @@ describe('config schema', () => {
}
`);
+ expect(ConfigSchema.validate({ encryptionKey: 'z'.repeat(32) }, { dist: true }))
+ .toMatchInlineSnapshot(`
+ Object {
+ "enabled": true,
+ "encryptionKey": "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz",
+ "keyRotation": Object {
+ "decryptionOnlyKeys": Array [],
+ },
+ }
+ `);
+
expect(ConfigSchema.validate({}, { dist: true })).toMatchInlineSnapshot(`
Object {
"enabled": true,
@@ -79,6 +87,18 @@ describe('config schema', () => {
);
});
+ it('should not allow `null` value for the encryption key', () => {
+ expect(() => ConfigSchema.validate({ encryptionKey: null })).toThrowErrorMatchingInlineSnapshot(
+ `"[encryptionKey]: expected value of type [string] but got [null]"`
+ );
+
+ expect(() =>
+ ConfigSchema.validate({ encryptionKey: null }, { dist: true })
+ ).toThrowErrorMatchingInlineSnapshot(
+ `"[encryptionKey]: expected value of type [string] but got [null]"`
+ );
+ });
+
it('should throw error if any of the xpack.encryptedSavedObjects.keyRotation.decryptionOnlyKeys is less than 32 characters', () => {
expect(() =>
ConfigSchema.validate({
@@ -121,43 +141,3 @@ describe('config schema', () => {
);
});
});
-
-describe('createConfig()', () => {
- it('should log a warning, set xpack.encryptedSavedObjects.encryptionKey and usingEphemeralEncryptionKey=true when encryptionKey is not set', () => {
- const mockRandomBytes = jest.requireMock('crypto').randomBytes;
- mockRandomBytes.mockReturnValue('ab'.repeat(16));
-
- const logger = loggingSystemMock.create().get();
- const config = createConfig(ConfigSchema.validate({}, { dist: true }), logger);
- expect(config).toEqual({
- enabled: true,
- encryptionKey: 'ab'.repeat(16),
- keyRotation: { decryptionOnlyKeys: [] },
- usingEphemeralEncryptionKey: true,
- });
-
- expect(loggingSystemMock.collect(logger).warn).toMatchInlineSnapshot(`
- Array [
- Array [
- "Generating a random key for xpack.encryptedSavedObjects.encryptionKey. To decrypt encrypted saved objects attributes after restart, please set xpack.encryptedSavedObjects.encryptionKey in the kibana.yml or use the bin/kibana-encryption-keys command.",
- ],
- ]
- `);
- });
-
- it('should not log a warning and set usingEphemeralEncryptionKey=false when encryptionKey is set', async () => {
- const logger = loggingSystemMock.create().get();
- const config = createConfig(
- ConfigSchema.validate({ encryptionKey: 'supersecret'.repeat(3) }, { dist: true }),
- logger
- );
- expect(config).toEqual({
- enabled: true,
- encryptionKey: 'supersecret'.repeat(3),
- keyRotation: { decryptionOnlyKeys: [] },
- usingEphemeralEncryptionKey: false,
- });
-
- expect(loggingSystemMock.collect(logger).warn).toEqual([]);
- });
-});
diff --git a/x-pack/plugins/encrypted_saved_objects/server/config.ts b/x-pack/plugins/encrypted_saved_objects/server/config.ts
index 40db0187162d0..2bcf0e9b69511 100644
--- a/x-pack/plugins/encrypted_saved_objects/server/config.ts
+++ b/x-pack/plugins/encrypted_saved_objects/server/config.ts
@@ -5,11 +5,9 @@
* 2.0.
*/
-import crypto from 'crypto';
import { schema, TypeOf } from '@kbn/config-schema';
-import { Logger } from 'src/core/server';
-export type ConfigType = ReturnType;
+export type ConfigType = TypeOf;
export const ConfigSchema = schema.object(
{
@@ -33,23 +31,3 @@ export const ConfigSchema = schema.object(
},
}
);
-
-export function createConfig(config: TypeOf, logger: Logger) {
- let encryptionKey = config.encryptionKey;
- const usingEphemeralEncryptionKey = encryptionKey === undefined;
- if (encryptionKey === undefined) {
- logger.warn(
- 'Generating a random key for xpack.encryptedSavedObjects.encryptionKey. ' +
- 'To decrypt encrypted saved objects attributes after restart, ' +
- 'please set xpack.encryptedSavedObjects.encryptionKey in the kibana.yml or use the bin/kibana-encryption-keys command.'
- );
-
- encryptionKey = crypto.randomBytes(16).toString('hex');
- }
-
- return {
- ...config,
- encryptionKey,
- usingEphemeralEncryptionKey,
- };
-}
diff --git a/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.test.ts b/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.test.ts
index 1760a85806786..f70810943d179 100644
--- a/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.test.ts
+++ b/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.test.ts
@@ -226,6 +226,72 @@ describe('#stripOrDecryptAttributes', () => {
);
});
});
+
+ describe('without encryption key', () => {
+ beforeEach(() => {
+ service = new EncryptedSavedObjectsService({
+ logger: loggingSystemMock.create().get(),
+ audit: mockAuditLogger,
+ });
+ });
+
+ it('does not fail if none of attributes are supposed to be encrypted', async () => {
+ const attributes = { attrOne: 'one', attrTwo: 'two', attrThree: 'three' };
+
+ service.registerType({ type: 'known-type-1', attributesToEncrypt: new Set(['attrFour']) });
+
+ await expect(
+ service.stripOrDecryptAttributes({ id: 'known-id', type: 'known-type-1' }, attributes)
+ ).resolves.toEqual({ attributes: { attrOne: 'one', attrTwo: 'two', attrThree: 'three' } });
+ });
+
+ it('does not fail if there are attributes are supposed to be encrypted, but should be stripped', async () => {
+ const attributes = { attrOne: 'one', attrTwo: 'two', attrThree: 'three' };
+
+ service.registerType({
+ type: 'known-type-1',
+ attributesToEncrypt: new Set(['attrOne', 'attrThree']),
+ });
+
+ await expect(
+ service.stripOrDecryptAttributes({ id: 'known-id', type: 'known-type-1' }, attributes)
+ ).resolves.toEqual({ attributes: { attrTwo: 'two' } });
+ });
+
+ it('fails if needs to decrypt any attribute', async () => {
+ service.registerType({
+ type: 'known-type-1',
+ attributesToEncrypt: new Set([
+ 'attrOne',
+ { key: 'attrThree', dangerouslyExposeValue: true },
+ ]),
+ });
+
+ const mockUser = mockAuthenticatedUser();
+ const { attributes, error } = await service.stripOrDecryptAttributes(
+ { type: 'known-type-1', id: 'object-id' },
+ { attrOne: 'one', attrTwo: 'two', attrThree: 'three' },
+ undefined,
+ { user: mockUser }
+ );
+
+ expect(attributes).toEqual({ attrTwo: 'two' });
+
+ const encryptionError = error as EncryptionError;
+ expect(encryptionError.attributeName).toBe('attrThree');
+ expect(encryptionError.message).toBe('Unable to decrypt attribute "attrThree"');
+ expect(encryptionError.cause).toEqual(
+ new Error('Decryption is disabled because of missing decryption keys.')
+ );
+
+ expect(mockAuditLogger.decryptAttributeFailure).toHaveBeenCalledTimes(1);
+ expect(mockAuditLogger.decryptAttributeFailure).toHaveBeenCalledWith(
+ 'attrThree',
+ { type: 'known-type-1', id: 'object-id' },
+ mockUser
+ );
+ });
+ });
});
describe('#encryptAttributes', () => {
@@ -465,6 +531,58 @@ describe('#encryptAttributes', () => {
mockUser
);
});
+
+ describe('without encryption key', () => {
+ beforeEach(() => {
+ service = new EncryptedSavedObjectsService({
+ logger: loggingSystemMock.create().get(),
+ audit: mockAuditLogger,
+ });
+ });
+
+ it('does not fail if none of attributes are supposed to be encrypted', async () => {
+ const attributes = { attrOne: 'one', attrTwo: 'two', attrThree: 'three' };
+
+ service.registerType({ type: 'known-type-1', attributesToEncrypt: new Set(['attrFour']) });
+
+ await expect(
+ service.encryptAttributes({ type: 'known-type-1', id: 'object-id' }, attributes)
+ ).resolves.toEqual({
+ attrOne: 'one',
+ attrTwo: 'two',
+ attrThree: 'three',
+ });
+ expect(mockAuditLogger.encryptAttributesSuccess).not.toHaveBeenCalled();
+ });
+
+ it('fails if needs to encrypt any attribute', async () => {
+ const attributes = { attrOne: 'one', attrTwo: 'two', attrThree: 'three' };
+ service.registerType({
+ type: 'known-type-1',
+ attributesToEncrypt: new Set(['attrOne', 'attrThree']),
+ });
+
+ const mockUser = mockAuthenticatedUser();
+ await expect(
+ service.encryptAttributes({ type: 'known-type-1', id: 'object-id' }, attributes, {
+ user: mockUser,
+ })
+ ).rejects.toThrowError(EncryptionError);
+
+ expect(attributes).toEqual({
+ attrOne: 'one',
+ attrTwo: 'two',
+ attrThree: 'three',
+ });
+ expect(mockAuditLogger.encryptAttributesSuccess).not.toHaveBeenCalled();
+ expect(mockAuditLogger.encryptAttributeFailure).toHaveBeenCalledTimes(1);
+ expect(mockAuditLogger.encryptAttributeFailure).toHaveBeenCalledWith(
+ 'attrOne',
+ { type: 'known-type-1', id: 'object-id' },
+ mockUser
+ );
+ });
+ });
});
describe('#decryptAttributes', () => {
@@ -1099,6 +1217,88 @@ describe('#decryptAttributes', () => {
expect(decryptionOnlyCryptoTwo.decrypt).not.toHaveBeenCalled();
});
});
+
+ describe('without encryption key', () => {
+ beforeEach(() => {
+ service = new EncryptedSavedObjectsService({
+ logger: loggingSystemMock.create().get(),
+ audit: mockAuditLogger,
+ });
+ });
+
+ it('does not fail if none of attributes are supposed to be decrypted', async () => {
+ const attributes = { attrOne: 'one', attrTwo: 'two', attrThree: 'three' };
+
+ service = new EncryptedSavedObjectsService({
+ decryptionOnlyCryptos: [],
+ logger: loggingSystemMock.create().get(),
+ audit: mockAuditLogger,
+ });
+ service.registerType({ type: 'known-type-1', attributesToEncrypt: new Set(['attrFour']) });
+
+ await expect(
+ service.decryptAttributes({ type: 'known-type-1', id: 'object-id' }, attributes)
+ ).resolves.toEqual({
+ attrOne: 'one',
+ attrTwo: 'two',
+ attrThree: 'three',
+ });
+ expect(mockAuditLogger.decryptAttributesSuccess).not.toHaveBeenCalled();
+ });
+
+ it('does not fail if can decrypt attributes with decryption only keys', async () => {
+ const decryptionOnlyCryptoOne = createNodeCryptMock('old-key-one');
+ decryptionOnlyCryptoOne.decrypt.mockImplementation(
+ async (encryptedOutput: string | Buffer, aad?: string) => `${encryptedOutput}||${aad}`
+ );
+
+ service = new EncryptedSavedObjectsService({
+ decryptionOnlyCryptos: [decryptionOnlyCryptoOne],
+ logger: loggingSystemMock.create().get(),
+ audit: mockAuditLogger,
+ });
+ service.registerType({
+ type: 'known-type-1',
+ attributesToEncrypt: new Set(['attrOne', 'attrThree', 'attrFour']),
+ });
+
+ const attributes = { attrOne: 'one', attrTwo: 'two', attrThree: 'three', attrFour: null };
+ await expect(
+ service.decryptAttributes({ type: 'known-type-1', id: 'object-id' }, attributes)
+ ).resolves.toEqual({
+ attrOne: 'one||["known-type-1","object-id",{"attrTwo":"two"}]',
+ attrTwo: 'two',
+ attrThree: 'three||["known-type-1","object-id",{"attrTwo":"two"}]',
+ attrFour: null,
+ });
+ expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledTimes(1);
+ expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledWith(
+ ['attrOne', 'attrThree'],
+ { type: 'known-type-1', id: 'object-id' },
+ undefined
+ );
+ });
+
+ it('fails if needs to decrypt any attribute', async () => {
+ const attributes = { attrOne: 'one', attrTwo: 'two', attrThree: 'three' };
+
+ service.registerType({ type: 'known-type-1', attributesToEncrypt: new Set(['attrOne']) });
+
+ const mockUser = mockAuthenticatedUser();
+ await expect(
+ service.decryptAttributes({ type: 'known-type-1', id: 'object-id' }, attributes, {
+ user: mockUser,
+ })
+ ).rejects.toThrowError(EncryptionError);
+
+ expect(mockAuditLogger.decryptAttributesSuccess).not.toHaveBeenCalled();
+ expect(mockAuditLogger.decryptAttributeFailure).toHaveBeenCalledWith(
+ 'attrOne',
+ { type: 'known-type-1', id: 'object-id' },
+ mockUser
+ );
+ });
+ });
});
describe('#encryptAttributesSync', () => {
@@ -1283,6 +1483,58 @@ describe('#encryptAttributesSync', () => {
attrThree: 'three',
});
});
+
+ describe('without encryption key', () => {
+ beforeEach(() => {
+ service = new EncryptedSavedObjectsService({
+ logger: loggingSystemMock.create().get(),
+ audit: mockAuditLogger,
+ });
+ });
+
+ it('does not fail if none of attributes are supposed to be encrypted', () => {
+ const attributes = { attrOne: 'one', attrTwo: 'two', attrThree: 'three' };
+
+ service.registerType({ type: 'known-type-1', attributesToEncrypt: new Set(['attrFour']) });
+
+ expect(
+ service.encryptAttributesSync({ type: 'known-type-1', id: 'object-id' }, attributes)
+ ).toEqual({
+ attrOne: 'one',
+ attrTwo: 'two',
+ attrThree: 'three',
+ });
+ expect(mockAuditLogger.encryptAttributesSuccess).not.toHaveBeenCalled();
+ });
+
+ it('fails if needs to encrypt any attribute', () => {
+ const attributes = { attrOne: 'one', attrTwo: 'two', attrThree: 'three' };
+ service.registerType({
+ type: 'known-type-1',
+ attributesToEncrypt: new Set(['attrOne', 'attrThree']),
+ });
+
+ const mockUser = mockAuthenticatedUser();
+ expect(() =>
+ service.encryptAttributesSync({ type: 'known-type-1', id: 'object-id' }, attributes, {
+ user: mockUser,
+ })
+ ).toThrowError(EncryptionError);
+
+ expect(attributes).toEqual({
+ attrOne: 'one',
+ attrTwo: 'two',
+ attrThree: 'three',
+ });
+ expect(mockAuditLogger.encryptAttributesSuccess).not.toHaveBeenCalled();
+ expect(mockAuditLogger.encryptAttributeFailure).toHaveBeenCalledTimes(1);
+ expect(mockAuditLogger.encryptAttributeFailure).toHaveBeenCalledWith(
+ 'attrOne',
+ { type: 'known-type-1', id: 'object-id' },
+ mockUser
+ );
+ });
+ });
});
describe('#decryptAttributesSync', () => {
@@ -1784,4 +2036,86 @@ describe('#decryptAttributesSync', () => {
expect(decryptionOnlyCryptoTwo.decryptSync).not.toHaveBeenCalled();
});
});
+
+ describe('without encryption key', () => {
+ beforeEach(() => {
+ service = new EncryptedSavedObjectsService({
+ logger: loggingSystemMock.create().get(),
+ audit: mockAuditLogger,
+ });
+ });
+
+ it('does not fail if none of attributes are supposed to be decrypted', () => {
+ const attributes = { attrOne: 'one', attrTwo: 'two', attrThree: 'three' };
+
+ service = new EncryptedSavedObjectsService({
+ decryptionOnlyCryptos: [],
+ logger: loggingSystemMock.create().get(),
+ audit: mockAuditLogger,
+ });
+ service.registerType({ type: 'known-type-1', attributesToEncrypt: new Set(['attrFour']) });
+
+ expect(
+ service.decryptAttributesSync({ type: 'known-type-1', id: 'object-id' }, attributes)
+ ).toEqual({
+ attrOne: 'one',
+ attrTwo: 'two',
+ attrThree: 'three',
+ });
+ expect(mockAuditLogger.decryptAttributesSuccess).not.toHaveBeenCalled();
+ });
+
+ it('does not fail if can decrypt attributes with decryption only keys', () => {
+ const decryptionOnlyCryptoOne = createNodeCryptMock('old-key-one');
+ decryptionOnlyCryptoOne.decryptSync.mockImplementation(
+ (encryptedOutput: string | Buffer, aad?: string) => `${encryptedOutput}||${aad}`
+ );
+
+ service = new EncryptedSavedObjectsService({
+ decryptionOnlyCryptos: [decryptionOnlyCryptoOne],
+ logger: loggingSystemMock.create().get(),
+ audit: mockAuditLogger,
+ });
+ service.registerType({
+ type: 'known-type-1',
+ attributesToEncrypt: new Set(['attrOne', 'attrThree', 'attrFour']),
+ });
+
+ const attributes = { attrOne: 'one', attrTwo: 'two', attrThree: 'three', attrFour: null };
+ expect(
+ service.decryptAttributesSync({ type: 'known-type-1', id: 'object-id' }, attributes)
+ ).toEqual({
+ attrOne: 'one||["known-type-1","object-id",{"attrTwo":"two"}]',
+ attrTwo: 'two',
+ attrThree: 'three||["known-type-1","object-id",{"attrTwo":"two"}]',
+ attrFour: null,
+ });
+ expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledTimes(1);
+ expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledWith(
+ ['attrOne', 'attrThree'],
+ { type: 'known-type-1', id: 'object-id' },
+ undefined
+ );
+ });
+
+ it('fails if needs to decrypt any attribute', () => {
+ const attributes = { attrOne: 'one', attrTwo: 'two', attrThree: 'three' };
+
+ service.registerType({ type: 'known-type-1', attributesToEncrypt: new Set(['attrOne']) });
+
+ const mockUser = mockAuthenticatedUser();
+ expect(() =>
+ service.decryptAttributesSync({ type: 'known-type-1', id: 'object-id' }, attributes, {
+ user: mockUser,
+ })
+ ).toThrowError(EncryptionError);
+
+ expect(mockAuditLogger.decryptAttributesSuccess).not.toHaveBeenCalled();
+ expect(mockAuditLogger.decryptAttributeFailure).toHaveBeenCalledWith(
+ 'attrOne',
+ { type: 'known-type-1', id: 'object-id' },
+ mockUser
+ );
+ });
+ });
});
diff --git a/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.ts b/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.ts
index 91a3cfc921624..23aef07ff8781 100644
--- a/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.ts
+++ b/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.ts
@@ -77,7 +77,7 @@ interface EncryptedSavedObjectsServiceOptions {
/**
* NodeCrypto instance used for both encryption and decryption.
*/
- primaryCrypto: Crypto;
+ primaryCrypto?: Crypto;
/**
* NodeCrypto instances used ONLY for decryption (i.e. rotated encryption keys).
@@ -293,12 +293,17 @@ export class EncryptedSavedObjectsService {
let iteratorResult = iterator.next();
while (!iteratorResult.done) {
const [attributeValue, encryptionAAD] = iteratorResult.value;
- try {
- iteratorResult = iterator.next(
- await this.options.primaryCrypto.encrypt(attributeValue, encryptionAAD)
- );
- } catch (err) {
- iterator.throw!(err);
+ // We check this inside of the iterator to throw only if we do need to encrypt anything.
+ if (this.options.primaryCrypto) {
+ try {
+ iteratorResult = iterator.next(
+ await this.options.primaryCrypto.encrypt(attributeValue, encryptionAAD)
+ );
+ } catch (err) {
+ iterator.throw!(err);
+ }
+ } else {
+ iterator.throw!(new Error('Encryption is disabled because of missing encryption key.'));
}
}
@@ -324,12 +329,17 @@ export class EncryptedSavedObjectsService {
let iteratorResult = iterator.next();
while (!iteratorResult.done) {
const [attributeValue, encryptionAAD] = iteratorResult.value;
- try {
- iteratorResult = iterator.next(
- this.options.primaryCrypto.encryptSync(attributeValue, encryptionAAD)
- );
- } catch (err) {
- iterator.throw!(err);
+ // We check this inside of the iterator to throw only if we do need to encrypt anything.
+ if (this.options.primaryCrypto) {
+ try {
+ iteratorResult = iterator.next(
+ this.options.primaryCrypto.encryptSync(attributeValue, encryptionAAD)
+ );
+ } catch (err) {
+ iterator.throw!(err);
+ }
+ } else {
+ iterator.throw!(new Error('Encryption is disabled because of missing encryption key.'));
}
}
@@ -358,7 +368,11 @@ export class EncryptedSavedObjectsService {
while (!iteratorResult.done) {
const [attributeValue, encryptionAAD] = iteratorResult.value;
- let decryptionError;
+ // We check this inside of the iterator to throw only if we do need to decrypt anything.
+ let decryptionError =
+ decrypters.length === 0
+ ? new Error('Decryption is disabled because of missing decryption keys.')
+ : undefined;
for (const decrypter of decrypters) {
try {
iteratorResult = iterator.next(await decrypter.decrypt(attributeValue, encryptionAAD));
@@ -402,7 +416,11 @@ export class EncryptedSavedObjectsService {
while (!iteratorResult.done) {
const [attributeValue, encryptionAAD] = iteratorResult.value;
- let decryptionError;
+ // We check this inside of the iterator to throw only if we do need to decrypt anything.
+ let decryptionError =
+ decrypters.length === 0
+ ? new Error('Decryption is disabled because of missing decryption keys.')
+ : undefined;
for (const decrypter of decrypters) {
try {
iteratorResult = iterator.next(decrypter.decryptSync(attributeValue, encryptionAAD));
@@ -541,6 +559,9 @@ export class EncryptedSavedObjectsService {
return this.options.decryptionOnlyCryptos;
}
- return [this.options.primaryCrypto, ...(this.options.decryptionOnlyCryptos ?? [])];
+ return [
+ ...(this.options.primaryCrypto ? [this.options.primaryCrypto] : []),
+ ...(this.options.decryptionOnlyCryptos ?? []),
+ ];
}
}
diff --git a/x-pack/plugins/encrypted_saved_objects/server/mocks.ts b/x-pack/plugins/encrypted_saved_objects/server/mocks.ts
index 6c8196b2ae03c..edb55513aabf5 100644
--- a/x-pack/plugins/encrypted_saved_objects/server/mocks.ts
+++ b/x-pack/plugins/encrypted_saved_objects/server/mocks.ts
@@ -8,11 +8,13 @@
import { EncryptedSavedObjectsPluginSetup, EncryptedSavedObjectsPluginStart } from './plugin';
import { EncryptedSavedObjectsClient, EncryptedSavedObjectsClientOptions } from './saved_objects';
-function createEncryptedSavedObjectsSetupMock() {
+function createEncryptedSavedObjectsSetupMock(
+ { canEncrypt }: { canEncrypt: boolean } = { canEncrypt: false }
+) {
return {
registerType: jest.fn(),
__legacyCompat: { registerLegacyAPI: jest.fn() },
- usingEphemeralEncryptionKey: true,
+ canEncrypt,
createMigration: jest.fn(),
} as jest.Mocked;
}
diff --git a/x-pack/plugins/encrypted_saved_objects/server/plugin.test.ts b/x-pack/plugins/encrypted_saved_objects/server/plugin.test.ts
index 823a6b0afa9dc..e71332b1c5aa7 100644
--- a/x-pack/plugins/encrypted_saved_objects/server/plugin.test.ts
+++ b/x-pack/plugins/encrypted_saved_objects/server/plugin.test.ts
@@ -19,12 +19,28 @@ describe('EncryptedSavedObjects Plugin', () => {
);
expect(plugin.setup(coreMock.createSetup(), { security: securityMock.createSetup() }))
.toMatchInlineSnapshot(`
- Object {
- "createMigration": [Function],
- "registerType": [Function],
- "usingEphemeralEncryptionKey": true,
- }
- `);
+ Object {
+ "canEncrypt": false,
+ "createMigration": [Function],
+ "registerType": [Function],
+ }
+ `);
+ });
+
+ it('exposes proper contract when encryption key is set', () => {
+ const plugin = new EncryptedSavedObjectsPlugin(
+ coreMock.createPluginInitializerContext(
+ ConfigSchema.validate({ encryptionKey: 'z'.repeat(32) }, { dist: true })
+ )
+ );
+ expect(plugin.setup(coreMock.createSetup(), { security: securityMock.createSetup() }))
+ .toMatchInlineSnapshot(`
+ Object {
+ "canEncrypt": true,
+ "createMigration": [Function],
+ "registerType": [Function],
+ }
+ `);
});
});
diff --git a/x-pack/plugins/encrypted_saved_objects/server/plugin.ts b/x-pack/plugins/encrypted_saved_objects/server/plugin.ts
index e846b133c26e0..c99d6bd32287d 100644
--- a/x-pack/plugins/encrypted_saved_objects/server/plugin.ts
+++ b/x-pack/plugins/encrypted_saved_objects/server/plugin.ts
@@ -6,10 +6,9 @@
*/
import nodeCrypto from '@elastic/node-crypto';
-import { Logger, PluginInitializerContext, CoreSetup, Plugin } from 'src/core/server';
-import { TypeOf } from '@kbn/config-schema';
-import { SecurityPluginSetup } from '../../security/server';
-import { createConfig, ConfigSchema } from './config';
+import type { Logger, PluginInitializerContext, CoreSetup, Plugin } from 'src/core/server';
+import type { SecurityPluginSetup } from '../../security/server';
+import type { ConfigType } from './config';
import {
EncryptedSavedObjectsService,
EncryptedSavedObjectTypeRegistration,
@@ -26,8 +25,11 @@ export interface PluginsSetup {
}
export interface EncryptedSavedObjectsPluginSetup {
+ /**
+ * Indicates if Saved Object encryption is possible. Requires an encryption key to be explicitly set via `xpack.encryptedSavedObjects.encryptionKey`.
+ */
+ canEncrypt: boolean;
registerType: (typeRegistration: EncryptedSavedObjectTypeRegistration) => void;
- usingEphemeralEncryptionKey: boolean;
createMigration: CreateEncryptedSavedObjectsMigrationFn;
}
@@ -50,19 +52,24 @@ export class EncryptedSavedObjectsPlugin
}
public setup(core: CoreSetup, deps: PluginsSetup): EncryptedSavedObjectsPluginSetup {
- const config = createConfig(
- this.initializerContext.config.get>(),
- this.initializerContext.logger.get('config')
- );
- const auditLogger = new EncryptedSavedObjectsAuditLogger(
- deps.security?.audit.getLogger('encryptedSavedObjects')
- );
+ const config = this.initializerContext.config.get();
+ const canEncrypt = config.encryptionKey !== undefined;
+ if (!canEncrypt) {
+ this.logger.warn(
+ 'Saved objects encryption key is not set. This will severely limit Kibana functionality. ' +
+ 'Please set xpack.encryptedSavedObjects.encryptionKey in the kibana.yml or use the bin/kibana-encryption-keys command.'
+ );
+ }
- const primaryCrypto = nodeCrypto({ encryptionKey: config.encryptionKey });
+ const primaryCrypto = config.encryptionKey
+ ? nodeCrypto({ encryptionKey: config.encryptionKey })
+ : undefined;
const decryptionOnlyCryptos = config.keyRotation.decryptionOnlyKeys.map((decryptionKey) =>
nodeCrypto({ encryptionKey: decryptionKey })
);
-
+ const auditLogger = new EncryptedSavedObjectsAuditLogger(
+ deps.security?.audit.getLogger('encryptedSavedObjects')
+ );
const service = Object.freeze(
new EncryptedSavedObjectsService({
primaryCrypto,
@@ -94,9 +101,9 @@ export class EncryptedSavedObjectsPlugin
});
return {
+ canEncrypt,
registerType: (typeRegistration: EncryptedSavedObjectTypeRegistration) =>
service.registerType(typeRegistration),
- usingEphemeralEncryptionKey: config.usingEphemeralEncryptionKey,
createMigration: getCreateMigration(
service,
(typeRegistration: EncryptedSavedObjectTypeRegistration) => {
diff --git a/x-pack/plugins/encrypted_saved_objects/server/routes/index.mock.ts b/x-pack/plugins/encrypted_saved_objects/server/routes/index.mock.ts
index c2dbc4c163b44..32ac1617f4a7e 100644
--- a/x-pack/plugins/encrypted_saved_objects/server/routes/index.mock.ts
+++ b/x-pack/plugins/encrypted_saved_objects/server/routes/index.mock.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import { ConfigSchema, createConfig } from '../config';
+import { ConfigSchema, ConfigType } from '../config';
import { httpServiceMock, loggingSystemMock } from '../../../../../src/core/server/mocks';
import { encryptionKeyRotationServiceMock } from '../crypto/index.mock';
@@ -14,7 +14,7 @@ export const routeDefinitionParamsMock = {
create: (config: Record = {}) => ({
router: httpServiceMock.createRouter(),
logger: loggingSystemMock.create().get(),
- config: createConfig(ConfigSchema.validate(config), loggingSystemMock.create().get()),
+ config: ConfigSchema.validate(config) as ConfigType,
encryptionKeyRotationService: encryptionKeyRotationServiceMock.create(),
}),
};
diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea.mock.ts b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea.mock.ts
index f284fef370f02..ecc7b991f0761 100644
--- a/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea.mock.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea.mock.ts
@@ -11,11 +11,11 @@
* NOTE: These variable names MUST start with 'mock*' in order for
* Jest to accept its use within a jest.mock()
*/
+import { mockFlashMessagesValues, mockFlashMessagesActions } from './flash_messages_logic.mock';
+import { mockHttpValues } from './http_logic.mock';
import { mockKibanaValues } from './kibana_logic.mock';
import { mockLicensingValues } from './licensing_logic.mock';
-import { mockHttpValues } from './http_logic.mock';
import { mockTelemetryActions } from './telemetry_logic.mock';
-import { mockFlashMessagesValues, mockFlashMessagesActions } from './flash_messages_logic.mock';
export const mockAllValues = {
...mockKibanaValues,
diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/kibana_logic.mock.ts b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kibana_logic.mock.ts
index a201a2b56c25c..d8d66e5ee1998 100644
--- a/x-pack/plugins/enterprise_search/public/applications/__mocks__/kibana_logic.mock.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kibana_logic.mock.ts
@@ -6,6 +6,7 @@
*/
import { chartPluginMock } from '../../../../../../src/plugins/charts/public/mocks';
+
import { mockHistory } from './';
export const mockKibanaValues = {
diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/mount_async.mock.tsx b/x-pack/plugins/enterprise_search/public/applications/__mocks__/mount_async.mock.tsx
index 27e8a1421f462..2b5c06df37e8c 100644
--- a/x-pack/plugins/enterprise_search/public/applications/__mocks__/mount_async.mock.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/mount_async.mock.tsx
@@ -6,8 +6,9 @@
*/
import React from 'react';
-import { act } from 'react-dom/test-utils';
+
import { mount, ReactWrapper } from 'enzyme';
+import { act } from 'react-dom/test-utils';
import { mountWithIntl } from './';
diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/mount_with_i18n.mock.tsx b/x-pack/plugins/enterprise_search/public/applications/__mocks__/mount_with_i18n.mock.tsx
index a5a2891d3699c..3a98616082412 100644
--- a/x-pack/plugins/enterprise_search/public/applications/__mocks__/mount_with_i18n.mock.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/mount_with_i18n.mock.tsx
@@ -6,7 +6,9 @@
*/
import React from 'react';
+
import { mount } from 'enzyme';
+
import { I18nProvider } from '@kbn/i18n/react';
/**
diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/shallow_with_i18n.mock.tsx b/x-pack/plugins/enterprise_search/public/applications/__mocks__/shallow_with_i18n.mock.tsx
index 224d71ac579a0..0127804374163 100644
--- a/x-pack/plugins/enterprise_search/public/applications/__mocks__/shallow_with_i18n.mock.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/shallow_with_i18n.mock.tsx
@@ -8,6 +8,7 @@
import React from 'react';
import { shallow, mount, ReactWrapper } from 'enzyme';
+
import { I18nProvider, __IntlProvider } from '@kbn/i18n/react';
// Use fake component to extract `intl` property to use in tests.
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/app_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/app_logic.test.ts
index 86f3993728e06..e5b0a702897bf 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/app_logic.test.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/app_logic.test.ts
@@ -5,9 +5,9 @@
* 2.0.
*/
+import { DEFAULT_INITIAL_APP_DATA } from '../../../common/__mocks__';
import { LogicMounter } from '../__mocks__';
-import { DEFAULT_INITIAL_APP_DATA } from '../../../common/__mocks__';
import { AppLogic } from './app_logic';
describe('AppLogic', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/app_logic.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/app_logic.ts
index 8a55b7c0add94..c33a0e89d2aee 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/app_logic.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/app_logic.ts
@@ -8,6 +8,7 @@
import { kea, MakeLogicType } from 'kea';
import { InitialAppData } from '../../../common/types';
+
import { ConfiguredLimits, Account, Role } from './types';
import { getRoleAbilities } from './utils/role';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_layout.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_layout.test.tsx
index 5248833d827b2..1a4e05c04f319 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_layout.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_layout.test.tsx
@@ -11,14 +11,15 @@ import { mockKibanaValues, setMockValues, setMockActions, rerender } from '../..
import React from 'react';
import { useParams } from 'react-router-dom';
+
import { shallow } from 'enzyme';
-import { Loading } from '../../../shared/loading';
import { FlashMessages } from '../../../shared/flash_messages';
+import { Loading } from '../../../shared/loading';
import { LogRetentionCallout } from '../log_retention';
-import { AnalyticsHeader, AnalyticsUnavailable } from './components';
import { AnalyticsLayout } from './analytics_layout';
+import { AnalyticsHeader, AnalyticsUnavailable } from './components';
describe('AnalyticsLayout', () => {
const { history } = mockKibanaValues;
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_layout.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_layout.tsx
index 88d0f77541166..0c90267c1dbad 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_layout.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_layout.tsx
@@ -7,18 +7,21 @@
import React, { useEffect } from 'react';
import { useParams } from 'react-router-dom';
+
import { useValues, useActions } from 'kea';
+
import { EuiSpacer } from '@elastic/eui';
-import { KibanaLogic } from '../../../shared/kibana';
import { FlashMessages } from '../../../shared/flash_messages';
+import { KibanaLogic } from '../../../shared/kibana';
import { Loading } from '../../../shared/loading';
import { LogRetentionCallout, LogRetentionOptions } from '../log_retention';
-import { AnalyticsLogic } from './';
import { AnalyticsHeader, AnalyticsUnavailable } from './components';
+import { AnalyticsLogic } from './';
+
interface Props {
title: string;
isQueryView?: boolean;
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_logic.test.ts
index 6ca9eb23c962b..ad612e48c770a 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_logic.test.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_logic.test.ts
@@ -19,6 +19,7 @@ jest.mock('../engine', () => ({
import { nextTick } from '@kbn/test/jest';
import { DEFAULT_START_DATE, DEFAULT_END_DATE } from './constants';
+
import { AnalyticsLogic } from './';
describe('AnalyticsLogic', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_logic.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_logic.ts
index e978d2c65398e..de0828f6d71ea 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_logic.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_logic.ts
@@ -8,9 +8,9 @@
import { kea, MakeLogicType } from 'kea';
import queryString from 'query-string';
-import { KibanaLogic } from '../../../shared/kibana';
-import { HttpLogic } from '../../../shared/http';
import { flashAPIErrors } from '../../../shared/flash_messages';
+import { HttpLogic } from '../../../shared/http';
+import { KibanaLogic } from '../../../shared/kibana';
import { EngineLogic } from '../engine';
import { DEFAULT_START_DATE, DEFAULT_END_DATE } from './constants';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_router.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_router.test.tsx
index 3f6bf77024c1e..3940151d3b7cd 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_router.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/analytics_router.test.tsx
@@ -8,9 +8,11 @@
import '../../__mocks__/engine_logic.mock';
import React from 'react';
-import { shallow } from 'enzyme';
+
import { Route, Switch } from 'react-router-dom';
+import { shallow } from 'enzyme';
+
import { AnalyticsRouter } from './';
describe('AnalyticsRouter', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_cards.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_cards.test.tsx
index 84ee392c2419e..8883d0d1ffcbd 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_cards.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_cards.test.tsx
@@ -6,7 +6,9 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiStat } from '@elastic/eui';
import { AnalyticsCards } from './';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_cards.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_cards.tsx
index 417fa0cc48f65..b08e391f845e6 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_cards.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_cards.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiStat } from '@elastic/eui';
interface Props {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_chart.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_chart.test.tsx
index dcea1f81e53eb..51238d62bdac7 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_chart.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_chart.test.tsx
@@ -8,7 +8,9 @@
import { mockKibanaValues } from '../../../../__mocks__';
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { Chart, Settings, LineSeries, Axis } from '@elastic/charts';
import { AnalyticsChart } from './';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_chart.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_chart.tsx
index 686cadda02f63..fa33389503beb 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_chart.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_chart.tsx
@@ -6,9 +6,11 @@
*/
import React from 'react';
+
import { useValues } from 'kea';
import moment from 'moment';
+
import { Chart, Settings, LineSeries, CurveType, Axis } from '@elastic/charts';
import { KibanaLogic } from '../../../../shared/kibana';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_header.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_header.test.tsx
index 3faf2b03097f7..952c4c2517a0e 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_header.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_header.test.tsx
@@ -8,13 +8,16 @@
import { setMockValues, mockKibanaValues } from '../../../../__mocks__';
import React, { ReactElement } from 'react';
+
import { shallow, ShallowWrapper } from 'enzyme';
import moment, { Moment } from 'moment';
+
import { EuiPageHeader, EuiSelect, EuiDatePickerRange, EuiButton } from '@elastic/eui';
import { LogRetentionTooltip } from '../../log_retention';
import { DEFAULT_START_DATE, DEFAULT_END_DATE } from '../constants';
+
import { AnalyticsHeader } from './';
describe('AnalyticsHeader', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_header.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_header.tsx
index 3986f7859bfd2..8a87a5e8c211c 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_header.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_header.tsx
@@ -6,12 +6,11 @@
*/
import React, { useState } from 'react';
-import { useValues } from 'kea';
-import queryString from 'query-string';
+import { useValues } from 'kea';
import moment from 'moment';
+import queryString from 'query-string';
-import { i18n } from '@kbn/i18n';
import {
EuiPageHeader,
EuiPageHeaderSection,
@@ -23,11 +22,12 @@ import {
EuiDatePicker,
EuiButton,
} from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+import { AnalyticsLogic } from '../';
import { KibanaLogic } from '../../../../shared/kibana';
import { LogRetentionTooltip, LogRetentionOptions } from '../../log_retention';
-import { AnalyticsLogic } from '../';
import { DEFAULT_START_DATE, DEFAULT_END_DATE, SERVER_DATE_FORMAT } from '../constants';
import { convertTagsToSelectOptions } from '../utils';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_search.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_search.test.tsx
index 4a3bbda5120bc..89fa5b4cc4b73 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_search.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_search.test.tsx
@@ -9,7 +9,9 @@ import { mockKibanaValues } from '../../../../__mocks__';
import '../../../__mocks__/engine_logic.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiFieldSearch } from '@elastic/eui';
import { AnalyticsSearch } from './';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_search.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_search.tsx
index 922e096701e84..4f2b525aaa168 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_search.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_search.tsx
@@ -6,10 +6,11 @@
*/
import React, { useState } from 'react';
+
import { useValues } from 'kea';
-import { i18n } from '@kbn/i18n';
import { EuiFlexGroup, EuiFlexItem, EuiFieldSearch, EuiButton, EuiSpacer } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
import { KibanaLogic } from '../../../../shared/kibana';
import { ENGINE_ANALYTICS_QUERY_DETAIL_PATH } from '../../../routes';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_section.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_section.test.tsx
index 981173e2a915b..56e30e6061173 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_section.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_section.test.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { AnalyticsSection } from './';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/analytics_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/analytics_table.test.tsx
index 0788edfdda427..2eac65fc21091 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/analytics_table.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/analytics_table.test.tsx
@@ -9,6 +9,7 @@ import { mountWithIntl, mockKibanaValues } from '../../../../../__mocks__';
import '../../../../__mocks__/engine_logic.mock';
import React from 'react';
+
import { EuiBasicTable, EuiBadge, EuiEmptyPrompt } from '@elastic/eui';
import { AnalyticsTable } from './';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/analytics_table.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/analytics_table.tsx
index 8e9853233cbed..a580047f1f635 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/analytics_table.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/analytics_table.tsx
@@ -6,10 +6,12 @@
*/
import React from 'react';
-import { i18n } from '@kbn/i18n';
+
import { EuiBasicTable, EuiBasicTableColumn, EuiEmptyPrompt } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
import { Query } from '../../types';
+
import {
TERM_COLUMN_PROPS,
TAGS_COLUMN,
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/inline_tags_list.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/inline_tags_list.test.tsx
index 9ad2cc32f99c5..9204fa6e75fa7 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/inline_tags_list.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/inline_tags_list.test.tsx
@@ -6,7 +6,9 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiBadge, EuiToolTip } from '@elastic/eui';
import { InlineTagsList } from './inline_tags_list';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/inline_tags_list.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/inline_tags_list.tsx
index 421ff1eedf278..908b096c80a9e 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/inline_tags_list.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/inline_tags_list.tsx
@@ -6,8 +6,9 @@
*/
import React from 'react';
-import { i18n } from '@kbn/i18n';
+
import { EuiBadgeGroup, EuiBadge, EuiToolTip } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
import { Query } from '../../types';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/query_clicks_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/query_clicks_table.test.tsx
index 4396f91136258..cc8f13299c57f 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/query_clicks_table.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/query_clicks_table.test.tsx
@@ -9,6 +9,7 @@ import { mountWithIntl } from '../../../../../__mocks__';
import '../../../../__mocks__/engine_logic.mock';
import React from 'react';
+
import { EuiBasicTable, EuiLink, EuiBadge, EuiEmptyPrompt } from '@elastic/eui';
import { QueryClicksTable } from './';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/query_clicks_table.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/query_clicks_table.tsx
index 7c333623df6c0..4a93724ff5245 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/query_clicks_table.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/query_clicks_table.tsx
@@ -7,15 +7,16 @@
import React from 'react';
-import { i18n } from '@kbn/i18n';
import { EuiBasicTable, EuiBasicTableColumn, EuiEmptyPrompt } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
import { EuiLinkTo } from '../../../../../shared/react_router_helpers';
import { ENGINE_DOCUMENT_DETAIL_PATH } from '../../../../routes';
-import { generateEnginePath } from '../../../engine';
import { DOCUMENTS_TITLE } from '../../../documents';
+import { generateEnginePath } from '../../../engine';
import { QueryClick } from '../../types';
+
import { FIRST_COLUMN_PROPS, TAGS_COLUMN, COUNT_COLUMN_PROPS } from './shared_columns';
interface Props {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/recent_queries_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/recent_queries_table.test.tsx
index fdbbd326c47a1..a5a582d3747bc 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/recent_queries_table.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/recent_queries_table.test.tsx
@@ -9,6 +9,7 @@ import { mountWithIntl, mockKibanaValues } from '../../../../../__mocks__';
import '../../../../__mocks__/engine_logic.mock';
import React from 'react';
+
import { EuiBasicTable, EuiBadge, EuiEmptyPrompt } from '@elastic/eui';
import { RecentQueriesTable } from './';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/recent_queries_table.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/recent_queries_table.tsx
index 20e50e633b321..7724ac5c393ec 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/recent_queries_table.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/recent_queries_table.tsx
@@ -7,11 +7,12 @@
import React from 'react';
+import { EuiBasicTable, EuiBasicTableColumn, EuiEmptyPrompt } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedDate, FormattedTime } from '@kbn/i18n/react';
-import { EuiBasicTable, EuiBasicTableColumn, EuiEmptyPrompt } from '@elastic/eui';
import { RecentQuery } from '../../types';
+
import {
TERM_COLUMN_PROPS,
TAGS_COLUMN,
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/shared_columns.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/shared_columns.tsx
index 0612fac1c07ed..9d8365a2f7af1 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/shared_columns.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_tables/shared_columns.tsx
@@ -6,14 +6,15 @@
*/
import React from 'react';
+
import { i18n } from '@kbn/i18n';
-import { EuiLinkTo } from '../../../../../shared/react_router_helpers';
import { KibanaLogic } from '../../../../../shared/kibana';
+import { EuiLinkTo } from '../../../../../shared/react_router_helpers';
import { ENGINE_ANALYTICS_QUERY_DETAIL_PATH } from '../../../../routes';
import { generateEnginePath } from '../../../engine';
-
import { Query, RecentQuery } from '../../types';
+
import { InlineTagsList } from './inline_tags_list';
/**
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_unavailable.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_unavailable.test.tsx
index ddc0e4636b3ad..e2ff440615dfc 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_unavailable.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_unavailable.test.tsx
@@ -6,7 +6,9 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiEmptyPrompt } from '@elastic/eui';
import { FlashMessages } from '../../../../shared/flash_messages';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_unavailable.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_unavailable.tsx
index 2ef020d2f4992..388570b32b6d2 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_unavailable.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/components/analytics_unavailable.tsx
@@ -6,8 +6,9 @@
*/
import React from 'react';
-import { i18n } from '@kbn/i18n';
+
import { EuiEmptyPrompt } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
import { FlashMessages } from '../../../../shared/flash_messages';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/constants.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/constants.ts
index a04a9474ce5ae..75001f5bc86d6 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/constants.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/constants.ts
@@ -6,6 +6,7 @@
*/
import moment from 'moment';
+
import { i18n } from '@kbn/i18n';
export const ANALYTICS_TITLE = i18n.translate(
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/utils.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/utils.ts
index 2d00c906b2aec..db679b0f387e8 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/utils.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/utils.ts
@@ -6,11 +6,12 @@
*/
import moment from 'moment';
-import { i18n } from '@kbn/i18n';
+
import { EuiSelectProps } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
-import { SERVER_DATE_FORMAT } from './constants';
import { ChartData } from './components/analytics_chart';
+import { SERVER_DATE_FORMAT } from './constants';
interface ConvertToChartData {
data: number[];
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/analytics.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/analytics.test.tsx
index 065b2208648bf..d8921ff0d3723 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/analytics.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/analytics.test.tsx
@@ -9,6 +9,7 @@ import { setMockValues } from '../../../../__mocks__';
import '../../../__mocks__/engine_logic.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
import {
@@ -18,6 +19,7 @@ import {
AnalyticsTable,
RecentQueriesTable,
} from '../components';
+
import { Analytics, ViewAllButton } from './analytics';
describe('Analytics overview', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/analytics.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/analytics.tsx
index 09b1ff45c6122..a4f0bc356ac78 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/analytics.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/analytics.tsx
@@ -6,10 +6,11 @@
*/
import React from 'react';
+
import { useValues } from 'kea';
-import { i18n } from '@kbn/i18n';
import { EuiSpacer, EuiTitle } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
import { EuiButtonTo } from '../../../../shared/react_router_helpers';
import {
@@ -21,6 +22,8 @@ import {
} from '../../../routes';
import { generateEnginePath } from '../../engine';
+import { AnalyticsLayout } from '../analytics_layout';
+import { AnalyticsSection, AnalyticsTable, RecentQueriesTable } from '../components';
import {
ANALYTICS_TITLE,
TOTAL_QUERIES,
@@ -32,9 +35,7 @@ import {
TOP_QUERIES_NO_CLICKS,
RECENT_QUERIES,
} from '../constants';
-import { AnalyticsLayout } from '../analytics_layout';
-import { AnalyticsSection, AnalyticsTable, RecentQueriesTable } from '../components';
-import { AnalyticsLogic, AnalyticsCards, AnalyticsChart, convertToChartData } from '../';
+import { AnalyticsLogic, AnalyticsCards, AnalyticsChart, convertToChartData } from '../index';
export const Analytics: React.FC = () => {
const {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/query_detail.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/query_detail.test.tsx
index 050770944edcd..978f11ddfd5cd 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/query_detail.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/query_detail.test.tsx
@@ -10,12 +10,14 @@ import { setMockValues } from '../../../../__mocks__';
import React from 'react';
import { useParams } from 'react-router-dom';
+
import { shallow } from 'enzyme';
import { SetAppSearchChrome as SetPageChrome } from '../../../../shared/kibana_chrome';
import { AnalyticsLayout } from '../analytics_layout';
import { AnalyticsCards, AnalyticsChart, QueryClicksTable } from '../components';
+
import { QueryDetail } from './';
describe('QueryDetail', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/query_detail.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/query_detail.tsx
index 96587eb528710..f00c4e29a7190 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/query_detail.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/query_detail.tsx
@@ -6,10 +6,11 @@
*/
import React from 'react';
+
import { useValues } from 'kea';
-import { i18n } from '@kbn/i18n';
import { EuiSpacer } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
import { SetAppSearchChrome as SetPageChrome } from '../../../../shared/kibana_chrome';
import { BreadcrumbTrail } from '../../../../shared/kibana_chrome/generate_breadcrumbs';
@@ -17,7 +18,7 @@ import { useDecodedParams } from '../../../utils/encode_path_params';
import { AnalyticsLayout } from '../analytics_layout';
import { AnalyticsSection, QueryClicksTable } from '../components';
-import { AnalyticsLogic, AnalyticsCards, AnalyticsChart, convertToChartData } from '../';
+import { AnalyticsLogic, AnalyticsCards, AnalyticsChart, convertToChartData } from '../index';
const QUERY_DETAIL_TITLE = i18n.translate(
'xpack.enterpriseSearch.appSearch.engine.analytics.queryDetail.title',
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/recent_queries.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/recent_queries.test.tsx
index 40577fb2d4447..21d515a7b9795 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/recent_queries.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/recent_queries.test.tsx
@@ -8,9 +8,11 @@
import { setMockValues } from '../../../../__mocks__';
import React from 'react';
+
import { shallow } from 'enzyme';
import { RecentQueriesTable } from '../components';
+
import { RecentQueries } from './';
describe('RecentQueries', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/recent_queries.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/recent_queries.tsx
index e5380258894ae..bb0c3c4d32244 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/recent_queries.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/recent_queries.tsx
@@ -6,12 +6,13 @@
*/
import React from 'react';
+
import { useValues } from 'kea';
-import { RECENT_QUERIES } from '../constants';
+import { AnalyticsLogic } from '../';
import { AnalyticsLayout } from '../analytics_layout';
import { AnalyticsSearch, RecentQueriesTable } from '../components';
-import { AnalyticsLogic } from '../';
+import { RECENT_QUERIES } from '../constants';
export const RecentQueries: React.FC = () => {
const { recentQueries } = useValues(AnalyticsLogic);
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries.test.tsx
index b037e6bf1d64e..46b2b37958435 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries.test.tsx
@@ -8,9 +8,11 @@
import { setMockValues } from '../../../../__mocks__';
import React from 'react';
+
import { shallow } from 'enzyme';
import { AnalyticsTable } from '../components';
+
import { TopQueries } from './';
describe('TopQueries', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries.tsx
index 76d523d16ee11..6459126560b3a 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries.tsx
@@ -6,12 +6,13 @@
*/
import React from 'react';
+
import { useValues } from 'kea';
-import { TOP_QUERIES } from '../constants';
+import { AnalyticsLogic } from '../';
import { AnalyticsLayout } from '../analytics_layout';
import { AnalyticsSearch, AnalyticsTable } from '../components';
-import { AnalyticsLogic } from '../';
+import { TOP_QUERIES } from '../constants';
export const TopQueries: React.FC = () => {
const { topQueries } = useValues(AnalyticsLogic);
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries_no_clicks.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries_no_clicks.test.tsx
index 1248a49fc5a9c..83212160d1350 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries_no_clicks.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries_no_clicks.test.tsx
@@ -8,9 +8,11 @@
import { setMockValues } from '../../../../__mocks__';
import React from 'react';
+
import { shallow } from 'enzyme';
import { AnalyticsTable } from '../components';
+
import { TopQueriesNoClicks } from './';
describe('TopQueriesNoClicks', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries_no_clicks.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries_no_clicks.tsx
index 604ab96b871e7..8e2591697feaa 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries_no_clicks.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries_no_clicks.tsx
@@ -6,12 +6,13 @@
*/
import React from 'react';
+
import { useValues } from 'kea';
-import { TOP_QUERIES_NO_CLICKS } from '../constants';
+import { AnalyticsLogic } from '../';
import { AnalyticsLayout } from '../analytics_layout';
import { AnalyticsSearch, AnalyticsTable } from '../components';
-import { AnalyticsLogic } from '../';
+import { TOP_QUERIES_NO_CLICKS } from '../constants';
export const TopQueriesNoClicks: React.FC = () => {
const { topQueriesNoClicks } = useValues(AnalyticsLogic);
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries_no_results.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries_no_results.test.tsx
index 3cb77b3c7afbc..dfc5b9c93ab64 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries_no_results.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries_no_results.test.tsx
@@ -8,9 +8,11 @@
import { setMockValues } from '../../../../__mocks__';
import React from 'react';
+
import { shallow } from 'enzyme';
import { AnalyticsTable } from '../components';
+
import { TopQueriesNoResults } from './';
describe('TopQueriesNoResults', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries_no_results.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries_no_results.tsx
index 425fdf8e88559..e093a5130d204 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries_no_results.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries_no_results.tsx
@@ -6,12 +6,13 @@
*/
import React from 'react';
+
import { useValues } from 'kea';
-import { TOP_QUERIES_NO_RESULTS } from '../constants';
+import { AnalyticsLogic } from '../';
import { AnalyticsLayout } from '../analytics_layout';
import { AnalyticsSearch, AnalyticsTable } from '../components';
-import { AnalyticsLogic } from '../';
+import { TOP_QUERIES_NO_RESULTS } from '../constants';
export const TopQueriesNoResults: React.FC = () => {
const { topQueriesNoResults } = useValues(AnalyticsLogic);
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries_with_clicks.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries_with_clicks.test.tsx
index 83be03e95d2cf..fb967ca06b387 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries_with_clicks.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries_with_clicks.test.tsx
@@ -8,9 +8,11 @@
import { setMockValues } from '../../../../__mocks__';
import React from 'react';
+
import { shallow } from 'enzyme';
import { AnalyticsTable } from '../components';
+
import { TopQueriesWithClicks } from './';
describe('TopQueriesWithClicks', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries_with_clicks.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries_with_clicks.tsx
index bec096019035b..87e276a8382c3 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries_with_clicks.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/analytics/views/top_queries_with_clicks.tsx
@@ -6,12 +6,13 @@
*/
import React from 'react';
+
import { useValues } from 'kea';
-import { TOP_QUERIES_WITH_CLICKS } from '../constants';
+import { AnalyticsLogic } from '../';
import { AnalyticsLayout } from '../analytics_layout';
import { AnalyticsSearch, AnalyticsTable } from '../components';
-import { AnalyticsLogic } from '../';
+import { TOP_QUERIES_WITH_CLICKS } from '../constants';
export const TopQueriesWithClicks: React.FC = () => {
const { topQueriesWithClicks } = useValues(AnalyticsLogic);
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/constants.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/constants.ts
index 2e28e5a272643..0fb118548a67b 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/constants.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/constants.ts
@@ -6,6 +6,7 @@
*/
import { i18n } from '@kbn/i18n';
+
import { DOCS_PREFIX } from '../../routes';
export const CREDENTIALS_TITLE = i18n.translate(
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials.test.tsx
index cc783e7c056e2..48fcf4b8c5b66 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials.test.tsx
@@ -9,12 +9,15 @@ import { setMockValues, setMockActions } from '../../../__mocks__/kea.mock';
import { unmountHandler } from '../../../__mocks__/shallow_useeffect.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
-import { Credentials } from './credentials';
import { EuiCopy, EuiLoadingContent, EuiPageContentBody } from '@elastic/eui';
import { externalUrl } from '../../../shared/enterprise_search_url';
+
+import { Credentials } from './credentials';
+
import { CredentialsFlyout } from './credentials_flyout';
describe('Credentials', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials.tsx
index 0266b64f97104..266e9467c300d 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials.tsx
@@ -6,6 +6,7 @@
*/
import React, { useEffect } from 'react';
+
import { useActions, useValues } from 'kea';
import {
@@ -24,14 +25,14 @@ import {
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
+import { externalUrl } from '../../../shared/enterprise_search_url/external_url';
import { FlashMessages } from '../../../shared/flash_messages';
+import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
-import { CredentialsLogic } from './credentials_logic';
-import { externalUrl } from '../../../shared/enterprise_search_url/external_url';
import { CREDENTIALS_TITLE } from './constants';
-import { CredentialsList } from './credentials_list';
import { CredentialsFlyout } from './credentials_flyout';
+import { CredentialsList } from './credentials_list';
+import { CredentialsLogic } from './credentials_logic';
export const Credentials: React.FC = () => {
const { initializeCredentialsData, resetCredentials, showCredentialsForm } = useActions(
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/body.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/body.test.tsx
index 8b5a59b82c19b..595bc1bcbb828 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/body.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/body.test.tsx
@@ -8,12 +8,15 @@
import { setMockValues, setMockActions } from '../../../../__mocks__/kea.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiFlyoutBody, EuiForm } from '@elastic/eui';
import { ApiTokenTypes } from '../constants';
import { defaultApiToken } from '../credentials_logic';
+import { CredentialsFlyoutBody } from './body';
import {
FormKeyName,
FormKeyType,
@@ -21,7 +24,6 @@ import {
FormKeyEngineAccess,
FormKeyUpdateWarning,
} from './form_components';
-import { CredentialsFlyoutBody } from './body';
describe('CredentialsFlyoutBody', () => {
const values = {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/body.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/body.tsx
index f3de25fe0a25d..def165f3f82a2 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/body.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/body.tsx
@@ -6,12 +6,14 @@
*/
import React from 'react';
+
import { useValues, useActions } from 'kea';
+
import { EuiFlyoutBody, EuiForm } from '@elastic/eui';
import { FlashMessages } from '../../../../shared/flash_messages';
-import { CredentialsLogic } from '../credentials_logic';
import { ApiTokenTypes } from '../constants';
+import { CredentialsLogic } from '../credentials_logic';
import {
FormKeyName,
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/footer.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/footer.test.tsx
index 036fe881c7d0d..23e85b92bb8b4 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/footer.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/footer.test.tsx
@@ -8,7 +8,9 @@
import { setMockValues, setMockActions } from '../../../../__mocks__/kea.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiFlyoutFooter, EuiButtonEmpty } from '@elastic/eui';
import { CredentialsFlyoutFooter } from './footer';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/footer.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/footer.tsx
index dc2d52a073b36..c05bd82c6206e 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/footer.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/footer.tsx
@@ -6,7 +6,9 @@
*/
import React from 'react';
+
import { useValues, useActions } from 'kea';
+
import {
EuiFlyoutFooter,
EuiFlexGroup,
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_engine_access.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_engine_access.test.tsx
index 51a737ce8c826..7247deb09f12b 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_engine_access.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_engine_access.test.tsx
@@ -8,7 +8,9 @@
import { setMockValues, setMockActions, rerender } from '../../../../../__mocks__';
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiRadio, EuiCheckbox } from '@elastic/eui';
import { FormKeyEngineAccess, EngineSelection } from './key_engine_access';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_engine_access.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_engine_access.tsx
index 2a9e8cf153dca..0d6ebfe437927 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_engine_access.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_engine_access.tsx
@@ -6,7 +6,9 @@
*/
import React from 'react';
+
import { useValues, useActions } from 'kea';
+
import {
EuiFormRow,
EuiRadio,
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_name.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_name.test.tsx
index 27f95f2ba7cd8..d54d0c89c90cb 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_name.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_name.test.tsx
@@ -8,7 +8,9 @@
import { setMockValues, setMockActions } from '../../../../../__mocks__/kea.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiFieldText, EuiFormRow } from '@elastic/eui';
import { FormKeyName } from './';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_name.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_name.tsx
index cb4dce76dfcc1..f4f4f5f0aaaaa 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_name.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_name.tsx
@@ -6,7 +6,9 @@
*/
import React from 'react';
+
import { useValues, useActions } from 'kea';
+
import { EuiFormRow, EuiFieldText } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_read_write_access.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_read_write_access.test.tsx
index 8cfa5b3c4571a..cf45576d691cf 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_read_write_access.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_read_write_access.test.tsx
@@ -8,7 +8,9 @@
import { setMockValues, setMockActions } from '../../../../../__mocks__/kea.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiCheckbox } from '@elastic/eui';
import { FormKeyReadWriteAccess } from './';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_read_write_access.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_read_write_access.tsx
index f9653159b4403..0b631089c3984 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_read_write_access.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_read_write_access.tsx
@@ -6,7 +6,9 @@
*/
import React from 'react';
+
import { useValues, useActions } from 'kea';
+
import { EuiCheckbox, EuiText, EuiTitle, EuiSpacer, EuiPanel } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_type.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_type.test.tsx
index 9cf6c82184579..5de2c7fda53ca 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_type.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_type.test.tsx
@@ -8,10 +8,13 @@
import { setMockValues, setMockActions } from '../../../../../__mocks__/kea.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiSelect } from '@elastic/eui';
import { ApiTokenTypes, TOKEN_TYPE_INFO } from '../../constants';
+
import { FormKeyType } from './';
describe('FormKeyType', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_type.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_type.tsx
index a8cc16b3b30e7..60308274fbb76 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_type.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_type.tsx
@@ -6,13 +6,15 @@
*/
import React from 'react';
+
import { useValues, useActions } from 'kea';
+
import { EuiFormRow, EuiSelect, EuiText, EuiLink } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { AppLogic } from '../../../../app_logic';
-import { CredentialsLogic } from '../../credentials_logic';
import { TOKEN_TYPE_DESCRIPTION, TOKEN_TYPE_INFO, DOCS_HREF } from '../../constants';
+import { CredentialsLogic } from '../../credentials_logic';
export const FormKeyType: React.FC = () => {
const { myRole } = useValues(AppLogic);
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_update_warning.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_update_warning.test.tsx
index 073c4ec1c92bf..38eec0b371576 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_update_warning.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_update_warning.test.tsx
@@ -6,7 +6,9 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiCallOut } from '@elastic/eui';
import { FormKeyUpdateWarning } from './';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_update_warning.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_update_warning.tsx
index 87cda9590f5cb..c24eebea9178b 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_update_warning.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_update_warning.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { EuiSpacer, EuiCallOut } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/header.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/header.test.tsx
index 0772a395dbe71..8ee7f810c1fa5 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/header.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/header.test.tsx
@@ -8,7 +8,9 @@
import { setMockValues } from '../../../../__mocks__/kea.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiFlyoutHeader } from '@elastic/eui';
import { ApiTokenTypes } from '../constants';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/header.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/header.tsx
index a9efcbe371c4f..586ddc5c22b97 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/header.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/header.tsx
@@ -6,12 +6,14 @@
*/
import React from 'react';
+
import { useValues } from 'kea';
+
import { EuiFlyoutHeader, EuiTitle } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import { CredentialsLogic } from '../credentials_logic';
import { FLYOUT_ARIA_LABEL_ID } from '../constants';
+import { CredentialsLogic } from '../credentials_logic';
export const CredentialsFlyoutHeader: React.FC = () => {
const { activeApiToken } = useValues(CredentialsLogic);
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/index.test.tsx
index 1f7408857857a..9932b8ca227b0 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/index.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/index.test.tsx
@@ -8,7 +8,9 @@
import { setMockActions } from '../../../../__mocks__/kea.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiFlyout } from '@elastic/eui';
import { CredentialsFlyout } from './';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/index.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/index.tsx
index 1335a3cdeea18..2ee73a6b80b5a 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/index.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/index.tsx
@@ -6,14 +6,17 @@
*/
import React from 'react';
+
import { useActions } from 'kea';
+
import { EuiPortal, EuiFlyout } from '@elastic/eui';
-import { CredentialsLogic } from '../credentials_logic';
import { FLYOUT_ARIA_LABEL_ID } from '../constants';
-import { CredentialsFlyoutHeader } from './header';
+import { CredentialsLogic } from '../credentials_logic';
+
import { CredentialsFlyoutBody } from './body';
import { CredentialsFlyoutFooter } from './footer';
+import { CredentialsFlyoutHeader } from './header';
export const CredentialsFlyout: React.FC = () => {
const { hideCredentialsForm } = useActions(CredentialsLogic);
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_list/credentials_list.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_list/credentials_list.test.tsx
index dd3d8ef8069ba..8c52df30bfc67 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_list/credentials_list.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_list/credentials_list.test.tsx
@@ -8,15 +8,18 @@
import { setMockValues, setMockActions } from '../../../../__mocks__/kea.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiBasicTable, EuiCopy, EuiEmptyPrompt } from '@elastic/eui';
-import { ApiToken } from '../types';
+import { HiddenText } from '../../../../shared/hidden_text';
import { ApiTokenTypes } from '../constants';
+import { ApiToken } from '../types';
-import { HiddenText } from '../../../../shared/hidden_text';
import { Key } from './key';
-import { CredentialsList } from './credentials_list';
+
+import { CredentialsList } from './';
describe('Credentials', () => {
const apiToken: ApiToken = {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_list/credentials_list.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_list/credentials_list.tsx
index 9d220469347f2..f23479017a680 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_list/credentials_list.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_list/credentials_list.tsx
@@ -6,19 +6,21 @@
*/
import React, { useMemo } from 'react';
-import { EuiBasicTable, EuiBasicTableColumn, EuiCopy, EuiEmptyPrompt } from '@elastic/eui';
-import { CriteriaWithPagination } from '@elastic/eui/src/components/basic_table/basic_table';
+
import { useActions, useValues } from 'kea';
+import { EuiBasicTable, EuiBasicTableColumn, EuiCopy, EuiEmptyPrompt } from '@elastic/eui';
+import { CriteriaWithPagination } from '@elastic/eui/src/components/basic_table/basic_table';
import { i18n } from '@kbn/i18n';
-import { CredentialsLogic } from '../credentials_logic';
-import { Key } from './key';
import { HiddenText } from '../../../../shared/hidden_text';
-import { ApiToken } from '../types';
import { TOKEN_TYPE_DISPLAY_NAMES } from '../constants';
-import { apiTokenSort } from '../utils/api_token_sort';
+import { CredentialsLogic } from '../credentials_logic';
+import { ApiToken } from '../types';
import { getModeDisplayText, getEnginesDisplayText } from '../utils';
+import { apiTokenSort } from '../utils/api_token_sort';
+
+import { Key } from './key';
export const CredentialsList: React.FC = () => {
const { deleteApiKey, fetchCredentials, showCredentialsForm } = useActions(CredentialsLogic);
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_list/key.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_list/key.test.tsx
index c18302db9ddfd..5e042319ae613 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_list/key.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_list/key.test.tsx
@@ -6,7 +6,9 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiButtonIcon } from '@elastic/eui';
import { Key } from './key';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_list/key.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_list/key.tsx
index 940453c83a1fe..ff14379b9aecc 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_list/key.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_list/key.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { EuiButtonIcon } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_logic.test.ts
index 005f487772d80..c9d6a43ebbbae 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_logic.test.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_logic.test.ts
@@ -17,6 +17,7 @@ jest.mock('../../app_logic', () => ({
import { nextTick } from '@kbn/test/jest';
import { AppLogic } from '../../app_logic';
+
import { ApiTokenTypes } from './constants';
import { CredentialsLogic } from './credentials_logic';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_logic.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_logic.ts
index 25cd1be93836d..ff4600872c589 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_logic.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_logic.ts
@@ -7,19 +7,19 @@
import { kea, MakeLogicType } from 'kea';
-import { formatApiName } from '../../utils/format_api_name';
-import { ApiTokenTypes, CREATE_MESSAGE, UPDATE_MESSAGE, DELETE_MESSAGE } from './constants';
-
-import { HttpLogic } from '../../../shared/http';
+import { Meta } from '../../../../../common/types';
import {
clearFlashMessages,
setSuccessMessage,
flashAPIErrors,
} from '../../../shared/flash_messages';
+import { HttpLogic } from '../../../shared/http';
import { AppLogic } from '../../app_logic';
-
-import { Meta } from '../../../../../common/types';
import { Engine } from '../../types';
+import { formatApiName } from '../../utils/format_api_name';
+
+import { ApiTokenTypes, CREATE_MESSAGE, UPDATE_MESSAGE, DELETE_MESSAGE } from './constants';
+
import { ApiToken, CredentialsDetails, TokenReadWrite } from './types';
export const defaultApiToken: ApiToken = {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/types.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/types.ts
index ddc81658eed2c..0427d25add49b 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/types.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/types.ts
@@ -6,6 +6,7 @@
*/
import { Engine } from '../../types';
+
import { ApiTokenTypes } from './constants';
export interface CredentialsDetails {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/utils/api_token_sort.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/utils/api_token_sort.test.ts
index 1f84caa7e1ef7..70277d6cb7f22 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/utils/api_token_sort.test.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/utils/api_token_sort.test.ts
@@ -5,11 +5,12 @@
* 2.0.
*/
-import { apiTokenSort } from '.';
import { ApiTokenTypes } from '../constants';
import { ApiToken } from '../types';
+import { apiTokenSort } from '.';
+
describe('apiTokenSort', () => {
const apiToken: ApiToken = {
name: '',
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/utils/get_engines_display_text.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/utils/get_engines_display_text.test.tsx
index e92957405a524..71d00efa2a868 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/utils/get_engines_display_text.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/utils/get_engines_display_text.test.tsx
@@ -6,22 +6,24 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
-import { getEnginesDisplayText } from './get_engines_display_text';
-import { ApiToken } from '../types';
import { ApiTokenTypes } from '../constants';
+import { ApiToken } from '../types';
-const apiToken: ApiToken = {
- name: '',
- type: ApiTokenTypes.Private,
- read: true,
- write: true,
- access_all_engines: true,
- engines: ['engine1', 'engine2', 'engine3'],
-};
+import { getEnginesDisplayText } from './get_engines_display_text';
describe('getEnginesDisplayText', () => {
+ const apiToken: ApiToken = {
+ name: '',
+ type: ApiTokenTypes.Private,
+ read: true,
+ write: true,
+ access_all_engines: true,
+ engines: ['engine1', 'engine2', 'engine3'],
+ };
+
it('returns "--" when the token is an admin token', () => {
const wrapper = shallow(
{getEnginesDisplayText({ ...apiToken, type: ApiTokenTypes.Admin })}
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/utils/get_engines_display_text.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/utils/get_engines_display_text.tsx
index 34089cacbf180..d3577ec14fec9 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/utils/get_engines_display_text.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/utils/get_engines_display_text.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { ApiTokenTypes, ALL } from '../constants';
import { ApiToken } from '../types';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/api_code_example.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/api_code_example.test.tsx
index 7203cf6982086..34afa9d1e39ed 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/api_code_example.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/api_code_example.test.tsx
@@ -9,7 +9,9 @@ import '../../../../__mocks__/enterprise_search_url.mock';
import { setMockValues, setMockActions } from '../../../../__mocks__/kea.mock';
import React from 'react';
+
import { shallow, ShallowWrapper } from 'enzyme';
+
import { EuiCode, EuiCodeBlock, EuiButtonEmpty } from '@elastic/eui';
import { ApiCodeExample, FlyoutHeader, FlyoutBody, FlyoutFooter } from './api_code_example';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/api_code_example.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/api_code_example.tsx
index 9167df25f75b5..88e9df5c2bbf5 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/api_code_example.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/api_code_example.tsx
@@ -5,12 +5,12 @@
* 2.0.
*/
-import dedent from 'dedent';
import React from 'react';
+
+import dedent from 'dedent';
+
import { useValues, useActions } from 'kea';
-import { i18n } from '@kbn/i18n';
-import { FormattedMessage } from '@kbn/i18n/react';
import {
EuiFlyoutHeader,
EuiTitle,
@@ -27,18 +27,19 @@ import {
EuiFlexGroup,
EuiFlexItem,
} from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+import { FormattedMessage } from '@kbn/i18n/react';
import { getEnterpriseSearchUrl } from '../../../../shared/enterprise_search_url';
+import { DOCS_PREFIX } from '../../../routes';
import { EngineLogic } from '../../engine';
import { EngineDetails } from '../../engine/types';
-
-import { DOCS_PREFIX } from '../../../routes';
import {
DOCUMENTS_API_JSON_EXAMPLE,
FLYOUT_ARIA_LABEL_ID,
FLYOUT_CANCEL_BUTTON,
} from '../constants';
-import { DocumentCreationLogic } from '../';
+import { DocumentCreationLogic } from '../index';
export const ApiCodeExample: React.FC = () => (
<>
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/paste_json_text.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/paste_json_text.test.tsx
index c1c0a554b4794..8b5b36094fbc6 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/paste_json_text.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/paste_json_text.test.tsx
@@ -8,10 +8,13 @@
import { setMockValues, setMockActions, rerender } from '../../../../__mocks__';
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiTextArea, EuiButtonEmpty, EuiButton } from '@elastic/eui';
import { Errors } from '../creation_response_components';
+
import { PasteJsonText, FlyoutHeader, FlyoutBody, FlyoutFooter } from './paste_json_text';
describe('PasteJsonText', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/paste_json_text.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/paste_json_text.tsx
index 377d795413714..2d4a6de26333f 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/paste_json_text.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/paste_json_text.tsx
@@ -6,9 +6,9 @@
*/
import React from 'react';
+
import { useValues, useActions } from 'kea';
-import { i18n } from '@kbn/i18n';
import {
EuiFlyoutHeader,
EuiTitle,
@@ -22,12 +22,13 @@ import {
EuiSpacer,
EuiText,
} from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
import { AppLogic } from '../../../app_logic';
import { FLYOUT_ARIA_LABEL_ID, FLYOUT_CANCEL_BUTTON, FLYOUT_CONTINUE_BUTTON } from '../constants';
import { Errors } from '../creation_response_components';
-import { DocumentCreationLogic } from '../';
+import { DocumentCreationLogic } from '../index';
import './paste_json_text.scss';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/show_creation_modes.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/show_creation_modes.test.tsx
index 2c66ae56dd3ce..739580d039a36 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/show_creation_modes.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/show_creation_modes.test.tsx
@@ -8,10 +8,13 @@
import { setMockActions } from '../../../../__mocks__/kea.mock';
import React from 'react';
+
import { shallow, ShallowWrapper } from 'enzyme';
+
import { EuiButtonEmpty } from '@elastic/eui';
import { DocumentCreationButtons } from '../';
+
import { ShowCreationModes } from './';
describe('ShowCreationModes', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/show_creation_modes.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/show_creation_modes.tsx
index b67c7689d816f..d46b9acbb63d7 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/show_creation_modes.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/show_creation_modes.tsx
@@ -6,9 +6,9 @@
*/
import React from 'react';
+
import { useActions } from 'kea';
-import { i18n } from '@kbn/i18n';
import {
EuiFlyoutHeader,
EuiTitle,
@@ -16,9 +16,10 @@ import {
EuiFlyoutFooter,
EuiButtonEmpty,
} from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
import { FLYOUT_ARIA_LABEL_ID, FLYOUT_CANCEL_BUTTON } from '../constants';
-import { DocumentCreationLogic, DocumentCreationButtons } from '../';
+import { DocumentCreationLogic, DocumentCreationButtons } from '../index';
export const ShowCreationModes: React.FC = () => {
const { closeDocumentCreation } = useActions(DocumentCreationLogic);
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/upload_json_file.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/upload_json_file.test.tsx
index cee76ebe6857e..7dc8952a18688 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/upload_json_file.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/upload_json_file.test.tsx
@@ -8,10 +8,13 @@
import { setMockValues, setMockActions, rerender } from '../../../../__mocks__';
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiFilePicker, EuiButtonEmpty, EuiButton } from '@elastic/eui';
import { Errors } from '../creation_response_components';
+
import { UploadJsonFile, FlyoutHeader, FlyoutBody, FlyoutFooter } from './upload_json_file';
describe('UploadJsonFile', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/upload_json_file.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/upload_json_file.tsx
index cab79a929f7b9..5d50ae55fcd10 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/upload_json_file.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/upload_json_file.tsx
@@ -6,9 +6,9 @@
*/
import React from 'react';
+
import { useValues, useActions } from 'kea';
-import { i18n } from '@kbn/i18n';
import {
EuiFlyoutHeader,
EuiTitle,
@@ -22,12 +22,13 @@ import {
EuiSpacer,
EuiText,
} from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
import { AppLogic } from '../../../app_logic';
import { FLYOUT_ARIA_LABEL_ID, FLYOUT_CANCEL_BUTTON, FLYOUT_CONTINUE_BUTTON } from '../constants';
import { Errors } from '../creation_response_components';
-import { DocumentCreationLogic } from '../';
+import { DocumentCreationLogic } from '../index';
export const UploadJsonFile: React.FC = () => (
<>
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/errors.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/errors.test.tsx
index 7ac97ae81b6ca..f03989aeaf5a3 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/errors.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/errors.test.tsx
@@ -8,7 +8,9 @@
import { setMockValues } from '../../../../__mocks__/kea.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiCallOut } from '@elastic/eui';
import { Errors } from './';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/errors.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/errors.tsx
index 618828182e67d..3564d8ad088ee 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/errors.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/errors.tsx
@@ -6,12 +6,13 @@
*/
import React from 'react';
+
import { useValues } from 'kea';
import { EuiCallOut } from '@elastic/eui';
import { DOCUMENT_CREATION_ERRORS, DOCUMENT_CREATION_WARNINGS } from '../constants';
-import { DocumentCreationLogic } from '../';
+import { DocumentCreationLogic } from '../index';
export const Errors: React.FC = () => {
const { errors, warnings } = useValues(DocumentCreationLogic);
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary.test.tsx
index 9558d23fa3a77..f53f94322879c 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary.test.tsx
@@ -8,15 +8,19 @@
import { setMockValues, setMockActions } from '../../../../__mocks__/kea.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiFlyoutBody, EuiCallOut, EuiButton } from '@elastic/eui';
+import { FlyoutHeader, FlyoutBody, FlyoutFooter } from './summary';
import {
InvalidDocumentsSummary,
ValidDocumentsSummary,
SchemaFieldsSummary,
} from './summary_sections';
-import { Summary, FlyoutHeader, FlyoutBody, FlyoutFooter } from './summary';
+
+import { Summary } from './';
describe('Summary', () => {
const values = {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary.tsx
index 673c6726afb5d..8361afe62e1ca 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary.tsx
@@ -6,9 +6,9 @@
*/
import React from 'react';
+
import { useValues, useActions } from 'kea';
-import { i18n } from '@kbn/i18n';
import {
EuiFlyoutHeader,
EuiTitle,
@@ -19,10 +19,11 @@ import {
EuiFlexItem,
EuiButton,
} from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+import { DocumentCreationLogic } from '../';
import { FLYOUT_ARIA_LABEL_ID, FLYOUT_CLOSE_BUTTON, DOCUMENT_CREATION_ERRORS } from '../constants';
import { DocumentCreationStep } from '../types';
-import { DocumentCreationLogic } from '../';
import {
InvalidDocumentsSummary,
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary_documents.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary_documents.test.tsx
index 0704d465bbac4..cd8209bafed3f 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary_documents.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary_documents.test.tsx
@@ -6,7 +6,9 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiCodeBlock, EuiCallOut } from '@elastic/eui';
import { ExampleDocumentJson, MoreDocumentsText } from './summary_documents';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary_documents.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary_documents.tsx
index be19a7677a1ab..0dad75cb1f98f 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary_documents.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary_documents.tsx
@@ -7,8 +7,8 @@
import React, { Fragment } from 'react';
-import { i18n } from '@kbn/i18n';
import { EuiCodeBlock, EuiCallOut, EuiTitle, EuiText, EuiSpacer } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
interface ExampleDocumentJsonProps {
document: object;
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary_section.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary_section.test.tsx
index 41028d61c55f2..24fa2766cb15d 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary_section.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary_section.test.tsx
@@ -6,7 +6,9 @@
*/
import React, { ReactElement } from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiAccordion, EuiIcon } from '@elastic/eui';
import { SummarySectionAccordion, SummarySectionEmpty } from './summary_section';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary_sections.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary_sections.test.tsx
index 9ead42f33521f..7eb9f3f46036d 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary_sections.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary_sections.test.tsx
@@ -8,11 +8,13 @@
import { setMockValues } from '../../../../__mocks__/kea.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiBadge } from '@elastic/eui';
-import { SummarySectionAccordion, SummarySectionEmpty } from './summary_section';
+
import { ExampleDocumentJson, MoreDocumentsText } from './summary_documents';
+import { SummarySectionAccordion, SummarySectionEmpty } from './summary_section';
import {
InvalidDocumentsSummary,
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary_sections.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary_sections.tsx
index 637188132d6bc..f2e863c2a9983 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary_sections.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_response_components/summary_sections.tsx
@@ -6,15 +6,16 @@
*/
import React from 'react';
+
import { useValues } from 'kea';
-import { i18n } from '@kbn/i18n';
import { EuiFlexGroup, EuiFlexItem, EuiBadge } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
import { DocumentCreationLogic } from '../';
-import { SummarySectionAccordion, SummarySectionEmpty } from './summary_section';
import { ExampleDocumentJson, MoreDocumentsText } from './summary_documents';
+import { SummarySectionAccordion, SummarySectionEmpty } from './summary_section';
export const InvalidDocumentsSummary: React.FC = () => {
const {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_buttons.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_buttons.test.tsx
index 4b90acfbc37a8..7cbcc6b17e047 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_buttons.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_buttons.test.tsx
@@ -9,8 +9,11 @@ import { setMockActions } from '../../../__mocks__/kea.mock';
import '../../__mocks__/engine_logic.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiCard } from '@elastic/eui';
+
import { EuiCardTo } from '../../../shared/react_router_helpers';
import { DocumentCreationButtons } from './';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_buttons.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_buttons.tsx
index ec9c6615f5b8c..6d3caca87dcc3 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_buttons.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_buttons.tsx
@@ -6,10 +6,9 @@
*/
import React from 'react';
+
import { useActions } from 'kea';
-import { i18n } from '@kbn/i18n';
-import { FormattedMessage } from '@kbn/i18n/react';
import {
EuiText,
EuiCode,
@@ -20,6 +19,8 @@ import {
EuiCard,
EuiIcon,
} from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+import { FormattedMessage } from '@kbn/i18n/react';
import { EuiCardTo } from '../../../shared/react_router_helpers';
import { DOCS_PREFIX, ENGINE_CRAWLER_PATH } from '../../routes';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_flyout.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_flyout.test.tsx
index 4c5375d78f95f..66995b8d20dfe 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_flyout.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_flyout.test.tsx
@@ -8,7 +8,9 @@
import { setMockValues, setMockActions } from '../../../__mocks__/kea.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiFlyout } from '@elastic/eui';
import {
@@ -18,9 +20,8 @@ import {
UploadJsonFile,
} from './creation_mode_components';
import { Summary } from './creation_response_components';
-import { DocumentCreationStep } from './types';
-
import { DocumentCreationFlyout, FlyoutContent } from './document_creation_flyout';
+import { DocumentCreationStep } from './types';
describe('DocumentCreationFlyout', () => {
const values = {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_flyout.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_flyout.tsx
index 16f805d7e86fd..159f3403d3740 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_flyout.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_flyout.tsx
@@ -6,14 +6,12 @@
*/
import React from 'react';
+
import { useValues, useActions } from 'kea';
import { EuiPortal, EuiFlyout } from '@elastic/eui';
-import { DocumentCreationLogic } from './';
-import { DocumentCreationStep } from './types';
import { FLYOUT_ARIA_LABEL_ID } from './constants';
-
import {
ShowCreationModes,
ApiCodeExample,
@@ -21,6 +19,9 @@ import {
UploadJsonFile,
} from './creation_mode_components';
import { Summary } from './creation_response_components';
+import { DocumentCreationStep } from './types';
+
+import { DocumentCreationLogic } from './';
export const DocumentCreationFlyout: React.FC = () => {
const { closeDocumentCreation } = useActions(DocumentCreationLogic);
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_logic.test.ts
index 63c59343580d3..37d3d1577767f 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_logic.test.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_logic.test.ts
@@ -7,13 +7,9 @@
import { LogicMounter, mockHttpValues } from '../../../__mocks__';
-import { nextTick } from '@kbn/test/jest';
import dedent from 'dedent';
-jest.mock('./utils', () => ({
- readUploadedFileAsText: jest.fn(),
-}));
-import { readUploadedFileAsText } from './utils';
+import { nextTick } from '@kbn/test/jest';
jest.mock('../engine', () => ({
EngineLogic: { values: { engineName: 'test-engine' } },
@@ -21,6 +17,12 @@ jest.mock('../engine', () => ({
import { DOCUMENTS_API_JSON_EXAMPLE } from './constants';
import { DocumentCreationStep } from './types';
+
+jest.mock('./utils', () => ({
+ readUploadedFileAsText: jest.fn(),
+}));
+import { readUploadedFileAsText } from './utils';
+
import { DocumentCreationLogic } from './';
describe('DocumentCreationLogic', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_logic.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_logic.ts
index 13d2618bcd31f..a0ef73bbcea21 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_logic.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/document_creation_logic.ts
@@ -5,8 +5,8 @@
* 2.0.
*/
-import { kea, MakeLogicType } from 'kea';
import dedent from 'dedent';
+import { kea, MakeLogicType } from 'kea';
import { isPlainObject, chunk, uniq } from 'lodash';
import { HttpLogic } from '../../../shared/http';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_creation_button.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_creation_button.test.tsx
index ab1679c455c6e..82fa9d3c82ce9 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_creation_button.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_creation_button.test.tsx
@@ -8,10 +8,13 @@
import { setMockActions } from '../../../__mocks__/kea.mock';
import React from 'react';
+
import { shallow, ShallowWrapper } from 'enzyme';
+
import { EuiButton } from '@elastic/eui';
import { DocumentCreationFlyout } from '../document_creation';
+
import { DocumentCreationButton } from './document_creation_button';
describe('DocumentCreationButton', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_creation_button.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_creation_button.tsx
index a05005fefa082..687f589d37594 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_creation_button.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_creation_button.tsx
@@ -6,10 +6,11 @@
*/
import React from 'react';
+
import { useActions } from 'kea';
-import { i18n } from '@kbn/i18n';
import { EuiButton } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
import { DocumentCreationLogic, DocumentCreationFlyout } from '../document_creation';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail.test.tsx
index 55613077efdba..ba060b7497270 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail.test.tsx
@@ -10,14 +10,17 @@ import { setMockValues, setMockActions } from '../../../__mocks__/kea.mock';
import { unmountHandler } from '../../../__mocks__/shallow_useeffect.mock';
import React from 'react';
-import { shallow } from 'enzyme';
import { useParams } from 'react-router-dom';
+
+import { shallow } from 'enzyme';
+
import { EuiPageContent, EuiBasicTable } from '@elastic/eui';
import { Loading } from '../../../shared/loading';
-import { DocumentDetail } from '.';
import { ResultFieldValue } from '../result';
+import { DocumentDetail } from '.';
+
describe('DocumentDetail', () => {
const values = {
dataLoading: false,
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail.tsx
index ca6af345de7ed..8f80978c29002 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail.tsx
@@ -6,9 +6,10 @@
*/
import React, { useEffect } from 'react';
-import { useActions, useValues } from 'kea';
import { useParams } from 'react-router-dom';
+import { useActions, useValues } from 'kea';
+
import {
EuiButton,
EuiPageHeader,
@@ -21,15 +22,15 @@ import {
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import { Loading } from '../../../shared/loading';
-import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
import { FlashMessages } from '../../../shared/flash_messages';
+import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
+import { Loading } from '../../../shared/loading';
import { useDecodedParams } from '../../utils/encode_path_params';
import { ResultFieldValue } from '../result';
+import { DOCUMENTS_TITLE } from './constants';
import { DocumentDetailLogic } from './document_detail_logic';
import { FieldDetails } from './types';
-import { DOCUMENTS_TITLE } from './constants';
const DOCUMENT_DETAIL_TITLE = (documentId: string) =>
i18n.translate('xpack.enterpriseSearch.appSearch.documentDetail.title', {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail_logic.test.ts
index ef5ebad3aea13..d2683fac649a0 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail_logic.test.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail_logic.test.ts
@@ -15,9 +15,10 @@ import { mockEngineValues } from '../../__mocks__';
import { nextTick } from '@kbn/test/jest';
-import { DocumentDetailLogic } from './document_detail_logic';
import { InternalSchemaTypes } from '../../../shared/types';
+import { DocumentDetailLogic } from './document_detail_logic';
+
describe('DocumentDetailLogic', () => {
const { mount } = new LogicMounter(DocumentDetailLogic);
const { http } = mockHttpValues;
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail_logic.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail_logic.ts
index 8b023fb585f86..17c2c788523d0 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail_logic.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail_logic.ts
@@ -6,11 +6,12 @@
*/
import { kea, MakeLogicType } from 'kea';
+
import { i18n } from '@kbn/i18n';
import { flashAPIErrors, setQueuedSuccessMessage } from '../../../shared/flash_messages';
-import { KibanaLogic } from '../../../shared/kibana';
import { HttpLogic } from '../../../shared/http';
+import { KibanaLogic } from '../../../shared/kibana';
import { ENGINE_DOCUMENTS_PATH } from '../../routes';
import { EngineLogic, generateEnginePath } from '../engine';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/documents.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/documents.test.tsx
index 43bbc6cc67895..ace76ae55c046 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/documents.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/documents.test.tsx
@@ -8,10 +8,12 @@
import { setMockValues } from '../../../__mocks__/kea.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
import { DocumentCreationButton } from './document_creation_button';
import { SearchExperience } from './search_experience';
+
import { Documents } from '.';
describe('Documents', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/documents.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/documents.tsx
index 7223900911512..8c3ae7fd24f6d 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/documents.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/documents.tsx
@@ -7,16 +7,19 @@
import React from 'react';
-import { EuiPageHeader, EuiPageHeaderSection, EuiTitle, EuiCallOut, EuiSpacer } from '@elastic/eui';
import { useValues } from 'kea';
+
+import { EuiPageHeader, EuiPageHeaderSection, EuiTitle, EuiCallOut, EuiSpacer } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import { DocumentCreationButton } from './document_creation_button';
-import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
import { FlashMessages } from '../../../shared/flash_messages';
-import { DOCUMENTS_TITLE } from './constants';
-import { EngineLogic } from '../engine';
+import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
+
import { AppLogic } from '../../app_logic';
+import { EngineLogic } from '../engine';
+
+import { DOCUMENTS_TITLE } from './constants';
+import { DocumentCreationButton } from './document_creation_button';
import { SearchExperience } from './search_experience';
interface Props {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/build_search_ui_config.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/build_search_ui_config.ts
index b9577d9d0f07d..9fac068555db5 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/build_search_ui_config.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/build_search_ui_config.ts
@@ -6,6 +6,7 @@
*/
import { Schema } from '../../../../shared/types';
+
import { Fields } from './types';
export const buildSearchUIConfig = (apiConnector: object, schema: Schema, fields: Fields) => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/build_sort_options.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/build_sort_options.ts
index ab3a943ef2f55..54cf2bdd4f257 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/build_sort_options.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/build_sort_options.ts
@@ -7,8 +7,8 @@
import { flatten } from 'lodash';
-import { Fields, SortOption, SortDirection } from './types';
import { ASCENDING, DESCENDING } from './constants';
+import { Fields, SortOption, SortDirection } from './types';
const fieldNameToSortOptions = (fieldName: string): SortOption[] =>
['asc', 'desc'].map((direction) => ({
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/customization_callout.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/customization_callout.test.tsx
index e62e4521927dc..6ed2d7edc9639 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/customization_callout.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/customization_callout.test.tsx
@@ -8,6 +8,7 @@
import React from 'react';
import { shallow, ShallowWrapper } from 'enzyme';
+
import { EuiButton } from '@elastic/eui';
import { CustomizationCallout } from './customization_callout';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/customization_callout.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/customization_callout.tsx
index 8954549f74651..48a9fcdeaa878 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/customization_callout.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/customization_callout.tsx
@@ -6,9 +6,9 @@
*/
import React from 'react';
-import { i18n } from '@kbn/i18n';
import { EuiButton, EuiFlexGroup, EuiIcon, EuiSpacer, EuiText } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
interface Props {
onClick(): void;
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/customization_modal.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/customization_modal.test.tsx
index 11e13f4222abb..332c5b822eb6d 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/customization_modal.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/customization_modal.test.tsx
@@ -8,7 +8,9 @@
import { setMockValues, setMockActions } from '../../../../__mocks__';
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiButton, EuiButtonEmpty } from '@elastic/eui';
import { CustomizationModal } from './customization_modal';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/customization_modal.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/customization_modal.tsx
index 2d3604b2ba279..e05fc10053ff1 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/customization_modal.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/customization_modal.tsx
@@ -7,6 +7,8 @@
import React, { useState, useMemo } from 'react';
+import { useValues } from 'kea';
+
import {
EuiButton,
EuiButtonEmpty,
@@ -21,7 +23,6 @@ import {
EuiOverlayMask,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import { useValues } from 'kea';
import { EngineLogic } from '../../engine';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/hooks.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/hooks.test.tsx
index aecb4cc154117..028a9af21311f 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/hooks.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/hooks.test.tsx
@@ -25,8 +25,9 @@ jest.mock('react', () => ({
}));
import React from 'react';
-import { act } from 'react-dom/test-utils';
+
import { mount, ReactWrapper } from 'enzyme';
+import { act } from 'react-dom/test-utils';
import { useSearchContextState, useSearchContextActions } from './hooks';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/pagination.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/pagination.test.tsx
index 5fe47d5942ab8..b55163ca9843a 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/pagination.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/pagination.test.tsx
@@ -8,6 +8,7 @@
import React from 'react';
import { shallow } from 'enzyme';
+
// @ts-expect-error types are not available for this package yet
import { Paging, ResultsPerPage } from '@elastic/react-search-ui';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/pagination.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/pagination.tsx
index 846671c62de82..d81b056842642 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/pagination.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/pagination.tsx
@@ -10,6 +10,7 @@ import React from 'react';
import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
// @ts-expect-error types are not available for this package yet
import { Paging, ResultsPerPage } from '@elastic/react-search-ui';
+
import { PagingView, ResultsPerPageView } from './views';
export const Pagination: React.FC<{ 'aria-label': string }> = ({ 'aria-label': ariaLabel }) => (
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/search_experience.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/search_experience.test.tsx
index b0dccf0583e2f..bfa5c8264fece 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/search_experience.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/search_experience.test.tsx
@@ -8,21 +8,24 @@
import '../../../../__mocks__/enterprise_search_url.mock';
import { setMockValues } from '../../../../__mocks__';
+import React from 'react';
+
+import { shallow, ShallowWrapper } from 'enzyme';
+
+// @ts-expect-error types are not available for this package yet
+import { SearchProvider, Facet } from '@elastic/react-search-ui';
+
jest.mock('../../../../shared/use_local_storage', () => ({
useLocalStorage: jest.fn(),
}));
import { useLocalStorage } from '../../../../shared/use_local_storage';
-import React from 'react';
-// @ts-expect-error types are not available for this package yet
-import { SearchProvider, Facet } from '@elastic/react-search-ui';
-import { shallow, ShallowWrapper } from 'enzyme';
-
import { CustomizationCallout } from './customization_callout';
import { CustomizationModal } from './customization_modal';
+
import { Fields } from './types';
-import { SearchExperience } from './search_experience';
+import { SearchExperience } from './';
describe('SearchExperience', () => {
const values = {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/search_experience.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/search_experience.tsx
index 6ae4f264d7c74..6fbc6305edb25 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/search_experience.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/search_experience.tsx
@@ -7,13 +7,14 @@
import React, { useState } from 'react';
-import { i18n } from '@kbn/i18n';
import { useValues } from 'kea';
+
import { EuiButton, EuiSpacer, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
// @ts-expect-error types are not available for this package yet;
import { SearchProvider, SearchBox, Sorting, Facet } from '@elastic/react-search-ui';
// @ts-expect-error types are not available for this package yet
import AppSearchAPIConnector from '@elastic/search-ui-app-search-connector';
+import { i18n } from '@kbn/i18n';
import './search_experience.scss';
@@ -21,14 +22,14 @@ import { externalUrl } from '../../../../shared/enterprise_search_url';
import { useLocalStorage } from '../../../../shared/use_local_storage';
import { EngineLogic } from '../../engine';
-import { Fields, SortOption } from './types';
-import { SearchBoxView, SortingView, MultiCheckboxFacetsView } from './views';
-import { SearchExperienceContent } from './search_experience_content';
import { buildSearchUIConfig } from './build_search_ui_config';
-import { CustomizationCallout } from './customization_callout';
-import { CustomizationModal } from './customization_modal';
import { buildSortOptions } from './build_sort_options';
import { ASCENDING, DESCENDING } from './constants';
+import { CustomizationCallout } from './customization_callout';
+import { CustomizationModal } from './customization_modal';
+import { SearchExperienceContent } from './search_experience_content';
+import { Fields, SortOption } from './types';
+import { SearchBoxView, SortingView, MultiCheckboxFacetsView } from './views';
const RECENTLY_UPLOADED = i18n.translate(
'xpack.enterpriseSearch.appSearch.documents.search.sortBy.option.recentlyUploaded',
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/search_experience_content.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/search_experience_content.test.tsx
index 737e3ea1b2999..49f51c2010e3a 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/search_experience_content.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/search_experience_content.test.tsx
@@ -6,18 +6,20 @@
*/
import { setMockValues } from '../../../../__mocks__/kea.mock';
-import { setMockSearchContextState } from './__mocks__/hooks.mock';
import React from 'react';
import { shallow, mount } from 'enzyme';
+
// @ts-expect-error types are not available for this package yet
import { Results } from '@elastic/react-search-ui';
-import { ResultView } from './views';
-import { Pagination } from './pagination';
import { SchemaTypes } from '../../../../shared/types';
+
+import { setMockSearchContextState } from './__mocks__/hooks.mock';
+import { Pagination } from './pagination';
import { SearchExperienceContent } from './search_experience_content';
+import { ResultView } from './views';
describe('SearchExperienceContent', () => {
const searchState = {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/search_experience_content.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/search_experience_content.tsx
index 45c20d8ffce2c..91db26ac676c9 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/search_experience_content.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/search_experience_content.tsx
@@ -7,20 +7,22 @@
import React from 'react';
-import { i18n } from '@kbn/i18n';
+import { useValues } from 'kea';
+
import { EuiFlexGroup, EuiSpacer, EuiButton, EuiEmptyPrompt } from '@elastic/eui';
// @ts-expect-error types are not available for this package yet
import { Results, Paging, ResultsPerPage } from '@elastic/react-search-ui';
-import { useValues } from 'kea';
+import { i18n } from '@kbn/i18n';
-import { ResultView } from './views';
-import { Pagination } from './pagination';
-import { useSearchContextState } from './hooks';
-import { DocumentCreationButton } from '../document_creation_button';
import { AppLogic } from '../../../app_logic';
-import { EngineLogic } from '../../engine';
import { DOCS_PREFIX } from '../../../routes';
+import { EngineLogic } from '../../engine';
import { Result } from '../../result/types';
+import { DocumentCreationButton } from '../document_creation_button';
+
+import { useSearchContextState } from './hooks';
+import { Pagination } from './pagination';
+import { ResultView } from './views';
export const SearchExperienceContent: React.FC = () => {
const { resultSearchTerm, totalResults, wasSearched } = useSearchContextState();
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/paging_view.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/paging_view.test.tsx
index 03b9e33f89fef..28cd126e5c004 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/paging_view.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/paging_view.test.tsx
@@ -8,6 +8,7 @@
import React from 'react';
import { shallow } from 'enzyme';
+
import { EuiPagination } from '@elastic/eui';
import { PagingView } from './paging_view';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/result_view.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/result_view.test.tsx
index e06603894c288..24685aef71078 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/result_view.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/result_view.test.tsx
@@ -9,10 +9,11 @@ import React from 'react';
import { shallow } from 'enzyme';
-import { ResultView } from '.';
import { SchemaTypes } from '../../../../../shared/types';
import { Result } from '../../../result/result';
+import { ResultView } from '.';
+
describe('ResultView', () => {
const result = {
id: {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/result_view.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/result_view.tsx
index 9dd3fcea5f754..b133780310a4c 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/result_view.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/result_view.tsx
@@ -7,9 +7,9 @@
import React from 'react';
-import { Result as ResultType } from '../../../result/types';
import { Schema } from '../../../../../shared/types';
import { Result } from '../../../result/result';
+import { Result as ResultType } from '../../../result/types';
export interface Props {
result: ResultType;
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/results_per_page_view.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/results_per_page_view.test.tsx
index 70e4d7e4e1878..24db762e26e32 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/results_per_page_view.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/results_per_page_view.test.tsx
@@ -8,6 +8,7 @@
import React from 'react';
import { shallow } from 'enzyme';
+
import { EuiSelect } from '@elastic/eui';
import { ResultsPerPageView } from '.';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/results_per_page_view.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/results_per_page_view.tsx
index b57944042e67f..5056d56d1f3d0 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/results_per_page_view.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/results_per_page_view.tsx
@@ -7,8 +7,8 @@
import React from 'react';
-import { i18n } from '@kbn/i18n';
import { EuiSelect, EuiSelectOption } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
const wrapResultsPerPageOptionForEuiSelect: (option: number) => EuiSelectOption = (option) => ({
text: option,
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/search_box_view.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/search_box_view.test.tsx
index 182e2ea222f90..a35fcefb30ac6 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/search_box_view.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/search_box_view.test.tsx
@@ -8,6 +8,7 @@
import React from 'react';
import { shallow } from 'enzyme';
+
import { EuiFieldSearch } from '@elastic/eui';
import { SearchBoxView } from './search_box_view';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/sorting_view.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/sorting_view.test.tsx
index 4f7317a2bf5d0..a147f45feef14 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/sorting_view.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/sorting_view.test.tsx
@@ -8,6 +8,7 @@
import React from 'react';
import { shallow } from 'enzyme';
+
import { EuiSelect } from '@elastic/eui';
import { SortingView } from '.';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/sorting_view.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/sorting_view.tsx
index 047caf6ca1e3b..e3f21b67a6530 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/sorting_view.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/sorting_view.tsx
@@ -7,8 +7,8 @@
import React from 'react';
-import { i18n } from '@kbn/i18n';
import { EuiSelect, EuiSelectOption } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
interface Option {
label: string;
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_logic.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_logic.ts
index fbe08cbeb939f..664a3006cfa2c 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_logic.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_logic.ts
@@ -10,6 +10,7 @@ import { kea, MakeLogicType } from 'kea';
import { HttpLogic } from '../../../shared/http';
import { IIndexingStatus } from '../../../shared/types';
+
import { EngineDetails } from './types';
interface EngineValues {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_nav.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_nav.test.tsx
index 8ed36ad5ab006..1781883aa6532 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_nav.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_nav.test.tsx
@@ -9,7 +9,9 @@ import { setMockValues, rerender } from '../../../__mocks__';
import { mockEngineValues } from '../../__mocks__';
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiBadge, EuiIcon } from '@elastic/eui';
import { EngineNav } from './engine_nav';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_nav.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_nav.tsx
index b1b31c245eb99..447e4d678bcdb 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_nav.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_nav.tsx
@@ -6,11 +6,13 @@
*/
import React from 'react';
+
import { useValues } from 'kea';
import { EuiText, EuiBadge, EuiIcon, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
+import { getAppSearchUrl } from '../../../shared/enterprise_search_url';
import { SideNavLink, SideNavItem } from '../../../shared/layout';
import { AppLogic } from '../../app_logic';
import {
@@ -27,23 +29,23 @@ import {
ENGINE_SEARCH_UI_PATH,
ENGINE_API_LOGS_PATH,
} from '../../routes';
-import { getAppSearchUrl } from '../../../shared/enterprise_search_url';
-import { ENGINES_TITLE } from '../engines';
-import { OVERVIEW_TITLE } from '../engine_overview';
import { ANALYTICS_TITLE } from '../analytics';
-import { DOCUMENTS_TITLE } from '../documents';
-import { SCHEMA_TITLE } from '../schema';
+import { API_LOGS_TITLE } from '../api_logs';
import { CRAWLER_TITLE } from '../crawler';
-import { RELEVANCE_TUNING_TITLE } from '../relevance_tuning';
-import { SYNONYMS_TITLE } from '../synonyms';
import { CURATIONS_TITLE } from '../curations';
+import { DOCUMENTS_TITLE } from '../documents';
+import { OVERVIEW_TITLE } from '../engine_overview';
+import { ENGINES_TITLE } from '../engines';
+import { RELEVANCE_TUNING_TITLE } from '../relevance_tuning';
import { RESULT_SETTINGS_TITLE } from '../result_settings';
+import { SCHEMA_TITLE } from '../schema';
import { SEARCH_UI_TITLE } from '../search_ui';
-import { API_LOGS_TITLE } from '../api_logs';
+import { SYNONYMS_TITLE } from '../synonyms';
-import { EngineLogic, generateEnginePath } from './';
import { EngineDetails } from './types';
+import { EngineLogic, generateEnginePath } from './';
+
import './engine_nav.scss';
export const EngineNav: React.FC = () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.test.tsx
index cff05b296846b..3740882dee3db 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.test.tsx
@@ -6,17 +6,18 @@
*/
import '../../../__mocks__/react_router_history.mock';
-import { unmountHandler } from '../../../__mocks__/shallow_useeffect.mock';
import { mockFlashMessageHelpers, setMockValues, setMockActions } from '../../../__mocks__';
+import { unmountHandler } from '../../../__mocks__/shallow_useeffect.mock';
import { mockEngineValues } from '../../__mocks__';
import React from 'react';
-import { shallow } from 'enzyme';
import { Switch, Redirect, useParams } from 'react-router-dom';
+import { shallow } from 'enzyme';
+
import { Loading } from '../../../shared/loading';
-import { EngineOverview } from '../engine_overview';
import { AnalyticsRouter } from '../analytics';
+import { EngineOverview } from '../engine_overview';
import { RelevanceTuning } from '../relevance_tuning';
import { EngineRouter } from './engine_router';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.tsx
index 257bb1e69ad7f..2f1c3bc57d331 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_router.tsx
@@ -7,12 +7,14 @@
import React, { useEffect } from 'react';
import { Route, Switch, Redirect, useParams } from 'react-router-dom';
+
import { useValues, useActions } from 'kea';
import { i18n } from '@kbn/i18n';
-import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
import { setQueuedErrorMessage } from '../../../shared/flash_messages';
+import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
+import { Loading } from '../../../shared/loading';
import { AppLogic } from '../../app_logic';
// TODO: Uncomment and add more routes as we migrate them
@@ -31,13 +33,11 @@ import {
// ENGINE_SEARCH_UI_PATH,
// ENGINE_API_LOGS_PATH,
} from '../../routes';
-import { ENGINES_TITLE } from '../engines';
-import { OVERVIEW_TITLE } from '../engine_overview';
-
-import { Loading } from '../../../shared/loading';
-import { EngineOverview } from '../engine_overview';
import { AnalyticsRouter } from '../analytics';
import { DocumentDetail, Documents } from '../documents';
+import { OVERVIEW_TITLE } from '../engine_overview';
+import { EngineOverview } from '../engine_overview';
+import { ENGINES_TITLE } from '../engines';
import { RelevanceTuning } from '../relevance_tuning';
import { EngineLogic } from './';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/types.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/types.ts
index d20f9890cd4db..b50e8eb555dc9 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/types.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/types.ts
@@ -5,8 +5,8 @@
* 2.0.
*/
-import { ApiToken } from '../credentials/types';
import { Schema, SchemaConflicts, IIndexingStatus } from '../../../shared/types';
+import { ApiToken } from '../credentials/types';
export interface Engine {
name: string;
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/recent_api_logs.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/recent_api_logs.test.tsx
index 7b52a04d07958..42fa9777563db 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/recent_api_logs.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/recent_api_logs.test.tsx
@@ -8,6 +8,7 @@
import '../../../__mocks__/engine_logic.mock';
import React from 'react';
+
import { shallow, ShallowWrapper } from 'enzyme';
import { EuiButtonTo } from '../../../../shared/react_router_helpers';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/recent_api_logs.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/recent_api_logs.tsx
index d7290533f4f7b..625ba2e905840 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/recent_api_logs.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/recent_api_logs.tsx
@@ -17,9 +17,9 @@ import {
import { EuiButtonTo } from '../../../../shared/react_router_helpers';
import { ENGINE_API_LOGS_PATH } from '../../../routes';
+import { RECENT_API_EVENTS } from '../../api_logs/constants';
import { generateEnginePath } from '../../engine';
-import { RECENT_API_EVENTS } from '../../api_logs/constants';
import { VIEW_API_LOGS } from '../constants';
export const RecentApiLogs: React.FC = () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/total_charts.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/total_charts.test.tsx
index 867b78f859a22..a2f35b4709939 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/total_charts.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/total_charts.test.tsx
@@ -9,6 +9,7 @@ import { setMockValues } from '../../../../__mocks__/kea.mock';
import '../../../__mocks__/engine_logic.mock';
import React from 'react';
+
import { shallow, ShallowWrapper } from 'enzyme';
import { EuiButtonTo } from '../../../../shared/react_router_helpers';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/total_charts.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/total_charts.tsx
index 4fa2246ee6170..6bd973ae142a8 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/total_charts.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/total_charts.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { useValues } from 'kea';
import {
@@ -21,12 +22,12 @@ import {
import { EuiButtonTo } from '../../../../shared/react_router_helpers';
import { ENGINE_ANALYTICS_PATH, ENGINE_API_LOGS_PATH } from '../../../routes';
+import { AnalyticsChart, convertToChartData } from '../../analytics';
+import { TOTAL_QUERIES, TOTAL_API_OPERATIONS } from '../../analytics/constants';
import { generateEnginePath } from '../../engine';
-import { TOTAL_QUERIES, TOTAL_API_OPERATIONS } from '../../analytics/constants';
import { VIEW_ANALYTICS, VIEW_API_LOGS, LAST_7_DAYS } from '../constants';
-import { AnalyticsChart, convertToChartData } from '../../analytics';
-import { EngineOverviewLogic } from '../';
+import { EngineOverviewLogic } from '../index';
export const TotalCharts: React.FC = () => {
const { startDate, queriesPerDay, operationsPerDay } = useValues(EngineOverviewLogic);
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/total_stats.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/total_stats.test.tsx
index a897c635eeadd..7fcda61073c5b 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/total_stats.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/total_stats.test.tsx
@@ -8,9 +8,11 @@
import { setMockValues } from '../../../../__mocks__/kea.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
import { AnalyticsCards } from '../../analytics';
+
import { TotalStats } from './total_stats';
describe('TotalStats', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/total_stats.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/total_stats.tsx
index 3eb208fa86504..35c6fa439a416 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/total_stats.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/total_stats.tsx
@@ -6,12 +6,12 @@
*/
import React from 'react';
+
import { useValues } from 'kea';
-import { TOTAL_QUERIES, TOTAL_DOCUMENTS, TOTAL_CLICKS } from '../../analytics/constants';
import { AnalyticsCards } from '../../analytics';
-
-import { EngineOverviewLogic } from '../';
+import { TOTAL_QUERIES, TOTAL_DOCUMENTS, TOTAL_CLICKS } from '../../analytics/constants';
+import { EngineOverviewLogic } from '../index';
export const TotalStats: React.FC = () => {
const { totalQueries, documentCount, totalClicks } = useValues(EngineOverviewLogic);
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/unavailable_prompt.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/unavailable_prompt.test.tsx
index 7cd042a646e73..4c61a713b3793 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/unavailable_prompt.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/unavailable_prompt.test.tsx
@@ -6,7 +6,9 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiEmptyPrompt } from '@elastic/eui';
import { UnavailablePrompt } from './unavailable_prompt';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/unavailable_prompt.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/unavailable_prompt.tsx
index 2916be92ead99..69e79ecfc580d 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/unavailable_prompt.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/unavailable_prompt.tsx
@@ -7,8 +7,8 @@
import React from 'react';
-import { i18n } from '@kbn/i18n';
import { EuiEmptyPrompt } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
export const UnavailablePrompt: React.FC = () => (
{
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview.tsx
index 9e673d48a7e5b..77552b36af239 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview.tsx
@@ -6,16 +6,19 @@
*/
import React, { useEffect } from 'react';
+
import { useActions, useValues } from 'kea';
+import { Loading } from '../../../shared/loading';
import { AppLogic } from '../../app_logic';
import { EngineLogic } from '../engine';
-import { Loading } from '../../../shared/loading';
-import { EngineOverviewLogic } from './';
import { EmptyEngineOverview } from './engine_overview_empty';
+
import { EngineOverviewMetrics } from './engine_overview_metrics';
+import { EngineOverviewLogic } from './';
+
export const EngineOverview: React.FC = () => {
const {
myRole: { canManageEngineDocuments, canViewEngineCredentials },
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.test.tsx
index 5947618e59c16..9066283229a04 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.test.tsx
@@ -6,12 +6,15 @@
*/
import React from 'react';
+
import { shallow, ShallowWrapper } from 'enzyme';
+
import { EuiButton } from '@elastic/eui';
import { docLinks } from '../../../shared/doc_links';
import { DocumentCreationButtons, DocumentCreationFlyout } from '../document_creation';
+
import { EmptyEngineOverview } from './engine_overview_empty';
describe('EmptyEngineOverview', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.tsx
index 6a0c46286907d..81bf3716edfb8 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_empty.tsx
@@ -7,7 +7,6 @@
import React from 'react';
-import { i18n } from '@kbn/i18n';
import {
EuiPageHeader,
EuiPageHeaderSection,
@@ -15,6 +14,7 @@ import {
EuiTitle,
EuiButton,
} from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
import { DOCS_PREFIX } from '../../routes';
import { DocumentCreationButtons, DocumentCreationFlyout } from '../document_creation';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_metrics.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_metrics.test.tsx
index ebcdbaf1f7f09..638c8b0da87ce 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_metrics.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_metrics.test.tsx
@@ -8,6 +8,7 @@
import { setMockValues } from '../../../__mocks__/kea.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
import { UnavailablePrompt, TotalStats, TotalCharts, RecentApiLogs } from './components';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_metrics.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_metrics.tsx
index ffb1a25d21cae..34a154ca83741 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_metrics.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview_metrics.tsx
@@ -6,15 +6,16 @@
*/
import React from 'react';
+
import { useValues } from 'kea';
-import { i18n } from '@kbn/i18n';
import { EuiPageHeader, EuiTitle, EuiSpacer } from '@elastic/eui';
-
-import { EngineOverviewLogic } from './';
+import { i18n } from '@kbn/i18n';
import { UnavailablePrompt, TotalStats, TotalCharts, RecentApiLogs } from './components';
+import { EngineOverviewLogic } from './';
+
export const EngineOverviewMetrics: React.FC = () => {
const { apiLogsUnavailable } = useValues(EngineOverviewLogic);
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/assets/icons.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/assets/icons.test.tsx
index 9c2818f9907a4..33ca5bd8248c9 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/assets/icons.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/assets/icons.test.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { EngineIcon } from './engine_icon';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/empty_state.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/empty_state.test.tsx
index b04226b6b1dfb..ac540eec3ff91 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/empty_state.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/empty_state.test.tsx
@@ -9,7 +9,9 @@ import '../../../../__mocks__/kea.mock';
import { mockTelemetryActions } from '../../../../__mocks__';
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiEmptyPrompt, EuiButton } from '@elastic/eui';
import { EmptyState } from './';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/empty_state.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/empty_state.tsx
index 60a454a5707c9..5419a175c9eff 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/empty_state.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/empty_state.tsx
@@ -6,13 +6,15 @@
*/
import React from 'react';
+
import { useActions } from 'kea';
+
import { EuiPageContent, EuiEmptyPrompt, EuiButton } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
-import { TelemetryLogic } from '../../../../shared/telemetry';
import { getAppSearchUrl } from '../../../../shared/enterprise_search_url';
import { SetAppSearchChrome as SetPageChrome } from '../../../../shared/kibana_chrome';
+import { TelemetryLogic } from '../../../../shared/telemetry';
import { CREATE_ENGINES_PATH } from '../../../routes';
import { EnginesOverviewHeader } from './header';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/header.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/header.test.tsx
index 6dedb90690ace..5ccd2c552ef02 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/header.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/header.test.tsx
@@ -10,6 +10,7 @@ import '../../../../__mocks__/enterprise_search_url.mock';
import { mockTelemetryActions } from '../../../../__mocks__';
import React from 'react';
+
import { shallow } from 'enzyme';
import { EnginesOverviewHeader } from './';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/header.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/header.tsx
index 8a8227821b492..290270c08258c 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/header.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/header.tsx
@@ -6,7 +6,9 @@
*/
import React from 'react';
+
import { useActions } from 'kea';
+
import {
EuiPageHeader,
EuiPageHeaderSection,
@@ -17,8 +19,8 @@ import {
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
-import { TelemetryLogic } from '../../../../shared/telemetry';
import { getAppSearchUrl } from '../../../../shared/enterprise_search_url';
+import { TelemetryLogic } from '../../../../shared/telemetry';
export const EnginesOverviewHeader: React.FC = () => {
const { sendAppSearchTelemetry } = useActions(TelemetryLogic);
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/loading_state.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/loading_state.test.tsx
index 4adc8c11fa0dd..f7ccfea4bb4d4 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/loading_state.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/loading_state.test.tsx
@@ -6,7 +6,9 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiLoadingContent } from '@elastic/eui';
import { LoadingState } from './';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/loading_state.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/loading_state.tsx
index 48160602106cd..155d8263c484d 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/loading_state.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/components/loading_state.tsx
@@ -6,9 +6,11 @@
*/
import React from 'react';
+
import { EuiPageContent, EuiSpacer, EuiLoadingContent } from '@elastic/eui';
import { SetAppSearchChrome as SetPageChrome } from '../../../../shared/kibana_chrome';
+
import { EnginesOverviewHeader } from './header';
export const LoadingState: React.FC = () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_logic.test.ts
index c25f60e47598e..9e9bfc4973124 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_logic.test.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_logic.test.ts
@@ -10,6 +10,7 @@ import { LogicMounter, mockHttpValues } from '../../../__mocks__';
import { nextTick } from '@kbn/test/jest';
import { EngineDetails } from '../engine/types';
+
import { EnginesLogic } from './';
describe('EnginesLogic', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.test.tsx
index f4aeb60a88250..cdc06dbbe3921 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.test.tsx
@@ -9,6 +9,7 @@ import '../../../__mocks__/shallow_useeffect.mock';
import { setMockValues, setMockActions, rerender } from '../../../__mocks__';
import React from 'react';
+
import { shallow, ShallowWrapper } from 'enzyme';
import { LoadingState, EmptyState } from './components';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.tsx
index c13db688fc2b6..2835c8b7cb3c4 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.tsx
@@ -6,7 +6,9 @@
*/
import React, { useEffect } from 'react';
+
import { useValues, useActions } from 'kea';
+
import {
EuiPageContent,
EuiPageContentHeader,
@@ -15,17 +17,17 @@ import {
EuiSpacer,
} from '@elastic/eui';
-import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
-import { SendAppSearchTelemetry as SendTelemetry } from '../../../shared/telemetry';
import { FlashMessages } from '../../../shared/flash_messages';
+import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
import { LicensingLogic } from '../../../shared/licensing';
+import { SendAppSearchTelemetry as SendTelemetry } from '../../../shared/telemetry';
import { EngineIcon } from './assets/engine_icon';
import { MetaEngineIcon } from './assets/meta_engine_icon';
-import { ENGINES_TITLE, META_ENGINES_TITLE } from './constants';
import { EnginesOverviewHeader, LoadingState, EmptyState } from './components';
-import { EnginesTable } from './engines_table';
+import { ENGINES_TITLE, META_ENGINES_TITLE } from './constants';
import { EnginesLogic } from './engines_logic';
+import { EnginesTable } from './engines_table';
import './engines_overview.scss';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_table.test.tsx
index 65b96035eaaee..d6f0946164ea4 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_table.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_table.test.tsx
@@ -9,10 +9,13 @@ import '../../../__mocks__/enterprise_search_url.mock';
import { mockTelemetryActions, mountWithIntl } from '../../../__mocks__';
import React from 'react';
+
import { EuiBasicTable, EuiPagination, EuiButtonEmpty } from '@elastic/eui';
+
import { EuiLinkTo } from '../../../shared/react_router_helpers';
import { EngineDetails } from '../engine/types';
+
import { EnginesTable } from './engines_table';
describe('EnginesTable', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_table.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_table.tsx
index b439d7e6bdf33..d41c5c908c08f 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_table.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_table.tsx
@@ -6,18 +6,19 @@
*/
import React from 'react';
+
import { useActions } from 'kea';
+
import { EuiBasicTable, EuiBasicTableColumn } from '@elastic/eui';
-import { FormattedMessage, FormattedDate, FormattedNumber } from '@kbn/i18n/react';
import { i18n } from '@kbn/i18n';
-
-import { TelemetryLogic } from '../../../shared/telemetry';
-import { EuiLinkTo } from '../../../shared/react_router_helpers';
-import { generateEncodedPath } from '../../utils/encode_path_params';
-import { ENGINE_PATH } from '../../routes';
+import { FormattedMessage, FormattedDate, FormattedNumber } from '@kbn/i18n/react';
import { ENGINES_PAGE_SIZE } from '../../../../../common/constants';
+import { EuiLinkTo } from '../../../shared/react_router_helpers';
+import { TelemetryLogic } from '../../../shared/telemetry';
import { UNIVERSAL_LANGUAGE } from '../../constants';
+import { ENGINE_PATH } from '../../routes';
+import { generateEncodedPath } from '../../utils/encode_path_params';
import { EngineDetails } from '../engine/types';
interface EnginesTablePagination {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/error_connecting/error_connecting.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/error_connecting/error_connecting.test.tsx
index 6ff33385df9a5..9ec3fdda63656 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/error_connecting/error_connecting.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/error_connecting/error_connecting.test.tsx
@@ -6,9 +6,11 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { ErrorStatePrompt } from '../../../shared/error_state';
+
import { ErrorConnecting } from './';
describe('ErrorConnecting', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/error_connecting/error_connecting.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/error_connecting/error_connecting.tsx
index ad5eff6c4dacf..d7fde0cd5dd25 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/error_connecting/error_connecting.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/error_connecting/error_connecting.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { EuiPageContent } from '@elastic/eui';
import { ErrorStatePrompt } from '../../../shared/error_state';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/library/library.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/library/library.tsx
index 2d39b5a9aa05c..f76ad78c847d1 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/library/library.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/library/library.tsx
@@ -5,6 +5,8 @@
* 2.0.
*/
+import React from 'react';
+
import {
EuiSpacer,
EuiPageHeader,
@@ -13,7 +15,6 @@ import {
EuiPageContentBody,
EuiPageContent,
} from '@elastic/eui';
-import React from 'react';
import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
import { Schema } from '../../../shared/types';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/components/log_retention_callout.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/components/log_retention_callout.test.tsx
index d0bc1c9a88c5f..124edb6871453 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/components/log_retention_callout.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/components/log_retention_callout.test.tsx
@@ -6,14 +6,16 @@
*/
import '../../../../__mocks__/shallow_useeffect.mock';
-import { setMockValues, setMockActions } from '../../../../__mocks__/kea.mock';
-import { mountWithIntl } from '../../../../__mocks__';
+import { setMockValues, setMockActions, mountWithIntl } from '../../../../__mocks__';
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiCallOut, EuiLink } from '@elastic/eui';
import { LogRetentionOptions } from '../';
+
import { LogRetentionCallout } from './';
describe('LogRetentionCallout', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/components/log_retention_callout.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/components/log_retention_callout.tsx
index 0252a788f75ef..235d977793161 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/components/log_retention_callout.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/components/log_retention_callout.tsx
@@ -6,11 +6,12 @@
*/
import React, { useEffect } from 'react';
+
import { useValues, useActions } from 'kea';
+import { EuiCallOut, EuiSpacer } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
-import { EuiCallOut, EuiSpacer } from '@elastic/eui';
import { EuiLinkTo } from '../../../../shared/react_router_helpers';
@@ -19,7 +20,7 @@ import { SETTINGS_PATH } from '../../../routes';
import { ANALYTICS_TITLE } from '../../analytics';
import { API_LOGS_TITLE } from '../../api_logs';
-import { LogRetentionLogic, LogRetentionOptions, renderLogRetentionDate } from '../';
+import { LogRetentionLogic, LogRetentionOptions, renderLogRetentionDate } from '../index';
const TITLE_MAP = {
[LogRetentionOptions.Analytics]: ANALYTICS_TITLE,
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/components/log_retention_tooltip.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/components/log_retention_tooltip.test.tsx
index 14615f6ac2dd9..854a9f1d8d162 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/components/log_retention_tooltip.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/components/log_retention_tooltip.test.tsx
@@ -9,10 +9,13 @@ import '../../../../__mocks__/shallow_useeffect.mock';
import { setMockValues, setMockActions } from '../../../../__mocks__/kea.mock';
import React from 'react';
+
import { shallow, mount } from 'enzyme';
+
import { EuiIconTip } from '@elastic/eui';
import { LogRetentionOptions, LogRetentionMessage } from '../';
+
import { LogRetentionTooltip } from './';
describe('LogRetentionTooltip', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/components/log_retention_tooltip.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/components/log_retention_tooltip.tsx
index e3b428baa6d9a..bf074ba0272f2 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/components/log_retention_tooltip.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/components/log_retention_tooltip.tsx
@@ -6,10 +6,11 @@
*/
import React, { useEffect } from 'react';
+
import { useValues, useActions } from 'kea';
-import { i18n } from '@kbn/i18n';
import { EuiIconTip } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
import { LogRetentionLogic, LogRetentionMessage, LogRetentionOptions } from '../';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/log_retention_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/log_retention_logic.test.ts
index 9615aba5fdef4..19bd2af50aad9 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/log_retention_logic.test.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/log_retention_logic.test.ts
@@ -10,7 +10,8 @@ import { LogicMounter, mockHttpValues, mockFlashMessageHelpers } from '../../../
import { nextTick } from '@kbn/test/jest';
import { LogRetentionOptions } from './types';
-import { LogRetentionLogic } from './log_retention_logic';
+
+import { LogRetentionLogic } from './';
describe('LogRetentionLogic', () => {
const { mount } = new LogicMounter(LogRetentionLogic);
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/log_retention_logic.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/log_retention_logic.ts
index 77d4cf395196a..ec078842dab55 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/log_retention_logic.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/log_retention_logic.ts
@@ -7,8 +7,8 @@
import { kea, MakeLogicType } from 'kea';
-import { HttpLogic } from '../../../shared/http';
import { flashAPIErrors } from '../../../shared/flash_messages';
+import { HttpLogic } from '../../../shared/http';
import { LogRetentionOptions, LogRetention, LogRetentionServer } from './types';
import { convertLogRetentionFromServerToClient } from './utils/convert_log_retention';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/messaging/constants.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/messaging/constants.tsx
index 0f231092a36e2..c7c4d90d91ce8 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/messaging/constants.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/messaging/constants.tsx
@@ -6,8 +6,9 @@
*/
import React from 'react';
-import { FormattedDate, FormattedMessage } from '@kbn/i18n/react';
+
import { i18n } from '@kbn/i18n';
+import { FormattedDate, FormattedMessage } from '@kbn/i18n/react';
import { LogRetentionOptions, LogRetentionSettings, LogRetentionPolicy } from '../types';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/messaging/log_retention_message.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/messaging/log_retention_message.test.tsx
index be95261a35c25..cd71e37108927 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/messaging/log_retention_message.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/messaging/log_retention_message.test.tsx
@@ -5,13 +5,14 @@
* 2.0.
*/
-import { setMockValues } from '../../../../__mocks__/kea.mock';
-import { mountWithIntl } from '../../../../__mocks__';
+import { setMockValues, mountWithIntl } from '../../../../__mocks__';
import React from 'react';
+
import { shallow } from 'enzyme';
import { LogRetentionOptions } from '../types';
+
import { LogRetentionMessage } from './';
describe('LogRetentionMessage', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/messaging/log_retention_message.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/messaging/log_retention_message.tsx
index 62bac44b122af..7d34a2567ba14 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/messaging/log_retention_message.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/log_retention/messaging/log_retention_message.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { useValues } from 'kea';
import { AppLogic } from '../../../app_logic';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/constants.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/constants.ts
index 3655c60bde3bf..211995b2a7d18 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/constants.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/constants.ts
@@ -11,3 +11,29 @@ export const RELEVANCE_TUNING_TITLE = i18n.translate(
'xpack.enterpriseSearch.appSearch.engine.relevanceTuning.title',
{ defaultMessage: 'Relevance Tuning' }
);
+
+export const UPDATE_SUCCESS_MESSAGE = i18n.translate(
+ 'xpack.enterpriseSearch.appSearch.relevanceTuning.messages.updateSuccess',
+ {
+ defaultMessage: 'Relevance successfully tuned. The changes will impact your results shortly.',
+ }
+);
+export const DELETE_SUCCESS_MESSAGE = i18n.translate(
+ 'xpack.enterpriseSearch.appSearch.relevanceTuning.messages.deleteSuccess',
+ {
+ defaultMessage:
+ 'Relevance has been reset to default values. The change will impact your results shortly.',
+ }
+);
+export const RESET_CONFIRMATION_MESSAGE = i18n.translate(
+ 'xpack.enterpriseSearch.appSearch.relevanceTuning.messages.resetConfirmation',
+ {
+ defaultMessage: 'Are you sure you want to restore relevance defaults?',
+ }
+);
+export const DELETE_CONFIRMATION_MESSAGE = i18n.translate(
+ 'xpack.enterpriseSearch.appSearch.relevanceTuning.messages.deleteConfirmation',
+ {
+ defaultMessage: 'Are you sure you want to delete this boost?',
+ }
+);
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning.tsx
index 56e31ec6bf970..83e83c0f9ea43 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import {
EuiPageHeader,
EuiPageHeaderSection,
@@ -14,8 +15,8 @@ import {
EuiPageContent,
} from '@elastic/eui';
-import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
import { FlashMessages } from '../../../shared/flash_messages';
+import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
import { RELEVANCE_TUNING_TITLE } from './constants';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_logic.test.ts
index 586a845ce382a..194848bcfc86c 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_logic.test.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_logic.test.ts
@@ -5,11 +5,17 @@
* 2.0.
*/
-import { LogicMounter } from '../../../__mocks__';
+import { LogicMounter, mockFlashMessageHelpers, mockHttpValues } from '../../../__mocks__';
-import { BoostType } from './types';
+import { nextTick } from '@kbn/test/jest';
-import { RelevanceTuningLogic } from './relevance_tuning_logic';
+import { Boost, BoostType } from './types';
+
+import { RelevanceTuningLogic } from './';
+
+jest.mock('../engine', () => ({
+ EngineLogic: { values: { engineName: 'test-engine' } },
+}));
describe('RelevanceTuningLogic', () => {
const { mount } = new LogicMounter(RelevanceTuningLogic);
@@ -32,13 +38,27 @@ describe('RelevanceTuningLogic', () => {
schema,
schemaConflicts,
};
- const searchResults = [{}, {}];
+ const searchResults = [
+ {
+ id: {
+ raw: '1',
+ },
+ _meta: {
+ id: '1',
+ score: 100,
+ engine: 'my-engine',
+ },
+ },
+ ];
const DEFAULT_VALUES = {
dataLoading: true,
schema: {},
schemaConflicts: {},
- searchSettings: {},
+ searchSettings: {
+ boosts: {},
+ search_fields: {},
+ },
unsavedChanges: false,
filterInputValue: '',
query: '',
@@ -188,6 +208,873 @@ describe('RelevanceTuningLogic', () => {
});
});
});
+
+ describe('setSearchSettingsResponse', () => {
+ it('should set searchSettings state and unsavedChanges to false', () => {
+ mount({
+ unsavedChanges: true,
+ });
+ RelevanceTuningLogic.actions.setSearchSettingsResponse(searchSettings);
+
+ expect(RelevanceTuningLogic.values).toEqual({
+ ...DEFAULT_VALUES,
+ searchSettings,
+ unsavedChanges: false,
+ });
+ });
+ });
+ });
+
+ describe('listeners', () => {
+ const { http } = mockHttpValues;
+ const { flashAPIErrors, setSuccessMessage } = mockFlashMessageHelpers;
+ let scrollToSpy: jest.SpyInstance;
+ let confirmSpy: jest.SpyInstance;
+
+ const searchSettingsWithBoost = (boost: Boost) => ({
+ ...searchSettings,
+ boosts: {
+ foo: [
+ {
+ factor: 1,
+ type: 'functional',
+ },
+ boost,
+ ],
+ },
+ });
+
+ beforeAll(() => {
+ scrollToSpy = jest.spyOn(window, 'scrollTo').mockImplementation(() => true);
+ confirmSpy = jest.spyOn(window, 'confirm');
+ });
+
+ afterAll(() => {
+ scrollToSpy.mockRestore();
+ confirmSpy.mockRestore();
+ });
+
+ describe('initializeRelevanceTuning', () => {
+ it('should make an API call and set state based on the normalized response', async () => {
+ mount();
+ http.get.mockReturnValueOnce(
+ Promise.resolve({
+ ...relevanceTuningProps,
+ searchSettings: {
+ ...relevanceTuningProps.searchSettings,
+ boosts: {
+ foo: [
+ {
+ type: 'value' as BoostType,
+ factor: 5,
+ value: 5,
+ },
+ ],
+ },
+ },
+ })
+ );
+ jest.spyOn(RelevanceTuningLogic.actions, 'onInitializeRelevanceTuning');
+
+ RelevanceTuningLogic.actions.initializeRelevanceTuning();
+ await nextTick();
+
+ expect(http.get).toHaveBeenCalledWith(
+ '/api/app_search/engines/test-engine/search_settings/details'
+ );
+ expect(RelevanceTuningLogic.actions.onInitializeRelevanceTuning).toHaveBeenCalledWith({
+ ...relevanceTuningProps,
+ searchSettings: {
+ ...relevanceTuningProps.searchSettings,
+ boosts: {
+ foo: [
+ {
+ type: 'value' as BoostType,
+ factor: 5,
+ value: ['5'],
+ },
+ ],
+ },
+ },
+ });
+ });
+
+ it('handles errors', async () => {
+ mount();
+ http.get.mockReturnValueOnce(Promise.reject('error'));
+
+ RelevanceTuningLogic.actions.initializeRelevanceTuning();
+ await nextTick();
+
+ expect(flashAPIErrors).toHaveBeenCalledWith('error');
+ });
+ });
+
+ describe('getSearchResults', () => {
+ beforeAll(() => {
+ jest.useFakeTimers();
+ });
+
+ afterAll(() => {
+ jest.useRealTimers();
+ });
+
+ it('should make an API call and set state based on the response', async () => {
+ const searchSettingsWithNewBoostProp = {
+ boosts: {
+ foo: [
+ {
+ type: 'value' as BoostType,
+ factor: 5,
+ newBoost: true, // This should be deleted before sent to the server
+ },
+ ],
+ },
+ };
+
+ const searchSettingsWithoutNewBoostProp = {
+ boosts: {
+ foo: [
+ {
+ type: 'value' as BoostType,
+ factor: 5,
+ },
+ ],
+ },
+ };
+
+ mount({
+ query: 'foo',
+ searchSettings: searchSettingsWithNewBoostProp,
+ });
+ jest.spyOn(RelevanceTuningLogic.actions, 'setSearchResults');
+ jest.spyOn(RelevanceTuningLogic.actions, 'setResultsLoading');
+ http.post.mockReturnValueOnce(
+ Promise.resolve({
+ results: searchResults,
+ })
+ );
+
+ RelevanceTuningLogic.actions.getSearchResults();
+ jest.runAllTimers();
+ await nextTick();
+
+ expect(RelevanceTuningLogic.actions.setResultsLoading).toHaveBeenCalledWith(true);
+ expect(http.post).toHaveBeenCalledWith(
+ '/api/app_search/engines/test-engine/search_settings_search',
+ {
+ body: JSON.stringify(searchSettingsWithoutNewBoostProp),
+ query: {
+ query: 'foo',
+ },
+ }
+ );
+ expect(RelevanceTuningLogic.actions.setSearchResults).toHaveBeenCalledWith(searchResults);
+ });
+
+ it("won't send boosts or search_fields on the API call if there are none", async () => {
+ mount({
+ query: 'foo',
+ searchSettings: {
+ searchField: {},
+ boosts: {},
+ },
+ });
+ jest.spyOn(RelevanceTuningLogic.actions, 'setSearchResults');
+ http.post.mockReturnValueOnce(
+ Promise.resolve({
+ results: searchResults,
+ })
+ );
+
+ RelevanceTuningLogic.actions.getSearchResults();
+
+ jest.runAllTimers();
+ await nextTick();
+
+ expect(http.post).toHaveBeenCalledWith(
+ '/api/app_search/engines/test-engine/search_settings_search',
+ {
+ body: '{}',
+ query: {
+ query: 'foo',
+ },
+ }
+ );
+ });
+
+ it('will call clearSearchResults if there is no query', async () => {
+ mount({
+ query: '',
+ });
+ jest.spyOn(RelevanceTuningLogic.actions, 'setSearchResults');
+ jest.spyOn(RelevanceTuningLogic.actions, 'setResultsLoading');
+ jest.spyOn(RelevanceTuningLogic.actions, 'clearSearchResults');
+
+ RelevanceTuningLogic.actions.getSearchResults();
+ jest.runAllTimers();
+ await nextTick();
+
+ expect(RelevanceTuningLogic.actions.clearSearchResults).toHaveBeenCalled();
+ expect(RelevanceTuningLogic.actions.setSearchResults).not.toHaveBeenCalled();
+ expect(RelevanceTuningLogic.actions.setResultsLoading).not.toHaveBeenCalled();
+ });
+
+ it('handles errors', async () => {
+ mount({
+ query: 'foo',
+ });
+ http.post.mockReturnValueOnce(Promise.reject('error'));
+ RelevanceTuningLogic.actions.getSearchResults();
+
+ jest.runAllTimers();
+ await nextTick();
+
+ expect(flashAPIErrors).toHaveBeenCalledWith('error');
+ });
+ });
+
+ describe('setSearchSettings', () => {
+ it('updates search results whenever search settings are changed', () => {
+ mount();
+ jest.spyOn(RelevanceTuningLogic.actions, 'getSearchResults');
+
+ RelevanceTuningLogic.actions.setSearchSettings(searchSettings);
+
+ expect(RelevanceTuningLogic.actions.getSearchResults).toHaveBeenCalled();
+ });
+ });
+
+ describe('onSearchSettingsSuccess', () => {
+ it('should save the response, trigger a new search, and then scroll to the top', () => {
+ mount();
+ jest.spyOn(RelevanceTuningLogic.actions, 'setSearchSettingsResponse');
+ jest.spyOn(RelevanceTuningLogic.actions, 'getSearchResults');
+
+ RelevanceTuningLogic.actions.onSearchSettingsSuccess(searchSettings);
+
+ expect(RelevanceTuningLogic.actions.setSearchSettingsResponse).toHaveBeenCalledWith(
+ searchSettings
+ );
+ expect(RelevanceTuningLogic.actions.getSearchResults).toHaveBeenCalled();
+ expect(scrollToSpy).toHaveBeenCalledWith(0, 0);
+ });
+ });
+
+ describe('onSearchSettingsError', () => {
+ it('scrolls to the top', () => {
+ mount();
+ RelevanceTuningLogic.actions.onSearchSettingsError();
+ expect(scrollToSpy).toHaveBeenCalledWith(0, 0);
+ });
+ });
+
+ describe('updateSearchSettings', () => {
+ it('calls an API endpoint and handles success response', async () => {
+ const searchSettingsWithNewBoostProp = {
+ boosts: {
+ foo: [
+ {
+ type: 'value' as BoostType,
+ factor: 5,
+ newBoost: true, // This should be deleted before sent to the server
+ },
+ ],
+ },
+ };
+
+ const searchSettingsWithoutNewBoostProp = {
+ boosts: {
+ foo: [
+ {
+ type: 'value' as BoostType,
+ factor: 5,
+ },
+ ],
+ },
+ };
+ mount({
+ searchSettings: searchSettingsWithNewBoostProp,
+ });
+ jest.spyOn(RelevanceTuningLogic.actions, 'onSearchSettingsSuccess');
+ http.put.mockReturnValueOnce(Promise.resolve(searchSettingsWithoutNewBoostProp));
+
+ RelevanceTuningLogic.actions.updateSearchSettings();
+ await nextTick();
+
+ expect(http.put).toHaveBeenCalledWith(
+ '/api/app_search/engines/test-engine/search_settings',
+ {
+ body: JSON.stringify(searchSettingsWithoutNewBoostProp),
+ }
+ );
+ expect(setSuccessMessage).toHaveBeenCalledWith(
+ 'Relevance successfully tuned. The changes will impact your results shortly.'
+ );
+ expect(RelevanceTuningLogic.actions.onSearchSettingsSuccess).toHaveBeenCalledWith(
+ searchSettingsWithoutNewBoostProp
+ );
+ });
+
+ it('handles errors', async () => {
+ mount();
+ jest.spyOn(RelevanceTuningLogic.actions, 'onSearchSettingsError');
+ http.put.mockReturnValueOnce(Promise.reject('error'));
+
+ RelevanceTuningLogic.actions.updateSearchSettings();
+ await nextTick();
+
+ expect(flashAPIErrors).toHaveBeenCalledWith('error');
+ expect(RelevanceTuningLogic.actions.onSearchSettingsError).toHaveBeenCalled();
+ });
+ });
+
+ describe('resetSearchSettings', () => {
+ it('calls and API endpoint, shows a success message, and saves the response', async () => {
+ mount();
+ jest.spyOn(RelevanceTuningLogic.actions, 'onSearchSettingsSuccess');
+ confirmSpy.mockImplementation(() => true);
+ http.post.mockReturnValueOnce(Promise.resolve(searchSettings));
+
+ RelevanceTuningLogic.actions.resetSearchSettings();
+ await nextTick();
+
+ expect(http.post).toHaveBeenCalledWith(
+ '/api/app_search/engines/test-engine/search_settings/reset'
+ );
+ expect(setSuccessMessage).toHaveBeenCalledWith(
+ 'Relevance has been reset to default values. The change will impact your results shortly.'
+ );
+ expect(RelevanceTuningLogic.actions.onSearchSettingsSuccess).toHaveBeenCalledWith(
+ searchSettings
+ );
+ });
+
+ it('does nothing if the user does not confirm', async () => {
+ mount();
+ confirmSpy.mockImplementation(() => false);
+
+ RelevanceTuningLogic.actions.resetSearchSettings();
+
+ expect(http.post).not.toHaveBeenCalledWith(
+ '/api/app_search/engines/test-engine/search_settings/reset'
+ );
+ });
+
+ it('handles errors', async () => {
+ mount();
+ jest.spyOn(RelevanceTuningLogic.actions, 'onSearchSettingsError');
+ confirmSpy.mockImplementation(() => true);
+ http.post.mockReturnValueOnce(Promise.reject('error'));
+
+ RelevanceTuningLogic.actions.resetSearchSettings();
+ await nextTick();
+
+ expect(flashAPIErrors).toHaveBeenCalledWith('error');
+ expect(RelevanceTuningLogic.actions.onSearchSettingsError).toHaveBeenCalled();
+ });
+ });
+
+ describe('toggleSearchField', () => {
+ it('updates search weight to 1 in search fields when enabling', () => {
+ mount({
+ searchSettings: {
+ ...searchSettings,
+ search_fields: {
+ bar: {
+ weight: 1,
+ },
+ },
+ },
+ });
+ jest.spyOn(RelevanceTuningLogic.actions, 'setSearchSettings');
+
+ RelevanceTuningLogic.actions.toggleSearchField('foo', false);
+
+ expect(RelevanceTuningLogic.actions.setSearchSettings).toHaveBeenCalledWith({
+ ...searchSettings,
+ search_fields: {
+ bar: {
+ weight: 1,
+ },
+ foo: {
+ weight: 1,
+ },
+ },
+ });
+ });
+
+ it('removes fields from search fields when disabling', () => {
+ mount({
+ searchSettings: {
+ ...searchSettings,
+ search_fields: {
+ bar: {
+ weight: 1,
+ },
+ },
+ },
+ });
+ jest.spyOn(RelevanceTuningLogic.actions, 'setSearchSettings');
+
+ RelevanceTuningLogic.actions.toggleSearchField('bar', true);
+
+ expect(RelevanceTuningLogic.actions.setSearchSettings).toHaveBeenCalledWith({
+ ...searchSettings,
+ });
+ });
+ });
+
+ describe('updateFieldWeight', () => {
+ it('updates the search weight in search fields', () => {
+ mount({
+ searchSettings,
+ });
+ jest.spyOn(RelevanceTuningLogic.actions, 'setSearchSettings');
+
+ RelevanceTuningLogic.actions.updateFieldWeight('foo', 3);
+
+ expect(RelevanceTuningLogic.actions.setSearchSettings).toHaveBeenCalledWith({
+ ...searchSettings,
+ search_fields: {
+ foo: {
+ weight: 3,
+ },
+ },
+ });
+ });
+
+ it('will round decimal numbers', () => {
+ mount({
+ searchSettings,
+ });
+ jest.spyOn(RelevanceTuningLogic.actions, 'setSearchSettings');
+
+ RelevanceTuningLogic.actions.updateFieldWeight('foo', 3.9393939);
+
+ expect(RelevanceTuningLogic.actions.setSearchSettings).toHaveBeenCalledWith({
+ ...searchSettings,
+ search_fields: {
+ foo: {
+ weight: 3.9,
+ },
+ },
+ });
+ });
+ });
+
+ describe('addBoost', () => {
+ it('adds a boost of given type for the given field', () => {
+ mount({
+ searchSettings: {
+ ...searchSettings,
+ boosts: {
+ foo: [
+ {
+ factor: 2,
+ type: 'value',
+ },
+ ],
+ },
+ },
+ });
+ jest.spyOn(RelevanceTuningLogic.actions, 'setSearchSettings');
+
+ RelevanceTuningLogic.actions.addBoost('foo', 'functional');
+
+ expect(RelevanceTuningLogic.actions.setSearchSettings).toHaveBeenCalledWith({
+ ...searchSettings,
+ boosts: {
+ foo: [
+ {
+ factor: 2,
+ type: 'value',
+ },
+ {
+ factor: 1,
+ newBoost: true,
+ type: 'functional',
+ },
+ ],
+ },
+ });
+ });
+
+ it('works even if there are no boosts yet', () => {
+ mount({
+ searchSettings: {
+ ...searchSettings,
+ boosts: {},
+ },
+ });
+ jest.spyOn(RelevanceTuningLogic.actions, 'setSearchSettings');
+
+ RelevanceTuningLogic.actions.addBoost('foo', 'functional');
+
+ expect(RelevanceTuningLogic.actions.setSearchSettings).toHaveBeenCalledWith({
+ ...searchSettings,
+ boosts: {
+ foo: [
+ {
+ factor: 1,
+ newBoost: true,
+ type: 'functional',
+ },
+ ],
+ },
+ });
+ });
+ });
+
+ describe('deleteBoost', () => {
+ it('deletes the boost with the given name and index', () => {
+ mount({
+ searchSettings: {
+ ...searchSettings,
+ boosts: {
+ foo: [
+ {
+ factor: 1,
+ type: 'functional',
+ },
+ {
+ factor: 2,
+ type: 'value',
+ },
+ ],
+ },
+ },
+ });
+ confirmSpy.mockImplementation(() => true);
+ jest.spyOn(RelevanceTuningLogic.actions, 'setSearchSettings');
+
+ RelevanceTuningLogic.actions.deleteBoost('foo', 1);
+
+ expect(RelevanceTuningLogic.actions.setSearchSettings).toHaveBeenCalledWith({
+ ...searchSettings,
+ boosts: {
+ foo: [
+ {
+ factor: 1,
+ type: 'functional',
+ },
+ ],
+ },
+ });
+ });
+
+ it('will delete they field key in boosts if this is the last boost or that field', () => {
+ mount({
+ searchSettings: {
+ ...searchSettings,
+ boosts: {
+ foo: [
+ {
+ factor: 1,
+ type: 'functional',
+ },
+ ],
+ },
+ },
+ });
+ confirmSpy.mockImplementation(() => true);
+ jest.spyOn(RelevanceTuningLogic.actions, 'setSearchSettings');
+
+ RelevanceTuningLogic.actions.deleteBoost('foo', 0);
+
+ expect(RelevanceTuningLogic.actions.setSearchSettings).toHaveBeenCalledWith({
+ ...searchSettings,
+ boosts: {},
+ });
+ });
+
+ it('will do nothing if the user does not confirm', () => {
+ mount({
+ searchSettings: {
+ ...searchSettings,
+ boosts: {
+ foo: [
+ {
+ factor: 1,
+ type: 'functional',
+ },
+ ],
+ },
+ },
+ });
+ confirmSpy.mockImplementation(() => false);
+ jest.spyOn(RelevanceTuningLogic.actions, 'setSearchSettings');
+
+ RelevanceTuningLogic.actions.deleteBoost('foo', 0);
+
+ expect(RelevanceTuningLogic.actions.setSearchSettings).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('updateBoostFactor', () => {
+ it('updates the boost factor of the target boost', () => {
+ mount({
+ searchSettings: searchSettingsWithBoost({
+ factor: 1,
+ type: 'functional',
+ }),
+ });
+ jest.spyOn(RelevanceTuningLogic.actions, 'setSearchSettings');
+
+ RelevanceTuningLogic.actions.updateBoostFactor('foo', 1, 5);
+
+ expect(RelevanceTuningLogic.actions.setSearchSettings).toHaveBeenCalledWith(
+ searchSettingsWithBoost({
+ factor: 5,
+ type: 'functional',
+ })
+ );
+ });
+
+ it('will round decimal numbers', () => {
+ mount({
+ searchSettings: searchSettingsWithBoost({
+ factor: 1,
+ type: 'functional',
+ }),
+ });
+ jest.spyOn(RelevanceTuningLogic.actions, 'setSearchSettings');
+
+ RelevanceTuningLogic.actions.updateBoostFactor('foo', 1, 5.293191);
+
+ expect(RelevanceTuningLogic.actions.setSearchSettings).toHaveBeenCalledWith(
+ searchSettingsWithBoost({
+ factor: 5.3,
+ type: 'functional',
+ })
+ );
+ });
+ });
+
+ describe('updateBoostValue', () => {
+ it('will update the boost value and update search reuslts', () => {
+ mount({
+ searchSettings: searchSettingsWithBoost({
+ factor: 1,
+ type: 'functional',
+ value: ['a', 'b', 'c'],
+ }),
+ });
+ jest.spyOn(RelevanceTuningLogic.actions, 'setSearchSettings');
+
+ RelevanceTuningLogic.actions.updateBoostValue('foo', 1, 1, 'a');
+
+ expect(RelevanceTuningLogic.actions.setSearchSettings).toHaveBeenCalledWith(
+ searchSettingsWithBoost({
+ factor: 1,
+ type: 'functional',
+ value: ['a', 'a', 'c'],
+ })
+ );
+ });
+
+ it('will create a new array if no array exists yet for value', () => {
+ mount({
+ searchSettings: searchSettingsWithBoost({
+ factor: 1,
+ type: 'functional',
+ }),
+ });
+ jest.spyOn(RelevanceTuningLogic.actions, 'setSearchSettings');
+
+ RelevanceTuningLogic.actions.updateBoostValue('foo', 1, 0, 'a');
+
+ expect(RelevanceTuningLogic.actions.setSearchSettings).toHaveBeenCalledWith(
+ searchSettingsWithBoost({
+ factor: 1,
+ type: 'functional',
+ value: ['a'],
+ })
+ );
+ });
+ });
+
+ describe('updateBoostCenter', () => {
+ it('will parse the provided provided value and set the center to that parsed value', () => {
+ mount({
+ schema: {
+ foo: 'number',
+ },
+ searchSettings: searchSettingsWithBoost({
+ factor: 1,
+ type: 'proximity',
+ center: 1,
+ }),
+ });
+ jest.spyOn(RelevanceTuningLogic.actions, 'setSearchSettings');
+
+ RelevanceTuningLogic.actions.updateBoostCenter('foo', 1, '4');
+
+ expect(RelevanceTuningLogic.actions.setSearchSettings).toHaveBeenCalledWith(
+ searchSettingsWithBoost({
+ factor: 1,
+ type: 'proximity',
+ center: 4,
+ })
+ );
+ });
+ });
+
+ describe('addBoostValue', () => {
+ it('will add an empty boost value', () => {
+ mount({
+ searchSettings: searchSettingsWithBoost({
+ factor: 1,
+ type: 'functional',
+ value: ['a'],
+ }),
+ });
+ jest.spyOn(RelevanceTuningLogic.actions, 'setSearchSettings');
+
+ RelevanceTuningLogic.actions.addBoostValue('foo', 1);
+
+ expect(RelevanceTuningLogic.actions.setSearchSettings).toHaveBeenCalledWith(
+ searchSettingsWithBoost({
+ factor: 1,
+ type: 'functional',
+ value: ['a', ''],
+ })
+ );
+ });
+
+ it('will add two empty boost values if none exist yet', () => {
+ mount({
+ searchSettings: searchSettingsWithBoost({
+ factor: 1,
+ type: 'functional',
+ }),
+ });
+ jest.spyOn(RelevanceTuningLogic.actions, 'setSearchSettings');
+
+ RelevanceTuningLogic.actions.addBoostValue('foo', 1);
+
+ expect(RelevanceTuningLogic.actions.setSearchSettings).toHaveBeenCalledWith(
+ searchSettingsWithBoost({
+ factor: 1,
+ type: 'functional',
+ value: ['', ''],
+ })
+ );
+ });
+
+ it('will still work if the boost index is out of range', () => {
+ mount({
+ searchSettings: searchSettingsWithBoost({
+ factor: 1,
+ type: 'functional',
+ value: ['a', ''],
+ }),
+ });
+ jest.spyOn(RelevanceTuningLogic.actions, 'setSearchSettings');
+
+ RelevanceTuningLogic.actions.addBoostValue('foo', 10);
+
+ expect(RelevanceTuningLogic.actions.setSearchSettings).toHaveBeenCalledWith(
+ searchSettingsWithBoost({
+ factor: 1,
+ type: 'functional',
+ value: ['a', ''],
+ })
+ );
+ });
+ });
+
+ describe('removeBoostValue', () => {
+ it('will remove a boost value', () => {
+ mount({
+ searchSettings: searchSettingsWithBoost({
+ factor: 1,
+ type: 'functional',
+ value: ['a', 'b', 'c'],
+ }),
+ });
+ jest.spyOn(RelevanceTuningLogic.actions, 'setSearchSettings');
+
+ RelevanceTuningLogic.actions.removeBoostValue('foo', 1, 1);
+
+ expect(RelevanceTuningLogic.actions.setSearchSettings).toHaveBeenCalledWith(
+ searchSettingsWithBoost({
+ factor: 1,
+ type: 'functional',
+ value: ['a', 'c'],
+ })
+ );
+ });
+
+ it('will do nothing if boost values do not exist', () => {
+ mount({
+ searchSettings: searchSettingsWithBoost({
+ factor: 1,
+ type: 'functional',
+ }),
+ });
+ jest.spyOn(RelevanceTuningLogic.actions, 'setSearchSettings');
+
+ RelevanceTuningLogic.actions.removeBoostValue('foo', 1, 1);
+
+ expect(RelevanceTuningLogic.actions.setSearchSettings).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('updateBoostSelectOption', () => {
+ it('will update the boost', () => {
+ mount({
+ searchSettings: searchSettingsWithBoost({
+ factor: 1,
+ type: 'functional',
+ }),
+ });
+ jest.spyOn(RelevanceTuningLogic.actions, 'setSearchSettings');
+
+ RelevanceTuningLogic.actions.updateBoostSelectOption('foo', 1, 'function', 'exponential');
+
+ expect(RelevanceTuningLogic.actions.setSearchSettings).toHaveBeenCalledWith(
+ searchSettingsWithBoost({
+ factor: 1,
+ type: 'functional',
+ function: 'exponential',
+ })
+ );
+ });
+
+ it('can also update operation', () => {
+ mount({
+ searchSettings: searchSettingsWithBoost({
+ factor: 1,
+ type: 'functional',
+ }),
+ });
+ jest.spyOn(RelevanceTuningLogic.actions, 'setSearchSettings');
+
+ RelevanceTuningLogic.actions.updateBoostSelectOption('foo', 1, 'operation', 'add');
+
+ expect(RelevanceTuningLogic.actions.setSearchSettings).toHaveBeenCalledWith(
+ searchSettingsWithBoost({
+ factor: 1,
+ type: 'functional',
+ operation: 'add',
+ })
+ );
+ });
+ });
+
+ describe('updateSearchValue', () => {
+ it('should update the query then update search results', () => {
+ mount();
+ jest.spyOn(RelevanceTuningLogic.actions, 'setSearchQuery');
+ jest.spyOn(RelevanceTuningLogic.actions, 'getSearchResults');
+
+ RelevanceTuningLogic.actions.updateSearchValue('foo');
+
+ expect(RelevanceTuningLogic.actions.setSearchQuery).toHaveBeenCalledWith('foo');
+ expect(RelevanceTuningLogic.actions.getSearchResults).toHaveBeenCalled();
+ });
+ });
});
describe('selectors', () => {
@@ -253,24 +1140,6 @@ describe('RelevanceTuningLogic', () => {
});
expect(RelevanceTuningLogic.values.filteredSchemaFields).toEqual(['bar', 'baz']);
});
-
- it('should return all schema fields if there is no filter applied', () => {
- mount({
- filterTerm: '',
- schema: {
- id: 'string',
- foo: 'string',
- bar: 'string',
- baz: 'string',
- },
- });
- expect(RelevanceTuningLogic.values.filteredSchemaFields).toEqual([
- 'id',
- 'foo',
- 'bar',
- 'baz',
- ]);
- });
});
describe('filteredSchemaFieldsWithConflicts', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_logic.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_logic.ts
index d4ec5e37f6ce5..cd3d8b5686cc0 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_logic.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/relevance_tuning_logic.ts
@@ -6,10 +6,28 @@
*/
import { kea, MakeLogicType } from 'kea';
+import { omit, cloneDeep, isEmpty } from 'lodash';
+import { setSuccessMessage, flashAPIErrors } from '../../../shared/flash_messages';
+import { HttpLogic } from '../../../shared/http';
import { Schema, SchemaConflicts } from '../../../shared/types';
-import { SearchSettings } from './types';
+import { EngineLogic } from '../engine';
+import { Result } from '../result/types';
+
+import {
+ UPDATE_SUCCESS_MESSAGE,
+ RESET_CONFIRMATION_MESSAGE,
+ DELETE_SUCCESS_MESSAGE,
+ DELETE_CONFIRMATION_MESSAGE,
+} from './constants';
+import { BaseBoost, Boost, BoostType, SearchSettings } from './types';
+import {
+ filterIfTerm,
+ parseBoostCenter,
+ removeBoostStateProps,
+ normalizeBoostValues,
+} from './utils';
interface RelevanceTuningProps {
searchSettings: SearchSettings;
@@ -22,15 +40,60 @@ interface RelevanceTuningActions {
setSearchSettings(searchSettings: SearchSettings): { searchSettings: SearchSettings };
setFilterValue(value: string): string;
setSearchQuery(value: string): string;
- setSearchResults(searchResults: object[]): object[];
+ setSearchResults(searchResults: Result[]): Result[];
setResultsLoading(resultsLoading: boolean): boolean;
clearSearchResults(): void;
resetSearchSettingsState(): void;
dismissSchemaConflictCallout(): void;
+ initializeRelevanceTuning(): void;
+ getSearchResults(): void;
+ setSearchSettingsResponse(searchSettings: SearchSettings): { searchSettings: SearchSettings };
+ onSearchSettingsSuccess(searchSettings: SearchSettings): { searchSettings: SearchSettings };
+ onSearchSettingsError(): void;
+ updateSearchSettings(): void;
+ resetSearchSettings(): void;
+ toggleSearchField(name: string, disableField: boolean): { name: string; disableField: boolean };
+ updateFieldWeight(name: string, weight: number): { name: string; weight: number };
+ addBoost(name: string, type: BoostType): { name: string; type: BoostType };
+ deleteBoost(name: string, index: number): { name: string; index: number };
+ updateBoostFactor(
+ name: string,
+ index: number,
+ factor: number
+ ): { name: string; index: number; factor: number };
+ updateBoostValue(
+ name: string,
+ boostIndex: number,
+ valueIndex: number,
+ value: string
+ ): { name: string; boostIndex: number; valueIndex: number; value: string };
+ updateBoostCenter(
+ name: string,
+ boostIndex: number,
+ value: string | number
+ ): { name: string; boostIndex: number; value: string | number };
+ addBoostValue(name: string, boostIndex: number): { name: string; boostIndex: number };
+ removeBoostValue(
+ name: string,
+ boostIndex: number,
+ valueIndex: number
+ ): { name: string; boostIndex: number; valueIndex: number };
+ updateBoostSelectOption(
+ name: string,
+ boostIndex: number,
+ optionType: keyof BaseBoost,
+ value: string
+ ): {
+ name: string;
+ boostIndex: number;
+ optionType: keyof BaseBoost;
+ value: string;
+ };
+ updateSearchValue(query: string): string;
}
interface RelevanceTuningValues {
- searchSettings: Partial;
+ searchSettings: SearchSettings;
schema: Schema;
schemaFields: string[];
schemaFieldsWithConflicts: string[];
@@ -43,15 +106,10 @@ interface RelevanceTuningValues {
query: string;
unsavedChanges: boolean;
dataLoading: boolean;
- searchResults: object[] | null;
+ searchResults: Result[] | null;
resultsLoading: boolean;
}
-// If the user hasn't entered a filter, then we can skip filtering the array entirely
-const filterIfTerm = (array: string[], filterTerm: string): string[] => {
- return filterTerm === '' ? array : array.filter((item) => item.includes(filterTerm));
-};
-
export const RelevanceTuningLogic = kea<
MakeLogicType
>({
@@ -66,13 +124,47 @@ export const RelevanceTuningLogic = kea<
clearSearchResults: true,
resetSearchSettingsState: true,
dismissSchemaConflictCallout: true,
+ initializeRelevanceTuning: true,
+ getSearchResults: true,
+ setSearchSettingsResponse: (searchSettings) => ({
+ searchSettings,
+ }),
+ onSearchSettingsSuccess: (searchSettings) => ({ searchSettings }),
+ onSearchSettingsError: () => true,
+ updateSearchSettings: true,
+ resetSearchSettings: true,
+ toggleSearchField: (name, disableField) => ({ name, disableField }),
+ updateFieldWeight: (name, weight) => ({ name, weight }),
+ addBoost: (name, type) => ({ name, type }),
+ deleteBoost: (name, index) => ({ name, index }),
+ updateBoostFactor: (name, index, factor) => ({ name, index, factor }),
+ updateBoostValue: (name, boostIndex, valueIndex, value) => ({
+ name,
+ boostIndex,
+ valueIndex,
+ value,
+ }),
+ updateBoostCenter: (name, boostIndex, value) => ({ name, boostIndex, value }),
+ addBoostValue: (name, boostIndex) => ({ name, boostIndex }),
+ removeBoostValue: (name, boostIndex, valueIndex) => ({ name, boostIndex, valueIndex }),
+ updateBoostSelectOption: (name, boostIndex, optionType, value) => ({
+ name,
+ boostIndex,
+ optionType,
+ value,
+ }),
+ updateSearchValue: (query) => query,
}),
reducers: () => ({
searchSettings: [
- {},
+ {
+ search_fields: {},
+ boosts: {},
+ },
{
onInitializeRelevanceTuning: (_, { searchSettings }) => searchSettings,
setSearchSettings: (_, { searchSettings }) => searchSettings,
+ setSearchSettingsResponse: (_, { searchSettings }) => searchSettings,
},
],
schema: [
@@ -109,6 +201,7 @@ export const RelevanceTuningLogic = kea<
false,
{
setSearchSettings: () => true,
+ setSearchSettingsResponse: () => false,
},
],
@@ -155,4 +248,268 @@ export const RelevanceTuningLogic = kea<
(schema: Schema): boolean => Object.keys(schema).length >= 2,
],
}),
+ listeners: ({ actions, values }) => ({
+ initializeRelevanceTuning: async () => {
+ const { http } = HttpLogic.values;
+ const { engineName } = EngineLogic.values;
+
+ const url = `/api/app_search/engines/${engineName}/search_settings/details`;
+
+ try {
+ const response = await http.get(url);
+ actions.onInitializeRelevanceTuning({
+ ...response,
+ searchSettings: {
+ ...response.searchSettings,
+ boosts: normalizeBoostValues(response.searchSettings.boosts),
+ },
+ });
+ } catch (e) {
+ flashAPIErrors(e);
+ }
+ },
+ getSearchResults: async (_, breakpoint) => {
+ await breakpoint(250);
+
+ const query = values.query;
+ if (!query) return actions.clearSearchResults();
+
+ const { engineName } = EngineLogic.values;
+ const { http } = HttpLogic.values;
+ const { search_fields: searchFields, boosts } = removeBoostStateProps(values.searchSettings);
+ const url = `/api/app_search/engines/${engineName}/search_settings_search`;
+
+ actions.setResultsLoading(true);
+
+ try {
+ const response = await http.post(url, {
+ query: {
+ query,
+ },
+ body: JSON.stringify({
+ boosts: isEmpty(boosts) ? undefined : boosts,
+ search_fields: isEmpty(searchFields) ? undefined : searchFields,
+ }),
+ });
+
+ actions.setSearchResults(response.results);
+ } catch (e) {
+ flashAPIErrors(e);
+ }
+ },
+ setSearchSettings: () => {
+ actions.getSearchResults();
+ },
+ onSearchSettingsSuccess: ({ searchSettings }) => {
+ actions.setSearchSettingsResponse(searchSettings);
+ actions.getSearchResults();
+ window.scrollTo(0, 0);
+ },
+ onSearchSettingsError: () => {
+ window.scrollTo(0, 0);
+ },
+ updateSearchSettings: async () => {
+ const { http } = HttpLogic.values;
+ const { engineName } = EngineLogic.values;
+
+ const url = `/api/app_search/engines/${engineName}/search_settings`;
+
+ try {
+ const response = await http.put(url, {
+ body: JSON.stringify(removeBoostStateProps(values.searchSettings)),
+ });
+ setSuccessMessage(UPDATE_SUCCESS_MESSAGE);
+ actions.onSearchSettingsSuccess(response);
+ } catch (e) {
+ flashAPIErrors(e);
+ actions.onSearchSettingsError();
+ }
+ },
+ resetSearchSettings: async () => {
+ if (window.confirm(RESET_CONFIRMATION_MESSAGE)) {
+ const { http } = HttpLogic.values;
+ const { engineName } = EngineLogic.values;
+
+ const url = `/api/app_search/engines/${engineName}/search_settings/reset`;
+
+ try {
+ const response = await http.post(url);
+ setSuccessMessage(DELETE_SUCCESS_MESSAGE);
+ actions.onSearchSettingsSuccess(response);
+ } catch (e) {
+ flashAPIErrors(e);
+ actions.onSearchSettingsError();
+ }
+ }
+ },
+ toggleSearchField: ({ name, disableField }) => {
+ const { searchSettings } = values;
+
+ const searchFields = disableField
+ ? omit(searchSettings.search_fields, name)
+ : { ...searchSettings.search_fields, [name]: { weight: 1 } };
+
+ actions.setSearchSettings({
+ ...searchSettings,
+ search_fields: searchFields,
+ });
+ },
+ updateFieldWeight: ({ name, weight }) => {
+ const { searchSettings } = values;
+ const { search_fields: searchFields } = searchSettings;
+
+ actions.setSearchSettings({
+ ...searchSettings,
+ search_fields: {
+ ...searchFields,
+ [name]: {
+ ...searchFields[name],
+ weight: Math.round(weight * 10) / 10,
+ },
+ },
+ });
+ },
+ addBoost: ({ name, type }) => {
+ const { searchSettings } = values;
+ const { boosts } = searchSettings;
+ const emptyBoost = { type, factor: 1, newBoost: true };
+ let boostArray;
+
+ if (Array.isArray(boosts[name])) {
+ boostArray = boosts[name].slice();
+ boostArray.push(emptyBoost);
+ } else {
+ boostArray = [emptyBoost];
+ }
+
+ actions.setSearchSettings({
+ ...searchSettings,
+ boosts: {
+ ...boosts,
+ [name]: boostArray,
+ },
+ });
+ },
+ deleteBoost: ({ name, index }) => {
+ if (window.confirm(DELETE_CONFIRMATION_MESSAGE)) {
+ const { searchSettings } = values;
+ const { boosts } = searchSettings;
+ const boostsRemoved = boosts[name].slice();
+ boostsRemoved.splice(index, 1);
+ const updatedBoosts = { ...boosts };
+
+ if (boostsRemoved.length > 0) {
+ updatedBoosts[name] = boostsRemoved;
+ } else {
+ delete updatedBoosts[name];
+ }
+
+ actions.setSearchSettings({
+ ...searchSettings,
+ boosts: updatedBoosts,
+ });
+ }
+ },
+ updateBoostFactor: ({ name, index, factor }) => {
+ const { searchSettings } = values;
+ const { boosts } = searchSettings;
+ const updatedBoosts = cloneDeep(boosts[name]);
+ updatedBoosts[index].factor = Math.round(factor * 10) / 10;
+
+ actions.setSearchSettings({
+ ...searchSettings,
+ boosts: {
+ ...boosts,
+ [name]: updatedBoosts,
+ },
+ });
+ },
+ updateBoostValue: ({ name, boostIndex, valueIndex, value }) => {
+ const { searchSettings } = values;
+ const { boosts } = searchSettings;
+ const updatedBoosts: Boost[] = cloneDeep(boosts[name]);
+ const existingValue = updatedBoosts[boostIndex].value;
+ if (existingValue === undefined) {
+ updatedBoosts[boostIndex].value = [value];
+ } else {
+ existingValue[valueIndex] = value;
+ }
+
+ actions.setSearchSettings({
+ ...searchSettings,
+ boosts: {
+ ...boosts,
+ [name]: updatedBoosts,
+ },
+ });
+ },
+ updateBoostCenter: ({ name, boostIndex, value }) => {
+ const { searchSettings } = values;
+ const { boosts } = searchSettings;
+ const updatedBoosts = cloneDeep(boosts[name]);
+ const fieldType = values.schema[name];
+ updatedBoosts[boostIndex].center = parseBoostCenter(fieldType, value);
+
+ actions.setSearchSettings({
+ ...searchSettings,
+ boosts: {
+ ...boosts,
+ [name]: updatedBoosts,
+ },
+ });
+ },
+ addBoostValue: ({ name, boostIndex }) => {
+ const { searchSettings } = values;
+ const { boosts } = searchSettings;
+ const updatedBoosts = cloneDeep(boosts[name]);
+ const updatedBoost = updatedBoosts[boostIndex];
+ if (updatedBoost) {
+ updatedBoost.value = Array.isArray(updatedBoost.value) ? updatedBoost.value : [''];
+ updatedBoost.value.push('');
+ }
+
+ actions.setSearchSettings({
+ ...searchSettings,
+ boosts: {
+ ...boosts,
+ [name]: updatedBoosts,
+ },
+ });
+ },
+ removeBoostValue: ({ name, boostIndex, valueIndex }) => {
+ const { searchSettings } = values;
+ const { boosts } = searchSettings;
+ const updatedBoosts = cloneDeep(boosts[name]);
+ const boostValue = updatedBoosts[boostIndex].value;
+
+ if (boostValue === undefined) return;
+
+ boostValue.splice(valueIndex, 1);
+ actions.setSearchSettings({
+ ...searchSettings,
+ boosts: {
+ ...boosts,
+ [name]: updatedBoosts,
+ },
+ });
+ },
+ updateBoostSelectOption: ({ name, boostIndex, optionType, value }) => {
+ const { searchSettings } = values;
+ const { boosts } = searchSettings;
+ const updatedBoosts = cloneDeep(boosts[name]);
+ updatedBoosts[boostIndex][optionType] = value;
+
+ actions.setSearchSettings({
+ ...searchSettings,
+ boosts: {
+ ...boosts,
+ [name]: updatedBoosts,
+ },
+ });
+ },
+ updateSearchValue: (query) => {
+ actions.setSearchQuery(query);
+ actions.getSearchResults();
+ },
+ }),
});
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/types.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/types.ts
index 25187df89d64c..a1ed9797b9f5a 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/types.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/types.ts
@@ -7,17 +7,31 @@
export type BoostType = 'value' | 'functional' | 'proximity';
-export interface Boost {
- type: BoostType;
+export interface BaseBoost {
operation?: string;
function?: string;
+}
+
+// A boost that comes from the server, before we normalize it has a much looser schema
+export interface RawBoost extends BaseBoost {
+ type: BoostType;
newBoost?: boolean;
center?: string | number;
- value?: string | number | string[] | number[];
+ value?: string | number | boolean | object | Array;
factor: number;
}
+// We normalize raw boosts to make them safer and easier to work with
+export interface Boost extends RawBoost {
+ value?: string[];
+}
export interface SearchSettings {
boosts: Record;
- search_fields: object;
+ search_fields: Record<
+ string,
+ {
+ weight: number;
+ }
+ >;
+ result_fields?: object;
}
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/utils.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/utils.test.ts
new file mode 100644
index 0000000000000..a6598bf991c13
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/utils.test.ts
@@ -0,0 +1,147 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import { BoostType } from './types';
+import {
+ filterIfTerm,
+ normalizeBoostValues,
+ removeBoostStateProps,
+ parseBoostCenter,
+} from './utils';
+
+describe('filterIfTerm', () => {
+ it('will filter a list of strings to a list of strings containing the specified string', () => {
+ expect(filterIfTerm(['jalepeno', 'no', 'not', 'panorama', 'truck'], 'no')).toEqual([
+ 'jalepeno',
+ 'no',
+ 'not',
+ 'panorama',
+ ]);
+ });
+
+ it('will not filter at all if an empty string is provided', () => {
+ expect(filterIfTerm(['jalepeno', 'no', 'not', 'panorama', 'truck'], '')).toEqual([
+ 'jalepeno',
+ 'no',
+ 'not',
+ 'panorama',
+ 'truck',
+ ]);
+ });
+});
+
+describe('removeBoostStateProps', () => {
+ it('will remove the newBoost flag from boosts within the provided searchSettings object', () => {
+ const searchSettings = {
+ boosts: {
+ foo: [
+ {
+ type: 'value' as BoostType,
+ factor: 5,
+ newBoost: true,
+ },
+ ],
+ },
+ search_fields: {
+ foo: {
+ weight: 1,
+ },
+ },
+ };
+ expect(removeBoostStateProps(searchSettings)).toEqual({
+ ...searchSettings,
+ boosts: {
+ foo: [
+ {
+ type: 'value' as BoostType,
+ factor: 5,
+ },
+ ],
+ },
+ });
+ });
+});
+
+describe('parseBoostCenter', () => {
+ it('should parse a boost center', () => {
+ expect(parseBoostCenter('text', 5)).toEqual(5);
+ expect(parseBoostCenter('text', '4')).toEqual('4');
+ expect(parseBoostCenter('number', 5)).toEqual(5);
+ expect(parseBoostCenter('number', '5')).toEqual(5);
+ });
+});
+
+describe('normalizeBoostValues', () => {
+ const boosts = {
+ foo: [
+ {
+ type: 'value' as BoostType,
+ factor: 9.5,
+ value: 1,
+ },
+ {
+ type: 'value' as BoostType,
+ factor: 9.5,
+ value: '1',
+ },
+ {
+ type: 'value' as BoostType,
+ factor: 9.5,
+ value: [1],
+ },
+ {
+ type: 'value' as BoostType,
+ factor: 9.5,
+ value: ['1'],
+ },
+ {
+ type: 'value' as BoostType,
+ factor: 9.5,
+ value: [
+ '1',
+ 1,
+ '2',
+ 2,
+ true,
+ {
+ b: 'a',
+ },
+ {},
+ ],
+ },
+ ],
+ bar: [
+ {
+ type: 'proximity' as BoostType,
+ factor: 9.5,
+ },
+ ],
+ sp_def: [
+ {
+ type: 'functional' as BoostType,
+ factor: 5,
+ },
+ ],
+ };
+
+ it('converts all value types to string for consistency', () => {
+ expect(normalizeBoostValues(boosts)).toEqual({
+ bar: [{ factor: 9.5, type: 'proximity' }],
+ foo: [
+ { factor: 9.5, type: 'value', value: ['1'] },
+ { factor: 9.5, type: 'value', value: ['1'] },
+ { factor: 9.5, type: 'value', value: ['1'] },
+ { factor: 9.5, type: 'value', value: ['1'] },
+ {
+ factor: 9.5,
+ type: 'value',
+ value: ['1', '1', '2', '2', 'true', '[object Object]', '[object Object]'],
+ },
+ ],
+ sp_def: [{ type: 'functional', factor: 5 }],
+ });
+ });
+});
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/utils.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/utils.ts
new file mode 100644
index 0000000000000..e2fd0f0bbd656
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/relevance_tuning/utils.ts
@@ -0,0 +1,63 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { cloneDeep, omit } from 'lodash';
+
+import { NUMBER } from '../../../shared/constants/field_types';
+import { SchemaTypes } from '../../../shared/types';
+
+import { RawBoost, Boost, SearchSettings, BoostType } from './types';
+
+// If the user hasn't entered a filter, then we can skip filtering the array entirely
+export const filterIfTerm = (array: string[], filterTerm: string): string[] => {
+ return filterTerm === '' ? array : array.filter((item) => item.includes(filterTerm));
+};
+
+export const removeBoostStateProps = (searchSettings: SearchSettings) => {
+ const updatedSettings = cloneDeep(searchSettings);
+ const { boosts } = updatedSettings;
+ const keys = Object.keys(boosts);
+ keys.forEach((key) => boosts[key].forEach((boost) => delete boost.newBoost));
+
+ return updatedSettings;
+};
+
+export const parseBoostCenter = (fieldType: SchemaTypes, value: string | number) => {
+ // Leave non-numeric fields alone
+ if (fieldType === NUMBER) {
+ const floatValue = parseFloat(value as string);
+ return isNaN(floatValue) ? value : floatValue;
+ }
+ return value;
+};
+
+const toArray = (v: T | T[]): T[] => (Array.isArray(v) ? v : [v]);
+const toString = (v1: T) => String(v1);
+
+const normalizeBoostValue = (boost: RawBoost): Boost => {
+ if (!boost.hasOwnProperty('value')) {
+ // Can't simply do `return boost` here as TS can't infer the correct type
+ return omit(boost, 'value');
+ }
+
+ return {
+ ...boost,
+ type: boost.type as BoostType,
+ value: toArray(boost.value).map(toString),
+ };
+};
+
+// Data may have been set to invalid types directly via the public App Search API. Since these are invalid, we don't want to deal
+// with them as valid types in the UI. For that reason, we stringify all values here, as the data comes in.
+// Additionally, values can be in single values or in arrays.
+export const normalizeBoostValues = (boosts: Record): Record =>
+ Object.entries(boosts).reduce((newBoosts, [fieldName, boostList]) => {
+ return {
+ ...newBoosts,
+ [fieldName]: boostList.map(normalizeBoostValue),
+ };
+ }, {});
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result.test.tsx
index 0c3749d1ccb3d..41428999b1e40 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result.test.tsx
@@ -6,15 +6,17 @@
*/
import React from 'react';
+
import { shallow, ShallowWrapper } from 'enzyme';
+
import { EuiPanel } from '@elastic/eui';
-import { ResultField } from './result_field';
-import { ResultHeader } from './result_header';
import { ReactRouterHelper } from '../../../shared/react_router_helpers/eui_components';
import { SchemaTypes } from '../../../shared/types';
import { Result } from './result';
+import { ResultField } from './result_field';
+import { ResultHeader } from './result_header';
describe('Result', () => {
const props = {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result.tsx
index d84b079ea9d72..7288fdf39f3ff 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result.tsx
@@ -6,6 +6,7 @@
*/
import React, { useState, useMemo } from 'react';
+
import classNames from 'classnames';
import './result.scss';
@@ -14,13 +15,14 @@ import { EuiPanel, EuiIcon } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { ReactRouterHelper } from '../../../shared/react_router_helpers/eui_components';
-import { generateEncodedPath } from '../../utils/encode_path_params';
-import { ENGINE_DOCUMENT_DETAIL_PATH } from '../../routes';
import { Schema } from '../../../shared/types';
-import { FieldValue, Result as ResultType } from './types';
+import { ENGINE_DOCUMENT_DETAIL_PATH } from '../../routes';
+import { generateEncodedPath } from '../../utils/encode_path_params';
+
import { ResultField } from './result_field';
import { ResultHeader } from './result_header';
+import { FieldValue, Result as ResultType } from './types';
interface Props {
result: ResultType;
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result_field.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result_field.test.tsx
index 6869708627b8d..1e79266dd7e7d 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result_field.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result_field.test.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { ResultField } from './result_field';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result_field.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result_field.tsx
index a1c3ccd93622a..003810ec40a8d 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result_field.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result_field.tsx
@@ -6,9 +6,11 @@
*/
import React from 'react';
-import { ResultFieldValue } from '.';
+
import { FieldType, Raw, Snippet } from './types';
+import { ResultFieldValue } from '.';
+
import './result_field.scss';
interface Props {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result_field_value.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result_field_value.test.tsx
index e1cefa1d79469..c732c9c8216c0 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result_field_value.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result_field_value.test.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { shallow, ShallowWrapper } from 'enzyme';
import { ResultFieldValue } from '.';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result_header.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result_header.test.tsx
index 9d90b3ae35a8f..dcefd0f6bc0b0 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result_header.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result_header.test.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { ResultHeader } from './result_header';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result_header_item.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result_header_item.test.tsx
index e8cc8796440a9..52fa81943bb2e 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result_header_item.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result_header_item.test.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { mount } from 'enzyme';
import { ResultHeaderItem } from './result_header_item';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/generic_confirmation_modal.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/generic_confirmation_modal.test.tsx
index 3e450b7a7bb70..8477f0e8e2ce2 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/generic_confirmation_modal.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/generic_confirmation_modal.test.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { GenericConfirmationModal } from './generic_confirmation_modal';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/generic_confirmation_modal.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/generic_confirmation_modal.tsx
index b792ace4dac3f..eb64fe6421d80 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/generic_confirmation_modal.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/generic_confirmation_modal.tsx
@@ -6,7 +6,6 @@
*/
import React, { ReactNode, useState } from 'react';
-import { i18n } from '@kbn/i18n';
import {
EuiButton,
@@ -21,6 +20,7 @@ import {
EuiSpacer,
EuiText,
} from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
interface GenericConfirmationModalProps {
description: ReactNode;
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_confirmation_modal.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_confirmation_modal.test.tsx
index a6d0cab532729..494517a438372 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_confirmation_modal.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_confirmation_modal.test.tsx
@@ -8,9 +8,11 @@
import { setMockActions, setMockValues } from '../../../../__mocks__';
import React from 'react';
+
import { shallow } from 'enzyme';
import { LogRetentionOptions } from '../../log_retention';
+
import { GenericConfirmationModal } from './generic_confirmation_modal';
import { LogRetentionConfirmationModal } from './log_retention_confirmation_modal';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_confirmation_modal.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_confirmation_modal.tsx
index 52a2478d7158e..ca1fa9a8d0737 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_confirmation_modal.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_confirmation_modal.tsx
@@ -6,12 +6,14 @@
*/
import React from 'react';
-import { i18n } from '@kbn/i18n';
-import { EuiTextColor, EuiOverlayMask } from '@elastic/eui';
import { useActions, useValues } from 'kea';
+import { EuiTextColor, EuiOverlayMask } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+
import { LogRetentionLogic, LogRetentionOptions } from '../../log_retention';
+
import { GenericConfirmationModal } from './generic_confirmation_modal';
export const LogRetentionConfirmationModal: React.FC = () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_panel.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_panel.test.tsx
index 882b82979a511..aee23e61e76fe 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_panel.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_panel.test.tsx
@@ -9,9 +9,11 @@ import '../../../../__mocks__/shallow_useeffect.mock';
import { setMockActions, setMockValues } from '../../../../__mocks__';
import React from 'react';
+
import { shallow } from 'enzyme';
import { LogRetention } from '../../log_retention/types';
+
import { LogRetentionPanel } from './log_retention_panel';
describe('', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_panel.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_panel.tsx
index 3a40be9efd5db..76fdcdac58ad4 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_panel.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_panel.tsx
@@ -6,11 +6,12 @@
*/
import React, { useEffect } from 'react';
-import { i18n } from '@kbn/i18n';
-import { EuiLink, EuiSpacer, EuiSwitch, EuiText, EuiTextColor, EuiTitle } from '@elastic/eui';
import { useActions, useValues } from 'kea';
+import { EuiLink, EuiSpacer, EuiSwitch, EuiText, EuiTextColor, EuiTitle } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+
import { DOCS_PREFIX } from '../../../routes';
import { LogRetentionLogic, LogRetentionOptions, LogRetentionMessage } from '../../log_retention';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/settings.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/settings.test.tsx
index fead8cda0c0e2..41d446b8e36fc 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/settings.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/settings.test.tsx
@@ -6,7 +6,9 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiPageContentBody } from '@elastic/eui';
import { Settings } from './settings';
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/settings.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/settings.tsx
index c029cf344f18b..510075eba4abf 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/settings.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/settings.tsx
@@ -15,10 +15,11 @@ import {
EuiTitle,
} from '@elastic/eui';
-import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
import { FlashMessages } from '../../../shared/flash_messages';
+import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
import { LogRetentionPanel, LogRetentionConfirmationModal } from './log_retention';
+
import { SETTINGS_TITLE } from './';
export const Settings: React.FC = () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/setup_guide/setup_guide.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/setup_guide/setup_guide.test.tsx
index e8dcb6ff98358..0b4a86870a69d 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/setup_guide/setup_guide.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/setup_guide/setup_guide.test.tsx
@@ -6,10 +6,12 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
import { SetupGuideLayout } from '../../../shared/setup_guide';
+
import { SetupGuide } from './';
describe('SetupGuide', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/setup_guide/setup_guide.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/setup_guide/setup_guide.tsx
index befb06c719a39..3d96b22859fad 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/setup_guide/setup_guide.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/setup_guide/setup_guide.tsx
@@ -6,15 +6,17 @@
*/
import React from 'react';
+
import { EuiSpacer, EuiTitle, EuiText } from '@elastic/eui';
-import { FormattedMessage } from '@kbn/i18n/react';
import { i18n } from '@kbn/i18n';
+import { FormattedMessage } from '@kbn/i18n/react';
import { APP_SEARCH_PLUGIN } from '../../../../../common/constants';
-import { SetupGuideLayout, SETUP_GUIDE_TITLE } from '../../../shared/setup_guide';
import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
+import { SetupGuideLayout, SETUP_GUIDE_TITLE } from '../../../shared/setup_guide';
import { SendAppSearchTelemetry as SendTelemetry } from '../../../shared/telemetry';
import { DOCS_PREFIX } from '../../routes';
+
import GettingStarted from './assets/getting_started.png';
export const SetupGuide: React.FC = () => (
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx
index dc3c0b03148d9..0e8220266d613 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx
@@ -11,13 +11,16 @@ import { setMockValues, setMockActions } from '../__mocks__';
import React from 'react';
import { Redirect } from 'react-router-dom';
+
import { shallow } from 'enzyme';
import { Layout, SideNav, SideNavLink } from '../shared/layout';
-import { SetupGuide } from './components/setup_guide';
-import { ErrorConnecting } from './components/error_connecting';
-import { EnginesOverview } from './components/engines';
+
import { EngineRouter } from './components/engine';
+import { EnginesOverview } from './components/engines';
+import { ErrorConnecting } from './components/error_connecting';
+import { SetupGuide } from './components/setup_guide';
+
import { AppSearch, AppSearchUnconfigured, AppSearchConfigured, AppSearchNav } from './';
describe('AppSearch', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx
index 918697422af6b..36ac3fb4dbc5b 100644
--- a/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx
@@ -7,18 +7,26 @@
import React, { useEffect } from 'react';
import { Route, Redirect, Switch } from 'react-router-dom';
+
import { useActions, useValues } from 'kea';
+import { APP_SEARCH_PLUGIN } from '../../../common/constants';
+import { InitialAppData } from '../../../common/types';
import { getAppSearchUrl } from '../shared/enterprise_search_url';
-import { KibanaLogic } from '../shared/kibana';
import { HttpLogic } from '../shared/http';
-import { AppLogic } from './app_logic';
-import { InitialAppData } from '../../../common/types';
-
-import { APP_SEARCH_PLUGIN } from '../../../common/constants';
+import { KibanaLogic } from '../shared/kibana';
import { Layout, SideNav, SideNavLink } from '../shared/layout';
-import { EngineNav, EngineRouter } from './components/engine';
+import { NotFound } from '../shared/not_found';
+import { AppLogic } from './app_logic';
+import { Credentials, CREDENTIALS_TITLE } from './components/credentials';
+import { EngineNav, EngineRouter } from './components/engine';
+import { EnginesOverview, ENGINES_TITLE } from './components/engines';
+import { ErrorConnecting } from './components/error_connecting';
+import { Library } from './components/library';
+import { ROLE_MAPPINGS_TITLE } from './components/role_mappings';
+import { Settings, SETTINGS_TITLE } from './components/settings';
+import { SetupGuide } from './components/setup_guide';
import {
ROOT_PATH,
SETUP_GUIDE_PATH,
@@ -30,15 +38,6 @@ import {
LIBRARY_PATH,
} from './routes';
-import { SetupGuide } from './components/setup_guide';
-import { ErrorConnecting } from './components/error_connecting';
-import { NotFound } from '../shared/not_found';
-import { EnginesOverview, ENGINES_TITLE } from './components/engines';
-import { Settings, SETTINGS_TITLE } from './components/settings';
-import { Credentials, CREDENTIALS_TITLE } from './components/credentials';
-import { ROLE_MAPPINGS_TITLE } from './components/role_mappings';
-import { Library } from './components/library';
-
export const AppSearch: React.FC = (props) => {
const { config } = useValues(KibanaLogic);
return !config.host ? : ;
diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/error_connecting/error_connecting.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/error_connecting/error_connecting.test.tsx
index 6ff33385df9a5..9ec3fdda63656 100644
--- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/error_connecting/error_connecting.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/error_connecting/error_connecting.test.tsx
@@ -6,9 +6,11 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { ErrorStatePrompt } from '../../../shared/error_state';
+
import { ErrorConnecting } from './';
describe('ErrorConnecting', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/error_connecting/error_connecting.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/error_connecting/error_connecting.tsx
index cb1abc275d37f..afee20df106e8 100644
--- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/error_connecting/error_connecting.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/error_connecting/error_connecting.tsx
@@ -6,10 +6,11 @@
*/
import React from 'react';
+
import { EuiPage, EuiPageContent } from '@elastic/eui';
-import { SendEnterpriseSearchTelemetry as SendTelemetry } from '../../../shared/telemetry';
import { ErrorStatePrompt } from '../../../shared/error_state';
+import { SendEnterpriseSearchTelemetry as SendTelemetry } from '../../../shared/telemetry';
export const ErrorConnecting: React.FC = () => (
diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.test.tsx
index a9098689b3d0e..8631e6e2a51d4 100644
--- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.test.tsx
@@ -8,11 +8,13 @@
import { setMockValues, mockTelemetryActions } from '../../../__mocks__';
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiCard } from '@elastic/eui';
-import { EuiButtonTo } from '../../../shared/react_router_helpers';
+
import { APP_SEARCH_PLUGIN, WORKPLACE_SEARCH_PLUGIN } from '../../../../../common/constants';
+import { EuiButtonTo } from '../../../shared/react_router_helpers';
import { ProductCard } from './';
diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.tsx
index d31daeef54de9..20727e37460f1 100644
--- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.tsx
@@ -6,14 +6,16 @@
*/
import React from 'react';
+
import { useValues, useActions } from 'kea';
import { snakeCase } from 'lodash';
-import { i18n } from '@kbn/i18n';
+
import { EuiCard, EuiTextColor } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+import { KibanaLogic } from '../../../shared/kibana';
import { EuiButtonTo } from '../../../shared/react_router_helpers';
import { TelemetryLogic } from '../../../shared/telemetry';
-import { KibanaLogic } from '../../../shared/kibana';
import './product_card.scss';
diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_selector/product_selector.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_selector/product_selector.test.tsx
index 0d55e2ce21c74..9ee34634e3797 100644
--- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_selector/product_selector.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_selector/product_selector.test.tsx
@@ -8,11 +8,13 @@
import { setMockValues } from '../../../__mocks__/kea.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiPage } from '@elastic/eui';
-import { SetupGuideCta } from '../setup_guide';
import { ProductCard } from '../product_card';
+import { SetupGuideCta } from '../setup_guide';
import { ProductSelector } from './';
diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_selector/product_selector.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_selector/product_selector.tsx
index 910840f023bb2..f2476a5770c25 100644
--- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_selector/product_selector.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_selector/product_selector.tsx
@@ -6,7 +6,9 @@
*/
import React from 'react';
+
import { useValues } from 'kea';
+
import {
EuiPage,
EuiPageBody,
@@ -25,11 +27,10 @@ import { KibanaLogic } from '../../../shared/kibana';
import { SetEnterpriseSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
import { SendEnterpriseSearchTelemetry as SendTelemetry } from '../../../shared/telemetry';
-import { ProductCard } from '../product_card';
-import { SetupGuideCta } from '../setup_guide';
-
import AppSearchImage from '../../assets/app_search.png';
import WorkplaceSearchImage from '../../assets/workplace_search.png';
+import { ProductCard } from '../product_card';
+import { SetupGuideCta } from '../setup_guide';
interface ProductSelectorProps {
access: {
diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/setup_guide/setup_guide.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/setup_guide/setup_guide.test.tsx
index e2f3595d26974..44f06de7ff137 100644
--- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/setup_guide/setup_guide.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/setup_guide/setup_guide.test.tsx
@@ -6,10 +6,12 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { SetEnterpriseSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
import { SetupGuideLayout } from '../../../shared/setup_guide';
+
import { SetupGuide } from './';
describe('SetupGuide', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/setup_guide/setup_guide.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/setup_guide/setup_guide.tsx
index 02327e01c5ede..c59742d7ccbea 100644
--- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/setup_guide/setup_guide.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/setup_guide/setup_guide.tsx
@@ -6,14 +6,16 @@
*/
import React from 'react';
+
import { EuiSpacer, EuiTitle, EuiText } from '@elastic/eui';
-import { FormattedMessage } from '@kbn/i18n/react';
import { i18n } from '@kbn/i18n';
+import { FormattedMessage } from '@kbn/i18n/react';
import { ENTERPRISE_SEARCH_PLUGIN } from '../../../../../common/constants';
-import { SetupGuideLayout, SETUP_GUIDE_TITLE } from '../../../shared/setup_guide';
import { SetEnterpriseSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
+import { SetupGuideLayout, SETUP_GUIDE_TITLE } from '../../../shared/setup_guide';
import { SendEnterpriseSearchTelemetry as SendTelemetry } from '../../../shared/telemetry';
+
import GettingStarted from './assets/getting_started.png';
export const SetupGuide: React.FC = () => (
diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/setup_guide/setup_guide_cta.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/setup_guide/setup_guide_cta.test.tsx
index 140e779df55d2..659af6d23c6d0 100644
--- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/setup_guide/setup_guide_cta.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/setup_guide/setup_guide_cta.test.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { SetupGuideCta } from './';
diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/setup_guide/setup_guide_cta.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/setup_guide/setup_guide_cta.tsx
index 7d32b11ba7ae8..17260cc15793a 100644
--- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/setup_guide/setup_guide_cta.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/setup_guide/setup_guide_cta.tsx
@@ -6,8 +6,10 @@
*/
import React from 'react';
-import { i18n } from '@kbn/i18n';
+
import { EuiFlexGroup, EuiFlexItem, EuiTitle, EuiText } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+
import { EuiPanelTo } from '../../../shared/react_router_helpers';
import CtaImage from './assets/getting_started.png';
diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.test.tsx
index e4508f4e99276..2d8dbd55f4366 100644
--- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.test.tsx
@@ -5,15 +5,17 @@
* 2.0.
*/
+import { setMockValues, rerender } from '../__mocks__';
+
import React from 'react';
-import { shallow } from 'enzyme';
-import { setMockValues, rerender } from '../__mocks__';
+import { shallow } from 'enzyme';
-import { EnterpriseSearch } from './';
-import { SetupGuide } from './components/setup_guide';
import { ErrorConnecting } from './components/error_connecting';
import { ProductSelector } from './components/product_selector';
+import { SetupGuide } from './components/setup_guide';
+
+import { EnterpriseSearch } from './';
describe('EnterpriseSearch', () => {
it('renders the Setup Guide and Product Selector', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.tsx
index 50ed0bce75cf8..b21e46429672a 100644
--- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.tsx
@@ -7,18 +7,17 @@
import React from 'react';
import { Route, Switch } from 'react-router-dom';
+
import { useValues } from 'kea';
-import { KibanaLogic } from '../shared/kibana';
import { InitialAppData } from '../../../common/types';
-
import { HttpLogic } from '../shared/http';
-
-import { ROOT_PATH, SETUP_GUIDE_PATH } from './routes';
+import { KibanaLogic } from '../shared/kibana';
import { ErrorConnecting } from './components/error_connecting';
import { ProductSelector } from './components/product_selector';
import { SetupGuide } from './components/setup_guide';
+import { ROOT_PATH, SETUP_GUIDE_PATH } from './routes';
import './index.scss';
diff --git a/x-pack/plugins/enterprise_search/public/applications/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/index.test.tsx
index f36561787eb69..2e0940b9c4af2 100644
--- a/x-pack/plugins/enterprise_search/public/applications/index.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/index.test.tsx
@@ -6,17 +6,19 @@
*/
import React from 'react';
+
import { getContext } from 'kea';
-import { coreMock } from 'src/core/public/mocks';
-import { licensingMock } from '../../../licensing/public/mocks';
+import { coreMock } from '../../../../../src/core/public/mocks';
import { chartPluginMock } from '../../../../../src/plugins/charts/public/mocks';
+import { licensingMock } from '../../../licensing/public/mocks';
-import { renderApp, renderHeaderActions } from './';
-import { EnterpriseSearch } from './enterprise_search';
import { AppSearch } from './app_search';
-import { WorkplaceSearch } from './workplace_search';
+import { EnterpriseSearch } from './enterprise_search';
import { KibanaLogic } from './shared/kibana';
+import { WorkplaceSearch } from './workplace_search';
+
+import { renderApp, renderHeaderActions } from './';
describe('renderApp', () => {
const kibanaDeps = {
diff --git a/x-pack/plugins/enterprise_search/public/applications/index.tsx b/x-pack/plugins/enterprise_search/public/applications/index.tsx
index 97e43f758e5b8..155ff5b92ba27 100644
--- a/x-pack/plugins/enterprise_search/public/applications/index.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/index.tsx
@@ -7,21 +7,23 @@
import React from 'react';
import ReactDOM from 'react-dom';
-import { Router } from 'react-router-dom';
import { Provider } from 'react-redux';
-import { Store } from 'redux';
+import { Router } from 'react-router-dom';
+
import { getContext, resetContext } from 'kea';
+import { Store } from 'redux';
+
import { I18nProvider } from '@kbn/i18n/react';
-import { AppMountParameters, CoreStart } from 'src/core/public';
-import { PluginsStart, ClientConfigType, ClientData } from '../plugin';
+import { AppMountParameters, CoreStart } from '../../../../../src/core/public';
import { InitialAppData } from '../../common/types';
+import { PluginsStart, ClientConfigType, ClientData } from '../plugin';
+import { externalUrl } from './shared/enterprise_search_url';
+import { mountFlashMessagesLogic } from './shared/flash_messages';
+import { mountHttpLogic } from './shared/http';
import { mountKibanaLogic } from './shared/kibana';
import { mountLicensingLogic } from './shared/licensing';
-import { mountHttpLogic } from './shared/http';
-import { mountFlashMessagesLogic } from './shared/flash_messages';
-import { externalUrl } from './shared/enterprise_search_url';
/**
* This file serves as a reusable wrapper to share Kibana-level context and other helpers
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.test.tsx
index 9870264eb1c2f..d9d31f5a45d4b 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.test.tsx
@@ -8,7 +8,9 @@
import '../../__mocks__/kea.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiEmptyPrompt } from '@elastic/eui';
import { ErrorStatePrompt } from './';
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.tsx
index cf8b234442002..f855c7b67dc6e 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.tsx
@@ -6,12 +6,14 @@
*/
import React from 'react';
+
import { useValues } from 'kea';
+
import { EuiEmptyPrompt, EuiCode } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
-import { EuiButtonTo } from '../react_router_helpers';
import { KibanaLogic } from '../../shared/kibana';
+import { EuiButtonTo } from '../react_router_helpers';
import './error_state_prompt.scss';
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/flash_messages.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/flash_messages.test.tsx
index 2a31c0ecd66a8..aa45ce58af86a 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/flash_messages.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/flash_messages.test.tsx
@@ -8,7 +8,9 @@
import { setMockValues } from '../../__mocks__/kea.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiCallOut } from '@elastic/eui';
import { FlashMessages } from './flash_messages';
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/flash_messages.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/flash_messages.tsx
index 5f38961b8a341..60d80487a2593 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/flash_messages.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/flash_messages.tsx
@@ -6,7 +6,9 @@
*/
import React, { Fragment } from 'react';
+
import { useValues } from 'kea';
+
import { EuiCallOut, EuiCallOutProps, EuiSpacer } from '@elastic/eui';
import { FlashMessagesLogic } from './flash_messages_logic';
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/flash_messages_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/flash_messages_logic.test.ts
index 61f667719e3e6..7fc78c99fb242 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/flash_messages_logic.test.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/flash_messages_logic.test.ts
@@ -5,12 +5,14 @@
* 2.0.
*/
+import { mockKibanaValues } from '../../__mocks__/kibana_logic.mock';
+
import { resetContext } from 'kea';
-import { mockKibanaValues } from '../../__mocks__/kibana_logic.mock';
const { history } = mockKibanaValues;
-import { FlashMessagesLogic, mountFlashMessagesLogic, IFlashMessage } from './flash_messages_logic';
+import { FlashMessagesLogic, mountFlashMessagesLogic } from './flash_messages_logic';
+import { IFlashMessage } from './types';
describe('FlashMessagesLogic', () => {
const mount = () => mountFlashMessagesLogic();
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/flash_messages_logic.ts b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/flash_messages_logic.ts
index 26af4103aada1..5993e67b28a39 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/flash_messages_logic.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/flash_messages_logic.ts
@@ -6,15 +6,10 @@
*/
import { kea, MakeLogicType } from 'kea';
-import { ReactNode } from 'react';
import { KibanaLogic } from '../kibana';
-export interface IFlashMessage {
- type: 'success' | 'info' | 'warning' | 'error';
- message: ReactNode;
- description?: ReactNode;
-}
+import { IFlashMessage } from './types';
interface FlashMessagesValues {
messages: IFlashMessage[];
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/handle_api_errors.test.ts b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/handle_api_errors.test.ts
index 1df1c6a7a680e..b6b0e23ce7d6a 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/handle_api_errors.test.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/handle_api_errors.test.ts
@@ -8,6 +8,7 @@
import '../../__mocks__/kibana_logic.mock';
import { FlashMessagesLogic } from './flash_messages_logic';
+
import { flashAPIErrors } from './handle_api_errors';
describe('flashAPIErrors', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/handle_api_errors.ts b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/handle_api_errors.ts
index 5fb824ebde9a0..11003d0fcc171 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/handle_api_errors.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/handle_api_errors.ts
@@ -7,7 +7,8 @@
import { HttpResponse } from 'src/core/public';
-import { FlashMessagesLogic, IFlashMessage } from './flash_messages_logic';
+import { FlashMessagesLogic } from './flash_messages_logic';
+import { IFlashMessage } from './types';
/**
* The API errors we are handling can come from one of two ways:
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/index.ts b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/index.ts
index 8d3605a19c22c..40317eb390547 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/index.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/index.ts
@@ -6,7 +6,8 @@
*/
export { FlashMessages } from './flash_messages';
-export { FlashMessagesLogic, IFlashMessage, mountFlashMessagesLogic } from './flash_messages_logic';
+export { FlashMessagesLogic, mountFlashMessagesLogic } from './flash_messages_logic';
+export { IFlashMessage } from './types';
export { flashAPIErrors } from './handle_api_errors';
export {
setSuccessMessage,
diff --git a/x-pack/plugins/maps_file_upload/server/client/errors.js b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/types.ts
similarity index 60%
rename from x-pack/plugins/maps_file_upload/server/client/errors.js
rename to x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/types.ts
index 8f8516158b303..c1d2f8420198d 100644
--- a/x-pack/plugins/maps_file_upload/server/client/errors.js
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/types.ts
@@ -5,8 +5,10 @@
* 2.0.
*/
-import { boomify } from '@hapi/boom';
+import { ReactNode } from 'react';
-export function wrapError(error) {
- return boomify(error, { statusCode: error.status });
+export interface IFlashMessage {
+ type: 'success' | 'info' | 'warning' | 'error';
+ message: ReactNode;
+ description?: ReactNode;
}
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/hidden_text/hidden_text.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/hidden_text/hidden_text.test.tsx
index 1888edca53034..af63b9a801edd 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/hidden_text/hidden_text.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/hidden_text/hidden_text.test.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { HiddenText } from '.';
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/hidden_text/hidden_text.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/hidden_text/hidden_text.tsx
index 5503baf0bdae4..35901496c5fbd 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/hidden_text/hidden_text.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/hidden_text/hidden_text.tsx
@@ -6,6 +6,7 @@
*/
import React, { useState, ReactElement } from 'react';
+
import { i18n } from '@kbn/i18n';
interface ChildrenProps {
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/indexing_status/indexing_status.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/indexing_status/indexing_status.test.tsx
index d8f02be60ef92..44bd8b78320d6 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/indexing_status/indexing_status.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/indexing_status/indexing_status.test.tsx
@@ -9,13 +9,14 @@ import '../../__mocks__/shallow_useeffect.mock';
import { setMockActions, setMockValues } from '../../__mocks__';
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiPanel } from '@elastic/eui';
+import { IndexingStatus } from './indexing_status';
import { IndexingStatusContent } from './indexing_status_content';
import { IndexingStatusErrors } from './indexing_status_errors';
-import { IndexingStatus } from './indexing_status';
describe('IndexingStatus', () => {
const getItemDetailPath = jest.fn();
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/indexing_status/indexing_status.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/indexing_status/indexing_status.tsx
index 3898eda126415..ee0557e15396c 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/indexing_status/indexing_status.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/indexing_status/indexing_status.tsx
@@ -11,12 +11,12 @@ import { useValues, useActions } from 'kea';
import { EuiPanel, EuiSpacer } from '@elastic/eui';
+import { IIndexingStatus } from '../types';
+
import { IndexingStatusContent } from './indexing_status_content';
import { IndexingStatusErrors } from './indexing_status_errors';
import { IndexingStatusLogic } from './indexing_status_logic';
-import { IIndexingStatus } from '../types';
-
export interface IIndexingStatusProps {
viewLinkPath: string;
itemId: string;
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/indexing_status/indexing_status_content.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/indexing_status/indexing_status_content.test.tsx
index a744ddf8b5290..8998e640d6c35 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/indexing_status/indexing_status_content.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/indexing_status/indexing_status_content.test.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiProgress, EuiTitle } from '@elastic/eui';
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/indexing_status/indexing_status_errors.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/indexing_status/indexing_status_errors.test.tsx
index 3747fe020af20..eb5fa9d70f026 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/indexing_status/indexing_status_errors.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/indexing_status/indexing_status_errors.test.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiCallOut } from '@elastic/eui';
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/indexing_status/indexing_status_logic.ts b/x-pack/plugins/enterprise_search/public/applications/shared/indexing_status/indexing_status_logic.ts
index 11ba1304d0a22..a436b669bcbe5 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/indexing_status/indexing_status_logic.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/indexing_status/indexing_status_logic.ts
@@ -7,9 +7,9 @@
import { kea, MakeLogicType } from 'kea';
+import { flashAPIErrors } from '../flash_messages';
import { HttpLogic } from '../http';
import { IIndexingStatus } from '../types';
-import { flashAPIErrors } from '../flash_messages';
interface IndexingStatusProps {
statusPath: string;
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana/kibana_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/shared/kibana/kibana_logic.test.ts
index 10b550fc93eb3..a5f54d16b2fad 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana/kibana_logic.test.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana/kibana_logic.test.ts
@@ -5,10 +5,10 @@
* 2.0.
*/
-import { resetContext } from 'kea';
-
import { mockKibanaValues } from '../../__mocks__';
+import { resetContext } from 'kea';
+
import { KibanaLogic, mountKibanaLogic } from './kibana_logic';
describe('KibanaLogic', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana/kibana_logic.ts b/x-pack/plugins/enterprise_search/public/applications/shared/kibana/kibana_logic.ts
index 4bb1859df09ea..8015d22f7c44a 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana/kibana_logic.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana/kibana_logic.ts
@@ -5,12 +5,13 @@
* 2.0.
*/
-import { kea, MakeLogicType } from 'kea';
-
import { FC } from 'react';
+
import { History } from 'history';
-import { ApplicationStart, ChromeBreadcrumb } from 'src/core/public';
-import { ChartsPluginStart } from 'src/plugins/charts/public';
+import { kea, MakeLogicType } from 'kea';
+
+import { ApplicationStart, ChromeBreadcrumb } from '../../../../../../../src/core/public';
+import { ChartsPluginStart } from '../../../../../../../src/plugins/charts/public';
import { CloudSetup } from '../../../../../cloud/public';
import { HttpLogic } from '../http';
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.ts b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.ts
index 64f53c767b17c..908cc0601ab9c 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.ts
@@ -6,10 +6,8 @@
*/
import { useValues } from 'kea';
-import { EuiBreadcrumb } from '@elastic/eui';
-import { KibanaLogic } from '../kibana';
-import { HttpLogic } from '../http';
+import { EuiBreadcrumb } from '@elastic/eui';
import {
ENTERPRISE_SEARCH_PLUGIN,
@@ -18,6 +16,8 @@ import {
} from '../../../../common/constants';
import { stripLeadingSlash } from '../../../../common/strip_slashes';
+import { HttpLogic } from '../http';
+import { KibanaLogic } from '../kibana';
import { letBrowserHandleEvent, createHref } from '../react_router_helpers';
/**
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.test.tsx
index 5b1aa64c42d64..c9743e6824018 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.test.tsx
@@ -9,6 +9,7 @@ import '../../__mocks__/shallow_useeffect.mock';
import { setMockValues, mockKibanaValues, mockHistory } from '../../__mocks__';
import React from 'react';
+
import { shallow } from 'enzyme';
jest.mock('./generate_breadcrumbs', () => ({
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.tsx
index fa127566b1b02..e639f9d22fb4b 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.tsx
@@ -6,6 +6,7 @@
*/
import React, { useEffect } from 'react';
+
import { useValues } from 'kea';
import { KibanaLogic } from '../kibana';
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/layout/layout.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/layout/layout.test.tsx
index c67518e977de2..28092f75cdede 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/layout/layout.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/layout/layout.test.tsx
@@ -6,7 +6,9 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiPageSideBar, EuiButton, EuiPageBody, EuiCallOut } from '@elastic/eui';
import { Layout, INavContext } from './layout';
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/layout/layout.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/layout/layout.tsx
index 1af85905e6ccb..9cf5fccddbd5b 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/layout/layout.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/layout/layout.tsx
@@ -6,6 +6,7 @@
*/
import React, { useState } from 'react';
+
import classNames from 'classnames';
import { EuiPage, EuiPageSideBar, EuiPageBody, EuiButton, EuiCallOut } from '@elastic/eui';
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/layout/side_nav.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/layout/side_nav.test.tsx
index ceb5f21ce056f..451b49738029d 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/layout/side_nav.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/layout/side_nav.test.tsx
@@ -9,11 +9,13 @@ import '../../__mocks__/react_router_history.mock';
import React from 'react';
import { useLocation } from 'react-router-dom';
+
import { shallow } from 'enzyme';
import { EuiLink } from '@elastic/eui';
-import { EuiLinkTo } from '../react_router_helpers';
+
import { ENTERPRISE_SEARCH_PLUGIN, APP_SEARCH_PLUGIN } from '../../../../common/constants';
+import { EuiLinkTo } from '../react_router_helpers';
import { SideNav, SideNavLink, SideNavItem } from './';
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/layout/side_nav.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/layout/side_nav.tsx
index 605d3940a8cc7..58a5c7bbb229f 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/layout/side_nav.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/layout/side_nav.tsx
@@ -7,14 +7,15 @@
import React, { useContext } from 'react';
import { useLocation } from 'react-router-dom';
+
import classNames from 'classnames';
-import { i18n } from '@kbn/i18n';
import { EuiIcon, EuiTitle, EuiText, EuiLink } from '@elastic/eui'; // TODO: Remove EuiLink after full Kibana transition
-import { EuiLinkTo } from '../react_router_helpers';
+import { i18n } from '@kbn/i18n';
import { ENTERPRISE_SEARCH_PLUGIN } from '../../../../common/constants';
import { stripTrailingSlash } from '../../../../common/strip_slashes';
+import { EuiLinkTo } from '../react_router_helpers';
import { NavContext, INavContext } from './layout';
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/loading/loading.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/loading/loading.test.tsx
index c443467d5cb32..eab5694a27968 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/loading/loading.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/loading/loading.test.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiLoadingSpinner } from '@elastic/eui';
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/loading/loading.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/loading/loading.tsx
index cfcbeaee72095..27a4dfdec0c07 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/loading/loading.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/loading/loading.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { EuiLoadingSpinner } from '@elastic/eui';
import './loading.scss';
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/not_found/not_found.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/not_found/not_found.test.tsx
index 0bda848bc8d6c..7e75b2b47bb7a 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/not_found/not_found.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/not_found/not_found.test.tsx
@@ -8,12 +8,14 @@
import { setMockValues } from '../../__mocks__/kea.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiButton as EuiButtonExternal, EuiEmptyPrompt } from '@elastic/eui';
import { APP_SEARCH_PLUGIN, WORKPLACE_SEARCH_PLUGIN } from '../../../../common/constants';
import { SetAppSearchChrome } from '../kibana_chrome';
+
import { AppSearchLogo } from './assets/app_search_logo';
import { WorkplaceSearchLogo } from './assets/workplace_search_logo';
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/not_found/not_found.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/not_found/not_found.tsx
index 6102987464f55..5699568c40558 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/not_found/not_found.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/not_found/not_found.tsx
@@ -6,8 +6,9 @@
*/
import React from 'react';
+
import { useValues } from 'kea';
-import { i18n } from '@kbn/i18n';
+
import {
EuiPageContent,
EuiEmptyPrompt,
@@ -16,6 +17,7 @@ import {
EuiFlexItem,
EuiButton,
} from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
import {
APP_SEARCH_PLUGIN,
@@ -23,11 +25,11 @@ import {
LICENSED_SUPPORT_URL,
} from '../../../../common/constants';
-import { EuiButtonTo } from '../react_router_helpers';
-import { BreadcrumbTrail } from '../kibana_chrome/generate_breadcrumbs';
import { SetAppSearchChrome, SetWorkplaceSearchChrome } from '../kibana_chrome';
-import { SendAppSearchTelemetry, SendWorkplaceSearchTelemetry } from '../telemetry';
+import { BreadcrumbTrail } from '../kibana_chrome/generate_breadcrumbs';
import { LicensingLogic } from '../licensing';
+import { EuiButtonTo } from '../react_router_helpers';
+import { SendAppSearchTelemetry, SendWorkplaceSearchTelemetry } from '../telemetry';
import { AppSearchLogo } from './assets/app_search_logo';
import { WorkplaceSearchLogo } from './assets/workplace_search_logo';
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/create_href.test.ts b/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/create_href.test.ts
index 0619dab19e2bd..fe2973cfdee32 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/create_href.test.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/create_href.test.ts
@@ -5,9 +5,10 @@
* 2.0.
*/
-import { httpServiceMock } from 'src/core/public/mocks';
import { mockHistory } from '../../__mocks__';
+import { httpServiceMock } from 'src/core/public/mocks';
+
import { createHref } from './';
describe('createHref', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/create_href.ts b/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/create_href.ts
index e36a65c2457db..ea28fc4d440c5 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/create_href.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/create_href.ts
@@ -6,6 +6,7 @@
*/
import { History } from 'history';
+
import { HttpSetup } from 'src/core/public';
/**
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_components.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_components.test.tsx
index 4de43ce997b48..75639ffeb9d6b 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_components.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_components.test.tsx
@@ -7,11 +7,13 @@
import '../../__mocks__/kea.mock';
+import { mockKibanaValues, mockHistory } from '../../__mocks__';
+
import React from 'react';
+
import { shallow, mount } from 'enzyme';
-import { EuiLink, EuiButton, EuiButtonEmpty, EuiPanel, EuiCard } from '@elastic/eui';
-import { mockKibanaValues, mockHistory } from '../../__mocks__';
+import { EuiLink, EuiButton, EuiButtonEmpty, EuiPanel, EuiCard } from '@elastic/eui';
import { EuiLinkTo, EuiButtonTo, EuiButtonEmptyTo, EuiPanelTo, EuiCardTo } from './eui_components';
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_components.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_components.tsx
index 384eb79c993c1..b9fee9d16273b 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_components.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_components.tsx
@@ -6,7 +6,9 @@
*/
import React from 'react';
+
import { useValues } from 'kea';
+
import {
EuiLink,
EuiButton,
@@ -20,8 +22,9 @@ import {
} from '@elastic/eui';
import { EuiPanelProps } from '@elastic/eui/src/components/panel/panel';
-import { KibanaLogic } from '../kibana';
import { HttpLogic } from '../http';
+import { KibanaLogic } from '../kibana';
+
import { letBrowserHandleEvent, createHref } from './';
/**
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/schema/schema_add_field_modal.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/schema/schema_add_field_modal.test.tsx
index c0bd1f3671f15..88c170b059d9c 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/schema/schema_add_field_modal.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/schema/schema_add_field_modal.test.tsx
@@ -6,16 +6,17 @@
*/
import React from 'react';
+
import { shallow, mount } from 'enzyme';
+import { EuiFieldText, EuiModal, EuiSelect } from '@elastic/eui';
+
import { NUMBER } from '../constants/field_types';
import { FIELD_NAME_CORRECTED_PREFIX } from './constants';
import { SchemaAddFieldModal } from './';
-import { EuiFieldText, EuiModal, EuiSelect } from '@elastic/eui';
-
describe('SchemaAddFieldModal', () => {
const addNewField = jest.fn();
const closeAddFieldModal = jest.fn();
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/schema/schema_errors_accordion.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/schema/schema_errors_accordion.test.tsx
index b1fde05906d44..a82f9e9b6113b 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/schema/schema_errors_accordion.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/schema/schema_errors_accordion.test.tsx
@@ -6,11 +6,13 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiAccordion, EuiTableRow } from '@elastic/eui';
import { EuiLinkTo } from '../react_router_helpers';
+
import { SchemaErrorsAccordion } from './schema_errors_accordion';
describe('SchemaErrorsAccordion', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/schema/schema_existing_field.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/schema/schema_existing_field.test.tsx
index 62f66bc95a5eb..5e89dce24bd4a 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/schema/schema_existing_field.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/schema/schema_existing_field.test.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiSelect } from '@elastic/eui';
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/cloud/instructions.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/cloud/instructions.test.tsx
index 5d69a8ea84acf..0136f9745c322 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/cloud/instructions.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/cloud/instructions.test.tsx
@@ -5,11 +5,13 @@
* 2.0.
*/
+import { mountWithIntl } from '../../../__mocks__';
+
import React from 'react';
+
import { shallow } from 'enzyme';
-import { EuiSteps, EuiLink } from '@elastic/eui';
-import { mountWithIntl } from '../../../__mocks__';
+import { EuiSteps, EuiLink } from '@elastic/eui';
import { CloudSetupInstructions } from './instructions';
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/cloud/instructions.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/cloud/instructions.tsx
index 24ba5bd4e5d0a..b355c88943a54 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/cloud/instructions.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/cloud/instructions.tsx
@@ -6,9 +6,10 @@
*/
import React from 'react';
-import { FormattedMessage } from '@kbn/i18n/react';
-import { i18n } from '@kbn/i18n';
+
import { EuiPageContent, EuiSteps, EuiText, EuiLink, EuiCallOut } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+import { FormattedMessage } from '@kbn/i18n/react';
import { docLinks } from '../../doc_links';
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/instructions.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/instructions.test.tsx
index 74fb74ce8cf70..fd31ca720b82b 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/instructions.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/instructions.test.tsx
@@ -5,11 +5,13 @@
* 2.0.
*/
+import { mountWithIntl } from '../../__mocks__';
+
import React from 'react';
+
import { shallow } from 'enzyme';
-import { EuiSteps, EuiLink } from '@elastic/eui';
-import { mountWithIntl } from '../../__mocks__';
+import { EuiSteps, EuiLink } from '@elastic/eui';
import { SetupInstructions } from './instructions';
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/instructions.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/instructions.tsx
index 83c244ea24ff1..5e39d1acdf189 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/instructions.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/instructions.tsx
@@ -6,8 +6,7 @@
*/
import React from 'react';
-import { FormattedMessage } from '@kbn/i18n/react';
-import { i18n } from '@kbn/i18n';
+
import {
EuiPageContent,
EuiSpacer,
@@ -18,6 +17,8 @@ import {
EuiAccordion,
EuiLink,
} from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+import { FormattedMessage } from '@kbn/i18n/react';
interface Props {
productName: string;
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/setup_guide.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/setup_guide.test.tsx
index 0b70bb70f8441..90ddddd7d20aa 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/setup_guide.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/setup_guide.test.tsx
@@ -8,11 +8,13 @@
import { setMockValues, rerender } from '../../__mocks__';
import React from 'react';
+
import { shallow, ShallowWrapper } from 'enzyme';
+
import { EuiIcon } from '@elastic/eui';
-import { SetupInstructions } from './instructions';
import { CloudSetupInstructions } from './cloud/instructions';
+import { SetupInstructions } from './instructions';
import { SetupGuideLayout } from './';
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/setup_guide.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/setup_guide.tsx
index a0e89bfd8e57d..2140b3392abae 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/setup_guide.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/setup_guide.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { useValues } from 'kea';
import {
@@ -22,9 +23,9 @@ import {
import { KibanaLogic } from '../kibana';
-import { SetupInstructions } from './instructions';
import { CloudSetupInstructions } from './cloud/instructions';
import { SETUP_GUIDE_TITLE } from './constants';
+import { SetupInstructions } from './instructions';
import './setup_guide.scss';
/**
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/table_header/table_header.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/table_header/table_header.test.tsx
index d2588ed8d4aca..a481f22095aa3 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/table_header/table_header.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/table_header/table_header.test.tsx
@@ -6,7 +6,9 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiTableHeader, EuiTableHeaderCell } from '@elastic/eui';
import { TableHeader } from './table_header';
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/telemetry/send_telemetry.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/telemetry/send_telemetry.test.tsx
index 60f4d404a917a..5fc8074d0a4d7 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/telemetry/send_telemetry.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/telemetry/send_telemetry.test.tsx
@@ -9,6 +9,7 @@ import '../../__mocks__/shallow_useeffect.mock';
import { mockTelemetryActions } from '../../__mocks__';
import React from 'react';
+
import { shallow } from 'enzyme';
import {
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/telemetry/send_telemetry.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/telemetry/send_telemetry.tsx
index e0f54a9e421bf..1759b4075deca 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/telemetry/send_telemetry.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/telemetry/send_telemetry.tsx
@@ -6,6 +6,7 @@
*/
import React, { useEffect } from 'react';
+
import { useActions } from 'kea';
import { TelemetryLogic, SendTelemetryHelper } from './telemetry_logic';
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/telemetry/telemetry_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/shared/telemetry/telemetry_logic.test.ts
index 52aec2c384adb..e516daedc1ba6 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/telemetry/telemetry_logic.test.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/telemetry/telemetry_logic.test.ts
@@ -5,9 +5,10 @@
* 2.0.
*/
-import { JSON_HEADER as headers } from '../../../../common/constants';
import { LogicMounter, mockHttpValues } from '../../__mocks__';
+import { JSON_HEADER as headers } from '../../../../common/constants';
+
import { TelemetryLogic } from './telemetry_logic';
describe('Telemetry logic', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/truncate/truncate.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/truncate/truncate.test.tsx
index 71ed60cbd1c93..f9bf55b4fe800 100644
--- a/x-pack/plugins/enterprise_search/public/applications/shared/truncate/truncate.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/shared/truncate/truncate.test.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { TruncatedContent } from './';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/__mocks__/content_sources.mock.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/__mocks__/content_sources.mock.ts
index c249f5ee20588..ce92f62d3a017 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/__mocks__/content_sources.mock.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/__mocks__/content_sources.mock.ts
@@ -5,10 +5,11 @@
* 2.0.
*/
-import { mergeServerAndStaticData } from '../views/content_sources/sources_logic';
-import { staticSourceData } from '../views/content_sources/source_data';
import { groups } from './groups.mock';
+import { staticSourceData } from '../views/content_sources/source_data';
+import { mergeServerAndStaticData } from '../views/content_sources/sources_logic';
+
export const contentSources = [
{
id: '123',
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/app_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/app_logic.test.ts
index f1e6ca237681f..8ba94e83d26cf 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/app_logic.test.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/app_logic.test.ts
@@ -5,9 +5,9 @@
* 2.0.
*/
+import { DEFAULT_INITIAL_APP_DATA } from '../../../common/__mocks__';
import { LogicMounter } from '../__mocks__';
-import { DEFAULT_INITIAL_APP_DATA } from '../../../common/__mocks__';
import { AppLogic } from './app_logic';
describe('AppLogic', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/kibana_header_actions.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/kibana_header_actions.test.tsx
index c2c645ebe439a..a7a788b48789a 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/kibana_header_actions.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/kibana_header_actions.test.tsx
@@ -5,12 +5,14 @@
* 2.0.
*/
-import { externalUrl } from '../../../shared/enterprise_search_url';
-
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiButtonEmpty } from '@elastic/eui';
+import { externalUrl } from '../../../shared/enterprise_search_url';
+
import { WorkplaceSearchHeaderActions } from './';
describe('WorkplaceSearchHeaderActions', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/kibana_header_actions.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/kibana_header_actions.tsx
index c1912deb8d40a..c79865d25ecd7 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/kibana_header_actions.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/kibana_header_actions.tsx
@@ -6,10 +6,10 @@
*/
import React from 'react';
+
import { EuiButtonEmpty, EuiText } from '@elastic/eui';
import { externalUrl, getWorkplaceSearchUrl } from '../../../shared/enterprise_search_url';
-
import { NAV } from '../../constants';
export const WorkplaceSearchHeaderActions: React.FC = () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/nav.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/nav.test.tsx
index d2b2da1a48176..8f37f608f4e28 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/nav.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/nav.test.tsx
@@ -8,9 +8,11 @@
import '../../../__mocks__/enterprise_search_url.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
import { SideNav, SideNavLink } from '../../../shared/layout';
+
import { WorkplaceSearchNav } from './';
describe('WorkplaceSearchNav', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/nav.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/nav.tsx
index 2696e5acf1c12..c184247b253d6 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/nav.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/nav.tsx
@@ -12,9 +12,7 @@ import { EuiSpacer } from '@elastic/eui';
import { WORKPLACE_SEARCH_PLUGIN } from '../../../../../common/constants';
import { getWorkplaceSearchUrl } from '../../../shared/enterprise_search_url';
import { SideNav, SideNavLink } from '../../../shared/layout';
-
import { NAV } from '../../constants';
-
import {
SOURCES_PATH,
SECURITY_PATH,
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/api_key/api_key.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/api_key/api_key.test.tsx
index 66e9ac9ed7a8b..32f21c158736f 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/api_key/api_key.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/api_key/api_key.test.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiCodeBlock, EuiFormLabel } from '@elastic/eui';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/component_loader/component_loader.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/component_loader/component_loader.test.tsx
index cb3fc32432999..991c7a061b4bb 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/component_loader/component_loader.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/component_loader/component_loader.test.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiLoadingSpinner, EuiTextColor } from '@elastic/eui';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/content_section/content_section.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/content_section/content_section.test.tsx
index c21e8b8d3449f..21280926d7aae 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/content_section/content_section.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/content_section/content_section.test.tsx
@@ -6,12 +6,15 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiSpacer } from '@elastic/eui';
-import { ContentSection } from './';
import { ViewContentHeader } from '../view_content_header';
+import { ContentSection } from './';
+
const props = {
children: ,
testSubj: 'contentSection',
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/content_section/content_section.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/content_section/content_section.tsx
index b0ab18bbfde95..e606263ac6f1c 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/content_section/content_section.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/content_section/content_section.tsx
@@ -10,7 +10,6 @@ import React from 'react';
import { EuiSpacer } from '@elastic/eui';
import { SpacerSizeTypes } from '../../../types';
-
import { ViewContentHeader } from '../view_content_header';
import './content_section.scss';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/credential_item/credential_item.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/credential_item/credential_item.test.tsx
index 79c4abdf2e223..13e2a229b3a76 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/credential_item/credential_item.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/credential_item/credential_item.test.tsx
@@ -6,6 +6,7 @@
*/
import * as React from 'react';
+
import { shallow } from 'enzyme';
import { EuiCopy, EuiButtonIcon, EuiFieldText } from '@elastic/eui';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/license_badge/license_badge.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/license_badge/license_badge.test.tsx
index 4e38894766d86..6deb37d850076 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/license_badge/license_badge.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/license_badge/license_badge.test.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiBadge } from '@elastic/eui';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/license_callout/license_callout.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/license_callout/license_callout.test.tsx
index d8266127a0f42..6a69178ad07da 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/license_callout/license_callout.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/license_callout/license_callout.test.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiLink, EuiText } from '@elastic/eui';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/product_button/product_button.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/product_button/product_button.test.tsx
index 5ef191d0d0fe8..0bced6a7fc4e0 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/product_button/product_button.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/product_button/product_button.test.tsx
@@ -9,7 +9,9 @@ import '../../../../__mocks__/kea.mock';
import { mockTelemetryActions } from '../../../../__mocks__';
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiButton } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/product_button/product_button.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/product_button/product_button.tsx
index ded4278c35e14..3611bfb2a3f69 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/product_button/product_button.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/product_button/product_button.tsx
@@ -6,13 +6,14 @@
*/
import React from 'react';
+
import { useActions } from 'kea';
import { EuiButton, EuiButtonProps, EuiLinkProps } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
-import { TelemetryLogic } from '../../../../shared/telemetry';
import { getWorkplaceSearchUrl } from '../../../../shared/enterprise_search_url';
+import { TelemetryLogic } from '../../../../shared/telemetry';
export const ProductButton: React.FC = () => {
const { sendWorkplaceSearchTelemetry } = useActions(TelemetryLogic);
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/source_config_fields/source_config_fields.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/source_config_fields/source_config_fields.test.tsx
index e5cd2bb2e0461..9af91107d7304 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/source_config_fields/source_config_fields.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/source_config_fields/source_config_fields.test.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { ApiKey } from '../api_key';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/source_config_fields/source_config_fields.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/source_config_fields/source_config_fields.tsx
index 8c6e2b0174eb0..236d475b8f687 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/source_config_fields/source_config_fields.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/source_config_fields/source_config_fields.tsx
@@ -16,7 +16,6 @@ import {
CLIENT_ID_LABEL,
CLIENT_SECRET_LABEL,
} from '../../../constants';
-
import { ApiKey } from '../api_key';
import { CredentialItem } from '../credential_item';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/source_icon/source_icon.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/source_icon/source_icon.test.tsx
index f8cf9d63915d6..3bea6f224dc2b 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/source_icon/source_icon.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/source_icon/source_icon.test.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiIcon } from '@elastic/eui';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/source_row/source_row.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/source_row/source_row.test.tsx
index cfac7148bf88a..9661471bb1dd7 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/source_row/source_row.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/source_row/source_row.test.tsx
@@ -5,11 +5,13 @@
* 2.0.
*/
+import { contentSources } from '../../../__mocks__/content_sources.mock';
+
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiTableRow, EuiSwitch, EuiIcon } from '@elastic/eui';
-import { contentSources } from '../../../__mocks__/content_sources.mock';
import { SourceIcon } from '../source_icon';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/source_row/source_row.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/source_row/source_row.tsx
index 11d71481751b0..6cfc68b45ee3c 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/source_row/source_row.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/source_row/source_row.tsx
@@ -26,14 +26,13 @@ import {
import { EuiLinkTo } from '../../../../shared/react_router_helpers';
import { SOURCE_STATUSES as statuses } from '../../../constants';
-import { ContentSourceDetails } from '../../../types';
import {
ADD_SOURCE_PATH,
SOURCE_DETAILS_PATH,
getContentSourcePath,
getSourcesPath,
} from '../../../routes';
-
+import { ContentSourceDetails } from '../../../types';
import { SourceIcon } from '../source_icon';
import './source_row.scss';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/sources_table/sources_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/sources_table/sources_table.test.tsx
index efe529bcfb289..f54f7ccdf24bd 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/sources_table/sources_table.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/sources_table/sources_table.test.tsx
@@ -5,13 +5,15 @@
* 2.0.
*/
+import { contentSources } from '../../../__mocks__/content_sources.mock';
+
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiTable } from '@elastic/eui';
-import { TableHeader } from '../../../../shared/table_header/table_header';
-import { contentSources } from '../../../__mocks__/content_sources.mock';
+import { TableHeader } from '../../../../shared/table_header/table_header';
import { SourceRow } from '../source_row';
import { SourcesTable } from './';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/sources_table/sources_table.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/sources_table/sources_table.tsx
index a0aba097d17f4..66e7e2e752a1e 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/sources_table/sources_table.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/sources_table/sources_table.tsx
@@ -10,8 +10,8 @@ import React from 'react';
import { EuiTable, EuiTableBody } from '@elastic/eui';
import { TableHeader } from '../../../../shared/table_header/table_header';
-import { SourceRow, ISourceRow } from '../source_row';
import { ContentSourceDetails } from '../../../types';
+import { SourceRow, ISourceRow } from '../source_row';
interface SourcesTableProps extends ISourceRow {
sources: ContentSourceDetails[];
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/table_pagination_bar/table_pagination_bar.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/table_pagination_bar/table_pagination_bar.test.tsx
index 343c9b68bc834..d22ddcce49dc4 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/table_pagination_bar/table_pagination_bar.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/table_pagination_bar/table_pagination_bar.test.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiFlexGroup, EuiTablePagination } from '@elastic/eui';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/user_icon/user_icon.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/user_icon/user_icon.test.tsx
index d8046bd88cf4a..5ce83b641cf8f 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/user_icon/user_icon.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/user_icon/user_icon.test.tsx
@@ -5,10 +5,11 @@
* 2.0.
*/
+import { users } from '../../../__mocks__/users.mock';
+
import React from 'react';
-import { shallow } from 'enzyme';
-import { users } from '../../../__mocks__/users.mock';
+import { shallow } from 'enzyme';
import { UserIcon } from './user_icon';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/user_row/user_row.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/user_row/user_row.test.tsx
index fe2bfd27db55a..f15c74ed1054b 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/user_row/user_row.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/user_row/user_row.test.tsx
@@ -5,13 +5,14 @@
* 2.0.
*/
+import { users } from '../../../__mocks__/users.mock';
+
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiTableRow } from '@elastic/eui';
-import { users } from '../../../__mocks__/users.mock';
-
import { UserRow } from './';
describe('SourcesTable', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/view_content_header/view_content_header.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/view_content_header/view_content_header.test.tsx
index 01a05a5d94c75..fda1a27e103c2 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/view_content_header/view_content_header.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/view_content_header/view_content_header.test.tsx
@@ -6,7 +6,9 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiFlexGroup } from '@elastic/eui';
import { ViewContentHeader } from './';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/view_content_header/view_content_header.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/view_content_header/view_content_header.tsx
index ed2989de5ce3c..fa3a1d3ccb2e4 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/view_content_header/view_content_header.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/view_content_header/view_content_header.tsx
@@ -8,7 +8,6 @@
import React from 'react';
import { EuiFlexGroup, EuiFlexItem, EuiText, EuiTitle, EuiSpacer } from '@elastic/eui';
-
import { FlexGroupAlignItems } from '@elastic/eui/src/components/flex/flex_group';
interface ViewContentHeaderProps {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.test.tsx
index 73ee7662888bb..5678ad545d50d 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.test.tsx
@@ -10,13 +10,15 @@ import { setMockValues, setMockActions, mockKibanaValues } from '../__mocks__';
import React from 'react';
import { Redirect } from 'react-router-dom';
+
import { shallow } from 'enzyme';
import { Layout } from '../shared/layout';
+
import { WorkplaceSearchHeaderActions } from './components/layout';
-import { SetupGuide } from './views/setup_guide';
import { ErrorState } from './views/error_state';
import { Overview } from './views/overview';
+import { SetupGuide } from './views/setup_guide';
import { WorkplaceSearch, WorkplaceSearchUnconfigured, WorkplaceSearchConfigured } from './';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.tsx
index a4c12f1d71d4e..d690dee4dc98c 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.tsx
@@ -7,16 +7,18 @@
import React, { useEffect } from 'react';
import { Route, Redirect, Switch, useLocation } from 'react-router-dom';
+
import { useActions, useValues } from 'kea';
import { WORKPLACE_SEARCH_PLUGIN } from '../../../common/constants';
import { InitialAppData } from '../../../common/types';
-import { KibanaLogic } from '../shared/kibana';
import { HttpLogic } from '../shared/http';
-import { AppLogic } from './app_logic';
+import { KibanaLogic } from '../shared/kibana';
import { Layout } from '../shared/layout';
-import { WorkplaceSearchNav, WorkplaceSearchHeaderActions } from './components/layout';
+import { NotFound } from '../shared/not_found';
+import { AppLogic } from './app_logic';
+import { WorkplaceSearchNav, WorkplaceSearchHeaderActions } from './components/layout';
import {
GROUPS_PATH,
SETUP_GUIDE_PATH,
@@ -25,19 +27,16 @@ import {
ORG_SETTINGS_PATH,
SECURITY_PATH,
} from './routes';
-
-import { SetupGuide } from './views/setup_guide';
+import { SourcesRouter } from './views/content_sources';
+import { SourceSubNav } from './views/content_sources/components/source_sub_nav';
import { ErrorState } from './views/error_state';
-import { NotFound } from '../shared/not_found';
-import { Overview } from './views/overview';
import { GroupsRouter } from './views/groups';
+import { GroupSubNav } from './views/groups/components/group_sub_nav';
+import { Overview } from './views/overview';
import { Security } from './views/security';
-import { SourcesRouter } from './views/content_sources';
import { SettingsRouter } from './views/settings';
-
-import { GroupSubNav } from './views/groups/components/group_sub_nav';
-import { SourceSubNav } from './views/content_sources/components/source_sub_nav';
import { SettingsSubNav } from './views/settings/components/settings_sub_nav';
+import { SetupGuide } from './views/setup_guide';
export const WorkplaceSearch: React.FC = (props) => {
const { config } = useValues(KibanaLogic);
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/routes.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/routes.test.tsx
index d9c1dbeefad92..68bec94270a01 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/routes.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/routes.test.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiLink } from '@elastic/eui';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source.test.tsx
index aa219a475406f..41f53523bca4e 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source.test.tsx
@@ -7,10 +7,10 @@
import '../../../../../__mocks__/shallow_useeffect.mock';
import { mockKibanaValues, setMockActions, setMockValues } from '../../../../../__mocks__';
-
import { sourceConfigData } from '../../../../__mocks__/content_sources.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
import { Loading } from '../../../../../shared/loading';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source.tsx
index 0664c930775bc..b00f9807f0acd 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source.tsx
@@ -9,16 +9,16 @@ import React, { useEffect } from 'react';
import { useActions, useValues } from 'kea';
-import { AppLogic } from '../../../../app_logic';
import { KibanaLogic } from '../../../../../shared/kibana';
import { Loading } from '../../../../../shared/loading';
+import { AppLogic } from '../../../../app_logic';
import { CUSTOM_SERVICE_TYPE } from '../../../../constants';
-import { staticSourceData } from '../../source_data';
-import { AddSourceLogic, AddSourceProps, AddSourceSteps } from './add_source_logic';
-import { SourceDataItem } from '../../../../types';
import { SOURCE_ADDED_PATH, getSourcesPath } from '../../../../routes';
+import { SourceDataItem } from '../../../../types';
+import { staticSourceData } from '../../source_data';
import { AddSourceHeader } from './add_source_header';
+import { AddSourceLogic, AddSourceProps, AddSourceSteps } from './add_source_logic';
import { ConfigCompleted } from './config_completed';
import { ConfigurationIntro } from './configuration_intro';
import { ConfigureCustom } from './configure_custom';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_header.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_header.test.tsx
index 7167fcf3bc252..879f7993f3dc1 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_header.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_header.test.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiText, EuiTextColor } from '@elastic/eui';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_list.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_list.test.tsx
index fe24eeb5c7cb5..90da349ea4f27 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_list.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_list.test.tsx
@@ -14,23 +14,23 @@ import {
} from '../../../../__mocks__/content_sources.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiEmptyPrompt, EuiFieldSearch } from '@elastic/eui';
-import { Loading } from '../../../../../../applications/shared/loading';
+import { Loading } from '../../../../../shared/loading';
import { ViewContentHeader } from '../../../../components/shared/view_content_header';
+import { AddSourceList } from './add_source_list';
+import { AvailableSourcesList } from './available_sources_list';
+import { ConfiguredSourcesList } from './configured_sources_list';
import {
ADD_SOURCE_NEW_SOURCE_DESCRIPTION,
ADD_SOURCE_ORG_SOURCE_DESCRIPTION,
ADD_SOURCE_PRIVATE_SOURCE_DESCRIPTION,
} from './constants';
-import { AddSourceList } from './add_source_list';
-import { AvailableSourcesList } from './available_sources_list';
-import { ConfiguredSourcesList } from './configured_sources_list';
-
describe('AddSourceList', () => {
const initializeSources = jest.fn();
const resetSourcesState = jest.fn();
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_list.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_list.tsx
index 3a0db0f44047d..372187485f277 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_list.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_list.tsx
@@ -18,15 +18,18 @@ import {
EuiPanel,
EuiEmptyPrompt,
} from '@elastic/eui';
-import noSharedSourcesIcon from '../../../../assets/share_circle.svg';
+import { Loading } from '../../../../../shared/loading';
import { AppLogic } from '../../../../app_logic';
+import noSharedSourcesIcon from '../../../../assets/share_circle.svg';
import { ContentSection } from '../../../../components/shared/content_section';
import { ViewContentHeader } from '../../../../components/shared/view_content_header';
-import { Loading } from '../../../../../../applications/shared/loading';
import { CUSTOM_SERVICE_TYPE } from '../../../../constants';
import { SourceDataItem } from '../../../../types';
+import { SourcesLogic } from '../../sources_logic';
+import { AvailableSourcesList } from './available_sources_list';
+import { ConfiguredSourcesList } from './configured_sources_list';
import {
ADD_SOURCE_NEW_SOURCE_DESCRIPTION,
ADD_SOURCE_ORG_SOURCE_DESCRIPTION,
@@ -39,10 +42,6 @@ import {
ADD_SOURCE_EMPTY_BODY,
} from './constants';
-import { SourcesLogic } from '../../sources_logic';
-import { AvailableSourcesList } from './available_sources_list';
-import { ConfiguredSourcesList } from './configured_sources_list';
-
export const AddSourceList: React.FC = () => {
const { contentSources, dataLoading, availableSources, configuredSources } = useValues(
SourcesLogic
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_logic.test.ts
index a3fd35503ea0d..ed67eb9994bc8 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_logic.test.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_logic.test.ts
@@ -11,20 +11,18 @@ import {
mockHttpValues,
mockKibanaValues,
} from '../../../../../__mocks__';
+import { sourceConfigData } from '../../../../__mocks__/content_sources.mock';
+
+import { nextTick } from '@kbn/test/jest';
-import { AppLogic } from '../../../../app_logic';
jest.mock('../../../../app_logic', () => ({
AppLogic: { values: { isOrganization: true } },
}));
+import { AppLogic } from '../../../../app_logic';
-import { SourcesLogic } from '../../sources_logic';
-
-import { nextTick } from '@kbn/test/jest';
-
-import { CustomSource } from '../../../../types';
import { SOURCES_PATH, getSourcesPath } from '../../../../routes';
-
-import { sourceConfigData } from '../../../../__mocks__/content_sources.mock';
+import { CustomSource } from '../../../../types';
+import { SourcesLogic } from '../../sources_logic';
import {
AddSourceLogic,
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_logic.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_logic.ts
index f10e81487567e..4e996aff6f5b0 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_logic.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_logic.ts
@@ -5,33 +5,27 @@
* 2.0.
*/
-import { keys, pickBy } from 'lodash';
-
-import { kea, MakeLogicType } from 'kea';
-
import { Search } from 'history';
+import { kea, MakeLogicType } from 'kea';
+import { keys, pickBy } from 'lodash';
import { i18n } from '@kbn/i18n';
-
import { HttpFetchQuery } from 'src/core/public';
-import { HttpLogic } from '../../../../../shared/http';
-import { KibanaLogic } from '../../../../../shared/kibana';
-import { parseQueryParams } from '../../../../../shared/query_params';
-
import {
flashAPIErrors,
setSuccessMessage,
clearFlashMessages,
} from '../../../../../shared/flash_messages';
-
-import { staticSourceData } from '../../source_data';
-import { SOURCES_PATH, getSourcesPath } from '../../../../routes';
-import { CUSTOM_SERVICE_TYPE, WORKPLACE_SEARCH_URL_PREFIX } from '../../../../constants';
-
+import { HttpLogic } from '../../../../../shared/http';
+import { KibanaLogic } from '../../../../../shared/kibana';
+import { parseQueryParams } from '../../../../../shared/query_params';
import { AppLogic } from '../../../../app_logic';
-import { SourcesLogic } from '../../sources_logic';
+import { CUSTOM_SERVICE_TYPE, WORKPLACE_SEARCH_URL_PREFIX } from '../../../../constants';
+import { SOURCES_PATH, getSourcesPath } from '../../../../routes';
import { CustomSource } from '../../../../types';
+import { staticSourceData } from '../../source_data';
+import { SourcesLogic } from '../../sources_logic';
export interface AddSourceProps {
sourceIndex: number;
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/available_sources_list.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/available_sources_list.test.tsx
index 43f1486644c72..fcb55f24ddb03 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/available_sources_list.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/available_sources_list.test.tsx
@@ -7,10 +7,10 @@
import '../../../../../__mocks__/shallow_useeffect.mock';
import { setMockValues } from '../../../../../__mocks__';
-
import { mergedAvailableSources } from '../../../../__mocks__/content_sources.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiCard, EuiToolTip, EuiTitle } from '@elastic/eui';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/available_sources_list.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/available_sources_list.tsx
index 8060f765a91b0..fafc1ea54a6cf 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/available_sources_list.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/available_sources_list.tsx
@@ -7,7 +7,7 @@
import React from 'react';
-import { i18n } from '@kbn/i18n';
+import { useValues } from 'kea';
import {
EuiCard,
@@ -18,15 +18,13 @@ import {
EuiText,
EuiToolTip,
} from '@elastic/eui';
-
-import { useValues } from 'kea';
+import { i18n } from '@kbn/i18n';
import { LicensingLogic } from '../../../../../shared/licensing';
import { EuiLinkTo } from '../../../../../shared/react_router_helpers';
-
import { SourceIcon } from '../../../../components/shared/source_icon';
-import { SourceDataItem } from '../../../../types';
import { ADD_CUSTOM_PATH, getSourcesPath } from '../../../../routes';
+import { SourceDataItem } from '../../../../types';
import {
AVAILABLE_SOURCE_EMPTY_STATE,
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/config_completed.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/config_completed.test.tsx
index cd40da7f6b376..163da5297e370 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/config_completed.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/config_completed.test.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { ConfigCompleted } from './config_completed';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/config_completed.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/config_completed.tsx
index bd85b3c7c2dd5..1d4f1f2fca980 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/config_completed.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/config_completed.tsx
@@ -7,9 +7,6 @@
import React from 'react';
-import { i18n } from '@kbn/i18n';
-import { FormattedMessage } from '@kbn/i18n/react';
-
import {
EuiButton,
EuiFlexGroup,
@@ -20,7 +17,10 @@ import {
EuiText,
EuiTextAlign,
} from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+import { FormattedMessage } from '@kbn/i18n/react';
+import { EuiLinkTo, EuiButtonTo } from '../../../../../shared/react_router_helpers';
import {
getSourcesPath,
ADD_SOURCE_PATH,
@@ -28,8 +28,6 @@ import {
PRIVATE_SOURCES_DOCS_URL,
} from '../../../../routes';
-import { EuiLinkTo, EuiButtonTo } from '../../../../../shared/react_router_helpers';
-
import {
CONFIG_COMPLETED_PRIVATE_SOURCES_DOCS_LINK,
CONFIG_COMPLETED_CONFIGURE_NEW_BUTTON,
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/config_docs_links.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/config_docs_links.test.tsx
index b56f36df5486e..914eca94ad6f3 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/config_docs_links.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/config_docs_links.test.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiButtonEmpty } from '@elastic/eui';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/config_docs_links.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/config_docs_links.tsx
index 259e911d6d54f..043d28e9dba03 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/config_docs_links.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/config_docs_links.tsx
@@ -7,9 +7,8 @@
import React from 'react';
-import { i18n } from '@kbn/i18n';
-
import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
import { DOCUMENTATION_LINK_TITLE } from '../../../../constants';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configuration_intro.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configuration_intro.test.tsx
index 2d26982cbc2f5..2ebc021925abf 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configuration_intro.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configuration_intro.test.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiText, EuiTitle } from '@elastic/eui';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configuration_intro.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configuration_intro.tsx
index ff1caafb91bdb..914eee74dfc4e 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configuration_intro.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configuration_intro.tsx
@@ -7,9 +7,6 @@
import React from 'react';
-import { i18n } from '@kbn/i18n';
-import { FormattedMessage } from '@kbn/i18n/react';
-
import {
EuiBadge,
EuiButton,
@@ -20,6 +17,10 @@ import {
EuiText,
EuiTitle,
} from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+import { FormattedMessage } from '@kbn/i18n/react';
+
+import connectionIllustration from '../../../../assets/connection_illustration.svg';
import {
CONFIG_INTRO_ALT_TEXT,
@@ -31,8 +32,6 @@ import {
CONFIG_INTRO_STEP2_TEXT,
} from './constants';
-import connectionIllustration from '../../../../assets/connection_illustration.svg';
-
interface ConfigurationIntroProps {
header: React.ReactNode;
name: string;
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_custom.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_custom.test.tsx
index a3b572737bdeb..099989255bf47 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_custom.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_custom.test.tsx
@@ -9,6 +9,7 @@ import '../../../../../__mocks__/shallow_useeffect.mock';
import { setMockActions, setMockValues } from '../../../../../__mocks__';
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiForm, EuiFieldText } from '@elastic/eui';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_custom.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_custom.tsx
index 2d0113f1d0e7d..36242f5523e77 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_custom.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_custom.tsx
@@ -9,8 +9,6 @@ import React, { ChangeEvent, FormEvent } from 'react';
import { useActions, useValues } from 'kea';
-import { FormattedMessage } from '@kbn/i18n/react';
-
import {
EuiButton,
EuiFieldText,
@@ -20,8 +18,10 @@ import {
EuiSpacer,
EuiText,
} from '@elastic/eui';
+import { FormattedMessage } from '@kbn/i18n/react';
import { CUSTOM_SOURCE_DOCS_URL } from '../../../../routes';
+
import { AddSourceLogic } from './add_source_logic';
import { CONFIG_CUSTOM_BUTTON } from './constants';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_oauth.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_oauth.test.tsx
index a57ff390150ea..533dfcda70db1 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_oauth.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_oauth.test.tsx
@@ -9,11 +9,12 @@ import '../../../../../__mocks__/shallow_useeffect.mock';
import { setMockActions, setMockValues } from '../../../../../__mocks__';
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiCheckboxGroup } from '@elastic/eui';
-import { Loading } from '../../../../../../applications/shared/loading';
+import { Loading } from '../../../../../shared/loading';
import { ConfigureOauth } from './configure_oauth';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_oauth.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_oauth.tsx
index 3eae438eb960c..69a2fbd1495c7 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_oauth.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_oauth.tsx
@@ -6,10 +6,10 @@
*/
import React, { useEffect, useState, FormEvent } from 'react';
+import { useLocation } from 'react-router-dom';
import { Location } from 'history';
import { useActions, useValues } from 'kea';
-import { useLocation } from 'react-router-dom';
import {
EuiButton,
@@ -19,13 +19,12 @@ import {
EuiFormRow,
EuiSpacer,
} from '@elastic/eui';
-
import { EuiCheckboxGroupIdToSelectedMap } from '@elastic/eui/src/components/form/checkbox/checkbox_group';
-import { parseQueryParams } from '../../../../../../applications/shared/query_params';
-import { Loading } from '../../../../../../applications/shared/loading';
-import { AddSourceLogic } from './add_source_logic';
+import { Loading } from '../../../../../shared/loading';
+import { parseQueryParams } from '../../../../../shared/query_params';
+import { AddSourceLogic } from './add_source_logic';
import { CONFIG_OAUTH_LABEL, CONFIG_OAUTH_BUTTON } from './constants';
interface OauthQueryParams {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configured_sources_list.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configured_sources_list.test.tsx
index 3bb7d42748f25..2e2e04556cdb7 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configured_sources_list.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configured_sources_list.test.tsx
@@ -5,13 +5,14 @@
* 2.0.
*/
+import { mergedConfiguredSources } from '../../../../__mocks__/content_sources.mock';
+
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiPanel } from '@elastic/eui';
-import { mergedConfiguredSources } from '../../../../__mocks__/content_sources.mock';
-
import { ConfiguredSourcesList } from './configured_sources_list';
describe('ConfiguredSourcesList', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configured_sources_list.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configured_sources_list.tsx
index cb5e96a4019a1..5f64913410d4c 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configured_sources_list.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configured_sources_list.tsx
@@ -21,8 +21,8 @@ import {
import { EuiButtonEmptyTo } from '../../../../../shared/react_router_helpers';
import { SourceIcon } from '../../../../components/shared/source_icon';
-import { SourceDataItem } from '../../../../types';
import { getSourcesPath } from '../../../../routes';
+import { SourceDataItem } from '../../../../types';
import {
CONFIGURED_SOURCES_LIST_UNCONNECTED_TOOLTIP,
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/connect_instance.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/connect_instance.test.tsx
index cff95136968db..b795b0af09944 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/connect_instance.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/connect_instance.test.tsx
@@ -9,12 +9,14 @@ import '../../../../../__mocks__/shallow_useeffect.mock';
import { setMockActions, setMockValues } from '../../../../../__mocks__';
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiBadge, EuiCallOut, EuiSwitch } from '@elastic/eui';
import { FeatureIds } from '../../../../types';
import { staticSourceData } from '../../source_data';
+
import { ConnectInstance } from './connect_instance';
describe('ConnectInstance', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/connect_instance.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/connect_instance.tsx
index ea5d556350759..08b29075f3d0d 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/connect_instance.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/connect_instance.tsx
@@ -8,8 +8,6 @@
import React, { useState, useEffect, FormEvent } from 'react';
import { useActions, useValues } from 'kea';
-import { i18n } from '@kbn/i18n';
-import { FormattedMessage } from '@kbn/i18n/react';
import {
EuiButton,
@@ -27,16 +25,16 @@ import {
EuiBadge,
EuiBadgeGroup,
} from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+import { FormattedMessage } from '@kbn/i18n/react';
-import { LicensingLogic } from '../../../../../../applications/shared/licensing';
-
+import { LicensingLogic } from '../../../../../shared/licensing';
import { AppLogic } from '../../../../app_logic';
-import { AddSourceLogic } from './add_source_logic';
-import { FeatureIds, Configuration, Features } from '../../../../types';
import { DOCUMENT_PERMISSIONS_DOCS_URL } from '../../../../routes';
-import { SourceFeatures } from './source_features';
-
+import { FeatureIds, Configuration, Features } from '../../../../types';
import { LEARN_MORE_LINK } from '../../constants';
+
+import { AddSourceLogic } from './add_source_logic';
import {
CONNECT_REMOTE,
CONNECT_PRIVATE,
@@ -47,6 +45,7 @@ import {
CONNECT_NOT_SYNCED_TITLE,
CONNECT_NOT_SYNCED_TEXT,
} from './constants';
+import { SourceFeatures } from './source_features';
interface ConnectInstanceProps {
header: React.ReactNode;
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/re_authenticate.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/re_authenticate.test.tsx
index 94c2e734751ee..38b6925008181 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/re_authenticate.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/re_authenticate.test.tsx
@@ -9,6 +9,7 @@ import '../../../../../__mocks__/shallow_useeffect.mock';
import { setMockActions, setMockValues } from '../../../../../__mocks__';
import React from 'react';
+
import { shallow } from 'enzyme';
import { ReAuthenticate } from './re_authenticate';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/re_authenticate.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/re_authenticate.tsx
index 0cdf461f2d64c..eb6736d84a197 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/re_authenticate.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/re_authenticate.tsx
@@ -6,14 +6,15 @@
*/
import React, { useEffect, useState, FormEvent } from 'react';
+import { useLocation } from 'react-router-dom';
import { Location } from 'history';
import { useActions, useValues } from 'kea';
-import { useLocation } from 'react-router-dom';
-import { i18n } from '@kbn/i18n';
import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiFormRow, EuiSpacer } from '@elastic/eui';
-import { parseQueryParams } from '../../../../../../applications/shared/query_params';
+import { i18n } from '@kbn/i18n';
+
+import { parseQueryParams } from '../../../../../shared/query_params';
import { AddSourceLogic } from './add_source_logic';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_config.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_config.test.tsx
index 4d1955d7928a8..c0f7f1139cb73 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_config.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_config.test.tsx
@@ -7,18 +7,18 @@
import '../../../../../__mocks__/shallow_useeffect.mock';
import { setMockActions, setMockValues } from '../../../../../__mocks__';
+import { sourceConfigData } from '../../../../__mocks__/content_sources.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiSteps, EuiButton, EuiButtonEmpty } from '@elastic/eui';
-import { sourceConfigData } from '../../../../__mocks__/content_sources.mock';
+import { ApiKey } from '../../../../components/shared/api_key';
import { staticSourceData } from '../../source_data';
-import { ApiKey } from '../../../../components/shared/api_key';
import { ConfigDocsLinks } from './config_docs_links';
-
import { SaveConfig } from './save_config';
describe('SaveConfig', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_config.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_config.tsx
index f6d5d0f4066ab..956d5143ef2c5 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_config.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_config.tsx
@@ -8,7 +8,6 @@
import React, { FormEvent } from 'react';
import { useActions, useValues } from 'kea';
-import { i18n } from '@kbn/i18n';
import {
EuiButton,
@@ -21,7 +20,10 @@ import {
EuiSpacer,
EuiSteps,
} from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+import { LicensingLogic } from '../../../../../shared/licensing';
+import { ApiKey } from '../../../../components/shared/api_key';
import {
PUBLIC_KEY_LABEL,
CONSUMER_KEY_LABEL,
@@ -31,16 +33,11 @@ import {
CLIENT_SECRET_LABEL,
REMOVE_BUTTON,
} from '../../../../constants';
-
-import { OAUTH_SAVE_CONFIG_BUTTON, OAUTH_BACK_BUTTON, OAUTH_STEP_2 } from './constants';
-
-import { LicensingLogic } from '../../../../../../applications/shared/licensing';
-
-import { ApiKey } from '../../../../components/shared/api_key';
-import { AddSourceLogic } from './add_source_logic';
import { Configuration } from '../../../../types';
+import { AddSourceLogic } from './add_source_logic';
import { ConfigDocsLinks } from './config_docs_links';
+import { OAUTH_SAVE_CONFIG_BUTTON, OAUTH_BACK_BUTTON, OAUTH_STEP_2 } from './constants';
interface SaveConfigProps {
header: React.ReactNode;
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_custom.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_custom.test.tsx
index 551bd7f1bb006..5ed777322cc08 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_custom.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_custom.test.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiLink, EuiPanel, EuiTitle } from '@elastic/eui';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_custom.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_custom.tsx
index a61ad1aeb728a..b42bd674109fe 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_custom.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_custom.tsx
@@ -7,9 +7,6 @@
import React from 'react';
-import { i18n } from '@kbn/i18n';
-import { FormattedMessage } from '@kbn/i18n/react';
-
import {
EuiFlexGroup,
EuiFlexItem,
@@ -22,12 +19,12 @@ import {
EuiLink,
EuiPanel,
} from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+import { FormattedMessage } from '@kbn/i18n/react';
import { EuiLinkTo } from '../../../../../shared/react_router_helpers';
import { CredentialItem } from '../../../../components/shared/credential_item';
import { LicenseBadge } from '../../../../components/shared/license_badge';
-
-import { CustomSource } from '../../../../types';
import {
SOURCES_PATH,
SOURCE_DISPLAY_SETTINGS_PATH,
@@ -36,7 +33,7 @@ import {
getContentSourcePath,
getSourcesPath,
} from '../../../../routes';
-
+import { CustomSource } from '../../../../types';
import { ACCESS_TOKEN_LABEL, ID_LABEL, LEARN_CUSTOM_FEATURES_BUTTON } from '../../constants';
import {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/source_features.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/source_features.test.tsx
index ccc6d05df5f9a..cd8ba37695ac6 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/source_features.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/source_features.test.tsx
@@ -11,10 +11,10 @@ import React from 'react';
import { EuiPanel } from '@elastic/eui';
-import { SourceFeatures } from './source_features';
-
import { staticSourceData } from '../../source_data';
+import { SourceFeatures } from './source_features';
+
describe('SourceFeatures', () => {
const { features, objTypes } = staticSourceData[0];
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/source_features.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/source_features.tsx
index 186e8fcdc3790..0838ab2ccdae2 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/source_features.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/source_features.tsx
@@ -8,7 +8,6 @@
import React from 'react';
import { useValues } from 'kea';
-import { FormattedMessage } from '@kbn/i18n/react';
import {
EuiFlexGroup,
@@ -19,13 +18,13 @@ import {
EuiText,
EuiTitle,
} from '@elastic/eui';
+import { FormattedMessage } from '@kbn/i18n/react';
-import { LicensingLogic } from '../../../../../../applications/shared/licensing';
-
+import { LicensingLogic } from '../../../../../shared/licensing';
import { AppLogic } from '../../../../app_logic';
import { LicenseBadge } from '../../../../components/shared/license_badge';
-import { Features, FeatureIds } from '../../../../types';
import { ENT_SEARCH_LICENSE_MANAGEMENT } from '../../../../routes';
+import { Features, FeatureIds } from '../../../../types';
import {
SOURCE_FEATURES_SEARCHABLE,
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/custom_source_icon.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/custom_source_icon.test.tsx
index 6567f74bd8790..fcce69d70ad50 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/custom_source_icon.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/custom_source_icon.test.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { CustomSourceIcon } from './custom_source_icon';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings.test.tsx
index 72744690baf30..feebc7f8d445e 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings.test.tsx
@@ -8,24 +8,21 @@
import '../../../../../__mocks__/shallow_useeffect.mock';
import { mockKibanaValues } from '../../../../../__mocks__';
-
import { setMockValues, setMockActions } from '../../../../../__mocks__';
import { unmountHandler } from '../../../../../__mocks__/shallow_useeffect.mock';
-
-import { shallow } from 'enzyme';
+import { exampleResult } from '../../../../__mocks__/content_sources.mock';
import React from 'react';
-import { EuiButton, EuiTabbedContent } from '@elastic/eui';
+import { shallow } from 'enzyme';
-import { exampleResult } from '../../../../__mocks__/content_sources.mock';
+import { EuiButton, EuiTabbedContent } from '@elastic/eui';
import { Loading } from '../../../../../shared/loading';
import { ViewContentHeader } from '../../../../components/shared/view_content_header';
-import { FieldEditorModal } from './field_editor_modal';
-
import { DisplaySettings } from './display_settings';
+import { FieldEditorModal } from './field_editor_modal';
describe('DisplaySettings', () => {
const { navigateToUrl } = mockKibanaValues;
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings.tsx
index 62beb4e40793b..29266cdefe584 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings.tsx
@@ -19,21 +19,18 @@ import {
EuiTabbedContentTab,
} from '@elastic/eui';
+import { clearFlashMessages } from '../../../../../shared/flash_messages';
+import { KibanaLogic } from '../../../../../shared/kibana';
+import { Loading } from '../../../../../shared/loading';
+import { AppLogic } from '../../../../app_logic';
+import { ViewContentHeader } from '../../../../components/shared/view_content_header';
+import { SAVE_BUTTON } from '../../../../constants';
import {
DISPLAY_SETTINGS_RESULT_DETAIL_PATH,
DISPLAY_SETTINGS_SEARCH_RESULT_PATH,
getContentSourcePath,
} from '../../../../routes';
-import { clearFlashMessages } from '../../../../../shared/flash_messages';
-
-import { KibanaLogic } from '../../../../../shared/kibana';
-import { AppLogic } from '../../../../app_logic';
-
-import { Loading } from '../../../../../shared/loading';
-import { ViewContentHeader } from '../../../../components/shared/view_content_header';
-
-import { SAVE_BUTTON } from '../../../../constants';
import {
UNSAVED_MESSAGE,
DISPLAY_SETTINGS_TITLE,
@@ -43,9 +40,7 @@ import {
SEARCH_RESULTS_LABEL,
RESULT_DETAIL_LABEL,
} from './constants';
-
import { DisplaySettingsLogic } from './display_settings_logic';
-
import { FieldEditorModal } from './field_editor_modal';
import { ResultDetail } from './result_detail';
import { SearchResults } from './search_results';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings_logic.test.ts
index c51f3e97bf155..73df0298ecd19 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings_logic.test.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings_logic.test.ts
@@ -5,25 +5,22 @@
* 2.0.
*/
-import { LogicMounter } from '../../../../../__mocks__/kea.mock';
+import { LogicMounter, mockFlashMessageHelpers, mockHttpValues } from '../../../../../__mocks__';
+import { exampleResult } from '../../../../__mocks__/content_sources.mock';
-import { mockFlashMessageHelpers, mockHttpValues } from '../../../../../__mocks__';
+import { nextTick } from '@kbn/test/jest';
const contentSource = { id: 'source123' };
jest.mock('../../source_logic', () => ({
SourceLogic: { values: { contentSource } },
}));
-import { AppLogic } from '../../../../app_logic';
jest.mock('../../../../app_logic', () => ({
AppLogic: { values: { isOrganization: true } },
}));
+import { AppLogic } from '../../../../app_logic';
-import { nextTick } from '@kbn/test/jest';
-
-import { exampleResult } from '../../../../__mocks__/content_sources.mock';
import { LEAVE_UNASSIGNED_FIELD } from './constants';
-
import { DisplaySettingsLogic, defaultSearchResultConfig } from './display_settings_logic';
describe('DisplaySettingsLogic', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings_logic.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings_logic.ts
index 7c5946d08292c..62d959083af59 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings_logic.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings_logic.ts
@@ -5,24 +5,23 @@
* 2.0.
*/
-import { cloneDeep, isEqual, differenceBy } from 'lodash';
import { DropResult } from 'react-beautiful-dnd';
import { kea, MakeLogicType } from 'kea';
-
-import { HttpLogic } from '../../../../../shared/http';
+import { cloneDeep, isEqual, differenceBy } from 'lodash';
import {
setSuccessMessage,
clearFlashMessages,
flashAPIErrors,
} from '../../../../../shared/flash_messages';
-
+import { HttpLogic } from '../../../../../shared/http';
import { AppLogic } from '../../../../app_logic';
+import { DetailField, SearchResultConfig, OptionValue, Result } from '../../../../types';
import { SourceLogic } from '../../source_logic';
-import { DetailField, SearchResultConfig, OptionValue, Result } from '../../../../types';
import { LEAVE_UNASSIGNED_FIELD, SUCCESS_MESSAGE } from './constants';
+
export interface DisplaySettingsResponseProps {
sourceName: string;
searchResultConfig: SearchResultConfig;
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings_router.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings_router.test.tsx
index f216cbf286b94..f04afe60aa49d 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings_router.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings_router.test.tsx
@@ -10,12 +10,11 @@ import '../../../../../__mocks__/shallow_useeffect.mock';
import { setMockValues } from '../../../../../__mocks__';
import React from 'react';
-import { shallow } from 'enzyme';
-
import { Route, Switch } from 'react-router-dom';
-import { DisplaySettings } from './display_settings';
+import { shallow } from 'enzyme';
+import { DisplaySettings } from './display_settings';
import { DisplaySettingsRouter } from './display_settings_router';
describe('DisplaySettingsRouter', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings_router.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings_router.tsx
index fa9817494ee09..bd753631ed48c 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings_router.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings_router.tsx
@@ -6,12 +6,11 @@
*/
import React from 'react';
+import { Route, Switch } from 'react-router-dom';
import { useValues } from 'kea';
-import { Route, Switch } from 'react-router-dom';
import { AppLogic } from '../../../../app_logic';
-
import {
DISPLAY_SETTINGS_RESULT_DETAIL_PATH,
DISPLAY_SETTINGS_SEARCH_RESULT_PATH,
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_result_detail_card.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_result_detail_card.test.tsx
index 381e4fe4c0b25..15e1fe0ed417c 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_result_detail_card.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_result_detail_card.test.tsx
@@ -8,11 +8,11 @@
import '../../../../../__mocks__/shallow_useeffect.mock';
import { setMockValues } from '../../../../../__mocks__';
-import { shallow } from 'enzyme';
+import { exampleResult } from '../../../../__mocks__/content_sources.mock';
import React from 'react';
-import { exampleResult } from '../../../../__mocks__/content_sources.mock';
+import { shallow } from 'enzyme';
import { ExampleResultDetailCard } from './example_result_detail_card';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_result_detail_card.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_result_detail_card.tsx
index 46c06f28af6d6..93a7d660215f0 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_result_detail_card.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_result_detail_card.tsx
@@ -14,9 +14,8 @@ import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiText, EuiTitle } from '@elasti
import { URL_LABEL } from '../../../../constants';
-import { DisplaySettingsLogic } from './display_settings_logic';
-
import { CustomSourceIcon } from './custom_source_icon';
+import { DisplaySettingsLogic } from './display_settings_logic';
import { TitleField } from './title_field';
export const ExampleResultDetailCard: React.FC = () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_search_result_group.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_search_result_group.test.tsx
index d08195f3e83bc..6f90c1045ae31 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_search_result_group.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_search_result_group.test.tsx
@@ -8,14 +8,13 @@
import '../../../../../__mocks__/shallow_useeffect.mock';
import { setMockValues } from '../../../../../__mocks__';
-import { shallow } from 'enzyme';
+import { exampleResult } from '../../../../__mocks__/content_sources.mock';
import React from 'react';
-import { exampleResult } from '../../../../__mocks__/content_sources.mock';
+import { shallow } from 'enzyme';
import { CustomSourceIcon } from './custom_source_icon';
-
import { ExampleSearchResultGroup } from './example_search_result_group';
describe('ExampleSearchResultGroup', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_search_result_group.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_search_result_group.tsx
index 5d5f73467f82c..df89eed38ae92 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_search_result_group.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_search_result_group.tsx
@@ -7,15 +7,15 @@
import React from 'react';
-import { isColorDark, hexToRgb } from '@elastic/eui';
import classNames from 'classnames';
import { useValues } from 'kea';
-import { DESCRIPTION_LABEL } from '../../../../constants';
+import { isColorDark, hexToRgb } from '@elastic/eui';
-import { DisplaySettingsLogic } from './display_settings_logic';
+import { DESCRIPTION_LABEL } from '../../../../constants';
import { CustomSourceIcon } from './custom_source_icon';
+import { DisplaySettingsLogic } from './display_settings_logic';
import { SubtitleField } from './subtitle_field';
import { TitleField } from './title_field';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_standout_result.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_standout_result.test.tsx
index 6241bcf05fbff..49845e79d86aa 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_standout_result.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_standout_result.test.tsx
@@ -8,14 +8,13 @@
import '../../../../../__mocks__/shallow_useeffect.mock';
import { setMockValues } from '../../../../../__mocks__';
-import { shallow } from 'enzyme';
+import { exampleResult } from '../../../../__mocks__/content_sources.mock';
import React from 'react';
-import { exampleResult } from '../../../../__mocks__/content_sources.mock';
+import { shallow } from 'enzyme';
import { CustomSourceIcon } from './custom_source_icon';
-
import { ExampleStandoutResult } from './example_standout_result';
describe('ExampleStandoutResult', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_standout_result.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_standout_result.tsx
index 3c139001d3ea2..48c3149e622bd 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_standout_result.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_standout_result.tsx
@@ -14,9 +14,8 @@ import { isColorDark, hexToRgb } from '@elastic/eui';
import { DESCRIPTION_LABEL } from '../../../../constants';
-import { DisplaySettingsLogic } from './display_settings_logic';
-
import { CustomSourceIcon } from './custom_source_icon';
+import { DisplaySettingsLogic } from './display_settings_logic';
import { SubtitleField } from './subtitle_field';
import { TitleField } from './title_field';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/field_editor_modal.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/field_editor_modal.test.tsx
index 82687165d0535..fe7bced843841 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/field_editor_modal.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/field_editor_modal.test.tsx
@@ -8,13 +8,13 @@
import '../../../../../__mocks__/shallow_useeffect.mock';
import { setMockValues, setMockActions } from '../../../../../__mocks__';
-import { shallow } from 'enzyme';
+import { exampleResult } from '../../../../__mocks__/content_sources.mock';
import React from 'react';
-import { EuiModal, EuiSelect, EuiFieldText } from '@elastic/eui';
+import { shallow } from 'enzyme';
-import { exampleResult } from '../../../../__mocks__/content_sources.mock';
+import { EuiModal, EuiSelect, EuiFieldText } from '@elastic/eui';
import { FieldEditorModal } from './field_editor_modal';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/result_detail.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/result_detail.test.tsx
index 217a8142af5d5..768573ce80fee 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/result_detail.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/result_detail.test.tsx
@@ -6,9 +6,8 @@
*/
import '../../../../../__mocks__/shallow_useeffect.mock';
-
import { setMockValues, setMockActions } from '../../../../../__mocks__';
-import { shallow, mount } from 'enzyme';
+import { exampleResult } from '../../../../__mocks__/content_sources.mock';
/**
* Mocking necessary due to console warnings from react d-n-d, which EUI uses
@@ -40,12 +39,11 @@ jest.mock('react-beautiful-dnd', () => ({
import React from 'react';
-import { EuiTextColor } from '@elastic/eui';
+import { shallow, mount } from 'enzyme';
-import { exampleResult } from '../../../../__mocks__/content_sources.mock';
+import { EuiTextColor } from '@elastic/eui';
import { ExampleResultDetailCard } from './example_result_detail_card';
-
import { ResultDetail } from './result_detail';
describe('ResultDetail', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/result_detail.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/result_detail.tsx
index 8382ddc9e82b3..6832f075476e7 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/result_detail.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/result_detail.tsx
@@ -28,10 +28,9 @@ import {
} from '@elastic/eui';
import { ADD_FIELD_LABEL, EDIT_FIELD_LABEL, REMOVE_FIELD_LABEL } from '../../../../constants';
-import { VISIBLE_FIELDS_TITLE, EMPTY_FIELDS_DESCRIPTION, PREVIEW_TITLE } from './constants';
+import { VISIBLE_FIELDS_TITLE, EMPTY_FIELDS_DESCRIPTION, PREVIEW_TITLE } from './constants';
import { DisplaySettingsLogic } from './display_settings_logic';
-
import { ExampleResultDetailCard } from './example_result_detail_card';
export const ResultDetail: React.FC = () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/search_results.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/search_results.test.tsx
index 26116a7e736bc..28de0006f162f 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/search_results.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/search_results.test.tsx
@@ -8,16 +8,15 @@
import '../../../../../__mocks__/shallow_useeffect.mock';
import { setMockValues, setMockActions } from '../../../../../__mocks__';
-import { shallow } from 'enzyme';
+import { exampleResult } from '../../../../__mocks__/content_sources.mock';
import React from 'react';
-import { exampleResult } from '../../../../__mocks__/content_sources.mock';
+import { shallow } from 'enzyme';
+import { LEAVE_UNASSIGNED_FIELD } from './constants';
import { ExampleSearchResultGroup } from './example_search_result_group';
import { ExampleStandoutResult } from './example_standout_result';
-
-import { LEAVE_UNASSIGNED_FIELD } from './constants';
import { SearchResults } from './search_results';
describe('SearchResults', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/search_results.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/search_results.tsx
index b2ba2b13e5ec3..859fb2d5d2a20 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/search_results.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/search_results.tsx
@@ -21,9 +21,8 @@ import {
EuiTitle,
} from '@elastic/eui';
-import { DisplaySettingsLogic } from './display_settings_logic';
-
import { DESCRIPTION_LABEL } from '../../../../constants';
+
import {
LEAVE_UNASSIGNED_FIELD,
SEARCH_RESULTS_TITLE,
@@ -34,7 +33,7 @@ import {
STANDARD_RESULTS_TITLE,
STANDARD_RESULTS_DESCRIPTION,
} from './constants';
-
+import { DisplaySettingsLogic } from './display_settings_logic';
import { ExampleSearchResultGroup } from './example_search_result_group';
import { ExampleStandoutResult } from './example_standout_result';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/subtitle_field.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/subtitle_field.test.tsx
index 812af1b1fd26b..76c28ae3d4060 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/subtitle_field.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/subtitle_field.test.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { SubtitleField } from './subtitle_field';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/title_field.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/title_field.test.tsx
index f2a82f058c0de..2ed4aa0b0fad1 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/title_field.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/title_field.test.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { TitleField } from './title_field';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/overview.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/overview.test.tsx
index 0e91d2a3a4a28..a30f1bfbd596a 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/overview.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/overview.test.tsx
@@ -8,14 +8,14 @@
import '../../../../__mocks__/shallow_useeffect.mock';
import { setMockValues } from '../../../../__mocks__';
+import { fullContentSources } from '../../../__mocks__/content_sources.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiEmptyPrompt, EuiPanel, EuiTable } from '@elastic/eui';
-import { fullContentSources } from '../../../__mocks__/content_sources.mock';
-
import { Loading } from '../../../../shared/loading';
import { ComponentLoader } from '../../../components/shared/component_loader';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/overview.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/overview.tsx
index a67adfdd3802a..34d7edd99c376 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/overview.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/overview.tsx
@@ -9,8 +9,6 @@ import React from 'react';
import { useValues } from 'kea';
-import { FormattedMessage } from '@kbn/i18n/react';
-
import {
EuiEmptyPrompt,
EuiFlexGroup,
@@ -30,7 +28,21 @@ import {
EuiTextColor,
EuiTitle,
} from '@elastic/eui';
+import { FormattedMessage } from '@kbn/i18n/react';
+import { Loading } from '../../../../shared/loading';
+import { EuiPanelTo } from '../../../../shared/react_router_helpers';
+import { AppLogic } from '../../../app_logic';
+import aclImage from '../../../assets/supports_acl.svg';
+import { ComponentLoader } from '../../../components/shared/component_loader';
+import { CredentialItem } from '../../../components/shared/credential_item';
+import { LicenseBadge } from '../../../components/shared/license_badge';
+import { ViewContentHeader } from '../../../components/shared/view_content_header';
+import {
+ RECENT_ACTIVITY_TITLE,
+ CREDENTIALS_TITLE,
+ DOCUMENTATION_LINK_TITLE,
+} from '../../../constants';
import {
CUSTOM_SOURCE_DOCS_URL,
DOCUMENT_PERMISSIONS_DOCS_URL,
@@ -38,12 +50,6 @@ import {
EXTERNAL_IDENTITIES_DOCS_URL,
getGroupPath,
} from '../../../routes';
-
-import {
- RECENT_ACTIVITY_TITLE,
- CREDENTIALS_TITLE,
- DOCUMENTATION_LINK_TITLE,
-} from '../../../constants';
import {
SOURCES_NO_CONTENT_TITLE,
CONTENT_SUMMARY_TITLE,
@@ -70,17 +76,6 @@ import {
DOC_PERMISSIONS_DESCRIPTION,
CUSTOM_CALLOUT_TITLE,
} from '../constants';
-
-import { AppLogic } from '../../../app_logic';
-
-import { ComponentLoader } from '../../../components/shared/component_loader';
-import { CredentialItem } from '../../../components/shared/credential_item';
-import { ViewContentHeader } from '../../../components/shared/view_content_header';
-import { LicenseBadge } from '../../../components/shared/license_badge';
-import { Loading } from '../../../../shared/loading';
-import { EuiPanelTo } from '../../../../shared/react_router_helpers';
-
-import aclImage from '../../../assets/supports_acl.svg';
import { SourceLogic } from '../source_logic';
export const Overview: React.FC = () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema.test.tsx
index b30c5d78fd42f..ccf3275ffd96f 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema.test.tsx
@@ -8,21 +8,20 @@
import '../../../../../__mocks__/shallow_useeffect.mock';
import { setMockValues, setMockActions } from '../../../../../__mocks__';
+import { mostRecentIndexJob } from '../../../../__mocks__/content_sources.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiEmptyPrompt, EuiFieldSearch } from '@elastic/eui';
-import { mostRecentIndexJob } from '../../../../__mocks__/content_sources.mock';
-
import { IndexingStatus } from '../../../../../shared/indexing_status';
import { Loading } from '../../../../../shared/loading';
import { SchemaAddFieldModal } from '../../../../../shared/schema/schema_add_field_modal';
-import { SchemaFieldsTable } from './schema_fields_table';
-
import { Schema } from './schema';
+import { SchemaFieldsTable } from './schema_fields_table';
describe('Schema', () => {
const initializeSchema = jest.fn();
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema.tsx
index fe48e1c14ff41..77d1002a9ad26 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema.tsx
@@ -20,17 +20,12 @@ import {
EuiPanel,
} from '@elastic/eui';
-import { getReindexJobRoute } from '../../../../routes';
-import { AppLogic } from '../../../../app_logic';
-
+import { IndexingStatus } from '../../../../../shared/indexing_status';
import { Loading } from '../../../../../shared/loading';
-import { ViewContentHeader } from '../../../../components/shared/view_content_header';
-
import { SchemaAddFieldModal } from '../../../../../shared/schema/schema_add_field_modal';
-import { IndexingStatus } from '../../../../../shared/indexing_status';
-
-import { SchemaFieldsTable } from './schema_fields_table';
-import { SchemaLogic } from './schema_logic';
+import { AppLogic } from '../../../../app_logic';
+import { ViewContentHeader } from '../../../../components/shared/view_content_header';
+import { getReindexJobRoute } from '../../../../routes';
import {
SCHEMA_ADD_FIELD_BUTTON,
@@ -42,6 +37,8 @@ import {
SCHEMA_EMPTY_SCHEMA_TITLE,
SCHEMA_EMPTY_SCHEMA_DESCRIPTION,
} from './constants';
+import { SchemaFieldsTable } from './schema_fields_table';
+import { SchemaLogic } from './schema_logic';
export const Schema: React.FC = () => {
const {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema_change_errors.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema_change_errors.test.tsx
index 421aa04692bd7..e9276b8ec3878 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema_change_errors.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema_change_errors.test.tsx
@@ -10,9 +10,10 @@ import '../../../../../__mocks__/shallow_useeffect.mock';
import { setMockValues, setMockActions } from '../../../../../__mocks__';
import React from 'react';
-import { shallow } from 'enzyme';
import { useParams } from 'react-router-dom';
+import { shallow } from 'enzyme';
+
import { SchemaErrorsAccordion } from '../../../../../shared/schema/schema_errors_accordion';
import { SchemaChangeErrors } from './schema_change_errors';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema_change_errors.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema_change_errors.tsx
index a212052e1beba..29cb2b7589220 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema_change_errors.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema_change_errors.tsx
@@ -14,8 +14,9 @@ import { EuiSpacer } from '@elastic/eui';
import { SchemaErrorsAccordion } from '../../../../../shared/schema/schema_errors_accordion';
import { ViewContentHeader } from '../../../../components/shared/view_content_header';
-import { SchemaLogic } from './schema_logic';
+
import { SCHEMA_ERRORS_HEADING } from './constants';
+import { SchemaLogic } from './schema_logic';
export const SchemaChangeErrors: React.FC = () => {
const { activeReindexJobId, sourceId } = useParams() as {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema_fields_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema_fields_table.test.tsx
index a9d6494dcee00..bc0363d55da69 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema_fields_table.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema_fields_table.test.tsx
@@ -10,6 +10,7 @@ import '../../../../../__mocks__/shallow_useeffect.mock';
import { setMockValues, setMockActions } from '../../../../../__mocks__';
import React from 'react';
+
import { shallow } from 'enzyme';
import { SchemaExistingField } from '../../../../../shared/schema/schema_existing_field';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema_fields_table.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema_fields_table.tsx
index a683d9384f636..3f56a2cfc745b 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema_fields_table.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema_fields_table.tsx
@@ -9,8 +9,6 @@ import React from 'react';
import { useActions, useValues } from 'kea';
-import { i18n } from '@kbn/i18n';
-
import {
EuiFlexGroup,
EuiFlexItem,
@@ -21,13 +19,15 @@ import {
EuiTableRow,
EuiTableRowCell,
} from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
import { SchemaExistingField } from '../../../../../shared/schema/schema_existing_field';
-import { SchemaLogic } from './schema_logic';
+
import {
SCHEMA_ERRORS_TABLE_FIELD_NAME_HEADER,
SCHEMA_ERRORS_TABLE_DATA_TYPE_HEADER,
} from './constants';
+import { SchemaLogic } from './schema_logic';
export const SchemaFieldsTable: React.FC = () => {
const { updateExistingFieldType } = useActions(SchemaLogic);
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema_logic.test.ts
index 5957822eb8d49..28850531ebb94 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema_logic.test.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema_logic.test.ts
@@ -6,6 +6,7 @@
*/
import { LogicMounter, mockFlashMessageHelpers, mockHttpValues } from '../../../../../__mocks__';
+import { mostRecentIndexJob } from '../../../../__mocks__/content_sources.mock';
import { nextTick } from '@kbn/test/jest';
@@ -14,7 +15,6 @@ jest.mock('../../source_logic', () => ({
SourceLogic: { values: { contentSource } },
}));
-import { AppLogic } from '../../../../app_logic';
jest.mock('../../../../app_logic', () => ({
AppLogic: { values: { isOrganization: true } },
}));
@@ -22,21 +22,25 @@ jest.mock('../../../../app_logic', () => ({
const spyScrollTo = jest.fn();
Object.defineProperty(global.window, 'scrollTo', { value: spyScrollTo });
-import { mostRecentIndexJob } from '../../../../__mocks__/content_sources.mock';
import { TEXT } from '../../../../../shared/constants/field_types';
import { ADD, UPDATE } from '../../../../../shared/constants/operations';
+import { AppLogic } from '../../../../app_logic';
import {
SCHEMA_FIELD_ERRORS_ERROR_MESSAGE,
SCHEMA_FIELD_ADDED_MESSAGE,
SCHEMA_UPDATED_MESSAGE,
} from './constants';
-
import { SchemaLogic, dataTypeOptions } from './schema_logic';
describe('SchemaLogic', () => {
const { http } = mockHttpValues;
- const { clearFlashMessages, flashAPIErrors, setSuccessMessage } = mockFlashMessageHelpers;
+ const {
+ clearFlashMessages,
+ flashAPIErrors,
+ setSuccessMessage,
+ setErrorMessage,
+ } = mockFlashMessageHelpers;
const { mount } = new LogicMounter(SchemaLogic);
const defaultValues = {
@@ -299,10 +303,7 @@ describe('SchemaLogic', () => {
);
await nextTick();
- expect(flashAPIErrors).toHaveBeenCalledWith({
- error: 'this is an error',
- message: SCHEMA_FIELD_ERRORS_ERROR_MESSAGE,
- });
+ expect(setErrorMessage).toHaveBeenCalledWith(SCHEMA_FIELD_ERRORS_ERROR_MESSAGE);
});
});
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema_logic.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema_logic.ts
index 09b608af43536..10b7f85a631bc 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema_logic.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/schema/schema_logic.ts
@@ -5,23 +5,21 @@
* 2.0.
*/
-import { cloneDeep, isEqual } from 'lodash';
import { kea, MakeLogicType } from 'kea';
-
-import { HttpLogic } from '../../../../../shared/http';
+import { cloneDeep, isEqual } from 'lodash';
import { TEXT } from '../../../../../shared/constants/field_types';
import { ADD, UPDATE } from '../../../../../shared/constants/operations';
-import { IndexJob, TOperation, Schema, SchemaTypes } from '../../../../../shared/types';
-import { OptionValue } from '../../../../types';
-
import {
flashAPIErrors,
setSuccessMessage,
+ setErrorMessage,
clearFlashMessages,
} from '../../../../../shared/flash_messages';
-
+import { HttpLogic } from '../../../../../shared/http';
+import { IndexJob, TOperation, Schema, SchemaTypes } from '../../../../../shared/types';
import { AppLogic } from '../../../../app_logic';
+import { OptionValue } from '../../../../types';
import { SourceLogic } from '../../source_logic';
import {
@@ -298,7 +296,7 @@ export const SchemaLogic = kea>({
fieldCoercionErrors: response.fieldCoercionErrors,
});
} catch (e) {
- flashAPIErrors({ ...e, message: SCHEMA_FIELD_ERRORS_ERROR_MESSAGE });
+ setErrorMessage(SCHEMA_FIELD_ERRORS_ERROR_MESSAGE);
}
},
addNewField: ({ fieldName, newFieldType }) => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_added.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_added.test.tsx
index d3256a86baebc..ddf89159b2675 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_added.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_added.test.tsx
@@ -10,10 +10,10 @@ import '../../../../__mocks__/shallow_useeffect.mock';
import { setMockActions } from '../../../../__mocks__';
import React from 'react';
-import { shallow } from 'enzyme';
-
import { useLocation } from 'react-router-dom';
+import { shallow } from 'enzyme';
+
import { Loading } from '../../../../shared/loading';
import { SourceAdded } from './source_added';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_added.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_added.tsx
index 5901c06b3f66c..5f1d2ed0c81c3 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_added.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_added.tsx
@@ -6,10 +6,10 @@
*/
import React, { useEffect } from 'react';
+import { useLocation } from 'react-router-dom';
import { Location } from 'history';
import { useActions } from 'kea';
-import { useLocation } from 'react-router-dom';
import { Loading } from '../../../../shared/loading';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_content.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_content.test.tsx
index 6a773b81909a3..12399d4822a13 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_content.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_content.test.tsx
@@ -8,8 +8,11 @@
import '../../../../__mocks__/shallow_useeffect.mock';
import { setMockValues, setMockActions } from '../../../../__mocks__';
+import { fullContentSources, contentItems } from '../../../__mocks__/content_sources.mock';
+import { meta } from '../../../__mocks__/meta.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
import {
@@ -21,12 +24,9 @@ import {
EuiLink,
} from '@elastic/eui';
-import { meta } from '../../../__mocks__/meta.mock';
-import { fullContentSources, contentItems } from '../../../__mocks__/content_sources.mock';
-
import { DEFAULT_META } from '../../../../shared/constants';
+import { Loading } from '../../../../shared/loading';
import { ComponentLoader } from '../../../components/shared/component_loader';
-import { Loading } from '../../../../../applications/shared/loading';
import { TablePaginationBar } from '../../../components/shared/table_pagination_bar';
import { SourceContent } from './source_content';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_content.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_content.tsx
index 61676279ada03..3dd8ad1dc7899 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_content.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_content.tsx
@@ -11,9 +11,6 @@ import { useActions, useValues } from 'kea';
import { startCase } from 'lodash';
import moment from 'moment';
-import { i18n } from '@kbn/i18n';
-import { FormattedMessage } from '@kbn/i18n/react';
-
import {
EuiButton,
EuiButtonEmpty,
@@ -31,20 +28,17 @@ import {
EuiTableRowCell,
EuiLink,
} from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+import { FormattedMessage } from '@kbn/i18n/react';
-import { CUSTOM_SOURCE_DOCS_URL } from '../../../routes';
-import { SourceContentItem } from '../../../types';
-
+import { Loading } from '../../../../shared/loading';
import { TruncatedContent } from '../../../../shared/truncate';
-
-const MAX_LENGTH = 28;
-
import { ComponentLoader } from '../../../components/shared/component_loader';
-import { Loading } from '../../../../../applications/shared/loading';
import { TablePaginationBar } from '../../../components/shared/table_pagination_bar';
import { ViewContentHeader } from '../../../components/shared/view_content_header';
-
import { CUSTOM_SERVICE_TYPE } from '../../../constants';
+import { CUSTOM_SOURCE_DOCS_URL } from '../../../routes';
+import { SourceContentItem } from '../../../types';
import {
NO_CONTENT_MESSAGE,
CUSTOM_DOCUMENTATION_LINK,
@@ -55,9 +49,10 @@ import {
SOURCE_CONTENT_TITLE,
CONTENT_LOADING_TEXT,
} from '../constants';
-
import { SourceLogic } from '../source_logic';
+const MAX_LENGTH = 28;
+
export const SourceContent: React.FC = () => {
const [searchTerm, setSearchTerm] = useState('');
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_info_card.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_info_card.test.tsx
index 7a8a932f391e1..7c4c02cdc9819 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_info_card.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_info_card.test.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiBadge, EuiHealth, EuiText, EuiTitle } from '@elastic/eui';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_info_card.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_info_card.tsx
index 8334c34d6c615..765836191ff00 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_info_card.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_info_card.tsx
@@ -18,7 +18,6 @@ import {
} from '@elastic/eui';
import { SourceIcon } from '../../../components/shared/source_icon';
-
import { REMOTE_SOURCE_LABEL, CREATED_LABEL, STATUS_LABEL, READY_TEXT } from '../constants';
interface SourceInfoCardProps {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_settings.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_settings.test.tsx
index d73da79375ffe..f13189afe8252 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_settings.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_settings.test.tsx
@@ -8,14 +8,14 @@
import '../../../../__mocks__/shallow_useeffect.mock';
import { setMockValues, setMockActions } from '../../../../__mocks__';
+import { fullContentSources, sourceConfigData } from '../../../__mocks__/content_sources.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiConfirmModal } from '@elastic/eui';
-import { fullContentSources, sourceConfigData } from '../../../__mocks__/content_sources.mock';
-
import { SourceConfigFields } from '../../../components/shared/source_config_fields';
import { SourceSettings } from './source_settings';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_settings.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_settings.tsx
index 2fa00c7f029f1..75a1779a1fda8 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_settings.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_settings.tsx
@@ -6,12 +6,10 @@
*/
import React, { useEffect, useState, ChangeEvent, FormEvent } from 'react';
+import { Link } from 'react-router-dom';
import { useActions, useValues } from 'kea';
import { isEmpty } from 'lodash';
-import { Link } from 'react-router-dom';
-
-import { FormattedMessage } from '@kbn/i18n/react';
import {
EuiButton,
@@ -23,7 +21,12 @@ import {
EuiFlexItem,
EuiFormRow,
} from '@elastic/eui';
+import { FormattedMessage } from '@kbn/i18n/react';
+import { AppLogic } from '../../../app_logic';
+import { ContentSection } from '../../../components/shared/content_section';
+import { SourceConfigFields } from '../../../components/shared/source_config_fields';
+import { ViewContentHeader } from '../../../components/shared/view_content_header';
import {
CANCEL_BUTTON,
OK_BUTTON,
@@ -31,6 +34,8 @@ import {
SAVE_CHANGES_BUTTON,
REMOVE_BUTTON,
} from '../../../constants';
+import { SourceDataItem } from '../../../types';
+import { AddSourceLogic } from '../components/add_source/add_source_logic';
import {
SOURCE_SETTINGS_TITLE,
SOURCE_SETTINGS_DESCRIPTION,
@@ -41,16 +46,7 @@ import {
SOURCE_REMOVE_TITLE,
SOURCE_REMOVE_DESCRIPTION,
} from '../constants';
-
-import { ContentSection } from '../../../components/shared/content_section';
-import { SourceConfigFields } from '../../../components/shared/source_config_fields';
-import { ViewContentHeader } from '../../../components/shared/view_content_header';
-
-import { SourceDataItem } from '../../../types';
-import { AppLogic } from '../../../app_logic';
-import { AddSourceLogic } from '../components/add_source/add_source_logic';
import { staticSourceData } from '../source_data';
-
import { SourceLogic } from '../source_logic';
export const SourceSettings: React.FC = () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_sub_nav.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_sub_nav.test.tsx
index fe5545668e4ce..59f3bfb0a5611 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_sub_nav.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_sub_nav.test.tsx
@@ -8,12 +8,13 @@
import { setMockValues } from '../../../../__mocks__';
import React from 'react';
+
import { shallow } from 'enzyme';
+import { SideNavLink } from '../../../../shared/layout';
import { CUSTOM_SERVICE_TYPE } from '../../../constants';
-import { SourceSubNav } from './source_sub_nav';
-import { SideNavLink } from '../../../../shared/layout';
+import { SourceSubNav } from './source_sub_nav';
describe('SourceSubNav', () => {
it('renders empty when no group id present', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_sub_nav.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_sub_nav.tsx
index 739b9ec138f29..99cebd5ded585 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_sub_nav.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_sub_nav.tsx
@@ -6,15 +6,12 @@
*/
import React from 'react';
+
import { useValues } from 'kea';
+import { SideNavLink } from '../../../../shared/layout';
import { AppLogic } from '../../../app_logic';
import { NAV, CUSTOM_SERVICE_TYPE } from '../../../constants';
-
-import { SourceLogic } from '../source_logic';
-
-import { SideNavLink } from '../../../../shared/layout';
-
import {
getContentSourcePath,
SOURCE_DETAILS_PATH,
@@ -23,6 +20,7 @@ import {
SOURCE_DISPLAY_SETTINGS_PATH,
SOURCE_SETTINGS_PATH,
} from '../../../routes';
+import { SourceLogic } from '../source_logic';
export const SourceSubNav: React.FC = () => {
const { isOrganization } = useValues(AppLogic);
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/organization_sources.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/organization_sources.test.tsx
index 68addbacc5a23..b986658f19fb3 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/organization_sources.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/organization_sources.test.tsx
@@ -8,18 +8,16 @@
import '../../../__mocks__/shallow_useeffect.mock';
import { setMockValues, setMockActions } from '../../../__mocks__';
-
-import { shallow } from 'enzyme';
+import { contentSources } from '../../__mocks__/content_sources.mock';
import React from 'react';
import { Redirect } from 'react-router-dom';
-import { contentSources } from '../../__mocks__/content_sources.mock';
+import { shallow } from 'enzyme';
import { Loading } from '../../../shared/loading';
import { SourcesTable } from '../../components/shared/sources_table';
import { ViewContentHeader } from '../../components/shared/view_content_header';
-
import { ADD_SOURCE_PATH, getSourcesPath } from '../../routes';
import { OrganizationSources } from './organization_sources';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/organization_sources.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/organization_sources.tsx
index 24c1f130da50d..4559003b4597f 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/organization_sources.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/organization_sources.tsx
@@ -6,11 +6,16 @@
*/
import React, { useEffect } from 'react';
+import { Link, Redirect } from 'react-router-dom';
import { useActions, useValues } from 'kea';
-import { Link, Redirect } from 'react-router-dom';
import { EuiButton } from '@elastic/eui';
+
+import { Loading } from '../../../shared/loading';
+import { ContentSection } from '../../components/shared/content_section';
+import { SourcesTable } from '../../components/shared/sources_table';
+import { ViewContentHeader } from '../../components/shared/view_content_header';
import { ADD_SOURCE_PATH, getSourcesPath } from '../../routes';
import {
@@ -18,14 +23,7 @@ import {
ORG_SOURCES_HEADER_TITLE,
ORG_SOURCES_HEADER_DESCRIPTION,
} from './constants';
-
-import { Loading } from '../../../shared/loading';
-import { ContentSection } from '../../components/shared/content_section';
-import { SourcesTable } from '../../components/shared/sources_table';
-import { ViewContentHeader } from '../../components/shared/view_content_header';
-
import { SourcesLogic } from './sources_logic';
-
import { SourcesView } from './sources_view';
export const OrganizationSources: React.FC = () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/private_sources.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/private_sources.tsx
index d68b451ffa6f5..087681fa89603 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/private_sources.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/private_sources.tsx
@@ -12,11 +12,15 @@ import { useActions, useValues } from 'kea';
import { EuiCallOut, EuiEmptyPrompt, EuiSpacer, EuiPanel } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import { LicensingLogic } from '../../../../applications/shared/licensing';
-
-import { ADD_SOURCE_PATH, getSourcesPath } from '../../routes';
-
+import { LicensingLogic } from '../../../shared/licensing';
+import { Loading } from '../../../shared/loading';
+import { EuiButtonTo } from '../../../shared/react_router_helpers';
+import { AppLogic } from '../../app_logic';
import noSharedSourcesIcon from '../../assets/share_circle.svg';
+import { ContentSection } from '../../components/shared/content_section';
+import { SourcesTable } from '../../components/shared/sources_table';
+import { ViewContentHeader } from '../../components/shared/view_content_header';
+import { ADD_SOURCE_PATH, getSourcesPath } from '../../routes';
import {
AND,
@@ -34,16 +38,8 @@ import {
LICENSE_CALLOUT_TITLE,
LICENSE_CALLOUT_DESCRIPTION,
} from './constants';
-
-import { Loading } from '../../../shared/loading';
-import { EuiButtonTo } from '../../../shared/react_router_helpers';
-import { ContentSection } from '../../components/shared/content_section';
-import { SourcesTable } from '../../components/shared/sources_table';
-import { ViewContentHeader } from '../../components/shared/view_content_header';
-
-import { AppLogic } from '../../app_logic';
-import { SourcesView } from './sources_view';
import { SourcesLogic } from './sources_logic';
+import { SourcesView } from './sources_view';
// TODO: Remove this after links in Kibana sidenav
interface SidebarLink {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_data.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_data.tsx
index 5b34603bca68f..cdad8e07a88be 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_data.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_data.tsx
@@ -7,6 +7,7 @@
import { i18n } from '@kbn/i18n';
+import { SOURCE_NAMES, SOURCE_OBJ_TYPES, GITHUB_LINK_TITLE } from '../../constants';
import {
ADD_BOX_PATH,
ADD_CONFLUENCE_PATH,
@@ -62,11 +63,8 @@ import {
ZENDESK_DOCS_URL,
CUSTOM_SOURCE_DOCS_URL,
} from '../../routes';
-
import { FeatureIds, SourceDataItem } from '../../types';
-import { SOURCE_NAMES, SOURCE_OBJ_TYPES, GITHUB_LINK_TITLE } from '../../constants';
-
const connectStepDescription = {
attachments: i18n.translate(
'xpack.enterpriseSearch.workplaceSearch.sources.connectStepDescription.attachments',
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.test.ts
index 15df7ddc99395..d20d0576d11ce 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.test.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.test.ts
@@ -12,16 +12,16 @@ import {
mockKibanaValues,
expectedAsyncError,
} from '../../../__mocks__';
+import { fullContentSources, contentItems } from '../../__mocks__/content_sources.mock';
+import { meta } from '../../__mocks__/meta.mock';
+
+import { DEFAULT_META } from '../../../shared/constants';
-import { AppLogic } from '../../app_logic';
jest.mock('../../app_logic', () => ({
AppLogic: { values: { isOrganization: true } },
}));
+import { AppLogic } from '../../app_logic';
-import { fullContentSources, contentItems } from '../../__mocks__/content_sources.mock';
-import { meta } from '../../__mocks__/meta.mock';
-
-import { DEFAULT_META } from '../../../shared/constants';
import { NOT_FOUND_PATH } from '../../routes';
import { SourceLogic } from './source_logic';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts
index c1f5d6033543f..72700ce42c75d 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_logic.ts
@@ -9,17 +9,15 @@ import { kea, MakeLogicType } from 'kea';
import { i18n } from '@kbn/i18n';
-import { HttpLogic } from '../../../shared/http';
-import { KibanaLogic } from '../../../shared/kibana';
-
+import { DEFAULT_META } from '../../../shared/constants';
import {
flashAPIErrors,
setSuccessMessage,
setQueuedSuccessMessage,
clearFlashMessages,
} from '../../../shared/flash_messages';
-
-import { DEFAULT_META } from '../../../shared/constants';
+import { HttpLogic } from '../../../shared/http';
+import { KibanaLogic } from '../../../shared/kibana';
import { AppLogic } from '../../app_logic';
import { NOT_FOUND_PATH, SOURCES_PATH, getSourcesPath } from '../../routes';
import { ContentSourceFullData, Meta, DocumentSummaryItem, SourceContentItem } from '../../types';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_router.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_router.test.tsx
index cf3c075d0c1e9..004f7e5e45bfa 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_router.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_router.test.tsx
@@ -8,20 +8,17 @@
import '../../../__mocks__/shallow_useeffect.mock';
import { setMockValues, setMockActions } from '../../../__mocks__';
+import { contentSources } from '../../__mocks__/content_sources.mock';
import React from 'react';
-import { shallow } from 'enzyme';
import { useParams } from 'react-router-dom';
-
import { Route, Switch } from 'react-router-dom';
-import { contentSources } from '../../__mocks__/content_sources.mock';
+import { shallow } from 'enzyme';
import { SetWorkplaceSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
-
-import { NAV } from '../../constants';
-
import { Loading } from '../../../shared/loading';
+import { NAV } from '../../constants';
import { DisplaySettingsRouter } from './components/display_settings';
import { Overview } from './components/overview';
@@ -29,7 +26,6 @@ import { Schema } from './components/schema';
import { SchemaChangeErrors } from './components/schema/schema_change_errors';
import { SourceContent } from './components/source_content';
import { SourceSettings } from './components/source_settings';
-
import { SourceRouter } from './source_router';
describe('SourceRouter', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_router.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_router.tsx
index ac450441f8783..ef9788efbdaf2 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_router.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/source_router.tsx
@@ -6,24 +6,19 @@
*/
import React, { useEffect } from 'react';
+import { Route, Switch, useParams } from 'react-router-dom';
import { useActions, useValues } from 'kea';
import moment from 'moment';
-import { Route, Switch, useParams } from 'react-router-dom';
import { EuiButton, EuiCallOut, EuiHorizontalRule, EuiSpacer } from '@elastic/eui';
import { SetWorkplaceSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
+import { Loading } from '../../../shared/loading';
import { SendWorkplaceSearchTelemetry as SendTelemetry } from '../../../shared/telemetry';
-
+import { AppLogic } from '../../app_logic';
import { NAV } from '../../constants';
-
-import {
- SOURCE_DISABLED_CALLOUT_TITLE,
- SOURCE_DISABLED_CALLOUT_DESCRIPTION,
- SOURCE_DISABLED_CALLOUT_BUTTON,
-} from './constants';
-
+import { CUSTOM_SERVICE_TYPE } from '../../constants';
import {
ENT_SEARCH_LICENSE_MANAGEMENT,
REINDEX_JOB_PATH,
@@ -36,13 +31,6 @@ import {
getSourcesPath,
} from '../../routes';
-import { AppLogic } from '../../app_logic';
-
-import { Loading } from '../../../shared/loading';
-
-import { CUSTOM_SERVICE_TYPE } from '../../constants';
-import { SourceLogic } from './source_logic';
-
import { DisplaySettingsRouter } from './components/display_settings';
import { Overview } from './components/overview';
import { Schema } from './components/schema';
@@ -50,6 +38,12 @@ import { SchemaChangeErrors } from './components/schema/schema_change_errors';
import { SourceContent } from './components/source_content';
import { SourceInfoCard } from './components/source_info_card';
import { SourceSettings } from './components/source_settings';
+import {
+ SOURCE_DISABLED_CALLOUT_TITLE,
+ SOURCE_DISABLED_CALLOUT_DESCRIPTION,
+ SOURCE_DISABLED_CALLOUT_BUTTON,
+} from './constants';
+import { SourceLogic } from './source_logic';
export const SourceRouter: React.FC = () => {
const { sourceId } = useParams() as { sourceId: string };
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_logic.test.ts
index b7db569eb704c..13844f51b2319 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_logic.test.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_logic.test.ts
@@ -11,13 +11,12 @@ import {
mockHttpValues,
expectedAsyncError,
} from '../../../__mocks__';
+import { configuredSources, contentSources } from '../../__mocks__/content_sources.mock';
-import { AppLogic } from '../../app_logic';
jest.mock('../../app_logic', () => ({
AppLogic: { values: { isOrganization: true } },
}));
-
-import { configuredSources, contentSources } from '../../__mocks__/content_sources.mock';
+import { AppLogic } from '../../app_logic';
import { SourcesLogic, fetchSourceStatuses, POLLING_INTERVAL } from './sources_logic';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_logic.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_logic.ts
index 5108ed45501f7..9de2b447619a6 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_logic.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_logic.ts
@@ -5,22 +5,18 @@
* 2.0.
*/
-import { cloneDeep, findIndex } from 'lodash';
-
import { kea, MakeLogicType } from 'kea';
+import { cloneDeep, findIndex } from 'lodash';
import { i18n } from '@kbn/i18n';
-import { HttpLogic } from '../../../shared/http';
-
import { flashAPIErrors, setQueuedSuccessMessage } from '../../../shared/flash_messages';
-
+import { HttpLogic } from '../../../shared/http';
+import { AppLogic } from '../../app_logic';
import { Connector, ContentSourceDetails, ContentSourceStatus, SourceDataItem } from '../../types';
import { staticSourceData } from './source_data';
-import { AppLogic } from '../../app_logic';
-
interface ServerStatuses {
[key: string]: string;
}
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_router.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_router.test.tsx
index b1a6ea128ac8c..2438061c67759 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_router.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_router.test.tsx
@@ -10,10 +10,10 @@ import '../../../__mocks__/shallow_useeffect.mock';
import { setMockValues, setMockActions } from '../../../__mocks__';
import React from 'react';
-import { shallow } from 'enzyme';
-
import { Route, Switch, Redirect } from 'react-router-dom';
+import { shallow } from 'enzyme';
+
import { ADD_SOURCE_PATH, PERSONAL_SOURCES_PATH, SOURCES_PATH, getSourcesPath } from '../../routes';
import { SourcesRouter } from './sources_router';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_router.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_router.tsx
index 28ad2fe3a3965..b7857cf4612a2 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_router.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_router.tsx
@@ -6,16 +6,16 @@
*/
import React, { useEffect } from 'react';
+import { Redirect, Route, Switch, useLocation } from 'react-router-dom';
import { Location } from 'history';
import { useActions, useValues } from 'kea';
-import { Redirect, Route, Switch, useLocation } from 'react-router-dom';
+import { FlashMessages } from '../../../shared/flash_messages';
import { SetWorkplaceSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
+import { LicensingLogic } from '../../../shared/licensing';
import { SendWorkplaceSearchTelemetry as SendTelemetry } from '../../../shared/telemetry';
-
-import { LicensingLogic } from '../../../../applications/shared/licensing';
-
+import { AppLogic } from '../../app_logic';
import { NAV } from '../../constants';
import {
ADD_SOURCE_PATH,
@@ -26,17 +26,13 @@ import {
getSourcesPath,
} from '../../routes';
-import { FlashMessages } from '../../../shared/flash_messages';
-
-import { AppLogic } from '../../app_logic';
-import { staticSourceData } from './source_data';
-import { SourcesLogic } from './sources_logic';
-
import { AddSource, AddSourceList } from './components/add_source';
import { SourceAdded } from './components/source_added';
import { OrganizationSources } from './organization_sources';
import { PrivateSources } from './private_sources';
+import { staticSourceData } from './source_data';
import { SourceRouter } from './source_router';
+import { SourcesLogic } from './sources_logic';
import './sources.scss';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_view.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_view.test.tsx
index 742d19ebbd156..06d7ecff50299 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_view.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_view.test.tsx
@@ -9,10 +9,10 @@ import '../../../__mocks__/shallow_useeffect.mock';
import { setMockValues, setMockActions } from '../../../__mocks__';
-import { shallow } from 'enzyme';
-
import React from 'react';
+import { shallow } from 'enzyme';
+
import { EuiModal } from '@elastic/eui';
import { Loading } from '../../../shared/loading';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_view.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_view.tsx
index ac70d74cc3d78..c62f0b00258d6 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_view.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_view.tsx
@@ -9,9 +9,6 @@ import React from 'react';
import { useActions, useValues } from 'kea';
-import { i18n } from '@kbn/i18n';
-import { FormattedMessage } from '@kbn/i18n/react';
-
import {
EuiButton,
EuiLink,
@@ -25,10 +22,11 @@ import {
EuiOverlayMask,
EuiText,
} from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+import { FormattedMessage } from '@kbn/i18n/react';
import { Loading } from '../../../shared/loading';
import { SourceIcon } from '../../components/shared/source_icon';
-
import { EXTERNAL_IDENTITIES_DOCS_URL, DOCUMENT_PERMISSIONS_DOCS_URL } from '../../routes';
import {
@@ -36,7 +34,6 @@ import {
DOCUMENT_PERMISSIONS_LINK,
UNDERSTAND_BUTTON,
} from './constants';
-
import { SourcesLogic } from './sources_logic';
interface SourcesViewProps {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/error_state/error_state.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/error_state/error_state.test.tsx
index 0408bbf3e7e84..a8fcdfd7cb257 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/error_state/error_state.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/error_state/error_state.test.tsx
@@ -6,9 +6,11 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { ErrorStatePrompt } from '../../../shared/error_state';
+
import { ErrorState } from './';
describe('ErrorState', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/error_state/error_state.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/error_state/error_state.tsx
index 74e52912b551b..8116d55542820 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/error_state/error_state.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/error_state/error_state.tsx
@@ -8,6 +8,7 @@
// TODO: Remove EuiPage & EuiPageBody before exposing full app
import React from 'react';
+
import { EuiPage, EuiPageBody, EuiPageContent } from '@elastic/eui';
import { WORKPLACE_SEARCH_PLUGIN } from '../../../../../common/constants';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/__mocks__/groups_logic.mock.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/__mocks__/groups_logic.mock.ts
index 3df7fbb5a0596..0e072210d2489 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/__mocks__/groups_logic.mock.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/__mocks__/groups_logic.mock.ts
@@ -5,9 +5,8 @@
* 2.0.
*/
-import { ContentSource, User, Group } from '../../../types';
-
import { DEFAULT_META } from '../../../../shared/constants';
+import { ContentSource, User, Group } from '../../../types';
export const mockGroupsValues = {
groups: [] as Group[],
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/add_group_modal.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/add_group_modal.test.tsx
index 1065c2c2df4c3..26ac5e484f0d7 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/add_group_modal.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/add_group_modal.test.tsx
@@ -8,12 +8,13 @@
import { setMockValues, setMockActions } from '../../../../__mocks__';
import React from 'react';
-import { shallow } from 'enzyme';
-import { AddGroupModal } from './add_group_modal';
+import { shallow } from 'enzyme';
import { EuiModal, EuiOverlayMask } from '@elastic/eui';
+import { AddGroupModal } from './add_group_modal';
+
describe('AddGroupModal', () => {
const closeNewGroupModal = jest.fn();
const saveNewGroup = jest.fn();
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/add_group_modal.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/add_group_modal.tsx
index f49c978d06e90..fb82e9393f2a2 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/add_group_modal.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/add_group_modal.tsx
@@ -8,7 +8,6 @@
import React from 'react';
import { useActions, useValues } from 'kea';
-import { i18n } from '@kbn/i18n';
import {
EuiButton,
@@ -22,9 +21,9 @@ import {
EuiModalHeaderTitle,
EuiOverlayMask,
} from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
import { CANCEL_BUTTON } from '../../../constants';
-
import { GroupsLogic } from '../groups_logic';
const ADD_GROUP_HEADER = i18n.translate(
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/clear_filters_link.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/clear_filters_link.test.tsx
index 2dffe89f38569..9118bc5e7adf3 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/clear_filters_link.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/clear_filters_link.test.tsx
@@ -8,12 +8,13 @@
import { setMockActions } from '../../../../__mocks__';
import React from 'react';
-import { shallow } from 'enzyme';
-import { ClearFiltersLink } from './clear_filters_link';
+import { shallow } from 'enzyme';
import { EuiLink } from '@elastic/eui';
+import { ClearFiltersLink } from './clear_filters_link';
+
describe('ClearFiltersLink', () => {
const resetGroupsFilters = jest.fn();
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/clear_filters_link.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/clear_filters_link.tsx
index 3734148ea3afa..6aeb2241bca61 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/clear_filters_link.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/clear_filters_link.tsx
@@ -8,9 +8,9 @@
import React from 'react';
import { useActions } from 'kea';
-import { i18n } from '@kbn/i18n';
import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiLink } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
import { GroupsLogic } from '../groups_logic';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/filterable_users_list.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/filterable_users_list.test.tsx
index 965a4887f4359..a460070772d1f 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/filterable_users_list.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/filterable_users_list.test.tsx
@@ -8,14 +8,15 @@
import { users } from '../../../__mocks__/users.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiFieldSearch, EuiFilterSelectItem, EuiCard, EuiPopoverTitle } from '@elastic/eui';
-import { FilterableUsersList } from './filterable_users_list';
-
import { User } from '../../../types';
+import { FilterableUsersList } from './filterable_users_list';
+
const mockSetState = jest.fn();
const useStateMock: any = (initState: any) => [initState, mockSetState];
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/filterable_users_list.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/filterable_users_list.tsx
index ef222e934260b..8a7875b5e8310 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/filterable_users_list.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/filterable_users_list.tsx
@@ -7,8 +7,6 @@
import React, { useState } from 'react';
-import { i18n } from '@kbn/i18n';
-
import {
EuiCard,
EuiFieldSearch,
@@ -17,6 +15,7 @@ import {
EuiPopoverTitle,
EuiSpacer,
} from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
import { User } from '../../../types';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/filterable_users_popover.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/filterable_users_popover.test.tsx
index 36a99425c9793..1813b766b9875 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/filterable_users_popover.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/filterable_users_popover.test.tsx
@@ -9,13 +9,14 @@ import { setMockActions } from '../../../../__mocks__';
import { users } from '../../../__mocks__/users.mock';
import React from 'react';
-import { shallow } from 'enzyme';
-import { FilterableUsersPopover } from './filterable_users_popover';
-import { FilterableUsersList } from './filterable_users_list';
+import { shallow } from 'enzyme';
import { EuiFilterGroup, EuiPopover } from '@elastic/eui';
+import { FilterableUsersList } from './filterable_users_list';
+import { FilterableUsersPopover } from './filterable_users_popover';
+
const closePopover = jest.fn();
const addFilteredUser = jest.fn();
const removeFilteredUser = jest.fn();
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/filterable_users_popover.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/filterable_users_popover.tsx
index b47232197c47f..3cf4d97c781d9 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/filterable_users_popover.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/filterable_users_popover.tsx
@@ -12,8 +12,8 @@ import { useActions } from 'kea';
import { EuiFilterGroup, EuiPopover } from '@elastic/eui';
import { User } from '../../../types';
-
import { GroupsLogic } from '../groups_logic';
+
import { FilterableUsersList } from './filterable_users_list';
interface FilterableUsersPopoverProps {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_manager_modal.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_manager_modal.test.tsx
index 8ee14b7c82cc4..949ae9d502e73 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_manager_modal.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_manager_modal.test.tsx
@@ -6,16 +6,17 @@
*/
import { setMockValues } from '../../../../__mocks__';
-import { groups } from '../../../__mocks__/groups.mock';
import { contentSources } from '../../../__mocks__/content_sources.mock';
+import { groups } from '../../../__mocks__/groups.mock';
import React from 'react';
-import { shallow } from 'enzyme';
-import { GroupManagerModal } from './group_manager_modal';
+import { shallow } from 'enzyme';
import { EuiOverlayMask, EuiModal, EuiEmptyPrompt } from '@elastic/eui';
+import { GroupManagerModal } from './group_manager_modal';
+
const hideModal = jest.fn();
const selectAll = jest.fn();
const saveItems = jest.fn();
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_manager_modal.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_manager_modal.tsx
index ae5c042fc27dc..b4317ed9bd417 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_manager_modal.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_manager_modal.tsx
@@ -9,8 +9,6 @@ import React from 'react';
import { useValues } from 'kea';
-import { i18n } from '@kbn/i18n';
-
import {
EuiButton,
EuiButtonEmpty,
@@ -26,15 +24,13 @@ import {
EuiOverlayMask,
EuiSpacer,
} from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
import { EuiButtonTo } from '../../../../shared/react_router_helpers';
-
-import { Group } from '../../../types';
+import noSharedSourcesIcon from '../../../assets/share_circle.svg';
import { CANCEL_BUTTON } from '../../../constants';
import { SOURCES_PATH } from '../../../routes';
-
-import noSharedSourcesIcon from '../../../assets/share_circle.svg';
-
+import { Group } from '../../../types';
import { GroupLogic } from '../group_logic';
import { GroupsLogic } from '../groups_logic';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_overview.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_overview.test.tsx
index ea49ae09f3a25..e39d72a861b6f 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_overview.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_overview.test.tsx
@@ -9,21 +9,22 @@ import { setMockActions, setMockValues } from '../../../../__mocks__';
import { groups } from '../../../__mocks__/groups.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
+import { EuiFieldText } from '@elastic/eui';
+
+import { Loading } from '../../../../shared/loading';
+import { ContentSection } from '../../../components/shared/content_section';
+import { SourcesTable } from '../../../components/shared/sources_table';
+import { ViewContentHeader } from '../../../components/shared/view_content_header';
+
import {
GroupOverview,
EMPTY_SOURCES_DESCRIPTION,
EMPTY_USERS_DESCRIPTION,
} from './group_overview';
-import { ContentSection } from '../../../components/shared/content_section';
-import { ViewContentHeader } from '../../../components/shared/view_content_header';
-import { SourcesTable } from '../../../components/shared/sources_table';
-import { Loading } from '../../../../shared/loading';
-
-import { EuiFieldText } from '@elastic/eui';
-
const deleteGroup = jest.fn();
const showSharedSourcesModal = jest.fn();
const showManageUsersModal = jest.fn();
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_overview.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_overview.tsx
index ca67c2aac98ad..df9c0b5db9b7d 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_overview.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_overview.tsx
@@ -9,8 +9,6 @@ import React from 'react';
import { useActions, useValues } from 'kea';
-import { i18n } from '@kbn/i18n';
-
import {
EuiButton,
EuiConfirmModal,
@@ -22,20 +20,19 @@ import {
EuiSpacer,
EuiHorizontalRule,
} from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
-import { CANCEL_BUTTON } from '../../../constants';
-
-import { AppLogic } from '../../../app_logic';
+import { Loading } from '../../../../shared/loading';
import { TruncatedContent } from '../../../../shared/truncate';
+import { AppLogic } from '../../../app_logic';
import { ContentSection } from '../../../components/shared/content_section';
-import { ViewContentHeader } from '../../../components/shared/view_content_header';
-import { Loading } from '../../../../shared/loading';
import { SourcesTable } from '../../../components/shared/sources_table';
+import { ViewContentHeader } from '../../../components/shared/view_content_header';
+import { CANCEL_BUTTON } from '../../../constants';
+import { GroupLogic, MAX_NAME_LENGTH } from '../group_logic';
import { GroupUsersTable } from './group_users_table';
-import { GroupLogic, MAX_NAME_LENGTH } from '../group_logic';
-
export const EMPTY_SOURCES_DESCRIPTION = i18n.translate(
'xpack.enterpriseSearch.workplaceSearch.groups.overview.emptySourcesDescription',
{
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row.test.tsx
index 19898172fb4e7..205eafd69cd10 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row.test.tsx
@@ -9,14 +9,15 @@ import { setMockValues } from '../../../../__mocks__';
import { groups } from '../../../__mocks__/groups.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
import moment from 'moment';
+import { EuiTableRow } from '@elastic/eui';
+
import { GroupRow, NO_USERS_MESSAGE, NO_SOURCES_MESSAGE } from './group_row';
import { GroupUsers } from './group_users';
-import { EuiTableRow } from '@elastic/eui';
-
describe('GroupRow', () => {
beforeEach(() => {
setMockValues({ isFederatedAuth: true });
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row.tsx
index 1a085aea93cc6..5e89d4491d597 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row.tsx
@@ -6,21 +6,20 @@
*/
import React from 'react';
-import moment from 'moment';
-import { useValues } from 'kea';
-import { i18n } from '@kbn/i18n';
+import { useValues } from 'kea';
+import moment from 'moment';
import { EuiTableRow, EuiTableRowCell, EuiIcon } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
-import { TruncatedContent } from '../../../../shared/truncate';
import { EuiLinkTo } from '../../../../shared/react_router_helpers';
-
-import { Group } from '../../../types';
-
+import { TruncatedContent } from '../../../../shared/truncate';
import { AppLogic } from '../../../app_logic';
import { getGroupPath } from '../../../routes';
+import { Group } from '../../../types';
import { MAX_NAME_LENGTH } from '../group_logic';
+
import { GroupSources } from './group_sources';
import { GroupUsers } from './group_users';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row_sources_dropdown.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row_sources_dropdown.test.tsx
index e4c626a28c1a6..23c00d0fa209e 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row_sources_dropdown.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row_sources_dropdown.test.tsx
@@ -8,13 +8,14 @@
import { contentSources } from '../../../__mocks__/content_sources.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
+import { EuiFilterGroup } from '@elastic/eui';
+
import { GroupRowSourcesDropdown } from './group_row_sources_dropdown';
import { SourceOptionItem } from './source_option_item';
-import { EuiFilterGroup } from '@elastic/eui';
-
const onButtonClick = jest.fn();
const closePopover = jest.fn();
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row_sources_dropdown.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row_sources_dropdown.tsx
index a8f8c18cc6f38..77d7de91caf7c 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row_sources_dropdown.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row_sources_dropdown.tsx
@@ -7,9 +7,8 @@
import React from 'react';
-import { i18n } from '@kbn/i18n';
-
import { EuiFilterGroup, EuiPopover, EuiPopoverTitle, EuiButtonEmpty } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
import { ContentSource } from '../../../types';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row_users_dropdown.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row_users_dropdown.test.tsx
index 7dae74155d0d6..e75b325a4eae9 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row_users_dropdown.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row_users_dropdown.test.tsx
@@ -9,12 +9,13 @@ import { setMockActions, setMockValues } from '../../../../__mocks__';
import { users } from '../../../__mocks__/users.mock';
import React from 'react';
+
import { shallow, mount } from 'enzyme';
import { EuiLoadingContent, EuiButtonEmpty } from '@elastic/eui';
-import { GroupRowUsersDropdown } from './group_row_users_dropdown';
import { FilterableUsersPopover } from './filterable_users_popover';
+import { GroupRowUsersDropdown } from './group_row_users_dropdown';
const fetchGroupUsers = jest.fn();
const onButtonClick = jest.fn();
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row_users_dropdown.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row_users_dropdown.tsx
index 9ca9c8339ba6a..aaf715fc71615 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row_users_dropdown.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row_users_dropdown.tsx
@@ -12,6 +12,7 @@ import { useActions, useValues } from 'kea';
import { EuiLoadingContent, EuiButtonEmpty } from '@elastic/eui';
import { GroupsLogic } from '../groups_logic';
+
import { FilterableUsersPopover } from './filterable_users_popover';
interface GroupRowUsersDropdownProps {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_source_prioritization.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_source_prioritization.test.tsx
index 49305ec33d228..4a9244486bf30 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_source_prioritization.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_source_prioritization.test.tsx
@@ -9,14 +9,15 @@ import { setMockActions, setMockValues } from '../../../../__mocks__';
import { groups } from '../../../__mocks__/groups.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
+import { EuiTable, EuiEmptyPrompt, EuiRange } from '@elastic/eui';
+
import { Loading } from '../../../../shared/loading';
import { GroupSourcePrioritization } from './group_source_prioritization';
-import { EuiTable, EuiEmptyPrompt, EuiRange } from '@elastic/eui';
-
const updatePriority = jest.fn();
const saveGroupSourcePrioritization = jest.fn();
const showSharedSourcesModal = jest.fn();
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_source_prioritization.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_source_prioritization.tsx
index 6907618e40b46..9b131e730b937 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_source_prioritization.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_source_prioritization.tsx
@@ -9,8 +9,6 @@ import React, { ChangeEvent, MouseEvent } from 'react';
import { useActions, useValues } from 'kea';
-import { i18n } from '@kbn/i18n';
-
import {
EuiButton,
EuiEmptyPrompt,
@@ -26,14 +24,13 @@ import {
EuiTableRow,
EuiTableRowCell,
} from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
import { Loading } from '../../../../shared/loading';
-import { ViewContentHeader } from '../../../components/shared/view_content_header';
import { SourceIcon } from '../../../components/shared/source_icon';
-
-import { GroupLogic } from '../group_logic';
-
+import { ViewContentHeader } from '../../../components/shared/view_content_header';
import { ContentSource } from '../../../types';
+import { GroupLogic } from '../group_logic';
const HEADER_TITLE = i18n.translate(
'xpack.enterpriseSearch.workplaceSearch.groups.sourceProioritization.headerTitle',
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_sources.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_sources.test.tsx
index fd2a5e2bc6d9a..a245f0a768b0e 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_sources.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_sources.test.tsx
@@ -8,15 +8,15 @@
import { contentSources } from '../../../__mocks__/content_sources.mock';
import React from 'react';
-import { shallow } from 'enzyme';
-import { GroupSources } from './group_sources';
-import { GroupRowSourcesDropdown } from './group_row_sources_dropdown';
+import { shallow } from 'enzyme';
import { SourceIcon } from '../../../components/shared/source_icon';
-
import { ContentSourceDetails } from '../../../types';
+import { GroupRowSourcesDropdown } from './group_row_sources_dropdown';
+import { GroupSources } from './group_sources';
+
describe('GroupSources', () => {
it('renders', () => {
const wrapper = shallow();
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_sources.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_sources.tsx
index ae3b5000941b1..97739e46caba4 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_sources.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_sources.tsx
@@ -9,7 +9,6 @@ import React, { useState } from 'react';
import { SourceIcon } from '../../../components/shared/source_icon';
import { MAX_TABLE_ROW_ICONS } from '../../../constants';
-
import { ContentSource } from '../../../types';
import { GroupRowSourcesDropdown } from './group_row_sources_dropdown';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_sub_nav.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_sub_nav.test.tsx
index ead4af451ee7a..e4dde81949bfa 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_sub_nav.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_sub_nav.test.tsx
@@ -8,12 +8,13 @@
import { setMockValues } from '../../../../__mocks__';
import React from 'react';
-import { shallow } from 'enzyme';
-import { GroupSubNav } from './group_sub_nav';
+import { shallow } from 'enzyme';
import { SideNavLink } from '../../../../shared/layout';
+import { GroupSubNav } from './group_sub_nav';
+
describe('GroupSubNav', () => {
it('renders empty when no group id present', () => {
setMockValues({ group: {} });
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_sub_nav.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_sub_nav.tsx
index e2bd6e8ae91f2..c5fc0717d1105 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_sub_nav.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_sub_nav.tsx
@@ -6,14 +6,13 @@
*/
import React from 'react';
-import { useValues } from 'kea';
-import { GroupLogic } from '../group_logic';
-import { NAV } from '../../../constants';
+import { useValues } from 'kea';
import { SideNavLink } from '../../../../shared/layout';
-
+import { NAV } from '../../../constants';
import { getGroupPath, getGroupSourcePrioritizationPath } from '../../../routes';
+import { GroupLogic } from '../group_logic';
export const GroupSubNav: React.FC = () => {
const {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_users.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_users.test.tsx
index f1bc063e1a223..eba79ea70177d 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_users.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_users.test.tsx
@@ -8,14 +8,14 @@
import { users } from '../../../__mocks__/users.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
+import { UserIcon } from '../../../components/shared/user_icon';
import { User } from '../../../types';
-import { GroupUsers } from './group_users';
import { GroupRowUsersDropdown } from './group_row_users_dropdown';
-
-import { UserIcon } from '../../../components/shared/user_icon';
+import { GroupUsers } from './group_users';
const props = {
groupUsers: users,
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_users.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_users.tsx
index 850910428c4b2..6e60df15ed30a 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_users.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_users.tsx
@@ -9,7 +9,6 @@ import React, { useState } from 'react';
import { UserIcon } from '../../../components/shared/user_icon';
import { MAX_TABLE_ROW_ICONS } from '../../../constants';
-
import { User } from '../../../types';
import { GroupRowUsersDropdown } from './group_row_users_dropdown';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_users_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_users_table.test.tsx
index 83e945547438f..a6376d7653627 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_users_table.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_users_table.test.tsx
@@ -9,14 +9,15 @@ import { setMockValues } from '../../../../__mocks__';
import { groups } from '../../../__mocks__/groups.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
-import { User } from '../../../types';
+import { EuiTable, EuiTablePagination } from '@elastic/eui';
-import { GroupUsersTable } from './group_users_table';
import { TableHeader } from '../../../../shared/table_header';
+import { User } from '../../../types';
-import { EuiTable, EuiTablePagination } from '@elastic/eui';
+import { GroupUsersTable } from './group_users_table';
const group = groups[0];
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_users_table.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_users_table.tsx
index 4b337fda9143d..5d070b1a21b7d 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_users_table.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_users_table.tsx
@@ -9,17 +9,14 @@ import React, { useState } from 'react';
import { useValues } from 'kea';
-import { i18n } from '@kbn/i18n';
-
import { EuiTable, EuiTableBody, EuiTablePagination } from '@elastic/eui';
import { Pager } from '@elastic/eui';
-
-import { User } from '../../../types';
+import { i18n } from '@kbn/i18n';
import { TableHeader } from '../../../../shared/table_header';
-import { UserRow } from '../../../components/shared/user_row';
-
import { AppLogic } from '../../../app_logic';
+import { UserRow } from '../../../components/shared/user_row';
+import { User } from '../../../types';
import { GroupLogic } from '../group_logic';
const USERS_PER_PAGE = 10;
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/groups_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/groups_table.test.tsx
index d6724499490cf..f60a13ec296d5 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/groups_table.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/groups_table.test.tsx
@@ -8,18 +8,18 @@
import { setMockActions, setMockValues } from '../../../../__mocks__';
import { groups } from '../../../__mocks__/groups.mock';
-import { DEFAULT_META } from '../../../../shared/constants';
-
import React from 'react';
+
import { shallow } from 'enzyme';
+import { EuiTable, EuiTableHeaderCell } from '@elastic/eui';
+
+import { DEFAULT_META } from '../../../../shared/constants';
import { TablePaginationBar } from '../../../components/shared/table_pagination_bar';
-import { GroupsTable } from './groups_table';
-import { GroupRow } from './group_row';
import { ClearFiltersLink } from './clear_filters_link';
-
-import { EuiTable, EuiTableHeaderCell } from '@elastic/eui';
+import { GroupRow } from './group_row';
+import { GroupsTable } from './groups_table';
const setActivePage = jest.fn();
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/groups_table.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/groups_table.tsx
index 31f549c3e2065..95292116cba05 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/groups_table.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/groups_table.tsx
@@ -9,8 +9,6 @@ import React from 'react';
import { useActions, useValues } from 'kea';
-import { i18n } from '@kbn/i18n';
-
import {
EuiSpacer,
EuiTable,
@@ -18,14 +16,14 @@ import {
EuiTableHeader,
EuiTableHeaderCell,
} from '@elastic/eui';
-
-import { TablePaginationBar } from '../../../components/shared/table_pagination_bar';
+import { i18n } from '@kbn/i18n';
import { AppLogic } from '../../../app_logic';
+import { TablePaginationBar } from '../../../components/shared/table_pagination_bar';
import { GroupsLogic } from '../groups_logic';
-import { GroupRow } from './group_row';
import { ClearFiltersLink } from './clear_filters_link';
+import { GroupRow } from './group_row';
const GROUP_TABLE_HEADER = i18n.translate(
'xpack.enterpriseSearch.workplaceSearch.groups.groupsTable.groupTableHeader',
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/manage_users_modal.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/manage_users_modal.test.tsx
index 059dff969aee3..49d51dfc7254c 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/manage_users_modal.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/manage_users_modal.test.tsx
@@ -9,11 +9,12 @@ import { setMockActions, setMockValues } from '../../../../__mocks__';
import { users } from '../../../__mocks__/users.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
-import { ManageUsersModal } from './manage_users_modal';
import { FilterableUsersList } from './filterable_users_list';
import { GroupManagerModal } from './group_manager_modal';
+import { ManageUsersModal } from './manage_users_modal';
const addGroupUser = jest.fn();
const removeGroupUser = jest.fn();
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/shared_sources_modal.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/shared_sources_modal.test.tsx
index f937ded7d4918..dd72850a06ad9 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/shared_sources_modal.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/shared_sources_modal.test.tsx
@@ -9,10 +9,11 @@ import { setMockActions, setMockValues } from '../../../../__mocks__';
import { groups } from '../../../__mocks__/groups.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
-import { SharedSourcesModal } from './shared_sources_modal';
import { GroupManagerModal } from './group_manager_modal';
+import { SharedSourcesModal } from './shared_sources_modal';
import { SourcesList } from './sources_list';
const group = groups[0];
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/source_option_item.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/source_option_item.test.tsx
index d037a49875a7e..bad60e15ed2d0 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/source_option_item.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/source_option_item.test.tsx
@@ -8,14 +8,14 @@
import { contentSources } from '../../../__mocks__/content_sources.mock';
import React from 'react';
-import { shallow } from 'enzyme';
-import { SourceOptionItem } from './source_option_item';
+import { shallow } from 'enzyme';
import { TruncatedContent } from '../../../../shared/truncate';
-
import { SourceIcon } from '../../../components/shared/source_icon';
+import { SourceOptionItem } from './source_option_item';
+
describe('SourceOptionItem', () => {
it('renders', () => {
const wrapper = shallow();
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/source_option_item.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/source_option_item.tsx
index a87980415bd1f..e2da597a83598 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/source_option_item.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/source_option_item.tsx
@@ -10,7 +10,6 @@ import React from 'react';
import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { TruncatedContent } from '../../../../shared/truncate';
-
import { SourceIcon } from '../../../components/shared/source_icon';
import { ContentSource } from '../../../types';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/sources_list.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/sources_list.test.tsx
index 56e700c10e04c..05fe2c92f9f72 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/sources_list.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/sources_list.test.tsx
@@ -8,12 +8,13 @@
import { contentSources } from '../../../__mocks__/content_sources.mock';
import React from 'react';
-import { shallow } from 'enzyme';
-import { SourcesList } from './sources_list';
+import { shallow } from 'enzyme';
import { EuiFilterSelectItem } from '@elastic/eui';
+import { SourcesList } from './sources_list';
+
const addFilteredSource = jest.fn();
const removeFilteredSource = jest.fn();
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filter_sources_dropdown.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filter_sources_dropdown.test.tsx
index b7efe84df180c..1e2a57da9ad2e 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filter_sources_dropdown.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filter_sources_dropdown.test.tsx
@@ -9,11 +9,11 @@ import { setMockActions, setMockValues } from '../../../../__mocks__';
import { contentSources } from '../../../__mocks__/content_sources.mock';
import React from 'react';
-import { shallow } from 'enzyme';
-import { TableFilterSourcesDropdown } from './table_filter_sources_dropdown';
+import { shallow } from 'enzyme';
import { SourcesList } from './sources_list';
+import { TableFilterSourcesDropdown } from './table_filter_sources_dropdown';
const addFilteredSource = jest.fn();
const removeFilteredSource = jest.fn();
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filter_sources_dropdown.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filter_sources_dropdown.tsx
index b38d5fc55b6f8..5f75340d562ef 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filter_sources_dropdown.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filter_sources_dropdown.tsx
@@ -9,11 +9,11 @@ import React from 'react';
import { useActions, useValues } from 'kea';
-import { i18n } from '@kbn/i18n';
-
import { EuiFilterButton, EuiFilterGroup, EuiPopover } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
import { GroupsLogic } from '../groups_logic';
+
import { SourcesList } from './sources_list';
const FILTER_SOURCES_BUTTON_TEXT = i18n.translate(
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filter_users_dropdown.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filter_users_dropdown.test.tsx
index 9eaaa64b1c4e4..e472563862015 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filter_users_dropdown.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filter_users_dropdown.test.tsx
@@ -9,10 +9,11 @@ import { setMockActions, setMockValues } from '../../../../__mocks__';
import { users } from '../../../__mocks__/users.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
-import { TableFilterUsersDropdown } from './table_filter_users_dropdown';
import { FilterableUsersPopover } from './filterable_users_popover';
+import { TableFilterUsersDropdown } from './table_filter_users_dropdown';
const closeFilterUsersDropdown = jest.fn();
const toggleFilterUsersDropdown = jest.fn();
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filter_users_dropdown.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filter_users_dropdown.tsx
index 9ddb955767c14..c09e1e3cf87cc 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filter_users_dropdown.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filter_users_dropdown.tsx
@@ -9,11 +9,11 @@ import React from 'react';
import { useActions, useValues } from 'kea';
-import { i18n } from '@kbn/i18n';
-
import { EuiFilterButton } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
import { GroupsLogic } from '../groups_logic';
+
import { FilterableUsersPopover } from './filterable_users_popover';
const FILTER_USERS_BUTTON_TEXT = i18n.translate(
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filters.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filters.test.tsx
index 0fdaf74376494..bcc58c394b516 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filters.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filters.test.tsx
@@ -8,13 +8,14 @@
import { setMockActions, setMockValues } from '../../../../__mocks__';
import React from 'react';
-import { shallow } from 'enzyme';
-import { TableFilters } from './table_filters';
+import { shallow } from 'enzyme';
import { EuiFieldSearch } from '@elastic/eui';
+
import { TableFilterSourcesDropdown } from './table_filter_sources_dropdown';
import { TableFilterUsersDropdown } from './table_filter_users_dropdown';
+import { TableFilters } from './table_filters';
const setFilterValue = jest.fn();
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filters.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filters.tsx
index cfd40e1a0df4e..e9ea6a7c6b4aa 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filters.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filters.tsx
@@ -9,9 +9,8 @@ import React, { ChangeEvent } from 'react';
import { useActions, useValues } from 'kea';
-import { i18n } from '@kbn/i18n';
-
import { EuiFieldSearch, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
import { AppLogic } from '../../../app_logic';
import { GroupsLogic } from '../groups_logic';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/user_option_item.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/user_option_item.test.tsx
index 01f67cc910afd..6c8dbbde2e69f 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/user_option_item.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/user_option_item.test.tsx
@@ -8,12 +8,14 @@
import { users } from '../../../__mocks__/users.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
-import { UserOptionItem } from './user_option_item';
+import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
+
import { UserIcon } from '../../../components/shared/user_icon';
-import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
+import { UserOptionItem } from './user_option_item';
const user = users[0];
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/group_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/group_logic.test.ts
index d8d41b5e2888a..836efa82995fc 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/group_logic.test.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/group_logic.test.ts
@@ -11,15 +11,15 @@ import {
mockFlashMessageHelpers,
mockHttpValues,
} from '../../../__mocks__';
+import { groups } from '../../__mocks__/groups.mock';
import { nextTick } from '@kbn/test/jest';
-import { groups } from '../../__mocks__/groups.mock';
+import { GROUPS_PATH } from '../../routes';
+
import { mockGroupValues } from './__mocks__/group_logic.mock';
import { GroupLogic } from './group_logic';
-import { GROUPS_PATH } from '../../routes';
-
describe('GroupLogic', () => {
const { mount } = new LogicMounter(GroupLogic);
const { http } = mockHttpValues;
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/group_logic.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/group_logic.ts
index 7e7ce838434f5..f23b182b98649 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/group_logic.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/group_logic.ts
@@ -7,10 +7,9 @@
import { kea, MakeLogicType } from 'kea';
import { isEqual } from 'lodash';
+
import { i18n } from '@kbn/i18n';
-import { HttpLogic } from '../../../shared/http';
-import { KibanaLogic } from '../../../shared/kibana';
import {
clearFlashMessages,
flashAPIErrors,
@@ -18,9 +17,9 @@ import {
setQueuedSuccessMessage,
setQueuedErrorMessage,
} from '../../../shared/flash_messages';
-
+import { HttpLogic } from '../../../shared/http';
+import { KibanaLogic } from '../../../shared/kibana';
import { GROUPS_PATH } from '../../routes';
-
import { ContentSourceDetails, GroupDetails, User, SourcePriority } from '../../types';
export const MAX_NAME_LENGTH = 40;
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/group_router.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/group_router.test.tsx
index a04fc4c744790..0b218f2496154 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/group_router.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/group_router.test.tsx
@@ -7,25 +7,21 @@
import '../../../__mocks__/shallow_useeffect.mock';
import { setMockValues, setMockActions } from '../../../__mocks__';
+import { groups } from '../../__mocks__/groups.mock';
import React from 'react';
-import { shallow } from 'enzyme';
-
import { Route, Switch } from 'react-router-dom';
-import { groups } from '../../__mocks__/groups.mock';
+import { shallow } from 'enzyme';
+import { FlashMessages } from '../../../shared/flash_messages';
import { SetWorkplaceSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
import { GroupOverview } from './components/group_overview';
import { GroupSourcePrioritization } from './components/group_source_prioritization';
-
-import { GroupRouter } from './group_router';
-
-import { FlashMessages } from '../../../shared/flash_messages';
-
import { ManageUsersModal } from './components/manage_users_modal';
import { SharedSourcesModal } from './components/shared_sources_modal';
+import { GroupRouter } from './group_router';
describe('GroupRouter', () => {
const initializeGroup = jest.fn();
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/group_router.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/group_router.tsx
index 82eb7931dfcdc..a5b8bd138d0c8 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/group_router.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/group_router.tsx
@@ -6,23 +6,21 @@
*/
import React, { useEffect } from 'react';
+import { Route, Switch, useParams } from 'react-router-dom';
import { useActions, useValues } from 'kea';
-import { Route, Switch, useParams } from 'react-router-dom';
import { FlashMessages } from '../../../shared/flash_messages';
import { SetWorkplaceSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
import { SendWorkplaceSearchTelemetry as SendTelemetry } from '../../../shared/telemetry';
-
-import { GROUP_SOURCE_PRIORITIZATION_PATH, GROUP_PATH } from '../../routes';
import { NAV } from '../../constants';
-import { GroupLogic } from './group_logic';
-
-import { ManageUsersModal } from './components/manage_users_modal';
-import { SharedSourcesModal } from './components/shared_sources_modal';
+import { GROUP_SOURCE_PRIORITIZATION_PATH, GROUP_PATH } from '../../routes';
import { GroupOverview } from './components/group_overview';
import { GroupSourcePrioritization } from './components/group_source_prioritization';
+import { ManageUsersModal } from './components/manage_users_modal';
+import { SharedSourcesModal } from './components/shared_sources_modal';
+import { GroupLogic } from './group_logic';
export const GroupRouter: React.FC = () => {
const { groupId } = useParams() as { groupId: string };
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups.test.tsx
index d67dd5857561e..8470c5d3e0f66 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups.test.tsx
@@ -11,23 +11,22 @@ import { groups } from '../../__mocks__/groups.mock';
import { meta } from '../../__mocks__/meta.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
-import { Groups } from './groups';
+import { EuiFieldSearch, EuiLoadingSpinner } from '@elastic/eui';
-import { ViewContentHeader } from '../../components/shared/view_content_header';
-import { Loading } from '../../../shared/loading';
+import { DEFAULT_META } from '../../../shared/constants';
import { FlashMessages } from '../../../shared/flash_messages';
+import { Loading } from '../../../shared/loading';
+import { EuiButtonTo } from '../../../shared/react_router_helpers';
+import { ViewContentHeader } from '../../components/shared/view_content_header';
import { AddGroupModal } from './components/add_group_modal';
import { ClearFiltersLink } from './components/clear_filters_link';
import { GroupsTable } from './components/groups_table';
import { TableFilters } from './components/table_filters';
-
-import { DEFAULT_META } from '../../../shared/constants';
-
-import { EuiFieldSearch, EuiLoadingSpinner } from '@elastic/eui';
-import { EuiButtonTo } from '../../../shared/react_router_helpers';
+import { Groups } from './groups';
const getSearchResults = jest.fn();
const openNewGroupModal = jest.fn();
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups.tsx
index 7a8b9343691f9..b2bf0364b2d1f 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups.tsx
@@ -8,26 +8,22 @@
import React, { useEffect } from 'react';
import { useActions, useValues } from 'kea';
-import { i18n } from '@kbn/i18n';
import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiLoadingSpinner, EuiSpacer } from '@elastic/eui';
-import { EuiButtonTo } from '../../../shared/react_router_helpers';
-
-import { AppLogic } from '../../app_logic';
+import { i18n } from '@kbn/i18n';
+import { FlashMessages, FlashMessagesLogic } from '../../../shared/flash_messages';
import { Loading } from '../../../shared/loading';
+import { EuiButtonTo } from '../../../shared/react_router_helpers';
+import { AppLogic } from '../../app_logic';
import { ViewContentHeader } from '../../components/shared/view_content_header';
-
import { getGroupPath, USERS_PATH } from '../../routes';
-import { FlashMessages, FlashMessagesLogic } from '../../../shared/flash_messages';
-
-import { GroupsLogic } from './groups_logic';
-
import { AddGroupModal } from './components/add_group_modal';
import { ClearFiltersLink } from './components/clear_filters_link';
import { GroupsTable } from './components/groups_table';
import { TableFilters } from './components/table_filters';
+import { GroupsLogic } from './groups_logic';
export const Groups: React.FC = () => {
const { messages } = useValues(FlashMessagesLogic);
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_logic.test.ts
index 26d7f9784cc6e..806c6e1c69f84 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_logic.test.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_logic.test.ts
@@ -6,15 +6,15 @@
*/
import { LogicMounter, mockFlashMessageHelpers, mockHttpValues } from '../../../__mocks__';
+import { contentSources } from '../../__mocks__/content_sources.mock';
+import { groups } from '../../__mocks__/groups.mock';
+import { users } from '../../__mocks__/users.mock';
import { nextTick } from '@kbn/test/jest';
-import { DEFAULT_META } from '../../../shared/constants';
import { JSON_HEADER as headers } from '../../../../../common/constants';
+import { DEFAULT_META } from '../../../shared/constants';
-import { groups } from '../../__mocks__/groups.mock';
-import { contentSources } from '../../__mocks__/content_sources.mock';
-import { users } from '../../__mocks__/users.mock';
import { mockGroupsValues } from './__mocks__/groups_logic.mock';
import { GroupsLogic } from './groups_logic';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_logic.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_logic.ts
index 68a6eb7bdf344..a036cdda3d68e 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_logic.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_logic.ts
@@ -6,22 +6,20 @@
*/
import { kea, MakeLogicType } from 'kea';
-import { i18n } from '@kbn/i18n';
-import { HttpLogic } from '../../../shared/http';
+import { i18n } from '@kbn/i18n';
+import { JSON_HEADER as headers } from '../../../../../common/constants';
+import { Meta } from '../../../../../common/types';
+import { DEFAULT_META } from '../../../shared/constants';
import {
clearFlashMessages,
flashAPIErrors,
setSuccessMessage,
} from '../../../shared/flash_messages';
-
+import { HttpLogic } from '../../../shared/http';
import { ContentSource, Group, User } from '../../types';
-import { JSON_HEADER as headers } from '../../../../../common/constants';
-import { DEFAULT_META } from '../../../shared/constants';
-import { Meta } from '../../../../../common/types';
-
export const MAX_NAME_LENGTH = 40;
interface GroupsServerData {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_router.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_router.test.tsx
index 43c31038a45c6..0295605eddd4d 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_router.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_router.test.tsx
@@ -9,14 +9,13 @@ import '../../../__mocks__/shallow_useeffect.mock';
import { setMockActions } from '../../../__mocks__';
import React from 'react';
-import { shallow } from 'enzyme';
-
import { Route, Switch } from 'react-router-dom';
-import { GroupsRouter } from './groups_router';
+import { shallow } from 'enzyme';
import { GroupRouter } from './group_router';
import { Groups } from './groups';
+import { GroupsRouter } from './groups_router';
describe('GroupsRouter', () => {
const initializeGroups = jest.fn();
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_router.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_router.tsx
index e835a2668f3d3..d8c4f4801ba24 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_router.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_router.tsx
@@ -6,21 +6,18 @@
*/
import React, { useEffect } from 'react';
+import { Route, Switch } from 'react-router-dom';
import { useActions } from 'kea';
-import { Route, Switch } from 'react-router-dom';
-
import { SetWorkplaceSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
import { SendWorkplaceSearchTelemetry as SendTelemetry } from '../../../shared/telemetry';
-
-import { GROUP_PATH, GROUPS_PATH } from '../../routes';
import { NAV } from '../../constants';
-
-import { GroupsLogic } from './groups_logic';
+import { GROUP_PATH, GROUPS_PATH } from '../../routes';
import { GroupRouter } from './group_router';
import { Groups } from './groups';
+import { GroupsLogic } from './groups_logic';
import './groups.scss';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/__mocks__/overview_logic.mock.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/__mocks__/overview_logic.mock.ts
index f03dcfe98ddd0..787354974cb31 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/__mocks__/overview_logic.mock.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/__mocks__/overview_logic.mock.ts
@@ -5,8 +5,8 @@
* 2.0.
*/
-import { setMockValues as setMockKeaValues, setMockActions } from '../../../../__mocks__/kea.mock';
import { DEFAULT_INITIAL_APP_DATA } from '../../../../../../common/__mocks__';
+import { setMockValues as setMockKeaValues, setMockActions } from '../../../../__mocks__/kea.mock';
const { workplaceSearch: mockAppValues } = DEFAULT_INITIAL_APP_DATA;
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_card.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_card.test.tsx
index 8f962ec4cf665..68dece976a09c 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_card.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_card.test.tsx
@@ -10,6 +10,7 @@ import '../../../__mocks__/enterprise_search_url.mock';
import { mockTelemetryActions } from '../../../__mocks__';
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiEmptyPrompt, EuiButton, EuiButtonEmpty } from '@elastic/eui';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_card.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_card.tsx
index 68a4c4dc10f4f..2f8d06b71fc27 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_card.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_card.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { useActions } from 'kea';
import {
@@ -20,8 +21,8 @@ import {
EuiLinkProps,
} from '@elastic/eui';
-import { TelemetryLogic } from '../../../shared/telemetry';
import { getWorkplaceSearchUrl } from '../../../shared/enterprise_search_url';
+import { TelemetryLogic } from '../../../shared/telemetry';
interface OnboardingCardProps {
title: React.ReactNode;
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_steps.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_steps.test.tsx
index 7f676ce2faac2..7a368e7d384ea 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_steps.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_steps.test.tsx
@@ -6,16 +6,18 @@
*/
import { mockTelemetryActions } from '../../../__mocks__';
+
import './__mocks__/overview_logic.mock';
-import { setMockValues } from './__mocks__';
import React from 'react';
+
import { shallow } from 'enzyme';
import { SOURCES_PATH, USERS_PATH } from '../../routes';
-import { OnboardingSteps, OrgNameOnboarding } from './onboarding_steps';
+import { setMockValues } from './__mocks__';
import { OnboardingCard } from './onboarding_card';
+import { OnboardingSteps, OrgNameOnboarding } from './onboarding_steps';
const account = {
id: '1',
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_steps.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_steps.tsx
index ae30a52c1541c..fc3998fcdfeec 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_steps.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_steps.tsx
@@ -6,8 +6,7 @@
*/
import React from 'react';
-import { i18n } from '@kbn/i18n';
-import { FormattedMessage } from '@kbn/i18n/react';
+
import { useValues, useActions } from 'kea';
import {
@@ -22,17 +21,18 @@ import {
EuiButtonEmptyProps,
EuiLinkProps,
} from '@elastic/eui';
-import sharedSourcesIcon from '../../components/shared/assets/source_icons/share_circle.svg';
-import { TelemetryLogic } from '../../../shared/telemetry';
-import { getWorkplaceSearchUrl } from '../../../shared/enterprise_search_url';
-import { SOURCES_PATH, USERS_PATH, ORG_SETTINGS_PATH } from '../../routes';
-
-import { ContentSection } from '../../components/shared/content_section';
+import { i18n } from '@kbn/i18n';
+import { FormattedMessage } from '@kbn/i18n/react';
+import { getWorkplaceSearchUrl } from '../../../shared/enterprise_search_url';
+import { TelemetryLogic } from '../../../shared/telemetry';
import { AppLogic } from '../../app_logic';
-import { OverviewLogic } from './overview_logic';
+import sharedSourcesIcon from '../../components/shared/assets/source_icons/share_circle.svg';
+import { ContentSection } from '../../components/shared/content_section';
+import { SOURCES_PATH, USERS_PATH, ORG_SETTINGS_PATH } from '../../routes';
import { OnboardingCard } from './onboarding_card';
+import { OverviewLogic } from './overview_logic';
const SOURCES_TITLE = i18n.translate(
'xpack.enterpriseSearch.workplaceSearch.overviewOnboardingSourcesCard.title',
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/organization_stats.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/organization_stats.test.tsx
index cf4f96f6b788b..412977f18fadf 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/organization_stats.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/organization_stats.test.tsx
@@ -6,12 +6,14 @@
*/
import './__mocks__/overview_logic.mock';
-import { setMockValues } from './__mocks__';
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiFlexGrid } from '@elastic/eui';
+import { setMockValues } from './__mocks__';
import { OrganizationStats } from './organization_stats';
import { StatisticCard } from './statistic_card';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/organization_stats.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/organization_stats.tsx
index 52c370caac989..525035030b8cc 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/organization_stats.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/organization_stats.tsx
@@ -6,18 +6,18 @@
*/
import React from 'react';
-import { EuiFlexGrid } from '@elastic/eui';
+
import { useValues } from 'kea';
-import { FormattedMessage } from '@kbn/i18n/react';
+import { EuiFlexGrid } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
+import { FormattedMessage } from '@kbn/i18n/react';
+import { AppLogic } from '../../app_logic';
import { ContentSection } from '../../components/shared/content_section';
import { SOURCES_PATH, USERS_PATH } from '../../routes';
-import { AppLogic } from '../../app_logic';
import { OverviewLogic } from './overview_logic';
-
import { StatisticCard } from './statistic_card';
export const OrganizationStats: React.FC = () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/overview.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/overview.test.tsx
index fc70a07e339e4..2ec2d949ff491 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/overview.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/overview.test.tsx
@@ -7,18 +7,19 @@
import '../../../__mocks__/react_router_history.mock';
import './__mocks__/overview_logic.mock';
-import { mockActions, setMockValues } from './__mocks__';
import React from 'react';
+
import { shallow, mount } from 'enzyme';
import { Loading } from '../../../shared/loading';
import { ViewContentHeader } from '../../components/shared/view_content_header';
+import { mockActions, setMockValues } from './__mocks__';
import { OnboardingSteps } from './onboarding_steps';
import { OrganizationStats } from './organization_stats';
-import { RecentActivity } from './recent_activity';
import { Overview } from './overview';
+import { RecentActivity } from './recent_activity';
describe('Overview', () => {
describe('non-happy-path states', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/overview.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/overview.tsx
index 07bc999922661..6bf84b585da80 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/overview.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/overview.tsx
@@ -8,22 +8,22 @@
// TODO: Remove EuiPage & EuiPageBody before exposing full app
import React, { useEffect } from 'react';
+
+import { useActions, useValues } from 'kea';
+
import { EuiPage, EuiPageBody, EuiSpacer } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import { useActions, useValues } from 'kea';
import { SetWorkplaceSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
+import { Loading } from '../../../shared/loading';
import { SendWorkplaceSearchTelemetry as SendTelemetry } from '../../../shared/telemetry';
-
import { AppLogic } from '../../app_logic';
-import { OverviewLogic } from './overview_logic';
-
-import { Loading } from '../../../shared/loading';
import { ProductButton } from '../../components/shared/product_button';
import { ViewContentHeader } from '../../components/shared/view_content_header';
import { OnboardingSteps } from './onboarding_steps';
import { OrganizationStats } from './organization_stats';
+import { OverviewLogic } from './overview_logic';
import { RecentActivity } from './recent_activity';
const ONBOARDING_HEADER_TITLE = i18n.translate(
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/overview_logic.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/overview_logic.ts
index 6d0beb638cd52..75513cfba3a09 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/overview_logic.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/overview_logic.ts
@@ -6,6 +6,7 @@
*/
import { kea, MakeLogicType } from 'kea';
+
import { HttpLogic } from '../../../shared/http';
import { FeedActivity } from './recent_activity';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/recent_activity.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/recent_activity.test.tsx
index 9c571bd8bc169..0b62207afc520 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/recent_activity.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/recent_activity.test.tsx
@@ -6,15 +6,17 @@
*/
import { mockTelemetryActions } from '../../../__mocks__';
+
import './__mocks__/overview_logic.mock';
-import { setMockValues } from './__mocks__';
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiEmptyPrompt, EuiLink } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
+import { setMockValues } from './__mocks__';
import { RecentActivity, RecentActivityItem } from './recent_activity';
const organization = { name: 'foo', defaultOrgName: 'bar' };
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/recent_activity.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/recent_activity.tsx
index 1dcec989a94c7..43d3f880feef4 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/recent_activity.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/recent_activity.tsx
@@ -7,19 +7,19 @@
import React from 'react';
-import moment from 'moment';
import { useValues, useActions } from 'kea';
+import moment from 'moment';
import { EuiEmptyPrompt, EuiLink, EuiPanel, EuiSpacer, EuiLinkProps } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
-import { ContentSection } from '../../components/shared/content_section';
-import { TelemetryLogic } from '../../../shared/telemetry';
import { getWorkplaceSearchUrl } from '../../../shared/enterprise_search_url';
-import { SOURCE_DETAILS_PATH, getContentSourcePath } from '../../routes';
+import { TelemetryLogic } from '../../../shared/telemetry';
+import { AppLogic } from '../../app_logic';
+import { ContentSection } from '../../components/shared/content_section';
import { RECENT_ACTIVITY_TITLE } from '../../constants';
+import { SOURCE_DETAILS_PATH, getContentSourcePath } from '../../routes';
-import { AppLogic } from '../../app_logic';
import { OverviewLogic } from './overview_logic';
import './recent_activity.scss';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/statistic_card.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/statistic_card.test.tsx
index 2893c3630393e..ff1d69e406830 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/statistic_card.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/statistic_card.test.tsx
@@ -8,6 +8,7 @@
import '../../../__mocks__/enterprise_search_url.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiCard } from '@elastic/eui';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/statistic_card.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/statistic_card.tsx
index 83e6c2012a046..346debb1c5251 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/statistic_card.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/statistic_card.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { EuiCard, EuiFlexItem, EuiTitle, EuiTextColor } from '@elastic/eui';
import { getWorkplaceSearchUrl } from '../../../shared/enterprise_search_url';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/components/private_sources_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/components/private_sources_table.test.tsx
index fb28fba9b3aea..4f7160ba631f1 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/components/private_sources_table.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/components/private_sources_table.test.tsx
@@ -8,7 +8,9 @@
import { setMockValues } from '../../../../__mocks__';
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiSwitch } from '@elastic/eui';
import { PrivateSourcesTable } from './private_sources_table';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/components/private_sources_table.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/components/private_sources_table.tsx
index 8ba29e5986e04..559b2fe3edbd1 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/components/private_sources_table.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/components/private_sources_table.tsx
@@ -24,11 +24,10 @@ import {
EuiTableRowCell,
EuiSpacer,
} from '@elastic/eui';
-import { FormattedMessage } from '@kbn/i18n/react';
import { i18n } from '@kbn/i18n';
+import { FormattedMessage } from '@kbn/i18n/react';
import { LicensingLogic } from '../../../../shared/licensing';
-import { SecurityLogic, PrivateSourceSection } from '../security_logic';
import {
REMOTE_SOURCES_TOGGLE_TEXT,
REMOTE_SOURCES_TABLE_DESCRIPTION,
@@ -38,6 +37,7 @@ import {
STANDARD_SOURCES_EMPTY_TABLE_TITLE,
SOURCE,
} from '../../../constants';
+import { SecurityLogic, PrivateSourceSection } from '../security_logic';
interface PrivateSourcesTableProps {
sourceType: 'remote' | 'standard';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/security.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/security.test.tsx
index 24e6e5808355a..4eed6a6fefe68 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/security.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/security.test.tsx
@@ -9,11 +9,14 @@ import { setMockValues, setMockActions } from '../../../__mocks__';
import { unmountHandler } from '../../../__mocks__/shallow_useeffect.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
+
import { EuiSwitch, EuiConfirmModal } from '@elastic/eui';
-import { Loading } from '../../../shared/loading';
+import { Loading } from '../../../shared/loading';
import { ViewContentHeader } from '../../components/shared/view_content_header';
+
import { Security } from './security';
describe('Security', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/security.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/security.tsx
index 818dd34447c73..ba1ffb66f4691 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/security.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/security.tsx
@@ -23,15 +23,11 @@ import {
EuiOverlayMask,
} from '@elastic/eui';
-import { LicensingLogic } from '../../../shared/licensing';
import { FlashMessages } from '../../../shared/flash_messages';
-import { LicenseCallout } from '../../components/shared/license_callout';
+import { LicensingLogic } from '../../../shared/licensing';
import { Loading } from '../../../shared/loading';
+import { LicenseCallout } from '../../components/shared/license_callout';
import { ViewContentHeader } from '../../components/shared/view_content_header';
-import { SecurityLogic } from './security_logic';
-
-import { PrivateSourcesTable } from './components/private_sources_table';
-
import {
SECURITY_UNSAVED_CHANGES_MESSAGE,
RESET_BUTTON,
@@ -46,6 +42,9 @@ import {
PRIVATE_SOURCES_UPDATE_CONFIRMATION_TEXT,
} from '../../constants';
+import { PrivateSourcesTable } from './components/private_sources_table';
+import { SecurityLogic } from './security_logic';
+
export const Security: React.FC = () => {
const [confirmModalVisible, setConfirmModalVisibility] = useState(false);
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/security_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/security_logic.test.ts
index c2bd1be390592..02d8fdd3c30e4 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/security_logic.test.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/security_logic.test.ts
@@ -5,11 +5,13 @@
* 2.0.
*/
-import { LogicMounter } from '../../../__mocks__/kea.mock';
import { mockHttpValues, mockFlashMessageHelpers } from '../../../__mocks__';
-import { SecurityLogic } from './security_logic';
+import { LogicMounter } from '../../../__mocks__/kea.mock';
+
import { nextTick } from '@kbn/test/jest';
+import { SecurityLogic } from './security_logic';
+
describe('SecurityLogic', () => {
const { http } = mockHttpValues;
const { flashAPIErrors } = mockFlashMessageHelpers;
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/security_logic.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/security_logic.ts
index 8689cec037848..07ebec41366b2 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/security_logic.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/security/security_logic.ts
@@ -5,11 +5,10 @@
* 2.0.
*/
+import { kea, MakeLogicType } from 'kea';
import { cloneDeep } from 'lodash';
import { isEqual } from 'lodash';
-import { kea, MakeLogicType } from 'kea';
-
import {
clearFlashMessages,
setSuccessMessage,
@@ -17,7 +16,6 @@ import {
} from '../../../shared/flash_messages';
import { HttpLogic } from '../../../shared/http';
import { AppLogic } from '../../app_logic';
-
import { SOURCE_RESTRICTIONS_SUCCESS_MESSAGE } from '../../constants';
export interface PrivateSource {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/connectors.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/connectors.test.tsx
index d1dd9e64c4d2d..13ef86a21a208 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/connectors.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/connectors.test.tsx
@@ -8,10 +8,10 @@
import '../../../../__mocks__/shallow_useeffect.mock';
import { setMockValues, setMockActions } from '../../../../__mocks__';
-
import { configuredSources } from '../../../__mocks__/content_sources.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
import { Loading } from '../../../../shared/loading';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/connectors.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/connectors.tsx
index 5b74f6d1d2806..9387cd4602255 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/connectors.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/connectors.tsx
@@ -19,12 +19,11 @@ import {
EuiSpacer,
} from '@elastic/eui';
-import { EuiButtonEmptyTo } from '../../../../shared/react_router_helpers';
import { Loading } from '../../../../shared/loading';
-import { SourceIcon } from '../../../components/shared/source_icon';
+import { EuiButtonEmptyTo } from '../../../../shared/react_router_helpers';
import { LicenseCallout } from '../../../components/shared/license_callout';
+import { SourceIcon } from '../../../components/shared/source_icon';
import { ViewContentHeader } from '../../../components/shared/view_content_header';
-
import {
CONFIGURE_BUTTON,
CONNECTORS_HEADER_TITLE,
@@ -36,9 +35,7 @@ import {
} from '../../../constants';
import { getSourcesPath } from '../../../routes';
import { SourceDataItem } from '../../../types';
-
import { staticSourceData } from '../../content_sources/source_data';
-
import { SettingsLogic } from '../settings_logic';
export const Connectors: React.FC = () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/customize.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/customize.test.tsx
index 8f77c229ad6f8..ed05829d9e082 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/customize.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/customize.test.tsx
@@ -10,6 +10,7 @@ import '../../../../__mocks__/shallow_useeffect.mock';
import { setMockValues, setMockActions } from '../../../../__mocks__';
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiFieldText } from '@elastic/eui';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/customize.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/customize.tsx
index d57621bd397db..37f9e288f7f3d 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/customize.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/customize.tsx
@@ -11,16 +11,14 @@ import { useActions, useValues } from 'kea';
import { EuiButton, EuiFieldText, EuiFlexGroup, EuiFlexItem, EuiFormRow } from '@elastic/eui';
+import { ContentSection } from '../../../components/shared/content_section';
+import { ViewContentHeader } from '../../../components/shared/view_content_header';
import {
CUSTOMIZE_HEADER_TITLE,
CUSTOMIZE_HEADER_DESCRIPTION,
CUSTOMIZE_NAME_LABEL,
CUSTOMIZE_NAME_BUTTON,
} from '../../../constants';
-
-import { ContentSection } from '../../../components/shared/content_section';
-import { ViewContentHeader } from '../../../components/shared/view_content_header';
-
import { SettingsLogic } from '../settings_logic';
export const Customize: React.FC = () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/oauth_application.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/oauth_application.test.tsx
index 6fc9d51f42a86..55a58610e0ed6 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/oauth_application.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/oauth_application.test.tsx
@@ -8,17 +8,18 @@
import '../../../../__mocks__/shallow_useeffect.mock';
import { setMockValues, setMockActions } from '../../../../__mocks__';
+import { oauthApplication } from '../../../__mocks__/content_sources.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiModal, EuiForm } from '@elastic/eui';
-import { oauthApplication } from '../../../__mocks__/content_sources.mock';
-import { OAUTH_DESCRIPTION, REDIRECT_INSECURE_ERROR_TEXT } from '../../../constants';
-
import { CredentialItem } from '../../../components/shared/credential_item';
import { ViewContentHeader } from '../../../components/shared/view_content_header';
+import { OAUTH_DESCRIPTION, REDIRECT_INSECURE_ERROR_TEXT } from '../../../constants';
+
import { OauthApplication } from './oauth_application';
describe('OauthApplication', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/oauth_application.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/oauth_application.tsx
index 04759e4f5fdd0..28e7e2a33eaa1 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/oauth_application.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/oauth_application.tsx
@@ -26,7 +26,11 @@ import {
EuiText,
} from '@elastic/eui';
-import { ENT_SEARCH_LICENSE_MANAGEMENT } from '../../../routes';
+import { LicensingLogic } from '../../../../shared/licensing';
+import { ContentSection } from '../../../components/shared/content_section';
+import { CredentialItem } from '../../../components/shared/credential_item';
+import { LicenseBadge } from '../../../components/shared/license_badge';
+import { ViewContentHeader } from '../../../components/shared/view_content_header';
import {
CLIENT_ID_LABEL,
CLIENT_SECRET_LABEL,
@@ -48,12 +52,7 @@ import {
LICENSE_MODAL_DESCRIPTION,
LICENSE_MODAL_LINK,
} from '../../../constants';
-
-import { LicensingLogic } from '../../../../shared/licensing';
-import { ContentSection } from '../../../components/shared/content_section';
-import { LicenseBadge } from '../../../components/shared/license_badge';
-import { ViewContentHeader } from '../../../components/shared/view_content_header';
-import { CredentialItem } from '../../../components/shared/credential_item';
+import { ENT_SEARCH_LICENSE_MANAGEMENT } from '../../../routes';
import { SettingsLogic } from '../settings_logic';
export const OauthApplication: React.FC = () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/settings_sub_nav.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/settings_sub_nav.test.tsx
index f00bb7d897e25..5cd8a3fc1cf03 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/settings_sub_nav.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/settings_sub_nav.test.tsx
@@ -6,6 +6,7 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { SideNavLink } from '../../../../shared/layout';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/settings_sub_nav.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/settings_sub_nav.tsx
index 20a6e349c1272..3f68997a17b8b 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/settings_sub_nav.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/settings_sub_nav.tsx
@@ -7,10 +7,8 @@
import React from 'react';
-import { NAV } from '../../../constants';
-
import { SideNavLink } from '../../../../shared/layout';
-
+import { NAV } from '../../../constants';
import {
ORG_SETTINGS_CUSTOMIZE_PATH,
ORG_SETTINGS_CONNECTORS_PATH,
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/source_config.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/source_config.test.tsx
index 73ea92117c6df..ed9f715fd6916 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/source_config.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/source_config.test.tsx
@@ -8,16 +8,17 @@
import '../../../../__mocks__/shallow_useeffect.mock';
import { setMockValues, setMockActions } from '../../../../__mocks__';
+import { sourceConfigData } from '../../../__mocks__/content_sources.mock';
import React from 'react';
+
import { shallow } from 'enzyme';
import { EuiConfirmModal } from '@elastic/eui';
-import { sourceConfigData } from '../../../__mocks__/content_sources.mock';
-
import { Loading } from '../../../../shared/loading';
import { SaveConfig } from '../../content_sources/components/add_source/save_config';
+
import { SourceConfig } from './source_config';
describe('SourceConfig', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/source_config.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/source_config.tsx
index 4b59e0f3401c5..4ed223931d6a4 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/source_config.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/source_config.tsx
@@ -8,18 +8,16 @@
import React, { useEffect, useState } from 'react';
import { useActions, useValues } from 'kea';
-import { i18n } from '@kbn/i18n';
import { EuiConfirmModal, EuiOverlayMask } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
import { Loading } from '../../../../shared/loading';
import { SourceDataItem } from '../../../types';
-import { staticSourceData } from '../../content_sources/source_data';
-import { AddSourceLogic } from '../../content_sources/components/add_source/add_source_logic';
-
import { AddSourceHeader } from '../../content_sources/components/add_source/add_source_header';
+import { AddSourceLogic } from '../../content_sources/components/add_source/add_source_logic';
import { SaveConfig } from '../../content_sources/components/add_source/save_config';
-
+import { staticSourceData } from '../../content_sources/source_data';
import { SettingsLogic } from '../settings_logic';
interface SourceConfigProps {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/settings_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/settings_logic.test.ts
index b8b08b8658372..a57c2c1f9ad44 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/settings_logic.test.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/settings_logic.test.ts
@@ -5,15 +5,14 @@
* 2.0.
*/
-import { LogicMounter } from '../../../__mocks__/kea.mock';
-
import { mockFlashMessageHelpers, mockHttpValues, mockKibanaValues } from '../../../__mocks__';
+import { LogicMounter } from '../../../__mocks__/kea.mock';
+import { configuredSources, oauthApplication } from '../../__mocks__/content_sources.mock';
import { nextTick } from '@kbn/test/jest';
-import { configuredSources, oauthApplication } from '../../__mocks__/content_sources.mock';
-
import { ORG_UPDATED_MESSAGE, OAUTH_APP_UPDATED_MESSAGE } from '../../constants';
+
import { SettingsLogic } from './settings_logic';
describe('SettingsLogic', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/settings_logic.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/settings_logic.ts
index 5a4f366c737d5..ad552ff8f5a41 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/settings_logic.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/settings_logic.ts
@@ -6,6 +6,7 @@
*/
import { kea, MakeLogicType } from 'kea';
+
import { i18n } from '@kbn/i18n';
import {
@@ -14,13 +15,11 @@ import {
setSuccessMessage,
flashAPIErrors,
} from '../../../shared/flash_messages';
-import { KibanaLogic } from '../../../shared/kibana';
import { HttpLogic } from '../../../shared/http';
-
-import { Connector } from '../../types';
+import { KibanaLogic } from '../../../shared/kibana';
import { ORG_UPDATED_MESSAGE, OAUTH_APP_UPDATED_MESSAGE } from '../../constants';
-
import { ORG_SETTINGS_CONNECTORS_PATH } from '../../routes';
+import { Connector } from '../../types';
interface IOauthApplication {
name: string;
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/settings_router.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/settings_router.test.tsx
index 7f3ba0a8f34b3..411414fb33eaf 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/settings_router.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/settings_router.test.tsx
@@ -10,19 +10,17 @@ import '../../../__mocks__/shallow_useeffect.mock';
import { setMockActions } from '../../../__mocks__';
import React from 'react';
-import { shallow } from 'enzyme';
-
import { Route, Redirect, Switch } from 'react-router-dom';
-import { staticSourceData } from '../content_sources/source_data';
+import { shallow } from 'enzyme';
import { FlashMessages } from '../../../shared/flash_messages';
+import { staticSourceData } from '../content_sources/source_data';
import { Connectors } from './components/connectors';
import { Customize } from './components/customize';
import { OauthApplication } from './components/oauth_application';
import { SourceConfig } from './components/source_config';
-
import { SettingsRouter } from './settings_router';
describe('SettingsRouter', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/settings_router.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/settings_router.tsx
index ee9122b015eff..34dcc48621a2e 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/settings_router.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/settings_router.tsx
@@ -6,26 +6,23 @@
*/
import React, { useEffect } from 'react';
+import { Redirect, Route, Switch } from 'react-router-dom';
import { useActions } from 'kea';
-import { Redirect, Route, Switch } from 'react-router-dom';
+import { FlashMessages } from '../../../shared/flash_messages';
import {
ORG_SETTINGS_PATH,
ORG_SETTINGS_CUSTOMIZE_PATH,
ORG_SETTINGS_CONNECTORS_PATH,
ORG_SETTINGS_OAUTH_APPLICATION_PATH,
} from '../../routes';
-
-import { FlashMessages } from '../../../shared/flash_messages';
+import { staticSourceData } from '../content_sources/source_data';
import { Connectors } from './components/connectors';
import { Customize } from './components/customize';
import { OauthApplication } from './components/oauth_application';
import { SourceConfig } from './components/source_config';
-
-import { staticSourceData } from '../content_sources/source_data';
-
import { SettingsLogic } from './settings_logic';
export const SettingsRouter: React.FC = () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/setup_guide/setup_guide.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/setup_guide/setup_guide.test.tsx
index 8bec56603cd80..6b03e86080402 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/setup_guide/setup_guide.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/setup_guide/setup_guide.test.tsx
@@ -6,10 +6,12 @@
*/
import React from 'react';
+
import { shallow } from 'enzyme';
import { SetWorkplaceSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
import { SetupGuideLayout } from '../../../shared/setup_guide';
+
import { SetupGuide } from './';
describe('SetupGuide', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/setup_guide/setup_guide.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/setup_guide/setup_guide.tsx
index 810125fc931a6..13191f42bc566 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/setup_guide/setup_guide.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/setup_guide/setup_guide.tsx
@@ -6,18 +6,19 @@
*/
import React from 'react';
+
import { EuiSpacer, EuiTitle, EuiText, EuiButton, EuiLink } from '@elastic/eui';
-import { FormattedMessage } from '@kbn/i18n/react';
import { i18n } from '@kbn/i18n';
+import { FormattedMessage } from '@kbn/i18n/react';
import { WORKPLACE_SEARCH_PLUGIN } from '../../../../../common/constants';
-import { SetupGuideLayout, SETUP_GUIDE_TITLE } from '../../../shared/setup_guide';
import { SetWorkplaceSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
+import { SetupGuideLayout, SETUP_GUIDE_TITLE } from '../../../shared/setup_guide';
import { SendWorkplaceSearchTelemetry as SendTelemetry } from '../../../shared/telemetry';
+import { DOCS_PREFIX } from '../../routes';
import GettingStarted from './assets/getting_started.png';
-import { DOCS_PREFIX } from '../../routes';
const GETTING_STARTED_LINK_URL = `${DOCS_PREFIX}/workplace-search-getting-started.html`;
export const SetupGuide: React.FC = () => {
diff --git a/x-pack/plugins/enterprise_search/public/index.ts b/x-pack/plugins/enterprise_search/public/index.ts
index da343728b7d41..b7131e70fec07 100644
--- a/x-pack/plugins/enterprise_search/public/index.ts
+++ b/x-pack/plugins/enterprise_search/public/index.ts
@@ -6,6 +6,7 @@
*/
import { PluginInitializerContext } from 'src/core/public';
+
import { EnterpriseSearchPlugin } from './plugin';
export const plugin = (initializerContext: PluginInitializerContext) => {
diff --git a/x-pack/plugins/enterprise_search/public/plugin.ts b/x-pack/plugins/enterprise_search/public/plugin.ts
index c10eb74f47720..f00e81a5accf7 100644
--- a/x-pack/plugins/enterprise_search/public/plugin.ts
+++ b/x-pack/plugins/enterprise_search/public/plugin.ts
@@ -12,15 +12,15 @@ import {
HttpSetup,
Plugin,
PluginInitializerContext,
-} from 'src/core/public';
-import { DEFAULT_APP_CATEGORIES } from '../../../../src/core/public';
+ DEFAULT_APP_CATEGORIES,
+} from '../../../../src/core/public';
+import { ChartsPluginStart } from '../../../../src/plugins/charts/public';
import {
FeatureCatalogueCategory,
HomePublicPluginSetup,
} from '../../../../src/plugins/home/public';
import { CloudSetup } from '../../cloud/public';
import { LicensingPluginStart } from '../../licensing/public';
-import { ChartsPluginStart } from '../../../../src/plugins/charts/public';
import {
APP_SEARCH_PLUGIN,
diff --git a/x-pack/plugins/enterprise_search/server/__mocks__/router.mock.ts b/x-pack/plugins/enterprise_search/server/__mocks__/router.mock.ts
index 88cf30bb2a549..5c19ca7062b65 100644
--- a/x-pack/plugins/enterprise_search/server/__mocks__/router.mock.ts
+++ b/x-pack/plugins/enterprise_search/server/__mocks__/router.mock.ts
@@ -5,13 +5,13 @@
* 2.0.
*/
-import { httpServiceMock, httpServerMock } from 'src/core/server/mocks';
import {
IRouter,
KibanaRequest,
RequestHandlerContext,
RouteValidatorConfig,
} from 'src/core/server';
+import { httpServiceMock, httpServerMock } from 'src/core/server/mocks';
/**
* Test helper that mocks Kibana's router and DRYs out various helper (callRoute, schema validation)
diff --git a/x-pack/plugins/enterprise_search/server/__mocks__/routerDependencies.mock.ts b/x-pack/plugins/enterprise_search/server/__mocks__/routerDependencies.mock.ts
index c84254660a728..50ff082858fc8 100644
--- a/x-pack/plugins/enterprise_search/server/__mocks__/routerDependencies.mock.ts
+++ b/x-pack/plugins/enterprise_search/server/__mocks__/routerDependencies.mock.ts
@@ -6,6 +6,7 @@
*/
import { loggingSystemMock } from 'src/core/server/mocks';
+
import { ConfigType } from '../';
export const mockLogger = loggingSystemMock.createLogger().get();
diff --git a/x-pack/plugins/enterprise_search/server/collectors/app_search/telemetry.ts b/x-pack/plugins/enterprise_search/server/collectors/app_search/telemetry.ts
index 537e1b77f3e84..36ba2976f929a 100644
--- a/x-pack/plugins/enterprise_search/server/collectors/app_search/telemetry.ts
+++ b/x-pack/plugins/enterprise_search/server/collectors/app_search/telemetry.ts
@@ -6,6 +6,7 @@
*/
import { get } from 'lodash';
+
import { SavedObjectsServiceStart, Logger } from 'src/core/server';
import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
diff --git a/x-pack/plugins/enterprise_search/server/collectors/enterprise_search/telemetry.ts b/x-pack/plugins/enterprise_search/server/collectors/enterprise_search/telemetry.ts
index 732dfbd02c10b..f71c8a5444c9c 100644
--- a/x-pack/plugins/enterprise_search/server/collectors/enterprise_search/telemetry.ts
+++ b/x-pack/plugins/enterprise_search/server/collectors/enterprise_search/telemetry.ts
@@ -6,6 +6,7 @@
*/
import { get } from 'lodash';
+
import { SavedObjectsServiceStart, Logger } from 'src/core/server';
import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
diff --git a/x-pack/plugins/enterprise_search/server/collectors/workplace_search/telemetry.ts b/x-pack/plugins/enterprise_search/server/collectors/workplace_search/telemetry.ts
index 01210eba95368..e36ce94066789 100644
--- a/x-pack/plugins/enterprise_search/server/collectors/workplace_search/telemetry.ts
+++ b/x-pack/plugins/enterprise_search/server/collectors/workplace_search/telemetry.ts
@@ -6,6 +6,7 @@
*/
import { get } from 'lodash';
+
import { SavedObjectsServiceStart, Logger } from 'src/core/server';
import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
diff --git a/x-pack/plugins/enterprise_search/server/index.ts b/x-pack/plugins/enterprise_search/server/index.ts
index ac012077fdf84..c4552b9134eae 100644
--- a/x-pack/plugins/enterprise_search/server/index.ts
+++ b/x-pack/plugins/enterprise_search/server/index.ts
@@ -5,8 +5,9 @@
* 2.0.
*/
-import { PluginInitializerContext, PluginConfigDescriptor } from 'src/core/server';
import { schema, TypeOf } from '@kbn/config-schema';
+import { PluginInitializerContext, PluginConfigDescriptor } from 'src/core/server';
+
import { EnterpriseSearchPlugin } from './plugin';
export const plugin = (initializerContext: PluginInitializerContext) => {
diff --git a/x-pack/plugins/enterprise_search/server/lib/check_access.test.ts b/x-pack/plugins/enterprise_search/server/lib/check_access.test.ts
index 4a978c66b16d6..3c5d33fa74d3b 100644
--- a/x-pack/plugins/enterprise_search/server/lib/check_access.test.ts
+++ b/x-pack/plugins/enterprise_search/server/lib/check_access.test.ts
@@ -5,14 +5,15 @@
* 2.0.
*/
+import { spacesMock } from '../../../spaces/server/mocks';
+
+import { checkAccess } from './check_access';
+
jest.mock('./enterprise_search_config_api', () => ({
callEnterpriseSearchConfigAPI: jest.fn(),
}));
import { callEnterpriseSearchConfigAPI } from './enterprise_search_config_api';
-import { checkAccess } from './check_access';
-import { spacesMock } from '../../../spaces/server/mocks';
-
const enabledSpace = {
id: 'space',
name: 'space',
diff --git a/x-pack/plugins/enterprise_search/server/lib/check_access.ts b/x-pack/plugins/enterprise_search/server/lib/check_access.ts
index 25c92d62c1203..0a5e0c9e2b832 100644
--- a/x-pack/plugins/enterprise_search/server/lib/check_access.ts
+++ b/x-pack/plugins/enterprise_search/server/lib/check_access.ts
@@ -6,9 +6,10 @@
*/
import { KibanaRequest, Logger } from 'src/core/server';
-import { SpacesPluginStart } from '../../../spaces/server';
+
import { SecurityPluginSetup } from '../../../security/server';
-import { ConfigType } from '../';
+import { SpacesPluginStart } from '../../../spaces/server';
+import { ConfigType } from '../index';
import { callEnterpriseSearchConfigAPI } from './enterprise_search_config_api';
diff --git a/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.test.ts b/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.test.ts
index 61aeffd99db00..6c6744ef3e32b 100644
--- a/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.test.ts
+++ b/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.test.ts
@@ -5,14 +5,15 @@
* 2.0.
*/
+import { DEFAULT_INITIAL_APP_DATA } from '../../common/__mocks__';
+
jest.mock('node-fetch');
-// eslint-disable-next-line @typescript-eslint/no-var-requires
-const fetchMock = require('node-fetch') as jest.Mock;
+import fetch from 'node-fetch';
+
const { Response } = jest.requireActual('node-fetch');
import { loggingSystemMock } from 'src/core/server/mocks';
-import { DEFAULT_INITIAL_APP_DATA } from '../../common/__mocks__';
import { callEnterpriseSearchConfigAPI } from './enterprise_search_config_api';
describe('callEnterpriseSearchConfigAPI', () => {
@@ -101,7 +102,7 @@ describe('callEnterpriseSearchConfigAPI', () => {
});
it('calls the config API endpoint', async () => {
- fetchMock.mockImplementationOnce((url: string) => {
+ ((fetch as unknown) as jest.Mock).mockImplementationOnce((url: string) => {
expect(url).toEqual('http://localhost:3002/api/ent/v2/internal/client_config');
return Promise.resolve(new Response(JSON.stringify(mockResponse)));
});
@@ -117,7 +118,7 @@ describe('callEnterpriseSearchConfigAPI', () => {
});
it('falls back without error when data is unavailable', async () => {
- fetchMock.mockImplementationOnce((url: string) => Promise.resolve(new Response('{}')));
+ ((fetch as unknown) as jest.Mock).mockReturnValueOnce(Promise.resolve(new Response('{}')));
expect(await callEnterpriseSearchConfigAPI(mockDependencies)).toEqual({
access: {
@@ -180,21 +181,17 @@ describe('callEnterpriseSearchConfigAPI', () => {
const config = { host: '' };
expect(await callEnterpriseSearchConfigAPI({ ...mockDependencies, config })).toEqual({});
- expect(fetchMock).not.toHaveBeenCalled();
+ expect(fetch).not.toHaveBeenCalled();
});
it('handles server errors', async () => {
- fetchMock.mockImplementationOnce(() => {
- return Promise.reject('500');
- });
+ ((fetch as unknown) as jest.Mock).mockReturnValueOnce(Promise.reject('500'));
expect(await callEnterpriseSearchConfigAPI(mockDependencies)).toEqual({});
expect(mockDependencies.log.error).toHaveBeenCalledWith(
'Could not perform access check to Enterprise Search: 500'
);
- fetchMock.mockImplementationOnce(() => {
- return Promise.resolve('Bad Data');
- });
+ ((fetch as unknown) as jest.Mock).mockReturnValueOnce(Promise.resolve('Bad Data'));
expect(await callEnterpriseSearchConfigAPI(mockDependencies)).toEqual({});
expect(mockDependencies.log.error).toHaveBeenCalledWith(
'Could not perform access check to Enterprise Search: TypeError: response.json is not a function'
@@ -212,7 +209,7 @@ describe('callEnterpriseSearchConfigAPI', () => {
);
// Timeout
- fetchMock.mockImplementationOnce(async () => {
+ ((fetch as unknown) as jest.Mock).mockImplementationOnce(async () => {
jest.advanceTimersByTime(250);
return Promise.reject({ name: 'AbortError' });
});
diff --git a/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.ts b/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.ts
index 9f207361cef91..0ed4ad257f30b 100644
--- a/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.ts
+++ b/x-pack/plugins/enterprise_search/server/lib/enterprise_search_config_api.ts
@@ -9,11 +9,12 @@ import AbortController from 'abort-controller';
import fetch from 'node-fetch';
import { KibanaRequest, Logger } from 'src/core/server';
-import { ConfigType } from '../';
-import { Access } from './check_access';
-import { InitialAppData } from '../../common/types';
import { stripTrailingSlash } from '../../common/strip_slashes';
+import { InitialAppData } from '../../common/types';
+import { ConfigType } from '../index';
+
+import { Access } from './check_access';
interface Params {
request: KibanaRequest;
diff --git a/x-pack/plugins/enterprise_search/server/lib/enterprise_search_request_handler.test.ts b/x-pack/plugins/enterprise_search/server/lib/enterprise_search_request_handler.test.ts
index 8d47ba0ec77ba..7199067a2c8f4 100644
--- a/x-pack/plugins/enterprise_search/server/lib/enterprise_search_request_handler.test.ts
+++ b/x-pack/plugins/enterprise_search/server/lib/enterprise_search_request_handler.test.ts
@@ -6,6 +6,7 @@
*/
import { mockConfig, mockLogger } from '../__mocks__';
+
import { JSON_HEADER, READ_ONLY_MODE_HEADER } from '../../common/constants';
import { EnterpriseSearchRequestHandler } from './enterprise_search_request_handler';
@@ -13,6 +14,7 @@ import { EnterpriseSearchRequestHandler } from './enterprise_search_request_hand
jest.mock('node-fetch');
// eslint-disable-next-line @typescript-eslint/no-var-requires
const fetchMock = require('node-fetch') as jest.Mock;
+
const { Response } = jest.requireActual('node-fetch');
const responseMock = {
diff --git a/x-pack/plugins/enterprise_search/server/lib/enterprise_search_request_handler.ts b/x-pack/plugins/enterprise_search/server/lib/enterprise_search_request_handler.ts
index 39590b310fc26..f47df58c4eca1 100644
--- a/x-pack/plugins/enterprise_search/server/lib/enterprise_search_request_handler.ts
+++ b/x-pack/plugins/enterprise_search/server/lib/enterprise_search_request_handler.ts
@@ -7,6 +7,7 @@
import fetch, { Response } from 'node-fetch';
import querystring from 'querystring';
+
import {
RequestHandler,
RequestHandlerContext,
@@ -14,8 +15,9 @@ import {
KibanaResponseFactory,
Logger,
} from 'src/core/server';
-import { ConfigType } from '../index';
+
import { JSON_HEADER, READ_ONLY_MODE_HEADER } from '../../common/constants';
+import { ConfigType } from '../index';
interface ConstructorDependencies {
config: ConfigType;
diff --git a/x-pack/plugins/enterprise_search/server/plugin.ts b/x-pack/plugins/enterprise_search/server/plugin.ts
index 569479f921cdd..1b9659899097d 100644
--- a/x-pack/plugins/enterprise_search/server/plugin.ts
+++ b/x-pack/plugins/enterprise_search/server/plugin.ts
@@ -13,37 +13,39 @@ import {
SavedObjectsServiceStart,
IRouter,
KibanaRequest,
-} from 'src/core/server';
-import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
-import { SpacesPluginStart } from '../../spaces/server';
-import { DEFAULT_APP_CATEGORIES } from '../../../../src/core/server';
-import { SecurityPluginSetup } from '../../security/server';
+ DEFAULT_APP_CATEGORIES,
+} from '../../../../src/core/server';
+import { UsageCollectionSetup } from '../../../../src/plugins/usage_collection/server';
import { PluginSetupContract as FeaturesPluginSetup } from '../../features/server';
+import { SecurityPluginSetup } from '../../security/server';
+import { SpacesPluginStart } from '../../spaces/server';
import {
ENTERPRISE_SEARCH_PLUGIN,
APP_SEARCH_PLUGIN,
WORKPLACE_SEARCH_PLUGIN,
} from '../common/constants';
-import { ConfigType } from './';
+
+import { registerTelemetryUsageCollector as registerASTelemetryUsageCollector } from './collectors/app_search/telemetry';
+import { registerTelemetryUsageCollector as registerESTelemetryUsageCollector } from './collectors/enterprise_search/telemetry';
+import { registerTelemetryUsageCollector as registerWSTelemetryUsageCollector } from './collectors/workplace_search/telemetry';
+
import { checkAccess } from './lib/check_access';
import {
EnterpriseSearchRequestHandler,
IEnterpriseSearchRequestHandler,
} from './lib/enterprise_search_request_handler';
-import { enterpriseSearchTelemetryType } from './saved_objects/enterprise_search/telemetry';
-import { registerTelemetryUsageCollector as registerESTelemetryUsageCollector } from './collectors/enterprise_search/telemetry';
-import { registerTelemetryRoute } from './routes/enterprise_search/telemetry';
+import { registerAppSearchRoutes } from './routes/app_search';
import { registerConfigDataRoute } from './routes/enterprise_search/config_data';
+import { registerTelemetryRoute } from './routes/enterprise_search/telemetry';
+import { registerWorkplaceSearchRoutes } from './routes/workplace_search';
import { appSearchTelemetryType } from './saved_objects/app_search/telemetry';
-import { registerTelemetryUsageCollector as registerASTelemetryUsageCollector } from './collectors/app_search/telemetry';
-import { registerAppSearchRoutes } from './routes/app_search';
-
+import { enterpriseSearchTelemetryType } from './saved_objects/enterprise_search/telemetry';
import { workplaceSearchTelemetryType } from './saved_objects/workplace_search/telemetry';
-import { registerTelemetryUsageCollector as registerWSTelemetryUsageCollector } from './collectors/workplace_search/telemetry';
-import { registerWorkplaceSearchRoutes } from './routes/workplace_search';
+
+import { ConfigType } from './';
interface PluginsSetup {
usageCollection?: UsageCollectionSetup;
diff --git a/x-pack/plugins/enterprise_search/server/routes/app_search/engines.ts b/x-pack/plugins/enterprise_search/server/routes/app_search/engines.ts
index 49ff0353bef03..0070680985a34 100644
--- a/x-pack/plugins/enterprise_search/server/routes/app_search/engines.ts
+++ b/x-pack/plugins/enterprise_search/server/routes/app_search/engines.ts
@@ -7,8 +7,8 @@
import { schema } from '@kbn/config-schema';
-import { RouteDependencies } from '../../plugin';
import { ENGINES_PAGE_SIZE } from '../../../common/constants';
+import { RouteDependencies } from '../../plugin';
interface EnginesResponse {
results: object[];
diff --git a/x-pack/plugins/enterprise_search/server/routes/app_search/index.ts b/x-pack/plugins/enterprise_search/server/routes/app_search/index.ts
index 233e728a3010a..92fdcb689db1d 100644
--- a/x-pack/plugins/enterprise_search/server/routes/app_search/index.ts
+++ b/x-pack/plugins/enterprise_search/server/routes/app_search/index.ts
@@ -7,12 +7,12 @@
import { RouteDependencies } from '../../plugin';
-import { registerEnginesRoutes } from './engines';
-import { registerCredentialsRoutes } from './credentials';
-import { registerSettingsRoutes } from './settings';
import { registerAnalyticsRoutes } from './analytics';
+import { registerCredentialsRoutes } from './credentials';
import { registerDocumentsRoutes, registerDocumentRoutes } from './documents';
+import { registerEnginesRoutes } from './engines';
import { registerSearchSettingsRoutes } from './search_settings';
+import { registerSettingsRoutes } from './settings';
export const registerAppSearchRoutes = (dependencies: RouteDependencies) => {
registerEnginesRoutes(dependencies);
diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/config_data.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/config_data.ts
index f9c65eedbb13a..e2cbd409bd396 100644
--- a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/config_data.ts
+++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/config_data.ts
@@ -5,8 +5,8 @@
* 2.0.
*/
-import { RouteDependencies } from '../../plugin';
import { callEnterpriseSearchConfigAPI } from '../../lib/enterprise_search_config_api';
+import { RouteDependencies } from '../../plugin';
export function registerConfigDataRoute({ router, config, log }: RouteDependencies) {
router.get(
diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/telemetry.test.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/telemetry.test.ts
index 08c398ba3eb0d..62f68748fcea1 100644
--- a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/telemetry.test.ts
+++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/telemetry.test.ts
@@ -5,9 +5,10 @@
* 2.0.
*/
-import { loggingSystemMock, savedObjectsServiceMock } from 'src/core/server/mocks';
import { MockRouter, mockLogger, mockDependencies } from '../../__mocks__';
+import { loggingSystemMock, savedObjectsServiceMock } from 'src/core/server/mocks';
+
jest.mock('../../collectors/lib/telemetry', () => ({
incrementUICounter: jest.fn(),
}));
diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/telemetry.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/telemetry.ts
index c8750bdff5d38..90afba414c044 100644
--- a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/telemetry.ts
+++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/telemetry.ts
@@ -7,12 +7,13 @@
import { schema } from '@kbn/config-schema';
-import { RouteDependencies } from '../../plugin';
-import { incrementUICounter } from '../../collectors/lib/telemetry';
-
-import { ES_TELEMETRY_NAME } from '../../collectors/enterprise_search/telemetry';
import { AS_TELEMETRY_NAME } from '../../collectors/app_search/telemetry';
+import { ES_TELEMETRY_NAME } from '../../collectors/enterprise_search/telemetry';
+import { incrementUICounter } from '../../collectors/lib/telemetry';
import { WS_TELEMETRY_NAME } from '../../collectors/workplace_search/telemetry';
+
+import { RouteDependencies } from '../../plugin';
+
const productToTelemetryMap = {
enterprise_search: ES_TELEMETRY_NAME,
app_search: AS_TELEMETRY_NAME,
diff --git a/x-pack/plugins/enterprise_search/server/routes/workplace_search/index.ts b/x-pack/plugins/enterprise_search/server/routes/workplace_search/index.ts
index c4819c3579adc..cc6226e340653 100644
--- a/x-pack/plugins/enterprise_search/server/routes/workplace_search/index.ts
+++ b/x-pack/plugins/enterprise_search/server/routes/workplace_search/index.ts
@@ -7,11 +7,11 @@
import { RouteDependencies } from '../../plugin';
-import { registerOverviewRoute } from './overview';
import { registerGroupsRoutes } from './groups';
-import { registerSourcesRoutes } from './sources';
-import { registerSettingsRoutes } from './settings';
+import { registerOverviewRoute } from './overview';
import { registerSecurityRoutes } from './security';
+import { registerSettingsRoutes } from './settings';
+import { registerSourcesRoutes } from './sources';
export const registerWorkplaceSearchRoutes = (dependencies: RouteDependencies) => {
registerOverviewRoute(dependencies);
diff --git a/x-pack/plugins/enterprise_search/server/saved_objects/app_search/telemetry.ts b/x-pack/plugins/enterprise_search/server/saved_objects/app_search/telemetry.ts
index 29b1ce8182f52..ab873b6678885 100644
--- a/x-pack/plugins/enterprise_search/server/saved_objects/app_search/telemetry.ts
+++ b/x-pack/plugins/enterprise_search/server/saved_objects/app_search/telemetry.ts
@@ -8,6 +8,7 @@
/* istanbul ignore file */
import { SavedObjectsType } from 'src/core/server';
+
import { AS_TELEMETRY_NAME } from '../../collectors/app_search/telemetry';
export const appSearchTelemetryType: SavedObjectsType = {
diff --git a/x-pack/plugins/enterprise_search/server/saved_objects/enterprise_search/telemetry.ts b/x-pack/plugins/enterprise_search/server/saved_objects/enterprise_search/telemetry.ts
index 07659299ef87f..e2edff1b6a213 100644
--- a/x-pack/plugins/enterprise_search/server/saved_objects/enterprise_search/telemetry.ts
+++ b/x-pack/plugins/enterprise_search/server/saved_objects/enterprise_search/telemetry.ts
@@ -8,6 +8,7 @@
/* istanbul ignore file */
import { SavedObjectsType } from 'src/core/server';
+
import { ES_TELEMETRY_NAME } from '../../collectors/enterprise_search/telemetry';
export const enterpriseSearchTelemetryType: SavedObjectsType = {
diff --git a/x-pack/plugins/enterprise_search/server/saved_objects/workplace_search/telemetry.ts b/x-pack/plugins/enterprise_search/server/saved_objects/workplace_search/telemetry.ts
index a466d69cf8343..af4d5908dec67 100644
--- a/x-pack/plugins/enterprise_search/server/saved_objects/workplace_search/telemetry.ts
+++ b/x-pack/plugins/enterprise_search/server/saved_objects/workplace_search/telemetry.ts
@@ -8,6 +8,7 @@
/* istanbul ignore file */
import { SavedObjectsType } from 'src/core/server';
+
import { WS_TELEMETRY_NAME } from '../../collectors/workplace_search/telemetry';
export const workplaceSearchTelemetryType: SavedObjectsType = {
diff --git a/x-pack/plugins/file_upload/kibana.json b/x-pack/plugins/file_upload/kibana.json
index 7ca024174ec6a..7676a01d0b0f9 100644
--- a/x-pack/plugins/file_upload/kibana.json
+++ b/x-pack/plugins/file_upload/kibana.json
@@ -3,6 +3,6 @@
"version": "8.0.0",
"kibanaVersion": "kibana",
"server": true,
- "ui": false,
- "requiredPlugins": ["usageCollection"]
+ "ui": true,
+ "requiredPlugins": ["data", "usageCollection"]
}
diff --git a/x-pack/plugins/maps_file_upload/public/components/index_settings.js b/x-pack/plugins/file_upload/public/components/index_settings.js
similarity index 100%
rename from x-pack/plugins/maps_file_upload/public/components/index_settings.js
rename to x-pack/plugins/file_upload/public/components/index_settings.js
diff --git a/x-pack/plugins/maps_file_upload/public/components/json_import_progress.js b/x-pack/plugins/file_upload/public/components/json_import_progress.js
similarity index 96%
rename from x-pack/plugins/maps_file_upload/public/components/json_import_progress.js
rename to x-pack/plugins/file_upload/public/components/json_import_progress.js
index 535142bc3500e..1f9293e77d33c 100644
--- a/x-pack/plugins/maps_file_upload/public/components/json_import_progress.js
+++ b/x-pack/plugins/file_upload/public/components/json_import_progress.js
@@ -118,9 +118,7 @@ export class JsonImportProgress extends Component {
{i18n.translate('xpack.fileUpload.jsonImport.indexMgmtLink', {
defaultMessage: 'Index Management',
diff --git a/x-pack/plugins/maps_file_upload/public/components/json_index_file_picker.js b/x-pack/plugins/file_upload/public/components/json_index_file_picker.js
similarity index 99%
rename from x-pack/plugins/maps_file_upload/public/components/json_index_file_picker.js
rename to x-pack/plugins/file_upload/public/components/json_index_file_picker.js
index 8721b5b60f039..a92412ae9d697 100644
--- a/x-pack/plugins/maps_file_upload/public/components/json_index_file_picker.js
+++ b/x-pack/plugins/file_upload/public/components/json_index_file_picker.js
@@ -10,8 +10,8 @@ import { EuiFilePicker, EuiFormRow, EuiProgress } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { i18n } from '@kbn/i18n';
import { parseFile } from '../util/file_parser';
-import { MAX_FILE_SIZE } from '../../common/constants/file_import';
+const MAX_FILE_SIZE = 52428800;
const ACCEPTABLE_FILETYPES = ['json', 'geojson'];
const acceptedFileTypeString = ACCEPTABLE_FILETYPES.map((type) => `.${type}`).join(',');
const acceptedFileTypeStringMessage = ACCEPTABLE_FILETYPES.map((type) => `.${type}`).join(', ');
diff --git a/x-pack/plugins/maps_file_upload/public/components/json_upload_and_parse.js b/x-pack/plugins/file_upload/public/components/json_upload_and_parse.js
similarity index 100%
rename from x-pack/plugins/maps_file_upload/public/components/json_upload_and_parse.js
rename to x-pack/plugins/file_upload/public/components/json_upload_and_parse.js
diff --git a/x-pack/plugins/maps_file_upload/public/get_file_upload_component.ts b/x-pack/plugins/file_upload/public/get_file_upload_component.ts
similarity index 100%
rename from x-pack/plugins/maps_file_upload/public/get_file_upload_component.ts
rename to x-pack/plugins/file_upload/public/get_file_upload_component.ts
diff --git a/x-pack/plugins/maps_file_upload/public/index.ts b/x-pack/plugins/file_upload/public/index.ts
similarity index 94%
rename from x-pack/plugins/maps_file_upload/public/index.ts
rename to x-pack/plugins/file_upload/public/index.ts
index 95553685cbbdd..efabc984e0220 100644
--- a/x-pack/plugins/maps_file_upload/public/index.ts
+++ b/x-pack/plugins/file_upload/public/index.ts
@@ -11,5 +11,7 @@ export function plugin() {
return new FileUploadPlugin();
}
+export * from '../common';
+
export { StartContract } from './plugin';
export { FileUploadComponentProps } from './get_file_upload_component';
diff --git a/x-pack/plugins/maps_file_upload/public/kibana_services.js b/x-pack/plugins/file_upload/public/kibana_services.js
similarity index 100%
rename from x-pack/plugins/maps_file_upload/public/kibana_services.js
rename to x-pack/plugins/file_upload/public/kibana_services.js
diff --git a/x-pack/plugins/maps_file_upload/public/plugin.ts b/x-pack/plugins/file_upload/public/plugin.ts
similarity index 100%
rename from x-pack/plugins/maps_file_upload/public/plugin.ts
rename to x-pack/plugins/file_upload/public/plugin.ts
diff --git a/x-pack/plugins/maps_file_upload/public/util/file_parser.js b/x-pack/plugins/file_upload/public/util/file_parser.js
similarity index 100%
rename from x-pack/plugins/maps_file_upload/public/util/file_parser.js
rename to x-pack/plugins/file_upload/public/util/file_parser.js
diff --git a/x-pack/plugins/maps_file_upload/public/util/file_parser.test.js b/x-pack/plugins/file_upload/public/util/file_parser.test.js
similarity index 100%
rename from x-pack/plugins/maps_file_upload/public/util/file_parser.test.js
rename to x-pack/plugins/file_upload/public/util/file_parser.test.js
diff --git a/x-pack/plugins/maps_file_upload/public/util/geo_json_clean_and_validate.js b/x-pack/plugins/file_upload/public/util/geo_json_clean_and_validate.js
similarity index 100%
rename from x-pack/plugins/maps_file_upload/public/util/geo_json_clean_and_validate.js
rename to x-pack/plugins/file_upload/public/util/geo_json_clean_and_validate.js
diff --git a/x-pack/plugins/maps_file_upload/public/util/geo_json_clean_and_validate.test.js b/x-pack/plugins/file_upload/public/util/geo_json_clean_and_validate.test.js
similarity index 100%
rename from x-pack/plugins/maps_file_upload/public/util/geo_json_clean_and_validate.test.js
rename to x-pack/plugins/file_upload/public/util/geo_json_clean_and_validate.test.js
diff --git a/x-pack/plugins/maps_file_upload/public/util/geo_processing.js b/x-pack/plugins/file_upload/public/util/geo_processing.js
similarity index 76%
rename from x-pack/plugins/maps_file_upload/public/util/geo_processing.js
rename to x-pack/plugins/file_upload/public/util/geo_processing.js
index d6f9651496aca..c90c55c2b49ac 100644
--- a/x-pack/plugins/maps_file_upload/public/util/geo_processing.js
+++ b/x-pack/plugins/file_upload/public/util/geo_processing.js
@@ -6,26 +6,12 @@
*/
import _ from 'lodash';
-import { ES_GEO_FIELD_TYPE } from '../../common/constants/file_import';
-const DEFAULT_SETTINGS = {
- number_of_shards: 1,
+export const ES_GEO_FIELD_TYPE = {
+ GEO_POINT: 'geo_point',
+ GEO_SHAPE: 'geo_shape',
};
-const DEFAULT_GEO_SHAPE_MAPPINGS = {
- coordinates: {
- type: ES_GEO_FIELD_TYPE.GEO_SHAPE,
- },
-};
-
-const DEFAULT_GEO_POINT_MAPPINGS = {
- coordinates: {
- type: ES_GEO_FIELD_TYPE.GEO_POINT,
- },
-};
-
-const DEFAULT_INGEST_PIPELINE = {};
-
export function getGeoIndexTypesForFeatures(featureTypes) {
const hasNoFeatureType = !featureTypes || !featureTypes.length;
if (hasNoFeatureType) {
@@ -77,11 +63,16 @@ export function geoJsonToEs(parsedGeojson, datatype) {
export function getGeoJsonIndexingDetails(parsedGeojson, dataType) {
return {
data: geoJsonToEs(parsedGeojson, dataType),
- ingestPipeline: DEFAULT_INGEST_PIPELINE,
- mappings:
- dataType === ES_GEO_FIELD_TYPE.GEO_POINT
- ? DEFAULT_GEO_POINT_MAPPINGS
- : DEFAULT_GEO_SHAPE_MAPPINGS,
- settings: DEFAULT_SETTINGS,
+ ingestPipeline: {},
+ mappings: {
+ properties: {
+ coordinates: {
+ type: dataType,
+ },
+ },
+ },
+ settings: {
+ number_of_shards: 1,
+ },
};
}
diff --git a/x-pack/plugins/maps_file_upload/public/util/geo_processing.test.js b/x-pack/plugins/file_upload/public/util/geo_processing.test.js
similarity index 97%
rename from x-pack/plugins/maps_file_upload/public/util/geo_processing.test.js
rename to x-pack/plugins/file_upload/public/util/geo_processing.test.js
index 75da5bae015af..37b665c0a3e16 100644
--- a/x-pack/plugins/maps_file_upload/public/util/geo_processing.test.js
+++ b/x-pack/plugins/file_upload/public/util/geo_processing.test.js
@@ -5,8 +5,7 @@
* 2.0.
*/
-import { geoJsonToEs } from './geo_processing';
-import { ES_GEO_FIELD_TYPE } from '../../common/constants/file_import';
+import { ES_GEO_FIELD_TYPE, geoJsonToEs } from './geo_processing';
describe('geo_processing', () => {
describe('getGeoJsonToEs', () => {
diff --git a/x-pack/plugins/maps_file_upload/public/util/http_service.js b/x-pack/plugins/file_upload/public/util/http_service.js
similarity index 100%
rename from x-pack/plugins/maps_file_upload/public/util/http_service.js
rename to x-pack/plugins/file_upload/public/util/http_service.js
diff --git a/x-pack/plugins/maps_file_upload/public/util/indexing_service.js b/x-pack/plugins/file_upload/public/util/indexing_service.js
similarity index 96%
rename from x-pack/plugins/maps_file_upload/public/util/indexing_service.js
rename to x-pack/plugins/file_upload/public/util/indexing_service.js
index c29e9685162bc..253681dad6a7d 100644
--- a/x-pack/plugins/maps_file_upload/public/util/indexing_service.js
+++ b/x-pack/plugins/file_upload/public/util/indexing_service.js
@@ -11,8 +11,6 @@ import { getGeoJsonIndexingDetails } from './geo_processing';
import { sizeLimitedChunking } from './size_limited_chunking';
import { i18n } from '@kbn/i18n';
-const fileType = 'json';
-
export async function indexData(parsedFile, transformDetails, indexName, dataType, appName) {
if (!parsedFile) {
throw i18n.translate('xpack.fileUpload.indexingService.noFileImported', {
@@ -117,10 +115,10 @@ function transformDataByFormatForIndexing(transform, parsedFile, dataType) {
async function writeToIndex(indexingDetails) {
const query = indexingDetails.id ? { id: indexingDetails.id } : null;
- const { appName, index, data, settings, mappings, ingestPipeline } = indexingDetails;
+ const { index, data, settings, mappings, ingestPipeline } = indexingDetails;
return await httpService({
- url: `/api/maps/fileupload/import`,
+ url: `/api/file_upload/import`,
method: 'POST',
...(query ? { query } : {}),
data: {
@@ -129,8 +127,6 @@ async function writeToIndex(indexingDetails) {
settings,
mappings,
ingestPipeline,
- fileType,
- ...(appName ? { app: appName } : {}),
},
});
}
diff --git a/x-pack/plugins/maps_file_upload/public/util/indexing_service.test.js b/x-pack/plugins/file_upload/public/util/indexing_service.test.js
similarity index 100%
rename from x-pack/plugins/maps_file_upload/public/util/indexing_service.test.js
rename to x-pack/plugins/file_upload/public/util/indexing_service.test.js
diff --git a/x-pack/plugins/maps_file_upload/public/util/size_limited_chunking.js b/x-pack/plugins/file_upload/public/util/size_limited_chunking.js
similarity index 95%
rename from x-pack/plugins/maps_file_upload/public/util/size_limited_chunking.js
rename to x-pack/plugins/file_upload/public/util/size_limited_chunking.js
index e42e11d0f27f0..09d4e8ca8e3a2 100644
--- a/x-pack/plugins/maps_file_upload/public/util/size_limited_chunking.js
+++ b/x-pack/plugins/file_upload/public/util/size_limited_chunking.js
@@ -5,7 +5,7 @@
* 2.0.
*/
-import { MAX_BYTES } from '../../common/constants/file_import';
+const MAX_BYTES = 31457280;
// MAX_BYTES is a good guideline for splitting up posts, but this logic
// occasionally sizes chunks so closely to the limit, that the remaining content
diff --git a/x-pack/plugins/maps_file_upload/public/util/size_limited_chunking.test.js b/x-pack/plugins/file_upload/public/util/size_limited_chunking.test.js
similarity index 100%
rename from x-pack/plugins/maps_file_upload/public/util/size_limited_chunking.test.js
rename to x-pack/plugins/file_upload/public/util/size_limited_chunking.test.js
diff --git a/x-pack/plugins/file_upload/server/routes.ts b/x-pack/plugins/file_upload/server/routes.ts
index 425e5551f2147..d7b7b8f99edd9 100644
--- a/x-pack/plugins/file_upload/server/routes.ts
+++ b/x-pack/plugins/file_upload/server/routes.ts
@@ -52,7 +52,7 @@ export function fileUploadRoutes(router: IRouter) {
accepts: ['application/json'],
maxBytes: MAX_FILE_SIZE_BYTES,
},
- tags: ['access:ml:canFindFileStructure'],
+ tags: ['access:fileUpload:import'],
},
},
async (context, request, response) => {
diff --git a/x-pack/plugins/file_upload/tsconfig.json b/x-pack/plugins/file_upload/tsconfig.json
index f985a4599d5fe..bebb08e6dd5e3 100644
--- a/x-pack/plugins/file_upload/tsconfig.json
+++ b/x-pack/plugins/file_upload/tsconfig.json
@@ -10,6 +10,7 @@
"include": ["common/**/*", "public/**/*", "server/**/*"],
"references": [
{ "path": "../../../src/core/tsconfig.json" },
+ { "path": "../../../src/plugins/data/tsconfig.json" },
{ "path": "../../../src/plugins/usage_collection/tsconfig.json" }
]
}
diff --git a/x-pack/plugins/fleet/kibana.json b/x-pack/plugins/fleet/kibana.json
index aa0761c8a39bd..4a4019e3e9e47 100644
--- a/x-pack/plugins/fleet/kibana.json
+++ b/x-pack/plugins/fleet/kibana.json
@@ -4,14 +4,13 @@
"server": true,
"ui": true,
"configPath": ["xpack", "fleet"],
- "requiredPlugins": ["licensing", "data"],
+ "requiredPlugins": ["licensing", "data", "encryptedSavedObjects"],
"optionalPlugins": [
"security",
"features",
"cloud",
"usageCollection",
- "home",
- "encryptedSavedObjects"
+ "home"
],
"extraPublicDirs": ["common"],
"requiredBundles": ["kibanaReact", "esUiShared", "home", "infra", "kibanaUtils"]
diff --git a/x-pack/plugins/fleet/public/applications/fleet/components/alpha_flyout.tsx b/x-pack/plugins/fleet/public/applications/fleet/components/alpha_flyout.tsx
index 82b2d20005225..c91d80124dd35 100644
--- a/x-pack/plugins/fleet/public/applications/fleet/components/alpha_flyout.tsx
+++ b/x-pack/plugins/fleet/public/applications/fleet/components/alpha_flyout.tsx
@@ -61,7 +61,7 @@ export const AlphaFlyout: React.FunctionComponent = ({ onClose }) => {
),
forumLink: (
-
+
& { name?: JSX.Element | string }>;
tabsClassName?: string;
'data-test-subj'?: string;
}
@@ -73,7 +73,7 @@ export const Header: React.FC