@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
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
import { useState, useMemo, useCallback, useRef, useEffect } from
|
|
2
|
-
import { useQuery } from
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import { useState, useMemo, useCallback, useRef, useEffect } from 'react';
|
|
2
|
+
import { useQuery } from '@tanstack/react-query';
|
|
3
|
+
import type {
|
|
4
|
+
ListResponseType,
|
|
5
|
+
ListOptionsType,
|
|
6
|
+
FilterType,
|
|
7
|
+
ConditionType,
|
|
8
|
+
} from '../../../types/common';
|
|
9
|
+
import { toError } from '../../../utils/error-handling';
|
|
10
|
+
import { useFilter } from '../useFilter';
|
|
11
|
+
import type { UseTableOptionsType, UseTableReturnType } from './types';
|
|
8
12
|
|
|
9
13
|
// ============================================================
|
|
10
14
|
// INTERNAL STATE TYPES
|
|
@@ -18,7 +22,7 @@ interface SearchState<T> {
|
|
|
18
22
|
|
|
19
23
|
interface SortingState<T> {
|
|
20
24
|
field: keyof T | null;
|
|
21
|
-
direction:
|
|
25
|
+
direction: 'ASC' | 'DESC' | null;
|
|
22
26
|
}
|
|
23
27
|
|
|
24
28
|
interface PaginationState {
|
|
@@ -31,15 +35,15 @@ interface PaginationState {
|
|
|
31
35
|
// ============================================================
|
|
32
36
|
|
|
33
37
|
export function useTable<T = any>(
|
|
34
|
-
options: UseTableOptionsType<T
|
|
38
|
+
options: UseTableOptionsType<T>,
|
|
35
39
|
): UseTableReturnType<T> {
|
|
36
40
|
// ============================================================
|
|
37
41
|
// STATE MANAGEMENT
|
|
38
42
|
// ============================================================
|
|
39
43
|
|
|
40
44
|
const [search, setSearch] = useState<SearchState<T>>({
|
|
41
|
-
query:
|
|
42
|
-
debouncedQuery:
|
|
45
|
+
query: '',
|
|
46
|
+
debouncedQuery: '',
|
|
43
47
|
field: null,
|
|
44
48
|
});
|
|
45
49
|
|
|
@@ -53,8 +57,8 @@ export function useTable<T = any>(
|
|
|
53
57
|
if (sortConfig && sortConfig.length > 0) {
|
|
54
58
|
const firstSort = sortConfig[0];
|
|
55
59
|
const field = Object.keys(firstSort)[0] as keyof T;
|
|
56
|
-
const raw = firstSort[field as string]?.toUpperCase() as
|
|
57
|
-
const direction = raw ===
|
|
60
|
+
const raw = firstSort[field as string]?.toUpperCase() as 'ASC' | 'DESC';
|
|
61
|
+
const direction = raw === 'ASC' || raw === 'DESC' ? raw : 'ASC';
|
|
58
62
|
return { field, direction };
|
|
59
63
|
}
|
|
60
64
|
return { field: null, direction: null };
|
|
@@ -73,7 +77,7 @@ export function useTable<T = any>(
|
|
|
73
77
|
|
|
74
78
|
const filter = useFilter<T>({
|
|
75
79
|
conditions: options.initialState?.filter?.conditions,
|
|
76
|
-
operator: options.initialState?.filter?.operator ||
|
|
80
|
+
operator: options.initialState?.filter?.operator || 'And',
|
|
77
81
|
});
|
|
78
82
|
|
|
79
83
|
// ============================================================
|
|
@@ -99,14 +103,14 @@ export function useTable<T = any>(
|
|
|
99
103
|
if (search.debouncedQuery && search.field) {
|
|
100
104
|
const searchCondition: ConditionType = {
|
|
101
105
|
LHSField: search.field,
|
|
102
|
-
Operator:
|
|
106
|
+
Operator: 'Contains',
|
|
103
107
|
RHSValue: search.debouncedQuery,
|
|
104
|
-
RHSType:
|
|
108
|
+
RHSType: 'Constant',
|
|
105
109
|
};
|
|
106
110
|
|
|
107
111
|
if (combinedFilter) {
|
|
108
112
|
// Merge with existing filter
|
|
109
|
-
if (combinedFilter.Operator ===
|
|
113
|
+
if (combinedFilter.Operator === 'And') {
|
|
110
114
|
combinedFilter = {
|
|
111
115
|
...combinedFilter,
|
|
112
116
|
Condition: [...(combinedFilter.Condition || []), searchCondition],
|
|
@@ -114,14 +118,14 @@ export function useTable<T = any>(
|
|
|
114
118
|
} else {
|
|
115
119
|
// Wrap existing filter in And with search condition
|
|
116
120
|
combinedFilter = {
|
|
117
|
-
Operator:
|
|
121
|
+
Operator: 'And',
|
|
118
122
|
Condition: [combinedFilter, searchCondition],
|
|
119
123
|
};
|
|
120
124
|
}
|
|
121
125
|
} else {
|
|
122
126
|
// Create new filter with just the search condition
|
|
123
127
|
combinedFilter = {
|
|
124
|
-
Operator:
|
|
128
|
+
Operator: 'And',
|
|
125
129
|
Condition: [searchCondition],
|
|
126
130
|
};
|
|
127
131
|
}
|
|
@@ -166,10 +170,10 @@ export function useTable<T = any>(
|
|
|
166
170
|
error,
|
|
167
171
|
refetch: queryRefetch,
|
|
168
172
|
} = useQuery({
|
|
169
|
-
queryKey: [
|
|
173
|
+
queryKey: [...options.queryKey, apiOptions],
|
|
170
174
|
queryFn: async (): Promise<ListResponseType<T>> => {
|
|
171
175
|
try {
|
|
172
|
-
const response = await
|
|
176
|
+
const response = await options.listFn(apiOptions);
|
|
173
177
|
if (options.onSuccess) {
|
|
174
178
|
options.onSuccess(response.Data);
|
|
175
179
|
}
|
|
@@ -193,10 +197,10 @@ export function useTable<T = any>(
|
|
|
193
197
|
error: countError,
|
|
194
198
|
refetch: countRefetch,
|
|
195
199
|
} = useQuery({
|
|
196
|
-
queryKey: [
|
|
200
|
+
queryKey: [...options.queryKey, 'count', countApiOptions],
|
|
197
201
|
queryFn: async () => {
|
|
198
202
|
try {
|
|
199
|
-
return await
|
|
203
|
+
return await options.countFn(countApiOptions);
|
|
200
204
|
} catch (err) {
|
|
201
205
|
if (options.onError) {
|
|
202
206
|
options.onError(toError(err));
|
|
@@ -226,13 +230,13 @@ export function useTable<T = any>(
|
|
|
226
230
|
const toggleSort = useCallback((field: keyof T) => {
|
|
227
231
|
setSorting((prev) => {
|
|
228
232
|
if (prev.field === field) {
|
|
229
|
-
if (prev.direction ===
|
|
230
|
-
return { field, direction:
|
|
231
|
-
} else if (prev.direction ===
|
|
233
|
+
if (prev.direction === 'ASC') {
|
|
234
|
+
return { field, direction: 'DESC' };
|
|
235
|
+
} else if (prev.direction === 'DESC') {
|
|
232
236
|
return { field: null, direction: null };
|
|
233
237
|
}
|
|
234
238
|
}
|
|
235
|
-
return { field, direction:
|
|
239
|
+
return { field, direction: 'ASC' };
|
|
236
240
|
});
|
|
237
241
|
}, []);
|
|
238
242
|
|
|
@@ -241,44 +245,47 @@ export function useTable<T = any>(
|
|
|
241
245
|
}, []);
|
|
242
246
|
|
|
243
247
|
const setSort = useCallback(
|
|
244
|
-
(field: keyof T | null, direction:
|
|
248
|
+
(field: keyof T | null, direction: 'ASC' | 'DESC' | null) => {
|
|
245
249
|
setSorting({ field, direction });
|
|
246
250
|
},
|
|
247
|
-
[]
|
|
251
|
+
[],
|
|
248
252
|
);
|
|
249
253
|
|
|
250
254
|
// ============================================================
|
|
251
255
|
// SEARCH OPERATIONS
|
|
252
256
|
// ============================================================
|
|
253
257
|
|
|
254
|
-
const setSearchFieldAndQuery = useCallback(
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
258
|
+
const setSearchFieldAndQuery = useCallback(
|
|
259
|
+
(field: keyof T, query: string) => {
|
|
260
|
+
// Validate search query length to prevent DoS
|
|
261
|
+
if (query.length > 255) {
|
|
262
|
+
console.warn('Search query exceeds maximum length of 255 characters');
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
260
265
|
|
|
261
|
-
|
|
262
|
-
|
|
266
|
+
// Update immediate value for UI
|
|
267
|
+
setSearch((prev) => ({ ...prev, query, field }));
|
|
263
268
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
269
|
+
// Clear existing debounce timeout
|
|
270
|
+
if (searchDebounceRef.current) {
|
|
271
|
+
clearTimeout(searchDebounceRef.current);
|
|
272
|
+
}
|
|
268
273
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
274
|
+
// Debounce the actual API query update
|
|
275
|
+
searchDebounceRef.current = setTimeout(() => {
|
|
276
|
+
setSearch((prev) => ({ ...prev, debouncedQuery: query }));
|
|
277
|
+
setPagination((prev) => ({ ...prev, pageNo: 1 }));
|
|
278
|
+
}, SEARCH_DEBOUNCE_MS);
|
|
279
|
+
},
|
|
280
|
+
[],
|
|
281
|
+
);
|
|
275
282
|
|
|
276
283
|
const clearSearch = useCallback(() => {
|
|
277
284
|
// Clear debounce timeout
|
|
278
285
|
if (searchDebounceRef.current) {
|
|
279
286
|
clearTimeout(searchDebounceRef.current);
|
|
280
287
|
}
|
|
281
|
-
setSearch({ query:
|
|
288
|
+
setSearch({ query: '', debouncedQuery: '', field: null });
|
|
282
289
|
setPagination((prev) => ({ ...prev, pageNo: 1 }));
|
|
283
290
|
}, []);
|
|
284
291
|
|
|
@@ -315,7 +322,7 @@ export function useTable<T = any>(
|
|
|
315
322
|
const pageNo = Math.max(1, Math.min(page, totalPages));
|
|
316
323
|
setPagination((prev) => ({ ...prev, pageNo }));
|
|
317
324
|
},
|
|
318
|
-
[totalPages]
|
|
325
|
+
[totalPages],
|
|
319
326
|
);
|
|
320
327
|
|
|
321
328
|
const setPageSize = useCallback((size: number) => {
|
package/sdk/form.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// ============================================================
|
|
2
2
|
// Form Entry Point
|
|
3
3
|
// ============================================================
|
|
4
|
-
// Exports
|
|
4
|
+
// Exports useBDOForm hook for forms with automatic validation and API operations.
|
|
5
5
|
|
|
6
|
-
export {
|
|
6
|
+
export { useBDOForm } from "./components/hooks/useBDOForm";
|
|
7
7
|
export { ValidationMode, FormOperation, InteractionMode } from "./types/constants";
|
package/sdk/form.types.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// ============================================================
|
|
2
2
|
// Form Types Entry Point
|
|
3
3
|
// ============================================================
|
|
4
|
-
// Type-only exports for
|
|
4
|
+
// Type-only exports for useBDOForm hook.
|
|
5
5
|
|
|
6
6
|
export type {
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
UseBDOFormOptionsType,
|
|
8
|
+
UseBDOFormReturnType,
|
|
9
9
|
FormItemType,
|
|
10
10
|
EditableFormFieldAccessorType,
|
|
11
11
|
ReadonlyFormFieldAccessorType,
|
|
@@ -14,4 +14,4 @@ export type {
|
|
|
14
14
|
ExtractEditableType,
|
|
15
15
|
ExtractReadonlyType,
|
|
16
16
|
AllFieldsType,
|
|
17
|
-
} from "./components/hooks/
|
|
17
|
+
} from "./components/hooks/useBDOForm";
|
package/sdk/table.ts
CHANGED
|
@@ -3,9 +3,12 @@
|
|
|
3
3
|
// @ram_28/kf-ai-sdk/table
|
|
4
4
|
// ============================================================
|
|
5
5
|
|
|
6
|
-
//
|
|
6
|
+
// Base hook
|
|
7
7
|
export { useTable } from './components/hooks/useTable/useTable';
|
|
8
8
|
|
|
9
|
+
// BDO wrapper hook
|
|
10
|
+
export { useBDOTable } from './components/hooks/useBDOTable/useBDOTable';
|
|
11
|
+
|
|
9
12
|
// Constants
|
|
10
13
|
export {
|
|
11
14
|
SortDirection,
|
package/sdk/table.types.ts
CHANGED
|
@@ -4,13 +4,16 @@
|
|
|
4
4
|
// ============================================================
|
|
5
5
|
|
|
6
6
|
export type {
|
|
7
|
-
//
|
|
7
|
+
// Base hook types
|
|
8
8
|
UseTableOptionsType,
|
|
9
9
|
UseTableReturnType,
|
|
10
10
|
|
|
11
|
-
// Column definition
|
|
12
|
-
ColumnDefinitionType,
|
|
13
|
-
|
|
14
11
|
// State types
|
|
15
12
|
PaginationStateType,
|
|
16
13
|
} from './components/hooks/useTable/types';
|
|
14
|
+
|
|
15
|
+
export type {
|
|
16
|
+
// BDO wrapper types
|
|
17
|
+
UseBDOTableOptionsType,
|
|
18
|
+
UseBDOTableReturnType,
|
|
19
|
+
} from './components/hooks/useBDOTable/types';
|
package/sdk/types/base-fields.ts
CHANGED
|
@@ -93,16 +93,16 @@ type Second = number;
|
|
|
93
93
|
|
|
94
94
|
/**
|
|
95
95
|
* DateTime field (date and time)
|
|
96
|
-
* API Request Format: "YYYY-MM-
|
|
96
|
+
* API Request Format: "YYYY-MM-DDTHH:MM:SSZ"
|
|
97
|
+
* API Response Format: "YYYY-MM-DDTHH:MM:SSZ" (always UTC)
|
|
97
98
|
* Use this for created_at, updated_at, event timestamps
|
|
98
99
|
*
|
|
99
100
|
* @example
|
|
100
|
-
*
|
|
101
|
-
* "2026-01-23T01:21:33"
|
|
101
|
+
* "2026-01-23T01:21:33Z"
|
|
102
102
|
*/
|
|
103
103
|
|
|
104
104
|
export type DateTimeFieldType =
|
|
105
|
-
`${Year}-${Month}-${Day}T${Hour}:${Minute}:${Second}`;
|
|
105
|
+
`${Year}-${Month}-${Day}T${Hour}:${Minute}:${Second}Z`;
|
|
106
106
|
|
|
107
107
|
// ============================================================
|
|
108
108
|
// COMPLEX FIELD TYPES
|
package/sdk/types/constants.ts
CHANGED
|
@@ -187,7 +187,7 @@ export const QueryType = {
|
|
|
187
187
|
* @example
|
|
188
188
|
* import { FormOperation } from "@ram_28/kf-ai-sdk/form";
|
|
189
189
|
*
|
|
190
|
-
* const { handleSubmit } =
|
|
190
|
+
* const { handleSubmit } = useBDOForm({
|
|
191
191
|
* source: "products",
|
|
192
192
|
* operation: FormOperation.Create,
|
|
193
193
|
* });
|
|
@@ -206,7 +206,7 @@ export const FormOperation = {
|
|
|
206
206
|
* @example
|
|
207
207
|
* import { InteractionMode } from "@ram_28/kf-ai-sdk/form";
|
|
208
208
|
*
|
|
209
|
-
* const { handleSubmit } =
|
|
209
|
+
* const { handleSubmit } = useBDOForm({
|
|
210
210
|
* source: "products",
|
|
211
211
|
* operation: "create",
|
|
212
212
|
* interactionMode: InteractionMode.Interactive,
|
|
@@ -225,7 +225,7 @@ export const InteractionMode = {
|
|
|
225
225
|
* @example
|
|
226
226
|
* import { ValidationMode } from "@ram_28/kf-ai-sdk/form";
|
|
227
227
|
*
|
|
228
|
-
* const { handleSubmit } =
|
|
228
|
+
* const { handleSubmit } = useBDOForm({
|
|
229
229
|
* source: "products",
|
|
230
230
|
* operation: "create",
|
|
231
231
|
* mode: ValidationMode.OnBlur,
|
package/sdk/workflow/Activity.ts
CHANGED
|
@@ -12,8 +12,10 @@
|
|
|
12
12
|
// Methods:
|
|
13
13
|
// activity.getInProgressList() // list in-progress activity instances
|
|
14
14
|
// activity.getCompletedList() // list completed activity instances
|
|
15
|
-
// activity.
|
|
16
|
-
// activity.
|
|
15
|
+
// activity.inProgressCount() // get in-progress count (returns number)
|
|
16
|
+
// activity.completedCount() // get completed count (returns number)
|
|
17
|
+
// activity.inProgressMetric(options) // get in-progress aggregated metrics
|
|
18
|
+
// activity.completedMetric(options) // get completed aggregated metrics
|
|
17
19
|
// activity.getInstance(instanceId) // get typed ActivityInstance
|
|
18
20
|
|
|
19
21
|
import { Workflow } from "./client";
|
|
@@ -22,6 +24,8 @@ import type { ActivityInstanceType } from "./ActivityInstance";
|
|
|
22
24
|
import type { ActivityInstanceFieldsType, ActivityOperations } from "./types";
|
|
23
25
|
import type {
|
|
24
26
|
ListResponseType,
|
|
27
|
+
ListOptionsType,
|
|
28
|
+
MetricOptionsType,
|
|
25
29
|
MetricResponseType,
|
|
26
30
|
} from "../types/common";
|
|
27
31
|
import { BaseField } from "../bdo/fields/BaseField";
|
|
@@ -124,32 +128,52 @@ export abstract class Activity<
|
|
|
124
128
|
|
|
125
129
|
/**
|
|
126
130
|
* List in-progress activity instances.
|
|
127
|
-
*
|
|
131
|
+
* Accepts optional filter/sort/pagination options.
|
|
128
132
|
*/
|
|
129
|
-
async getInProgressList(): Promise<ListResponseType<ActivityInstanceFieldsType & TEntity>> {
|
|
130
|
-
return this._ops().inProgressList();
|
|
133
|
+
async getInProgressList(options?: ListOptionsType): Promise<ListResponseType<ActivityInstanceFieldsType & TEntity>> {
|
|
134
|
+
return this._ops().inProgressList(options);
|
|
131
135
|
}
|
|
132
136
|
|
|
133
137
|
/**
|
|
134
138
|
* List completed activity instances.
|
|
135
|
-
*
|
|
139
|
+
* Accepts optional filter/sort/pagination options.
|
|
136
140
|
*/
|
|
137
|
-
async getCompletedList(): Promise<ListResponseType<ActivityInstanceFieldsType & TEntity>> {
|
|
138
|
-
return this._ops().completedList();
|
|
141
|
+
async getCompletedList(options?: ListOptionsType): Promise<ListResponseType<ActivityInstanceFieldsType & TEntity>> {
|
|
142
|
+
return this._ops().completedList(options);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Get count of in-progress activity instances.
|
|
147
|
+
* Returns a number (same as BDO count()).
|
|
148
|
+
*/
|
|
149
|
+
async inProgressCount(options?: ListOptionsType): Promise<number> {
|
|
150
|
+
const response = await this._ops().inProgressCount(options);
|
|
151
|
+
return response.Count;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Get count of completed activity instances.
|
|
156
|
+
* Returns a number (same as BDO count()).
|
|
157
|
+
*/
|
|
158
|
+
async completedCount(options?: ListOptionsType): Promise<number> {
|
|
159
|
+
const response = await this._ops().completedCount(options);
|
|
160
|
+
return response.Count;
|
|
139
161
|
}
|
|
140
162
|
|
|
141
163
|
/**
|
|
142
164
|
* Get aggregated metrics for in-progress activity instances.
|
|
165
|
+
* Accepts MetricOptionsType (without Type) for custom aggregations (Sum, Avg, etc.).
|
|
143
166
|
*/
|
|
144
|
-
async
|
|
145
|
-
return this._ops().inProgressMetric();
|
|
167
|
+
async inProgressMetric(options: Omit<MetricOptionsType, 'Type'>): Promise<MetricResponseType> {
|
|
168
|
+
return this._ops().inProgressMetric(options);
|
|
146
169
|
}
|
|
147
170
|
|
|
148
171
|
/**
|
|
149
172
|
* Get aggregated metrics for completed activity instances.
|
|
173
|
+
* Accepts MetricOptionsType (without Type) for custom aggregations (Sum, Avg, etc.).
|
|
150
174
|
*/
|
|
151
|
-
async
|
|
152
|
-
return this._ops().completedMetric();
|
|
175
|
+
async completedMetric(options: Omit<MetricOptionsType, 'Type'>): Promise<MetricResponseType> {
|
|
176
|
+
return this._ops().completedMetric(options);
|
|
153
177
|
}
|
|
154
178
|
|
|
155
179
|
/**
|
package/sdk/workflow/client.ts
CHANGED
|
@@ -8,6 +8,9 @@ import {
|
|
|
8
8
|
} from "../api/client";
|
|
9
9
|
import type {
|
|
10
10
|
ListResponseType,
|
|
11
|
+
ListOptionsType,
|
|
12
|
+
CountResponseType,
|
|
13
|
+
MetricOptionsType,
|
|
11
14
|
MetricResponseType,
|
|
12
15
|
ReadResponseType,
|
|
13
16
|
DraftResponseType,
|
|
@@ -42,8 +45,8 @@ import type {
|
|
|
42
45
|
* // List operations (by status — filtering/pagination handled server-side)
|
|
43
46
|
* await act.inProgressList();
|
|
44
47
|
* await act.completedList();
|
|
45
|
-
* await act.
|
|
46
|
-
* await act.
|
|
48
|
+
* await act.inProgressCount();
|
|
49
|
+
* await act.completedCount();
|
|
47
50
|
*
|
|
48
51
|
* // Process progress (requires instance_id)
|
|
49
52
|
* const progress = await wf.progress("bp_inst_123");
|
|
@@ -109,10 +112,11 @@ export class Workflow<T = any> {
|
|
|
109
112
|
return {
|
|
110
113
|
// ── List-level ────────────────────────────────────────────
|
|
111
114
|
|
|
112
|
-
async inProgressList(): Promise<ListResponseType<ActivityInstanceFieldsType & T>> {
|
|
115
|
+
async inProgressList(options?: ListOptionsType): Promise<ListResponseType<ActivityInstanceFieldsType & T>> {
|
|
113
116
|
const response = await fetch(`${getApiBaseUrl()}${base}/inprogress/list`, {
|
|
114
|
-
method: "
|
|
117
|
+
method: "POST",
|
|
115
118
|
headers: getDefaultHeaders(),
|
|
119
|
+
body: options ? JSON.stringify(options) : undefined,
|
|
116
120
|
});
|
|
117
121
|
|
|
118
122
|
if (!response.ok) {
|
|
@@ -122,10 +126,11 @@ export class Workflow<T = any> {
|
|
|
122
126
|
return response.json();
|
|
123
127
|
},
|
|
124
128
|
|
|
125
|
-
async completedList(): Promise<ListResponseType<ActivityInstanceFieldsType & T>> {
|
|
129
|
+
async completedList(options?: ListOptionsType): Promise<ListResponseType<ActivityInstanceFieldsType & T>> {
|
|
126
130
|
const response = await fetch(`${getApiBaseUrl()}${base}/completed/list`, {
|
|
127
|
-
method: "
|
|
131
|
+
method: "POST",
|
|
128
132
|
headers: getDefaultHeaders(),
|
|
133
|
+
body: options ? JSON.stringify(options) : undefined,
|
|
129
134
|
});
|
|
130
135
|
|
|
131
136
|
if (!response.ok) {
|
|
@@ -135,27 +140,75 @@ export class Workflow<T = any> {
|
|
|
135
140
|
return response.json();
|
|
136
141
|
},
|
|
137
142
|
|
|
138
|
-
async
|
|
143
|
+
async inProgressCount(options?: ListOptionsType): Promise<CountResponseType> {
|
|
144
|
+
const requestBody = {
|
|
145
|
+
Type: 'Metric',
|
|
146
|
+
GroupBy: [],
|
|
147
|
+
Metric: [{ Field: '_id', Type: 'Count' }],
|
|
148
|
+
...(options?.Filter && { Filter: options.Filter }),
|
|
149
|
+
};
|
|
139
150
|
const response = await fetch(`${getApiBaseUrl()}${base}/inprogress/metric`, {
|
|
140
|
-
method:
|
|
151
|
+
method: 'POST',
|
|
152
|
+
headers: getDefaultHeaders(),
|
|
153
|
+
body: JSON.stringify(requestBody),
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
if (!response.ok) {
|
|
157
|
+
throw new Error(`Failed to get in-progress count: ${response.statusText}`);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const result = await response.json();
|
|
161
|
+
const count = result.Data?.[0]?.count__id ?? 0;
|
|
162
|
+
return { Count: count };
|
|
163
|
+
},
|
|
164
|
+
|
|
165
|
+
async completedCount(options?: ListOptionsType): Promise<CountResponseType> {
|
|
166
|
+
const requestBody = {
|
|
167
|
+
Type: 'Metric',
|
|
168
|
+
GroupBy: [],
|
|
169
|
+
Metric: [{ Field: '_id', Type: 'Count' }],
|
|
170
|
+
...(options?.Filter && { Filter: options.Filter }),
|
|
171
|
+
};
|
|
172
|
+
const response = await fetch(`${getApiBaseUrl()}${base}/completed/metric`, {
|
|
173
|
+
method: 'POST',
|
|
174
|
+
headers: getDefaultHeaders(),
|
|
175
|
+
body: JSON.stringify(requestBody),
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
if (!response.ok) {
|
|
179
|
+
throw new Error(`Failed to get completed count: ${response.statusText}`);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const result = await response.json();
|
|
183
|
+
const count = result.Data?.[0]?.count__id ?? 0;
|
|
184
|
+
return { Count: count };
|
|
185
|
+
},
|
|
186
|
+
|
|
187
|
+
async inProgressMetric(options: Omit<MetricOptionsType, 'Type'>): Promise<MetricResponseType> {
|
|
188
|
+
const requestBody: MetricOptionsType = { Type: 'Metric', ...options };
|
|
189
|
+
const response = await fetch(`${getApiBaseUrl()}${base}/inprogress/metric`, {
|
|
190
|
+
method: 'POST',
|
|
141
191
|
headers: getDefaultHeaders(),
|
|
192
|
+
body: JSON.stringify(requestBody),
|
|
142
193
|
});
|
|
143
194
|
|
|
144
195
|
if (!response.ok) {
|
|
145
|
-
throw new Error(`Failed to get in-progress
|
|
196
|
+
throw new Error(`Failed to get in-progress metrics: ${response.statusText}`);
|
|
146
197
|
}
|
|
147
198
|
|
|
148
199
|
return response.json();
|
|
149
200
|
},
|
|
150
201
|
|
|
151
|
-
async completedMetric(): Promise<MetricResponseType> {
|
|
202
|
+
async completedMetric(options: Omit<MetricOptionsType, 'Type'>): Promise<MetricResponseType> {
|
|
203
|
+
const requestBody: MetricOptionsType = { Type: 'Metric', ...options };
|
|
152
204
|
const response = await fetch(`${getApiBaseUrl()}${base}/completed/metric`, {
|
|
153
|
-
method:
|
|
205
|
+
method: 'POST',
|
|
154
206
|
headers: getDefaultHeaders(),
|
|
207
|
+
body: JSON.stringify(requestBody),
|
|
155
208
|
});
|
|
156
209
|
|
|
157
210
|
if (!response.ok) {
|
|
158
|
-
throw new Error(`Failed to get completed
|
|
211
|
+
throw new Error(`Failed to get completed metrics: ${response.statusText}`);
|
|
159
212
|
}
|
|
160
213
|
|
|
161
214
|
return response.json();
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// FIELD FACTORY — Runtime Field Construction from Metadata
|
|
3
|
+
// ============================================================
|
|
4
|
+
// Creates BaseField instances from raw BP activity Input metadata.
|
|
5
|
+
// Used by useActivityForm to dynamically build fields when BP
|
|
6
|
+
// metadata is fetched at runtime.
|
|
7
|
+
|
|
8
|
+
import { StringField } from '../bdo/fields/StringField';
|
|
9
|
+
import { NumberField } from '../bdo/fields/NumberField';
|
|
10
|
+
import { BooleanField } from '../bdo/fields/BooleanField';
|
|
11
|
+
import { DateField } from '../bdo/fields/DateField';
|
|
12
|
+
import { DateTimeField } from '../bdo/fields/DateTimeField';
|
|
13
|
+
import { TextField } from '../bdo/fields/TextField';
|
|
14
|
+
import { SelectField } from '../bdo/fields/SelectField';
|
|
15
|
+
import { ReferenceField } from '../bdo/fields/ReferenceField';
|
|
16
|
+
import { UserField } from '../bdo/fields/UserField';
|
|
17
|
+
import { FileField } from '../bdo/fields/FileField';
|
|
18
|
+
import type { BaseField } from '../bdo/fields/BaseField';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Create a BaseField instance from raw Input field metadata.
|
|
22
|
+
* Used by useActivityForm to dynamically construct fields from BP metadata.
|
|
23
|
+
*
|
|
24
|
+
* @param fieldId - The field identifier (e.g., "StartDate", "LeaveType")
|
|
25
|
+
* @param meta - Raw field metadata from BP Activity Input definition
|
|
26
|
+
* @returns A BaseField instance matching the metadata Type
|
|
27
|
+
*/
|
|
28
|
+
export function createFieldFromMeta(
|
|
29
|
+
fieldId: string,
|
|
30
|
+
meta: Record<string, unknown>,
|
|
31
|
+
): BaseField<unknown> {
|
|
32
|
+
const fullMeta = { _id: fieldId, ...meta };
|
|
33
|
+
const type = meta.Type as string;
|
|
34
|
+
|
|
35
|
+
// String + Enum constraint → SelectField
|
|
36
|
+
if (
|
|
37
|
+
type === 'String' &&
|
|
38
|
+
(meta.Constraint as Record<string, unknown> | undefined)?.Enum
|
|
39
|
+
) {
|
|
40
|
+
return new SelectField(fullMeta as any);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
switch (type) {
|
|
44
|
+
case 'String':
|
|
45
|
+
return new StringField(fullMeta as any);
|
|
46
|
+
case 'Number':
|
|
47
|
+
return new NumberField(fullMeta as any);
|
|
48
|
+
case 'Boolean':
|
|
49
|
+
return new BooleanField(fullMeta as any);
|
|
50
|
+
case 'Date':
|
|
51
|
+
return new DateField(fullMeta as any);
|
|
52
|
+
case 'DateTime':
|
|
53
|
+
return new DateTimeField(fullMeta as any);
|
|
54
|
+
case 'Text':
|
|
55
|
+
return new TextField(fullMeta as any);
|
|
56
|
+
case 'Reference':
|
|
57
|
+
return new ReferenceField(fullMeta as any);
|
|
58
|
+
case 'User':
|
|
59
|
+
return new UserField(fullMeta as any);
|
|
60
|
+
case 'File':
|
|
61
|
+
return new FileField(fullMeta as any);
|
|
62
|
+
default:
|
|
63
|
+
return new StringField(fullMeta as any);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Build a fields map from an Activity's Input metadata.
|
|
69
|
+
*
|
|
70
|
+
* @param input - The Input object from BP Activity definition
|
|
71
|
+
* (Record of fieldId → raw field metadata)
|
|
72
|
+
* @returns Record of fieldId → BaseField instance
|
|
73
|
+
*/
|
|
74
|
+
export function buildFieldsFromInput(
|
|
75
|
+
input: Record<string, Record<string, unknown>>,
|
|
76
|
+
): Record<string, BaseField<unknown>> {
|
|
77
|
+
const fields: Record<string, BaseField<unknown>> = {};
|
|
78
|
+
for (const [fieldId, fieldMeta] of Object.entries(input)) {
|
|
79
|
+
fields[fieldId] = createFieldFromMeta(fieldId, fieldMeta);
|
|
80
|
+
}
|
|
81
|
+
return fields;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Search all activities in a BP blob for a field definition by name.
|
|
86
|
+
* Used to discover field metadata for Context-derived readonly fields.
|
|
87
|
+
*
|
|
88
|
+
* @param currentActivityDef - The current activity definition (to skip)
|
|
89
|
+
* @param bpSchema - The full BP schema (with BDOBlob)
|
|
90
|
+
* @param fieldName - The field name to search for
|
|
91
|
+
* @returns The field metadata or null if not found
|
|
92
|
+
*/
|
|
93
|
+
export function findFieldInBpActivities(
|
|
94
|
+
currentActivityDef: Record<string, unknown> | null,
|
|
95
|
+
bpSchema: Record<string, unknown> | null | undefined,
|
|
96
|
+
fieldName: string,
|
|
97
|
+
): Record<string, unknown> | null {
|
|
98
|
+
const blob = (bpSchema as any)?.BDOBlob;
|
|
99
|
+
if (!blob?.Activity) return null;
|
|
100
|
+
|
|
101
|
+
const currentId = (currentActivityDef as any)?.Id;
|
|
102
|
+
|
|
103
|
+
for (const activity of blob.Activity as any[]) {
|
|
104
|
+
if (activity.Id === currentId) continue;
|
|
105
|
+
if (activity.Input?.[fieldName]) {
|
|
106
|
+
return activity.Input[fieldName];
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return null;
|
|
110
|
+
}
|