fitlers
This commit is contained in:
1 parent
83b628c8f9
commit
6063532c79
4 files changed
+117
-30
No files matched your search
@@ -0,0 +1,81 @@
|
||||
import Stack from "@mui/material/Stack";
|
||||
import { Select, Button } from "@/Components/v2/inputs";
|
||||
import MenuItem from "@mui/material/MenuItem";
|
||||
import useMediaQuery from "@mui/material/useMediaQuery";
|
||||
import { Typography, useTheme } from "@mui/material";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import type { Monitor } from "@/Types/Monitor";
|
||||
|
||||
const resolutionTypes = ["manual", "automatic"];
|
||||
|
||||
interface ControlsIncidentFilterProps {
|
||||
monitors?: Monitor[];
|
||||
selectedMonitor: string;
|
||||
setSelectedMonitor: React.Dispatch<React.SetStateAction<string>>;
|
||||
selectedResolutionType: string;
|
||||
setSelectedResolutionType: React.Dispatch<React.SetStateAction<string>>;
|
||||
onClearFilters: () => void;
|
||||
}
|
||||
|
||||
export const ControlsIncidentFilter = ({
|
||||
monitors,
|
||||
selectedMonitor,
|
||||
setSelectedMonitor,
|
||||
selectedResolutionType,
|
||||
setSelectedResolutionType,
|
||||
onClearFilters,
|
||||
}: ControlsIncidentFilterProps) => {
|
||||
const { t } = useTranslation();
|
||||
const theme = useTheme();
|
||||
const isSmall = useMediaQuery(theme.breakpoints.down("md"));
|
||||
const isFilterActive = selectedMonitor !== "0" || selectedResolutionType !== "";
|
||||
|
||||
return (
|
||||
<Stack
|
||||
direction={isSmall ? "column" : "row"}
|
||||
gap={theme.spacing(2)}
|
||||
>
|
||||
<Select
|
||||
placeholder={t("pages.incidents.filters.monitor")}
|
||||
value={selectedMonitor}
|
||||
onChange={(e) => setSelectedMonitor(e.target.value)}
|
||||
>
|
||||
<MenuItem value="0">
|
||||
<Typography>{t("pages.incidents.filters.allMonitors")}</Typography>
|
||||
</MenuItem>
|
||||
{monitors?.map((monitor) => (
|
||||
<MenuItem
|
||||
key={monitor.id}
|
||||
value={monitor.id}
|
||||
>
|
||||
<Typography>{monitor.name}</Typography>
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
<Select
|
||||
placeholder={t("pages.incidents.filters.resolutionType")}
|
||||
value={selectedResolutionType}
|
||||
onChange={(e) => setSelectedResolutionType(e.target.value)}
|
||||
>
|
||||
{resolutionTypes.map((type) => (
|
||||
<MenuItem
|
||||
key={type}
|
||||
value={type}
|
||||
>
|
||||
<Typography textTransform="capitalize">
|
||||
{t(`pages.incidents.filters.resolutionTypes.${type}`)}
|
||||
</Typography>
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
{isFilterActive && (
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={onClearFilters}
|
||||
>
|
||||
{t("pages.incidents.filters.clearFilters")}
|
||||
</Button>
|
||||
)}
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
@@ -18,6 +18,7 @@ import { useTheme } from "@mui/material/styles";
|
||||
import Box from "@mui/material/Box";
|
||||
|
||||
interface IncidentsTableProps {
|
||||
title?: string;
|
||||
incidents?: Incident[];
|
||||
monitors?: Monitor[];
|
||||
incidentsCount: number;
|
||||
@@ -30,7 +31,6 @@ interface IncidentsTableProps {
|
||||
}
|
||||
|
||||
export const IncidentsTable = ({
|
||||
title,
|
||||
incidents,
|
||||
monitors,
|
||||
incidentsCount,
|
||||
|
||||
@@ -12,6 +12,7 @@ import { IncidentsTable } from "@/Pages/Incidents/Components/IncidentTable";
|
||||
import { DialogResolution } from "@/Pages/Incidents/Components/DialogResolution";
|
||||
import { DialogIncidentDetails } from "@/Pages/Incidents/Components/DialogIncidentDetails";
|
||||
import { HeaderTimeRange } from "@/Components/v2/common";
|
||||
import { ControlsIncidentFilter } from "@/Pages/Incidents/Components/ControlsIncidentFilter";
|
||||
|
||||
import { useGet } from "@/Hooks/UseApi";
|
||||
import { useState, useEffect, useMemo } from "react";
|
||||
@@ -64,7 +65,6 @@ const IncidentsPage = () => {
|
||||
const {
|
||||
data: incidentsData,
|
||||
isLoading: isLoadingIncidents,
|
||||
error: incidentsError,
|
||||
refetch: refetchIncidents,
|
||||
} = useGet<IncidentsResponse>(
|
||||
incidentsUrl,
|
||||
@@ -73,11 +73,7 @@ const IncidentsPage = () => {
|
||||
);
|
||||
|
||||
// Fetch monitors for lookup
|
||||
const {
|
||||
data: monitorsData,
|
||||
isLoading: isLoadingMonitors,
|
||||
error: monitorsError,
|
||||
} = useGet<Monitor[]>("/monitors/team");
|
||||
const { data: monitorsData } = useGet<Monitor[]>("/monitors/team");
|
||||
|
||||
// Build active incidents URL (always fetch all active, no date filter)
|
||||
const activeIncidentsUrl = useMemo(() => {
|
||||
@@ -99,12 +95,9 @@ const IncidentsPage = () => {
|
||||
);
|
||||
|
||||
// Fetch incident summary
|
||||
const {
|
||||
data: summaryData,
|
||||
isLoading: isLoadingSummary,
|
||||
error: summaryError,
|
||||
refetch: refetchSummary,
|
||||
} = useGet<IncidentSummary>("/incidents/team/summary");
|
||||
const { data: summaryData, refetch: refetchSummary } = useGet<IncidentSummary>(
|
||||
"/incidents/team/summary"
|
||||
);
|
||||
|
||||
// Reset page when filters change
|
||||
useEffect(() => {
|
||||
@@ -116,17 +109,11 @@ const IncidentsPage = () => {
|
||||
const incidentsCount = incidentsData?.count ?? 0;
|
||||
const activeIncidents = activeIncidentsData?.incidents ?? [];
|
||||
const activeIncidentsCount = activeIncidentsData?.count ?? 0;
|
||||
const networkError = !!incidentsError || !!monitorsError || !!summaryError;
|
||||
|
||||
// Expose state and handlers for future UI use
|
||||
void selectedMonitor;
|
||||
void setSelectedMonitor;
|
||||
void filter;
|
||||
void setFilter;
|
||||
void isLoadingIncidents;
|
||||
void isLoadingMonitors;
|
||||
void isLoadingSummary;
|
||||
void networkError;
|
||||
const handleClearFilters = () => {
|
||||
setSelectedMonitor("0");
|
||||
setFilter("all");
|
||||
};
|
||||
|
||||
const handleOpenDetails = (incidentId: string) => {
|
||||
const incident =
|
||||
@@ -176,15 +163,23 @@ const IncidentsPage = () => {
|
||||
<SummaryCardLatestIncidents summary={summaryData} />
|
||||
<SummaryCardStats summary={summaryData} />
|
||||
</Stack>
|
||||
<Typography
|
||||
variant="h6"
|
||||
sx={{ mb: theme.spacing(4), textTransform: "uppercase" }}
|
||||
>
|
||||
{t("pages.incidents.table.activeIncidents")}
|
||||
</Typography>
|
||||
|
||||
<ControlsIncidentFilter
|
||||
monitors={monitorsData ?? undefined}
|
||||
selectedMonitor={selectedMonitor}
|
||||
setSelectedMonitor={setSelectedMonitor}
|
||||
selectedResolutionType={filter}
|
||||
setSelectedResolutionType={setFilter}
|
||||
onClearFilters={handleClearFilters}
|
||||
/>
|
||||
{activeIncidentsCount > 0 && (
|
||||
<>
|
||||
<Typography
|
||||
variant="h6"
|
||||
sx={{ mb: theme.spacing(4), textTransform: "uppercase" }}
|
||||
>
|
||||
{t("pages.incidents.table.activeIncidents")}
|
||||
</Typography>
|
||||
|
||||
<IncidentsTable
|
||||
incidents={activeIncidents}
|
||||
monitors={monitorsData ?? undefined}
|
||||
@@ -206,6 +201,7 @@ const IncidentsPage = () => {
|
||||
>
|
||||
{t("pages.incidents.table.resolvedIncidents")}
|
||||
</Typography>
|
||||
|
||||
<HeaderTimeRange
|
||||
dateRange={dateRange}
|
||||
setDateRange={setDateRange}
|
||||
|
||||
@@ -414,6 +414,16 @@
|
||||
"resolveManually": "Resolve Manually"
|
||||
}
|
||||
},
|
||||
"filters": {
|
||||
"monitor": "Monitor",
|
||||
"allMonitors": "All monitors",
|
||||
"resolutionType": "Resolution type",
|
||||
"resolutionTypes": {
|
||||
"automatic": "Automatic",
|
||||
"manual": "Manual"
|
||||
},
|
||||
"clearFilters": "Clear Filters"
|
||||
},
|
||||
"dialog": {
|
||||
"details": {
|
||||
"title": "Incident details",
|
||||
|
||||
Reference in new issue
Block a user