MCPcopy Create free account
hub / github.com/TraderAlice/OpenAlice / useSchemaForm

Function useSchemaForm

ui/src/hooks/useSchemaForm.ts:38–135  ·  view source on GitHub ↗
(
  schema: JsonSchema | undefined,
  initialValues?: Record<string, string>,
)

Source from the content-addressed store, hash-verified

36// ==================== Hook ====================
37
38export function useSchemaForm(
39 schema: JsonSchema | undefined,
40 initialValues?: Record<string, string>,
41): UseSchemaFormResult {
42 // Parse schema into const values and editable field descriptors
43 const { constValues, fieldDefs, defaults, booleanKeys } = useMemo(() => {
44 const consts: Record<string, unknown> = {}
45 const fields: SchemaField[] = []
46 const defs: Record<string, string> = {}
47
48 const props = (schema?.properties ?? {}) as Record<string, JsonSchemaProperty>
49 const required = new Set((schema?.required as string[]) ?? [])
50
51 for (const [key, prop] of Object.entries(props)) {
52 // const → hidden, value auto-merged
53 if (prop.const !== undefined) {
54 consts[key] = prop.const
55 continue
56 }
57
58 const title = prop.title ?? key.charAt(0).toUpperCase() + key.slice(1)
59 const isRequired = required.has(key)
60
61 // Determine field type
62 if (prop.writeOnly) {
63 fields.push({ key, type: 'password', title, description: prop.description, required: isRequired })
64 } else if (prop.oneOf) {
65 const options = prop.oneOf.map(o => ({ value: o.const, label: o.title }))
66 fields.push({ key, type: 'select', title, description: prop.description, required: isRequired, options })
67 } else if (prop.enum) {
68 const options = prop.enum.map(v => ({ value: v, label: v }))
69 fields.push({ key, type: 'select', title, description: prop.description, required: isRequired, options })
70 } else if (prop.type === 'boolean') {
71 // Stored in string form-state as 'true'/'false'; getSubmitData
72 // converts back to a real boolean. Rendered as a checkbox.
73 fields.push({ key, type: 'boolean', title, description: prop.description, required: isRequired, defaultValue: String(prop.default ?? false) })
74 } else {
75 fields.push({ key, type: 'text', title, description: prop.description, required: isRequired, defaultValue: prop.default !== undefined ? String(prop.default) : undefined })
76 }
77
78 // Collect defaults. Booleans always seed (a checkbox/toggle is never
79 // "unset"), so even a required boolean with no .default() lands in form
80 // state and submits a real `false` rather than going missing.
81 if (prop.type === 'boolean') {
82 defs[key] = String(prop.default ?? false)
83 } else if (prop.default !== undefined) {
84 defs[key] = String(prop.default)
85 }
86 }
87
88 const booleanKeys = new Set(fields.filter(f => f.type === 'boolean').map(f => f.key))
89 return { constValues: consts, fieldDefs: fields, defaults: defs, booleanKeys }
90 }, [schema])
91
92 // Form state — reset when schema changes (e.g. user picks a different preset)
93 const [formData, setFormData] = useState<Record<string, string>>(() => ({
94 ...defaults,
95 ...(initialValues ?? {}),

Callers 3

EditUTADialogFunction · 0.90
CreateWizardFunction · 0.90

Calls 2

hasMethod · 0.65
pushMethod · 0.65

Tested by

no test coverage detected