From 64233fa28bcd5d9d3d3e895bf484d9d8414a4fd6 Mon Sep 17 00:00:00 2001 From: Sebastian Barrenechea Date: Thu, 16 May 2024 20:47:48 -0400 Subject: [PATCH 1/6] feat: add board model in about tab --- src/components/skeletons/about.tsx | 1 + src/lib/api/get.ts | 9 +++++---- src/routes/_tabLayout/about.lazy.tsx | 1 + 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/components/skeletons/about.tsx b/src/components/skeletons/about.tsx index 17162f1..8920c03 100644 --- a/src/components/skeletons/about.tsx +++ b/src/components/skeletons/about.tsx @@ -5,6 +5,7 @@ export default function AboutSkeleton() { return (
+
diff --git a/src/lib/api/get.ts b/src/lib/api/get.ts index bb439c8..deb56b2 100644 --- a/src/lib/api/get.ts +++ b/src/lib/api/get.ts @@ -22,12 +22,13 @@ interface PowerTabResponse { } interface AboutTabResponse { - api: string; - build_version: string; - buildroot: string; - buildtime: Date; + model: string; hostname: string; + api: string; version: string; + buildtime: Date; + buildroot: string; + build_version: string; } export interface FlashStatus { diff --git a/src/routes/_tabLayout/about.lazy.tsx b/src/routes/_tabLayout/about.lazy.tsx index c44b51c..fdeb832 100644 --- a/src/routes/_tabLayout/about.lazy.tsx +++ b/src/routes/_tabLayout/about.lazy.tsx @@ -23,6 +23,7 @@ function About() { return (
+ {data.model} {data.hostname} {`v${data.version}`} From 9e6ad9b10aa2c811be2a28bf7d4d25b9e1ec649d Mon Sep 17 00:00:00 2001 From: Sebastian Barrenechea Date: Thu, 23 May 2024 17:36:56 -0400 Subject: [PATCH 2/6] feat: add initial batch flashing support --- package-lock.json | 31 +++++++- package.json | 3 +- src/components/ui/toggle.tsx | 43 ++++++++++ src/contexts/FlashContext.tsx | 13 +-- src/lib/api/file.ts | 7 ++ src/lib/api/get.ts | 3 +- src/routes/_tabLayout/about.lazy.tsx | 4 +- src/routes/_tabLayout/flash-node.lazy.tsx | 97 +++++++++++++++-------- 8 files changed, 156 insertions(+), 45 deletions(-) create mode 100644 src/components/ui/toggle.tsx diff --git a/package-lock.json b/package-lock.json index b3d5f07..029c498 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "bmc-ui", - "version": "3.1.3", + "version": "3.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "bmc-ui", - "version": "3.1.3", + "version": "3.2.0", "dependencies": { "@fontsource/inter": "^5.0.18", "@radix-ui/react-checkbox": "^1.0.4", @@ -17,6 +17,7 @@ "@radix-ui/react-slot": "^1.0.2", "@radix-ui/react-switch": "^1.0.3", "@radix-ui/react-toast": "^1.1.5", + "@radix-ui/react-toggle": "^1.0.3", "@radix-ui/react-tooltip": "^1.0.7", "@tanstack/react-query": "^5.45.0", "@tanstack/react-router": "^1.36.3", @@ -1925,6 +1926,32 @@ } } }, + "node_modules/@radix-ui/react-toggle": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.0.3.tgz", + "integrity": "sha512-Pkqg3+Bc98ftZGsl60CLANXQBBQ4W3mTFS9EJvNxKMZ7magklKV69/id1mlAlOFDDfHvlCms0fx8fA4CMKDJHg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-controllable-state": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-tooltip": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.0.7.tgz", diff --git a/package.json b/package.json index 4bfdd99..ad67aca 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bmc-ui", - "version": "3.1.3", + "version": "3.2.0", "private": true, "type": "module", "scripts": { @@ -21,6 +21,7 @@ "@radix-ui/react-slot": "^1.0.2", "@radix-ui/react-switch": "^1.0.3", "@radix-ui/react-toast": "^1.1.5", + "@radix-ui/react-toggle": "^1.0.3", "@radix-ui/react-tooltip": "^1.0.7", "@tanstack/react-query": "^5.45.0", "@tanstack/react-router": "^1.36.3", diff --git a/src/components/ui/toggle.tsx b/src/components/ui/toggle.tsx new file mode 100644 index 0000000..32768c6 --- /dev/null +++ b/src/components/ui/toggle.tsx @@ -0,0 +1,43 @@ +import { Root } from "@radix-ui/react-toggle"; +import { cva, type VariantProps } from "class-variance-authority"; +import { forwardRef } from "react"; + +import { cn } from "@/lib/utils"; + +const toggleVariants = cva( + "inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-white transition-colors hover:bg-neutral-100 hover:text-neutral-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-neutral-950 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-neutral-100 data-[state=on]:text-neutral-900 dark:ring-offset-neutral-950 dark:hover:bg-neutral-800 dark:hover:text-neutral-400 dark:focus-visible:ring-neutral-300 dark:data-[state=on]:bg-neutral-800 dark:data-[state=on]:text-neutral-50", + { + variants: { + variant: { + default: "bg-transparent", + outline: + "border border-neutral-200 bg-transparent hover:bg-neutral-100 hover:text-neutral-900 dark:border-neutral-800 dark:hover:bg-neutral-800 dark:hover:text-neutral-50", + }, + size: { + default: "h-10 px-3", + sm: "h-9 px-2.5", + lg: "h-11 px-5", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + } +); + +const Toggle = forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & + VariantProps +>(({ className, variant, size, ...props }, ref) => ( + +)); + +Toggle.displayName = Root.displayName; + +export { Toggle }; diff --git a/src/contexts/FlashContext.tsx b/src/contexts/FlashContext.tsx index 80de6ae..f48558d 100644 --- a/src/contexts/FlashContext.tsx +++ b/src/contexts/FlashContext.tsx @@ -40,6 +40,7 @@ interface FlashContextValue { }) => Promise; handleNodeUpdate: (variables: { nodeId: number; + batch?: number[]; file?: File; url?: string; sha256?: string; @@ -133,27 +134,29 @@ export const FlashProvider: React.FC = ({ children }) => { const handleNodeUpdate = async (variables: { nodeId: number; + batch?: number[]; file?: File; url?: string; sha256?: string; skipCRC: boolean; }) => { + const nodeWord = variables.batch?.length ? "nodes" : "node"; setFlashType("node"); setIsUploading(true); - setStatusMessage(`Transferring image to node ${variables.nodeId + 1}...`); + setStatusMessage(`Transferring image to selected ${nodeWord}...`); await nodeUpdateMutation.mutateAsync(variables, { onSuccess: () => { setIsUploading(false); setIsFlashing(true); const msg = variables.skipCRC - ? "Transferring image to the node..." - : "Checking CRC and transferring image to the node..."; + ? `Transferring image to the ${nodeWord}...` + : `Checking CRC and transferring image to the ${nodeWord}...`; setStatusMessage(msg); void flashStatus.refetch(); }, onError: (error) => { setIsUploading(false); - const msg = `Failed to transfer the image to node ${variables.nodeId + 1}`; + const msg = `Failed to transfer the image to selected ${nodeWord}`; setStatusMessage(msg); toast({ title: msg, @@ -203,7 +206,7 @@ export const FlashProvider: React.FC = ({ children }) => { } else if (flashStatus.data?.Done) { handleSuccess( "Flashing successful", - "Image flashed successfully to the node" + "Image flashed successfully to the target node(s)" ); } } diff --git a/src/lib/api/file.ts b/src/lib/api/file.ts index a0a963d..e807e7b 100644 --- a/src/lib/api/file.ts +++ b/src/lib/api/file.ts @@ -10,6 +10,7 @@ const handleParams = (variables: { sha256?: string; skipCRC?: boolean; node?: number; + batch?: number[]; }) => { const params: Record = { opt: "set", @@ -35,6 +36,10 @@ const handleParams = (variables: { params.node = variables.node; } + if (variables.batch !== undefined) { + params.batch = variables.batch.join(","); + } + return params; }; @@ -114,6 +119,7 @@ export function useNodeUpdateMutation( mutationKey: ["nodeUpdateMutation"], mutationFn: async (variables: { nodeId: number; + batch?: number[]; file?: File; url?: string; sha256?: string; @@ -129,6 +135,7 @@ export function useNodeUpdateMutation( params: handleParams({ type: "flash", node: variables.nodeId, + batch: variables.batch, file: variables.file, url: variables.url, skipCRC: variables.skipCRC, diff --git a/src/lib/api/get.ts b/src/lib/api/get.ts index deb56b2..8a2a2aa 100644 --- a/src/lib/api/get.ts +++ b/src/lib/api/get.ts @@ -22,7 +22,8 @@ interface PowerTabResponse { } interface AboutTabResponse { - model: string; + board_model: string; + board_revision: string; hostname: string; api: string; version: string; diff --git a/src/routes/_tabLayout/about.lazy.tsx b/src/routes/_tabLayout/about.lazy.tsx index fdeb832..dd5b899 100644 --- a/src/routes/_tabLayout/about.lazy.tsx +++ b/src/routes/_tabLayout/about.lazy.tsx @@ -23,7 +23,9 @@ function About() { return (
- {data.model} + + {data.board_model} (v{data.board_revision}) + {data.hostname} {`v${data.version}`} diff --git a/src/routes/_tabLayout/flash-node.lazy.tsx b/src/routes/_tabLayout/flash-node.lazy.tsx index 295dc5b..5eea8fb 100644 --- a/src/routes/_tabLayout/flash-node.lazy.tsx +++ b/src/routes/_tabLayout/flash-node.lazy.tsx @@ -1,5 +1,6 @@ import { createLazyFileRoute } from "@tanstack/react-router"; -import { useEffect, useRef, useState } from "react"; +import { Cpu } from "lucide-react"; +import { useEffect, useMemo, useRef, useState } from "react"; import ConfirmationModal from "@/components/ConfirmationModal"; import TabView from "@/components/TabView"; @@ -7,39 +8,37 @@ import { Button } from "@/components/ui/button"; import { Checkbox } from "@/components/ui/checkbox"; import { Input } from "@/components/ui/input"; import { Progress } from "@/components/ui/progress"; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from "@/components/ui/select"; +import { Toggle } from "@/components/ui/toggle"; import { useFlash } from "@/hooks/use-flash"; -import { useToast } from "@/hooks/use-toast"; +import { useAboutTabData } from "@/lib/api/get"; export const Route = createLazyFileRoute("/_tabLayout/flash-node")({ component: FlashNode, }); -interface SelectOption { - value: string; - label: string; -} - -const nodeOptions: SelectOption[] = [ - { value: "0", label: "Node 1" }, - { value: "1", label: "Node 2" }, - { value: "2", label: "Node 3" }, - { value: "3", label: "Node 4" }, +const nodeOptions = [ + { value: 0, label: "Node 1" }, + { value: 1, label: "Node 2" }, + { value: 2, label: "Node 3" }, + { value: 3, label: "Node 4" }, ]; +const isSemverGreaterOrEqual = (a: string, b: string) => { + return a.localeCompare(b, undefined, { numeric: true }) >= 0; +}; + function FlashNode() { - const { toast } = useToast(); + const { data: aboutData } = useAboutTabData(); + const batchFlashingSupport = useMemo( + () => isSemverGreaterOrEqual(aboutData.board_revision, "2.5"), + [aboutData] + ); + + const [selectedNodes, setSelectedNodes] = useState([]); const formRef = useRef(null); const [confirmFlashModal, setConfirmFlashModal] = useState(false); const { flashType, - setFlashType, isFlashing, statusMessage: _statusMessage, nodeUpdateMutation, @@ -58,8 +57,6 @@ function FlashNode() { setConfirmFlashModal(false); const form = formRef.current; - const nodeId = (form.elements.namedItem("node") as HTMLSelectElement) - .selectedOptions[0].value; const file = (form.elements.namedItem("file") as HTMLInputElement) .files?.[0]; const url = (form.elements.namedItem("file-url") as HTMLInputElement) @@ -69,10 +66,13 @@ function FlashNode() { const skipCRC = (form.elements.namedItem("skipCrc") as HTMLInputElement) .checked; - const parsedNodeId = Number.parseInt(nodeId); + // If more than one node is selected, batch flashing is enabled + const batch = + selectedNodes.length > 1 ? selectedNodes.slice(1) : undefined; void handleNodeUpdate({ - nodeId: parsedNodeId, + nodeId: selectedNodes[0], + batch, file, url, sha256, @@ -82,21 +82,48 @@ function FlashNode() { }; return ( - +
- +
+
From 13b8826157887812b8f2f36501161a5205463af6 Mon Sep 17 00:00:00 2001 From: Sebastian Barrenechea Date: Fri, 24 May 2024 16:08:31 -0400 Subject: [PATCH 3/6] chore: flash node skeleton --- src/components/skeletons/flash-node.tsx | 30 +++++++++++++++++++++++ src/routes/_tabLayout/flash-node.lazy.tsx | 2 ++ 2 files changed, 32 insertions(+) create mode 100644 src/components/skeletons/flash-node.tsx diff --git a/src/components/skeletons/flash-node.tsx b/src/components/skeletons/flash-node.tsx new file mode 100644 index 0000000..a040688 --- /dev/null +++ b/src/components/skeletons/flash-node.tsx @@ -0,0 +1,30 @@ +import TabView from "../TabView"; + +export default function FlashNodeSkeleton() { + return ( + +
+
+
+
+
+
+ {Array.from({ length: 4 }).map((_, index) => ( +
+ ))} +
+
+
+
+
+
+
+
+
+
+
+ ); +} diff --git a/src/routes/_tabLayout/flash-node.lazy.tsx b/src/routes/_tabLayout/flash-node.lazy.tsx index 5eea8fb..caf740a 100644 --- a/src/routes/_tabLayout/flash-node.lazy.tsx +++ b/src/routes/_tabLayout/flash-node.lazy.tsx @@ -3,6 +3,7 @@ import { Cpu } from "lucide-react"; import { useEffect, useMemo, useRef, useState } from "react"; import ConfirmationModal from "@/components/ConfirmationModal"; +import FlashNodeSkeleton from "@/components/skeletons/flash-node"; import TabView from "@/components/TabView"; import { Button } from "@/components/ui/button"; import { Checkbox } from "@/components/ui/checkbox"; @@ -14,6 +15,7 @@ import { useAboutTabData } from "@/lib/api/get"; export const Route = createLazyFileRoute("/_tabLayout/flash-node")({ component: FlashNode, + pendingComponent: FlashNodeSkeleton, }); const nodeOptions = [ From 5d4fc0dcc96f5743f89259426d68e0669a836159 Mon Sep 17 00:00:00 2001 From: Sebastian Barrenechea Date: Sat, 13 Jul 2024 08:26:16 -0400 Subject: [PATCH 4/6] fix: i18n keys --- src/locale/de.ts | 23 +++++++++++++++-------- src/locale/en.ts | 21 ++++++++++++++------- src/locale/es.ts | 19 +++++++++++++------ src/locale/nl.ts | 21 +++++++++++++++------ src/locale/pl.ts | 19 +++++++++++++------ src/locale/zh-Hans.ts | 19 +++++++++++++------ src/routes/_tabLayout/about.lazy.tsx | 2 +- 7 files changed, 84 insertions(+), 40 deletions(-) diff --git a/src/locale/de.ts b/src/locale/de.ts index 7468f2f..fce6802 100644 --- a/src/locale/de.ts +++ b/src/locale/de.ts @@ -113,9 +113,12 @@ const translations = { "<0>Um die Aktualisierung abzuschließen, ist ein Systemneustart erforderlich.<1>Möchten Sie jetzt mit dem Neustart fortfahren?<2>Die Knoten verlieren vorübergehend die Stromversorgung, bis der Neustart abgeschlossen ist.", }, flashNode: { - header: - "Installieren Sie ein Betriebssystemabbild auf einem ausgewählten Knoten", - nodeSelect: "Ausgewählter Knoten:", + header_one: + "Installiere ein Betriebssystemabbild auf einem ausgewählten Knoten", + header_other: + "Installiere ein Betriebssystemabbild auf ausgewählten Knoten", + nodeSelect_one: "Ausgewählter Knoten:", + nodeSelect_other: "Ausgewählte Knoten:", fileInput: "Datei (Remote oder lokal):", shaInput: "SHA-256 (optional):", skipCrc: "CRC überspringen", @@ -124,15 +127,19 @@ const translations = { flashModalTitle: "Betriebssystemabbild installieren", flashModalDescription: "Sie sind dabei, ein neues Image auf den ausgewählten Knoten zu überschreiben.", - uploading: "Übertrage Image auf Knoten {{nodeId}}...", - flashing: "Flashe Image auf Knoten {{nodeId}}...", - flashingCrc: "Prüfe CRC und flashe Image auf Knoten {{nodeId}}...", - transferFailed: - "Übertragung des Images auf Knoten {{nodeId}} fehlgeschlagen", + uploading_one: "Übertrage Image auf Knoten...", + uploading_other: "Übertrage Image auf Knoten...", + flashing_one: "Flashe Image auf Knoten...", + flashing_other: "Flashe Image auf Knoten...", + flashingCrc_one: "Prüfe CRC und flashe Image auf Knoten...", + flashingCrc_other: "Prüfe CRC und flashe Image auf Knoten...", + transferFailed_one: "Übertragung des Images auf Knoten fehlgeschlagen", + transferFailed_other: "Übertragung des Images auf Knoten fehlgeschlagen", success: "Flashen erfolgreich", successMessage: "Image erfolgreich auf den Knoten geflasht", }, about: { + boardModel: "Board-Modell", hostname: "Hostname", daemonVersion: "Daemon-Version", buildTime: "Build-Zeit", diff --git a/src/locale/en.ts b/src/locale/en.ts index 0b0ec58..32ac0bb 100644 --- a/src/locale/en.ts +++ b/src/locale/en.ts @@ -108,8 +108,10 @@ const translations = { "<0>To finalize the upgrade, a system reboot is necessary.<1>Would you like to proceed with the reboot now?<2>The nodes will temporarily lose power until the reboot process is completed.", }, flashNode: { - header: "Install an OS image on a selected node", - nodeSelect: "Selected node:", + header_one: "Install an OS image on a selected node", + header_other: "Install an OS image on selected nodes", + nodeSelect_one: "Selected node:", + nodeSelect_other: "Selected nodes:", fileInput: "File (remote or local):", shaInput: "SHA-256 (optional):", skipCrc: "Skip CRC", @@ -118,14 +120,19 @@ const translations = { flashModalTitle: "Install OS Image", flashModalDescription: "You are about to overwrite a new image to the selected node.", - uploading: "Transferring image to node {{nodeId}}...", - flashing: "Flashing image to node {{nodeId}}...", - flashingCrc: "Checking CRC and flashing image to node {{nodeId}}...", - transferFailed: "Failed to transfer the image to node {{nodeId}}", + uploading_one: "Transferring image to node...", + uploading_other: "Transferring image to nodes...", + flashing_one: "Flashing image to node...", + flashing_other: "Flashing image to nodes...", + flashingCrc_one: "Checking CRC and flashing image to node...", + flashingCrc_other: "Checking CRC and flashing image to nodes...", + transferFailed_one: "Failed to transfer the image to node", + transferFailed_other: "Failed to transfer the image to nodes", success: "Flashing successful", - successMessage: "Image flashed successfully to the node", + successMessage: "Image flashed successfully to the node(s)", }, about: { + boardModel: "Board model", hostname: "Hostname", daemonVersion: "Daemon version", buildTime: "Build time", diff --git a/src/locale/es.ts b/src/locale/es.ts index b26c3f3..7ce5939 100644 --- a/src/locale/es.ts +++ b/src/locale/es.ts @@ -111,8 +111,10 @@ const translations = { "<0>Para finalizar la actualización, es necesario reiniciar el sistema.<1>¿Desea proceder con el reinicio ahora?<2>Los nodos perderán energía temporalmente hasta que se complete el proceso de reinicio.", }, flashNode: { - header: "Instalar una imagen de SO en un nodo seleccionado", - nodeSelect: "Nodo seleccionado:", + header_one: "Instalar una imagen de SO en un nodo seleccionado", + header_other: "Instalar una imagen de SO en nodos seleccionados", + nodeSelect_one: "Nodo seleccionado:", + nodeSelect_other: "Nodos seleccionados:", fileInput: "Archivo (remoto o local):", shaInput: "SHA-256 (opcional):", skipCrc: "Omitir CRC", @@ -121,14 +123,19 @@ const translations = { flashModalTitle: "Instalar imagen de SO", flashModalDescription: "Estás a punto de sobrescribir una nueva imagen en el nodo seleccionado.", - uploading: "Subiendo imagen al nodo {{nodeId}}...", - flashing: "Flasheando imagen al nodo {{nodeId}}...", - flashingCrc: "Verificando CRC y flasheando imagen al nodo {{nodeId}}...", - transferFailed: "Error al transferir la imagen al nodo {{nodeId}}", + uploading_one: "Subiendo imagen al nodo...", + uploading_other: "Subiendo imagen a los nodos...", + flashing_one: "Flasheando imagen al nodo...", + flashing_other: "Flasheando imagen a los nodos...", + flashingCrc_one: "Verificando CRC y flasheando imagen al nodo...", + flashingCrc_other: "Verificando CRC y flasheando imagen a los nodos...", + transferFailed_one: "Error al transferir la imagen al nodo", + transferFailed_other: "Error al transferir la imagen a los nodos", success: "Flasheo exitoso", successMessage: "Imagen flasheada con éxito al nodo", }, about: { + boardModel: "Modelo de placa", hostname: "Nombre de host", daemonVersion: "Versión del daemon", buildTime: "Fecha de compilación", diff --git a/src/locale/nl.ts b/src/locale/nl.ts index 4d4e584..2d7937f 100644 --- a/src/locale/nl.ts +++ b/src/locale/nl.ts @@ -110,8 +110,12 @@ const translations = { "<0>Om de upgrade af te ronden, is een herstart van het systeem nodig.<1>Wilt u nu doorgaan met de herstart?<2>De nodes verliezen tijdelijk de stroom totdat het herstartsproces is voltooid.", }, flashNode: { - header: "Installeer een besturingssysteemimage op een geselecteerde node", - nodeSelect: "Geselecteerde node:", + header_one: + "Installeer een besturingssysteemimage op een geselecteerde node", + header_other: + "Installeer een besturingssysteemimage op geselecteerde nodes", + nodeSelect_one: "Geselecteerde node:", + nodeSelect_other: "Geselecteerde nodes:", fileInput: "Bestand (extern of lokaal):", shaInput: "SHA-256 (optioneel):", skipCrc: "CRC overslaan", @@ -120,14 +124,19 @@ const translations = { flashModalTitle: "Besturingssysteemimage installeren", flashModalDescription: "U staat op het punt een nieuw image naar de geselecteerde node te schrijven.", - uploading: "Image overbrengen naar node {{nodeId}}...", - flashing: "Image flashen naar node {{nodeId}}...", - flashingCrc: "CRC controleren en image flashen naar node {{nodeId}}...", - transferFailed: "Overbrengen van image naar node {{nodeId}} mislukt", + uploading_one: "Image overbrengen naar node...", + uploading_other: "Image overbrengen naar nodes...", + flashing_one: "Image flashen naar node...", + flashing_other: "Image flashen naar nodes...", + flashingCrc_one: "CRC controleren en image flashen naar node...", + flashingCrc_other: "CRC controleren en image flashen naar nodes...", + transferFailed_one: "Overbrengen van image naar node mislukt", + transferFailed_other: "Overbrengen van image naar nodes mislukt", success: "Flashen geslaagd", successMessage: "Image succesvol geflasht naar de node", }, about: { + boardModel: "Boardmodel", hostname: "Hostnaam", daemonVersion: "Daemonversie", buildTime: "Buildtijd", diff --git a/src/locale/pl.ts b/src/locale/pl.ts index b472c81..d2f4ffd 100644 --- a/src/locale/pl.ts +++ b/src/locale/pl.ts @@ -111,8 +111,10 @@ const translations = { "<0>Aby sfinalizować aktualizację, wymagany jest restart systemu.<1>Czy chcesz teraz przejść do restartu?<2>Węzły tymczasowo stracą zasilanie do czasu zakończenia procesu restartu.", }, flashNode: { - header: "Zainstaluj obraz systemu operacyjnego na wybranym węźle", - nodeSelect: "Wybrany węzeł:", + header_one: "Zainstaluj obraz systemu operacyjnego na wybranym węźle", + header_other: "Zainstaluj obraz systemu operacyjnego na wybranych węzłach", + nodeSelect_one: "Wybrany węzeł:", + nodeSelect_other: "Wybrane węzły:", fileInput: "Plik (zdalnie lub lokalnie):", shaInput: "SHA-256 (opcjonalnie):", skipCrc: "Pomiń CRC", @@ -120,14 +122,19 @@ const translations = { ariaProgress: "Postęp flashowania", flashModalTitle: "Zainstalować obraz systemu?", flashModalDescription: "Masz zamiar nadpisać nowy obraz na wybranym węźle.", - uploading: "Przesyłanie obrazu do węzła {{nodeId}}...", - flashing: "Flashowanie obrazu do węzła {{nodeId}}...", - flashingCrc: "Sprawdzanie CRC i flashowanie obrazu do węzła {{nodeId}}...", - transferFailed: "Nie udało się przesłać obrazu do węzła {{nodeId}}", + uploading_one: "Przesyłanie obrazu do węzła...", + uploading_other: "Przesyłanie obrazu do węzłów...", + flashing_one: "Flashowanie obrazu do węzła...", + flashing_other: "Flashowanie obrazu do węzłów...", + flashingCrc_one: "Sprawdzanie CRC i flashowanie obrazu do węzła...", + flashingCrc_other: "Sprawdzanie CRC i flashowanie obrazu do węzłów...", + transferFailed_one: "Nie udało się przesłać obrazu do węzła", + transferFailed_other: "Nie udało się przesłać obrazu do węzłów", success: "Flashowanie zakończone pomyślnie", successMessage: "Obraz został pomyślnie sflashowany na węźle", }, about: { + boardModel: "Model płyty", hostname: "Nazwa hosta", daemonVersion: "Wersja demona", buildTime: "Czas kompilacji", diff --git a/src/locale/zh-Hans.ts b/src/locale/zh-Hans.ts index c8cf0f2..937fd25 100644 --- a/src/locale/zh-Hans.ts +++ b/src/locale/zh-Hans.ts @@ -107,8 +107,10 @@ const translations = { "<0>要完成升级,需要重启系统。<1>是否要立即重启?<2>在重启过程完成之前,节点将暂时断电。", }, flashNode: { - header: "在选定的节点上安装操作系统镜像", - nodeSelect: "选定的节点:", + header_one: "在选定的节点上安装操作系统镜像", + header_other: "在选定的多个节点上安装操作系统镜像", + nodeSelect_one: "选定的节点:", + nodeSelect_other: "选定的节点:", fileInput: "文件(远程或本地):", shaInput: "SHA-256(可选):", skipCrc: "跳过 CRC", @@ -116,14 +118,19 @@ const translations = { ariaProgress: "刷写进度", flashModalTitle: "安装操作系统镜像", flashModalDescription: "您即将覆盖选定节点上的新镜像。", - uploading: "正在将镜像传输到节点 {{nodeId}}...", - flashing: "正在将镜像刷写到节点 {{nodeId}}...", - flashingCrc: "正在检查 CRC 并将镜像刷写到节点 {{nodeId}}...", - transferFailed: "将镜像传输到节点 {{nodeId}} 失败", + uploading_one: "正在将镜像传输到节点...", + uploading_other: "正在将镜像传输到多个节点...", + flashing_one: "正在将镜像刷写到节点...", + flashing_other: "正在将镜像刷写到多个节点...", + flashingCrc_one: "正在检查 CRC 并将镜像刷写到节点...", + flashingCrc_other: "正在检查 CRC 并将镜像刷写到多个节点...", + transferFailed_one: "将镜像传输到节点失败", + transferFailed_other: "将镜像传输到多个节点失败", success: "刷写成功", successMessage: "镜像已成功刷写到节点。", }, about: { + boardModel: "主板型号", hostname: "主机名", daemonVersion: "守护进程版本", buildTime: "构建时间", diff --git a/src/routes/_tabLayout/about.lazy.tsx b/src/routes/_tabLayout/about.lazy.tsx index d692ee4..0c24e75 100644 --- a/src/routes/_tabLayout/about.lazy.tsx +++ b/src/routes/_tabLayout/about.lazy.tsx @@ -40,7 +40,7 @@ function About() { return (
- + {data.board_model} (v{data.board_revision}) {data.hostname} From 0b76f7ce7ee01ec883f384b5fb62ca4ba354b12a Mon Sep 17 00:00:00 2001 From: Sebastian Barrenechea Date: Sat, 13 Jul 2024 08:36:19 -0400 Subject: [PATCH 5/6] chore: bump version --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9de6bcc..6a6ed6e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "bmc-ui", - "version": "3.2.0", + "version": "3.3.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "bmc-ui", - "version": "3.2.0", + "version": "3.3.0", "dependencies": { "@fontsource/inter": "^5.0.18", "@radix-ui/react-avatar": "^1.0.4", diff --git a/package.json b/package.json index bfea527..391f165 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bmc-ui", - "version": "3.2.0", + "version": "3.3.0", "private": true, "type": "module", "scripts": { From 9268d82fdba7f85e0f474e9d42c27d91f9f13498 Mon Sep 17 00:00:00 2001 From: Sebastian Barrenechea Date: Thu, 18 Jul 2024 10:45:59 -0400 Subject: [PATCH 6/6] chore: bump version --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6a6ed6e..10faa21 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "bmc-ui", - "version": "3.3.0", + "version": "3.4.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "bmc-ui", - "version": "3.3.0", + "version": "3.4.0", "dependencies": { "@fontsource/inter": "^5.0.18", "@radix-ui/react-avatar": "^1.0.4", diff --git a/package.json b/package.json index 391f165..831d496 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bmc-ui", - "version": "3.3.0", + "version": "3.4.0", "private": true, "type": "module", "scripts": {