diff --git a/web/src/pages/ConfigEditor.tsx b/web/src/pages/ConfigEditor.tsx
index 55df04e34..dc351e7f7 100644
--- a/web/src/pages/ConfigEditor.tsx
+++ b/web/src/pages/ConfigEditor.tsx
@@ -124,12 +124,49 @@ function ConfigEditor() {
};
});
+ // monitoring state
+
+ const [hasChanges, setHasChanges] = useState(false);
+
+ useEffect(() => {
+ if (!config || !modelRef.current) {
+ return;
+ }
+
+ modelRef.current.onDidChangeContent(() => {
+ if (modelRef.current?.getValue() != config) {
+ setHasChanges(true);
+ } else {
+ setHasChanges(false);
+ }
+ });
+ }, [config]);
+
useEffect(() => {
if (config && modelRef.current) {
modelRef.current.setValue(config);
+ setHasChanges(false);
}
}, [config]);
+ useEffect(() => {
+ let listener: ((e: BeforeUnloadEvent) => void) | undefined;
+ if (hasChanges) {
+ listener = (e) => {
+ e.preventDefault();
+ e.returnValue = true;
+ return "Exit without saving?";
+ };
+ window.addEventListener("beforeunload", listener);
+ }
+
+ return () => {
+ if (listener) {
+ window.removeEventListener("beforeunload", listener);
+ }
+ };
+ }, [hasChanges]);
+
if (!config) {
return ;
}
diff --git a/web/src/pages/Logs.tsx b/web/src/pages/Logs.tsx
index 0691cb635..582190098 100644
--- a/web/src/pages/Logs.tsx
+++ b/web/src/pages/Logs.tsx
@@ -286,6 +286,7 @@ function Logs() {
key={item}
className={`flex items-center justify-between gap-2 ${logService == item ? "" : "text-muted-foreground"}`}
value={item}
+ data-nav-item={item}
aria-label={`Select ${item}`}
>
{item}
diff --git a/web/src/views/system/GeneralMetrics.tsx b/web/src/views/system/GeneralMetrics.tsx
index fa23d47b0..f617e9654 100644
--- a/web/src/views/system/GeneralMetrics.tsx
+++ b/web/src/views/system/GeneralMetrics.tsx
@@ -163,7 +163,7 @@ export default function GeneralMetrics({
series[key] = { name: key, data: [] };
}
- const data = stats.cpu_usages[detStats.pid.toString()].cpu;
+ const data = stats.cpu_usages[detStats.pid.toString()]?.cpu;
if (data != undefined) {
series[key].data.push({
@@ -304,7 +304,7 @@ export default function GeneralMetrics({
series[key] = { name: key, data: [] };
}
- const data = stats.cpu_usages[procStats.pid.toString()].cpu;
+ const data = stats.cpu_usages[procStats.pid.toString()]?.cpu;
if (data != undefined) {
series[key].data.push({
@@ -338,10 +338,14 @@ export default function GeneralMetrics({
series[key] = { name: key, data: [] };
}
- series[key].data.push({
- x: statsIdx + 1,
- y: stats.cpu_usages[procStats.pid.toString()].mem,
- });
+ const data = stats.cpu_usages[procStats.pid.toString()]?.mem;
+
+ if (data) {
+ series[key].data.push({
+ x: statsIdx + 1,
+ y: data,
+ });
+ }
}
});
});