fix: fix i18n (#23144)

* fix: fix genai roles i18n

* fix: add plus object label

* fix: fix some options miss i18n key

* fix: fix genai runtime_options i18n

* fix: format

* fix: add logger level i18n

* fix: add Per-process log level i18n
This commit is contained in:
GuoQing Liu 2026-05-11 01:09:50 +08:00 committed by GitHub
parent c4b74c9148
commit d1bb3d94e5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 121 additions and 12 deletions

View File

@ -121,5 +121,9 @@
"royal_mail": "Royal Mail", "royal_mail": "Royal Mail",
"school_bus": "School Bus", "school_bus": "School Bus",
"skunk": "Skunk", "skunk": "Skunk",
"kangaroo": "Kangaroo" "kangaroo": "Kangaroo",
"baby": "Baby",
"baby_stroller": "Baby Stroller",
"rickshaw": "Rickshaw",
"Rodent": "Rodent"
} }

View File

@ -1490,8 +1490,8 @@
"genaiRoles": { "genaiRoles": {
"options": { "options": {
"embeddings": "Embedding", "embeddings": "Embedding",
"vision": "Vision", "descriptions": "Descriptions",
"tools": "Tools" "chat": "Chat"
} }
}, },
"semanticSearchModel": { "semanticSearchModel": {
@ -1643,10 +1643,60 @@
"hardwareAuto": "Automatic hardware acceleration" "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": { "onvif": {
"profileAuto": "Auto", "profileAuto": "Auto",
"profileLoading": "Loading profiles..." "profileLoading": "Loading profiles..."
}, },
"modelSize": {
"small": "Small",
"large": "Large"
},
"configMessages": { "configMessages": {
"review": { "review": {
"recordDisabled": "Recording is disabled, review items will not be generated.", "recordDisabled": "Recording is disabled, review items will not be generated.",

View File

@ -22,6 +22,14 @@ const birdseye: SectionConfigOverrides = {
hiddenFields: [], hiddenFields: [],
advancedFields: [], advancedFields: [],
overrideFields: ["enabled", "mode"], overrideFields: ["enabled", "mode"],
uiSchema: {
mode: {
"ui:size": "xs",
"ui:options": {
enumI18nPrefix: "birdseye.trackingMode",
},
},
},
}, },
global: { global: {
fieldOrder: [ fieldOrder: [

View File

@ -6,6 +6,16 @@ const logger: SectionConfigOverrides = {
restartRequired: ["default", "logs"], restartRequired: ["default", "logs"],
fieldOrder: ["default", "logs"], fieldOrder: ["default", "logs"],
advancedFields: ["logs"], advancedFields: ["logs"],
uiSchema: {
default: {
"ui:options": { enumI18nPrefix: "logger.logLevel" },
},
logs: {
additionalProperties: {
"ui:options": { enumI18nPrefix: "logger.logLevel" },
},
},
},
}, },
}; };

View File

@ -94,7 +94,7 @@ const lpr: SectionConfigOverrides = {
}, },
}, },
model_size: { model_size: {
"ui:options": { size: "xs" }, "ui:options": { size: "xs", enumI18nPrefix: "modelSize" },
}, },
}, },
}, },

View File

@ -130,6 +130,11 @@ const review: SectionConfigOverrides = {
size: "full", size: "full",
}, },
}, },
image_source: {
"ui:options": {
enumI18nPrefix: "review.imageSource",
},
},
}, },
}, },
}, },

View File

@ -34,6 +34,9 @@ const semanticSearch: SectionConfigOverrides = {
model: { model: {
"ui:widget": "semanticSearchModel", "ui:widget": "semanticSearchModel",
}, },
model_size: {
"ui:options": { size: "xs", enumI18nPrefix: "modelSize" },
},
}, },
}, },
}; };

View File

@ -35,6 +35,11 @@ const snapshots: SectionConfigOverrides = {
suppressMultiSchema: true, suppressMultiSchema: true,
}, },
}, },
"retain.mode": {
"ui:options": {
enumI18nPrefix: "snapshot.retainMode",
},
},
}, },
}, },
global: { global: {

View File

@ -23,6 +23,18 @@ const ui: SectionConfigOverrides = {
timezone: { timezone: {
"ui:widget": "timezoneSelect", "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" },
},
}, },
}, },
}; };

View File

@ -3,6 +3,8 @@ import yaml from "js-yaml";
import { Textarea } from "@/components/ui/textarea"; import { Textarea } from "@/components/ui/textarea";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { ConfigFormContext } from "@/types/configForm";
import { useTranslation } from "react-i18next";
function formatYaml(value: unknown): string { function formatYaml(value: unknown): string {
if ( if (
@ -45,8 +47,14 @@ function parseYaml(text: string): {
} }
export function DictAsYamlField(props: FieldProps) { 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 emptyPath = useMemo(() => [] as FieldPathList, []);
const fieldPath = const fieldPath =
(props as { fieldPathId?: { path?: FieldPathList } }).fieldPathId?.path ?? (props as { fieldPathId?: { path?: FieldPathList } }).fieldPathId?.path ??
@ -94,12 +102,16 @@ export function DictAsYamlField(props: FieldProps) {
); );
const id = idSchema?.$id ?? props.name; 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 ( return (
<div className="flex flex-col gap-1.5"> <div className="flex flex-col gap-1.5">
{schema.title && ( {title && (
<label htmlFor={id} className="text-sm font-medium"> <label htmlFor={id} className="text-sm font-medium">
{schema.title} {title}
</label> </label>
)} )}
<Textarea <Textarea
@ -114,8 +126,8 @@ export function DictAsYamlField(props: FieldProps) {
onBlur={handleBlur} onBlur={handleBlur}
/> />
{error && <p className="text-xs text-destructive">{error}</p>} {error && <p className="text-xs text-destructive">{error}</p>}
{schema.description && ( {description && (
<p className="text-xs text-muted-foreground">{schema.description}</p> <p className="text-xs text-muted-foreground">{description}</p>
)} )}
</div> </div>
); );