Resolve merge conflicts in DynamicJsonForm.tsx and ToolsTab.tsx
- Merged JSON validation functionality from PR branch with enhanced form features from main - Preserved validateJson method and DynamicJsonFormRef interface for tool validation - Added support for oneOf schemas, enum dropdowns, and enhanced string field types - Integrated meta display functionality and resource content props - Maintained JSON validation before tool execution to prevent invalid data submission
This commit is contained in:
commit
8ce1bbd346
1 changed files with 3238 additions and 582 deletions
|
|
@ -28,10 +28,10 @@ export interface DynamicJsonFormRef {
|
|||
|
||||
const isSimpleObject = (schema: JsonSchemaType): boolean => {
|
||||
const supportedTypes = ["string", "number", "integer", "boolean", "null"];
|
||||
if (supportedTypes.includes(schema.type)) return true;
|
||||
if (schema.type && supportedTypes.includes(schema.type)) return true;
|
||||
if (schema.type === "object") {
|
||||
return Object.values(schema.properties ?? {}).every((prop) =>
|
||||
supportedTypes.includes(prop.type),
|
||||
return Object.values(schema.properties ?? {}).every(
|
||||
(prop) => prop.type && supportedTypes.includes(prop.type),
|
||||
);
|
||||
}
|
||||
if (schema.type === "array") {
|
||||
|
|
@ -236,10 +236,89 @@ const DynamicJsonForm = forwardRef<DynamicJsonFormRef, DynamicJsonFormProps>(
|
|||
parentSchema?.required?.includes(propertyName || "") ?? false;
|
||||
|
||||
switch (propSchema.type) {
|
||||
case "string":
|
||||
case "string": {
|
||||
if (
|
||||
propSchema.oneOf &&
|
||||
propSchema.oneOf.every(
|
||||
(option) =>
|
||||
typeof option.const === "string" &&
|
||||
typeof option.title === "string",
|
||||
)
|
||||
) {
|
||||
return (
|
||||
<select
|
||||
value={(currentValue as string) ?? ""}
|
||||
onChange={(e) => {
|
||||
const val = e.target.value;
|
||||
if (!val && !isRequired) {
|
||||
handleFieldChange(path, undefined);
|
||||
} else {
|
||||
handleFieldChange(path, val);
|
||||
}
|
||||
}}
|
||||
required={isRequired}
|
||||
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-800"
|
||||
>
|
||||
<option value="">Select an option...</option>
|
||||
{propSchema.oneOf.map((option) => (
|
||||
<option
|
||||
key={option.const as string}
|
||||
value={option.const as string}
|
||||
>
|
||||
{option.title as string}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
);
|
||||
}
|
||||
|
||||
if (propSchema.enum) {
|
||||
return (
|
||||
<select
|
||||
value={(currentValue as string) ?? ""}
|
||||
onChange={(e) => {
|
||||
const val = e.target.value;
|
||||
if (!val && !isRequired) {
|
||||
handleFieldChange(path, undefined);
|
||||
} else {
|
||||
handleFieldChange(path, val);
|
||||
}
|
||||
}}
|
||||
required={isRequired}
|
||||
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-800"
|
||||
>
|
||||
<option value="">Select an option...</option>
|
||||
{propSchema.enum.map((option) => (
|
||||
<option key={option} value={option}>
|
||||
{option}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
);
|
||||
}
|
||||
|
||||
let inputType = "text";
|
||||
switch (propSchema.format) {
|
||||
case "email":
|
||||
inputType = "email";
|
||||
break;
|
||||
case "uri":
|
||||
inputType = "url";
|
||||
break;
|
||||
case "date":
|
||||
inputType = "date";
|
||||
break;
|
||||
case "date-time":
|
||||
inputType = "datetime-local";
|
||||
break;
|
||||
default:
|
||||
inputType = "text";
|
||||
break;
|
||||
}
|
||||
|
||||
return (
|
||||
<Input
|
||||
type="text"
|
||||
type={inputType}
|
||||
value={(currentValue as string) ?? ""}
|
||||
onChange={(e) => {
|
||||
const val = e.target.value;
|
||||
|
|
@ -248,8 +327,13 @@ const DynamicJsonForm = forwardRef<DynamicJsonFormRef, DynamicJsonFormProps>(
|
|||
}}
|
||||
placeholder={propSchema.description}
|
||||
required={isRequired}
|
||||
minLength={propSchema.minLength}
|
||||
maxLength={propSchema.maxLength}
|
||||
pattern={propSchema.pattern}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
case "number":
|
||||
return (
|
||||
<Input
|
||||
|
|
@ -268,8 +352,11 @@ const DynamicJsonForm = forwardRef<DynamicJsonFormRef, DynamicJsonFormProps>(
|
|||
}}
|
||||
placeholder={propSchema.description}
|
||||
required={isRequired}
|
||||
min={propSchema.minimum}
|
||||
max={propSchema.maximum}
|
||||
/>
|
||||
);
|
||||
|
||||
case "integer":
|
||||
return (
|
||||
<Input
|
||||
|
|
@ -282,7 +369,6 @@ const DynamicJsonForm = forwardRef<DynamicJsonFormRef, DynamicJsonFormProps>(
|
|||
handleFieldChange(path, undefined);
|
||||
} else {
|
||||
const num = Number(val);
|
||||
// Only update if it's a valid integer
|
||||
if (!isNaN(num) && Number.isInteger(num)) {
|
||||
handleFieldChange(path, num);
|
||||
}
|
||||
|
|
@ -290,8 +376,11 @@ const DynamicJsonForm = forwardRef<DynamicJsonFormRef, DynamicJsonFormProps>(
|
|||
}}
|
||||
placeholder={propSchema.description}
|
||||
required={isRequired}
|
||||
min={propSchema.minimum}
|
||||
max={propSchema.maximum}
|
||||
/>
|
||||
);
|
||||
|
||||
case "boolean":
|
||||
return (
|
||||
<Input
|
||||
|
|
|
|||
Loading…
Reference in a new issue