From 7f6887d8b258f0265c3af438a93bbda43d39c545 Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Wed, 28 Jan 2026 11:00:41 -0600 Subject: [PATCH] tweaks --- .../theme/templates/FieldTemplate.tsx | 4 ++-- .../theme/templates/ObjectFieldTemplate.tsx | 21 ++++++++++++++----- web/src/views/settings/CameraConfigView.tsx | 7 ------- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/web/src/components/config-form/theme/templates/FieldTemplate.tsx b/web/src/components/config-form/theme/templates/FieldTemplate.tsx index 4270374a6..a4af19f4e 100644 --- a/web/src/components/config-form/theme/templates/FieldTemplate.tsx +++ b/web/src/components/config-form/theme/templates/FieldTemplate.tsx @@ -106,7 +106,7 @@ export function FieldTemplate(props: FieldTemplateProps) { return (
) : ( <> + {children} {finalDescription && !isMultiSchemaWrapper && !isObjectField && (

{finalDescription}

)} - {children} )} diff --git a/web/src/components/config-form/theme/templates/ObjectFieldTemplate.tsx b/web/src/components/config-form/theme/templates/ObjectFieldTemplate.tsx index 4d504d4ef..d77d8dccd 100644 --- a/web/src/components/config-form/theme/templates/ObjectFieldTemplate.tsx +++ b/web/src/components/config-form/theme/templates/ObjectFieldTemplate.tsx @@ -12,6 +12,14 @@ import { LuChevronDown, LuChevronRight } from "react-icons/lu"; import { useTranslation } from "react-i18next"; import { cn } from "@/lib/utils"; +/** + * Build the i18n translation key path for nested fields using the field path + * provided by RJSF. This avoids ambiguity with underscores in field names. + */ +function buildTranslationPath(path: Array): string { + return path.filter((segment) => typeof segment === "string").join("."); +} + export function ObjectFieldTemplate(props: ObjectFieldTemplateProps) { const { title, description, properties, uiSchema, registry, schema } = props; type FormContext = { i18nNamespace?: string }; @@ -45,13 +53,16 @@ export function ObjectFieldTemplate(props: ObjectFieldTemplateProps) { const toTitle = (value: string) => value.replace(/_/g, " ").replace(/\b\w/g, (char) => char.toUpperCase()); - // Get the property name from the field path (e.g., "alerts" from path) + // Get the full translation path from the field path const fieldPathId = ( props as { fieldPathId?: { path?: (string | number)[] } } ).fieldPathId; let propertyName: string | undefined; + let translationPath: string | undefined; const path = fieldPathId?.path; if (path) { + translationPath = buildTranslationPath(path); + // Also get the last property name for fallback label generation for (let i = path.length - 1; i >= 0; i -= 1) { const segment = path[i]; if (typeof segment === "string") { @@ -65,8 +76,8 @@ export function ObjectFieldTemplate(props: ObjectFieldTemplateProps) { const i18nNs = formContext?.i18nNamespace; let inferredLabel: string | undefined; - if (i18nNs && propertyName) { - const translated = t(`${propertyName}.label`, { + if (i18nNs && translationPath) { + const translated = t(`${translationPath}.label`, { ns: i18nNs, defaultValue: "", }); @@ -78,8 +89,8 @@ export function ObjectFieldTemplate(props: ObjectFieldTemplateProps) { inferredLabel = inferredLabel ?? fallbackLabel; let inferredDescription: string | undefined; - if (i18nNs && propertyName) { - const translated = t(`${propertyName}.description`, { + if (i18nNs && translationPath) { + const translated = t(`${translationPath}.description`, { ns: i18nNs, defaultValue: "", }); diff --git a/web/src/views/settings/CameraConfigView.tsx b/web/src/views/settings/CameraConfigView.tsx index b770d02a6..a9d34621f 100644 --- a/web/src/views/settings/CameraConfigView.tsx +++ b/web/src/views/settings/CameraConfigView.tsx @@ -21,7 +21,6 @@ import { LprSection } from "@/components/config-form/sections/LprSection"; import { NotificationsSection } from "@/components/config-form/sections/NotificationsSection"; import { OnvifSection } from "@/components/config-form/sections/OnvifSection"; import { LiveSection } from "@/components/config-form/sections/LiveSection"; -import { SemanticSearchSection } from "@/components/config-form/sections/SemanticSearchSection"; import { TimestampSection } from "@/components/config-form/sections/TimestampSection"; import { useAllCameraOverrides } from "@/hooks/use-config-override"; import type { FrigateConfig } from "@/types/frigateConfig"; @@ -291,12 +290,6 @@ const CameraConfigContent = memo(function CameraConfigContent({ component: LprSection, showOverrideIndicator: true, }, - { - key: "semantic_search", - i18nNamespace: "config/semantic_search", - component: SemanticSearchSection, - showOverrideIndicator: false, - }, { key: "mqtt", i18nNamespace: "config/camera_mqtt",