search
This commit is contained in:
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>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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 };
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in new issue
Block a user