Skip to content

Commit

Permalink
[8.0][RAC] 117686 replace alert workflow status in alerts view (elast…
Browse files Browse the repository at this point in the history
…ic#118723) (elastic#120198)

* Add AlertStatus types

* Add alert status filter component

* Remove Filter in action from the t grid table

* Update group buttons to applied Alert status filter instead of Workflow status

* Keep the Alert status button in sync when typing and first page load

* Fix data test object name and translation keys label

* Add possibility to hide the bulk actions

* Update how hide the bulk actions

* Fix showCheckboxes hardcoded "true". Instead use the leadingControlColumns props

* Hide the leading checkboxes  in the T Grid with the bulk actions

* Update showCheckboxes to false

* Fix test as the leading checkboxes are hidden

* Update tests

* Get back disabledCellActions as it's required by T Grid

* Update tests to skip test related to Workflow action buttons

* Skip workflow tests

* Revert fix showCheckboxes

* Remove unused imports

* Revert the o11y tests as the checkBoxes fix is reverted

* Reactive the tests effected by checkBoxes

* Skip alert workflow status

* [Code review] use predefined types

* Remove unused prop

* Use the alert-data index name in the RegEx

* Detect * in KQL as "show al"l alert filter

Co-authored-by: Kibana Machine <[email protected]>

Co-authored-by: Kibana Machine <[email protected]>
  • Loading branch information
fkanout and kibanamachine authored Dec 2, 2021
1 parent 563d793 commit 7b9763f
Show file tree
Hide file tree
Showing 7 changed files with 202 additions and 91 deletions.
13 changes: 13 additions & 0 deletions x-pack/plugins/observability/common/typings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
import * as t from 'io-ts';

export type Maybe<T> = T | null | undefined;
import {
ALERT_STATUS_ACTIVE,
ALERT_STATUS_RECOVERED,
} from '@kbn/rule-data-utils/alerts_as_data_status';

export const alertWorkflowStatusRt = t.keyof({
open: null,
Expand All @@ -25,3 +29,12 @@ export interface ApmIndicesConfig {
apmAgentConfigurationIndex: string;
apmCustomLinkIndex: string;
}
export type AlertStatusFilterButton =
| typeof ALERT_STATUS_ACTIVE
| typeof ALERT_STATUS_RECOVERED
| '';
export interface AlertStatusFilter {
status: AlertStatusFilterButton;
query: string;
label: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* 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 {
ALERT_STATUS_ACTIVE,
ALERT_STATUS_RECOVERED,
} from '@kbn/rule-data-utils/alerts_as_data_status';
import { ALERT_STATUS } from '@kbn/rule-data-utils/technical_field_names';
import { AlertStatusFilterButton } from '../../../common/typings';
import { AlertStatusFilter } from '../../../common/typings';

export interface AlertStatusFilterProps {
status: AlertStatusFilterButton;
onChange: (id: string, value: string) => void;
}

export const allAlerts: AlertStatusFilter = {
status: '',
query: '',
label: i18n.translate('xpack.observability.alerts.alertStatusFilter.showAll', {
defaultMessage: 'Show all',
}),
};

export const activeAlerts: AlertStatusFilter = {
status: ALERT_STATUS_ACTIVE,
query: `${ALERT_STATUS}: "${ALERT_STATUS_ACTIVE}"`,
label: i18n.translate('xpack.observability.alerts.alertStatusFilter.active', {
defaultMessage: 'Active',
}),
};

export const recoveredAlerts: AlertStatusFilter = {
status: ALERT_STATUS_RECOVERED,
query: `${ALERT_STATUS}: "${ALERT_STATUS_RECOVERED}"`,
label: i18n.translate('xpack.observability.alerts.alertStatusFilter.recovered', {
defaultMessage: 'Recovered',
}),
};

const options: EuiButtonGroupOptionProps[] = [
{
id: allAlerts.status,
label: allAlerts.label,
value: allAlerts.query,
'data-test-subj': 'alert-status-filter-show-all-button',
},
{
id: activeAlerts.status,
label: activeAlerts.label,
value: activeAlerts.query,
'data-test-subj': 'alert-status-filter-active-button',
},
{
id: recoveredAlerts.status,
label: recoveredAlerts.label,
value: recoveredAlerts.query,
'data-test-subj': 'alert-status-filter-recovered-button',
},
];

export function AlertsStatusFilter({ status, onChange }: AlertStatusFilterProps) {
return (
<EuiButtonGroup
legend="Filter by"
color="primary"
options={options}
idSelected={status}
onChange={onChange}
/>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
import {
ALERT_DURATION,
ALERT_REASON,
ALERT_RULE_CONSUMER,
ALERT_RULE_PRODUCER,
ALERT_STATUS,
ALERT_WORKFLOW_STATUS,
TIMESTAMP,
Expand All @@ -34,33 +32,30 @@ import {
import styled from 'styled-components';
import React, { Suspense, useMemo, useState, useCallback, useEffect } from 'react';
import usePrevious from 'react-use/lib/usePrevious';
import { get, pick } from 'lodash';
import {
getAlertsPermissions,
useGetUserAlertsPermissions,
} from '../../hooks/use_alert_permission';
import { pick } from 'lodash';
import { getAlertsPermissions } from '../../hooks/use_alert_permission';
import type {
TimelinesUIStart,
TGridType,
TGridState,
TGridModel,
SortDirection,
} from '../../../../timelines/public';
import { useStatusBulkActionItems } from '../../../../timelines/public';

import type { TopAlert } from './';
import { useKibana } from '../../../../../../src/plugins/kibana_react/public';
import type {
ActionProps,
AlertWorkflowStatus,
ColumnHeaderOptions,
ControlColumnProps,
RowRenderer,
} from '../../../../timelines/common';

import { getRenderCellValue } from './render_cell_value';
import { observabilityFeatureId } from '../../../common';
import { useGetUserCasesPermissions } from '../../hooks/use_get_user_cases_permissions';
import { usePluginContext } from '../../hooks/use_plugin_context';
import { getDefaultCellActions } from './default_cell_actions';
import { LazyAlertsFlyout } from '../..';
import { parseAlert } from './parse_alert';
import { CoreStart } from '../../../../../../src/core/public';
Expand All @@ -75,7 +70,6 @@ interface AlertsTableTGridProps {
kuery: string;
workflowStatus: AlertWorkflowStatus;
setRefetch: (ref: () => void) => void;
addToQuery: (value: string) => void;
}

interface ObservabilityActionsProps extends ActionProps {
Expand Down Expand Up @@ -154,21 +148,21 @@ function ObservabilityActions({
const [openActionsPopoverId, setActionsPopover] = useState(null);
const {
timelines,
application: { capabilities },
application: {},
} = useKibana<CoreStart & { timelines: TimelinesUIStart }>().services;

const parseObservabilityAlert = useMemo(
() => parseAlert(observabilityRuleTypeRegistry),
[observabilityRuleTypeRegistry]
);
const alertDataConsumer = useMemo<string>(
() => get(dataFieldEs, ALERT_RULE_CONSUMER, [''])[0],
[dataFieldEs]
);
const alertDataProducer = useMemo<string>(
() => get(dataFieldEs, ALERT_RULE_PRODUCER, [''])[0],
[dataFieldEs]
);
// const alertDataConsumer = useMemo<string>(
// () => get(dataFieldEs, ALERT_RULE_CONSUMER, [''])[0],
// [dataFieldEs]
// );
// const alertDataProducer = useMemo<string>(
// () => get(dataFieldEs, ALERT_RULE_PRODUCER, [''])[0],
// [dataFieldEs]
// );

const alert = parseObservabilityAlert(dataFieldEs);
const { prepend } = core.http.basePath;
Expand All @@ -194,27 +188,29 @@ function ObservabilityActions({
};
}, [data, eventId, ecsData]);

const onAlertStatusUpdated = useCallback(() => {
setActionsPopover(null);
if (refetch) {
refetch();
}
}, [setActionsPopover, refetch]);

const alertPermissions = useGetUserAlertsPermissions(
capabilities,
alertDataConsumer === 'alerts' ? alertDataProducer : alertDataConsumer
);

const statusActionItems = useStatusBulkActionItems({
eventIds: [eventId],
currentStatus,
indexName: ecsData._index ?? '',
setEventsLoading,
setEventsDeleted,
onUpdateSuccess: onAlertStatusUpdated,
onUpdateFailure: onAlertStatusUpdated,
});
// Hide the WorkFlow filter, but keep its code as required in https://github.com/elastic/kibana/issues/117686

// const onAlertStatusUpdated = useCallback(() => {
// setActionsPopover(null);
// if (refetch) {
// refetch();
// }
// }, [setActionsPopover, refetch]);

// const alertPermissions = useGetUserAlertsPermissions(
// capabilities,
// alertDataConsumer === 'alerts' ? alertDataProducer : alertDataConsumer
// );

// const statusActionItems = useStatusBulkActionItems({
// eventIds: [eventId],
// currentStatus,
// indexName: ecsData._index ?? '',
// setEventsLoading,
// setEventsDeleted,
// onUpdateSuccess: onAlertStatusUpdated,
// onUpdateFailure: onAlertStatusUpdated,
// });

const ruleId = alert.fields['kibana.alert.rule.uuid'] ?? null;
const linkToRule = ruleId ? prepend(paths.management.ruleDetails(ruleId)) : null;
Expand All @@ -239,7 +235,8 @@ function ObservabilityActions({
}),
]
: []),
...(alertPermissions.crud ? statusActionItems : []),
// Hide the WorkFlow filter, but keep its code as required in https://github.com/elastic/kibana/issues/117686
// ...(alertPermissions.crud ? statusActionItems : []),
...(!!linkToRule
? [
<EuiContextMenuItem
Expand All @@ -252,15 +249,7 @@ function ObservabilityActions({
]
: []),
];
}, [
afterCaseSelection,
casePermissions,
timelines,
event,
statusActionItems,
alertPermissions,
linkToRule,
]);
}, [afterCaseSelection, casePermissions, timelines, event, linkToRule]);

const actionsToolTip =
actionsMenuItems.length <= 0
Expand Down Expand Up @@ -320,6 +309,7 @@ function ObservabilityActions({
</>
);
}
// Hide the WorkFlow filter, but keep its code as required in https://github.com/elastic/kibana/issues/117686

const FIELDS_WITHOUT_CELL_ACTIONS = [
'@timestamp',
Expand All @@ -330,7 +320,7 @@ const FIELDS_WITHOUT_CELL_ACTIONS = [
];

export function AlertsTableTGrid(props: AlertsTableTGridProps) {
const { indexNames, rangeFrom, rangeTo, kuery, workflowStatus, setRefetch, addToQuery } = props;
const { indexNames, rangeFrom, rangeTo, kuery, workflowStatus, setRefetch } = props;
const prevWorkflowStatus = usePrevious(workflowStatus);
const {
timelines,
Expand Down Expand Up @@ -382,7 +372,7 @@ export function AlertsTableTGrid(props: AlertsTableTGridProps) {
}
}, []);

const leadingControlColumns = useMemo(() => {
const leadingControlColumns: ControlColumnProps[] = useMemo(() => {
return [
{
id: 'expand',
Expand Down Expand Up @@ -428,7 +418,8 @@ export function AlertsTableTGrid(props: AlertsTableTGridProps) {
type,
columns: tGridState?.columns ?? columns,
deletedEventIds,
defaultCellActions: getDefaultCellActions({ addToQuery }),
// Hide the WorkFlow filter, but keep its code as required in https://github.com/elastic/kibana/issues/117686
// defaultCellActions: getDefaultCellActions({ addToQuery }),
disabledCellActions: FIELDS_WITHOUT_CELL_ACTIONS,
end: rangeTo,
filters: [],
Expand Down Expand Up @@ -462,7 +453,6 @@ export function AlertsTableTGrid(props: AlertsTableTGridProps) {
};
}, [
casePermissions,
addToQuery,
rangeTo,
hasAlertsCrudPermissions,
indexNames,
Expand Down
Loading

0 comments on commit 7b9763f

Please sign in to comment.