@ram_28/kf-ai-sdk 2.0.16 → 2.0.18
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 +16 -8
- package/dist/{FileField-BWrSHNRq.js → FileField-CZjS2uLh.js} +3 -3
- package/dist/{FileField-eDeuzln8.cjs → FileField-DU4UWo_t.cjs} +1 -1
- package/dist/api.cjs +1 -1
- package/dist/api.mjs +1 -1
- package/dist/auth/authConfig.d.ts +1 -1
- package/dist/auth/types.d.ts +1 -1
- package/dist/auth/types.d.ts.map +1 -1
- package/dist/auth.cjs +1 -1
- package/dist/auth.mjs +1 -1
- package/dist/bdo/core/Item.d.ts +0 -4
- package/dist/bdo/core/Item.d.ts.map +1 -1
- package/dist/bdo/fields/ReferenceField.d.ts +1 -1
- package/dist/bdo/fields/ReferenceField.d.ts.map +1 -1
- package/dist/bdo/fields/SelectField.d.ts +1 -1
- package/dist/bdo/fields/SelectField.d.ts.map +1 -1
- package/dist/bdo/fields/UserField.d.ts +1 -1
- package/dist/bdo/fields/UserField.d.ts.map +1 -1
- package/dist/bdo.cjs +1 -1
- package/dist/bdo.mjs +53 -62
- package/dist/components/hooks/useActivityForm/types.d.ts +4 -5
- 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 +5 -4
- package/dist/components/hooks/useActivityTable/types.d.ts.map +1 -1
- package/dist/components/hooks/useActivityTable/useActivityTable.d.ts.map +1 -1
- package/dist/components/hooks/useBDOForm/createItemProxy.d.ts +2 -3
- package/dist/components/hooks/useBDOForm/createItemProxy.d.ts.map +1 -1
- package/dist/components/hooks/useBDOTable/types.d.ts +20 -12
- package/dist/components/hooks/useBDOTable/types.d.ts.map +1 -1
- package/dist/components/hooks/useBDOTable/useBDOTable.d.ts +2 -2
- package/dist/components/hooks/useBDOTable/useBDOTable.d.ts.map +1 -1
- package/dist/{constants-ConHc1oS.js → constants-Cyi942Yr.js} +5 -5
- package/dist/constants-DEmYwKfC.cjs +1 -0
- package/dist/filter.cjs +1 -1
- package/dist/filter.mjs +1 -1
- package/dist/form.cjs +1 -1
- package/dist/form.mjs +226 -243
- package/dist/table.cjs +1 -1
- package/dist/table.mjs +15 -16
- package/dist/table.types.d.ts +1 -1
- package/dist/table.types.d.ts.map +1 -1
- package/dist/types/constants.d.ts +1 -1
- package/dist/workflow/Activity.d.ts +8 -5
- package/dist/workflow/Activity.d.ts.map +1 -1
- package/dist/workflow.cjs +1 -1
- package/dist/workflow.mjs +461 -476
- package/docs/README.md +57 -0
- package/docs/bdo/README.md +161 -0
- package/docs/bdo/api_reference.md +281 -0
- package/docs/examples/bdo/create-product.md +69 -0
- package/docs/examples/bdo/edit-product-dialog.md +95 -0
- package/docs/examples/bdo/filtered-product-table.md +100 -0
- package/docs/examples/bdo/product-listing.md +73 -0
- package/docs/examples/bdo/supplier-dropdown.md +60 -0
- package/docs/examples/fields/complex-fields.md +248 -0
- package/docs/examples/fields/primitive-fields.md +217 -0
- package/docs/examples/workflow/approve-leave-request.md +76 -0
- package/docs/examples/workflow/filtered-activity-table.md +101 -0
- package/docs/examples/workflow/my-pending-requests.md +90 -0
- package/docs/examples/workflow/start-new-workflow.md +47 -0
- package/docs/examples/workflow/submit-leave-request.md +72 -0
- package/docs/examples/workflow/workflow-progress.md +49 -0
- package/docs/fields/README.md +141 -0
- package/docs/fields/api_reference.md +134 -0
- package/docs/useActivityForm/README.md +244 -0
- package/docs/useActivityForm/api_reference.md +279 -0
- package/docs/useActivityTable/README.md +263 -0
- package/docs/useActivityTable/api_reference.md +294 -0
- package/docs/useBDOForm/README.md +175 -0
- package/docs/useBDOForm/api_reference.md +244 -0
- package/docs/useBDOTable/README.md +242 -0
- package/docs/useBDOTable/api_reference.md +253 -0
- package/docs/useFilter/README.md +323 -0
- package/docs/useFilter/api_reference.md +228 -0
- package/docs/workflow/README.md +158 -0
- package/docs/workflow/api_reference.md +161 -0
- package/package.json +1 -1
- package/sdk/auth/authConfig.ts +1 -1
- package/sdk/auth/types.ts +1 -1
- package/sdk/bdo/core/Item.ts +1 -10
- package/sdk/bdo/fields/ReferenceField.ts +1 -1
- package/sdk/bdo/fields/SelectField.ts +1 -1
- package/sdk/bdo/fields/UserField.ts +1 -1
- package/sdk/components/hooks/useActivityForm/types.ts +4 -6
- package/sdk/components/hooks/useActivityForm/useActivityForm.ts +10 -73
- package/sdk/components/hooks/useActivityTable/types.ts +4 -5
- package/sdk/components/hooks/useActivityTable/useActivityTable.ts +10 -8
- package/sdk/components/hooks/useBDOForm/createItemProxy.ts +17 -58
- package/sdk/components/hooks/useBDOTable/types.ts +20 -10
- package/sdk/components/hooks/useBDOTable/useBDOTable.ts +12 -8
- package/sdk/table.types.ts +2 -0
- package/sdk/types/constants.ts +1 -1
- package/sdk/workflow/Activity.ts +39 -7
- package/dist/constants-QX2RX-wu.cjs +0 -1
- package/docs/api.md +0 -95
- package/docs/bdo.md +0 -224
- package/docs/gaps.md +0 -360
- package/docs/useActivityForm.md +0 -393
- package/docs/useActivityTable.md +0 -418
- package/docs/useBDOForm.md +0 -376
- package/docs/useBDOTable.md +0 -284
- package/docs/useFilter.md +0 -188
- package/docs/workflow.md +0 -560
- /package/docs/{useAuth.md → useAuth/README.md} +0 -0
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# useFilter API Reference
|
|
2
|
+
|
|
3
|
+
```tsx
|
|
4
|
+
import { useFilter, ConditionOperator, GroupOperator, FilterValueSource } from "@ram_28/kf-ai-sdk/filter";
|
|
5
|
+
import { isCondition, isConditionGroup } from "@ram_28/kf-ai-sdk/filter";
|
|
6
|
+
import type {
|
|
7
|
+
UseFilterOptionsType,
|
|
8
|
+
UseFilterReturnType,
|
|
9
|
+
ConditionType,
|
|
10
|
+
ConditionGroupType,
|
|
11
|
+
ConditionGroupOperatorType,
|
|
12
|
+
FilterType,
|
|
13
|
+
FilterRHSType,
|
|
14
|
+
} from "@ram_28/kf-ai-sdk/filter/types";
|
|
15
|
+
import type { ConditionOperatorType } from "@ram_28/kf-ai-sdk/api/types";
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Signature
|
|
19
|
+
|
|
20
|
+
```tsx
|
|
21
|
+
const filter: UseFilterReturnType<T> = useFilter<T>(options: UseFilterOptionsType<T>);
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Options
|
|
25
|
+
|
|
26
|
+
`UseFilterOptionsType<T>`
|
|
27
|
+
|
|
28
|
+
- `conditions?: Array<ConditionType<T> | ConditionGroupType<T>>`
|
|
29
|
+
- **Optional**, defaults to `[]`
|
|
30
|
+
- Initial filter conditions. Each item is cloned and assigned an auto-generated `id`.
|
|
31
|
+
- `operator?: ConditionGroupOperatorType`
|
|
32
|
+
- **Optional**, defaults to `"And"`
|
|
33
|
+
- Root operator for combining top-level conditions.
|
|
34
|
+
|
|
35
|
+
## Return Value
|
|
36
|
+
|
|
37
|
+
`UseFilterReturnType<T>`
|
|
38
|
+
|
|
39
|
+
### State
|
|
40
|
+
|
|
41
|
+
- `operator: ConditionGroupOperatorType`
|
|
42
|
+
- Current root operator (`"And"` | `"Or"` | `"Not"`).
|
|
43
|
+
- `items: Array<ConditionType<T> | ConditionGroupType<T>>`
|
|
44
|
+
- Current filter items with `id` populated. This is the stateful tree used for rendering and lookups.
|
|
45
|
+
- `payload: FilterType<T> | undefined`
|
|
46
|
+
- API-ready filter payload with all `id` fields stripped. Returns `undefined` when there are no conditions.
|
|
47
|
+
- `hasConditions: boolean`
|
|
48
|
+
- `true` when at least one condition exists. Equivalent to `items.length > 0`.
|
|
49
|
+
|
|
50
|
+
### Add Operations
|
|
51
|
+
|
|
52
|
+
Both methods return the `id` (string) of the newly created item.
|
|
53
|
+
|
|
54
|
+
- `addCondition(condition: Omit<ConditionType<T>, "id">, parentId?: string): string`
|
|
55
|
+
- Add a leaf condition. When `parentId` is omitted, appended at root level. When provided, added inside the matching group's `Condition` array. Returns the auto-generated `id`.
|
|
56
|
+
- `addConditionGroup(operator: ConditionGroupOperatorType, parentId?: string): string`
|
|
57
|
+
- Create an empty condition group with the given operator. Same `parentId` behavior as `addCondition`. Returns the group's `id`.
|
|
58
|
+
|
|
59
|
+
### Update Operations
|
|
60
|
+
|
|
61
|
+
- `updateCondition(id: string, updates: Partial<Omit<ConditionType<T>, "id">>): void`
|
|
62
|
+
- Partially update a leaf condition by `id`. Only provided fields are merged. No effect if `id` matches a group.
|
|
63
|
+
- `updateGroupOperator(id: string, operator: ConditionGroupOperatorType): void`
|
|
64
|
+
- Change the `Operator` of a condition group by `id`. No effect if `id` matches a leaf condition.
|
|
65
|
+
|
|
66
|
+
### Remove & Access
|
|
67
|
+
|
|
68
|
+
- `removeCondition(id: string): void`
|
|
69
|
+
- Remove a condition or group by `id`. Searches recursively. Removing a group removes all its children.
|
|
70
|
+
- `getCondition(id: string): ConditionType<T> | ConditionGroupType<T> | undefined`
|
|
71
|
+
- Look up a condition or group by `id`. Returns `undefined` if not found. Searches recursively.
|
|
72
|
+
|
|
73
|
+
### Utility
|
|
74
|
+
|
|
75
|
+
- `clearAllConditions(): void`
|
|
76
|
+
- Remove all conditions and groups, resetting `items` to `[]`. After this, `payload` is `undefined` and `hasConditions` is `false`.
|
|
77
|
+
- `setRootOperator(op: ConditionGroupOperatorType): void`
|
|
78
|
+
- Change the root-level operator that combines all top-level conditions.
|
|
79
|
+
|
|
80
|
+
## Exported Constants
|
|
81
|
+
|
|
82
|
+
### ConditionOperator
|
|
83
|
+
|
|
84
|
+
Import from `@ram_28/kf-ai-sdk/filter`. Used as the `Operator` value on leaf conditions (`ConditionType`).
|
|
85
|
+
|
|
86
|
+
**Comparison:**
|
|
87
|
+
|
|
88
|
+
- `EQ` (`"EQ"`) -- Equal. RHSValue: single value.
|
|
89
|
+
- `NE` (`"NE"`) -- Not equal. RHSValue: single value.
|
|
90
|
+
- `GT` (`"GT"`) -- Greater than. RHSValue: single value.
|
|
91
|
+
- `GTE` (`"GTE"`) -- Greater than or equal. RHSValue: single value.
|
|
92
|
+
- `LT` (`"LT"`) -- Less than. RHSValue: single value.
|
|
93
|
+
- `LTE` (`"LTE"`) -- Less than or equal. RHSValue: single value.
|
|
94
|
+
|
|
95
|
+
**Range:**
|
|
96
|
+
|
|
97
|
+
- `Between` (`"Between"`) -- Value within range. RHSValue: `[min, max]`.
|
|
98
|
+
- `NotBetween` (`"NotBetween"`) -- Value outside range. RHSValue: `[min, max]`.
|
|
99
|
+
|
|
100
|
+
**List:**
|
|
101
|
+
|
|
102
|
+
- `IN` (`"IN"`) -- Value in list. RHSValue: `[value1, value2, ...]`.
|
|
103
|
+
- `NIN` (`"NIN"`) -- Value not in list. RHSValue: `[value1, value2, ...]`.
|
|
104
|
+
|
|
105
|
+
**Presence:**
|
|
106
|
+
|
|
107
|
+
- `Empty` (`"Empty"`) -- Field is empty/null. RHSValue: not required.
|
|
108
|
+
- `NotEmpty` (`"NotEmpty"`) -- Field is not empty. RHSValue: not required.
|
|
109
|
+
|
|
110
|
+
**String:**
|
|
111
|
+
|
|
112
|
+
- `Contains` (`"Contains"`) -- String contains substring. RHSValue: string.
|
|
113
|
+
- `NotContains` (`"NotContains"`) -- Does not contain. RHSValue: string.
|
|
114
|
+
|
|
115
|
+
**Length:**
|
|
116
|
+
|
|
117
|
+
- `MinLength` (`"MinLength"`) -- Minimum length. RHSValue: number.
|
|
118
|
+
- `MaxLength` (`"MaxLength"`) -- Maximum length. RHSValue: number.
|
|
119
|
+
- `Length` (`"Length"`) -- Exact length. RHSValue: number.
|
|
120
|
+
|
|
121
|
+
### GroupOperator
|
|
122
|
+
|
|
123
|
+
Import from `@ram_28/kf-ai-sdk/filter`. Used as the `Operator` value on condition groups (`ConditionGroupType`).
|
|
124
|
+
|
|
125
|
+
- `And` (`"And"`) -- All conditions must match.
|
|
126
|
+
- `Or` (`"Or"`) -- Any condition can match.
|
|
127
|
+
- `Not` (`"Not"`) -- Negate the conditions.
|
|
128
|
+
|
|
129
|
+
### FilterValueSource
|
|
130
|
+
|
|
131
|
+
Import from `@ram_28/kf-ai-sdk/filter`. Used as the `RHSType` value on leaf conditions. The import name is `FilterValueSource`; the property name on the condition object is `RHSType`.
|
|
132
|
+
|
|
133
|
+
- `Constant` (`"Constant"`) -- RHSValue is a literal value (string, number, boolean, array, etc.).
|
|
134
|
+
- `BDOField` (`"BDOField"`) -- RHSValue is another field name (field-to-field comparison).
|
|
135
|
+
- `AppVariable` (`"AppVariable"`) -- RHSValue is an application-level variable.
|
|
136
|
+
|
|
137
|
+
## Type Guards
|
|
138
|
+
|
|
139
|
+
Import from `@ram_28/kf-ai-sdk/filter`.
|
|
140
|
+
|
|
141
|
+
- `isCondition(item): item is ConditionType` -- Returns `true` when the item has an `LHSField` property (leaf condition).
|
|
142
|
+
- `isConditionGroup(item): item is ConditionGroupType` -- Returns `true` when the item has a `Condition` property (group node).
|
|
143
|
+
|
|
144
|
+
```tsx
|
|
145
|
+
filter.items.forEach((item) => {
|
|
146
|
+
if (isCondition(item)) {
|
|
147
|
+
console.log(item.LHSField, item.Operator, item.RHSValue);
|
|
148
|
+
}
|
|
149
|
+
if (isConditionGroup(item)) {
|
|
150
|
+
console.log(item.Operator, "group with", item.Condition.length, "children");
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Types
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
// ============================================================
|
|
159
|
+
// Condition types
|
|
160
|
+
// ============================================================
|
|
161
|
+
|
|
162
|
+
interface ConditionType<T = any> {
|
|
163
|
+
/** Auto-generated by useFilter for state management. Stripped from payload. */
|
|
164
|
+
id?: string;
|
|
165
|
+
/** Comparison operator (use ConditionOperator constants). */
|
|
166
|
+
Operator: ConditionOperatorType;
|
|
167
|
+
/** Field name to compare. When T is provided, autocompletes to keyof T. */
|
|
168
|
+
LHSField: T extends any ? keyof T | string : string;
|
|
169
|
+
/** Value to compare against. Format depends on the Operator. */
|
|
170
|
+
RHSValue: any;
|
|
171
|
+
/** How RHSValue is interpreted. Use FilterValueSource constants. */
|
|
172
|
+
RHSType?: FilterRHSType;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
interface ConditionGroupType<T = any> {
|
|
176
|
+
/** Auto-generated by useFilter for state management. Stripped from payload. */
|
|
177
|
+
id?: string;
|
|
178
|
+
/** Logical operator: "And", "Or", or "Not" (use GroupOperator constants). */
|
|
179
|
+
Operator: ConditionGroupOperatorType;
|
|
180
|
+
/** Nested conditions and/or groups. */
|
|
181
|
+
Condition: Array<ConditionType<T> | ConditionGroupType<T>>;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/** Root filter structure sent to the API. Alias for ConditionGroupType. */
|
|
185
|
+
type FilterType<T = any> = ConditionGroupType<T>;
|
|
186
|
+
|
|
187
|
+
type ConditionOperatorType = (typeof ConditionOperator)[keyof typeof ConditionOperator];
|
|
188
|
+
// "EQ" | "NE" | "GT" | "GTE" | "LT" | "LTE" | "Between" | "NotBetween"
|
|
189
|
+
// | "IN" | "NIN" | "Empty" | "NotEmpty" | "Contains" | "NotContains"
|
|
190
|
+
// | "MinLength" | "MaxLength" | "Length"
|
|
191
|
+
|
|
192
|
+
type ConditionGroupOperatorType = (typeof GroupOperator)[keyof typeof GroupOperator];
|
|
193
|
+
// "And" | "Or" | "Not"
|
|
194
|
+
|
|
195
|
+
type FilterRHSType = (typeof FilterValueSource)[keyof typeof FilterValueSource];
|
|
196
|
+
// "Constant" | "BDOField" | "AppVariable"
|
|
197
|
+
|
|
198
|
+
interface UseFilterOptionsType<T = any> {
|
|
199
|
+
/** Initial filter conditions. Each item is cloned and assigned an auto-generated id. */
|
|
200
|
+
conditions?: Array<ConditionType<T> | ConditionGroupType<T>>;
|
|
201
|
+
/** Root operator for combining conditions. Defaults to "And". */
|
|
202
|
+
operator?: ConditionGroupOperatorType;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
interface UseFilterReturnType<T = any> {
|
|
206
|
+
// State
|
|
207
|
+
operator: ConditionGroupOperatorType;
|
|
208
|
+
items: Array<ConditionType<T> | ConditionGroupType<T>>;
|
|
209
|
+
payload: FilterType<T> | undefined;
|
|
210
|
+
hasConditions: boolean;
|
|
211
|
+
|
|
212
|
+
// Add (return id of created item)
|
|
213
|
+
addCondition: (condition: Omit<ConditionType<T>, "id">, parentId?: string) => string;
|
|
214
|
+
addConditionGroup: (operator: ConditionGroupOperatorType, parentId?: string) => string;
|
|
215
|
+
|
|
216
|
+
// Update
|
|
217
|
+
updateCondition: (id: string, updates: Partial<Omit<ConditionType<T>, "id">>) => void;
|
|
218
|
+
updateGroupOperator: (id: string, operator: ConditionGroupOperatorType) => void;
|
|
219
|
+
|
|
220
|
+
// Remove and access
|
|
221
|
+
removeCondition: (id: string) => void;
|
|
222
|
+
getCondition: (id: string) => ConditionType<T> | ConditionGroupType<T> | undefined;
|
|
223
|
+
|
|
224
|
+
// Utility
|
|
225
|
+
clearAllConditions: () => void;
|
|
226
|
+
setRootOperator: (op: ConditionGroupOperatorType) => void;
|
|
227
|
+
}
|
|
228
|
+
```
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# Workflow
|
|
2
|
+
|
|
3
|
+
Business process orchestration with typed Activity classes and a Workflow wrapper. Activity classes use the same three-generics pattern as BDO (`Activity<TEntity, TEditable, TReadonly>`), and a Workflow class ties multiple activities into a process.
|
|
4
|
+
|
|
5
|
+
## Imports
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
// Page component — import the generated workflow and activity classes, plus hooks
|
|
9
|
+
import { LeaveProcess } from "../workflow/LeaveProcess";
|
|
10
|
+
import { EmployeeInputActivity } from "../workflow/EmployeeInputActivity";
|
|
11
|
+
import { useActivityForm } from "@ram_28/kf-ai-sdk/workflow";
|
|
12
|
+
import { useActivityTable, ActivityTableStatus } from "@ram_28/kf-ai-sdk/workflow";
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
// Workflow class definition — used by the js_sdk generator
|
|
17
|
+
import { Activity, Workflow } from "@ram_28/kf-ai-sdk/workflow";
|
|
18
|
+
import type { WorkflowStartResponseType, ActivityProgressType } from "@ram_28/kf-ai-sdk/workflow";
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Field classes and field value types are imported from `@ram_28/kf-ai-sdk/bdo` and `@ram_28/kf-ai-sdk/types`, same as BDO.
|
|
22
|
+
|
|
23
|
+
## Common Mistakes (READ FIRST)
|
|
24
|
+
|
|
25
|
+
1. **`BPInstanceId` vs `_id`** — `start()` returns both. `BPInstanceId` is for `progress()`. `_id` is the first activity instance ID for `getInstance()`.
|
|
26
|
+
2. **`complete()` does not save** — `complete()` only marks the activity done and advances the workflow. Call `update()` first to persist field changes, then `complete()`.
|
|
27
|
+
3. **No single `list()` method** — Use `getInProgressList()` or `getCompletedList()`. The backend filters by status automatically.
|
|
28
|
+
4. **Memoize Activity instances in React** — Wrap in `useMemo` to prevent re-creation on every render:
|
|
29
|
+
```typescript
|
|
30
|
+
const activity = useMemo(() => new EmployeeInputActivity(), []);
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
const leaveProcess = new LeaveProcess();
|
|
37
|
+
const employeeInput = new EmployeeInputActivity();
|
|
38
|
+
|
|
39
|
+
// Start workflow — returns { BPInstanceId, ActivityId, _id }
|
|
40
|
+
const { BPInstanceId, _id } = await leaveProcess.start();
|
|
41
|
+
|
|
42
|
+
// Get the first activity instance
|
|
43
|
+
const instance = await employeeInput.getInstance(_id);
|
|
44
|
+
instance.StartDate.get(); // read field value
|
|
45
|
+
|
|
46
|
+
// Update fields, then complete
|
|
47
|
+
await instance.update({ StartDate: "2026-04-01", EndDate: "2026-04-05", LeaveType: "PTO" });
|
|
48
|
+
await instance.complete();
|
|
49
|
+
|
|
50
|
+
// Check workflow progress
|
|
51
|
+
const stages = await leaveProcess.progress(BPInstanceId);
|
|
52
|
+
// [{ ActivityId: "EMPLOYEE_INPUT", Status: "COMPLETED" }, { ActivityId: "MANAGER_APPROVAL", Status: "IN_PROGRESS" }]
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Usage Guide
|
|
56
|
+
|
|
57
|
+
### Workflow Methods
|
|
58
|
+
|
|
59
|
+
The Workflow class is a thin wrapper — `start()` and `progress()` only.
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
const leaveProcess = new LeaveProcess();
|
|
63
|
+
|
|
64
|
+
// Start a new instance
|
|
65
|
+
const { BPInstanceId, ActivityId, _id } = await leaveProcess.start();
|
|
66
|
+
|
|
67
|
+
// Get progress for all stages (pass BPInstanceId, not _id)
|
|
68
|
+
const stages = await leaveProcess.progress(BPInstanceId);
|
|
69
|
+
stages.forEach((s) => console.log(s.ActivityId, s.Status));
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Activity Methods
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
const activity = new EmployeeInputActivity();
|
|
76
|
+
|
|
77
|
+
// List instances by status
|
|
78
|
+
const inProgress = await activity.getInProgressList({ Page: 1, PageSize: 10 });
|
|
79
|
+
const completed = await activity.getCompletedList({ Page: 1, PageSize: 10 });
|
|
80
|
+
|
|
81
|
+
// Count
|
|
82
|
+
const pendingCount = await activity.inProgressCount();
|
|
83
|
+
const doneCount = await activity.completedCount();
|
|
84
|
+
|
|
85
|
+
// Metrics
|
|
86
|
+
const result = await activity.inProgressMetric({
|
|
87
|
+
GroupBy: ["LeaveType"],
|
|
88
|
+
Metric: [{ Field: "LeaveDays", Type: "Sum" }],
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// Get single instance
|
|
92
|
+
const instance = await activity.getInstance("instance_id");
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### ActivityInstance Field Accessors
|
|
96
|
+
|
|
97
|
+
Same accessor pattern as BDO `ItemType`.
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
const instance = await activity.getInstance(_id);
|
|
101
|
+
|
|
102
|
+
// Read values
|
|
103
|
+
instance._id; // string (direct)
|
|
104
|
+
instance.StartDate.get(); // DateFieldType | undefined
|
|
105
|
+
instance.LeaveDays.getOrDefault(0); // number (never undefined)
|
|
106
|
+
|
|
107
|
+
// Write values (editable fields only)
|
|
108
|
+
instance.StartDate.set("2026-04-01");
|
|
109
|
+
|
|
110
|
+
// Field metadata
|
|
111
|
+
instance.StartDate.label; // "Start Date"
|
|
112
|
+
instance.StartDate.required; // true
|
|
113
|
+
instance.StartDate.readOnly; // false
|
|
114
|
+
|
|
115
|
+
// Validation
|
|
116
|
+
instance.StartDate.validate(); // { valid, errors }
|
|
117
|
+
instance.validate(); // validates all fields
|
|
118
|
+
|
|
119
|
+
// Serialize
|
|
120
|
+
instance.toJSON(); // { StartDate: "2026-04-01", ... }
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Persistence: update, save, complete
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
const instance = await activity.getInstance(_id);
|
|
127
|
+
|
|
128
|
+
// update() — persists field changes
|
|
129
|
+
await instance.update({ StartDate: "2026-04-01", EndDate: "2026-04-05" });
|
|
130
|
+
|
|
131
|
+
// save() — commits a draft (used by useActivityForm internally)
|
|
132
|
+
await instance.save({ StartDate: "2026-04-01" });
|
|
133
|
+
|
|
134
|
+
// complete() — marks activity done, advances workflow (does NOT auto-save)
|
|
135
|
+
await instance.complete();
|
|
136
|
+
|
|
137
|
+
// progress() — get workflow progress from this instance
|
|
138
|
+
const stages = await instance.progress();
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Progress Tracking
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
const stages = await leaveProcess.progress(BPInstanceId);
|
|
145
|
+
|
|
146
|
+
for (const stage of stages) {
|
|
147
|
+
console.log(stage.ActivityId); // "EMPLOYEE_INPUT"
|
|
148
|
+
console.log(stage.Status); // "COMPLETED" | "IN_PROGRESS"
|
|
149
|
+
console.log(stage.CompletedAt); // string | null
|
|
150
|
+
console.log(stage.CompletedBy); // { _id, _name } | null
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Further Reading
|
|
155
|
+
|
|
156
|
+
- [API Reference](./api_reference.md) — full method signatures, parameter types, and return types
|
|
157
|
+
- [Start New Workflow](../examples/workflow/start-new-workflow.md) — `workflow.start()` flow
|
|
158
|
+
- [Workflow Progress](../examples/workflow/workflow-progress.md) — progress badges for activity stages
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
```typescript
|
|
2
|
+
import { Activity, Workflow } from "@ram_28/kf-ai-sdk/workflow";
|
|
3
|
+
import { useActivityForm } from "@ram_28/kf-ai-sdk/workflow";
|
|
4
|
+
import { useActivityTable, ActivityTableStatus } from "@ram_28/kf-ai-sdk/workflow";
|
|
5
|
+
import type {
|
|
6
|
+
WorkflowStartResponseType,
|
|
7
|
+
ActivityProgressType,
|
|
8
|
+
ActivityInstanceFieldsType,
|
|
9
|
+
ActivityTableStatusType,
|
|
10
|
+
} from "@ram_28/kf-ai-sdk/workflow";
|
|
11
|
+
import type {
|
|
12
|
+
ListOptionsType,
|
|
13
|
+
CreateUpdateResponseType,
|
|
14
|
+
MetricOptionsType,
|
|
15
|
+
MetricResponseType,
|
|
16
|
+
} from "@ram_28/kf-ai-sdk/api/types";
|
|
17
|
+
import type { ValidationResultType } from "@ram_28/kf-ai-sdk/bdo/types";
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Workflow Methods
|
|
21
|
+
|
|
22
|
+
| Method | Params | Returns |
|
|
23
|
+
|--------|--------|---------|
|
|
24
|
+
| `start()` | — | `Promise<WorkflowStartResponseType>` |
|
|
25
|
+
| `progress(instanceId)` | `instance_id: string` (pass `BPInstanceId`) | `Promise<ActivityProgressType[]>` |
|
|
26
|
+
|
|
27
|
+
## Activity Methods
|
|
28
|
+
|
|
29
|
+
| Method | Params | Returns |
|
|
30
|
+
|--------|--------|---------|
|
|
31
|
+
| `getInstance(id)` | `instanceId: string` | `Promise<ActivityInstanceType<TEntity, TEditable, TReadonly>>` |
|
|
32
|
+
| `getInProgressList(options?)` | `options?: ListOptionsType` | `Promise<ActivityInstanceType<...>[]>` |
|
|
33
|
+
| `getCompletedList(options?)` | `options?: ListOptionsType` | `Promise<ActivityInstanceType<...>[]>` |
|
|
34
|
+
| `inProgressCount(options?)` | `options?: ListOptionsType` | `Promise<number>` |
|
|
35
|
+
| `completedCount(options?)` | `options?: ListOptionsType` | `Promise<number>` |
|
|
36
|
+
| `inProgressMetric(options)` | `options: Omit<MetricOptionsType, "Type">` | `Promise<MetricResponseType>` |
|
|
37
|
+
| `completedMetric(options)` | `options: Omit<MetricOptionsType, "Type">` | `Promise<MetricResponseType>` |
|
|
38
|
+
|
|
39
|
+
## ActivityInstance Methods
|
|
40
|
+
|
|
41
|
+
| Method | Params | Returns |
|
|
42
|
+
|--------|--------|---------|
|
|
43
|
+
| `update(data)` | `data: Partial<TEditable>` | `Promise<CreateUpdateResponseType>` |
|
|
44
|
+
| `complete()` | — | `Promise<CreateUpdateResponseType>` |
|
|
45
|
+
| `save(data)` | `data: Partial<TEditable>` | `Promise<CreateUpdateResponseType>` |
|
|
46
|
+
| `progress()` | — | `Promise<ActivityProgressType[]>` |
|
|
47
|
+
| `toJSON()` | — | `Partial<TEntity>` |
|
|
48
|
+
| `validate()` | — | `ValidationResultType` |
|
|
49
|
+
|
|
50
|
+
ActivityInstance field accessors follow the same pattern as BDO `ItemType` — see [BDO API Reference](../bdo/api_reference.md#editablefieldaccessortypet) for `EditableFieldAccessorType` and `ReadonlyFieldAccessorType`.
|
|
51
|
+
|
|
52
|
+
## Types
|
|
53
|
+
|
|
54
|
+
### WorkflowStartResponseType
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
interface WorkflowStartResponseType {
|
|
58
|
+
BPInstanceId: string; // business process instance ID — pass to progress()
|
|
59
|
+
ActivityId: string; // first activity's ID
|
|
60
|
+
_id: string; // first activity instance ID — pass to getInstance()
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### ActivityProgressType
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
interface ActivityProgressType {
|
|
68
|
+
ActivityId: string;
|
|
69
|
+
ActivityInstanceId: string;
|
|
70
|
+
ActivityType: string;
|
|
71
|
+
AssignedTo: { Type: string; _id: string }[];
|
|
72
|
+
CompletedAt: string | null;
|
|
73
|
+
CompletedBy: { _id: string; _name: string } | null;
|
|
74
|
+
Status: "COMPLETED" | "IN_PROGRESS";
|
|
75
|
+
_name: string;
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### ActivityInstanceType\<TEntity, TEditable, TReadonly\>
|
|
80
|
+
|
|
81
|
+
Proxy-wrapped activity instance. Same accessor pattern as BDO `ItemType`.
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
type ActivityInstanceType<TEntity, TEditable, TReadonly> = {
|
|
85
|
+
readonly _id: string;
|
|
86
|
+
|
|
87
|
+
// Editable fields → EditableFieldAccessorType<T> (get/set/validate)
|
|
88
|
+
// Readonly fields → ReadonlyFieldAccessorType<T> (get/validate, no set)
|
|
89
|
+
|
|
90
|
+
update(data: Partial<TEditable>): Promise<CreateUpdateResponseType>;
|
|
91
|
+
complete(): Promise<CreateUpdateResponseType>;
|
|
92
|
+
save(data: Partial<TEditable>): Promise<CreateUpdateResponseType>;
|
|
93
|
+
progress(): Promise<ActivityProgressType[]>;
|
|
94
|
+
toJSON(): Partial<TEntity>;
|
|
95
|
+
validate(): ValidationResultType;
|
|
96
|
+
};
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### ActivityInstanceFieldsType
|
|
100
|
+
|
|
101
|
+
System fields present on every activity instance record.
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
type ActivityInstanceFieldsType = {
|
|
105
|
+
_id: StringFieldType;
|
|
106
|
+
BPInstanceId: StringFieldType;
|
|
107
|
+
Status: SelectFieldType<"InProgress" | "Completed">;
|
|
108
|
+
AssignedTo: UserFieldType[];
|
|
109
|
+
CompletedAt: DateTimeFieldType;
|
|
110
|
+
};
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### ActivityTableStatus
|
|
114
|
+
|
|
115
|
+
Constants for the `useActivityTable` status parameter.
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
const ActivityTableStatus = {
|
|
119
|
+
InProgress: "inprogress",
|
|
120
|
+
Completed: "completed",
|
|
121
|
+
} as const;
|
|
122
|
+
|
|
123
|
+
type ActivityTableStatusType =
|
|
124
|
+
(typeof ActivityTableStatus)[keyof typeof ActivityTableStatus];
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### ListOptionsType
|
|
128
|
+
|
|
129
|
+
Same type as BDO — see [BDO API Reference](../bdo/api_reference.md#listoptionstype).
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
interface ListOptionsType {
|
|
133
|
+
Filter?: FilterType;
|
|
134
|
+
Sort?: SortType;
|
|
135
|
+
Page?: number; // 1-indexed
|
|
136
|
+
PageSize?: number;
|
|
137
|
+
Search?: string;
|
|
138
|
+
Field?: string[];
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Generated Type Patterns
|
|
143
|
+
|
|
144
|
+
The js_sdk generator creates these types per activity:
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
// workflow/EmployeeInputActivity.ts
|
|
148
|
+
type LeaveEntityType = {
|
|
149
|
+
StartDate: DateFieldType;
|
|
150
|
+
EndDate: DateFieldType;
|
|
151
|
+
LeaveType: StringFieldType;
|
|
152
|
+
LeaveDays: NumberFieldType;
|
|
153
|
+
};
|
|
154
|
+
type LeaveEditableFieldType = Pick<LeaveEntityType, "StartDate" | "EndDate" | "LeaveType">;
|
|
155
|
+
type LeaveReadonlyFieldType = Pick<LeaveEntityType, "LeaveDays">;
|
|
156
|
+
|
|
157
|
+
class EmployeeInputActivity extends Activity<LeaveEntityType, LeaveEditableFieldType, LeaveReadonlyFieldType> {
|
|
158
|
+
readonly meta = { businessProcessId: "SimpleLeaveProcess", activityId: "EMPLOYEE_INPUT" } as const;
|
|
159
|
+
// ... field declarations
|
|
160
|
+
}
|
|
161
|
+
```
|
package/package.json
CHANGED
package/sdk/auth/authConfig.ts
CHANGED
|
@@ -43,7 +43,7 @@ let authConfig: AuthConfigType = { ...defaultAuthConfig };
|
|
|
43
43
|
* autoRedirect: true,
|
|
44
44
|
* providers: {
|
|
45
45
|
* google: { loginPath: "/api/auth/google/login" },
|
|
46
|
-
*
|
|
46
|
+
* azure: { loginPath: "/api/auth/azure/login" },
|
|
47
47
|
* },
|
|
48
48
|
* });
|
|
49
49
|
* ```
|
package/sdk/auth/types.ts
CHANGED
|
@@ -29,7 +29,7 @@ export type AuthStatusType = "loading" | "authenticated" | "unauthenticated";
|
|
|
29
29
|
/**
|
|
30
30
|
* Authentication provider type (extensible for multiple OAuth providers)
|
|
31
31
|
*/
|
|
32
|
-
export type AuthProviderNameType = "google" | "
|
|
32
|
+
export type AuthProviderNameType = "google" | "azure" | "github" | "custom";
|
|
33
33
|
|
|
34
34
|
/**
|
|
35
35
|
* Auth endpoint configuration for a specific provider
|
package/sdk/bdo/core/Item.ts
CHANGED
|
@@ -196,18 +196,9 @@ export class Item<T extends Record<string, unknown>> {
|
|
|
196
196
|
}) as Item<T>;
|
|
197
197
|
}
|
|
198
198
|
|
|
199
|
-
/**
|
|
200
|
-
* Require instanceId or throw.
|
|
201
|
-
* TODO: Support create flow via draftInteraction to get temp _id
|
|
202
|
-
*/
|
|
203
199
|
private _requireInstanceId(): string {
|
|
204
200
|
const id = this._data._id as string | undefined;
|
|
205
|
-
|
|
206
|
-
throw new Error(
|
|
207
|
-
"Cannot perform attachment operation: item has no _id. Save the item first.",
|
|
208
|
-
);
|
|
209
|
-
}
|
|
210
|
-
return id;
|
|
201
|
+
return id || "draft";
|
|
211
202
|
}
|
|
212
203
|
|
|
213
204
|
/**
|
|
@@ -71,7 +71,7 @@ export class ReferenceField<TRef = unknown> extends BaseField<
|
|
|
71
71
|
* Fetch referenced records from the backend via the fetchField API.
|
|
72
72
|
* Requires the field to be bound to a parent BDO.
|
|
73
73
|
*/
|
|
74
|
-
async fetchOptions(instanceId: string): Promise<TRef[]> {
|
|
74
|
+
async fetchOptions(instanceId: string = "draft"): Promise<TRef[]> {
|
|
75
75
|
if (!this._parentBoId) {
|
|
76
76
|
throw new Error(
|
|
77
77
|
`Field ${this.id} not bound to a BDO. Cannot fetch options.`
|
|
@@ -57,7 +57,7 @@ export class SelectField<T extends string | number = string> extends BaseField<T
|
|
|
57
57
|
/**
|
|
58
58
|
* Fetch dynamic options from the backend, returned as typed SelectOption[]
|
|
59
59
|
*/
|
|
60
|
-
async fetchOptions(instanceId: string): Promise<SelectOptionType<T>[]> {
|
|
60
|
+
async fetchOptions(instanceId: string = "draft"): Promise<SelectOptionType<T>[]> {
|
|
61
61
|
if (!this._parentBoId) {
|
|
62
62
|
throw new Error(
|
|
63
63
|
`Field ${this.id} not bound to a BDO. Cannot fetch options.`
|
|
@@ -32,7 +32,7 @@ export class UserField extends BaseField<UserFieldType> {
|
|
|
32
32
|
* Fetch user records from the backend via the fetchField API.
|
|
33
33
|
* Requires the field to be bound to a parent BDO.
|
|
34
34
|
*/
|
|
35
|
-
async fetchOptions(instanceId: string): Promise<UserFieldType[]> {
|
|
35
|
+
async fetchOptions(instanceId: string = "draft"): Promise<UserFieldType[]> {
|
|
36
36
|
if (!this._parentBoId) {
|
|
37
37
|
throw new Error(
|
|
38
38
|
`Field ${this.id} not bound to a BDO. Cannot fetch options.`,
|
|
@@ -15,6 +15,7 @@ import type {
|
|
|
15
15
|
} from 'react-hook-form';
|
|
16
16
|
|
|
17
17
|
import type { Activity } from '../../../workflow/Activity';
|
|
18
|
+
import type { CreateUpdateResponseType } from '../../../types/common';
|
|
18
19
|
|
|
19
20
|
// Reuse shared types from useBDOForm — identical interfaces, no duplication
|
|
20
21
|
import type {
|
|
@@ -104,11 +105,8 @@ export interface UseActivityFormReturn<A extends Activity<any, any, any>> {
|
|
|
104
105
|
ExtractActivityReadonly<A>
|
|
105
106
|
>;
|
|
106
107
|
|
|
107
|
-
/** Handle form submission —
|
|
108
|
-
handleSubmit: HandleSubmitType<
|
|
109
|
-
|
|
110
|
-
/** Handle form completion — calls activity.update() + activity.complete() */
|
|
111
|
-
handleComplete: HandleSubmitType<AllActivityFields<A>>;
|
|
108
|
+
/** Handle form submission — validates, updates dirty fields, then completes the activity */
|
|
109
|
+
handleSubmit: HandleSubmitType<CreateUpdateResponseType>;
|
|
112
110
|
|
|
113
111
|
/** Watch field values */
|
|
114
112
|
watch: UseFormWatch<AllActivityFields<A>>;
|
|
@@ -141,7 +139,7 @@ export interface UseActivityFormReturn<A extends Activity<any, any, any>> {
|
|
|
141
139
|
/** Form has been modified */
|
|
142
140
|
isDirty: boolean;
|
|
143
141
|
|
|
144
|
-
/** Form is currently submitting
|
|
142
|
+
/** Form is currently submitting */
|
|
145
143
|
isSubmitting: boolean;
|
|
146
144
|
|
|
147
145
|
/** Form submission was successful */
|