From fbc802ccc42880b90b06e3fa33f6fa0bc2a67656 Mon Sep 17 00:00:00 2001 From: YouQam Date: Wed, 11 Oct 2023 14:58:35 +0200 Subject: [PATCH 1/8] mqtt check url connection --- .../account.mydevices.$boxId.edit.mqtt.tsx | 115 ++++++++++++++++-- package.json | 1 + 2 files changed, 105 insertions(+), 11 deletions(-) diff --git a/app/routes/account.mydevices.$boxId.edit.mqtt.tsx b/app/routes/account.mydevices.$boxId.edit.mqtt.tsx index fb28b5a3..81f075c7 100644 --- a/app/routes/account.mydevices.$boxId.edit.mqtt.tsx +++ b/app/routes/account.mydevices.$boxId.edit.mqtt.tsx @@ -1,14 +1,16 @@ import type { ActionFunctionArgs, LoaderFunctionArgs } from "@remix-run/node"; -import { redirect } from "@remix-run/node"; -import { Form } from "@remix-run/react"; +import { json, redirect } from "@remix-run/node"; +import { Form, useActionData } from "@remix-run/react"; import { getUserId } from "~/session.server"; import { Save } from "lucide-react"; import { Checkbox } from "@/components/ui/checkbox"; -import { useState } from "react"; +import React, { useState } from "react"; import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"; import { Label } from "@/components/ui/label"; import ErrorMessage from "~/components/error-message"; +import * as mqtt from "mqtt/dist/mqtt.min"; + //***************************************************** export async function loader({ request, params }: LoaderFunctionArgs) { //* if user is not logged in, redirect to home @@ -20,12 +22,79 @@ export async function loader({ request, params }: LoaderFunctionArgs) { //***************************************************** export async function action({ request, params }: ActionFunctionArgs) { - return ""; + console.log("actions"); + + const formData = await request.formData(); + const { enableMQTTcb, mqqtURL, mqqtTopic } = Object.fromEntries(formData); + + //* ToDo: if mqtt checkbox is not enabled, reset mqtt to default + if (!enableMQTTcb) { + return json({ + errors: { + mqqtURL: null, + mqqtTopic: null, + reset: true, + }, + status: 200, + }); + } + + const errors = { + mqqtURL: mqqtURL ? null : "Invalid URL (please use ws or wss URL)", + mqqtTopic: mqqtTopic ? null : "Invalid mqqt topic", + reset: false, + }; + + return json({ + errors, + status: 200, + }); } //********************************** export default function EditBoxMQTT() { - const [mqttVal, setMqttVal] = useState(false); + const [mqttEnabled, setMqttEnabled] = useState(false); + const [mqttURL, setMqttURL] = useState(""); + const [mqttValid, setMqttValid] = useState(true); + const actionData = useActionData(); + + const mqqtURLRef = React.useRef(null); + const mqqtTopicRef = React.useRef(null); + + React.useEffect(() => { + if (actionData) { + const hasErrors = Object.values(actionData?.errors).some( + (errorMessage) => errorMessage, + ); + + // ToDo + if (actionData.errors.reset) { + // Do nothing for now + } else if (!hasErrors) { + let isValidURL = false; + const client = mqtt + .connectAsync(mqttURL) + // .connectAsync("wss://broker.emqx.io:8084/mqtt") + .then((e) => { + isValidURL = true; + }); + + setTimeout(() => { + if (isValidURL) { + console.log("🚀 MQTT URL is valid"); + } else { + console.log("🚀 MQTT URL is not valid"); + setMqttValid(false); + mqqtURLRef.current?.focus(); + } + }, 1000); + } else if (hasErrors && actionData?.errors?.mqqtURL) { + mqqtURLRef.current?.focus(); + } else if (hasErrors && actionData?.errors?.mqqtTopic) { + mqqtTopicRef.current?.focus(); + } + } + }, [actionData]); return (
@@ -43,6 +112,7 @@ export default function EditBoxMQTT() {
{/* Save button */}
@@ -126,8 +213,15 @@ export default function EditBoxMQTT() { autoFocus={true} name="mqqtTopic" type="text" + ref={mqqtTopicRef} className="w-full rounded border border-gray-200 px-2 py-1 text-base disabled:cursor-not-allowed disabled:bg-[#eee]" + disabled={!mqttEnabled} /> + {actionData?.errors?.mqqtTopic && ( +
+ {actionData.errors.mqqtTopic} +
+ )}
@@ -142,7 +236,7 @@ export default function EditBoxMQTT() {
@@ -173,7 +267,7 @@ export default function EditBoxMQTT() { name="mqqtDecode" type="text" className="w-full rounded border border-gray-200 px-2 py-1 text-base disabled:cursor-not-allowed disabled:bg-[#eee]" - disabled={!mqttVal} + disabled={!mqttEnabled} />
@@ -193,7 +287,7 @@ export default function EditBoxMQTT() { name="mqqtConn" type="text" className="w-full rounded border border-gray-200 px-2 py-1 text-base disabled:cursor-not-allowed disabled:bg-[#eee]" - disabled={!mqttVal} + disabled={!mqttEnabled} /> @@ -211,4 +305,3 @@ export function ErrorBoundary() { ); } - diff --git a/package.json b/package.json index 8b47557e..279c5431 100644 --- a/package.json +++ b/package.json @@ -90,6 +90,7 @@ "lucide-react": "^0.263.1", "mapbox-gl": "^2.14.1", "morgan": "^1.10.0", + "mqtt": "^5.1.2", "postcss-import": "^15.1.0", "prom-client": "^14.1.1", "react": "^18.2.0", From f9cf17c04fee5460661f3fa4448677dc648df4a9 Mon Sep 17 00:00:00 2001 From: YouQam Date: Wed, 11 Oct 2023 15:17:47 +0200 Subject: [PATCH 2/8] some updates --- .../account.mydevices.$boxId.edit.mqtt.tsx | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/app/routes/account.mydevices.$boxId.edit.mqtt.tsx b/app/routes/account.mydevices.$boxId.edit.mqtt.tsx index 81f075c7..affca0fe 100644 --- a/app/routes/account.mydevices.$boxId.edit.mqtt.tsx +++ b/app/routes/account.mydevices.$boxId.edit.mqtt.tsx @@ -1,6 +1,6 @@ import type { ActionFunctionArgs, LoaderFunctionArgs } from "@remix-run/node"; import { json, redirect } from "@remix-run/node"; -import { Form, useActionData } from "@remix-run/react"; +import { Form, useActionData, useOutletContext } from "@remix-run/react"; import { getUserId } from "~/session.server"; import { Save } from "lucide-react"; import { Checkbox } from "@/components/ui/checkbox"; @@ -27,7 +27,7 @@ export async function action({ request, params }: ActionFunctionArgs) { const formData = await request.formData(); const { enableMQTTcb, mqqtURL, mqqtTopic } = Object.fromEntries(formData); - //* ToDo: if mqtt checkbox is not enabled, reset mqtt to default + //* ToDo: if mqtt checkbox is not enabled, reset mqtt to default if (!enableMQTTcb) { return json({ errors: { @@ -61,6 +61,9 @@ export default function EditBoxMQTT() { const mqqtURLRef = React.useRef(null); const mqqtTopicRef = React.useRef(null); + //* to view toast on edit page + const [setToastOpen] = useOutletContext<[(_open: boolean) => void]>(); + React.useEffect(() => { if (actionData) { const hasErrors = Object.values(actionData?.errors).some( @@ -72,7 +75,9 @@ export default function EditBoxMQTT() { // Do nothing for now } else if (!hasErrors) { let isValidURL = false; - const client = mqtt + + //* check mqtt url connection + mqtt .connectAsync(mqttURL) // .connectAsync("wss://broker.emqx.io:8084/mqtt") .then((e) => { @@ -82,6 +87,9 @@ export default function EditBoxMQTT() { setTimeout(() => { if (isValidURL) { console.log("🚀 MQTT URL is valid"); + setMqttValid(true); + //* if qmtt url is valid, show success msg + setToastOpen(true); } else { console.log("🚀 MQTT URL is not valid"); setMqttValid(false); @@ -94,7 +102,7 @@ export default function EditBoxMQTT() { mqqtTopicRef.current?.focus(); } } - }, [actionData]); + }, [actionData, mqttURL, setToastOpen]); return (
@@ -191,7 +199,8 @@ export default function EditBoxMQTT() { {!mqttValid && (
- Entered mqtt url is not valid, please try again with a valid one. + Entered mqtt url is not valid, please try again with a valid + one.
)}
From 914cf5687f48847f51fa0aea7066f2b005f0e7b4 Mon Sep 17 00:00:00 2001 From: YouQam Date: Wed, 11 Oct 2023 16:00:02 +0200 Subject: [PATCH 3/8] show success msg after connection with mqtt url --- app/routes/account.mydevices.$boxId.edit.mqtt.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/app/routes/account.mydevices.$boxId.edit.mqtt.tsx b/app/routes/account.mydevices.$boxId.edit.mqtt.tsx index affca0fe..e375b542 100644 --- a/app/routes/account.mydevices.$boxId.edit.mqtt.tsx +++ b/app/routes/account.mydevices.$boxId.edit.mqtt.tsx @@ -1,6 +1,6 @@ import type { ActionFunctionArgs, LoaderFunctionArgs } from "@remix-run/node"; import { json, redirect } from "@remix-run/node"; -import { Form, useActionData, useOutletContext } from "@remix-run/react"; +import { Form, useActionData } from "@remix-run/react"; import { getUserId } from "~/session.server"; import { Save } from "lucide-react"; import { Checkbox } from "@/components/ui/checkbox"; @@ -10,6 +10,7 @@ import { Label } from "@/components/ui/label"; import ErrorMessage from "~/components/error-message"; import * as mqtt from "mqtt/dist/mqtt.min"; +import { toast } from "~/components/ui/use-toast"; //***************************************************** export async function loader({ request, params }: LoaderFunctionArgs) { @@ -61,9 +62,6 @@ export default function EditBoxMQTT() { const mqqtURLRef = React.useRef(null); const mqqtTopicRef = React.useRef(null); - //* to view toast on edit page - const [setToastOpen] = useOutletContext<[(_open: boolean) => void]>(); - React.useEffect(() => { if (actionData) { const hasErrors = Object.values(actionData?.errors).some( @@ -88,8 +86,10 @@ export default function EditBoxMQTT() { if (isValidURL) { console.log("🚀 MQTT URL is valid"); setMqttValid(true); - //* if qmtt url is valid, show success msg - setToastOpen(true); + //* if qmtt url is valid, show conn. success msg + toast({ + description: "Successfully connected to mqtt url!", + }); } else { console.log("🚀 MQTT URL is not valid"); setMqttValid(false); @@ -102,7 +102,7 @@ export default function EditBoxMQTT() { mqqtTopicRef.current?.focus(); } } - }, [actionData, mqttURL, setToastOpen]); + }, [actionData, mqttURL]); return (
From c96f0cd21f04d34afa78c9de9813cc6865ccb545 Mon Sep 17 00:00:00 2001 From: YouQam Date: Thu, 12 Oct 2023 17:24:55 +0200 Subject: [PATCH 4/8] update getting mqtt url value --- app/routes/account.mydevices.$boxId.edit.mqtt.tsx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/app/routes/account.mydevices.$boxId.edit.mqtt.tsx b/app/routes/account.mydevices.$boxId.edit.mqtt.tsx index e375b542..6941bc53 100644 --- a/app/routes/account.mydevices.$boxId.edit.mqtt.tsx +++ b/app/routes/account.mydevices.$boxId.edit.mqtt.tsx @@ -36,6 +36,7 @@ export async function action({ request, params }: ActionFunctionArgs) { mqqtTopic: null, reset: true, }, + mqttURL: mqqtURL, status: 200, }); } @@ -48,6 +49,7 @@ export async function action({ request, params }: ActionFunctionArgs) { return json({ errors, + mqttURL: mqqtURL, status: 200, }); } @@ -55,7 +57,6 @@ export async function action({ request, params }: ActionFunctionArgs) { //********************************** export default function EditBoxMQTT() { const [mqttEnabled, setMqttEnabled] = useState(false); - const [mqttURL, setMqttURL] = useState(""); const [mqttValid, setMqttValid] = useState(true); const actionData = useActionData(); @@ -76,7 +77,7 @@ export default function EditBoxMQTT() { //* check mqtt url connection mqtt - .connectAsync(mqttURL) + .connectAsync(actionData.mqttURL.toString()) // .connectAsync("wss://broker.emqx.io:8084/mqtt") .then((e) => { isValidURL = true; @@ -102,7 +103,7 @@ export default function EditBoxMQTT() { mqqtTopicRef.current?.focus(); } } - }, [actionData, mqttURL]); + }, [actionData]); return (
@@ -188,8 +189,6 @@ export default function EditBoxMQTT() { ref={mqqtURLRef} className="w-full rounded border border-gray-200 px-2 py-1 text-base disabled:cursor-not-allowed disabled:bg-[#eee]" disabled={!mqttEnabled} - value={mqttURL} - onChange={(e) => setMqttURL(e.target.value)} /> {actionData?.errors?.mqqtURL && (
From 5aad872d6ffb9b2fed776a899ca88d6bf47cb2fc Mon Sep 17 00:00:00 2001 From: YouQam Date: Fri, 13 Oct 2023 12:23:20 +0200 Subject: [PATCH 5/8] update mqtt naming --- .../account.mydevices.$boxId.edit.mqtt.tsx | 70 +++++++++---------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/app/routes/account.mydevices.$boxId.edit.mqtt.tsx b/app/routes/account.mydevices.$boxId.edit.mqtt.tsx index 6941bc53..a381f9c7 100644 --- a/app/routes/account.mydevices.$boxId.edit.mqtt.tsx +++ b/app/routes/account.mydevices.$boxId.edit.mqtt.tsx @@ -26,30 +26,30 @@ export async function action({ request, params }: ActionFunctionArgs) { console.log("actions"); const formData = await request.formData(); - const { enableMQTTcb, mqqtURL, mqqtTopic } = Object.fromEntries(formData); + const { enableMQTTcb, mqttURL, mqttTopic } = Object.fromEntries(formData); //* ToDo: if mqtt checkbox is not enabled, reset mqtt to default if (!enableMQTTcb) { return json({ errors: { - mqqtURL: null, - mqqtTopic: null, + mqttURL: null, + mqttTopic: null, reset: true, }, - mqttURL: mqqtURL, + mqttURL: mqttURL, status: 200, }); } const errors = { - mqqtURL: mqqtURL ? null : "Invalid URL (please use ws or wss URL)", - mqqtTopic: mqqtTopic ? null : "Invalid mqqt topic", + mqttURL: mqttURL ? null : "Invalid URL (please use ws or wss URL)", + mqttTopic: mqttTopic ? null : "Invalid mqtt topic", reset: false, }; return json({ errors, - mqttURL: mqqtURL, + mqttURL: mqttURL, status: 200, }); } @@ -60,8 +60,8 @@ export default function EditBoxMQTT() { const [mqttValid, setMqttValid] = useState(true); const actionData = useActionData(); - const mqqtURLRef = React.useRef(null); - const mqqtTopicRef = React.useRef(null); + const mqttURLRef = React.useRef(null); + const mqttTopicRef = React.useRef(null); React.useEffect(() => { if (actionData) { @@ -94,13 +94,13 @@ export default function EditBoxMQTT() { } else { console.log("🚀 MQTT URL is not valid"); setMqttValid(false); - mqqtURLRef.current?.focus(); + mqttURLRef.current?.focus(); } }, 1000); - } else if (hasErrors && actionData?.errors?.mqqtURL) { - mqqtURLRef.current?.focus(); - } else if (hasErrors && actionData?.errors?.mqqtTopic) { - mqqtTopicRef.current?.focus(); + } else if (hasErrors && actionData?.errors?.mqttURL) { + mqttURLRef.current?.focus(); + } else if (hasErrors && actionData?.errors?.mqttTopic) { + mqttTopicRef.current?.focus(); } } }, [actionData]); @@ -181,23 +181,23 @@ export default function EditBoxMQTT() {
- {actionData?.errors?.mqqtURL && ( -
- {actionData.errors.mqqtURL} + {actionData?.errors?.mqttURL && ( +
+ {actionData.errors.mqttURL}
)} {!mqttValid && ( -
+
Entered mqtt url is not valid, please try again with a valid one.
@@ -208,7 +208,7 @@ export default function EditBoxMQTT() { {/* MQTT Topic */}