fix: widget edit crash (#185) + resizable textarea for complex fields
WidgetConfigDialog crashed on edit with React error #185 (Maximum update depth exceeded) when the references/instances query returned undefined and the inline '= []' fallback created a new array ref every render, looping the auto-edit useEffect. Stabilize via useMemo(data ?? []). Also moved the referencedWidgetIds Set inside the availableWidgets useMemo (clears the pre-existing exhaustive-deps warning). Complex config fields (promql, query, text, command, notes, or opt-in via format: 'textarea') now render as a taller resizable Textarea (rows=6, min-h-120px, font-mono, resize) in both WidgetConfigFields and ServiceConfigFields, instead of a single-line Input. Build + lint clean (referencedWidgetIds warning gone), 165 vitest pass.
This commit is contained in:
@@ -5,6 +5,7 @@ import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
import {
|
||||
Dialog,
|
||||
@@ -99,20 +100,33 @@ function ServiceConfigFields({
|
||||
const properties =
|
||||
(
|
||||
type.config_schema as {
|
||||
properties?: Record<string, { type?: string; description?: string }>;
|
||||
properties?: Record<string, { type?: string; description?: string; format?: string }>;
|
||||
}
|
||||
).properties ?? {};
|
||||
// Multi-line resizable textarea for fields that hold complex values (opt-in
|
||||
// via `format: "textarea"`, or well-known multi-line keys).
|
||||
const TEXTAREA_KEYS = new Set(["notes", "command"]);
|
||||
return (
|
||||
<div className="flex flex-col gap-3">
|
||||
{Object.entries(properties).map(([key, schema]) => {
|
||||
const isNumber = schema.type === "integer" || schema.type === "number";
|
||||
const isTextarea = schema.format === "textarea" || TEXTAREA_KEYS.has(key);
|
||||
return (
|
||||
<Field
|
||||
key={key}
|
||||
label={key}
|
||||
htmlFor={`cfg-${key}`}
|
||||
helper={schema.description}
|
||||
>
|
||||
<Field
|
||||
key={key}
|
||||
label={key}
|
||||
htmlFor={`cfg-${key}`}
|
||||
helper={schema.description}
|
||||
>
|
||||
{isTextarea ? (
|
||||
<Textarea
|
||||
id={`cfg-${key}`}
|
||||
rows={6}
|
||||
className="resize font-mono text-xs min-h-[120px]"
|
||||
value={String(config[key] ?? "")}
|
||||
onChange={(e) => onChange({ ...config, [key]: e.target.value })}
|
||||
/>
|
||||
) : (
|
||||
<Input
|
||||
id={`cfg-${key}`}
|
||||
type={isNumber ? "number" : "text"}
|
||||
@@ -128,7 +142,8 @@ function ServiceConfigFields({
|
||||
})
|
||||
}
|
||||
/>
|
||||
</Field>
|
||||
)}
|
||||
</Field>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user