Skip to content

Commit

Permalink
[FEATURE] Add loading state for all tables visualizations on overview…
Browse files Browse the repository at this point in the history
… page (opensearch-project#237)

* [FEATURE] Add loading state for all tables/visualizations on Overview page opensearch-project#118

Signed-off-by: Jovan Cvetkovic <jovanca.cvetkovic@gmail.com>

* [FEATURE] Add loading state for all tables/visualizations on Overview page opensearch-project#118

Signed-off-by: Jovan Cvetkovic <jovanca.cvetkovic@gmail.com>

Signed-off-by: Jovan Cvetkovic <jovanca.cvetkovic@gmail.com>
  • Loading branch information
jovancacvetkovic committed Dec 19, 2022
1 parent 8d835ce commit b5f752b
Show file tree
Hide file tree
Showing 11 changed files with 93 additions and 16 deletions.
2 changes: 2 additions & 0 deletions public/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,5 @@ $euiTextColor: $euiColorDarkestShade !default;
.state-accordion:hover {
text-decoration: none;
}

@import "./components/Charts/ChartContainer.scss";
21 changes: 21 additions & 0 deletions public/components/Charts/ChartContainer.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
.chart-view-container {
position: relative;
width: 100%;
height: 100%;

.chart-view-container-mask {
width: 100%;
height: 100%;
background: white;
opacity: 0.5;
position: absolute;
}

.chart-view-container-loading {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 1;
}
}
21 changes: 21 additions & 0 deletions public/components/Charts/ChartContainer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react';
import { EuiLoadingChart } from '@elastic/eui';

interface ChartContainerProps {
loading?: boolean;
chartViewId: string;
}

export const ChartContainer: React.FC<ChartContainerProps> = ({ chartViewId, loading = false }) => {
return (
<div className="chart-view-container">
{loading && (
<>
<EuiLoadingChart size="xl" className="chart-view-container-loading" />
<div className="chart-view-container-mask"></div>
</>
)}
<div id={chartViewId}></div>
</div>
);
};
13 changes: 11 additions & 2 deletions public/pages/Overview/components/Widgets/DetectorsWidget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,14 @@ const getColumns = (

export interface DetectorsWidgetProps extends RouteComponentProps {
detectorHits: DetectorHit[];
loading?: boolean;
}

export const DetectorsWidget: React.FC<DetectorsWidgetProps> = ({ detectorHits, history }) => {
export const DetectorsWidget: React.FC<DetectorsWidgetProps> = ({
detectorHits,
history,
loading = false,
}) => {
const detectors = detectorHits.map((detectorHit) => ({
detectorName: detectorHit._source.name,
id: detectorHit._id,
Expand Down Expand Up @@ -76,7 +81,11 @@ export const DetectorsWidget: React.FC<DetectorsWidgetProps> = ({ detectorHits,

return (
<WidgetContainer title={`Detectors (${detectors.length})`} actions={actions}>
<TableWidget columns={getColumns(detectorIdToHit, showDetectorDetails)} items={detectors} />
<TableWidget
columns={getColumns(detectorIdToHit, showDetectorDetails)}
items={detectors}
loading={loading}
/>
</WidgetContainer>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,13 @@ const columns: EuiBasicTableColumn<AlertItem>[] = [

export interface RecentAlertsWidgetProps {
items: AlertItem[];
loading?: boolean;
}

export const RecentAlertsWidget: React.FC<RecentAlertsWidgetProps> = ({ items }) => {
export const RecentAlertsWidget: React.FC<RecentAlertsWidgetProps> = ({
items,
loading = false,
}) => {
const [alertItems, setAlertItems] = useState<AlertItem[]>([]);

useEffect(() => {
Expand All @@ -61,7 +65,7 @@ export const RecentAlertsWidget: React.FC<RecentAlertsWidgetProps> = ({ items })
title={`Top ${alertItems.length < 20 ? '' : 20} recent alerts`}
actions={actions}
>
<TableWidget columns={columns} items={alertItems} />
<TableWidget columns={columns} items={alertItems} loading={loading} />
</WidgetContainer>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,13 @@ const columns: EuiBasicTableColumn<FindingItem>[] = [

export interface RecentFindingsWidgetProps {
items: FindingItem[];
loading?: boolean;
}

export const RecentFindingsWidget: React.FC<RecentFindingsWidgetProps> = ({ items }) => {
export const RecentFindingsWidget: React.FC<RecentFindingsWidgetProps> = ({
items,
loading = false,
}) => {
const [findingItems, setFindingItems] = useState<FindingItem[]>([]);

useEffect(() => {
Expand All @@ -66,7 +70,7 @@ export const RecentFindingsWidget: React.FC<RecentFindingsWidgetProps> = ({ item
title={`Top ${findingItems.length < 20 ? '' : 20} recent findings`}
actions={actions}
>
<TableWidget columns={columns} items={findingItems} />
<TableWidget columns={columns} items={findingItems} loading={loading} />
</WidgetContainer>
);
};
6 changes: 4 additions & 2 deletions public/pages/Overview/components/Widgets/Summary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ import { getOverviewVisualizationSpec, getTimeWithMinPrecision } from '../../uti
import { AlertItem, FindingItem } from '../../models/interfaces';
import { createSelectComponent, renderVisualization } from '../../../../utils/helpers';
import { ROUTES } from '../../../../utils/constants';
import { ChartContainer } from '../../../../components/Charts/ChartContainer';

export interface SummaryProps {
findings: FindingItem[];
alerts: AlertItem[];
loading?: boolean;
}

export interface SummaryData {
Expand All @@ -24,7 +26,7 @@ export interface SummaryData {
logType?: string;
}

export const Summary: React.FC<SummaryProps> = ({ alerts, findings }) => {
export const Summary: React.FC<SummaryProps> = ({ alerts, findings, loading = false }) => {
const [groupBy, setGroupBy] = useState('');
const [summaryData, setSummaryData] = useState<SummaryData[]>([]);
const [activeAlerts, setActiveAlerts] = useState(0);
Expand Down Expand Up @@ -112,7 +114,7 @@ export const Summary: React.FC<SummaryProps> = ({ alerts, findings }) => {
</EuiFlexGroup>
</EuiFlexItem>
<EuiFlexItem>
<div id="summary-view" style={{ width: '100%' }}></div>
<ChartContainer chartViewId={'summary-view'} loading={loading} />
</EuiFlexItem>
</EuiFlexGroup>
</WidgetContainer>
Expand Down
3 changes: 2 additions & 1 deletion public/pages/Overview/components/Widgets/TableWidget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { TableWidgetItem, TableWidgetProps } from '../../models/types';

export class TableWidget<T extends TableWidgetItem> extends React.Component<TableWidgetProps<T>> {
render() {
const { columns, items } = this.props;
const { columns, items, loading = false } = this.props;

return (
<EuiInMemoryTable<T>
Expand All @@ -18,6 +18,7 @@ export class TableWidget<T extends TableWidgetItem> extends React.Component<Tabl
items={items}
itemId={(item: T) => `${item.id}`}
pagination={{ pageSize: 10, pageSizeOptions: [10] }}
loading={loading}
/>
);
}
Expand Down
6 changes: 4 additions & 2 deletions public/pages/Overview/components/Widgets/TopRulesWidget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@ import React, { useEffect } from 'react';
import { FindingItem } from '../../models/interfaces';
import { WidgetContainer } from './WidgetContainer';
import { getTopRulesVisualizationSpec } from '../../utils/helpers';
import { ChartContainer } from '../../../../components/Charts/ChartContainer';

export interface TopRulesWidgetProps {
findings: FindingItem[];
loading?: boolean;
}

type RulesCount = { [ruleName: string]: number };

export const TopRulesWidget: React.FC<TopRulesWidgetProps> = ({ findings }) => {
export const TopRulesWidget: React.FC<TopRulesWidgetProps> = ({ findings, loading = false }) => {
useEffect(() => {
const rulesCount: RulesCount = {};
findings.forEach((finding) => {
Expand All @@ -33,7 +35,7 @@ export const TopRulesWidget: React.FC<TopRulesWidgetProps> = ({ findings }) => {

return (
<WidgetContainer title="Most frequent detection rules">
<div id="top-rules-view"></div>
<ChartContainer chartViewId={'top-rules-view'} loading={loading} />
</WidgetContainer>
);
};
16 changes: 12 additions & 4 deletions public/pages/Overview/containers/Overview/Overview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export const Overview: React.FC<OverviewProps> = (props) => {
alerts: [],
},
});
const [loading, setLoading] = useState(true);
const context = useContext(CoreServicesContext);
const services = useContext(ServicesContext);

Expand All @@ -44,6 +45,7 @@ export const Overview: React.FC<OverviewProps> = (props) => {
...state,
overviewViewModel: { ...overviewViewModel },
});
setLoading(false);
};

const overviewViewModelActor = useMemo(
Expand Down Expand Up @@ -78,6 +80,7 @@ export const Overview: React.FC<OverviewProps> = (props) => {
};

const onRefresh = async () => {
setLoading(true);
overviewViewModelActor.onRefresh();
};

Expand Down Expand Up @@ -121,15 +124,20 @@ export const Overview: React.FC<OverviewProps> = (props) => {
<Summary
alerts={state.overviewViewModel.alerts}
findings={state.overviewViewModel.findings}
loading={loading}
/>
</EuiFlexItem>

<EuiFlexItem>
<EuiFlexGrid columns={2} gutterSize="m">
<RecentAlertsWidget items={state.overviewViewModel.alerts} />
<RecentFindingsWidget items={state.overviewViewModel.findings} />
<TopRulesWidget findings={state.overviewViewModel.findings} />
<DetectorsWidget detectorHits={state.overviewViewModel.detectors} {...props} />
<RecentAlertsWidget items={state.overviewViewModel.alerts} loading={loading} />
<RecentFindingsWidget items={state.overviewViewModel.findings} loading={loading} />
<TopRulesWidget findings={state.overviewViewModel.findings} loading={loading} />
<DetectorsWidget
detectorHits={state.overviewViewModel.detectors}
{...props}
loading={loading}
/>
</EuiFlexGrid>
</EuiFlexItem>
</EuiFlexGroup>
Expand Down
5 changes: 4 additions & 1 deletion public/pages/Overview/models/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/
*/ {
loading;
}

import { EuiBasicTableColumn } from '@elastic/eui';
import { AlertItem, DetectorItem, FindingItem } from './interfaces';
Expand All @@ -11,4 +13,5 @@ export type TableWidgetItem = FindingItem | AlertItem | DetectorItem;
export type TableWidgetProps<T extends TableWidgetItem> = {
columns: EuiBasicTableColumn<T>[];
items: T[];
loading?: boolean;
};

0 comments on commit b5f752b

Please sign in to comment.