@withwiz/toolkit 0.2.0 → 0.2.1
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/auth/index.js +18 -18
- package/dist/chunk-6JZQE7ZQ.js +225 -0
- package/dist/chunk-7IY3RQQL.js +151 -0
- package/dist/{chunk-SLG26KHZ.js → chunk-FH6E36YZ.js} +1 -1
- package/dist/chunk-IPXPCBDO.js +127 -0
- package/dist/chunk-KHYY4KCV.js +110 -0
- package/dist/chunk-MAATEX2R.js +81 -0
- package/dist/chunk-NY5QXT33.js +31 -0
- package/dist/chunk-SEZJN4TC.js +136 -0
- package/dist/components/ui/DataTable.d.ts +8 -103
- package/dist/components/ui/DataTable.js +17 -602
- package/dist/components/ui/data-table/DataTable.d.ts +2 -0
- package/dist/components/ui/data-table/DataTable.js +22 -0
- package/dist/components/ui/data-table/DataTableBody.d.ts +19 -0
- package/dist/components/ui/data-table/DataTableBody.js +10 -0
- package/dist/components/ui/data-table/DataTableBulkActions.d.ts +17 -0
- package/dist/components/ui/data-table/DataTableBulkActions.js +12 -0
- package/dist/components/ui/data-table/DataTableFilters.d.ts +15 -0
- package/dist/components/ui/data-table/DataTableFilters.js +13 -0
- package/dist/components/ui/data-table/DataTablePagination.d.ts +10 -0
- package/dist/components/ui/data-table/DataTablePagination.js +11 -0
- package/dist/components/ui/data-table/DataTableSearch.d.ts +24 -0
- package/dist/components/ui/data-table/DataTableSearch.js +12 -0
- package/dist/components/ui/data-table/index.d.ts +13 -0
- package/dist/components/ui/data-table/types.d.ts +115 -0
- package/dist/constants/index.js +13 -13
- package/dist/error/hooks/index.js +2 -2
- package/dist/error/hooks/useErrorHandler.js +2 -2
- package/dist/error/index.js +28 -28
- package/dist/error/recovery/index.js +5 -5
- package/dist/hooks/useDataTable.d.ts +45 -0
- package/dist/hooks/useDataTable.js +13 -11
- package/dist/middleware/error-handler.js +2 -2
- package/dist/middleware/index.js +3 -3
- package/dist/middleware/wrappers.js +3 -3
- package/package.json +3 -1
- package/dist/{chunk-TMVS4F7E.js → chunk-5OWZKYWQ.js} +3 -3
- package/dist/{chunk-IAJNC34M.js → chunk-6UAYU5NU.js} +3 -3
package/dist/auth/index.js
CHANGED
|
@@ -1,24 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
OAuthManager
|
|
3
|
-
} from "../chunk-V5K5FYU7.js";
|
|
4
|
-
import {
|
|
5
|
-
DEFAULT_PASSWORD_CONFIG,
|
|
6
|
-
createPasswordHasher,
|
|
7
|
-
createPasswordSchema,
|
|
8
|
-
createPasswordValidator,
|
|
9
|
-
getPasswordStrength,
|
|
10
|
-
passwordValidator,
|
|
11
|
-
validatePassword
|
|
12
|
-
} from "../chunk-G26T2PRQ.js";
|
|
13
|
-
import {
|
|
14
|
-
PasswordHasher,
|
|
15
|
-
PasswordValidator,
|
|
16
|
-
defaultPasswordSchema,
|
|
17
|
-
strongPasswordSchema
|
|
18
|
-
} from "../chunk-IHXRF3BH.js";
|
|
19
1
|
import {
|
|
20
2
|
TokenGenerator
|
|
21
3
|
} from "../chunk-GDWEDUHO.js";
|
|
4
|
+
import {
|
|
5
|
+
OAuthManager
|
|
6
|
+
} from "../chunk-V5K5FYU7.js";
|
|
22
7
|
import {
|
|
23
8
|
JWTClientManager,
|
|
24
9
|
clearStoredTokens,
|
|
@@ -35,6 +20,21 @@ import {
|
|
|
35
20
|
isTokenExpiringSoon,
|
|
36
21
|
storeTokens
|
|
37
22
|
} from "../chunk-XRRPEBKB.js";
|
|
23
|
+
import {
|
|
24
|
+
DEFAULT_PASSWORD_CONFIG,
|
|
25
|
+
createPasswordHasher,
|
|
26
|
+
createPasswordSchema,
|
|
27
|
+
createPasswordValidator,
|
|
28
|
+
getPasswordStrength,
|
|
29
|
+
passwordValidator,
|
|
30
|
+
validatePassword
|
|
31
|
+
} from "../chunk-G26T2PRQ.js";
|
|
32
|
+
import {
|
|
33
|
+
PasswordHasher,
|
|
34
|
+
PasswordValidator,
|
|
35
|
+
defaultPasswordSchema,
|
|
36
|
+
strongPasswordSchema
|
|
37
|
+
} from "../chunk-IHXRF3BH.js";
|
|
38
38
|
import {
|
|
39
39
|
OAuthProvider,
|
|
40
40
|
PasswordStrength,
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DataTableBody
|
|
3
|
+
} from "./chunk-7IY3RQQL.js";
|
|
4
|
+
import {
|
|
5
|
+
DataTableBulkActions
|
|
6
|
+
} from "./chunk-MAATEX2R.js";
|
|
7
|
+
import {
|
|
8
|
+
DataTableFilters
|
|
9
|
+
} from "./chunk-SEZJN4TC.js";
|
|
10
|
+
import {
|
|
11
|
+
DataTablePagination
|
|
12
|
+
} from "./chunk-IPXPCBDO.js";
|
|
13
|
+
import {
|
|
14
|
+
DataTableSearch
|
|
15
|
+
} from "./chunk-KHYY4KCV.js";
|
|
16
|
+
import {
|
|
17
|
+
DEFAULT_LABELS
|
|
18
|
+
} from "./chunk-NY5QXT33.js";
|
|
19
|
+
import {
|
|
20
|
+
Alert,
|
|
21
|
+
AlertDescription
|
|
22
|
+
} from "./chunk-F6LCSFSU.js";
|
|
23
|
+
import {
|
|
24
|
+
cn
|
|
25
|
+
} from "./chunk-62FLBG6B.js";
|
|
26
|
+
import {
|
|
27
|
+
__spreadValues
|
|
28
|
+
} from "./chunk-ORMEWXMH.js";
|
|
29
|
+
|
|
30
|
+
// src/components/ui/data-table/DataTable.tsx
|
|
31
|
+
import { useState, useEffect, useMemo } from "react";
|
|
32
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
33
|
+
function DataTable({
|
|
34
|
+
data,
|
|
35
|
+
columns,
|
|
36
|
+
loading = false,
|
|
37
|
+
error = null,
|
|
38
|
+
pagination,
|
|
39
|
+
sort,
|
|
40
|
+
bulkActions = [],
|
|
41
|
+
filters = [],
|
|
42
|
+
filterValues = {},
|
|
43
|
+
onFilterChange,
|
|
44
|
+
onClearFilters,
|
|
45
|
+
selectable = false,
|
|
46
|
+
onSelectionChange,
|
|
47
|
+
selectedIds = [],
|
|
48
|
+
getRowId,
|
|
49
|
+
className,
|
|
50
|
+
emptyMessage = "No data",
|
|
51
|
+
searchPlaceholder = "Search...",
|
|
52
|
+
onSearch,
|
|
53
|
+
onSearchValueChange,
|
|
54
|
+
searchValue = "",
|
|
55
|
+
showFilters = false,
|
|
56
|
+
onToggleFilters,
|
|
57
|
+
createButton,
|
|
58
|
+
labels: customLabels,
|
|
59
|
+
syncWithUrl = false
|
|
60
|
+
}) {
|
|
61
|
+
const labels = __spreadValues(__spreadValues({}, DEFAULT_LABELS), customLabels);
|
|
62
|
+
const [localSelectedIds, setLocalSelectedIds] = useState(selectedIds);
|
|
63
|
+
const [bulkActionLoading, setBulkActionLoading] = useState(null);
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
setLocalSelectedIds(selectedIds);
|
|
66
|
+
}, [selectedIds]);
|
|
67
|
+
const hasActiveFilters = useMemo(() => {
|
|
68
|
+
if (searchValue && searchValue.trim()) return true;
|
|
69
|
+
for (const [key, value] of Object.entries(filterValues)) {
|
|
70
|
+
if (value === void 0 || value === null || value === "") continue;
|
|
71
|
+
if (value === "all") continue;
|
|
72
|
+
if (typeof value === "object" && value !== null) {
|
|
73
|
+
if (key === "dateRange" && (value.start || value.end)) return true;
|
|
74
|
+
if (key === "clickRange" && (value.min || value.max)) return true;
|
|
75
|
+
if (key === "lastClickedRange" && (value.start || value.end)) return true;
|
|
76
|
+
} else {
|
|
77
|
+
if (key === "activeFilter" && value !== "all") return true;
|
|
78
|
+
if (key === "publicFilter" && value !== "all") return true;
|
|
79
|
+
if (key === "expirationFilter" && value !== "all") return true;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return false;
|
|
83
|
+
}, [searchValue, filterValues]);
|
|
84
|
+
useEffect(() => {
|
|
85
|
+
if (!syncWithUrl || typeof window === "undefined") return;
|
|
86
|
+
const params = new URLSearchParams(window.location.search);
|
|
87
|
+
let changed = false;
|
|
88
|
+
if (searchValue) {
|
|
89
|
+
if (params.get("search") !== searchValue) {
|
|
90
|
+
params.set("search", searchValue);
|
|
91
|
+
changed = true;
|
|
92
|
+
}
|
|
93
|
+
} else {
|
|
94
|
+
if (params.has("search")) {
|
|
95
|
+
params.delete("search");
|
|
96
|
+
changed = true;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (sort) {
|
|
100
|
+
if (params.get("sort") !== sort.sort) {
|
|
101
|
+
params.set("sort", sort.sort);
|
|
102
|
+
changed = true;
|
|
103
|
+
}
|
|
104
|
+
if (params.get("order") !== sort.order) {
|
|
105
|
+
params.set("order", sort.order);
|
|
106
|
+
changed = true;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if (pagination) {
|
|
110
|
+
const pageStr = String(pagination.page);
|
|
111
|
+
const pageSizeStr = String(pagination.pageSize);
|
|
112
|
+
if (params.get("page") !== pageStr) {
|
|
113
|
+
params.set("page", pageStr);
|
|
114
|
+
changed = true;
|
|
115
|
+
}
|
|
116
|
+
if (params.get("pageSize") !== pageSizeStr) {
|
|
117
|
+
params.set("pageSize", pageSizeStr);
|
|
118
|
+
changed = true;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (changed) {
|
|
122
|
+
const newUrl = `${window.location.pathname}?${params.toString()}`;
|
|
123
|
+
window.history.replaceState(null, "", newUrl);
|
|
124
|
+
}
|
|
125
|
+
}, [syncWithUrl, searchValue, sort == null ? void 0 : sort.sort, sort == null ? void 0 : sort.order, pagination == null ? void 0 : pagination.page, pagination == null ? void 0 : pagination.pageSize]);
|
|
126
|
+
const handleSelectAll = (checked) => {
|
|
127
|
+
const newSelection = checked ? data.map((item) => getRowId(item)) : [];
|
|
128
|
+
setLocalSelectedIds(newSelection);
|
|
129
|
+
onSelectionChange == null ? void 0 : onSelectionChange(newSelection);
|
|
130
|
+
};
|
|
131
|
+
const handleSelect = (id, checked) => {
|
|
132
|
+
const newSelection = checked ? [...localSelectedIds, id] : localSelectedIds.filter((item) => item !== id);
|
|
133
|
+
setLocalSelectedIds(newSelection);
|
|
134
|
+
onSelectionChange == null ? void 0 : onSelectionChange(newSelection);
|
|
135
|
+
};
|
|
136
|
+
const handleSort = (columnKey) => {
|
|
137
|
+
if (!sort) return;
|
|
138
|
+
if (sort.sort === columnKey) {
|
|
139
|
+
sort.onSortChange(columnKey, sort.order === "asc" ? "desc" : "asc");
|
|
140
|
+
} else {
|
|
141
|
+
sort.onSortChange(columnKey, "asc");
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
const handleBulkAction = async (action) => {
|
|
145
|
+
if (localSelectedIds.length === 0 || bulkActionLoading) return;
|
|
146
|
+
setBulkActionLoading(action.key);
|
|
147
|
+
try {
|
|
148
|
+
await action.onClick(localSelectedIds);
|
|
149
|
+
} finally {
|
|
150
|
+
setBulkActionLoading(null);
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
const visibleColumns = columns.filter((col) => !col.hidden);
|
|
154
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("space-y-4", className), children: [
|
|
155
|
+
(onSearch || createButton) && /* @__PURE__ */ jsx(
|
|
156
|
+
DataTableSearch,
|
|
157
|
+
{
|
|
158
|
+
onSearch,
|
|
159
|
+
onSearchValueChange,
|
|
160
|
+
searchValue,
|
|
161
|
+
searchPlaceholder,
|
|
162
|
+
labels,
|
|
163
|
+
filters,
|
|
164
|
+
onToggleFilters,
|
|
165
|
+
showFilters,
|
|
166
|
+
hasActiveFilters,
|
|
167
|
+
pagination,
|
|
168
|
+
createButton
|
|
169
|
+
}
|
|
170
|
+
),
|
|
171
|
+
showFilters && filters.length > 0 && /* @__PURE__ */ jsx(
|
|
172
|
+
DataTableFilters,
|
|
173
|
+
{
|
|
174
|
+
filters,
|
|
175
|
+
filterValues,
|
|
176
|
+
onFilterChange,
|
|
177
|
+
onClearFilters,
|
|
178
|
+
hasActiveFilters,
|
|
179
|
+
labels
|
|
180
|
+
}
|
|
181
|
+
),
|
|
182
|
+
selectable && bulkActions.length > 0 && /* @__PURE__ */ jsx(
|
|
183
|
+
DataTableBulkActions,
|
|
184
|
+
{
|
|
185
|
+
bulkActions,
|
|
186
|
+
localSelectedIds,
|
|
187
|
+
dataLength: data.length,
|
|
188
|
+
bulkActionLoading,
|
|
189
|
+
onSelectAll: handleSelectAll,
|
|
190
|
+
onBulkAction: handleBulkAction,
|
|
191
|
+
labels
|
|
192
|
+
}
|
|
193
|
+
),
|
|
194
|
+
error && /* @__PURE__ */ jsx(Alert, { variant: "destructive", children: /* @__PURE__ */ jsx(AlertDescription, { children: error }) }),
|
|
195
|
+
/* @__PURE__ */ jsx(
|
|
196
|
+
DataTableBody,
|
|
197
|
+
{
|
|
198
|
+
data,
|
|
199
|
+
visibleColumns,
|
|
200
|
+
loading,
|
|
201
|
+
error,
|
|
202
|
+
emptyMessage,
|
|
203
|
+
selectable,
|
|
204
|
+
localSelectedIds,
|
|
205
|
+
getRowId,
|
|
206
|
+
onSelectAll: handleSelectAll,
|
|
207
|
+
onSelect: handleSelect,
|
|
208
|
+
sort,
|
|
209
|
+
onSort: handleSort,
|
|
210
|
+
labels
|
|
211
|
+
}
|
|
212
|
+
),
|
|
213
|
+
pagination && pagination.total > 0 && /* @__PURE__ */ jsx(
|
|
214
|
+
DataTablePagination,
|
|
215
|
+
{
|
|
216
|
+
pagination,
|
|
217
|
+
labels
|
|
218
|
+
}
|
|
219
|
+
)
|
|
220
|
+
] });
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export {
|
|
224
|
+
DataTable
|
|
225
|
+
};
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import {
|
|
2
|
+
LoadingBar
|
|
3
|
+
} from "./chunk-34WAGUT5.js";
|
|
4
|
+
import {
|
|
5
|
+
cn
|
|
6
|
+
} from "./chunk-62FLBG6B.js";
|
|
7
|
+
|
|
8
|
+
// src/components/ui/data-table/DataTableBody.tsx
|
|
9
|
+
import { useRef, useEffect } from "react";
|
|
10
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
+
function DataTableBody({
|
|
12
|
+
data,
|
|
13
|
+
visibleColumns,
|
|
14
|
+
loading,
|
|
15
|
+
error,
|
|
16
|
+
emptyMessage,
|
|
17
|
+
selectable,
|
|
18
|
+
localSelectedIds,
|
|
19
|
+
getRowId,
|
|
20
|
+
onSelectAll,
|
|
21
|
+
onSelect,
|
|
22
|
+
sort,
|
|
23
|
+
onSort,
|
|
24
|
+
labels
|
|
25
|
+
}) {
|
|
26
|
+
const selectAllRef = useRef(null);
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
if (selectAllRef.current) {
|
|
29
|
+
selectAllRef.current.indeterminate = localSelectedIds.length > 0 && localSelectedIds.length < data.length;
|
|
30
|
+
}
|
|
31
|
+
}, [localSelectedIds, data.length]);
|
|
32
|
+
return /* @__PURE__ */ jsx("div", { className: "border rounded-lg overflow-hidden", children: /* @__PURE__ */ jsx("div", { className: "overflow-x-auto max-w-full", children: /* @__PURE__ */ jsxs("table", { className: "w-full text-sm min-w-full", children: [
|
|
33
|
+
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { className: "border-b bg-muted/50", children: [
|
|
34
|
+
selectable && /* @__PURE__ */ jsx("th", { className: "px-1 py-2 text-left font-medium w-8", children: /* @__PURE__ */ jsx(
|
|
35
|
+
"input",
|
|
36
|
+
{
|
|
37
|
+
"data-testid": "select-all-checkbox",
|
|
38
|
+
type: "checkbox",
|
|
39
|
+
ref: selectAllRef,
|
|
40
|
+
checked: data.length > 0 && localSelectedIds.length === data.length,
|
|
41
|
+
onChange: (e) => onSelectAll(e.target.checked),
|
|
42
|
+
className: "h-4 w-4"
|
|
43
|
+
}
|
|
44
|
+
) }),
|
|
45
|
+
visibleColumns.map((column) => {
|
|
46
|
+
var _a, _b, _c, _d;
|
|
47
|
+
const width = column.width === "auto" ? void 0 : column.width;
|
|
48
|
+
const minWidth = column.minWidth;
|
|
49
|
+
return /* @__PURE__ */ jsx(
|
|
50
|
+
"th",
|
|
51
|
+
{
|
|
52
|
+
className: cn(
|
|
53
|
+
"px-2 py-2 font-medium",
|
|
54
|
+
column.sortable && "cursor-pointer",
|
|
55
|
+
column.className,
|
|
56
|
+
((_a = column.responsive) == null ? void 0 : _a.sm) && "hidden sm:table-cell",
|
|
57
|
+
((_b = column.responsive) == null ? void 0 : _b.md) && "hidden md:table-cell",
|
|
58
|
+
((_c = column.responsive) == null ? void 0 : _c.lg) && "hidden lg:table-cell",
|
|
59
|
+
((_d = column.responsive) == null ? void 0 : _d.xl) && "hidden xl:table-cell"
|
|
60
|
+
),
|
|
61
|
+
style: {
|
|
62
|
+
width,
|
|
63
|
+
minWidth: minWidth || width || void 0,
|
|
64
|
+
maxWidth: column.maxWidth || void 0
|
|
65
|
+
},
|
|
66
|
+
onClick: column.sortable ? () => onSort(column.key) : void 0,
|
|
67
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-1", children: [
|
|
68
|
+
column.header,
|
|
69
|
+
column.sortable && sort && sort.sort === column.key && /* @__PURE__ */ jsx("span", { children: sort.order === "asc" ? "\u25B2" : "\u25BC" })
|
|
70
|
+
] })
|
|
71
|
+
},
|
|
72
|
+
column.key
|
|
73
|
+
);
|
|
74
|
+
})
|
|
75
|
+
] }) }),
|
|
76
|
+
/* @__PURE__ */ jsx("tbody", { children: loading ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
|
|
77
|
+
"td",
|
|
78
|
+
{
|
|
79
|
+
colSpan: visibleColumns.length + (selectable ? 1 : 0),
|
|
80
|
+
className: "text-center py-8",
|
|
81
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center space-y-3", children: [
|
|
82
|
+
/* @__PURE__ */ jsx(LoadingBar, { size: "md", variant: "primary", className: "w-64" }),
|
|
83
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: labels.loading })
|
|
84
|
+
] })
|
|
85
|
+
}
|
|
86
|
+
) }) : error ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
|
|
87
|
+
"td",
|
|
88
|
+
{
|
|
89
|
+
colSpan: visibleColumns.length + (selectable ? 1 : 0),
|
|
90
|
+
className: "text-center py-8 text-destructive",
|
|
91
|
+
children: error
|
|
92
|
+
}
|
|
93
|
+
) }) : data.length === 0 ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
|
|
94
|
+
"td",
|
|
95
|
+
{
|
|
96
|
+
colSpan: visibleColumns.length + (selectable ? 1 : 0),
|
|
97
|
+
className: "text-center py-8 text-muted-foreground",
|
|
98
|
+
children: emptyMessage
|
|
99
|
+
}
|
|
100
|
+
) }) : data.map((item) => {
|
|
101
|
+
const rowId = getRowId(item);
|
|
102
|
+
return /* @__PURE__ */ jsxs(
|
|
103
|
+
"tr",
|
|
104
|
+
{
|
|
105
|
+
className: cn(
|
|
106
|
+
"border-b last:border-0 hover:bg-muted/30",
|
|
107
|
+
localSelectedIds.includes(rowId) && "bg-primary/5"
|
|
108
|
+
),
|
|
109
|
+
children: [
|
|
110
|
+
selectable && /* @__PURE__ */ jsx("td", { className: "px-1 py-2 w-8", children: /* @__PURE__ */ jsx(
|
|
111
|
+
"input",
|
|
112
|
+
{
|
|
113
|
+
"data-testid": `row-checkbox-${rowId}`,
|
|
114
|
+
type: "checkbox",
|
|
115
|
+
checked: localSelectedIds.includes(rowId),
|
|
116
|
+
onChange: (e) => onSelect(rowId, e.target.checked),
|
|
117
|
+
className: "h-4 w-4"
|
|
118
|
+
}
|
|
119
|
+
) }),
|
|
120
|
+
visibleColumns.map((column) => {
|
|
121
|
+
var _a, _b, _c, _d;
|
|
122
|
+
return /* @__PURE__ */ jsx(
|
|
123
|
+
"td",
|
|
124
|
+
{
|
|
125
|
+
className: cn(
|
|
126
|
+
"px-2 py-3 overflow-hidden",
|
|
127
|
+
column.className,
|
|
128
|
+
((_a = column.responsive) == null ? void 0 : _a.sm) && "hidden sm:table-cell",
|
|
129
|
+
((_b = column.responsive) == null ? void 0 : _b.md) && "hidden md:table-cell",
|
|
130
|
+
((_c = column.responsive) == null ? void 0 : _c.lg) && "hidden lg:table-cell",
|
|
131
|
+
((_d = column.responsive) == null ? void 0 : _d.xl) && "hidden xl:table-cell"
|
|
132
|
+
),
|
|
133
|
+
style: {
|
|
134
|
+
maxWidth: column.maxWidth || column.width || void 0
|
|
135
|
+
},
|
|
136
|
+
children: column.cell ? column.cell(item) : column.accessorKey ? String(item[column.accessorKey] || "") : ""
|
|
137
|
+
},
|
|
138
|
+
column.key
|
|
139
|
+
);
|
|
140
|
+
})
|
|
141
|
+
]
|
|
142
|
+
},
|
|
143
|
+
rowId
|
|
144
|
+
);
|
|
145
|
+
}) })
|
|
146
|
+
] }) }) });
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export {
|
|
150
|
+
DataTableBody
|
|
151
|
+
};
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import {
|
|
2
|
+
formatLabel
|
|
3
|
+
} from "./chunk-NY5QXT33.js";
|
|
4
|
+
import {
|
|
5
|
+
Pagination,
|
|
6
|
+
PaginationContent,
|
|
7
|
+
PaginationEllipsis,
|
|
8
|
+
PaginationItem,
|
|
9
|
+
PaginationLink,
|
|
10
|
+
PaginationNext,
|
|
11
|
+
PaginationPrevious
|
|
12
|
+
} from "./chunk-YJWLWUFK.js";
|
|
13
|
+
|
|
14
|
+
// src/components/ui/data-table/DataTablePagination.tsx
|
|
15
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
16
|
+
function DataTablePagination({
|
|
17
|
+
pagination,
|
|
18
|
+
labels
|
|
19
|
+
}) {
|
|
20
|
+
const totalPages = Math.ceil(pagination.total / pagination.pageSize);
|
|
21
|
+
return /* @__PURE__ */ jsx("div", { className: "flex flex-col sm:flex-row items-center justify-between gap-3 p-3 bg-muted/50 rounded-lg", children: /* @__PURE__ */ jsx(Pagination, { className: "w-full", children: /* @__PURE__ */ jsxs(PaginationContent, { className: "flex-wrap gap-1 justify-between w-full items-center", children: [
|
|
22
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground text-center sm:text-left whitespace-nowrap", children: formatLabel(labels.showing, {
|
|
23
|
+
start: (pagination.page - 1) * pagination.pageSize + 1,
|
|
24
|
+
end: Math.min(pagination.page * pagination.pageSize, pagination.total),
|
|
25
|
+
total: pagination.total
|
|
26
|
+
}) }),
|
|
27
|
+
/* @__PURE__ */ jsx(PaginationItem, { children: /* @__PURE__ */ jsxs(
|
|
28
|
+
PaginationPrevious,
|
|
29
|
+
{
|
|
30
|
+
href: "#",
|
|
31
|
+
onClick: (e) => {
|
|
32
|
+
e.preventDefault();
|
|
33
|
+
if (pagination.page > 1) pagination.onPageChange(pagination.page - 1);
|
|
34
|
+
},
|
|
35
|
+
className: pagination.page <= 1 ? "pointer-events-none opacity-50" : "",
|
|
36
|
+
children: [
|
|
37
|
+
/* @__PURE__ */ jsx("span", { className: "hidden sm:inline", children: labels.previous }),
|
|
38
|
+
/* @__PURE__ */ jsx("span", { className: "sm:hidden", children: "\u2190" })
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
) }),
|
|
42
|
+
/* @__PURE__ */ jsx("div", { className: "hidden sm:flex", children: (() => {
|
|
43
|
+
const pages = [];
|
|
44
|
+
if (pagination.page > 3) {
|
|
45
|
+
pages.push(
|
|
46
|
+
/* @__PURE__ */ jsx(PaginationItem, { children: /* @__PURE__ */ jsx(
|
|
47
|
+
PaginationLink,
|
|
48
|
+
{
|
|
49
|
+
href: "#",
|
|
50
|
+
onClick: (e) => {
|
|
51
|
+
e.preventDefault();
|
|
52
|
+
pagination.onPageChange(1);
|
|
53
|
+
},
|
|
54
|
+
children: "1"
|
|
55
|
+
}
|
|
56
|
+
) }, 1)
|
|
57
|
+
);
|
|
58
|
+
if (pagination.page > 4) {
|
|
59
|
+
pages.push(
|
|
60
|
+
/* @__PURE__ */ jsx(PaginationItem, { children: /* @__PURE__ */ jsx(PaginationEllipsis, {}) }, "ellipsis1")
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
for (let i = Math.max(1, pagination.page - 2); i <= Math.min(totalPages, pagination.page + 2); i++) {
|
|
65
|
+
pages.push(
|
|
66
|
+
/* @__PURE__ */ jsx(PaginationItem, { children: /* @__PURE__ */ jsx(
|
|
67
|
+
PaginationLink,
|
|
68
|
+
{
|
|
69
|
+
href: "#",
|
|
70
|
+
isActive: i === pagination.page,
|
|
71
|
+
onClick: (e) => {
|
|
72
|
+
e.preventDefault();
|
|
73
|
+
pagination.onPageChange(i);
|
|
74
|
+
},
|
|
75
|
+
children: i
|
|
76
|
+
}
|
|
77
|
+
) }, i)
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
if (pagination.page < totalPages - 2) {
|
|
81
|
+
if (pagination.page < totalPages - 3) {
|
|
82
|
+
pages.push(
|
|
83
|
+
/* @__PURE__ */ jsx(PaginationItem, { children: /* @__PURE__ */ jsx(PaginationEllipsis, {}) }, "ellipsis2")
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
pages.push(
|
|
87
|
+
/* @__PURE__ */ jsx(PaginationItem, { children: /* @__PURE__ */ jsx(
|
|
88
|
+
PaginationLink,
|
|
89
|
+
{
|
|
90
|
+
href: "#",
|
|
91
|
+
onClick: (e) => {
|
|
92
|
+
e.preventDefault();
|
|
93
|
+
pagination.onPageChange(totalPages);
|
|
94
|
+
},
|
|
95
|
+
children: totalPages
|
|
96
|
+
}
|
|
97
|
+
) }, totalPages)
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
return pages;
|
|
101
|
+
})() }),
|
|
102
|
+
/* @__PURE__ */ jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxs("span", { className: "px-3 py-2 text-sm font-medium", children: [
|
|
103
|
+
pagination.page,
|
|
104
|
+
" / ",
|
|
105
|
+
totalPages
|
|
106
|
+
] }) }),
|
|
107
|
+
/* @__PURE__ */ jsx(PaginationItem, { children: /* @__PURE__ */ jsxs(
|
|
108
|
+
PaginationNext,
|
|
109
|
+
{
|
|
110
|
+
href: "#",
|
|
111
|
+
onClick: (e) => {
|
|
112
|
+
e.preventDefault();
|
|
113
|
+
if (pagination.page < totalPages) pagination.onPageChange(pagination.page + 1);
|
|
114
|
+
},
|
|
115
|
+
className: pagination.page >= totalPages ? "pointer-events-none opacity-50" : "",
|
|
116
|
+
children: [
|
|
117
|
+
/* @__PURE__ */ jsx("span", { className: "hidden sm:inline", children: labels.next }),
|
|
118
|
+
/* @__PURE__ */ jsx("span", { className: "sm:hidden", children: "\u2192" })
|
|
119
|
+
]
|
|
120
|
+
}
|
|
121
|
+
) })
|
|
122
|
+
] }) }) });
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export {
|
|
126
|
+
DataTablePagination
|
|
127
|
+
};
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import {
|
|
2
|
+
formatLabel
|
|
3
|
+
} from "./chunk-NY5QXT33.js";
|
|
4
|
+
import {
|
|
5
|
+
Input
|
|
6
|
+
} from "./chunk-RJUVBBZG.js";
|
|
7
|
+
import {
|
|
8
|
+
Button
|
|
9
|
+
} from "./chunk-L25BNU3E.js";
|
|
10
|
+
|
|
11
|
+
// src/components/ui/data-table/DataTableSearch.tsx
|
|
12
|
+
import { isValidElement } from "react";
|
|
13
|
+
import { Filter } from "lucide-react";
|
|
14
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
15
|
+
function DataTableSearch({
|
|
16
|
+
onSearch,
|
|
17
|
+
onSearchValueChange,
|
|
18
|
+
searchValue,
|
|
19
|
+
searchPlaceholder,
|
|
20
|
+
labels,
|
|
21
|
+
filters,
|
|
22
|
+
onToggleFilters,
|
|
23
|
+
showFilters,
|
|
24
|
+
hasActiveFilters,
|
|
25
|
+
pagination,
|
|
26
|
+
createButton
|
|
27
|
+
}) {
|
|
28
|
+
const handleSearch = (e) => {
|
|
29
|
+
if (e.key === "Enter" && onSearch) {
|
|
30
|
+
onSearch(searchValue);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
const handleSearchClick = () => {
|
|
34
|
+
if (onSearch) {
|
|
35
|
+
onSearch(searchValue);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
const handleSearchInputChange = (value) => {
|
|
39
|
+
if (onSearchValueChange) {
|
|
40
|
+
onSearchValueChange(value);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
return /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-3 p-3 bg-muted rounded-lg", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-row items-center gap-2", children: [
|
|
44
|
+
onSearch && /* @__PURE__ */ jsxs("div", { className: "relative flex-1 min-w-0", children: [
|
|
45
|
+
/* @__PURE__ */ jsx(
|
|
46
|
+
Input,
|
|
47
|
+
{
|
|
48
|
+
"data-testid": "search-input",
|
|
49
|
+
placeholder: searchPlaceholder,
|
|
50
|
+
value: searchValue,
|
|
51
|
+
onChange: (e) => handleSearchInputChange(e.target.value),
|
|
52
|
+
onKeyPress: handleSearch,
|
|
53
|
+
className: "min-w-0 pr-20 h-10"
|
|
54
|
+
}
|
|
55
|
+
),
|
|
56
|
+
/* @__PURE__ */ jsx(
|
|
57
|
+
Button,
|
|
58
|
+
{
|
|
59
|
+
"data-testid": "search-btn",
|
|
60
|
+
size: "sm",
|
|
61
|
+
onClick: handleSearchClick,
|
|
62
|
+
className: "absolute right-1 top-1/2 transform -translate-y-1/2 h-8 px-3 text-sm",
|
|
63
|
+
children: labels.search
|
|
64
|
+
}
|
|
65
|
+
)
|
|
66
|
+
] }),
|
|
67
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 flex-shrink-0", children: [
|
|
68
|
+
filters.length > 0 && onToggleFilters && /* @__PURE__ */ jsxs(
|
|
69
|
+
Button,
|
|
70
|
+
{
|
|
71
|
+
"data-testid": "filter-toggle-btn",
|
|
72
|
+
variant: "outline",
|
|
73
|
+
size: "sm",
|
|
74
|
+
onClick: () => onToggleFilters(!showFilters),
|
|
75
|
+
className: "flex items-center gap-1 h-10 px-3",
|
|
76
|
+
children: [
|
|
77
|
+
/* @__PURE__ */ jsx(Filter, { className: "h-4 w-4" }),
|
|
78
|
+
/* @__PURE__ */ jsx("span", { className: "hidden sm:inline", children: labels.filter }),
|
|
79
|
+
hasActiveFilters && /* @__PURE__ */ jsx("span", { className: "ml-1 bg-primary text-primary-foreground text-xs px-1.5 py-0.5 rounded-full", children: labels.filterActive })
|
|
80
|
+
]
|
|
81
|
+
}
|
|
82
|
+
),
|
|
83
|
+
pagination && /* @__PURE__ */ jsx(
|
|
84
|
+
"select",
|
|
85
|
+
{
|
|
86
|
+
"data-testid": "page-size-select",
|
|
87
|
+
value: pagination.pageSize,
|
|
88
|
+
onChange: (e) => pagination.onPageSizeChange(Number(e.target.value)),
|
|
89
|
+
className: "border rounded px-3 py-2 text-sm bg-background h-10 min-w-[100px]",
|
|
90
|
+
children: (pagination.pageSizeOptions || [10, 20, 50]).map((size) => /* @__PURE__ */ jsx("option", { value: size, children: formatLabel(labels.perPage, { size }) }, size))
|
|
91
|
+
}
|
|
92
|
+
),
|
|
93
|
+
createButton && (isValidElement(createButton) ? createButton : /* @__PURE__ */ jsx(
|
|
94
|
+
Button,
|
|
95
|
+
{
|
|
96
|
+
"data-testid": "create-btn",
|
|
97
|
+
onClick: createButton.onClick,
|
|
98
|
+
variant: "default",
|
|
99
|
+
size: "sm",
|
|
100
|
+
className: "flex-shrink-0 h-10 px-3",
|
|
101
|
+
children: createButton.label
|
|
102
|
+
}
|
|
103
|
+
))
|
|
104
|
+
] })
|
|
105
|
+
] }) });
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export {
|
|
109
|
+
DataTableSearch
|
|
110
|
+
};
|