Skip to content

Commit c8240bd

Browse files
committed
feat: fix misaligned start dates by always loading 15 days
1 parent fe667e7 commit c8240bd

5 files changed

Lines changed: 55 additions & 9 deletions

File tree

web/src/components/Incidents/AlertsChart/AlertsChart.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import {
3232
generateDateArray,
3333
generateAlertsDateArray,
3434
getCurrentTime,
35+
isInTimeWindow,
3536
} from '../utils';
3637
import { dateTimeFormatter, timeFormatter } from '../../console/utils/datetime';
3738
import { useTranslation } from 'react-i18next';
@@ -41,7 +42,7 @@ import { MonitoringState } from '../../../store/store';
4142
import { isEmpty } from 'lodash-es';
4243
import { DataTestIDs } from '../../data-test';
4344

44-
const AlertsChart = ({ theme }: { theme: 'light' | 'dark' }) => {
45+
const AlertsChart = ({ theme, daysSpan }: { theme: 'light' | 'dark'; daysSpan: number }) => {
4546
const dispatch = useDispatch();
4647
const [chartContainerHeight, setChartContainerHeight] = useState<number>();
4748
const [chartHeight, setChartHeight] = useState<number>();
@@ -72,8 +73,13 @@ const AlertsChart = ({ theme }: { theme: 'light' | 'dark' }) => {
7273

7374
const chartData: AlertsChartBar[][] = useMemo(() => {
7475
if (!Array.isArray(alertsData) || alertsData.length === 0) return [];
75-
return alertsData.map((alert) => createAlertsChartBars(alert));
76-
}, [alertsData]);
76+
return alertsData
77+
.filter((alert) => {
78+
const lastTimestamp = alert.values[alert.values.length - 1][0];
79+
return isInTimeWindow(lastTimestamp, daysSpan, currentTime);
80+
})
81+
.map((alert) => createAlertsChartBars(alert));
82+
}, [alertsData, currentTime, daysSpan]);
7783

7884
useEffect(() => {
7985
setChartContainerHeight(chartData?.length < 5 ? 300 : chartData?.length * 55);

web/src/components/Incidents/IncidentsChart/IncidentsChart.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import {
3333
calculateIncidentsChartDomain,
3434
createIncidentsChartBars,
3535
generateDateArray,
36+
isInTimeWindow,
3637
} from '../utils';
3738
import { dateTimeFormatter, timeFormatter } from '../../console/utils/datetime';
3839
import { useTranslation } from 'react-i18next';
@@ -84,10 +85,15 @@ const IncidentsChart = ({
8485
const chartData = useMemo(() => {
8586
if (!Array.isArray(incidentsData) || incidentsData.length === 0) return [];
8687

87-
const filteredIncidents = selectedGroupId
88+
const groupFilteredIncidents = selectedGroupId
8889
? incidentsData.filter((incident) => incident.group_id === selectedGroupId)
8990
: incidentsData;
9091

92+
const filteredIncidents = groupFilteredIncidents.filter((incident) => {
93+
const lastTimestamp = incident.values[incident.values.length - 1][0];
94+
return isInTimeWindow(lastTimestamp, chartDays * (60 * 60 * 24 * 1000), currentTime);
95+
});
96+
9197
// Create chart bars and sort by original x values to maintain proper order
9298
const chartBars = filteredIncidents.map((incident) =>
9399
createIncidentsChartBars(incident, dateValues),
@@ -96,7 +102,7 @@ const IncidentsChart = ({
96102

97103
// Reassign consecutive x values to eliminate gaps between bars
98104
return chartBars.map((bars, index) => bars.map((bar) => ({ ...bar, x: index + 1 })));
99-
}, [incidentsData, dateValues, selectedGroupId]);
105+
}, [incidentsData, dateValues, selectedGroupId, currentTime, chartDays]);
100106

101107
useEffect(() => {
102108
setIsLoading(false);

web/src/components/Incidents/IncidentsPage.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,12 @@ const IncidentsPage = () => {
265265
if (rules && alertsData) {
266266
dispatch(
267267
setAlertsTableData({
268-
alertsTableData: groupAlertsForTable(alertsData, rules),
268+
alertsTableData: groupAlertsForTable(
269+
alertsData,
270+
rules,
271+
incidentsLastRefreshTime,
272+
daysSpan,
273+
),
269274
}),
270275
);
271276
}
@@ -604,7 +609,7 @@ const IncidentsPage = () => {
604609
<StackItem>
605610
<IncidentsChart
606611
incidentsData={filteredData}
607-
chartDays={timeRanges.length}
612+
chartDays={daysSpan / (60 * 60 * 24 * 1000)} // Convert ms to days
608613
theme={theme}
609614
selectedGroupId={selectedGroupId}
610615
onIncidentClick={handleIncidentChartClick}
@@ -613,7 +618,7 @@ const IncidentsPage = () => {
613618
/>
614619
</StackItem>
615620
<StackItem>
616-
<AlertsChart theme={theme} />
621+
<AlertsChart theme={theme} daysSpan={daysSpan} />
617622
</StackItem>
618623
</>
619624
)}

web/src/components/Incidents/processAlerts.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,8 +290,19 @@ export function convertToAlerts(
290290
export const groupAlertsForTable = (
291291
alerts: Array<Alert>,
292292
alertingRulesData: Array<PrometheusRule>,
293+
currentTime: number,
294+
daysSpan: number,
293295
): Array<GroupedAlert> => {
294-
const groupedAlerts = alerts.reduce((acc: Array<GroupedAlert>, alert) => {
296+
const filteredAlerts = alerts.filter((alert) => {
297+
const endTime = alert.values[alert.values.length - 1][0];
298+
const delta = (currentTime - daysSpan) / 1000;
299+
if (endTime < delta) {
300+
return false;
301+
}
302+
return true;
303+
});
304+
305+
const groupedAlerts = filteredAlerts.reduce((acc: Array<GroupedAlert>, alert) => {
295306
const { component, alertstate, severity, layer, alertname, silenced } = alert;
296307
const existingGroup = acc.find((group) => group.component === component);
297308
const rule = alertingRulesData?.find((rule) => alertname === rule.name);

web/src/components/Incidents/utils.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,24 @@ export const isResolved = (lastTimestamp: number, currentTime: number): boolean
7272
return delta >= threshold;
7373
};
7474

75+
/**
76+
* Checks if the last timestamp is in the time window.
77+
* @param lastTimestamp - The last timestamp in the incident/alert (in seconds)
78+
* @param daysSpan - The number of days in the time window (in milliseconds).
79+
* @param currentTime - The current time in milliseconds.
80+
* @returns true if the last timestamp is in the time window, false otherwise.
81+
*/
82+
export const isInTimeWindow = (
83+
lastTimestamp: number,
84+
daysSpan: number,
85+
currentTime: number,
86+
): boolean => {
87+
// convert chartDays to ms and then convert the result to seconds
88+
const timeWindow = (currentTime - daysSpan) / 1000;
89+
// if endTime is lower than currentTime-chartDays, return false else true
90+
return lastTimestamp >= timeWindow;
91+
};
92+
7593
/**
7694
* Inserts padding data points to ensure the chart renders correctly.
7795
* This allows the chart to properly render events, especially single data points.

0 commit comments

Comments
 (0)