[RAC] Enable workflow status filtering (#108215)

Co-authored-by: Jason Rhodes <jason.matthew.rhodes@gmail.com>
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Alejandro Fernández Gómez 2021-08-20 12:07:09 +02:00 committed by GitHub
parent 60af98a1b7
commit 5fd903b7fe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 172 additions and 166 deletions

View file

@ -8,8 +8,12 @@ import * as t from 'io-ts';
export type Maybe<T> = T | null | undefined;
export const alertStatusRt = t.union([t.literal('all'), t.literal('open'), t.literal('closed')]);
export type AlertStatus = t.TypeOf<typeof alertStatusRt>;
export const alertWorkflowStatusRt = t.keyof({
open: null,
acknowledged: null,
closed: null,
});
export type AlertWorkflowStatus = t.TypeOf<typeof alertWorkflowStatusRt>;
export interface ApmIndicesConfig {
/* eslint-disable @typescript-eslint/naming-convention */

View file

@ -13,21 +13,22 @@
import {
AlertConsumers as AlertConsumersTyped,
ALERT_DURATION as ALERT_DURATION_TYPED,
ALERT_STATUS as ALERT_STATUS_TYPED,
ALERT_REASON as ALERT_REASON_TYPED,
ALERT_RULE_CONSUMER,
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_STATUS as ALERT_STATUS_NON_TYPED,
ALERT_REASON as ALERT_REASON_NON_TYPED,
ALERT_STATUS as ALERT_STATUS_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,
@ -47,7 +48,7 @@ import type { TopAlert } from './';
import { useKibana } from '../../../../../../src/plugins/kibana_react/public';
import type {
ActionProps,
AlertStatus,
AlertWorkflowStatus,
ColumnHeaderOptions,
RowRenderer,
} from '../../../../timelines/common';
@ -63,21 +64,22 @@ import { CoreStart } from '../../../../../../src/core/public';
const AlertConsumers: typeof AlertConsumersTyped = AlertConsumersNonTyped;
const ALERT_DURATION: typeof ALERT_DURATION_TYPED = ALERT_DURATION_NON_TYPED;
const ALERT_STATUS: typeof ALERT_STATUS_TYPED = ALERT_STATUS_NON_TYPED;
const ALERT_REASON: typeof ALERT_REASON_TYPED = ALERT_REASON_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;
interface AlertsTableTGridProps {
indexName: string;
rangeFrom: string;
rangeTo: string;
kuery: string;
status: string;
workflowStatus: AlertWorkflowStatus;
setRefetch: (ref: () => void) => void;
addToQuery: (value: string) => void;
}
interface ObservabilityActionsProps extends ActionProps {
currentStatus: AlertStatus;
currentStatus: AlertWorkflowStatus;
setFlyoutAlert: React.Dispatch<React.SetStateAction<TopAlert | undefined>>;
}
@ -288,7 +290,7 @@ function ObservabilityActions({
}
export function AlertsTableTGrid(props: AlertsTableTGridProps) {
const { indexName, rangeFrom, rangeTo, kuery, status, setRefetch, addToQuery } = props;
const { indexName, rangeFrom, rangeTo, kuery, workflowStatus, setRefetch, addToQuery } = props;
const { timelines } = useKibana<{ timelines: TimelinesUIStart }>().services;
const [flyoutAlert, setFlyoutAlert] = useState<TopAlert | undefined>(undefined);
@ -313,14 +315,14 @@ export function AlertsTableTGrid(props: AlertsTableTGridProps) {
return (
<ObservabilityActions
{...actionProps}
currentStatus={status as AlertStatus}
currentStatus={workflowStatus}
setFlyoutAlert={setFlyoutAlert}
/>
);
},
},
];
}, [status]);
}, [workflowStatus]);
const tGridProps = useMemo(() => {
const type: TGridType = 'standalone';
@ -345,7 +347,7 @@ export function AlertsTableTGrid(props: AlertsTableTGridProps) {
defaultMessage: 'alerts',
}),
query: {
query: `${ALERT_STATUS}: ${status}${kuery !== '' ? ` and ${kuery}` : ''}`,
query: `${ALERT_WORKFLOW_STATUS}: ${workflowStatus}${kuery !== '' ? ` and ${kuery}` : ''}`,
language: 'kuery',
},
renderCellValue: getRenderCellValue({ rangeFrom, rangeTo, setFlyoutAlert }),
@ -359,7 +361,7 @@ export function AlertsTableTGrid(props: AlertsTableTGridProps) {
sortDirection,
},
],
filterStatus: status as AlertStatus,
filterStatus: workflowStatus as AlertWorkflowStatus,
leadingControlColumns,
trailingControlColumns,
unit: (totalAlerts: number) =>
@ -376,7 +378,7 @@ export function AlertsTableTGrid(props: AlertsTableTGridProps) {
rangeFrom,
rangeTo,
setRefetch,
status,
workflowStatus,
addToQuery,
]);
const handleFlyoutClose = () => setFlyoutAlert(undefined);

View file

@ -10,16 +10,16 @@ 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';
import './styles.scss';
export interface TopAlert {
@ -44,7 +44,7 @@ export function AlertsPage({ routeParams }: AlertsPageProps) {
rangeFrom = 'now-15m',
rangeTo = 'now',
kuery = 'kibana.alert.status: "open"', // TODO change hardcoded values as part of another PR
status = 'open',
workflowStatus = 'open',
},
} = routeParams;
@ -72,10 +72,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(),
@ -172,28 +172,26 @@ export function AlertsPage({ routeParams }: AlertsPageProps) {
onQueryChange={onQueryChange}
/>
</EuiFlexItem>
<EuiFlexItem>
<EuiFlexGroup direction="column">
<EuiFlexItem>
<EuiFlexGroup justifyContent="flexStart">
<EuiFlexItem grow={false}>
<StatusFilter status={status} onChange={setStatusFilter} />
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
<EuiFlexItem>
<AlertsTableTGrid
indexName={dynamicIndexPattern.length > 0 ? dynamicIndexPattern[0].title : ''}
rangeFrom={rangeFrom}
rangeTo={rangeTo}
kuery={kuery}
status={status}
setRefetch={setRefetch}
addToQuery={addToQuery}
/>
<EuiFlexGroup justifyContent="spaceBetween" alignItems="center">
<EuiFlexItem grow={false}>
<WorkflowStatusFilter status={workflowStatus} onChange={setWorkflowStatusFilter} />
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
<EuiFlexItem>
<AlertsTableTGrid
indexName={dynamicIndexPattern.length > 0 ? dynamicIndexPattern[0].title : ''}
rangeFrom={rangeFrom}
rangeTo={rangeTo}
kuery={kuery}
workflowStatus={workflowStatus}
setRefetch={setRefetch}
addToQuery={addToQuery}
/>
</EuiFlexItem>
</EuiFlexGroup>
</ObservabilityPageTemplate>
);

View file

@ -1,56 +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 { EuiFilterButton, EuiFilterGroup } 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;
}
export function StatusFilter({ status = 'open', onChange }: StatusFilterProps) {
return (
<EuiFilterGroup
aria-label={i18n.translate('xpack.observability.alerts.statusFilterAriaLabel', {
defaultMessage: 'Filter alerts by open and closed status',
})}
>
<EuiFilterButton
data-test-subj="StatusFilter open button"
hasActiveFilters={status === 'open'}
onClick={() => onChange('open')}
withNext={true}
>
{i18n.translate('xpack.observability.alerts.statusFilter.openButtonLabel', {
defaultMessage: 'Open',
})}
</EuiFilterButton>
<EuiFilterButton
data-test-subj="StatusFilter closed button"
hasActiveFilters={status === 'closed'}
onClick={() => onChange('closed')}
withNext={true}
>
{i18n.translate('xpack.observability.alerts.statusFilter.closedButtonLabel', {
defaultMessage: 'Closed',
})}
</EuiFilterButton>
<EuiFilterButton
data-test-subj="StatusFilter all button"
hasActiveFilters={status === 'all'}
onClick={() => onChange('all')}
>
{i18n.translate('xpack.observability.alerts.statusFilter.allButtonLabel', {
defaultMessage: 'All',
})}
</EuiFilterButton>
</EuiFilterGroup>
);
}

View file

@ -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<typeof StatusFilter>;
type Args = ComponentProps<typeof WorkflowStatusFilter>;
export default {
title: 'app/Alerts/StatusFilter',
component: StatusFilter,
component: WorkflowStatusFilter,
argTypes: {
onChange: { action: 'change' },
},
};
export function Example({ onChange }: Args) {
const [status, setStatus] = useState<AlertStatus>('open');
const [status, setStatus] = useState<AlertWorkflowStatus>('open');
return (
<StatusFilter
<WorkflowStatusFilter
status={status}
onChange={(value) => {
setStatus(value);

View file

@ -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 = 'all';
const status: AlertWorkflowStatus = 'open';
const props = { onChange, status };
expect(() => render(<StatusFilter {...props} />)).not.toThrowError();
expect(() => render(<WorkflowStatusFilter {...props} />)).not.toThrowError();
});
(['all', 'open', '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(<StatusFilter {...props} />);
const button = getByTestId(`StatusFilter ${status} button`);
const { getByTestId } = render(<WorkflowStatusFilter {...props} />);
const button = getByTestId(`WorkflowStatusFilter ${status} button`);
button.click();

View file

@ -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: Array<EuiButtonGroupOptionProps & { id: AlertWorkflowStatus }> = [
{
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 (
<EuiButtonGroup
legend="Filter by"
color="primary"
options={options}
idSelected={status}
onChange={(id) => onChange(id as AlertWorkflowStatus)}
/>
);
}

View file

@ -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),
}),

View file

@ -24,16 +24,17 @@ import {
ALERT_DURATION,
ALERT_END,
ALERT_ID,
ALERT_START,
ALERT_STATUS,
ALERT_UUID,
EVENT_ACTION,
EVENT_KIND,
ALERT_RULE_CONSUMER,
ALERT_RULE_TYPE_ID,
ALERT_RULE_UUID,
TIMESTAMP,
ALERT_START,
ALERT_STATUS,
ALERT_UUID,
ALERT_WORKFLOW_STATUS,
EVENT_ACTION,
EVENT_KIND,
SPACE_IDS,
TIMESTAMP,
} from '../../common/technical_rule_data_field_names';
import { IRuleDataClient } from '../rule_data_client';
import { AlertExecutorOptionsWithExtraServices } from '../types';
@ -263,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

View file

@ -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",
],

View file

@ -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 { useIsExperimentalFeatureEnabled } from '../../../common/hooks/use_experimental_features';
import { combineQueries } from '../../../timelines/components/timeline/helpers';
import { useKibana } from '../../../common/lib/kibana';
import { inputsSelectors, State, inputsModel } from '../../../common/store';
import { timelineActions, timelineSelectors } from '../../../timelines/store/timeline';
import { TimelineModel } from '../../../timelines/store/timeline/model';
import { timelineDefaults } from '../../../timelines/store/timeline/defaults';
import { updateAlertStatusAction } from './actions';
import {
requiredFieldsForActions,
alertsDefaultModel,
buildAlertStatusFilter,
alertsDefaultModelRuleRegistry,
buildAlertStatusFilterRuleRegistry,
} from './default_config';
import { AditionalFiltersAction, AlertsUtilityBar } from './alerts_utility_bar';
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 { 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 { 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 { 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 {
alertsDefaultModel,
alertsDefaultModelRuleRegistry,
buildAlertStatusFilter,
buildAlertStatusFilterRuleRegistry,
requiredFieldsForActions,
} from './default_config';
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<AlertsTableComponentProps> = ({
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);
@ -173,7 +173,6 @@ export const AlertsTableComponent: React.FC<AlertsTableComponentProps> = ({
case 'open':
title = i18n.OPENED_ALERT_SUCCESS_TOAST(updated);
break;
case 'in-progress':
case 'acknowledged':
title = i18n.ACKNOWLEDGED_ALERT_SUCCESS_TOAST(updated);
}
@ -185,7 +184,7 @@ export const AlertsTableComponent: React.FC<AlertsTableComponentProps> = ({
const onAlertStatusUpdateFailure = useCallback(
(status: Status, error: Error) => {
let title: string;
let title = '';
switch (status) {
case 'closed':
title = i18n.CLOSED_ALERT_FAILED_TOAST;
@ -193,7 +192,6 @@ export const AlertsTableComponent: React.FC<AlertsTableComponentProps> = ({
case 'open':
title = i18n.OPENED_ALERT_FAILED_TOAST;
break;
case 'in-progress':
case 'acknowledged':
title = i18n.ACKNOWLEDGED_ALERT_FAILED_TOAST;
}

View file

@ -9,10 +9,11 @@ import { useCallback } from 'react';
import { useDispatch } from 'react-redux';
import { useGetUserAlertsPermissions } from '@kbn/alerts';
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 { useStatusBulkActionItems } from '../../../../../../timelines/public';
import { useKibana } from '../../../../common/lib/kibana';
import { SERVER_APP_ID } from '../../../../../common/constants';
interface Props {

View file

@ -118,10 +118,12 @@ export interface BulkActionsObjectProp {
}
export type BulkActionsProp = boolean | BulkActionsObjectProp;
export type AlertWorkflowStatus = 'open' | 'closed' | 'acknowledged';
/**
* @deprecated
* TODO: remove when `acknowledged` migrations are finished
*/
export type InProgressStatus = 'in-progress';
export type AlertStatus = 'open' | 'closed' | 'acknowledged' | InProgressStatus;
export type AlertStatus = AlertWorkflowStatus | InProgressStatus;

View file

@ -18138,10 +18138,6 @@
"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": "実験的",

View file

@ -18547,10 +18547,6 @@
"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": "实验性",

View file

@ -9,11 +9,11 @@ import expect from '@kbn/expect';
import {
ALERT_DURATION,
ALERT_END,
ALERT_RULE_UUID,
ALERT_START,
ALERT_STATUS,
ALERT_UUID,
EVENT_KIND,
ALERT_RULE_UUID,
} from '@kbn/rule-data-utils';
import { merge, omit } from 'lodash';
import { FtrProviderContext } from '../../common/ftr_provider_context';
@ -393,6 +393,9 @@ export default function ApiTest({ getService }: FtrProviderContext) {
"kibana.alert.status": Array [
"open",
],
"kibana.alert.workflow_status": Array [
"open",
],
"kibana.space_ids": Array [
"default",
],
@ -500,6 +503,9 @@ export default function ApiTest({ getService }: FtrProviderContext) {
"kibana.alert.status": Array [
"closed",
],
"kibana.alert.workflow_status": Array [
"open",
],
"kibana.space_ids": Array [
"default",
],