From 081c9ec22833fa9c1f79a498d361a87b3ddc88ca Mon Sep 17 00:00:00 2001 From: Nicolas Mowen Date: Sat, 24 May 2025 10:16:53 -0600 Subject: [PATCH] Adjust Frigate config editor when in safe mode --- web/public/locales/en/views/configEditor.json | 2 + web/src/pages/ConfigEditor.tsx | 43 ++++++++++++------- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/web/public/locales/en/views/configEditor.json b/web/public/locales/en/views/configEditor.json index ef3035f38..614143c16 100644 --- a/web/public/locales/en/views/configEditor.json +++ b/web/public/locales/en/views/configEditor.json @@ -1,6 +1,8 @@ { "documentTitle": "Config Editor - Frigate", "configEditor": "Config Editor", + "safeConfigEditor": "Config Editor (Safe Mode)", + "safeModeDescription": "Frigate is in safe mode due to a config validation error.", "copyConfig": "Copy Config", "saveAndRestart": "Save & Restart", "saveOnly": "Save Only", diff --git a/web/src/pages/ConfigEditor.tsx b/web/src/pages/ConfigEditor.tsx index 01d76303d..e6ac593d0 100644 --- a/web/src/pages/ConfigEditor.tsx +++ b/web/src/pages/ConfigEditor.tsx @@ -1,7 +1,7 @@ import useSWR from "swr"; import * as monaco from "monaco-editor"; import { configureMonacoYaml } from "monaco-yaml"; -import { useCallback, useEffect, useRef, useState } from "react"; +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { useApiHost } from "@/api"; import Heading from "@/components/ui/heading"; import ActivityIndicator from "@/components/indicators/activity-indicator"; @@ -16,6 +16,7 @@ import { MdOutlineRestartAlt } from "react-icons/md"; import RestartDialog from "@/components/overlay/dialog/RestartDialog"; import { useTranslation } from "react-i18next"; import { useRestart } from "@/api/ws"; +import { FrigateConfig } from "@/types/frigateConfig"; type SaveOptions = "saveonly" | "restart"; @@ -32,7 +33,10 @@ function ConfigEditor() { document.title = t("documentTitle"); }, [t]); - const { data: config } = useSWR("config/raw"); + const { data: config } = useSWR("config", { + revalidateOnFocus: false, + }); + const { data: rawConfig } = useSWR("config/raw"); const { theme, systemTheme } = useTheme(); const [error, setError] = useState(); @@ -102,7 +106,7 @@ function ConfigEditor() { }, [onHandleSaveConfig]); useEffect(() => { - if (!config) { + if (!rawConfig) { return; } @@ -129,9 +133,9 @@ function ConfigEditor() { } if (!modelRef.current) { - modelRef.current = monaco.editor.createModel(config, "yaml", modelUri); + modelRef.current = monaco.editor.createModel(rawConfig, "yaml", modelUri); } else { - modelRef.current.setValue(config); + modelRef.current.setValue(rawConfig); } const container = configRef.current; @@ -164,32 +168,32 @@ function ConfigEditor() { } schemaConfiguredRef.current = false; }; - }, [config, apiHost, systemTheme, theme, onHandleSaveConfig]); + }, [rawConfig, apiHost, systemTheme, theme, onHandleSaveConfig]); // monitoring state const [hasChanges, setHasChanges] = useState(false); useEffect(() => { - if (!config || !modelRef.current) { + if (!rawConfig || !modelRef.current) { return; } modelRef.current.onDidChangeContent(() => { - if (modelRef.current?.getValue() != config) { + if (modelRef.current?.getValue() != rawConfig) { setHasChanges(true); } else { setHasChanges(false); } }); - }, [config]); + }, [rawConfig]); useEffect(() => { - if (config && modelRef.current) { - modelRef.current.setValue(config); + if (rawConfig && modelRef.current) { + modelRef.current.setValue(rawConfig); setHasChanges(false); } - }, [config]); + }, [rawConfig]); useEffect(() => { let listener: ((e: BeforeUnloadEvent) => void) | undefined; @@ -209,7 +213,7 @@ function ConfigEditor() { }; }, [hasChanges, t]); - if (!config) { + if (!rawConfig) { return ; } @@ -217,9 +221,16 @@ function ConfigEditor() {
- - {t("configEditor")} - +
+ + {t(config?.safe_mode ? "safeConfigEditor" : "configEditor")} + + {config?.safe_mode && ( +
+ {t("safeModeDescription")} +
+ )} +