new react-openapi
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
import React, { useCallback } from "react";
|
||||
import { Box, FormControl, InputLabel, Select, MenuItem, Typography } from "@mui/material";
|
||||
import type { FieldConfig } from "../../../types";
|
||||
import { FormFieldRenderer } from "../FormFieldRenderer";
|
||||
|
||||
interface Props {
|
||||
field: FieldConfig;
|
||||
value: any;
|
||||
onChange: (value: any) => void;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export function DiscriminatorField({ field, value, onChange, error }: Props) {
|
||||
const options = field.oneOfOptions ?? [];
|
||||
const discProp = field.discriminatorProperty ?? "type";
|
||||
const currentType = value?.[discProp] ?? "";
|
||||
|
||||
const handleTypeChange = useCallback((e: any) => {
|
||||
const newType = e.target.value;
|
||||
const option = options.find((o) => o.value === newType);
|
||||
const newValue: Record<string, any> = { [discProp]: newType };
|
||||
if (option) {
|
||||
for (const f of option.fields) {
|
||||
newValue[f.name] = f.enumValues?.[0] ?? f.type === "number" ? 0 : f.type === "integer" ? 0 : "";
|
||||
}
|
||||
}
|
||||
onChange(newValue);
|
||||
}, [discProp, onChange, options]);
|
||||
|
||||
const handleFieldChange = useCallback((fieldName: string, fieldValue: any) => {
|
||||
onChange({ ...(value ?? {}), [fieldName]: fieldValue });
|
||||
}, [onChange, value]);
|
||||
|
||||
const activeFields = options.find((o) => o.value === currentType)?.fields ?? [];
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<FormControl fullWidth size="small" sx={{ mb: 2 }}>
|
||||
<InputLabel>{field.label}</InputLabel>
|
||||
<Select
|
||||
value={currentType}
|
||||
label={field.label}
|
||||
onChange={handleTypeChange}
|
||||
error={!!error}
|
||||
>
|
||||
<MenuItem value="" disabled>Select type</MenuItem>
|
||||
{options.map((opt) => (
|
||||
<MenuItem key={opt.value} value={opt.value}>{opt.label}</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
{currentType && activeFields.length > 0 && (
|
||||
<Box sx={{ pl: 2, borderLeft: "2px solid", borderColor: "divider" }}>
|
||||
{activeFields.map((f) => (
|
||||
<FormFieldRenderer
|
||||
key={f.name}
|
||||
field={f}
|
||||
value={value?.[f.name]}
|
||||
onChange={(v) => handleFieldChange(f.name, v)}
|
||||
/>
|
||||
))}
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user