Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Cases] Update UI to use the new connector's API #149276

Merged
merged 38 commits into from
Jan 31, 2023
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
8edad49
Create getCaseConnectors hook
cnasikas Jan 19, 2023
816e8e1
Show push info
cnasikas Jan 20, 2023
c906ce4
Get fields from the new API
cnasikas Jan 20, 2023
c2eaf8c
Remove button & callout components from usePushToService
cnasikas Jan 21, 2023
71e543d
Move isValid and connectorName to edit connector component
cnasikas Jan 21, 2023
fe1d996
Reset form based on key
cnasikas Jan 22, 2023
2e6a8c6
Remove spacer on last item in CasesCallouts
cnasikas Jan 22, 2023
f9ce0d4
Move push button and callouts to seperate files
cnasikas Jan 22, 2023
085f86f
Improve styles
cnasikas Jan 22, 2023
865accf
Contruct connector on submit inside edit connector component
cnasikas Jan 22, 2023
a46c8c3
Fixes
cnasikas Jan 22, 2023
dad1ec6
Silent errors from actions client
cnasikas Jan 23, 2023
75c3c57
Minor fixes
cnasikas Jan 23, 2023
a482321
Adding oldest push timestamp
jonathan-buttner Jan 24, 2023
5d57d65
Fix tests and types
cnasikas Jan 25, 2023
db30357
Merge branch 'main' into get_connectors_info_from_server
cnasikas Jan 25, 2023
f5f4913
Merge branch 'cases-first-push-info' into get_connectors_info_from_se…
cnasikas Jan 25, 2023
7f9d189
Improve tests
cnasikas Jan 25, 2023
39162ce
Fix i18n
cnasikas Jan 25, 2023
ec5e1c7
Add more tests
cnasikas Jan 25, 2023
c50cde7
Fix bug
cnasikas Jan 25, 2023
304c450
Fix tests
cnasikas Jan 25, 2023
fb62ecc
Adding new external services field
jonathan-buttner Jan 25, 2023
d6e8fe2
Clarifying date field names
jonathan-buttner Jan 25, 2023
7296f8a
Merge branch 'main' into get_connectors_info_from_server
cnasikas Jan 25, 2023
965d17d
Merge branch 'cases-latest-push-info' into get_connectors_info_from_s…
cnasikas Jan 25, 2023
54963b3
Get external service from case connectors
cnasikas Jan 26, 2023
c31815f
Add API unit test
cnasikas Jan 26, 2023
8aee8e0
PR feedback
cnasikas Jan 26, 2023
b5b626b
Merge branch 'main' into get_connectors_info_from_server
cnasikas Jan 27, 2023
fc04401
PR feedback
cnasikas Jan 27, 2023
183a915
Fix types
cnasikas Jan 27, 2023
56611dc
Fix tests
cnasikas Jan 27, 2023
908ca2d
Merge branch 'main' into get_connectors_info_from_server
cnasikas Jan 30, 2023
5cbd246
Fix conflicts
cnasikas Jan 30, 2023
9b00d2a
Rename action connectors apis
cnasikas Jan 30, 2023
50554fe
PR feedback
cnasikas Jan 30, 2023
45eeba9
Merge branch 'main' into get_connectors_info_from_server
cnasikas Jan 31, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion x-pack/plugins/cases/common/api/cases/case.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { NumberFromString } from '../saved_object';
import { UserRT } from '../user';
import { CommentResponseRt } from './comment';
import { CasesStatusResponseRt, CaseStatusRt } from './status';
import { CaseConnectorRt } from '../connectors';
import { CaseConnectorRt } from '../connectors/connector';
import { CaseAssigneesRt } from './assignee';

export const AttachmentTotalsRt = rt.type({
Expand Down
125 changes: 125 additions & 0 deletions x-pack/plugins/cases/common/api/connectors/connector.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*
* 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';

import type { ActionType } from '@kbn/actions-plugin/common';
/**
* ActionResult type from the common folder is outdated.
* The type from server is not exported properly so we
* disable the linting for the moment
*/

import type { ActionResult } from '@kbn/actions-plugin/server/types';
import { JiraFieldsRT } from './jira';
import { ResilientFieldsRT } from './resilient';
import { ServiceNowITSMFieldsRT } from './servicenow_itsm';
import { ServiceNowSIRFieldsRT } from './servicenow_sir';
import { SwimlaneFieldsRT } from './swimlane';

export type ActionConnector = ActionResult;
export type ActionTypeConnector = ActionType;

export const ConnectorFieldsRt = rt.union([
JiraFieldsRT,
ResilientFieldsRT,
ServiceNowITSMFieldsRT,
ServiceNowSIRFieldsRT,
rt.null,
]);
cnasikas marked this conversation as resolved.
Show resolved Hide resolved

export enum ConnectorTypes {
casesWebhook = '.cases-webhook',
jira = '.jira',
none = '.none',
resilient = '.resilient',
serviceNowITSM = '.servicenow',
serviceNowSIR = '.servicenow-sir',
swimlane = '.swimlane',
}

const ConnectorCasesWebhookTypeFieldsRt = rt.type({
type: rt.literal(ConnectorTypes.casesWebhook),
fields: rt.null,
});

const ConnectorJiraTypeFieldsRt = rt.type({
type: rt.literal(ConnectorTypes.jira),
fields: rt.union([JiraFieldsRT, rt.null]),
});

const ConnectorResilientTypeFieldsRt = rt.type({
type: rt.literal(ConnectorTypes.resilient),
fields: rt.union([ResilientFieldsRT, rt.null]),
});

const ConnectorServiceNowITSMTypeFieldsRt = rt.type({
type: rt.literal(ConnectorTypes.serviceNowITSM),
fields: rt.union([ServiceNowITSMFieldsRT, rt.null]),
});

const ConnectorSwimlaneTypeFieldsRt = rt.type({
type: rt.literal(ConnectorTypes.swimlane),
fields: rt.union([SwimlaneFieldsRT, rt.null]),
});

const ConnectorServiceNowSIRTypeFieldsRt = rt.type({
type: rt.literal(ConnectorTypes.serviceNowSIR),
fields: rt.union([ServiceNowSIRFieldsRT, rt.null]),
});

const ConnectorNoneTypeFieldsRt = rt.type({
type: rt.literal(ConnectorTypes.none),
fields: rt.null,
});

export const NONE_CONNECTOR_ID: string = 'none';

export const ConnectorTypeFieldsRt = rt.union([
ConnectorCasesWebhookTypeFieldsRt,
ConnectorJiraTypeFieldsRt,
ConnectorNoneTypeFieldsRt,
ConnectorResilientTypeFieldsRt,
ConnectorServiceNowITSMTypeFieldsRt,
ConnectorServiceNowSIRTypeFieldsRt,
ConnectorSwimlaneTypeFieldsRt,
]);

/**
* This type represents the connector's format when it is encoded within a user action.
*/
export const CaseUserActionConnectorRt = rt.union([
rt.intersection([ConnectorCasesWebhookTypeFieldsRt, rt.type({ name: rt.string })]),
rt.intersection([ConnectorJiraTypeFieldsRt, rt.type({ name: rt.string })]),
rt.intersection([ConnectorNoneTypeFieldsRt, rt.type({ name: rt.string })]),
rt.intersection([ConnectorResilientTypeFieldsRt, rt.type({ name: rt.string })]),
rt.intersection([ConnectorServiceNowITSMTypeFieldsRt, rt.type({ name: rt.string })]),
rt.intersection([ConnectorServiceNowSIRTypeFieldsRt, rt.type({ name: rt.string })]),
rt.intersection([ConnectorSwimlaneTypeFieldsRt, rt.type({ name: rt.string })]),
]);

export const CaseConnectorRt = rt.intersection([
rt.type({
id: rt.string,
}),
CaseUserActionConnectorRt,
]);

export type CaseUserActionConnector = rt.TypeOf<typeof CaseUserActionConnectorRt>;
export type CaseConnector = rt.TypeOf<typeof CaseConnectorRt>;
export type ConnectorTypeFields = rt.TypeOf<typeof ConnectorTypeFieldsRt>;
export type ConnectorCasesWebhookTypeFields = rt.TypeOf<typeof ConnectorCasesWebhookTypeFieldsRt>;
export type ConnectorJiraTypeFields = rt.TypeOf<typeof ConnectorJiraTypeFieldsRt>;
export type ConnectorResilientTypeFields = rt.TypeOf<typeof ConnectorResilientTypeFieldsRt>;
export type ConnectorSwimlaneTypeFields = rt.TypeOf<typeof ConnectorSwimlaneTypeFieldsRt>;
export type ConnectorServiceNowITSMTypeFields = rt.TypeOf<
typeof ConnectorServiceNowITSMTypeFieldsRt
>;
export type ConnectorServiceNowSIRTypeFields = rt.TypeOf<typeof ConnectorServiceNowSIRTypeFieldsRt>;

// we need to change these types back and forth for storing in ES (arrays overwrite, objects merge)
export type ConnectorFields = rt.TypeOf<typeof ConnectorFieldsRt>;
36 changes: 36 additions & 0 deletions x-pack/plugins/cases/common/api/connectors/get_connectors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* 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';
import { CaseConnectorRt } from './connector';
import { CaseExternalServiceBasicRt } from '../cases';

const CaseConnectorPushInfoRt = rt.intersection([
rt.type({
needsToBePushed: rt.boolean,
hasBeenPushed: rt.boolean,
}),
rt.partial(
rt.type({
latestUserActionPushDate: rt.string,
oldestUserActionPushDate: rt.string,
externalService: CaseExternalServiceBasicRt,
}).props
),
]);

export const GetCaseConnectorsResponseRt = rt.record(
rt.string,
rt.intersection([
rt.type({
push: CaseConnectorPushInfoRt,
}),
CaseConnectorRt,
])
);

export type GetCaseConnectorsResponse = rt.TypeOf<typeof GetCaseConnectorsResponseRt>;
132 changes: 2 additions & 130 deletions x-pack/plugins/cases/common/api/connectors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,139 +5,11 @@
* 2.0.
*/

import * as rt from 'io-ts';

import type { ActionType } from '@kbn/actions-plugin/common';
/**
* ActionResult type from the common folder is outdated.
* The type from server is not exported properly so we
* disable the linting for the moment
*/

import type { ActionResult } from '@kbn/actions-plugin/server/types';
import { JiraFieldsRT } from './jira';
import { ResilientFieldsRT } from './resilient';
import { ServiceNowITSMFieldsRT } from './servicenow_itsm';
import { ServiceNowSIRFieldsRT } from './servicenow_sir';
import { SwimlaneFieldsRT } from './swimlane';

export * from './jira';
export * from './servicenow_itsm';
export * from './servicenow_sir';
export * from './resilient';
export * from './mappings';
export * from './swimlane';

export type ActionConnector = ActionResult;
export type ActionTypeConnector = ActionType;

export const ConnectorFieldsRt = rt.union([
JiraFieldsRT,
ResilientFieldsRT,
ServiceNowITSMFieldsRT,
ServiceNowSIRFieldsRT,
rt.null,
]);

export enum ConnectorTypes {
casesWebhook = '.cases-webhook',
jira = '.jira',
none = '.none',
resilient = '.resilient',
serviceNowITSM = '.servicenow',
serviceNowSIR = '.servicenow-sir',
swimlane = '.swimlane',
}

const ConnectorCasesWebhookTypeFieldsRt = rt.type({
type: rt.literal(ConnectorTypes.casesWebhook),
fields: rt.null,
});

const ConnectorJiraTypeFieldsRt = rt.type({
type: rt.literal(ConnectorTypes.jira),
fields: rt.union([JiraFieldsRT, rt.null]),
});

const ConnectorResilientTypeFieldsRt = rt.type({
type: rt.literal(ConnectorTypes.resilient),
fields: rt.union([ResilientFieldsRT, rt.null]),
});

const ConnectorServiceNowITSMTypeFieldsRt = rt.type({
type: rt.literal(ConnectorTypes.serviceNowITSM),
fields: rt.union([ServiceNowITSMFieldsRT, rt.null]),
});

const ConnectorSwimlaneTypeFieldsRt = rt.type({
type: rt.literal(ConnectorTypes.swimlane),
fields: rt.union([SwimlaneFieldsRT, rt.null]),
});

const ConnectorServiceNowSIRTypeFieldsRt = rt.type({
type: rt.literal(ConnectorTypes.serviceNowSIR),
fields: rt.union([ServiceNowSIRFieldsRT, rt.null]),
});

const ConnectorNoneTypeFieldsRt = rt.type({
type: rt.literal(ConnectorTypes.none),
fields: rt.null,
});

export const NONE_CONNECTOR_ID: string = 'none';

export const ConnectorTypeFieldsRt = rt.union([
ConnectorCasesWebhookTypeFieldsRt,
ConnectorJiraTypeFieldsRt,
ConnectorNoneTypeFieldsRt,
ConnectorResilientTypeFieldsRt,
ConnectorServiceNowITSMTypeFieldsRt,
ConnectorServiceNowSIRTypeFieldsRt,
ConnectorSwimlaneTypeFieldsRt,
]);

/**
* This type represents the connector's format when it is encoded within a user action.
*/
export const CaseUserActionConnectorRt = rt.union([
rt.intersection([ConnectorCasesWebhookTypeFieldsRt, rt.type({ name: rt.string })]),
rt.intersection([ConnectorJiraTypeFieldsRt, rt.type({ name: rt.string })]),
rt.intersection([ConnectorNoneTypeFieldsRt, rt.type({ name: rt.string })]),
rt.intersection([ConnectorResilientTypeFieldsRt, rt.type({ name: rt.string })]),
rt.intersection([ConnectorServiceNowITSMTypeFieldsRt, rt.type({ name: rt.string })]),
rt.intersection([ConnectorServiceNowSIRTypeFieldsRt, rt.type({ name: rt.string })]),
rt.intersection([ConnectorSwimlaneTypeFieldsRt, rt.type({ name: rt.string })]),
]);

export const CaseConnectorRt = rt.intersection([
rt.type({
id: rt.string,
}),
CaseUserActionConnectorRt,
]);

export const GetCaseConnectorsResponseRt = rt.record(
rt.string,
rt.intersection([
rt.type({ needsToBePushed: rt.boolean, hasBeenPushed: rt.boolean }),
rt.partial(rt.type({ latestPushDate: rt.string, oldestPushDate: rt.string }).props),
CaseConnectorRt,
])
);

export type CaseUserActionConnector = rt.TypeOf<typeof CaseUserActionConnectorRt>;
export type CaseConnector = rt.TypeOf<typeof CaseConnectorRt>;
export type ConnectorTypeFields = rt.TypeOf<typeof ConnectorTypeFieldsRt>;
export type ConnectorCasesWebhookTypeFields = rt.TypeOf<typeof ConnectorCasesWebhookTypeFieldsRt>;
export type ConnectorJiraTypeFields = rt.TypeOf<typeof ConnectorJiraTypeFieldsRt>;
export type ConnectorResilientTypeFields = rt.TypeOf<typeof ConnectorResilientTypeFieldsRt>;
export type ConnectorSwimlaneTypeFields = rt.TypeOf<typeof ConnectorSwimlaneTypeFieldsRt>;
export type ConnectorServiceNowITSMTypeFields = rt.TypeOf<
typeof ConnectorServiceNowITSMTypeFieldsRt
>;
export type ConnectorServiceNowSIRTypeFields = rt.TypeOf<typeof ConnectorServiceNowSIRTypeFieldsRt>;

// we need to change these types back and forth for storing in ES (arrays overwrite, objects merge)
export type ConnectorFields = rt.TypeOf<typeof ConnectorFieldsRt>;

export type GetCaseConnectorsResponse = rt.TypeOf<typeof GetCaseConnectorsResponseRt>;
export * from './get_connectors';
export * from './connector';
5 changes: 5 additions & 0 deletions x-pack/plugins/cases/common/api/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
CASE_ALERTS_URL,
CASE_COMMENT_DELETE_URL,
CASE_FIND_USER_ACTIONS_URL,
INTERNAL_CONNECTORS_URL,
} from '../constants';

export const getCaseDetailsUrl = (id: string): string => {
Expand Down Expand Up @@ -57,3 +58,7 @@ export const getCaseConfigurationDetailsUrl = (configureID: string): string => {
export const getCasesFromAlertsUrl = (alertId: string): string => {
return CASE_ALERTS_URL.replace('{alert_id}', alertId);
};

export const getCaseConnectorsUrl = (id: string): string => {
return INTERNAL_CONNECTORS_URL.replace('{case_id}', id);
};
4 changes: 2 additions & 2 deletions x-pack/plugins/cases/common/ui/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import type {
CaseStatuses,
User,
ActionConnector,
CaseExternalServiceBasic,
CaseUserActionResponse,
SingleCaseMetricsResponse,
CommentResponse,
Expand All @@ -29,6 +28,7 @@ import type {
CaseSeverity,
CommentResponseExternalReferenceType,
CommentResponseTypePersistableState,
GetCaseConnectorsResponse,
} from '../api';
import type { PUSH_CASES_CAPABILITY } from '../constants';
import type { SnakeToCamelCase } from '../types';
Expand Down Expand Up @@ -77,12 +77,12 @@ export type AlertComment = SnakeToCamelCase<CommentResponseAlertsType>;
export type ExternalReferenceComment = SnakeToCamelCase<CommentResponseExternalReferenceType>;
export type PersistableComment = SnakeToCamelCase<CommentResponseTypePersistableState>;
export type CaseUserActions = SnakeToCamelCase<CaseUserActionResponse>;
export type CaseExternalService = SnakeToCamelCase<CaseExternalServiceBasic>;
export type Case = Omit<SnakeToCamelCase<CaseResponse>, 'comments'> & { comments: Comment[] };
export type Cases = Omit<SnakeToCamelCase<CasesFindResponse>, 'cases'> & { cases: Case[] };
export type CasesStatus = SnakeToCamelCase<CasesStatusResponse>;
export type CasesMetrics = SnakeToCamelCase<CasesMetricsResponse>;
export type CaseUpdateRequest = SnakeToCamelCase<CasePatchRequest>;
export type CaseConnectors = SnakeToCamelCase<GetCaseConnectorsResponse>;

export interface ResolvedCase {
case: Case;
Expand Down
Loading