@ram_28/kf-ai-sdk 1.0.7 → 1.0.9
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/dist/api/index.d.ts +1 -1
- package/dist/api/index.d.ts.map +1 -1
- package/dist/components/hooks/index.d.ts +2 -1
- package/dist/components/hooks/index.d.ts.map +1 -1
- package/dist/components/hooks/useFilter/index.d.ts +3 -3
- package/dist/components/hooks/useFilter/index.d.ts.map +1 -1
- package/dist/components/hooks/useFilter/types.d.ts +83 -109
- package/dist/components/hooks/useFilter/types.d.ts.map +1 -1
- package/dist/components/hooks/useFilter/useFilter.d.ts +1 -1
- package/dist/components/hooks/useFilter/useFilter.d.ts.map +1 -1
- package/dist/components/hooks/useForm/apiClient.d.ts +4 -4
- package/dist/components/hooks/useForm/apiClient.d.ts.map +1 -1
- package/dist/components/hooks/useForm/expressionValidator.utils.d.ts +3 -3
- package/dist/components/hooks/useForm/expressionValidator.utils.d.ts.map +1 -1
- package/dist/components/hooks/useForm/index.d.ts +7 -4
- package/dist/components/hooks/useForm/index.d.ts.map +1 -1
- package/dist/components/hooks/useForm/optimizedExpressionValidator.utils.d.ts +5 -5
- package/dist/components/hooks/useForm/optimizedExpressionValidator.utils.d.ts.map +1 -1
- package/dist/components/hooks/useForm/ruleClassifier.utils.d.ts +7 -6
- package/dist/components/hooks/useForm/ruleClassifier.utils.d.ts.map +1 -1
- package/dist/components/hooks/useForm/schemaParser.utils.d.ts +8 -8
- package/dist/components/hooks/useForm/schemaParser.utils.d.ts.map +1 -1
- package/dist/components/hooks/useForm/types.d.ts +86 -93
- package/dist/components/hooks/useForm/types.d.ts.map +1 -1
- package/dist/components/hooks/useKanban/index.d.ts +1 -1
- package/dist/components/hooks/useKanban/index.d.ts.map +1 -1
- package/dist/components/hooks/useKanban/types.d.ts +6 -46
- package/dist/components/hooks/useKanban/types.d.ts.map +1 -1
- package/dist/components/hooks/useKanban/useKanban.d.ts.map +1 -1
- package/dist/components/hooks/useTable/types.d.ts +5 -33
- package/dist/components/hooks/useTable/types.d.ts.map +1 -1
- package/dist/components/hooks/useTable/useTable.d.ts +0 -5
- package/dist/components/hooks/useTable/useTable.d.ts.map +1 -1
- package/dist/index.cjs +13 -13
- package/dist/index.mjs +1990 -2234
- package/dist/types/common.d.ts +35 -26
- package/dist/types/common.d.ts.map +1 -1
- package/package.json +1 -1
- package/sdk/api/index.ts +7 -3
- package/sdk/components/hooks/index.ts +24 -4
- package/sdk/components/hooks/useFilter/index.ts +19 -18
- package/sdk/components/hooks/useFilter/types.ts +157 -123
- package/sdk/components/hooks/useFilter/useFilter.ts +259 -393
- package/sdk/components/hooks/useForm/apiClient.ts +5 -5
- package/sdk/components/hooks/useForm/expressionValidator.utils.ts +11 -11
- package/sdk/components/hooks/useForm/index.ts +41 -45
- package/sdk/components/hooks/useForm/optimizedExpressionValidator.utils.ts +7 -7
- package/sdk/components/hooks/useForm/ruleClassifier.utils.ts +21 -20
- package/sdk/components/hooks/useForm/schemaParser.utils.ts +36 -41
- package/sdk/components/hooks/useForm/types.ts +107 -113
- package/sdk/components/hooks/useForm/useForm.ts +54 -54
- package/sdk/components/hooks/useKanban/index.ts +0 -1
- package/sdk/components/hooks/useKanban/types.ts +8 -66
- package/sdk/components/hooks/useKanban/useKanban.ts +14 -75
- package/sdk/components/hooks/useTable/types.ts +7 -60
- package/sdk/components/hooks/useTable/useTable.ts +13 -121
- package/sdk/types/common.ts +42 -26
- package/dist/components/hooks/useFilter/payloadBuilder.utils.d.ts +0 -33
- package/dist/components/hooks/useFilter/payloadBuilder.utils.d.ts.map +0 -1
- package/sdk/components/hooks/useFilter/payloadBuilder.utils.ts +0 -298
|
@@ -34,12 +34,11 @@ export function useKanban<T extends Record<string, any> = Record<string, any>>(
|
|
|
34
34
|
onCardUpdate,
|
|
35
35
|
onCardDelete,
|
|
36
36
|
onError,
|
|
37
|
-
onFilterError,
|
|
38
37
|
} = options;
|
|
39
38
|
|
|
40
39
|
// Use source or cardSource (backwards compatibility)
|
|
41
40
|
const dataSource = source || cardSource;
|
|
42
|
-
|
|
41
|
+
|
|
43
42
|
if (!dataSource) {
|
|
44
43
|
throw new Error('useKanban requires either "source" or "cardSource" parameter');
|
|
45
44
|
}
|
|
@@ -89,11 +88,9 @@ export function useKanban<T extends Record<string, any> = Record<string, any>>(
|
|
|
89
88
|
// FILTER INTEGRATION
|
|
90
89
|
// ============================================================
|
|
91
90
|
|
|
92
|
-
const
|
|
91
|
+
const filter = useFilter({
|
|
93
92
|
initialConditions: initialState?.filters,
|
|
94
|
-
|
|
95
|
-
validateOnChange: true,
|
|
96
|
-
onValidationError: onFilterError,
|
|
93
|
+
initialOperator: initialState?.filterOperator || "And",
|
|
97
94
|
});
|
|
98
95
|
|
|
99
96
|
// Helper to generate API options for a specific column
|
|
@@ -107,7 +104,7 @@ export function useKanban<T extends Record<string, any> = Record<string, any>>(
|
|
|
107
104
|
RHSType: "Constant"
|
|
108
105
|
};
|
|
109
106
|
|
|
110
|
-
const basePayload =
|
|
107
|
+
const basePayload = filter.payload;
|
|
111
108
|
let combinedPayload: any;
|
|
112
109
|
|
|
113
110
|
if (!basePayload) {
|
|
@@ -154,9 +151,9 @@ export function useKanban<T extends Record<string, any> = Record<string, any>>(
|
|
|
154
151
|
if (search.query) {
|
|
155
152
|
opts.Search = search.query;
|
|
156
153
|
}
|
|
157
|
-
|
|
154
|
+
|
|
158
155
|
return opts;
|
|
159
|
-
}, [
|
|
156
|
+
}, [filter.payload, columnPagination, sorting, search.query]);
|
|
160
157
|
|
|
161
158
|
// ============================================================
|
|
162
159
|
// COLUMN QUERY GENERATION
|
|
@@ -188,21 +185,13 @@ export function useKanban<T extends Record<string, any> = Record<string, any>>(
|
|
|
188
185
|
await Promise.all(columnQueries.map(q => q.refetch()));
|
|
189
186
|
};
|
|
190
187
|
|
|
191
|
-
// Get total card count (Global count, or sum of columns? Usually global might differ if filters applied)
|
|
192
|
-
// For simplicity, we can fetch global count but restricted by filters?
|
|
193
|
-
// Actually, standard Kanban usually doesn't show "Total Cards" unless it's per column.
|
|
194
|
-
// We will keep the global count query for now but it might be slightly inaccurate if we want "Total Visible".
|
|
195
|
-
// Let's rely on summing up column counts for "Total Visible" and keep this for "Total Database"?
|
|
196
|
-
// Or just query with base filters?
|
|
197
|
-
// Let's keep existing logic but apply ONLY base filters + search.
|
|
198
|
-
|
|
199
188
|
const cardApiOptions = useMemo((): ListOptions => {
|
|
200
189
|
// This is for the GLOBAL count (ignoring column split)
|
|
201
190
|
const opts: ListOptions = {};
|
|
202
191
|
if (search.query) opts.Search = search.query;
|
|
203
|
-
if (
|
|
192
|
+
if (filter.payload) opts.Filter = filter.payload;
|
|
204
193
|
return opts;
|
|
205
|
-
}, [search.query,
|
|
194
|
+
}, [search.query, filter.payload]);
|
|
206
195
|
|
|
207
196
|
const {
|
|
208
197
|
data: countData,
|
|
@@ -230,11 +219,6 @@ export function useKanban<T extends Record<string, any> = Record<string, any>>(
|
|
|
230
219
|
|
|
231
220
|
const createCardMutation = useMutation({
|
|
232
221
|
mutationFn: async (card: Partial<KanbanCard<T>> & { columnId: string }) => {
|
|
233
|
-
// We need to fetch the current count or max position to append correclty if not provided
|
|
234
|
-
// Simplification: just send position=999999 or let backend handle it?
|
|
235
|
-
// Since we want optimistic UI, we should calculate it.
|
|
236
|
-
// But calculating it from partial data (paginated) is risky.
|
|
237
|
-
// Let's rely on backend or default to top/bottom logic.
|
|
238
222
|
const position = card.position ?? 999999;
|
|
239
223
|
const response = await api<KanbanCard<T>>(dataSource).create({ ...card, position });
|
|
240
224
|
return response._id;
|
|
@@ -249,7 +233,6 @@ export function useKanban<T extends Record<string, any> = Record<string, any>>(
|
|
|
249
233
|
const previousCards = queryClient.getQueryData<ListResponse<KanbanCard<T>>>(queryKey);
|
|
250
234
|
|
|
251
235
|
if (previousCards) {
|
|
252
|
-
// Determine position
|
|
253
236
|
const currentCards = previousCards.Data;
|
|
254
237
|
const position = newCardVariables.position ?? currentCards.length;
|
|
255
238
|
|
|
@@ -271,7 +254,6 @@ export function useKanban<T extends Record<string, any> = Record<string, any>>(
|
|
|
271
254
|
return { previousCards, queryKey };
|
|
272
255
|
},
|
|
273
256
|
onSuccess: async (cardId, _variables, context) => {
|
|
274
|
-
// Refetch the specific column
|
|
275
257
|
if (context?.queryKey) {
|
|
276
258
|
await queryClient.invalidateQueries({ queryKey: context.queryKey });
|
|
277
259
|
}
|
|
@@ -299,22 +281,10 @@ export function useKanban<T extends Record<string, any> = Record<string, any>>(
|
|
|
299
281
|
return { id, updates };
|
|
300
282
|
},
|
|
301
283
|
onMutate: async () => {
|
|
302
|
-
// We don't know the columnId easily without passing it.
|
|
303
|
-
// We can try to finding it in all column queries
|
|
304
|
-
// For now, simpler to just invalidate everything on success/error
|
|
305
|
-
// OR pass columnId in updates if available.
|
|
306
|
-
// If we want optimistic updates, we need to iterate all queries.
|
|
307
|
-
|
|
308
|
-
// Strategy: Invalidate all columns. Optimistic update is hard without knowing columnId.
|
|
309
|
-
// If the user passes columnId in updates, we can optimize.
|
|
310
|
-
|
|
311
284
|
await queryClient.cancelQueries({ queryKey: ["kanban-cards", dataSource] });
|
|
312
285
|
return {};
|
|
313
286
|
},
|
|
314
287
|
onSuccess: async (result) => {
|
|
315
|
-
// Find the card to trigger callback
|
|
316
|
-
// Since we don't have a single list, this is harder.
|
|
317
|
-
// We can skip finding it for now or iterate queries.
|
|
318
288
|
onCardUpdateRef.current?.({ _id: result.id, ...result.updates } as any);
|
|
319
289
|
},
|
|
320
290
|
onError: (error, _variables, _context) => {
|
|
@@ -332,8 +302,6 @@ export function useKanban<T extends Record<string, any> = Record<string, any>>(
|
|
|
332
302
|
},
|
|
333
303
|
onMutate: async () => {
|
|
334
304
|
await queryClient.cancelQueries({ queryKey: ["kanban-cards", dataSource] });
|
|
335
|
-
// Optimistic delete: Iterate all column queries and remove?
|
|
336
|
-
// For now, simple invalidation
|
|
337
305
|
return {};
|
|
338
306
|
},
|
|
339
307
|
onSuccess: async (id) => {
|
|
@@ -354,7 +322,6 @@ export function useKanban<T extends Record<string, any> = Record<string, any>>(
|
|
|
354
322
|
return { cardId, fromColumnId, toColumnId, position };
|
|
355
323
|
},
|
|
356
324
|
onMutate: async ({ cardId, fromColumnId, toColumnId, position }) => {
|
|
357
|
-
// Cancel queries for only the affected columns
|
|
358
325
|
const fromOpts = getColumnApiOptions(fromColumnId);
|
|
359
326
|
const toOpts = getColumnApiOptions(toColumnId);
|
|
360
327
|
const fromQueryKey = ["kanban-cards", dataSource, fromColumnId, fromOpts];
|
|
@@ -363,23 +330,18 @@ export function useKanban<T extends Record<string, any> = Record<string, any>>(
|
|
|
363
330
|
await queryClient.cancelQueries({ queryKey: fromQueryKey });
|
|
364
331
|
await queryClient.cancelQueries({ queryKey: toQueryKey });
|
|
365
332
|
|
|
366
|
-
// Get current data for both columns
|
|
367
333
|
const previousFromData = queryClient.getQueryData<ListResponse<KanbanCard<T>>>(fromQueryKey);
|
|
368
334
|
const previousToData = queryClient.getQueryData<ListResponse<KanbanCard<T>>>(toQueryKey);
|
|
369
335
|
|
|
370
|
-
// Optimistic update: move card between columns
|
|
371
336
|
if (previousFromData && previousToData) {
|
|
372
|
-
// Find the card in the source column
|
|
373
337
|
const cardToMove = previousFromData.Data.find(c => c._id === cardId);
|
|
374
338
|
|
|
375
339
|
if (cardToMove) {
|
|
376
|
-
// Remove card from source column
|
|
377
340
|
const newFromData = {
|
|
378
341
|
...previousFromData,
|
|
379
342
|
Data: previousFromData.Data.filter(c => c._id !== cardId)
|
|
380
343
|
};
|
|
381
344
|
|
|
382
|
-
// Add card to target column with updated columnId
|
|
383
345
|
const movedCard = {
|
|
384
346
|
...cardToMove,
|
|
385
347
|
columnId: toColumnId,
|
|
@@ -392,7 +354,6 @@ export function useKanban<T extends Record<string, any> = Record<string, any>>(
|
|
|
392
354
|
Data: [...previousToData.Data, movedCard].sort((a, b) => a.position - b.position)
|
|
393
355
|
};
|
|
394
356
|
|
|
395
|
-
// Update cache optimistically
|
|
396
357
|
queryClient.setQueryData(fromQueryKey, newFromData);
|
|
397
358
|
queryClient.setQueryData(toQueryKey, newToData);
|
|
398
359
|
}
|
|
@@ -415,7 +376,6 @@ export function useKanban<T extends Record<string, any> = Record<string, any>>(
|
|
|
415
376
|
);
|
|
416
377
|
},
|
|
417
378
|
onError: (error, _variables, context) => {
|
|
418
|
-
// Rollback optimistic update on error
|
|
419
379
|
if (context?.previousFromData && context?.fromQueryKey) {
|
|
420
380
|
queryClient.setQueryData(context.fromQueryKey, context.previousFromData);
|
|
421
381
|
}
|
|
@@ -425,7 +385,6 @@ export function useKanban<T extends Record<string, any> = Record<string, any>>(
|
|
|
425
385
|
onErrorRef.current?.(error as Error);
|
|
426
386
|
},
|
|
427
387
|
onSettled: (_data, _error, variables) => {
|
|
428
|
-
// Invalidate queries to ensure sync with server
|
|
429
388
|
const fromOpts = getColumnApiOptions(variables.fromColumnId);
|
|
430
389
|
const toOpts = getColumnApiOptions(variables.toColumnId);
|
|
431
390
|
queryClient.invalidateQueries({ queryKey: ["kanban-cards", dataSource, variables.fromColumnId, fromOpts] });
|
|
@@ -443,15 +402,12 @@ export function useKanban<T extends Record<string, any> = Record<string, any>>(
|
|
|
443
402
|
);
|
|
444
403
|
},
|
|
445
404
|
onMutate: async ({ columnId }) => {
|
|
446
|
-
// Optimistic reorder restricted to single column
|
|
447
405
|
const opts = getColumnApiOptions(columnId);
|
|
448
406
|
const queryKey = ["kanban-cards", dataSource, columnId, opts];
|
|
449
407
|
await queryClient.cancelQueries({ queryKey });
|
|
450
|
-
// Can implement optimistic reorder here if we want to parse cardIds
|
|
451
|
-
// But simpler to just invalidate.
|
|
452
408
|
return {};
|
|
453
409
|
},
|
|
454
|
-
onSuccess: () => {},
|
|
410
|
+
onSuccess: () => {},
|
|
455
411
|
onError: (error, _variables, _context) => {
|
|
456
412
|
onErrorRef.current?.(error as Error);
|
|
457
413
|
},
|
|
@@ -472,7 +428,7 @@ export function useKanban<T extends Record<string, any> = Record<string, any>>(
|
|
|
472
428
|
cardId: card._id,
|
|
473
429
|
fromColumnId,
|
|
474
430
|
toColumnId,
|
|
475
|
-
position: undefined,
|
|
431
|
+
position: undefined,
|
|
476
432
|
});
|
|
477
433
|
} catch (error) {
|
|
478
434
|
// Error already handled in mutation onError
|
|
@@ -482,11 +438,10 @@ export function useKanban<T extends Record<string, any> = Record<string, any>>(
|
|
|
482
438
|
);
|
|
483
439
|
|
|
484
440
|
// ============================================================
|
|
485
|
-
// COMPUTED VALUES
|
|
441
|
+
// COMPUTED VALUES
|
|
486
442
|
// ============================================================
|
|
487
443
|
|
|
488
444
|
const processedColumns = useMemo(() => {
|
|
489
|
-
// Map column configs to KanbanColumn structure using query results
|
|
490
445
|
return columnConfigs
|
|
491
446
|
.sort((a, b) => a.position - b.position)
|
|
492
447
|
.map((config, index) => {
|
|
@@ -500,7 +455,6 @@ export function useKanban<T extends Record<string, any> = Record<string, any>>(
|
|
|
500
455
|
color: config.color,
|
|
501
456
|
limit: config.limit,
|
|
502
457
|
cards: cards.sort((a, b) => a.position - b.position),
|
|
503
|
-
// We can expose loading/error state per column here if needed in the future
|
|
504
458
|
_created_at: new Date(),
|
|
505
459
|
_modified_at: new Date(),
|
|
506
460
|
};
|
|
@@ -530,9 +484,7 @@ export function useKanban<T extends Record<string, any> = Record<string, any>>(
|
|
|
530
484
|
"aria-grabbed": enableDragDrop && dragDropManager.draggedCard?._id === card._id,
|
|
531
485
|
onDragStart: (e: any) => {
|
|
532
486
|
if (!enableDragDrop) return;
|
|
533
|
-
// Abstracting the dataTransfer logic
|
|
534
487
|
e.dataTransfer.setData("text/plain", JSON.stringify(card));
|
|
535
|
-
// Use native event if available (ShadCN/Radix sometimes wraps events) or fallback to e
|
|
536
488
|
const nativeEvent = e.nativeEvent || e;
|
|
537
489
|
dragDropManager.handleDragStart(nativeEvent, card);
|
|
538
490
|
},
|
|
@@ -576,14 +528,6 @@ export function useKanban<T extends Record<string, any> = Record<string, any>>(
|
|
|
576
528
|
setSearch({ query: "" });
|
|
577
529
|
}, []);
|
|
578
530
|
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
// ============================================================
|
|
582
|
-
// PROP GETTERS
|
|
583
|
-
// ============================================================
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
531
|
const totalCards = countData?.Count || 0;
|
|
588
532
|
|
|
589
533
|
const isLoading = isLoadingCards || isLoadingCount;
|
|
@@ -656,9 +600,7 @@ export function useKanban<T extends Record<string, any> = Record<string, any>>(
|
|
|
656
600
|
),
|
|
657
601
|
moveCard: useCallback(
|
|
658
602
|
async (cardId: string, toColumnId: string, position?: number, fromColumnId?: string) => {
|
|
659
|
-
// If fromColumnId is not provided, we need to find it
|
|
660
603
|
if (!fromColumnId) {
|
|
661
|
-
// Find the card in the columns to get its current columnId
|
|
662
604
|
for (const column of processedColumns) {
|
|
663
605
|
const card = column.cards.find(c => c._id === cardId);
|
|
664
606
|
if (card) {
|
|
@@ -686,8 +628,8 @@ export function useKanban<T extends Record<string, any> = Record<string, any>>(
|
|
|
686
628
|
setSearchQuery,
|
|
687
629
|
clearSearch,
|
|
688
630
|
|
|
689
|
-
// Filter (
|
|
690
|
-
filter
|
|
631
|
+
// Filter (Simplified chainable API)
|
|
632
|
+
filter,
|
|
691
633
|
|
|
692
634
|
// Drag Drop (Flat Access)
|
|
693
635
|
isDragging: enableDragDrop ? dragDropManager.isDragging : false,
|
|
@@ -700,13 +642,10 @@ export function useKanban<T extends Record<string, any> = Record<string, any>>(
|
|
|
700
642
|
handleDrop: enableDragDrop ? dragDropManager.handleDrop : () => {},
|
|
701
643
|
handleDragEnd: enableDragDrop ? dragDropManager.handleDragEnd : () => {},
|
|
702
644
|
handleKeyDown: enableDragDrop ? dragDropManager.handleKeyDown : () => {},
|
|
703
|
-
|
|
704
|
-
// Prop Getters
|
|
645
|
+
|
|
705
646
|
// Prop Getters
|
|
706
647
|
getCardProps: enableDragDrop ? getCardProps : (_card: any) => ({} as any),
|
|
707
648
|
getColumnProps: enableDragDrop ? getColumnProps : (_columnId: string) => ({} as any),
|
|
708
|
-
|
|
709
|
-
|
|
710
649
|
|
|
711
650
|
// Load More (Per Column)
|
|
712
651
|
loadMore: useCallback((columnId: string) => {
|
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
import type { ListResponse,
|
|
2
|
-
import type {
|
|
3
|
-
FilterConditionWithId,
|
|
4
|
-
TypedFilterConditionInput,
|
|
5
|
-
ValidationError,
|
|
6
|
-
} from "../useFilter";
|
|
1
|
+
import type { ListResponse, ConditionGroupOperator } from "../../../types/common";
|
|
2
|
+
import type { Condition, ConditionGroup, UseFilterReturn } from "../useFilter";
|
|
7
3
|
|
|
8
4
|
// ============================================================
|
|
9
5
|
// TYPE DEFINITIONS
|
|
@@ -36,23 +32,20 @@ export interface UseTableOptions<T> {
|
|
|
36
32
|
/** Initial state */
|
|
37
33
|
initialState?: {
|
|
38
34
|
pagination?: {
|
|
39
|
-
pageNo: number;
|
|
35
|
+
pageNo: number;
|
|
40
36
|
pageSize: number;
|
|
41
37
|
};
|
|
42
38
|
sorting?: {
|
|
43
39
|
field: keyof T;
|
|
44
40
|
direction: "asc" | "desc";
|
|
45
41
|
};
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
filterOperator?: LogicalOperator;
|
|
42
|
+
filters?: Array<Condition | ConditionGroup>;
|
|
43
|
+
filterOperator?: ConditionGroupOperator;
|
|
49
44
|
};
|
|
50
45
|
/** Error callback */
|
|
51
46
|
onError?: (error: Error) => void;
|
|
52
47
|
/** Success callback */
|
|
53
48
|
onSuccess?: (data: T[]) => void;
|
|
54
|
-
/** Filter error callback */
|
|
55
|
-
onFilterError?: (errors: ValidationError[]) => void;
|
|
56
49
|
}
|
|
57
50
|
|
|
58
51
|
export interface UseTableReturn<T> {
|
|
@@ -83,54 +76,8 @@ export interface UseTableReturn<T> {
|
|
|
83
76
|
set: (field: keyof T, direction: "asc" | "desc") => void;
|
|
84
77
|
};
|
|
85
78
|
|
|
86
|
-
//
|
|
87
|
-
|
|
88
|
-
value: string;
|
|
89
|
-
setValue: (value: string) => void;
|
|
90
|
-
clear: () => void;
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
// Advanced Filtering (Filter Conditions) - Type-safe: lhsField constrained to keyof T
|
|
94
|
-
filter: {
|
|
95
|
-
// State
|
|
96
|
-
conditions: FilterConditionWithId[];
|
|
97
|
-
logicalOperator: LogicalOperator;
|
|
98
|
-
isValid: boolean;
|
|
99
|
-
validationErrors: ValidationError[];
|
|
100
|
-
hasConditions: boolean;
|
|
101
|
-
|
|
102
|
-
// Condition Management (type-safe)
|
|
103
|
-
addCondition: (condition: TypedFilterConditionInput<T>) => string;
|
|
104
|
-
updateCondition: (
|
|
105
|
-
id: string,
|
|
106
|
-
updates: Partial<TypedFilterConditionInput<T>>
|
|
107
|
-
) => boolean;
|
|
108
|
-
removeCondition: (id: string) => boolean;
|
|
109
|
-
clearConditions: () => void;
|
|
110
|
-
getCondition: (id: string) => FilterConditionWithId | undefined;
|
|
111
|
-
|
|
112
|
-
// Logical Operator
|
|
113
|
-
setLogicalOperator: (operator: LogicalOperator) => void;
|
|
114
|
-
|
|
115
|
-
// Bulk Operations
|
|
116
|
-
setConditions: (conditions: FilterConditionWithId[]) => void;
|
|
117
|
-
replaceCondition: (
|
|
118
|
-
id: string,
|
|
119
|
-
newCondition: TypedFilterConditionInput<T>
|
|
120
|
-
) => boolean;
|
|
121
|
-
|
|
122
|
-
// Validation
|
|
123
|
-
validateCondition: (condition: Partial<FilterConditionWithId>) => any;
|
|
124
|
-
validateAllConditions: () => any;
|
|
125
|
-
|
|
126
|
-
// State Management
|
|
127
|
-
exportState: () => any;
|
|
128
|
-
importState: (state: any) => void;
|
|
129
|
-
resetToInitial: () => void;
|
|
130
|
-
|
|
131
|
-
// Utilities
|
|
132
|
-
getConditionCount: () => number;
|
|
133
|
-
};
|
|
79
|
+
// Filter (Simplified chainable API)
|
|
80
|
+
filter: UseFilterReturn;
|
|
134
81
|
|
|
135
82
|
// Pagination (Flat Access)
|
|
136
83
|
pagination: {
|
|
@@ -18,44 +18,11 @@ interface SortingState<T> {
|
|
|
18
18
|
direction: "asc" | "desc" | null;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
interface FilteringState {
|
|
22
|
-
global: string;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
21
|
interface PaginationState {
|
|
26
22
|
pageNo: number; // 1-indexed page number
|
|
27
23
|
pageSize: number;
|
|
28
24
|
}
|
|
29
25
|
|
|
30
|
-
// ============================================================
|
|
31
|
-
// FIELD TYPE DETECTION
|
|
32
|
-
// ============================================================
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Detect field type for auto-formatting
|
|
36
|
-
* This will be enhanced with actual type introspection in the future
|
|
37
|
-
* Currently unused but kept for future auto-formatting implementation
|
|
38
|
-
*/
|
|
39
|
-
// function _detectFieldType<T>(fieldId: keyof T): string {
|
|
40
|
-
// const fieldName = String(fieldId);
|
|
41
|
-
//
|
|
42
|
-
// // Basic pattern matching - will be replaced with actual type introspection
|
|
43
|
-
// if (fieldName.includes('price') || fieldName.includes('cost') || fieldName.includes('amount')) {
|
|
44
|
-
// return 'currency';
|
|
45
|
-
// }
|
|
46
|
-
// if (fieldName.includes('date') || fieldName.includes('At') || fieldName === 'created' || fieldName === 'updated') {
|
|
47
|
-
// return 'datetime';
|
|
48
|
-
// }
|
|
49
|
-
// if (fieldName.includes('stock') || fieldName.includes('quantity') || fieldName.includes('count')) {
|
|
50
|
-
// return 'number';
|
|
51
|
-
// }
|
|
52
|
-
// if (fieldName.includes('status') || fieldName.includes('type') || fieldName.includes('category')) {
|
|
53
|
-
// return 'string';
|
|
54
|
-
// }
|
|
55
|
-
//
|
|
56
|
-
// return 'string'; // default
|
|
57
|
-
// }
|
|
58
|
-
|
|
59
26
|
// ============================================================
|
|
60
27
|
// MAIN HOOK
|
|
61
28
|
// ============================================================
|
|
@@ -76,12 +43,8 @@ export function useTable<T = any>(
|
|
|
76
43
|
direction: options.initialState?.sorting?.direction || null,
|
|
77
44
|
});
|
|
78
45
|
|
|
79
|
-
const [filtering, setFiltering] = useState<FilteringState>({
|
|
80
|
-
global: options.initialState?.globalFilter || "",
|
|
81
|
-
});
|
|
82
|
-
|
|
83
46
|
const [pagination, setPagination] = useState<PaginationState>({
|
|
84
|
-
pageNo: options.initialState?.pagination?.pageNo || 1,
|
|
47
|
+
pageNo: options.initialState?.pagination?.pageNo || 1,
|
|
85
48
|
pageSize: options.initialState?.pagination?.pageSize || 10,
|
|
86
49
|
});
|
|
87
50
|
|
|
@@ -89,23 +52,9 @@ export function useTable<T = any>(
|
|
|
89
52
|
// FILTER HOOK INTEGRATION
|
|
90
53
|
// ============================================================
|
|
91
54
|
|
|
92
|
-
const
|
|
55
|
+
const filter = useFilter({
|
|
93
56
|
initialConditions: options.initialState?.filters,
|
|
94
|
-
|
|
95
|
-
validateOnChange: true,
|
|
96
|
-
onValidationError: options.onFilterError,
|
|
97
|
-
onConditionAdd: () => {
|
|
98
|
-
// Reset to first page when adding filters
|
|
99
|
-
setPagination((prev) => ({ ...prev, pageNo: 1 }));
|
|
100
|
-
},
|
|
101
|
-
onConditionUpdate: () => {
|
|
102
|
-
// Reset to first page when updating filters
|
|
103
|
-
setPagination((prev) => ({ ...prev, pageNo: 1 }));
|
|
104
|
-
},
|
|
105
|
-
onConditionRemove: () => {
|
|
106
|
-
// Reset to first page when removing filters
|
|
107
|
-
setPagination((prev) => ({ ...prev, pageNo: 1 }));
|
|
108
|
-
},
|
|
57
|
+
initialOperator: options.initialState?.filterOperator || "And",
|
|
109
58
|
});
|
|
110
59
|
|
|
111
60
|
// ============================================================
|
|
@@ -122,12 +71,12 @@ export function useTable<T = any>(
|
|
|
122
71
|
}
|
|
123
72
|
|
|
124
73
|
// Add filter conditions (affects count)
|
|
125
|
-
if (
|
|
126
|
-
opts.Filter =
|
|
74
|
+
if (filter.payload) {
|
|
75
|
+
opts.Filter = filter.payload;
|
|
127
76
|
}
|
|
128
77
|
|
|
129
78
|
return opts;
|
|
130
|
-
}, [search.query,
|
|
79
|
+
}, [search.query, filter.payload]);
|
|
131
80
|
|
|
132
81
|
// Options for list query - includes all options
|
|
133
82
|
const apiOptions = useMemo((): ListOptions => {
|
|
@@ -144,7 +93,7 @@ export function useTable<T = any>(
|
|
|
144
93
|
|
|
145
94
|
// Add pagination
|
|
146
95
|
if (options.enablePagination) {
|
|
147
|
-
opts.Page = pagination.pageNo;
|
|
96
|
+
opts.Page = pagination.pageNo;
|
|
148
97
|
opts.PageSize = pagination.pageSize;
|
|
149
98
|
}
|
|
150
99
|
|
|
@@ -181,7 +130,7 @@ export function useTable<T = any>(
|
|
|
181
130
|
gcTime: 0,
|
|
182
131
|
});
|
|
183
132
|
|
|
184
|
-
// Count query for accurate total items
|
|
133
|
+
// Count query for accurate total items
|
|
185
134
|
const {
|
|
186
135
|
data: countData,
|
|
187
136
|
isLoading: isCountLoading,
|
|
@@ -222,14 +171,12 @@ export function useTable<T = any>(
|
|
|
222
171
|
const toggleSort = useCallback((field: keyof T) => {
|
|
223
172
|
setSorting((prev) => {
|
|
224
173
|
if (prev.field === field) {
|
|
225
|
-
// Same field - toggle direction or clear
|
|
226
174
|
if (prev.direction === "asc") {
|
|
227
175
|
return { field, direction: "desc" };
|
|
228
176
|
} else if (prev.direction === "desc") {
|
|
229
177
|
return { field: null, direction: null };
|
|
230
178
|
}
|
|
231
179
|
}
|
|
232
|
-
// New field or no current sort
|
|
233
180
|
return { field, direction: "asc" };
|
|
234
181
|
});
|
|
235
182
|
}, []);
|
|
@@ -251,7 +198,6 @@ export function useTable<T = any>(
|
|
|
251
198
|
|
|
252
199
|
const setSearchQuery = useCallback((value: string) => {
|
|
253
200
|
setSearch({ query: value });
|
|
254
|
-
// Reset to first page when searching
|
|
255
201
|
setPagination((prev) => ({ ...prev, pageNo: 1 }));
|
|
256
202
|
}, []);
|
|
257
203
|
|
|
@@ -259,20 +205,6 @@ export function useTable<T = any>(
|
|
|
259
205
|
setSearch({ query: "" });
|
|
260
206
|
}, []);
|
|
261
207
|
|
|
262
|
-
// ============================================================
|
|
263
|
-
// FILTERING OPERATIONS
|
|
264
|
-
// ============================================================
|
|
265
|
-
|
|
266
|
-
const setGlobalFilter = useCallback((value: string) => {
|
|
267
|
-
setFiltering((prev) => ({ ...prev, global: value }));
|
|
268
|
-
// Reset to first page when filtering
|
|
269
|
-
setPagination((prev) => ({ ...prev, pageNo: 1 }));
|
|
270
|
-
}, []);
|
|
271
|
-
|
|
272
|
-
const clearFilter = useCallback(() => {
|
|
273
|
-
setFiltering({ global: "" });
|
|
274
|
-
}, []);
|
|
275
|
-
|
|
276
208
|
// ============================================================
|
|
277
209
|
// PAGINATION OPERATIONS
|
|
278
210
|
// ============================================================
|
|
@@ -294,7 +226,7 @@ export function useTable<T = any>(
|
|
|
294
226
|
|
|
295
227
|
const goToPage = useCallback(
|
|
296
228
|
(page: number) => {
|
|
297
|
-
const pageNo = Math.max(1, Math.min(page, totalPages));
|
|
229
|
+
const pageNo = Math.max(1, Math.min(page, totalPages));
|
|
298
230
|
setPagination((prev) => ({ ...prev, pageNo }));
|
|
299
231
|
},
|
|
300
232
|
[totalPages]
|
|
@@ -304,7 +236,7 @@ export function useTable<T = any>(
|
|
|
304
236
|
setPagination((prev) => ({
|
|
305
237
|
...prev,
|
|
306
238
|
pageSize: size,
|
|
307
|
-
pageNo: 1,
|
|
239
|
+
pageNo: 1,
|
|
308
240
|
}));
|
|
309
241
|
}, []);
|
|
310
242
|
|
|
@@ -349,52 +281,12 @@ export function useTable<T = any>(
|
|
|
349
281
|
set: setSort,
|
|
350
282
|
},
|
|
351
283
|
|
|
352
|
-
//
|
|
353
|
-
|
|
354
|
-
value: filtering.global,
|
|
355
|
-
setValue: setGlobalFilter,
|
|
356
|
-
clear: clearFilter,
|
|
357
|
-
},
|
|
358
|
-
|
|
359
|
-
// Advanced Filtering (Filter Conditions)
|
|
360
|
-
filter: {
|
|
361
|
-
// State
|
|
362
|
-
conditions: filterHook.conditions,
|
|
363
|
-
logicalOperator: filterHook.logicalOperator,
|
|
364
|
-
isValid: filterHook.isValid,
|
|
365
|
-
validationErrors: filterHook.validationErrors,
|
|
366
|
-
hasConditions: filterHook.hasConditions,
|
|
367
|
-
|
|
368
|
-
// Condition Management
|
|
369
|
-
addCondition: filterHook.addCondition,
|
|
370
|
-
updateCondition: filterHook.updateCondition,
|
|
371
|
-
removeCondition: filterHook.removeCondition,
|
|
372
|
-
clearConditions: filterHook.clearConditions,
|
|
373
|
-
getCondition: filterHook.getCondition,
|
|
374
|
-
|
|
375
|
-
// Logical Operator
|
|
376
|
-
setLogicalOperator: filterHook.setLogicalOperator,
|
|
377
|
-
|
|
378
|
-
// Bulk Operations
|
|
379
|
-
setConditions: filterHook.setConditions,
|
|
380
|
-
replaceCondition: filterHook.replaceCondition,
|
|
381
|
-
|
|
382
|
-
// Validation
|
|
383
|
-
validateCondition: filterHook.validateCondition,
|
|
384
|
-
validateAllConditions: filterHook.validateAllConditions,
|
|
385
|
-
|
|
386
|
-
// State Management
|
|
387
|
-
exportState: filterHook.exportState,
|
|
388
|
-
importState: filterHook.importState,
|
|
389
|
-
resetToInitial: filterHook.resetToInitial,
|
|
390
|
-
|
|
391
|
-
// Utilities
|
|
392
|
-
getConditionCount: filterHook.getConditionCount,
|
|
393
|
-
},
|
|
284
|
+
// Filter (Simplified chainable API)
|
|
285
|
+
filter,
|
|
394
286
|
|
|
395
287
|
// Pagination (Flat Access)
|
|
396
288
|
pagination: {
|
|
397
|
-
currentPage: pagination.pageNo,
|
|
289
|
+
currentPage: pagination.pageNo,
|
|
398
290
|
pageSize: pagination.pageSize,
|
|
399
291
|
totalPages,
|
|
400
292
|
totalItems,
|