diff --git a/web/public/locales/en/objects.json b/web/public/locales/en/objects.json index 1315104be..fc02ed0f5 100644 --- a/web/public/locales/en/objects.json +++ b/web/public/locales/en/objects.json @@ -121,5 +121,9 @@ "royal_mail": "Royal Mail", "school_bus": "School Bus", "skunk": "Skunk", - "kangaroo": "Kangaroo" -} + "kangaroo": "Kangaroo", + "baby": "Baby", + "baby_stroller": "Baby Stroller", + "rickshaw": "Rickshaw", + "Rodent": "Rodent" +} \ No newline at end of file diff --git a/web/public/locales/en/views/settings.json b/web/public/locales/en/views/settings.json index 5f534cf37..b47b6ba39 100644 --- a/web/public/locales/en/views/settings.json +++ b/web/public/locales/en/views/settings.json @@ -1490,8 +1490,8 @@ "genaiRoles": { "options": { "embeddings": "Embedding", - "vision": "Vision", - "tools": "Tools" + "descriptions": "Descriptions", + "chat": "Chat" } }, "semanticSearchModel": { @@ -1643,10 +1643,60 @@ "hardwareAuto": "Automatic hardware acceleration" } }, + "birdseye": { + "trackingMode": { + "objects": "Objects", + "motion": "Motion", + "continuous": "Continuous" + } + }, + "snapshot": { + "retainMode": { + "all": "All", + "motion": "Motion", + "active_objects": "Active Objects" + } + }, + "ui": { + "timeFormat": { + "browser": "Browser", + "12hour": "12 hour", + "24hour": "24 hour" + }, + "TimeOrDateStyle": { + "full": "Full", + "long": "Long", + "medium": "Medium", + "short": "Short" + }, + "unitSystem": { + "metric": "Metric", + "imperial": "Imperial" + } + }, + "review": { + "imageSource": { + "recordings": "Recordings", + "previews": "Previews" + } + }, + "logger": { + "logLevel": { + "debug": "Debug", + "info": "Info", + "warning": "Warning", + "error": "Error", + "critical": "Critical" + } + }, "onvif": { "profileAuto": "Auto", "profileLoading": "Loading profiles..." }, + "modelSize": { + "small": "Small", + "large": "Large" + }, "configMessages": { "review": { "recordDisabled": "Recording is disabled, review items will not be generated.", @@ -1694,4 +1744,4 @@ "jinav2SmallModelSize": "The 'small' size with the Jina V2 model has high RAM and inference cost. The 'large' model with a discrete GPU is recommended." } } -} +} \ No newline at end of file diff --git a/web/src/components/config-form/section-configs/birdseye.ts b/web/src/components/config-form/section-configs/birdseye.ts index d621c9203..26e3d2ec8 100644 --- a/web/src/components/config-form/section-configs/birdseye.ts +++ b/web/src/components/config-form/section-configs/birdseye.ts @@ -22,6 +22,14 @@ const birdseye: SectionConfigOverrides = { hiddenFields: [], advancedFields: [], overrideFields: ["enabled", "mode"], + uiSchema: { + mode: { + "ui:size": "xs", + "ui:options": { + enumI18nPrefix: "birdseye.trackingMode", + }, + }, + }, }, global: { fieldOrder: [ diff --git a/web/src/components/config-form/section-configs/logger.ts b/web/src/components/config-form/section-configs/logger.ts index 8100ee4c1..d70b48aae 100644 --- a/web/src/components/config-form/section-configs/logger.ts +++ b/web/src/components/config-form/section-configs/logger.ts @@ -6,6 +6,16 @@ const logger: SectionConfigOverrides = { restartRequired: ["default", "logs"], fieldOrder: ["default", "logs"], advancedFields: ["logs"], + uiSchema: { + default: { + "ui:options": { enumI18nPrefix: "logger.logLevel" }, + }, + logs: { + additionalProperties: { + "ui:options": { enumI18nPrefix: "logger.logLevel" }, + }, + }, + }, }, }; diff --git a/web/src/components/config-form/section-configs/lpr.ts b/web/src/components/config-form/section-configs/lpr.ts index 8df2d7d8b..5d2a91179 100644 --- a/web/src/components/config-form/section-configs/lpr.ts +++ b/web/src/components/config-form/section-configs/lpr.ts @@ -94,7 +94,7 @@ const lpr: SectionConfigOverrides = { }, }, model_size: { - "ui:options": { size: "xs" }, + "ui:options": { size: "xs", enumI18nPrefix: "modelSize" }, }, }, }, diff --git a/web/src/components/config-form/section-configs/review.ts b/web/src/components/config-form/section-configs/review.ts index 9d6e5e1e8..294a438e4 100644 --- a/web/src/components/config-form/section-configs/review.ts +++ b/web/src/components/config-form/section-configs/review.ts @@ -130,6 +130,11 @@ const review: SectionConfigOverrides = { size: "full", }, }, + image_source: { + "ui:options": { + enumI18nPrefix: "review.imageSource", + }, + }, }, }, }, diff --git a/web/src/components/config-form/section-configs/semantic_search.ts b/web/src/components/config-form/section-configs/semantic_search.ts index f464e637f..884401b7d 100644 --- a/web/src/components/config-form/section-configs/semantic_search.ts +++ b/web/src/components/config-form/section-configs/semantic_search.ts @@ -34,6 +34,9 @@ const semanticSearch: SectionConfigOverrides = { model: { "ui:widget": "semanticSearchModel", }, + model_size: { + "ui:options": { size: "xs", enumI18nPrefix: "modelSize" }, + }, }, }, }; diff --git a/web/src/components/config-form/section-configs/snapshots.ts b/web/src/components/config-form/section-configs/snapshots.ts index 7d08cc728..48d6fe92a 100644 --- a/web/src/components/config-form/section-configs/snapshots.ts +++ b/web/src/components/config-form/section-configs/snapshots.ts @@ -35,6 +35,11 @@ const snapshots: SectionConfigOverrides = { suppressMultiSchema: true, }, }, + "retain.mode": { + "ui:options": { + enumI18nPrefix: "snapshot.retainMode", + }, + }, }, }, global: { diff --git a/web/src/components/config-form/section-configs/ui.ts b/web/src/components/config-form/section-configs/ui.ts index 2de77d879..bb1a50c24 100644 --- a/web/src/components/config-form/section-configs/ui.ts +++ b/web/src/components/config-form/section-configs/ui.ts @@ -23,6 +23,18 @@ const ui: SectionConfigOverrides = { timezone: { "ui:widget": "timezoneSelect", }, + time_format: { + "ui:options": { enumI18nPrefix: "ui.timeFormat" }, + }, + date_style: { + "ui:options": { enumI18nPrefix: "ui.TimeOrDateStyle" }, + }, + time_style: { + "ui:options": { enumI18nPrefix: "ui.TimeOrDateStyle" }, + }, + unit_system: { + "ui:options": { enumI18nPrefix: "ui.unitSystem" }, + }, }, }, }; diff --git a/web/src/components/config-form/theme/fields/DictAsYamlField.tsx b/web/src/components/config-form/theme/fields/DictAsYamlField.tsx index ff1145cfc..75c834385 100644 --- a/web/src/components/config-form/theme/fields/DictAsYamlField.tsx +++ b/web/src/components/config-form/theme/fields/DictAsYamlField.tsx @@ -3,6 +3,8 @@ import yaml from "js-yaml"; import { Textarea } from "@/components/ui/textarea"; import { cn } from "@/lib/utils"; import { useCallback, useEffect, useMemo, useRef, useState } from "react"; +import { ConfigFormContext } from "@/types/configForm"; +import { useTranslation } from "react-i18next"; function formatYaml(value: unknown): string { if ( @@ -45,8 +47,14 @@ function parseYaml(text: string): { } export function DictAsYamlField(props: FieldProps) { - const { formData, onChange, readonly, disabled, idSchema, schema } = props; - + const { formData, onChange, readonly, disabled, idSchema, schema, registry } = + props; + const formContext = registry.formContext as ConfigFormContext | undefined; + const configNamespace = + formContext?.i18nNamespace ?? + (formContext?.level === "camera" ? "config/cameras" : "config/global"); + const { t: fallbackT } = useTranslation(["common", configNamespace]); + const t = formContext?.t ?? fallbackT; const emptyPath = useMemo(() => [] as FieldPathList, []); const fieldPath = (props as { fieldPathId?: { path?: FieldPathList } }).fieldPathId?.path ?? @@ -94,12 +102,16 @@ export function DictAsYamlField(props: FieldProps) { ); const id = idSchema?.$id ?? props.name; + const sectionPrefix = formContext?.sectionI18nPrefix; + const title = t(`${sectionPrefix}.${id}.label`) ?? schema.title; + const description = + t(`${sectionPrefix}.${id}.description`) ?? schema.description; return (
- {schema.title && ( + {title && ( )}