This commit is contained in:
Alex Holliday committed 2025-11-26 22:22:15 +00:00
1 parent c50b0cbfd6
commit 8774042725
5 files changed
+49 -2

No files matched your search

@@ -1,8 +1,10 @@
import Stack from "@mui/material/Stack";
import Box from "@mui/material/Box";
import MenuItem from "@mui/material/MenuItem";
import Typography from "@mui/material/Typography";
import { Select, Checkbox } from "@/components/inputs";
import { Select, Checkbox, TextInput } from "@/components/inputs";
import { useEffect, useState } from "react";
import { useTheme } from "@mui/material/styles";
import type { SelectChangeEvent } from "@mui/material/Select";
import {
@@ -17,6 +19,8 @@ type HeaderFilterProps = {
selectedStatuses: MonitorStatus[];
onTypesChange: (types: UptimeMonitorType[]) => void;
onStatusesChange: (statuses: MonitorStatus[]) => void;
searchString: string;
onSearchStringChange?: (value: string) => void;
};
const coerceValue = <T extends string>(value: string | string[]): T[] => {
@@ -31,8 +35,24 @@ export const HeaderFilter = ({
selectedStatuses,
onTypesChange,
onStatusesChange,
searchString,
onSearchStringChange,
}: HeaderFilterProps) => {
const theme = useTheme();
const [localSearch, setLocalSearch] = useState<string>(searchString);
useEffect(() => {
setLocalSearch(searchString);
}, [searchString]);
useEffect(() => {
const handle = setTimeout(() => {
if (localSearch !== searchString) {
onSearchStringChange?.(localSearch);
}
}, 300);
return () => clearTimeout(handle);
}, [localSearch, onSearchStringChange, searchString]);
const handleTypeChange = (event: SelectChangeEvent<UptimeMonitorType[]>) => {
onTypesChange(coerceValue<UptimeMonitorType>(event.target.value));
@@ -76,6 +96,14 @@ export const HeaderFilter = ({
</MenuItem>
))}
</Select>
<Box flex={1} display={{ xs: "none", md: "inherit" }} />
<TextInput
fieldLabel="Search"
value={localSearch}
onChange={(event) => {
setLocalSearch(event.target.value);
}}
/>
</Stack>
);
};
+7 -1
View File
@@ -41,6 +41,7 @@ const UptimeMonitors = () => {
const [rowsPerPage, setRowsPerPage] = useState(10);
const [selectedTypes, setSelectedTypes] = useState<UptimeMonitorType[]>([]);
const [selectedStatuses, setSelectedStatuses] = useState<MonitorStatus[]>([]);
const [searchString, setSearchString] = useState<string>("");
const { deleteFn, loading: isDeleting } = useDelete();
@@ -60,6 +61,7 @@ const UptimeMonitors = () => {
"embedChecks=true",
typeQuery,
statusQuery,
`search=${searchString}`,
`sortField=${sortField}`,
`sortOrder=${sortOrder}`,
`page=${page}`,
@@ -99,7 +101,9 @@ const UptimeMonitors = () => {
};
const hasActiveFilters =
selectedTypes.length > 0 || selectedStatuses.length > 0;
selectedTypes.length > 0 ||
selectedStatuses.length > 0 ||
searchString.trim() !== "";
const showFallback = monitors.length === 0 && !hasActiveFilters;
const monitorItems = showFallback
@@ -134,6 +138,8 @@ const UptimeMonitors = () => {
selectedStatuses={selectedStatuses}
onTypesChange={setSelectedTypes}
onStatusesChange={setSelectedStatuses}
searchString={searchString}
onSearchStringChange={setSearchString}
/>
<MonitorTable
monitors={monitors}
@@ -78,6 +78,7 @@ class MonitorController {
let result;
if (req.validatedQuery.embedChecks === true) {
const search = req.validatedQuery.search || "";
const sortField = req.validatedQuery.sortField || "name";
const sortOrder = req.validatedQuery.sortOrder || "desc";
const page = req.validatedQuery.page || 0;
@@ -87,6 +88,7 @@ class MonitorController {
result = await this.monitorService.getAllEmbedChecks(
teamId,
search,
sortField,
sortOrder,
page,
@@ -26,6 +26,7 @@ export interface IMonitorService {
getAll: (teamId: string) => Promise<IMonitor[]>;
getAllEmbedChecks: (
teamId: string,
search: string,
sortField: string,
sortOrder: string,
page: number,
@@ -104,6 +105,7 @@ class MonitorService implements IMonitorService {
getAllEmbedChecks = async (
teamId: string,
search: string,
sortField: string,
sortOrder: string,
page: number,
@@ -117,6 +119,14 @@ class MonitorService implements IMonitorService {
teamId: teamObjectId,
};
if (search && search.trim() !== "") {
const term = search.trim();
(matchConditions as any).$or = [
{ name: { $regex: term, $options: "i" } },
{ url: { $regex: term, $options: "i" } },
];
}
if (Array.isArray(type) && type.length > 0) {
matchConditions.type = { $in: type };
}
+1
View File
@@ -181,6 +181,7 @@ export const monitorAllEmbedChecksQuerySchema = z.object({
if (!val) return [];
return Array.isArray(val) ? val : [val];
}),
search: z.string().optional(),
sortField: z.string().optional(),
sortOrder: z.string().optional(),
page: z