@ram_28/kf-ai-sdk 2.0.16 → 2.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/README.md +16 -8
  2. package/dist/api.cjs +1 -1
  3. package/dist/api.mjs +1 -1
  4. package/dist/auth/authConfig.d.ts +1 -1
  5. package/dist/auth/types.d.ts +1 -1
  6. package/dist/auth/types.d.ts.map +1 -1
  7. package/dist/auth.cjs +1 -1
  8. package/dist/auth.mjs +1 -1
  9. package/dist/bdo.cjs +1 -1
  10. package/dist/bdo.mjs +1 -1
  11. package/dist/components/hooks/useActivityForm/types.d.ts +4 -5
  12. package/dist/components/hooks/useActivityForm/types.d.ts.map +1 -1
  13. package/dist/components/hooks/useActivityForm/useActivityForm.d.ts.map +1 -1
  14. package/dist/components/hooks/useActivityTable/types.d.ts +5 -4
  15. package/dist/components/hooks/useActivityTable/types.d.ts.map +1 -1
  16. package/dist/components/hooks/useActivityTable/useActivityTable.d.ts.map +1 -1
  17. package/dist/components/hooks/useBDOTable/types.d.ts +20 -12
  18. package/dist/components/hooks/useBDOTable/types.d.ts.map +1 -1
  19. package/dist/components/hooks/useBDOTable/useBDOTable.d.ts +2 -2
  20. package/dist/components/hooks/useBDOTable/useBDOTable.d.ts.map +1 -1
  21. package/dist/{constants-ConHc1oS.js → constants-Cyi942Yr.js} +5 -5
  22. package/dist/constants-DEmYwKfC.cjs +1 -0
  23. package/dist/filter.cjs +1 -1
  24. package/dist/filter.mjs +1 -1
  25. package/dist/form.cjs +1 -1
  26. package/dist/form.mjs +1 -1
  27. package/dist/table.cjs +1 -1
  28. package/dist/table.mjs +15 -16
  29. package/dist/table.types.d.ts +1 -1
  30. package/dist/table.types.d.ts.map +1 -1
  31. package/dist/types/constants.d.ts +1 -1
  32. package/dist/workflow/Activity.d.ts +8 -5
  33. package/dist/workflow/Activity.d.ts.map +1 -1
  34. package/dist/workflow.cjs +1 -1
  35. package/dist/workflow.mjs +461 -476
  36. package/docs/README.md +51 -0
  37. package/docs/bdo/README.md +161 -0
  38. package/docs/bdo/api_reference.md +281 -0
  39. package/docs/examples/bdo/create-product.md +69 -0
  40. package/docs/examples/bdo/edit-product-dialog.md +95 -0
  41. package/docs/examples/bdo/filtered-product-table.md +100 -0
  42. package/docs/examples/bdo/product-listing.md +73 -0
  43. package/docs/examples/bdo/supplier-dropdown.md +60 -0
  44. package/docs/examples/workflow/approve-leave-request.md +76 -0
  45. package/docs/examples/workflow/filtered-activity-table.md +101 -0
  46. package/docs/examples/workflow/my-pending-requests.md +90 -0
  47. package/docs/examples/workflow/start-new-workflow.md +47 -0
  48. package/docs/examples/workflow/submit-leave-request.md +72 -0
  49. package/docs/examples/workflow/workflow-progress.md +49 -0
  50. package/docs/useActivityForm/README.md +241 -0
  51. package/docs/useActivityForm/api_reference.md +279 -0
  52. package/docs/useActivityTable/README.md +263 -0
  53. package/docs/useActivityTable/api_reference.md +294 -0
  54. package/docs/useBDOForm/README.md +172 -0
  55. package/docs/useBDOForm/api_reference.md +244 -0
  56. package/docs/useBDOTable/README.md +242 -0
  57. package/docs/useBDOTable/api_reference.md +253 -0
  58. package/docs/useFilter/README.md +323 -0
  59. package/docs/useFilter/api_reference.md +228 -0
  60. package/docs/workflow/README.md +158 -0
  61. package/docs/workflow/api_reference.md +161 -0
  62. package/package.json +1 -1
  63. package/sdk/auth/authConfig.ts +1 -1
  64. package/sdk/auth/types.ts +1 -1
  65. package/sdk/components/hooks/useActivityForm/types.ts +4 -6
  66. package/sdk/components/hooks/useActivityForm/useActivityForm.ts +10 -73
  67. package/sdk/components/hooks/useActivityTable/types.ts +4 -5
  68. package/sdk/components/hooks/useActivityTable/useActivityTable.ts +10 -8
  69. package/sdk/components/hooks/useBDOTable/types.ts +20 -10
  70. package/sdk/components/hooks/useBDOTable/useBDOTable.ts +12 -8
  71. package/sdk/table.types.ts +2 -0
  72. package/sdk/types/constants.ts +1 -1
  73. package/sdk/workflow/Activity.ts +39 -7
  74. package/dist/constants-QX2RX-wu.cjs +0 -1
  75. package/docs/api.md +0 -95
  76. package/docs/bdo.md +0 -224
  77. package/docs/gaps.md +0 -360
  78. package/docs/useActivityForm.md +0 -393
  79. package/docs/useActivityTable.md +0 -418
  80. package/docs/useBDOForm.md +0 -376
  81. package/docs/useBDOTable.md +0 -284
  82. package/docs/useFilter.md +0 -188
  83. package/docs/workflow.md +0 -560
  84. /package/docs/{useAuth.md → useAuth/README.md} +0 -0
@@ -0,0 +1,263 @@
1
+ # useActivityTable
2
+
3
+ Activity-integrated table hook for listing workflow instances with search, sorting, filtering, and pagination.
4
+
5
+ ## When to Use
6
+
7
+ **Use `useActivityTable` when:**
8
+
9
+ - Displaying in-progress or completed workflow activity instances
10
+ - You need search, sort, filter, and/or pagination on activity data
11
+
12
+ **Use something else when:**
13
+
14
+ - Displaying BDO records (not workflow) — use [`useBDOTable`](../useBDOTable/README.md) instead
15
+ - Building a form for an activity instance — use [`useActivityForm`](../useActivityForm/README.md) instead
16
+
17
+ ## Imports
18
+
19
+ ```tsx
20
+ import { useActivityTable, ActivityTableStatus } from "@ram_28/kf-ai-sdk/workflow";
21
+ ```
22
+
23
+ ## Quick Start
24
+
25
+ ```tsx
26
+ import { useMemo } from "react";
27
+ import { useActivityTable, ActivityTableStatus } from "@ram_28/kf-ai-sdk/workflow";
28
+ import { EmployeeInputActivity } from "@/bdo/workflows/SimpleLeaveProcess";
29
+
30
+ function PendingLeaveRequests() {
31
+ const activity = useMemo(() => new EmployeeInputActivity(), []);
32
+
33
+ const table = useActivityTable({
34
+ activity,
35
+ status: ActivityTableStatus.InProgress,
36
+ });
37
+
38
+ if (table.isLoading) return <p>Loading...</p>;
39
+ if (table.error) return <p>Error: {table.error.message}</p>;
40
+
41
+ return (
42
+ <div>
43
+ <ul>
44
+ {table.rows.map((row) => (
45
+ <li key={row._id}>
46
+ {row.LeaveType.get()} — {row.StartDate.get()} to {row.EndDate.get()}
47
+ </li>
48
+ ))}
49
+ </ul>
50
+
51
+ <button
52
+ onClick={table.pagination.goToPrevious}
53
+ disabled={!table.pagination.canGoPrevious}
54
+ >
55
+ Previous
56
+ </button>
57
+ <span>
58
+ Page {table.pagination.pageNo} of {table.pagination.totalPages}
59
+ </span>
60
+ <button
61
+ onClick={table.pagination.goToNext}
62
+ disabled={!table.pagination.canGoNext}
63
+ >
64
+ Next
65
+ </button>
66
+ </div>
67
+ );
68
+ }
69
+ ```
70
+
71
+ ## Usage Guide
72
+
73
+ ### Status Filter
74
+
75
+ Every `useActivityTable` call requires a `status` option that determines which items are fetched:
76
+
77
+ ```tsx
78
+ const [status, setStatus] = useState(ActivityTableStatus.InProgress);
79
+
80
+ const table = useActivityTable({
81
+ activity,
82
+ status,
83
+ });
84
+ ```
85
+
86
+ - **`ActivityTableStatus.InProgress`** — fetches the in-progress items of the current activity
87
+ - **`ActivityTableStatus.Completed`** — fetches the completed items of the current activity
88
+ - Raw values are `'inprogress'` (all lowercase, no underscore) and `'completed'`
89
+ - Always use the `ActivityTableStatus` constants — never raw strings
90
+ - Changing status re-fetches automatically (status is part of the query key)
91
+
92
+ ### Accessing Row Data
93
+
94
+ Rows are `ActivityInstanceType` proxies, not plain objects. Access field values through the `.get()` method on each field accessor:
95
+
96
+ ```tsx
97
+ table.rows.map((row) => (
98
+ <tr key={row._id}>
99
+ <td>{row.LeaveType.get()}</td>
100
+ <td>{row.StartDate.get()}</td>
101
+ <td>{row.EndDate.get()}</td>
102
+ <td>{row.LeaveDays.get()}</td>
103
+ <td>{row.Status.get()}</td>
104
+ </tr>
105
+ ));
106
+ ```
107
+
108
+ - `row._id` is a direct string (no `.get()` needed)
109
+ - `row.LeaveType.get()` returns the field's current value
110
+ - Activity system fields: `row.BPInstanceId.get()`, `row.Status.get()`, `row.AssignedTo.get()`, `row.CompletedAt.get()`
111
+ - `row.toJSON()` converts the entire row to a plain object
112
+ - Editable fields also have `.set()`, but this is typically not used in a table context
113
+ - Persistence methods available on each row: `row.update()`, `row.save()`, `row.complete()`, `row.progress()`
114
+
115
+ ### Search
116
+
117
+ Search filters results by matching a query string against a specific field. The input value updates immediately for a responsive UI, while the data fetch is debounced.
118
+
119
+ ```tsx
120
+ <input
121
+ type="text"
122
+ placeholder={`Search by ${activity.EmployeeName.label}...`}
123
+ value={table.search.query}
124
+ onChange={(e) => table.search.set(activity.EmployeeName.id, e.target.value)}
125
+ />
126
+ {table.search.query && (
127
+ <button onClick={table.search.clear}>Clear</button>
128
+ )}
129
+ {table.isFetching && <span>Searching...</span>}
130
+ ```
131
+
132
+ - **`search.set(field, query)`** — set the field and query text. The data fetch is debounced by 300ms. Pagination resets to page 1.
133
+ - **`search.clear()`** — clear the search field and query. Pagination resets to page 1.
134
+ - **`search.query`** — current query string (updates immediately, API call debounced)
135
+ - **`search.field`** — field currently being searched, or `null`
136
+ - Queries longer than 255 characters are silently ignored.
137
+
138
+ ### Sorting
139
+
140
+ Sorting is controlled through the `sort` object. Column headers typically use `toggle()` for click-to-sort behavior:
141
+
142
+ ```tsx
143
+ <th
144
+ onClick={() => table.sort.toggle(activity.StartDate.id)}
145
+ style={{ cursor: "pointer" }}
146
+ >
147
+ {activity.StartDate.label}
148
+ {table.sort.field === activity.StartDate.id &&
149
+ (table.sort.direction === "ASC" ? " ↑" : " ↓")}
150
+ </th>
151
+ ```
152
+
153
+ - **`sort.toggle(field)`** — cycles through ASC, DESC, then cleared. Toggling a different field starts at ASC.
154
+ - **`sort.set(field, direction)`** — set the sort field and direction directly. Pass `null` for both to clear.
155
+ - **`sort.clear()`** — remove sorting entirely.
156
+ - **`sort.field`** / **`sort.direction`** — current sort state, or `null` when no sort is active.
157
+ - **`initialState.sort`** format is an array of single-key objects: `[{ fieldName: "ASC" }]`.
158
+
159
+ ### Filtering
160
+
161
+ The table includes an integrated [`useFilter`](../useFilter/README.md) instance at `table.filter`. Use it to build filter conditions that narrow down the table results:
162
+
163
+ ```tsx
164
+ import { ConditionOperator } from "@ram_28/kf-ai-sdk/table";
165
+
166
+ // Filter by leave type
167
+ table.filter.addCondition({
168
+ Operator: ConditionOperator.EQ,
169
+ LHSField: activity.LeaveType.id,
170
+ RHSValue: "PTO",
171
+ RHSType: "Constant",
172
+ });
173
+
174
+ // Date range filter
175
+ table.filter.addCondition({
176
+ Operator: ConditionOperator.GTE,
177
+ LHSField: activity.StartDate.id,
178
+ RHSValue: "2026-01-01",
179
+ RHSType: "Constant",
180
+ });
181
+
182
+ // Clear all filters
183
+ table.filter.clearAllConditions();
184
+
185
+ // Check if any filters are active
186
+ if (table.filter.hasConditions) {
187
+ // ...
188
+ }
189
+ ```
190
+
191
+ - **`table.filter.addCondition(condition)`** — add a filter condition
192
+ - **`table.filter.clearAllConditions()`** — remove all filter conditions
193
+ - **`table.filter.hasConditions`** — `true` if any conditions are active
194
+ - Filter changes automatically reset pagination to page 1, preventing empty pages after narrowing results.
195
+ - See the [useFilter documentation](../useFilter/README.md) for the full filter API.
196
+
197
+ ### Pagination
198
+
199
+ Pages are 1-indexed (they start at 1, not 0). The default page is 1 and the default page size is 10.
200
+
201
+ ```tsx
202
+ <div>
203
+ <button
204
+ onClick={table.pagination.goToPrevious}
205
+ disabled={!table.pagination.canGoPrevious}
206
+ >
207
+ Previous
208
+ </button>
209
+ <span>
210
+ Page {table.pagination.pageNo} of {table.pagination.totalPages}
211
+ {" "}({table.pagination.totalItems} total)
212
+ </span>
213
+ <button
214
+ onClick={table.pagination.goToNext}
215
+ disabled={!table.pagination.canGoNext}
216
+ >
217
+ Next
218
+ </button>
219
+ </div>
220
+
221
+ <select
222
+ value={table.pagination.pageSize}
223
+ onChange={(e) => table.pagination.setPageSize(Number(e.target.value))}
224
+ >
225
+ <option value={10}>10</option>
226
+ <option value={25}>25</option>
227
+ <option value={50}>50</option>
228
+ </select>
229
+ ```
230
+
231
+ - **`pagination.goToNext()`** / **`pagination.goToPrevious()`** — navigate forward/backward. No-op at boundaries.
232
+ - **`pagination.goToPage(n)`** — jump to a specific page. Clamped to `[1, totalPages]`.
233
+ - **`pagination.canGoNext`** / **`pagination.canGoPrevious`** — whether navigation is possible.
234
+ - **`pagination.setPageSize(n)`** — change the page size. Resets to page 1.
235
+ - **`pagination.pageNo`** / **`pagination.pageSize`** / **`pagination.totalPages`** / **`pagination.totalItems`** — current pagination state.
236
+
237
+ ### Refetching
238
+
239
+ Call `refetch()` to manually refresh the table data. This refetches both the list and the count:
240
+
241
+ ```tsx
242
+ const handleComplete = async (row) => {
243
+ await row.complete();
244
+ table.refetch();
245
+ };
246
+ ```
247
+
248
+ This is the standard pattern after any mutation (complete, update, save) that should be reflected in the table. Also use `table.refetch()` after closing a form dialog that modifies an activity instance.
249
+
250
+ ## Further Reading
251
+
252
+ - [API Reference](./api_reference.md) — All options, return values, and type definitions
253
+ - [My Pending Requests](../examples/workflow/my-pending-requests.md) — In Progress / Completed tabs
254
+ - [Filtered Activity Table](../examples/workflow/filtered-activity-table.md) — Date range filter on activities
255
+
256
+ ## Common Mistakes
257
+
258
+ - **Don't forget `useMemo` on the Activity instance.** `new ActivityClass()` must be wrapped in `useMemo(() => ..., [])`. Re-creating the instance on every render causes infinite refetching.
259
+ - **Don't access row fields directly.** `row.LeaveType` is an accessor object, not the value. Use `row.LeaveType.get()` to read the value.
260
+ - **Don't use raw strings for status.** Use `ActivityTableStatus.InProgress` and `ActivityTableStatus.Completed`, not `'inProgress'` or `'in_progress'`.
261
+ - **Don't use 0-indexed pagination.** Pages start at 1. Passing `pageNo: 0` will produce incorrect results.
262
+ - **Don't forget to guard on `isLoading` before rendering rows.** While loading, `rows` is an empty array. Guard with `if (table.isLoading) return <Loading />` to avoid rendering an empty table.
263
+ - **Don't hardcode field names as strings.** Use the activity field IDs (`activity.StartDate.id`) instead of raw strings (`"StartDate"`). This keeps your code type-safe and resilient to field renames.
@@ -0,0 +1,294 @@
1
+ # useActivityTable API Reference
2
+
3
+ ```tsx
4
+ import { useActivityTable, ActivityTableStatus } from "@ram_28/kf-ai-sdk/workflow";
5
+ import type {
6
+ UseActivityTableOptionsType,
7
+ UseActivityTableReturnType,
8
+ ActivityRowType,
9
+ ActivityTableStatusType,
10
+ } from "@ram_28/kf-ai-sdk/workflow";
11
+ import type { ActivityInstanceFieldsType } from "@ram_28/kf-ai-sdk/workflow";
12
+ ```
13
+
14
+ ## Signature
15
+
16
+ ```tsx
17
+ const table: UseActivityTableReturnType<A> = useActivityTable<A>(options: UseActivityTableOptionsType<A>);
18
+ ```
19
+
20
+ ## Options
21
+
22
+ `UseActivityTableOptionsType<A>`
23
+
24
+ - `activity: A`
25
+ - **Required**
26
+ - Activity instance with `getInProgressList()`, `getCompletedList()`, `inProgressCount()`, and `completedCount()` methods. Must be memoized with `useMemo()`.
27
+ - `status: ActivityTableStatusType`
28
+ - **Required**
29
+ - `ActivityTableStatus.InProgress` or `ActivityTableStatus.Completed`. Determines whether in-progress or completed items are fetched.
30
+ - `initialState`
31
+ - **Optional**
32
+ - Object with:
33
+ - `sort?: SortType` — Initial sort configuration. Format: `[{ "fieldName": "ASC" }]`
34
+ - `pagination?: PaginationStateType` — Initial page and page size. Defaults to `{ pageNo: 1, pageSize: 10 }`.
35
+ - `filter?: UseFilterOptionsType<ActivityRowType<A>>` — Initial filter conditions and operator.
36
+ - `onError?: (error: Error) => void`
37
+ - **Optional**
38
+ - Called when fetching items or count fails.
39
+ - `onSuccess?: (data: ActivityRowType<A>[]) => void`
40
+ - **Optional**
41
+ - Called with the current page rows after a successful list fetch.
42
+
43
+ ## Return Value
44
+
45
+ `UseActivityTableReturnType<A>`
46
+
47
+ Alias for `UseTableReturnType<ActivityRowType<A>>`. `ActivityRowType<A>` resolves to `ActivityInstanceType<TEntity & ActivityInstanceFieldsType, TEditable, TReadonly & ActivitySystemReadonlyType>` — inferred from the Activity's `getInProgressList()` return type. Rows are proxy objects with `.get()` accessors, persistence methods, and activity system fields.
48
+
49
+ ### Data
50
+
51
+ - `rows: ActivityInstanceType<...>[]`
52
+ - Array of `ActivityInstanceType` proxy instances for the current page. Access field values via `.get()` (e.g. `row.LeaveType.get()`), not direct property access. Each row also has persistence methods (`update()`, `save()`, `complete()`, `progress()`) and activity system fields (`BPInstanceId`, `Status`, `AssignedTo`, `CompletedAt`). Empty array during initial loading.
53
+ - `totalItems: number`
54
+ - Total number of records matching the current filters and search. `0` while count is loading.
55
+
56
+ ### Loading & Error
57
+
58
+ - `isLoading: boolean`
59
+ - `true` during the initial load of both items and count.
60
+ - `isFetching: boolean`
61
+ - `true` during any fetch including background refetches for items or count.
62
+ - `error: Error | null`
63
+ - Most recent fetch error from either items or count. `null` when no error.
64
+
65
+ ### Search
66
+
67
+ - `search.query: string`
68
+ - Current search input value (updated immediately on `set()`).
69
+ - `search.field: keyof T | null`
70
+ - The field currently being searched. `null` when no search is active.
71
+ - `search.set(field: keyof T, query: string): void`
72
+ - Set the search field and query. The input value updates immediately; the data fetch is debounced by 300 ms. Pagination resets to page 1 after the debounce. Query is capped at 255 characters.
73
+ - `search.clear(): void`
74
+ - Clear the search field and query. Pagination resets to page 1.
75
+
76
+ ### Sort
77
+
78
+ - `sort.field: keyof T | null`
79
+ - Currently sorted field. `null` when no sort is active.
80
+ - `sort.direction: "ASC" | "DESC" | null`
81
+ - Current sort direction. `null` when no sort is active.
82
+ - `sort.toggle(field: keyof T): void`
83
+ - Cycle the sort for a field: ASC -> DESC -> cleared. If a different field was sorted, starts at ASC.
84
+ - `sort.clear(): void`
85
+ - Remove all sorting.
86
+ - `sort.set(field: keyof T | null, direction: "ASC" | "DESC" | null): void`
87
+ - Explicitly set the sort field and direction.
88
+
89
+ ### Filter
90
+
91
+ - `filter: UseFilterReturnType<T>`
92
+ - Full filter state and operations. See [useFilter reference](../useFilter/api_reference.md) for the complete API.
93
+
94
+ ### Pagination
95
+
96
+ - `pagination.pageNo: number`
97
+ - Current page number (1-indexed).
98
+ - `pagination.pageSize: number`
99
+ - Current number of items per page.
100
+ - `pagination.totalPages: number`
101
+ - Total number of pages based on `totalItems` and `pageSize`.
102
+ - `pagination.totalItems: number`
103
+ - Same as the top-level `totalItems`.
104
+ - `pagination.canGoNext: boolean`
105
+ - `true` when a next page exists.
106
+ - `pagination.canGoPrevious: boolean`
107
+ - `true` when a previous page exists (i.e. `pageNo > 1`).
108
+ - `pagination.goToNext(): void`
109
+ - Navigate to the next page. No-op if already on the last page.
110
+ - `pagination.goToPrevious(): void`
111
+ - Navigate to the previous page. No-op if already on page 1.
112
+ - `pagination.goToPage(page: number): void`
113
+ - Navigate to a specific page. Clamped to `[1, totalPages]`.
114
+ - `pagination.setPageSize(size: number): void`
115
+ - Change the page size. Resets to page 1.
116
+
117
+ ### Operations
118
+
119
+ - `refetch(): Promise<ListResponseType<T>>`
120
+ - Manually refetch both the items and the count. Returns the list response.
121
+
122
+ ## Exported Constants
123
+
124
+ Available from `@ram_28/kf-ai-sdk/workflow`:
125
+
126
+ ```typescript
127
+ import { ActivityTableStatus } from "@ram_28/kf-ai-sdk/workflow";
128
+ ```
129
+
130
+ **ActivityTableStatus**
131
+
132
+ | Key | Value | Description |
133
+ |-----|-------|-------------|
134
+ | `InProgress` | `"inprogress"` | Fetches the in-progress items of the current activity |
135
+ | `Completed` | `"completed"` | Fetches the completed items of the current activity |
136
+
137
+ **SortDirection** (from `@ram_28/kf-ai-sdk/table`)
138
+
139
+ | Key | Value |
140
+ |-----|-------|
141
+ | `ASC` | `"ASC"` |
142
+ | `DESC` | `"DESC"` |
143
+
144
+ **TableDefaults** (from `@ram_28/kf-ai-sdk/table`)
145
+
146
+ | Key | Value | Description |
147
+ |-----|-------|-------------|
148
+ | `SEARCH_DEBOUNCE_MS` | `300` | Debounce delay for search (ms) |
149
+ | `PAGE_SIZE` | `10` | Default items per page |
150
+ | `PAGE` | `1` | Default page number (1-indexed) |
151
+ | `SEARCH_MAX_LENGTH` | `255` | Maximum search query length |
152
+
153
+ For filter constants (`ConditionOperator`, `GroupOperator`, `RHSType`), see [useFilter reference](../useFilter/api_reference.md).
154
+
155
+ ## Types
156
+
157
+ ```typescript
158
+ import type { ActivityInstanceType } from "@ram_28/kf-ai-sdk/workflow";
159
+
160
+ // ============================================================
161
+ // Options
162
+ // ============================================================
163
+
164
+ interface UseActivityTableOptionsType<A extends Activity<any, any, any>> {
165
+ activity: A;
166
+ status: ActivityTableStatusType;
167
+ initialState?: {
168
+ sort?: SortType;
169
+ pagination?: PaginationStateType;
170
+ filter?: UseFilterOptionsType<ActivityRowType<A>>;
171
+ };
172
+ onError?: (error: Error) => void;
173
+ onSuccess?: (data: ActivityRowType<A>[]) => void;
174
+ }
175
+
176
+ // ============================================================
177
+ // Return type
178
+ // ============================================================
179
+
180
+ type UseActivityTableReturnType<A extends Activity<any, any, any>> =
181
+ UseTableReturnType<ActivityRowType<A>>;
182
+
183
+ // ActivityRowType resolves to ActivityInstanceType<...>
184
+ // ActivityInstanceType<TEntity, TEditable, TReadonly> provides:
185
+ // row._id: string (direct access, no .get())
186
+ // row.Field.get(): value (read field value)
187
+ // row.Field.set(value): void (editable fields only)
188
+ // row.Field.validate(): ValidationResultType (single field)
189
+ // row.Field.label / .required / .readOnly / .defaultValue / .meta
190
+ // row.toJSON(): plain object
191
+ // row.validate(): ValidationResultType (all fields)
192
+ // row.update(data): Promise (persist changes)
193
+ // row.save(data): Promise (commit draft)
194
+ // row.complete(): Promise (complete activity)
195
+ // row.progress(): Promise (get workflow progress)
196
+
197
+ interface UseTableReturnType<T> {
198
+ // Data
199
+ rows: T[];
200
+ totalItems: number;
201
+
202
+ // Loading States
203
+ isLoading: boolean;
204
+ isFetching: boolean;
205
+
206
+ // Error Handling
207
+ error: Error | null;
208
+
209
+ // Search
210
+ search: {
211
+ query: string;
212
+ field: keyof T | null;
213
+ set: (field: keyof T, query: string) => void;
214
+ clear: () => void;
215
+ };
216
+
217
+ // Sorting
218
+ sort: {
219
+ field: keyof T | null;
220
+ direction: "ASC" | "DESC" | null;
221
+ toggle: (field: keyof T) => void;
222
+ clear: () => void;
223
+ set: (field: keyof T | null, direction: "ASC" | "DESC" | null) => void;
224
+ };
225
+
226
+ // Filter
227
+ filter: UseFilterReturnType<T>;
228
+
229
+ // Pagination
230
+ pagination: {
231
+ pageNo: number;
232
+ pageSize: number;
233
+ totalPages: number;
234
+ totalItems: number;
235
+ canGoNext: boolean;
236
+ canGoPrevious: boolean;
237
+ goToNext: () => void;
238
+ goToPrevious: () => void;
239
+ goToPage: (page: number) => void;
240
+ setPageSize: (size: number) => void;
241
+ };
242
+
243
+ // Operations
244
+ refetch: () => Promise<ListResponseType<T>>;
245
+ }
246
+
247
+ // ============================================================
248
+ // Status
249
+ // ============================================================
250
+
251
+ const ActivityTableStatus = {
252
+ InProgress: "inprogress",
253
+ Completed: "completed",
254
+ } as const;
255
+
256
+ type ActivityTableStatusType =
257
+ (typeof ActivityTableStatus)[keyof typeof ActivityTableStatus];
258
+ // resolves to: "inprogress" | "completed"
259
+
260
+ // ============================================================
261
+ // Row type inference
262
+ // ============================================================
263
+
264
+ type ActivityRowType<A extends Activity<any, any, any>> =
265
+ A extends { getInProgressList(opts?: any): Promise<(infer R)[]> }
266
+ ? R
267
+ : never;
268
+
269
+ // ============================================================
270
+ // Activity system fields
271
+ // ============================================================
272
+
273
+ type ActivityInstanceFieldsType = {
274
+ _id: string;
275
+ BPInstanceId: string;
276
+ Status: "InProgress" | "Completed";
277
+ AssignedTo: Array<{ _id: string; _name: string }>;
278
+ CompletedAt: string; // ISO 8601 datetime
279
+ };
280
+
281
+ // ============================================================
282
+ // State types
283
+ // ============================================================
284
+
285
+ interface PaginationStateType {
286
+ pageNo: number;
287
+ pageSize: number;
288
+ }
289
+
290
+ type SortOptionType = Record<string, "ASC" | "DESC">;
291
+ type SortType = SortOptionType[];
292
+
293
+ // Filter types — see useFilter reference (../useFilter/api_reference.md)
294
+ ```