From f82f5b39ff52ad6fcd8f317e38fe780b0aa94367 Mon Sep 17 00:00:00 2001
From: Ying Mao
Date: Fri, 29 Jan 2021 10:29:21 -0500
Subject: [PATCH 01/13] Adding tooltips to alert list and modal for license
upgrade
---
.../components/alert_details.tsx | 453 ++++++++++--------
.../components/manage_license_modal.tsx | 45 ++
.../alerts_list/components/alerts_list.tsx | 17 +-
.../sections/alerts_list/translations.ts | 18 +-
4 files changed, 311 insertions(+), 222 deletions(-)
create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/manage_license_modal.tsx
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details.tsx
index c2a64bfa3a207..53e4b8672a216 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details.tsx
+++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details.tsx
@@ -39,9 +39,13 @@ import { AlertInstancesRouteWithApi } from './alert_instances_route';
import { ViewInApp } from './view_in_app';
import { AlertEdit } from '../../alert_form';
import { routeToAlertDetails } from '../../../constants';
-import { alertsErrorReasonTranslationsMapping } from '../../alerts_list/translations';
+import {
+ alertsErrorReasonTranslationsMapping,
+ AlertErrorReasons,
+} from '../../alerts_list/translations';
import { useKibana } from '../../../../common/lib/kibana';
import { alertReducer } from '../../alert_form/alert_reducer';
+import { ManageLicenseModal } from './manage_license_modal';
type AlertDetailsProps = {
alert: Alert;
@@ -99,12 +103,15 @@ export const AlertDetails: React.FunctionComponent = ({
? !alertTypeRegistry.get(alert.alertTypeId).requiresAppContext
: false);
+ const licenseManagementLink = `${http.basePath.get()}/app/management/stack/license_management`;
+
const alertActions = alert.actions;
const uniqueActions = Array.from(new Set(alertActions.map((item: any) => item.actionTypeId)));
const [isEnabled, setIsEnabled] = useState(alert.enabled);
const [isMuted, setIsMuted] = useState(alert.muteAll);
const [editFlyoutVisible, setEditFlyoutVisibility] = useState(false);
- const [dissmissAlertErrors, setDissmissAlertErrors] = useState(false);
+ const [dismissAlertErrors, setDismissAlertErrors] = useState(false);
+ const [isManageLicenseModalOpen, setIsManageLicenseModalOpen] = useState(false);
const setAlert = async () => {
history.push(routeToAlertDetails.replace(`:alertId`, alert.id));
@@ -118,234 +125,254 @@ export const AlertDetails: React.FunctionComponent = ({
}
};
+ useEffect(() => {
+ setIsManageLicenseModalOpen(
+ alert.executionStatus.error &&
+ alert.executionStatus.error.reason &&
+ alert.executionStatus.error.reason === AlertErrorReasons.LICENSE
+ );
+ }, [alert.executionStatus.error]);
+
return (
-
-
-
-
-
-
-
- {alert.name}
-
-
-
-
-
- {hasEditButton ? (
+ <>
+
+
+
+
+
+
+
+ {alert.name}
+
+
+
+
+
+ {hasEditButton ? (
+
+
+ {' '}
+ setEditFlyoutVisibility(true)}
+ name="edit"
+ disabled={!alertType.enabledInLicense}
+ >
+
+
+ {editFlyoutVisible && (
+ {
+ setInitialAlert(alert);
+ setEditFlyoutVisibility(false);
+ }}
+ actionTypeRegistry={actionTypeRegistry}
+ alertTypeRegistry={alertTypeRegistry}
+ reloadAlerts={setAlert}
+ />
+ )}
+
+
+ ) : null}
-
- {' '}
- setEditFlyoutVisibility(true)}
- name="edit"
- disabled={!alertType.enabledInLicense}
- >
-
-
- {editFlyoutVisible && (
- {
- setInitialAlert(alert);
- setEditFlyoutVisibility(false);
- }}
- actionTypeRegistry={actionTypeRegistry}
- alertTypeRegistry={alertTypeRegistry}
- reloadAlerts={setAlert}
- />
- )}
-
+
+
+
+
+
+
- ) : null}
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+ {alertType.name}
+
+
+ {uniqueActions && uniqueActions.length ? (
+
+
+
+
+
+
+
+
+ {uniqueActions.map((action, index) => (
+
+
+ {actionTypesByTypeId[action].name ?? action}
+
+
+ ))}
+
+
+ ) : null}
-
+
+
+
+ {
+ if (isEnabled) {
+ setIsEnabled(false);
+ await disableAlert(alert);
+ } else {
+ setIsEnabled(true);
+ await enableAlert(alert);
+ }
+ requestRefresh();
+ }}
+ label={
+
+ }
+ />
+
+
+ {
+ if (isMuted) {
+ setIsMuted(false);
+ await unmuteAlert(alert);
+ } else {
+ setIsMuted(true);
+ await muteAlert(alert);
+ }
+ requestRefresh();
+ }}
+ label={
+
+ }
+ />
+
+
-
-
-
-
-
-
-
-
-
-
-
- {alertType.name}
-
-
- {uniqueActions && uniqueActions.length ? (
-
-
-
-
-
-
-
-
- {uniqueActions.map((action, index) => (
-
-
- {actionTypesByTypeId[action].name ?? action}
-
+ {!dismissAlertErrors && alert.executionStatus.status === 'error' ? (
+
+
+
+
+ {alert.executionStatus.error?.message}
+
+
+
+
+ setDismissAlertErrors(true)}>
+
+
- ))}
-
-
- ) : null}
-
-
-
-
-
- {
- if (isEnabled) {
- setIsEnabled(false);
- await disableAlert(alert);
- } else {
- setIsEnabled(true);
- await enableAlert(alert);
- }
- requestRefresh();
- }}
- label={
-
- }
- />
-
-
- {
- if (isMuted) {
- setIsMuted(false);
- await unmuteAlert(alert);
- } else {
- setIsMuted(true);
- await muteAlert(alert);
- }
- requestRefresh();
- }}
- label={
-
- }
- />
+ {alert.executionStatus.error?.reason ===
+ AlertExecutionStatusErrorReasons.License && (
+
+
+
+
+
+ )}
+
+
-
-
- {!dissmissAlertErrors && alert.executionStatus.status === 'error' ? (
+ ) : null}
-
-
- {alert.executionStatus.error?.message}
-
-
-
-
- setDissmissAlertErrors(true)}>
+ {alert.enabled ? (
+
+ ) : (
+
+
+
+
-
-
- {alert.executionStatus.error?.reason ===
- AlertExecutionStatusErrorReasons.License && (
-
-
-
-
-
- )}
-
-
+
+
+
+ )}
- ) : null}
-
-
- {alert.enabled ? (
-
- ) : (
-
-
-
-
-
-
-
-
- )}
-
-
-
-
-
-
+
+
+
+
+ {isManageLicenseModalOpen && (
+ {
+ window.open(licenseManagementLink, '_blank');
+ }}
+ onCancel={() => setIsManageLicenseModalOpen(false)}
+ />
+ )}
+ >
);
};
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/manage_license_modal.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/manage_license_modal.tsx
new file mode 100644
index 0000000000000..e2e2212943357
--- /dev/null
+++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/manage_license_modal.tsx
@@ -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;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React from 'react';
+import { i18n } from '@kbn/i18n';
+import { EuiOverlayMask, EuiConfirmModal } from '@elastic/eui';
+
+interface Props {
+ message: string;
+ onConfirm: () => void;
+ onCancel: () => void;
+}
+
+export const ManageLicenseModal: React.FC = ({ message, onConfirm, onCancel }) => {
+ return (
+
+
+ {message}
+
+
+ );
+};
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx
index 293d471560503..4cbe915769b99 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx
+++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx
@@ -96,7 +96,7 @@ export const AlertsList: React.FunctionComponent = () => {
const [actionTypesFilter, setActionTypesFilter] = useState([]);
const [alertStatusesFilter, setAlertStatusesFilter] = useState([]);
const [alertFlyoutVisible, setAlertFlyoutVisibility] = useState(false);
- const [dissmissAlertErrors, setDissmissAlertErrors] = useState(false);
+ const [dismissAlertErrors, setDismissAlertErrors] = useState(false);
const [alertsStatusesTotal, setAlertsStatusesTotal] = useState>(
AlertExecutionStatusValues.reduce(
(prev: Record, status: string) =>
@@ -249,11 +249,20 @@ export const AlertsList: React.FunctionComponent = () => {
'data-test-subj': 'alertsTableCell-status',
render: (executionStatus: AlertExecutionStatus) => {
const healthColor = getHealthColor(executionStatus.status);
- return (
+ const tooltipMessage =
+ executionStatus.status === 'error' ? `Error: ${executionStatus?.error?.message}` : null;
+ const health = (
{alertsStatusesTranslationsMapping[executionStatus.status]}
);
+ return tooltipMessage ? (
+
+ {health}
+
+ ) : (
+ health
+ );
},
},
{
@@ -491,7 +500,7 @@ export const AlertsList: React.FunctionComponent = () => {
- {!dissmissAlertErrors && alertsStatusesTotal.error > 0 ? (
+ {!dismissAlertErrors && alertsStatusesTotal.error > 0 ? (
{
defaultMessage="View"
/>
- setDissmissAlertErrors(true)}>
+ setDismissAlertErrors(true)}>
Date: Mon, 1 Feb 2021 10:19:25 -0500
Subject: [PATCH 02/13] Fixing typings
---
.../alert_details/components/alert_details.tsx | 11 +++++------
.../components/manage_license_modal.tsx | 2 +-
.../sections/alerts_list/translations.ts | 18 +++++-------------
3 files changed, 11 insertions(+), 20 deletions(-)
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details.tsx
index 53e4b8672a216..a7f99663dbf0f 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details.tsx
+++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details.tsx
@@ -39,10 +39,7 @@ import { AlertInstancesRouteWithApi } from './alert_instances_route';
import { ViewInApp } from './view_in_app';
import { AlertEdit } from '../../alert_form';
import { routeToAlertDetails } from '../../../constants';
-import {
- alertsErrorReasonTranslationsMapping,
- AlertErrorReasons,
-} from '../../alerts_list/translations';
+import { alertsErrorReasonTranslationsMapping } from '../../alerts_list/translations';
import { useKibana } from '../../../../common/lib/kibana';
import { alertReducer } from '../../alert_form/alert_reducer';
import { ManageLicenseModal } from './manage_license_modal';
@@ -127,9 +124,11 @@ export const AlertDetails: React.FunctionComponent = ({
useEffect(() => {
setIsManageLicenseModalOpen(
- alert.executionStatus.error &&
+ !!(
+ alert.executionStatus.error &&
alert.executionStatus.error.reason &&
- alert.executionStatus.error.reason === AlertErrorReasons.LICENSE
+ alert.executionStatus.error.reason === AlertExecutionStatusErrorReasons.License
+ )
);
}, [alert.executionStatus.error]);
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/manage_license_modal.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/manage_license_modal.tsx
index e2e2212943357..489cf1d949454 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/manage_license_modal.tsx
+++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/manage_license_modal.tsx
@@ -9,7 +9,7 @@ import { i18n } from '@kbn/i18n';
import { EuiOverlayMask, EuiConfirmModal } from '@elastic/eui';
interface Props {
- message: string;
+ message?: string;
onConfirm: () => void;
onCancel: () => void;
}
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/translations.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/translations.ts
index 0d29b42d22254..a57cca5476420 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/translations.ts
+++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/translations.ts
@@ -84,18 +84,10 @@ export const ALERT_ERROR_LICENSE_REASON = i18n.translate(
}
);
-export enum AlertErrorReasons {
- READ = 'read',
- DECRYPT = 'decrypt',
- EXECUTE = 'execute',
- UNKNOWN = 'unknown',
- LICENSE = 'license',
-}
-
export const alertsErrorReasonTranslationsMapping = {
- [AlertErrorReasons.READ]: ALERT_ERROR_READING_REASON,
- [AlertErrorReasons.DECRYPT]: ALERT_ERROR_DECRYPTING_REASON,
- [AlertErrorReasons.EXECUTE]: ALERT_ERROR_EXECUTION_REASON,
- [AlertErrorReasons.UNKNOWN]: ALERT_ERROR_UNKNOWN_REASON,
- [AlertErrorReasons.LICENSE]: ALERT_ERROR_LICENSE_REASON,
+ read: ALERT_ERROR_READING_REASON,
+ decrypt: ALERT_ERROR_DECRYPTING_REASON,
+ execute: ALERT_ERROR_EXECUTION_REASON,
+ unknown: ALERT_ERROR_UNKNOWN_REASON,
+ license: ALERT_ERROR_LICENSE_REASON,
};
From 9e3055ce6c3c01a29a0a219f4ec51ba41e091ad6 Mon Sep 17 00:00:00 2001
From: Ying Mao
Date: Mon, 1 Feb 2021 14:56:35 -0500
Subject: [PATCH 03/13] Custom License Error status. Moving modal to alerts
list page
---
.../components/alert_details.tsx | 449 +++++++++---------
.../alerts_list/components/alerts_list.tsx | 99 ++--
.../components/manage_license_modal.tsx | 0
.../sections/alerts_list/translations.ts | 7 +
4 files changed, 290 insertions(+), 265 deletions(-)
rename x-pack/plugins/triggers_actions_ui/public/application/sections/{alert_details => alerts_list}/components/manage_license_modal.tsx (100%)
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details.tsx
index a7f99663dbf0f..1cf5a9a61997b 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details.tsx
+++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details.tsx
@@ -42,7 +42,6 @@ import { routeToAlertDetails } from '../../../constants';
import { alertsErrorReasonTranslationsMapping } from '../../alerts_list/translations';
import { useKibana } from '../../../../common/lib/kibana';
import { alertReducer } from '../../alert_form/alert_reducer';
-import { ManageLicenseModal } from './manage_license_modal';
type AlertDetailsProps = {
alert: Alert;
@@ -100,15 +99,12 @@ export const AlertDetails: React.FunctionComponent = ({
? !alertTypeRegistry.get(alert.alertTypeId).requiresAppContext
: false);
- const licenseManagementLink = `${http.basePath.get()}/app/management/stack/license_management`;
-
const alertActions = alert.actions;
const uniqueActions = Array.from(new Set(alertActions.map((item: any) => item.actionTypeId)));
const [isEnabled, setIsEnabled] = useState(alert.enabled);
const [isMuted, setIsMuted] = useState(alert.muteAll);
const [editFlyoutVisible, setEditFlyoutVisibility] = useState(false);
const [dismissAlertErrors, setDismissAlertErrors] = useState(false);
- const [isManageLicenseModalOpen, setIsManageLicenseModalOpen] = useState(false);
const setAlert = async () => {
history.push(routeToAlertDetails.replace(`:alertId`, alert.id));
@@ -122,256 +118,235 @@ export const AlertDetails: React.FunctionComponent = ({
}
};
- useEffect(() => {
- setIsManageLicenseModalOpen(
- !!(
- alert.executionStatus.error &&
- alert.executionStatus.error.reason &&
- alert.executionStatus.error.reason === AlertExecutionStatusErrorReasons.License
- )
- );
- }, [alert.executionStatus.error]);
-
return (
- <>
-
-
-
-
-
-
-
- {alert.name}
-
-
-
-
-
- {hasEditButton ? (
-
-
- {' '}
- setEditFlyoutVisibility(true)}
- name="edit"
- disabled={!alertType.enabledInLicense}
- >
-
-
- {editFlyoutVisible && (
- {
- setInitialAlert(alert);
- setEditFlyoutVisibility(false);
- }}
- actionTypeRegistry={actionTypeRegistry}
- alertTypeRegistry={alertTypeRegistry}
- reloadAlerts={setAlert}
- />
- )}
-
-
- ) : null}
+
+
+
+
+
+
+
+ {alert.name}
+
+
+
+
+
+ {hasEditButton ? (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {alertType.name}
-
-
- {uniqueActions && uniqueActions.length ? (
-
-
-
-
-
-
-
- {uniqueActions.map((action, index) => (
-
-
- {actionTypesByTypeId[action].name ?? action}
-
-
- ))}
-
+ {' '}
+ setEditFlyoutVisibility(true)}
+ name="edit"
+ disabled={!alertType.enabledInLicense}
+ >
+
+
+ {editFlyoutVisible && (
+ {
+ setInitialAlert(alert);
+ setEditFlyoutVisibility(false);
+ }}
+ actionTypeRegistry={actionTypeRegistry}
+ alertTypeRegistry={alertTypeRegistry}
+ reloadAlerts={setAlert}
+ />
+ )}
- ) : null}
+
+ ) : null}
+
+
+
+
-
-
-
- {
- if (isEnabled) {
- setIsEnabled(false);
- await disableAlert(alert);
- } else {
- setIsEnabled(true);
- await enableAlert(alert);
- }
- requestRefresh();
- }}
- label={
-
- }
- />
-
-
- {
- if (isMuted) {
- setIsMuted(false);
- await unmuteAlert(alert);
- } else {
- setIsMuted(true);
- await muteAlert(alert);
- }
- requestRefresh();
- }}
- label={
-
- }
- />
-
-
+
- {!dismissAlertErrors && alert.executionStatus.status === 'error' ? (
-
-
-
-
- {alert.executionStatus.error?.message}
-
-
-
-
- setDismissAlertErrors(true)}>
-
-
+
+
+
+
+
+
+
+
+
+
+
+ {alertType.name}
+
+
+ {uniqueActions && uniqueActions.length ? (
+
+
+
+
+
+
+
+
+ {uniqueActions.map((action, index) => (
+
+
+ {actionTypesByTypeId[action].name ?? action}
+
- {alert.executionStatus.error?.reason ===
- AlertExecutionStatusErrorReasons.License && (
-
-
-
-
-
- )}
-
-
+ ))}
+
+
+ ) : null}
+
+
+
+
+
+ {
+ if (isEnabled) {
+ setIsEnabled(false);
+ await disableAlert(alert);
+ } else {
+ setIsEnabled(true);
+ await enableAlert(alert);
+ }
+ requestRefresh();
+ }}
+ label={
+
+ }
+ />
+
+
+ {
+ if (isMuted) {
+ setIsMuted(false);
+ await unmuteAlert(alert);
+ } else {
+ setIsMuted(true);
+ await muteAlert(alert);
+ }
+ requestRefresh();
+ }}
+ label={
+
+ }
+ />
- ) : null}
+
+
+ {!dismissAlertErrors && alert.executionStatus.status === 'error' ? (
- {alert.enabled ? (
-
- ) : (
-
-
-
-
+
+
+ {alert.executionStatus.error?.message}
+
+
+
+
+ setDismissAlertErrors(true)}>
-
-
-
- )}
+
+
+ {alert.executionStatus.error?.reason ===
+ AlertExecutionStatusErrorReasons.License && (
+
+
+
+
+
+ )}
+
+
-
-
-
-
- {isManageLicenseModalOpen && (
- {
- window.open(licenseManagementLink, '_blank');
- }}
- onCancel={() => setIsManageLicenseModalOpen(false)}
- />
- )}
- >
+ ) : null}
+
+
+ {alert.enabled ? (
+
+ ) : (
+
+
+
+
+
+
+
+
+ )}
+
+
+
+
+
+
);
};
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx
index 4cbe915769b99..d4dd22ed3d557 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx
+++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx
@@ -52,14 +52,16 @@ import {
AlertExecutionStatus,
AlertExecutionStatusValues,
ALERTS_FEATURE_ID,
+ AlertExecutionStatusErrorReasons,
} from '../../../../../../alerts/common';
import { hasAllPrivilege } from '../../../lib/capabilities';
-import { alertsStatusesTranslationsMapping } from '../translations';
+import { alertsStatusesTranslationsMapping, ALERT_STATUS_LICENSE_ERROR } from '../translations';
import { useKibana } from '../../../../common/lib/kibana';
import { checkAlertTypeEnabled } from '../../../lib/check_alert_type_enabled';
import { DEFAULT_HIDDEN_ACTION_TYPES } from '../../../../common/constants';
import './alerts_list.scss';
import { CenterJustifiedSpinner } from '../../../components/center_justified_spinner';
+import { ManageLicenseModal } from './manage_license_modal';
const ENTER_KEY = 13;
@@ -97,6 +99,7 @@ export const AlertsList: React.FunctionComponent = () => {
const [alertStatusesFilter, setAlertStatusesFilter] = useState([]);
const [alertFlyoutVisible, setAlertFlyoutVisibility] = useState(false);
const [dismissAlertErrors, setDismissAlertErrors] = useState(false);
+ const [manageLicenseMessage, setManageLicenseMessage] = useState(undefined);
const [alertsStatusesTotal, setAlertsStatusesTotal] = useState>(
AlertExecutionStatusValues.reduce(
(prev: Record, status: string) =>
@@ -237,34 +240,52 @@ export const AlertsList: React.FunctionComponent = () => {
}
}
+ const renderAlertExecutionStatus = (executionStatus: AlertExecutionStatus) => {
+ const healthColor = getHealthColor(executionStatus.status);
+ const tooltipMessage =
+ executionStatus.status === 'error' ? `Error: ${executionStatus?.error?.message}` : null;
+ const statusMessage =
+ executionStatus.error?.reason === AlertExecutionStatusErrorReasons.License
+ ? ALERT_STATUS_LICENSE_ERROR
+ : alertsStatusesTranslationsMapping[executionStatus.status];
+ const showLicenseLink =
+ executionStatus.error?.reason === AlertExecutionStatusErrorReasons.License;
+
+ const health = (
+
+ {statusMessage}
+
+ );
+
+ const healthWithTooltip = tooltipMessage ? (
+
+ {health}
+
+ ) : (
+ health
+ );
+
+ return (
+
+ {healthWithTooltip}
+ {showLicenseLink && (
+
+ setManageLicenseMessage(executionStatus?.error?.message)}
+ >
+
+
+
+ )}
+
+ );
+ };
+
const alertsTableColumns = [
- {
- field: 'executionStatus',
- name: i18n.translate(
- 'xpack.triggersActionsUI.sections.alertsList.alertsListTable.columns.statusTitle',
- { defaultMessage: 'Status' }
- ),
- sortable: false,
- truncateText: false,
- 'data-test-subj': 'alertsTableCell-status',
- render: (executionStatus: AlertExecutionStatus) => {
- const healthColor = getHealthColor(executionStatus.status);
- const tooltipMessage =
- executionStatus.status === 'error' ? `Error: ${executionStatus?.error?.message}` : null;
- const health = (
-
- {alertsStatusesTranslationsMapping[executionStatus.status]}
-
- );
- return tooltipMessage ? (
-
- {health}
-
- ) : (
- health
- );
- },
- },
{
field: 'name',
name: i18n.translate(
@@ -301,6 +322,19 @@ export const AlertsList: React.FunctionComponent = () => {
);
},
},
+ {
+ field: 'executionStatus',
+ name: i18n.translate(
+ 'xpack.triggersActionsUI.sections.alertsList.alertsListTable.columns.statusTitle',
+ { defaultMessage: 'Status' }
+ ),
+ sortable: false,
+ truncateText: false,
+ 'data-test-subj': 'alertsTableCell-status',
+ render: (executionStatus: AlertExecutionStatus) => {
+ return renderAlertExecutionStatus(executionStatus);
+ },
+ },
{
field: 'tagsText',
name: i18n.translate(
@@ -647,6 +681,15 @@ export const AlertsList: React.FunctionComponent = () => {
setPage(changedPage);
}}
/>
+ {manageLicenseMessage !== undefined && (
+ {
+ window.open(`${http.basePath.get()}/app/management/stack/license_management`, '_blank');
+ }}
+ onCancel={() => setManageLicenseMessage(undefined)}
+ />
+ )}
);
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/manage_license_modal.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/manage_license_modal.tsx
similarity index 100%
rename from x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/manage_license_modal.tsx
rename to x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/manage_license_modal.tsx
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/translations.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/translations.ts
index a57cca5476420..db174661c020e 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/translations.ts
+++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/translations.ts
@@ -27,6 +27,13 @@ export const ALERT_STATUS_ERROR = i18n.translate(
}
);
+export const ALERT_STATUS_LICENSE_ERROR = i18n.translate(
+ 'xpack.triggersActionsUI.sections.alertsList.alertStatusLicenseError',
+ {
+ defaultMessage: 'License Error',
+ }
+);
+
export const ALERT_STATUS_PENDING = i18n.translate(
'xpack.triggersActionsUI.sections.alertsList.alertStatusPending',
{
From 09af8f193e37ed280c2d0e7c18a7388bd4a11c13 Mon Sep 17 00:00:00 2001
From: Ying Mao
Date: Mon, 1 Feb 2021 21:25:43 -0500
Subject: [PATCH 04/13] Adding unit test
---
.../components/alerts_list.test.tsx | 265 +++++++++++-------
.../alerts_list/components/alerts_list.tsx | 20 +-
2 files changed, 172 insertions(+), 113 deletions(-)
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.test.tsx
index bd50bf3270f1a..9403e089d3ed6 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.test.tsx
+++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.test.tsx
@@ -125,11 +125,16 @@ describe('alerts_list component empty', () => {
wrapper.find('button[data-test-subj="createFirstAlertButton"]').simulate('click');
- // When the AlertAdd component is rendered, it waits for the healthcheck to resolve
- await new Promise((resolve) => {
- setTimeout(resolve, 1000);
+ await act(async () => {
+ // When the AlertAdd component is rendered, it waits for the healthcheck to resolve
+ await new Promise((resolve) => {
+ setTimeout(resolve, 1000);
+ });
+
+ await nextTick();
+ wrapper.update();
});
- wrapper.update();
+
expect(wrapper.find('AlertAdd').exists()).toEqual(true);
});
});
@@ -137,104 +142,131 @@ describe('alerts_list component empty', () => {
describe('alerts_list component with items', () => {
let wrapper: ReactWrapper;
+ const mockedAlertsData = [
+ {
+ id: '1',
+ name: 'test alert',
+ tags: ['tag1'],
+ enabled: true,
+ alertTypeId: 'test_alert_type',
+ schedule: { interval: '5d' },
+ actions: [],
+ params: { name: 'test alert type name' },
+ scheduledTaskId: null,
+ createdBy: null,
+ updatedBy: null,
+ apiKeyOwner: null,
+ throttle: '1m',
+ muteAll: false,
+ mutedInstanceIds: [],
+ executionStatus: {
+ status: 'active',
+ lastExecutionDate: new Date('2020-08-20T19:23:38Z'),
+ error: null,
+ },
+ },
+ {
+ id: '2',
+ name: 'test alert ok',
+ tags: ['tag1'],
+ enabled: true,
+ alertTypeId: 'test_alert_type',
+ schedule: { interval: '5d' },
+ actions: [],
+ params: { name: 'test alert type name' },
+ scheduledTaskId: null,
+ createdBy: null,
+ updatedBy: null,
+ apiKeyOwner: null,
+ throttle: '1m',
+ muteAll: false,
+ mutedInstanceIds: [],
+ executionStatus: {
+ status: 'ok',
+ lastExecutionDate: new Date('2020-08-20T19:23:38Z'),
+ error: null,
+ },
+ },
+ {
+ id: '3',
+ name: 'test alert pending',
+ tags: ['tag1'],
+ enabled: true,
+ alertTypeId: 'test_alert_type',
+ schedule: { interval: '5d' },
+ actions: [],
+ params: { name: 'test alert type name' },
+ scheduledTaskId: null,
+ createdBy: null,
+ updatedBy: null,
+ apiKeyOwner: null,
+ throttle: '1m',
+ muteAll: false,
+ mutedInstanceIds: [],
+ executionStatus: {
+ status: 'pending',
+ lastExecutionDate: new Date('2020-08-20T19:23:38Z'),
+ error: null,
+ },
+ },
+ {
+ id: '4',
+ name: 'test alert error',
+ tags: ['tag1'],
+ enabled: true,
+ alertTypeId: 'test_alert_type',
+ schedule: { interval: '5d' },
+ actions: [{ id: 'test', group: 'alert', params: { message: 'test' } }],
+ params: { name: 'test alert type name' },
+ scheduledTaskId: null,
+ createdBy: null,
+ updatedBy: null,
+ apiKeyOwner: null,
+ throttle: '1m',
+ muteAll: false,
+ mutedInstanceIds: [],
+ executionStatus: {
+ status: 'error',
+ lastExecutionDate: new Date('2020-08-20T19:23:38Z'),
+ error: {
+ reason: AlertExecutionStatusErrorReasons.Unknown,
+ message: 'test',
+ },
+ },
+ },
+ {
+ id: '5',
+ name: 'test alert license error',
+ tags: ['tag1'],
+ enabled: true,
+ alertTypeId: 'test_alert_type',
+ schedule: { interval: '5d' },
+ actions: [{ id: 'test', group: 'alert', params: { message: 'test' } }],
+ params: { name: 'test alert type name' },
+ scheduledTaskId: null,
+ createdBy: null,
+ updatedBy: null,
+ apiKeyOwner: null,
+ throttle: '1m',
+ muteAll: false,
+ mutedInstanceIds: [],
+ executionStatus: {
+ status: 'error',
+ lastExecutionDate: new Date('2020-08-20T19:23:38Z'),
+ error: {
+ reason: AlertExecutionStatusErrorReasons.License,
+ message: 'test',
+ },
+ },
+ },
+ ];
+
async function setup() {
loadAlerts.mockResolvedValue({
page: 1,
perPage: 10000,
total: 4,
- data: [
- {
- id: '1',
- name: 'test alert',
- tags: ['tag1'],
- enabled: true,
- alertTypeId: 'test_alert_type',
- schedule: { interval: '5d' },
- actions: [],
- params: { name: 'test alert type name' },
- scheduledTaskId: null,
- createdBy: null,
- updatedBy: null,
- apiKeyOwner: null,
- throttle: '1m',
- muteAll: false,
- mutedInstanceIds: [],
- executionStatus: {
- status: 'active',
- lastExecutionDate: new Date('2020-08-20T19:23:38Z'),
- error: null,
- },
- },
- {
- id: '2',
- name: 'test alert ok',
- tags: ['tag1'],
- enabled: true,
- alertTypeId: 'test_alert_type',
- schedule: { interval: '5d' },
- actions: [],
- params: { name: 'test alert type name' },
- scheduledTaskId: null,
- createdBy: null,
- updatedBy: null,
- apiKeyOwner: null,
- throttle: '1m',
- muteAll: false,
- mutedInstanceIds: [],
- executionStatus: {
- status: 'ok',
- lastExecutionDate: new Date('2020-08-20T19:23:38Z'),
- error: null,
- },
- },
- {
- id: '3',
- name: 'test alert pending',
- tags: ['tag1'],
- enabled: true,
- alertTypeId: 'test_alert_type',
- schedule: { interval: '5d' },
- actions: [],
- params: { name: 'test alert type name' },
- scheduledTaskId: null,
- createdBy: null,
- updatedBy: null,
- apiKeyOwner: null,
- throttle: '1m',
- muteAll: false,
- mutedInstanceIds: [],
- executionStatus: {
- status: 'pending',
- lastExecutionDate: new Date('2020-08-20T19:23:38Z'),
- error: null,
- },
- },
- {
- id: '4',
- name: 'test alert error',
- tags: ['tag1'],
- enabled: true,
- alertTypeId: 'test_alert_type',
- schedule: { interval: '5d' },
- actions: [{ id: 'test', group: 'alert', params: { message: 'test' } }],
- params: { name: 'test alert type name' },
- scheduledTaskId: null,
- createdBy: null,
- updatedBy: null,
- apiKeyOwner: null,
- throttle: '1m',
- muteAll: false,
- mutedInstanceIds: [],
- executionStatus: {
- status: 'error',
- lastExecutionDate: new Date('2020-08-20T19:23:38Z'),
- error: {
- reason: AlertExecutionStatusErrorReasons.Unknown,
- message: 'test',
- },
- },
- },
- ],
+ data: mockedAlertsData,
});
loadActionTypes.mockResolvedValue([
{
@@ -269,19 +301,40 @@ describe('alerts_list component with items', () => {
it('renders table of alerts', async () => {
await setup();
expect(wrapper.find('EuiBasicTable')).toHaveLength(1);
- expect(wrapper.find('EuiTableRow')).toHaveLength(4);
- expect(wrapper.find('[data-test-subj="alertsTableCell-status"]').length).toBeGreaterThan(0);
- expect(wrapper.find('[data-test-subj="alertStatus-active"]').length).toBeGreaterThan(0);
- expect(wrapper.find('[data-test-subj="alertStatus-error"]').length).toBeGreaterThan(0);
- expect(wrapper.find('[data-test-subj="alertStatus-ok"]').length).toBeGreaterThan(0);
- expect(wrapper.find('[data-test-subj="alertStatus-pending"]').length).toBeGreaterThan(0);
- expect(wrapper.find('[data-test-subj="alertStatus-unknown"]').length).toBe(0);
+ expect(wrapper.find('EuiTableRow')).toHaveLength(mockedAlertsData.length);
+ expect(wrapper.find('EuiTableRowCell[data-test-subj="alertsTableCell-status"]').length).toEqual(
+ mockedAlertsData.length
+ );
+ expect(wrapper.find('EuiHealth[data-test-subj="alertStatus-active"]').length).toEqual(1);
+ expect(wrapper.find('EuiHealth[data-test-subj="alertStatus-ok"]').length).toEqual(1);
+ expect(wrapper.find('EuiHealth[data-test-subj="alertStatus-pending"]').length).toEqual(1);
+ expect(wrapper.find('EuiHealth[data-test-subj="alertStatus-unknown"]').length).toEqual(0);
+
+ expect(wrapper.find('EuiHealth[data-test-subj="alertStatus-error"]').length).toEqual(2);
+ expect(wrapper.find('[data-test-subj="alertStatus-error-tooltip"]').length).toEqual(2);
+ expect(
+ wrapper.find('EuiButtonEmpty[data-test-subj="alertStatus-error-license-fix"]').length
+ ).toEqual(1);
+
expect(wrapper.find('[data-test-subj="refreshAlertsButton"]').exists()).toBeTruthy();
+
+ expect(wrapper.find('EuiHealth[data-test-subj="alertStatus-error"]').first().text()).toEqual(
+ 'Error'
+ );
+ expect(wrapper.find('EuiHealth[data-test-subj="alertStatus-error"]').last().text()).toEqual(
+ 'License Error'
+ );
});
it('loads alerts when refresh button is clicked', async () => {
await setup();
wrapper.find('[data-test-subj="refreshAlertsButton"]').first().simulate('click');
+
+ await act(async () => {
+ await nextTick();
+ wrapper.update();
+ });
+
expect(loadAlerts).toHaveBeenCalled();
});
});
@@ -306,7 +359,9 @@ describe('alerts_list component empty with show only capability', () => {
name: 'Test2',
},
]);
- loadAlertTypes.mockResolvedValue([{ id: 'test_alert_type', name: 'some alert type' }]);
+ loadAlertTypes.mockResolvedValue([
+ { id: 'test_alert_type', name: 'some alert type', authorizedConsumers: {} },
+ ]);
loadAllActions.mockResolvedValue([]);
// eslint-disable-next-line react-hooks/rules-of-hooks
useKibanaMock().services.alertTypeRegistry = alertTypeRegistry;
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx
index d4dd22ed3d557..75a377820b246 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx
+++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx
@@ -244,12 +244,11 @@ export const AlertsList: React.FunctionComponent = () => {
const healthColor = getHealthColor(executionStatus.status);
const tooltipMessage =
executionStatus.status === 'error' ? `Error: ${executionStatus?.error?.message}` : null;
- const statusMessage =
- executionStatus.error?.reason === AlertExecutionStatusErrorReasons.License
- ? ALERT_STATUS_LICENSE_ERROR
- : alertsStatusesTranslationsMapping[executionStatus.status];
- const showLicenseLink =
+ const isLicenseError =
executionStatus.error?.reason === AlertExecutionStatusErrorReasons.License;
+ const statusMessage = isLicenseError
+ ? ALERT_STATUS_LICENSE_ERROR
+ : alertsStatusesTranslationsMapping[executionStatus.status];
const health = (
@@ -258,7 +257,11 @@ export const AlertsList: React.FunctionComponent = () => {
);
const healthWithTooltip = tooltipMessage ? (
-
+
{health}
) : (
@@ -267,11 +270,12 @@ export const AlertsList: React.FunctionComponent = () => {
return (
- {healthWithTooltip}
- {showLicenseLink && (
+ {healthWithTooltip}
+ {isLicenseError && (
setManageLicenseMessage(executionStatus?.error?.message)}
>
Date: Mon, 1 Feb 2021 21:34:06 -0500
Subject: [PATCH 05/13] Cleanup
---
.../sections/alert_details/components/alert_details.tsx | 7 +++----
.../sections/alerts_list/components/alerts_list.tsx | 1 +
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details.tsx
index 1cf5a9a61997b..c2a64bfa3a207 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details.tsx
+++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details.tsx
@@ -104,7 +104,7 @@ export const AlertDetails: React.FunctionComponent = ({
const [isEnabled, setIsEnabled] = useState(alert.enabled);
const [isMuted, setIsMuted] = useState(alert.muteAll);
const [editFlyoutVisible, setEditFlyoutVisibility] = useState(false);
- const [dismissAlertErrors, setDismissAlertErrors] = useState(false);
+ const [dissmissAlertErrors, setDissmissAlertErrors] = useState(false);
const setAlert = async () => {
history.push(routeToAlertDetails.replace(`:alertId`, alert.id));
@@ -170,7 +170,6 @@ export const AlertDetails: React.FunctionComponent = ({
onClick={requestRefresh}
name="refresh"
color="primary"
- disabled={!alertType.enabledInLicense}
>
= ({
- {!dismissAlertErrors && alert.executionStatus.status === 'error' ? (
+ {!dissmissAlertErrors && alert.executionStatus.status === 'error' ? (
= ({
- setDismissAlertErrors(true)}>
+ setDissmissAlertErrors(true)}>
{
message={manageLicenseMessage}
onConfirm={() => {
window.open(`${http.basePath.get()}/app/management/stack/license_management`, '_blank');
+ setManageLicenseMessage(undefined);
}}
onCancel={() => setManageLicenseMessage(undefined)}
/>
From 5188f146e31cd174a044187bb241b56293bc6ab7 Mon Sep 17 00:00:00 2001
From: Ying Mao
Date: Mon, 1 Feb 2021 22:39:30 -0500
Subject: [PATCH 06/13] Unit tests
---
.../components/alerts_list.test.tsx | 24 +++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.test.tsx
index 9403e089d3ed6..0482f352bdd18 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.test.tsx
+++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.test.tsx
@@ -337,6 +337,30 @@ describe('alerts_list component with items', () => {
expect(loadAlerts).toHaveBeenCalled();
});
+
+ it('renders license errors and manage license modal on click', async () => {
+ global.open = jest.fn();
+ await setup();
+ expect(wrapper.find('ManageLicenseModal').exists()).toBeFalsy();
+ expect(
+ wrapper.find('EuiButtonEmpty[data-test-subj="alertStatus-error-license-fix"]').length
+ ).toEqual(1);
+ wrapper
+ .find('EuiButtonEmpty[data-test-subj="alertStatus-error-license-fix"]')
+ .simulate('click');
+
+ await act(async () => {
+ await nextTick();
+ wrapper.update();
+ });
+
+ expect(wrapper.find('ManageLicenseModal').exists()).toBeTruthy();
+ expect(wrapper.find('EuiButton[data-test-subj="confirmModalConfirmButton"]').text()).toEqual(
+ 'Manage license'
+ );
+ wrapper.find('EuiButton[data-test-subj="confirmModalConfirmButton"]').simulate('click');
+ expect(global.open).toHaveBeenCalled();
+ });
});
describe('alerts_list component empty with show only capability', () => {
From e5acc758849c98a336728f06f0625ba8aaa48297 Mon Sep 17 00:00:00 2001
From: Ying Mao
Date: Tue, 2 Feb 2021 08:43:23 -0500
Subject: [PATCH 07/13] Removing tooltip from alert name
---
.../alerts_list/components/alerts_list.tsx | 17 +----------------
1 file changed, 1 insertion(+), 16 deletions(-)
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx
index fd40eaff3ff1a..d74b94473b175 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx
+++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx
@@ -57,7 +57,6 @@ import {
import { hasAllPrivilege } from '../../../lib/capabilities';
import { alertsStatusesTranslationsMapping, ALERT_STATUS_LICENSE_ERROR } from '../translations';
import { useKibana } from '../../../../common/lib/kibana';
-import { checkAlertTypeEnabled } from '../../../lib/check_alert_type_enabled';
import { DEFAULT_HIDDEN_ACTION_TYPES } from '../../../../common/constants';
import './alerts_list.scss';
import { CenterJustifiedSpinner } from '../../../components/center_justified_spinner';
@@ -300,10 +299,7 @@ export const AlertsList: React.FunctionComponent = () => {
truncateText: true,
'data-test-subj': 'alertsTableCell-name',
render: (name: string, alert: AlertTableItem) => {
- const checkEnabledResult = checkAlertTypeEnabled(
- alertTypesState.data.get(alert.alertTypeId)
- );
- const link = (
+ return (
{
@@ -313,17 +309,6 @@ export const AlertsList: React.FunctionComponent = () => {
{name}
);
- return checkEnabledResult.isEnabled ? (
- link
- ) : (
-
- {link}
-
- );
},
},
{
From aa05bb55cb90ae6b6bb7df5b4ddbf933bb3962b9 Mon Sep 17 00:00:00 2001
From: Ying Mao
Date: Thu, 4 Feb 2021 07:53:04 -0500
Subject: [PATCH 08/13] License
---
.../sections/alerts_list/components/manage_license_modal.tsx | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/manage_license_modal.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/manage_license_modal.tsx
index 489cf1d949454..465e6234f9802 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/manage_license_modal.tsx
+++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/manage_license_modal.tsx
@@ -1,7 +1,8 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
+ * 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 React from 'react';
From 95f6333779de6f049009c3ff266894954daef11a Mon Sep 17 00:00:00 2001
From: Ying Mao
Date: Fri, 5 Feb 2021 08:35:28 -0500
Subject: [PATCH 09/13] PR fixes
---
.../sections/alerts_list/components/alerts_list.tsx | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx
index 655b5dfe775bc..a78dc796dbf8f 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx
+++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx
@@ -280,7 +280,7 @@ export const AlertsList: React.FunctionComponent = () => {
>
@@ -298,6 +298,7 @@ export const AlertsList: React.FunctionComponent = () => {
),
sortable: false,
truncateText: true,
+ width: '35%',
'data-test-subj': 'alertsTableCell-name',
render: (name: string, alert: AlertTableItem) => {
return (
@@ -320,6 +321,7 @@ export const AlertsList: React.FunctionComponent = () => {
),
sortable: false,
truncateText: false,
+ width: '150px',
'data-test-subj': 'alertsTableCell-status',
render: (executionStatus: AlertExecutionStatus) => {
return renderAlertExecutionStatus(executionStatus);
From 4a134a750e9a981b382b0639d5e4692328e2f20c Mon Sep 17 00:00:00 2001
From: Ying Mao
Date: Tue, 9 Feb 2021 11:59:40 -0500
Subject: [PATCH 10/13] Updating modal wording
---
.../alerts_list/components/alerts_list.tsx | 30 +++++++++++++------
.../components/manage_license_modal.tsx | 24 ++++++++++++---
2 files changed, 41 insertions(+), 13 deletions(-)
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx
index a78dc796dbf8f..11761cec7cdbb 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx
+++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx
@@ -99,7 +99,10 @@ export const AlertsList: React.FunctionComponent = () => {
const [alertStatusesFilter, setAlertStatusesFilter] = useState([]);
const [alertFlyoutVisible, setAlertFlyoutVisibility] = useState(false);
const [dismissAlertErrors, setDismissAlertErrors] = useState(false);
- const [manageLicenseMessage, setManageLicenseMessage] = useState(undefined);
+ const [manageLicenseModalOpts, setManageLicenseModalOpts] = useState<{
+ licenseType: string;
+ alertTypeId: string;
+ } | null>(null);
const [alertsStatusesTotal, setAlertsStatusesTotal] = useState>(
AlertExecutionStatusValues.reduce(
(prev: Record, status: string) =>
@@ -240,7 +243,10 @@ export const AlertsList: React.FunctionComponent = () => {
}
}
- const renderAlertExecutionStatus = (executionStatus: AlertExecutionStatus) => {
+ const renderAlertExecutionStatus = (
+ executionStatus: AlertExecutionStatus,
+ item: AlertTableItem
+ ) => {
const healthColor = getHealthColor(executionStatus.status);
const tooltipMessage =
executionStatus.status === 'error' ? `Error: ${executionStatus?.error?.message}` : null;
@@ -276,7 +282,12 @@ export const AlertsList: React.FunctionComponent = () => {
setManageLicenseMessage(executionStatus?.error?.message)}
+ onClick={() =>
+ setManageLicenseModalOpts({
+ licenseType: alertTypesState.data.get(item.alertTypeId)?.minimumLicenseRequired!,
+ alertTypeId: item.alertTypeId,
+ })
+ }
>
{
truncateText: false,
width: '150px',
'data-test-subj': 'alertsTableCell-status',
- render: (executionStatus: AlertExecutionStatus) => {
- return renderAlertExecutionStatus(executionStatus);
+ render: (executionStatus: AlertExecutionStatus, item: AlertTableItem) => {
+ return renderAlertExecutionStatus(executionStatus, item);
},
},
{
@@ -673,14 +684,15 @@ export const AlertsList: React.FunctionComponent = () => {
setPage(changedPage);
}}
/>
- {manageLicenseMessage !== undefined && (
+ {manageLicenseModalOpts && (
{
window.open(`${http.basePath.get()}/app/management/stack/license_management`, '_blank');
- setManageLicenseMessage(undefined);
+ setManageLicenseModalOpts(null);
}}
- onCancel={() => setManageLicenseMessage(undefined)}
+ onCancel={() => setManageLicenseModalOpts(null)}
/>
)}
diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/manage_license_modal.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/manage_license_modal.tsx
index 465e6234f9802..f13e5fd96d2ad 100644
--- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/manage_license_modal.tsx
+++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/manage_license_modal.tsx
@@ -7,20 +7,30 @@
import React from 'react';
import { i18n } from '@kbn/i18n';
+import { FormattedMessage } from '@kbn/i18n/react';
import { EuiOverlayMask, EuiConfirmModal } from '@elastic/eui';
+import { capitalize } from 'lodash';
interface Props {
- message?: string;
+ licenseType: string;
+ alertTypeId: string;
onConfirm: () => void;
onCancel: () => void;
}
-export const ManageLicenseModal: React.FC = ({ message, onConfirm, onCancel }) => {
+export const ManageLicenseModal: React.FC = ({
+ licenseType,
+ alertTypeId,
+ onConfirm,
+ onCancel,
+}) => {
+ const licenseRequired = capitalize(licenseType);
return (
= ({ message, onConfirm, onCanc
defaultFocusedButton="confirm"
data-test-subj="manageLicenseModal"
>
- {message}
+
+
+
);
From 9a1fccc9caf6f4676ff39c3652136d05ef079566 Mon Sep 17 00:00:00 2001
From: Ying Mao
Date: Tue, 9 Feb 2021 19:03:02 -0500
Subject: [PATCH 11/13] Updating license state error message
---
x-pack/plugins/alerts/server/lib/license_state.test.ts | 2 +-
x-pack/plugins/alerts/server/lib/license_state.ts | 8 ++++++--
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/x-pack/plugins/alerts/server/lib/license_state.test.ts b/x-pack/plugins/alerts/server/lib/license_state.test.ts
index 07074b9187547..a1c326656f735 100644
--- a/x-pack/plugins/alerts/server/lib/license_state.test.ts
+++ b/x-pack/plugins/alerts/server/lib/license_state.test.ts
@@ -248,7 +248,7 @@ describe('ensureLicenseForAlertType()', () => {
expect(() =>
licenseState.ensureLicenseForAlertType(alertType)
).toThrowErrorMatchingInlineSnapshot(
- `"Alert test is disabled because it requires a Gold license. Contact your administrator to upgrade your license."`
+ `"Alert test is disabled because it requires a Gold license. Go to License Management to view upgrade options."`
);
});
diff --git a/x-pack/plugins/alerts/server/lib/license_state.ts b/x-pack/plugins/alerts/server/lib/license_state.ts
index f95c6cb42a17b..238b2e97c4cdf 100644
--- a/x-pack/plugins/alerts/server/lib/license_state.ts
+++ b/x-pack/plugins/alerts/server/lib/license_state.ts
@@ -9,6 +9,7 @@ import Boom from '@hapi/boom';
import { i18n } from '@kbn/i18n';
import type { PublicMethodsOf } from '@kbn/utility-types';
import { assertNever } from '@kbn/std';
+import { capitalize } from 'lodash';
import { Observable, Subscription } from 'rxjs';
import { LicensingPluginStart } from '../../../licensing/server';
import { ILicense, LicenseType } from '../../../licensing/common/types';
@@ -190,8 +191,11 @@ export class LicenseState {
throw new AlertTypeDisabledError(
i18n.translate('xpack.alerts.serverSideErrors.invalidLicenseErrorMessage', {
defaultMessage:
- 'Alert {alertTypeId} is disabled because it requires a Gold license. Contact your administrator to upgrade your license.',
- values: { alertTypeId: alertType.id },
+ 'Alert {alertTypeId} is disabled because it requires a {licenseType} license. Go to License Management to view upgrade options.',
+ values: {
+ alertTypeId: alertType.id,
+ licenseType: capitalize(alertType.minimumLicenseRequired),
+ },
}),
'license_invalid'
);
From ab2bb14d94b9740b37706aee641b38727d654b98 Mon Sep 17 00:00:00 2001
From: Ying Mao
Date: Tue, 9 Feb 2021 20:04:58 -0500
Subject: [PATCH 12/13] i18n fix
---
x-pack/plugins/translations/translations/ja-JP.json | 1 -
x-pack/plugins/translations/translations/zh-CN.json | 1 -
2 files changed, 2 deletions(-)
diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json
index 6e9d0329eaff8..52d6ed4452cea 100644
--- a/x-pack/plugins/translations/translations/ja-JP.json
+++ b/x-pack/plugins/translations/translations/ja-JP.json
@@ -4830,7 +4830,6 @@
"xpack.alerts.server.healthStatus.degraded": "アラートフレームワークは劣化しました",
"xpack.alerts.server.healthStatus.unavailable": "アラートフレームワークを使用できません",
"xpack.alerts.serverSideErrors.expirerdLicenseErrorMessage": "{licenseType} ライセンスの期限が切れたのでアラートタイプ {alertTypeId} は無効です。",
- "xpack.alerts.serverSideErrors.invalidLicenseErrorMessage": "アラート {alertTypeId} は無効です。Gold ライセンスが必要です。ライセンスをアップグレードするには、管理者に問い合わせてください。",
"xpack.alerts.serverSideErrors.unavailableLicenseErrorMessage": "現時点でライセンス情報を入手できないため、アラートタイプ {alertTypeId} は無効です。",
"xpack.alerts.serverSideErrors.unavailableLicenseInformationErrorMessage": "アラートを利用できません。現在ライセンス情報が利用できません。",
"xpack.apm.a.thresholdMet": "しきい値一致",
diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json
index eeda709104479..082f42a5cb35c 100644
--- a/x-pack/plugins/translations/translations/zh-CN.json
+++ b/x-pack/plugins/translations/translations/zh-CN.json
@@ -4836,7 +4836,6 @@
"xpack.alerts.server.healthStatus.degraded": "告警框架已降级",
"xpack.alerts.server.healthStatus.unavailable": "告警框架不可用",
"xpack.alerts.serverSideErrors.expirerdLicenseErrorMessage": "告警类型 {alertTypeId} 已禁用,因为您的{licenseType}许可证已过期。",
- "xpack.alerts.serverSideErrors.invalidLicenseErrorMessage": "告警 {alertTypeId} 已禁用,因为它需要黄金级许可证。请联系管理员升级您的许可证。",
"xpack.alerts.serverSideErrors.unavailableLicenseErrorMessage": "告警类型 {alertTypeId} 已禁用,因为许可证信息当前不可用。",
"xpack.alerts.serverSideErrors.unavailableLicenseInformationErrorMessage": "告警不可用 - 许可信息当前不可用。",
"xpack.apm.a.thresholdMet": "已达到阈值",
From 5c8aa7611d100748e3369e8988bfb26663d5eeb9 Mon Sep 17 00:00:00 2001
From: Ying Mao
Date: Tue, 9 Feb 2021 21:35:15 -0500
Subject: [PATCH 13/13] Fixing functional test
---
.../basic/tests/alerts/gold_noop_alert_type.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/x-pack/test/alerting_api_integration/basic/tests/alerts/gold_noop_alert_type.ts b/x-pack/test/alerting_api_integration/basic/tests/alerts/gold_noop_alert_type.ts
index 488b39eabb637..211d1acb2a005 100644
--- a/x-pack/test/alerting_api_integration/basic/tests/alerts/gold_noop_alert_type.ts
+++ b/x-pack/test/alerting_api_integration/basic/tests/alerts/gold_noop_alert_type.ts
@@ -22,7 +22,7 @@ export default function emailTest({ getService }: FtrProviderContext) {
statusCode: 403,
error: 'Forbidden',
message:
- 'Alert test.gold.noop is disabled because it requires a Gold license. Contact your administrator to upgrade your license.',
+ 'Alert test.gold.noop is disabled because it requires a Gold license. Go to License Management to view upgrade options.',
});
});
});