import React from "react"; import { Box, Checkbox, Input, Field, Text } from "rimble-ui"; import { JsonSchemaNode } from "vc-schema-tools"; import { DidSearchWithMessagingInfo } from "../../../elements/DidSearchWithMessagingInfo"; import { DidSearch } from "../../../elements/DidSearch"; import { Identifier } from "../../../../types"; import { isoToDatetimeLocal } from "../../../../utils/helpers"; export interface IssueVcFormInputProps { name: string; value: any; node: JsonSchemaNode; identifiers: Identifier[]; required?: boolean; defaultSubjectDid?: string; subjectSupportsMessaging?: boolean; isNested?: boolean; onChange(value: any): void; setSubjectSupportsMessaging(supported: boolean): void; } export const IssueVcFormInput: React.FunctionComponent = (props) => { const { name, node, value, onChange, required, identifiers, defaultSubjectDid, subjectSupportsMessaging, setSubjectSupportsMessaging, isNested, } = props; const isDid = node.type === "string" && node.format === "uri" && node.$linkedData?.["@id"] === "@id"; const isSubjectDid = isDid && name === "id" && !isNested; React.useEffect(() => { // Most required fields will be handled by form validation, but requiring a boolean or a nested object is not. // @TODO/tobek In some cases this isn't handling nested required booleans but that's a heck of an edge case and ideally we should check final VC against JSON Schema anyway which would catch this. if (required && typeof value === "undefined") { if (node.type === "boolean") { onChange(false); } else if (node.type === "object") { onChange({}); } } }, [node.type, required, value, onChange]); const renderInput = () => { if (node.properties && node.type === "object") { return ( {Object.entries(node.properties).map(([nestedKey, nestedNode]) => ( onChange({ ...value, [nestedKey]: updatedNestedValue, }) } subjectSupportsMessaging={subjectSupportsMessaging} setSubjectSupportsMessaging={setSubjectSupportsMessaging} isNested /> ))} ); } if (isSubjectDid) { return ( onChange(val.did)} required={required} identifiers={identifiers} defaultSelectedDid={defaultSubjectDid} supportsMessaging={subjectSupportsMessaging} setSupportsMessaging={setSubjectSupportsMessaging} /> ); } else if (isDid) { return ( onChange(val.did)} required={required} identifiers={identifiers} defaultSelectedDid={defaultSubjectDid} /> ); } if (node.type === "boolean") { return onChange(!value)} />; } let type = "text"; let placeholder = ""; let width: string | undefined = "100%"; let inputValue = value || ""; if (node.type === "number" || node.type === "integer") { type = "number"; width = undefined; } else if (node.format === "date") { type = "date"; } else if (node.format === "date-time") { type = "datetime-local"; inputValue = inputValue && isoToDatetimeLocal(inputValue); } else if (node.format === "uri") { type = "url"; placeholder = "URL"; } function changeHandler(event: any) { const newValue = event.target.value; if (type === "number") { onChange(parseInt(newValue, 10)); } else if (type === "datetime-local") { onChange(new Date(newValue).toISOString()); } else { onChange(newValue); } } return ( ); }; return ( {node.description ? {node.description} : <>} {renderInput()} ); };