Skip to content

Commit

Permalink
[FEATURE] Provide empty states for Findings and Alerts page #471 (#494)
Browse files Browse the repository at this point in the history
Signed-off-by: Jovan Cvetkovic <[email protected]>
  • Loading branch information
jovancvetkovic3006 authored Apr 10, 2023
1 parent 5425b9b commit 0452437
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 37 deletions.
37 changes: 34 additions & 3 deletions public/pages/Alerts/containers/Alerts/Alerts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
EuiSuperDatePicker,
EuiTitle,
EuiToolTip,
EuiEmptyPrompt,
} from '@elastic/eui';
import { FieldValueSelectionFilterConfigType } from '@elastic/eui/src/components/search_bar/filters/field_value_selection_filter';
import dateMath from '@elastic/datemath';
Expand Down Expand Up @@ -81,6 +82,7 @@ export interface AlertsState {
loading: boolean;
timeUnit: TimeUnit;
dateFormat: string;
widgetEmptyMessage: React.ReactNode | undefined;
}

const groupByOptions = [
Expand Down Expand Up @@ -112,6 +114,7 @@ export class Alerts extends Component<AlertsProps, AlertsState> {
detectors: {},
timeUnit: timeUnits.timeUnit,
dateFormat: timeUnits.dateFormat,
widgetEmptyMessage: undefined,
};
}

Expand Down Expand Up @@ -148,7 +151,20 @@ export class Alerts extends Component<AlertsProps, AlertsState> {
const filteredAlerts = alerts.filter((alert) =>
moment(alert.last_notification_time).isBetween(moment(startMoment), moment(endMoment))
);
this.setState({ alertsFiltered: true, filteredAlerts: filteredAlerts });
this.setState({
alertsFiltered: true,
filteredAlerts: filteredAlerts,
widgetEmptyMessage: filteredAlerts.length ? undefined : (
<EuiEmptyPrompt
body={
<p>
<span style={{ display: 'block' }}>No alerts.</span>Adjust the time range to see more
results.
</p>
}
/>
),
});
renderVisualization(this.generateVisualizationSpec(filteredAlerts), 'alerts-view');
};

Expand Down Expand Up @@ -413,6 +429,7 @@ export class Alerts extends Component<AlertsProps, AlertsState> {
flyoutData,
loading,
recentlyUsedRanges,
widgetEmptyMessage,
} = this.state;

const {
Expand Down Expand Up @@ -505,7 +522,7 @@ export class Alerts extends Component<AlertsProps, AlertsState> {
/>
</EuiFlexItem>
</EuiFlexGroup>
<EuiSpacer size="xxl" />
<EuiSpacer size={'m'} />
</EuiFlexItem>
<EuiFlexItem>
<EuiPanel>
Expand All @@ -514,7 +531,20 @@ export class Alerts extends Component<AlertsProps, AlertsState> {
{this.createGroupByControl()}
</EuiFlexItem>
<EuiFlexItem>
<ChartContainer chartViewId={'alerts-view'} loading={loading} />
{!alerts || alerts.length === 0 ? (
<EuiEmptyPrompt
title={<h2>No alerts</h2>}
body={
<p>
Adjust the time range to see more results or create alert triggers in your{' '}
<EuiLink href={`${location.pathname}#/detectors`}>detectors</EuiLink> to
generate alerts.
</p>
}
/>
) : (
<ChartContainer chartViewId={'alerts-view'} loading={loading} />
)}
</EuiFlexItem>
</EuiFlexGroup>
</EuiPanel>
Expand All @@ -532,6 +562,7 @@ export class Alerts extends Component<AlertsProps, AlertsState> {
sorting={sorting}
selection={selection}
loading={loading}
message={widgetEmptyMessage}
/>
</ContentPanel>
</EuiFlexItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -707,10 +707,10 @@ exports[`<Alerts /> spec renders the component 1`] = `
</div>
</EuiFlexGroup>
<EuiSpacer
size="xxl"
size="m"
>
<div
className="euiSpacer euiSpacer--xxl"
className="euiSpacer euiSpacer--m"
/>
</EuiSpacer>
</div>
Expand Down Expand Up @@ -873,42 +873,76 @@ exports[`<Alerts /> spec renders the component 1`] = `
<div
className="euiFlexItem"
>
<ChartContainer
chartViewId="alerts-view"
loading={true}
<EuiEmptyPrompt
body={
<p>
Adjust the time range to see more results or create alert triggers in your
<EuiLink
href="/#/detectors"
>
detectors
</EuiLink>
to generate alerts.
</p>
}
title={
<h2>
No alerts
</h2>
}
>
<div
className="chart-view-container"
className="euiEmptyPrompt"
>
<EuiLoadingChart
className="chart-view-container-loading"
size="xl"
<EuiTitle
size="m"
>
<h2
className="euiTitle euiTitle--medium"
>
No alerts
</h2>
</EuiTitle>
<EuiTextColor
color="subdued"
>
<span
className="euiLoadingChart chart-view-container-loading euiLoadingChart--xLarge"
className="euiTextColor euiTextColor--subdued"
>
<span
className="euiLoadingChart__bar"
/>
<span
className="euiLoadingChart__bar"
/>
<span
className="euiLoadingChart__bar"
/>
<span
className="euiLoadingChart__bar"
/>
<EuiSpacer
size="m"
>
<div
className="euiSpacer euiSpacer--m"
/>
</EuiSpacer>
<EuiText>
<div
className="euiText euiText--medium"
>
<p>
Adjust the time range to see more results or create alert triggers in your
<EuiLink
href="/#/detectors"
>
<a
className="euiLink euiLink--primary"
href="/#/detectors"
rel="noreferrer"
>
detectors
</a>
</EuiLink>
to generate alerts.
</p>
</div>
</EuiText>
</span>
</EuiLoadingChart>
<div
className="chart-view-container-mask"
/>
<div
id="alerts-view"
/>
</EuiTextColor>
</div>
</ChartContainer>
</EuiEmptyPrompt>
</div>
</EuiFlexItem>
</div>
Expand Down
28 changes: 26 additions & 2 deletions public/pages/Findings/components/FindingsTable/FindingsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
EuiInMemoryTable,
EuiLink,
EuiToolTip,
EuiEmptyPrompt,
} from '@elastic/eui';
import { FieldValueSelectionFilterConfigType } from '@elastic/eui/src/components/search_bar/filters/field_value_selection_filter';
import dateMath from '@elastic/datemath';
Expand Down Expand Up @@ -48,6 +49,7 @@ interface FindingsTableState {
flyout: object | undefined;
flyoutOpen: boolean;
selectedFinding?: Finding;
widgetEmptyMessage: React.ReactNode | undefined;
}

export default class FindingsTable extends Component<FindingsTableProps, FindingsTableState> {
Expand All @@ -59,6 +61,7 @@ export default class FindingsTable extends Component<FindingsTableProps, Finding
flyout: undefined,
flyoutOpen: false,
selectedFinding: undefined,
widgetEmptyMessage: undefined,
};
}

Expand All @@ -82,7 +85,21 @@ export default class FindingsTable extends Component<FindingsTableProps, Finding
const filteredFindings = findings.filter((finding) =>
moment(finding.timestamp).isBetween(moment(startMoment), moment(endMoment))
);
this.setState({ findingsFiltered: true, filteredFindings: filteredFindings });
this.setState({
findingsFiltered: true,
filteredFindings: filteredFindings,
widgetEmptyMessage:
filteredFindings.length || findings.length ? undefined : (
<EuiEmptyPrompt
body={
<p>
<span style={{ display: 'block' }}>No findings.</span>Adjust the time range to see
more results.
</p>
}
/>
),
});
this.props.onFindingsFiltered(filteredFindings);
};

Expand Down Expand Up @@ -142,7 +159,13 @@ export default class FindingsTable extends Component<FindingsTableProps, Finding

render() {
const { findings, loading, rules } = this.props;
const { findingsFiltered, filteredFindings, flyout, flyoutOpen } = this.state;
const {
findingsFiltered,
filteredFindings,
flyout,
flyoutOpen,
widgetEmptyMessage,
} = this.state;

const columns: EuiBasicTableColumn<Finding>[] = [
{
Expand Down Expand Up @@ -285,6 +308,7 @@ export default class FindingsTable extends Component<FindingsTableProps, Finding
sorting={sorting}
isSelectable={false}
loading={loading}
message={widgetEmptyMessage}
/>
{flyoutOpen && flyout}
</div>
Expand Down
21 changes: 19 additions & 2 deletions public/pages/Findings/containers/Findings/Findings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import {
EuiSpacer,
EuiSuperDatePicker,
EuiTitle,
EuiEmptyPrompt,
EuiLink,
} from '@elastic/eui';
import FindingsTable from '../../components/FindingsTable';
import FindingsService from '../../../../services/FindingsService';
Expand All @@ -37,7 +39,6 @@ import {
} from '../../../Overview/utils/helpers';
import { CoreServicesContext } from '../../../../components/core_services';
import { Finding } from '../../models/interfaces';
import { Detector } from '../../../../../models/interfaces';
import { FeatureChannelList } from '../../../../../server/models/interfaces';
import {
getNotificationChannels,
Expand All @@ -54,6 +55,7 @@ import { NotificationsStart } from 'opensearch-dashboards/public';
import { DateTimeFilter } from '../../../Overview/models/interfaces';
import { ChartContainer } from '../../../../components/Charts/ChartContainer';
import { DataStore } from '../../../../store/DataStore';
import { Detector } from '../../../../../types';

interface FindingsProps extends RouteComponentProps {
detectorService: DetectorsService;
Expand Down Expand Up @@ -340,7 +342,22 @@ class Findings extends Component<FindingsProps, FindingsState> {
{this.createGroupByControl()}
</EuiFlexItem>
<EuiFlexItem>
<ChartContainer chartViewId={'findings-view'} loading={loading} />
{!findings || findings.length === 0 ? (
<EuiEmptyPrompt
title={<h2>No findings</h2>}
body={
<p>
Adjust the time range to see more results or{' '}
<EuiLink href={`${location.pathname}#/create-detector`}>
create a detector
</EuiLink>{' '}
to generate findings.
</p>
}
/>
) : (
<ChartContainer chartViewId={'findings-view'} loading={loading} />
)}
</EuiFlexItem>
</EuiFlexGroup>
</EuiPanel>
Expand Down
2 changes: 2 additions & 0 deletions public/pages/Overview/containers/Overview/Overview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
EuiPopover,
EuiSuperDatePicker,
EuiTitle,
EuiSpacer,
} from '@elastic/eui';
import React, { useContext, useEffect, useMemo, useState } from 'react';
import {
Expand Down Expand Up @@ -166,6 +167,7 @@ export const Overview: React.FC<OverviewProps> = (props) => {
/>
</EuiFlexItem>
</EuiFlexGroup>
<EuiSpacer size={'m'} />
</EuiFlexItem>
<EuiFlexItem>
<Summary
Expand Down

0 comments on commit 0452437

Please sign in to comment.