@ram_28/kf-ai-sdk 2.0.13 → 2.0.15
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 +2 -1
- 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.cjs +1 -1
- package/dist/bdo.mjs +228 -472
- 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 +11 -7
- 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/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 +26 -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/createResolver-AIgUwoS6.cjs +1 -0
- package/dist/createResolver-ZHXQ7QMa.js +1078 -0
- package/dist/form.cjs +1 -1
- package/dist/form.mjs +252 -314
- package/dist/{metadata-DpfI3zRN.js → metadata-Cc1mBcLS.js} +1 -1
- package/dist/{metadata-DgLSJkF5.cjs → metadata-DWXQPDav.cjs} +1 -1
- 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 +16 -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/useTable-CeRklbdT.cjs +1 -0
- package/dist/useTable-DS0-WInw.js +203 -0
- package/dist/workflow/Activity.d.ts +9 -9
- package/dist/workflow/Activity.d.ts.map +1 -1
- 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 +12 -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 +716 -338
- package/dist/workflow.types.d.ts +1 -0
- package/dist/workflow.types.d.ts.map +1 -1
- package/docs/bdo.md +3 -3
- package/docs/gaps.md +410 -0
- package/docs/useActivityTable.md +481 -0
- package/docs/useBDOTable.md +317 -0
- package/docs/useForm.md +4 -1
- package/docs/workflow.md +143 -34
- package/package.json +1 -1
- 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 +21 -8
- package/sdk/components/hooks/useActivityForm/useActivityForm.ts +628 -0
- package/sdk/components/hooks/useActivityTable/index.ts +8 -0
- package/sdk/components/hooks/useActivityTable/types.ts +45 -0
- package/sdk/components/hooks/useActivityTable/useActivityTable.ts +71 -0
- package/sdk/components/hooks/useBDOTable/index.ts +2 -0
- package/sdk/components/hooks/useBDOTable/types.ts +24 -0
- package/sdk/components/hooks/useBDOTable/useBDOTable.ts +15 -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/table.ts +4 -1
- package/sdk/table.types.ts +7 -4
- package/sdk/types/base-fields.ts +4 -4
- package/sdk/workflow/Activity.ts +14 -13
- package/sdk/workflow/client.ts +21 -8
- package/sdk/workflow/createFieldFromMeta.ts +110 -0
- package/sdk/workflow/index.ts +1 -6
- package/sdk/workflow/types.ts +13 -12
- 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/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/sdk/{workflow/components → components/hooks}/useActivityForm/index.ts +0 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import { useTable } from '../useTable';
|
|
3
|
+
import type { Activity } from '../../../workflow/Activity';
|
|
4
|
+
import type {
|
|
5
|
+
UseActivityTableOptionsType,
|
|
6
|
+
UseActivityTableReturnType,
|
|
7
|
+
ActivityRowType,
|
|
8
|
+
} from './types';
|
|
9
|
+
|
|
10
|
+
const ACTIVITY_SYSTEM_FIELDS = new Set([
|
|
11
|
+
'_id',
|
|
12
|
+
'BPInstanceId',
|
|
13
|
+
'Status',
|
|
14
|
+
'AssignedTo',
|
|
15
|
+
'CompletedAt',
|
|
16
|
+
]);
|
|
17
|
+
|
|
18
|
+
function nestEntityFields(
|
|
19
|
+
flatRow: Record<string, unknown>,
|
|
20
|
+
): Record<string, unknown> {
|
|
21
|
+
const result: Record<string, unknown> = {};
|
|
22
|
+
const ado: Record<string, unknown> = {};
|
|
23
|
+
for (const [key, value] of Object.entries(flatRow)) {
|
|
24
|
+
if (ACTIVITY_SYSTEM_FIELDS.has(key)) {
|
|
25
|
+
result[key] = value;
|
|
26
|
+
} else {
|
|
27
|
+
ado[key] = value;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
result.ADO = ado;
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function useActivityTable<A extends Activity<any, any, any>>(
|
|
35
|
+
activity: A,
|
|
36
|
+
options: UseActivityTableOptionsType<A>,
|
|
37
|
+
): UseActivityTableReturnType<A> {
|
|
38
|
+
const { status, ...rest } = options;
|
|
39
|
+
const { businessProcessId, activityId } = activity.meta;
|
|
40
|
+
|
|
41
|
+
const ops = useMemo(() => activity._getOps(), [activity]);
|
|
42
|
+
|
|
43
|
+
const listFn = useMemo(() => {
|
|
44
|
+
const rawFn =
|
|
45
|
+
status === 'inprogress'
|
|
46
|
+
? (opts: any) => ops.inProgressList(opts)
|
|
47
|
+
: (opts: any) => ops.completedList(opts);
|
|
48
|
+
return async (opts: any) => {
|
|
49
|
+
const result = await rawFn(opts);
|
|
50
|
+
return {
|
|
51
|
+
...result,
|
|
52
|
+
Data: result.Data.map(nestEntityFields),
|
|
53
|
+
} as typeof result;
|
|
54
|
+
};
|
|
55
|
+
}, [ops, status]);
|
|
56
|
+
|
|
57
|
+
const countFn = useMemo(
|
|
58
|
+
() =>
|
|
59
|
+
status === 'inprogress'
|
|
60
|
+
? (opts: any) => ops.inProgressMetric(opts)
|
|
61
|
+
: (opts: any) => ops.completedMetric(opts),
|
|
62
|
+
[ops, status],
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
return useTable<ActivityRowType<A>>({
|
|
66
|
+
queryKey: ['activity-table', businessProcessId, activityId, status],
|
|
67
|
+
listFn,
|
|
68
|
+
countFn,
|
|
69
|
+
...rest,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { UseTableReturnType, PaginationStateType } from '../useTable/types';
|
|
2
|
+
import type { UseFilterOptionsType } from '../useFilter/types';
|
|
3
|
+
import type { SortType } from '../../../types/common';
|
|
4
|
+
|
|
5
|
+
export interface UseBDOTableOptionsType<T> {
|
|
6
|
+
/** BDO instance with list() and count() methods */
|
|
7
|
+
bdo: {
|
|
8
|
+
meta: { readonly _id: string; readonly name: string };
|
|
9
|
+
list(options?: any): Promise<any>;
|
|
10
|
+
count(options?: any): Promise<any>;
|
|
11
|
+
};
|
|
12
|
+
/** Initial state */
|
|
13
|
+
initialState?: {
|
|
14
|
+
sort?: SortType;
|
|
15
|
+
pagination?: PaginationStateType;
|
|
16
|
+
filter?: UseFilterOptionsType<T>;
|
|
17
|
+
};
|
|
18
|
+
/** Error callback */
|
|
19
|
+
onError?: (error: Error) => void;
|
|
20
|
+
/** Success callback — receives rows from current page */
|
|
21
|
+
onSuccess?: (data: T[]) => void;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export type UseBDOTableReturnType<T> = UseTableReturnType<T>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { useTable } from '../useTable';
|
|
2
|
+
import type { UseBDOTableOptionsType, UseBDOTableReturnType } from './types';
|
|
3
|
+
|
|
4
|
+
export function useBDOTable<T = any>(
|
|
5
|
+
options: UseBDOTableOptionsType<T>,
|
|
6
|
+
): UseBDOTableReturnType<T> {
|
|
7
|
+
const { bdo, ...rest } = options;
|
|
8
|
+
|
|
9
|
+
return useTable<T>({
|
|
10
|
+
queryKey: ['table', bdo.meta._id],
|
|
11
|
+
listFn: (opts) => bdo.list(opts),
|
|
12
|
+
countFn: (opts) => bdo.count(opts),
|
|
13
|
+
...rest,
|
|
14
|
+
});
|
|
15
|
+
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import type {
|
|
2
|
+
ListResponseType,
|
|
3
|
+
ListOptionsType,
|
|
4
|
+
CountResponseType,
|
|
5
|
+
SortType,
|
|
6
|
+
} from '../../../types/common';
|
|
7
|
+
import type { UseFilterReturnType, UseFilterOptionsType } from '../useFilter';
|
|
6
8
|
|
|
7
9
|
// ============================================================
|
|
8
10
|
// STATE TYPE DEFINITIONS
|
|
@@ -23,10 +25,12 @@ export interface PaginationStateType {
|
|
|
23
25
|
// ============================================================
|
|
24
26
|
|
|
25
27
|
export interface UseTableOptionsType<T> {
|
|
26
|
-
/**
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
|
|
28
|
+
/** Unique query key for React Query caching */
|
|
29
|
+
queryKey: string[];
|
|
30
|
+
/** Fetch list data (POST with filter/sort/pagination) */
|
|
31
|
+
listFn: (options: ListOptionsType) => Promise<ListResponseType<T>>;
|
|
32
|
+
/** Fetch count (POST with filter only) */
|
|
33
|
+
countFn: (options: ListOptionsType) => Promise<CountResponseType>;
|
|
30
34
|
/** Initial state */
|
|
31
35
|
initialState?: {
|
|
32
36
|
/** Sort configuration: [{ "fieldName": "ASC" }] */
|
|
@@ -38,7 +42,7 @@ export interface UseTableOptionsType<T> {
|
|
|
38
42
|
};
|
|
39
43
|
/** Error callback */
|
|
40
44
|
onError?: (error: Error) => void;
|
|
41
|
-
/** Success callback */
|
|
45
|
+
/** Success callback — receives rows from current page */
|
|
42
46
|
onSuccess?: (data: T[]) => void;
|
|
43
47
|
}
|
|
44
48
|
|
|
@@ -65,10 +69,10 @@ export interface UseTableReturnType<T> {
|
|
|
65
69
|
// Sorting (Flat Access)
|
|
66
70
|
sort: {
|
|
67
71
|
field: keyof T | null;
|
|
68
|
-
direction:
|
|
72
|
+
direction: 'ASC' | 'DESC' | null;
|
|
69
73
|
toggle: (field: keyof T) => void;
|
|
70
74
|
clear: () => void;
|
|
71
|
-
set: (field: keyof T, direction:
|
|
75
|
+
set: (field: keyof T | null, direction: 'ASC' | 'DESC' | null) => void;
|
|
72
76
|
};
|
|
73
77
|
|
|
74
78
|
// Filter (Simplified chainable API)
|
|
@@ -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/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/workflow/Activity.ts
CHANGED
|
@@ -22,7 +22,8 @@ import type { ActivityInstanceType } from "./ActivityInstance";
|
|
|
22
22
|
import type { ActivityInstanceFieldsType, ActivityOperations } from "./types";
|
|
23
23
|
import type {
|
|
24
24
|
ListResponseType,
|
|
25
|
-
|
|
25
|
+
ListOptionsType,
|
|
26
|
+
CountResponseType,
|
|
26
27
|
} from "../types/common";
|
|
27
28
|
import { BaseField } from "../bdo/fields/BaseField";
|
|
28
29
|
|
|
@@ -124,32 +125,32 @@ export abstract class Activity<
|
|
|
124
125
|
|
|
125
126
|
/**
|
|
126
127
|
* List in-progress activity instances.
|
|
127
|
-
*
|
|
128
|
+
* Accepts optional filter/sort/pagination options.
|
|
128
129
|
*/
|
|
129
|
-
async getInProgressList(): Promise<ListResponseType<ActivityInstanceFieldsType & TEntity>> {
|
|
130
|
-
return this._ops().inProgressList();
|
|
130
|
+
async getInProgressList(options?: ListOptionsType): Promise<ListResponseType<ActivityInstanceFieldsType & TEntity>> {
|
|
131
|
+
return this._ops().inProgressList(options);
|
|
131
132
|
}
|
|
132
133
|
|
|
133
134
|
/**
|
|
134
135
|
* List completed activity instances.
|
|
135
|
-
*
|
|
136
|
+
* Accepts optional filter/sort/pagination options.
|
|
136
137
|
*/
|
|
137
|
-
async getCompletedList(): Promise<ListResponseType<ActivityInstanceFieldsType & TEntity>> {
|
|
138
|
-
return this._ops().completedList();
|
|
138
|
+
async getCompletedList(options?: ListOptionsType): Promise<ListResponseType<ActivityInstanceFieldsType & TEntity>> {
|
|
139
|
+
return this._ops().completedList(options);
|
|
139
140
|
}
|
|
140
141
|
|
|
141
142
|
/**
|
|
142
|
-
* Get
|
|
143
|
+
* Get count of in-progress activity instances.
|
|
143
144
|
*/
|
|
144
|
-
async inProgressMetrics(): Promise<
|
|
145
|
-
return this._ops().inProgressMetric();
|
|
145
|
+
async inProgressMetrics(options?: ListOptionsType): Promise<CountResponseType> {
|
|
146
|
+
return this._ops().inProgressMetric(options);
|
|
146
147
|
}
|
|
147
148
|
|
|
148
149
|
/**
|
|
149
|
-
* Get
|
|
150
|
+
* Get count of completed activity instances.
|
|
150
151
|
*/
|
|
151
|
-
async completedMetrics(): Promise<
|
|
152
|
-
return this._ops().completedMetric();
|
|
152
|
+
async completedMetrics(options?: ListOptionsType): Promise<CountResponseType> {
|
|
153
|
+
return this._ops().completedMetric(options);
|
|
153
154
|
}
|
|
154
155
|
|
|
155
156
|
/**
|
package/sdk/workflow/client.ts
CHANGED
|
@@ -8,7 +8,8 @@ import {
|
|
|
8
8
|
} from "../api/client";
|
|
9
9
|
import type {
|
|
10
10
|
ListResponseType,
|
|
11
|
-
|
|
11
|
+
ListOptionsType,
|
|
12
|
+
CountResponseType,
|
|
12
13
|
ReadResponseType,
|
|
13
14
|
DraftResponseType,
|
|
14
15
|
CreateUpdateResponseType,
|
|
@@ -108,8 +109,20 @@ export class Workflow<T = any> {
|
|
|
108
109
|
|
|
109
110
|
return {
|
|
110
111
|
// ── List-level ────────────────────────────────────────────
|
|
111
|
-
|
|
112
|
-
|
|
112
|
+
// TODO: Backend currently only supports GET for list/metric endpoints.
|
|
113
|
+
// Once backend is updated to accept POST with Filter/Sort/Page body,
|
|
114
|
+
// switch back to POST so useTable features (search, sort, pagination) work.
|
|
115
|
+
//
|
|
116
|
+
// POST version (waiting for backend):
|
|
117
|
+
// async inProgressList(options?: ListOptionsType) {
|
|
118
|
+
// return fetch(url + "/inprogress/list", {
|
|
119
|
+
// method: "POST", headers: getDefaultHeaders(),
|
|
120
|
+
// body: options ? JSON.stringify(options) : undefined,
|
|
121
|
+
// });
|
|
122
|
+
// }
|
|
123
|
+
// (same pattern for completedList, inProgressMetric, completedMetric)
|
|
124
|
+
|
|
125
|
+
async inProgressList(_options?: ListOptionsType): Promise<ListResponseType<ActivityInstanceFieldsType & T>> {
|
|
113
126
|
const response = await fetch(`${getApiBaseUrl()}${base}/inprogress/list`, {
|
|
114
127
|
method: "GET",
|
|
115
128
|
headers: getDefaultHeaders(),
|
|
@@ -122,7 +135,7 @@ export class Workflow<T = any> {
|
|
|
122
135
|
return response.json();
|
|
123
136
|
},
|
|
124
137
|
|
|
125
|
-
async completedList(): Promise<ListResponseType<ActivityInstanceFieldsType & T>> {
|
|
138
|
+
async completedList(_options?: ListOptionsType): Promise<ListResponseType<ActivityInstanceFieldsType & T>> {
|
|
126
139
|
const response = await fetch(`${getApiBaseUrl()}${base}/completed/list`, {
|
|
127
140
|
method: "GET",
|
|
128
141
|
headers: getDefaultHeaders(),
|
|
@@ -135,27 +148,27 @@ export class Workflow<T = any> {
|
|
|
135
148
|
return response.json();
|
|
136
149
|
},
|
|
137
150
|
|
|
138
|
-
async inProgressMetric(): Promise<
|
|
151
|
+
async inProgressMetric(_options?: ListOptionsType): Promise<CountResponseType> {
|
|
139
152
|
const response = await fetch(`${getApiBaseUrl()}${base}/inprogress/metric`, {
|
|
140
153
|
method: "GET",
|
|
141
154
|
headers: getDefaultHeaders(),
|
|
142
155
|
});
|
|
143
156
|
|
|
144
157
|
if (!response.ok) {
|
|
145
|
-
throw new Error(`Failed to get in-progress activity
|
|
158
|
+
throw new Error(`Failed to get in-progress activity count: ${response.statusText}`);
|
|
146
159
|
}
|
|
147
160
|
|
|
148
161
|
return response.json();
|
|
149
162
|
},
|
|
150
163
|
|
|
151
|
-
async completedMetric(): Promise<
|
|
164
|
+
async completedMetric(_options?: ListOptionsType): Promise<CountResponseType> {
|
|
152
165
|
const response = await fetch(`${getApiBaseUrl()}${base}/completed/metric`, {
|
|
153
166
|
method: "GET",
|
|
154
167
|
headers: getDefaultHeaders(),
|
|
155
168
|
});
|
|
156
169
|
|
|
157
170
|
if (!response.ok) {
|
|
158
|
-
throw new Error(`Failed to get completed activity
|
|
171
|
+
throw new Error(`Failed to get completed activity count: ${response.statusText}`);
|
|
159
172
|
}
|
|
160
173
|
|
|
161
174
|
return response.json();
|