@ram_28/kf-ai-sdk 1.0.21 → 1.0.23

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/docs/useTable.md CHANGED
@@ -16,71 +16,204 @@ import type {
16
16
 
17
17
  ## Type Definitions
18
18
 
19
- ```typescript
20
- // Column configuration
21
- interface ColumnDefinitionType<T> {
22
- fieldId: keyof T;
23
- label?: string;
24
- enableSorting?: boolean;
25
- enableFiltering?: boolean;
26
- transform?: (value: any, row: T) => React.ReactNode;
27
- }
28
-
29
- // Pagination state
30
- interface PaginationStateType {
31
- pageNo: number;
32
- pageSize: number;
33
- }
19
+ ### UseTableOptionsType
34
20
 
35
- // Hook options
21
+ ```typescript
22
+ // Hook options for initializing the table
36
23
  interface UseTableOptionsType<T> {
24
+ // Business Object ID (required)
25
+ // Example: "BDO_Product", "BDO_Order"
37
26
  source: string;
27
+
28
+ // Column configurations (required)
29
+ // Defines which fields to display and their behavior
38
30
  columns: ColumnDefinitionType<T>[];
31
+
32
+ // Initial state for the table (optional)
39
33
  initialState?: {
40
- sort?: Array<Record<string, "ASC" | "DESC">>;
41
- pagination?: PaginationStateType; // Defaults: { pageNo: 1, pageSize: 10 }
42
- filter?: UseFilterOptionsType<T>; // { conditions?, operator? }
34
+ // Initial sort configuration
35
+ // Format: [{ "fieldName": "ASC" }] or [{ "fieldName": "DESC" }]
36
+ sort?: SortType;
37
+
38
+ // Initial pagination
39
+ // Defaults: { pageNo: 1, pageSize: 10 }
40
+ pagination?: PaginationStateType;
41
+
42
+ // Initial filter conditions
43
+ // See useFilter docs for full options
44
+ filter?: UseFilterOptionsType<T>;
43
45
  };
46
+
47
+ // Called when data fetch fails
44
48
  onError?: (error: Error) => void;
49
+
50
+ // Called with fetched data after successful load
45
51
  onSuccess?: (data: T[]) => void;
46
52
  }
53
+ ```
54
+
55
+ ### ColumnDefinitionType
56
+
57
+ ```typescript
58
+ // Column configuration for table display
59
+ interface ColumnDefinitionType<T> {
60
+ // Field name from the data type (required)
61
+ fieldId: keyof T;
62
+
63
+ // Display label for column header
64
+ // Defaults to fieldId if not provided
65
+ label?: string;
66
+
67
+ // Enable sorting for this column
68
+ // When true, column header is clickable to toggle sort
69
+ enableSorting?: boolean;
47
70
 
48
- // Hook return type
71
+ // Enable filtering for this column
72
+ // When true, column can be used in filter conditions
73
+ enableFiltering?: boolean;
74
+
75
+ // Custom value transformer for display
76
+ // Receives raw value and full row, returns rendered content
77
+ transform?: (value: any, row: T) => React.ReactNode;
78
+ }
79
+ ```
80
+
81
+ ### UseTableReturnType
82
+
83
+ ```typescript
84
+ // Hook return type with all table state and methods
49
85
  interface UseTableReturnType<T> {
86
+ // ============================================================
87
+ // DATA
88
+ // ============================================================
89
+
90
+ // Current page data (array of records)
50
91
  rows: T[];
92
+
93
+ // Total matching records across all pages
51
94
  totalItems: number;
95
+
96
+ // ============================================================
97
+ // LOADING STATES
98
+ // ============================================================
99
+
100
+ // True during initial load
52
101
  isLoading: boolean;
102
+
103
+ // True during background refetch
53
104
  isFetching: boolean;
105
+
106
+ // ============================================================
107
+ // ERROR HANDLING
108
+ // ============================================================
109
+
110
+ // Current error state, null when no error
54
111
  error: Error | null;
112
+
113
+ // ============================================================
114
+ // SEARCH (full-text search across all fields)
115
+ // ============================================================
116
+
55
117
  search: {
118
+ // Current search query string
56
119
  query: string;
120
+
121
+ // Update search query (300ms debounced internally)
57
122
  setQuery: (value: string) => void;
123
+
124
+ // Clear search and reset to empty string
58
125
  clear: () => void;
59
126
  };
127
+
128
+ // ============================================================
129
+ // SORT (single column sorting)
130
+ // ============================================================
131
+
60
132
  sort: {
133
+ // Currently sorted field, null if no sort active
61
134
  field: keyof T | null;
135
+
136
+ // Current sort direction, null if no sort active
62
137
  direction: "asc" | "desc" | null;
138
+
139
+ // Toggle sort on a field
140
+ // Cycles: none → asc → desc → none
63
141
  toggle: (field: keyof T) => void;
142
+
143
+ // Clear sorting (return to default order)
64
144
  clear: () => void;
145
+
146
+ // Set explicit sort field and direction
65
147
  set: (field: keyof T, direction: "asc" | "desc") => void;
66
148
  };
149
+
150
+ // ============================================================
151
+ // FILTER (see useFilter docs for full API)
152
+ // ============================================================
153
+
154
+ // Full useFilter return type
155
+ // Includes addCondition, removeCondition, clearAllConditions, etc.
67
156
  filter: UseFilterReturnType<T>;
157
+
158
+ // ============================================================
159
+ // PAGINATION (1-indexed pages)
160
+ // ============================================================
161
+
68
162
  pagination: {
163
+ // Current page number (1-indexed, starts at 1)
69
164
  pageNo: number;
165
+
166
+ // Number of items per page
70
167
  pageSize: number;
168
+
169
+ // Total number of pages
71
170
  totalPages: number;
171
+
172
+ // Total matching records (same as top-level totalItems)
72
173
  totalItems: number;
174
+
175
+ // True if there's a next page available
73
176
  canGoNext: boolean;
177
+
178
+ // True if there's a previous page available
74
179
  canGoPrevious: boolean;
180
+
181
+ // Navigate to next page
75
182
  goToNext: () => void;
183
+
184
+ // Navigate to previous page
76
185
  goToPrevious: () => void;
186
+
187
+ // Navigate to specific page number (1-indexed)
77
188
  goToPage: (page: number) => void;
189
+
190
+ // Change items per page (resets to page 1)
78
191
  setPageSize: (size: number) => void;
79
192
  };
193
+
194
+ // ============================================================
195
+ // OPERATIONS
196
+ // ============================================================
197
+
198
+ // Manually trigger data refetch
199
+ // Returns promise with the list response
80
200
  refetch: () => Promise<ListResponseType<T>>;
81
201
  }
82
202
  ```
83
203
 
204
+ ### PaginationStateType
205
+
206
+ ```typescript
207
+ // Pagination state for initial configuration
208
+ interface PaginationStateType {
209
+ // Page number (1-indexed)
210
+ pageNo: number;
211
+
212
+ // Number of items per page
213
+ pageSize: number;
214
+ }
215
+ ```
216
+
84
217
  ## Basic Example
85
218
 
86
219
  A minimal table displaying data with loading and error states.
@@ -881,3 +1014,4 @@ function ProductListPage() {
881
1014
  );
882
1015
  }
883
1016
  ```
1017
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ram_28/kf-ai-sdk",
3
- "version": "1.0.21",
3
+ "version": "1.0.23",
4
4
  "description": "Type-safe, AI-driven SDK for building modern web applications with role-based access control",
5
5
  "author": "Ramprasad",
6
6
  "license": "MIT",
@@ -138,8 +138,8 @@ export function initiateLogin(
138
138
  });
139
139
  }
140
140
 
141
- window.location.href = loginUrl.toString();
142
- // Promise never resolves - browser navigates away
141
+ window.open(loginUrl.toString(), '_blank');
142
+ // Promise never resolves - login opens in new tab
143
143
  });
144
144
  }
145
145
 
@@ -304,6 +304,15 @@ export interface UseFormOptionsType<
304
304
  * @default "interactive"
305
305
  */
306
306
  interactionMode?: InteractionModeType;
307
+
308
+ /**
309
+ * Enable draft API calls in update mode
310
+ * When false (default), no draft API calls (e.g., /instance_id/draft) are made during
311
+ * field blur in update mode. The update API is only called on form submission.
312
+ * When true, draft API calls are made on blur for computed field dependencies.
313
+ * @default false
314
+ */
315
+ enableDraftInUpdateMode?: boolean;
307
316
  }
308
317
 
309
318
  // ============================================================
@@ -527,15 +536,12 @@ export interface UseFormReturnType<
527
536
  // LOADING STATES
528
537
  // ============================================================
529
538
 
530
- /** Loading initial schema/data */
531
- isLoadingInitialData: boolean;
532
-
533
- /** Loading record data for update */
534
- isLoadingRecord: boolean;
535
-
536
- /** Any loading state active */
539
+ /** True during initial load */
537
540
  isLoading: boolean;
538
541
 
542
+ /** True during background operations */
543
+ isFetching: boolean;
544
+
539
545
  // ============================================================
540
546
  // INTERACTIVE MODE STATE
541
547
  // ============================================================
@@ -54,6 +54,7 @@ export function useForm<T extends Record<string, any> = Record<string, any>>(
54
54
  skipSchemaFetch = false,
55
55
  schema: manualSchema,
56
56
  interactionMode = "interactive",
57
+ enableDraftInUpdateMode = false,
57
58
  } = options;
58
59
 
59
60
  // Derived interaction mode flags
@@ -346,10 +347,15 @@ export function useForm<T extends Record<string, any> = Record<string, any>>(
346
347
  return;
347
348
  }
348
349
 
349
- // Determine if draft should be triggered based on interaction mode
350
- // For update mode, always behave as non-interactive (only trigger for computed deps)
350
+ // Determine if draft should be triggered based on interaction mode and configuration
351
+ // For update mode: skip draft API calls unless explicitly enabled via enableDraftInUpdateMode
351
352
  // Interactive mode (create only): Always trigger draft API on blur
352
353
  // Non-interactive mode: Only trigger for computed field dependencies
354
+ if (operation === "update" && !enableDraftInUpdateMode) {
355
+ // Skip draft API calls in update mode when enableDraftInUpdateMode is false (default)
356
+ return;
357
+ }
358
+
353
359
  const shouldTrigger =
354
360
  isInteractiveMode && operation !== "update"
355
361
  ? true // Interactive mode (create only): always trigger
@@ -533,6 +539,7 @@ export function useForm<T extends Record<string, any> = Record<string, any>>(
533
539
  computedFieldDependencies,
534
540
  isInteractiveMode,
535
541
  draftId,
542
+ enableDraftInUpdateMode,
536
543
  ],
537
544
  );
538
545
 
@@ -808,11 +815,13 @@ export function useForm<T extends Record<string, any> = Record<string, any>>(
808
815
  // ============================================================
809
816
 
810
817
  // Loading state includes interactive mode draft creation
811
- const isLoadingInitialData =
818
+ const isLoading =
812
819
  isLoadingSchema ||
813
820
  (operation === "update" && isLoadingRecord) ||
814
821
  (isInteractiveMode && operation === "create" && isCreatingDraft);
815
- const isLoading = isLoadingInitialData || isSubmitting;
822
+
823
+ // Background operations (submission)
824
+ const isFetching = isSubmitting;
816
825
  const loadError = schemaError || recordError || draftError;
817
826
  const hasError = !!loadError;
818
827
 
@@ -967,9 +976,8 @@ export function useForm<T extends Record<string, any> = Record<string, any>>(
967
976
  isSubmitSuccessful: rhfForm.formState.isSubmitSuccessful,
968
977
 
969
978
  // Loading states
970
- isLoadingInitialData,
971
- isLoadingRecord,
972
979
  isLoading,
980
+ isFetching,
973
981
 
974
982
  // Interactive mode state
975
983
  draftId,