feat(frontend): widget registry + universal fallback
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
import { useState } from "react";
|
||||
import type { WidgetProps } from "./types";
|
||||
|
||||
export function FallbackWidget({ descriptor, onRespond }: WidgetProps) {
|
||||
const [text, setText] = useState("");
|
||||
return (
|
||||
<div className="border rounded p-3 space-y-2">
|
||||
<p className="text-sm text-amber-600">Widget non supportato (kind: {descriptor.widget}) — rispondi manualmente</p>
|
||||
<pre className="text-xs overflow-auto max-h-48 bg-muted p-2">{JSON.stringify(descriptor, null, 2)}</pre>
|
||||
<textarea className="w-full border rounded p-1" value={text} onChange={(e) => setText(e.target.value)} />
|
||||
<button className="border rounded px-2 py-1" onClick={() => onRespond({ id: descriptor.id, control: "freetext", text })}>Invia</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import { register, resolve } from "./registry";
|
||||
import type { WidgetProps } from "./types";
|
||||
|
||||
test("resolve returns the registered renderer", () => {
|
||||
const Dummy = (_: WidgetProps) => <div>dummy</div>;
|
||||
register("dummy", Dummy);
|
||||
expect(resolve("dummy")).toBe(Dummy);
|
||||
});
|
||||
|
||||
test("resolve falls back for unknown kind and shows the JSON", () => {
|
||||
const Comp = resolve("totally-unknown");
|
||||
render(<Comp descriptor={{ id: "u1", widget: "totally-unknown", title: "X" } as any} onRespond={() => {}} />);
|
||||
expect(screen.getByText(/Widget non supportato/i)).toBeInTheDocument();
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
import type React from "react";
|
||||
import type { WidgetProps } from "./types";
|
||||
import { FallbackWidget } from "./FallbackWidget";
|
||||
|
||||
const registry = new Map<string, React.FC<WidgetProps>>();
|
||||
|
||||
export function register(kind: string, comp: React.FC<WidgetProps>) {
|
||||
registry.set(kind, comp);
|
||||
}
|
||||
|
||||
export function resolve(kind: string): React.FC<WidgetProps> {
|
||||
return registry.get(kind) ?? FallbackWidget;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
import type { WidgetDescriptor, UiResponse } from "../api/types";
|
||||
|
||||
export type WidgetProps = { descriptor: WidgetDescriptor; onRespond: (r: UiResponse) => void };
|
||||
Reference in New Issue
Block a user