mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[RAM] Refactor alert 011y fly-out to just use hook (#135161)
* refactor alert flyout to just use hook * fix unit test * thanks to test, we find out discrepency between reconcilliation of components * open rule details from o11y
This commit is contained in:
parent
1916efbb1c
commit
c4350f1f2a
25 changed files with 239 additions and 439 deletions
|
@ -51,7 +51,7 @@ describe('Case View Page activity tab', () => {
|
|||
values: ['alert-id-1'],
|
||||
},
|
||||
},
|
||||
flyoutState: 'internal',
|
||||
flyoutSize: 'm',
|
||||
showExpandToDetails: true,
|
||||
});
|
||||
});
|
||||
|
@ -73,7 +73,7 @@ describe('Case View Page activity tab', () => {
|
|||
values: ['alert-id-1'],
|
||||
},
|
||||
},
|
||||
flyoutState: 'external',
|
||||
flyoutSize: 's',
|
||||
showExpandToDetails: false,
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,8 +7,7 @@
|
|||
|
||||
import React, { useMemo } from 'react';
|
||||
|
||||
import { AlertsTableFlyoutState } from '@kbn/triggers-actions-ui-plugin/public';
|
||||
import { EuiFlexItem, EuiFlexGroup, EuiProgress } from '@elastic/eui';
|
||||
import { EuiFlexItem, EuiFlexGroup, EuiProgress, EuiFlyoutSize } from '@elastic/eui';
|
||||
import { Case } from '../../../../common';
|
||||
import { useKibana } from '../../../common/lib/kibana';
|
||||
import { getManualAlertIds, getRegistrationContextFromAlerts } from './helpers';
|
||||
|
@ -41,9 +40,7 @@ export const CaseViewAlerts = ({ caseData }: CaseViewAlertsProps) => {
|
|||
alertsTableConfigurationRegistry: triggersActionsUi.alertsTableConfigurationRegistry,
|
||||
configurationId: caseData.owner,
|
||||
id: `case-details-alerts-${caseData.owner}`,
|
||||
flyoutState: alertFeatureIds.includes('siem')
|
||||
? AlertsTableFlyoutState.internal
|
||||
: AlertsTableFlyoutState.external,
|
||||
flyoutSize: (alertFeatureIds.includes('siem') ? 'm' : 's') as EuiFlyoutSize,
|
||||
featureIds: alertFeatureIds,
|
||||
query: alertIdsQuery,
|
||||
showExpandToDetails: alertFeatureIds.includes('siem'),
|
||||
|
|
|
@ -5,36 +5,26 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type {
|
||||
AlertTableFlyoutComponent,
|
||||
GetRenderCellValue,
|
||||
} from '@kbn/triggers-actions-ui-plugin/public';
|
||||
import { lazy } from 'react';
|
||||
|
||||
import type { GetRenderCellValue } from '@kbn/triggers-actions-ui-plugin/public';
|
||||
import { observabilityFeatureId } from '../../common';
|
||||
import { TopAlert, useToGetInternalFlyout } from '../pages/alerts';
|
||||
import { getRenderCellValue } from '../pages/alerts/components/render_cell_value';
|
||||
import { addDisplayNames } from '../pages/alerts/containers/alerts_table_t_grid/add_display_names';
|
||||
import { columns as alertO11yColumns } from '../pages/alerts/containers/alerts_table_t_grid/alerts_table_t_grid';
|
||||
import type { ObservabilityRuleTypeRegistry } from '../rules/create_observability_rule_type_registry';
|
||||
|
||||
const AlertsPageFlyoutHeaderLazy = lazy(
|
||||
() => import('../pages/alerts/components/alerts_flyout/alerts_flyout_header')
|
||||
);
|
||||
const AlertsPageFlyoutBodyLazy = lazy(
|
||||
() => import('../pages/alerts/components/alerts_flyout/alerts_flyout_body')
|
||||
);
|
||||
const AlertsFlyoutFooterLazy = lazy(
|
||||
() => import('../pages/alerts/components/alerts_flyout/alerts_flyout_footer')
|
||||
);
|
||||
|
||||
const getO11yAlertsTableConfiguration = () => ({
|
||||
const getO11yAlertsTableConfiguration = (
|
||||
observabilityRuleTypeRegistry: ObservabilityRuleTypeRegistry
|
||||
) => ({
|
||||
id: observabilityFeatureId,
|
||||
columns: alertO11yColumns.map(addDisplayNames),
|
||||
externalFlyout: {
|
||||
header: AlertsPageFlyoutHeaderLazy as AlertTableFlyoutComponent,
|
||||
body: AlertsPageFlyoutBodyLazy as AlertTableFlyoutComponent,
|
||||
footer: AlertsFlyoutFooterLazy as AlertTableFlyoutComponent,
|
||||
useInternalFlyout: () => {
|
||||
const { header, body, footer } = useToGetInternalFlyout(observabilityRuleTypeRegistry);
|
||||
return { header, body, footer };
|
||||
},
|
||||
getRenderCellValue: getRenderCellValue as GetRenderCellValue,
|
||||
getRenderCellValue: (({ setFlyoutAlert }: { setFlyoutAlert: (data: TopAlert) => void }) => {
|
||||
return getRenderCellValue({ observabilityRuleTypeRegistry, setFlyoutAlert });
|
||||
}) as unknown as GetRenderCellValue,
|
||||
});
|
||||
|
||||
export { getO11yAlertsTableConfiguration };
|
||||
|
|
|
@ -5,41 +5,15 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import {
|
||||
EuiButton,
|
||||
EuiDescriptionList,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiFlyout,
|
||||
EuiFlyoutBody,
|
||||
EuiFlyoutFooter,
|
||||
EuiFlyoutHeader,
|
||||
EuiFlyoutProps,
|
||||
EuiLink,
|
||||
EuiSpacer,
|
||||
EuiText,
|
||||
EuiTitle,
|
||||
EuiHorizontalRule,
|
||||
} from '@elastic/eui';
|
||||
import {
|
||||
ALERT_DURATION,
|
||||
ALERT_EVALUATION_THRESHOLD,
|
||||
ALERT_EVALUATION_VALUE,
|
||||
ALERT_UUID,
|
||||
ALERT_RULE_CATEGORY,
|
||||
ALERT_RULE_NAME,
|
||||
ALERT_STATUS_ACTIVE,
|
||||
ALERT_STATUS_RECOVERED,
|
||||
} from '@kbn/rule-data-utils';
|
||||
import moment from 'moment-timezone';
|
||||
import { EuiFlyout, EuiFlyoutHeader, EuiFlyoutProps } from '@elastic/eui';
|
||||
import { ALERT_UUID } from '@kbn/rule-data-utils';
|
||||
import React, { useMemo } from 'react';
|
||||
import { useKibana, useUiSetting } from '@kbn/kibana-react-plugin/public';
|
||||
import type { TopAlert } from '../../containers';
|
||||
import { asDuration } from '../../../../../common/utils/formatters';
|
||||
import type { ObservabilityRuleTypeRegistry } from '../../../../rules/create_observability_rule_type_registry';
|
||||
import { parseAlert } from '../parse_alert';
|
||||
import { AlertStatusIndicator } from '../../../../components/shared/alert_status_indicator';
|
||||
import { translations, paths } from '../../../../config';
|
||||
import AlertsFlyoutHeader from './alerts_flyout_header';
|
||||
import AlertsFlyoutBody from './alerts_flyout_body';
|
||||
import AlertsFlyoutFooter from './alerts_flyout_footer';
|
||||
|
||||
type AlertsFlyoutProps = {
|
||||
alert?: TopAlert;
|
||||
|
@ -57,11 +31,6 @@ export function AlertsFlyout({
|
|||
onClose,
|
||||
selectedAlertId,
|
||||
}: AlertsFlyoutProps) {
|
||||
const dateFormat = useUiSetting<string>('dateFormat');
|
||||
const { services } = useKibana();
|
||||
const { http } = services;
|
||||
const prepend = http?.basePath.prepend;
|
||||
|
||||
const decoratedAlerts = useMemo(() => {
|
||||
const parseObservabilityAlert = parseAlert(observabilityRuleTypeRegistry);
|
||||
return (alerts ?? []).map(parseObservabilityAlert);
|
||||
|
@ -69,107 +38,19 @@ export function AlertsFlyout({
|
|||
|
||||
let alertData = alert;
|
||||
if (!alertData) {
|
||||
alertData = decoratedAlerts?.find((a) => a.fields[ALERT_UUID] === selectedAlertId);
|
||||
alertData = decoratedAlerts?.find((a) => a.fields[ALERT_UUID] === selectedAlertId) as TopAlert;
|
||||
}
|
||||
if (!alertData) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const ruleId = alertData.fields['kibana.alert.rule.uuid'] ?? null;
|
||||
const linkToRule = ruleId && prepend ? prepend(paths.observability.ruleDetails(ruleId)) : null;
|
||||
const overviewListItems = [
|
||||
{
|
||||
title: translations.alertsFlyout.statusLabel,
|
||||
description: (
|
||||
<AlertStatusIndicator
|
||||
alertStatus={alertData.active ? ALERT_STATUS_ACTIVE : ALERT_STATUS_RECOVERED}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: translations.alertsFlyout.startedAtLabel,
|
||||
description: (
|
||||
<span title={alertData.start.toString()}>{moment(alertData.start).format(dateFormat)}</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: translations.alertsFlyout.lastUpdatedLabel,
|
||||
description: (
|
||||
<span title={alertData.lastUpdated.toString()}>
|
||||
{moment(alertData.lastUpdated).format(dateFormat)}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: translations.alertsFlyout.durationLabel,
|
||||
description: asDuration(alertData.fields[ALERT_DURATION], { extended: true }),
|
||||
},
|
||||
{
|
||||
title: translations.alertsFlyout.expectedValueLabel,
|
||||
description: alertData.fields[ALERT_EVALUATION_THRESHOLD] ?? '-',
|
||||
},
|
||||
{
|
||||
title: translations.alertsFlyout.actualValueLabel,
|
||||
description: alertData.fields[ALERT_EVALUATION_VALUE] ?? '-',
|
||||
},
|
||||
{
|
||||
title: translations.alertsFlyout.ruleTypeLabel,
|
||||
description: alertData.fields[ALERT_RULE_CATEGORY] ?? '-',
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<EuiFlyout onClose={onClose} size="s" data-test-subj="alertsFlyout">
|
||||
<EuiFlyoutHeader hasBorder>
|
||||
<EuiSpacer size="s" />
|
||||
<EuiTitle size="m" data-test-subj="alertsFlyoutTitle">
|
||||
<h2>{alertData.fields[ALERT_RULE_NAME]}</h2>
|
||||
</EuiTitle>
|
||||
<AlertsFlyoutHeader alert={alertData} />
|
||||
</EuiFlyoutHeader>
|
||||
<EuiFlyoutBody>
|
||||
<EuiTitle size="xs">
|
||||
<h4>{translations.alertsFlyout.reasonTitle}</h4>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size="s" />
|
||||
<EuiText size="s">{alertData.reason}</EuiText>
|
||||
<EuiSpacer size="s" />
|
||||
{!!linkToRule && (
|
||||
<EuiLink href={linkToRule} data-test-subj="viewRuleDetailsFlyout">
|
||||
{translations.alertsFlyout.viewRulesDetailsLinkText}
|
||||
</EuiLink>
|
||||
)}
|
||||
<EuiHorizontalRule size="full" />
|
||||
<EuiTitle size="xs">
|
||||
<h4>{translations.alertsFlyout.documentSummaryTitle}</h4>
|
||||
</EuiTitle>
|
||||
<EuiSpacer size="m" />
|
||||
<EuiDescriptionList
|
||||
compressed={true}
|
||||
type="responsiveColumn"
|
||||
listItems={overviewListItems}
|
||||
titleProps={{
|
||||
'data-test-subj': 'alertsFlyoutDescriptionListTitle',
|
||||
}}
|
||||
descriptionProps={{
|
||||
'data-test-subj': 'alertsFlyoutDescriptionListDescription',
|
||||
}}
|
||||
/>
|
||||
</EuiFlyoutBody>
|
||||
{alertData.link && !isInApp && (
|
||||
<EuiFlyoutFooter>
|
||||
<EuiFlexGroup justifyContent="flexEnd">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton
|
||||
href={prepend && prepend(alertData.link)}
|
||||
data-test-subj="alertsFlyoutViewInAppButton"
|
||||
fill
|
||||
>
|
||||
{translations.alertsFlyout.viewInAppButtonText}
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlyoutFooter>
|
||||
)}
|
||||
<AlertsFlyoutBody alert={alertData} />
|
||||
<AlertsFlyoutFooter alert={alertData} isInApp={isInApp} />
|
||||
</EuiFlyout>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -13,12 +13,14 @@ import {
|
|||
EuiLink,
|
||||
EuiHorizontalRule,
|
||||
EuiDescriptionList,
|
||||
EuiFlyoutBody,
|
||||
} from '@elastic/eui';
|
||||
import {
|
||||
ALERT_DURATION,
|
||||
ALERT_EVALUATION_THRESHOLD,
|
||||
ALERT_EVALUATION_VALUE,
|
||||
ALERT_RULE_CATEGORY,
|
||||
ALERT_RULE_UUID,
|
||||
ALERT_STATUS_ACTIVE,
|
||||
ALERT_STATUS_RECOVERED,
|
||||
} from '@kbn/rule-data-utils';
|
||||
|
@ -27,22 +29,17 @@ import { useKibana, useUiSetting } from '@kbn/kibana-react-plugin/public';
|
|||
import { asDuration } from '../../../../../common/utils/formatters';
|
||||
import { translations, paths } from '../../../../config';
|
||||
import { AlertStatusIndicator } from '../../../../components/shared/alert_status_indicator';
|
||||
import { usePluginContext } from '../../../../hooks/use_plugin_context';
|
||||
import { parseAlert } from '../parse_alert';
|
||||
import { FlyoutProps } from './types';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default function AlertsFlyoutBody(props: FlyoutProps) {
|
||||
const { observabilityRuleTypeRegistry } = usePluginContext();
|
||||
const alert = props.alert.start
|
||||
? props.alert
|
||||
: parseAlert(observabilityRuleTypeRegistry)(props.alert as unknown as Record<string, unknown>);
|
||||
const alert = props.alert;
|
||||
const { services } = useKibana();
|
||||
const { http } = services;
|
||||
const dateFormat = useUiSetting<string>('dateFormat');
|
||||
const prepend = http?.basePath.prepend;
|
||||
const ruleId = get(props.alert, 'kibana.alert.rule.uuid') ?? null;
|
||||
const linkToRule = ruleId && prepend ? prepend(paths.management.ruleDetails(ruleId)) : null;
|
||||
const ruleId = get(props.alert.fields, ALERT_RULE_UUID) ?? null;
|
||||
const linkToRule = ruleId && prepend ? prepend(paths.observability.ruleDetails(ruleId)) : null;
|
||||
const overviewListItems = [
|
||||
{
|
||||
title: translations.alertsFlyout.statusLabel,
|
||||
|
@ -53,11 +50,19 @@ export default function AlertsFlyoutBody(props: FlyoutProps) {
|
|||
),
|
||||
},
|
||||
{
|
||||
title: translations.alertsFlyout.lastUpdatedLabel,
|
||||
title: translations.alertsFlyout.startedAtLabel,
|
||||
description: (
|
||||
<span title={alert.start.toString()}>{moment(alert.start).format(dateFormat)}</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: translations.alertsFlyout.lastUpdatedLabel,
|
||||
description: (
|
||||
<span title={alert.lastUpdated.toString()}>
|
||||
{moment(alert.lastUpdated).format(dateFormat)}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: translations.alertsFlyout.durationLabel,
|
||||
description: asDuration(alert.fields[ALERT_DURATION], { extended: true }),
|
||||
|
@ -77,7 +82,7 @@ export default function AlertsFlyoutBody(props: FlyoutProps) {
|
|||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<EuiFlyoutBody>
|
||||
<EuiTitle size="xs">
|
||||
<h4>{translations.alertsFlyout.reasonTitle}</h4>
|
||||
</EuiTitle>
|
||||
|
@ -105,6 +110,6 @@ export default function AlertsFlyoutBody(props: FlyoutProps) {
|
|||
'data-test-subj': 'alertsFlyoutDescriptionListDescription',
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
</EuiFlyoutBody>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
import React from 'react';
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiButton } from '@elastic/eui';
|
||||
import { EuiFlyoutFooter, EuiFlexGroup, EuiFlexItem, EuiButton } from '@elastic/eui';
|
||||
import { useKibana } from '@kbn/kibana-react-plugin/public';
|
||||
import { FlyoutProps } from './types';
|
||||
import { translations } from '../../../../config';
|
||||
|
@ -18,16 +18,18 @@ export default function AlertsFlyoutFooter({ alert, isInApp }: FlyoutProps & { i
|
|||
|
||||
if (!alert.link || isInApp) return <></>;
|
||||
return (
|
||||
<EuiFlexGroup justifyContent="flexEnd">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton
|
||||
href={prepend && prepend(alert.link)}
|
||||
data-test-subj="alertsFlyoutViewInAppButton"
|
||||
fill
|
||||
>
|
||||
{translations.alertsFlyout.viewInAppButtonText}
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
<EuiFlyoutFooter>
|
||||
<EuiFlexGroup justifyContent="flexEnd">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton
|
||||
href={prepend && prepend(alert.link)}
|
||||
data-test-subj="alertsFlyoutViewInAppButton"
|
||||
fill
|
||||
>
|
||||
{translations.alertsFlyout.viewInAppButtonText}
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlyoutFooter>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
import React from 'react';
|
||||
import { ALERT_RULE_NAME } from '@kbn/rule-data-utils';
|
||||
import { get } from 'lodash';
|
||||
import { EuiSpacer, EuiTitle } from '@elastic/eui';
|
||||
import { FlyoutProps } from './types';
|
||||
|
||||
|
@ -16,7 +15,7 @@ export default function AlertsFlyoutHeader({ alert }: FlyoutProps) {
|
|||
<>
|
||||
<EuiSpacer size="s" />
|
||||
<EuiTitle size="m" data-test-subj="alertsFlyoutTitle">
|
||||
<h2>{get(alert, ALERT_RULE_NAME)}</h2>
|
||||
<h2>{alert.fields[ALERT_RULE_NAME]}</h2>
|
||||
</EuiTitle>
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -1,8 +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.
|
||||
*/
|
||||
|
||||
export { AlertsFlyout } from './alerts_flyout';
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* 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 React, { useCallback, useMemo } from 'react';
|
||||
import { AlertsTableFlyoutBaseProps } from '@kbn/triggers-actions-ui-plugin/public';
|
||||
import { ObservabilityRuleTypeRegistry } from '../../../../rules/create_observability_rule_type_registry';
|
||||
import { parseAlert } from '../parse_alert';
|
||||
|
||||
import AlertsFlyoutHeader from './alerts_flyout_header';
|
||||
import AlertsFlyoutBody from './alerts_flyout_body';
|
||||
import AlertsFlyoutFooter from './alerts_flyout_footer';
|
||||
|
||||
export { AlertsFlyout } from './alerts_flyout';
|
||||
|
||||
export const useToGetInternalFlyout = (
|
||||
observabilityRuleTypeRegistry: ObservabilityRuleTypeRegistry
|
||||
) => {
|
||||
const body = useCallback(
|
||||
(props: AlertsTableFlyoutBaseProps) => {
|
||||
const alert = parseAlert(observabilityRuleTypeRegistry)(
|
||||
props.alert as unknown as Record<string, unknown>
|
||||
);
|
||||
return <AlertsFlyoutBody alert={alert} />;
|
||||
},
|
||||
[observabilityRuleTypeRegistry]
|
||||
);
|
||||
|
||||
const header = useCallback(
|
||||
(props: AlertsTableFlyoutBaseProps) => {
|
||||
const alert = parseAlert(observabilityRuleTypeRegistry)(
|
||||
props.alert as unknown as Record<string, unknown>
|
||||
);
|
||||
return <AlertsFlyoutHeader alert={alert} />;
|
||||
},
|
||||
[observabilityRuleTypeRegistry]
|
||||
);
|
||||
|
||||
const footer = useCallback(
|
||||
(props: AlertsTableFlyoutBaseProps) => {
|
||||
const alert = parseAlert(observabilityRuleTypeRegistry)(
|
||||
props.alert as unknown as Record<string, unknown>
|
||||
);
|
||||
return <AlertsFlyoutFooter isInApp={false} alert={alert} />;
|
||||
},
|
||||
[observabilityRuleTypeRegistry]
|
||||
);
|
||||
|
||||
return useMemo(
|
||||
() => ({
|
||||
body,
|
||||
header,
|
||||
footer,
|
||||
}),
|
||||
[body, header, footer]
|
||||
);
|
||||
};
|
|
@ -4,17 +4,9 @@
|
|||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
import { AlertsTableFlyoutBaseProps } from '@kbn/triggers-actions-ui-plugin/public';
|
||||
import { ParsedTechnicalFields } from '@kbn/rule-registry-plugin/common/parse_technical_fields';
|
||||
import { ParsedExperimentalFields } from '@kbn/rule-registry-plugin/common/parse_experimental_fields';
|
||||
import { EcsFieldsResponse } from '@kbn/rule-registry-plugin/common/search_strategy';
|
||||
|
||||
export type FlyoutProps = AlertsTableFlyoutBaseProps & {
|
||||
alert: EcsFieldsResponse & {
|
||||
fields: ParsedTechnicalFields & ParsedExperimentalFields;
|
||||
start: number;
|
||||
reason: string;
|
||||
link?: string;
|
||||
active: boolean;
|
||||
};
|
||||
};
|
||||
import { TopAlert } from '../../containers';
|
||||
|
||||
export interface FlyoutProps {
|
||||
alert: TopAlert;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
import { ALERT_STATUS, ALERT_STATUS_ACTIVE, ALERT_STATUS_RECOVERED } from '@kbn/rule-data-utils';
|
||||
import type { CellValueElementProps } from '@kbn/timelines-plugin/common';
|
||||
import { createObservabilityRuleTypeRegistryMock } from '../../../../rules/observability_rule_type_registry_mock';
|
||||
import * as PluginHook from '../../../../hooks/use_plugin_context';
|
||||
import { render } from '../../../../utils/test_helper';
|
||||
import { getRenderCellValue } from './render_cell_value';
|
||||
|
||||
|
@ -18,15 +17,10 @@ interface AlertsTableRow {
|
|||
|
||||
describe('getRenderCellValue', () => {
|
||||
const observabilityRuleTypeRegistryMock = createObservabilityRuleTypeRegistryMock();
|
||||
jest.spyOn(PluginHook, 'usePluginContext').mockImplementation(
|
||||
() =>
|
||||
({
|
||||
observabilityRuleTypeRegistry: observabilityRuleTypeRegistryMock,
|
||||
} as any)
|
||||
);
|
||||
|
||||
const renderCellValue = getRenderCellValue({
|
||||
setFlyoutAlert: jest.fn(),
|
||||
observabilityRuleTypeRegistry: observabilityRuleTypeRegistryMock,
|
||||
});
|
||||
|
||||
describe('when column is alert status', () => {
|
||||
|
|
|
@ -22,7 +22,7 @@ import { asDuration } from '../../../../../common/utils/formatters';
|
|||
import { SeverityBadge } from '../severity_badge';
|
||||
import { TopAlert } from '../..';
|
||||
import { parseAlert } from '../parse_alert';
|
||||
import { usePluginContext } from '../../../../hooks/use_plugin_context';
|
||||
import { ObservabilityRuleTypeRegistry } from '../../../../rules/create_observability_rule_type_registry';
|
||||
|
||||
export const getMappedNonEcsValue = ({
|
||||
data,
|
||||
|
@ -46,12 +46,13 @@ export const getMappedNonEcsValue = ({
|
|||
|
||||
export const getRenderCellValue = ({
|
||||
setFlyoutAlert,
|
||||
observabilityRuleTypeRegistry,
|
||||
}: {
|
||||
setFlyoutAlert: (data: TopAlert) => void;
|
||||
observabilityRuleTypeRegistry: ObservabilityRuleTypeRegistry;
|
||||
}) => {
|
||||
return ({ columnId, data }: CellValueElementProps) => {
|
||||
if (!data) return null;
|
||||
const { observabilityRuleTypeRegistry } = usePluginContext();
|
||||
const value = getMappedNonEcsValue({
|
||||
data,
|
||||
fieldName: columnId,
|
||||
|
|
|
@ -325,6 +325,7 @@ export function AlertsTableTGrid(props: AlertsTableTGridProps) {
|
|||
timelines,
|
||||
application: { capabilities },
|
||||
} = useKibana<ObservabilityAppServices>().services;
|
||||
const { observabilityRuleTypeRegistry } = usePluginContext();
|
||||
|
||||
const [flyoutAlert, setFlyoutAlert] = useState<TopAlert | undefined>(undefined);
|
||||
const [tGridState, setTGridState] = useState<Partial<TGridModel> | null>(
|
||||
|
@ -432,7 +433,7 @@ export function AlertsTableTGrid(props: AlertsTableTGridProps) {
|
|||
query: kuery ?? '',
|
||||
language: 'kuery',
|
||||
},
|
||||
renderCellValue: getRenderCellValue({ setFlyoutAlert }),
|
||||
renderCellValue: getRenderCellValue({ setFlyoutAlert, observabilityRuleTypeRegistry }),
|
||||
rowRenderers: NO_ROW_RENDER,
|
||||
// TODO: implement Kibana data view runtime fields in observability
|
||||
runtimeMappings: {},
|
||||
|
@ -471,6 +472,7 @@ export function AlertsTableTGrid(props: AlertsTableTGridProps) {
|
|||
hasAlertsCrudPermissions,
|
||||
indexNames,
|
||||
itemsPerPage,
|
||||
observabilityRuleTypeRegistry,
|
||||
onStateChange,
|
||||
kuery,
|
||||
rangeFrom,
|
||||
|
@ -480,7 +482,6 @@ export function AlertsTableTGrid(props: AlertsTableTGridProps) {
|
|||
]);
|
||||
|
||||
const handleFlyoutClose = () => setFlyoutAlert(undefined);
|
||||
const { observabilityRuleTypeRegistry } = usePluginContext();
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
|
@ -15,6 +15,7 @@ import {
|
|||
EuiButtonEmpty,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiFlyoutSize,
|
||||
EuiButtonIcon,
|
||||
EuiPanel,
|
||||
EuiTitle,
|
||||
|
@ -36,7 +37,6 @@ import {
|
|||
RuleType,
|
||||
getNotifyWhenOptions,
|
||||
RuleEventLogListProps,
|
||||
AlertsTableFlyoutState,
|
||||
} from '@kbn/triggers-actions-ui-plugin/public';
|
||||
// TODO: use a Delete modal from triggersActionUI when it's sharable
|
||||
import { ALERTS_FEATURE_ID } from '@kbn/alerting-plugin/common';
|
||||
|
@ -177,7 +177,7 @@ export function RuleDetailsPage() {
|
|||
alertsTableConfigurationRegistry,
|
||||
configurationId: observabilityFeatureId,
|
||||
id: `case-details-alerts-o11y`,
|
||||
flyoutState: AlertsTableFlyoutState.external,
|
||||
flyoutSize: 's' as EuiFlyoutSize,
|
||||
featureIds: [features] as AlertConsumers[],
|
||||
query: {
|
||||
bool: {
|
||||
|
|
|
@ -37,7 +37,10 @@ import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/public';
|
|||
import { observabilityAppId, observabilityFeatureId, casesPath } from '../common';
|
||||
import { createLazyObservabilityPageTemplate } from './components/shared';
|
||||
import { registerDataHandler } from './data_handler';
|
||||
import { createObservabilityRuleTypeRegistry } from './rules/create_observability_rule_type_registry';
|
||||
import {
|
||||
createObservabilityRuleTypeRegistry,
|
||||
ObservabilityRuleTypeRegistry,
|
||||
} from './rules/create_observability_rule_type_registry';
|
||||
import { createCallObservabilityApi } from './services/call_observability_api';
|
||||
import { createNavigationRegistry, NavigationEntry } from './services/navigation_registry';
|
||||
import { updateGlobalNavigation } from './update_global_navigation';
|
||||
|
@ -83,6 +86,8 @@ export class Plugin
|
|||
{
|
||||
private readonly appUpdater$ = new BehaviorSubject<AppUpdater>(() => ({}));
|
||||
private readonly navigationRegistry = createNavigationRegistry();
|
||||
private observabilityRuleTypeRegistry: ObservabilityRuleTypeRegistry =
|
||||
{} as ObservabilityRuleTypeRegistry;
|
||||
|
||||
// Define deep links as constant and hidden. Whether they are shown or hidden
|
||||
// in the global navigation will happen in `updateGlobalNavigation`.
|
||||
|
@ -134,7 +139,7 @@ export class Plugin
|
|||
|
||||
createCallObservabilityApi(coreSetup.http);
|
||||
|
||||
const observabilityRuleTypeRegistry = createObservabilityRuleTypeRegistry(
|
||||
this.observabilityRuleTypeRegistry = createObservabilityRuleTypeRegistry(
|
||||
pluginsSetup.triggersActionsUi.ruleTypeRegistry
|
||||
);
|
||||
|
||||
|
@ -158,7 +163,7 @@ export class Plugin
|
|||
core: coreStart,
|
||||
plugins: pluginsStart,
|
||||
appMountParameters: params,
|
||||
observabilityRuleTypeRegistry,
|
||||
observabilityRuleTypeRegistry: this.observabilityRuleTypeRegistry,
|
||||
ObservabilityPageTemplate: navigation.PageTemplate,
|
||||
kibanaFeatures,
|
||||
usageCollection: pluginsSetup.usageCollection,
|
||||
|
@ -257,7 +262,7 @@ export class Plugin
|
|||
|
||||
return {
|
||||
dashboard: { register: registerDataHandler },
|
||||
observabilityRuleTypeRegistry,
|
||||
observabilityRuleTypeRegistry: this.observabilityRuleTypeRegistry,
|
||||
navigation: {
|
||||
registerSections: this.navigationRegistry.registerSections,
|
||||
},
|
||||
|
@ -286,7 +291,7 @@ export class Plugin
|
|||
const { getO11yAlertsTableConfiguration } = await import(
|
||||
'./config/register_alerts_table_configuration'
|
||||
);
|
||||
return getO11yAlertsTableConfiguration();
|
||||
return getO11yAlertsTableConfiguration(this.observabilityRuleTypeRegistry);
|
||||
};
|
||||
|
||||
const { alertsTableConfigurationRegistry } = pluginsStart.triggersActionsUi;
|
||||
|
|
|
@ -8,7 +8,7 @@ import React from 'react';
|
|||
import { mountWithIntl, nextTick } from '@kbn/test-jest-helpers';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { AlertsFlyout } from './alerts_flyout';
|
||||
import { AlertsField, AlertsTableFlyoutState } from '../../../../types';
|
||||
import { AlertsField } from '../../../../types';
|
||||
|
||||
const onClose = jest.fn();
|
||||
const onPaginate = jest.fn();
|
||||
|
@ -33,9 +33,6 @@ const props = {
|
|||
initialWidth: 250,
|
||||
},
|
||||
],
|
||||
externalFlyout: {
|
||||
body: () => <h3>External flyout body</h3>,
|
||||
},
|
||||
useInternalFlyout: () => ({
|
||||
body: () => <h3>Internal flyout body</h3>,
|
||||
header: null,
|
||||
|
@ -49,7 +46,6 @@ const props = {
|
|||
flyoutIndex: 0,
|
||||
alertsCount: 4,
|
||||
isLoading: false,
|
||||
state: AlertsTableFlyoutState.internal,
|
||||
onClose,
|
||||
onPaginate,
|
||||
};
|
||||
|
@ -66,123 +62,70 @@ describe('AlertsFlyout', () => {
|
|||
wrapper.update();
|
||||
});
|
||||
expect(wrapper.find('h3').first().text()).toBe('Internal flyout body');
|
||||
|
||||
const externalWrapper = mountWithIntl(
|
||||
<AlertsFlyout
|
||||
{...{
|
||||
...props,
|
||||
state: AlertsTableFlyoutState.external,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
await act(async () => {
|
||||
await nextTick();
|
||||
externalWrapper.update();
|
||||
});
|
||||
expect(externalWrapper.find('h3').first().text()).toBe('External flyout body');
|
||||
});
|
||||
|
||||
const configurations = [AlertsTableFlyoutState.external, AlertsTableFlyoutState.internal];
|
||||
for (const configuration of configurations) {
|
||||
const base = {
|
||||
body: () => <h5>Body</h5>,
|
||||
footer: () => null,
|
||||
const base = {
|
||||
body: () => null,
|
||||
header: () => null,
|
||||
footer: () => null,
|
||||
};
|
||||
it(`should use header from useInternalFlyout configuration`, async () => {
|
||||
const customProps = {
|
||||
...props,
|
||||
alertsTableConfiguration: {
|
||||
...props.alertsTableConfiguration,
|
||||
useInternalFlyout: () => ({
|
||||
...base,
|
||||
header: () => <h4>Header</h4>,
|
||||
footer: () => null,
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
||||
it(`should use ${configuration} header configuration`, async () => {
|
||||
const customProps = {
|
||||
...props,
|
||||
alertsTableConfiguration: {
|
||||
...props.alertsTableConfiguration,
|
||||
...(configuration === AlertsTableFlyoutState.external
|
||||
? {
|
||||
[`${configuration}Flyout`]: {
|
||||
...base,
|
||||
header: () => <h4>Header</h4>,
|
||||
footer: () => null,
|
||||
},
|
||||
}
|
||||
: {
|
||||
useInternalFlyout: () => ({
|
||||
...base,
|
||||
header: () => <h4>Header</h4>,
|
||||
footer: () => null,
|
||||
}),
|
||||
}),
|
||||
},
|
||||
state: configuration,
|
||||
};
|
||||
const wrapper = mountWithIntl(<AlertsFlyout {...customProps} />);
|
||||
await act(async () => {
|
||||
await nextTick();
|
||||
wrapper.update();
|
||||
});
|
||||
expect(wrapper.find('h4').first().text()).toBe('Header');
|
||||
expect(wrapper.find('h5').first().text()).toBe('Body');
|
||||
const wrapper = mountWithIntl(<AlertsFlyout {...customProps} />);
|
||||
await act(async () => {
|
||||
await nextTick();
|
||||
wrapper.update();
|
||||
});
|
||||
expect(wrapper.find('h4').first().text()).toBe('Header');
|
||||
});
|
||||
|
||||
it(`should use ${configuration} body configuration`, async () => {
|
||||
const customProps = {
|
||||
...props,
|
||||
alertsTableConfiguration: {
|
||||
...props.alertsTableConfiguration,
|
||||
...(configuration === AlertsTableFlyoutState.external
|
||||
? {
|
||||
[`${configuration}Flyout`]: {
|
||||
...base,
|
||||
},
|
||||
}
|
||||
: {
|
||||
useInternalFlyout: () => ({
|
||||
...base,
|
||||
}),
|
||||
}),
|
||||
[`${configuration}Flyout`]: {
|
||||
...base,
|
||||
},
|
||||
},
|
||||
state: configuration,
|
||||
};
|
||||
const wrapper = mountWithIntl(<AlertsFlyout {...customProps} />);
|
||||
await act(async () => {
|
||||
await nextTick();
|
||||
wrapper.update();
|
||||
});
|
||||
expect(wrapper.find('h2').first().text()).toBe('one');
|
||||
expect(wrapper.find('h5').first().text()).toBe('Body');
|
||||
it(`should use body from useInternalFlyout configuration`, async () => {
|
||||
const customProps = {
|
||||
...props,
|
||||
alertsTableConfiguration: {
|
||||
...props.alertsTableConfiguration,
|
||||
useInternalFlyout: () => ({
|
||||
...base,
|
||||
body: () => <h5>Body</h5>,
|
||||
}),
|
||||
},
|
||||
};
|
||||
const wrapper = mountWithIntl(<AlertsFlyout {...customProps} />);
|
||||
await act(async () => {
|
||||
await nextTick();
|
||||
wrapper.update();
|
||||
});
|
||||
expect(wrapper.find('h5').first().text()).toBe('Body');
|
||||
});
|
||||
|
||||
it(`should use ${configuration} body configuration`, async () => {
|
||||
const customProps = {
|
||||
...props,
|
||||
alertsTableConfiguration: {
|
||||
...props.alertsTableConfiguration,
|
||||
...(configuration === AlertsTableFlyoutState.external
|
||||
? {
|
||||
[`${configuration}Flyout`]: {
|
||||
...base,
|
||||
footer: () => <h6>Footer</h6>,
|
||||
},
|
||||
}
|
||||
: {
|
||||
useInternalFlyout: () => ({
|
||||
...base,
|
||||
footer: () => <h6>Footer</h6>,
|
||||
}),
|
||||
}),
|
||||
},
|
||||
state: configuration,
|
||||
};
|
||||
const wrapper = mountWithIntl(<AlertsFlyout {...customProps} />);
|
||||
await act(async () => {
|
||||
await nextTick();
|
||||
wrapper.update();
|
||||
});
|
||||
expect(wrapper.find('h2').first().text()).toBe('one');
|
||||
expect(wrapper.find('h5').first().text()).toBe('Body');
|
||||
expect(wrapper.find('h6').first().text()).toBe('Footer');
|
||||
it(`should use footer from useInternalFlyout configuration`, async () => {
|
||||
const customProps = {
|
||||
...props,
|
||||
alertsTableConfiguration: {
|
||||
...props.alertsTableConfiguration,
|
||||
useInternalFlyout: () => ({
|
||||
...base,
|
||||
footer: () => <h6>Footer</h6>,
|
||||
}),
|
||||
},
|
||||
};
|
||||
const wrapper = mountWithIntl(<AlertsFlyout {...customProps} />);
|
||||
await act(async () => {
|
||||
await nextTick();
|
||||
wrapper.update();
|
||||
});
|
||||
}
|
||||
expect(wrapper.find('h6').first().text()).toBe('Footer');
|
||||
});
|
||||
|
||||
it('should allow pagination with next', async () => {
|
||||
const wrapper = mountWithIntl(<AlertsFlyout {...props} />);
|
||||
|
|
|
@ -8,21 +8,16 @@ import React, { Suspense, lazy, useCallback, useMemo } from 'react';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import {
|
||||
EuiFlyout,
|
||||
EuiFlyoutBody,
|
||||
EuiFlyoutHeader,
|
||||
EuiSpacer,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiPagination,
|
||||
EuiProgress,
|
||||
EuiFlyoutFooter,
|
||||
EuiFlyoutSize,
|
||||
} from '@elastic/eui';
|
||||
import type { EcsFieldsResponse } from '@kbn/rule-registry-plugin/common/search_strategy';
|
||||
import {
|
||||
AlertsTableConfigurationRegistry,
|
||||
AlertsTableFlyoutState,
|
||||
AlertTableFlyoutComponent,
|
||||
} from '../../../../types';
|
||||
import { AlertsTableConfigurationRegistry } from '../../../../types';
|
||||
|
||||
const AlertsFlyoutHeader = lazy(() => import('./alerts_flyout_header'));
|
||||
const PAGINATION_LABEL = i18n.translate(
|
||||
|
@ -36,9 +31,9 @@ interface AlertsFlyoutProps {
|
|||
alert: EcsFieldsResponse;
|
||||
alertsTableConfiguration: AlertsTableConfigurationRegistry;
|
||||
flyoutIndex: number;
|
||||
flyoutSize?: EuiFlyoutSize;
|
||||
alertsCount: number;
|
||||
isLoading: boolean;
|
||||
state: AlertsTableFlyoutState;
|
||||
onClose: () => void;
|
||||
onPaginate: (pageIndex: number) => void;
|
||||
}
|
||||
|
@ -46,39 +41,22 @@ export const AlertsFlyout: React.FunctionComponent<AlertsFlyoutProps> = ({
|
|||
alert,
|
||||
alertsTableConfiguration,
|
||||
flyoutIndex,
|
||||
flyoutSize = 'm',
|
||||
alertsCount,
|
||||
isLoading,
|
||||
state,
|
||||
onClose,
|
||||
onPaginate,
|
||||
}: AlertsFlyoutProps) => {
|
||||
let Header: AlertTableFlyoutComponent;
|
||||
let Body: AlertTableFlyoutComponent;
|
||||
let Footer: AlertTableFlyoutComponent;
|
||||
|
||||
const {
|
||||
header: internalHeader,
|
||||
body: internalBody,
|
||||
footer: internalFooter,
|
||||
header: Header,
|
||||
body: Body,
|
||||
footer: Footer,
|
||||
} = alertsTableConfiguration?.useInternalFlyout?.() ?? {
|
||||
header: null,
|
||||
header: AlertsFlyoutHeader,
|
||||
body: null,
|
||||
footer: null,
|
||||
};
|
||||
|
||||
switch (state) {
|
||||
case AlertsTableFlyoutState.external:
|
||||
Header = alertsTableConfiguration?.externalFlyout?.header ?? AlertsFlyoutHeader;
|
||||
Body = alertsTableConfiguration?.externalFlyout?.body ?? null;
|
||||
Footer = alertsTableConfiguration?.externalFlyout?.footer ?? null;
|
||||
break;
|
||||
case AlertsTableFlyoutState.internal:
|
||||
Header = internalHeader ?? AlertsFlyoutHeader;
|
||||
Body = internalBody ?? null;
|
||||
Footer = internalFooter ?? null;
|
||||
break;
|
||||
}
|
||||
|
||||
const passedProps = useMemo(
|
||||
() => ({
|
||||
alert,
|
||||
|
@ -107,42 +85,22 @@ export const AlertsFlyout: React.FunctionComponent<AlertsFlyoutProps> = ({
|
|||
[Footer, passedProps]
|
||||
);
|
||||
|
||||
const FlyoutBodyMemo = useMemo(() => {
|
||||
if (FlyoutBody) {
|
||||
if (state === AlertsTableFlyoutState.external) {
|
||||
return (
|
||||
<EuiFlyoutBody>
|
||||
<FlyoutBody />
|
||||
</EuiFlyoutBody>
|
||||
);
|
||||
}
|
||||
return <FlyoutBody />;
|
||||
}
|
||||
}, [FlyoutBody, state]);
|
||||
|
||||
const FlyoutFooterMemo = useMemo(() => {
|
||||
if (FlyoutFooter) {
|
||||
if (state === AlertsTableFlyoutState.external) {
|
||||
return (
|
||||
<EuiFlyoutFooter>
|
||||
<FlyoutFooter />
|
||||
</EuiFlyoutFooter>
|
||||
);
|
||||
}
|
||||
return <FlyoutFooter />;
|
||||
}
|
||||
}, [FlyoutFooter, state]);
|
||||
const FlyoutHeader = useCallback(
|
||||
() =>
|
||||
Header ? (
|
||||
<Suspense fallback={null}>
|
||||
<Header {...passedProps} />
|
||||
</Suspense>
|
||||
) : null,
|
||||
[Header, passedProps]
|
||||
);
|
||||
|
||||
return (
|
||||
<EuiFlyout
|
||||
onClose={onClose}
|
||||
size={state === AlertsTableFlyoutState.external ? 's' : 'm'}
|
||||
data-test-subj="alertsFlyout"
|
||||
>
|
||||
<EuiFlyout onClose={onClose} size={flyoutSize} data-test-subj="alertsFlyout">
|
||||
{isLoading && <EuiProgress size="xs" color="accent" data-test-subj="alertsFlyoutLoading" />}
|
||||
<EuiFlyoutHeader hasBorder>
|
||||
<Suspense fallback={null}>
|
||||
<Header {...passedProps} />
|
||||
<FlyoutHeader />
|
||||
</Suspense>
|
||||
<EuiSpacer size="m" />
|
||||
<EuiFlexGroup gutterSize="none" justifyContent="flexEnd">
|
||||
|
@ -158,8 +116,8 @@ export const AlertsFlyout: React.FunctionComponent<AlertsFlyoutProps> = ({
|
|||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlyoutHeader>
|
||||
{FlyoutBodyMemo}
|
||||
{FlyoutFooterMemo}
|
||||
<FlyoutBody />
|
||||
<FlyoutFooter />
|
||||
</EuiFlyout>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -10,7 +10,7 @@ import { AlertConsumers } from '@kbn/rule-data-utils';
|
|||
import { getAlertsTableStateLazy } from '../../../../common/get_alerts_table_state';
|
||||
import { PLUGIN_ID } from '../../../../common/constants';
|
||||
import { useKibana } from '../../../../common/lib/kibana';
|
||||
import { AlertsTableConfigurationRegistry, AlertsTableFlyoutState } from '../../../../types';
|
||||
import { AlertsTableConfigurationRegistry } from '../../../../types';
|
||||
import { TypeRegistry } from '../../../type_registry';
|
||||
|
||||
const consumers = [
|
||||
|
@ -28,7 +28,6 @@ const AlertsPage: React.FunctionComponent = () => {
|
|||
alertsTableConfigurationRegistry as TypeRegistry<AlertsTableConfigurationRegistry>,
|
||||
configurationId: PLUGIN_ID,
|
||||
id: `internal-alerts-page`,
|
||||
flyoutState: AlertsTableFlyoutState.internal,
|
||||
featureIds: consumers,
|
||||
query: { bool: { must: [] } },
|
||||
showExpandToDetails: true,
|
||||
|
|
|
@ -48,10 +48,6 @@ export function registerAlertsTableConfiguration({
|
|||
},
|
||||
],
|
||||
useInternalFlyout,
|
||||
externalFlyout: {
|
||||
header: AlertsPageFlyoutHeader,
|
||||
body: AlertsPageFlyoutBody,
|
||||
},
|
||||
getRenderCellValue: () => (props) => {
|
||||
const myProps = props as any;
|
||||
const value = myProps.data.find((d: any) => d.field === myProps.columnId)?.value ?? [];
|
||||
|
|
|
@ -11,7 +11,7 @@ import userEvent from '@testing-library/user-event';
|
|||
import { EcsFieldsResponse } from '@kbn/rule-registry-plugin/common/search_strategy';
|
||||
|
||||
import { AlertsTable } from './alerts_table';
|
||||
import { AlertsField, AlertsTableFlyoutState } from '../../../types';
|
||||
import { AlertsField } from '../../../types';
|
||||
|
||||
jest.mock('@kbn/data-plugin/public');
|
||||
|
||||
|
@ -60,16 +60,11 @@ describe('AlertsTable', () => {
|
|||
id: '',
|
||||
columns,
|
||||
sort: [],
|
||||
externalFlyout: {
|
||||
useInternalFlyout: jest.fn().mockImplementation(() => ({
|
||||
header: jest.fn(),
|
||||
body: jest.fn(),
|
||||
footer: jest.fn(),
|
||||
},
|
||||
internalFlyout: {
|
||||
header: jest.fn(),
|
||||
body: jest.fn(),
|
||||
footer: jest.fn(),
|
||||
},
|
||||
})),
|
||||
getRenderCellValue: () =>
|
||||
jest.fn().mockImplementation((props) => {
|
||||
return `${props.colIndex}:${props.rowIndex}`;
|
||||
|
@ -89,7 +84,6 @@ describe('AlertsTable', () => {
|
|||
showExpandToDetails: true,
|
||||
trailingControlColumns: [],
|
||||
alerts,
|
||||
flyoutState: AlertsTableFlyoutState.internal,
|
||||
useFetchAlertsData,
|
||||
visibleColumns: columns.map((c) => c.id),
|
||||
'data-test-subj': 'testTable',
|
||||
|
|
|
@ -181,7 +181,6 @@ const AlertsTable: React.FunctionComponent<AlertsTableProps> = (props: AlertsTab
|
|||
<AlertsFlyout
|
||||
alert={alerts[flyoutAlertIndex]}
|
||||
alertsCount={alertsCount}
|
||||
state={props.flyoutState}
|
||||
onClose={handleFlyoutClose}
|
||||
alertsTableConfiguration={props.alertsTableConfiguration}
|
||||
flyoutIndex={flyoutAlertIndex + pagination.pageIndex * pagination.pageSize}
|
||||
|
|
|
@ -16,7 +16,6 @@ import {
|
|||
AlertsField,
|
||||
AlertsTableConfigurationRegistry,
|
||||
AlertsTableFlyoutBaseProps,
|
||||
AlertsTableFlyoutState,
|
||||
} from '../../../types';
|
||||
import { PLUGIN_ID } from '../../../common/constants';
|
||||
import { TypeRegistry } from '../../type_registry';
|
||||
|
@ -110,7 +109,6 @@ describe('AlertsTableState', () => {
|
|||
configurationId: PLUGIN_ID,
|
||||
id: `test-alerts`,
|
||||
featureIds: [AlertConsumers.LOGS],
|
||||
flyoutState: AlertsTableFlyoutState.internal,
|
||||
query: {},
|
||||
showExpandToDetails: true,
|
||||
};
|
||||
|
|
|
@ -6,7 +6,13 @@
|
|||
*/
|
||||
import React, { useState, useCallback, useRef, useMemo } from 'react';
|
||||
import { isEmpty } from 'lodash';
|
||||
import { EuiDataGridColumn, EuiProgress, EuiDataGridSorting, EuiEmptyPrompt } from '@elastic/eui';
|
||||
import {
|
||||
EuiDataGridColumn,
|
||||
EuiProgress,
|
||||
EuiDataGridSorting,
|
||||
EuiEmptyPrompt,
|
||||
EuiFlyoutSize,
|
||||
} from '@elastic/eui';
|
||||
import type { ValidFeatureId } from '@kbn/rule-data-utils';
|
||||
import type { RuleRegistrySearchRequestPagination } from '@kbn/rule-registry-plugin/common';
|
||||
import { Storage } from '@kbn/kibana-utils-plugin/public';
|
||||
|
@ -16,7 +22,7 @@ import type {
|
|||
} from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
import { useFetchAlerts } from './hooks/use_fetch_alerts';
|
||||
import { AlertsTable } from './alerts_table';
|
||||
import { AlertsTableConfigurationRegistry, AlertsTableFlyoutState } from '../../../types';
|
||||
import { AlertsTableConfigurationRegistry } from '../../../types';
|
||||
import { ALERTS_TABLE_CONF_ERROR_MESSAGE, ALERTS_TABLE_CONF_ERROR_TITLE } from './translations';
|
||||
import { TypeRegistry } from '../../type_registry';
|
||||
|
||||
|
@ -30,7 +36,7 @@ export interface AlertsTableStateProps {
|
|||
configurationId: string;
|
||||
id: string;
|
||||
featureIds: ValidFeatureId[];
|
||||
flyoutState: AlertsTableFlyoutState;
|
||||
flyoutSize?: EuiFlyoutSize;
|
||||
query: Pick<QueryDslQueryContainer, 'bool' | 'ids'>;
|
||||
pageSize?: number;
|
||||
showExpandToDetails: boolean;
|
||||
|
@ -64,7 +70,7 @@ const AlertsTableState = ({
|
|||
configurationId,
|
||||
id,
|
||||
featureIds,
|
||||
flyoutState,
|
||||
flyoutSize,
|
||||
query,
|
||||
pageSize,
|
||||
showExpandToDetails,
|
||||
|
@ -191,7 +197,7 @@ const AlertsTableState = ({
|
|||
bulkActions: [],
|
||||
deletedEventIds: [],
|
||||
disabledCellActions: [],
|
||||
flyoutState,
|
||||
flyoutSize,
|
||||
pageSize: pagination.pageSize,
|
||||
pageSizeOptions: [10, 20, 50, 100],
|
||||
leadingControlColumns: [],
|
||||
|
@ -205,7 +211,7 @@ const AlertsTableState = ({
|
|||
[
|
||||
alertsTableConfiguration,
|
||||
columns,
|
||||
flyoutState,
|
||||
flyoutSize,
|
||||
pagination.pageSize,
|
||||
showCheckboxes,
|
||||
showExpandToDetails,
|
||||
|
|
|
@ -41,8 +41,6 @@ export type {
|
|||
GetRenderCellValue,
|
||||
} from './types';
|
||||
|
||||
export { AlertsTableFlyoutState } from './types';
|
||||
|
||||
export {
|
||||
ActionForm,
|
||||
CreateConnectorFlyout,
|
||||
|
|
|
@ -13,7 +13,7 @@ import type { ChartsPluginSetup } from '@kbn/charts-plugin/public';
|
|||
import type { DataPublicPluginStart } from '@kbn/data-plugin/public';
|
||||
import type { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public';
|
||||
import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public';
|
||||
import type { IconType } from '@elastic/eui';
|
||||
import type { IconType, EuiFlyoutSize } from '@elastic/eui';
|
||||
import { EuiDataGridColumn, EuiDataGridControlColumn, EuiDataGridSorting } from '@elastic/eui';
|
||||
import {
|
||||
ActionType,
|
||||
|
@ -390,7 +390,7 @@ export interface AlertsTableProps {
|
|||
// defaultCellActions: TGridCellAction[];
|
||||
deletedEventIds: string[];
|
||||
disabledCellActions: string[];
|
||||
flyoutState: AlertsTableFlyoutState;
|
||||
flyoutSize?: EuiFlyoutSize;
|
||||
pageSize: number;
|
||||
pageSizeOptions: number[];
|
||||
leadingControlColumns: EuiDataGridControlColumn[];
|
||||
|
@ -416,15 +416,10 @@ export type AlertTableFlyoutComponent =
|
|||
export interface AlertsTableConfigurationRegistry {
|
||||
id: string;
|
||||
columns: EuiDataGridColumn[];
|
||||
externalFlyout?: {
|
||||
header?: AlertTableFlyoutComponent;
|
||||
body?: AlertTableFlyoutComponent;
|
||||
footer?: AlertTableFlyoutComponent;
|
||||
};
|
||||
useInternalFlyout?: () => {
|
||||
header?: AlertTableFlyoutComponent;
|
||||
body?: AlertTableFlyoutComponent;
|
||||
footer?: AlertTableFlyoutComponent;
|
||||
header: AlertTableFlyoutComponent;
|
||||
body: AlertTableFlyoutComponent;
|
||||
footer: AlertTableFlyoutComponent;
|
||||
};
|
||||
sort?: SortCombinations[];
|
||||
getRenderCellValue?: GetRenderCellValue;
|
||||
|
@ -435,11 +430,6 @@ export interface AlertsTableFlyoutBaseProps {
|
|||
isLoading: boolean;
|
||||
}
|
||||
|
||||
export enum AlertsTableFlyoutState {
|
||||
internal = 'internal',
|
||||
external = 'external',
|
||||
}
|
||||
|
||||
export type RuleStatus = 'enabled' | 'disabled' | 'snoozed';
|
||||
|
||||
export enum RRuleFrequency {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue