mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[AO] Fix overview alerts loading state (#150868)
Fixes #140387 ## Summary Fix alerts table lazy loading state Before  After 
This commit is contained in:
parent
cf94e1a288
commit
50b83014a3
15 changed files with 83 additions and 49 deletions
|
@ -218,9 +218,10 @@ export function OverviewPage() {
|
||||||
<AlertsStateTable
|
<AlertsStateTable
|
||||||
alertsTableConfigurationRegistry={alertsTableConfigurationRegistry}
|
alertsTableConfigurationRegistry={alertsTableConfigurationRegistry}
|
||||||
configurationId={AlertConsumers.OBSERVABILITY}
|
configurationId={AlertConsumers.OBSERVABILITY}
|
||||||
id={ALERTS_TABLE_ID}
|
|
||||||
flyoutSize="s"
|
flyoutSize="s"
|
||||||
featureIds={observabilityAlertFeatureIds}
|
featureIds={observabilityAlertFeatureIds}
|
||||||
|
hideLazyLoader
|
||||||
|
id={ALERTS_TABLE_ID}
|
||||||
pageSize={ALERTS_PER_PAGE}
|
pageSize={ALERTS_PER_PAGE}
|
||||||
query={esQuery}
|
query={esQuery}
|
||||||
showExpandToDetails={false}
|
showExpandToDetails={false}
|
||||||
|
|
|
@ -5,14 +5,14 @@
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { EuiLoadingChart } from '@elastic/eui';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useLoadAlertSummary } from '../../hooks/use_load_alert_summary';
|
import { useLoadAlertSummary } from '../../hooks/use_load_alert_summary';
|
||||||
import { AlertSummaryWidgetProps } from '.';
|
import { AlertSummaryWidgetProps } from '.';
|
||||||
import {
|
import {
|
||||||
AlertSummaryWidgetError,
|
AlertSummaryWidgetError,
|
||||||
AlertsSummaryWidgetCompact,
|
AlertSummaryWidgetCompact,
|
||||||
AlertsSummaryWidgetFullSize,
|
AlertSummaryWidgetFullSize,
|
||||||
|
AlertSummaryWidgetLoader,
|
||||||
} from './components';
|
} from './components';
|
||||||
|
|
||||||
export const AlertSummaryWidget = ({
|
export const AlertSummaryWidget = ({
|
||||||
|
@ -33,25 +33,14 @@ export const AlertSummaryWidget = ({
|
||||||
timeRange,
|
timeRange,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (isLoading)
|
if (isLoading) return <AlertSummaryWidgetLoader fullSize={fullSize} />;
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
minHeight: fullSize ? 238 : 224,
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<EuiLoadingChart size="l" data-test-subj="alertSummaryWidgetLoading" />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
if (error) return <AlertSummaryWidgetError />;
|
if (error) return <AlertSummaryWidgetError />;
|
||||||
|
|
||||||
return fullSize ? (
|
return fullSize ? (
|
||||||
// Only show full size version if there is data
|
// Only show full size version if there is data
|
||||||
activeAlertCount || recoveredAlertCount ? (
|
activeAlertCount || recoveredAlertCount ? (
|
||||||
<AlertsSummaryWidgetFullSize
|
<AlertSummaryWidgetFullSize
|
||||||
activeAlertCount={activeAlertCount}
|
activeAlertCount={activeAlertCount}
|
||||||
activeAlerts={activeAlerts}
|
activeAlerts={activeAlerts}
|
||||||
recoveredAlertCount={recoveredAlertCount}
|
recoveredAlertCount={recoveredAlertCount}
|
||||||
|
@ -60,7 +49,7 @@ export const AlertSummaryWidget = ({
|
||||||
/>
|
/>
|
||||||
) : null
|
) : null
|
||||||
) : (
|
) : (
|
||||||
<AlertsSummaryWidgetCompact
|
<AlertSummaryWidgetCompact
|
||||||
activeAlertCount={activeAlertCount}
|
activeAlertCount={activeAlertCount}
|
||||||
activeAlerts={activeAlerts}
|
activeAlerts={activeAlerts}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { action } from '@storybook/addon-actions';
|
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';
|
import { mockedAlertSummaryResponse, mockedChartThemes } from '../../../mock/alert_summary_widget';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -8,17 +8,17 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { __IntlProvider as IntlProvider } from '@kbn/i18n-react';
|
import { __IntlProvider as IntlProvider } from '@kbn/i18n-react';
|
||||||
import {
|
import {
|
||||||
AlertsSummaryWidgetCompact,
|
AlertSummaryWidgetCompact,
|
||||||
AlertsSummaryWidgetCompactProps,
|
AlertSummaryWidgetCompactProps,
|
||||||
} from './alert_summary_widget_compact';
|
} from './alert_summary_widget_compact';
|
||||||
import { render } from '@testing-library/react';
|
import { render } from '@testing-library/react';
|
||||||
import { mockedAlertSummaryResponse, mockedChartThemes } from '../../../mock/alert_summary_widget';
|
import { mockedAlertSummaryResponse, mockedChartThemes } from '../../../mock/alert_summary_widget';
|
||||||
|
|
||||||
describe('AlertsSummaryWidgetCompact', () => {
|
describe('AlertSummaryWidgetCompact', () => {
|
||||||
const renderComponent = (props: Partial<AlertsSummaryWidgetCompactProps> = {}) =>
|
const renderComponent = (props: Partial<AlertSummaryWidgetCompactProps> = {}) =>
|
||||||
render(
|
render(
|
||||||
<IntlProvider locale="en">
|
<IntlProvider locale="en">
|
||||||
<AlertsSummaryWidgetCompact
|
<AlertSummaryWidgetCompact
|
||||||
chartThemes={mockedChartThemes}
|
chartThemes={mockedChartThemes}
|
||||||
onClick={jest.fn}
|
onClick={jest.fn}
|
||||||
{...mockedAlertSummaryResponse}
|
{...mockedAlertSummaryResponse}
|
||||||
|
@ -27,7 +27,7 @@ describe('AlertsSummaryWidgetCompact', () => {
|
||||||
</IntlProvider>
|
</IntlProvider>
|
||||||
);
|
);
|
||||||
|
|
||||||
it('should render AlertsSummaryWidgetCompact', async () => {
|
it('should render AlertSummaryWidgetCompact', async () => {
|
||||||
const alertSummaryWidget = renderComponent();
|
const alertSummaryWidget = renderComponent();
|
||||||
|
|
||||||
expect(alertSummaryWidget.queryByTestId('alertSummaryWidgetCompact')).toBeTruthy();
|
expect(alertSummaryWidget.queryByTestId('alertSummaryWidgetCompact')).toBeTruthy();
|
||||||
|
|
|
@ -14,7 +14,7 @@ import { AlertCounts } from './alert_counts';
|
||||||
import { ALL_ALERT_COLOR, WIDGET_TITLE } from './constants';
|
import { ALL_ALERT_COLOR, WIDGET_TITLE } from './constants';
|
||||||
import { Alert, ChartThemes } from '../types';
|
import { Alert, ChartThemes } from '../types';
|
||||||
|
|
||||||
export interface AlertsSummaryWidgetCompactProps {
|
export interface AlertSummaryWidgetCompactProps {
|
||||||
activeAlertCount: number;
|
activeAlertCount: number;
|
||||||
activeAlerts: Alert[];
|
activeAlerts: Alert[];
|
||||||
chartThemes: ChartThemes;
|
chartThemes: ChartThemes;
|
||||||
|
@ -23,14 +23,14 @@ export interface AlertsSummaryWidgetCompactProps {
|
||||||
onClick: (status?: AlertStatus) => void;
|
onClick: (status?: AlertStatus) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AlertsSummaryWidgetCompact = ({
|
export const AlertSummaryWidgetCompact = ({
|
||||||
activeAlertCount,
|
activeAlertCount,
|
||||||
activeAlerts,
|
activeAlerts,
|
||||||
chartThemes: { theme, baseTheme },
|
chartThemes: { theme, baseTheme },
|
||||||
recoveredAlertCount,
|
recoveredAlertCount,
|
||||||
timeRangeTitle,
|
timeRangeTitle,
|
||||||
onClick,
|
onClick,
|
||||||
}: AlertsSummaryWidgetCompactProps) => {
|
}: AlertSummaryWidgetCompactProps) => {
|
||||||
const chartTheme = [
|
const chartTheme = [
|
||||||
theme,
|
theme,
|
||||||
EUI_SPARKLINE_THEME_PARTIAL,
|
EUI_SPARKLINE_THEME_PARTIAL,
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* 2.0.
|
* 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';
|
import { mockedAlertSummaryResponse, mockedChartThemes } from '../../../mock/alert_summary_widget';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -8,17 +8,17 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { __IntlProvider as IntlProvider } from '@kbn/i18n-react';
|
import { __IntlProvider as IntlProvider } from '@kbn/i18n-react';
|
||||||
import {
|
import {
|
||||||
AlertsSummaryWidgetFullSize,
|
AlertSummaryWidgetFullSize,
|
||||||
AlertsSummaryWidgetFullSizeProps,
|
AlertSummaryWidgetFullSizeProps,
|
||||||
} from './alert_summary_widget_full_size';
|
} from './alert_summary_widget_full_size';
|
||||||
import { render } from '@testing-library/react';
|
import { render } from '@testing-library/react';
|
||||||
import { mockedAlertSummaryResponse, mockedChartThemes } from '../../../mock/alert_summary_widget';
|
import { mockedAlertSummaryResponse, mockedChartThemes } from '../../../mock/alert_summary_widget';
|
||||||
|
|
||||||
describe('AlertSummaryWidgetFullSize', () => {
|
describe('AlertSummaryWidgetFullSize', () => {
|
||||||
const renderComponent = (props: Partial<AlertsSummaryWidgetFullSizeProps> = {}) =>
|
const renderComponent = (props: Partial<AlertSummaryWidgetFullSizeProps> = {}) =>
|
||||||
render(
|
render(
|
||||||
<IntlProvider locale="en">
|
<IntlProvider locale="en">
|
||||||
<AlertsSummaryWidgetFullSize
|
<AlertSummaryWidgetFullSize
|
||||||
chartThemes={mockedChartThemes}
|
chartThemes={mockedChartThemes}
|
||||||
{...mockedAlertSummaryResponse}
|
{...mockedAlertSummaryResponse}
|
||||||
{...props}
|
{...props}
|
||||||
|
|
|
@ -13,7 +13,7 @@ import { AlertCounts } from './alert_counts';
|
||||||
import { ALL_ALERT_COLOR, TOOLTIP_DATE_FORMAT } from './constants';
|
import { ALL_ALERT_COLOR, TOOLTIP_DATE_FORMAT } from './constants';
|
||||||
import { Alert, ChartThemes } from '../types';
|
import { Alert, ChartThemes } from '../types';
|
||||||
|
|
||||||
export interface AlertsSummaryWidgetFullSizeProps {
|
export interface AlertSummaryWidgetFullSizeProps {
|
||||||
activeAlertCount: number;
|
activeAlertCount: number;
|
||||||
activeAlerts: Alert[];
|
activeAlerts: Alert[];
|
||||||
chartThemes: ChartThemes;
|
chartThemes: ChartThemes;
|
||||||
|
@ -21,13 +21,13 @@ export interface AlertsSummaryWidgetFullSizeProps {
|
||||||
dateFormat?: string;
|
dateFormat?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AlertsSummaryWidgetFullSize = ({
|
export const AlertSummaryWidgetFullSize = ({
|
||||||
activeAlertCount,
|
activeAlertCount,
|
||||||
activeAlerts,
|
activeAlerts,
|
||||||
chartThemes: { theme, baseTheme },
|
chartThemes: { theme, baseTheme },
|
||||||
dateFormat,
|
dateFormat,
|
||||||
recoveredAlertCount,
|
recoveredAlertCount,
|
||||||
}: AlertsSummaryWidgetFullSizeProps) => {
|
}: AlertSummaryWidgetFullSizeProps) => {
|
||||||
const chartTheme = [
|
const chartTheme = [
|
||||||
theme,
|
theme,
|
||||||
{
|
{
|
||||||
|
|
|
@ -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>
|
||||||
|
);
|
||||||
|
};
|
|
@ -5,6 +5,7 @@
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export { AlertsSummaryWidgetCompact } from './alert_summary_widget_compact';
|
export { AlertSummaryWidgetCompact } from './alert_summary_widget_compact';
|
||||||
export { AlertSummaryWidgetError } from './alert_summary_widget_error';
|
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';
|
||||||
|
|
|
@ -58,9 +58,6 @@ export const RuleDefinition = suspendedComponentWithProps(
|
||||||
export const RuleTagBadge = suspendedComponentWithProps(
|
export const RuleTagBadge = suspendedComponentWithProps(
|
||||||
lazy(() => import('./rules_list/components/rule_tag_badge'))
|
lazy(() => import('./rules_list/components/rule_tag_badge'))
|
||||||
);
|
);
|
||||||
export const AlertSummaryWidget = suspendedComponentWithProps(
|
|
||||||
lazy(() => import('./alert_summary_widget/alert_summary_widget'))
|
|
||||||
);
|
|
||||||
export const RuleStatusPanel = suspendedComponentWithProps(
|
export const RuleStatusPanel = suspendedComponentWithProps(
|
||||||
lazy(() => import('./rule_details/components/rule_status_panel'))
|
lazy(() => import('./rule_details/components/rule_status_panel'))
|
||||||
);
|
);
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
import { EuiLoadingSpinner } from '@elastic/eui';
|
import { EuiLoadingSpinner } from '@elastic/eui';
|
||||||
import React, { lazy, Suspense } from 'react';
|
import React, { lazy, Suspense } from 'react';
|
||||||
|
import { LazyLoadProps } from '../types';
|
||||||
|
|
||||||
import type { AlertsTableStateProps } from '../application/sections/alerts_table/alerts_table_state';
|
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')
|
() => import('../application/sections/alerts_table/alerts_table_state')
|
||||||
);
|
);
|
||||||
|
|
||||||
export const getAlertsTableStateLazy = (props: AlertsTableStateProps) => (
|
export const getAlertsTableStateLazy = ({
|
||||||
<Suspense fallback={<EuiLoadingSpinner />}>
|
hideLazyLoader,
|
||||||
|
...props
|
||||||
|
}: AlertsTableStateProps & LazyLoadProps) => (
|
||||||
|
<Suspense fallback={hideLazyLoader ? null : <EuiLoadingSpinner />}>
|
||||||
<AlertsTableStateLazy {...props} />
|
<AlertsTableStateLazy {...props} />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
);
|
);
|
||||||
|
|
|
@ -5,10 +5,18 @@
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React, { lazy, Suspense } from 'react';
|
||||||
import { AlertSummaryWidget } from '../application/sections';
|
import { AlertSummaryWidgetLoader } from '../application/sections/alert_summary_widget/components';
|
||||||
import { AlertSummaryWidgetProps } from '../application/sections/alert_summary_widget';
|
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) => {
|
export const getAlertSummaryWidgetLazy = (props: AlertSummaryWidgetProps) => {
|
||||||
return <AlertSummaryWidget {...props} />;
|
return (
|
||||||
|
<Suspense fallback={<AlertSummaryWidgetLoader fullSize={props.fullSize} />}>
|
||||||
|
<AlertSummaryWidgetLazy {...props} />
|
||||||
|
</Suspense>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -47,6 +47,7 @@ import {
|
||||||
ExperimentalFeatures,
|
ExperimentalFeatures,
|
||||||
parseExperimentalConfigValue,
|
parseExperimentalConfigValue,
|
||||||
} from '../common/experimental_features';
|
} from '../common/experimental_features';
|
||||||
|
import { LazyLoadProps } from './types';
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
ActionTypeModel,
|
ActionTypeModel,
|
||||||
|
@ -111,7 +112,9 @@ export interface TriggersAndActionsUIPublicPluginStart {
|
||||||
props: Omit<RuleEditProps, 'actionTypeRegistry' | 'ruleTypeRegistry'>
|
props: Omit<RuleEditProps, 'actionTypeRegistry' | 'ruleTypeRegistry'>
|
||||||
) => ReactElement<RuleEditProps>;
|
) => ReactElement<RuleEditProps>;
|
||||||
getAlertsTable: (props: AlertsTableProps) => ReactElement<AlertsTableProps>;
|
getAlertsTable: (props: AlertsTableProps) => ReactElement<AlertsTableProps>;
|
||||||
getAlertsStateTable: (props: AlertsTableStateProps) => ReactElement<AlertsTableStateProps>;
|
getAlertsStateTable: (
|
||||||
|
props: AlertsTableStateProps & LazyLoadProps
|
||||||
|
) => ReactElement<AlertsTableStateProps>;
|
||||||
getAlertsSearchBar: (props: AlertsSearchBarProps) => ReactElement<AlertsSearchBarProps>;
|
getAlertsSearchBar: (props: AlertsSearchBarProps) => ReactElement<AlertsSearchBarProps>;
|
||||||
getFieldBrowser: (props: FieldBrowserProps) => ReactElement<FieldBrowserProps>;
|
getFieldBrowser: (props: FieldBrowserProps) => ReactElement<FieldBrowserProps>;
|
||||||
getRuleStatusDropdown: (props: RuleStatusDropdownProps) => ReactElement<RuleStatusDropdownProps>;
|
getRuleStatusDropdown: (props: RuleStatusDropdownProps) => ReactElement<RuleStatusDropdownProps>;
|
||||||
|
@ -381,7 +384,7 @@ export class Plugin
|
||||||
connectorServices: this.connectorServices!,
|
connectorServices: this.connectorServices!,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
getAlertsStateTable: (props: AlertsTableStateProps) => {
|
getAlertsStateTable: (props: AlertsTableStateProps & LazyLoadProps) => {
|
||||||
return getAlertsTableStateLazy(props);
|
return getAlertsTableStateLazy(props);
|
||||||
},
|
},
|
||||||
getAlertsSearchBar: (props: AlertsSearchBarProps) => {
|
getAlertsSearchBar: (props: AlertsSearchBarProps) => {
|
||||||
|
|
|
@ -666,3 +666,7 @@ export interface UpdateRulesToBulkEditProps {
|
||||||
rules?: RuleTableItem[];
|
rules?: RuleTableItem[];
|
||||||
filter?: KueryNode | null;
|
filter?: KueryNode | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface LazyLoadProps {
|
||||||
|
hideLazyLoader?: boolean;
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue