diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/config.test.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/config.test.ts
index 26550f1732655..8830b2cc23c38 100644
--- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/config.test.ts
+++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/config.test.ts
@@ -24,6 +24,7 @@ describe('config', () => {
table: 'incident',
useImportAPI: true,
commentFieldKey: 'work_notes',
+ appId: '7148dbc91bf1f450ced060a7234bcb88',
});
});
@@ -35,6 +36,7 @@ describe('config', () => {
table: 'sn_si_incident',
useImportAPI: true,
commentFieldKey: 'work_notes',
+ appId: '2f0746801baeb01019ae54e4604bcb0f',
});
});
diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/config.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/config.ts
index ba29bcc39b25a..11f18f0407fdf 100644
--- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/config.ts
+++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/config.ts
@@ -14,6 +14,9 @@ export const ServiceNowITSMActionTypeId = '.servicenow';
export const ServiceNowSIRActionTypeId = '.servicenow-sir';
export const ServiceNowITOMActionTypeId = '.servicenow-itom';
+const SN_ITSM_APP_ID = '7148dbc91bf1f450ced060a7234bcb88';
+const SN_SIR_APP_ID = '2f0746801baeb01019ae54e4604bcb0f';
+
export const snExternalServiceConfig: SNProductsConfig = {
'.servicenow': {
importSetTable: 'x_elas2_inc_int_elastic_incident',
@@ -21,6 +24,7 @@ export const snExternalServiceConfig: SNProductsConfig = {
table: 'incident',
useImportAPI: true,
commentFieldKey: 'work_notes',
+ appId: SN_ITSM_APP_ID,
},
'.servicenow-sir': {
importSetTable: 'x_elas2_sir_int_elastic_si_incident',
@@ -28,6 +32,7 @@ export const snExternalServiceConfig: SNProductsConfig = {
table: 'sn_si_incident',
useImportAPI: true,
commentFieldKey: 'work_notes',
+ appId: SN_SIR_APP_ID,
},
'.servicenow-itom': {
importSetTable: 'x_elas2_inc_int_elastic_incident',
diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/types.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/types.ts
index 31af3781c6b04..352a0c22c7ec8 100644
--- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/types.ts
+++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/types.ts
@@ -253,6 +253,7 @@ export interface SNProductsConfigValue {
useImportAPI: boolean;
importSetTable: string;
commentFieldKey: string;
+ appId?: string;
}
export type SNProductsConfig = Record;
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/application_required_callout.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/application_required_callout.test.tsx
index 67c3238b04774..cf192305a14fb 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/application_required_callout.test.tsx
+++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/application_required_callout.test.tsx
@@ -9,9 +9,11 @@ import React from 'react';
import { render, screen } from '@testing-library/react';
import { ApplicationRequiredCallout } from './application_required_callout';
+const appId = 'test';
+
describe('ApplicationRequiredCallout', () => {
test('it renders the callout', () => {
- render();
+ render();
expect(screen.getByText('Elastic ServiceNow App not installed')).toBeInTheDocument();
expect(
screen.getByText('Please go to the ServiceNow app store and install the application')
@@ -19,12 +21,20 @@ describe('ApplicationRequiredCallout', () => {
});
test('it renders the ServiceNow store button', () => {
- render();
+ render();
expect(screen.getByText('Visit ServiceNow app store')).toBeInTheDocument();
});
+ it('should render with correct href for the ServiceNow store button', () => {
+ render();
+ expect(screen.getByRole('link')).toHaveAttribute(
+ 'href',
+ 'https://store.servicenow.com/sn_appstore_store.do#!/store/application/test'
+ );
+ });
+
test('it renders an error message if provided', () => {
- render();
+ render();
expect(screen.getByText('Error message: Denied')).toBeInTheDocument();
});
});
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/application_required_callout.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/application_required_callout.tsx
index 2faa5a9f4a5e0..462d68d50508d 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/application_required_callout.tsx
+++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/application_required_callout.tsx
@@ -25,10 +25,11 @@ const ERROR_MESSAGE = i18n.translate(
);
interface Props {
+ appId: string;
message?: string | null;
}
-const ApplicationRequiredCalloutComponent: React.FC = ({ message }) => {
+const ApplicationRequiredCalloutComponent: React.FC = ({ appId, message }) => {
return (
<>
@@ -50,7 +51,7 @@ const ApplicationRequiredCalloutComponent: React.FC = ({ message }) => {
{ERROR_MESSAGE}: {message}
)}
-
+
>
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/installation_callout.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/installation_callout.test.tsx
index ee63a546e6aa1..9b3d00973cd6d 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/installation_callout.test.tsx
+++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/installation_callout.test.tsx
@@ -10,9 +10,11 @@ import { render, screen } from '@testing-library/react';
import { InstallationCallout } from './installation_callout';
+const appId = 'test';
+
describe('DeprecatedCallout', () => {
test('it renders correctly', () => {
- render();
+ render();
expect(
screen.getByText(
'To use this connector, first install the Elastic app from the ServiceNow app store.'
@@ -21,7 +23,15 @@ describe('DeprecatedCallout', () => {
});
test('it renders the button', () => {
- render();
+ render();
expect(screen.getByRole('link')).toBeInTheDocument();
});
+
+ it('should render with correct href for the ServiceNow store button', () => {
+ render();
+ expect(screen.getByRole('link')).toHaveAttribute(
+ 'href',
+ 'https://store.servicenow.com/sn_appstore_store.do#!/store/application/test'
+ );
+ });
});
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/installation_callout.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/installation_callout.tsx
index 064207910568f..536cf8923abd1 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/installation_callout.tsx
+++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/installation_callout.tsx
@@ -11,7 +11,11 @@ import { EuiSpacer, EuiCallOut } from '@elastic/eui';
import * as i18n from './translations';
import { SNStoreButton } from './sn_store_button';
-const InstallationCalloutComponent: React.FC = () => {
+interface Props {
+ appId: string;
+}
+
+const InstallationCalloutComponent: React.FC = ({ appId }) => {
return (
<>
@@ -22,7 +26,7 @@ const InstallationCalloutComponent: React.FC = () => {
data-test-subj="snInstallationCallout"
title={i18n.INSTALLATION_CALLOUT_TITLE}
>
-
+
>
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx
index db3c32755f0ed..7c53d4322ddb9 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx
+++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx
@@ -20,6 +20,8 @@ import { InstallationCallout } from './installation_callout';
import { UpdateConnector } from './update_connector';
import { updateActionConnector } from '../../../lib/action_connector_api';
import { Credentials } from './credentials';
+// eslint-disable-next-line @kbn/eslint/no-restricted-paths
+import { snExternalServiceConfig } from '../../../../../../actions/server/builtin_action_types/servicenow/config';
const ServiceNowConnectorFields: React.FC> =
({
@@ -151,7 +153,9 @@ const ServiceNowConnectorFields: React.FC
)}
- {requiresNewApplication && }
+ {requiresNewApplication && (
+
+ )}
{!requiresNewApplication && }
{showApplicationRequiredCallout && requiresNewApplication && (
-
+
)}
>
);
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/sn_store_button.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/sn_store_button.test.tsx
index 500325202b651..795101d9dbc59 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/sn_store_button.test.tsx
+++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/sn_store_button.test.tsx
@@ -9,41 +9,49 @@ import React from 'react';
import { render, screen } from '@testing-library/react';
import { SNStoreButton, SNStoreLink } from './sn_store_button';
+const appId = 'test';
+
describe('SNStoreButton', () => {
it('should render the button', () => {
- render();
+ render();
expect(screen.getByText('Visit ServiceNow app store')).toBeInTheDocument();
});
it('should render a danger button', () => {
- render();
+ render();
expect(screen.getByRole('link')).toHaveClass('euiButton--danger');
});
it('should render with correct href', () => {
- render();
- expect(screen.getByRole('link')).toHaveAttribute('href', 'https://store.servicenow.com/');
+ render();
+ expect(screen.getByRole('link')).toHaveAttribute(
+ 'href',
+ 'https://store.servicenow.com/sn_appstore_store.do#!/store/application/test'
+ );
});
it('should render with target blank', () => {
- render();
+ render();
expect(screen.getByRole('link')).toHaveAttribute('target', '_blank');
});
});
describe('SNStoreLink', () => {
it('should render the link', () => {
- render();
+ render();
expect(screen.getByText('Visit ServiceNow app store')).toBeInTheDocument();
});
it('should render with correct href', () => {
- render();
- expect(screen.getByRole('link')).toHaveAttribute('href', 'https://store.servicenow.com/');
+ render();
+ expect(screen.getByRole('link')).toHaveAttribute(
+ 'href',
+ 'https://store.servicenow.com/sn_appstore_store.do#!/store/application/test'
+ );
});
it('should render with target blank', () => {
- render();
+ render();
expect(screen.getByRole('link')).toHaveAttribute('target', '_blank');
});
});
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/sn_store_button.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/sn_store_button.tsx
index 5a33237159a02..3cbec513d179c 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/sn_store_button.tsx
+++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/sn_store_button.tsx
@@ -10,15 +10,23 @@ import { EuiButtonProps, EuiButton, EuiLink } from '@elastic/eui';
import * as i18n from './translations';
-const STORE_URL = 'https://store.servicenow.com/';
+const getStoreURL = (appId: string): string =>
+ `https://store.servicenow.com/sn_appstore_store.do#!/store/application/${appId}`;
interface Props {
+ appId: string;
color: EuiButtonProps['color'];
}
-const SNStoreButtonComponent: React.FC = ({ color }) => {
+const SNStoreButtonComponent: React.FC = ({ color, appId }) => {
return (
-
+
{i18n.VISIT_SN_STORE}
);
@@ -26,8 +34,8 @@ const SNStoreButtonComponent: React.FC = ({ color }) => {
export const SNStoreButton = memo(SNStoreButtonComponent);
-const SNStoreLinkComponent: React.FC = () => (
-
+const SNStoreLinkComponent: React.FC> = ({ appId }) => (
+
{i18n.VISIT_SN_STORE}
);
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/update_connector.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/update_connector.tsx
index 02127eb6ff4f0..f937b4e0a9be4 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/update_connector.tsx
+++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/update_connector.tsx
@@ -28,6 +28,8 @@ import { isFieldInvalid } from './helpers';
import { ApplicationRequiredCallout } from './application_required_callout';
import { SNStoreLink } from './sn_store_button';
import { CredentialsAuth } from './credentials_auth';
+// eslint-disable-next-line @kbn/eslint/no-restricted-paths
+import { snExternalServiceConfig } from '../../../../../../actions/server/builtin_action_types/servicenow/config';
const title = i18n.translate(
'xpack.triggersActionsUI.components.builtinActionTypes.serviceNow.updateFormTitle',
@@ -140,7 +142,11 @@ const UpdateConnectorComponent: React.FC = ({
id="xpack.triggersActionsUI.components.builtinActionTypes.serviceNowAction.serviceNowAppRunning"
defaultMessage="The Elastic App from the ServiceNow app store must be installed prior to running the update. {visitLink} to install the app"
values={{
- visitLink: ,
+ visitLink: (
+
+ ),
}}
/>
),
@@ -175,7 +181,10 @@ const UpdateConnectorComponent: React.FC = ({
{applicationInfoErrorMsg && (
-
+
)}