From b208bda4ed4bea4cb1f3ef93384119e3dd78d654 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez=20G=C3=B3mez?= Date: Wed, 11 Aug 2021 13:24:12 +0200 Subject: [PATCH 01/19] Move filter buttons to the left --- .../public/pages/alerts/index.tsx | 39 +++++++++---------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/x-pack/plugins/observability/public/pages/alerts/index.tsx b/x-pack/plugins/observability/public/pages/alerts/index.tsx index fb23856dcd5a3..3442ceeed22a6 100644 --- a/x-pack/plugins/observability/public/pages/alerts/index.tsx +++ b/x-pack/plugins/observability/public/pages/alerts/index.tsx @@ -159,26 +159,25 @@ export function AlertsPage({ routeParams }: AlertsPageProps) { onQueryChange={onQueryChange} /> - - - - - - - - - - - 0 ? dynamicIndexPattern[0].title : ''} - rangeFrom={rangeFrom} - rangeTo={rangeTo} - kuery={kuery} - status={status} - setRefetch={setRefetch} - /> - - + + + + + + + + + + + 0 ? dynamicIndexPattern[0].title : ''} + rangeFrom={rangeFrom} + rangeTo={rangeTo} + kuery={kuery} + status={status} + setRefetch={setRefetch} + /> + ); From 5b1b2be6ab45c89dd4e75f756b0561c3ae783fa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez=20G=C3=B3mez?= Date: Wed, 11 Aug 2021 15:39:08 +0200 Subject: [PATCH 02/19] Change filter button labels and add "acknowledged" filter --- .../plugins/observability/common/typings.ts | 7 ++++++- .../public/pages/alerts/status_filter.tsx | 19 ++++++++++--------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/x-pack/plugins/observability/common/typings.ts b/x-pack/plugins/observability/common/typings.ts index 305a18903fe7e..26f1159cd6271 100644 --- a/x-pack/plugins/observability/common/typings.ts +++ b/x-pack/plugins/observability/common/typings.ts @@ -8,7 +8,12 @@ import * as t from 'io-ts'; export type Maybe = T | null | undefined; -export const alertStatusRt = t.union([t.literal('all'), t.literal('open'), t.literal('closed')]); +export const alertStatusRt = t.union([ + t.literal('all'), + t.literal('open'), + t.literal('acknowledged'), + t.literal('closed'), +]); export type AlertStatus = t.TypeOf; export interface ApmIndicesConfig { diff --git a/x-pack/plugins/observability/public/pages/alerts/status_filter.tsx b/x-pack/plugins/observability/public/pages/alerts/status_filter.tsx index 26169717d2967..f034994656d7d 100644 --- a/x-pack/plugins/observability/public/pages/alerts/status_filter.tsx +++ b/x-pack/plugins/observability/public/pages/alerts/status_filter.tsx @@ -34,21 +34,22 @@ export function StatusFilter({ status = 'open', onChange }: StatusFilterProps) { onChange('closed')} + hasActiveFilters={status === 'acknowledged'} + onClick={() => onChange('acknowledged')} withNext={true} > - {i18n.translate('xpack.observability.alerts.statusFilter.closedButtonLabel', { - defaultMessage: 'Closed', + {i18n.translate('xpack.observability.alerts.statusFilter.acknowledgedButtonLabel', { + defaultMessage: 'Acknowledged', })} onChange('all')} + data-test-subj="StatusFilter closed button" + hasActiveFilters={status === 'closed'} + onClick={() => onChange('closed')} + withNext={true} > - {i18n.translate('xpack.observability.alerts.statusFilter.allButtonLabel', { - defaultMessage: 'All', + {i18n.translate('xpack.observability.alerts.statusFilter.closedButtonLabel', { + defaultMessage: 'Closed', })} From fd9c7e09dd759820a8ebc7a48456ce4c455018d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez=20G=C3=B3mez?= Date: Wed, 11 Aug 2021 15:48:01 +0200 Subject: [PATCH 03/19] Switch button widget --- .../public/pages/alerts/status_filter.tsx | 66 ++++++++----------- 1 file changed, 29 insertions(+), 37 deletions(-) diff --git a/x-pack/plugins/observability/public/pages/alerts/status_filter.tsx b/x-pack/plugins/observability/public/pages/alerts/status_filter.tsx index f034994656d7d..14c4a76fe0de6 100644 --- a/x-pack/plugins/observability/public/pages/alerts/status_filter.tsx +++ b/x-pack/plugins/observability/public/pages/alerts/status_filter.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { EuiFilterButton, EuiFilterGroup } from '@elastic/eui'; +import { EuiButtonGroup } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React from 'react'; import type { AlertStatus } from '../../../common/typings'; @@ -15,43 +15,35 @@ export interface StatusFilterProps { onChange: (value: AlertStatus) => void; } +const options: Array<{ id: AlertStatus; label: string }> = [ + { + id: 'open', + label: i18n.translate('xpack.observability.alerts.statusFilter.openButtonLabel', { + defaultMessage: 'Open', + }), + }, + { + id: 'acknowledged', + label: i18n.translate('xpack.observability.alerts.statusFilter.acknowledgedButtonLabel', { + defaultMessage: 'Acknowledged', + }), + }, + { + id: 'closed', + label: i18n.translate('xpack.observability.alerts.statusFilter.closedButtonLabel', { + defaultMessage: 'Closed', + }), + }, +]; + export function StatusFilter({ status = 'open', onChange }: StatusFilterProps) { return ( - - onChange('open')} - withNext={true} - > - {i18n.translate('xpack.observability.alerts.statusFilter.openButtonLabel', { - defaultMessage: 'Open', - })} - - onChange('acknowledged')} - withNext={true} - > - {i18n.translate('xpack.observability.alerts.statusFilter.acknowledgedButtonLabel', { - defaultMessage: 'Acknowledged', - })} - - onChange('closed')} - withNext={true} - > - {i18n.translate('xpack.observability.alerts.statusFilter.closedButtonLabel', { - defaultMessage: 'Closed', - })} - - + onChange(id as AlertStatus)} + /> ); } From b4296c0b1d6c18d75968f0513b207d81ed6bbc49 Mon Sep 17 00:00:00 2001 From: Jason Rhodes Date: Thu, 12 Aug 2021 17:32:31 -0400 Subject: [PATCH 04/19] Automated removal of unused translations via scripts/i18n_check --fix --- x-pack/plugins/translations/translations/ja-JP.json | 2 -- x-pack/plugins/translations/translations/zh-CN.json | 2 -- 2 files changed, 4 deletions(-) diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 9d880276312f7..7d2bd81b708ea 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -18303,10 +18303,8 @@ "xpack.monitoring.updateLicenseTitle": "ライセンスの更新", "xpack.monitoring.useAvailableLicenseDescription": "すでに新しいライセンスがある場合は、今すぐアップロードしてください。", "xpack.observability.alerts.searchBarPlaceholder": "\"domain\": \"ecommerce\" AND (\"service.name\":\"ProductCatalogService\" …)", - "xpack.observability.alerts.statusFilter.allButtonLabel": "すべて", "xpack.observability.alerts.statusFilter.closedButtonLabel": "終了", "xpack.observability.alerts.statusFilter.openButtonLabel": "開く", - "xpack.observability.alerts.statusFilterAriaLabel": "未解決および終了ステータスでアラートをフィルター", "xpack.observability.alertsDisclaimerLinkText": "アラートとアクション", "xpack.observability.alertsDisclaimerText": "このページには実験アラートビューが表示されます。ここに表示されるデータは、アラートを正確に表していない可能性があります。アラートの非実験リストは、スタック管理のアラートとアクション設定にあります。", "xpack.observability.alertsDisclaimerTitle": "実験的", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index addbe289ee990..aa89bb889eaa8 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -18714,10 +18714,8 @@ "xpack.monitoring.updateLicenseTitle": "更新您的许可证", "xpack.monitoring.useAvailableLicenseDescription": "如果您已经持有新的许可证,请立即上传。", "xpack.observability.alerts.searchBarPlaceholder": "\"domain\": \"ecommerce\" AND (\"service.name\":\"ProductCatalogService\" …)", - "xpack.observability.alerts.statusFilter.allButtonLabel": "全部", "xpack.observability.alerts.statusFilter.closedButtonLabel": "已关闭", "xpack.observability.alerts.statusFilter.openButtonLabel": "打开", - "xpack.observability.alerts.statusFilterAriaLabel": "按未结和关闭状态筛选告警", "xpack.observability.alertsDisclaimerLinkText": "告警和操作", "xpack.observability.alertsDisclaimerText": "此页面显示实验性告警视图。此处显示的数据可能无法准确表示告警。在“堆栈管理”的“告警和操作”中提供了告警的非实验性列表。", "xpack.observability.alertsDisclaimerTitle": "实验性", From ed182a708d2cbade9068ca427031dc33a848b2e8 Mon Sep 17 00:00:00 2001 From: Jason Rhodes Date: Thu, 12 Aug 2021 17:46:50 -0400 Subject: [PATCH 05/19] Fixed broken tests --- .../public/pages/alerts/status_filter.test.tsx | 4 ++-- .../observability/public/pages/alerts/status_filter.tsx | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/observability/public/pages/alerts/status_filter.test.tsx b/x-pack/plugins/observability/public/pages/alerts/status_filter.test.tsx index 72e07ebb8cadf..266cc2177ab8c 100644 --- a/x-pack/plugins/observability/public/pages/alerts/status_filter.test.tsx +++ b/x-pack/plugins/observability/public/pages/alerts/status_filter.test.tsx @@ -14,13 +14,13 @@ describe('StatusFilter', () => { describe('render', () => { it('renders', () => { const onChange = jest.fn(); - const status: AlertStatus = 'all'; + const status: AlertStatus = 'open'; const props = { onChange, status }; expect(() => render()).not.toThrowError(); }); - (['all', 'open', 'closed'] as AlertStatus[]).map((status) => { + (['open', 'acknowledged', 'closed'] as AlertStatus[]).map((status) => { describe(`when clicking the ${status} button`, () => { it('calls the onChange callback with "${status}"', () => { const onChange = jest.fn(); diff --git a/x-pack/plugins/observability/public/pages/alerts/status_filter.tsx b/x-pack/plugins/observability/public/pages/alerts/status_filter.tsx index 14c4a76fe0de6..9bcc07208d742 100644 --- a/x-pack/plugins/observability/public/pages/alerts/status_filter.tsx +++ b/x-pack/plugins/observability/public/pages/alerts/status_filter.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { EuiButtonGroup } from '@elastic/eui'; +import { EuiButtonGroup, EuiButtonGroupOptionProps } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React from 'react'; import type { AlertStatus } from '../../../common/typings'; @@ -15,24 +15,27 @@ export interface StatusFilterProps { onChange: (value: AlertStatus) => void; } -const options: Array<{ id: AlertStatus; label: string }> = [ +const options: EuiButtonGroupOptionProps[] = [ { id: 'open', label: i18n.translate('xpack.observability.alerts.statusFilter.openButtonLabel', { defaultMessage: 'Open', }), + 'data-test-subj': 'StatusFilter open button', }, { id: 'acknowledged', label: i18n.translate('xpack.observability.alerts.statusFilter.acknowledgedButtonLabel', { defaultMessage: 'Acknowledged', }), + 'data-test-subj': 'StatusFilter acknowledged button', }, { id: 'closed', label: i18n.translate('xpack.observability.alerts.statusFilter.closedButtonLabel', { defaultMessage: 'Closed', }), + 'data-test-subj': 'StatusFilter closed button', }, ]; From 3f69056d2e8d621d4ebd4b433952bca13a46d105 Mon Sep 17 00:00:00 2001 From: Jason Rhodes Date: Thu, 12 Aug 2021 22:08:31 -0400 Subject: [PATCH 06/19] Fixes for workflow status change --- .../public/pages/alerts/alerts_table_t_grid.tsx | 4 ++-- .../plugins/timelines/common/types/timeline/actions/index.ts | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/observability/public/pages/alerts/alerts_table_t_grid.tsx b/x-pack/plugins/observability/public/pages/alerts/alerts_table_t_grid.tsx index 1932a1114bc8f..e015b3de86cf7 100644 --- a/x-pack/plugins/observability/public/pages/alerts/alerts_table_t_grid.tsx +++ b/x-pack/plugins/observability/public/pages/alerts/alerts_table_t_grid.tsx @@ -39,7 +39,7 @@ import type { TopAlert } from './'; import { useKibana } from '../../../../../../src/plugins/kibana_react/public'; import type { ActionProps, - AlertStatus, + AlertWorkflowStatus, ColumnHeaderOptions, RowRenderer, } from '../../../../timelines/common'; @@ -245,7 +245,7 @@ export function AlertsTableTGrid(props: AlertsTableTGridProps) { sortDirection: 'desc', }, ], - filterStatus: status as AlertStatus, + filterStatus: workflowStatus as AlertWorkflowStatus, leadingControlColumns, trailingControlColumns, unit: (totalAlerts: number) => diff --git a/x-pack/plugins/timelines/common/types/timeline/actions/index.ts b/x-pack/plugins/timelines/common/types/timeline/actions/index.ts index e61361233cda6..4b25283d59d3a 100644 --- a/x-pack/plugins/timelines/common/types/timeline/actions/index.ts +++ b/x-pack/plugins/timelines/common/types/timeline/actions/index.ts @@ -100,4 +100,7 @@ export interface BulkActionsObjectProp { } export type BulkActionsProp = boolean | BulkActionsObjectProp; -export type AlertStatus = 'open' | 'closed' | 'in-progress'; +export type AlertWorkflowStatus = 'open' | 'closed' | 'acknowledged'; + +// for backwards compatibility while we switch everything to use AlertWorkflowStatus +export type AlertStatus = AlertWorkflowStatus | 'in-progress'; From a1d8f22c27686eda555258912bc7b6e1a6b37d7d Mon Sep 17 00:00:00 2001 From: Jason Rhodes Date: Thu, 12 Aug 2021 22:44:04 -0400 Subject: [PATCH 07/19] Updated translations --- x-pack/plugins/translations/translations/ja-JP.json | 2 -- x-pack/plugins/translations/translations/zh-CN.json | 2 -- 2 files changed, 4 deletions(-) diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 7d2bd81b708ea..ad90157922d11 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -18303,8 +18303,6 @@ "xpack.monitoring.updateLicenseTitle": "ライセンスの更新", "xpack.monitoring.useAvailableLicenseDescription": "すでに新しいライセンスがある場合は、今すぐアップロードしてください。", "xpack.observability.alerts.searchBarPlaceholder": "\"domain\": \"ecommerce\" AND (\"service.name\":\"ProductCatalogService\" …)", - "xpack.observability.alerts.statusFilter.closedButtonLabel": "終了", - "xpack.observability.alerts.statusFilter.openButtonLabel": "開く", "xpack.observability.alertsDisclaimerLinkText": "アラートとアクション", "xpack.observability.alertsDisclaimerText": "このページには実験アラートビューが表示されます。ここに表示されるデータは、アラートを正確に表していない可能性があります。アラートの非実験リストは、スタック管理のアラートとアクション設定にあります。", "xpack.observability.alertsDisclaimerTitle": "実験的", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index aa89bb889eaa8..250e40d968b9b 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -18714,8 +18714,6 @@ "xpack.monitoring.updateLicenseTitle": "更新您的许可证", "xpack.monitoring.useAvailableLicenseDescription": "如果您已经持有新的许可证,请立即上传。", "xpack.observability.alerts.searchBarPlaceholder": "\"domain\": \"ecommerce\" AND (\"service.name\":\"ProductCatalogService\" …)", - "xpack.observability.alerts.statusFilter.closedButtonLabel": "已关闭", - "xpack.observability.alerts.statusFilter.openButtonLabel": "打开", "xpack.observability.alertsDisclaimerLinkText": "告警和操作", "xpack.observability.alertsDisclaimerText": "此页面显示实验性告警视图。此处显示的数据可能无法准确表示告警。在“堆栈管理”的“告警和操作”中提供了告警的非实验性列表。", "xpack.observability.alertsDisclaimerTitle": "实验性", From bcb8dfe580166f88c98367a6f0086c3c2b222a5a Mon Sep 17 00:00:00 2001 From: Jason Rhodes Date: Thu, 12 Aug 2021 23:58:29 -0400 Subject: [PATCH 08/19] Fixes broken type --- .../bulk_actions/alert_status_bulk_actions.tsx | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/timelines/public/components/t_grid/toolbar/bulk_actions/alert_status_bulk_actions.tsx b/x-pack/plugins/timelines/public/components/t_grid/toolbar/bulk_actions/alert_status_bulk_actions.tsx index ef1f7e524ef5f..77efdba48a302 100644 --- a/x-pack/plugins/timelines/public/components/t_grid/toolbar/bulk_actions/alert_status_bulk_actions.tsx +++ b/x-pack/plugins/timelines/public/components/t_grid/toolbar/bulk_actions/alert_status_bulk_actions.tsx @@ -87,7 +87,7 @@ export const AlertStatusBulkActionsComponent = React.memo { - let title: string; + let title; switch (newStatus) { case 'closed': title = i18n.CLOSED_ALERT_FAILED_TOAST; @@ -121,7 +123,9 @@ export const AlertStatusBulkActionsComponent = React.memo Date: Thu, 12 Aug 2021 23:59:30 -0400 Subject: [PATCH 09/19] Adds default 'open' value for lifecycle helper rules --- .../server/utils/create_lifecycle_executor.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/rule_registry/server/utils/create_lifecycle_executor.ts b/x-pack/plugins/rule_registry/server/utils/create_lifecycle_executor.ts index 7a00457f2c4e1..e4e1558d0e6b0 100644 --- a/x-pack/plugins/rule_registry/server/utils/create_lifecycle_executor.ts +++ b/x-pack/plugins/rule_registry/server/utils/create_lifecycle_executor.ts @@ -24,16 +24,17 @@ import { ALERT_DURATION, ALERT_END, ALERT_ID, + ALERT_RULE_CONSUMER, + ALERT_RULE_TYPE_ID, + ALERT_RULE_UUID, ALERT_START, ALERT_STATUS, ALERT_UUID, + ALERT_WORKFLOW_STATUS, EVENT_ACTION, EVENT_KIND, - ALERT_RULE_CONSUMER, - ALERT_RULE_TYPE_ID, - ALERT_RULE_UUID, - TIMESTAMP, SPACE_IDS, + TIMESTAMP, } from '../../common/technical_rule_data_field_names'; import { RuleDataClient } from '../rule_data_client'; import { AlertExecutorOptionsWithExtraServices } from '../types'; @@ -157,6 +158,7 @@ export const createLifecycleExecutor = ( [ALERT_ID]: id, [ALERT_RULE_TYPE_ID]: rule.ruleTypeId, [ALERT_RULE_CONSUMER]: rule.consumer, + [ALERT_WORKFLOW_STATUS]: 'open', // TODO: how do we prevent overwriting this field back to "open"? }; return alertInstanceFactory(id); }, From 6fd20bd20384530eccc1e92ff22cee04cf741765 Mon Sep 17 00:00:00 2001 From: Jason Rhodes Date: Fri, 13 Aug 2021 00:07:49 -0400 Subject: [PATCH 10/19] Workflow status change again --- .../plugins/observability/common/typings.ts | 5 +- .../pages/alerts/alerts_table_t_grid.tsx | 42 +++++++------- .../public/pages/alerts/index.tsx | 29 ++++------ .../public/pages/alerts/status_filter.tsx | 52 ------------------ ...tsx => workflow_status_filter.stories.tsx} | 12 ++-- ...st.tsx => workflow_status_filter.test.tsx} | 14 ++--- .../pages/alerts/workflow_status_filter.tsx | 55 +++++++++++++++++++ .../observability/public/routes/index.tsx | 4 +- 8 files changed, 102 insertions(+), 111 deletions(-) delete mode 100644 x-pack/plugins/observability/public/pages/alerts/status_filter.tsx rename x-pack/plugins/observability/public/pages/alerts/{status_filter.stories.tsx => workflow_status_filter.stories.tsx} (65%) rename x-pack/plugins/observability/public/pages/alerts/{status_filter.test.tsx => workflow_status_filter.test.tsx} (62%) create mode 100644 x-pack/plugins/observability/public/pages/alerts/workflow_status_filter.tsx diff --git a/x-pack/plugins/observability/common/typings.ts b/x-pack/plugins/observability/common/typings.ts index 26f1159cd6271..ebce96ee1b3e9 100644 --- a/x-pack/plugins/observability/common/typings.ts +++ b/x-pack/plugins/observability/common/typings.ts @@ -8,13 +8,12 @@ import * as t from 'io-ts'; export type Maybe = T | null | undefined; -export const alertStatusRt = t.union([ - t.literal('all'), +export const alertWorkflowStatusRt = t.union([ t.literal('open'), t.literal('acknowledged'), t.literal('closed'), ]); -export type AlertStatus = t.TypeOf; +export type AlertWorkflowStatus = t.TypeOf; export interface ApmIndicesConfig { /* eslint-disable @typescript-eslint/naming-convention */ diff --git a/x-pack/plugins/observability/public/pages/alerts/alerts_table_t_grid.tsx b/x-pack/plugins/observability/public/pages/alerts/alerts_table_t_grid.tsx index e015b3de86cf7..1299b7697a98c 100644 --- a/x-pack/plugins/observability/public/pages/alerts/alerts_table_t_grid.tsx +++ b/x-pack/plugins/observability/public/pages/alerts/alerts_table_t_grid.tsx @@ -10,32 +10,28 @@ * We have types and code at different imports because we don't want to import the whole package in the resulting webpack bundle for the plugin. * This way plugins can do targeted imports to reduce the final code bundle */ +import { EuiButtonIcon, EuiDataGridColumn } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; import type { AlertConsumers as AlertConsumersTyped, ALERT_DURATION as ALERT_DURATION_TYPED, - ALERT_SEVERITY_LEVEL as ALERT_SEVERITY_LEVEL_TYPED, - ALERT_STATUS as ALERT_STATUS_TYPED, ALERT_RULE_NAME as ALERT_RULE_NAME_TYPED, + ALERT_SEVERITY_LEVEL as ALERT_SEVERITY_LEVEL_TYPED, + ALERT_WORKFLOW_STATUS as ALERT_WORKFLOW_STATUS_TYPED, } from '@kbn/rule-data-utils'; +// @ts-expect-error importing from a place other than root because we want to limit what we import from this package +import { AlertConsumers as AlertConsumersNonTyped } from '@kbn/rule-data-utils/target_node/alerts_as_data_rbac'; import { ALERT_DURATION as ALERT_DURATION_NON_TYPED, - ALERT_SEVERITY_LEVEL as ALERT_SEVERITY_LEVEL_NON_TYPED, - ALERT_STATUS as ALERT_STATUS_NON_TYPED, ALERT_RULE_NAME as ALERT_RULE_NAME_NON_TYPED, + ALERT_SEVERITY_LEVEL as ALERT_SEVERITY_LEVEL_NON_TYPED, + ALERT_WORKFLOW_STATUS as ALERT_WORKFLOW_STATUS_NON_TYPED, TIMESTAMP, // @ts-expect-error importing from a place other than root because we want to limit what we import from this package } from '@kbn/rule-data-utils/target_node/technical_field_names'; - -// @ts-expect-error importing from a place other than root because we want to limit what we import from this package -import { AlertConsumers as AlertConsumersNonTyped } from '@kbn/rule-data-utils/target_node/alerts_as_data_rbac'; - -import { EuiButtonIcon, EuiDataGridColumn } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import styled from 'styled-components'; import React, { Suspense, useMemo, useState } from 'react'; - -import type { TimelinesUIStart } from '../../../../timelines/public'; -import type { TopAlert } from './'; +import styled from 'styled-components'; +import { LazyAlertsFlyout } from '../..'; import { useKibana } from '../../../../../../src/plugins/kibana_react/public'; import type { ActionProps, @@ -43,17 +39,17 @@ import type { ColumnHeaderOptions, RowRenderer, } from '../../../../timelines/common'; - -import { getRenderCellValue } from './render_cell_value'; +import type { TimelinesUIStart } from '../../../../timelines/public'; import { usePluginContext } from '../../hooks/use_plugin_context'; +import type { TopAlert } from './'; import { getDefaultCellActions } from './default_cell_actions'; -import { LazyAlertsFlyout } from '../..'; import { parseAlert } from './parse_alert'; +import { getRenderCellValue } from './render_cell_value'; const AlertConsumers: typeof AlertConsumersTyped = AlertConsumersNonTyped; const ALERT_DURATION: typeof ALERT_DURATION_TYPED = ALERT_DURATION_NON_TYPED; const ALERT_SEVERITY_LEVEL: typeof ALERT_SEVERITY_LEVEL_TYPED = ALERT_SEVERITY_LEVEL_NON_TYPED; -const ALERT_STATUS: typeof ALERT_STATUS_TYPED = ALERT_STATUS_NON_TYPED; +const ALERT_WORKFLOW_STATUS: typeof ALERT_WORKFLOW_STATUS_TYPED = ALERT_WORKFLOW_STATUS_NON_TYPED; const ALERT_RULE_NAME: typeof ALERT_RULE_NAME_TYPED = ALERT_RULE_NAME_NON_TYPED; interface AlertsTableTGridProps { @@ -61,7 +57,7 @@ interface AlertsTableTGridProps { rangeFrom: string; rangeTo: string; kuery: string; - status: string; + workflowStatus: AlertWorkflowStatus; setRefetch: (ref: () => void) => void; } @@ -96,7 +92,7 @@ export const columns: Array< displayAsText: i18n.translate('xpack.observability.alertsTGrid.statusColumnDescription', { defaultMessage: 'Status', }), - id: ALERT_STATUS, + id: ALERT_WORKFLOW_STATUS, initialWidth: 79, }, { @@ -147,7 +143,7 @@ const OBSERVABILITY_ALERT_CONSUMERS = [ export function AlertsTableTGrid(props: AlertsTableTGridProps) { const { core, observabilityRuleTypeRegistry } = usePluginContext(); const { prepend } = core.http.basePath; - const { indexName, rangeFrom, rangeTo, kuery, status, setRefetch } = props; + const { indexName, rangeFrom, rangeTo, kuery, workflowStatus, setRefetch } = props; const [flyoutAlert, setFlyoutAlert] = useState(undefined); const handleFlyoutClose = () => setFlyoutAlert(undefined); const { timelines } = useKibana<{ timelines: TimelinesUIStart }>().services; @@ -231,7 +227,7 @@ export function AlertsTableTGrid(props: AlertsTableTGridProps) { defaultMessage: 'alerts', }), query: { - query: `${ALERT_STATUS}: ${status}${kuery !== '' ? ` and ${kuery}` : ''}`, + query: `${ALERT_WORKFLOW_STATUS}: ${status}${kuery !== '' ? ` and ${kuery}` : ''}`, language: 'kuery', }, renderCellValue: getRenderCellValue({ rangeFrom, rangeTo, setFlyoutAlert }), @@ -245,7 +241,7 @@ export function AlertsTableTGrid(props: AlertsTableTGridProps) { sortDirection: 'desc', }, ], - filterStatus: workflowStatus as AlertWorkflowStatus, + filterStatus: workflowStatus, leadingControlColumns, trailingControlColumns, unit: (totalAlerts: number) => diff --git a/x-pack/plugins/observability/public/pages/alerts/index.tsx b/x-pack/plugins/observability/public/pages/alerts/index.tsx index 3442ceeed22a6..242d6eb01dc4a 100644 --- a/x-pack/plugins/observability/public/pages/alerts/index.tsx +++ b/x-pack/plugins/observability/public/pages/alerts/index.tsx @@ -5,28 +5,21 @@ * 2.0. */ -import { - EuiButtonEmpty, - EuiCallOut, - EuiFlexGroup, - EuiFlexItem, - EuiLink, - EuiSpacer, -} from '@elastic/eui'; +import { EuiButtonEmpty, EuiCallOut, EuiFlexGroup, EuiFlexItem, EuiLink } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React, { useCallback, useMemo, useRef } from 'react'; import { useHistory } from 'react-router-dom'; import { ParsedTechnicalFields } from '../../../../rule_registry/common/parse_technical_fields'; -import type { AlertStatus } from '../../../common/typings'; +import type { AlertWorkflowStatus } from '../../../common/typings'; import { ExperimentalBadge } from '../../components/shared/experimental_badge'; import { useBreadcrumbs } from '../../hooks/use_breadcrumbs'; +import { useFetcher } from '../../hooks/use_fetcher'; import { usePluginContext } from '../../hooks/use_plugin_context'; import { RouteParams } from '../../routes'; +import { callObservabilityApi } from '../../services/call_observability_api'; import { AlertsSearchBar } from './alerts_search_bar'; import { AlertsTableTGrid } from './alerts_table_t_grid'; -import { StatusFilter } from './status_filter'; -import { useFetcher } from '../../hooks/use_fetcher'; -import { callObservabilityApi } from '../../services/call_observability_api'; +import { WorkflowStatusFilter } from './workflow_status_filter'; export interface TopAlert { fields: ParsedTechnicalFields; @@ -46,7 +39,7 @@ export function AlertsPage({ routeParams }: AlertsPageProps) { const history = useHistory(); const refetch = useRef<() => void>(); const { - query: { rangeFrom = 'now-15m', rangeTo = 'now', kuery = '', status = 'open' }, + query: { rangeFrom = 'now-15m', rangeTo = 'now', kuery = '', workflowStatus = 'open' }, } = routeParams; useBreadcrumbs([ @@ -73,10 +66,10 @@ export function AlertsPage({ routeParams }: AlertsPageProps) { [dynamicIndexPatternResp] ); - const setStatusFilter = useCallback( - (value: AlertStatus) => { + const setWorkflowStatusFilter = useCallback( + (value: AlertWorkflowStatus) => { const nextSearchParams = new URLSearchParams(history.location.search); - nextSearchParams.set('status', value); + nextSearchParams.set('workflowStatus', value); history.push({ ...history.location, search: nextSearchParams.toString(), @@ -163,7 +156,7 @@ export function AlertsPage({ routeParams }: AlertsPageProps) { - + @@ -174,7 +167,7 @@ export function AlertsPage({ routeParams }: AlertsPageProps) { rangeFrom={rangeFrom} rangeTo={rangeTo} kuery={kuery} - status={status} + workflowStatus={workflowStatus} setRefetch={setRefetch} /> diff --git a/x-pack/plugins/observability/public/pages/alerts/status_filter.tsx b/x-pack/plugins/observability/public/pages/alerts/status_filter.tsx deleted file mode 100644 index 9bcc07208d742..0000000000000 --- a/x-pack/plugins/observability/public/pages/alerts/status_filter.tsx +++ /dev/null @@ -1,52 +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 { EuiButtonGroup, EuiButtonGroupOptionProps } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import React from 'react'; -import type { AlertStatus } from '../../../common/typings'; - -export interface StatusFilterProps { - status: AlertStatus; - onChange: (value: AlertStatus) => void; -} - -const options: EuiButtonGroupOptionProps[] = [ - { - id: 'open', - label: i18n.translate('xpack.observability.alerts.statusFilter.openButtonLabel', { - defaultMessage: 'Open', - }), - 'data-test-subj': 'StatusFilter open button', - }, - { - id: 'acknowledged', - label: i18n.translate('xpack.observability.alerts.statusFilter.acknowledgedButtonLabel', { - defaultMessage: 'Acknowledged', - }), - 'data-test-subj': 'StatusFilter acknowledged button', - }, - { - id: 'closed', - label: i18n.translate('xpack.observability.alerts.statusFilter.closedButtonLabel', { - defaultMessage: 'Closed', - }), - 'data-test-subj': 'StatusFilter closed button', - }, -]; - -export function StatusFilter({ status = 'open', onChange }: StatusFilterProps) { - return ( - onChange(id as AlertStatus)} - /> - ); -} diff --git a/x-pack/plugins/observability/public/pages/alerts/status_filter.stories.tsx b/x-pack/plugins/observability/public/pages/alerts/workflow_status_filter.stories.tsx similarity index 65% rename from x-pack/plugins/observability/public/pages/alerts/status_filter.stories.tsx rename to x-pack/plugins/observability/public/pages/alerts/workflow_status_filter.stories.tsx index 851e0cb6c3ddd..e06b5d333a9a6 100644 --- a/x-pack/plugins/observability/public/pages/alerts/status_filter.stories.tsx +++ b/x-pack/plugins/observability/public/pages/alerts/workflow_status_filter.stories.tsx @@ -6,24 +6,24 @@ */ import React, { ComponentProps, useState } from 'react'; -import type { AlertStatus } from '../../../common/typings'; -import { StatusFilter } from './status_filter'; +import type { AlertWorkflowStatus } from '../../../common/typings'; +import { WorkflowStatusFilter } from './workflow_status_filter'; -type Args = ComponentProps; +type Args = ComponentProps; export default { title: 'app/Alerts/StatusFilter', - component: StatusFilter, + component: WorkflowStatusFilter, argTypes: { onChange: { action: 'change' }, }, }; export function Example({ onChange }: Args) { - const [status, setStatus] = useState('open'); + const [status, setStatus] = useState('open'); return ( - { setStatus(value); diff --git a/x-pack/plugins/observability/public/pages/alerts/status_filter.test.tsx b/x-pack/plugins/observability/public/pages/alerts/workflow_status_filter.test.tsx similarity index 62% rename from x-pack/plugins/observability/public/pages/alerts/status_filter.test.tsx rename to x-pack/plugins/observability/public/pages/alerts/workflow_status_filter.test.tsx index 266cc2177ab8c..817ca7706df9f 100644 --- a/x-pack/plugins/observability/public/pages/alerts/status_filter.test.tsx +++ b/x-pack/plugins/observability/public/pages/alerts/workflow_status_filter.test.tsx @@ -7,27 +7,27 @@ import { render } from '@testing-library/react'; import React from 'react'; -import type { AlertStatus } from '../../../common/typings'; -import { StatusFilter } from './status_filter'; +import type { AlertWorkflowStatus } from '../../../common/typings'; +import { WorkflowStatusFilter } from './workflow_status_filter'; describe('StatusFilter', () => { describe('render', () => { it('renders', () => { const onChange = jest.fn(); - const status: AlertStatus = 'open'; + const status: AlertWorkflowStatus = 'open'; const props = { onChange, status }; - expect(() => render()).not.toThrowError(); + expect(() => render()).not.toThrowError(); }); - (['open', 'acknowledged', 'closed'] as AlertStatus[]).map((status) => { + (['open', 'acknowledged', 'closed'] as AlertWorkflowStatus[]).map((status) => { describe(`when clicking the ${status} button`, () => { it('calls the onChange callback with "${status}"', () => { const onChange = jest.fn(); const props = { onChange, status }; - const { getByTestId } = render(); - const button = getByTestId(`StatusFilter ${status} button`); + const { getByTestId } = render(); + const button = getByTestId(`WorkflowStatusFilter ${status} button`); button.click(); diff --git a/x-pack/plugins/observability/public/pages/alerts/workflow_status_filter.tsx b/x-pack/plugins/observability/public/pages/alerts/workflow_status_filter.tsx new file mode 100644 index 0000000000000..0281e66a6a57f --- /dev/null +++ b/x-pack/plugins/observability/public/pages/alerts/workflow_status_filter.tsx @@ -0,0 +1,55 @@ +/* + * 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 { EuiButtonGroup, EuiButtonGroupOptionProps } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import React from 'react'; +import type { AlertWorkflowStatus } from '../../../common/typings'; + +export interface WorkflowStatusFilterProps { + status: AlertWorkflowStatus; + onChange: (value: AlertWorkflowStatus) => void; +} + +const options: EuiButtonGroupOptionProps[] = [ + { + id: 'open', + label: i18n.translate('xpack.observability.alerts.workflowStatusFilter.openButtonLabel', { + defaultMessage: 'Open', + }), + 'data-test-subj': 'WorkflowStatusFilter open button', + }, + { + id: 'acknowledged', + label: i18n.translate( + 'xpack.observability.alerts.workflowStatusFilter.acknowledgedButtonLabel', + { + defaultMessage: 'Acknowledged', + } + ), + 'data-test-subj': 'WorkflowStatusFilter acknowledged button', + }, + { + id: 'closed', + label: i18n.translate('xpack.observability.alerts.workflowStatusFilter.closedButtonLabel', { + defaultMessage: 'Closed', + }), + 'data-test-subj': 'WorkflowStatusFilter closed button', + }, +]; + +export function WorkflowStatusFilter({ status = 'open', onChange }: WorkflowStatusFilterProps) { + return ( + onChange(id as AlertWorkflowStatus)} + /> + ); +} diff --git a/x-pack/plugins/observability/public/routes/index.tsx b/x-pack/plugins/observability/public/routes/index.tsx index f97e3fb996441..00e487da7f9b7 100644 --- a/x-pack/plugins/observability/public/routes/index.tsx +++ b/x-pack/plugins/observability/public/routes/index.tsx @@ -7,7 +7,7 @@ import * as t from 'io-ts'; import React from 'react'; -import { alertStatusRt } from '../../common/typings'; +import { alertWorkflowStatusRt } from '../../common/typings'; import { ExploratoryViewPage } from '../components/shared/exploratory_view'; import { AlertsPage } from '../pages/alerts'; import { AllCasesPage } from '../pages/cases/all_cases'; @@ -93,7 +93,7 @@ export const routes = { rangeFrom: t.string, rangeTo: t.string, kuery: t.string, - status: alertStatusRt, + workflowStatus: alertWorkflowStatusRt, refreshPaused: jsonRt.pipe(t.boolean), refreshInterval: jsonRt.pipe(t.number), }), From 13055ba0b6508c32e0206929555a363cb26af27a Mon Sep 17 00:00:00 2001 From: Jason Rhodes Date: Fri, 13 Aug 2021 08:03:20 -0400 Subject: [PATCH 11/19] Workflow status type fixes --- .../schemas/common/schemas.ts | 7 ++++- .../timeline_actions/use_alerts_actions.tsx | 31 +++++++++++-------- .../components/alerts_table/translations.ts | 17 ++++++++++ 3 files changed, 41 insertions(+), 14 deletions(-) diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/common/schemas.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/common/schemas.ts index c869a12faf360..52285d1339bbd 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/common/schemas.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/common/schemas.ts @@ -170,7 +170,12 @@ export type RuleNameOverride = t.TypeOf; export const ruleNameOverrideOrUndefined = t.union([rule_name_override, t.undefined]); export type RuleNameOverrideOrUndefined = t.TypeOf; -export const status = t.keyof({ open: null, closed: null, 'in-progress': null }); +export const status = t.keyof({ + open: null, + closed: null, + acknowledged: null, + 'in-progress': null, +}); export type Status = t.TypeOf; export enum RuleExecutionStatus { diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_alerts_actions.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_alerts_actions.tsx index 4fdebee6e1f4d..488a49d15537e 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_alerts_actions.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_alerts_actions.tsx @@ -7,20 +7,18 @@ import { useCallback } from 'react'; import { useDispatch } from 'react-redux'; - -import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; +import { useStatusBulkActionItems } from '../../../../../../timelines/public'; import { Status } from '../../../../../common/detection_engine/schemas/common/schemas'; -import { timelineActions } from '../../../../timelines/store/timeline'; -import { SetEventsDeletedProps, SetEventsLoadingProps } from '../types'; -import * as i18nCommon from '../../../../common/translations'; -import * as i18n from '../translations'; - import { - useStateToaster, - displaySuccessToast, displayErrorToast, + displaySuccessToast, + useStateToaster, } from '../../../../common/components/toasters'; -import { useStatusBulkActionItems } from '../../../../../../timelines/public'; +import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; +import * as i18nCommon from '../../../../common/translations'; +import { timelineActions } from '../../../../timelines/store/timeline'; +import * as i18n from '../translations'; +import { SetEventsDeletedProps, SetEventsLoadingProps } from '../types'; interface Props { alertStatus?: Status; @@ -45,7 +43,7 @@ export const useAlertsActions = ({ alertStatus, closePopover, eventId, timelineI text: i18nCommon.UPDATE_ALERT_STATUS_FAILED_DETAILED(updated, conflicts), }); } else { - let title: string; + let title = ''; switch (newStatus) { case 'closed': title = i18n.CLOSED_ALERT_SUCCESS_TOAST(updated); @@ -55,8 +53,11 @@ export const useAlertsActions = ({ alertStatus, closePopover, eventId, timelineI break; case 'in-progress': title = i18n.IN_PROGRESS_ALERT_SUCCESS_TOAST(updated); + break; + case 'acknowledged': + title = i18n.ACKNOWLEDGED_ALERT_SUCCESS_TOAST(updated); + break; } - displaySuccessToast(title, dispatchToaster); } }, @@ -65,7 +66,7 @@ export const useAlertsActions = ({ alertStatus, closePopover, eventId, timelineI const onAlertStatusUpdateFailure = useCallback( (newStatus: Status, error: Error) => { - let title: string; + let title = ''; closePopover(); switch (newStatus) { @@ -77,6 +78,10 @@ export const useAlertsActions = ({ alertStatus, closePopover, eventId, timelineI break; case 'in-progress': title = i18n.IN_PROGRESS_ALERT_FAILED_TOAST; + break; + case 'acknowledged': + title = i18n.ACKNOWLEDGED_ALERT_FAILED_TOAST; + break; } displayErrorToast(title, [error.message], dispatchToaster); }, diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/translations.ts b/x-pack/plugins/security_solution/public/detections/components/alerts_table/translations.ts index badc077244acd..171cd8c2da042 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/translations.ts +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/translations.ts @@ -223,6 +223,16 @@ export const IN_PROGRESS_ALERT_SUCCESS_TOAST = (totalAlerts: number) => } ); +export const ACKNOWLEDGED_ALERT_SUCCESS_TOAST = (totalAlerts: number) => + i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.acknowledgedAlertSuccessToastMessage', + { + values: { totalAlerts }, + defaultMessage: + 'Successfully marked {totalAlerts} {totalAlerts, plural, =1 {alert} other {alerts}} as acknowledged.', + } + ); + export const CLOSED_ALERT_FAILED_TOAST = i18n.translate( 'xpack.securitySolution.detectionEngine.alerts.closedAlertFailedToastMessage', { @@ -244,6 +254,13 @@ export const IN_PROGRESS_ALERT_FAILED_TOAST = i18n.translate( } ); +export const ACKNOWLEDGED_ALERT_FAILED_TOAST = i18n.translate( + 'xpack.securitySolution.detectionEngine.alerts.acknowledgedAlertFailedToastMessage', + { + defaultMessage: 'Failed to mark alert(s) as acknowledged', + } +); + export const MORE_ACTIONS = i18n.translate( 'xpack.securitySolution.detectionEngine.alerts.moreActionsAriaLabel', { From dcc73d28595bd2f0f35d30160305de9e2c6f6b77 Mon Sep 17 00:00:00 2001 From: Jason Rhodes Date: Fri, 13 Aug 2021 08:26:53 -0400 Subject: [PATCH 12/19] Workflow status test updates --- .../server/utils/create_lifecycle_rule_type.test.ts | 2 ++ .../apm_api_integration/tests/alerts/rule_registry.ts | 9 +++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/rule_registry/server/utils/create_lifecycle_rule_type.test.ts b/x-pack/plugins/rule_registry/server/utils/create_lifecycle_rule_type.test.ts index 3469187122127..6d9803ae3680f 100644 --- a/x-pack/plugins/rule_registry/server/utils/create_lifecycle_rule_type.test.ts +++ b/x-pack/plugins/rule_registry/server/utils/create_lifecycle_rule_type.test.ts @@ -199,6 +199,7 @@ describe('createLifecycleRuleTypeFactory', () => { "kibana.alert.rule.uuid": "alertId", "kibana.alert.start": "2021-06-16T09:01:00.000Z", "kibana.alert.status": "open", + "kibana.alert.workflow_status": "open", "kibana.space_ids": Array [ "spaceId", ], @@ -221,6 +222,7 @@ describe('createLifecycleRuleTypeFactory', () => { "kibana.alert.rule.uuid": "alertId", "kibana.alert.start": "2021-06-16T09:01:00.000Z", "kibana.alert.status": "open", + "kibana.alert.workflow_status": "open", "kibana.space_ids": Array [ "spaceId", ], diff --git a/x-pack/test/apm_api_integration/tests/alerts/rule_registry.ts b/x-pack/test/apm_api_integration/tests/alerts/rule_registry.ts index 857101ebcc18c..643e5ec64b406 100644 --- a/x-pack/test/apm_api_integration/tests/alerts/rule_registry.ts +++ b/x-pack/test/apm_api_integration/tests/alerts/rule_registry.ts @@ -8,12 +8,10 @@ import expect from '@kbn/expect'; import { ALERT_DURATION, - ALERT_END, - ALERT_START, + ALERT_END, ALERT_RULE_UUID, ALERT_START, ALERT_STATUS, ALERT_UUID, - EVENT_KIND, - ALERT_RULE_UUID, + EVENT_KIND } from '@kbn/rule-data-utils'; import { merge, omit } from 'lodash'; import { FtrProviderContext } from '../../common/ftr_provider_context'; @@ -390,6 +388,9 @@ export default function ApiTest({ getService }: FtrProviderContext) { "kibana.alert.status": Array [ "open", ], + "kibana.alert.workflow_status": Array [ + "open", + ], "kibana.space_ids": Array [ "default", ], From 69a0af550016495dd9cd6a9df8379dc86ad06fba Mon Sep 17 00:00:00 2001 From: Jason Rhodes Date: Fri, 13 Aug 2021 11:21:33 -0400 Subject: [PATCH 13/19] Fixes more type failures and test failures that only show up in CI --- .../components/alerts_table/index.tsx | 58 +++++++++++-------- .../tests/alerts/rule_registry.ts | 9 ++- 2 files changed, 40 insertions(+), 27 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx index d8d6424ef2a73..410b6f7c0b5bb 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/index.tsx @@ -5,34 +5,47 @@ * 2.0. */ -import { EuiPanel, EuiLoadingContent } from '@elastic/eui'; +import { EuiLoadingContent, EuiPanel } from '@elastic/eui'; import { isEmpty } from 'lodash/fp'; import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { connect, ConnectedProps, useDispatch } from 'react-redux'; import { Dispatch } from 'redux'; +import { esQuery, Filter } from '../../../../../../../src/plugins/data/public'; import { Status } from '../../../../common/detection_engine/schemas/common/schemas'; -import { Filter, esQuery } from '../../../../../../../src/plugins/data/public'; import { RowRendererId, TimelineIdLiteral } from '../../../../common/types/timeline'; -import { useAppToasts } from '../../../common/hooks/use_app_toasts'; import { StatefulEventsViewer } from '../../../common/components/events_viewer'; import { HeaderSection } from '../../../common/components/header_section'; +import { + displayErrorToast, + displaySuccessToast, + useStateToaster, +} from '../../../common/components/toasters'; +import { useSourcererScope } from '../../../common/containers/sourcerer'; +import { useAppToasts } from '../../../common/hooks/use_app_toasts'; import { useIsExperimentalFeatureEnabled } from '../../../common/hooks/use_experimental_features'; -import { combineQueries } from '../../../timelines/components/timeline/helpers'; +import { useInvalidFilterQuery } from '../../../common/hooks/use_invalid_filter_query'; +import { defaultCellActions } from '../../../common/lib/cell_actions/default_cell_actions'; import { useKibana } from '../../../common/lib/kibana'; -import { inputsSelectors, State, inputsModel } from '../../../common/store'; +import { inputsModel, inputsSelectors, State } from '../../../common/store'; +import { SourcererScopeName } from '../../../common/store/sourcerer/model'; +import * as i18nCommon from '../../../common/translations'; +import { DEFAULT_COLUMN_MIN_WIDTH } from '../../../timelines/components/timeline/body/constants'; +import { defaultRowRenderers } from '../../../timelines/components/timeline/body/renderers'; +import { combineQueries } from '../../../timelines/components/timeline/helpers'; import { timelineActions, timelineSelectors } from '../../../timelines/store/timeline'; -import { TimelineModel } from '../../../timelines/store/timeline/model'; import { timelineDefaults } from '../../../timelines/store/timeline/defaults'; +import { TimelineModel } from '../../../timelines/store/timeline/model'; +import { columns, RenderCellValue } from '../../configurations/security_solution_detections'; import { updateAlertStatusAction } from './actions'; +import { AditionalFiltersAction, AlertsUtilityBar } from './alerts_utility_bar'; import { - requiredFieldsForActions, alertsDefaultModel, - buildAlertStatusFilter, alertsDefaultModelRuleRegistry, + buildAlertStatusFilter, buildAlertStatusFilterRuleRegistry, + requiredFieldsForActions, } from './default_config'; -import { AditionalFiltersAction, AlertsUtilityBar } from './alerts_utility_bar'; -import * as i18nCommon from '../../../common/translations'; +import { buildTimeRangeFilter } from './helpers'; import * as i18n from './translations'; import { SetEventsDeletedProps, @@ -40,19 +53,6 @@ import { UpdateAlertsStatusCallback, UpdateAlertsStatusProps, } from './types'; -import { - useStateToaster, - displaySuccessToast, - displayErrorToast, -} from '../../../common/components/toasters'; -import { SourcererScopeName } from '../../../common/store/sourcerer/model'; -import { useSourcererScope } from '../../../common/containers/sourcerer'; -import { buildTimeRangeFilter } from './helpers'; -import { defaultRowRenderers } from '../../../timelines/components/timeline/body/renderers'; -import { columns, RenderCellValue } from '../../configurations/security_solution_detections'; -import { useInvalidFilterQuery } from '../../../common/hooks/use_invalid_filter_query'; -import { DEFAULT_COLUMN_MIN_WIDTH } from '../../../timelines/components/timeline/body/constants'; -import { defaultCellActions } from '../../../common/lib/cell_actions/default_cell_actions'; interface OwnProps { defaultFilters?: Filter[]; @@ -165,7 +165,7 @@ export const AlertsTableComponent: React.FC = ({ text: i18nCommon.UPDATE_ALERT_STATUS_FAILED_DETAILED(updated, conflicts), }); } else { - let title: string; + let title = ''; switch (status) { case 'closed': title = i18n.CLOSED_ALERT_SUCCESS_TOAST(updated); @@ -175,6 +175,10 @@ export const AlertsTableComponent: React.FC = ({ break; case 'in-progress': title = i18n.IN_PROGRESS_ALERT_SUCCESS_TOAST(updated); + break; + case 'acknowledged': + title = i18n.ACKNOWLEDGED_ALERT_SUCCESS_TOAST(updated); + break; } displaySuccessToast(title, dispatchToaster); } @@ -184,7 +188,7 @@ export const AlertsTableComponent: React.FC = ({ const onAlertStatusUpdateFailure = useCallback( (status: Status, error: Error) => { - let title: string; + let title = ''; switch (status) { case 'closed': title = i18n.CLOSED_ALERT_FAILED_TOAST; @@ -194,6 +198,10 @@ export const AlertsTableComponent: React.FC = ({ break; case 'in-progress': title = i18n.IN_PROGRESS_ALERT_FAILED_TOAST; + break; + case 'acknowledged': + title = i18n.ACKNOWLEDGED_ALERT_FAILED_TOAST; + break; } displayErrorToast(title, [error.message], dispatchToaster); }, diff --git a/x-pack/test/apm_api_integration/tests/alerts/rule_registry.ts b/x-pack/test/apm_api_integration/tests/alerts/rule_registry.ts index 643e5ec64b406..2a0c4fe0ff23f 100644 --- a/x-pack/test/apm_api_integration/tests/alerts/rule_registry.ts +++ b/x-pack/test/apm_api_integration/tests/alerts/rule_registry.ts @@ -8,10 +8,12 @@ import expect from '@kbn/expect'; import { ALERT_DURATION, - ALERT_END, ALERT_RULE_UUID, ALERT_START, + ALERT_END, + ALERT_RULE_UUID, + ALERT_START, ALERT_STATUS, ALERT_UUID, - EVENT_KIND + EVENT_KIND, } from '@kbn/rule-data-utils'; import { merge, omit } from 'lodash'; import { FtrProviderContext } from '../../common/ftr_provider_context'; @@ -498,6 +500,9 @@ export default function ApiTest({ getService }: FtrProviderContext) { "kibana.alert.status": Array [ "closed", ], + "kibana.alert.workflow_status": Array [ + "open", + ], "kibana.space_ids": Array [ "default", ], From 2f6f3e33a23f13186730a5e42802ff9d62d77a7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez=20G=C3=B3mez?= Date: Tue, 17 Aug 2021 14:30:07 +0200 Subject: [PATCH 14/19] Prevent workflow status from overwrites --- .../rule_registry/server/utils/create_lifecycle_executor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/rule_registry/server/utils/create_lifecycle_executor.ts b/x-pack/plugins/rule_registry/server/utils/create_lifecycle_executor.ts index e4e1558d0e6b0..693ef30bee0c0 100644 --- a/x-pack/plugins/rule_registry/server/utils/create_lifecycle_executor.ts +++ b/x-pack/plugins/rule_registry/server/utils/create_lifecycle_executor.ts @@ -158,7 +158,6 @@ export const createLifecycleExecutor = ( [ALERT_ID]: id, [ALERT_RULE_TYPE_ID]: rule.ruleTypeId, [ALERT_RULE_CONSUMER]: rule.consumer, - [ALERT_WORKFLOW_STATUS]: 'open', // TODO: how do we prevent overwriting this field back to "open"? }; return alertInstanceFactory(id); }, @@ -265,6 +264,7 @@ export const createLifecycleExecutor = ( event[ALERT_START] = started; event[ALERT_UUID] = alertUuid; + event[ALERT_WORKFLOW_STATUS] = event[ALERT_WORKFLOW_STATUS] ?? 'open'; // not sure why typescript needs the non-null assertion here // we already assert the value is not undefined with the ternary From 69c07d2f0242bb988cf78c6ed658d13c4b63b843 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez=20G=C3=B3mez?= Date: Tue, 17 Aug 2021 15:42:22 +0200 Subject: [PATCH 15/19] Remove duplicate import --- .../observability/public/pages/alerts/alerts_table_t_grid.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/x-pack/plugins/observability/public/pages/alerts/alerts_table_t_grid.tsx b/x-pack/plugins/observability/public/pages/alerts/alerts_table_t_grid.tsx index 47e7ecf0ad540..9d6eb6048cf15 100644 --- a/x-pack/plugins/observability/public/pages/alerts/alerts_table_t_grid.tsx +++ b/x-pack/plugins/observability/public/pages/alerts/alerts_table_t_grid.tsx @@ -28,9 +28,6 @@ import { // @ts-expect-error importing from a place other than root because we want to limit what we import from this package } from '@kbn/rule-data-utils/target_node/technical_field_names'; -// @ts-expect-error importing from a place other than root because we want to limit what we import from this package -import { AlertConsumers as AlertConsumersNonTyped } from '@kbn/rule-data-utils/target_node/alerts_as_data_rbac'; - import { EuiButtonIcon, EuiDataGridColumn, From d9354143305c92573ed5705ed4bb1f0d774dd9ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez=20G=C3=B3mez?= Date: Wed, 18 Aug 2021 16:15:48 +0200 Subject: [PATCH 16/19] Tweak io-ts types --- x-pack/plugins/observability/common/typings.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/observability/common/typings.ts b/x-pack/plugins/observability/common/typings.ts index ebce96ee1b3e9..71337075e1617 100644 --- a/x-pack/plugins/observability/common/typings.ts +++ b/x-pack/plugins/observability/common/typings.ts @@ -8,11 +8,11 @@ import * as t from 'io-ts'; export type Maybe = T | null | undefined; -export const alertWorkflowStatusRt = t.union([ - t.literal('open'), - t.literal('acknowledged'), - t.literal('closed'), -]); +export const alertWorkflowStatusRt = t.keyof({ + open: null, + acknowledged: null, + closed: null, +}); export type AlertWorkflowStatus = t.TypeOf; export interface ApmIndicesConfig { From 8f9027b747cee8f77a7bb8b4ae93fac2482070e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez=20G=C3=B3mez?= Date: Wed, 18 Aug 2021 16:16:04 +0200 Subject: [PATCH 17/19] Remove outdated type cast --- .../observability/public/pages/alerts/alerts_table_t_grid.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/observability/public/pages/alerts/alerts_table_t_grid.tsx b/x-pack/plugins/observability/public/pages/alerts/alerts_table_t_grid.tsx index 318fe61175598..807149fa101f5 100644 --- a/x-pack/plugins/observability/public/pages/alerts/alerts_table_t_grid.tsx +++ b/x-pack/plugins/observability/public/pages/alerts/alerts_table_t_grid.tsx @@ -323,7 +323,7 @@ export function AlertsTableTGrid(props: AlertsTableTGridProps) { return ( ); From df7d0eba9496e81c3a211f978e2ff1f7efbbcc6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez=20G=C3=B3mez?= Date: Wed, 18 Aug 2021 16:37:02 +0200 Subject: [PATCH 18/19] Restore the correct field for the status column --- .../public/pages/alerts/alerts_table_t_grid.tsx | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/observability/public/pages/alerts/alerts_table_t_grid.tsx b/x-pack/plugins/observability/public/pages/alerts/alerts_table_t_grid.tsx index 807149fa101f5..fe1dfef4d8b38 100644 --- a/x-pack/plugins/observability/public/pages/alerts/alerts_table_t_grid.tsx +++ b/x-pack/plugins/observability/public/pages/alerts/alerts_table_t_grid.tsx @@ -13,18 +13,20 @@ import { AlertConsumers as AlertConsumersTyped, ALERT_DURATION as ALERT_DURATION_TYPED, - ALERT_SEVERITY_LEVEL as ALERT_SEVERITY_LEVEL_TYPED, - ALERT_WORKFLOW_STATUS as ALERT_WORKFLOW_STATUS_TYPED, ALERT_REASON as ALERT_REASON_TYPED, ALERT_RULE_CONSUMER, + ALERT_SEVERITY_LEVEL as ALERT_SEVERITY_LEVEL_TYPED, + ALERT_STATUS as ALERT_STATUS_TYPED, + ALERT_WORKFLOW_STATUS as ALERT_WORKFLOW_STATUS_TYPED, } from '@kbn/rule-data-utils'; // @ts-expect-error importing from a place other than root because we want to limit what we import from this package import { AlertConsumers as AlertConsumersNonTyped } from '@kbn/rule-data-utils/target_node/alerts_as_data_rbac'; import { ALERT_DURATION as ALERT_DURATION_NON_TYPED, + ALERT_REASON as ALERT_REASON_NON_TYPED, ALERT_SEVERITY_LEVEL as ALERT_SEVERITY_LEVEL_NON_TYPED, + ALERT_STATUS as ALERT_STATUS_NON_TYPED, ALERT_WORKFLOW_STATUS as ALERT_WORKFLOW_STATUS_NON_TYPED, - ALERT_REASON as ALERT_REASON_NON_TYPED, TIMESTAMP, // @ts-expect-error importing from a place other than root because we want to limit what we import from this package } from '@kbn/rule-data-utils/target_node/technical_field_names'; @@ -64,9 +66,10 @@ import { CoreStart } from '../../../../../../src/core/public'; const AlertConsumers: typeof AlertConsumersTyped = AlertConsumersNonTyped; const ALERT_DURATION: typeof ALERT_DURATION_TYPED = ALERT_DURATION_NON_TYPED; +const ALERT_REASON: typeof ALERT_REASON_TYPED = ALERT_REASON_NON_TYPED; const ALERT_SEVERITY_LEVEL: typeof ALERT_SEVERITY_LEVEL_TYPED = ALERT_SEVERITY_LEVEL_NON_TYPED; +const ALERT_STATUS: typeof ALERT_STATUS_TYPED = ALERT_STATUS_NON_TYPED; const ALERT_WORKFLOW_STATUS: typeof ALERT_WORKFLOW_STATUS_TYPED = ALERT_WORKFLOW_STATUS_NON_TYPED; -const ALERT_REASON: typeof ALERT_REASON_TYPED = ALERT_REASON_NON_TYPED; interface AlertsTableTGridProps { indexName: string; @@ -114,7 +117,7 @@ export const columns: Array< displayAsText: i18n.translate('xpack.observability.alertsTGrid.statusColumnDescription', { defaultMessage: 'Alert Status', }), - id: ALERT_WORKFLOW_STATUS, + id: ALERT_STATUS, initialWidth: 110, }, { From 847368473762864097c3776322c40ae4cba4cf07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez=20G=C3=B3mez?= Date: Thu, 19 Aug 2021 11:25:27 +0200 Subject: [PATCH 19/19] Narrow down the valid IDs for the filter options --- .../public/pages/alerts/workflow_status_filter.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/observability/public/pages/alerts/workflow_status_filter.tsx b/x-pack/plugins/observability/public/pages/alerts/workflow_status_filter.tsx index 0281e66a6a57f..475ba17a9d2f5 100644 --- a/x-pack/plugins/observability/public/pages/alerts/workflow_status_filter.tsx +++ b/x-pack/plugins/observability/public/pages/alerts/workflow_status_filter.tsx @@ -15,7 +15,7 @@ export interface WorkflowStatusFilterProps { onChange: (value: AlertWorkflowStatus) => void; } -const options: EuiButtonGroupOptionProps[] = [ +const options: Array = [ { id: 'open', label: i18n.translate('xpack.observability.alerts.workflowStatusFilter.openButtonLabel', {