Resolve issues where JSON fields are not being rendered in form mode

This commit is contained in:
Ola Hungerford
2025-02-26 19:34:33 -07:00
parent 592dacad39
commit 0e29e2c1cf

View File

@@ -1,4 +1,4 @@
import { useState } from "react"; import { useState, useEffect } from "react";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label"; import { Label } from "@/components/ui/label";
@@ -73,25 +73,24 @@ const DynamicJsonForm = ({
JSON.stringify(value ?? generateDefaultValue(schema), null, 2) JSON.stringify(value ?? generateDefaultValue(schema), null, 2)
); );
const validateJsonBeforeSubmit = () => { // Update rawJsonValue when value prop changes
if (isJsonMode && rawJsonValue) { useEffect(() => {
try { if (!isJsonMode) {
const parsed = JSON.parse(rawJsonValue); setRawJsonValue(JSON.stringify(value ?? generateDefaultValue(schema), null, 2));
onChange(parsed);
setJsonError(undefined);
return true;
} catch (err) {
setJsonError(err instanceof Error ? err.message : "Invalid JSON");
return false;
} }
} }, [value, schema, isJsonMode]);
return true;
};
const handleSwitchToFormMode = () => { const handleSwitchToFormMode = () => {
if (isJsonMode) { if (isJsonMode) {
if (validateJsonBeforeSubmit()) { // When switching to Form mode, ensure we have valid JSON
try {
const parsed = JSON.parse(rawJsonValue);
// Update the parent component's state with the parsed value
onChange(parsed);
// Switch to form mode
setIsJsonMode(false); setIsJsonMode(false);
} catch (err) {
setJsonError(err instanceof Error ? err.message : "Invalid JSON");
} }
} else { } else {
// Update raw JSON value when switching to JSON mode // Update raw JSON value when switching to JSON mode
@@ -160,8 +159,12 @@ const DynamicJsonForm = ({
className="w-4 h-4" className="w-4 h-4"
/> />
); );
case "object": case "object": {
if (!propSchema.properties) return null; // Handle case where we have a value but no schema properties
const objectValue = currentValue as JsonObject || {};
// If we have schema properties, use them to render fields
if (propSchema.properties) {
return ( return (
<div className="space-y-4 border rounded-md p-4"> <div className="space-y-4 border rounded-md p-4">
{Object.entries(propSchema.properties).map(([key, prop]) => ( {Object.entries(propSchema.properties).map(([key, prop]) => (
@@ -169,7 +172,7 @@ const DynamicJsonForm = ({
<Label>{formatFieldLabel(key)}</Label> <Label>{formatFieldLabel(key)}</Label>
{renderFormFields( {renderFormFields(
prop, prop,
(currentValue as JsonObject)?.[key], objectValue[key],
[...path, key], [...path, key],
depth + 1, depth + 1,
)} )}
@@ -177,6 +180,29 @@ const DynamicJsonForm = ({
))} ))}
</div> </div>
); );
}
// If we have a value but no schema properties, render fields based on the value
else if (Object.keys(objectValue).length > 0) {
return (
<div className="space-y-4 border rounded-md p-4">
{Object.entries(objectValue).map(([key, value]) => (
<div key={key} className="space-y-2">
<Label>{formatFieldLabel(key)}</Label>
<Input
type="text"
value={String(value)}
onChange={(e) =>
handleFieldChange([...path, key], e.target.value)
}
/>
</div>
))}
</div>
);
}
// If we have neither schema properties nor value, return null
return null;
}
case "array": { case "array": {
const arrayValue = Array.isArray(currentValue) ? currentValue : []; const arrayValue = Array.isArray(currentValue) ? currentValue : [];
if (!propSchema.items) return null; if (!propSchema.items) return null;
@@ -384,8 +410,23 @@ const DynamicJsonForm = ({
}} }}
error={jsonError} error={jsonError}
/> />
) : (
// If schema type is object but value is not an object or is empty, and we have actual JSON data,
// render a simple representation of the JSON data
schema.type === "object" &&
(typeof value !== "object" || value === null || Object.keys(value).length === 0) &&
rawJsonValue &&
rawJsonValue !== "{}" ? (
<div className="space-y-4 border rounded-md p-4">
<p className="text-sm text-gray-500">Form view not available for this JSON structure. Using simplified view:</p>
<pre className="bg-gray-50 dark:bg-gray-800 dark:text-gray-100 p-4 rounded text-sm overflow-auto">
{rawJsonValue}
</pre>
<p className="text-sm text-gray-500">Use JSON mode for full editing capabilities.</p>
</div>
) : ( ) : (
renderFormFields(schema, value) renderFormFields(schema, value)
)
)} )}
</div> </div>
); );