Full UI configuration (#22151)

* use react-jsonschema-form for UI config

* don't use properties wrapper when generating config i18n json

* configure for full i18n support

* section fields

* add descriptions to all fields for i18n

* motion i18n

* fix nullable fields

* sanitize internal fields

* add switches widgets and use friendly names

* fix nullable schema entries

* ensure update_topic is added to api calls

this needs further backend implementation to work correctly

* add global sections, camera config overrides, and reset button

* i18n

* add reset logic to global config view

* tweaks

* fix sections and live validation

* fix validation for schema objects that can be null

* generic and custom per-field validation

* improve generic error validation messages

* remove show advanced fields switch

* tweaks

* use shadcn theme

* fix array field template

* i18n tweaks

* remove collapsible around root section

* deep merge schema for advanced fields

* add array field item template and fix ffmpeg section

* add missing i18n keys

* tweaks

* comment out api call for testing

* add config groups as a separate i18n namespace

* add descriptions to all pydantic fields

* make titles more concise

* new titles as i18n

* update i18n config generation script to use json schema

* tweaks

* tweaks

* rebase

* clean up

* form tweaks

* add wildcards and fix object filter fields

* add field template for additionalproperties schema objects

* improve typing

* add section description from schema and clarify global vs camera level descriptions

* separate and consolidate global and camera i18n namespaces

* clean up now obsolete namespaces

* tweaks

* refactor sections and overrides

* add ability to render components before and after fields

* fix titles

* chore(sections): remove legacy single-section components replaced by template

* refactor configs to use individual files with a template

* fix review description

* apply hidden fields after ui schema

* move util

* remove unused i18n

* clean up error messages

* fix fast refresh

* add custom validation and use it for ffmpeg input roles

* update nav tree

* remove unused

* re-add override and modified indicators

* mark pending changes and add confirmation dialog for resets

* fix red unsaved dot

* tweaks

* add docs links, readonly keys, and restart required per field

* add special case and comments for global motion section

* add section form special cases

* combine review sections

* tweaks

* add audio labels endpoint

* add audio label switches and input to filter list

* fix type

* remove key from config when resetting to default/global

* don't show description for new key/val fields

* tweaks

* spacing tweaks

* add activity indicator and scrollbar tweaks

* add docs to filter fields

* wording changes

* fix global ffmpeg section

* add review classification zones to review form

* add backend endpoint and frontend widget for ffmpeg presets and manual args

* improve wording

* hide descriptions for additional properties arrays

* add warning log about incorrectly nested model config

* spacing and language tweaks

* fix i18n keys

* networking section docs and description

* small wording tweaks

* add layout grid field

* refactor with shared utilities

* field order

* add individual detectors to schema

add detector titles and descriptions (docstrings in pydantic are used for descriptions) and add i18n keys to globals

* clean up detectors section and i18n

* don't save model config back to yaml when saving detectors

* add full detectors config to api model dump

works around the way we use detector plugins so we can have the full detector config for the frontend

* add restart button to toast when restart is required

* add ui option to remove inner cards

* fix buttons

* section tweaks

* don't zoom into text on mobile

* make buttons sticky at bottom of sections

* small tweaks

* highlight label of changed fields

* add null to enum list when unwrapping

* refactor to shared utils and add save all button

* add undo all button

* add RJSF to dictionary

* consolidate utils

* preserve form data when changing cameras

* add mono fonts

* add popover to show what fields will be saved

* fix mobile menu not re-rendering with unsaved dots

* tweaks

* fix logger and env vars config section saving

use escaped periods in keys to retain them in the config file (eg "frigate.embeddings")

* add timezone widget

* role map field with validation

* fix validation for model section

* add another hidden field

* add footer message for required restart

* use rjsf for notifications view

* fix config saving

* add replace rules field

* default column layout and add field sizing

* clean up field template

* refactor profile settings to match rjsf forms

* tweaks

* refactor frigate+ view and make tweaks to sections

* show frigate+ model info in detection model settings when using a frigate+ model

* update restartRequired for all fields

* fix restart fields

* tweaks and add ability enable disabled cameras

more backend changes required

* require restart when enabling camera that is disabled in config

* disable save when form is invalid

* refactor ffmpeg section for readability

* change label

* clean up camera inputs fields

* misc tweaks to ffmpeg section

- add raw paths endpoint to ensure credentials get saved
- restart required tooltip

* maintenance settings tweaks

* don't mutate with lodash

* fix description re-rendering for nullable object fields

* hide reindex field

* update rjsf

* add frigate+ description to settings pane

* disable save all when any section is invalid

* show translated field name in validation error pane

* clean up

* remove unused

* fix genai merge

* fix genai
This commit is contained in:
Josh Hawkins
2026-02-27 08:55:36 -07:00
committed by GitHub
parent eeefbf2bb5
commit e7250f24cb
206 changed files with 22200 additions and 4435 deletions
+280 -11
View File
@@ -8,23 +8,82 @@
"masksAndZones": "Mask and Zone Editor - Frigate",
"motionTuner": "Motion Tuner - Frigate",
"object": "Debug - Frigate",
"general": "UI Settings - Frigate",
"general": "Profile Settings - Frigate",
"globalConfig": "Global Configuration - Frigate",
"cameraConfig": "Camera Configuration - Frigate",
"frigatePlus": "Frigate+ Settings - Frigate",
"notifications": "Notification Settings - Frigate"
"notifications": "Notification Settings - Frigate",
"maintenance": "Maintenance - Frigate"
},
"menu": {
"general": "General",
"globalConfig": "Global configuration",
"system": "System",
"integrations": "Integrations",
"cameras": "Camera configuration",
"ui": "UI",
"enrichments": "Enrichments",
"profileSettings": "Profile settings",
"globalDetect": "Object detection",
"globalRecording": "Recording",
"globalSnapshots": "Snapshots",
"globalFfmpeg": "FFmpeg",
"globalMotion": "Motion detection",
"globalObjects": "Objects",
"globalReview": "Review",
"globalAudioEvents": "Audio events",
"globalLivePlayback": "Live playback",
"globalTimestampStyle": "Timestamp style",
"systemDatabase": "Database",
"systemTls": "TLS",
"systemAuthentication": "Authentication",
"systemNetworking": "Networking",
"systemProxy": "Proxy",
"systemUi": "UI",
"systemLogging": "Logging",
"systemEnvironmentVariables": "Environment variables",
"systemTelemetry": "Telemetry",
"systemBirdseye": "Birdseye",
"systemFfmpeg": "FFmpeg",
"systemDetectorHardware": "Detector hardware",
"systemDetectionModel": "Detection model",
"systemMqtt": "MQTT",
"integrationSemanticSearch": "Semantic search",
"integrationGenerativeAi": "Generative AI",
"integrationFaceRecognition": "Face recognition",
"integrationLpr": "License plate recognition",
"integrationObjectClassification": "Object classification",
"integrationAudioTranscription": "Audio transcription",
"cameraDetect": "Object detection",
"cameraFfmpeg": "FFmpeg",
"cameraRecording": "Recording",
"cameraSnapshots": "Snapshots",
"cameraMotion": "Motion detection",
"cameraObjects": "Objects",
"cameraConfigReview": "Review",
"cameraAudioEvents": "Audio events",
"cameraAudioTranscription": "Audio transcription",
"cameraNotifications": "Notifications",
"cameraLivePlayback": "Live playback",
"cameraBirdseye": "Birdseye",
"cameraFaceRecognition": "Face recognition",
"cameraLpr": "License plate recognition",
"cameraMqttConfig": "MQTT",
"cameraOnvif": "ONVIF",
"cameraUi": "Camera UI",
"cameraTimestampStyle": "Timestamp style",
"cameraMqtt": "Camera MQTT",
"cameraManagement": "Management",
"cameraReview": "Review",
"masksAndZones": "Masks / Zones",
"motionTuner": "Motion Tuner",
"triggers": "Triggers",
"debug": "Debug",
"motionTuner": "Motion tuner",
"enrichments": "Enrichments",
"users": "Users",
"roles": "Roles",
"notifications": "Notifications",
"frigateplus": "Frigate+"
"triggers": "Triggers",
"debug": "Debug",
"frigateplus": "Frigate+",
"maintenance": "Maintenance"
},
"dialog": {
"unsavedChanges": {
@@ -32,12 +91,29 @@
"desc": "Do you want to save your changes before continuing?"
}
},
"saveAllPreview": {
"title": "Changes to be saved",
"triggerLabel": "Review pending changes",
"empty": "No pending changes.",
"scope": {
"label": "Scope",
"global": "Global",
"camera": "Camera: {{cameraName}}"
},
"field": {
"label": "Field"
},
"value": {
"label": "New value",
"reset": "Reset"
}
},
"cameraSetting": {
"camera": "Camera",
"noCamera": "No Camera"
},
"general": {
"title": "UI Settings",
"title": "Profile Settings",
"liveDashboard": {
"title": "Live Dashboard",
"automaticLiveView": {
@@ -106,7 +182,7 @@
"desc": "Semantic Search in Frigate allows you to find tracked objects within your review items using either the image itself, a user-defined text description, or an automatically generated one.",
"reindexNow": {
"label": "Reindex Now",
"desc": "Reindexing will regenerate embeddings for all tracked object. This process runs in the background and may max out your CPU and take a fair amount of time depending on the number of tracked objects you have.",
"desc": "Reindexing will regenerate embeddings for all tracked objects. This process runs in the background and may max out your CPU and take a fair amount of time depending on the number of tracked objects you have.",
"confirmTitle": "Confirm Reindexing",
"confirmDesc": "Are you sure you want to reindex all tracked object embeddings? This process will run in the background but it may max out your CPU and take a fair amount of time. You can watch the progress on the Explore page.",
"confirmButton": "Reindex",
@@ -350,7 +426,11 @@
"backToSettings": "Back to Camera Settings",
"streams": {
"title": "Enable / Disable Cameras",
"desc": "Temporarily disable a camera until Frigate restarts. Disabling a camera completely stops Frigate's processing of this camera's streams. Detection, recording, and debugging will be unavailable.<br /> <em>Note: This does not disable go2rtc restreams.</em>"
"enableLabel": "Enabled cameras",
"enableDesc": "Temporarily disable an enabled camera until Frigate restarts. Disabling a camera completely stops Frigate's processing of this camera's streams. Detection, recording, and debugging will be unavailable.<br /> <em>Note: This does not disable go2rtc restreams.</em>",
"disableLabel": "Disabled cameras",
"disableDesc": "Enable a camera that is currently not visible in the UI and disabled in the configuration. A restart of Frigate is required after enabling.",
"enableSuccess": "Enabled {{cameraName}} in configuration. Restart Frigate to apply the changes."
},
"cameraConfig": {
"add": "Add Camera",
@@ -906,6 +986,13 @@
},
"frigatePlus": {
"title": "Frigate+ Settings",
"description": "Frigate+ is a subscription service that provides access to additional features and capabilities for your Frigate instance, including the ability to use custom object detection models trained on your own data. You can manage your Frigate+ model settings here.",
"cardTitles": {
"api": "API",
"currentModel": "Current Model",
"otherModels": "Other Models",
"configuration": "Configuration"
},
"apiKey": {
"title": "Frigate+ API Key",
"validated": "Frigate+ API key is detected and validated",
@@ -947,6 +1034,15 @@
"error": "Failed to save config changes: {{errorMessage}}"
}
},
"detectionModel": {
"plusActive": {
"title": "Frigate+ model management",
"label": "Current model source",
"description": "This instance is running a Frigate+ model. Select or change your model in Frigate+ settings.",
"goToFrigatePlus": "Go to Frigate+ settings",
"showModelForm": "Manually configure a model"
}
},
"triggers": {
"documentTitle": "Triggers",
"semanticSearch": {
@@ -1115,5 +1211,178 @@
"exports": "Exports",
"recordings": "Recordings"
}
}
},
"configForm": {
"global": {
"title": "Global Settings",
"description": "These settings apply to all cameras unless overridden in the camera-specific settings."
},
"camera": {
"title": "Camera Settings",
"description": "These settings apply only to this camera and override the global settings."
},
"advancedSettingsCount": "Advanced Settings ({{count}})",
"advancedCount": "Advanced ({{count}})",
"showAdvanced": "Show Advanced Settings",
"tabs": {
"sharedDefaults": "Shared Defaults",
"system": "System",
"integrations": "Integrations"
},
"additionalProperties": {
"keyLabel": "Key",
"valueLabel": "Value",
"keyPlaceholder": "New key",
"remove": "Remove"
},
"timezone": {
"defaultOption": "Use browser timezone"
},
"roleMap": {
"empty": "No role mappings",
"roleLabel": "Role",
"groupsLabel": "Groups",
"addMapping": "Add role mapping",
"remove": "Remove"
},
"ffmpegArgs": {
"preset": "Preset",
"manual": "Manual arguments",
"inherit": "Inherit from camera setting",
"selectPreset": "Select preset",
"manualPlaceholder": "Enter FFmpeg arguments"
},
"cameraInputs": {
"itemTitle": "Stream {{index}}"
},
"restartRequiredField": "Restart required",
"restartRequiredFooter": "Configuration changed - Restart required",
"sections": {
"detect": "Detection",
"record": "Recording",
"snapshots": "Snapshots",
"motion": "Motion",
"objects": "Objects",
"review": "Review",
"audio": "Audio",
"notifications": "Notifications",
"live": "Live View",
"timestamp_style": "Timestamps",
"mqtt": "MQTT",
"database": "Database",
"telemetry": "Telemetry",
"auth": "Authentication",
"tls": "TLS",
"proxy": "Proxy",
"go2rtc": "go2rtc",
"ffmpeg": "FFmpeg",
"detectors": "Detectors",
"model": "Model",
"semantic_search": "Semantic Search",
"genai": "GenAI",
"face_recognition": "Face Recognition",
"lpr": "License Plate Recognition",
"birdseye": "Birdseye"
},
"detect": {
"title": "Detection Settings"
},
"detectors": {
"title": "Detector Settings",
"singleType": "Only one {{type}} detector is allowed.",
"keyRequired": "Detector name is required.",
"keyDuplicate": "Detector name already exists.",
"noSchema": "No detector schemas are available.",
"none": "No detector instances configured.",
"add": "Add detector"
},
"record": {
"title": "Recording Settings"
},
"snapshots": {
"title": "Snapshot Settings"
},
"motion": {
"title": "Motion Settings"
},
"objects": {
"title": "Object Settings"
},
"audioLabels": {
"summary": "{{count}} audio labels selected",
"empty": "No audio labels available"
},
"objectLabels": {
"summary": "{{count}} object types selected",
"empty": "No object labels available"
},
"filters": {
"objectFieldLabel": "{{field}} for {{label}}"
},
"zoneNames": {
"summary": "{{count}} selected",
"empty": "No zones available"
},
"inputRoles": {
"summary": "{{count}} roles selected",
"empty": "No roles available",
"options": {
"detect": "Detect",
"record": "Record",
"audio": "Audio"
}
},
"review": {
"title": "Review Settings"
},
"audio": {
"title": "Audio Settings"
},
"notifications": {
"title": "Notification Settings"
},
"live": {
"title": "Live View Settings"
},
"timestamp_style": {
"title": "Timestamp Settings"
},
"searchPlaceholder": "Search..."
},
"globalConfig": {
"title": "Global Configuration",
"description": "Configure global settings that apply to all cameras unless overridden.",
"toast": {
"success": "Global settings saved successfully",
"error": "Failed to save global settings",
"validationError": "Validation failed"
}
},
"cameraConfig": {
"title": "Camera Configuration",
"description": "Configure settings for individual cameras. Settings override global defaults.",
"overriddenBadge": "Overridden",
"resetToGlobal": "Reset to Global",
"toast": {
"success": "Camera settings saved successfully",
"error": "Failed to save camera settings"
}
},
"toast": {
"success": "Settings saved successfully",
"successRestartRequired": "Settings saved successfully. Restart Frigate to apply your changes.",
"error": "Failed to save settings",
"validationError": "Validation failed: {{message}}",
"resetSuccess": "Reset to global defaults",
"resetError": "Failed to reset settings",
"saveAllSuccess_one": "Saved {{count}} section successfully.",
"saveAllSuccess_other": "All {{count}} sections saved successfully.",
"saveAllPartial_one": "{{successCount}} of {{totalCount}} section saved. {{failCount}} failed.",
"saveAllPartial_other": "{{successCount}} of {{totalCount}} sections saved. {{failCount}} failed.",
"saveAllFailure": "Failed to save all sections."
},
"unsavedChanges": "You have unsaved changes",
"confirmReset": "Confirm Reset",
"resetToDefaultDescription": "This will reset all settings in this section to their default values. This action cannot be undone.",
"resetToGlobalDescription": "This will reset the settings in this section to the global defaults. This action cannot be undone."
}