@ram_28/kf-ai-sdk 2.0.15 → 2.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/README.md +22 -14
  2. package/dist/api.cjs +1 -1
  3. package/dist/api.mjs +1 -1
  4. package/dist/auth/authConfig.d.ts +1 -1
  5. package/dist/auth/types.d.ts +1 -1
  6. package/dist/auth/types.d.ts.map +1 -1
  7. package/dist/auth.cjs +1 -1
  8. package/dist/auth.mjs +1 -1
  9. package/dist/bdo/core/BaseBdo.d.ts +1 -1
  10. package/dist/bdo.cjs +1 -1
  11. package/dist/bdo.mjs +3 -3
  12. package/dist/components/hooks/useActivityForm/createActivityItemProxy.d.ts +1 -1
  13. package/dist/components/hooks/useActivityForm/createActivityItemProxy.d.ts.map +1 -1
  14. package/dist/components/hooks/useActivityForm/types.d.ts +6 -7
  15. package/dist/components/hooks/useActivityForm/types.d.ts.map +1 -1
  16. package/dist/components/hooks/useActivityForm/useActivityForm.d.ts.map +1 -1
  17. package/dist/components/hooks/useActivityTable/types.d.ts +7 -6
  18. package/dist/components/hooks/useActivityTable/types.d.ts.map +1 -1
  19. package/dist/components/hooks/useActivityTable/useActivityTable.d.ts +1 -1
  20. package/dist/components/hooks/useActivityTable/useActivityTable.d.ts.map +1 -1
  21. package/dist/components/hooks/useBDOForm/createItemProxy.d.ts.map +1 -0
  22. package/dist/components/hooks/useBDOForm/createResolver.d.ts.map +1 -0
  23. package/dist/components/hooks/useBDOForm/index.d.ts +6 -0
  24. package/dist/components/hooks/useBDOForm/index.d.ts.map +1 -0
  25. package/dist/components/hooks/useBDOForm/shared.d.ts +50 -0
  26. package/dist/components/hooks/useBDOForm/shared.d.ts.map +1 -0
  27. package/dist/components/hooks/{useForm → useBDOForm}/types.d.ts +6 -6
  28. package/dist/components/hooks/useBDOForm/types.d.ts.map +1 -0
  29. package/dist/components/hooks/{useForm/useForm.d.ts → useBDOForm/useBDOForm.d.ts} +4 -4
  30. package/dist/components/hooks/useBDOForm/useBDOForm.d.ts.map +1 -0
  31. package/dist/components/hooks/useBDOTable/types.d.ts +20 -14
  32. package/dist/components/hooks/useBDOTable/types.d.ts.map +1 -1
  33. package/dist/components/hooks/useBDOTable/useBDOTable.d.ts +2 -2
  34. package/dist/components/hooks/useBDOTable/useBDOTable.d.ts.map +1 -1
  35. package/dist/{constants-ConHc1oS.js → constants-Cyi942Yr.js} +5 -5
  36. package/dist/constants-DEmYwKfC.cjs +1 -0
  37. package/dist/filter.cjs +1 -1
  38. package/dist/filter.mjs +1 -1
  39. package/dist/form.cjs +1 -1
  40. package/dist/form.d.ts +1 -1
  41. package/dist/form.d.ts.map +1 -1
  42. package/dist/form.mjs +250 -253
  43. package/dist/form.types.d.ts +1 -1
  44. package/dist/form.types.d.ts.map +1 -1
  45. package/dist/shared-5a7UkED1.js +1180 -0
  46. package/dist/shared-nnmlRVs7.cjs +1 -0
  47. package/dist/table.cjs +1 -1
  48. package/dist/table.mjs +14 -14
  49. package/dist/table.types.d.ts +1 -1
  50. package/dist/table.types.d.ts.map +1 -1
  51. package/dist/types/constants.d.ts +4 -4
  52. package/dist/workflow/Activity.d.ts +22 -7
  53. package/dist/workflow/Activity.d.ts.map +1 -1
  54. package/dist/workflow/client.d.ts +2 -2
  55. package/dist/workflow/client.d.ts.map +1 -1
  56. package/dist/workflow/types.d.ts +7 -3
  57. package/dist/workflow/types.d.ts.map +1 -1
  58. package/dist/workflow.cjs +1 -1
  59. package/dist/workflow.mjs +518 -576
  60. package/docs/README.md +51 -0
  61. package/docs/bdo/README.md +161 -0
  62. package/docs/bdo/api_reference.md +281 -0
  63. package/docs/examples/bdo/create-product.md +69 -0
  64. package/docs/examples/bdo/edit-product-dialog.md +95 -0
  65. package/docs/examples/bdo/filtered-product-table.md +100 -0
  66. package/docs/examples/bdo/product-listing.md +73 -0
  67. package/docs/examples/bdo/supplier-dropdown.md +60 -0
  68. package/docs/examples/workflow/approve-leave-request.md +76 -0
  69. package/docs/examples/workflow/filtered-activity-table.md +101 -0
  70. package/docs/examples/workflow/my-pending-requests.md +90 -0
  71. package/docs/examples/workflow/start-new-workflow.md +47 -0
  72. package/docs/examples/workflow/submit-leave-request.md +72 -0
  73. package/docs/examples/workflow/workflow-progress.md +49 -0
  74. package/docs/useActivityForm/README.md +241 -0
  75. package/docs/useActivityForm/api_reference.md +279 -0
  76. package/docs/useActivityTable/README.md +263 -0
  77. package/docs/useActivityTable/api_reference.md +294 -0
  78. package/docs/useBDOForm/README.md +172 -0
  79. package/docs/useBDOForm/api_reference.md +244 -0
  80. package/docs/useBDOTable/README.md +242 -0
  81. package/docs/useBDOTable/api_reference.md +253 -0
  82. package/docs/useFilter/README.md +323 -0
  83. package/docs/useFilter/api_reference.md +228 -0
  84. package/docs/workflow/README.md +158 -0
  85. package/docs/workflow/api_reference.md +161 -0
  86. package/package.json +2 -2
  87. package/sdk/auth/authConfig.ts +1 -1
  88. package/sdk/auth/types.ts +1 -1
  89. package/sdk/bdo/core/BaseBdo.ts +2 -2
  90. package/sdk/components/hooks/useActivityForm/createActivityItemProxy.ts +1 -1
  91. package/sdk/components/hooks/useActivityForm/createActivityResolver.ts +1 -1
  92. package/sdk/components/hooks/useActivityForm/types.ts +8 -10
  93. package/sdk/components/hooks/useActivityForm/useActivityForm.ts +52 -265
  94. package/sdk/components/hooks/useActivityTable/types.ts +6 -5
  95. package/sdk/components/hooks/useActivityTable/useActivityTable.ts +14 -43
  96. package/sdk/components/hooks/{useForm → useBDOForm}/index.ts +4 -3
  97. package/sdk/components/hooks/useBDOForm/shared.ts +250 -0
  98. package/sdk/components/hooks/{useForm → useBDOForm}/types.ts +9 -9
  99. package/sdk/components/hooks/{useForm/useForm.ts → useBDOForm/useBDOForm.ts} +70 -96
  100. package/sdk/components/hooks/useBDOTable/types.ts +20 -12
  101. package/sdk/components/hooks/useBDOTable/useBDOTable.ts +12 -7
  102. package/sdk/form.ts +2 -2
  103. package/sdk/form.types.ts +4 -4
  104. package/sdk/table.types.ts +2 -0
  105. package/sdk/types/constants.ts +4 -4
  106. package/sdk/workflow/Activity.ts +68 -13
  107. package/sdk/workflow/client.ts +65 -25
  108. package/sdk/workflow/types.ts +10 -2
  109. package/dist/components/hooks/useForm/createItemProxy.d.ts.map +0 -1
  110. package/dist/components/hooks/useForm/createResolver.d.ts.map +0 -1
  111. package/dist/components/hooks/useForm/index.d.ts +0 -5
  112. package/dist/components/hooks/useForm/index.d.ts.map +0 -1
  113. package/dist/components/hooks/useForm/types.d.ts.map +0 -1
  114. package/dist/components/hooks/useForm/useForm.d.ts.map +0 -1
  115. package/dist/constants-QX2RX-wu.cjs +0 -1
  116. package/dist/createResolver-AIgUwoS6.cjs +0 -1
  117. package/dist/createResolver-ZHXQ7QMa.js +0 -1078
  118. package/docs/api.md +0 -95
  119. package/docs/bdo.md +0 -224
  120. package/docs/gaps.md +0 -410
  121. package/docs/useActivityTable.md +0 -481
  122. package/docs/useBDOTable.md +0 -317
  123. package/docs/useFilter.md +0 -188
  124. package/docs/useForm.md +0 -376
  125. package/docs/workflow.md +0 -818
  126. /package/dist/components/hooks/{useForm → useBDOForm}/createItemProxy.d.ts +0 -0
  127. /package/dist/components/hooks/{useForm → useBDOForm}/createResolver.d.ts +0 -0
  128. /package/docs/{useAuth.md → useAuth/README.md} +0 -0
  129. /package/sdk/components/hooks/{useForm → useBDOForm}/createItemProxy.ts +0 -0
  130. /package/sdk/components/hooks/{useForm → useBDOForm}/createResolver.ts +0 -0
package/docs/useForm.md DELETED
@@ -1,376 +0,0 @@
1
- # Form SDK API
2
-
3
- React hook for forms with validation, API integration, and typed field handling.
4
-
5
- ## Imports
6
-
7
- ```typescript
8
- import { useForm } from "@ram_28/kf-ai-sdk/form";
9
- import { ValidationMode, FormOperation } from "@ram_28/kf-ai-sdk/form";
10
- import type { UseFormOptionsType, UseFormReturnType, FormItemType, FormRegisterType, HandleSubmitType } from "@ram_28/kf-ai-sdk/form/types";
11
- import type { CreateUpdateResponseType } from "@ram_28/kf-ai-sdk/api/types";
12
-
13
- // Pre-built components for special field types
14
- import { ReferenceSelect } from "@/components/ui/reference-select";
15
- import { ImageUpload } from "@/components/ui/image-upload";
16
- import { FileUpload } from "@/components/ui/file-upload";
17
- ```
18
-
19
- ---
20
-
21
- ## Common Mistakes (READ FIRST)
22
-
23
- ### 1. Missing `operation` in useForm options (TS2345)
24
-
25
- ALWAYS include `operation`. Without it, TypeScript cannot resolve the union type.
26
-
27
- ```typescript
28
- // ❌ WRONG — missing operation (TS2345)
29
- useForm({ bdo: product, mode: ValidationMode.OnBlur });
30
-
31
- // ✅ CORRECT — always include operation
32
- useForm({ bdo: product, operation: FormOperation.Create, mode: ValidationMode.OnBlur });
33
- useForm({ bdo: product, operation: FormOperation.Update, recordId: id, mode: ValidationMode.OnBlur });
34
- ```
35
-
36
- ### 2. Annotating ternary with UseFormOptionsType (TS2322)
37
-
38
- `UseFormOptionsType` is a discriminated union. Type-annotating a variable prevents TS narrowing. NEVER annotate — call useForm inline in each branch.
39
-
40
- ```typescript
41
- // ❌ WRONG — type annotation prevents union narrowing (TS2322)
42
- const options: UseFormOptionsType<typeof bdo> = id
43
- ? { bdo, operation: FormOperation.Update, recordId: id, mode: ValidationMode.OnBlur }
44
- : { bdo, operation: FormOperation.Create, mode: ValidationMode.OnBlur };
45
- const formResult = useForm(options);
46
-
47
- // ✅ CORRECT — call useForm inline, no type annotation
48
- const formResult = id
49
- ? useForm({ bdo, operation: FormOperation.Update, recordId: id, mode: ValidationMode.OnBlur })
50
- : useForm({ bdo, operation: FormOperation.Create, mode: ValidationMode.OnBlur });
51
- const { register, handleSubmit, watch, setValue, item, formState: { errors, isSubmitting }, isLoading } = formResult;
52
- ```
53
-
54
- ### 3. Using `.options` on StringField (TS2339)
55
-
56
- ONLY `SelectField` has `.options` getter. `StringField` with `Constraint.Enum` does NOT — use hardcoded `<option>` values from the BDO file.
57
-
58
- ```tsx
59
- // Check the BDO class to determine field type:
60
- // new SelectField({...}) → has .options → use bdo.field.options.map()
61
- // new StringField({..."Constraint": {"Enum": [...]}}) → NO .options → hardcode from Enum array
62
-
63
- // ❌ WRONG — StringField has no .options (TS2339)
64
- // Given: readonly status = new StringField({... "Constraint": { "Enum": ["Active", "Discontinued"] }})
65
- <select {...register(bdo.status.id)}>
66
- {bdo.status.options.map((opt) => ( // TS2339: Property 'options' does not exist on StringField
67
- <option key={opt.value} value={opt.value}>{opt.label}</option>
68
- ))}
69
- </select>
70
-
71
- // ✅ CORRECT for StringField with Enum — hardcode options from BDO Constraint.Enum array
72
- <select {...register(bdo.status.id)}>
73
- <option value="">Select {bdo.status.label}</option>
74
- <option value="Active">Active</option>
75
- <option value="Discontinued">Discontinued</option>
76
- </select>
77
-
78
- // ✅ CORRECT for SelectField — use .options getter
79
- // Given: readonly status = new SelectField({...})
80
- <select {...register(bdo.status.id)}>
81
- <option value="">Select {bdo.status.label}</option>
82
- {bdo.status.options.map((opt) => (
83
- <option key={opt.value} value={opt.value}>{opt.label}</option>
84
- ))}
85
- </select>
86
- ```
87
-
88
- ### 4. Using register() for BooleanField
89
-
90
- HTML checkboxes don't work with register(). Use watch/setValue.
91
-
92
- ```tsx
93
- // ❌ WRONG
94
- <input type="checkbox" {...register(bdo.is_active.id)} />
95
-
96
- // ✅ CORRECT
97
- <Checkbox
98
- checked={Boolean(watch(bdo.is_active.id))}
99
- onCheckedChange={(v) => setValue(bdo.is_active.id, v as boolean, { shouldDirty: true })}
100
- />
101
- ```
102
-
103
- ### 5. Using `<input>` for ReferenceField (should use `<ReferenceSelect>`)
104
-
105
- ReferenceField stores an object `{ _id, _name, ... }`, not a string. Use the pre-built component.
106
-
107
- ```tsx
108
- // ❌ WRONG — text input for reference field
109
- <input {...register(bdo.category.id)} />
110
-
111
- // ✅ CORRECT
112
- <ReferenceSelect
113
- bdoField={bdo.category}
114
- instanceId={id || String(watch("_id") ?? "")}
115
- value={watch(bdo.category.id)}
116
- onChange={(val) => setValue(bdo.category.id, val, { shouldDirty: true })}
117
- />
118
- ```
119
-
120
- ### 6. Using custom Image/File upload (should use template components)
121
-
122
- Use `<ImageUpload>` and `<FileUpload>`. CRITICAL: `instanceId` must work for BOTH edit and create mode.
123
-
124
- ```tsx
125
- // ❌ WRONG — instanceId={id} is undefined in create mode
126
- <ImageUpload field={item.icon} value={watch(bdo.icon.id)} boId={bdo.meta._id} instanceId={id} fieldId={bdo.icon.id} />
127
-
128
- // ✅ CORRECT — ImageUpload (single image)
129
- <ImageUpload
130
- field={item.product_image}
131
- value={watch(bdo.product_image.id)}
132
- boId={bdo.meta._id}
133
- instanceId={id || String(watch("_id") ?? "")}
134
- fieldId={bdo.product_image.id}
135
- />
136
-
137
- // ✅ CORRECT — FileUpload (multi-file)
138
- <FileUpload
139
- field={item.specification_document}
140
- value={watch(bdo.specification_document.id)}
141
- boId={bdo.meta._id}
142
- instanceId={id || String(watch("_id") ?? "")}
143
- fieldId={bdo.specification_document.id}
144
- />
145
- ```
146
-
147
- Props: `field` = item accessor (`item.fieldName`), `value` = `watch(bdo.field.id)`, `boId` = `bdo.meta._id`, `instanceId` = `id || String(watch("_id") ?? "")`, `fieldId` = `bdo.field.id`. Parent component MUST have `"use no memo"` directive.
148
-
149
- ### 7. Wrong handleSubmit onSuccess type
150
-
151
- ```typescript
152
- // ❌ WRONG
153
- const onSuccess = (data: unknown) => { ... };
154
-
155
- // ✅ CORRECT — CreateUpdateResponseType = { _id: string }
156
- import type { CreateUpdateResponseType } from "@ram_28/kf-ai-sdk/api/types";
157
- const onSuccess = (data: CreateUpdateResponseType) => { toast.success("Saved"); navigate("/list"); };
158
- ```
159
-
160
- ### 8. Passing FieldType instead of BDO instance
161
-
162
- ```typescript
163
- // ❌ WRONG
164
- useForm<ProductFieldType>({ ... });
165
-
166
- // ✅ CORRECT — pass BDO class instance
167
- const product = useMemo(() => new SellerProduct(), []);
168
- useForm({ bdo: product, operation: FormOperation.Create, mode: ValidationMode.OnBlur });
169
- ```
170
-
171
- ### 9. Wrong default values for date fields
172
-
173
- ```typescript
174
- // ❌ WRONG — empty string causes type errors
175
- defaultValues: { start_date: "" }
176
-
177
- // ✅ CORRECT
178
- defaultValues: { start_date: undefined }
179
- ```
180
-
181
- ---
182
-
183
- ## Complete Form Example (Create + Edit)
184
-
185
- ```tsx
186
- "use no memo";
187
-
188
- import { useMemo } from "react";
189
- import { useNavigate, useParams } from "react-router-dom";
190
- import { useForm, ValidationMode, FormOperation } from "@ram_28/kf-ai-sdk/form";
191
- import type { CreateUpdateResponseType } from "@ram_28/kf-ai-sdk/api/types";
192
- import { AdminProduct } from "@/bdo/admin/Product";
193
- import { ReferenceSelect } from "@/components/ui/reference-select";
194
- import { ImageUpload } from "@/components/ui/image-upload";
195
- import { FileUpload } from "@/components/ui/file-upload";
196
- import { Checkbox } from "@/components/ui/checkbox";
197
- import { toast } from "sonner";
198
-
199
- export default function ProductForm() {
200
- const { id } = useParams<{ id: string }>();
201
- const navigate = useNavigate();
202
- const bdo = useMemo(() => new AdminProduct(), []);
203
-
204
- // Create/Edit ternary — NO type annotation on result
205
- const formResult = id
206
- ? useForm({ bdo, operation: FormOperation.Update, recordId: id, mode: ValidationMode.OnBlur })
207
- : useForm({ bdo, operation: FormOperation.Create, mode: ValidationMode.OnBlur });
208
-
209
- const { register, handleSubmit, watch, setValue, item, formState: { errors, isSubmitting }, isLoading } = formResult;
210
-
211
- // Loading guard AFTER all hooks
212
- if (isLoading) return <div className="flex items-center justify-center h-full"><div className="animate-spin w-8 h-8 border-4 border-primary border-t-transparent rounded-full" /></div>;
213
-
214
- const onSuccess = (data: CreateUpdateResponseType) => {
215
- toast.success(id ? "Updated" : "Created");
216
- navigate("/products");
217
- };
218
-
219
- const onError = (error: any) => {
220
- toast.error(error instanceof Error ? error.message : "Please fix errors above");
221
- };
222
-
223
- return (
224
- <form onSubmit={handleSubmit(onSuccess, onError)} className="space-y-6">
225
- {/* StringField — register */}
226
- <div>
227
- <label>{bdo.product_name.label}{bdo.product_name.required && <span className="text-red-500"> *</span>}</label>
228
- <input {...register(bdo.product_name.id)} className="w-full border rounded px-3 py-2" />
229
- {errors.product_name && <p className="text-red-600 text-sm">{errors.product_name.message}</p>}
230
- </div>
231
-
232
- {/* NumberField — register */}
233
- <div>
234
- <label>{bdo.unit_price.label}</label>
235
- <input type="number" step="0.01" {...register(bdo.unit_price.id)} className="w-full border rounded px-3 py-2" />
236
- {errors.unit_price && <p className="text-red-600 text-sm">{errors.unit_price.message}</p>}
237
- </div>
238
-
239
- {/* StringField with Constraint.Enum — hardcoded options (NO .options getter) */}
240
- <div>
241
- <label>{bdo.status.label}</label>
242
- <select {...register(bdo.status.id)} className="w-full border rounded px-3 py-2">
243
- <option value="">Select {bdo.status.label}</option>
244
- <option value="Active">Active</option>
245
- <option value="Discontinued">Discontinued</option>
246
- </select>
247
- {errors.status && <p className="text-red-600 text-sm">{errors.status.message}</p>}
248
- </div>
249
-
250
- {/* ReferenceField — ReferenceSelect component */}
251
- <div>
252
- <label>{bdo.category.label}</label>
253
- <ReferenceSelect
254
- bdoField={bdo.category}
255
- instanceId={id || String(watch("_id") ?? "")}
256
- value={watch(bdo.category.id)}
257
- onChange={(val) => setValue(bdo.category.id, val, { shouldDirty: true })}
258
- />
259
- {errors.category && <p className="text-red-600 text-sm">{String(errors.category.message ?? "")}</p>}
260
- </div>
261
-
262
- {/* BooleanField — watch + setValue */}
263
- <div className="flex items-center gap-2">
264
- <Checkbox
265
- checked={Boolean(watch(bdo.is_active.id))}
266
- onCheckedChange={(v) => setValue(bdo.is_active.id, v as boolean, { shouldDirty: true })}
267
- />
268
- <label>{bdo.is_active.label}</label>
269
- </div>
270
-
271
- {/* ImageField — ImageUpload component */}
272
- <div>
273
- <label>{bdo.product_image.label}</label>
274
- <ImageUpload
275
- field={item.product_image}
276
- value={watch(bdo.product_image.id)}
277
- boId={bdo.meta._id}
278
- instanceId={id || String(watch("_id") ?? "")}
279
- fieldId={bdo.product_image.id}
280
- />
281
- </div>
282
-
283
- {/* FileField — FileUpload component */}
284
- <div>
285
- <label>{bdo.specification_document.label}</label>
286
- <FileUpload
287
- field={item.specification_document}
288
- value={watch(bdo.specification_document.id)}
289
- boId={bdo.meta._id}
290
- instanceId={id || String(watch("_id") ?? "")}
291
- fieldId={bdo.specification_document.id}
292
- />
293
- </div>
294
-
295
- {/* TextField — textarea with register */}
296
- <div>
297
- <label>{bdo.description.label}</label>
298
- <textarea {...register(bdo.description.id)} rows={4} className="w-full border rounded px-3 py-2" />
299
- </div>
300
-
301
- <button type="submit" disabled={isSubmitting} className="px-4 py-2 bg-primary text-white rounded">
302
- {isSubmitting ? "Saving..." : id ? "Update" : "Create"}
303
- </button>
304
- </form>
305
- );
306
- }
307
- ```
308
-
309
- ---
310
-
311
- ## Type Definitions
312
-
313
- ### UseFormOptionsType (Discriminated Union)
314
-
315
- ```typescript
316
- type UseFormOptionsType<B extends BaseBdo<any, any, any>> =
317
- | { bdo: B; operation: "create"; defaultValues?: Partial<EditableFieldType>; mode?: ValidationModeType; }
318
- | { bdo: B; operation: "update"; recordId: string; mode?: ValidationModeType; }
319
- | { bdo: B; recordId?: string; defaultValues?: Partial<EditableFieldType>; mode?: ValidationModeType; };
320
- ```
321
-
322
- ### UseFormReturnType
323
-
324
- ```typescript
325
- interface UseFormReturnType<B> {
326
- item: FormItemType<EditableFieldType, ReadonlyFieldType>; // Field accessors (.get(), .set(), .upload())
327
- register: FormRegisterType; // Auto-disables readonly fields
328
- handleSubmit: HandleSubmitType; // Auto-calls bdo.create() or bdo.update()
329
- watch: UseFormWatch; // Watch field values by bdo.field.id
330
- setValue: UseFormSetValue; // Set field values by bdo.field.id
331
- getValues: UseFormGetValues;
332
- control: Control;
333
- formState: FormState;
334
- errors: FieldErrors;
335
- isLoading: boolean; // Fetching record data (edit mode)
336
- isSubmitting: boolean;
337
- isDirty: boolean;
338
- loadError: Error | null;
339
- }
340
- ```
341
-
342
- ### File & Image Types
343
-
344
- ```typescript
345
- interface FileType { _id: string; _name: string; FileName: string; FileExtension: string; Size: number; ContentType: string; }
346
- type ImageFieldType = FileType | null; // Single image, nullable
347
- type FileFieldType = FileType[]; // Array of files
348
- ```
349
-
350
- Image accessor: `item.field.get()` returns `FileType | null`. Has `upload(file: File)`, `deleteAttachment()`, `getDownloadUrl()`.
351
- File accessor: `item.field.get()` returns `FileType[]`. Has `upload(files: File[])`, `deleteAttachment(id)`, `getDownloadUrl(id)`.
352
-
353
- ### Constants
354
-
355
- ```typescript
356
- FormOperation.Create // "create"
357
- FormOperation.Update // "update"
358
- ValidationMode.OnBlur / .OnChange / .OnSubmit / .OnTouched / .All
359
- ```
360
-
361
- ### Field-Type to UI Component Mapping
362
-
363
- | BDO Field Class | UI Pattern |
364
- |---|---|
365
- | `StringField` | `<input {...register(bdo.field.id)} />` |
366
- | `StringField` with `Constraint.Enum` | `<select {...register(bdo.field.id)}>` with hardcoded `<option>` from Enum array |
367
- | `SelectField` | `<select {...register(bdo.field.id)}>` with `bdo.field.options.map()` |
368
- | `TextField` | `<textarea {...register(bdo.field.id)} />` |
369
- | `NumberField` | `<input type="number" {...register(bdo.field.id)} />` |
370
- | `BooleanField` | `<Checkbox checked={watch()} onCheckedChange={v => setValue()} />` |
371
- | `DateField` | `<input type="date" {...register(bdo.field.id)} />` |
372
- | `DateTimeField` | `<input type="datetime-local" {...register(bdo.field.id)} />` |
373
- | `ReferenceField` | `<ReferenceSelect bdoField={bdo.field} instanceId={id \|\| String(watch("_id") ?? "")} value={watch()} onChange={...} />` |
374
- | `UserField` | `<ReferenceSelect bdoField={bdo.field} instanceId={id \|\| String(watch("_id") ?? "")} value={watch()} onChange={...} />` |
375
- | `ImageField` | `<ImageUpload field={item.field} value={watch()} boId={} instanceId={} fieldId={} />` |
376
- | `FileField` | `<FileUpload field={item.field} value={watch()} boId={} instanceId={} fieldId={} />` |