Skip to content

Commit 76273e4

Browse files
Merge pull request #511 from Fewwy/ou-923
OU-781: fix links in incidents table
2 parents 6407eed + 8278f49 commit 76273e4

3 files changed

Lines changed: 35 additions & 120 deletions

File tree

web/src/components/Incidents/IncidentsDetailsRowTable.tsx

Lines changed: 10 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { useRef, useState, useEffect } from 'react';
21
import { Table, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table';
32
import {
43
GreenCheckCircleIcon,
@@ -7,71 +6,24 @@ import {
76
useActiveNamespace,
87
} from '@openshift-console/dynamic-plugin-sdk';
98
import { BellIcon } from '@patternfly/react-icons';
10-
import { Bullseye, DropdownItem, Spinner, Tooltip } from '@patternfly/react-core';
11-
import { Link, useHistory } from 'react-router-dom';
12-
import { AlertResource } from '../utils';
13-
import KebabDropdown from '../kebab-dropdown';
9+
import { Bullseye, Spinner } from '@patternfly/react-core';
10+
import { Link } from 'react-router-dom';
11+
import { RuleResource } from '../utils';
1412
import { useTranslation } from 'react-i18next';
15-
import {
16-
getAlertUrl,
17-
getLegacyObserveState,
18-
getNewSilenceAlertUrl,
19-
getRuleUrl,
20-
usePerspective,
21-
} from '../hooks/usePerspective';
22-
import { OutlinedQuestionCircleIcon } from '@patternfly/react-icons';
13+
import { getRuleUrl, usePerspective } from '../hooks/usePerspective';
2314
import './incidents-styles.css';
2415
import { SeverityBadge } from '../alerting/AlertUtils';
25-
import { useAlertsPoller } from '../hooks/useAlertsPoller';
26-
import { useSelector } from 'react-redux';
27-
import isEqual from 'lodash/isEqual';
28-
import { MonitoringState } from 'src/reducers/observe';
29-
30-
function useDeepCompareMemoize(value) {
31-
const ref = useRef();
32-
33-
if (!isEqual(value, ref.current)) {
34-
ref.current = value;
35-
}
36-
37-
return ref.current;
38-
}
3916

4017
const IncidentsDetailsRowTable = ({ alerts }) => {
41-
const history = useHistory();
4218
const [namespace] = useActiveNamespace();
43-
useAlertsPoller();
44-
const { perspective, alertsKey } = usePerspective();
45-
const [alertsWithMatchedData, setAlertsWithMatchedData] = useState([]);
19+
const { perspective } = usePerspective();
4620
const { t } = useTranslation(process.env.I18N_NAMESPACE);
4721

48-
const alertsWithLabels = useSelector((state: MonitoringState) =>
49-
getLegacyObserveState(perspective, state)?.get(alertsKey),
50-
);
51-
52-
function findMatchingAlertsWithId(alertsArray, rulesArray) {
53-
return alertsArray.map((alert) => {
54-
if (!Array.isArray(rulesArray?.data)) {
55-
return alert;
56-
}
57-
const match = rulesArray.data.find((rule) => alert.alertname === rule.labels.alertname);
58-
if (match) {
59-
return { ...alert, rule: match };
60-
}
61-
return alert;
62-
});
63-
}
64-
const memoizedAlerts = useDeepCompareMemoize(alerts);
65-
66-
useEffect(() => {
67-
setAlertsWithMatchedData(findMatchingAlertsWithId(memoizedAlerts, alertsWithLabels));
68-
}, [memoizedAlerts, alertsWithLabels]);
69-
7022
return (
7123
<Table borders={false} variant="compact">
7224
<Thead>
7325
<Tr>
74-
<Th width={25}>{t('Alert Name')}</Th>
26+
<Th width={25}>{t('Alert Rule')}</Th>
7527
<Th width={15}>{t('Namespace')}</Th>
7628
<Th width={10}>{t('Severity')}</Th>
7729
<Th width={10}>{t('State')}</Th>
@@ -80,40 +32,19 @@ const IncidentsDetailsRowTable = ({ alerts }) => {
8032
</Tr>
8133
</Thead>
8234
<Tbody>
83-
{!alertsWithMatchedData ? (
35+
{!alerts ? (
8436
<Bullseye>
8537
<Spinner aria-label="incidents-chart-spinner" />
8638
</Bullseye>
8739
) : (
88-
alertsWithMatchedData?.map((alertDetails, rowIndex) => {
40+
alerts?.map((alertDetails, rowIndex) => {
8941
return (
9042
<Tr key={rowIndex}>
9143
<Td dataLabel="expanded-details-alertname">
92-
<ResourceIcon kind={AlertResource.kind} />
93-
<Link
94-
to={
95-
alertDetails?.rule
96-
? getAlertUrl(
97-
perspective,
98-
alertDetails,
99-
alertDetails?.rule?.rule.id,
100-
namespace,
101-
)
102-
: '#'
103-
}
104-
style={
105-
!alertDetails?.rule || alertDetails.resolved
106-
? { pointerEvents: 'none', color: 'inherit', textDecoration: 'inherit' }
107-
: {}
108-
}
109-
>
44+
<ResourceIcon kind={RuleResource.kind} />
45+
<Link to={getRuleUrl(perspective, alertDetails?.rule, namespace)}>
11046
{alertDetails.alertname}
11147
</Link>
112-
{(!alertDetails?.rule || alertDetails.resolved) && (
113-
<Tooltip content={<div>No details can be shown for inactive alerts.</div>}>
114-
<OutlinedQuestionCircleIcon className="expanded-details-text-margin" />
115-
</Tooltip>
116-
)}
11748
</Td>
11849
<Td dataLabel="expanded-details-namespace">{alertDetails.namespace || '---'}</Td>
11950
<Td dataLabel="expanded-details-severity">
@@ -142,35 +73,6 @@ const IncidentsDetailsRowTable = ({ alerts }) => {
14273
<Timestamp simple={true} timestamp={alertDetails.alertsEndFiring} />
14374
)}
14475
</Td>
145-
<Td>
146-
<KebabDropdown
147-
dropdownItems={[
148-
<DropdownItem
149-
component="button"
150-
key="silence alert"
151-
isDisabled={!alertDetails?.rule}
152-
onClick={() =>
153-
history.push(
154-
getNewSilenceAlertUrl(perspective, alertDetails.rule, namespace),
155-
)
156-
}
157-
>
158-
{t('Silence alert')}
159-
</DropdownItem>,
160-
<DropdownItem
161-
key="view-rule"
162-
isDisabled={alertDetails?.alertstate === 'resolved' ? true : false}
163-
>
164-
<Link
165-
to={getRuleUrl(perspective, alertDetails?.rule?.rule)}
166-
style={{ color: 'inherit', textDecoration: 'inherit' }}
167-
>
168-
{t('View alerting rule')}
169-
</Link>
170-
</DropdownItem>,
171-
]}
172-
/>
173-
</Td>
17476
</Tr>
17577
);
17678
})

web/src/components/Incidents/IncidentsPage.tsx

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ import {
4949
setIncidentsActiveFilters,
5050
} from '../../actions/observe';
5151
import { useLocation } from 'react-router-dom';
52-
import { usePerspective } from '../hooks/usePerspective';
52+
import { getLegacyObserveState, usePerspective } from '../hooks/usePerspective';
5353
import { changeDaysFilter } from './utils';
5454
import { parsePrometheusDuration } from '../console/console-shared/src/datetime/prometheus';
5555
import withFallback from '../console/console-shared/error/fallbacks/withFallback';
@@ -58,13 +58,16 @@ import AlertsChart from './AlertsChart/AlertsChart';
5858
import { usePatternFlyTheme } from '../hooks/usePatternflyTheme';
5959
import { MonitoringState } from 'src/reducers/observe';
6060
import { Incident } from './model';
61+
import { useAlertsPoller } from '../hooks/useAlertsPoller';
62+
import { Rule } from '@openshift-console/dynamic-plugin-sdk';
6163

6264
const IncidentsPage = () => {
6365
const { t } = useTranslation(process.env.I18N_NAMESPACE);
6466
const dispatch = useDispatch();
6567
const location = useLocation();
6668
const urlParams = useMemo(() => parseUrlParams(location.search), [location.search]);
67-
const { perspective } = usePerspective();
69+
const { perspective, rulesKey } = usePerspective();
70+
useAlertsPoller();
6871
const { theme } = usePatternFlyTheme();
6972
// loading states
7073
const [incidentsAreLoading, setIncidentsAreLoading] = useState(true);
@@ -206,13 +209,19 @@ const IncidentsPage = () => {
206209
})();
207210
}, [incidentForAlertProcessing]);
208211

212+
const alertingRulesData: Rule[] = useSelector((state: MonitoringState) =>
213+
getLegacyObserveState(perspective, state)?.get(rulesKey),
214+
);
215+
209216
useEffect(() => {
210-
dispatch(
211-
setAlertsTableData({
212-
alertsTableData: groupAlertsForTable(alertsData),
213-
}),
214-
);
215-
}, [alertsData]);
217+
if (alertingRulesData && alertsData) {
218+
dispatch(
219+
setAlertsTableData({
220+
alertsTableData: groupAlertsForTable(alertsData, alertingRulesData),
221+
}),
222+
);
223+
}
224+
}, [alertsData, alertingRulesData]);
216225

217226
useEffect(() => {
218227
(async () => {

web/src/components/Incidents/processAlerts.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -188,13 +188,17 @@ export function processAlerts(
188188
.filter((alert) => alert !== null);
189189
}
190190

191-
export const groupAlertsForTable = (alerts: Array<Alert>): Array<Alert> => {
191+
export const groupAlertsForTable = (alerts: Array<Alert>, alertingRulesData): Array<Alert> => {
192192
// group alerts by the component and coun
193193
const groupedAlerts: Array<Alert> = alerts.reduce((acc, alert) => {
194-
const { component, alertstate, severity, layer } = alert;
194+
const { component, alertstate, severity, layer, alertname } = alert;
195195
const existingGroup = acc.find((group) => group.component === component);
196+
let rule;
197+
if (alertingRulesData) {
198+
rule = alertingRulesData.find((rule) => alertname === rule.name);
199+
}
196200
if (existingGroup) {
197-
existingGroup.alertsExpandedRowData.push(alert);
201+
existingGroup.alertsExpandedRowData.push({ ...alert, rule });
198202
if (severity === 'warning') existingGroup.warning += 1;
199203
else if (severity === 'info') existingGroup.info += 1;
200204
else if (severity === 'critical') existingGroup.critical += 1;
@@ -206,7 +210,7 @@ export const groupAlertsForTable = (alerts: Array<Alert>): Array<Alert> => {
206210
warning: severity === 'warning' ? 1 : 0,
207211
info: severity === 'info' ? 1 : 0,
208212
critical: severity === 'critical' ? 1 : 0,
209-
alertsExpandedRowData: [alert],
213+
alertsExpandedRowData: [{ ...alert, rule }],
210214
});
211215
}
212216

0 commit comments

Comments
 (0)