mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-07-15 00:11:15 +03:00
fix DictAsYamlField feedback loop
formData sync overwrites user input, fix was to skip external sync while the field is focused
This commit is contained in:
parent
9ba81d6dc8
commit
f3a9bf7763
@ -2,7 +2,7 @@ import type { FieldPathList, FieldProps } from "@rjsf/utils";
|
|||||||
import yaml from "js-yaml";
|
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, useState } from "react";
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||||
|
|
||||||
function formatYaml(value: unknown): string {
|
function formatYaml(value: unknown): string {
|
||||||
if (
|
if (
|
||||||
@ -54,10 +54,14 @@ export function DictAsYamlField(props: FieldProps) {
|
|||||||
|
|
||||||
const [text, setText] = useState(() => formatYaml(formData));
|
const [text, setText] = useState(() => formatYaml(formData));
|
||||||
const [error, setError] = useState<string>();
|
const [error, setError] = useState<string>();
|
||||||
|
const focusedRef = useRef(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
// Only sync from external formData changes, not our own onChange
|
||||||
|
if (!focusedRef.current) {
|
||||||
setText(formatYaml(formData));
|
setText(formatYaml(formData));
|
||||||
setError(undefined);
|
setError(undefined);
|
||||||
|
}
|
||||||
}, [formData]);
|
}, [formData]);
|
||||||
|
|
||||||
const handleChange = useCallback(
|
const handleChange = useCallback(
|
||||||
@ -73,8 +77,13 @@ export function DictAsYamlField(props: FieldProps) {
|
|||||||
[onChange, fieldPath],
|
[onChange, fieldPath],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handleFocus = useCallback(() => {
|
||||||
|
focusedRef.current = true;
|
||||||
|
}, []);
|
||||||
|
|
||||||
const handleBlur = useCallback(
|
const handleBlur = useCallback(
|
||||||
(_e: React.FocusEvent<HTMLTextAreaElement>) => {
|
(_e: React.FocusEvent<HTMLTextAreaElement>) => {
|
||||||
|
focusedRef.current = false;
|
||||||
// Reformat on blur if valid
|
// Reformat on blur if valid
|
||||||
const { value } = parseYaml(text);
|
const { value } = parseYaml(text);
|
||||||
if (value !== undefined) {
|
if (value !== undefined) {
|
||||||
@ -101,6 +110,7 @@ export function DictAsYamlField(props: FieldProps) {
|
|||||||
placeholder={"key: value"}
|
placeholder={"key: value"}
|
||||||
rows={Math.max(3, text.split("\n").length + 1)}
|
rows={Math.max(3, text.split("\n").length + 1)}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
|
onFocus={handleFocus}
|
||||||
onBlur={handleBlur}
|
onBlur={handleBlur}
|
||||||
/>
|
/>
|
||||||
{error && <p className="text-xs text-destructive">{error}</p>}
|
{error && <p className="text-xs text-destructive">{error}</p>}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user