From 9237f46e7ca91f00c665d73941b376272650e474 Mon Sep 17 00:00:00 2001 From: Shemy Gan Date: Thu, 7 Nov 2024 15:26:22 -0500 Subject: [PATCH] - handle Validation onBlur , special cases for usage numbers required on condition of checkbox checked - handle generate payload correspondant to BE format - comment out retain log period,retry max and 3 other usage threshold currently not avalable yet in BE --- .../CreateMonitor/index.jsx | 267 ++++++++++-------- Client/src/Validation/error.js | 4 + Client/src/Validation/validation.js | 16 +- 3 files changed, 168 insertions(+), 119 deletions(-) diff --git a/Client/src/Pages/InfrastructureMonitors/CreateMonitor/index.jsx b/Client/src/Pages/InfrastructureMonitors/CreateMonitor/index.jsx index 02f4ae853..1997e3714 100644 --- a/Client/src/Pages/InfrastructureMonitors/CreateMonitor/index.jsx +++ b/Client/src/Pages/InfrastructureMonitors/CreateMonitor/index.jsx @@ -16,21 +16,40 @@ import Field from "../../../Components/Inputs/Field"; import Select from "../../../Components/Inputs/Select"; import Checkbox from "../../../Components/Inputs/Checkbox"; import Breadcrumbs from "../../../Components/Breadcrumbs"; +import { buildErrors, hasValidationErrors } from "../../../Validation/error"; const CreateInfrastructureMonitor = () => { + const [infrastructureMonitor, setInfrastructureMonitor] = useState({ + url: "", + name: "", + notifications: [], + interval: 1, + cpu: false, + usage_cpu: "", + secret: "", + }); + + const MS_PER_MINUTE = 60000; + const { user, authToken } = useSelector((state) => state.auth); + const monitorState = useSelector((state) => state.infrastructureMonitor); + const dispatch = useDispatch(); + const navigate = useNavigate(); + const theme = useTheme(); + + const idMap = { + "notify-email-default": "notification-email", + }; + + const [errors, setErrors] = useState({}); + const CustomAlertStack = ({ checkboxId, checkboxLabel, - checkboxValue, - isChecked, - onChange, fieldId, - fieldValue, alertUnit, - }) => { - console.log("fieldValue") - console.log(fieldValue) - return ( + onChange, + onBlur, + }) => ( { { type="number" className="field-infrastructure-alert" id={fieldId} - value={fieldValue} + value={infrastructureMonitor[fieldId]} + onBlur={onBlur} + onChange={onChange} + error={errors[`${fieldId}`]} + disabled={!infrastructureMonitor[checkboxId]} > { - );} + ); - const MS_PER_MINUTE = 60000; - const { user, authToken } = useSelector((state) => state.auth); - const monitorState = useSelector((state) => state.infrastructureMonitor); - const dispatch = useDispatch(); - const navigate = useNavigate(); - const theme = useTheme(); - - const idMap = { - "monitor-url": "url", - "monitor-name": "name", - "monitor-secret": "secret", - "notify-email-default": "notification-email", + const handleCustomAlertCheckChange = (event) => { + const { value, id } = event.target; + setInfrastructureMonitor((prev) => { + const newState = { + [id]: prev[id] == undefined && value == "on" ? true : !prev[id], + }; + return { + ...prev, + ...newState, + [`usage_${id}`]: newState[id] ? prev[`usage_${id}`] : "", + }; + }); + // Remove the error if unchecked + setErrors((prev) => { + return buildErrors(prev, [`usage_${id}`]); + }); }; - const [infrastructureMonitor, setInfrastructureMonitor] = useState({ - url: "", - name: "", - notifications: [], - interval: 1, - threshold: {cpu: "", disk: "", memory: ""} - }); - const [errors, setErrors] = useState({}); - - const handleChange = (event, name) => { + const handleBlur = (event) => { const { value, id } = event.target; - if (!name) name = idMap[id]; + const { error } = infrastractureMonitorValidation.validate( + { [id]: value }, + { + abortEarly: false, + } + ); + setErrors((prev) => { + return buildErrors(prev, id, error); + }); + }; + + const handleChange = (event, appendedId) => { + event.preventDefault(); + const { value, id } = event.target; + let name = appendedId ?? idMap[id] ?? id; if (name.includes("notification-")) { name = name.replace("notification-", ""); @@ -126,67 +157,59 @@ const CreateInfrastructureMonitor = () => { ...prev, [name]: value, })); - - const { error } = infrastractureMonitorValidation.validate( - { [name]: value }, - { abortEarly: false } - ); - console.log(error); - setErrors((prev) => { - const updatedErrors = { ...prev }; - if (error) updatedErrors[name] = error.details[0].message; - else delete updatedErrors[name]; - return updatedErrors; - }); } }; + const generatePayload = (form) => { + let thresholds = {}; + thresholds.usage_cpu = form.usage_cpu; + thresholds.usage_memory = form.usage_memory; + thresholds.usage_disk = form.usage_disk; + + delete form.cpu; + delete form.memory; + delete form.disk; + + delete form.usage_cpu; + delete form.usage_memory; + delete form.usage_disk; + form = { + ...form, + description: form.name, + teamId: user.teamId, + userId: user._id, + type: "hardware", + notifications: infrastructureMonitor.notifications, + thresholds, + }; + return form; + }; const handleCreateInfrastructureMonitor = async (event) => { event.preventDefault(); - //obj to submit let form = { - url:infrastructureMonitor.url, + ...infrastructureMonitor, name: infrastructureMonitor.name === "" ? infrastructureMonitor.url : infrastructureMonitor.name, interval: infrastructureMonitor.interval * MS_PER_MINUTE, }; - - const { error } =infrastractureMonitorValidation.validate(form, { - abortEarly: false, - }); - - if (error) { - const newErrors = {}; - error.details.forEach((err) => { - newErrors[err.path[0]] = err.message; - }); - setErrors(newErrors); - createToast({ body: "Error validation data." }); + delete form.notifications; + if (hasValidationErrors(form, infrastractureMonitorValidation, setErrors)) { + return; } else { - if (infrastructureMonitor.type === "http") { - const checkEndpointAction = await dispatch( - checkInfrastructureEndpointResolution({ authToken, monitorURL: form.url }) - ); - if (checkEndpointAction.meta.requestStatus === "rejected") { - createToast({ - body: "The endpoint you entered doesn't resolve. Check the URL again.", - }); - setErrors({ url: "The entered URL is not reachable." }); - return; - } + const checkEndpointAction = await dispatch( + checkInfrastructureEndpointResolution({ authToken, monitorURL: form.url }) + ); + if (checkEndpointAction.meta.requestStatus === "rejected") { + createToast({ + body: "The endpoint you entered doesn't resolve. Check the URL again.", + }); + setErrors({ url: "The entered URL is not reachable." }); + return; } - - form = { - ...form, - description: form.name, - teamId: user.teamId, - userId: user._id, - notifications: infrastructureMonitor.notifications, - }; const action = await dispatch( - createInfrastructureMonitor({ authToken, monitor: form }) + createInfrastructureMonitor({ authToken, monitor: generatePayload(form) }) ); if (action.meta.requestStatus === "fulfilled") { createToast({ body: "Infrastructure monitor created successfully!" }); @@ -199,12 +222,12 @@ const CreateInfrastructureMonitor = () => { //select values const frequencies = [ - { _id: 1, name: "15 seconds" }, - { _id: 2, name: "30 seconds" }, - { _id: 3, name: "1 minute" }, - { _id: 4, name: "2 minutes" }, - { _id: 5, name: "5 minutes" }, - { _id: 6, name: "10 minutes" }, + { _id: 15, name: "15 seconds" }, + { _id: 30, name: "30 seconds" }, + { _id: 60, name: "1 minute" }, + { _id: 120, name: "2 minutes" }, + { _id: 300, name: "5 minutes" }, + { _id: 600, name: "10 minutes" }, ]; return ( @@ -252,28 +275,31 @@ const CreateInfrastructureMonitor = () => { @@ -295,7 +321,8 @@ const CreateInfrastructureMonitor = () => { (notification) => notification.type === "email" )} value={user?.email} - onChange={(event) => handleChange(event)} + onChange={(e) => handleChange(e)} + onBlur={handleBlur} /> { isChecked={false} value="" onChange={() => logger.warn("disabled")} + onBlur={handleBlur} isDisabled={true} /> @@ -312,6 +340,7 @@ const CreateInfrastructureMonitor = () => { placeholder="name@gmail.com" value="" onChange={() => logger.warn("disabled")} + onBlur={handleBlur} /> You can separate multiple emails with a comma @@ -330,51 +359,57 @@ const CreateInfrastructureMonitor = () => { handleChange(event)} + fieldValue={infrastructureMonitor.usage_cpu ?? ""} + onChange={handleChange} + onBlur={handleBlur} alertUnit="%" /> - handleChange(event)} + fieldValue={infrastructureMonitor.usage_memory??""} + onChange={handleChange} + onBlur={handleBlur} alertUnit="%" /> handleChange(event)} + fieldValue={infrastructureMonitor.usage_disk??""} + onChange={handleChange} + onBlur={handleBlur} alertUnit="%" - /> + /> */} {/* handleChange(event)} + onChange={handleChange} + onBlur={handleBlur} alertUnit="°C" /> handleChange(event)} + onChange={handleChange} + onBlur={handleBlur} alertUnit="%" /> handleChange(event)} + checkboxValue={""} + onChange={handleChange} + onBlur={handleBlur} alertUnit="%" /> */} @@ -393,7 +428,8 @@ const CreateInfrastructureMonitor = () => { checkboxLabel="Retain data for" checkboxValue={""} fieldId={"retries_max"} - onChange={(event) => handleChange(event)} + onChange={handleChange} + onBlur={handleBlur} alertUnit="days" /> */} @@ -404,20 +440,22 @@ const CreateInfrastructureMonitor = () => {