diff --git a/client/src/Components/Inputs/Search/index.jsx b/client/src/Components/Inputs/Search/index.jsx index 6c1d3e9a1..9f033cd52 100644 --- a/client/src/Components/Inputs/Search/index.jsx +++ b/client/src/Components/Inputs/Search/index.jsx @@ -25,6 +25,7 @@ import FieldWrapper from "../FieldWrapper"; * @param {Function} props.handleChange - Function to call when the input changes * @param {Function} Prop.onBlur - Function to call when the input is blured * @param {Object} props.sx - Additional styles to apply to the component + * @param {string} props.unit - Label to identify type of options * @returns {JSX.Element} The rendered Search component */ @@ -75,6 +76,7 @@ const Search = ({ labelFontWeight, labelVariant, labelSx = {}, + unit = "option", }) => { const theme = useTheme(); const { t } = useTranslation(); @@ -195,7 +197,12 @@ const Search = ({ ); if (filtered.length === 0) { - return [{ [filteredBy]: "No monitors found", noOptions: true }]; + return [ + { + [filteredBy]: t("general.noOptionsFound", { unit: unit }), + noOptions: true, + }, + ]; } return filtered; }} @@ -290,7 +297,7 @@ Search.propTypes = { options: PropTypes.array.isRequired, filteredBy: PropTypes.string.isRequired, secondaryLabel: PropTypes.string, - value: PropTypes.array, + value: PropTypes.oneOfType([PropTypes.array, PropTypes.object]), inputValue: PropTypes.string.isRequired, handleInputChange: PropTypes.func.isRequired, handleChange: PropTypes.func, @@ -301,6 +308,7 @@ Search.propTypes = { startAdornment: PropTypes.object, endAdornment: PropTypes.object, onBlur: PropTypes.func, + unit: PropTypes.string, }; export default Search; diff --git a/client/src/Hooks/logHooks.js b/client/src/Hooks/logHooks.js index 4b8657cbf..b954efb4b 100644 --- a/client/src/Hooks/logHooks.js +++ b/client/src/Hooks/logHooks.js @@ -89,22 +89,26 @@ const useFetchDiagnostics = () => { const [error, setError] = useState(undefined); const [diagnostics, setDiagnostics] = useState(undefined); + const fetchDiagnostics = async () => { + try { + setIsLoading(true); + const response = await networkService.getDiagnostics(); + setDiagnostics(response.data.data); + } catch (error) { + createToast({ + body: error.message, + }); + setError(error); + } finally { + setIsLoading(false); + } + }; + useEffect(() => { - const fetchDiagnostics = async () => { - try { - setIsLoading(true); - const response = await networkService.getDiagnostics(); - setDiagnostics(response.data.data); - } catch (error) { - setError(error); - } finally { - setIsLoading(false); - } - }; fetchDiagnostics(); }, []); - return [diagnostics, isLoading, error]; + return [diagnostics, fetchDiagnostics, isLoading, error]; }; export { useFetchLogs, useFetchQueueData, useFlushQueue, useFetchDiagnostics }; diff --git a/client/src/Pages/Logs/Diagnostics/index.jsx b/client/src/Pages/Logs/Diagnostics/index.jsx index e000c05bc..7c5d1f5a9 100644 --- a/client/src/Pages/Logs/Diagnostics/index.jsx +++ b/client/src/Pages/Logs/Diagnostics/index.jsx @@ -4,9 +4,9 @@ import Typography from "@mui/material/Typography"; import Gauges from "./components/gauges"; import Stats from "./components/stats"; import Divider from "@mui/material/Divider"; +import Button from "@mui/material/Button"; import { useTheme } from "@emotion/react"; -import { useState } from "react"; import { useTranslation } from "react-i18next"; import { useFetchDiagnostics } from "../../../Hooks/logHooks"; @@ -16,7 +16,7 @@ const Diagnostics = () => { // Hooks const theme = useTheme(); const { t } = useTranslation(); - const [diagnostics, isLoading, error] = useFetchDiagnostics(); + const [diagnostics, fetchDiagnostics, isLoading, error] = useFetchDiagnostics(); // Setup return ( @@ -36,6 +36,16 @@ const Diagnostics = () => { diagnostics={diagnostics} isLoading={isLoading} /> + + + ); diff --git a/client/src/Pages/Settings/SettingsTimeZone.jsx b/client/src/Pages/Settings/SettingsTimeZone.jsx index 346e4e546..be255ab52 100644 --- a/client/src/Pages/Settings/SettingsTimeZone.jsx +++ b/client/src/Pages/Settings/SettingsTimeZone.jsx @@ -2,16 +2,37 @@ import Box from "@mui/material/Box"; import Stack from "@mui/material/Stack"; import Typography from "@mui/material/Typography"; import ConfigBox from "../../Components/ConfigBox"; -import Select from "../../Components/Inputs/Select"; +import Search from "../../Components/Inputs/Search"; import timezones from "../../Utils/timezones.json"; // Utils import { useTheme } from "@emotion/react"; import { PropTypes } from "prop-types"; import { useTranslation } from "react-i18next"; +import { useCallback, useMemo, useState } from "react"; const SettingsTimeZone = ({ HEADING_SX, handleChange, timezone }) => { const theme = useTheme(); const { t } = useTranslation(); + const [rawInput, setRawInput] = useState(""); + + const selectedTimezone = useMemo( + () => timezones.find((tz) => tz._id === timezone) ?? null, + [timezone] + ); + + const handleTimezoneChange = useCallback( + (newValue) => { + setRawInput(""); + handleChange({ + target: { + name: "timezone", + value: newValue?._id ?? "", + }, + }); + }, + [handleChange] + ); + return ( @@ -28,12 +49,17 @@ const SettingsTimeZone = ({ HEADING_SX, handleChange, timezone }) => { - setRawInput(newVal)} + handleChange={handleTimezoneChange} + isAdorned={false} + unit="timezone" /> diff --git a/client/src/locales/en.json b/client/src/locales/en.json index 3eedb292b..c36014fb3 100644 --- a/client/src/locales/en.json +++ b/client/src/locales/en.json @@ -229,6 +229,9 @@ "unknownError": "Unknown error" } }, + "general": { + "noOptionsFound": "No {{unit}} found" + }, "commonSave": "Save", "commonSaving": "Saving...", "companyName": "Company name", diff --git a/server/controllers/diagnosticController.js b/server/controllers/diagnosticController.js index 4410a28a5..e5368866a 100755 --- a/server/controllers/diagnosticController.js +++ b/server/controllers/diagnosticController.js @@ -56,12 +56,13 @@ class DiagnosticController { async getCPUUsage() { try { const startUsage = process.cpuUsage(); - await new Promise((resolve) => setTimeout(resolve, 1000)); + const timingPeriod = 1000; // measured in ms + await new Promise((resolve) => setTimeout(resolve, timingPeriod)); const endUsage = process.cpuUsage(startUsage); const cpuUsage = { userUsageMs: endUsage.user / 1000, systemUsageMs: endUsage.system / 1000, - usagePercentage: ((endUsage.user + endUsage.system) / 1000 / 1000) * 100, + usagePercentage: ((endUsage.user + endUsage.system) / 1000 / timingPeriod) * 100, }; return cpuUsage; } catch (error) {