Path: blob/master/docker/dd-extension/ui/src/components/Snapshot.tsx
1091 views
import type React from "react";1import { useCallback, useEffect, useState } from "react";2import { Button, Col, Row } from "react-bootstrap";3import Form from "react-bootstrap/Form";4import { openBrowserUrl } from "../helpers";5import { useDockerDesktopClient } from "../hooks/useDockerDesktopClient";6import Loader from "./Loader";7import ShowCommand from "./ShowCommand";8import Uninstall from "./Uninstall";9import Update from "./Update";1011const countryOptions = [12{ value: "", label: "Select country" },13{ value: "Global", label: "Global" },14{ value: "egypt", label: "Egypt" },15{ value: "germany", label: "Germany" },16{ value: "japan", label: "Japan" },17{ value: "korea", label: "Korea" },18{ value: "thailand", label: "Thailand" },19{ value: "uae", label: "United Arab Emirates" },20];2122const architectureOptionsSnapshot = [23{ value: "alpr", label: "Intel x86 or amd64(x64)" },24{ value: "alpr-no-avx", label: "Intel x86 or amd64(x64) no-avx" },25{ value: "alpr-gpu", label: "Intel x86 or amd64(x64) with Nvidia GPU" },26{ value: "alpr-arm", label: "ARM based CPUs, Raspberry Pi or Apple M1" },27{ value: "alpr-jetson", label: "Nvidia Jetson (with GPU) for Jetpack 4.6 (r32)" },28{ value: "alpr-jetson:r35", label: "Nvidia Jetson (with GPU) for Jetpack 5.x (r35)" },29{ value: "alpr-zcu104", label: "ZCU" },30];3132export default function Snapshot() {33const [licenseKey, setLicenseKey] = useState("");34const [token, setToken] = useState("");35const [tokenValidated, setTokenValidated] = useState(false);36const [isLoading, setLoading] = useState(false);3738const [command, setCommand] = useState<string>("");39const [curlPort, setCurlPort] = useState("8080");40const [dockerimage, setDockerimage] = useState("");41const [country, setCountry] = useState("Global");42const [architecture, setArchitecture] = useState("alpr");43const [restartPolicy, setRestartPolicy] = useState("no");4445const ddClient = useDockerDesktopClient();4647const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {48setTokenValidated(false);49const { name, value } = e.target;50if (name === "license") {51setLicenseKey(value);52} else if (name === "token") {53setToken(value);54} else if (name === "port") {55setCurlPort(value);56} else if (name === "restart-policy") {57setRestartPolicy(value);58}59};6061const handleArchitectureChange = (e: React.ChangeEvent<HTMLSelectElement>) => {62setTokenValidated(false);63setArchitecture(e.target.value);64};6566const generateDockerImage = useCallback(() => {67let dockerImage = "platerecognizer/";68if (69country === "Global" ||70architecture === "alpr-jetson:r35" ||71architecture === "alpr-no-avx"72) {73dockerImage += `${architecture}`;74} else {75dockerImage += `${architecture}:${country}`;76}77setDockerimage(dockerImage);78return dockerImage;79}, [country, architecture]);8081const generateDockerRunCommand = useCallback(82(dockerImage: string) => {83let restartOption: string;84switch (restartPolicy) {85case "no":86restartOption = "";87break;88default:89restartOption = `--restart=${restartPolicy} `;90break;91}92const baseCommand = `docker run ${restartOption}-t -p ${curlPort}:8080 -v license:/license`;93let platformSpecificCommand = "";9495switch (architecture) {96case "alpr-jetson":97case "alpr-jetson:r35":98platformSpecificCommand = ` --runtime nvidia -e LICENSE_KEY=${licenseKey} -e TOKEN=${token} ${dockerImage}`;99break;100case "alpr-gpu":101platformSpecificCommand = ` --gpus all -e LICENSE_KEY=${licenseKey} -e TOKEN=${token} ${dockerImage}`;102break;103case "alpr":104case "alpr-no-avx":105case "alpr-arm":106case "alpr-zcu104":107platformSpecificCommand = ` -e LICENSE_KEY=${licenseKey} -e TOKEN=${token} ${dockerImage}`;108break;109default:110break;111}112113setCommand(`${baseCommand} ${platformSpecificCommand}`);114},115[restartPolicy, curlPort, architecture, licenseKey, token],116);117118useEffect(() => {119const imagem = generateDockerImage();120generateDockerRunCommand(imagem);121}, [generateDockerImage, generateDockerRunCommand]);122123// Load any existing data from local storage on component mount124useEffect(() => {125const storedData = localStorage.getItem("snapshot");126if (storedData) {127const snapshotData = JSON.parse(storedData);128setToken(snapshotData?.token);129setLicenseKey(snapshotData?.license);130setRestartPolicy(snapshotData?.restartPolicy);131setCurlPort(snapshotData?.curlPort);132setCountry(snapshotData?.country);133setArchitecture(snapshotData?.architecture);134}135}, []);136137const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {138event.preventDefault();139const form: HTMLFormElement = event.currentTarget;140const formData = new FormData(form);141142const data: any = Object.fromEntries(formData.entries());143// console.log(data);144setLoading(true);145146ddClient.extension.vm?.service?.post("/verify-token", data).then((res: any) => {147console.debug(res);148const valid = res.valid;149const message = res.message;150if (valid) {151localStorage.setItem(152"snapshot",153JSON.stringify({154token: token,155license: licenseKey,156restartPolicy: restartPolicy,157curlPort: curlPort,158country: country,159architecture: architecture,160}),161);162// Pull image and update163ddClient.docker.cli.exec("pull", [dockerimage]).then((result) => {164console.debug(result);165setTokenValidated(valid);166setLoading(false);167});168} else {169setLoading(false);170ddClient.desktopUI.toast.error(`Verify Token: ${message}`);171}172});173};174const handleCountryChange = (e: any) => {175setTokenValidated(false);176setCountry(e.target.value);177};178const handleLinkClick = (e: React.MouseEvent<HTMLAnchorElement>) => {179e.preventDefault();180openBrowserUrl(ddClient, e.currentTarget.href);181};182return (183<Form onSubmit={handleSubmit}>184<Form.Group as={Row} className="mb-3" controlId="snapshotToken">185<Form.Label column sm={4}>186Please enter your Plate Recognizer{" "}187<a188href="https://app.platerecognizer.com/service/snapshot-sdk/"189onClick={handleLinkClick}190>191API Token192</a>193:194</Form.Label>195<Col sm={8}>196<Form.Control197type="text"198placeholder="Token"199required200name="token"201value={token}202onChange={handleInputChange}203/>204</Col>205</Form.Group>206207<Form.Group as={Row} className="mb-3" controlId="snapshotLicense">208<Form.Label column sm={4}>209Please enter your{" "}210<a211href="https://app.platerecognizer.com/service/snapshot-sdk/"212onClick={handleLinkClick}213>214Snapshot License Key215</a>216:217</Form.Label>218<Col sm={8}>219<Form.Control220type="text"221placeholder="License Key"222required223value={licenseKey}224name="license"225onChange={handleInputChange}226/>227</Col>228</Form.Group>229230<Form.Group as={Row} className="mb-3">231<Form.Label column sm={4}>232Restart policy233</Form.Label>234<Col sm={8} className="mt-2 d-flex justify-content-between">235<Form.Check236type="radio"237name="restart-policy"238label="No (Docker Default)"239id="rps1"240value="no"241checked={restartPolicy === "no"}242onChange={handleInputChange}243/>244<Form.Check245type="radio"246name="restart-policy"247label="Unless Stopped"248id="rps2"249value="unless-stopped"250checked={restartPolicy === "unless-stopped"}251onChange={handleInputChange}252/>253<Form.Check254type="radio"255name="restart-policy"256label="Always"257id="rps3"258value="always"259checked={restartPolicy === "always"}260onChange={handleInputChange}261/>262<Form.Check263type="radio"264name="restart-policy"265label="On Failure"266id="rps4"267value="on-failure"268checked={restartPolicy === "on-failure"}269onChange={handleInputChange}270/>271</Col>272</Form.Group>273274<Form.Group as={Row} className="mb-3" controlId="snapshotPort">275<Form.Label column sm={4}>276Set the container port (default is 8080):277</Form.Label>278<Col sm={8}>279<Form.Control280type="number"281min="0"282max="65535"283placeholder="Port"284name="port"285required286value={curlPort}287onChange={handleInputChange}288/>289</Col>290</Form.Group>291292<Form.Group as={Row} className="mb-3" controlId="snapshotDockerImage">293<Form.Label column sm={4}>294Docker image to use:295</Form.Label>296<Col sm={3}>297<Form.Select298aria-label="Snapshot Docker Image Country"299onChange={handleCountryChange}300name="country"301defaultValue={country}302disabled={303architecture === "alpr-jetson:r35" || architecture === "alpr-no-avx"304}305>306{countryOptions.map(({ value, label }) => (307<option key={label} value={value}>308{label}309</option>310))}311</Form.Select>312</Col>313<Col sm={5}>314<Form.Select315aria-label="Snapshot Docker Image"316onChange={handleArchitectureChange}317name="image"318defaultValue={architecture}319>320{architectureOptionsSnapshot.map(({ value, label }) => (321<option key={value} value={value}>322{label}323</option>324))}325</Form.Select>326</Col>327</Form.Group>328329<ShowCommand curlPort={curlPort} command={command} validated={tokenValidated} />330331<Form.Group as={Row} className="mb-3">332<div className="col-2">333<Button className="btn btn-primary" type="submit" id="validateSnapshotBtn">334<Loader isLoading={isLoading} />335Show Docker Command336</Button>337</div>338<label339className="col-auto align-self-center form-label"340htmlFor="validateSnapshotBtn"341>342Confirm settings and show docker command.343</label>344</Form.Group>345346<Update isEnabled={true} image={dockerimage} />347<Uninstall isEnabled={true} image={dockerimage} />348</Form>349);350}351352353