From 07b04833524a955c7a450a1010de917f773a73b3 Mon Sep 17 00:00:00 2001 From: mannilakash Date: Mon, 9 Feb 2026 10:43:29 -0500 Subject: [PATCH 1/4] fix: changes for debounce search in uptime/infrastructure pages --- client/src/Pages/Infrastructure/Monitors/index.tsx | 8 ++++++-- client/src/Pages/Uptime/Monitors/index.tsx | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/client/src/Pages/Infrastructure/Monitors/index.tsx b/client/src/Pages/Infrastructure/Monitors/index.tsx index 507ecb1ef..0db682272 100644 --- a/client/src/Pages/Infrastructure/Monitors/index.tsx +++ b/client/src/Pages/Infrastructure/Monitors/index.tsx @@ -20,6 +20,7 @@ import { useSelector, useDispatch } from "react-redux"; import { setRowsPerPage } from "@/Features/UI/uiSlice.js"; import type { RootState } from "@/Types/state"; import { InfraMonitorsTable } from "./Components/MonitorsTable"; +import useDebounce from "@/Utils/debounce"; const InfrastructureMonitors = () => { const { t } = useTranslation(); @@ -43,6 +44,9 @@ const InfrastructureMonitors = () => { const [selectedMonitor, setSelectedMonitor] = useState(null); const isDialogOpen = Boolean(selectedMonitor); + // Debounce search input - 300ms delay + const debouncedSearch = useDebounce(search, 300); + const handleClearFilters = useCallback(() => { setSelectedStatus(""); setSelectedState(""); @@ -69,8 +73,8 @@ const InfrastructureMonitors = () => { [toFilterActive, "isActive"], ]); const activeFilter = [...filterLookup].find(([key]) => key !== undefined); - const field = activeFilter?.[1] || (search ? "name" : sortField || undefined); - const filter = activeFilter?.[0] || search || undefined; + const field = activeFilter?.[1] || (debouncedSearch ? "name" : sortField || undefined); + const filter = activeFilter?.[0] || debouncedSearch || undefined; // Build URL for monitors with checks const monitorsWithChecksUrl = useMemo(() => { diff --git a/client/src/Pages/Uptime/Monitors/index.tsx b/client/src/Pages/Uptime/Monitors/index.tsx index 8aaed16d2..a06362744 100644 --- a/client/src/Pages/Uptime/Monitors/index.tsx +++ b/client/src/Pages/Uptime/Monitors/index.tsx @@ -20,6 +20,7 @@ import { setRowsPerPage } from "@/Features/UI/uiSlice.js"; import { useIsAdmin } from "@/Hooks/useIsAdmin"; import type { RootState } from "@/Types/state"; import { useTheme } from "@mui/material"; +import useDebounce from "@/Utils/debounce"; const UptimeMonitorsPage = () => { const { t } = useTranslation(); @@ -43,6 +44,9 @@ const UptimeMonitorsPage = () => { const [selectedMonitor, setSelectedMonitor] = useState(null); const isDialogOpen = Boolean(selectedMonitor); + // Debounce search input - 300ms delay + const debouncedSearch = useDebounce(search, 300); + // Convert filter selections to API filter values // Status: "up" -> true, "down" -> false // State: "active" -> true, "paused" -> false @@ -65,8 +69,8 @@ const UptimeMonitorsPage = () => { [toFilterActive, "isActive"], ]); const activeFilter = [...filterLookup].find(([key]) => key !== undefined); - const field = activeFilter?.[1] || (search ? "name" : sortField || undefined); - const filter = activeFilter?.[0] || search; + const field = activeFilter?.[1] || (debouncedSearch ? "name" : sortField || undefined); + const filter = activeFilter?.[0] || debouncedSearch; // Default to all types when none selected const effectiveTypes = From e75606aad3a4fc3bfb825a5af34fd1fb70e1dbac Mon Sep 17 00:00:00 2001 From: mannilakash Date: Mon, 9 Feb 2026 12:38:39 -0500 Subject: [PATCH 2/4] refactor: debounce.jsx to typescript and moving it to Hooks --- client/src/Hooks/useDebounce.ts | 29 +++++++++++++++++++ .../Pages/Infrastructure/Monitors/index.tsx | 2 +- client/src/Pages/Uptime/Monitors/index.tsx | 2 +- client/src/Utils/debounce.jsx | 18 ------------ 4 files changed, 31 insertions(+), 20 deletions(-) create mode 100644 client/src/Hooks/useDebounce.ts delete mode 100644 client/src/Utils/debounce.jsx diff --git a/client/src/Hooks/useDebounce.ts b/client/src/Hooks/useDebounce.ts new file mode 100644 index 000000000..da26e8e59 --- /dev/null +++ b/client/src/Hooks/useDebounce.ts @@ -0,0 +1,29 @@ +import { useState, useEffect } from "react"; + +/** + * Custom hook for debouncing values + * @template T - The type of the value being debounced + * @param value - The value to debounce + * @param delay - The debounce delay in milliseconds + * @returns The debounced value + * + * @example + * const debouncedSearch = useDebounce(search, 300); // Debounces the search input with a 300ms delay + */ +const useDebounce = (value: T, delay: number): T => { + const [debouncedValue, setDebouncedValue] = useState(value); + + useEffect(() => { + const handler = setTimeout(() => { + setDebouncedValue(value); + }, delay); + + return () => { + clearTimeout(handler); + }; + }, [value, delay]); + + return debouncedValue; +}; + +export default useDebounce; diff --git a/client/src/Pages/Infrastructure/Monitors/index.tsx b/client/src/Pages/Infrastructure/Monitors/index.tsx index 0db682272..303c7d0f7 100644 --- a/client/src/Pages/Infrastructure/Monitors/index.tsx +++ b/client/src/Pages/Infrastructure/Monitors/index.tsx @@ -20,7 +20,7 @@ import { useSelector, useDispatch } from "react-redux"; import { setRowsPerPage } from "@/Features/UI/uiSlice.js"; import type { RootState } from "@/Types/state"; import { InfraMonitorsTable } from "./Components/MonitorsTable"; -import useDebounce from "@/Utils/debounce"; +import useDebounce from "@/Hooks/useDebounce"; const InfrastructureMonitors = () => { const { t } = useTranslation(); diff --git a/client/src/Pages/Uptime/Monitors/index.tsx b/client/src/Pages/Uptime/Monitors/index.tsx index a06362744..ec4935221 100644 --- a/client/src/Pages/Uptime/Monitors/index.tsx +++ b/client/src/Pages/Uptime/Monitors/index.tsx @@ -20,7 +20,7 @@ import { setRowsPerPage } from "@/Features/UI/uiSlice.js"; import { useIsAdmin } from "@/Hooks/useIsAdmin"; import type { RootState } from "@/Types/state"; import { useTheme } from "@mui/material"; -import useDebounce from "@/Utils/debounce"; +import useDebounce from "@/Hooks/useDebounce"; const UptimeMonitorsPage = () => { const { t } = useTranslation(); diff --git a/client/src/Utils/debounce.jsx b/client/src/Utils/debounce.jsx deleted file mode 100644 index 11d639f14..000000000 --- a/client/src/Utils/debounce.jsx +++ /dev/null @@ -1,18 +0,0 @@ -import { useState, useEffect } from "react"; - -const useDebounce = (value, delay) => { - const [debouncedValue, setDebouncedValue] = useState(value); - - useEffect(() => { - const handler = setTimeout(() => { - setDebouncedValue(value); - }, delay); - - return () => { - clearTimeout(handler); - }; - }, [value, delay]); - return debouncedValue; -}; - -export default useDebounce; From c670653ab3a8324e14bf95d4cf868c84c3050be9 Mon Sep 17 00:00:00 2001 From: mannilakash Date: Mon, 9 Feb 2026 12:40:44 -0500 Subject: [PATCH 3/4] fix: format fix --- client/src/Hooks/useDebounce.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/Hooks/useDebounce.ts b/client/src/Hooks/useDebounce.ts index da26e8e59..175d079fa 100644 --- a/client/src/Hooks/useDebounce.ts +++ b/client/src/Hooks/useDebounce.ts @@ -10,7 +10,7 @@ import { useState, useEffect } from "react"; * @example * const debouncedSearch = useDebounce(search, 300); // Debounces the search input with a 300ms delay */ -const useDebounce = (value: T, delay: number): T => { +const useDebounce = (value: T, delay: number): T => { const [debouncedValue, setDebouncedValue] = useState(value); useEffect(() => { From 98943ad4611cf3837e208b41f1ae2cd7a150b9cb Mon Sep 17 00:00:00 2001 From: mannilakash Date: Tue, 10 Feb 2026 08:10:44 -0500 Subject: [PATCH 4/4] fix: removing JSdoc for usedebounce and comments --- client/src/Hooks/useDebounce.ts | 10 ---------- client/src/Pages/Infrastructure/Monitors/index.tsx | 3 +-- client/src/Pages/Uptime/Monitors/index.tsx | 3 +-- 3 files changed, 2 insertions(+), 14 deletions(-) diff --git a/client/src/Hooks/useDebounce.ts b/client/src/Hooks/useDebounce.ts index 175d079fa..57a7d4079 100644 --- a/client/src/Hooks/useDebounce.ts +++ b/client/src/Hooks/useDebounce.ts @@ -1,15 +1,5 @@ import { useState, useEffect } from "react"; -/** - * Custom hook for debouncing values - * @template T - The type of the value being debounced - * @param value - The value to debounce - * @param delay - The debounce delay in milliseconds - * @returns The debounced value - * - * @example - * const debouncedSearch = useDebounce(search, 300); // Debounces the search input with a 300ms delay - */ const useDebounce = (value: T, delay: number): T => { const [debouncedValue, setDebouncedValue] = useState(value); diff --git a/client/src/Pages/Infrastructure/Monitors/index.tsx b/client/src/Pages/Infrastructure/Monitors/index.tsx index 303c7d0f7..1d38dbdd3 100644 --- a/client/src/Pages/Infrastructure/Monitors/index.tsx +++ b/client/src/Pages/Infrastructure/Monitors/index.tsx @@ -44,8 +44,7 @@ const InfrastructureMonitors = () => { const [selectedMonitor, setSelectedMonitor] = useState(null); const isDialogOpen = Boolean(selectedMonitor); - // Debounce search input - 300ms delay - const debouncedSearch = useDebounce(search, 300); + const debouncedSearch = useDebounce(search, 300); const handleClearFilters = useCallback(() => { setSelectedStatus(""); diff --git a/client/src/Pages/Uptime/Monitors/index.tsx b/client/src/Pages/Uptime/Monitors/index.tsx index ec4935221..702bbd928 100644 --- a/client/src/Pages/Uptime/Monitors/index.tsx +++ b/client/src/Pages/Uptime/Monitors/index.tsx @@ -44,8 +44,7 @@ const UptimeMonitorsPage = () => { const [selectedMonitor, setSelectedMonitor] = useState(null); const isDialogOpen = Boolean(selectedMonitor); - // Debounce search input - 300ms delay - const debouncedSearch = useDebounce(search, 300); + const debouncedSearch = useDebounce(search, 300); // Convert filter selections to API filter values // Status: "up" -> true, "down" -> false