@ram_28/kf-ai-sdk 2.0.14 → 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 +10 -9
- package/dist/FileField-BWrSHNRq.js +296 -0
- package/dist/FileField-eDeuzln8.cjs +1 -0
- package/dist/api.cjs +1 -1
- package/dist/api.mjs +2 -2
- package/dist/auth.cjs +1 -1
- package/dist/auth.mjs +1 -1
- package/dist/bdo/core/BaseBdo.d.ts +1 -1
- package/dist/bdo.cjs +1 -1
- package/dist/bdo.mjs +230 -474
- package/dist/{client-DnO2KKrw.cjs → client-D5k4SYuw.cjs} +1 -1
- package/dist/{client-iQTqFDNI.js → client-_ayziI1d.js} +33 -32
- package/dist/components/hooks/index.d.ts +9 -3
- package/dist/components/hooks/index.d.ts.map +1 -1
- package/dist/{workflow/components → components/hooks}/useActivityForm/createActivityItemProxy.d.ts +9 -5
- package/dist/components/hooks/useActivityForm/createActivityItemProxy.d.ts.map +1 -0
- package/dist/components/hooks/useActivityForm/createActivityResolver.d.ts +23 -0
- package/dist/components/hooks/useActivityForm/createActivityResolver.d.ts.map +1 -0
- package/dist/components/hooks/useActivityForm/index.d.ts.map +1 -0
- package/dist/{workflow/components → components/hooks}/useActivityForm/types.d.ts +12 -8
- package/dist/components/hooks/useActivityForm/types.d.ts.map +1 -0
- package/dist/{workflow/components → components/hooks}/useActivityForm/useActivityForm.d.ts +2 -2
- package/dist/components/hooks/useActivityForm/useActivityForm.d.ts.map +1 -0
- package/dist/components/hooks/useActivityTable/index.d.ts +4 -0
- package/dist/components/hooks/useActivityTable/index.d.ts.map +1 -0
- package/dist/components/hooks/useActivityTable/types.d.ts +36 -0
- package/dist/components/hooks/useActivityTable/types.d.ts.map +1 -0
- package/dist/components/hooks/useActivityTable/useActivityTable.d.ts +4 -0
- package/dist/components/hooks/useActivityTable/useActivityTable.d.ts.map +1 -0
- 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/index.d.ts +3 -0
- package/dist/components/hooks/useBDOTable/index.d.ts.map +1 -0
- package/dist/components/hooks/useBDOTable/types.d.ts +24 -0
- package/dist/components/hooks/useBDOTable/types.d.ts.map +1 -0
- package/dist/components/hooks/useBDOTable/useBDOTable.d.ts +3 -0
- package/dist/components/hooks/useBDOTable/useBDOTable.d.ts.map +1 -0
- package/dist/components/hooks/useTable/index.d.ts +2 -2
- package/dist/components/hooks/useTable/index.d.ts.map +1 -1
- package/dist/components/hooks/useTable/types.d.ts +11 -10
- package/dist/components/hooks/useTable/types.d.ts.map +1 -1
- package/dist/components/hooks/useTable/useTable.d.ts +1 -1
- package/dist/components/hooks/useTable/useTable.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 +279 -344
- package/dist/form.types.d.ts +1 -1
- package/dist/form.types.d.ts.map +1 -1
- package/dist/{metadata-DpfI3zRN.js → metadata-Cc1mBcLS.js} +1 -1
- package/dist/{metadata-DgLSJkF5.cjs → metadata-DWXQPDav.cjs} +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.d.ts +1 -0
- package/dist/table.d.ts.map +1 -1
- package/dist/table.mjs +17 -192
- package/dist/table.types.d.ts +2 -1
- package/dist/table.types.d.ts.map +1 -1
- package/dist/types/base-fields.d.ts +4 -4
- package/dist/types/base-fields.d.ts.map +1 -1
- package/dist/types/constants.d.ts +3 -3
- package/dist/useTable-CeRklbdT.cjs +1 -0
- package/dist/useTable-DS0-WInw.js +203 -0
- package/dist/workflow/Activity.d.ts +19 -7
- 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/createFieldFromMeta.d.ts +29 -0
- package/dist/workflow/createFieldFromMeta.d.ts.map +1 -0
- package/dist/workflow/index.d.ts +1 -2
- package/dist/workflow/index.d.ts.map +1 -1
- package/dist/workflow/types.d.ts +16 -12
- package/dist/workflow/types.d.ts.map +1 -1
- package/dist/workflow.cjs +1 -1
- package/dist/workflow.d.ts +5 -2
- package/dist/workflow.d.ts.map +1 -1
- package/dist/workflow.mjs +687 -352
- package/dist/workflow.types.d.ts +1 -0
- package/dist/workflow.types.d.ts.map +1 -1
- package/docs/bdo.md +1 -1
- package/docs/gaps.md +360 -0
- package/docs/useActivityForm.md +393 -0
- package/docs/useActivityTable.md +418 -0
- package/docs/{useForm.md → useBDOForm.md} +24 -24
- package/docs/useBDOTable.md +284 -0
- package/docs/workflow.md +148 -297
- package/package.json +2 -2
- package/sdk/bdo/core/BaseBdo.ts +2 -2
- package/sdk/bdo/fields/UserField.ts +1 -1
- package/sdk/components/hooks/index.ts +28 -5
- package/sdk/components/hooks/useActivityForm/createActivityItemProxy.ts +400 -0
- package/sdk/components/hooks/useActivityForm/createActivityResolver.ts +87 -0
- package/sdk/{workflow/components → components/hooks}/useActivityForm/types.ts +24 -11
- package/sdk/components/hooks/useActivityForm/useActivityForm.ts +478 -0
- package/sdk/components/hooks/useActivityTable/index.ts +8 -0
- package/sdk/components/hooks/useActivityTable/types.ts +47 -0
- package/sdk/components/hooks/useActivityTable/useActivityTable.ts +40 -0
- 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/index.ts +2 -0
- package/sdk/components/hooks/useBDOTable/types.ts +22 -0
- package/sdk/components/hooks/useBDOTable/useBDOTable.ts +16 -0
- package/sdk/components/hooks/useTable/index.ts +3 -3
- package/sdk/components/hooks/useTable/types.ts +16 -12
- package/sdk/components/hooks/useTable/useTable.ts +56 -49
- package/sdk/form.ts +2 -2
- package/sdk/form.types.ts +4 -4
- package/sdk/table.ts +4 -1
- package/sdk/table.types.ts +7 -4
- package/sdk/types/base-fields.ts +4 -4
- package/sdk/types/constants.ts +3 -3
- package/sdk/workflow/Activity.ts +36 -12
- package/sdk/workflow/client.ts +65 -12
- package/sdk/workflow/createFieldFromMeta.ts +110 -0
- package/sdk/workflow/index.ts +1 -6
- package/sdk/workflow/types.ts +20 -11
- package/sdk/workflow.ts +11 -2
- package/sdk/workflow.types.ts +7 -0
- package/dist/BaseField-B6da88U7.js +0 -40
- package/dist/BaseField-Drp0-OxL.cjs +0 -1
- 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/error-handling-CAoD0Kwb.cjs +0 -1
- package/dist/error-handling-CrhTtD88.js +0 -14
- package/dist/index.esm-Cj63v5ny.js +0 -1014
- package/dist/index.esm-DuwT11sx.cjs +0 -1
- package/dist/workflow/components/useActivityForm/createActivityItemProxy.d.ts.map +0 -1
- package/dist/workflow/components/useActivityForm/createActivityResolver.d.ts +0 -22
- package/dist/workflow/components/useActivityForm/createActivityResolver.d.ts.map +0 -1
- package/dist/workflow/components/useActivityForm/index.d.ts.map +0 -1
- package/dist/workflow/components/useActivityForm/types.d.ts.map +0 -1
- package/dist/workflow/components/useActivityForm/useActivityForm.d.ts.map +0 -1
- package/docs/useTable.md +0 -369
- package/sdk/workflow/components/useActivityForm/createActivityItemProxy.ts +0 -130
- package/sdk/workflow/components/useActivityForm/createActivityResolver.ts +0 -61
- package/sdk/workflow/components/useActivityForm/useActivityForm.ts +0 -386
- /package/dist/{workflow/components → components/hooks}/useActivityForm/index.d.ts +0 -0
- /package/dist/components/hooks/{useForm → useBDOForm}/createItemProxy.d.ts +0 -0
- /package/dist/components/hooks/{useForm → useBDOForm}/createResolver.d.ts +0 -0
- /package/sdk/{workflow/components → components/hooks}/useActivityForm/index.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/workflow.md
CHANGED
|
@@ -11,6 +11,8 @@ import {
|
|
|
11
11
|
Activity,
|
|
12
12
|
ActivityInstance,
|
|
13
13
|
useActivityForm,
|
|
14
|
+
useActivityTable,
|
|
15
|
+
ActivityTableStatus,
|
|
14
16
|
} from "@ram_28/kf-ai-sdk/workflow";
|
|
15
17
|
|
|
16
18
|
// Type-only exports
|
|
@@ -20,6 +22,10 @@ import type {
|
|
|
20
22
|
WorkflowStartResponseType,
|
|
21
23
|
UseActivityFormOptions,
|
|
22
24
|
UseActivityFormReturn,
|
|
25
|
+
UseActivityTableOptionsType,
|
|
26
|
+
UseActivityTableReturnType,
|
|
27
|
+
ActivityTableStatusType,
|
|
28
|
+
ActivityRowType,
|
|
23
29
|
} from "@ram_28/kf-ai-sdk/workflow";
|
|
24
30
|
|
|
25
31
|
// Field classes (for defining Activity fields)
|
|
@@ -31,7 +37,7 @@ import {
|
|
|
31
37
|
DateTimeField,
|
|
32
38
|
SelectField,
|
|
33
39
|
ReferenceField,
|
|
34
|
-
} from
|
|
40
|
+
} from '@ram_28/kf-ai-sdk/bdo/fields';
|
|
35
41
|
|
|
36
42
|
// Field types (for entity type definitions)
|
|
37
43
|
import type {
|
|
@@ -42,7 +48,7 @@ import type {
|
|
|
42
48
|
DateTimeFieldType,
|
|
43
49
|
SelectFieldType,
|
|
44
50
|
ReferenceFieldType,
|
|
45
|
-
} from
|
|
51
|
+
} from '@ram_28/kf-ai-sdk/types';
|
|
46
52
|
```
|
|
47
53
|
|
|
48
54
|
---
|
|
@@ -82,64 +88,28 @@ System fields present on every activity instance. Returned alongside activity-sp
|
|
|
82
88
|
type ActivityInstanceFieldsType = {
|
|
83
89
|
_id: StringFieldType;
|
|
84
90
|
Status: SelectFieldType<"InProgress" | "Completed">;
|
|
85
|
-
AssignedTo:
|
|
91
|
+
AssignedTo: UserFieldType[];
|
|
86
92
|
CompletedAt: DateTimeFieldType;
|
|
87
93
|
};
|
|
88
94
|
```
|
|
89
95
|
|
|
90
|
-
###
|
|
96
|
+
### Activity Table Types
|
|
91
97
|
|
|
92
|
-
|
|
93
|
-
interface UseActivityFormOptions<A extends Activity<any, any, any>> {
|
|
94
|
-
/** Activity instance identifier (from wf.start() or getInProgressList()) */
|
|
95
|
-
activity_instance_id: string;
|
|
98
|
+
See the dedicated [useActivityTable documentation](./useActivityTable.md) for `ActivityTableStatus`, `ActivityRowType`, `UseActivityTableOptionsType`, and `UseActivityTableReturnType`.
|
|
96
99
|
|
|
97
|
-
|
|
98
|
-
defaultValues?: Partial<ExtractActivityEditable<A>>;
|
|
100
|
+
Entity fields and system fields are flat at the top level, same as BDO tables. Access entity fields as `row.FieldName`.
|
|
99
101
|
|
|
100
|
-
/** Validation mode (default: "onBlur") */
|
|
101
|
-
mode?: "onBlur" | "onChange" | "onSubmit" | "onTouched" | "all";
|
|
102
102
|
|
|
103
|
-
|
|
104
|
-
enabled?: boolean;
|
|
105
|
-
}
|
|
106
|
-
```
|
|
103
|
+
### UseActivityFormOptions\<A\> / UseActivityFormReturn\<A\>
|
|
107
104
|
|
|
108
|
-
|
|
105
|
+
See the dedicated [useActivityForm documentation](./useActivityForm.md) for the full type definitions.
|
|
109
106
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
handleSubmit: HandleSubmitType; // Save the activity form
|
|
117
|
-
handleComplete: HandleSubmitType; // Complete the activity
|
|
118
|
-
|
|
119
|
-
// RHF methods
|
|
120
|
-
watch: UseFormWatch;
|
|
121
|
-
setValue: UseFormSetValue;
|
|
122
|
-
getValues: UseFormGetValues;
|
|
123
|
-
reset: UseFormReset;
|
|
124
|
-
trigger: UseFormTrigger;
|
|
125
|
-
control: Control;
|
|
126
|
-
|
|
127
|
-
// Form state
|
|
128
|
-
errors: FieldErrors;
|
|
129
|
-
isValid: boolean;
|
|
130
|
-
isDirty: boolean;
|
|
131
|
-
isSubmitting: boolean;
|
|
132
|
-
isSubmitSuccessful: boolean;
|
|
133
|
-
|
|
134
|
-
// Loading
|
|
135
|
-
isLoading: boolean;
|
|
136
|
-
loadError: Error | null;
|
|
137
|
-
hasError: boolean;
|
|
138
|
-
|
|
139
|
-
// Operations
|
|
140
|
-
clearErrors: () => void;
|
|
141
|
-
}
|
|
142
|
-
```
|
|
107
|
+
### File & Image Types
|
|
108
|
+
|
|
109
|
+
Image accessor: `item.field.get()` returns `FileType | null`. Has `upload(file: File)`, `deleteAttachment()`, `getDownloadUrl()`.
|
|
110
|
+
File accessor: `item.field.get()` returns `FileType[]`. Has `upload(files: File[])`, `deleteAttachment(id)`, `getDownloadUrl(id)`.
|
|
111
|
+
|
|
112
|
+
Activity forms always have an instance ID, so attachment operations work immediately — no draft creation is needed.
|
|
143
113
|
|
|
144
114
|
---
|
|
145
115
|
|
|
@@ -250,21 +220,30 @@ Each Activity class provides methods to query and access activity instances. Lis
|
|
|
250
220
|
const activity = wf.employeeInputActivity();
|
|
251
221
|
```
|
|
252
222
|
|
|
253
|
-
### getInProgressList()
|
|
223
|
+
### getInProgressList(options?)
|
|
254
224
|
|
|
255
|
-
List in-progress activity instances.
|
|
225
|
+
List in-progress activity instances. Accepts optional `ListOptionsType` payload for server-side filtering, sorting, and pagination.
|
|
256
226
|
|
|
257
227
|
```typescript
|
|
228
|
+
// No options — returns all in-progress items (default pagination)
|
|
258
229
|
const result = await activity.getInProgressList();
|
|
259
230
|
|
|
260
231
|
for (const item of result.Data) {
|
|
261
232
|
console.log(item._id, item.Status, item.StartDate);
|
|
262
233
|
}
|
|
234
|
+
|
|
235
|
+
// With options — server-side filter, sort, and pagination
|
|
236
|
+
const filtered = await activity.getInProgressList({
|
|
237
|
+
Filter: { Operator: 'And', Condition: [{ LHSField: 'Status', Operator: 'EQ', RHSValue: 'InProgress', RHSType: 'Constant' }] },
|
|
238
|
+
Sort: [{ '_created_at': 'DESC' }],
|
|
239
|
+
Page: 1,
|
|
240
|
+
PageSize: 10,
|
|
241
|
+
});
|
|
263
242
|
```
|
|
264
243
|
|
|
265
|
-
### getCompletedList()
|
|
244
|
+
### getCompletedList(options?)
|
|
266
245
|
|
|
267
|
-
List completed activity instances.
|
|
246
|
+
List completed activity instances. Same options as `getInProgressList`.
|
|
268
247
|
|
|
269
248
|
```typescript
|
|
270
249
|
const result = await activity.getCompletedList();
|
|
@@ -274,20 +253,46 @@ for (const item of result.Data) {
|
|
|
274
253
|
}
|
|
275
254
|
```
|
|
276
255
|
|
|
277
|
-
###
|
|
256
|
+
### inProgressCount(options?)
|
|
257
|
+
|
|
258
|
+
Get count of in-progress activity instances. Returns `number`.
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
const count = await activity.inProgressCount();
|
|
262
|
+
console.log('In-progress count:', count);
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### completedCount(options?)
|
|
266
|
+
|
|
267
|
+
Get count of completed activity instances. Returns `number`.
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
const count = await activity.completedCount();
|
|
271
|
+
console.log('Completed count:', count);
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### inProgressMetric(options)
|
|
278
275
|
|
|
279
|
-
Get aggregated metrics for in-progress activity instances.
|
|
276
|
+
Get aggregated metrics for in-progress activity instances. Accepts `Omit<MetricOptionsType, 'Type'>` for custom aggregations (Sum, Avg, Count, etc.). Returns `MetricResponseType` (`{ Data: Record<string, any>[] }`).
|
|
280
277
|
|
|
281
278
|
```typescript
|
|
282
|
-
const
|
|
279
|
+
const result = await activity.inProgressMetric({
|
|
280
|
+
GroupBy: ['Status'],
|
|
281
|
+
Metric: [{ Field: '_id', Type: 'Count' }],
|
|
282
|
+
});
|
|
283
|
+
console.log(result.Data);
|
|
283
284
|
```
|
|
284
285
|
|
|
285
|
-
###
|
|
286
|
+
### completedMetric(options)
|
|
286
287
|
|
|
287
|
-
Get aggregated metrics for completed activity instances.
|
|
288
|
+
Get aggregated metrics for completed activity instances. Same signature as `inProgressMetric`.
|
|
288
289
|
|
|
289
290
|
```typescript
|
|
290
|
-
const
|
|
291
|
+
const result = await activity.completedMetric({
|
|
292
|
+
GroupBy: [],
|
|
293
|
+
Metric: [{ Field: 'LeaveDays', Type: 'Sum' }],
|
|
294
|
+
});
|
|
295
|
+
console.log('Total leave days:', result.Data[0]?.sum_LeaveDays);
|
|
291
296
|
```
|
|
292
297
|
|
|
293
298
|
### getInstance(instanceId)
|
|
@@ -320,68 +325,19 @@ const progress = await instance.progress(); // get progress (ActivityP
|
|
|
320
325
|
|
|
321
326
|
## useActivityForm Hook
|
|
322
327
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
### Options
|
|
328
|
+
See the dedicated [useActivityForm documentation](./useActivityForm.md) for the full API reference, type definitions, and examples.
|
|
326
329
|
|
|
327
|
-
|
|
328
|
-
|----------|------|---------|-------------|
|
|
329
|
-
| `activity_instance_id` | `string` | *required* | Activity instance ID (from `wf.start()` or `getInProgressList()`) |
|
|
330
|
-
| `defaultValues` | `Partial<Editable>` | `{}` | Initial form values |
|
|
331
|
-
| `mode` | `"onBlur" \| "onChange" \| "onSubmit" \| "onTouched" \| "all"` | `"onBlur"` | Validation timing |
|
|
332
|
-
| `enabled` | `boolean` | `true` | Whether to load activity data on mount |
|
|
330
|
+
---
|
|
333
331
|
|
|
334
|
-
|
|
332
|
+
## useActivityTable Hook
|
|
335
333
|
|
|
336
|
-
|
|
337
|
-
Mount
|
|
338
|
-
|
|
|
339
|
-
|-> Load activity instance data -> populate form
|
|
340
|
-
|
|
|
341
|
-
v
|
|
342
|
-
User edits field -> blurs
|
|
343
|
-
|
|
|
344
|
-
|-> Field validation (BaseField.validate)
|
|
345
|
-
|-> If valid + readonly fields exist -> update computed fields
|
|
346
|
-
|
|
|
347
|
-
v
|
|
348
|
-
User clicks Save
|
|
349
|
-
|
|
|
350
|
-
|-> handleSubmit -> save activity data
|
|
351
|
-
|
|
|
352
|
-
v
|
|
353
|
-
User clicks Complete
|
|
354
|
-
|
|
|
355
|
-
|-> handleComplete -> complete activity
|
|
356
|
-
```
|
|
334
|
+
See the dedicated [useActivityTable documentation](./useActivityTable.md) for the full API reference, type definitions, and examples.
|
|
357
335
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
| Property | Type | Description |
|
|
361
|
-
|----------|------|-------------|
|
|
362
|
-
| `item` | `FormItemType` | Proxy with typed field accessors (`.get()`, `.set()`, `.meta`) |
|
|
363
|
-
| `activity` | `A` | The Activity instance |
|
|
364
|
-
| `register` | `FormRegisterType` | Smart register (auto-disables readonly fields) |
|
|
365
|
-
| `handleSubmit` | `HandleSubmitType` | Save activity data |
|
|
366
|
-
| `handleComplete` | `HandleSubmitType` | Complete the activity |
|
|
367
|
-
| `watch` | `UseFormWatch` | Watch field values |
|
|
368
|
-
| `setValue` | `UseFormSetValue` | Set field value programmatically |
|
|
369
|
-
| `getValues` | `UseFormGetValues` | Get current field values |
|
|
370
|
-
| `reset` | `UseFormReset` | Reset form to default values |
|
|
371
|
-
| `trigger` | `UseFormTrigger` | Trigger validation |
|
|
372
|
-
| `control` | `Control` | RHF control (for Controller components) |
|
|
373
|
-
| `errors` | `FieldErrors` | Validation errors |
|
|
374
|
-
| `isValid` | `boolean` | Form is valid |
|
|
375
|
-
| `isDirty` | `boolean` | Form has been modified |
|
|
376
|
-
| `isSubmitting` | `boolean` | Currently submitting |
|
|
377
|
-
| `isSubmitSuccessful` | `boolean` | Last submission succeeded |
|
|
378
|
-
| `isLoading` | `boolean` | Loading activity data |
|
|
379
|
-
| `loadError` | `Error \| null` | Load error |
|
|
380
|
-
| `hasError` | `boolean` | Any error active |
|
|
381
|
-
| `clearErrors` | `() => void` | Clear all form errors |
|
|
336
|
+
`useActivityTable` provides search, sort, filter, and pagination capabilities, same as `useBDOTable`. Entity fields are accessed at the top level (e.g., `row.FieldName`).
|
|
382
337
|
|
|
383
338
|
---
|
|
384
339
|
|
|
340
|
+
|
|
385
341
|
## Use Case: Employee Creating Leave
|
|
386
342
|
|
|
387
343
|
### Step 1 — Start the workflow
|
|
@@ -399,115 +355,7 @@ const progress = await wf.progress(BPInstanceId);
|
|
|
399
355
|
|
|
400
356
|
### Step 2 — React component with useActivityForm
|
|
401
357
|
|
|
402
|
-
|
|
403
|
-
import { useMemo } from "react";
|
|
404
|
-
import { useActivityForm } from "@ram_28/kf-ai-sdk/workflow";
|
|
405
|
-
import type { UseActivityFormOptions } from "@ram_28/kf-ai-sdk/workflow";
|
|
406
|
-
import type { FieldErrors } from "react-hook-form";
|
|
407
|
-
import { SimpleLeaveProcess, EmployeeInputActivity } from "@/bdo/workflows/SimpleLeaveProcess";
|
|
408
|
-
|
|
409
|
-
interface LeaveRequestFormProps {
|
|
410
|
-
activityInstanceId: string;
|
|
411
|
-
onComplete: () => void;
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
function LeaveRequestForm({ activityInstanceId, onComplete }: LeaveRequestFormProps) {
|
|
415
|
-
// 1. Get the typed activity from the workflow
|
|
416
|
-
const activity = useMemo(() => new SimpleLeaveProcess().employeeInputActivity(), []);
|
|
417
|
-
|
|
418
|
-
// 2. Hook options
|
|
419
|
-
const options: UseActivityFormOptions<EmployeeInputActivity> = {
|
|
420
|
-
activity_instance_id: activityInstanceId,
|
|
421
|
-
defaultValues: {
|
|
422
|
-
StartDate: undefined,
|
|
423
|
-
EndDate: undefined,
|
|
424
|
-
LeaveType: undefined,
|
|
425
|
-
},
|
|
426
|
-
mode: "onBlur",
|
|
427
|
-
};
|
|
428
|
-
|
|
429
|
-
// 3. Initialize hook
|
|
430
|
-
const {
|
|
431
|
-
register,
|
|
432
|
-
handleSubmit,
|
|
433
|
-
handleComplete,
|
|
434
|
-
item,
|
|
435
|
-
errors,
|
|
436
|
-
isLoading,
|
|
437
|
-
isSubmitting,
|
|
438
|
-
loadError,
|
|
439
|
-
} = useActivityForm(activity, options);
|
|
440
|
-
|
|
441
|
-
if (isLoading) return <div>Loading...</div>;
|
|
442
|
-
if (loadError) return <div>Error: {loadError.message}</div>;
|
|
443
|
-
|
|
444
|
-
// 4. Handlers
|
|
445
|
-
const onSaveSuccess = (): void => {
|
|
446
|
-
console.log("Saved!");
|
|
447
|
-
};
|
|
448
|
-
|
|
449
|
-
const onCompleteSuccess = (): void => {
|
|
450
|
-
console.log("Leave request submitted!");
|
|
451
|
-
onComplete();
|
|
452
|
-
};
|
|
453
|
-
|
|
454
|
-
const onError = (error: FieldErrors | Error): void => {
|
|
455
|
-
if (error instanceof Error) {
|
|
456
|
-
console.error("API Error:", error.message);
|
|
457
|
-
} else {
|
|
458
|
-
console.error("Validation errors:", error);
|
|
459
|
-
}
|
|
460
|
-
};
|
|
461
|
-
|
|
462
|
-
return (
|
|
463
|
-
<form>
|
|
464
|
-
<h2>Leave Request</h2>
|
|
465
|
-
|
|
466
|
-
{/* Start Date */}
|
|
467
|
-
<div>
|
|
468
|
-
<label>{activity.StartDate.meta.label}</label>
|
|
469
|
-
<input type="date" {...register(activity.StartDate.meta.id)} />
|
|
470
|
-
{errors.StartDate && <span>{errors.StartDate.message}</span>}
|
|
471
|
-
</div>
|
|
472
|
-
|
|
473
|
-
{/* End Date */}
|
|
474
|
-
<div>
|
|
475
|
-
<label>{activity.EndDate.meta.label}</label>
|
|
476
|
-
<input type="date" {...register(activity.EndDate.meta.id)} />
|
|
477
|
-
{errors.EndDate && <span>{errors.EndDate.message}</span>}
|
|
478
|
-
</div>
|
|
479
|
-
|
|
480
|
-
{/* Leave Type */}
|
|
481
|
-
<div>
|
|
482
|
-
<label>{activity.LeaveType.meta.label}</label>
|
|
483
|
-
<select {...register(activity.LeaveType.meta.id)}>
|
|
484
|
-
<option value="">Select type</option>
|
|
485
|
-
<option value="PTO">PTO</option>
|
|
486
|
-
<option value="Sick">Sick</option>
|
|
487
|
-
<option value="Parental">Parental</option>
|
|
488
|
-
</select>
|
|
489
|
-
{errors.LeaveType && <span>{errors.LeaveType.message}</span>}
|
|
490
|
-
</div>
|
|
491
|
-
|
|
492
|
-
{/* Leave Days (readonly — auto-disabled, computed by server) */}
|
|
493
|
-
<div>
|
|
494
|
-
<label>{activity.LeaveDays.meta.label}</label>
|
|
495
|
-
<input type="number" {...register(activity.LeaveDays.meta.id)} />
|
|
496
|
-
</div>
|
|
497
|
-
|
|
498
|
-
{/* Actions */}
|
|
499
|
-
<div>
|
|
500
|
-
<button type="button" onClick={handleSubmit(onSaveSuccess, onError)}>
|
|
501
|
-
{isSubmitting ? "Saving..." : "Save Draft"}
|
|
502
|
-
</button>
|
|
503
|
-
<button type="button" onClick={handleComplete(onCompleteSuccess, onError)}>
|
|
504
|
-
{isSubmitting ? "Submitting..." : "Submit Leave Request"}
|
|
505
|
-
</button>
|
|
506
|
-
</div>
|
|
507
|
-
</form>
|
|
508
|
-
);
|
|
509
|
-
}
|
|
510
|
-
```
|
|
358
|
+
See [useActivityForm](./useActivityForm.md) for the full form component example.
|
|
511
359
|
|
|
512
360
|
### Full flow orchestration
|
|
513
361
|
|
|
@@ -544,90 +392,80 @@ function LeaveRequestPage() {
|
|
|
544
392
|
|
|
545
393
|
### Step 1 — List in-progress items
|
|
546
394
|
|
|
547
|
-
```typescript
|
|
548
|
-
import { SimpleLeaveProcess } from "@/bdo/workflows/SimpleLeaveProcess";
|
|
549
|
-
|
|
550
|
-
const wf = new SimpleLeaveProcess();
|
|
551
|
-
const activity = wf.managerApprovalActivity();
|
|
552
|
-
|
|
553
|
-
const result = await activity.getInProgressList();
|
|
554
|
-
|
|
555
|
-
for (const item of result.Data) {
|
|
556
|
-
console.log(item._id, item.Status, item.AssignedTo.username);
|
|
557
|
-
}
|
|
558
|
-
```
|
|
559
|
-
|
|
560
|
-
### Step 2 — Approval form component
|
|
561
|
-
|
|
562
395
|
```tsx
|
|
563
|
-
import { useMemo } from "react";
|
|
564
|
-
import {
|
|
565
|
-
import type { UseActivityFormOptions } from "@ram_28/kf-ai-sdk/workflow";
|
|
566
|
-
import type { FieldErrors } from "react-hook-form";
|
|
396
|
+
import { useMemo, useState } from "react";
|
|
397
|
+
import { useActivityTable, ActivityTableStatus } from "@ram_28/kf-ai-sdk/workflow";
|
|
567
398
|
import { SimpleLeaveProcess, ManagerApprovalActivity } from "@/bdo/workflows/SimpleLeaveProcess";
|
|
568
399
|
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
onComplete: () => void;
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
function ApprovalForm({ activityInstanceId, onComplete }: ApprovalFormProps) {
|
|
575
|
-
const activity = useMemo(() => new SimpleLeaveProcess().managerApprovalActivity(), []);
|
|
400
|
+
const wf = new SimpleLeaveProcess();
|
|
401
|
+
const activity = wf.managerApprovalActivity();
|
|
576
402
|
|
|
577
|
-
const
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
403
|
+
const { rows, totalItems, isLoading, error, pagination, refetch } = useActivityTable({
|
|
404
|
+
activity,
|
|
405
|
+
status: ActivityTableStatus.InProgress,
|
|
406
|
+
initialState: {
|
|
407
|
+
pagination: { pageNo: 1, pageSize: 10 },
|
|
582
408
|
},
|
|
583
|
-
|
|
584
|
-
};
|
|
585
|
-
|
|
586
|
-
const {
|
|
587
|
-
register,
|
|
588
|
-
handleComplete,
|
|
589
|
-
errors,
|
|
590
|
-
isLoading,
|
|
591
|
-
isSubmitting,
|
|
592
|
-
loadError,
|
|
593
|
-
} = useActivityForm(activity, options);
|
|
409
|
+
});
|
|
594
410
|
|
|
595
411
|
if (isLoading) return <div>Loading...</div>;
|
|
596
|
-
if (
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
412
|
+
if (error) return <div>Error: {error.message}</div>;
|
|
413
|
+
|
|
414
|
+
if (selectedId) {
|
|
415
|
+
return (
|
|
416
|
+
<ApprovalForm
|
|
417
|
+
activityInstanceId={selectedId}
|
|
418
|
+
onComplete={() => {
|
|
419
|
+
setSelectedId(null);
|
|
420
|
+
refetch();
|
|
421
|
+
}}
|
|
422
|
+
/>
|
|
423
|
+
);
|
|
424
|
+
}
|
|
606
425
|
|
|
607
426
|
return (
|
|
608
|
-
<
|
|
609
|
-
<h2>
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
427
|
+
<div>
|
|
428
|
+
<h2>Pending Approvals ({totalItems})</h2>
|
|
429
|
+
<table>
|
|
430
|
+
<thead>
|
|
431
|
+
<tr>
|
|
432
|
+
<th>ID</th>
|
|
433
|
+
<th>Status</th>
|
|
434
|
+
<th>Assigned To</th>
|
|
435
|
+
<th>Approved</th>
|
|
436
|
+
<th>Reason</th>
|
|
437
|
+
<th>Action</th>
|
|
438
|
+
</tr>
|
|
439
|
+
</thead>
|
|
440
|
+
<tbody>
|
|
441
|
+
{rows.map((row) => (
|
|
442
|
+
<tr key={row._id}>
|
|
443
|
+
<td>{row._id}</td>
|
|
444
|
+
<td>{row.Status}</td>
|
|
445
|
+
<td>{row.AssignedTo.map((u) => u._name).join(", ")}</td>
|
|
446
|
+
<td>{row.ManagerApproved ? "Yes" : "No"}</td>
|
|
447
|
+
<td>{row.ManagerReason}</td>
|
|
448
|
+
<td>
|
|
449
|
+
<button onClick={() => setSelectedId(row._id)}>Review</button>
|
|
450
|
+
</td>
|
|
451
|
+
</tr>
|
|
452
|
+
))}
|
|
453
|
+
</tbody>
|
|
454
|
+
</table>
|
|
618
455
|
<div>
|
|
619
|
-
<
|
|
620
|
-
<
|
|
456
|
+
<button onClick={pagination.goToPrevious} disabled={!pagination.canGoPrevious}>Previous</button>
|
|
457
|
+
<span>Page {pagination.pageNo} of {pagination.totalPages}</span>
|
|
458
|
+
<button onClick={pagination.goToNext} disabled={!pagination.canGoNext}>Next</button>
|
|
621
459
|
</div>
|
|
622
|
-
|
|
623
|
-
<button type="button" onClick={handleComplete(onSuccess, onError)}>
|
|
624
|
-
{isSubmitting ? "Submitting..." : "Submit Decision"}
|
|
625
|
-
</button>
|
|
626
|
-
</form>
|
|
460
|
+
</div>
|
|
627
461
|
);
|
|
628
462
|
}
|
|
629
463
|
```
|
|
630
464
|
|
|
465
|
+
### Step 2 — Approval form component
|
|
466
|
+
|
|
467
|
+
See [useActivityForm](./useActivityForm.md) for the full approval form component example.
|
|
468
|
+
|
|
631
469
|
---
|
|
632
470
|
|
|
633
471
|
## Use Case: Programmatic ActivityInstance
|
|
@@ -653,7 +491,7 @@ instance.StartDate.set("2026-03-01");
|
|
|
653
491
|
instance.EndDate.set("2026-03-05");
|
|
654
492
|
|
|
655
493
|
// Field metadata
|
|
656
|
-
console.log(instance.StartDate.
|
|
494
|
+
console.log(instance.StartDate.label); // "Start Date"
|
|
657
495
|
|
|
658
496
|
// Persist changes
|
|
659
497
|
await instance.update({ StartDate: "2026-03-01", EndDate: "2026-03-05" });
|
|
@@ -672,18 +510,31 @@ const progress = await instance.progress();
|
|
|
672
510
|
|
|
673
511
|
## Filtering Reference
|
|
674
512
|
|
|
675
|
-
Status filtering is built into the method names (`getInProgressList` / `getCompletedList`).
|
|
513
|
+
Status filtering is built into the method names (`getInProgressList` / `getCompletedList`). Internal filters (ActivityId, Status, AssignedTo) are **always applied** by the backend. Frontend filters passed via `ListOptionsType` are AND-merged with the internal filters.
|
|
514
|
+
|
|
515
|
+
All four list/metric endpoints now use **POST** with an optional `ListOptionsType` body (same shape as BDO list API: `{ Filter, Sort, Page, PageSize }`).
|
|
676
516
|
|
|
677
517
|
### In-progress items
|
|
678
518
|
|
|
679
519
|
```typescript
|
|
520
|
+
// No options — returns all (default pagination)
|
|
680
521
|
const result = await activity.getInProgressList();
|
|
522
|
+
|
|
523
|
+
// With filter + pagination
|
|
524
|
+
const result = await activity.getInProgressList({
|
|
525
|
+
Sort: [{ '_created_at': 'DESC' }],
|
|
526
|
+
Page: 1,
|
|
527
|
+
PageSize: 25,
|
|
528
|
+
});
|
|
681
529
|
```
|
|
682
530
|
|
|
683
531
|
### Completed items
|
|
684
532
|
|
|
685
533
|
```typescript
|
|
686
|
-
const result = await activity.getCompletedList(
|
|
534
|
+
const result = await activity.getCompletedList({
|
|
535
|
+
Page: 1,
|
|
536
|
+
PageSize: 25,
|
|
537
|
+
});
|
|
687
538
|
```
|
|
688
539
|
|
|
689
540
|
### Process progress
|
|
@@ -703,7 +554,7 @@ const progressList = await wf.progress(BPInstanceId);
|
|
|
703
554
|
|-------|------|-------------|
|
|
704
555
|
| `_id` | `StringFieldType` | Unique activity instance identifier |
|
|
705
556
|
| `Status` | `SelectFieldType<"InProgress" \| "Completed">` | Current status |
|
|
706
|
-
| `AssignedTo` | `
|
|
557
|
+
| `AssignedTo` | `UserFieldType[]` | Assigned users (each has `._id` and `._name`) |
|
|
707
558
|
| `CompletedAt` | `DateTimeFieldType` | Completion timestamp (`"YYYY-MM-DDTHH:MM:SS"`) |
|
|
708
559
|
|
|
709
560
|
---
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ram_28/kf-ai-sdk",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.16",
|
|
4
4
|
"description": "Type-safe, AI-driven SDK for building modern web applications with role-based access control",
|
|
5
5
|
"author": "Ramprasad",
|
|
6
6
|
"license": "MIT",
|
|
@@ -189,7 +189,7 @@
|
|
|
189
189
|
"react",
|
|
190
190
|
"hooks",
|
|
191
191
|
"typescript",
|
|
192
|
-
"
|
|
192
|
+
"useBDOForm",
|
|
193
193
|
"useTable",
|
|
194
194
|
"useFilter",
|
|
195
195
|
"bdo",
|
package/sdk/bdo/core/BaseBdo.ts
CHANGED
|
@@ -127,7 +127,7 @@ export abstract class BaseBdo<
|
|
|
127
127
|
/**
|
|
128
128
|
* Load backend metadata for expression-based validation
|
|
129
129
|
*
|
|
130
|
-
* Called by
|
|
130
|
+
* Called by useBDOForm after fetching schema from the backend.
|
|
131
131
|
* This enables expression-based validation rules to be used
|
|
132
132
|
* in addition to type validation.
|
|
133
133
|
*
|
|
@@ -241,7 +241,7 @@ export abstract class BaseBdo<
|
|
|
241
241
|
}
|
|
242
242
|
|
|
243
243
|
// ============================================================
|
|
244
|
-
// DRAFT OPERATIONS (for
|
|
244
|
+
// DRAFT OPERATIONS (for useBDOForm integration)
|
|
245
245
|
// ============================================================
|
|
246
246
|
|
|
247
247
|
/**
|
|
@@ -35,7 +35,7 @@ export class UserField extends BaseField<UserFieldType> {
|
|
|
35
35
|
async fetchOptions(instanceId: string): Promise<UserFieldType[]> {
|
|
36
36
|
if (!this._parentBoId) {
|
|
37
37
|
throw new Error(
|
|
38
|
-
`Field ${this.id} not bound to a BDO. Cannot fetch options
|
|
38
|
+
`Field ${this.id} not bound to a BDO. Cannot fetch options.`,
|
|
39
39
|
);
|
|
40
40
|
}
|
|
41
41
|
return api(this._parentBoId).fetchField<UserFieldType>(instanceId, this.id);
|
|
@@ -1,10 +1,33 @@
|
|
|
1
|
-
// Table hook
|
|
2
|
-
export { useTable } from
|
|
1
|
+
// Table hook (base)
|
|
2
|
+
export { useTable } from './useTable';
|
|
3
3
|
export type {
|
|
4
4
|
UseTableOptionsType,
|
|
5
5
|
UseTableReturnType,
|
|
6
|
-
|
|
7
|
-
} from
|
|
6
|
+
PaginationStateType,
|
|
7
|
+
} from './useTable';
|
|
8
|
+
|
|
9
|
+
// BDO table hook
|
|
10
|
+
export { useBDOTable } from './useBDOTable';
|
|
11
|
+
export type {
|
|
12
|
+
UseBDOTableOptionsType,
|
|
13
|
+
UseBDOTableReturnType,
|
|
14
|
+
} from './useBDOTable';
|
|
15
|
+
|
|
16
|
+
// Activity table hook
|
|
17
|
+
export { useActivityTable, ActivityTableStatus } from './useActivityTable';
|
|
18
|
+
export type {
|
|
19
|
+
UseActivityTableOptionsType,
|
|
20
|
+
UseActivityTableReturnType,
|
|
21
|
+
ActivityTableStatusType,
|
|
22
|
+
ActivityRowType,
|
|
23
|
+
} from './useActivityTable';
|
|
24
|
+
|
|
25
|
+
// Activity form hook
|
|
26
|
+
export { useActivityForm } from './useActivityForm';
|
|
27
|
+
export type {
|
|
28
|
+
UseActivityFormOptions,
|
|
29
|
+
UseActivityFormReturn,
|
|
30
|
+
} from './useActivityForm';
|
|
8
31
|
|
|
9
32
|
// Filter hook
|
|
10
|
-
export * from
|
|
33
|
+
export * from './useFilter';
|