From afe513336ce7b62ef363fb107ad7032d1b47705d Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Mon, 19 May 2025 16:45:02 -0500 Subject: [PATCH] fix missing i18n keys (#18309) --- web/public/locales/en/common.json | 4 ++ web/public/locales/en/components/camera.json | 3 + web/public/locales/en/views/configEditor.json | 1 + web/public/locales/en/views/explore.json | 5 +- web/public/locales/en/views/settings.json | 20 ++++++- web/public/locales/en/views/system.json | 1 + .../components/overlay/CameraInfoDialog.tsx | 4 +- .../components/overlay/CreateUserDialog.tsx | 6 +- .../overlay/FaceSelectionDialog.tsx | 4 +- .../overlay/MobileTimelineDrawer.tsx | 6 +- .../components/overlay/RoleChangeDialog.tsx | 2 +- .../components/overlay/SetPasswordDialog.tsx | 4 +- .../overlay/detail/AnnotationSettingsPane.tsx | 4 +- .../overlay/detail/SearchDetailDialog.tsx | 4 +- .../settings/CameraStreamingDialog.tsx | 10 +++- .../settings/ObjectMaskEditPane.tsx | 7 ++- web/src/components/settings/ZoneEditPane.tsx | 58 ++++++++++++------- web/src/pages/ConfigEditor.tsx | 4 +- web/src/pages/FaceLibrary.tsx | 2 +- 19 files changed, 103 insertions(+), 46 deletions(-) diff --git a/web/public/locales/en/common.json b/web/public/locales/en/common.json index 56aa659e6..422e722ca 100644 --- a/web/public/locales/en/common.json +++ b/web/public/locales/en/common.json @@ -78,6 +78,10 @@ "speed": { "mph": "mph", "kph": "kph" + }, + "length": { + "feet": "feet", + "meters": "meters" } }, "label": { diff --git a/web/public/locales/en/components/camera.json b/web/public/locales/en/components/camera.json index 4a1495326..10513a729 100644 --- a/web/public/locales/en/components/camera.json +++ b/web/public/locales/en/components/camera.json @@ -39,8 +39,11 @@ "document": "Read the documentation " } }, + "stream": "Stream", + "placeholder": "Choose a stream", "streamMethod": { "label": "Streaming Method", + "placeholder": "Choose a streaming method", "method": { "noStreaming": { "label": "No Streaming", diff --git a/web/public/locales/en/views/configEditor.json b/web/public/locales/en/views/configEditor.json index 8d319bbc2..ef3035f38 100644 --- a/web/public/locales/en/views/configEditor.json +++ b/web/public/locales/en/views/configEditor.json @@ -4,6 +4,7 @@ "copyConfig": "Copy Config", "saveAndRestart": "Save & Restart", "saveOnly": "Save Only", + "confirm": "Exit without saving?", "toast": { "success": { "copyToClipboard": "Config copied to clipboard." diff --git a/web/public/locales/en/views/explore.json b/web/public/locales/en/views/explore.json index 4837835e5..7e2381445 100644 --- a/web/public/locales/en/views/explore.json +++ b/web/public/locales/en/views/explore.json @@ -75,7 +75,10 @@ "desc": "This data comes from your camera's detect feed but is overlayed on images from the the record feed. It is unlikely that the two streams are perfectly in sync. As a result, the bounding box and the footage will not line up perfectly. However, the annotation_offset field can be used to adjust this.", "documentation": "Read the documentation ", "millisecondsToOffset": "Milliseconds to offset detect annotations by. Default: 0", - "tips": "TIP: Imagine there is an event clip with a person walking from left to right. If the event timeline bounding box is consistently to the left of the person then the value should be decreased. Similarly, if a person is walking from left to right and the bounding box is consistently ahead of the person then the value should be increased." + "tips": "TIP: Imagine there is an event clip with a person walking from left to right. If the event timeline bounding box is consistently to the left of the person then the value should be decreased. Similarly, if a person is walking from left to right and the bounding box is consistently ahead of the person then the value should be increased.", + "toast": { + "success": "Annotation offset for {{camera}} has been saved to the config file. Restart Frigate to apply your changes." + } } }, "carousel": { diff --git a/web/public/locales/en/views/settings.json b/web/public/locales/en/views/settings.json index 7b604cc6e..21e316cb9 100644 --- a/web/public/locales/en/views/settings.json +++ b/web/public/locales/en/views/settings.json @@ -219,6 +219,11 @@ "mustBeGreaterOrEqualZero": "Loitering time must be greater than or equal to 0." } }, + "speed": { + "error": { + "mustBeGreaterOrEqualTo": "Speed threshold must greater than or equal to 0.1." + } + }, "polygonDrawing": { "removeLastPoint": "Remove last point", "reset": { @@ -271,7 +276,11 @@ "speedEstimation": { "title": "Speed Estimation", "desc": "Enable speed estimation for objects in this zone. The zone must have exactly 4 points.", - "docs": "Read the documentation" + "docs": "Read the documentation", + "lineADistance": "Line A distance ({{unit}})", + "lineBDistance": "Line B distance ({{unit}})", + "lineCDistance": "Line C distance ({{unit}})", + "lineDDistance": "Line D distance ({{unit}})" }, "speedThreshold": { "title": "Speed Threshold ({{unit}})", @@ -473,12 +482,14 @@ "placeholder": "Re-enter new password" } }, - "usernameIsRequired": "Username is required" + "usernameIsRequired": "Username is required", + "passwordIsRequired": "Password is required" }, "createUser": { "title": "Create New User", "desc": "Add a new user account and specify an role for access to areas of the Frigate UI.", - "usernameOnlyInclude": "Username may only include letters, numbers, . or _" + "usernameOnlyInclude": "Username may only include letters, numbers, . or _", + "confirmPassword": "Please confirm your password" }, "deleteUser": { "title": "Delete User", @@ -486,12 +497,15 @@ "warn": "Are you sure you want to delete {{username}}?" }, "passwordSetting": { + "cannotBeEmpty": "Password cannot be empty", + "doNotMatch": "Passwords do not match", "updatePassword": "Update Password for {{username}}", "setPassword": "Set Password", "desc": "Create a strong password to secure this account." }, "changeRole": { "title": "Change User Role", + "select": "Select a role", "desc": "Update permissions for {{username}}", "roleInfo": { "intro": "Select the appropriate role for this user:", diff --git a/web/public/locales/en/views/system.json b/web/public/locales/en/views/system.json index 2750d14a9..059f05f9f 100644 --- a/web/public/locales/en/views/system.json +++ b/web/public/locales/en/views/system.json @@ -108,6 +108,7 @@ "title": "Cameras", "overview": "Overview", "info": { + "aspectRatio": "aspect ratio", "cameraProbeInfo": "{{camera}} Camera Probe Info", "streamDataFromFFPROBE": "Stream data is obtained with ffprobe.", "fetching": "Fetching Camera Data", diff --git a/web/src/components/overlay/CameraInfoDialog.tsx b/web/src/components/overlay/CameraInfoDialog.tsx index 6ff2570a4..ce03bd8e2 100644 --- a/web/src/components/overlay/CameraInfoDialog.tsx +++ b/web/src/components/overlay/CameraInfoDialog.tsx @@ -132,14 +132,14 @@ export default function CameraInfoDialog({ / {codec.height / gcd(codec.width, codec.height)}{" "} - aspect ratio) + {t("cameras.info.aspectRatio")}) ) : ( {t("cameras.info.resolution")}{" "} - Unknown + t("cameras.info.unknown") )} diff --git a/web/src/components/overlay/CreateUserDialog.tsx b/web/src/components/overlay/CreateUserDialog.tsx index 7f81fc792..b73ba6b8f 100644 --- a/web/src/components/overlay/CreateUserDialog.tsx +++ b/web/src/components/overlay/CreateUserDialog.tsx @@ -56,8 +56,10 @@ export default function CreateUserDialog({ .regex(/^[A-Za-z0-9._]+$/, { message: t("users.dialog.createUser.usernameOnlyInclude"), }), - password: z.string().min(1, "Password is required"), - confirmPassword: z.string().min(1, "Please confirm your password"), + password: z.string().min(1, t("users.dialog.form.passwordIsRequired")), + confirmPassword: z + .string() + .min(1, t("users.dialog.createUser.confirmPassword")), role: z.enum(["admin", "viewer"]), }) .refine((data) => data.password === data.confirmPassword, { diff --git a/web/src/components/overlay/FaceSelectionDialog.tsx b/web/src/components/overlay/FaceSelectionDialog.tsx index 8dd92e00d..85595a597 100644 --- a/web/src/components/overlay/FaceSelectionDialog.tsx +++ b/web/src/components/overlay/FaceSelectionDialog.tsx @@ -79,8 +79,8 @@ export default function FaceSelectionDialog({ > {isMobile && ( - Log Details - Log details + Details + Details )} {t("trainFaceAs")} diff --git a/web/src/components/overlay/MobileTimelineDrawer.tsx b/web/src/components/overlay/MobileTimelineDrawer.tsx index 0e8aa9127..ed71f8a23 100644 --- a/web/src/components/overlay/MobileTimelineDrawer.tsx +++ b/web/src/components/overlay/MobileTimelineDrawer.tsx @@ -4,6 +4,7 @@ import { Button } from "../ui/button"; import { FaFlag } from "react-icons/fa"; import { TimelineType } from "@/types/timeline"; import { isMobile } from "react-device-detect"; +import { useTranslation } from "react-i18next"; type MobileTimelineDrawerProps = { selected: TimelineType; @@ -13,6 +14,7 @@ export default function MobileTimelineDrawer({ selected, onSelect, }: MobileTimelineDrawerProps) { + const { t } = useTranslation(["views/events"]); const [drawer, setDrawer] = useState(false); if (!isMobile) { @@ -38,7 +40,7 @@ export default function MobileTimelineDrawer({ setDrawer(false); }} > - Timeline + {t("timeline")}
- Events + {t("events.label")}
diff --git a/web/src/components/overlay/RoleChangeDialog.tsx b/web/src/components/overlay/RoleChangeDialog.tsx index c63152398..ed9e73436 100644 --- a/web/src/components/overlay/RoleChangeDialog.tsx +++ b/web/src/components/overlay/RoleChangeDialog.tsx @@ -83,7 +83,7 @@ export default function RoleChangeDialog({ } > - + diff --git a/web/src/components/overlay/SetPasswordDialog.tsx b/web/src/components/overlay/SetPasswordDialog.tsx index 317048144..05aff4cdf 100644 --- a/web/src/components/overlay/SetPasswordDialog.tsx +++ b/web/src/components/overlay/SetPasswordDialog.tsx @@ -66,12 +66,12 @@ export default function SetPasswordDialog({ const handleSave = () => { if (!password) { - setError("Password cannot be empty"); + setError(t("users.dialog.passwordSetting.cannotBeEmpty")); return; } if (password !== confirmPassword) { - setError("Passwords do not match"); + setError(t("users.dialog.passwordSetting.doNotMatch")); return; } diff --git a/web/src/components/overlay/detail/AnnotationSettingsPane.tsx b/web/src/components/overlay/detail/AnnotationSettingsPane.tsx index 55680d405..682c0379d 100644 --- a/web/src/components/overlay/detail/AnnotationSettingsPane.tsx +++ b/web/src/components/overlay/detail/AnnotationSettingsPane.tsx @@ -77,7 +77,9 @@ export function AnnotationSettingsPane({ .then((res) => { if (res.status === 200) { toast.success( - `Annotation offset for ${event?.camera} has been saved to the config file. Restart Frigate to apply your changes.`, + t("objectLifecycle.annotationSettings.offset.toast.success", { + camera: event?.camera, + }), { position: "top-center", }, diff --git a/web/src/components/overlay/detail/SearchDetailDialog.tsx b/web/src/components/overlay/detail/SearchDetailDialog.tsx index b6e1b0a14..28ef5c45b 100644 --- a/web/src/components/overlay/detail/SearchDetailDialog.tsx +++ b/web/src/components/overlay/detail/SearchDetailDialog.tsx @@ -909,7 +909,9 @@ function ObjectDetailsTab({ search.label, )) ? ( <> -
Description
+
+ {t("details.description.label")} +
diff --git a/web/src/components/settings/CameraStreamingDialog.tsx b/web/src/components/settings/CameraStreamingDialog.tsx index 0aae164e8..eabb77bb5 100644 --- a/web/src/components/settings/CameraStreamingDialog.tsx +++ b/web/src/components/settings/CameraStreamingDialog.tsx @@ -240,11 +240,13 @@ export function CameraStreamingDialog({ Object.entries(config?.cameras[camera].live.streams).length > 0 && (
( - Line B distance ( - {config?.ui.unit_system == "imperial" - ? "feet" - : "meters"} - ) + {t( + "masksAndZones.zones.speedEstimation.lineBDistance", + { + unit: + config?.ui.unit_system == "imperial" + ? t("feet", { ns: "common" }) + : t("meters", { ns: "common" }), + }, + )} ( - Line C distance ( - {config?.ui.unit_system == "imperial" - ? "feet" - : "meters"} - ) + {t( + "masksAndZones.zones.speedEstimation.lineCDistance", + { + unit: + config?.ui.unit_system == "imperial" + ? t("feet", { ns: "common" }) + : t("meters", { ns: "common" }), + }, + )} ( - Line D distance ( - {config?.ui.unit_system == "imperial" - ? "feet" - : "meters"} - ) + {t( + "masksAndZones.zones.speedEstimation.lineDDistance", + { + unit: + config?.ui.unit_system == "imperial" + ? t("feet", { ns: "common" }) + : t("meters", { ns: "common" }), + }, + )} { e.preventDefault(); e.returnValue = true; - return "Exit without saving?"; + return t("confirm"); }; window.addEventListener("beforeunload", listener); } @@ -207,7 +207,7 @@ function ConfigEditor() { window.removeEventListener("beforeunload", listener); } }; - }, [hasChanges]); + }, [hasChanges, t]); if (!config) { return ; diff --git a/web/src/pages/FaceLibrary.tsx b/web/src/pages/FaceLibrary.tsx index 7c59eba23..387bf5a5f 100644 --- a/web/src/pages/FaceLibrary.tsx +++ b/web/src/pages/FaceLibrary.tsx @@ -1044,7 +1044,7 @@ function FaceGrid({ return (
- No faces available + (t("nofaces"))
); }