@pagamio/frontend-commons-lib 0.8.213 → 0.8.214

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/lib/api/TanstackQueryProvider.d.ts +146 -0
  2. package/lib/api/TanstackQueryProvider.js +140 -0
  3. package/lib/api/index.d.ts +2 -0
  4. package/lib/api/index.js +2 -0
  5. package/lib/api/tanstackQuery.d.ts +249 -0
  6. package/lib/api/tanstackQuery.js +299 -0
  7. package/lib/components/layout/Sidebar.js +47 -24
  8. package/lib/components/ui/Sheet.d.ts +1 -1
  9. package/lib/context/SidebarContext.d.ts +10 -0
  10. package/lib/dashboard-visuals-v2/DashboardWrapperV2.d.ts +81 -0
  11. package/lib/dashboard-visuals-v2/DashboardWrapperV2.js +217 -0
  12. package/lib/dashboard-visuals-v2/cards/CardGrid.d.ts +22 -0
  13. package/lib/dashboard-visuals-v2/cards/CardGrid.js +27 -0
  14. package/lib/dashboard-visuals-v2/cards/InfoCard.d.ts +7 -0
  15. package/lib/dashboard-visuals-v2/cards/InfoCard.js +26 -0
  16. package/lib/dashboard-visuals-v2/cards/MetricCard.d.ts +7 -0
  17. package/lib/dashboard-visuals-v2/cards/MetricCard.js +37 -0
  18. package/lib/dashboard-visuals-v2/cards/StatCard.d.ts +7 -0
  19. package/lib/dashboard-visuals-v2/cards/StatCard.js +92 -0
  20. package/lib/dashboard-visuals-v2/cards/TopItemsCard.d.ts +7 -0
  21. package/lib/dashboard-visuals-v2/cards/TopItemsCard.js +34 -0
  22. package/lib/dashboard-visuals-v2/cards/TransactionListCard.d.ts +7 -0
  23. package/lib/dashboard-visuals-v2/cards/TransactionListCard.js +24 -0
  24. package/lib/dashboard-visuals-v2/cards/index.d.ts +9 -0
  25. package/lib/dashboard-visuals-v2/cards/index.js +9 -0
  26. package/lib/dashboard-visuals-v2/charts/AreaChart.d.ts +7 -0
  27. package/lib/dashboard-visuals-v2/charts/AreaChart.js +124 -0
  28. package/lib/dashboard-visuals-v2/charts/BarChart.d.ts +7 -0
  29. package/lib/dashboard-visuals-v2/charts/BarChart.js +106 -0
  30. package/lib/dashboard-visuals-v2/charts/BaseChart.d.ts +61 -0
  31. package/lib/dashboard-visuals-v2/charts/BaseChart.js +173 -0
  32. package/lib/dashboard-visuals-v2/charts/DonutChart.d.ts +7 -0
  33. package/lib/dashboard-visuals-v2/charts/DonutChart.js +108 -0
  34. package/lib/dashboard-visuals-v2/charts/HeatmapChart.d.ts +7 -0
  35. package/lib/dashboard-visuals-v2/charts/HeatmapChart.js +101 -0
  36. package/lib/dashboard-visuals-v2/charts/LineChart.d.ts +7 -0
  37. package/lib/dashboard-visuals-v2/charts/LineChart.js +109 -0
  38. package/lib/dashboard-visuals-v2/charts/MixedChart.d.ts +7 -0
  39. package/lib/dashboard-visuals-v2/charts/MixedChart.js +106 -0
  40. package/lib/dashboard-visuals-v2/charts/PieChart.d.ts +7 -0
  41. package/lib/dashboard-visuals-v2/charts/PieChart.js +10 -0
  42. package/lib/dashboard-visuals-v2/charts/RadialChart.d.ts +7 -0
  43. package/lib/dashboard-visuals-v2/charts/RadialChart.js +72 -0
  44. package/lib/dashboard-visuals-v2/charts/index.d.ts +12 -0
  45. package/lib/dashboard-visuals-v2/charts/index.js +12 -0
  46. package/lib/dashboard-visuals-v2/components/DataFetchingVisual.d.ts +0 -0
  47. package/lib/dashboard-visuals-v2/components/DataFetchingVisual.js +1 -0
  48. package/lib/dashboard-visuals-v2/components/index.d.ts +0 -0
  49. package/lib/dashboard-visuals-v2/components/index.js +1 -0
  50. package/lib/dashboard-visuals-v2/hooks/index.d.ts +4 -0
  51. package/lib/dashboard-visuals-v2/hooks/index.js +4 -0
  52. package/lib/dashboard-visuals-v2/hooks/useChartData.d.ts +72 -0
  53. package/lib/dashboard-visuals-v2/hooks/useChartData.js +122 -0
  54. package/lib/dashboard-visuals-v2/index.d.ts +10 -0
  55. package/lib/dashboard-visuals-v2/index.js +16 -0
  56. package/lib/dashboard-visuals-v2/types/card.types.d.ts +237 -0
  57. package/lib/dashboard-visuals-v2/types/card.types.js +30 -0
  58. package/lib/dashboard-visuals-v2/types/chart.types.d.ts +308 -0
  59. package/lib/dashboard-visuals-v2/types/chart.types.js +25 -0
  60. package/lib/dashboard-visuals-v2/types/index.d.ts +6 -0
  61. package/lib/dashboard-visuals-v2/types/index.js +6 -0
  62. package/lib/dashboard-visuals-v2/utils/index.d.ts +0 -0
  63. package/lib/dashboard-visuals-v2/utils/index.js +1 -0
  64. package/lib/dashboard-visuals-v2/utils/propsTransformer.d.ts +0 -0
  65. package/lib/dashboard-visuals-v2/utils/propsTransformer.js +1 -0
  66. package/lib/dashboard-visuals-v2/visualRegistry.d.ts +59 -0
  67. package/lib/dashboard-visuals-v2/visualRegistry.js +110 -0
  68. package/lib/data-table-v2/DataTable.d.ts +7 -0
  69. package/lib/data-table-v2/DataTable.js +206 -0
  70. package/lib/data-table-v2/components/DataTableBody.d.ts +19 -0
  71. package/lib/data-table-v2/components/DataTableBody.js +20 -0
  72. package/lib/data-table-v2/components/DataTableEmpty.d.ts +17 -0
  73. package/lib/data-table-v2/components/DataTableEmpty.js +13 -0
  74. package/lib/data-table-v2/components/DataTableError.d.ts +16 -0
  75. package/lib/data-table-v2/components/DataTableError.js +14 -0
  76. package/lib/data-table-v2/components/DataTableHeader.d.ts +15 -0
  77. package/lib/data-table-v2/components/DataTableHeader.js +31 -0
  78. package/lib/data-table-v2/components/DataTableLoading.d.ts +14 -0
  79. package/lib/data-table-v2/components/DataTableLoading.js +19 -0
  80. package/lib/data-table-v2/components/DataTablePagination.d.ts +36 -0
  81. package/lib/data-table-v2/components/DataTablePagination.js +20 -0
  82. package/lib/data-table-v2/components/DataTableRowActions.d.ts +13 -0
  83. package/lib/data-table-v2/components/DataTableRowActions.js +57 -0
  84. package/lib/data-table-v2/components/DataTableSearch.d.ts +19 -0
  85. package/lib/data-table-v2/components/DataTableSearch.js +33 -0
  86. package/lib/data-table-v2/components/DataTableToolbar.d.ts +54 -0
  87. package/lib/data-table-v2/components/DataTableToolbar.js +28 -0
  88. package/lib/data-table-v2/components/index.d.ts +12 -0
  89. package/lib/data-table-v2/components/index.js +12 -0
  90. package/lib/data-table-v2/hooks/index.d.ts +4 -0
  91. package/lib/data-table-v2/hooks/index.js +4 -0
  92. package/lib/data-table-v2/hooks/useTableData.d.ts +118 -0
  93. package/lib/data-table-v2/hooks/useTableData.js +210 -0
  94. package/lib/data-table-v2/index.d.ts +9 -0
  95. package/lib/data-table-v2/index.js +12 -0
  96. package/lib/data-table-v2/types/index.d.ts +296 -0
  97. package/lib/data-table-v2/types/index.js +1 -0
  98. package/lib/data-table-v2/utils/export.d.ts +26 -0
  99. package/lib/data-table-v2/utils/export.js +92 -0
  100. package/lib/data-table-v2/utils/index.d.ts +4 -0
  101. package/lib/data-table-v2/utils/index.js +4 -0
  102. package/lib/index.d.ts +4 -0
  103. package/lib/index.js +23 -0
  104. package/lib/styles.css +212 -0
  105. package/package.json +7 -1
@@ -0,0 +1,13 @@
1
+ import type { RowAction } from '../types';
2
+ interface DataTableRowActionsProps<TData> {
3
+ /** Row data */
4
+ row: TData;
5
+ /** Actions configuration */
6
+ actions: RowAction<TData>[];
7
+ }
8
+ /**
9
+ * DataTable Row Actions Component
10
+ * Dropdown menu for row-level actions
11
+ */
12
+ export declare function DataTableRowActions<TData>({ row, actions }: DataTableRowActionsProps<TData>): import("react/jsx-runtime").JSX.Element | null;
13
+ export default DataTableRowActions;
@@ -0,0 +1,57 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * @fileoverview DataTable Row Actions Component
4
+ */
5
+ import { MoreHorizontal } from 'lucide-react';
6
+ import { useEffect, useRef, useState } from 'react';
7
+ import { cn } from '../../helpers';
8
+ /**
9
+ * DataTable Row Actions Component
10
+ * Dropdown menu for row-level actions
11
+ */
12
+ export function DataTableRowActions({ row, actions }) {
13
+ const [isOpen, setIsOpen] = useState(false);
14
+ const menuRef = useRef(null);
15
+ // Close menu on outside click
16
+ useEffect(() => {
17
+ const handleClickOutside = (event) => {
18
+ if (menuRef.current && !menuRef.current.contains(event.target)) {
19
+ setIsOpen(false);
20
+ }
21
+ };
22
+ if (isOpen) {
23
+ document.addEventListener('mousedown', handleClickOutside);
24
+ }
25
+ return () => {
26
+ document.removeEventListener('mousedown', handleClickOutside);
27
+ };
28
+ }, [isOpen]);
29
+ // Filter visible actions
30
+ const visibleActions = actions.filter((action) => {
31
+ if (typeof action.hidden === 'function') {
32
+ return !action.hidden(row);
33
+ }
34
+ return !action.hidden;
35
+ });
36
+ if (visibleActions.length === 0) {
37
+ return null;
38
+ }
39
+ return (_jsxs("div", { className: "relative", ref: menuRef, children: [_jsx("button", { onClick: (e) => {
40
+ e.stopPropagation();
41
+ setIsOpen(!isOpen);
42
+ }, className: "p-1.5 rounded-md hover:bg-gray-100 transition-colors", children: _jsx(MoreHorizontal, { className: "w-4 h-4 text-gray-500" }) }), isOpen && (_jsx("div", { className: "absolute right-0 top-full mt-1 w-40 bg-white border border-gray-200 rounded-lg shadow-lg z-30", children: _jsx("div", { className: "py-1", children: visibleActions.map((action) => {
43
+ const isDisabled = typeof action.disabled === 'function' ? action.disabled(row) : action.disabled;
44
+ return (_jsxs("button", { onClick: (e) => {
45
+ e.stopPropagation();
46
+ if (!isDisabled) {
47
+ action.onClick(row);
48
+ setIsOpen(false);
49
+ }
50
+ }, disabled: isDisabled, className: cn('w-full flex items-center gap-2 px-3 py-2 text-sm text-left transition-colors', action.variant === 'danger'
51
+ ? 'text-red-600 hover:bg-red-50'
52
+ : action.variant === 'primary'
53
+ ? 'text-blue-600 hover:bg-blue-50'
54
+ : 'text-gray-700 hover:bg-gray-50', isDisabled && 'opacity-50 cursor-not-allowed hover:bg-transparent'), children: [action.icon && _jsx("span", { className: "w-4 h-4", children: action.icon }), action.label] }, action.id));
55
+ }) }) }))] }));
56
+ }
57
+ export default DataTableRowActions;
@@ -0,0 +1,19 @@
1
+ import type { DataTableClassNames } from '../types';
2
+ interface DataTableSearchProps {
3
+ /** Current global filter value */
4
+ value: string;
5
+ /** On change handler */
6
+ onChange: (value: string) => void;
7
+ /** Placeholder text */
8
+ placeholder?: string;
9
+ /** Debounce delay in ms */
10
+ debounceMs?: number;
11
+ /** Custom classNames */
12
+ classNames?: DataTableClassNames;
13
+ }
14
+ /**
15
+ * DataTable Search Component
16
+ * Global search/filter input with debounce
17
+ */
18
+ export declare function DataTableSearch({ value: externalValue, onChange, placeholder, debounceMs, classNames, }: DataTableSearchProps): import("react/jsx-runtime").JSX.Element;
19
+ export default DataTableSearch;
@@ -0,0 +1,33 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * @fileoverview DataTable Search/Filter Component
4
+ */
5
+ import { Search, X } from 'lucide-react';
6
+ import { useEffect, useState } from 'react';
7
+ import { cn } from '../../helpers';
8
+ /**
9
+ * DataTable Search Component
10
+ * Global search/filter input with debounce
11
+ */
12
+ export function DataTableSearch({ value: externalValue, onChange, placeholder = 'Search...', debounceMs = 300, classNames, }) {
13
+ const [value, setValue] = useState(externalValue);
14
+ // Sync external value
15
+ useEffect(() => {
16
+ setValue(externalValue);
17
+ }, [externalValue]);
18
+ // Debounced onChange
19
+ useEffect(() => {
20
+ const timer = setTimeout(() => {
21
+ if (value !== externalValue) {
22
+ onChange(value);
23
+ }
24
+ }, debounceMs);
25
+ return () => clearTimeout(timer);
26
+ }, [value, debounceMs, onChange, externalValue]);
27
+ const handleClear = () => {
28
+ setValue('');
29
+ onChange('');
30
+ };
31
+ return (_jsxs("div", { className: cn('relative', classNames?.search), children: [_jsx("div", { className: "absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none", children: _jsx(Search, { className: "w-4 h-4 text-gray-400" }) }), _jsx("input", { type: "text", value: value, onChange: (e) => setValue(e.target.value), placeholder: placeholder, className: "w-full pl-10 pr-10 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" }), value && (_jsx("button", { onClick: handleClear, className: "absolute inset-y-0 right-0 flex items-center pr-3 text-gray-400 hover:text-gray-600", children: _jsx(X, { className: "w-4 h-4" }) }))] }));
32
+ }
33
+ export default DataTableSearch;
@@ -0,0 +1,54 @@
1
+ import React from 'react';
2
+ import type { BulkAction, ColumnVisibilityOptions, DataTableClassNames, ExportOptions } from '../types';
3
+ interface DataTableToolbarProps<TData> {
4
+ /** Table title */
5
+ title?: string;
6
+ /** Table description */
7
+ description?: string;
8
+ /** Global filter value */
9
+ globalFilter: string;
10
+ /** Global filter setter */
11
+ setGlobalFilter: (value: string) => void;
12
+ /** Enable global filter */
13
+ enableGlobalFilter?: boolean;
14
+ /** Global filter placeholder */
15
+ globalFilterPlaceholder?: string;
16
+ /** Filter debounce time */
17
+ filterDebounceMs?: number;
18
+ /** Column visibility state */
19
+ columnVisibility: Record<string, boolean>;
20
+ /** Column visibility setter */
21
+ setColumnVisibility: (visibility: Record<string, boolean>) => void;
22
+ /** Column visibility options */
23
+ columnVisibilityOptions?: ColumnVisibilityOptions;
24
+ /** All columns for visibility toggle */
25
+ allColumns: Array<{
26
+ id: string;
27
+ getIsVisible: () => boolean;
28
+ toggleVisibility: (value: boolean) => void;
29
+ columnDef: {
30
+ header?: unknown;
31
+ };
32
+ }>;
33
+ /** Export options */
34
+ exportOptions?: ExportOptions;
35
+ /** Export handler */
36
+ onExport?: (format: string) => void;
37
+ /** Refresh handler */
38
+ onRefresh?: () => void;
39
+ /** Selected row count */
40
+ selectedCount?: number;
41
+ /** Bulk actions */
42
+ bulkActions?: BulkAction<TData>[];
43
+ /** Selected rows for bulk actions */
44
+ selectedRows?: TData[];
45
+ /** Custom header content */
46
+ headerContent?: React.ReactNode;
47
+ /** Custom classNames */
48
+ classNames?: DataTableClassNames;
49
+ }
50
+ /**
51
+ * DataTable Toolbar Component
52
+ */
53
+ export declare function DataTableToolbar<TData>({ title, description, globalFilter, setGlobalFilter, enableGlobalFilter, globalFilterPlaceholder, filterDebounceMs, columnVisibility, setColumnVisibility, columnVisibilityOptions, allColumns, exportOptions, onExport, onRefresh, selectedCount, bulkActions, selectedRows, headerContent, classNames, }: DataTableToolbarProps<TData>): import("react/jsx-runtime").JSX.Element;
54
+ export default DataTableToolbar;
@@ -0,0 +1,28 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * @fileoverview DataTable Toolbar Component
4
+ */
5
+ import { Columns, Download, RefreshCw } from 'lucide-react';
6
+ import { useState } from 'react';
7
+ import { cn } from '../../helpers';
8
+ import { DataTableSearch } from './DataTableSearch';
9
+ /**
10
+ * DataTable Toolbar Component
11
+ */
12
+ export function DataTableToolbar({ title, description, globalFilter, setGlobalFilter, enableGlobalFilter = true, globalFilterPlaceholder, filterDebounceMs, columnVisibility, setColumnVisibility, columnVisibilityOptions, allColumns, exportOptions, onExport, onRefresh, selectedCount = 0, bulkActions, selectedRows = [], headerContent, classNames, }) {
13
+ const [showColumnMenu, setShowColumnMenu] = useState(false);
14
+ const [showExportMenu, setShowExportMenu] = useState(false);
15
+ return (_jsxs("div", { className: cn('px-4 py-3 border-b border-gray-200 bg-white', classNames?.toolbar), children: [(title || description) && (_jsxs("div", { className: "mb-3", children: [title && _jsx("h2", { className: "text-lg font-semibold text-gray-900", children: title }), description && _jsx("p", { className: "text-sm text-gray-500", children: description })] })), _jsxs("div", { className: "flex items-center justify-between gap-4", children: [_jsxs("div", { className: "flex items-center gap-3 flex-1", children: [enableGlobalFilter && (_jsx("div", { className: "w-64", children: _jsx(DataTableSearch, { value: globalFilter, onChange: setGlobalFilter, placeholder: globalFilterPlaceholder, debounceMs: filterDebounceMs, classNames: classNames }) })), selectedCount > 0 && bulkActions && bulkActions.length > 0 && (_jsxs("div", { className: "flex items-center gap-2 ml-2 pl-2 border-l border-gray-200", children: [_jsxs("span", { className: "text-sm text-gray-600", children: [selectedCount, " selected"] }), bulkActions.map((action) => (_jsxs("button", { onClick: () => action.onClick(selectedRows), disabled: action.disabled, className: cn('px-3 py-1.5 text-sm font-medium rounded-md transition-colors', action.variant === 'danger'
16
+ ? 'text-red-600 hover:bg-red-50'
17
+ : action.variant === 'primary'
18
+ ? 'text-blue-600 hover:bg-blue-50'
19
+ : 'text-gray-600 hover:bg-gray-100', action.disabled && 'opacity-50 cursor-not-allowed'), children: [action.icon && _jsx("span", { className: "mr-1.5", children: action.icon }), action.label] }, action.id)))] }))] }), _jsxs("div", { className: "flex items-center gap-2", children: [headerContent, onRefresh && (_jsx("button", { onClick: onRefresh, className: "p-2 text-gray-600 hover:bg-gray-100 rounded-md transition-colors", title: "Refresh", children: _jsx(RefreshCw, { className: "w-4 h-4" }) })), columnVisibilityOptions?.enabled !== false && (_jsxs("div", { className: "relative", children: [_jsx("button", { onClick: () => setShowColumnMenu(!showColumnMenu), className: "p-2 text-gray-600 hover:bg-gray-100 rounded-md transition-colors", title: "Toggle columns", children: _jsx(Columns, { className: "w-4 h-4" }) }), showColumnMenu && (_jsx("div", { className: "absolute right-0 top-full mt-1 w-48 bg-white border border-gray-200 rounded-lg shadow-lg z-20", children: _jsx("div", { className: "p-2 max-h-64 overflow-y-auto", children: allColumns.map((column) => {
20
+ const isAlwaysVisible = columnVisibilityOptions?.alwaysVisible?.includes(column.id);
21
+ const header = typeof column.columnDef.header === 'string' ? column.columnDef.header : column.id;
22
+ return (_jsxs("label", { className: cn('flex items-center gap-2 px-2 py-1.5 rounded hover:bg-gray-50 cursor-pointer', isAlwaysVisible && 'opacity-50 cursor-not-allowed'), children: [_jsx("input", { type: "checkbox", checked: column.getIsVisible(), onChange: (e) => column.toggleVisibility(e.target.checked), disabled: isAlwaysVisible, className: "rounded border-gray-300 text-blue-600 focus:ring-blue-500" }), _jsx("span", { className: "text-sm text-gray-700", children: header })] }, column.id));
23
+ }) }) }))] })), exportOptions?.enabled && onExport && (_jsxs("div", { className: "relative", children: [_jsxs("button", { onClick: () => setShowExportMenu(!showExportMenu), className: "flex items-center gap-1.5 px-3 py-2 text-sm font-medium text-gray-600 hover:bg-gray-100 rounded-md transition-colors", children: [_jsx(Download, { className: "w-4 h-4" }), "Export"] }), showExportMenu && (_jsx("div", { className: "absolute right-0 top-full mt-1 w-36 bg-white border border-gray-200 rounded-lg shadow-lg z-20", children: _jsx("div", { className: "p-1", children: (exportOptions.formats ?? ['csv', 'excel', 'json']).map((format) => (_jsxs("button", { onClick: () => {
24
+ onExport(format);
25
+ setShowExportMenu(false);
26
+ }, className: "w-full px-3 py-2 text-sm text-left text-gray-700 hover:bg-gray-50 rounded", children: ["Export as ", format.toUpperCase()] }, format))) }) }))] }))] })] })] }));
27
+ }
28
+ export default DataTableToolbar;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @fileoverview DataTable V2 Components Index
3
+ */
4
+ export { DataTableHeader } from './DataTableHeader';
5
+ export { DataTableBody } from './DataTableBody';
6
+ export { DataTablePagination } from './DataTablePagination';
7
+ export { DataTableSearch } from './DataTableSearch';
8
+ export { DataTableToolbar } from './DataTableToolbar';
9
+ export { DataTableEmpty } from './DataTableEmpty';
10
+ export { DataTableLoading } from './DataTableLoading';
11
+ export { DataTableError } from './DataTableError';
12
+ export { DataTableRowActions } from './DataTableRowActions';
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @fileoverview DataTable V2 Components Index
3
+ */
4
+ export { DataTableHeader } from './DataTableHeader';
5
+ export { DataTableBody } from './DataTableBody';
6
+ export { DataTablePagination } from './DataTablePagination';
7
+ export { DataTableSearch } from './DataTableSearch';
8
+ export { DataTableToolbar } from './DataTableToolbar';
9
+ export { DataTableEmpty } from './DataTableEmpty';
10
+ export { DataTableLoading } from './DataTableLoading';
11
+ export { DataTableError } from './DataTableError';
12
+ export { DataTableRowActions } from './DataTableRowActions';
@@ -0,0 +1,4 @@
1
+ /**
2
+ * @fileoverview DataTable V2 Hooks
3
+ */
4
+ export { useTableData, usePaginatedTableData, type UseTableDataOptions, type UsePaginatedTableDataOptions, type UseTableDataResult, type UsePaginatedTableDataResult, } from './useTableData';
@@ -0,0 +1,4 @@
1
+ /**
2
+ * @fileoverview DataTable V2 Hooks
3
+ */
4
+ export { useTableData, usePaginatedTableData, } from './useTableData';
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Options for useTableData hook
3
+ */
4
+ export interface UseTableDataOptions<TData> {
5
+ /** API endpoint URL */
6
+ url: string;
7
+ /** Query key for TanStack Query cache management */
8
+ queryKey?: unknown[];
9
+ /** HTTP method */
10
+ method?: 'GET' | 'POST';
11
+ /** Request body for POST requests */
12
+ body?: Record<string, unknown>;
13
+ /** Query parameters */
14
+ params?: Record<string, string | number>;
15
+ /** Transform function for response data */
16
+ transform?: (data: unknown) => TData[];
17
+ /** Whether to enable the query */
18
+ enabled?: boolean;
19
+ /** Stale time in milliseconds (how long data is considered fresh) */
20
+ staleTime?: number;
21
+ /** Garbage collection time in milliseconds */
22
+ gcTime?: number;
23
+ /** Refetch interval in milliseconds (0 = disabled) */
24
+ refetchInterval?: number;
25
+ /** Refetch on window focus */
26
+ refetchOnWindowFocus?: boolean;
27
+ /** Initial data */
28
+ initialData?: TData[];
29
+ }
30
+ /**
31
+ * Options for usePaginatedTableData hook
32
+ */
33
+ export interface UsePaginatedTableDataOptions<TData> extends UseTableDataOptions<TData> {
34
+ /** Current page (0-indexed) */
35
+ page?: number;
36
+ /** Page size */
37
+ pageSize?: number;
38
+ /** Sort field */
39
+ sortField?: string;
40
+ /** Sort direction */
41
+ sortDirection?: 'asc' | 'desc';
42
+ /** Search/filter query */
43
+ search?: string;
44
+ /** Additional filters */
45
+ filters?: Record<string, string | number | boolean | null>;
46
+ }
47
+ /**
48
+ * Result from useTableData hook
49
+ */
50
+ export interface UseTableDataResult<TData> {
51
+ /** The fetched and transformed data */
52
+ data: TData[];
53
+ /** Whether the initial fetch is in progress */
54
+ isLoading: boolean;
55
+ /** Whether a background refetch is in progress */
56
+ isFetching: boolean;
57
+ /** Whether there was an error */
58
+ isError: boolean;
59
+ /** The error object if any */
60
+ error: Error | null;
61
+ /** Function to manually refetch data */
62
+ refetch: () => void;
63
+ }
64
+ /**
65
+ * Result from usePaginatedTableData hook
66
+ */
67
+ export interface UsePaginatedTableDataResult<TData> extends UseTableDataResult<TData> {
68
+ /** Total number of items */
69
+ totalItems: number;
70
+ /** Total number of pages */
71
+ totalPages: number;
72
+ /** Current page (0-indexed) */
73
+ currentPage: number;
74
+ /** Whether there's a next page */
75
+ hasNextPage: boolean;
76
+ /** Whether there's a previous page */
77
+ hasPreviousPage: boolean;
78
+ }
79
+ /**
80
+ * Hook for fetching table data using TanStack Query
81
+ *
82
+ * @example
83
+ * ```tsx
84
+ * const { data, isLoading, error, refetch } = useTableData<User>({
85
+ * url: '/api/users',
86
+ * queryKey: ['users'],
87
+ * params: { status: 'active' },
88
+ * transform: (raw) => raw.users,
89
+ * });
90
+ * ```
91
+ */
92
+ export declare function useTableData<TData = unknown>(options: UseTableDataOptions<TData>): UseTableDataResult<TData>;
93
+ /**
94
+ * Hook for fetching paginated table data using TanStack Query
95
+ * Designed for Spring Boot style paginated responses
96
+ *
97
+ * @example
98
+ * ```tsx
99
+ * const {
100
+ * data,
101
+ * isLoading,
102
+ * totalItems,
103
+ * totalPages,
104
+ * hasNextPage,
105
+ * } = usePaginatedTableData<User>({
106
+ * url: '/api/users',
107
+ * queryKey: ['users'],
108
+ * page: 0,
109
+ * pageSize: 20,
110
+ * sortField: 'createdAt',
111
+ * sortDirection: 'desc',
112
+ * search: searchQuery,
113
+ * filters: { status: 'active' },
114
+ * });
115
+ * ```
116
+ */
117
+ export declare function usePaginatedTableData<TData = unknown>(options: UsePaginatedTableDataOptions<TData>): UsePaginatedTableDataResult<TData>;
118
+ export default useTableData;
@@ -0,0 +1,210 @@
1
+ /**
2
+ * @fileoverview useTableData hook - Data fetching for DataTable V2
3
+ * Uses TanStack Query for declarative, cache-aware data fetching with pagination support
4
+ */
5
+ import { useCallback, useMemo } from 'react';
6
+ import { useApiQuery, usePaginatedApiQuery } from '../../api/tanstackQuery';
7
+ /**
8
+ * Hook for fetching table data using TanStack Query
9
+ *
10
+ * @example
11
+ * ```tsx
12
+ * const { data, isLoading, error, refetch } = useTableData<User>({
13
+ * url: '/api/users',
14
+ * queryKey: ['users'],
15
+ * params: { status: 'active' },
16
+ * transform: (raw) => raw.users,
17
+ * });
18
+ * ```
19
+ */
20
+ export function useTableData(options) {
21
+ const { url, queryKey: customQueryKey, method = 'GET', body, params, transform, enabled = true, staleTime, gcTime, refetchInterval, refetchOnWindowFocus, initialData = [], } = options;
22
+ // Build query string
23
+ const queryString = useMemo(() => {
24
+ if (!params || Object.keys(params).length === 0)
25
+ return '';
26
+ const searchParams = new URLSearchParams();
27
+ Object.entries(params).forEach(([key, value]) => {
28
+ if (value !== undefined && value !== null) {
29
+ searchParams.append(key, String(value));
30
+ }
31
+ });
32
+ return '?' + searchParams.toString();
33
+ }, [params]);
34
+ const fullUrl = `${url}${queryString}`;
35
+ // Build stable query key
36
+ const queryKey = useMemo(() => customQueryKey || ['table', url, method, params, body].filter(Boolean), [customQueryKey, url, method, params, body]);
37
+ // Use TanStack Query for data fetching
38
+ const { data: rawData, isLoading, isFetching, isError, error, refetch: queryRefetch, } = useApiQuery({
39
+ queryKey,
40
+ endpoint: fullUrl,
41
+ requestConfig: {
42
+ method,
43
+ ...(method === 'POST' && body ? { body: JSON.stringify(body) } : {}),
44
+ },
45
+ enabled: enabled && !!url,
46
+ staleTime,
47
+ gcTime,
48
+ refetchInterval: refetchInterval || false,
49
+ refetchOnWindowFocus: refetchOnWindowFocus ?? false,
50
+ });
51
+ // Transform data
52
+ const transformedData = useMemo(() => {
53
+ if (!rawData)
54
+ return initialData;
55
+ if (transform) {
56
+ try {
57
+ return transform(rawData);
58
+ }
59
+ catch (e) {
60
+ console.error('Error transforming table data:', e);
61
+ return initialData;
62
+ }
63
+ }
64
+ // Default: assume data is array or has data/content property
65
+ if (Array.isArray(rawData))
66
+ return rawData;
67
+ if (rawData && typeof rawData === 'object') {
68
+ if ('content' in rawData) {
69
+ return rawData.content;
70
+ }
71
+ if ('data' in rawData) {
72
+ return rawData.data;
73
+ }
74
+ }
75
+ return initialData;
76
+ }, [rawData, transform, initialData]);
77
+ const refetch = useCallback(() => {
78
+ queryRefetch();
79
+ }, [queryRefetch]);
80
+ return {
81
+ data: transformedData,
82
+ isLoading,
83
+ isFetching,
84
+ isError,
85
+ error: error,
86
+ refetch,
87
+ };
88
+ }
89
+ /**
90
+ * Hook for fetching paginated table data using TanStack Query
91
+ * Designed for Spring Boot style paginated responses
92
+ *
93
+ * @example
94
+ * ```tsx
95
+ * const {
96
+ * data,
97
+ * isLoading,
98
+ * totalItems,
99
+ * totalPages,
100
+ * hasNextPage,
101
+ * } = usePaginatedTableData<User>({
102
+ * url: '/api/users',
103
+ * queryKey: ['users'],
104
+ * page: 0,
105
+ * pageSize: 20,
106
+ * sortField: 'createdAt',
107
+ * sortDirection: 'desc',
108
+ * search: searchQuery,
109
+ * filters: { status: 'active' },
110
+ * });
111
+ * ```
112
+ */
113
+ export function usePaginatedTableData(options) {
114
+ const { url, queryKey: customQueryKey, method = 'GET', body, params: additionalParams, transform, enabled = true, staleTime, gcTime, refetchInterval, refetchOnWindowFocus, initialData = [], page = 0, pageSize = 20, sortField, sortDirection, search, filters, } = options;
115
+ // Build params with pagination
116
+ const params = useMemo(() => {
117
+ const p = {
118
+ page,
119
+ size: pageSize,
120
+ ...additionalParams,
121
+ };
122
+ if (sortField) {
123
+ p.sort = sortDirection ? `${sortField},${sortDirection}` : sortField;
124
+ }
125
+ if (search) {
126
+ p.search = search;
127
+ }
128
+ if (filters) {
129
+ Object.entries(filters).forEach(([key, value]) => {
130
+ if (value !== undefined && value !== null && value !== '') {
131
+ p[key] = String(value);
132
+ }
133
+ });
134
+ }
135
+ return p;
136
+ }, [page, pageSize, sortField, sortDirection, search, filters, additionalParams]);
137
+ // Build query string
138
+ const queryString = useMemo(() => {
139
+ const searchParams = new URLSearchParams();
140
+ Object.entries(params).forEach(([key, value]) => {
141
+ searchParams.append(key, String(value));
142
+ });
143
+ return '?' + searchParams.toString();
144
+ }, [params]);
145
+ const fullUrl = `${url}${queryString}`;
146
+ // Build stable query key
147
+ const queryKey = useMemo(() => customQueryKey || ['table-paginated', url, params, body].filter(Boolean), [customQueryKey, url, params, body]);
148
+ // Use paginated API query
149
+ const { data: rawData, isLoading, isFetching, isError, error, refetch: queryRefetch, } = usePaginatedApiQuery({
150
+ queryKey,
151
+ endpoint: fullUrl,
152
+ requestConfig: {
153
+ method,
154
+ ...(method === 'POST' && body ? { body: JSON.stringify(body) } : {}),
155
+ },
156
+ enabled: enabled && !!url,
157
+ staleTime,
158
+ gcTime,
159
+ refetchInterval: refetchInterval || false,
160
+ refetchOnWindowFocus: refetchOnWindowFocus ?? false,
161
+ });
162
+ // Extract data and pagination info
163
+ const { data, totalItems, totalPages, hasNextPage, hasPreviousPage } = useMemo(() => {
164
+ if (!rawData) {
165
+ return {
166
+ data: initialData,
167
+ totalItems: 0,
168
+ totalPages: 0,
169
+ hasNextPage: false,
170
+ hasPreviousPage: false,
171
+ };
172
+ }
173
+ // Handle Spring Boot response
174
+ const springResponse = rawData;
175
+ let content = springResponse.content || [];
176
+ if (transform) {
177
+ try {
178
+ content = transform(content);
179
+ }
180
+ catch (e) {
181
+ console.error('Error transforming table data:', e);
182
+ content = initialData;
183
+ }
184
+ }
185
+ return {
186
+ data: content,
187
+ totalItems: springResponse.totalElements || 0,
188
+ totalPages: springResponse.totalPages || 0,
189
+ hasNextPage: !springResponse.last,
190
+ hasPreviousPage: !springResponse.first,
191
+ };
192
+ }, [rawData, transform, initialData]);
193
+ const refetch = useCallback(() => {
194
+ queryRefetch();
195
+ }, [queryRefetch]);
196
+ return {
197
+ data,
198
+ isLoading,
199
+ isFetching,
200
+ isError,
201
+ error: error,
202
+ refetch,
203
+ totalItems,
204
+ totalPages,
205
+ currentPage: page,
206
+ hasNextPage,
207
+ hasPreviousPage,
208
+ };
209
+ }
210
+ export default useTableData;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @fileoverview DataTable V2 - Main exports
3
+ * TanStack Table-based data table with headless architecture
4
+ */
5
+ export { DataTable } from './DataTable';
6
+ export type { DataTableProps, DataTableColumn, DataTableClassNames, RowSelectionOptions, PaginationOptions, SortingOptions, FilteringOptions, ColumnVisibilityOptions, ExportOptions, RowAction, BulkAction, DataTableServerResponse, DataTableServerRequest, } from './types';
7
+ export { DataTableHeader, DataTableBody, DataTablePagination, DataTableSearch, DataTableToolbar, DataTableEmpty, DataTableLoading, DataTableError, DataTableRowActions, } from './components';
8
+ export { useTableData, usePaginatedTableData, type UseTableDataOptions, type UsePaginatedTableDataOptions, type UseTableDataResult, type UsePaginatedTableDataResult, } from './hooks';
9
+ export { exportToCSV, exportToJSON, downloadFile, createExportHandler } from './utils';
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @fileoverview DataTable V2 - Main exports
3
+ * TanStack Table-based data table with headless architecture
4
+ */
5
+ // Main component
6
+ export { DataTable } from './DataTable';
7
+ // Sub-components (for customization)
8
+ export { DataTableHeader, DataTableBody, DataTablePagination, DataTableSearch, DataTableToolbar, DataTableEmpty, DataTableLoading, DataTableError, DataTableRowActions, } from './components';
9
+ // Hooks (TanStack Query based)
10
+ export { useTableData, usePaginatedTableData, } from './hooks';
11
+ // Utilities
12
+ export { exportToCSV, exportToJSON, downloadFile, createExportHandler } from './utils';