@ram_28/kf-ai-sdk 2.0.15 → 2.0.16
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.
- package/README.md +8 -8
- package/dist/bdo/core/BaseBdo.d.ts +1 -1
- package/dist/bdo.mjs +2 -2
- package/dist/components/hooks/useActivityForm/createActivityItemProxy.d.ts +1 -1
- package/dist/components/hooks/useActivityForm/createActivityItemProxy.d.ts.map +1 -1
- package/dist/components/hooks/useActivityForm/types.d.ts +2 -2
- package/dist/components/hooks/useActivityForm/types.d.ts.map +1 -1
- package/dist/components/hooks/useActivityForm/useActivityForm.d.ts.map +1 -1
- package/dist/components/hooks/useActivityTable/types.d.ts +4 -4
- package/dist/components/hooks/useActivityTable/types.d.ts.map +1 -1
- package/dist/components/hooks/useActivityTable/useActivityTable.d.ts +1 -1
- package/dist/components/hooks/useActivityTable/useActivityTable.d.ts.map +1 -1
- package/dist/components/hooks/useBDOForm/createItemProxy.d.ts.map +1 -0
- package/dist/components/hooks/useBDOForm/createResolver.d.ts.map +1 -0
- package/dist/components/hooks/useBDOForm/index.d.ts +6 -0
- package/dist/components/hooks/useBDOForm/index.d.ts.map +1 -0
- package/dist/components/hooks/useBDOForm/shared.d.ts +50 -0
- package/dist/components/hooks/useBDOForm/shared.d.ts.map +1 -0
- package/dist/components/hooks/{useForm → useBDOForm}/types.d.ts +6 -6
- package/dist/components/hooks/useBDOForm/types.d.ts.map +1 -0
- package/dist/components/hooks/{useForm/useForm.d.ts → useBDOForm/useBDOForm.d.ts} +4 -4
- package/dist/components/hooks/useBDOForm/useBDOForm.d.ts.map +1 -0
- package/dist/components/hooks/useBDOTable/types.d.ts +1 -3
- package/dist/components/hooks/useBDOTable/types.d.ts.map +1 -1
- package/dist/components/hooks/useBDOTable/useBDOTable.d.ts.map +1 -1
- package/dist/form.cjs +1 -1
- package/dist/form.d.ts +1 -1
- package/dist/form.d.ts.map +1 -1
- package/dist/form.mjs +250 -253
- package/dist/form.types.d.ts +1 -1
- package/dist/form.types.d.ts.map +1 -1
- package/dist/shared-5a7UkED1.js +1180 -0
- package/dist/shared-nnmlRVs7.cjs +1 -0
- package/dist/table.cjs +1 -1
- package/dist/table.mjs +12 -11
- package/dist/types/constants.d.ts +3 -3
- package/dist/workflow/Activity.d.ts +15 -3
- package/dist/workflow/Activity.d.ts.map +1 -1
- package/dist/workflow/client.d.ts +2 -2
- package/dist/workflow/client.d.ts.map +1 -1
- package/dist/workflow/types.d.ts +7 -3
- package/dist/workflow/types.d.ts.map +1 -1
- package/dist/workflow.cjs +1 -1
- package/dist/workflow.mjs +503 -546
- package/docs/bdo.md +1 -1
- package/docs/gaps.md +14 -64
- package/docs/useActivityForm.md +393 -0
- package/docs/useActivityTable.md +42 -105
- package/docs/{useForm.md → useBDOForm.md} +24 -24
- package/docs/useBDOTable.md +6 -39
- package/docs/workflow.md +43 -301
- package/package.json +2 -2
- package/sdk/bdo/core/BaseBdo.ts +2 -2
- package/sdk/components/hooks/useActivityForm/createActivityItemProxy.ts +1 -1
- package/sdk/components/hooks/useActivityForm/createActivityResolver.ts +1 -1
- package/sdk/components/hooks/useActivityForm/types.ts +4 -4
- package/sdk/components/hooks/useActivityForm/useActivityForm.ts +44 -194
- package/sdk/components/hooks/useActivityTable/types.ts +4 -2
- package/sdk/components/hooks/useActivityTable/useActivityTable.ts +8 -39
- package/sdk/components/hooks/{useForm → useBDOForm}/index.ts +4 -3
- package/sdk/components/hooks/useBDOForm/shared.ts +250 -0
- package/sdk/components/hooks/{useForm → useBDOForm}/types.ts +9 -9
- package/sdk/components/hooks/{useForm/useForm.ts → useBDOForm/useBDOForm.ts} +70 -96
- package/sdk/components/hooks/useBDOTable/types.ts +1 -3
- package/sdk/components/hooks/useBDOTable/useBDOTable.ts +3 -2
- package/sdk/form.ts +2 -2
- package/sdk/form.types.ts +4 -4
- package/sdk/types/constants.ts +3 -3
- package/sdk/workflow/Activity.ts +29 -6
- package/sdk/workflow/client.ts +65 -25
- package/sdk/workflow/types.ts +10 -2
- package/dist/components/hooks/useForm/createItemProxy.d.ts.map +0 -1
- package/dist/components/hooks/useForm/createResolver.d.ts.map +0 -1
- package/dist/components/hooks/useForm/index.d.ts +0 -5
- package/dist/components/hooks/useForm/index.d.ts.map +0 -1
- package/dist/components/hooks/useForm/types.d.ts.map +0 -1
- package/dist/components/hooks/useForm/useForm.d.ts.map +0 -1
- package/dist/createResolver-AIgUwoS6.cjs +0 -1
- package/dist/createResolver-ZHXQ7QMa.js +0 -1078
- /package/dist/components/hooks/{useForm → useBDOForm}/createItemProxy.d.ts +0 -0
- /package/dist/components/hooks/{useForm → useBDOForm}/createResolver.d.ts +0 -0
- /package/sdk/components/hooks/{useForm → useBDOForm}/createItemProxy.ts +0 -0
- /package/sdk/components/hooks/{useForm → useBDOForm}/createResolver.ts +0 -0
package/docs/useActivityTable.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# useActivityTable
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Hook for listing workflow activity (business process) instances with search, sort, filter, and pagination.
|
|
4
4
|
|
|
5
5
|
## Imports
|
|
6
6
|
|
|
@@ -18,94 +18,62 @@ import type {
|
|
|
18
18
|
|
|
19
19
|
## Common Mistakes (READ FIRST)
|
|
20
20
|
|
|
21
|
-
### 1.
|
|
21
|
+
### 1. Passing a Workflow instead of an Activity
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
```typescript
|
|
26
|
-
// ❌ WRONG — entity fields are not at the top level
|
|
27
|
-
row.StartDate
|
|
28
|
-
row.LeaveType
|
|
29
|
-
row.ManagerApproved
|
|
30
|
-
|
|
31
|
-
// ✅ CORRECT — access entity fields through ADO
|
|
32
|
-
row.ADO.StartDate
|
|
33
|
-
row.ADO.LeaveType
|
|
34
|
-
row.ADO.ManagerApproved
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
### 2. Passing a Workflow instead of an Activity
|
|
38
|
-
|
|
39
|
-
The first argument must be an `Activity` instance, not a `Workflow` instance.
|
|
23
|
+
The `activity` property must be an `Activity` instance, not a `Workflow` instance.
|
|
40
24
|
|
|
41
25
|
```typescript
|
|
42
26
|
// ❌ WRONG — passing the workflow class
|
|
43
27
|
const wf = new SimpleLeaveProcess();
|
|
44
|
-
useActivityTable(wf,
|
|
28
|
+
useActivityTable({ activity: wf, status: ActivityTableStatus.InProgress });
|
|
45
29
|
|
|
46
30
|
// ✅ CORRECT — pass the activity instance
|
|
47
31
|
const activity = new SimpleLeaveProcess().employeeInputActivity();
|
|
48
|
-
useActivityTable(activity,
|
|
32
|
+
useActivityTable({ activity, status: ActivityTableStatus.InProgress });
|
|
49
33
|
```
|
|
50
34
|
|
|
51
|
-
###
|
|
35
|
+
### 2. Using string literals instead of ActivityTableStatus
|
|
52
36
|
|
|
53
37
|
While string literals work at runtime, always use the `ActivityTableStatus` constant for type safety and readability.
|
|
54
38
|
|
|
55
39
|
```typescript
|
|
56
40
|
// ❌ WRONG — raw string (no type safety, easy to typo)
|
|
57
|
-
useActivityTable(activity,
|
|
58
|
-
useActivityTable(activity,
|
|
41
|
+
useActivityTable({ activity, status: "inProgress" });
|
|
42
|
+
useActivityTable({ activity, status: "in_progress" });
|
|
59
43
|
|
|
60
44
|
// ✅ CORRECT — use the constant
|
|
61
|
-
useActivityTable(activity,
|
|
62
|
-
useActivityTable(activity,
|
|
45
|
+
useActivityTable({ activity, status: ActivityTableStatus.InProgress });
|
|
46
|
+
useActivityTable({ activity, status: ActivityTableStatus.Completed });
|
|
63
47
|
```
|
|
64
48
|
|
|
65
|
-
###
|
|
49
|
+
### 3. Forgetting to memoize the activity instance
|
|
66
50
|
|
|
67
51
|
Like BDO instances passed to `useBDOTable`, the activity instance should be memoized to prevent unnecessary re-renders and refetches.
|
|
68
52
|
|
|
69
53
|
```typescript
|
|
70
54
|
// ❌ WRONG — creates a new activity on every render
|
|
71
55
|
const activity = new SimpleLeaveProcess().employeeInputActivity();
|
|
72
|
-
useActivityTable(activity,
|
|
56
|
+
useActivityTable({ activity, status: ActivityTableStatus.InProgress });
|
|
73
57
|
|
|
74
58
|
// ✅ CORRECT — memoize with useMemo
|
|
75
59
|
const activity = useMemo(
|
|
76
60
|
() => new SimpleLeaveProcess().employeeInputActivity(),
|
|
77
61
|
[],
|
|
78
62
|
);
|
|
79
|
-
useActivityTable(activity,
|
|
63
|
+
useActivityTable({ activity, status: ActivityTableStatus.InProgress });
|
|
80
64
|
```
|
|
81
65
|
|
|
82
|
-
###
|
|
83
|
-
|
|
84
|
-
Use `useActivityTable` instead of `useTable` for activity data. The hook handles the query key construction, endpoint selection based on status, and proper typing automatically.
|
|
85
|
-
|
|
86
|
-
```typescript
|
|
87
|
-
// ❌ WRONG — manual setup with useTable
|
|
88
|
-
useTable({
|
|
89
|
-
queryKey: ["activity-table", bpId, activityId, "inprogress"],
|
|
90
|
-
listFn: (opts) => activity._getOps().inProgressList(opts),
|
|
91
|
-
countFn: (opts) => activity._getOps().inProgressMetric(opts),
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
// ✅ CORRECT — let useActivityTable handle it
|
|
95
|
-
useActivityTable(activity, { status: ActivityTableStatus.InProgress });
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
### 6. Calling `.get()` on activity table rows
|
|
66
|
+
### 4. Calling `.get()` on activity table rows
|
|
99
67
|
|
|
100
68
|
Table rows are plain objects, not `ActivityInstance` proxies. There is no `.get()` method.
|
|
101
69
|
|
|
102
70
|
```typescript
|
|
103
71
|
// ❌ WRONG — rows are plain objects
|
|
104
|
-
row.
|
|
72
|
+
row.StartDate.get();
|
|
105
73
|
row.Status.get();
|
|
106
74
|
|
|
107
75
|
// ✅ CORRECT — access values directly
|
|
108
|
-
row.
|
|
76
|
+
row.StartDate;
|
|
109
77
|
row.Status;
|
|
110
78
|
```
|
|
111
79
|
|
|
@@ -138,7 +106,8 @@ function EmployeeLeaveTable() {
|
|
|
138
106
|
sort,
|
|
139
107
|
pagination,
|
|
140
108
|
refetch,
|
|
141
|
-
} = useActivityTable(
|
|
109
|
+
} = useActivityTable({
|
|
110
|
+
activity,
|
|
142
111
|
status: ActivityTableStatus.InProgress,
|
|
143
112
|
initialState: {
|
|
144
113
|
pagination: { pageNo: 1, pageSize: 10 },
|
|
@@ -159,7 +128,7 @@ function EmployeeLeaveTable() {
|
|
|
159
128
|
type="text"
|
|
160
129
|
placeholder="Search by leave type..."
|
|
161
130
|
value={search.query}
|
|
162
|
-
onChange={(e) => search.set(
|
|
131
|
+
onChange={(e) => search.set(activity.LeaveType.id, e.target.value)}
|
|
163
132
|
/>
|
|
164
133
|
{search.query && <button onClick={search.clear}>Clear</button>}
|
|
165
134
|
{isFetching && <span>Loading...</span>}
|
|
@@ -174,7 +143,7 @@ function EmployeeLeaveTable() {
|
|
|
174
143
|
<th>Assigned To</th>
|
|
175
144
|
<th
|
|
176
145
|
style={{ cursor: "pointer" }}
|
|
177
|
-
onClick={() => sort.toggle(
|
|
146
|
+
onClick={() => sort.toggle(activity.LeaveType.id)}
|
|
178
147
|
>
|
|
179
148
|
Leave Type
|
|
180
149
|
</th>
|
|
@@ -190,10 +159,10 @@ function EmployeeLeaveTable() {
|
|
|
190
159
|
<td>{row._id}</td>
|
|
191
160
|
<td>{row.Status}</td>
|
|
192
161
|
<td>{row.AssignedTo.map((u) => u._name).join(", ")}</td>
|
|
193
|
-
<td>{row.
|
|
194
|
-
<td>{row.
|
|
195
|
-
<td>{row.
|
|
196
|
-
<td>{row.
|
|
162
|
+
<td>{row.LeaveType}</td>
|
|
163
|
+
<td>{row.StartDate}</td>
|
|
164
|
+
<td>{row.EndDate}</td>
|
|
165
|
+
<td>{row.LeaveDays}</td>
|
|
197
166
|
<td>
|
|
198
167
|
<button onClick={() => setSelectedId(row._id)}>View</button>
|
|
199
168
|
</td>
|
|
@@ -237,14 +206,8 @@ import {
|
|
|
237
206
|
useActivityTable,
|
|
238
207
|
ActivityTableStatus,
|
|
239
208
|
} from "@ram_28/kf-ai-sdk/workflow";
|
|
240
|
-
import type {
|
|
241
|
-
|
|
242
|
-
UseActivityTableOptionsType,
|
|
243
|
-
} from "@ram_28/kf-ai-sdk/workflow";
|
|
244
|
-
import {
|
|
245
|
-
SimpleLeaveProcess,
|
|
246
|
-
ManagerApprovalActivity,
|
|
247
|
-
} from "@/bdo/workflows/SimpleLeaveProcess";
|
|
209
|
+
import type { ActivityRowType } from "@ram_28/kf-ai-sdk/workflow";
|
|
210
|
+
import { SimpleLeaveProcess } from "@/bdo/workflows/SimpleLeaveProcess";
|
|
248
211
|
|
|
249
212
|
type StatusTab = "inprogress" | "completed";
|
|
250
213
|
|
|
@@ -256,14 +219,6 @@ function ManagerApprovalTable() {
|
|
|
256
219
|
const [activeTab, setActiveTab] = useState<StatusTab>("inprogress");
|
|
257
220
|
const [selectedId, setSelectedId] = useState<string | null>(null);
|
|
258
221
|
|
|
259
|
-
const options: UseActivityTableOptionsType<ManagerApprovalActivity> = {
|
|
260
|
-
status: activeTab,
|
|
261
|
-
initialState: {
|
|
262
|
-
pagination: { pageNo: 1, pageSize: 10 },
|
|
263
|
-
},
|
|
264
|
-
onError: (err) => console.error("Fetch failed:", err.message),
|
|
265
|
-
};
|
|
266
|
-
|
|
267
222
|
const {
|
|
268
223
|
rows,
|
|
269
224
|
totalItems,
|
|
@@ -275,7 +230,14 @@ function ManagerApprovalTable() {
|
|
|
275
230
|
filter,
|
|
276
231
|
pagination,
|
|
277
232
|
refetch,
|
|
278
|
-
} = useActivityTable(
|
|
233
|
+
} = useActivityTable({
|
|
234
|
+
activity,
|
|
235
|
+
status: activeTab,
|
|
236
|
+
initialState: {
|
|
237
|
+
pagination: { pageNo: 1, pageSize: 10 },
|
|
238
|
+
},
|
|
239
|
+
onError: (err) => console.error("Fetch failed:", err.message),
|
|
240
|
+
});
|
|
279
241
|
|
|
280
242
|
if (selectedId) {
|
|
281
243
|
return (
|
|
@@ -311,14 +273,6 @@ function ManagerApprovalTable() {
|
|
|
311
273
|
{activeTab === "inprogress" ? "Pending" : "Completed"} Approvals ({totalItems})
|
|
312
274
|
</h2>
|
|
313
275
|
|
|
314
|
-
{/* Search */}
|
|
315
|
-
<input
|
|
316
|
-
type="text"
|
|
317
|
-
placeholder="Search..."
|
|
318
|
-
value={search.query}
|
|
319
|
-
onChange={(e) => search.set("_id", e.target.value)}
|
|
320
|
-
/>
|
|
321
|
-
|
|
322
276
|
{isLoading && <div>Loading...</div>}
|
|
323
277
|
{error && <div>Error: {error.message}</div>}
|
|
324
278
|
|
|
@@ -348,8 +302,8 @@ function ManagerApprovalTable() {
|
|
|
348
302
|
<td>{row._id}</td>
|
|
349
303
|
<td>{row.Status}</td>
|
|
350
304
|
<td>{row.AssignedTo.map((u) => u._name).join(", ")}</td>
|
|
351
|
-
<td>{row.
|
|
352
|
-
<td>{row.
|
|
305
|
+
<td>{row.ManagerApproved ? "Yes" : "No"}</td>
|
|
306
|
+
<td>{row.ManagerReason}</td>
|
|
353
307
|
{activeTab === "inprogress" && (
|
|
354
308
|
<td>
|
|
355
309
|
<button onClick={() => setSelectedId(row._id)}>Review</button>
|
|
@@ -393,26 +347,6 @@ function ManagerApprovalTable() {
|
|
|
393
347
|
|
|
394
348
|
---
|
|
395
349
|
|
|
396
|
-
## Accessing Entity Fields
|
|
397
|
-
|
|
398
|
-
Activity row data has a two-level structure. System fields (`_id`, `Status`, `AssignedTo`, `CompletedAt`) are at the top level. Entity-specific fields are nested under the `ADO` property.
|
|
399
|
-
|
|
400
|
-
```typescript
|
|
401
|
-
// System fields — top level
|
|
402
|
-
row._id
|
|
403
|
-
row.Status
|
|
404
|
-
row.AssignedTo.map((u) => u._name)
|
|
405
|
-
row.CompletedAt
|
|
406
|
-
|
|
407
|
-
// Entity fields — under ADO
|
|
408
|
-
row.ADO.StartDate
|
|
409
|
-
row.ADO.LeaveType
|
|
410
|
-
row.ADO.LeaveDays
|
|
411
|
-
row.ADO.ManagerApproved
|
|
412
|
-
```
|
|
413
|
-
|
|
414
|
-
---
|
|
415
|
-
|
|
416
350
|
## Type Definitions
|
|
417
351
|
|
|
418
352
|
### ActivityTableStatus
|
|
@@ -429,12 +363,12 @@ export type ActivityTableStatusType =
|
|
|
429
363
|
|
|
430
364
|
### ActivityRowType\<A\>
|
|
431
365
|
|
|
432
|
-
Row type for activity table data. System fields
|
|
366
|
+
Row type for activity table data. System fields and entity fields are flat at the top level.
|
|
433
367
|
|
|
434
368
|
```typescript
|
|
435
369
|
export type ActivityRowType<A extends Activity<any, any, any>> =
|
|
436
370
|
A extends Activity<infer E, any, any>
|
|
437
|
-
? ActivityInstanceFieldsType &
|
|
371
|
+
? ActivityInstanceFieldsType & E
|
|
438
372
|
: never;
|
|
439
373
|
```
|
|
440
374
|
|
|
@@ -442,6 +376,9 @@ export type ActivityRowType<A extends Activity<any, any, any>> =
|
|
|
442
376
|
|
|
443
377
|
```typescript
|
|
444
378
|
export interface UseActivityTableOptionsType<A extends Activity<any, any, any>> {
|
|
379
|
+
/** The activity instance to fetch data for */
|
|
380
|
+
activity: A;
|
|
381
|
+
|
|
445
382
|
/** Which activity instances to fetch — determines endpoint */
|
|
446
383
|
status: ActivityTableStatusType;
|
|
447
384
|
|
|
@@ -473,7 +410,7 @@ The return type is identical to `UseTableReturnType`. All properties — `rows`,
|
|
|
473
410
|
|
|
474
411
|
## Search, Sort, Filter, and Pagination
|
|
475
412
|
|
|
476
|
-
|
|
413
|
+
`useActivityTable` supports `initialState`, `onError`, and `onSuccess` options.
|
|
477
414
|
|
|
478
415
|
- **Search** — `search.set(field, query)`, `search.clear()`, 300ms debounce
|
|
479
416
|
- **Sort** — `sort.toggle(field)`, `sort.set(field, direction)`, `sort.clear()`
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
#
|
|
1
|
+
# useBDOForm
|
|
2
2
|
|
|
3
|
-
React hook for forms with validation, API integration, and typed field handling.
|
|
3
|
+
React hook for BDO forms with validation, API integration, and typed field handling.
|
|
4
4
|
|
|
5
5
|
## Imports
|
|
6
6
|
|
|
7
7
|
```typescript
|
|
8
|
-
import {
|
|
8
|
+
import { useBDOForm } from "@ram_28/kf-ai-sdk/form";
|
|
9
9
|
import { ValidationMode, FormOperation } from "@ram_28/kf-ai-sdk/form";
|
|
10
|
-
import type {
|
|
10
|
+
import type { UseBDOFormOptionsType, UseBDOFormReturnType, FormItemType, FormRegisterType, HandleSubmitType } from "@ram_28/kf-ai-sdk/form/types";
|
|
11
11
|
import type { CreateUpdateResponseType } from "@ram_28/kf-ai-sdk/api/types";
|
|
12
12
|
|
|
13
13
|
// Pre-built components for special field types
|
|
@@ -20,34 +20,34 @@ import { FileUpload } from "@/components/ui/file-upload";
|
|
|
20
20
|
|
|
21
21
|
## Common Mistakes (READ FIRST)
|
|
22
22
|
|
|
23
|
-
### 1. Missing `operation` in
|
|
23
|
+
### 1. Missing `operation` in useBDOForm options (TS2345)
|
|
24
24
|
|
|
25
25
|
ALWAYS include `operation`. Without it, TypeScript cannot resolve the union type.
|
|
26
26
|
|
|
27
27
|
```typescript
|
|
28
28
|
// ❌ WRONG — missing operation (TS2345)
|
|
29
|
-
|
|
29
|
+
useBDOForm({ bdo: product, mode: ValidationMode.OnBlur });
|
|
30
30
|
|
|
31
31
|
// ✅ CORRECT — always include operation
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
useBDOForm({ bdo: product, operation: FormOperation.Create, mode: ValidationMode.OnBlur });
|
|
33
|
+
useBDOForm({ bdo: product, operation: FormOperation.Update, recordId: id, mode: ValidationMode.OnBlur });
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
### 2. Annotating ternary with
|
|
36
|
+
### 2. Annotating ternary with UseBDOFormOptionsType (TS2322)
|
|
37
37
|
|
|
38
|
-
`
|
|
38
|
+
`UseBDOFormOptionsType` is a discriminated union. Type-annotating a variable prevents TS narrowing. NEVER annotate — call useBDOForm inline in each branch.
|
|
39
39
|
|
|
40
40
|
```typescript
|
|
41
41
|
// ❌ WRONG — type annotation prevents union narrowing (TS2322)
|
|
42
|
-
const options:
|
|
42
|
+
const options: UseBDOFormOptionsType<typeof bdo> = id
|
|
43
43
|
? { bdo, operation: FormOperation.Update, recordId: id, mode: ValidationMode.OnBlur }
|
|
44
44
|
: { bdo, operation: FormOperation.Create, mode: ValidationMode.OnBlur };
|
|
45
|
-
const formResult =
|
|
45
|
+
const formResult = useBDOForm(options);
|
|
46
46
|
|
|
47
|
-
// ✅ CORRECT — call
|
|
47
|
+
// ✅ CORRECT — call useBDOForm inline, no type annotation
|
|
48
48
|
const formResult = id
|
|
49
|
-
?
|
|
50
|
-
:
|
|
49
|
+
? useBDOForm({ bdo, operation: FormOperation.Update, recordId: id, mode: ValidationMode.OnBlur })
|
|
50
|
+
: useBDOForm({ bdo, operation: FormOperation.Create, mode: ValidationMode.OnBlur });
|
|
51
51
|
const { register, handleSubmit, watch, setValue, item, formState: { errors, isSubmitting }, isLoading } = formResult;
|
|
52
52
|
```
|
|
53
53
|
|
|
@@ -161,11 +161,11 @@ const onSuccess = (data: CreateUpdateResponseType) => { toast.success("Saved");
|
|
|
161
161
|
|
|
162
162
|
```typescript
|
|
163
163
|
// ❌ WRONG
|
|
164
|
-
|
|
164
|
+
useBDOForm<ProductFieldType>({ ... });
|
|
165
165
|
|
|
166
166
|
// ✅ CORRECT — pass BDO class instance
|
|
167
167
|
const product = useMemo(() => new SellerProduct(), []);
|
|
168
|
-
|
|
168
|
+
useBDOForm({ bdo: product, operation: FormOperation.Create, mode: ValidationMode.OnBlur });
|
|
169
169
|
```
|
|
170
170
|
|
|
171
171
|
### 9. Wrong default values for date fields
|
|
@@ -187,7 +187,7 @@ defaultValues: { start_date: undefined }
|
|
|
187
187
|
|
|
188
188
|
import { useMemo } from "react";
|
|
189
189
|
import { useNavigate, useParams } from "react-router-dom";
|
|
190
|
-
import {
|
|
190
|
+
import { useBDOForm, ValidationMode, FormOperation } from "@ram_28/kf-ai-sdk/form";
|
|
191
191
|
import type { CreateUpdateResponseType } from "@ram_28/kf-ai-sdk/api/types";
|
|
192
192
|
import { AdminProduct } from "@/bdo/admin/Product";
|
|
193
193
|
import { ReferenceSelect } from "@/components/ui/reference-select";
|
|
@@ -203,8 +203,8 @@ export default function ProductForm() {
|
|
|
203
203
|
|
|
204
204
|
// Create/Edit ternary — NO type annotation on result
|
|
205
205
|
const formResult = id
|
|
206
|
-
?
|
|
207
|
-
:
|
|
206
|
+
? useBDOForm({ bdo, operation: FormOperation.Update, recordId: id, mode: ValidationMode.OnBlur })
|
|
207
|
+
: useBDOForm({ bdo, operation: FormOperation.Create, mode: ValidationMode.OnBlur });
|
|
208
208
|
|
|
209
209
|
const { register, handleSubmit, watch, setValue, item, formState: { errors, isSubmitting }, isLoading } = formResult;
|
|
210
210
|
|
|
@@ -310,19 +310,19 @@ export default function ProductForm() {
|
|
|
310
310
|
|
|
311
311
|
## Type Definitions
|
|
312
312
|
|
|
313
|
-
###
|
|
313
|
+
### UseBDOFormOptionsType (Discriminated Union)
|
|
314
314
|
|
|
315
315
|
```typescript
|
|
316
|
-
type
|
|
316
|
+
type UseBDOFormOptionsType<B extends BaseBdo<any, any, any>> =
|
|
317
317
|
| { bdo: B; operation: "create"; defaultValues?: Partial<EditableFieldType>; mode?: ValidationModeType; }
|
|
318
318
|
| { bdo: B; operation: "update"; recordId: string; mode?: ValidationModeType; }
|
|
319
319
|
| { bdo: B; recordId?: string; defaultValues?: Partial<EditableFieldType>; mode?: ValidationModeType; };
|
|
320
320
|
```
|
|
321
321
|
|
|
322
|
-
###
|
|
322
|
+
### UseBDOFormReturnType
|
|
323
323
|
|
|
324
324
|
```typescript
|
|
325
|
-
interface
|
|
325
|
+
interface UseBDOFormReturnType<B> {
|
|
326
326
|
item: FormItemType<EditableFieldType, ReadonlyFieldType>; // Field accessors (.get(), .set(), .upload())
|
|
327
327
|
register: FormRegisterType; // Auto-disables readonly fields
|
|
328
328
|
handleSubmit: HandleSubmitType; // Auto-calls bdo.create() or bdo.update()
|
package/docs/useBDOTable.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# useBDOTable
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Hook for BDO (Business Data Object) tables with search, sort, filter, and pagination. Pass a BDO instance and the hook handles the rest.
|
|
4
4
|
|
|
5
5
|
## Imports
|
|
6
6
|
|
|
@@ -28,10 +28,10 @@ useBDOTable({ bdo: product });
|
|
|
28
28
|
|
|
29
29
|
### 2. Passing a raw object instead of a BDO instance
|
|
30
30
|
|
|
31
|
-
The `bdo` property expects an object with `meta
|
|
31
|
+
The `bdo` property expects an object with a `meta` property containing `_id` and `name`. A plain object or entity type will not work.
|
|
32
32
|
|
|
33
33
|
```typescript
|
|
34
|
-
// ❌ WRONG — plain object without
|
|
34
|
+
// ❌ WRONG — plain object without meta
|
|
35
35
|
useBDOTable({ bdo: { _id: 'BO_Product', name: 'Product' } });
|
|
36
36
|
|
|
37
37
|
// ✅ CORRECT — a BDO class instance
|
|
@@ -78,7 +78,7 @@ const table = useBDOTable({ bdo: product });
|
|
|
78
78
|
|
|
79
79
|
### 5. Calling `.get()` on table rows
|
|
80
80
|
|
|
81
|
-
Table `rows` are plain objects, NOT `ItemType`. The `.get()` accessor is only available on items returned by `bdo.get()`, `bdo.create()`, or the `
|
|
81
|
+
Table `rows` are plain objects, NOT `ItemType`. The `.get()` accessor is only available on items returned by `bdo.get()`, `bdo.create()`, or the `useBDOForm` item proxy.
|
|
82
82
|
|
|
83
83
|
```typescript
|
|
84
84
|
// ❌ WRONG — rows are plain objects, not ItemType
|
|
@@ -243,11 +243,9 @@ function ProductListPage() {
|
|
|
243
243
|
|
|
244
244
|
```typescript
|
|
245
245
|
export interface UseBDOTableOptionsType<T> {
|
|
246
|
-
/** BDO instance
|
|
246
|
+
/** BDO instance — only meta._id is used (for API routing) */
|
|
247
247
|
bdo: {
|
|
248
248
|
meta: { readonly _id: string; readonly name: string };
|
|
249
|
-
list(options?: any): Promise<any>;
|
|
250
|
-
count(options?: any): Promise<any>;
|
|
251
249
|
};
|
|
252
250
|
|
|
253
251
|
/** Initial state */
|
|
@@ -277,41 +275,10 @@ The return type is identical to `UseTableReturnType<T>`. All properties — `row
|
|
|
277
275
|
|
|
278
276
|
## Search, Sort, Filter, and Pagination
|
|
279
277
|
|
|
280
|
-
|
|
278
|
+
`useBDOTable` supports `initialState`, `onError`, and `onSuccess` options.
|
|
281
279
|
|
|
282
280
|
- **Search** — `table.search.set(field, query)`, `table.search.clear()`, 300ms debounce
|
|
283
281
|
- **Sort** — `table.sort.toggle(field)`, `table.sort.set(field, direction)`, `table.sort.clear()`
|
|
284
282
|
- **Filter** — `table.filter.addCondition(...)`, `table.filter.removeCondition(...)`, `table.filter.clearAllConditions()`
|
|
285
283
|
- **Pagination** — `table.pagination.goToNext()`, `table.pagination.goToPrevious()`, `table.pagination.goToPage(n)`, `table.pagination.setPageSize(n)`
|
|
286
284
|
|
|
287
|
-
---
|
|
288
|
-
|
|
289
|
-
## Migration Guide: `useTable` to `useBDOTable`
|
|
290
|
-
|
|
291
|
-
### Before (useTable)
|
|
292
|
-
|
|
293
|
-
```typescript
|
|
294
|
-
const table = useTable<BuyerProductFieldType>({
|
|
295
|
-
queryKey: ["table", product.meta._id],
|
|
296
|
-
listFn: (opts) => product.list(opts),
|
|
297
|
-
countFn: (opts) => product.count(opts),
|
|
298
|
-
initialState: { sort: [{ [product.Title.id]: "ASC" }], pagination: { pageNo: 1, pageSize: 10 } },
|
|
299
|
-
});
|
|
300
|
-
```
|
|
301
|
-
|
|
302
|
-
### After (useBDOTable)
|
|
303
|
-
|
|
304
|
-
```typescript
|
|
305
|
-
const table = useBDOTable<BuyerProductFieldType>({
|
|
306
|
-
bdo: product,
|
|
307
|
-
initialState: { sort: [{ [product.Title.id]: "ASC" }], pagination: { pageNo: 1, pageSize: 10 } },
|
|
308
|
-
});
|
|
309
|
-
```
|
|
310
|
-
|
|
311
|
-
| Property | `useTable` | `useBDOTable` |
|
|
312
|
-
|----------|-----------|---------------|
|
|
313
|
-
| Data source | `queryKey` + `listFn` + `countFn` | `bdo` (single property) |
|
|
314
|
-
| Query key | Manual: `["table", bdo.meta._id]` | Automatic: derived from `bdo.meta._id` |
|
|
315
|
-
| List function | Manual: `(opts) => bdo.list(opts)` | Automatic: bound from `bdo.list()` |
|
|
316
|
-
| Count function | Manual: `(opts) => bdo.count(opts)` | Automatic: bound from `bdo.count()` |
|
|
317
|
-
| Return type | `UseTableReturnType<T>` | `UseBDOTableReturnType<T>` (alias) |
|