From dc1b14dfd93ea6c36b11646cedf9954d988ce309 Mon Sep 17 00:00:00 2001 From: Bram Suurd <78373894+BramSuurdje@users.noreply.github.com> Date: Sat, 23 Nov 2024 08:14:22 +0100 Subject: [PATCH] Enhance InstallMethod component: add operating system selection and version handling with new input structure (#426) --- .../json-editor/_components/InstallMethod.tsx | 189 ++++++++++-------- frontend/src/config/siteConfig.tsx | 20 +- frontend/src/lib/types.ts | 10 + 3 files changed, 138 insertions(+), 81 deletions(-) diff --git a/frontend/src/app/json-editor/_components/InstallMethod.tsx b/frontend/src/app/json-editor/_components/InstallMethod.tsx index 9a0a035b..6cf6813c 100644 --- a/frontend/src/app/json-editor/_components/InstallMethod.tsx +++ b/frontend/src/app/json-editor/_components/InstallMethod.tsx @@ -1,4 +1,5 @@ import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; import { Select, SelectContent, @@ -6,11 +7,11 @@ import { SelectTrigger, SelectValue, } from "@/components/ui/select"; +import { OperatingSystems } from "@/config/siteConfig"; import { PlusCircle, Trash2 } from "lucide-react"; -import { Input } from "@/components/ui/input"; +import { memo, useCallback, useEffect, useRef } from "react"; import { z } from "zod"; import { InstallMethodSchema, ScriptSchema } from "../_schemas/schemas"; -import { memo, useCallback } from "react"; type Script = z.infer; @@ -27,6 +28,10 @@ function InstallMethod({ setIsValid, setZodErrors, }: InstallMethodProps) { + const cpuRefs = useRef<(HTMLInputElement | null)[]>([]); + const ramRefs = useRef<(HTMLInputElement | null)[]>([]); + const hddRefs = useRef<(HTMLInputElement | null)[]>([]); + const addInstallMethod = useCallback(() => { setScript((prev) => { const method = InstallMethodSchema.parse({ @@ -47,71 +52,62 @@ function InstallMethod({ }); }, [setScript]); - const updateInstallMethod = useCallback(( - index: number, - key: keyof Script["install_methods"][number], - value: Script["install_methods"][number][keyof Script["install_methods"][number]], - ) => { - setScript((prev) => { - const updatedMethods = prev.install_methods.map((method, i) => { - if (i === index) { - const updatedMethod = { ...method, [key]: value }; + const updateInstallMethod = useCallback( + ( + index: number, + key: keyof Script["install_methods"][number], + value: Script["install_methods"][number][keyof Script["install_methods"][number]], + ) => { + setScript((prev) => { + const updatedMethods = prev.install_methods.map((method, i) => { + if (i === index) { + const updatedMethod = { ...method, [key]: value }; - if (key === "type") { - updatedMethod.script = - value === "alpine" - ? `/${prev.type}/alpine-${prev.slug}.sh` - : `/${prev.type}/${prev.slug}.sh`; + if (key === "type") { + updatedMethod.script = + value === "alpine" + ? `/${prev.type}/alpine-${prev.slug}.sh` + : `/${prev.type}/${prev.slug}.sh`; + + // Set OS to Alpine and reset version if type is alpine + if (value === "alpine") { + updatedMethod.resources.os = "Alpine"; + updatedMethod.resources.version = null; + } + } + + return updatedMethod; } + return method; + }); - return updatedMethod; + const updated = { + ...prev, + install_methods: updatedMethods, + }; + + const result = ScriptSchema.safeParse(updated); + setIsValid(result.success); + if (!result.success) { + setZodErrors(result.error); + } else { + setZodErrors(null); } - return method; + return updated; }); + }, + [setScript, setIsValid, setZodErrors], + ); - const updated = { + const removeInstallMethod = useCallback( + (index: number) => { + setScript((prev) => ({ ...prev, - install_methods: updatedMethods, - }; - - const result = ScriptSchema.safeParse(updated); - setIsValid(result.success); - if (!result.success) { - setZodErrors(result.error); - } else { - setZodErrors(null); - } - return updated; - }); - }, [setScript, setIsValid, setZodErrors]); - - const removeInstallMethod = useCallback((index: number) => { - setScript((prev) => ({ - ...prev, - install_methods: prev.install_methods.filter((_, i) => i !== index), - })); - }, [setScript]); - - const ResourceInput = memo(({ - placeholder, - value, - onChange, - type = "text" - }: { - placeholder: string; - value: string | number | null; - onChange: (e: React.ChangeEvent) => void; - type?: string; - }) => ( - - )); - - ResourceInput.displayName = 'ResourceInput'; + install_methods: prev.install_methods.filter((_, i) => i !== index), + })); + }, + [setScript], + ); return ( <> @@ -131,10 +127,13 @@ function InstallMethod({
- { + cpuRefs.current[index] = el; + }} placeholder="CPU in Cores" type="number" - value={method.resources.cpu} + value={method.resources.cpu || ""} onChange={(e) => updateInstallMethod(index, "resources", { ...method.resources, @@ -142,10 +141,13 @@ function InstallMethod({ }) } /> - { + ramRefs.current[index] = el; + }} placeholder="RAM in MB" type="number" - value={method.resources.ram} + value={method.resources.ram || ""} onChange={(e) => updateInstallMethod(index, "resources", { ...method.resources, @@ -153,10 +155,13 @@ function InstallMethod({ }) } /> - { + hddRefs.current[index] = el; + }} + placeholder="HDD in GB" type="number" - value={method.resources.hdd} + value={method.resources.hdd || ""} onChange={(e) => updateInstallMethod(index, "resources", { ...method.resources, @@ -166,27 +171,51 @@ function InstallMethod({ />
- + +