/* ============================================================================ * Copyright (c) Palo Alto Networks * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * ========================================================================== */ import React, { useEffect, useState } from "react"; import FormFileUpload from "@theme/ApiExplorer/FormFileUpload"; import FormLabel from "@theme/ApiExplorer/FormLabel"; import FormSelect from "@theme/ApiExplorer/FormSelect"; import FormTextInput from "@theme/ApiExplorer/FormTextInput"; import LiveApp from "@theme/ApiExplorer/LiveEditor"; import { useTypedDispatch } from "@theme/ApiItem/hooks"; import type { SchemaObject } from "docusaurus-plugin-openapi-docs/src/openapi/types"; import FileArrayFormBodyItem from "../FileArrayFormBodyItem"; import { clearFormBodyKey, setFileFormBody, setStringFormBody } from "../slice"; import { setFieldEncoding } from "../../EncodingSelection/slice"; interface FormBodyItemProps { schemaObject: SchemaObject; id: string; schema: SchemaObject; label?: string; required?: boolean; exampleValue?: SchemaObject["example"]; fieldEncoding?: string; } export default function FormBodyItem({ schemaObject, id, schema, label, required, exampleValue, fieldEncoding, }: FormBodyItemProps): React.JSX.Element { const dispatch = useTypedDispatch(); // Parse comma-separated encoding contentType into selectable options const encodingOptions = fieldEncoding ? fieldEncoding .split(",") .map((t) => t.trim()) .filter(Boolean) : []; const hasMultipleEncodings = encodingOptions.length > 1; // Initialize with the first declared content type const [selectedEncoding, setSelectedEncoding] = useState( encodingOptions[0] ?? "" ); // Seed Redux with the first declared encoding on mount so the code snippet // reflects a content type immediately, even before the user interacts. // The empty dep array is intentional: `fieldEncoding` comes from a static // spec value that never changes for the lifetime of this component instance, // and re-seeding on every render would fight user selections. useEffect(() => { if (encodingOptions[0]) { dispatch( setFieldEncoding({ field: id, contentType: encodingOptions[0] }) ); } // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const [value, setValue] = useState(() => { let initialValue = exampleValue ?? ""; if (schemaObject.type === "object" && exampleValue) { initialValue = JSON.stringify(exampleValue, null, 2); } return initialValue; }); useEffect(() => { if (value) { dispatch(setStringFormBody({ key: id, value })); } else { dispatch(clearFormBodyKey(id)); } // eslint-disable-next-line react-hooks/exhaustive-deps }, []); if ( schemaObject.type === "array" && schemaObject.items?.format === "binary" ) { return ( <> {label && } ); } if (schemaObject.format === "binary") { return ( <> {label && } {hasMultipleEncodings && (
) => { const ct = e.target.value; setSelectedEncoding(ct); dispatch(setFieldEncoding({ field: id, contentType: ct })); }} />
)} { if (file === undefined) { dispatch(clearFormBodyKey(id)); return; } dispatch( setFileFormBody({ key: id, value: { src: `/path/to/${file.name}`, content: file, }, }) ); }} /> ); } if (schemaObject.type === "object") { return ( <> {label && } dispatch(setStringFormBody({ key: id, value: code })) } > {value} ); } if ( schemaObject.enum && schemaObject.enum.every((value) => typeof value === "string") ) { return ( ) => { const val = e.target.value; setValue(val); if (val === "---") { dispatch(clearFormBodyKey(id)); } else { dispatch( setStringFormBody({ key: id, value: val, }) ); } }} /> ); } // TODO: support all the other types. return ( ) => { setValue(e.target.value); dispatch(setStringFormBody({ key: id, value: e.target.value })); }} /> ); }