mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-04-05 06:44:53 +03:00
fix genai additional_concerns validation error with textarea array widget
The additional_concerns field is list[str] in the backend but was using the textarea widget which produces a string value, causing validation errors. Created a TextareaArrayWidget that converts between array (one item per line) and textarea display, and switched additional_concerns to use it
This commit is contained in:
parent
5f61079f81
commit
b74dcf43b2
@ -29,7 +29,7 @@ const review: SectionConfigOverrides = {
|
||||
},
|
||||
genai: {
|
||||
additional_concerns: {
|
||||
"ui:widget": "textarea",
|
||||
"ui:widget": "textareaArray",
|
||||
"ui:options": {
|
||||
size: "full",
|
||||
},
|
||||
|
||||
@ -30,6 +30,7 @@ import { CameraPathWidget } from "./widgets/CameraPathWidget";
|
||||
import { OptionalFieldWidget } from "./widgets/OptionalFieldWidget";
|
||||
import { SemanticSearchModelWidget } from "./widgets/SemanticSearchModelWidget";
|
||||
import { OnvifProfileWidget } from "./widgets/OnvifProfileWidget";
|
||||
import { TextareaArrayWidget } from "./widgets/TextareaArrayWidget";
|
||||
|
||||
import { FieldTemplate } from "./templates/FieldTemplate";
|
||||
import { ObjectFieldTemplate } from "./templates/ObjectFieldTemplate";
|
||||
@ -81,6 +82,7 @@ export const frigateTheme: FrigateTheme = {
|
||||
optionalField: OptionalFieldWidget,
|
||||
semanticSearchModel: SemanticSearchModelWidget,
|
||||
onvifProfile: OnvifProfileWidget,
|
||||
textareaArray: TextareaArrayWidget,
|
||||
},
|
||||
templates: {
|
||||
FieldTemplate: FieldTemplate as React.ComponentType<FieldTemplateProps>,
|
||||
|
||||
@ -0,0 +1,50 @@
|
||||
// Textarea Array Widget - displays an array of strings as a multiline textarea
|
||||
// Each line in the textarea corresponds to one item in the array.
|
||||
import type { WidgetProps } from "@rjsf/utils";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { getSizedFieldClassName } from "../utils";
|
||||
import { useCallback } from "react";
|
||||
|
||||
export function TextareaArrayWidget(props: WidgetProps) {
|
||||
const { id, value, disabled, readonly, onChange, onBlur, onFocus, schema, options } =
|
||||
props;
|
||||
|
||||
// Convert array to newline-separated text for display
|
||||
let textValue = "";
|
||||
if (Array.isArray(value) && value.length > 0) {
|
||||
textValue = value.join("\n");
|
||||
} else if (typeof value === "string") {
|
||||
textValue = value;
|
||||
}
|
||||
|
||||
const fieldClassName = getSizedFieldClassName(options, "md");
|
||||
|
||||
const handleChange = useCallback(
|
||||
(e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
||||
const text = e.target.value;
|
||||
if (text === "") {
|
||||
onChange([]);
|
||||
return;
|
||||
}
|
||||
// Split by newlines and filter out empty lines
|
||||
const items = text.split("\n").filter((line) => line.trim() !== "");
|
||||
onChange(items);
|
||||
},
|
||||
[onChange],
|
||||
);
|
||||
|
||||
return (
|
||||
<Textarea
|
||||
id={id}
|
||||
className={cn("text-md", fieldClassName)}
|
||||
value={textValue}
|
||||
disabled={disabled || readonly}
|
||||
rows={(options.rows as number) || 3}
|
||||
onChange={handleChange}
|
||||
onBlur={(e) => onBlur(id, e.target.value)}
|
||||
onFocus={(e) => onFocus(id, e.target.value)}
|
||||
aria-label={schema.title}
|
||||
/>
|
||||
);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user