add llama suggestions and fix genericFallback error

This commit is contained in:
karenvicent committed 2025-12-18 12:47:01 -05:00
1 parent 75acb1ade6
commit 9555ff43c7
7 files changed
+95 -39

No files matched your search

@@ -40,13 +40,13 @@ const GenericFallback = ({ children }) => {
<Box
component="img"
src={mode === "light" ? OutputAnimation : DarkmodeOutput}
Background="transparent"
alt="Loading animation"
sx={{
zIndex: 1,
border: "none",
borderRadius: theme.spacing(8),
width: "100%",
backgroundColor: "transparent",
}}
/>
<Box
@@ -32,8 +32,12 @@ const IncidentTable = ({
const theme = useTheme();
const handleResolveIncident = async (incidentId) => {
await resolveIncident(incidentId);
handleUpdateTrigger();
try {
await resolveIncident(incidentId);
handleUpdateTrigger();
} catch (error) {
console.error(t("incidentsPage.errorResolvingIncident"), error);
}
};
const headers = [
@@ -156,7 +160,7 @@ const IncidentTable = ({
);
}
if (!isLoading && incidents == undefined) {
if (!isLoading && !networkError && incidents?.length === 0) {
return (
<GenericFallback>
{t("incidentsTableNoIncidents", "No incidents found")}
@@ -34,7 +34,7 @@ const StatisticsPanel = ({ isLoading = false, error = null, summary = {} }) => {
const theme = useTheme();
const { t } = useTranslation();
const totalResolutions =
summary?.totalManualResolutions + summary?.totalAutomaticResolutions;
(summary?.totalManualResolutions || 0) + (summary?.totalAutomaticResolutions || 0);
const automaticPercentage =
totalResolutions > 0
? (summary?.totalAutomaticResolutions / totalResolutions) * 100
@@ -39,7 +39,7 @@ const useFetchIncidents = () => {
* @param {number} [config.page] - Page number
* @param {number} [config.rowsPerPage] - Rows per page
*/
const fetchIncidentsByTeam = async (config = {}) => {
const fetchIncidentsByTeam = useCallback(async (config = {}) => {
try {
setIsLoading(true);
setNetworkError(false);
@@ -55,42 +55,51 @@ const useFetchIncidents = () => {
} finally {
setIsLoading(false);
}
};
}, []);
/**
* Fetch active (open) incidents - Default function
*
* @param {Object} config - Additional configuration
*/
const fetchActiveIncidents = async (config = {}) => {
await fetchIncidentsByTeam({
status: true,
sortOrder: "desc",
...config,
});
};
const fetchActiveIncidents = useCallback(
async (config = {}) => {
await fetchIncidentsByTeam({
status: true,
sortOrder: "desc",
...config,
});
},
[fetchIncidentsByTeam]
);
/**
* Fetch resolved incidents
*
* @param {Object} config - Additional configuration
*/
const fetchResolvedIncidents = async (config = {}) => {
await fetchIncidentsByTeam({
status: false,
sortOrder: "desc",
...config,
});
};
const fetchResolvedIncidents = useCallback(
async (config = {}) => {
await fetchIncidentsByTeam({
status: false,
sortOrder: "desc",
...config,
});
},
[fetchIncidentsByTeam]
);
/**
* Fetch incidents with custom filters (alias for fetchIncidentsByTeam)
*
* @param {Object} config - Configuration object
*/
const fetchIncidents = async (config = {}) => {
await fetchIncidentsByTeam(config);
};
const fetchIncidents = useCallback(
async (config = {}) => {
await fetchIncidentsByTeam(config);
},
[fetchIncidentsByTeam]
);
/**
* Fetch a single incident by ID
@@ -98,9 +107,9 @@ const useFetchIncidents = () => {
* @param {string} incidentId - The ID of the incident to fetch
* @returns {Promise<Object|null>} The incident object or null if not found
*/
const fetchIncidentById = async (incidentId) => {
const fetchIncidentById = useCallback(async (incidentId) => {
if (!incidentId) {
console.error(t("incidentsPage.noIcidentIdProvided"));
console.error(t("incidentsPage.noIncidentIdProvided"));
return null;
}
@@ -118,7 +127,7 @@ const useFetchIncidents = () => {
} finally {
setIsLoading(false);
}
};
}, []);
/**
* Resolve an incident manually
@@ -129,9 +138,9 @@ const useFetchIncidents = () => {
* @param {Function} [onSuccess] - Callback function to call on success
* @param {Function} [onError] - Callback function to call on error
*/
const resolveIncident = async (incidentId, options = {}) => {
const resolveIncident = useCallback(async (incidentId, options = {}) => {
if (!incidentId) {
console.error(t("incidentsPage.noIcidentIdProvided"));
console.error(t("incidentsPage.noIncidentIdProvided"));
return;
}
@@ -156,7 +165,7 @@ const useFetchIncidents = () => {
} finally {
setIsLoading(false);
}
};
}, []);
/**
* Fetch incident summary
+13 -3
View File
@@ -23,8 +23,8 @@ const Incidents2 = () => {
{ name: t("incidentsPageTitle", "Incidents"), path: "/incidents" },
];
const [selectedMonitor, setSelectedMonitor] = useState(undefined);
const [filter, setFilter] = useState(undefined);
const [selectedMonitor, setSelectedMonitor] = useState("0");
const [filter, setFilter] = useState("all");
const [dateRange, setDateRange] = useState("all");
const [page, setPage] = useState(0);
const [rowsPerPage, setRowsPerPage] = useState(10);
@@ -73,7 +73,17 @@ const Incidents2 = () => {
} else {
fetchIncidents(config);
}
}, [selectedMonitor, filter, dateRange, page, rowsPerPage, updateTrigger]); // Refetch when filters or pagination change
}, [
selectedMonitor,
filter,
dateRange,
page,
rowsPerPage,
updateTrigger,
fetchActiveIncidents,
fetchResolvedIncidents,
fetchIncidents,
]);
useEffect(() => {
const lookup = monitors?.reduce((acc, monitor) => {
+1 -1
View File
@@ -1178,7 +1178,7 @@
"incidentResolvedFailed": "Error resolving incident",
"errorFetchingIncidents": "Error fetching incidents",
"errorFetchingIncident": "Error fetching incident",
"noIcidentIdProvided": "No incident ID provided",
"noIncidentIdProvided": "No incident ID provided",
"errorFetchingIncidentSummary": "Error fetching incident summary",
"incidentsOptionsHeaderFilterManual": "Manual",
"incidentsOptionsHeaderFilterAll": "All",
+38 -5
View File
@@ -166,6 +166,38 @@ class IncidentModule {
}
};
/**
* Get incidents by team with filtering
*
* STATUS PARAMETER CONTRACT (IMPORTANT - Frontend dependency):
* This method has an implicit contract with frontend's useFetchIncidents hook:
*
* - status === undefined: Frontend uses this to represent "all incidents" (filter === "all")
* Backend applies $or logic: { status: true } OR { status: false, endTime: >= dateRange }
* This shows all active incidents + resolved incidents within the date range
*
* - status === true: Frontend uses for "active incidents" (filter === "active")
* Backend shows all active incidents (no date filter applied)
* Active incidents are currently happening, so date range doesn't apply
*
* - status === false: Frontend uses for "resolved incidents" (filter === "resolved")
* Backend filters by endTime >= dateRange
* Only shows incidents that were resolved within the specified date range
*
* WARNING: Changing this logic will break frontend filtering behavior.
* The frontend depends on undefined status triggering the $or logic for "all incidents".
* This contract must be maintained when modifying either frontend or backend code.
*
* @param {Object} params - Query parameters
* @param {string} params.teamId - Team ID
* @param {string} [params.sortOrder] - Sort order (asc/desc)
* @param {string} [params.dateRange] - Date range filter
* @param {number} [params.page] - Page number
* @param {number} [params.rowsPerPage] - Rows per page
* @param {boolean|undefined} [params.status] - Status filter. undefined = all, true = active, false = resolved
* @param {string} [params.monitorId] - Monitor ID filter
* @param {string} [params.resolutionType] - Resolution type filter
*/
getIncidentsByTeam = async ({ teamId, sortOrder, dateRange, page, rowsPerPage, status, monitorId, resolutionType }) => {
try {
page = Number.isFinite(parseInt(page)) ? parseInt(page) : 0;
@@ -187,10 +219,10 @@ class IncidentModule {
...(resolutionType && { resolutionType }),
};
// Date range filter:
// - Active incidents: always show (no date filter) - they're currently happening
// - Resolved incidents: filter by endTime (when they were resolved)
// - All incidents: show all active + resolved in the range
// Date range filter logic (see contract documentation above):
// - Active incidents (statusBoolean === true): always show (no date filter) - they're currently happening
// - Resolved incidents (statusBoolean === false): filter by endTime (when they were resolved)
// - All incidents (statusBoolean === undefined): show all active + resolved in the range using $or
if (dateRangeLookup[dateRange]) {
const dateThreshold = dateRangeLookup[dateRange];
if (statusBoolean === true) {
@@ -201,6 +233,7 @@ class IncidentModule {
matchStage.endTime = { $gte: dateThreshold };
} else {
// All incidents: show all active + resolved incidents in the range
// This is the critical contract: undefined status triggers $or logic
matchStage.$or = [
{ status: true }, // All active incidents
{ status: false, endTime: { $gte: dateThreshold } }, // Resolved in range
@@ -374,7 +407,7 @@ class IncidentModule {
const latestIncidentsPipeline = [
{ $match: matchStage },
{ $sort: { createdAt: -1 } },
{ $limit: parseInt(limit) },
{ $limit: Math.max(1, parseInt(limit) || 10) },
{
$lookup: {
from: "monitors",