mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-07-31 08:09:02 +03:00
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:
@@ -0,0 +1,42 @@
|
||||
import type { SectionConfigOverrides } from "./types";
|
||||
|
||||
const audio: SectionConfigOverrides = {
|
||||
base: {
|
||||
sectionDocs: "/configuration/audio_detectors",
|
||||
restartRequired: [],
|
||||
fieldOrder: [
|
||||
"enabled",
|
||||
"listen",
|
||||
"filters",
|
||||
"min_volume",
|
||||
"max_not_heard",
|
||||
"num_threads",
|
||||
],
|
||||
fieldGroups: {
|
||||
detection: ["enabled", "listen", "filters"],
|
||||
sensitivity: ["min_volume", "max_not_heard"],
|
||||
},
|
||||
hiddenFields: ["enabled_in_config"],
|
||||
advancedFields: ["min_volume", "max_not_heard", "num_threads"],
|
||||
uiSchema: {
|
||||
listen: {
|
||||
"ui:widget": "audioLabels",
|
||||
},
|
||||
},
|
||||
},
|
||||
global: {
|
||||
restartRequired: [
|
||||
"enabled",
|
||||
"listen",
|
||||
"filters",
|
||||
"min_volume",
|
||||
"max_not_heard",
|
||||
"num_threads",
|
||||
],
|
||||
},
|
||||
camera: {
|
||||
restartRequired: ["num_threads"],
|
||||
},
|
||||
};
|
||||
|
||||
export default audio;
|
||||
@@ -0,0 +1,19 @@
|
||||
import type { SectionConfigOverrides } from "./types";
|
||||
|
||||
const audioTranscription: SectionConfigOverrides = {
|
||||
base: {
|
||||
sectionDocs: "/configuration/audio_detectors#audio-transcription",
|
||||
restartRequired: [],
|
||||
fieldOrder: ["enabled", "language", "device", "model_size"],
|
||||
hiddenFields: ["enabled_in_config", "live_enabled"],
|
||||
advancedFields: ["language", "device", "model_size"],
|
||||
overrideFields: ["enabled", "live_enabled"],
|
||||
},
|
||||
global: {
|
||||
fieldOrder: ["enabled", "language", "device", "model_size"],
|
||||
advancedFields: ["language", "device", "model_size"],
|
||||
restartRequired: ["enabled", "language", "device", "model_size"],
|
||||
},
|
||||
};
|
||||
|
||||
export default audioTranscription;
|
||||
@@ -0,0 +1,49 @@
|
||||
import type { SectionConfigOverrides } from "./types";
|
||||
|
||||
const auth: SectionConfigOverrides = {
|
||||
base: {
|
||||
sectionDocs: "/configuration/authentication",
|
||||
restartRequired: [
|
||||
"enabled",
|
||||
"reset_admin_password",
|
||||
"failed_login_rate_limit",
|
||||
],
|
||||
fieldOrder: [
|
||||
"enabled",
|
||||
"reset_admin_password",
|
||||
"cookie_name",
|
||||
"cookie_secure",
|
||||
"session_length",
|
||||
"refresh_time",
|
||||
"native_oauth_url",
|
||||
"failed_login_rate_limit",
|
||||
"trusted_proxies",
|
||||
"hash_iterations",
|
||||
"roles",
|
||||
],
|
||||
hiddenFields: ["admin_first_time_login", "roles"],
|
||||
advancedFields: [
|
||||
"cookie_name",
|
||||
"cookie_secure",
|
||||
"session_length",
|
||||
"refresh_time",
|
||||
"failed_login_rate_limit",
|
||||
"trusted_proxies",
|
||||
"hash_iterations",
|
||||
"roles",
|
||||
],
|
||||
uiSchema: {
|
||||
reset_admin_password: {
|
||||
"ui:widget": "switch",
|
||||
},
|
||||
native_oauth_url: {
|
||||
"ui:options": { size: "lg" },
|
||||
},
|
||||
failed_login_rate_limit: {
|
||||
"ui:options": { size: "md" },
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default auth;
|
||||
@@ -0,0 +1,45 @@
|
||||
import type { SectionConfigOverrides } from "./types";
|
||||
|
||||
const birdseye: SectionConfigOverrides = {
|
||||
base: {
|
||||
sectionDocs: "/configuration/birdseye",
|
||||
restartRequired: [],
|
||||
fieldOrder: ["enabled", "mode", "order"],
|
||||
hiddenFields: [],
|
||||
advancedFields: [],
|
||||
overrideFields: ["enabled", "mode"],
|
||||
},
|
||||
global: {
|
||||
fieldOrder: [
|
||||
"enabled",
|
||||
"restream",
|
||||
"width",
|
||||
"height",
|
||||
"quality",
|
||||
"mode",
|
||||
"layout",
|
||||
"inactivity_threshold",
|
||||
"idle_heartbeat_fps",
|
||||
],
|
||||
advancedFields: ["width", "height", "quality", "inactivity_threshold"],
|
||||
restartRequired: [
|
||||
"enabled",
|
||||
"restream",
|
||||
"width",
|
||||
"height",
|
||||
"quality",
|
||||
"mode",
|
||||
"layout.scaling_factor",
|
||||
"inactivity_threshold",
|
||||
"layout.max_cameras",
|
||||
"idle_heartbeat_fps",
|
||||
],
|
||||
uiSchema: {
|
||||
mode: {
|
||||
"ui:size": "xs",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default birdseye;
|
||||
@@ -0,0 +1,12 @@
|
||||
import type { SectionConfigOverrides } from "./types";
|
||||
|
||||
const classification: SectionConfigOverrides = {
|
||||
base: {
|
||||
sectionDocs: "/configuration/custom_classification/object_classification",
|
||||
restartRequired: ["bird.enabled", "bird.threshold"],
|
||||
hiddenFields: ["custom"],
|
||||
advancedFields: [],
|
||||
},
|
||||
};
|
||||
|
||||
export default classification;
|
||||
@@ -0,0 +1,17 @@
|
||||
import type { SectionConfigOverrides } from "./types";
|
||||
|
||||
const database: SectionConfigOverrides = {
|
||||
base: {
|
||||
sectionDocs: "/configuration/advanced#database",
|
||||
restartRequired: ["path"],
|
||||
fieldOrder: ["path"],
|
||||
advancedFields: [],
|
||||
uiSchema: {
|
||||
path: {
|
||||
"ui:options": { size: "md" },
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default database;
|
||||
@@ -0,0 +1,49 @@
|
||||
import type { SectionConfigOverrides } from "./types";
|
||||
|
||||
const detect: SectionConfigOverrides = {
|
||||
base: {
|
||||
sectionDocs: "/configuration/camera_specific",
|
||||
fieldOrder: [
|
||||
"enabled",
|
||||
"width",
|
||||
"height",
|
||||
"fps",
|
||||
"min_initialized",
|
||||
"max_disappeared",
|
||||
"annotation_offset",
|
||||
"stationary",
|
||||
"interval",
|
||||
"threshold",
|
||||
"max_frames",
|
||||
],
|
||||
restartRequired: [],
|
||||
fieldGroups: {
|
||||
resolution: ["enabled", "width", "height", "fps"],
|
||||
tracking: ["min_initialized", "max_disappeared"],
|
||||
},
|
||||
hiddenFields: ["enabled_in_config"],
|
||||
advancedFields: [
|
||||
"min_initialized",
|
||||
"max_disappeared",
|
||||
"annotation_offset",
|
||||
"stationary",
|
||||
],
|
||||
},
|
||||
global: {
|
||||
restartRequired: [
|
||||
"enabled",
|
||||
"width",
|
||||
"height",
|
||||
"fps",
|
||||
"min_initialized",
|
||||
"max_disappeared",
|
||||
"annotation_offset",
|
||||
"stationary",
|
||||
],
|
||||
},
|
||||
camera: {
|
||||
restartRequired: ["width", "height", "min_initialized", "max_disappeared"],
|
||||
},
|
||||
};
|
||||
|
||||
export default detect;
|
||||
@@ -0,0 +1,28 @@
|
||||
import type { SectionConfigOverrides } from "./types";
|
||||
|
||||
const detectorHiddenFields = [
|
||||
"*.model.labelmap",
|
||||
"*.model.attributes_map",
|
||||
"*.model",
|
||||
"*.model_path",
|
||||
];
|
||||
|
||||
const detectors: SectionConfigOverrides = {
|
||||
base: {
|
||||
sectionDocs: "/configuration/object_detectors",
|
||||
fieldOrder: [],
|
||||
advancedFields: [],
|
||||
hiddenFields: detectorHiddenFields,
|
||||
uiSchema: {
|
||||
"ui:field": "DetectorHardwareField",
|
||||
"ui:options": {
|
||||
multiInstanceTypes: ["cpu", "onnx", "openvino"],
|
||||
typeOrder: ["onnx", "openvino", "edgetpu"],
|
||||
hiddenByType: {},
|
||||
hiddenFields: detectorHiddenFields,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default detectors;
|
||||
@@ -0,0 +1,16 @@
|
||||
import type { SectionConfigOverrides } from "./types";
|
||||
|
||||
const environmentVars: SectionConfigOverrides = {
|
||||
base: {
|
||||
sectionDocs: "/configuration/advanced#environment_vars",
|
||||
fieldOrder: [],
|
||||
advancedFields: [],
|
||||
uiSchema: {
|
||||
additionalProperties: {
|
||||
"ui:options": { size: "lg" },
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default environmentVars;
|
||||
@@ -0,0 +1,50 @@
|
||||
import type { SectionConfigOverrides } from "./types";
|
||||
|
||||
const faceRecognition: SectionConfigOverrides = {
|
||||
base: {
|
||||
sectionDocs: "/configuration/face_recognition",
|
||||
restartRequired: [],
|
||||
fieldOrder: ["enabled", "min_area"],
|
||||
hiddenFields: [],
|
||||
advancedFields: ["min_area"],
|
||||
overrideFields: ["enabled", "min_area"],
|
||||
},
|
||||
global: {
|
||||
fieldOrder: [
|
||||
"enabled",
|
||||
"model_size",
|
||||
"unknown_score",
|
||||
"detection_threshold",
|
||||
"recognition_threshold",
|
||||
"min_area",
|
||||
"min_faces",
|
||||
"save_attempts",
|
||||
"blur_confidence_filter",
|
||||
"device",
|
||||
],
|
||||
advancedFields: [
|
||||
"unknown_score",
|
||||
"detection_threshold",
|
||||
"recognition_threshold",
|
||||
"min_area",
|
||||
"min_faces",
|
||||
"save_attempts",
|
||||
"blur_confidence_filter",
|
||||
"device",
|
||||
],
|
||||
restartRequired: [
|
||||
"enabled",
|
||||
"model_size",
|
||||
"unknown_score",
|
||||
"detection_threshold",
|
||||
"recognition_threshold",
|
||||
"min_area",
|
||||
"min_faces",
|
||||
"save_attempts",
|
||||
"blur_confidence_filter",
|
||||
"device",
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
export default faceRecognition;
|
||||
@@ -0,0 +1,179 @@
|
||||
import type { SectionConfigOverrides } from "./types";
|
||||
|
||||
const arrayAsTextWidget = {
|
||||
"ui:widget": "ArrayAsTextWidget",
|
||||
"ui:options": {
|
||||
suppressMultiSchema: true,
|
||||
},
|
||||
};
|
||||
|
||||
const ffmpegArgsWidget = (
|
||||
presetField: string,
|
||||
extraOptions?: Record<string, unknown>,
|
||||
) => ({
|
||||
"ui:widget": "FfmpegArgsWidget",
|
||||
"ui:options": {
|
||||
suppressMultiSchema: true,
|
||||
ffmpegPresetField: presetField,
|
||||
...extraOptions,
|
||||
},
|
||||
});
|
||||
|
||||
const ffmpeg: SectionConfigOverrides = {
|
||||
base: {
|
||||
sectionDocs: "/configuration/ffmpeg_presets",
|
||||
fieldDocs: {
|
||||
hwaccel_args: "/configuration/ffmpeg_presets#hwaccel-presets",
|
||||
"inputs.hwaccel_args": "/configuration/ffmpeg_presets#hwaccel-presets",
|
||||
input_args: "/configuration/ffmpeg_presets#input-args-presets",
|
||||
"inputs.input_args": "/configuration/ffmpeg_presets#input-args-presets",
|
||||
output_args: "/configuration/ffmpeg_presets#output-args-presets",
|
||||
"inputs.output_args": "/configuration/ffmpeg_presets#output-args-presets",
|
||||
"output_args.record": "/configuration/ffmpeg_presets#output-args-presets",
|
||||
"inputs.roles": "/configuration/cameras/#setting-up-camera-inputs",
|
||||
},
|
||||
restartRequired: [],
|
||||
fieldOrder: [
|
||||
"inputs",
|
||||
"global_args",
|
||||
"input_args",
|
||||
"hwaccel_args",
|
||||
"output_args",
|
||||
"path",
|
||||
"retry_interval",
|
||||
"apple_compatibility",
|
||||
"gpu",
|
||||
],
|
||||
hiddenFields: [],
|
||||
advancedFields: [
|
||||
"path",
|
||||
"global_args",
|
||||
"retry_interval",
|
||||
"apple_compatibility",
|
||||
"gpu",
|
||||
],
|
||||
overrideFields: [
|
||||
"inputs",
|
||||
"path",
|
||||
"global_args",
|
||||
"input_args",
|
||||
"hwaccel_args",
|
||||
"output_args",
|
||||
"retry_interval",
|
||||
"apple_compatibility",
|
||||
"gpu",
|
||||
],
|
||||
uiSchema: {
|
||||
path: {
|
||||
"ui:options": { size: "md" },
|
||||
},
|
||||
global_args: arrayAsTextWidget,
|
||||
hwaccel_args: ffmpegArgsWidget("hwaccel_args"),
|
||||
input_args: ffmpegArgsWidget("input_args"),
|
||||
output_args: {
|
||||
detect: arrayAsTextWidget,
|
||||
record: ffmpegArgsWidget("output_args.record"),
|
||||
items: {
|
||||
detect: arrayAsTextWidget,
|
||||
record: ffmpegArgsWidget("output_args.record"),
|
||||
},
|
||||
},
|
||||
inputs: {
|
||||
"ui:field": "CameraInputsField",
|
||||
items: {
|
||||
path: {
|
||||
"ui:options": { size: "full" },
|
||||
},
|
||||
roles: {
|
||||
"ui:widget": "inputRoles",
|
||||
"ui:options": {
|
||||
showArrayItemDescription: true,
|
||||
},
|
||||
},
|
||||
global_args: {
|
||||
"ui:widget": "hidden",
|
||||
},
|
||||
hwaccel_args: ffmpegArgsWidget("hwaccel_args", {
|
||||
allowInherit: true,
|
||||
hideDescription: true,
|
||||
forceSplitLayout: true,
|
||||
showArrayItemDescription: true,
|
||||
}),
|
||||
input_args: ffmpegArgsWidget("input_args", {
|
||||
allowInherit: true,
|
||||
hideDescription: true,
|
||||
forceSplitLayout: true,
|
||||
showArrayItemDescription: true,
|
||||
}),
|
||||
output_args: {
|
||||
items: {
|
||||
detect: arrayAsTextWidget,
|
||||
record: ffmpegArgsWidget("output_args.record"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
global: {
|
||||
restartRequired: [
|
||||
"path",
|
||||
"global_args",
|
||||
"hwaccel_args",
|
||||
"input_args",
|
||||
"output_args",
|
||||
"retry_interval",
|
||||
"apple_compatibility",
|
||||
"gpu",
|
||||
],
|
||||
fieldOrder: [
|
||||
"hwaccel_args",
|
||||
"path",
|
||||
"global_args",
|
||||
"input_args",
|
||||
"output_args",
|
||||
"retry_interval",
|
||||
"apple_compatibility",
|
||||
"gpu",
|
||||
],
|
||||
advancedFields: [
|
||||
"global_args",
|
||||
"input_args",
|
||||
"output_args",
|
||||
"path",
|
||||
"retry_interval",
|
||||
"apple_compatibility",
|
||||
"gpu",
|
||||
],
|
||||
uiSchema: {
|
||||
path: {
|
||||
"ui:options": { size: "md" },
|
||||
},
|
||||
global_args: arrayAsTextWidget,
|
||||
hwaccel_args: ffmpegArgsWidget("hwaccel_args"),
|
||||
input_args: ffmpegArgsWidget("input_args"),
|
||||
output_args: {
|
||||
detect: arrayAsTextWidget,
|
||||
record: ffmpegArgsWidget("output_args.record"),
|
||||
},
|
||||
},
|
||||
},
|
||||
camera: {
|
||||
fieldGroups: {
|
||||
cameraFfmpeg: ["input_args", "hwaccel_args", "output_args"],
|
||||
},
|
||||
restartRequired: [
|
||||
"inputs",
|
||||
"path",
|
||||
"global_args",
|
||||
"hwaccel_args",
|
||||
"input_args",
|
||||
"output_args",
|
||||
"retry_interval",
|
||||
"apple_compatibility",
|
||||
"gpu",
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
export default ffmpeg;
|
||||
@@ -0,0 +1,48 @@
|
||||
import type { SectionConfigOverrides } from "./types";
|
||||
|
||||
const genai: SectionConfigOverrides = {
|
||||
base: {
|
||||
sectionDocs: "/configuration/genai/config",
|
||||
restartRequired: [
|
||||
"provider",
|
||||
"api_key",
|
||||
"base_url",
|
||||
"model",
|
||||
"provider_options",
|
||||
"runtime_options",
|
||||
],
|
||||
fieldOrder: [
|
||||
"provider",
|
||||
"api_key",
|
||||
"base_url",
|
||||
"model",
|
||||
"provider_options",
|
||||
"runtime_options",
|
||||
],
|
||||
advancedFields: ["base_url", "provider_options", "runtime_options"],
|
||||
hiddenFields: ["genai.enabled_in_config"],
|
||||
uiSchema: {
|
||||
api_key: {
|
||||
"ui:options": { size: "md" },
|
||||
},
|
||||
base_url: {
|
||||
"ui:options": { size: "lg" },
|
||||
},
|
||||
model: {
|
||||
"ui:options": { size: "md" },
|
||||
},
|
||||
provider_options: {
|
||||
additionalProperties: {
|
||||
"ui:options": { size: "lg" },
|
||||
},
|
||||
},
|
||||
runtime_options: {
|
||||
additionalProperties: {
|
||||
"ui:options": { size: "lg" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default genai;
|
||||
@@ -0,0 +1,21 @@
|
||||
import type { SectionConfigOverrides } from "./types";
|
||||
|
||||
const live: SectionConfigOverrides = {
|
||||
base: {
|
||||
sectionDocs: "/configuration/live",
|
||||
restartRequired: [],
|
||||
fieldOrder: ["stream_name", "height", "quality"],
|
||||
fieldGroups: {},
|
||||
hiddenFields: ["enabled_in_config"],
|
||||
advancedFields: ["height", "quality"],
|
||||
},
|
||||
global: {
|
||||
restartRequired: ["stream_name", "height", "quality"],
|
||||
hiddenFields: ["streams"],
|
||||
},
|
||||
camera: {
|
||||
restartRequired: ["height", "quality"],
|
||||
},
|
||||
};
|
||||
|
||||
export default live;
|
||||
@@ -0,0 +1,12 @@
|
||||
import type { SectionConfigOverrides } from "./types";
|
||||
|
||||
const logger: SectionConfigOverrides = {
|
||||
base: {
|
||||
sectionDocs: "/configuration/advanced#logger",
|
||||
restartRequired: ["default", "logs"],
|
||||
fieldOrder: ["default", "logs"],
|
||||
advancedFields: ["logs"],
|
||||
},
|
||||
};
|
||||
|
||||
export default logger;
|
||||
@@ -0,0 +1,73 @@
|
||||
import type { SectionConfigOverrides } from "./types";
|
||||
|
||||
const lpr: SectionConfigOverrides = {
|
||||
base: {
|
||||
sectionDocs: "/configuration/license_plate_recognition",
|
||||
fieldDocs: {
|
||||
enhancement: "/configuration/license_plate_recognition#enhancement",
|
||||
},
|
||||
restartRequired: [],
|
||||
fieldOrder: ["enabled", "expire_time", "min_area", "enhancement"],
|
||||
hiddenFields: [],
|
||||
advancedFields: ["expire_time", "min_area", "enhancement"],
|
||||
overrideFields: ["enabled", "min_area", "enhancement"],
|
||||
},
|
||||
global: {
|
||||
fieldOrder: [
|
||||
"enabled",
|
||||
"model_size",
|
||||
"detection_threshold",
|
||||
"min_area",
|
||||
"recognition_threshold",
|
||||
"min_plate_length",
|
||||
"format",
|
||||
"match_distance",
|
||||
"known_plates",
|
||||
"enhancement",
|
||||
"debug_save_plates",
|
||||
"device",
|
||||
"replace_rules",
|
||||
],
|
||||
advancedFields: [
|
||||
"detection_threshold",
|
||||
"recognition_threshold",
|
||||
"min_plate_length",
|
||||
"format",
|
||||
"match_distance",
|
||||
"known_plates",
|
||||
"enhancement",
|
||||
"debug_save_plates",
|
||||
"device",
|
||||
"replace_rules",
|
||||
],
|
||||
restartRequired: [
|
||||
"enabled",
|
||||
"model_size",
|
||||
"detection_threshold",
|
||||
"min_area",
|
||||
"recognition_threshold",
|
||||
"min_plate_length",
|
||||
"format",
|
||||
"match_distance",
|
||||
"known_plates",
|
||||
"enhancement",
|
||||
"debug_save_plates",
|
||||
"device",
|
||||
"replace_rules",
|
||||
],
|
||||
uiSchema: {
|
||||
format: {
|
||||
"ui:options": { size: "md" },
|
||||
},
|
||||
replace_rules: {
|
||||
"ui:field": "ReplaceRulesField",
|
||||
"ui:options": {
|
||||
label: false,
|
||||
suppressDescription: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default lpr;
|
||||
@@ -0,0 +1,53 @@
|
||||
import type { SectionConfigOverrides } from "./types";
|
||||
|
||||
const model: SectionConfigOverrides = {
|
||||
base: {
|
||||
sectionDocs: "/configuration/object_detectors#model",
|
||||
restartRequired: [
|
||||
"path",
|
||||
"labelmap_path",
|
||||
"width",
|
||||
"height",
|
||||
"labelmap",
|
||||
"attributes_map",
|
||||
"input_tensor",
|
||||
"input_pixel_format",
|
||||
"input_dtype",
|
||||
"model_type",
|
||||
],
|
||||
fieldOrder: [
|
||||
"path",
|
||||
"labelmap_path",
|
||||
"width",
|
||||
"height",
|
||||
"input_pixel_format",
|
||||
"input_tensor",
|
||||
"input_dtype",
|
||||
"model_type",
|
||||
],
|
||||
advancedFields: [
|
||||
"input_pixel_format",
|
||||
"input_tensor",
|
||||
"input_dtype",
|
||||
"model_type",
|
||||
],
|
||||
hiddenFields: [
|
||||
"labelmap",
|
||||
"attributes_map",
|
||||
"colormap",
|
||||
"all_attributes",
|
||||
"non_logo_attributes",
|
||||
"plus",
|
||||
],
|
||||
uiSchema: {
|
||||
path: {
|
||||
"ui:options": { size: "md" },
|
||||
},
|
||||
labelmap_path: {
|
||||
"ui:options": { size: "md" },
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default model;
|
||||
@@ -0,0 +1,49 @@
|
||||
import type { SectionConfigOverrides } from "./types";
|
||||
|
||||
const motion: SectionConfigOverrides = {
|
||||
base: {
|
||||
sectionDocs: "/configuration/motion_detection",
|
||||
restartRequired: [],
|
||||
fieldOrder: [
|
||||
"enabled",
|
||||
"threshold",
|
||||
"lightning_threshold",
|
||||
"improve_contrast",
|
||||
"contour_area",
|
||||
"delta_alpha",
|
||||
"frame_alpha",
|
||||
"frame_height",
|
||||
"mqtt_off_delay",
|
||||
],
|
||||
fieldGroups: {
|
||||
sensitivity: ["enabled", "threshold", "contour_area"],
|
||||
algorithm: ["improve_contrast", "delta_alpha", "frame_alpha"],
|
||||
},
|
||||
hiddenFields: ["enabled_in_config", "mask", "raw_mask"],
|
||||
advancedFields: [
|
||||
"lightning_threshold",
|
||||
"delta_alpha",
|
||||
"frame_alpha",
|
||||
"frame_height",
|
||||
"mqtt_off_delay",
|
||||
],
|
||||
},
|
||||
global: {
|
||||
restartRequired: [
|
||||
"enabled",
|
||||
"threshold",
|
||||
"lightning_threshold",
|
||||
"improve_contrast",
|
||||
"contour_area",
|
||||
"delta_alpha",
|
||||
"frame_alpha",
|
||||
"frame_height",
|
||||
"mqtt_off_delay",
|
||||
],
|
||||
},
|
||||
camera: {
|
||||
restartRequired: ["frame_height"],
|
||||
},
|
||||
};
|
||||
|
||||
export default motion;
|
||||
@@ -0,0 +1,73 @@
|
||||
import type { SectionConfigOverrides } from "./types";
|
||||
|
||||
const mqtt: SectionConfigOverrides = {
|
||||
base: {
|
||||
sectionDocs: "/integrations/mqtt",
|
||||
restartRequired: [],
|
||||
fieldOrder: [
|
||||
"enabled",
|
||||
"timestamp",
|
||||
"bounding_box",
|
||||
"crop",
|
||||
"height",
|
||||
"required_zones",
|
||||
"quality",
|
||||
],
|
||||
hiddenFields: [],
|
||||
advancedFields: ["height", "quality"],
|
||||
overrideFields: [],
|
||||
uiSchema: {
|
||||
required_zones: {
|
||||
"ui:widget": "zoneNames",
|
||||
},
|
||||
},
|
||||
},
|
||||
global: {
|
||||
fieldOrder: [
|
||||
"enabled",
|
||||
"host",
|
||||
"port",
|
||||
"user",
|
||||
"password",
|
||||
"topic_prefix",
|
||||
"client_id",
|
||||
"stats_interval",
|
||||
"qos",
|
||||
"tls_ca_certs",
|
||||
"tls_client_cert",
|
||||
"tls_client_key",
|
||||
"tls_insecure",
|
||||
],
|
||||
advancedFields: [
|
||||
"stats_interval",
|
||||
"qos",
|
||||
"tls_ca_certs",
|
||||
"tls_client_cert",
|
||||
"tls_client_key",
|
||||
"tls_insecure",
|
||||
],
|
||||
restartRequired: [
|
||||
"enabled",
|
||||
"host",
|
||||
"port",
|
||||
"user",
|
||||
"password",
|
||||
"topic_prefix",
|
||||
"client_id",
|
||||
"stats_interval",
|
||||
"qos",
|
||||
"tls_ca_certs",
|
||||
"tls_client_cert",
|
||||
"tls_client_key",
|
||||
"tls_insecure",
|
||||
],
|
||||
liveValidate: true,
|
||||
uiSchema: {
|
||||
password: {
|
||||
"ui:options": { size: "xs" },
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default mqtt;
|
||||
@@ -0,0 +1,30 @@
|
||||
import type { SectionConfigOverrides } from "./types";
|
||||
|
||||
const networking: SectionConfigOverrides = {
|
||||
base: {
|
||||
sectionDocs: "/configuration/advanced",
|
||||
fieldDocs: {
|
||||
"listen.internal": "/configuration/advanced#listen-on-different-ports",
|
||||
"listen.external": "/configuration/advanced#listen-on-different-ports",
|
||||
},
|
||||
restartRequired: ["ipv6.enabled", "listen.internal", "listen.external"],
|
||||
fieldOrder: [],
|
||||
advancedFields: [],
|
||||
uiSchema: {
|
||||
"listen.internal": {
|
||||
"ui:options": {
|
||||
suppressMultiSchema: true,
|
||||
size: "sm",
|
||||
},
|
||||
},
|
||||
"listen.external": {
|
||||
"ui:options": {
|
||||
suppressMultiSchema: true,
|
||||
size: "sm",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default networking;
|
||||
@@ -0,0 +1,26 @@
|
||||
import type { SectionConfigOverrides } from "./types";
|
||||
|
||||
const notifications: SectionConfigOverrides = {
|
||||
base: {
|
||||
sectionDocs: "/configuration/notifications",
|
||||
restartRequired: [],
|
||||
fieldOrder: ["enabled", "email"],
|
||||
fieldGroups: {},
|
||||
hiddenFields: ["enabled_in_config"],
|
||||
advancedFields: [],
|
||||
},
|
||||
global: {
|
||||
uiSchema: {
|
||||
"ui:before": { render: "NotificationsSettingsExtras" },
|
||||
enabled: { "ui:widget": "hidden" },
|
||||
email: { "ui:widget": "hidden" },
|
||||
cooldown: { "ui:widget": "hidden" },
|
||||
enabled_in_config: { "ui:widget": "hidden" },
|
||||
},
|
||||
},
|
||||
camera: {
|
||||
hiddenFields: ["enabled_in_config", "email"],
|
||||
},
|
||||
};
|
||||
|
||||
export default notifications;
|
||||
@@ -0,0 +1,104 @@
|
||||
import type { SectionConfigOverrides } from "./types";
|
||||
|
||||
const objects: SectionConfigOverrides = {
|
||||
base: {
|
||||
sectionDocs: "/configuration/object_filters",
|
||||
fieldDocs: {
|
||||
"filters.min_area": "/configuration/object_filters#object-area",
|
||||
"filters.max_area": "/configuration/object_filters#object-area",
|
||||
"filters.min_score": "/configuration/object_filters#minimum-score",
|
||||
"filters.threshold": "/configuration/object_filters#threshold",
|
||||
"filters.min_ratio": "/configuration/object_filters/#object-proportions",
|
||||
"filters.max_ratio": "/configuration/object_filters/#object-proportions",
|
||||
},
|
||||
restartRequired: [],
|
||||
fieldOrder: ["track", "alert", "detect", "filters"],
|
||||
fieldGroups: {
|
||||
tracking: ["track", "alert", "detect"],
|
||||
filtering: ["filters"],
|
||||
},
|
||||
hiddenFields: [
|
||||
"enabled_in_config",
|
||||
"mask",
|
||||
"raw_mask",
|
||||
"genai.enabled_in_config",
|
||||
"filters.*.mask",
|
||||
"filters.*.raw_mask",
|
||||
"filters.mask",
|
||||
"filters.raw_mask",
|
||||
],
|
||||
advancedFields: ["genai"],
|
||||
uiSchema: {
|
||||
"filters.*.min_area": {
|
||||
"ui:options": {
|
||||
suppressMultiSchema: true,
|
||||
},
|
||||
},
|
||||
"filters.*": {
|
||||
"ui:options": {
|
||||
additionalPropertyKeyReadonly: true,
|
||||
},
|
||||
},
|
||||
"filters.*.max_area": {
|
||||
"ui:options": {
|
||||
suppressMultiSchema: true,
|
||||
},
|
||||
},
|
||||
track: {
|
||||
"ui:widget": "objectLabels",
|
||||
"ui:options": {
|
||||
suppressMultiSchema: true,
|
||||
},
|
||||
},
|
||||
genai: {
|
||||
objects: {
|
||||
"ui:widget": "objectLabels",
|
||||
"ui:options": {
|
||||
suppressMultiSchema: true,
|
||||
},
|
||||
},
|
||||
prompt: {
|
||||
"ui:widget": "textarea",
|
||||
"ui:options": {
|
||||
size: "full",
|
||||
},
|
||||
},
|
||||
object_prompts: {
|
||||
additionalProperties: {
|
||||
"ui:options": {
|
||||
size: "full",
|
||||
},
|
||||
},
|
||||
},
|
||||
required_zones: {
|
||||
"ui:widget": "zoneNames",
|
||||
"ui:options": {
|
||||
suppressMultiSchema: true,
|
||||
},
|
||||
},
|
||||
enabled_in_config: {
|
||||
"ui:widget": "hidden",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
global: {
|
||||
restartRequired: ["track", "alert", "detect", "filters", "genai"],
|
||||
hiddenFields: [
|
||||
"enabled_in_config",
|
||||
"mask",
|
||||
"raw_mask",
|
||||
"genai.enabled_in_config",
|
||||
"filters.*.mask",
|
||||
"filters.*.raw_mask",
|
||||
"filters.mask",
|
||||
"filters.raw_mask",
|
||||
"genai.required_zones",
|
||||
],
|
||||
},
|
||||
camera: {
|
||||
restartRequired: [],
|
||||
},
|
||||
};
|
||||
|
||||
export default objects;
|
||||
@@ -0,0 +1,46 @@
|
||||
import type { SectionConfigOverrides } from "./types";
|
||||
|
||||
const onvif: SectionConfigOverrides = {
|
||||
base: {
|
||||
sectionDocs: "/configuration/cameras#setting-up-camera-ptz-controls",
|
||||
restartRequired: [
|
||||
"host",
|
||||
"port",
|
||||
"user",
|
||||
"password",
|
||||
"tls_insecure",
|
||||
"ignore_time_mismatch",
|
||||
"autotracking.calibrate_on_startup",
|
||||
],
|
||||
fieldOrder: [
|
||||
"host",
|
||||
"port",
|
||||
"user",
|
||||
"password",
|
||||
"tls_insecure",
|
||||
"ignore_time_mismatch",
|
||||
"autotracking",
|
||||
],
|
||||
hiddenFields: [
|
||||
"autotracking.enabled_in_config",
|
||||
"autotracking.movement_weights",
|
||||
],
|
||||
advancedFields: ["tls_insecure", "ignore_time_mismatch"],
|
||||
overrideFields: [],
|
||||
uiSchema: {
|
||||
host: {
|
||||
"ui:options": { size: "sm" },
|
||||
},
|
||||
autotracking: {
|
||||
required_zones: {
|
||||
"ui:widget": "zoneNames",
|
||||
},
|
||||
track: {
|
||||
"ui:widget": "objectLabels",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default onvif;
|
||||
@@ -0,0 +1,33 @@
|
||||
import type { SectionConfigOverrides } from "./types";
|
||||
|
||||
const proxy: SectionConfigOverrides = {
|
||||
base: {
|
||||
sectionDocs: "/configuration/authentication#proxy",
|
||||
restartRequired: [],
|
||||
fieldOrder: [
|
||||
"header_map",
|
||||
"logout_url",
|
||||
"auth_secret",
|
||||
"default_role",
|
||||
"separator",
|
||||
],
|
||||
advancedFields: ["header_map", "auth_secret", "separator"],
|
||||
liveValidate: true,
|
||||
uiSchema: {
|
||||
logout_url: {
|
||||
"ui:options": { size: "lg" },
|
||||
},
|
||||
auth_secret: {
|
||||
"ui:options": { size: "md" },
|
||||
},
|
||||
header_map: {
|
||||
"ui:after": { render: "ProxyRoleMap" },
|
||||
},
|
||||
"header_map.role_map": {
|
||||
"ui:widget": "hidden",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default proxy;
|
||||
@@ -0,0 +1,48 @@
|
||||
import type { SectionConfigOverrides } from "./types";
|
||||
|
||||
const record: SectionConfigOverrides = {
|
||||
base: {
|
||||
sectionDocs: "/configuration/record",
|
||||
restartRequired: [],
|
||||
fieldOrder: [
|
||||
"enabled",
|
||||
"expire_interval",
|
||||
"continuous",
|
||||
"motion",
|
||||
"alerts",
|
||||
"detections",
|
||||
"preview",
|
||||
"export",
|
||||
],
|
||||
fieldGroups: {
|
||||
retention: ["enabled", "continuous", "motion"],
|
||||
events: ["alerts", "detections"],
|
||||
},
|
||||
hiddenFields: ["enabled_in_config", "sync_recordings"],
|
||||
advancedFields: ["expire_interval", "preview", "export"],
|
||||
uiSchema: {
|
||||
export: {
|
||||
hwaccel_args: {
|
||||
"ui:options": { size: "lg" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
global: {
|
||||
restartRequired: [
|
||||
"enabled",
|
||||
"expire_interval",
|
||||
"continuous",
|
||||
"motion",
|
||||
"alerts",
|
||||
"detections",
|
||||
"preview",
|
||||
"export",
|
||||
],
|
||||
},
|
||||
camera: {
|
||||
restartRequired: [],
|
||||
},
|
||||
};
|
||||
|
||||
export default record;
|
||||
@@ -0,0 +1,54 @@
|
||||
import type { SectionConfigOverrides } from "./types";
|
||||
|
||||
const review: SectionConfigOverrides = {
|
||||
base: {
|
||||
sectionDocs: "/configuration/review",
|
||||
restartRequired: [],
|
||||
fieldOrder: ["alerts", "detections", "genai"],
|
||||
fieldGroups: {},
|
||||
hiddenFields: [
|
||||
"enabled_in_config",
|
||||
"alerts.labels",
|
||||
"alerts.enabled_in_config",
|
||||
"detections.labels",
|
||||
"detections.enabled_in_config",
|
||||
"genai.enabled_in_config",
|
||||
],
|
||||
advancedFields: [],
|
||||
uiSchema: {
|
||||
alerts: {
|
||||
"ui:before": { render: "CameraReviewStatusToggles" },
|
||||
required_zones: {
|
||||
"ui:widget": "hidden",
|
||||
},
|
||||
},
|
||||
detections: {
|
||||
required_zones: {
|
||||
"ui:widget": "hidden",
|
||||
},
|
||||
},
|
||||
genai: {
|
||||
additional_concerns: {
|
||||
"ui:widget": "textarea",
|
||||
"ui:options": {
|
||||
size: "full",
|
||||
},
|
||||
},
|
||||
activity_context_prompt: {
|
||||
"ui:widget": "textarea",
|
||||
"ui:options": {
|
||||
size: "full",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
global: {
|
||||
restartRequired: ["alerts", "detections", "genai"],
|
||||
},
|
||||
camera: {
|
||||
restartRequired: [],
|
||||
},
|
||||
};
|
||||
|
||||
export default review;
|
||||
@@ -0,0 +1,24 @@
|
||||
import type { SectionConfigOverrides } from "./types";
|
||||
|
||||
const semanticSearch: SectionConfigOverrides = {
|
||||
base: {
|
||||
sectionDocs: "/configuration/semantic_search",
|
||||
restartRequired: [],
|
||||
hiddenFields: [],
|
||||
advancedFields: [],
|
||||
overrideFields: [],
|
||||
uiSchema: {
|
||||
enabled: {
|
||||
"ui:after": { render: "SemanticSearchReindex" },
|
||||
},
|
||||
},
|
||||
},
|
||||
global: {
|
||||
fieldOrder: ["enabled", "reindex", "model", "model_size", "device"],
|
||||
advancedFields: ["reindex", "device"],
|
||||
restartRequired: ["enabled", "model", "model_size", "device"],
|
||||
hiddenFields: ["reindex"],
|
||||
},
|
||||
};
|
||||
|
||||
export default semanticSearch;
|
||||
@@ -0,0 +1,45 @@
|
||||
import type { SectionConfigOverrides } from "./types";
|
||||
|
||||
const snapshots: SectionConfigOverrides = {
|
||||
base: {
|
||||
sectionDocs: "/configuration/snapshots",
|
||||
restartRequired: [],
|
||||
fieldOrder: [
|
||||
"enabled",
|
||||
"bounding_box",
|
||||
"crop",
|
||||
"quality",
|
||||
"timestamp",
|
||||
"retain",
|
||||
],
|
||||
fieldGroups: {
|
||||
display: ["enabled", "bounding_box", "crop", "quality", "timestamp"],
|
||||
},
|
||||
hiddenFields: ["enabled_in_config"],
|
||||
advancedFields: ["height", "quality", "retain"],
|
||||
uiSchema: {
|
||||
required_zones: {
|
||||
"ui:widget": "zoneNames",
|
||||
"ui:options": {
|
||||
suppressMultiSchema: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
global: {
|
||||
restartRequired: [
|
||||
"enabled",
|
||||
"bounding_box",
|
||||
"crop",
|
||||
"quality",
|
||||
"timestamp",
|
||||
"retain",
|
||||
],
|
||||
hiddenFields: ["enabled_in_config", "required_zones"],
|
||||
},
|
||||
camera: {
|
||||
restartRequired: [],
|
||||
},
|
||||
};
|
||||
|
||||
export default snapshots;
|
||||
@@ -0,0 +1,19 @@
|
||||
import type { SectionConfigOverrides } from "./types";
|
||||
|
||||
const telemetry: SectionConfigOverrides = {
|
||||
base: {
|
||||
sectionDocs: "/configuration/reference",
|
||||
restartRequired: [
|
||||
"network_interfaces",
|
||||
"stats.amd_gpu_stats",
|
||||
"stats.intel_gpu_stats",
|
||||
"stats.intel_gpu_device",
|
||||
"stats.network_bandwidth",
|
||||
"version_check",
|
||||
],
|
||||
fieldOrder: ["network_interfaces", "stats", "version_check"],
|
||||
advancedFields: [],
|
||||
},
|
||||
};
|
||||
|
||||
export default telemetry;
|
||||
@@ -0,0 +1,27 @@
|
||||
import type { SectionConfigOverrides } from "./types";
|
||||
|
||||
const timestampStyle: SectionConfigOverrides = {
|
||||
base: {
|
||||
sectionDocs: "/configuration/reference",
|
||||
restartRequired: [],
|
||||
fieldOrder: ["position", "format", "color", "thickness"],
|
||||
hiddenFields: ["effect", "enabled_in_config"],
|
||||
advancedFields: [],
|
||||
uiSchema: {
|
||||
position: {
|
||||
"ui:size": "xs",
|
||||
},
|
||||
format: {
|
||||
"ui:size": "xs",
|
||||
},
|
||||
},
|
||||
},
|
||||
global: {
|
||||
restartRequired: ["position", "format", "color", "thickness", "effect"],
|
||||
},
|
||||
camera: {
|
||||
restartRequired: [],
|
||||
},
|
||||
};
|
||||
|
||||
export default timestampStyle;
|
||||
@@ -0,0 +1,20 @@
|
||||
import type { SectionConfigOverrides } from "./types";
|
||||
|
||||
const tls: SectionConfigOverrides = {
|
||||
base: {
|
||||
sectionDocs: "/configuration/tls",
|
||||
restartRequired: ["enabled"],
|
||||
fieldOrder: ["enabled", "cert", "key"],
|
||||
advancedFields: [],
|
||||
uiSchema: {
|
||||
cert: {
|
||||
"ui:options": { size: "md" },
|
||||
},
|
||||
key: {
|
||||
"ui:options": { size: "md" },
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default tls;
|
||||
@@ -0,0 +1,7 @@
|
||||
import type { SectionConfig } from "../sections/BaseSection";
|
||||
|
||||
export type SectionConfigOverrides = {
|
||||
base?: SectionConfig;
|
||||
global?: Partial<SectionConfig>;
|
||||
camera?: Partial<SectionConfig>;
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
import type { SectionConfigOverrides } from "./types";
|
||||
|
||||
const ui: SectionConfigOverrides = {
|
||||
base: {
|
||||
sectionDocs: "/configuration/reference",
|
||||
restartRequired: [],
|
||||
fieldOrder: ["dashboard", "order"],
|
||||
hiddenFields: [],
|
||||
advancedFields: [],
|
||||
overrideFields: [],
|
||||
},
|
||||
global: {
|
||||
fieldOrder: [
|
||||
"timezone",
|
||||
"time_format",
|
||||
"date_style",
|
||||
"time_style",
|
||||
"unit_system",
|
||||
],
|
||||
advancedFields: [],
|
||||
restartRequired: ["unit_system"],
|
||||
uiSchema: {
|
||||
timezone: {
|
||||
"ui:widget": "timezoneSelect",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default ui;
|
||||
Reference in New Issue
Block a user