[AO] Fix overview alerts loading state (#150868)

Fixes #140387

## Summary

Fix alerts table lazy loading state

Before

![image](https://user-images.githubusercontent.com/12370520/218094792-24d00334-5414-4737-8f64-d619cbcc9f12.png)

After

![image](https://user-images.githubusercontent.com/12370520/218094828-6b3559ce-1f7a-45a7-ae0d-96f5dad141a1.png)
This commit is contained in:
Maryam Saeidi 2023-02-14 13:35:40 +01:00 committed by GitHub
parent cf94e1a288
commit 50b83014a3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 83 additions and 49 deletions

View file

@ -218,9 +218,10 @@ export function OverviewPage() {
<AlertsStateTable
alertsTableConfigurationRegistry={alertsTableConfigurationRegistry}
configurationId={AlertConsumers.OBSERVABILITY}
id={ALERTS_TABLE_ID}
flyoutSize="s"
featureIds={observabilityAlertFeatureIds}
hideLazyLoader
id={ALERTS_TABLE_ID}
pageSize={ALERTS_PER_PAGE}
query={esQuery}
showExpandToDetails={false}

View file

@ -5,14 +5,14 @@
* 2.0.
*/
import { EuiLoadingChart } from '@elastic/eui';
import React from 'react';
import { useLoadAlertSummary } from '../../hooks/use_load_alert_summary';
import { AlertSummaryWidgetProps } from '.';
import {
AlertSummaryWidgetError,
AlertsSummaryWidgetCompact,
AlertsSummaryWidgetFullSize,
AlertSummaryWidgetCompact,
AlertSummaryWidgetFullSize,
AlertSummaryWidgetLoader,
} from './components';
export const AlertSummaryWidget = ({
@ -33,25 +33,14 @@ export const AlertSummaryWidget = ({
timeRange,
});
if (isLoading)
return (
<div
style={{
minHeight: fullSize ? 238 : 224,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
>
<EuiLoadingChart size="l" data-test-subj="alertSummaryWidgetLoading" />
</div>
);
if (isLoading) return <AlertSummaryWidgetLoader fullSize={fullSize} />;
if (error) return <AlertSummaryWidgetError />;
return fullSize ? (
// Only show full size version if there is data
activeAlertCount || recoveredAlertCount ? (
<AlertsSummaryWidgetFullSize
<AlertSummaryWidgetFullSize
activeAlertCount={activeAlertCount}
activeAlerts={activeAlerts}
recoveredAlertCount={recoveredAlertCount}
@ -60,7 +49,7 @@ export const AlertSummaryWidget = ({
/>
) : null
) : (
<AlertsSummaryWidgetCompact
<AlertSummaryWidgetCompact
activeAlertCount={activeAlertCount}
activeAlerts={activeAlerts}
onClick={onClick}

View file

@ -6,7 +6,7 @@
*/
import { action } from '@storybook/addon-actions';
import { AlertsSummaryWidgetCompact as Component } from './alert_summary_widget_compact';
import { AlertSummaryWidgetCompact as Component } from './alert_summary_widget_compact';
import { mockedAlertSummaryResponse, mockedChartThemes } from '../../../mock/alert_summary_widget';
export default {

View file

@ -8,17 +8,17 @@
import React from 'react';
import { __IntlProvider as IntlProvider } from '@kbn/i18n-react';
import {
AlertsSummaryWidgetCompact,
AlertsSummaryWidgetCompactProps,
AlertSummaryWidgetCompact,
AlertSummaryWidgetCompactProps,
} from './alert_summary_widget_compact';
import { render } from '@testing-library/react';
import { mockedAlertSummaryResponse, mockedChartThemes } from '../../../mock/alert_summary_widget';
describe('AlertsSummaryWidgetCompact', () => {
const renderComponent = (props: Partial<AlertsSummaryWidgetCompactProps> = {}) =>
describe('AlertSummaryWidgetCompact', () => {
const renderComponent = (props: Partial<AlertSummaryWidgetCompactProps> = {}) =>
render(
<IntlProvider locale="en">
<AlertsSummaryWidgetCompact
<AlertSummaryWidgetCompact
chartThemes={mockedChartThemes}
onClick={jest.fn}
{...mockedAlertSummaryResponse}
@ -27,7 +27,7 @@ describe('AlertsSummaryWidgetCompact', () => {
</IntlProvider>
);
it('should render AlertsSummaryWidgetCompact', async () => {
it('should render AlertSummaryWidgetCompact', async () => {
const alertSummaryWidget = renderComponent();
expect(alertSummaryWidget.queryByTestId('alertSummaryWidgetCompact')).toBeTruthy();

View file

@ -14,7 +14,7 @@ import { AlertCounts } from './alert_counts';
import { ALL_ALERT_COLOR, WIDGET_TITLE } from './constants';
import { Alert, ChartThemes } from '../types';
export interface AlertsSummaryWidgetCompactProps {
export interface AlertSummaryWidgetCompactProps {
activeAlertCount: number;
activeAlerts: Alert[];
chartThemes: ChartThemes;
@ -23,14 +23,14 @@ export interface AlertsSummaryWidgetCompactProps {
onClick: (status?: AlertStatus) => void;
}
export const AlertsSummaryWidgetCompact = ({
export const AlertSummaryWidgetCompact = ({
activeAlertCount,
activeAlerts,
chartThemes: { theme, baseTheme },
recoveredAlertCount,
timeRangeTitle,
onClick,
}: AlertsSummaryWidgetCompactProps) => {
}: AlertSummaryWidgetCompactProps) => {
const chartTheme = [
theme,
EUI_SPARKLINE_THEME_PARTIAL,

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { AlertsSummaryWidgetFullSize as Component } from './alert_summary_widget_full_size';
import { AlertSummaryWidgetFullSize as Component } from './alert_summary_widget_full_size';
import { mockedAlertSummaryResponse, mockedChartThemes } from '../../../mock/alert_summary_widget';
export default {

View file

@ -8,17 +8,17 @@
import React from 'react';
import { __IntlProvider as IntlProvider } from '@kbn/i18n-react';
import {
AlertsSummaryWidgetFullSize,
AlertsSummaryWidgetFullSizeProps,
AlertSummaryWidgetFullSize,
AlertSummaryWidgetFullSizeProps,
} from './alert_summary_widget_full_size';
import { render } from '@testing-library/react';
import { mockedAlertSummaryResponse, mockedChartThemes } from '../../../mock/alert_summary_widget';
describe('AlertSummaryWidgetFullSize', () => {
const renderComponent = (props: Partial<AlertsSummaryWidgetFullSizeProps> = {}) =>
const renderComponent = (props: Partial<AlertSummaryWidgetFullSizeProps> = {}) =>
render(
<IntlProvider locale="en">
<AlertsSummaryWidgetFullSize
<AlertSummaryWidgetFullSize
chartThemes={mockedChartThemes}
{...mockedAlertSummaryResponse}
{...props}

View file

@ -13,7 +13,7 @@ import { AlertCounts } from './alert_counts';
import { ALL_ALERT_COLOR, TOOLTIP_DATE_FORMAT } from './constants';
import { Alert, ChartThemes } from '../types';
export interface AlertsSummaryWidgetFullSizeProps {
export interface AlertSummaryWidgetFullSizeProps {
activeAlertCount: number;
activeAlerts: Alert[];
chartThemes: ChartThemes;
@ -21,13 +21,13 @@ export interface AlertsSummaryWidgetFullSizeProps {
dateFormat?: string;
}
export const AlertsSummaryWidgetFullSize = ({
export const AlertSummaryWidgetFullSize = ({
activeAlertCount,
activeAlerts,
chartThemes: { theme, baseTheme },
dateFormat,
recoveredAlertCount,
}: AlertsSummaryWidgetFullSizeProps) => {
}: AlertSummaryWidgetFullSizeProps) => {
const chartTheme = [
theme,
{

View file

@ -0,0 +1,27 @@
/*
* 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 from 'react';
import { EuiLoadingChart } from '@elastic/eui';
import { AlertSummaryWidgetProps } from '..';
type Props = Pick<AlertSummaryWidgetProps, 'fullSize'>;
export const AlertSummaryWidgetLoader = ({ fullSize }: Props) => {
return (
<div
style={{
minHeight: fullSize ? 238 : 224,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
>
<EuiLoadingChart size="l" data-test-subj="alertSummaryWidgetLoading" />
</div>
);
};

View file

@ -5,6 +5,7 @@
* 2.0.
*/
export { AlertsSummaryWidgetCompact } from './alert_summary_widget_compact';
export { AlertSummaryWidgetCompact } from './alert_summary_widget_compact';
export { AlertSummaryWidgetError } from './alert_summary_widget_error';
export { AlertsSummaryWidgetFullSize } from './alert_summary_widget_full_size';
export { AlertSummaryWidgetFullSize } from './alert_summary_widget_full_size';
export { AlertSummaryWidgetLoader } from './alert_summary_widget_loader';

View file

@ -58,9 +58,6 @@ export const RuleDefinition = suspendedComponentWithProps(
export const RuleTagBadge = suspendedComponentWithProps(
lazy(() => import('./rules_list/components/rule_tag_badge'))
);
export const AlertSummaryWidget = suspendedComponentWithProps(
lazy(() => import('./alert_summary_widget/alert_summary_widget'))
);
export const RuleStatusPanel = suspendedComponentWithProps(
lazy(() => import('./rule_details/components/rule_status_panel'))
);

View file

@ -7,6 +7,7 @@
import { EuiLoadingSpinner } from '@elastic/eui';
import React, { lazy, Suspense } from 'react';
import { LazyLoadProps } from '../types';
import type { AlertsTableStateProps } from '../application/sections/alerts_table/alerts_table_state';
@ -14,8 +15,11 @@ const AlertsTableStateLazy: React.FC<AlertsTableStateProps> = lazy(
() => import('../application/sections/alerts_table/alerts_table_state')
);
export const getAlertsTableStateLazy = (props: AlertsTableStateProps) => (
<Suspense fallback={<EuiLoadingSpinner />}>
export const getAlertsTableStateLazy = ({
hideLazyLoader,
...props
}: AlertsTableStateProps & LazyLoadProps) => (
<Suspense fallback={hideLazyLoader ? null : <EuiLoadingSpinner />}>
<AlertsTableStateLazy {...props} />
</Suspense>
);

View file

@ -5,10 +5,18 @@
* 2.0.
*/
import React from 'react';
import { AlertSummaryWidget } from '../application/sections';
import React, { lazy, Suspense } from 'react';
import { AlertSummaryWidgetLoader } from '../application/sections/alert_summary_widget/components';
import { AlertSummaryWidgetProps } from '../application/sections/alert_summary_widget';
const AlertSummaryWidgetLazy: React.FC<AlertSummaryWidgetProps> = lazy(
() => import('../application/sections/alert_summary_widget/alert_summary_widget')
);
export const getAlertSummaryWidgetLazy = (props: AlertSummaryWidgetProps) => {
return <AlertSummaryWidget {...props} />;
return (
<Suspense fallback={<AlertSummaryWidgetLoader fullSize={props.fullSize} />}>
<AlertSummaryWidgetLazy {...props} />
</Suspense>
);
};

View file

@ -47,6 +47,7 @@ import {
ExperimentalFeatures,
parseExperimentalConfigValue,
} from '../common/experimental_features';
import { LazyLoadProps } from './types';
import type {
ActionTypeModel,
@ -111,7 +112,9 @@ export interface TriggersAndActionsUIPublicPluginStart {
props: Omit<RuleEditProps, 'actionTypeRegistry' | 'ruleTypeRegistry'>
) => ReactElement<RuleEditProps>;
getAlertsTable: (props: AlertsTableProps) => ReactElement<AlertsTableProps>;
getAlertsStateTable: (props: AlertsTableStateProps) => ReactElement<AlertsTableStateProps>;
getAlertsStateTable: (
props: AlertsTableStateProps & LazyLoadProps
) => ReactElement<AlertsTableStateProps>;
getAlertsSearchBar: (props: AlertsSearchBarProps) => ReactElement<AlertsSearchBarProps>;
getFieldBrowser: (props: FieldBrowserProps) => ReactElement<FieldBrowserProps>;
getRuleStatusDropdown: (props: RuleStatusDropdownProps) => ReactElement<RuleStatusDropdownProps>;
@ -381,7 +384,7 @@ export class Plugin
connectorServices: this.connectorServices!,
});
},
getAlertsStateTable: (props: AlertsTableStateProps) => {
getAlertsStateTable: (props: AlertsTableStateProps & LazyLoadProps) => {
return getAlertsTableStateLazy(props);
},
getAlertsSearchBar: (props: AlertsSearchBarProps) => {

View file

@ -666,3 +666,7 @@ export interface UpdateRulesToBulkEditProps {
rules?: RuleTableItem[];
filter?: KueryNode | null;
}
export interface LazyLoadProps {
hideLazyLoader?: boolean;
}