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 }) => {
-
diff --git a/client/src/Pages/StatusPage/Create/Components/Tabs/Settings.jsx b/client/src/Pages/StatusPage/Create/Components/Tabs/Settings.jsx
index a1ba117b0..4c2842b71 100644
--- a/client/src/Pages/StatusPage/Create/Components/Tabs/Settings.jsx
+++ b/client/src/Pages/StatusPage/Create/Components/Tabs/Settings.jsx
@@ -4,7 +4,7 @@ import { TabPanel } from "@mui/lab";
import ConfigBox from "../../../../../Components/ConfigBox";
import Checkbox from "../../../../../Components/Inputs/Checkbox";
import TextInput from "../../../../../Components/Inputs/TextInput";
-import Select from "../../../../../Components/Inputs/Select";
+import Search from "../../../../../Components/Inputs/Search";
import ImageUpload from "../../../../../Components/Inputs/ImageUpload";
import ColorPicker from "../../../../../Components/Inputs/ColorPicker";
import Progress from "../Progress";
@@ -14,6 +14,7 @@ import { useTheme } from "@emotion/react";
import timezones from "../../../../../Utils/timezones.json";
import PropTypes from "prop-types";
import { useTranslation } from "react-i18next";
+import { useMemo, useState, useCallback } from "react";
const TabSettings = ({
isCreate,
@@ -28,6 +29,25 @@ const TabSettings = ({
// Utils
const theme = useTheme();
const { t } = useTranslation();
+ const [rawInput, setRawInput] = useState("");
+
+ const selectedTimezone = useMemo(
+ () => timezones.find((tz) => tz._id === form.timezone) ?? null,
+ [form.timezone]
+ );
+
+ const handleTimezoneChange = useCallback(
+ (newValue) => {
+ setRawInput("");
+ handleFormChange({
+ target: {
+ name: "timezone",
+ value: newValue?._id ?? "",
+ },
+ });
+ },
+ [handleFormChange]
+ );
return (
@@ -101,13 +121,17 @@ const TabSettings = ({
-
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) {