@wordrhyme/auto-crud 1.3.0 → 1.3.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/index.cjs +1165 -1666
- package/dist/index.d.cts +79 -65
- package/dist/index.d.ts +63 -49
- package/dist/index.js +896 -1396
- package/package.json +5 -9
package/dist/index.cjs
CHANGED
|
@@ -27,8 +27,8 @@ let lucide_react = require("lucide-react");
|
|
|
27
27
|
lucide_react = __toESM(lucide_react);
|
|
28
28
|
let __tanstack_react_table = require("@tanstack/react-table");
|
|
29
29
|
__tanstack_react_table = __toESM(__tanstack_react_table);
|
|
30
|
-
let
|
|
31
|
-
|
|
30
|
+
let __wordrhyme_shadcn = require("@wordrhyme/shadcn");
|
|
31
|
+
__wordrhyme_shadcn = __toESM(__wordrhyme_shadcn);
|
|
32
32
|
let clsx = require("clsx");
|
|
33
33
|
clsx = __toESM(clsx);
|
|
34
34
|
let tailwind_merge = require("tailwind-merge");
|
|
@@ -37,28 +37,16 @@ let react_jsx_runtime = require("react/jsx-runtime");
|
|
|
37
37
|
react_jsx_runtime = __toESM(react_jsx_runtime);
|
|
38
38
|
let nanoid = require("nanoid");
|
|
39
39
|
nanoid = __toESM(nanoid);
|
|
40
|
-
let
|
|
41
|
-
|
|
42
|
-
let __dnd_kit_modifiers = require("@dnd-kit/modifiers");
|
|
43
|
-
__dnd_kit_modifiers = __toESM(__dnd_kit_modifiers);
|
|
44
|
-
let __dnd_kit_sortable = require("@dnd-kit/sortable");
|
|
45
|
-
__dnd_kit_sortable = __toESM(__dnd_kit_sortable);
|
|
46
|
-
let __dnd_kit_utilities = require("@dnd-kit/utilities");
|
|
47
|
-
__dnd_kit_utilities = __toESM(__dnd_kit_utilities);
|
|
48
|
-
let __radix_ui_react_slot = require("@radix-ui/react-slot");
|
|
49
|
-
__radix_ui_react_slot = __toESM(__radix_ui_react_slot);
|
|
50
|
-
let react_dom = require("react-dom");
|
|
51
|
-
react_dom = __toESM(react_dom);
|
|
52
|
-
let __radix_ui_react_direction = require("@radix-ui/react-direction");
|
|
53
|
-
__radix_ui_react_direction = __toESM(__radix_ui_react_direction);
|
|
40
|
+
let __wordrhyme_shadcn_ui = require("@wordrhyme/shadcn-ui");
|
|
41
|
+
__wordrhyme_shadcn_ui = __toESM(__wordrhyme_shadcn_ui);
|
|
54
42
|
let zod = require("zod");
|
|
55
43
|
zod = __toESM(zod);
|
|
56
44
|
let __formily_core = require("@formily/core");
|
|
57
45
|
__formily_core = __toESM(__formily_core);
|
|
58
|
-
let
|
|
59
|
-
|
|
60
|
-
let
|
|
61
|
-
|
|
46
|
+
let __formily_reactive = require("@formily/reactive");
|
|
47
|
+
__formily_reactive = __toESM(__formily_reactive);
|
|
48
|
+
let __wordrhyme_formily_shadcn = require("@wordrhyme/formily-shadcn");
|
|
49
|
+
__wordrhyme_formily_shadcn = __toESM(__wordrhyme_formily_shadcn);
|
|
62
50
|
let sonner = require("sonner");
|
|
63
51
|
sonner = __toESM(sonner);
|
|
64
52
|
let __tanstack_react_query = require("@tanstack/react-query");
|
|
@@ -98,17 +86,17 @@ function DataTablePagination({ table, pageSizeOptions = [
|
|
|
98
86
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
99
87
|
className: "whitespace-nowrap font-medium text-sm",
|
|
100
88
|
children: "Rows per page"
|
|
101
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
89
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Select, {
|
|
102
90
|
value: `${table.getState().pagination.pageSize}`,
|
|
103
91
|
onValueChange: (value) => {
|
|
104
92
|
table.setPageSize(Number(value));
|
|
105
93
|
},
|
|
106
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
94
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.SelectTrigger, {
|
|
107
95
|
className: "h-8 w-18 data-size:h-8",
|
|
108
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
109
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
96
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.SelectValue, { placeholder: table.getState().pagination.pageSize })
|
|
97
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.SelectContent, {
|
|
110
98
|
side: "top",
|
|
111
|
-
children: pageSizeOptions.map((pageSize) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
99
|
+
children: pageSizeOptions.map((pageSize) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.SelectItem, {
|
|
112
100
|
value: `${pageSize}`,
|
|
113
101
|
children: pageSize
|
|
114
102
|
}, pageSize))
|
|
@@ -128,7 +116,7 @@ function DataTablePagination({ table, pageSizeOptions = [
|
|
|
128
116
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
129
117
|
className: "flex items-center space-x-2",
|
|
130
118
|
children: [
|
|
131
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
119
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
132
120
|
"aria-label": "Go to first page",
|
|
133
121
|
variant: "outline",
|
|
134
122
|
size: "icon",
|
|
@@ -137,7 +125,7 @@ function DataTablePagination({ table, pageSizeOptions = [
|
|
|
137
125
|
disabled: !table.getCanPreviousPage(),
|
|
138
126
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronsLeft, {})
|
|
139
127
|
}),
|
|
140
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
128
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
141
129
|
"aria-label": "Go to previous page",
|
|
142
130
|
variant: "outline",
|
|
143
131
|
size: "icon",
|
|
@@ -146,7 +134,7 @@ function DataTablePagination({ table, pageSizeOptions = [
|
|
|
146
134
|
disabled: !table.getCanPreviousPage(),
|
|
147
135
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronLeft, {})
|
|
148
136
|
}),
|
|
149
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
137
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
150
138
|
"aria-label": "Go to next page",
|
|
151
139
|
variant: "outline",
|
|
152
140
|
size: "icon",
|
|
@@ -155,7 +143,7 @@ function DataTablePagination({ table, pageSizeOptions = [
|
|
|
155
143
|
disabled: !table.getCanNextPage(),
|
|
156
144
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronRight, {})
|
|
157
145
|
}),
|
|
158
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
146
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
159
147
|
"aria-label": "Go to last page",
|
|
160
148
|
variant: "outline",
|
|
161
149
|
size: "icon",
|
|
@@ -171,55 +159,6 @@ function DataTablePagination({ table, pageSizeOptions = [
|
|
|
171
159
|
});
|
|
172
160
|
}
|
|
173
161
|
|
|
174
|
-
//#endregion
|
|
175
|
-
//#region src/components/ui/table.tsx
|
|
176
|
-
function Table({ className,...props }) {
|
|
177
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
178
|
-
"data-slot": "table-container",
|
|
179
|
-
className: "relative w-full overflow-x-auto",
|
|
180
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("table", {
|
|
181
|
-
"data-slot": "table",
|
|
182
|
-
className: cn("w-full caption-bottom text-sm", className),
|
|
183
|
-
...props
|
|
184
|
-
})
|
|
185
|
-
});
|
|
186
|
-
}
|
|
187
|
-
function TableHeader({ className,...props }) {
|
|
188
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("thead", {
|
|
189
|
-
"data-slot": "table-header",
|
|
190
|
-
className: cn("[&_tr]:border-b", className),
|
|
191
|
-
...props
|
|
192
|
-
});
|
|
193
|
-
}
|
|
194
|
-
function TableBody({ className,...props }) {
|
|
195
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tbody", {
|
|
196
|
-
"data-slot": "table-body",
|
|
197
|
-
className: cn("[&_tr:last-child]:border-0", className),
|
|
198
|
-
...props
|
|
199
|
-
});
|
|
200
|
-
}
|
|
201
|
-
function TableRow({ className,...props }) {
|
|
202
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tr", {
|
|
203
|
-
"data-slot": "table-row",
|
|
204
|
-
className: cn("border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted", className),
|
|
205
|
-
...props
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
function TableHead({ className,...props }) {
|
|
209
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
|
|
210
|
-
"data-slot": "table-head",
|
|
211
|
-
className: cn("h-10 whitespace-nowrap px-2 text-left align-middle font-medium text-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]", className),
|
|
212
|
-
...props
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
|
-
function TableCell({ className,...props }) {
|
|
216
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
|
|
217
|
-
"data-slot": "table-cell",
|
|
218
|
-
className: cn("whitespace-nowrap p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]", className),
|
|
219
|
-
...props
|
|
220
|
-
});
|
|
221
|
-
}
|
|
222
|
-
|
|
223
162
|
//#endregion
|
|
224
163
|
//#region src/config/data-table.ts
|
|
225
164
|
const dataTableConfig = {
|
|
@@ -452,17 +391,17 @@ function DataTable({ table, actionBar, children, className,...props }) {
|
|
|
452
391
|
children,
|
|
453
392
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
454
393
|
className: "overflow-hidden rounded-md border",
|
|
455
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Table, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableHeader, { children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableRow, { children: headerGroup.headers.map((header) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableHead, {
|
|
394
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Table, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.TableHeader, { children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.TableRow, { children: headerGroup.headers.map((header) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.TableHead, {
|
|
456
395
|
colSpan: header.colSpan,
|
|
457
396
|
style: { ...getColumnPinningStyle({ column: header.column }) },
|
|
458
397
|
children: header.isPlaceholder ? null : (0, __tanstack_react_table.flexRender)(header.column.columnDef.header, header.getContext())
|
|
459
|
-
}, header.id)) }, headerGroup.id)) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableBody, { children: table.getRowModel().rows?.length ? table.getRowModel().rows.map((row) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableRow, {
|
|
398
|
+
}, header.id)) }, headerGroup.id)) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.TableBody, { children: table.getRowModel().rows?.length ? table.getRowModel().rows.map((row) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.TableRow, {
|
|
460
399
|
"data-state": row.getIsSelected() && "selected",
|
|
461
|
-
children: row.getVisibleCells().map((cell) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableCell, {
|
|
400
|
+
children: row.getVisibleCells().map((cell) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.TableCell, {
|
|
462
401
|
style: { ...getColumnPinningStyle({ column: cell.column }) },
|
|
463
402
|
children: (0, __tanstack_react_table.flexRender)(cell.column.columnDef.cell, cell.getContext())
|
|
464
403
|
}, cell.id))
|
|
465
|
-
}, row.id)) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableRow, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableCell, {
|
|
404
|
+
}, row.id)) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.TableRow, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.TableCell, {
|
|
466
405
|
colSpan: table.getAllColumns().length,
|
|
467
406
|
className: "h-24 text-center",
|
|
468
407
|
children: "No results."
|
|
@@ -916,7 +855,7 @@ function DataTableRangeFilter({ filter, column, inputId, onFilterUpdate, classNa
|
|
|
916
855
|
className: cn("flex w-full items-center gap-2", className),
|
|
917
856
|
...props,
|
|
918
857
|
children: [
|
|
919
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
858
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Input, {
|
|
920
859
|
id: `${inputId}-min`,
|
|
921
860
|
type: "number",
|
|
922
861
|
"aria-label": `${meta?.label} minimum value`,
|
|
@@ -935,7 +874,7 @@ function DataTableRangeFilter({ filter, column, inputId, onFilterUpdate, classNa
|
|
|
935
874
|
className: "sr-only shrink-0 text-muted-foreground",
|
|
936
875
|
children: "to"
|
|
937
876
|
}),
|
|
938
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
877
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Input, {
|
|
939
878
|
id: `${inputId}-max`,
|
|
940
879
|
type: "number",
|
|
941
880
|
"aria-label": `${meta?.label} maximum value`,
|
|
@@ -954,454 +893,6 @@ function DataTableRangeFilter({ filter, column, inputId, onFilterUpdate, classNa
|
|
|
954
893
|
});
|
|
955
894
|
}
|
|
956
895
|
|
|
957
|
-
//#endregion
|
|
958
|
-
//#region src/components/ui/faceted.tsx
|
|
959
|
-
const FacetedContext = react.createContext(null);
|
|
960
|
-
function useFacetedContext(name) {
|
|
961
|
-
const context = react.useContext(FacetedContext);
|
|
962
|
-
if (!context) throw new Error(`\`${name}\` must be within Faceted`);
|
|
963
|
-
return context;
|
|
964
|
-
}
|
|
965
|
-
function Faceted(props) {
|
|
966
|
-
const { open: openProp, onOpenChange: onOpenChangeProp, value, onValueChange, children, multiple = false,...facetedProps } = props;
|
|
967
|
-
const [uncontrolledOpen, setUncontrolledOpen] = react.useState(false);
|
|
968
|
-
const isControlled = openProp !== void 0;
|
|
969
|
-
const open = isControlled ? openProp : uncontrolledOpen;
|
|
970
|
-
const onOpenChange = react.useCallback((newOpen) => {
|
|
971
|
-
if (!isControlled) setUncontrolledOpen(newOpen);
|
|
972
|
-
onOpenChangeProp?.(newOpen);
|
|
973
|
-
}, [isControlled, onOpenChangeProp]);
|
|
974
|
-
const onItemSelect = react.useCallback((selectedValue) => {
|
|
975
|
-
if (!onValueChange) return;
|
|
976
|
-
if (multiple) {
|
|
977
|
-
const currentValue = Array.isArray(value) ? value : [];
|
|
978
|
-
onValueChange(currentValue.includes(selectedValue) ? currentValue.filter((v) => v !== selectedValue) : [...currentValue, selectedValue]);
|
|
979
|
-
} else {
|
|
980
|
-
if (value === selectedValue) onValueChange(void 0);
|
|
981
|
-
else onValueChange(selectedValue);
|
|
982
|
-
requestAnimationFrame(() => onOpenChange(false));
|
|
983
|
-
}
|
|
984
|
-
}, [
|
|
985
|
-
multiple,
|
|
986
|
-
value,
|
|
987
|
-
onValueChange,
|
|
988
|
-
onOpenChange
|
|
989
|
-
]);
|
|
990
|
-
const contextValue = react.useMemo(() => ({
|
|
991
|
-
value,
|
|
992
|
-
onItemSelect,
|
|
993
|
-
multiple
|
|
994
|
-
}), [
|
|
995
|
-
value,
|
|
996
|
-
onItemSelect,
|
|
997
|
-
multiple
|
|
998
|
-
]);
|
|
999
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FacetedContext.Provider, {
|
|
1000
|
-
value: contextValue,
|
|
1001
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.Popover, {
|
|
1002
|
-
open,
|
|
1003
|
-
onOpenChange,
|
|
1004
|
-
...facetedProps,
|
|
1005
|
-
children
|
|
1006
|
-
})
|
|
1007
|
-
});
|
|
1008
|
-
}
|
|
1009
|
-
function FacetedTrigger(props) {
|
|
1010
|
-
const { className, children,...triggerProps } = props;
|
|
1011
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.PopoverTrigger, {
|
|
1012
|
-
...triggerProps,
|
|
1013
|
-
className: cn("justify-between text-left", className),
|
|
1014
|
-
children
|
|
1015
|
-
});
|
|
1016
|
-
}
|
|
1017
|
-
function FacetedBadgeList(props) {
|
|
1018
|
-
const { options = [], max = 2, placeholder = "Select options...", className, badgeClassName,...badgeListProps } = props;
|
|
1019
|
-
const context = useFacetedContext("FacetedBadgeList");
|
|
1020
|
-
const values = Array.isArray(context.value) ? context.value : [context.value].filter(Boolean);
|
|
1021
|
-
const getLabel = react.useCallback((value) => {
|
|
1022
|
-
return options.find((opt) => opt.value === value)?.label ?? value;
|
|
1023
|
-
}, [options]);
|
|
1024
|
-
if (!values || values.length === 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1025
|
-
...badgeListProps,
|
|
1026
|
-
className: "flex w-full items-center gap-1 text-muted-foreground",
|
|
1027
|
-
children: [placeholder, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronsUpDown, { className: "ml-auto size-4 shrink-0 opacity-50" })]
|
|
1028
|
-
});
|
|
1029
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1030
|
-
...badgeListProps,
|
|
1031
|
-
className: cn("flex flex-wrap items-center gap-1", className),
|
|
1032
|
-
children: values.length > max ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__pixpilot_shadcn.Badge, {
|
|
1033
|
-
variant: "secondary",
|
|
1034
|
-
className: cn("rounded-sm px-1 font-normal", badgeClassName),
|
|
1035
|
-
children: [values.length, " selected"]
|
|
1036
|
-
}) : values.map((value) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.Badge, {
|
|
1037
|
-
variant: "secondary",
|
|
1038
|
-
className: cn("rounded-sm px-1 font-normal", badgeClassName),
|
|
1039
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1040
|
-
className: "truncate",
|
|
1041
|
-
children: getLabel(value)
|
|
1042
|
-
})
|
|
1043
|
-
}, value))
|
|
1044
|
-
});
|
|
1045
|
-
}
|
|
1046
|
-
function FacetedContent(props) {
|
|
1047
|
-
const { className, children,...contentProps } = props;
|
|
1048
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.PopoverContent, {
|
|
1049
|
-
...contentProps,
|
|
1050
|
-
align: "start",
|
|
1051
|
-
className: cn("w-[200px] origin-(--radix-popover-content-transform-origin) p-0", className),
|
|
1052
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.Command, { children })
|
|
1053
|
-
});
|
|
1054
|
-
}
|
|
1055
|
-
const FacetedInput = __pixpilot_shadcn.CommandInput;
|
|
1056
|
-
const FacetedList = __pixpilot_shadcn.CommandList;
|
|
1057
|
-
const FacetedEmpty = __pixpilot_shadcn.CommandEmpty;
|
|
1058
|
-
const FacetedGroup = __pixpilot_shadcn.CommandGroup;
|
|
1059
|
-
function FacetedItem(props) {
|
|
1060
|
-
const { value, onSelect, className, children,...itemProps } = props;
|
|
1061
|
-
const context = useFacetedContext("FacetedItem");
|
|
1062
|
-
const isSelected = context.multiple ? Array.isArray(context.value) && context.value.includes(value) : context.value === value;
|
|
1063
|
-
const onItemSelect = react.useCallback((currentValue) => {
|
|
1064
|
-
if (onSelect) onSelect(currentValue);
|
|
1065
|
-
else if (context.onItemSelect) context.onItemSelect(currentValue);
|
|
1066
|
-
}, [onSelect, context]);
|
|
1067
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__pixpilot_shadcn.CommandItem, {
|
|
1068
|
-
value,
|
|
1069
|
-
"aria-selected": isSelected,
|
|
1070
|
-
"data-selected": isSelected,
|
|
1071
|
-
className: cn("gap-2", className),
|
|
1072
|
-
onSelect: () => onItemSelect(value),
|
|
1073
|
-
...itemProps,
|
|
1074
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1075
|
-
className: cn("flex size-4 items-center justify-center rounded-sm border border-primary", isSelected ? "bg-primary text-primary-foreground" : "opacity-50 [&_svg]:invisible"),
|
|
1076
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Check, { className: "size-4" })
|
|
1077
|
-
}), children]
|
|
1078
|
-
});
|
|
1079
|
-
}
|
|
1080
|
-
|
|
1081
|
-
//#endregion
|
|
1082
|
-
//#region src/lib/compose-refs.ts
|
|
1083
|
-
/**
|
|
1084
|
-
* Set a given ref to a given value
|
|
1085
|
-
* This utility takes care of different types of refs: callback refs and RefObject(s)
|
|
1086
|
-
*/
|
|
1087
|
-
function setRef(ref, value) {
|
|
1088
|
-
if (typeof ref === "function") return ref(value);
|
|
1089
|
-
if (ref !== null && ref !== void 0) ref.current = value;
|
|
1090
|
-
}
|
|
1091
|
-
/**
|
|
1092
|
-
* A utility to compose multiple refs together
|
|
1093
|
-
* Accepts callback refs and RefObject(s)
|
|
1094
|
-
*/
|
|
1095
|
-
function composeRefs(...refs) {
|
|
1096
|
-
return (node) => {
|
|
1097
|
-
let hasCleanup = false;
|
|
1098
|
-
const cleanups = refs.map((ref) => {
|
|
1099
|
-
const cleanup = setRef(ref, node);
|
|
1100
|
-
if (!hasCleanup && typeof cleanup === "function") hasCleanup = true;
|
|
1101
|
-
return cleanup;
|
|
1102
|
-
});
|
|
1103
|
-
if (hasCleanup) return () => {
|
|
1104
|
-
for (let i = 0; i < cleanups.length; i++) {
|
|
1105
|
-
const cleanup = cleanups[i];
|
|
1106
|
-
if (typeof cleanup === "function") cleanup();
|
|
1107
|
-
else setRef(refs[i], null);
|
|
1108
|
-
}
|
|
1109
|
-
};
|
|
1110
|
-
};
|
|
1111
|
-
}
|
|
1112
|
-
/**
|
|
1113
|
-
* A custom hook that composes multiple refs
|
|
1114
|
-
* Accepts callback refs and RefObject(s)
|
|
1115
|
-
*/
|
|
1116
|
-
function useComposedRefs(...refs) {
|
|
1117
|
-
return react.useCallback(composeRefs(...refs), refs);
|
|
1118
|
-
}
|
|
1119
|
-
|
|
1120
|
-
//#endregion
|
|
1121
|
-
//#region src/components/ui/sortable.tsx
|
|
1122
|
-
const orientationConfig = {
|
|
1123
|
-
vertical: {
|
|
1124
|
-
modifiers: [__dnd_kit_modifiers.restrictToVerticalAxis, __dnd_kit_modifiers.restrictToParentElement],
|
|
1125
|
-
strategy: __dnd_kit_sortable.verticalListSortingStrategy,
|
|
1126
|
-
collisionDetection: __dnd_kit_core.closestCenter
|
|
1127
|
-
},
|
|
1128
|
-
horizontal: {
|
|
1129
|
-
modifiers: [__dnd_kit_modifiers.restrictToHorizontalAxis, __dnd_kit_modifiers.restrictToParentElement],
|
|
1130
|
-
strategy: __dnd_kit_sortable.horizontalListSortingStrategy,
|
|
1131
|
-
collisionDetection: __dnd_kit_core.closestCenter
|
|
1132
|
-
},
|
|
1133
|
-
mixed: {
|
|
1134
|
-
modifiers: [__dnd_kit_modifiers.restrictToParentElement],
|
|
1135
|
-
strategy: void 0,
|
|
1136
|
-
collisionDetection: __dnd_kit_core.closestCorners
|
|
1137
|
-
}
|
|
1138
|
-
};
|
|
1139
|
-
const ROOT_NAME$1 = "Sortable";
|
|
1140
|
-
const CONTENT_NAME = "SortableContent";
|
|
1141
|
-
const ITEM_NAME$1 = "SortableItem";
|
|
1142
|
-
const ITEM_HANDLE_NAME = "SortableItemHandle";
|
|
1143
|
-
const OVERLAY_NAME = "SortableOverlay";
|
|
1144
|
-
const SortableRootContext = react.createContext(null);
|
|
1145
|
-
function useSortableContext(consumerName) {
|
|
1146
|
-
const context = react.useContext(SortableRootContext);
|
|
1147
|
-
if (!context) throw new Error(`\`${consumerName}\` must be used within \`${ROOT_NAME$1}\``);
|
|
1148
|
-
return context;
|
|
1149
|
-
}
|
|
1150
|
-
function SortableRoot(props) {
|
|
1151
|
-
const { value, onValueChange, collisionDetection, modifiers, strategy, onMove, orientation = "vertical", flatCursor = false, getItemValue: getItemValueProp, accessibility, onDragStart: onDragStartProp, onDragEnd: onDragEndProp, onDragCancel: onDragCancelProp,...sortableProps } = props;
|
|
1152
|
-
const id = react.useId();
|
|
1153
|
-
const [activeId, setActiveId] = react.useState(null);
|
|
1154
|
-
const sensors = (0, __dnd_kit_core.useSensors)((0, __dnd_kit_core.useSensor)(__dnd_kit_core.MouseSensor), (0, __dnd_kit_core.useSensor)(__dnd_kit_core.TouchSensor), (0, __dnd_kit_core.useSensor)(__dnd_kit_core.KeyboardSensor, { coordinateGetter: __dnd_kit_sortable.sortableKeyboardCoordinates }));
|
|
1155
|
-
const config = react.useMemo(() => orientationConfig[orientation], [orientation]);
|
|
1156
|
-
const getItemValue = react.useCallback((item) => {
|
|
1157
|
-
if (typeof item === "object" && !getItemValueProp) throw new Error("getItemValue is required when using array of objects");
|
|
1158
|
-
return getItemValueProp ? getItemValueProp(item) : item;
|
|
1159
|
-
}, [getItemValueProp]);
|
|
1160
|
-
const items = react.useMemo(() => {
|
|
1161
|
-
return value.map((item) => getItemValue(item));
|
|
1162
|
-
}, [value, getItemValue]);
|
|
1163
|
-
const onDragStart = react.useCallback((event) => {
|
|
1164
|
-
onDragStartProp?.(event);
|
|
1165
|
-
if (event.activatorEvent.defaultPrevented) return;
|
|
1166
|
-
setActiveId(event.active.id);
|
|
1167
|
-
}, [onDragStartProp]);
|
|
1168
|
-
const onDragEnd = react.useCallback((event) => {
|
|
1169
|
-
onDragEndProp?.(event);
|
|
1170
|
-
if (event.activatorEvent.defaultPrevented) return;
|
|
1171
|
-
const { active, over } = event;
|
|
1172
|
-
if (over && active.id !== over?.id) {
|
|
1173
|
-
const activeIndex = value.findIndex((item) => getItemValue(item) === active.id);
|
|
1174
|
-
const overIndex = value.findIndex((item) => getItemValue(item) === over.id);
|
|
1175
|
-
if (onMove) onMove({
|
|
1176
|
-
...event,
|
|
1177
|
-
activeIndex,
|
|
1178
|
-
overIndex
|
|
1179
|
-
});
|
|
1180
|
-
else onValueChange?.((0, __dnd_kit_sortable.arrayMove)(value, activeIndex, overIndex));
|
|
1181
|
-
}
|
|
1182
|
-
setActiveId(null);
|
|
1183
|
-
}, [
|
|
1184
|
-
value,
|
|
1185
|
-
onValueChange,
|
|
1186
|
-
onMove,
|
|
1187
|
-
getItemValue,
|
|
1188
|
-
onDragEndProp
|
|
1189
|
-
]);
|
|
1190
|
-
const onDragCancel = react.useCallback((event) => {
|
|
1191
|
-
onDragCancelProp?.(event);
|
|
1192
|
-
if (event.activatorEvent.defaultPrevented) return;
|
|
1193
|
-
setActiveId(null);
|
|
1194
|
-
}, [onDragCancelProp]);
|
|
1195
|
-
const announcements = react.useMemo(() => ({
|
|
1196
|
-
onDragStart({ active }) {
|
|
1197
|
-
return `Grabbed sortable item "${active.id.toString()}". Current position is ${active.data.current?.sortable.index + 1} of ${value.length}. Use arrow keys to move, space to drop.`;
|
|
1198
|
-
},
|
|
1199
|
-
onDragOver({ active, over }) {
|
|
1200
|
-
if (over) {
|
|
1201
|
-
const overIndex = over.data.current?.sortable.index ?? 0;
|
|
1202
|
-
const moveDirection = overIndex > (active.data.current?.sortable.index ?? 0) ? "down" : "up";
|
|
1203
|
-
return `Sortable item "${active.id.toString()}" moved ${moveDirection} to position ${overIndex + 1} of ${value.length}.`;
|
|
1204
|
-
}
|
|
1205
|
-
return "Sortable item is no longer over a droppable area. Press escape to cancel.";
|
|
1206
|
-
},
|
|
1207
|
-
onDragEnd({ active, over }) {
|
|
1208
|
-
const activeValue = active.id.toString();
|
|
1209
|
-
if (over) return `Sortable item "${activeValue}" dropped at position ${(over.data.current?.sortable.index ?? 0) + 1} of ${value.length}.`;
|
|
1210
|
-
return `Sortable item "${activeValue}" dropped. No changes were made.`;
|
|
1211
|
-
},
|
|
1212
|
-
onDragCancel({ active }) {
|
|
1213
|
-
const activeIndex = active.data.current?.sortable.index ?? 0;
|
|
1214
|
-
return `Sorting cancelled. Sortable item "${active.id.toString()}" returned to position ${activeIndex + 1} of ${value.length}.`;
|
|
1215
|
-
},
|
|
1216
|
-
onDragMove({ active, over }) {
|
|
1217
|
-
if (over) {
|
|
1218
|
-
const overIndex = over.data.current?.sortable.index ?? 0;
|
|
1219
|
-
const moveDirection = overIndex > (active.data.current?.sortable.index ?? 0) ? "down" : "up";
|
|
1220
|
-
return `Sortable item "${active.id.toString()}" is moving ${moveDirection} to position ${overIndex + 1} of ${value.length}.`;
|
|
1221
|
-
}
|
|
1222
|
-
return "Sortable item is no longer over a droppable area. Press escape to cancel.";
|
|
1223
|
-
}
|
|
1224
|
-
}), [value]);
|
|
1225
|
-
const screenReaderInstructions = react.useMemo(() => ({ draggable: `
|
|
1226
|
-
To pick up a sortable item, press space or enter.
|
|
1227
|
-
While dragging, use the ${orientation === "vertical" ? "up and down" : orientation === "horizontal" ? "left and right" : "arrow"} keys to move the item.
|
|
1228
|
-
Press space or enter again to drop the item in its new position, or press escape to cancel.
|
|
1229
|
-
` }), [orientation]);
|
|
1230
|
-
const contextValue = react.useMemo(() => ({
|
|
1231
|
-
id,
|
|
1232
|
-
items,
|
|
1233
|
-
modifiers: modifiers ?? config.modifiers,
|
|
1234
|
-
strategy: strategy ?? config.strategy,
|
|
1235
|
-
activeId,
|
|
1236
|
-
setActiveId,
|
|
1237
|
-
getItemValue,
|
|
1238
|
-
flatCursor
|
|
1239
|
-
}), [
|
|
1240
|
-
id,
|
|
1241
|
-
items,
|
|
1242
|
-
modifiers,
|
|
1243
|
-
strategy,
|
|
1244
|
-
config.modifiers,
|
|
1245
|
-
config.strategy,
|
|
1246
|
-
activeId,
|
|
1247
|
-
getItemValue,
|
|
1248
|
-
flatCursor
|
|
1249
|
-
]);
|
|
1250
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SortableRootContext.Provider, {
|
|
1251
|
-
value: contextValue,
|
|
1252
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__dnd_kit_core.DndContext, {
|
|
1253
|
-
collisionDetection: collisionDetection ?? config.collisionDetection,
|
|
1254
|
-
modifiers: modifiers ?? config.modifiers,
|
|
1255
|
-
sensors,
|
|
1256
|
-
...sortableProps,
|
|
1257
|
-
id,
|
|
1258
|
-
onDragStart,
|
|
1259
|
-
onDragEnd,
|
|
1260
|
-
onDragCancel,
|
|
1261
|
-
accessibility: {
|
|
1262
|
-
announcements,
|
|
1263
|
-
screenReaderInstructions,
|
|
1264
|
-
...accessibility
|
|
1265
|
-
}
|
|
1266
|
-
})
|
|
1267
|
-
});
|
|
1268
|
-
}
|
|
1269
|
-
const SortableContentContext = react.createContext(false);
|
|
1270
|
-
function SortableContent(props) {
|
|
1271
|
-
const { strategy: strategyProp, asChild, withoutSlot, children, ref,...contentProps } = props;
|
|
1272
|
-
const context = useSortableContext(CONTENT_NAME);
|
|
1273
|
-
const ContentPrimitive = asChild ? __radix_ui_react_slot.Slot : "div";
|
|
1274
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SortableContentContext.Provider, {
|
|
1275
|
-
value: true,
|
|
1276
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__dnd_kit_sortable.SortableContext, {
|
|
1277
|
-
items: context.items,
|
|
1278
|
-
strategy: strategyProp ?? context.strategy,
|
|
1279
|
-
children: withoutSlot ? children : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ContentPrimitive, {
|
|
1280
|
-
"data-slot": "sortable-content",
|
|
1281
|
-
...contentProps,
|
|
1282
|
-
ref,
|
|
1283
|
-
children
|
|
1284
|
-
})
|
|
1285
|
-
})
|
|
1286
|
-
});
|
|
1287
|
-
}
|
|
1288
|
-
const SortableItemContext = react.createContext(null);
|
|
1289
|
-
function useSortableItemContext(consumerName) {
|
|
1290
|
-
const context = react.useContext(SortableItemContext);
|
|
1291
|
-
if (!context) throw new Error(`\`${consumerName}\` must be used within \`${ITEM_NAME$1}\``);
|
|
1292
|
-
return context;
|
|
1293
|
-
}
|
|
1294
|
-
function SortableItem(props) {
|
|
1295
|
-
const { value, style, asHandle, asChild, disabled, className, ref,...itemProps } = props;
|
|
1296
|
-
const inSortableContent = react.useContext(SortableContentContext);
|
|
1297
|
-
const inSortableOverlay = react.useContext(SortableOverlayContext);
|
|
1298
|
-
if (!inSortableContent && !inSortableOverlay) throw new Error(`\`${ITEM_NAME$1}\` must be used within \`${CONTENT_NAME}\` or \`${OVERLAY_NAME}\``);
|
|
1299
|
-
if (value === "") throw new Error(`\`${ITEM_NAME$1}\` value cannot be an empty string`);
|
|
1300
|
-
const context = useSortableContext(ITEM_NAME$1);
|
|
1301
|
-
const id = react.useId();
|
|
1302
|
-
const { attributes, listeners: listeners$1, setNodeRef, setActivatorNodeRef, transform, transition, isDragging } = (0, __dnd_kit_sortable.useSortable)({
|
|
1303
|
-
id: value,
|
|
1304
|
-
disabled
|
|
1305
|
-
});
|
|
1306
|
-
const composedRef = useComposedRefs(ref, (node) => {
|
|
1307
|
-
if (disabled) return;
|
|
1308
|
-
setNodeRef(node);
|
|
1309
|
-
if (asHandle) setActivatorNodeRef(node);
|
|
1310
|
-
});
|
|
1311
|
-
const composedStyle = react.useMemo(() => {
|
|
1312
|
-
return {
|
|
1313
|
-
transform: __dnd_kit_utilities.CSS.Translate.toString(transform),
|
|
1314
|
-
transition,
|
|
1315
|
-
...style
|
|
1316
|
-
};
|
|
1317
|
-
}, [
|
|
1318
|
-
transform,
|
|
1319
|
-
transition,
|
|
1320
|
-
style
|
|
1321
|
-
]);
|
|
1322
|
-
const itemContext = react.useMemo(() => ({
|
|
1323
|
-
id,
|
|
1324
|
-
attributes,
|
|
1325
|
-
listeners: listeners$1,
|
|
1326
|
-
setActivatorNodeRef,
|
|
1327
|
-
isDragging,
|
|
1328
|
-
disabled
|
|
1329
|
-
}), [
|
|
1330
|
-
id,
|
|
1331
|
-
attributes,
|
|
1332
|
-
listeners$1,
|
|
1333
|
-
setActivatorNodeRef,
|
|
1334
|
-
isDragging,
|
|
1335
|
-
disabled
|
|
1336
|
-
]);
|
|
1337
|
-
const ItemPrimitive = asChild ? __radix_ui_react_slot.Slot : "div";
|
|
1338
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SortableItemContext.Provider, {
|
|
1339
|
-
value: itemContext,
|
|
1340
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ItemPrimitive, {
|
|
1341
|
-
id,
|
|
1342
|
-
"data-disabled": disabled,
|
|
1343
|
-
"data-dragging": isDragging ? "" : void 0,
|
|
1344
|
-
"data-slot": "sortable-item",
|
|
1345
|
-
...itemProps,
|
|
1346
|
-
...asHandle && !disabled ? attributes : {},
|
|
1347
|
-
...asHandle && !disabled ? listeners$1 : {},
|
|
1348
|
-
ref: composedRef,
|
|
1349
|
-
style: composedStyle,
|
|
1350
|
-
className: cn("focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1", {
|
|
1351
|
-
"touch-none select-none": asHandle,
|
|
1352
|
-
"cursor-default": context.flatCursor,
|
|
1353
|
-
"data-dragging:cursor-grabbing": !context.flatCursor,
|
|
1354
|
-
"cursor-grab": !isDragging && asHandle && !context.flatCursor,
|
|
1355
|
-
"opacity-50": isDragging,
|
|
1356
|
-
"pointer-events-none opacity-50": disabled
|
|
1357
|
-
}, className)
|
|
1358
|
-
})
|
|
1359
|
-
});
|
|
1360
|
-
}
|
|
1361
|
-
function SortableItemHandle(props) {
|
|
1362
|
-
const { asChild, disabled, className, ref,...itemHandleProps } = props;
|
|
1363
|
-
const context = useSortableContext(ITEM_HANDLE_NAME);
|
|
1364
|
-
const itemContext = useSortableItemContext(ITEM_HANDLE_NAME);
|
|
1365
|
-
const isDisabled = disabled ?? itemContext.disabled;
|
|
1366
|
-
const composedRef = useComposedRefs(ref, (node) => {
|
|
1367
|
-
if (!isDisabled) return;
|
|
1368
|
-
itemContext.setActivatorNodeRef(node);
|
|
1369
|
-
});
|
|
1370
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(asChild ? __radix_ui_react_slot.Slot : "button", {
|
|
1371
|
-
type: "button",
|
|
1372
|
-
"aria-controls": itemContext.id,
|
|
1373
|
-
"data-disabled": isDisabled,
|
|
1374
|
-
"data-dragging": itemContext.isDragging ? "" : void 0,
|
|
1375
|
-
"data-slot": "sortable-item-handle",
|
|
1376
|
-
...itemHandleProps,
|
|
1377
|
-
...isDisabled ? {} : itemContext.attributes,
|
|
1378
|
-
...isDisabled ? {} : itemContext.listeners,
|
|
1379
|
-
ref: composedRef,
|
|
1380
|
-
className: cn("select-none disabled:pointer-events-none disabled:opacity-50", context.flatCursor ? "cursor-default" : "cursor-grab data-dragging:cursor-grabbing", className),
|
|
1381
|
-
disabled: isDisabled
|
|
1382
|
-
});
|
|
1383
|
-
}
|
|
1384
|
-
const SortableOverlayContext = react.createContext(false);
|
|
1385
|
-
const dropAnimation = { sideEffects: (0, __dnd_kit_core.defaultDropAnimationSideEffects)({ styles: { active: { opacity: "0.4" } } }) };
|
|
1386
|
-
function SortableOverlay(props) {
|
|
1387
|
-
const { container: containerProp, children,...overlayProps } = props;
|
|
1388
|
-
const context = useSortableContext(OVERLAY_NAME);
|
|
1389
|
-
const [mounted, setMounted] = react.useState(false);
|
|
1390
|
-
react.useLayoutEffect(() => setMounted(true), []);
|
|
1391
|
-
const container = containerProp ?? (mounted ? globalThis.document?.body : null);
|
|
1392
|
-
if (!container) return null;
|
|
1393
|
-
return react_dom.createPortal(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__dnd_kit_core.DragOverlay, {
|
|
1394
|
-
dropAnimation,
|
|
1395
|
-
modifiers: context.modifiers,
|
|
1396
|
-
className: cn(!context.flatCursor && "cursor-grabbing"),
|
|
1397
|
-
...overlayProps,
|
|
1398
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SortableOverlayContext.Provider, {
|
|
1399
|
-
value: true,
|
|
1400
|
-
children: context.activeId ? typeof children === "function" ? children({ value: context.activeId }) : children : null
|
|
1401
|
-
})
|
|
1402
|
-
}), container);
|
|
1403
|
-
}
|
|
1404
|
-
|
|
1405
896
|
//#endregion
|
|
1406
897
|
//#region src/hooks/use-callback-ref.ts
|
|
1407
898
|
/**
|
|
@@ -1518,16 +1009,16 @@ function DataTableFilterList({ table, debounceMs = DEBOUNCE_MS$2, throttleMs = T
|
|
|
1518
1009
|
window.addEventListener("keydown", onKeyDown);
|
|
1519
1010
|
return () => window.removeEventListener("keydown", onKeyDown);
|
|
1520
1011
|
}, []);
|
|
1521
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
1012
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn_ui.Sortable, {
|
|
1522
1013
|
value: filters,
|
|
1523
1014
|
onValueChange: setFilters,
|
|
1524
1015
|
getItemValue: (item) => item.filterId,
|
|
1525
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
1016
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Popover, {
|
|
1526
1017
|
open,
|
|
1527
1018
|
onOpenChange: setOpen,
|
|
1528
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1019
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.PopoverTrigger, {
|
|
1529
1020
|
asChild: true,
|
|
1530
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
1021
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
1531
1022
|
variant: "outline",
|
|
1532
1023
|
size: "sm",
|
|
1533
1024
|
className: "font-normal",
|
|
@@ -1541,14 +1032,14 @@ function DataTableFilterList({ table, debounceMs = DEBOUNCE_MS$2, throttleMs = T
|
|
|
1541
1032
|
children: [
|
|
1542
1033
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ListFilter, { className: "text-muted-foreground" }),
|
|
1543
1034
|
"Filter",
|
|
1544
|
-
filters.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1035
|
+
filters.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Badge, {
|
|
1545
1036
|
variant: "secondary",
|
|
1546
1037
|
className: "h-[18.24px] rounded-[3.2px] px-[5.12px] font-mono font-normal text-[10.4px]",
|
|
1547
1038
|
children: filters.length
|
|
1548
1039
|
})
|
|
1549
1040
|
]
|
|
1550
1041
|
})
|
|
1551
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
1042
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.PopoverContent, {
|
|
1552
1043
|
"aria-describedby": descriptionId,
|
|
1553
1044
|
"aria-labelledby": labelId,
|
|
1554
1045
|
className: "flex w-full max-w-(--radix-popover-content-available-width) flex-col gap-3.5 p-4 sm:min-w-[380px]",
|
|
@@ -1566,7 +1057,7 @@ function DataTableFilterList({ table, debounceMs = DEBOUNCE_MS$2, throttleMs = T
|
|
|
1566
1057
|
children: filters.length > 0 ? "Modify filters to refine your rows." : "Add filters to refine your rows."
|
|
1567
1058
|
})]
|
|
1568
1059
|
}),
|
|
1569
|
-
filters.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SortableContent, {
|
|
1060
|
+
filters.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn_ui.SortableContent, {
|
|
1570
1061
|
asChild: true,
|
|
1571
1062
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1572
1063
|
role: "list",
|
|
@@ -1585,13 +1076,13 @@ function DataTableFilterList({ table, debounceMs = DEBOUNCE_MS$2, throttleMs = T
|
|
|
1585
1076
|
}) : null,
|
|
1586
1077
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1587
1078
|
className: "flex w-full items-center gap-2",
|
|
1588
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1079
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
1589
1080
|
size: "sm",
|
|
1590
1081
|
className: "rounded",
|
|
1591
1082
|
ref: addButtonRef,
|
|
1592
1083
|
onClick: onFilterAdd,
|
|
1593
1084
|
children: "Add filter"
|
|
1594
|
-
}), filters.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1085
|
+
}), filters.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
1595
1086
|
variant: "outline",
|
|
1596
1087
|
size: "sm",
|
|
1597
1088
|
className: "rounded",
|
|
@@ -1601,7 +1092,7 @@ function DataTableFilterList({ table, debounceMs = DEBOUNCE_MS$2, throttleMs = T
|
|
|
1601
1092
|
})
|
|
1602
1093
|
]
|
|
1603
1094
|
})]
|
|
1604
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SortableOverlay, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1095
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn_ui.SortableOverlay, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1605
1096
|
className: "flex items-center gap-2",
|
|
1606
1097
|
children: [
|
|
1607
1098
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "h-8 min-w-[72px] rounded-sm bg-primary/10" }),
|
|
@@ -1640,7 +1131,7 @@ function DataTableFilterItem$1({ filter, index: index$1, filterItemId, joinOpera
|
|
|
1640
1131
|
onFilterRemove
|
|
1641
1132
|
]);
|
|
1642
1133
|
if (!column) return null;
|
|
1643
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SortableItem, {
|
|
1134
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn_ui.SortableItem, {
|
|
1644
1135
|
value: filter.filterId,
|
|
1645
1136
|
asChild: true,
|
|
1646
1137
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -1655,20 +1146,20 @@ function DataTableFilterItem$1({ filter, index: index$1, filterItemId, joinOpera
|
|
|
1655
1146
|
children: index$1 === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1656
1147
|
className: "text-muted-foreground text-sm",
|
|
1657
1148
|
children: "Where"
|
|
1658
|
-
}) : index$1 === 1 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
1149
|
+
}) : index$1 === 1 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Select, {
|
|
1659
1150
|
value: joinOperator,
|
|
1660
1151
|
onValueChange: (value) => setJoinOperator(value),
|
|
1661
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1152
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.SelectTrigger, {
|
|
1662
1153
|
"aria-label": "Select join operator",
|
|
1663
1154
|
"aria-controls": joinOperatorListboxId,
|
|
1664
1155
|
size: "sm",
|
|
1665
1156
|
className: "rounded lowercase",
|
|
1666
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1667
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1157
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.SelectValue, { placeholder: joinOperator })
|
|
1158
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.SelectContent, {
|
|
1668
1159
|
id: joinOperatorListboxId,
|
|
1669
1160
|
position: "popper",
|
|
1670
1161
|
className: "min-w-(--radix-select-trigger-width) lowercase",
|
|
1671
|
-
children: dataTableConfig.joinOperators.map((joinOperator$1) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1162
|
+
children: dataTableConfig.joinOperators.map((joinOperator$1) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.SelectItem, {
|
|
1672
1163
|
value: joinOperator$1,
|
|
1673
1164
|
children: joinOperator$1
|
|
1674
1165
|
}, joinOperator$1))
|
|
@@ -1678,12 +1169,12 @@ function DataTableFilterItem$1({ filter, index: index$1, filterItemId, joinOpera
|
|
|
1678
1169
|
children: joinOperator
|
|
1679
1170
|
})
|
|
1680
1171
|
}),
|
|
1681
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
1172
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Popover, {
|
|
1682
1173
|
open: showFieldSelector,
|
|
1683
1174
|
onOpenChange: setShowFieldSelector,
|
|
1684
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1175
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.PopoverTrigger, {
|
|
1685
1176
|
asChild: true,
|
|
1686
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
1177
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
1687
1178
|
"aria-controls": fieldListboxId,
|
|
1688
1179
|
variant: "outline",
|
|
1689
1180
|
size: "sm",
|
|
@@ -1693,11 +1184,11 @@ function DataTableFilterItem$1({ filter, index: index$1, filterItemId, joinOpera
|
|
|
1693
1184
|
children: columns.find((column$1) => column$1.id === filter.id)?.columnDef.meta?.label ?? "Select field"
|
|
1694
1185
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronsUpDown, { className: "opacity-50" })]
|
|
1695
1186
|
})
|
|
1696
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1187
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.PopoverContent, {
|
|
1697
1188
|
id: fieldListboxId,
|
|
1698
1189
|
align: "start",
|
|
1699
1190
|
className: "w-40 p-0",
|
|
1700
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
1191
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Command, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.CommandInput, { placeholder: "Search fields..." }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.CommandList, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.CommandEmpty, { children: "No fields found." }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.CommandGroup, { children: columns.map((column$1) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.CommandItem, {
|
|
1701
1192
|
value: column$1.id,
|
|
1702
1193
|
onSelect: (value) => {
|
|
1703
1194
|
onFilterUpdate(filter.filterId, {
|
|
@@ -1715,7 +1206,7 @@ function DataTableFilterItem$1({ filter, index: index$1, filterItemId, joinOpera
|
|
|
1715
1206
|
}, column$1.id)) })] })] })
|
|
1716
1207
|
})]
|
|
1717
1208
|
}),
|
|
1718
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
1209
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Select, {
|
|
1719
1210
|
open: showOperatorSelector,
|
|
1720
1211
|
onOpenChange: setShowOperatorSelector,
|
|
1721
1212
|
value: filter.operator,
|
|
@@ -1723,17 +1214,17 @@ function DataTableFilterItem$1({ filter, index: index$1, filterItemId, joinOpera
|
|
|
1723
1214
|
operator: value,
|
|
1724
1215
|
value: value === "isEmpty" || value === "isNotEmpty" ? "" : filter.value
|
|
1725
1216
|
}),
|
|
1726
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1217
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.SelectTrigger, {
|
|
1727
1218
|
"aria-controls": operatorListboxId,
|
|
1728
1219
|
size: "sm",
|
|
1729
1220
|
className: "w-32 rounded lowercase",
|
|
1730
1221
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1731
1222
|
className: "truncate",
|
|
1732
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1223
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.SelectValue, { placeholder: filter.operator })
|
|
1733
1224
|
})
|
|
1734
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1225
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.SelectContent, {
|
|
1735
1226
|
id: operatorListboxId,
|
|
1736
|
-
children: filterOperators.map((operator) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1227
|
+
children: filterOperators.map((operator) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.SelectItem, {
|
|
1737
1228
|
value: operator.value,
|
|
1738
1229
|
className: "lowercase",
|
|
1739
1230
|
children: operator.label
|
|
@@ -1752,7 +1243,7 @@ function DataTableFilterItem$1({ filter, index: index$1, filterItemId, joinOpera
|
|
|
1752
1243
|
setShowValueSelector
|
|
1753
1244
|
})
|
|
1754
1245
|
}),
|
|
1755
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1246
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
1756
1247
|
"aria-controls": filterItemId,
|
|
1757
1248
|
variant: "outline",
|
|
1758
1249
|
size: "icon",
|
|
@@ -1760,9 +1251,9 @@ function DataTableFilterItem$1({ filter, index: index$1, filterItemId, joinOpera
|
|
|
1760
1251
|
onClick: () => onFilterRemove(filter.filterId),
|
|
1761
1252
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Trash2, {})
|
|
1762
1253
|
}),
|
|
1763
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SortableItemHandle, {
|
|
1254
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn_ui.SortableItemHandle, {
|
|
1764
1255
|
asChild: true,
|
|
1765
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1256
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
1766
1257
|
variant: "outline",
|
|
1767
1258
|
size: "icon",
|
|
1768
1259
|
className: "size-8 rounded",
|
|
@@ -1792,7 +1283,7 @@ function onFilterInputRender$1({ filter, inputId, column, columnMeta, onFilterUp
|
|
|
1792
1283
|
onFilterUpdate
|
|
1793
1284
|
});
|
|
1794
1285
|
const isNumber = filter.variant === "number" || filter.variant === "range";
|
|
1795
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1286
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Input, {
|
|
1796
1287
|
id: inputId,
|
|
1797
1288
|
type: isNumber ? "number" : filter.variant,
|
|
1798
1289
|
"aria-label": `${columnMeta?.label} filter value`,
|
|
@@ -1807,24 +1298,24 @@ function onFilterInputRender$1({ filter, inputId, column, columnMeta, onFilterUp
|
|
|
1807
1298
|
case "boolean": {
|
|
1808
1299
|
if (Array.isArray(filter.value)) return null;
|
|
1809
1300
|
const inputListboxId = `${inputId}-listbox`;
|
|
1810
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
1301
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Select, {
|
|
1811
1302
|
open: showValueSelector,
|
|
1812
1303
|
onOpenChange: setShowValueSelector,
|
|
1813
1304
|
value: filter.value,
|
|
1814
1305
|
onValueChange: (value) => onFilterUpdate(filter.filterId, { value }),
|
|
1815
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1306
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.SelectTrigger, {
|
|
1816
1307
|
id: inputId,
|
|
1817
1308
|
"aria-controls": inputListboxId,
|
|
1818
1309
|
"aria-label": `${columnMeta?.label} boolean filter`,
|
|
1819
1310
|
size: "sm",
|
|
1820
1311
|
className: "w-full rounded",
|
|
1821
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1822
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
1312
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.SelectValue, { placeholder: filter.value ? "True" : "False" })
|
|
1313
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.SelectContent, {
|
|
1823
1314
|
id: inputListboxId,
|
|
1824
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1315
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.SelectItem, {
|
|
1825
1316
|
value: "true",
|
|
1826
1317
|
children: "True"
|
|
1827
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1318
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.SelectItem, {
|
|
1828
1319
|
value: "false",
|
|
1829
1320
|
children: "False"
|
|
1830
1321
|
})]
|
|
@@ -1834,8 +1325,9 @@ function onFilterInputRender$1({ filter, inputId, column, columnMeta, onFilterUp
|
|
|
1834
1325
|
case "select":
|
|
1835
1326
|
case "multiSelect": {
|
|
1836
1327
|
const inputListboxId = `${inputId}-listbox`;
|
|
1328
|
+
const optionList = columnMeta?.autoCrudFilterOptions ?? columnMeta?.options;
|
|
1837
1329
|
const multiple = filter.variant === "multiSelect";
|
|
1838
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Faceted, {
|
|
1330
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn_ui.Faceted, {
|
|
1839
1331
|
open: showValueSelector,
|
|
1840
1332
|
onOpenChange: setShowValueSelector,
|
|
1841
1333
|
value: multiple ? Array.isArray(filter.value) ? filter.value : [] : typeof filter.value === "string" ? filter.value : void 0,
|
|
@@ -1843,37 +1335,58 @@ function onFilterInputRender$1({ filter, inputId, column, columnMeta, onFilterUp
|
|
|
1843
1335
|
onFilterUpdate(filter.filterId, { value });
|
|
1844
1336
|
},
|
|
1845
1337
|
multiple,
|
|
1846
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(FacetedTrigger, {
|
|
1338
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn_ui.FacetedTrigger, {
|
|
1847
1339
|
asChild: true,
|
|
1848
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1340
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
1849
1341
|
id: inputId,
|
|
1850
1342
|
"aria-controls": inputListboxId,
|
|
1851
1343
|
"aria-label": `${columnMeta?.label} filter value${multiple ? "s" : ""}`,
|
|
1852
1344
|
variant: "outline",
|
|
1853
1345
|
size: "sm",
|
|
1854
1346
|
className: "w-full rounded font-normal",
|
|
1855
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FacetedBadgeList, {
|
|
1347
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn_ui.FacetedBadgeList, {
|
|
1856
1348
|
options: columnMeta?.options,
|
|
1857
1349
|
placeholder: columnMeta?.placeholder ?? `Select option${multiple ? "s" : ""}...`
|
|
1858
1350
|
})
|
|
1859
1351
|
})
|
|
1860
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(FacetedContent, {
|
|
1352
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn_ui.FacetedContent, {
|
|
1861
1353
|
id: inputListboxId,
|
|
1862
1354
|
className: "w-[200px]",
|
|
1863
|
-
|
|
1355
|
+
commandProps: { shouldFilter: columnMeta?.autoCrudFilterShouldFilter },
|
|
1356
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn_ui.FacetedInput, {
|
|
1864
1357
|
"aria-label": `Search ${columnMeta?.label} options`,
|
|
1865
|
-
placeholder: columnMeta?.placeholder ?? "Search options..."
|
|
1866
|
-
|
|
1867
|
-
|
|
1358
|
+
placeholder: columnMeta?.placeholder ?? "Search options...",
|
|
1359
|
+
value: columnMeta?.autoCrudFilterSearchValue,
|
|
1360
|
+
onValueChange: columnMeta?.autoCrudFilterOnSearch
|
|
1361
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn_ui.FacetedList, {
|
|
1362
|
+
onScroll: columnMeta?.autoCrudFilterOnPopupScroll,
|
|
1868
1363
|
children: [
|
|
1869
|
-
|
|
1870
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1364
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn_ui.FacetedEmpty, { children: "No options found." }),
|
|
1365
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn_ui.FacetedGroup, { children: optionList?.map((option) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn_ui.FacetedItem, {
|
|
1366
|
+
value: option.value,
|
|
1367
|
+
children: [
|
|
1368
|
+
option.icon && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(option.icon, {}),
|
|
1369
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: option.label }),
|
|
1370
|
+
option.count && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1371
|
+
className: "ml-auto font-mono text-xs",
|
|
1372
|
+
children: option.count
|
|
1373
|
+
})
|
|
1374
|
+
]
|
|
1375
|
+
}, option.value)) }),
|
|
1376
|
+
columnMeta?.autoCrudFilterLoading && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn_ui.FacetedGroup, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1377
|
+
role: "status",
|
|
1378
|
+
"aria-live": "polite",
|
|
1379
|
+
className: "py-2 text-center text-sm text-muted-foreground",
|
|
1380
|
+
children: "Loading..."
|
|
1381
|
+
}) }),
|
|
1382
|
+
!columnMeta?.autoCrudFilterLoading && columnMeta?.autoCrudFilterHasMore && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1383
|
+
role: "status",
|
|
1384
|
+
"aria-live": "polite",
|
|
1385
|
+
className: "sr-only",
|
|
1386
|
+
children: "Load more"
|
|
1874
1387
|
})
|
|
1875
1388
|
]
|
|
1876
|
-
}
|
|
1389
|
+
})]
|
|
1877
1390
|
})]
|
|
1878
1391
|
});
|
|
1879
1392
|
}
|
|
@@ -1885,12 +1398,12 @@ function onFilterInputRender$1({ filter, inputId, column, columnMeta, onFilterUp
|
|
|
1885
1398
|
const endDate = dateValue[1] ? new Date(Number(dateValue[1])) : void 0;
|
|
1886
1399
|
const isSameDate = startDate && endDate && startDate.toDateString() === endDate.toDateString();
|
|
1887
1400
|
const displayValue = filter.operator === "isBetween" && dateValue.length === 2 && !isSameDate ? `${formatDate(startDate, { month: "short" })} - ${formatDate(endDate, { month: "short" })}` : startDate ? formatDate(startDate, { month: "short" }) : "Pick a date";
|
|
1888
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
1401
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Popover, {
|
|
1889
1402
|
open: showValueSelector,
|
|
1890
1403
|
onOpenChange: setShowValueSelector,
|
|
1891
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1404
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.PopoverTrigger, {
|
|
1892
1405
|
asChild: true,
|
|
1893
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
1406
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
1894
1407
|
id: inputId,
|
|
1895
1408
|
"aria-controls": inputListboxId,
|
|
1896
1409
|
"aria-label": `${columnMeta?.label} date filter`,
|
|
@@ -1902,11 +1415,11 @@ function onFilterInputRender$1({ filter, inputId, column, columnMeta, onFilterUp
|
|
|
1902
1415
|
children: displayValue
|
|
1903
1416
|
})]
|
|
1904
1417
|
})
|
|
1905
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1418
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.PopoverContent, {
|
|
1906
1419
|
id: inputListboxId,
|
|
1907
1420
|
align: "start",
|
|
1908
1421
|
className: "w-auto p-0",
|
|
1909
|
-
children: filter.operator === "isBetween" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1422
|
+
children: filter.operator === "isBetween" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Calendar, {
|
|
1910
1423
|
"aria-label": `Select ${columnMeta?.label} date range`,
|
|
1911
1424
|
autoFocus: true,
|
|
1912
1425
|
captionLayout: "dropdown",
|
|
@@ -1921,7 +1434,7 @@ function onFilterInputRender$1({ filter, inputId, column, columnMeta, onFilterUp
|
|
|
1921
1434
|
onSelect: (date) => {
|
|
1922
1435
|
onFilterUpdate(filter.filterId, { value: date ? [(date.from?.getTime() ?? "").toString(), (date.to?.getTime() ?? "").toString()] : [] });
|
|
1923
1436
|
}
|
|
1924
|
-
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1437
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Calendar, {
|
|
1925
1438
|
"aria-label": `Select ${columnMeta?.label} date`,
|
|
1926
1439
|
autoFocus: true,
|
|
1927
1440
|
captionLayout: "dropdown",
|
|
@@ -1952,6 +1465,9 @@ function getOptionCommandValue(option) {
|
|
|
1952
1465
|
option.searchText
|
|
1953
1466
|
].filter(Boolean).join(" ");
|
|
1954
1467
|
}
|
|
1468
|
+
function getColumnFilterOptions(column) {
|
|
1469
|
+
return column.columnDef.meta?.autoCrudFilterOptions ?? column.columnDef.meta?.options;
|
|
1470
|
+
}
|
|
1955
1471
|
function DataTableFilterMenu({ table, debounceMs = DEBOUNCE_MS$1, throttleMs = THROTTLE_MS$1, shallow = true, disabled,...props }) {
|
|
1956
1472
|
const id = react.useId();
|
|
1957
1473
|
const columnDefs = table.options.columns;
|
|
@@ -2037,6 +1553,12 @@ function DataTableFilterMenu({ table, debounceMs = DEBOUNCE_MS$1, throttleMs = T
|
|
|
2037
1553
|
onFilterRemove(filters[filters.length - 1]?.filterId ?? "");
|
|
2038
1554
|
}
|
|
2039
1555
|
}, [filters, onFilterRemove]);
|
|
1556
|
+
const selectedColumnMeta = selectedColumn?.columnDef.meta;
|
|
1557
|
+
const commandInputValue = selectedColumnMeta?.autoCrudFilterOnSearch !== void 0 ? selectedColumnMeta.autoCrudFilterSearchValue ?? "" : inputValue;
|
|
1558
|
+
const onCommandInputValueChange = react.useCallback((value) => {
|
|
1559
|
+
setInputValue(value);
|
|
1560
|
+
selectedColumn?.columnDef.meta?.autoCrudFilterOnSearch?.(value);
|
|
1561
|
+
}, [selectedColumn]);
|
|
2040
1562
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2041
1563
|
role: "list",
|
|
2042
1564
|
className: "flex flex-wrap items-center gap-2",
|
|
@@ -2048,7 +1570,7 @@ function DataTableFilterMenu({ table, debounceMs = DEBOUNCE_MS$1, throttleMs = T
|
|
|
2048
1570
|
onFilterUpdate,
|
|
2049
1571
|
onFilterRemove
|
|
2050
1572
|
}, filter.filterId)),
|
|
2051
|
-
filters.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1573
|
+
filters.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
2052
1574
|
"aria-label": "Reset all filters",
|
|
2053
1575
|
variant: "outline",
|
|
2054
1576
|
size: "icon",
|
|
@@ -2056,12 +1578,12 @@ function DataTableFilterMenu({ table, debounceMs = DEBOUNCE_MS$1, throttleMs = T
|
|
|
2056
1578
|
onClick: onFiltersReset,
|
|
2057
1579
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.X, {})
|
|
2058
1580
|
}),
|
|
2059
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
1581
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Popover, {
|
|
2060
1582
|
open,
|
|
2061
1583
|
onOpenChange,
|
|
2062
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1584
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.PopoverTrigger, {
|
|
2063
1585
|
asChild: true,
|
|
2064
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
1586
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
2065
1587
|
"aria-label": "Open filter command menu",
|
|
2066
1588
|
variant: "outline",
|
|
2067
1589
|
size: filters.length > 0 ? "icon" : "sm",
|
|
@@ -2071,36 +1593,55 @@ function DataTableFilterMenu({ table, debounceMs = DEBOUNCE_MS$1, throttleMs = T
|
|
|
2071
1593
|
disabled,
|
|
2072
1594
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ListFilter, { className: "text-muted-foreground" }), filters.length > 0 ? null : "Filter"]
|
|
2073
1595
|
})
|
|
2074
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1596
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.PopoverContent, {
|
|
2075
1597
|
className: "w-full max-w-(--radix-popover-content-available-width) p-0",
|
|
2076
1598
|
...props,
|
|
2077
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
1599
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Command, {
|
|
2078
1600
|
loop: true,
|
|
1601
|
+
shouldFilter: selectedColumnMeta?.autoCrudFilterShouldFilter,
|
|
2079
1602
|
className: "[&_[cmdk-input-wrapper]_svg]:hidden",
|
|
2080
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1603
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.CommandInput, {
|
|
2081
1604
|
ref: inputRef,
|
|
2082
1605
|
placeholder: selectedColumn ? selectedColumn.columnDef.meta?.label ?? selectedColumn.id : "Search fields...",
|
|
2083
|
-
value:
|
|
2084
|
-
onValueChange:
|
|
1606
|
+
value: commandInputValue,
|
|
1607
|
+
onValueChange: onCommandInputValueChange,
|
|
2085
1608
|
onKeyDown: onInputKeyDown
|
|
2086
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
1609
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.CommandList, {
|
|
1610
|
+
onScroll: selectedColumnMeta?.autoCrudFilterOnPopupScroll,
|
|
1611
|
+
children: selectedColumn ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
1612
|
+
selectedColumn.columnDef.meta?.options && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.CommandEmpty, { children: "No options found." }),
|
|
1613
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(FilterValueSelector, {
|
|
1614
|
+
column: selectedColumn,
|
|
1615
|
+
value: inputValue,
|
|
1616
|
+
onSelect: (value) => onFilterAdd(selectedColumn, value)
|
|
1617
|
+
}),
|
|
1618
|
+
selectedColumnMeta?.autoCrudFilterLoading && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.CommandGroup, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1619
|
+
role: "status",
|
|
1620
|
+
"aria-live": "polite",
|
|
1621
|
+
className: "py-2 text-center text-sm text-muted-foreground",
|
|
1622
|
+
children: "Loading..."
|
|
1623
|
+
}) }),
|
|
1624
|
+
!selectedColumnMeta?.autoCrudFilterLoading && selectedColumnMeta?.autoCrudFilterHasMore && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1625
|
+
role: "status",
|
|
1626
|
+
"aria-live": "polite",
|
|
1627
|
+
className: "sr-only",
|
|
1628
|
+
children: "Load more"
|
|
1629
|
+
})
|
|
1630
|
+
] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.CommandEmpty, { children: "No fields found." }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.CommandGroup, { children: columns.map((column) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.CommandItem, {
|
|
1631
|
+
value: column.id,
|
|
1632
|
+
onSelect: () => {
|
|
1633
|
+
setSelectedColumn(column);
|
|
1634
|
+
setInputValue("");
|
|
1635
|
+
requestAnimationFrame(() => {
|
|
1636
|
+
inputRef.current?.focus();
|
|
1637
|
+
});
|
|
1638
|
+
},
|
|
1639
|
+
children: [column.columnDef.meta?.icon && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(column.columnDef.meta.icon, {}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1640
|
+
className: "truncate",
|
|
1641
|
+
children: column.columnDef.meta?.label ?? column.id
|
|
1642
|
+
})]
|
|
1643
|
+
}, column.id)) })] })
|
|
1644
|
+
})]
|
|
2104
1645
|
})
|
|
2105
1646
|
})]
|
|
2106
1647
|
})
|
|
@@ -2138,23 +1679,23 @@ function DataTableFilterItem({ filter, filterItemId, columns, onFilterUpdate, on
|
|
|
2138
1679
|
className: "flex h-8 items-center rounded-md bg-background",
|
|
2139
1680
|
onKeyDown: onItemKeyDown,
|
|
2140
1681
|
children: [
|
|
2141
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
1682
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Popover, {
|
|
2142
1683
|
open: showFieldSelector,
|
|
2143
1684
|
onOpenChange: setShowFieldSelector,
|
|
2144
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1685
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.PopoverTrigger, {
|
|
2145
1686
|
asChild: true,
|
|
2146
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
1687
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
2147
1688
|
variant: "ghost",
|
|
2148
1689
|
size: "sm",
|
|
2149
1690
|
className: "rounded-none rounded-l-md border border-r-0 font-normal dark:bg-input/30",
|
|
2150
1691
|
children: [columnMeta?.icon && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(columnMeta.icon, { className: "text-muted-foreground" }), columnMeta?.label ?? column.id]
|
|
2151
1692
|
})
|
|
2152
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1693
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.PopoverContent, {
|
|
2153
1694
|
align: "start",
|
|
2154
1695
|
className: "w-48 p-0",
|
|
2155
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
1696
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Command, {
|
|
2156
1697
|
loop: true,
|
|
2157
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1698
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.CommandInput, { placeholder: "Search fields..." }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.CommandList, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.CommandEmpty, { children: "No fields found." }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.CommandGroup, { children: columns.map((column$1) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.CommandItem, {
|
|
2158
1699
|
value: column$1.id,
|
|
2159
1700
|
onSelect: () => {
|
|
2160
1701
|
onFilterUpdate(filter.filterId, {
|
|
@@ -2177,7 +1718,7 @@ function DataTableFilterItem({ filter, filterItemId, columns, onFilterUpdate, on
|
|
|
2177
1718
|
})
|
|
2178
1719
|
})]
|
|
2179
1720
|
}),
|
|
2180
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
1721
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Select, {
|
|
2181
1722
|
open: showOperatorSelector,
|
|
2182
1723
|
onOpenChange: setShowOperatorSelector,
|
|
2183
1724
|
value: filter.operator,
|
|
@@ -2185,13 +1726,13 @@ function DataTableFilterItem({ filter, filterItemId, columns, onFilterUpdate, on
|
|
|
2185
1726
|
operator: value,
|
|
2186
1727
|
value: value === "isEmpty" || value === "isNotEmpty" ? "" : filter.value
|
|
2187
1728
|
}),
|
|
2188
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1729
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.SelectTrigger, {
|
|
2189
1730
|
"aria-controls": operatorListboxId,
|
|
2190
1731
|
className: "h-8 rounded-none border-r-0 px-2.5 lowercase data-size:h-8 [&_svg]:hidden",
|
|
2191
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2192
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1732
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.SelectValue, { placeholder: filter.operator })
|
|
1733
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.SelectContent, {
|
|
2193
1734
|
id: operatorListboxId,
|
|
2194
|
-
children: filterOperators.map((operator) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1735
|
+
children: filterOperators.map((operator) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.SelectItem, {
|
|
2195
1736
|
className: "lowercase",
|
|
2196
1737
|
value: operator.value,
|
|
2197
1738
|
children: operator.label
|
|
@@ -2206,7 +1747,7 @@ function DataTableFilterItem({ filter, filterItemId, columns, onFilterUpdate, on
|
|
|
2206
1747
|
showValueSelector,
|
|
2207
1748
|
setShowValueSelector
|
|
2208
1749
|
}),
|
|
2209
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1750
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
2210
1751
|
"aria-controls": filterItemId,
|
|
2211
1752
|
variant: "ghost",
|
|
2212
1753
|
size: "sm",
|
|
@@ -2220,17 +1761,17 @@ function DataTableFilterItem({ filter, filterItemId, columns, onFilterUpdate, on
|
|
|
2220
1761
|
}
|
|
2221
1762
|
function FilterValueSelector({ column, value, onSelect }) {
|
|
2222
1763
|
switch (column.columnDef.meta?.variant ?? "text") {
|
|
2223
|
-
case "boolean": return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
1764
|
+
case "boolean": return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.CommandGroup, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.CommandItem, {
|
|
2224
1765
|
value: "true",
|
|
2225
1766
|
onSelect: () => onSelect("true"),
|
|
2226
1767
|
children: "True"
|
|
2227
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1768
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.CommandItem, {
|
|
2228
1769
|
value: "false",
|
|
2229
1770
|
onSelect: () => onSelect("false"),
|
|
2230
1771
|
children: "False"
|
|
2231
1772
|
})] });
|
|
2232
1773
|
case "select":
|
|
2233
|
-
case "multiSelect": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1774
|
+
case "multiSelect": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.CommandGroup, { children: getColumnFilterOptions(column)?.map((option) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.CommandItem, {
|
|
2234
1775
|
value: getOptionCommandValue(option),
|
|
2235
1776
|
onSelect: () => onSelect(option.value),
|
|
2236
1777
|
children: [
|
|
@@ -2246,7 +1787,7 @@ function FilterValueSelector({ column, value, onSelect }) {
|
|
|
2246
1787
|
]
|
|
2247
1788
|
}, option.value)) });
|
|
2248
1789
|
case "date":
|
|
2249
|
-
case "dateRange": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1790
|
+
case "dateRange": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Calendar, {
|
|
2250
1791
|
autoFocus: true,
|
|
2251
1792
|
captionLayout: "dropdown",
|
|
2252
1793
|
mode: "single",
|
|
@@ -2255,7 +1796,7 @@ function FilterValueSelector({ column, value, onSelect }) {
|
|
|
2255
1796
|
});
|
|
2256
1797
|
default: {
|
|
2257
1798
|
const isEmpty = !value.trim();
|
|
2258
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1799
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.CommandGroup, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.CommandItem, {
|
|
2259
1800
|
value,
|
|
2260
1801
|
onSelect: () => onSelect(value),
|
|
2261
1802
|
disabled: isEmpty,
|
|
@@ -2291,7 +1832,7 @@ function onFilterInputRender({ filter, column, inputId, onFilterUpdate, showValu
|
|
|
2291
1832
|
className: "size-full max-w-28 gap-0 **:data-[slot='range-min']:border-r-0 [&_input]:rounded-none [&_input]:px-1.5"
|
|
2292
1833
|
});
|
|
2293
1834
|
const isNumber = filter.variant === "number" || filter.variant === "range";
|
|
2294
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1835
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Input, {
|
|
2295
1836
|
id: inputId,
|
|
2296
1837
|
type: isNumber ? "number" : "text",
|
|
2297
1838
|
inputMode: isNumber ? "numeric" : void 0,
|
|
@@ -2303,22 +1844,22 @@ function onFilterInputRender({ filter, column, inputId, onFilterUpdate, showValu
|
|
|
2303
1844
|
}
|
|
2304
1845
|
case "boolean": {
|
|
2305
1846
|
const inputListboxId = `${inputId}-listbox`;
|
|
2306
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
1847
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Select, {
|
|
2307
1848
|
open: showValueSelector,
|
|
2308
1849
|
onOpenChange: setShowValueSelector,
|
|
2309
1850
|
value: typeof filter.value === "string" ? filter.value : "true",
|
|
2310
1851
|
onValueChange: (value) => onFilterUpdate(filter.filterId, { value }),
|
|
2311
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1852
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.SelectTrigger, {
|
|
2312
1853
|
id: inputId,
|
|
2313
1854
|
"aria-controls": inputListboxId,
|
|
2314
1855
|
className: "rounded-none bg-transparent px-1.5 py-0.5 [&_svg]:hidden",
|
|
2315
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2316
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
1856
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.SelectValue, { placeholder: filter.value ? "True" : "False" })
|
|
1857
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.SelectContent, {
|
|
2317
1858
|
id: inputListboxId,
|
|
2318
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1859
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.SelectItem, {
|
|
2319
1860
|
value: "true",
|
|
2320
1861
|
children: "True"
|
|
2321
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1862
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.SelectItem, {
|
|
2322
1863
|
value: "false",
|
|
2323
1864
|
children: "False"
|
|
2324
1865
|
})]
|
|
@@ -2329,14 +1870,15 @@ function onFilterInputRender({ filter, column, inputId, onFilterUpdate, showValu
|
|
|
2329
1870
|
case "multiSelect": {
|
|
2330
1871
|
const inputListboxId = `${inputId}-listbox`;
|
|
2331
1872
|
const options = column.columnDef.meta?.options ?? [];
|
|
1873
|
+
const optionList = getColumnFilterOptions(column) ?? [];
|
|
2332
1874
|
const selectedValues = Array.isArray(filter.value) ? filter.value : [filter.value];
|
|
2333
1875
|
const selectedOptions = options.filter((option) => selectedValues.includes(option.value));
|
|
2334
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
1876
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Popover, {
|
|
2335
1877
|
open: showValueSelector,
|
|
2336
1878
|
onOpenChange: setShowValueSelector,
|
|
2337
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1879
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.PopoverTrigger, {
|
|
2338
1880
|
asChild: true,
|
|
2339
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1881
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
2340
1882
|
id: inputId,
|
|
2341
1883
|
"aria-controls": inputListboxId,
|
|
2342
1884
|
variant: "ghost",
|
|
@@ -2353,25 +1895,50 @@ function onFilterInputRender({ filter, column, inputId, onFilterUpdate, showValu
|
|
|
2353
1895
|
children: selectedOptions.length > 1 ? `${selectedOptions.length} selected` : selectedOptions[0]?.label
|
|
2354
1896
|
})] })
|
|
2355
1897
|
})
|
|
2356
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1898
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.PopoverContent, {
|
|
2357
1899
|
id: inputListboxId,
|
|
2358
1900
|
align: "start",
|
|
2359
1901
|
className: "w-48 p-0",
|
|
2360
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
children: option.
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
1902
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Command, {
|
|
1903
|
+
shouldFilter: column.columnDef.meta?.autoCrudFilterShouldFilter,
|
|
1904
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.CommandInput, {
|
|
1905
|
+
placeholder: "Search options...",
|
|
1906
|
+
value: column.columnDef.meta?.autoCrudFilterSearchValue,
|
|
1907
|
+
onValueChange: column.columnDef.meta?.autoCrudFilterOnSearch
|
|
1908
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.CommandList, {
|
|
1909
|
+
onScroll: column.columnDef.meta?.autoCrudFilterOnPopupScroll,
|
|
1910
|
+
children: [
|
|
1911
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.CommandEmpty, { children: "No options found." }),
|
|
1912
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.CommandGroup, { children: optionList.map((option) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.CommandItem, {
|
|
1913
|
+
value: getOptionCommandValue(option),
|
|
1914
|
+
onSelect: () => {
|
|
1915
|
+
const value = filter.variant === "multiSelect" ? selectedValues.includes(option.value) ? selectedValues.filter((v) => v !== option.value) : [...selectedValues, option.value] : option.value;
|
|
1916
|
+
onFilterUpdate(filter.filterId, { value });
|
|
1917
|
+
},
|
|
1918
|
+
children: [
|
|
1919
|
+
option.icon && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(option.icon, {}),
|
|
1920
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1921
|
+
className: "truncate",
|
|
1922
|
+
children: option.label
|
|
1923
|
+
}),
|
|
1924
|
+
filter.variant === "multiSelect" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Check, { className: cn("ml-auto", selectedValues.includes(option.value) ? "opacity-100" : "opacity-0") })
|
|
1925
|
+
]
|
|
1926
|
+
}, option.value)) }),
|
|
1927
|
+
column.columnDef.meta?.autoCrudFilterLoading && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.CommandGroup, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1928
|
+
role: "status",
|
|
1929
|
+
"aria-live": "polite",
|
|
1930
|
+
className: "py-2 text-center text-sm text-muted-foreground",
|
|
1931
|
+
children: "Loading..."
|
|
1932
|
+
}) }),
|
|
1933
|
+
!column.columnDef.meta?.autoCrudFilterLoading && column.columnDef.meta?.autoCrudFilterHasMore && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1934
|
+
role: "status",
|
|
1935
|
+
"aria-live": "polite",
|
|
1936
|
+
className: "sr-only",
|
|
1937
|
+
children: "Load more"
|
|
1938
|
+
})
|
|
1939
|
+
]
|
|
1940
|
+
})]
|
|
1941
|
+
})
|
|
2375
1942
|
})]
|
|
2376
1943
|
});
|
|
2377
1944
|
}
|
|
@@ -2383,12 +1950,12 @@ function onFilterInputRender({ filter, column, inputId, onFilterUpdate, showValu
|
|
|
2383
1950
|
const endDate = dateValue[1] ? new Date(Number(dateValue[1])) : void 0;
|
|
2384
1951
|
const isSameDate = startDate && endDate && startDate.toDateString() === endDate.toDateString();
|
|
2385
1952
|
const displayValue = filter.operator === "isBetween" && dateValue.length === 2 && !isSameDate ? `${formatDate(startDate, { month: "short" })} - ${formatDate(endDate, { month: "short" })}` : startDate ? formatDate(startDate, { month: "short" }) : "Pick date...";
|
|
2386
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
1953
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Popover, {
|
|
2387
1954
|
open: showValueSelector,
|
|
2388
1955
|
onOpenChange: setShowValueSelector,
|
|
2389
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1956
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.PopoverTrigger, {
|
|
2390
1957
|
asChild: true,
|
|
2391
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
1958
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
2392
1959
|
id: inputId,
|
|
2393
1960
|
"aria-controls": inputListboxId,
|
|
2394
1961
|
variant: "ghost",
|
|
@@ -2399,11 +1966,11 @@ function onFilterInputRender({ filter, column, inputId, onFilterUpdate, showValu
|
|
|
2399
1966
|
children: displayValue
|
|
2400
1967
|
})]
|
|
2401
1968
|
})
|
|
2402
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1969
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.PopoverContent, {
|
|
2403
1970
|
id: inputListboxId,
|
|
2404
1971
|
align: "start",
|
|
2405
1972
|
className: "w-auto p-0",
|
|
2406
|
-
children: filter.operator === "isBetween" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1973
|
+
children: filter.operator === "isBetween" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Calendar, {
|
|
2407
1974
|
autoFocus: true,
|
|
2408
1975
|
captionLayout: "dropdown",
|
|
2409
1976
|
mode: "range",
|
|
@@ -2417,7 +1984,7 @@ function onFilterInputRender({ filter, column, inputId, onFilterUpdate, showValu
|
|
|
2417
1984
|
onSelect: (date) => {
|
|
2418
1985
|
onFilterUpdate(filter.filterId, { value: date ? [(date.from?.getTime() ?? "").toString(), (date.to?.getTime() ?? "").toString()] : [] });
|
|
2419
1986
|
}
|
|
2420
|
-
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1987
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Calendar, {
|
|
2421
1988
|
autoFocus: true,
|
|
2422
1989
|
captionLayout: "dropdown",
|
|
2423
1990
|
mode: "single",
|
|
@@ -2495,16 +2062,16 @@ function DataTableSortList({ table, disabled,...props }) {
|
|
|
2495
2062
|
window.addEventListener("keydown", onKeyDown);
|
|
2496
2063
|
return () => window.removeEventListener("keydown", onKeyDown);
|
|
2497
2064
|
}, []);
|
|
2498
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2065
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn_ui.Sortable, {
|
|
2499
2066
|
value: sorting,
|
|
2500
2067
|
onValueChange: onSortingChange,
|
|
2501
2068
|
getItemValue: (item) => item.id,
|
|
2502
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2069
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Popover, {
|
|
2503
2070
|
open,
|
|
2504
2071
|
onOpenChange: setOpen,
|
|
2505
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2072
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.PopoverTrigger, {
|
|
2506
2073
|
asChild: true,
|
|
2507
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2074
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
2508
2075
|
variant: "outline",
|
|
2509
2076
|
size: "sm",
|
|
2510
2077
|
className: "font-normal",
|
|
@@ -2518,14 +2085,14 @@ function DataTableSortList({ table, disabled,...props }) {
|
|
|
2518
2085
|
children: [
|
|
2519
2086
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ArrowDownUp, { className: "text-muted-foreground" }),
|
|
2520
2087
|
"Sort",
|
|
2521
|
-
sorting.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2088
|
+
sorting.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Badge, {
|
|
2522
2089
|
variant: "secondary",
|
|
2523
2090
|
className: "h-[18.24px] rounded-[3.2px] px-[5.12px] font-mono font-normal text-[10.4px]",
|
|
2524
2091
|
children: sorting.length
|
|
2525
2092
|
})
|
|
2526
2093
|
]
|
|
2527
2094
|
})
|
|
2528
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2095
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.PopoverContent, {
|
|
2529
2096
|
"aria-labelledby": labelId,
|
|
2530
2097
|
"aria-describedby": descriptionId,
|
|
2531
2098
|
className: "flex w-full max-w-(--radix-popover-content-available-width) flex-col gap-3.5 p-4 sm:min-w-[380px]",
|
|
@@ -2543,7 +2110,7 @@ function DataTableSortList({ table, disabled,...props }) {
|
|
|
2543
2110
|
children: sorting.length > 0 ? "Modify sorting to organize your rows." : "Add sorting to organize your rows."
|
|
2544
2111
|
})]
|
|
2545
2112
|
}),
|
|
2546
|
-
sorting.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SortableContent, {
|
|
2113
|
+
sorting.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn_ui.SortableContent, {
|
|
2547
2114
|
asChild: true,
|
|
2548
2115
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2549
2116
|
role: "list",
|
|
@@ -2560,14 +2127,14 @@ function DataTableSortList({ table, disabled,...props }) {
|
|
|
2560
2127
|
}),
|
|
2561
2128
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2562
2129
|
className: "flex w-full items-center gap-2",
|
|
2563
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2130
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
2564
2131
|
size: "sm",
|
|
2565
2132
|
className: "rounded",
|
|
2566
2133
|
ref: addButtonRef,
|
|
2567
2134
|
onClick: onSortAdd,
|
|
2568
2135
|
disabled: columns.length === 0,
|
|
2569
2136
|
children: "Add sort"
|
|
2570
|
-
}), sorting.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2137
|
+
}), sorting.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
2571
2138
|
variant: "outline",
|
|
2572
2139
|
size: "sm",
|
|
2573
2140
|
className: "rounded",
|
|
@@ -2577,7 +2144,7 @@ function DataTableSortList({ table, disabled,...props }) {
|
|
|
2577
2144
|
})
|
|
2578
2145
|
]
|
|
2579
2146
|
})]
|
|
2580
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SortableOverlay, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2147
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn_ui.SortableOverlay, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2581
2148
|
className: "flex items-center gap-2",
|
|
2582
2149
|
children: [
|
|
2583
2150
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "h-8 w-[180px] rounded-sm bg-primary/10" }),
|
|
@@ -2607,7 +2174,7 @@ function DataTableSortItem({ sort, sortItemId, columns, columnLabels, onSortUpda
|
|
|
2607
2174
|
showDirectionSelector,
|
|
2608
2175
|
onSortRemove
|
|
2609
2176
|
]);
|
|
2610
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SortableItem, {
|
|
2177
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn_ui.SortableItem, {
|
|
2611
2178
|
value: sort.id,
|
|
2612
2179
|
asChild: true,
|
|
2613
2180
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -2617,12 +2184,12 @@ function DataTableSortItem({ sort, sortItemId, columns, columnLabels, onSortUpda
|
|
|
2617
2184
|
className: "flex items-center gap-2",
|
|
2618
2185
|
onKeyDown: onItemKeyDown,
|
|
2619
2186
|
children: [
|
|
2620
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2187
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Popover, {
|
|
2621
2188
|
open: showFieldSelector,
|
|
2622
2189
|
onOpenChange: setShowFieldSelector,
|
|
2623
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2190
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.PopoverTrigger, {
|
|
2624
2191
|
asChild: true,
|
|
2625
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2192
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
2626
2193
|
id: fieldTriggerId,
|
|
2627
2194
|
"aria-controls": fieldListboxId,
|
|
2628
2195
|
variant: "outline",
|
|
@@ -2633,10 +2200,10 @@ function DataTableSortItem({ sort, sortItemId, columns, columnLabels, onSortUpda
|
|
|
2633
2200
|
children: columnLabels.get(sort.id)
|
|
2634
2201
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronsUpDown, { className: "opacity-50" })]
|
|
2635
2202
|
})
|
|
2636
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2203
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.PopoverContent, {
|
|
2637
2204
|
id: fieldListboxId,
|
|
2638
2205
|
className: "w-(--radix-popover-trigger-width) p-0",
|
|
2639
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2206
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Command, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.CommandInput, { placeholder: "Search fields..." }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.CommandList, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.CommandEmpty, { children: "No fields found." }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.CommandGroup, { children: columns.map((column) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.CommandItem, {
|
|
2640
2207
|
value: column.id,
|
|
2641
2208
|
onSelect: (value) => onSortUpdate(sort.id, { id: value }),
|
|
2642
2209
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
@@ -2646,26 +2213,26 @@ function DataTableSortItem({ sort, sortItemId, columns, columnLabels, onSortUpda
|
|
|
2646
2213
|
}, column.id)) })] })] })
|
|
2647
2214
|
})]
|
|
2648
2215
|
}),
|
|
2649
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2216
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Select, {
|
|
2650
2217
|
open: showDirectionSelector,
|
|
2651
2218
|
onOpenChange: setShowDirectionSelector,
|
|
2652
2219
|
value: sort.desc ? "desc" : "asc",
|
|
2653
2220
|
onValueChange: (value) => onSortUpdate(sort.id, { desc: value === "desc" }),
|
|
2654
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2221
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.SelectTrigger, {
|
|
2655
2222
|
"aria-controls": directionListboxId,
|
|
2656
2223
|
size: "sm",
|
|
2657
2224
|
className: "w-24 rounded",
|
|
2658
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2659
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2225
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.SelectValue, {})
|
|
2226
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.SelectContent, {
|
|
2660
2227
|
id: directionListboxId,
|
|
2661
2228
|
className: "min-w-(--radix-select-trigger-width)",
|
|
2662
|
-
children: dataTableConfig.sortOrders.map((order) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2229
|
+
children: dataTableConfig.sortOrders.map((order) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.SelectItem, {
|
|
2663
2230
|
value: order.value,
|
|
2664
2231
|
children: order.label
|
|
2665
2232
|
}, order.value))
|
|
2666
2233
|
})]
|
|
2667
2234
|
}),
|
|
2668
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2235
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
2669
2236
|
"aria-controls": sortItemId,
|
|
2670
2237
|
variant: "outline",
|
|
2671
2238
|
size: "icon",
|
|
@@ -2673,9 +2240,9 @@ function DataTableSortItem({ sort, sortItemId, columns, columnLabels, onSortUpda
|
|
|
2673
2240
|
onClick: () => onSortRemove(sort.id),
|
|
2674
2241
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Trash2, {})
|
|
2675
2242
|
}),
|
|
2676
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SortableItemHandle, {
|
|
2243
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn_ui.SortableItemHandle, {
|
|
2677
2244
|
asChild: true,
|
|
2678
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2245
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
2679
2246
|
variant: "outline",
|
|
2680
2247
|
size: "icon",
|
|
2681
2248
|
className: "size-8 shrink-0 rounded",
|
|
@@ -2691,9 +2258,9 @@ function DataTableSortItem({ sort, sortItemId, columns, columnLabels, onSortUpda
|
|
|
2691
2258
|
//#region src/components/data-table/data-table-view-options.tsx
|
|
2692
2259
|
function DataTableViewOptions({ table, disabled,...props }) {
|
|
2693
2260
|
const columns = react.useMemo(() => table.getAllColumns().filter((column) => typeof column.accessorFn !== "undefined" && column.getCanHide()), [table]);
|
|
2694
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2261
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Popover, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.PopoverTrigger, {
|
|
2695
2262
|
asChild: true,
|
|
2696
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2263
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
2697
2264
|
"aria-label": "Toggle columns",
|
|
2698
2265
|
role: "combobox",
|
|
2699
2266
|
variant: "outline",
|
|
@@ -2702,10 +2269,10 @@ function DataTableViewOptions({ table, disabled,...props }) {
|
|
|
2702
2269
|
disabled,
|
|
2703
2270
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Settings2, { className: "text-muted-foreground" }), "View"]
|
|
2704
2271
|
})
|
|
2705
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2272
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.PopoverContent, {
|
|
2706
2273
|
className: "w-44 p-0",
|
|
2707
2274
|
...props,
|
|
2708
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2275
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Command, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.CommandInput, { placeholder: "Search columns..." }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.CommandList, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.CommandEmpty, { children: "No columns found." }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.CommandGroup, { children: columns.map((column) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.CommandItem, {
|
|
2709
2276
|
onSelect: () => column.toggleVisibility(!column.getIsVisible()),
|
|
2710
2277
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2711
2278
|
className: "truncate",
|
|
@@ -2715,207 +2282,12 @@ function DataTableViewOptions({ table, disabled,...props }) {
|
|
|
2715
2282
|
})] });
|
|
2716
2283
|
}
|
|
2717
2284
|
|
|
2718
|
-
//#endregion
|
|
2719
|
-
//#region src/components/ui/multi-combobox.tsx
|
|
2720
|
-
const DEFAULT_OPTIONS = [];
|
|
2721
|
-
const SCROLLABLE_COMMAND_GROUP_STYLE = {
|
|
2722
|
-
maxHeight: "300px",
|
|
2723
|
-
overscrollBehavior: "contain",
|
|
2724
|
-
overflowX: "hidden",
|
|
2725
|
-
overflowY: "auto"
|
|
2726
|
-
};
|
|
2727
|
-
function getWheelDeltaY(event) {
|
|
2728
|
-
if (event.deltaMode === 1) return event.deltaY * 16;
|
|
2729
|
-
if (event.deltaMode === 2) return event.deltaY * event.currentTarget.clientHeight;
|
|
2730
|
-
return event.deltaY;
|
|
2731
|
-
}
|
|
2732
|
-
function handleScrollableCommandGroupWheel(event) {
|
|
2733
|
-
const target = event.currentTarget;
|
|
2734
|
-
if (target.scrollHeight <= target.clientHeight) return;
|
|
2735
|
-
const maxScrollTop = target.scrollHeight - target.clientHeight;
|
|
2736
|
-
const nextScrollTop = Math.max(0, Math.min(target.scrollTop + getWheelDeltaY(event), maxScrollTop));
|
|
2737
|
-
if (nextScrollTop === target.scrollTop) return;
|
|
2738
|
-
event.preventDefault();
|
|
2739
|
-
event.stopPropagation();
|
|
2740
|
-
target.scrollTop = nextScrollTop;
|
|
2741
|
-
}
|
|
2742
|
-
function collectSearchText(...parts) {
|
|
2743
|
-
const texts = [];
|
|
2744
|
-
for (const part of parts) {
|
|
2745
|
-
if (!part) continue;
|
|
2746
|
-
if (Array.isArray(part)) texts.push(...part.map(String));
|
|
2747
|
-
else if (typeof part === "object") texts.push(...Object.values(part).filter(Boolean).map(String));
|
|
2748
|
-
else texts.push(String(part));
|
|
2749
|
-
}
|
|
2750
|
-
return texts.join(" ");
|
|
2751
|
-
}
|
|
2752
|
-
function getOptionKeywords(option) {
|
|
2753
|
-
return collectSearchText(typeof option.label === "string" || typeof option.label === "number" ? option.label : void 0, option.searchText, option.keywords).split(/\s+/).filter(Boolean);
|
|
2754
|
-
}
|
|
2755
|
-
function getOptionText(option) {
|
|
2756
|
-
if (typeof option.label === "string" || typeof option.label === "number") return String(option.label);
|
|
2757
|
-
return option.value;
|
|
2758
|
-
}
|
|
2759
|
-
function createNextValue(currentValue, optionValue, isSelected, selectionMode) {
|
|
2760
|
-
if (selectionMode === "single") return isSelected ? [] : [optionValue];
|
|
2761
|
-
return isSelected ? currentValue.filter((value) => value !== optionValue) : [...currentValue, optionValue];
|
|
2762
|
-
}
|
|
2763
|
-
function DefaultMultiComboboxTrigger({ open, selectedOptions, selectedValues, clearSelection, disabled, readOnly, placeholder, selectedText, className,...buttonProps }) {
|
|
2764
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__pixpilot_shadcn.Button, {
|
|
2765
|
-
...buttonProps,
|
|
2766
|
-
type: "button",
|
|
2767
|
-
variant: "outline",
|
|
2768
|
-
role: "combobox",
|
|
2769
|
-
"aria-expanded": open,
|
|
2770
|
-
disabled,
|
|
2771
|
-
className: (0, __pixpilot_shadcn.cn)("w-full justify-between", className),
|
|
2772
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2773
|
-
className: "flex min-w-0 flex-1 items-center gap-1 overflow-hidden",
|
|
2774
|
-
children: selectedValues.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2775
|
-
className: "truncate text-muted-foreground",
|
|
2776
|
-
children: placeholder
|
|
2777
|
-
}) : selectedOptions.length <= 2 ? selectedOptions.map((option) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.Badge, {
|
|
2778
|
-
variant: "secondary",
|
|
2779
|
-
className: "max-w-[8rem] rounded-sm px-1 font-normal",
|
|
2780
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2781
|
-
className: "truncate",
|
|
2782
|
-
children: option.label
|
|
2783
|
-
})
|
|
2784
|
-
}, option.value)) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__pixpilot_shadcn.Badge, {
|
|
2785
|
-
variant: "secondary",
|
|
2786
|
-
className: "rounded-sm px-1 font-normal",
|
|
2787
|
-
children: [
|
|
2788
|
-
selectedValues.length,
|
|
2789
|
-
" ",
|
|
2790
|
-
selectedText
|
|
2791
|
-
]
|
|
2792
|
-
})
|
|
2793
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2794
|
-
className: "ml-2 flex shrink-0 items-center gap-1",
|
|
2795
|
-
children: [selectedValues.length > 0 && !readOnly && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2796
|
-
role: "button",
|
|
2797
|
-
"aria-label": "Clear selection",
|
|
2798
|
-
tabIndex: 0,
|
|
2799
|
-
className: "rounded-sm px-1 text-muted-foreground opacity-70 transition-opacity hover:opacity-100 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
2800
|
-
onClick: clearSelection,
|
|
2801
|
-
onKeyDown: (event) => {
|
|
2802
|
-
if (event.key === "Enter" || event.key === " ") {
|
|
2803
|
-
event.preventDefault();
|
|
2804
|
-
clearSelection(event);
|
|
2805
|
-
}
|
|
2806
|
-
},
|
|
2807
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.X, { className: "size-3" })
|
|
2808
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronsUpDown, { className: "h-4 w-4 opacity-50" })]
|
|
2809
|
-
})]
|
|
2810
|
-
});
|
|
2811
|
-
}
|
|
2812
|
-
const MultiCombobox = ({ value, defaultValue, onChange, options = DEFAULT_OPTIONS, placeholder = "Select options...", searchPlaceholder = "Search...", emptyText = "No options found.", clearText = "Clear selection", selectedText = "selected", selectionMode = "multiple", disabled, readOnly, className, contentClassName, triggerClassName, matchTriggerWidth = true, renderTrigger, filter,...commandProps }) => {
|
|
2813
|
-
const [open, setOpen] = react.useState(false);
|
|
2814
|
-
const [internalValue, setInternalValue] = react.useState(defaultValue ?? []);
|
|
2815
|
-
const selectedValues = value ?? internalValue;
|
|
2816
|
-
const selectedValueSet = react.useMemo(() => new Set(selectedValues), [selectedValues]);
|
|
2817
|
-
const selectedOptions = react.useMemo(() => options.filter((option) => selectedValueSet.has(option.value)), [options, selectedValueSet]);
|
|
2818
|
-
const commitChange = react.useCallback((nextValue) => {
|
|
2819
|
-
if (value === void 0) setInternalValue(nextValue);
|
|
2820
|
-
onChange?.(nextValue);
|
|
2821
|
-
}, [onChange, value]);
|
|
2822
|
-
const clearSelection = react.useCallback((event) => {
|
|
2823
|
-
event?.preventDefault();
|
|
2824
|
-
event?.stopPropagation();
|
|
2825
|
-
if (readOnly) return;
|
|
2826
|
-
commitChange([]);
|
|
2827
|
-
}, [commitChange, readOnly]);
|
|
2828
|
-
const onItemSelect = react.useCallback((option) => {
|
|
2829
|
-
if (option.disabled || readOnly) return;
|
|
2830
|
-
const isSelected = selectedValueSet.has(option.value);
|
|
2831
|
-
commitChange(createNextValue(selectedValues, option.value, isSelected, selectionMode));
|
|
2832
|
-
if (selectionMode === "single") setOpen(false);
|
|
2833
|
-
}, [
|
|
2834
|
-
commitChange,
|
|
2835
|
-
readOnly,
|
|
2836
|
-
selectedValues,
|
|
2837
|
-
selectedValueSet,
|
|
2838
|
-
selectionMode
|
|
2839
|
-
]);
|
|
2840
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__pixpilot_shadcn.Popover, {
|
|
2841
|
-
open,
|
|
2842
|
-
onOpenChange: setOpen,
|
|
2843
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.PopoverTrigger, {
|
|
2844
|
-
asChild: true,
|
|
2845
|
-
children: renderTrigger ? renderTrigger({
|
|
2846
|
-
open,
|
|
2847
|
-
selectedOptions,
|
|
2848
|
-
selectedValues,
|
|
2849
|
-
clearSelection,
|
|
2850
|
-
disabled,
|
|
2851
|
-
readOnly
|
|
2852
|
-
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DefaultMultiComboboxTrigger, {
|
|
2853
|
-
open,
|
|
2854
|
-
selectedOptions,
|
|
2855
|
-
selectedValues,
|
|
2856
|
-
clearSelection,
|
|
2857
|
-
disabled,
|
|
2858
|
-
readOnly,
|
|
2859
|
-
placeholder,
|
|
2860
|
-
selectedText,
|
|
2861
|
-
className: triggerClassName
|
|
2862
|
-
})
|
|
2863
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.PopoverContent, {
|
|
2864
|
-
className: (0, __pixpilot_shadcn.cn)("w-full p-0", contentClassName),
|
|
2865
|
-
style: matchTriggerWidth ? { width: "var(--radix-popover-trigger-width)" } : void 0,
|
|
2866
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__pixpilot_shadcn.Command, {
|
|
2867
|
-
className,
|
|
2868
|
-
filter,
|
|
2869
|
-
...commandProps,
|
|
2870
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.CommandInput, { placeholder: searchPlaceholder }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__pixpilot_shadcn.CommandList, {
|
|
2871
|
-
className: "max-h-full",
|
|
2872
|
-
children: [
|
|
2873
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.CommandEmpty, { children: emptyText }),
|
|
2874
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.CommandGroup, {
|
|
2875
|
-
className: "max-h-[300px] scroll-py-1 overflow-y-auto overflow-x-hidden",
|
|
2876
|
-
onWheelCapture: handleScrollableCommandGroupWheel,
|
|
2877
|
-
style: SCROLLABLE_COMMAND_GROUP_STYLE,
|
|
2878
|
-
children: options.map((option) => {
|
|
2879
|
-
const isSelected = selectedValueSet.has(option.value);
|
|
2880
|
-
const Icon = option.icon;
|
|
2881
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__pixpilot_shadcn.CommandItem, {
|
|
2882
|
-
value: option.value,
|
|
2883
|
-
keywords: getOptionKeywords(option),
|
|
2884
|
-
disabled: option.disabled,
|
|
2885
|
-
onSelect: () => onItemSelect(option),
|
|
2886
|
-
children: [
|
|
2887
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2888
|
-
className: (0, __pixpilot_shadcn.cn)("flex size-4 items-center justify-center rounded-sm border border-primary", isSelected ? "bg-primary text-primary-foreground" : "opacity-50 [&_svg]:invisible"),
|
|
2889
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Check, {})
|
|
2890
|
-
}),
|
|
2891
|
-
Icon && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, { className: "size-4" }),
|
|
2892
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2893
|
-
className: "truncate",
|
|
2894
|
-
children: getOptionText(option)
|
|
2895
|
-
}),
|
|
2896
|
-
option.count !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2897
|
-
className: "ml-auto font-mono text-xs",
|
|
2898
|
-
children: option.count
|
|
2899
|
-
})
|
|
2900
|
-
]
|
|
2901
|
-
}, option.value);
|
|
2902
|
-
})
|
|
2903
|
-
}),
|
|
2904
|
-
selectedValues.length > 0 && !readOnly && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.CommandSeparator, {}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.CommandGroup, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.CommandItem, {
|
|
2905
|
-
onSelect: () => commitChange([]),
|
|
2906
|
-
className: "justify-center text-center",
|
|
2907
|
-
children: clearText
|
|
2908
|
-
}) })] })
|
|
2909
|
-
]
|
|
2910
|
-
})]
|
|
2911
|
-
})
|
|
2912
|
-
})]
|
|
2913
|
-
});
|
|
2914
|
-
};
|
|
2915
|
-
MultiCombobox.displayName = "MultiCombobox";
|
|
2916
|
-
|
|
2917
2285
|
//#endregion
|
|
2918
2286
|
//#region src/components/auto-crud/auto-table-simple-filters.tsx
|
|
2287
|
+
function mergeSelectedFilterOptions(currentOptions, labelOptions, selectedValues) {
|
|
2288
|
+
const currentValues = new Set(currentOptions.map((option) => option.value));
|
|
2289
|
+
return [...labelOptions.filter((option) => selectedValues.includes(option.value) && !currentValues.has(option.value)), ...currentOptions];
|
|
2290
|
+
}
|
|
2919
2291
|
function AutoTableSimpleFilters({ table, shallow = false, filters: externalFilters, onFiltersChange, leading }) {
|
|
2920
2292
|
const columnDefs = table.options.columns;
|
|
2921
2293
|
const columns = react.useMemo(() => table.getAllColumns().filter((col) => col.getCanFilter()).sort((a, b) => {
|
|
@@ -3096,7 +2468,7 @@ function AutoTableSimpleFilters({ table, shallow = false, filters: externalFilte
|
|
|
3096
2468
|
case "text": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3097
2469
|
className: isHidden ? "hidden" : "",
|
|
3098
2470
|
"data-filter-item": true,
|
|
3099
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2471
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Input, {
|
|
3100
2472
|
placeholder: meta.placeholder ?? meta.label ?? column.id,
|
|
3101
2473
|
value: typeof value === "string" ? value : "",
|
|
3102
2474
|
onChange: (e) => updateFilter(column.id, e.target.value || void 0),
|
|
@@ -3104,17 +2476,27 @@ function AutoTableSimpleFilters({ table, shallow = false, filters: externalFilte
|
|
|
3104
2476
|
})
|
|
3105
2477
|
}, column.id);
|
|
3106
2478
|
case "select":
|
|
3107
|
-
case "multiSelect":
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
|
|
2479
|
+
case "multiSelect": {
|
|
2480
|
+
const selectedValues = Array.isArray(value) ? value : value ? [value] : [];
|
|
2481
|
+
const filterOptions = mergeSelectedFilterOptions(meta.autoCrudFilterOptions ?? meta.options ?? [], meta.options ?? [], selectedValues);
|
|
2482
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2483
|
+
className: isHidden ? "hidden" : "",
|
|
2484
|
+
"data-filter-item": true,
|
|
2485
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SimpleFacetedFilter, {
|
|
2486
|
+
title: meta.label ?? column.id,
|
|
2487
|
+
options: filterOptions,
|
|
2488
|
+
multiple: meta.variant === "multiSelect",
|
|
2489
|
+
value: selectedValues,
|
|
2490
|
+
hasMore: meta.autoCrudFilterHasMore,
|
|
2491
|
+
loading: meta.autoCrudFilterLoading,
|
|
2492
|
+
searchValue: meta.autoCrudFilterSearchValue,
|
|
2493
|
+
shouldFilter: meta.autoCrudFilterShouldFilter,
|
|
2494
|
+
onChange: (v) => updateFilter(column.id, v.length ? v : void 0),
|
|
2495
|
+
onPopupScroll: meta.autoCrudFilterOnPopupScroll,
|
|
2496
|
+
onSearch: meta.autoCrudFilterOnSearch
|
|
2497
|
+
})
|
|
2498
|
+
}, column.id);
|
|
2499
|
+
}
|
|
3118
2500
|
case "range": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3119
2501
|
className: isHidden ? "hidden" : "",
|
|
3120
2502
|
"data-filter-item": true,
|
|
@@ -3140,7 +2522,7 @@ function AutoTableSimpleFilters({ table, shallow = false, filters: externalFilte
|
|
|
3140
2522
|
default: return null;
|
|
3141
2523
|
}
|
|
3142
2524
|
}),
|
|
3143
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2525
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
3144
2526
|
"data-filter-toggle": true,
|
|
3145
2527
|
variant: "ghost",
|
|
3146
2528
|
size: "icon",
|
|
@@ -3150,7 +2532,7 @@ function AutoTableSimpleFilters({ table, shallow = false, filters: externalFilte
|
|
|
3150
2532
|
"aria-expanded": expanded,
|
|
3151
2533
|
children: expanded ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronUp, { className: "size-4" }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronDown, { className: "size-4" })
|
|
3152
2534
|
}),
|
|
3153
|
-
hasFilters && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2535
|
+
hasFilters && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
3154
2536
|
"data-filter-reset": true,
|
|
3155
2537
|
variant: "outline",
|
|
3156
2538
|
size: "sm",
|
|
@@ -3161,17 +2543,23 @@ function AutoTableSimpleFilters({ table, shallow = false, filters: externalFilte
|
|
|
3161
2543
|
]
|
|
3162
2544
|
});
|
|
3163
2545
|
}
|
|
3164
|
-
function SimpleFacetedFilter({ title, options, multiple, value, onChange }) {
|
|
3165
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MultiCombobox, {
|
|
2546
|
+
function SimpleFacetedFilter({ title, options, multiple, value, hasMore, loading, searchValue, shouldFilter, onChange, onPopupScroll, onSearch }) {
|
|
2547
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn_ui.MultiCombobox, {
|
|
3166
2548
|
value,
|
|
3167
2549
|
onChange,
|
|
3168
2550
|
options,
|
|
3169
2551
|
selectionMode: multiple ? "multiple" : "single",
|
|
3170
2552
|
searchPlaceholder: title,
|
|
2553
|
+
hasMore,
|
|
2554
|
+
loading,
|
|
2555
|
+
searchValue,
|
|
2556
|
+
shouldFilter,
|
|
2557
|
+
onPopupScroll,
|
|
2558
|
+
onSearch,
|
|
3171
2559
|
contentClassName: "w-50",
|
|
3172
2560
|
matchTriggerWidth: false,
|
|
3173
2561
|
clearText: "Clear filters",
|
|
3174
|
-
renderTrigger: ({ selectedOptions, selectedValues, clearSelection }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2562
|
+
renderTrigger: ({ selectedOptions, selectedValues, clearSelection }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
3175
2563
|
variant: "outline",
|
|
3176
2564
|
size: "sm",
|
|
3177
2565
|
className: "border-dashed font-normal",
|
|
@@ -3191,22 +2579,22 @@ function SimpleFacetedFilter({ title, options, multiple, value, onChange }) {
|
|
|
3191
2579
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.PlusCircle, {}),
|
|
3192
2580
|
title,
|
|
3193
2581
|
selectedValues.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
3194
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2582
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Separator, {
|
|
3195
2583
|
orientation: "vertical",
|
|
3196
2584
|
className: "mx-0.5 h-4"
|
|
3197
2585
|
}),
|
|
3198
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2586
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Badge, {
|
|
3199
2587
|
variant: "secondary",
|
|
3200
2588
|
className: "rounded-sm px-1 font-normal lg:hidden",
|
|
3201
2589
|
children: selectedValues.length
|
|
3202
2590
|
}),
|
|
3203
2591
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3204
2592
|
className: "hidden items-center gap-1 lg:flex",
|
|
3205
|
-
children: selectedValues.length > 2 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2593
|
+
children: selectedValues.length > 2 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Badge, {
|
|
3206
2594
|
variant: "secondary",
|
|
3207
2595
|
className: "rounded-sm px-1 font-normal",
|
|
3208
2596
|
children: [selectedValues.length, " selected"]
|
|
3209
|
-
}) : selectedOptions.map((option) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2597
|
+
}) : selectedOptions.map((option) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Badge, {
|
|
3210
2598
|
variant: "secondary",
|
|
3211
2599
|
className: "rounded-sm px-1 font-normal",
|
|
3212
2600
|
children: option.label
|
|
@@ -3243,9 +2631,9 @@ function SimpleSliderFilter({ title, range, unit, value, onChange }) {
|
|
|
3243
2631
|
setLocalRange(nextRange);
|
|
3244
2632
|
onChange(nextRange);
|
|
3245
2633
|
};
|
|
3246
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2634
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Popover, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.PopoverTrigger, {
|
|
3247
2635
|
asChild: true,
|
|
3248
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2636
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
3249
2637
|
variant: "outline",
|
|
3250
2638
|
size: "sm",
|
|
3251
2639
|
className: "border-dashed font-normal",
|
|
@@ -3265,7 +2653,7 @@ function SimpleSliderFilter({ title, range, unit, value, onChange }) {
|
|
|
3265
2653
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.PlusCircle, {}),
|
|
3266
2654
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: title }),
|
|
3267
2655
|
value && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
3268
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2656
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Separator, {
|
|
3269
2657
|
orientation: "vertical",
|
|
3270
2658
|
className: "mx-0.5 h-4"
|
|
3271
2659
|
}),
|
|
@@ -3276,7 +2664,7 @@ function SimpleSliderFilter({ title, range, unit, value, onChange }) {
|
|
|
3276
2664
|
] })
|
|
3277
2665
|
]
|
|
3278
2666
|
})
|
|
3279
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2667
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.PopoverContent, {
|
|
3280
2668
|
align: "start",
|
|
3281
2669
|
className: "flex w-auto flex-col gap-4",
|
|
3282
2670
|
children: [
|
|
@@ -3287,14 +2675,14 @@ function SimpleSliderFilter({ title, range, unit, value, onChange }) {
|
|
|
3287
2675
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3288
2676
|
className: "flex items-center gap-4",
|
|
3289
2677
|
children: [
|
|
3290
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2678
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Label, {
|
|
3291
2679
|
htmlFor: `${id}-from`,
|
|
3292
2680
|
className: "sr-only",
|
|
3293
2681
|
children: "From"
|
|
3294
2682
|
}),
|
|
3295
2683
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3296
2684
|
className: "relative",
|
|
3297
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2685
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Input, {
|
|
3298
2686
|
id: `${id}-from`,
|
|
3299
2687
|
type: "number",
|
|
3300
2688
|
min,
|
|
@@ -3307,14 +2695,14 @@ function SimpleSliderFilter({ title, range, unit, value, onChange }) {
|
|
|
3307
2695
|
children: unit
|
|
3308
2696
|
})]
|
|
3309
2697
|
}),
|
|
3310
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2698
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Label, {
|
|
3311
2699
|
htmlFor: `${id}-to`,
|
|
3312
2700
|
className: "sr-only",
|
|
3313
2701
|
children: "To"
|
|
3314
2702
|
}),
|
|
3315
2703
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3316
2704
|
className: "relative",
|
|
3317
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2705
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Input, {
|
|
3318
2706
|
id: `${id}-to`,
|
|
3319
2707
|
type: "number",
|
|
3320
2708
|
min,
|
|
@@ -3329,14 +2717,14 @@ function SimpleSliderFilter({ title, range, unit, value, onChange }) {
|
|
|
3329
2717
|
})
|
|
3330
2718
|
]
|
|
3331
2719
|
}),
|
|
3332
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2720
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Slider, {
|
|
3333
2721
|
min,
|
|
3334
2722
|
max,
|
|
3335
2723
|
value: localRange,
|
|
3336
2724
|
onValueChange: (v) => setLocalRange(v),
|
|
3337
2725
|
onValueCommit: (v) => onChange(v)
|
|
3338
2726
|
}),
|
|
3339
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2727
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
3340
2728
|
variant: "outline",
|
|
3341
2729
|
size: "sm",
|
|
3342
2730
|
onClick: onReset,
|
|
@@ -3372,9 +2760,9 @@ function SimpleDateFilter({ title, multiple, value, onChange }) {
|
|
|
3372
2760
|
onChange(void 0);
|
|
3373
2761
|
};
|
|
3374
2762
|
const label = multiple ? fromDate && toDate ? `${formatDate(fromDate)} - ${formatDate(toDate)}` : fromDate ? formatDate(fromDate) : void 0 : fromDate ? formatDate(fromDate) : void 0;
|
|
3375
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2763
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Popover, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.PopoverTrigger, {
|
|
3376
2764
|
asChild: true,
|
|
3377
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2765
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
3378
2766
|
variant: "outline",
|
|
3379
2767
|
size: "sm",
|
|
3380
2768
|
className: "border-dashed font-normal",
|
|
@@ -3393,16 +2781,16 @@ function SimpleDateFilter({ title, multiple, value, onChange }) {
|
|
|
3393
2781
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.XCircle, {})
|
|
3394
2782
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.CalendarIcon, {}),
|
|
3395
2783
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: title }),
|
|
3396
|
-
label && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2784
|
+
label && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Separator, {
|
|
3397
2785
|
orientation: "vertical",
|
|
3398
2786
|
className: "mx-0.5 h-4"
|
|
3399
2787
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: label })] })
|
|
3400
2788
|
]
|
|
3401
2789
|
})
|
|
3402
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2790
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.PopoverContent, {
|
|
3403
2791
|
className: "w-auto p-0",
|
|
3404
2792
|
align: "start",
|
|
3405
|
-
children: multiple ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2793
|
+
children: multiple ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Calendar, {
|
|
3406
2794
|
autoFocus: true,
|
|
3407
2795
|
captionLayout: "dropdown",
|
|
3408
2796
|
mode: "range",
|
|
@@ -3456,7 +2844,7 @@ function SimpleDateFilter({ title, multiple, value, onChange }) {
|
|
|
3456
2844
|
return;
|
|
3457
2845
|
}
|
|
3458
2846
|
}
|
|
3459
|
-
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2847
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Calendar, {
|
|
3460
2848
|
captionLayout: "dropdown",
|
|
3461
2849
|
mode: "single",
|
|
3462
2850
|
selected: fromDate,
|
|
@@ -3465,386 +2853,6 @@ function SimpleDateFilter({ title, multiple, value, onChange }) {
|
|
|
3465
2853
|
})] });
|
|
3466
2854
|
}
|
|
3467
2855
|
|
|
3468
|
-
//#endregion
|
|
3469
|
-
//#region src/hooks/use-isomorphic-layout-effect.ts
|
|
3470
|
-
const useIsomorphicLayoutEffect = typeof window !== "undefined" ? react.useLayoutEffect : react.useEffect;
|
|
3471
|
-
|
|
3472
|
-
//#endregion
|
|
3473
|
-
//#region src/hooks/use-as-ref.ts
|
|
3474
|
-
function useAsRef(props) {
|
|
3475
|
-
const ref = react.useRef(props);
|
|
3476
|
-
useIsomorphicLayoutEffect(() => {
|
|
3477
|
-
ref.current = props;
|
|
3478
|
-
});
|
|
3479
|
-
return ref;
|
|
3480
|
-
}
|
|
3481
|
-
|
|
3482
|
-
//#endregion
|
|
3483
|
-
//#region src/components/ui/action-bar.tsx
|
|
3484
|
-
const ROOT_NAME = "ActionBar";
|
|
3485
|
-
const GROUP_NAME = "ActionBarGroup";
|
|
3486
|
-
const ITEM_NAME = "ActionBarItem";
|
|
3487
|
-
const CLOSE_NAME = "ActionBarClose";
|
|
3488
|
-
const SEPARATOR_NAME = "ActionBarSeparator";
|
|
3489
|
-
const ITEM_SELECT = "actionbar.itemSelect";
|
|
3490
|
-
const ENTRY_FOCUS = "actionbarFocusGroup.onEntryFocus";
|
|
3491
|
-
const EVENT_OPTIONS = {
|
|
3492
|
-
bubbles: false,
|
|
3493
|
-
cancelable: true
|
|
3494
|
-
};
|
|
3495
|
-
function focusFirst(candidates, preventScroll = false) {
|
|
3496
|
-
const PREVIOUSLY_FOCUSED_ELEMENT = document.activeElement;
|
|
3497
|
-
for (const candidateRef of candidates) {
|
|
3498
|
-
const candidate = candidateRef.current;
|
|
3499
|
-
if (!candidate) continue;
|
|
3500
|
-
if (candidate === PREVIOUSLY_FOCUSED_ELEMENT) return;
|
|
3501
|
-
candidate.focus({ preventScroll });
|
|
3502
|
-
if (document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT) return;
|
|
3503
|
-
}
|
|
3504
|
-
}
|
|
3505
|
-
function wrapArray(array, startIndex) {
|
|
3506
|
-
return array.map((_, index$1) => array[(startIndex + index$1) % array.length]);
|
|
3507
|
-
}
|
|
3508
|
-
function getDirectionAwareKey(key, dir) {
|
|
3509
|
-
if (dir !== "rtl") return key;
|
|
3510
|
-
return key === "ArrowLeft" ? "ArrowRight" : key === "ArrowRight" ? "ArrowLeft" : key;
|
|
3511
|
-
}
|
|
3512
|
-
const ActionBarContext = react.createContext(null);
|
|
3513
|
-
function useActionBarContext(consumerName) {
|
|
3514
|
-
const context = react.useContext(ActionBarContext);
|
|
3515
|
-
if (!context) throw new Error(`\`${consumerName}\` must be used within \`${ROOT_NAME}\``);
|
|
3516
|
-
return context;
|
|
3517
|
-
}
|
|
3518
|
-
const FocusContext = react.createContext(null);
|
|
3519
|
-
function useFocusContext(consumerName) {
|
|
3520
|
-
const context = react.useContext(FocusContext);
|
|
3521
|
-
if (!context) throw new Error(`\`${consumerName}\` must be used within \`FocusProvider\``);
|
|
3522
|
-
return context;
|
|
3523
|
-
}
|
|
3524
|
-
function ActionBar(props) {
|
|
3525
|
-
const { open = false, onOpenChange, onEscapeKeyDown, side = "bottom", alignOffset = 0, align = "center", sideOffset = 16, portalContainer: portalContainerProp, dir: dirProp, orientation = "horizontal", loop = true, className, style, ref, asChild,...rootProps } = props;
|
|
3526
|
-
const [mounted, setMounted] = react.useState(false);
|
|
3527
|
-
const rootRef = react.useRef(null);
|
|
3528
|
-
const composedRef = useComposedRefs(ref, rootRef);
|
|
3529
|
-
const propsRef = useAsRef({
|
|
3530
|
-
onEscapeKeyDown,
|
|
3531
|
-
onOpenChange
|
|
3532
|
-
});
|
|
3533
|
-
const dir = (0, __radix_ui_react_direction.useDirection)(dirProp);
|
|
3534
|
-
react.useLayoutEffect(() => {
|
|
3535
|
-
setMounted(true);
|
|
3536
|
-
}, []);
|
|
3537
|
-
react.useEffect(() => {
|
|
3538
|
-
if (!open) return;
|
|
3539
|
-
const ownerDocument = rootRef.current?.ownerDocument ?? document;
|
|
3540
|
-
function onKeyDown(event) {
|
|
3541
|
-
if (event.key === "Escape") {
|
|
3542
|
-
propsRef.current.onEscapeKeyDown?.(event);
|
|
3543
|
-
if (!event.defaultPrevented) propsRef.current.onOpenChange?.(false);
|
|
3544
|
-
}
|
|
3545
|
-
}
|
|
3546
|
-
ownerDocument.addEventListener("keydown", onKeyDown);
|
|
3547
|
-
return () => ownerDocument.removeEventListener("keydown", onKeyDown);
|
|
3548
|
-
}, [open, propsRef]);
|
|
3549
|
-
const contextValue = react.useMemo(() => ({
|
|
3550
|
-
onOpenChange,
|
|
3551
|
-
dir,
|
|
3552
|
-
orientation,
|
|
3553
|
-
loop
|
|
3554
|
-
}), [
|
|
3555
|
-
onOpenChange,
|
|
3556
|
-
dir,
|
|
3557
|
-
orientation,
|
|
3558
|
-
loop
|
|
3559
|
-
]);
|
|
3560
|
-
const portalContainer = portalContainerProp ?? (mounted ? globalThis.document?.body : null);
|
|
3561
|
-
if (!portalContainer || !open) return null;
|
|
3562
|
-
const RootPrimitive = asChild ? __radix_ui_react_slot.Slot : "div";
|
|
3563
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ActionBarContext.Provider, {
|
|
3564
|
-
value: contextValue,
|
|
3565
|
-
children: react_dom.createPortal(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(RootPrimitive, {
|
|
3566
|
-
role: "toolbar",
|
|
3567
|
-
"aria-orientation": orientation,
|
|
3568
|
-
"data-slot": "action-bar",
|
|
3569
|
-
"data-side": side,
|
|
3570
|
-
"data-align": align,
|
|
3571
|
-
"data-orientation": orientation,
|
|
3572
|
-
dir,
|
|
3573
|
-
...rootProps,
|
|
3574
|
-
ref: composedRef,
|
|
3575
|
-
className: cn("fixed z-50 rounded-lg border bg-card shadow-lg outline-none", "fade-in-0 zoom-in-95 animate-in duration-250 [animation-timing-function:cubic-bezier(0.16,1,0.3,1)]", "data-[side=bottom]:slide-in-from-bottom-4 data-[side=top]:slide-in-from-top-4", "motion-reduce:animate-none motion-reduce:transition-none", orientation === "horizontal" ? "flex flex-row items-center gap-2 px-2 py-1.5" : "flex flex-col items-start gap-2 px-1.5 py-2", className),
|
|
3576
|
-
style: {
|
|
3577
|
-
[side]: `${sideOffset}px`,
|
|
3578
|
-
...align === "center" && {
|
|
3579
|
-
left: "50%",
|
|
3580
|
-
translate: "-50% 0"
|
|
3581
|
-
},
|
|
3582
|
-
...align === "start" && { left: `${alignOffset}px` },
|
|
3583
|
-
...align === "end" && { right: `${alignOffset}px` },
|
|
3584
|
-
...style
|
|
3585
|
-
}
|
|
3586
|
-
}), portalContainer)
|
|
3587
|
-
});
|
|
3588
|
-
}
|
|
3589
|
-
function ActionBarSelection(props) {
|
|
3590
|
-
const { className, asChild,...selectionProps } = props;
|
|
3591
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(asChild ? __radix_ui_react_slot.Slot : "div", {
|
|
3592
|
-
"data-slot": "action-bar-selection",
|
|
3593
|
-
...selectionProps,
|
|
3594
|
-
className: cn("flex items-center gap-1 rounded-sm border px-2 py-1 font-medium text-sm tabular-nums", className)
|
|
3595
|
-
});
|
|
3596
|
-
}
|
|
3597
|
-
function ActionBarGroup(props) {
|
|
3598
|
-
const { onBlur: onBlurProp, onFocus: onFocusProp, onMouseDown: onMouseDownProp, className, asChild, ref,...groupProps } = props;
|
|
3599
|
-
const [tabStopId, setTabStopId] = react.useState(null);
|
|
3600
|
-
const [isTabbingBackOut, setIsTabbingBackOut] = react.useState(false);
|
|
3601
|
-
const [focusableItemCount, setFocusableItemCount] = react.useState(0);
|
|
3602
|
-
const composedRef = useComposedRefs(ref, react.useRef(null));
|
|
3603
|
-
const isClickFocusRef = react.useRef(false);
|
|
3604
|
-
const itemsRef = react.useRef(/* @__PURE__ */ new Map());
|
|
3605
|
-
const { dir, orientation } = useActionBarContext(GROUP_NAME);
|
|
3606
|
-
const onItemFocus = react.useCallback((tabStopId$1) => {
|
|
3607
|
-
setTabStopId(tabStopId$1);
|
|
3608
|
-
}, []);
|
|
3609
|
-
const onItemShiftTab = react.useCallback(() => {
|
|
3610
|
-
setIsTabbingBackOut(true);
|
|
3611
|
-
}, []);
|
|
3612
|
-
const onFocusableItemAdd = react.useCallback(() => {
|
|
3613
|
-
setFocusableItemCount((prevCount) => prevCount + 1);
|
|
3614
|
-
}, []);
|
|
3615
|
-
const onFocusableItemRemove = react.useCallback(() => {
|
|
3616
|
-
setFocusableItemCount((prevCount) => prevCount - 1);
|
|
3617
|
-
}, []);
|
|
3618
|
-
const onItemRegister = react.useCallback((item) => {
|
|
3619
|
-
itemsRef.current.set(item.id, item);
|
|
3620
|
-
}, []);
|
|
3621
|
-
const onItemUnregister = react.useCallback((id) => {
|
|
3622
|
-
itemsRef.current.delete(id);
|
|
3623
|
-
}, []);
|
|
3624
|
-
const getItems = react.useCallback(() => {
|
|
3625
|
-
return Array.from(itemsRef.current.values()).filter((item) => item.ref.current).sort((a, b) => {
|
|
3626
|
-
const elementA = a.ref.current;
|
|
3627
|
-
const elementB = b.ref.current;
|
|
3628
|
-
if (!elementA || !elementB) return 0;
|
|
3629
|
-
const position = elementA.compareDocumentPosition(elementB);
|
|
3630
|
-
if (position & Node.DOCUMENT_POSITION_FOLLOWING) return -1;
|
|
3631
|
-
if (position & Node.DOCUMENT_POSITION_PRECEDING) return 1;
|
|
3632
|
-
return 0;
|
|
3633
|
-
});
|
|
3634
|
-
}, []);
|
|
3635
|
-
const onBlur = react.useCallback((event) => {
|
|
3636
|
-
onBlurProp?.(event);
|
|
3637
|
-
if (event.defaultPrevented) return;
|
|
3638
|
-
setIsTabbingBackOut(false);
|
|
3639
|
-
}, [onBlurProp]);
|
|
3640
|
-
const onFocus = react.useCallback((event) => {
|
|
3641
|
-
onFocusProp?.(event);
|
|
3642
|
-
if (event.defaultPrevented) return;
|
|
3643
|
-
const isKeyboardFocus = !isClickFocusRef.current;
|
|
3644
|
-
if (event.target === event.currentTarget && isKeyboardFocus && !isTabbingBackOut) {
|
|
3645
|
-
const entryFocusEvent = new CustomEvent(ENTRY_FOCUS, EVENT_OPTIONS);
|
|
3646
|
-
event.currentTarget.dispatchEvent(entryFocusEvent);
|
|
3647
|
-
if (!entryFocusEvent.defaultPrevented) {
|
|
3648
|
-
const items = Array.from(itemsRef.current.values()).filter((item) => !item.disabled);
|
|
3649
|
-
focusFirst([items.find((item) => item.id === tabStopId), ...items].filter(Boolean).map((item) => item.ref), false);
|
|
3650
|
-
}
|
|
3651
|
-
}
|
|
3652
|
-
isClickFocusRef.current = false;
|
|
3653
|
-
}, [
|
|
3654
|
-
onFocusProp,
|
|
3655
|
-
isTabbingBackOut,
|
|
3656
|
-
tabStopId
|
|
3657
|
-
]);
|
|
3658
|
-
const onMouseDown = react.useCallback((event) => {
|
|
3659
|
-
onMouseDownProp?.(event);
|
|
3660
|
-
if (event.defaultPrevented) return;
|
|
3661
|
-
isClickFocusRef.current = true;
|
|
3662
|
-
}, [onMouseDownProp]);
|
|
3663
|
-
const focusContextValue = react.useMemo(() => ({
|
|
3664
|
-
tabStopId,
|
|
3665
|
-
onItemFocus,
|
|
3666
|
-
onItemShiftTab,
|
|
3667
|
-
onFocusableItemAdd,
|
|
3668
|
-
onFocusableItemRemove,
|
|
3669
|
-
onItemRegister,
|
|
3670
|
-
onItemUnregister,
|
|
3671
|
-
getItems
|
|
3672
|
-
}), [
|
|
3673
|
-
tabStopId,
|
|
3674
|
-
onItemFocus,
|
|
3675
|
-
onItemShiftTab,
|
|
3676
|
-
onFocusableItemAdd,
|
|
3677
|
-
onFocusableItemRemove,
|
|
3678
|
-
onItemRegister,
|
|
3679
|
-
onItemUnregister,
|
|
3680
|
-
getItems
|
|
3681
|
-
]);
|
|
3682
|
-
const GroupPrimitive = asChild ? __radix_ui_react_slot.Slot : "div";
|
|
3683
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FocusContext.Provider, {
|
|
3684
|
-
value: focusContextValue,
|
|
3685
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GroupPrimitive, {
|
|
3686
|
-
role: "group",
|
|
3687
|
-
"data-slot": "action-bar-group",
|
|
3688
|
-
"data-orientation": orientation,
|
|
3689
|
-
dir,
|
|
3690
|
-
tabIndex: isTabbingBackOut || focusableItemCount === 0 ? -1 : 0,
|
|
3691
|
-
...groupProps,
|
|
3692
|
-
ref: composedRef,
|
|
3693
|
-
className: cn("flex gap-2 outline-none", orientation === "horizontal" ? "items-center" : "w-full flex-col items-start", className),
|
|
3694
|
-
onBlur,
|
|
3695
|
-
onFocus,
|
|
3696
|
-
onMouseDown
|
|
3697
|
-
})
|
|
3698
|
-
});
|
|
3699
|
-
}
|
|
3700
|
-
function ActionBarItem(props) {
|
|
3701
|
-
const { onSelect, onClick: onClickProp, onFocus: onFocusProp, onKeyDown: onKeyDownProp, onMouseDown: onMouseDownProp, className, disabled, ref,...itemProps } = props;
|
|
3702
|
-
const itemRef = react.useRef(null);
|
|
3703
|
-
const composedRef = useComposedRefs(ref, itemRef);
|
|
3704
|
-
const isMouseClickRef = react.useRef(false);
|
|
3705
|
-
const { onOpenChange, dir, orientation, loop } = useActionBarContext(ITEM_NAME);
|
|
3706
|
-
const focusContext = useFocusContext(ITEM_NAME);
|
|
3707
|
-
const itemId = react.useId();
|
|
3708
|
-
const isTabStop = focusContext.tabStopId === itemId;
|
|
3709
|
-
useIsomorphicLayoutEffect(() => {
|
|
3710
|
-
focusContext.onItemRegister({
|
|
3711
|
-
id: itemId,
|
|
3712
|
-
ref: itemRef,
|
|
3713
|
-
disabled: !!disabled
|
|
3714
|
-
});
|
|
3715
|
-
if (!disabled) focusContext.onFocusableItemAdd();
|
|
3716
|
-
return () => {
|
|
3717
|
-
focusContext.onItemUnregister(itemId);
|
|
3718
|
-
if (!disabled) focusContext.onFocusableItemRemove();
|
|
3719
|
-
};
|
|
3720
|
-
}, [
|
|
3721
|
-
focusContext,
|
|
3722
|
-
itemId,
|
|
3723
|
-
disabled
|
|
3724
|
-
]);
|
|
3725
|
-
const onClick = react.useCallback((event) => {
|
|
3726
|
-
onClickProp?.(event);
|
|
3727
|
-
if (event.defaultPrevented) return;
|
|
3728
|
-
const item = itemRef.current;
|
|
3729
|
-
if (!item) return;
|
|
3730
|
-
const itemSelectEvent = new CustomEvent(ITEM_SELECT, {
|
|
3731
|
-
bubbles: true,
|
|
3732
|
-
cancelable: true
|
|
3733
|
-
});
|
|
3734
|
-
item.addEventListener(ITEM_SELECT, (event$1) => onSelect?.(event$1), { once: true });
|
|
3735
|
-
item.dispatchEvent(itemSelectEvent);
|
|
3736
|
-
if (!itemSelectEvent.defaultPrevented) onOpenChange?.(false);
|
|
3737
|
-
}, [
|
|
3738
|
-
onClickProp,
|
|
3739
|
-
onOpenChange,
|
|
3740
|
-
onSelect
|
|
3741
|
-
]);
|
|
3742
|
-
const onFocus = react.useCallback((event) => {
|
|
3743
|
-
onFocusProp?.(event);
|
|
3744
|
-
if (event.defaultPrevented) return;
|
|
3745
|
-
focusContext.onItemFocus(itemId);
|
|
3746
|
-
isMouseClickRef.current = false;
|
|
3747
|
-
}, [
|
|
3748
|
-
onFocusProp,
|
|
3749
|
-
focusContext,
|
|
3750
|
-
itemId
|
|
3751
|
-
]);
|
|
3752
|
-
const onKeyDown = react.useCallback((event) => {
|
|
3753
|
-
onKeyDownProp?.(event);
|
|
3754
|
-
if (event.defaultPrevented) return;
|
|
3755
|
-
if (event.key === "Tab" && event.shiftKey) {
|
|
3756
|
-
focusContext.onItemShiftTab();
|
|
3757
|
-
return;
|
|
3758
|
-
}
|
|
3759
|
-
if (event.target !== event.currentTarget) return;
|
|
3760
|
-
const key = getDirectionAwareKey(event.key, dir);
|
|
3761
|
-
let focusIntent;
|
|
3762
|
-
if (orientation === "horizontal") {
|
|
3763
|
-
if (key === "ArrowLeft") focusIntent = "prev";
|
|
3764
|
-
else if (key === "ArrowRight") focusIntent = "next";
|
|
3765
|
-
else if (key === "Home") focusIntent = "first";
|
|
3766
|
-
else if (key === "End") focusIntent = "last";
|
|
3767
|
-
} else if (key === "ArrowUp") focusIntent = "prev";
|
|
3768
|
-
else if (key === "ArrowDown") focusIntent = "next";
|
|
3769
|
-
else if (key === "Home") focusIntent = "first";
|
|
3770
|
-
else if (key === "End") focusIntent = "last";
|
|
3771
|
-
if (focusIntent !== void 0) {
|
|
3772
|
-
if (event.metaKey || event.ctrlKey || event.altKey || event.shiftKey) return;
|
|
3773
|
-
event.preventDefault();
|
|
3774
|
-
let candidateRefs = focusContext.getItems().filter((item) => !item.disabled).map((item) => item.ref);
|
|
3775
|
-
if (focusIntent === "last") candidateRefs.reverse();
|
|
3776
|
-
else if (focusIntent === "prev" || focusIntent === "next") {
|
|
3777
|
-
if (focusIntent === "prev") candidateRefs.reverse();
|
|
3778
|
-
const currentIndex = candidateRefs.findIndex((ref$1) => ref$1.current === event.currentTarget);
|
|
3779
|
-
candidateRefs = loop ? wrapArray(candidateRefs, currentIndex + 1) : candidateRefs.slice(currentIndex + 1);
|
|
3780
|
-
}
|
|
3781
|
-
queueMicrotask(() => focusFirst(candidateRefs));
|
|
3782
|
-
}
|
|
3783
|
-
}, [
|
|
3784
|
-
onKeyDownProp,
|
|
3785
|
-
focusContext,
|
|
3786
|
-
dir,
|
|
3787
|
-
orientation,
|
|
3788
|
-
loop
|
|
3789
|
-
]);
|
|
3790
|
-
const onMouseDown = react.useCallback((event) => {
|
|
3791
|
-
onMouseDownProp?.(event);
|
|
3792
|
-
if (event.defaultPrevented) return;
|
|
3793
|
-
isMouseClickRef.current = true;
|
|
3794
|
-
if (disabled) event.preventDefault();
|
|
3795
|
-
else focusContext.onItemFocus(itemId);
|
|
3796
|
-
}, [
|
|
3797
|
-
onMouseDownProp,
|
|
3798
|
-
focusContext,
|
|
3799
|
-
itemId,
|
|
3800
|
-
disabled
|
|
3801
|
-
]);
|
|
3802
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.Button, {
|
|
3803
|
-
type: "button",
|
|
3804
|
-
"data-slot": "action-bar-item",
|
|
3805
|
-
variant: "secondary",
|
|
3806
|
-
size: "sm",
|
|
3807
|
-
disabled,
|
|
3808
|
-
tabIndex: isTabStop ? 0 : -1,
|
|
3809
|
-
...itemProps,
|
|
3810
|
-
className: cn(orientation === "vertical" && "w-full", className),
|
|
3811
|
-
ref: composedRef,
|
|
3812
|
-
onClick,
|
|
3813
|
-
onFocus,
|
|
3814
|
-
onKeyDown,
|
|
3815
|
-
onMouseDown
|
|
3816
|
-
});
|
|
3817
|
-
}
|
|
3818
|
-
function ActionBarClose(props) {
|
|
3819
|
-
const { asChild, className, onClick,...closeProps } = props;
|
|
3820
|
-
const { onOpenChange } = useActionBarContext(CLOSE_NAME);
|
|
3821
|
-
const onCloseClick = react.useCallback((event) => {
|
|
3822
|
-
onClick?.(event);
|
|
3823
|
-
if (event.defaultPrevented) return;
|
|
3824
|
-
onOpenChange?.(false);
|
|
3825
|
-
}, [onOpenChange, onClick]);
|
|
3826
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(asChild ? __radix_ui_react_slot.Slot : "button", {
|
|
3827
|
-
type: "button",
|
|
3828
|
-
"data-slot": "action-bar-close",
|
|
3829
|
-
...closeProps,
|
|
3830
|
-
className: cn("rounded-xs opacity-70 outline-none hover:opacity-100 focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/50 disabled:pointer-events-none [&_svg:not([class*='size-'])]:size-3.5 [&_svg]:pointer-events-none [&_svg]:shrink-0", className),
|
|
3831
|
-
onClick: onCloseClick
|
|
3832
|
-
});
|
|
3833
|
-
}
|
|
3834
|
-
function ActionBarSeparator(props) {
|
|
3835
|
-
const { orientation: orientationProp, asChild, className,...separatorProps } = props;
|
|
3836
|
-
const context = useActionBarContext(SEPARATOR_NAME);
|
|
3837
|
-
const orientation = orientationProp ?? context.orientation;
|
|
3838
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(asChild ? __radix_ui_react_slot.Slot : "div", {
|
|
3839
|
-
role: "separator",
|
|
3840
|
-
"aria-orientation": orientation,
|
|
3841
|
-
"aria-hidden": "true",
|
|
3842
|
-
"data-slot": "action-bar-separator",
|
|
3843
|
-
...separatorProps,
|
|
3844
|
-
className: cn("in-data-[slot=action-bar-selection]:ml-0.5 in-data-[slot=action-bar-selection]:h-4 in-data-[slot=action-bar-selection]:w-px bg-border", orientation === "horizontal" ? "h-6 w-px" : "h-px w-full", className)
|
|
3845
|
-
});
|
|
3846
|
-
}
|
|
3847
|
-
|
|
3848
2856
|
//#endregion
|
|
3849
2857
|
//#region src/components/data-table/data-table-column-header.tsx
|
|
3850
2858
|
function DataTableColumnHeader({ column, label, className,...props }) {
|
|
@@ -3852,32 +2860,32 @@ function DataTableColumnHeader({ column, label, className,...props }) {
|
|
|
3852
2860
|
className: cn(className),
|
|
3853
2861
|
children: label
|
|
3854
2862
|
});
|
|
3855
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2863
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.DropdownMenu, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.DropdownMenuTrigger, {
|
|
3856
2864
|
className: cn("-ml-1.5 flex h-8 items-center gap-1.5 rounded-md px-2 py-1.5 hover:bg-accent focus:outline-none focus:ring-1 focus:ring-ring data-[state=open]:bg-accent [&_svg]:size-4 [&_svg]:shrink-0 [&_svg]:text-muted-foreground", className),
|
|
3857
2865
|
...props,
|
|
3858
2866
|
children: [label, column.getCanSort() && (column.getIsSorted() === "desc" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronDown, {}) : column.getIsSorted() === "asc" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronUp, {}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronsUpDown, {}))]
|
|
3859
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2867
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.DropdownMenuContent, {
|
|
3860
2868
|
align: "start",
|
|
3861
2869
|
className: "w-28",
|
|
3862
2870
|
children: [column.getCanSort() && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
3863
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2871
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.DropdownMenuCheckboxItem, {
|
|
3864
2872
|
className: "relative pr-8 pl-2 [&>span:first-child]:right-2 [&>span:first-child]:left-auto [&_svg]:text-muted-foreground",
|
|
3865
2873
|
checked: column.getIsSorted() === "asc",
|
|
3866
2874
|
onClick: () => column.toggleSorting(false),
|
|
3867
2875
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronUp, {}), "Asc"]
|
|
3868
2876
|
}),
|
|
3869
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2877
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.DropdownMenuCheckboxItem, {
|
|
3870
2878
|
className: "relative pr-8 pl-2 [&>span:first-child]:right-2 [&>span:first-child]:left-auto [&_svg]:text-muted-foreground",
|
|
3871
2879
|
checked: column.getIsSorted() === "desc",
|
|
3872
2880
|
onClick: () => column.toggleSorting(true),
|
|
3873
2881
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronDown, {}), "Desc"]
|
|
3874
2882
|
}),
|
|
3875
|
-
column.getIsSorted() && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2883
|
+
column.getIsSorted() && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.DropdownMenuItem, {
|
|
3876
2884
|
className: "pl-2 [&_svg]:text-muted-foreground",
|
|
3877
2885
|
onClick: () => column.clearSorting(),
|
|
3878
2886
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.X, {}), "Reset"]
|
|
3879
2887
|
})
|
|
3880
|
-
] }), column.getCanHide() && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2888
|
+
] }), column.getCanHide() && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.DropdownMenuCheckboxItem, {
|
|
3881
2889
|
className: "relative pr-8 pl-2 [&>span:first-child]:right-2 [&>span:first-child]:left-auto [&_svg]:text-muted-foreground",
|
|
3882
2890
|
checked: !column.getIsVisible(),
|
|
3883
2891
|
onClick: () => column.toggleVisibility(false),
|
|
@@ -4137,15 +3145,15 @@ function renderCell(value, type, options) {
|
|
|
4137
3145
|
if (options && options.length > 0) {
|
|
4138
3146
|
if (Array.isArray(value)) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4139
3147
|
className: "flex gap-1 flex-wrap",
|
|
4140
|
-
children: [value.slice(0, 3).map((v, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
3148
|
+
children: [value.slice(0, 3).map((v, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Badge, {
|
|
4141
3149
|
variant: "secondary",
|
|
4142
3150
|
children: formatOptionValue(v)
|
|
4143
|
-
}, i)), value.length > 3 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
3151
|
+
}, i)), value.length > 3 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Badge, {
|
|
4144
3152
|
variant: "outline",
|
|
4145
3153
|
children: ["+", value.length - 3]
|
|
4146
3154
|
})]
|
|
4147
3155
|
});
|
|
4148
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
3156
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Badge, {
|
|
4149
3157
|
variant: "outline",
|
|
4150
3158
|
className: "capitalize",
|
|
4151
3159
|
children: formatOptionValue(value)
|
|
@@ -4154,17 +3162,17 @@ function renderCell(value, type, options) {
|
|
|
4154
3162
|
switch (type) {
|
|
4155
3163
|
case "boolean": return value ? "✓" : "✗";
|
|
4156
3164
|
case "date": return formatDate(value);
|
|
4157
|
-
case "enum": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
3165
|
+
case "enum": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Badge, {
|
|
4158
3166
|
variant: "outline",
|
|
4159
3167
|
className: "capitalize",
|
|
4160
3168
|
children: String(value)
|
|
4161
3169
|
});
|
|
4162
3170
|
case "array": return Array.isArray(value) ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4163
3171
|
className: "flex gap-1 flex-wrap",
|
|
4164
|
-
children: [value.slice(0, 3).map((v, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
3172
|
+
children: [value.slice(0, 3).map((v, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Badge, {
|
|
4165
3173
|
variant: "secondary",
|
|
4166
3174
|
children: String(v)
|
|
4167
|
-
}, i)), value.length > 3 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
3175
|
+
}, i)), value.length > 3 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Badge, {
|
|
4168
3176
|
variant: "outline",
|
|
4169
3177
|
children: ["+", value.length - 3]
|
|
4170
3178
|
})]
|
|
@@ -4245,13 +3253,13 @@ function createTableSchema(schema, options) {
|
|
|
4245
3253
|
function createSelectColumn() {
|
|
4246
3254
|
return {
|
|
4247
3255
|
id: "select",
|
|
4248
|
-
header: ({ table }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
3256
|
+
header: ({ table }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Checkbox, {
|
|
4249
3257
|
"aria-label": "Select all",
|
|
4250
3258
|
className: "translate-y-0.5",
|
|
4251
3259
|
checked: table.getIsAllPageRowsSelected() || table.getIsSomePageRowsSelected() && "indeterminate",
|
|
4252
3260
|
onCheckedChange: (value) => table.toggleAllPageRowsSelected(!!value)
|
|
4253
3261
|
}),
|
|
4254
|
-
cell: ({ row }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
3262
|
+
cell: ({ row }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Checkbox, {
|
|
4255
3263
|
"aria-label": "Select row",
|
|
4256
3264
|
className: "translate-y-0.5",
|
|
4257
3265
|
checked: row.getIsSelected(),
|
|
@@ -4272,18 +3280,18 @@ function createActionsColumn(items) {
|
|
|
4272
3280
|
};
|
|
4273
3281
|
return {
|
|
4274
3282
|
id: "actions",
|
|
4275
|
-
cell: ({ row }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
3283
|
+
cell: ({ row }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.DropdownMenu, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.DropdownMenuTrigger, {
|
|
4276
3284
|
asChild: true,
|
|
4277
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
3285
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
4278
3286
|
"aria-label": "Open menu",
|
|
4279
3287
|
variant: "ghost",
|
|
4280
3288
|
className: "flex size-8 p-0 data-[state=open]:bg-muted",
|
|
4281
3289
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Ellipsis, { className: "size-4" })
|
|
4282
3290
|
})
|
|
4283
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
3291
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.DropdownMenuContent, {
|
|
4284
3292
|
align: "end",
|
|
4285
3293
|
className: "w-40",
|
|
4286
|
-
children: items.map((item, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react.Fragment, { children: [item.separator && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
3294
|
+
children: items.map((item, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react.Fragment, { children: [item.separator && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.DropdownMenuSeparator, {}), item.component ? renderActionComponent(item, row) : item.label && item.onClick ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.DropdownMenuItem, {
|
|
4287
3295
|
className: item.variant === "destructive" ? "text-destructive" : "",
|
|
4288
3296
|
onClick: () => item.onClick?.(row.original),
|
|
4289
3297
|
children: item.label
|
|
@@ -4505,12 +3513,22 @@ function downloadCSV(csvContent, filename) {
|
|
|
4505
3513
|
|
|
4506
3514
|
//#endregion
|
|
4507
3515
|
//#region src/components/auto-crud/auto-table-action-bar.tsx
|
|
4508
|
-
|
|
4509
|
-
|
|
3516
|
+
const DEFAULT_DELETE_CONFIRMATION = {
|
|
3517
|
+
title: "确认批量删除",
|
|
3518
|
+
description: (count) => `此操作无法撤销。确定要删除选中的 ${count} 条记录吗?`,
|
|
3519
|
+
cancel: "取消",
|
|
3520
|
+
confirm: "确认删除"
|
|
3521
|
+
};
|
|
3522
|
+
function isBatchCustomAction(action$1) {
|
|
3523
|
+
return action$1.type === "custom";
|
|
4510
3524
|
}
|
|
4511
|
-
function AutoTableActionBar({ table, onDeleteSelected, onUpdateSelected, batchUpdateFields, enableExport = true, showDefaultExport = true, enableDelete = true, extraActions, actions }) {
|
|
3525
|
+
function AutoTableActionBar({ table, onDeleteSelected, onUpdateSelected, batchUpdateFields, enableExport = true, showDefaultExport = true, enableDelete = true, extraActions, actions, deleteConfirmation = DEFAULT_DELETE_CONFIRMATION }) {
|
|
4512
3526
|
const rows = table.getFilteredSelectedRowModel().rows;
|
|
4513
3527
|
const selectedRows = react.useMemo(() => rows.map((row) => row.original), [rows]);
|
|
3528
|
+
const [deleteDialogOpen, setDeleteDialogOpen] = react.useState(false);
|
|
3529
|
+
react.useEffect(() => {
|
|
3530
|
+
if (selectedRows.length === 0) setDeleteDialogOpen(false);
|
|
3531
|
+
}, [selectedRows.length]);
|
|
4514
3532
|
const clearSelection = react.useCallback(() => {
|
|
4515
3533
|
table.toggleAllRowsSelected(false);
|
|
4516
3534
|
}, [table]);
|
|
@@ -4533,8 +3551,34 @@ function AutoTableActionBar({ table, onDeleteSelected, onUpdateSelected, batchUp
|
|
|
4533
3551
|
});
|
|
4534
3552
|
}, [table]);
|
|
4535
3553
|
const onDelete = react.useCallback(() => {
|
|
4536
|
-
if (onDeleteSelected
|
|
4537
|
-
|
|
3554
|
+
if (onDeleteSelected && selectedRows.length > 0) {
|
|
3555
|
+
onDeleteSelected(selectedRows);
|
|
3556
|
+
clearSelection();
|
|
3557
|
+
}
|
|
3558
|
+
setDeleteDialogOpen(false);
|
|
3559
|
+
}, [
|
|
3560
|
+
selectedRows,
|
|
3561
|
+
onDeleteSelected,
|
|
3562
|
+
clearSelection
|
|
3563
|
+
]);
|
|
3564
|
+
const runDeleteAction = react.useCallback((action$1, event) => {
|
|
3565
|
+
if (selectedRows.length === 0) {
|
|
3566
|
+
setDeleteDialogOpen(false);
|
|
3567
|
+
return;
|
|
3568
|
+
}
|
|
3569
|
+
if (action$1.onClick) {
|
|
3570
|
+
action$1.onClick(selectedRows, actionContext, event);
|
|
3571
|
+
clearSelection();
|
|
3572
|
+
setDeleteDialogOpen(false);
|
|
3573
|
+
return;
|
|
3574
|
+
}
|
|
3575
|
+
onDelete();
|
|
3576
|
+
}, [
|
|
3577
|
+
actionContext,
|
|
3578
|
+
clearSelection,
|
|
3579
|
+
onDelete,
|
|
3580
|
+
selectedRows
|
|
3581
|
+
]);
|
|
4538
3582
|
const handleBatchUpdate = react.useCallback((field, value) => {
|
|
4539
3583
|
if (onUpdateSelected) {
|
|
4540
3584
|
onUpdateSelected(selectedRows, { [field]: value });
|
|
@@ -4546,33 +3590,43 @@ function AutoTableActionBar({ table, onDeleteSelected, onUpdateSelected, batchUp
|
|
|
4546
3590
|
clearSelection
|
|
4547
3591
|
]);
|
|
4548
3592
|
const renderComponent = react.useCallback((component) => typeof component === "function" ? component(actionContext) : component, [actionContext]);
|
|
4549
|
-
const renderBatchUpdate = react.useCallback((keyPrefix = "batch-update") => batchUpdateFields?.map((fieldConfig) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
3593
|
+
const renderBatchUpdate = react.useCallback((keyPrefix = "batch-update") => batchUpdateFields?.map((fieldConfig) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.DropdownMenu, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.DropdownMenuTrigger, {
|
|
4550
3594
|
asChild: true,
|
|
4551
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
3595
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
4552
3596
|
variant: "ghost",
|
|
4553
3597
|
size: "sm",
|
|
4554
3598
|
className: "h-7 gap-1 px-2",
|
|
4555
3599
|
children: [fieldConfig.label, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronDown, { className: "size-3.5" })]
|
|
4556
3600
|
})
|
|
4557
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
3601
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.DropdownMenuContent, {
|
|
4558
3602
|
align: "start",
|
|
4559
|
-
children: fieldConfig.options.map((option) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
3603
|
+
children: fieldConfig.options.map((option) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.DropdownMenuItem, {
|
|
4560
3604
|
onClick: () => handleBatchUpdate(fieldConfig.field, option.value),
|
|
4561
3605
|
children: option.label
|
|
4562
3606
|
}, option.value))
|
|
4563
3607
|
})] }, `${keyPrefix}-${fieldConfig.field}`)), [batchUpdateFields, handleBatchUpdate]);
|
|
4564
|
-
const renderBuiltinAction = react.useCallback((action) => {
|
|
4565
|
-
if (!(action.type === "batchUpdate" ? !!onUpdateSelected && !!batchUpdateFields?.length : action.type === "export" ? enableExport : enableDelete && !!onDeleteSelected)) return null;
|
|
4566
|
-
if (action.component) return renderComponent(action.component);
|
|
4567
|
-
if (action.type === "batchUpdate") return renderBatchUpdate(action.type);
|
|
4568
|
-
if (action.type === "export") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(ActionBarItem, {
|
|
4569
|
-
onClick: (event) => action.onClick ? action.onClick(selectedRows, actionContext, event) : onExport(),
|
|
4570
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Download, {}), action.label ?? "Export"]
|
|
3608
|
+
const renderBuiltinAction = react.useCallback((action$1) => {
|
|
3609
|
+
if (!(action$1.type === "batchUpdate" ? !!onUpdateSelected && !!batchUpdateFields?.length : action$1.type === "export" ? enableExport : enableDelete && !!onDeleteSelected)) return null;
|
|
3610
|
+
if (action$1.component) return renderComponent(action$1.component);
|
|
3611
|
+
if (action$1.type === "batchUpdate") return renderBatchUpdate(action$1.type);
|
|
3612
|
+
if (action$1.type === "export") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn_ui.ActionBarItem, {
|
|
3613
|
+
onClick: (event) => action$1.onClick ? action$1.onClick(selectedRows, actionContext, event) : onExport(),
|
|
3614
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Download, {}), action$1.label ?? "Export"]
|
|
4571
3615
|
}, "export");
|
|
4572
|
-
if (action.type === "delete") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.
|
|
3616
|
+
if (action$1.type === "delete") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.AlertDialog, {
|
|
3617
|
+
open: deleteDialogOpen,
|
|
3618
|
+
onOpenChange: setDeleteDialogOpen,
|
|
3619
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn_ui.ActionBarItem, {
|
|
3620
|
+
variant: "destructive",
|
|
3621
|
+
onClick: () => setDeleteDialogOpen(true),
|
|
3622
|
+
onSelect: (event) => event.preventDefault(),
|
|
3623
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Trash2, {}), action$1.label ?? "Delete"]
|
|
3624
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.AlertDialogContent, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.AlertDialogHeader, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.AlertDialogTitle, { children: deleteConfirmation.title }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.AlertDialogDescription, { children: deleteConfirmation.description(selectedRows.length) })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.AlertDialogFooter, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.AlertDialogCancel, { children: deleteConfirmation.cancel }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.AlertDialogAction, {
|
|
3625
|
+
className: "bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30",
|
|
3626
|
+
disabled: selectedRows.length === 0,
|
|
3627
|
+
onClick: (event) => runDeleteAction(action$1, event),
|
|
3628
|
+
children: deleteConfirmation.confirm
|
|
3629
|
+
})] })] })]
|
|
4576
3630
|
}, "delete");
|
|
4577
3631
|
return null;
|
|
4578
3632
|
}, [
|
|
@@ -4580,21 +3634,24 @@ function AutoTableActionBar({ table, onDeleteSelected, onUpdateSelected, batchUp
|
|
|
4580
3634
|
batchUpdateFields?.length,
|
|
4581
3635
|
enableDelete,
|
|
4582
3636
|
enableExport,
|
|
3637
|
+
deleteConfirmation,
|
|
3638
|
+
deleteDialogOpen,
|
|
4583
3639
|
onDelete,
|
|
4584
3640
|
onDeleteSelected,
|
|
4585
3641
|
onUpdateSelected,
|
|
4586
3642
|
onExport,
|
|
4587
3643
|
renderBatchUpdate,
|
|
4588
3644
|
renderComponent,
|
|
3645
|
+
runDeleteAction,
|
|
4589
3646
|
selectedRows
|
|
4590
3647
|
]);
|
|
4591
|
-
const renderCustomAction = react.useCallback((action, index$1) => {
|
|
4592
|
-
if (action.component) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children: renderComponent(action.component) }, `custom-${index$1}`);
|
|
4593
|
-
if (!action.label || !action.onClick) return null;
|
|
4594
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ActionBarItem, {
|
|
4595
|
-
variant: action.variant === "destructive" ? "destructive" : "secondary",
|
|
4596
|
-
onClick: (event) => action.onClick?.(selectedRows, actionContext, event),
|
|
4597
|
-
children: action.label
|
|
3648
|
+
const renderCustomAction = react.useCallback((action$1, index$1) => {
|
|
3649
|
+
if (action$1.component) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children: renderComponent(action$1.component) }, `custom-${index$1}`);
|
|
3650
|
+
if (!action$1.label || !action$1.onClick) return null;
|
|
3651
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn_ui.ActionBarItem, {
|
|
3652
|
+
variant: action$1.variant === "destructive" ? "destructive" : "secondary",
|
|
3653
|
+
onClick: (event) => action$1.onClick?.(selectedRows, actionContext, event),
|
|
3654
|
+
children: action$1.label
|
|
4598
3655
|
}, `custom-${index$1}`);
|
|
4599
3656
|
}, [
|
|
4600
3657
|
actionContext,
|
|
@@ -4607,7 +3664,7 @@ function AutoTableActionBar({ table, onDeleteSelected, onUpdateSelected, batchUp
|
|
|
4607
3664
|
{ type: "export" },
|
|
4608
3665
|
{ type: "delete" }
|
|
4609
3666
|
]) : actions;
|
|
4610
|
-
const resolvedActions = configuredActions?.filter((action) => !action.hidden);
|
|
3667
|
+
const resolvedActions = configuredActions?.filter((action$1) => !action$1.hidden);
|
|
4611
3668
|
if (configuredActions === void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
4612
3669
|
renderBuiltinAction({ type: "batchUpdate" }),
|
|
4613
3670
|
extraActions,
|
|
@@ -4615,9 +3672,9 @@ function AutoTableActionBar({ table, onDeleteSelected, onUpdateSelected, batchUp
|
|
|
4615
3672
|
renderBuiltinAction({ type: "delete" })
|
|
4616
3673
|
] });
|
|
4617
3674
|
if (!resolvedActions || resolvedActions.length === 0) return null;
|
|
4618
|
-
if (!resolvedActions.some((action) => action.type !== "custom")) {
|
|
4619
|
-
const startNodes = resolvedActions.filter(isBatchCustomAction).filter((action) => action.position === "start").map((action, index$1) => renderCustomAction(action, index$1));
|
|
4620
|
-
const endNodes = resolvedActions.filter(isBatchCustomAction).filter((action) => action.position !== "start").map((action, index$1) => renderCustomAction(action, index$1));
|
|
3675
|
+
if (!resolvedActions.some((action$1) => action$1.type !== "custom")) {
|
|
3676
|
+
const startNodes = resolvedActions.filter(isBatchCustomAction).filter((action$1) => action$1.position === "start").map((action$1, index$1) => renderCustomAction(action$1, index$1));
|
|
3677
|
+
const endNodes = resolvedActions.filter(isBatchCustomAction).filter((action$1) => action$1.position !== "start").map((action$1, index$1) => renderCustomAction(action$1, index$1));
|
|
4621
3678
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
4622
3679
|
startNodes,
|
|
4623
3680
|
renderBuiltinAction({ type: "batchUpdate" }),
|
|
@@ -4627,9 +3684,9 @@ function AutoTableActionBar({ table, onDeleteSelected, onUpdateSelected, batchUp
|
|
|
4627
3684
|
endNodes
|
|
4628
3685
|
] });
|
|
4629
3686
|
}
|
|
4630
|
-
return resolvedActions.map((action, index$1) => {
|
|
4631
|
-
if (action.type === "custom") return renderCustomAction(action, index$1);
|
|
4632
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children: renderBuiltinAction(action) }, action.type);
|
|
3687
|
+
return resolvedActions.map((action$1, index$1) => {
|
|
3688
|
+
if (action$1.type === "custom") return renderCustomAction(action$1, index$1);
|
|
3689
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children: renderBuiltinAction(action$1) }, action$1.type);
|
|
4633
3690
|
});
|
|
4634
3691
|
}, [
|
|
4635
3692
|
actions,
|
|
@@ -4638,21 +3695,21 @@ function AutoTableActionBar({ table, onDeleteSelected, onUpdateSelected, batchUp
|
|
|
4638
3695
|
renderCustomAction,
|
|
4639
3696
|
showDefaultExport
|
|
4640
3697
|
]);
|
|
4641
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(ActionBar, {
|
|
3698
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn_ui.ActionBar, {
|
|
4642
3699
|
open: rows.length > 0,
|
|
4643
3700
|
onOpenChange,
|
|
4644
3701
|
children: [
|
|
4645
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(ActionBarSelection, { children: [
|
|
3702
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn_ui.ActionBarSelection, { children: [
|
|
4646
3703
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4647
3704
|
className: "font-medium",
|
|
4648
3705
|
children: rows.length
|
|
4649
3706
|
}),
|
|
4650
3707
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "selected" }),
|
|
4651
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ActionBarSeparator, {}),
|
|
4652
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ActionBarClose, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.X, {}) })
|
|
3708
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn_ui.ActionBarSeparator, {}),
|
|
3709
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn_ui.ActionBarClose, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.X, {}) })
|
|
4653
3710
|
] }),
|
|
4654
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ActionBarSeparator, {}),
|
|
4655
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ActionBarGroup, { children: renderedActions })
|
|
3711
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn_ui.ActionBarSeparator, {}),
|
|
3712
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn_ui.ActionBarGroup, { children: renderedActions })
|
|
4656
3713
|
]
|
|
4657
3714
|
});
|
|
4658
3715
|
}
|
|
@@ -4913,7 +3970,7 @@ const filterModeConfig = {
|
|
|
4913
3970
|
tooltip: "Linear-style command filters"
|
|
4914
3971
|
}
|
|
4915
3972
|
};
|
|
4916
|
-
function AutoTable({ schema, data, pageCount = 1, overrides, enableRowSelection = true, exclude, actions, pinnedColumns, filterMode = "simple", search = false, onDeleteSelected, onUpdateSelected, batchUpdateFields, actionBarExtra, actionBarActions, initialSorting, enableExport = true, showDefaultExport = true, onSelectedCountChange, onSelectedRowsChange, getSelectedRows }) {
|
|
3973
|
+
function AutoTable({ schema, data, pageCount = 1, overrides, enableRowSelection = true, exclude, actions, pinnedColumns, filterMode = "simple", search = false, onDeleteSelected, onUpdateSelected, batchUpdateFields, actionBarExtra, actionBarActions, deleteConfirmation, initialSorting, enableExport = true, showDefaultExport = true, onSelectedCountChange, onSelectedRowsChange, getSelectedRows }) {
|
|
4917
3974
|
const modes = filterMode ? Array.isArray(filterMode) ? filterMode : [filterMode] : DEFAULT_MODES;
|
|
4918
3975
|
const [currentMode, setCurrentMode] = useQueryState("filterMode", parseAsStringEnum(modes).withDefault(modes[0] ?? "simple"));
|
|
4919
3976
|
const showToggle = modes.length > 1;
|
|
@@ -4984,9 +4041,9 @@ function AutoTable({ schema, data, pageCount = 1, overrides, enableRowSelection
|
|
|
4984
4041
|
(0, react.useEffect)(() => {
|
|
4985
4042
|
onSelectedRowsChange?.(selectedRows);
|
|
4986
4043
|
}, [selectedRows, onSelectedRowsChange]);
|
|
4987
|
-
const FilterModeSelect = showToggle ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
4044
|
+
const FilterModeSelect = showToggle ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.DropdownMenu, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.DropdownMenuTrigger, {
|
|
4988
4045
|
asChild: true,
|
|
4989
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
4046
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
4990
4047
|
variant: "outline",
|
|
4991
4048
|
size: "sm",
|
|
4992
4049
|
className: "h-8 w-8 p-0",
|
|
@@ -4996,21 +4053,21 @@ function AutoTable({ schema, data, pageCount = 1, overrides, enableRowSelection
|
|
|
4996
4053
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, { className: "size-4 text-muted-foreground" });
|
|
4997
4054
|
})()
|
|
4998
4055
|
})
|
|
4999
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
4056
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.DropdownMenuContent, {
|
|
5000
4057
|
align: "end",
|
|
5001
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
4058
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.DropdownMenuRadioGroup, {
|
|
5002
4059
|
value: currentMode,
|
|
5003
4060
|
onValueChange: (v) => setCurrentMode(v),
|
|
5004
4061
|
children: modes.map((mode) => {
|
|
5005
4062
|
const config = filterModeConfig[mode];
|
|
5006
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
4063
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.DropdownMenuRadioItem, {
|
|
5007
4064
|
value: mode,
|
|
5008
4065
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(config.icon, { className: "size-4" }), config.label]
|
|
5009
4066
|
}, mode);
|
|
5010
4067
|
})
|
|
5011
4068
|
})
|
|
5012
4069
|
})] }) : null;
|
|
5013
|
-
const searchInput = search ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
4070
|
+
const searchInput = search ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Input, {
|
|
5014
4071
|
value: searchValue,
|
|
5015
4072
|
onChange: (event) => {
|
|
5016
4073
|
setSearchValue(event.target.value);
|
|
@@ -5090,7 +4147,8 @@ function AutoTable({ schema, data, pageCount = 1, overrides, enableRowSelection
|
|
|
5090
4147
|
enableExport,
|
|
5091
4148
|
showDefaultExport,
|
|
5092
4149
|
extraActions: actionBarExtra,
|
|
5093
|
-
actions: actionBarActions
|
|
4150
|
+
actions: actionBarActions,
|
|
4151
|
+
deleteConfirmation
|
|
5094
4152
|
})
|
|
5095
4153
|
]
|
|
5096
4154
|
});
|
|
@@ -5099,16 +4157,16 @@ function AutoTable({ schema, data, pageCount = 1, overrides, enableRowSelection
|
|
|
5099
4157
|
//#endregion
|
|
5100
4158
|
//#region src/components/auto-crud/form-modal.tsx
|
|
5101
4159
|
function FormModal({ open, onOpenChange, title, description, children, variant = "dialog", side = "right", className, footer }) {
|
|
5102
|
-
if (variant === "sheet") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
4160
|
+
if (variant === "sheet") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Sheet, {
|
|
5103
4161
|
open,
|
|
5104
4162
|
onOpenChange,
|
|
5105
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
4163
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.SheetContent, {
|
|
5106
4164
|
side,
|
|
5107
4165
|
className: cn("sm:max-w-lg flex flex-col p-0", className),
|
|
5108
4166
|
children: [
|
|
5109
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
4167
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.SheetHeader, {
|
|
5110
4168
|
className: "flex-shrink-0 px-6 pt-6",
|
|
5111
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
4169
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.SheetTitle, { children: title }), description && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.SheetDescription, { children: description })]
|
|
5112
4170
|
}),
|
|
5113
4171
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5114
4172
|
className: "flex-1 overflow-y-auto min-h-0",
|
|
@@ -5124,15 +4182,15 @@ function FormModal({ open, onOpenChange, title, description, children, variant =
|
|
|
5124
4182
|
]
|
|
5125
4183
|
})
|
|
5126
4184
|
});
|
|
5127
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
4185
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Dialog, {
|
|
5128
4186
|
open,
|
|
5129
4187
|
onOpenChange,
|
|
5130
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
4188
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.DialogContent, {
|
|
5131
4189
|
className: cn("max-w-2xl sm:max-w-2xl flex flex-col max-h-[85vh] overflow-hidden p-0", className),
|
|
5132
4190
|
children: [
|
|
5133
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
4191
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.DialogHeader, {
|
|
5134
4192
|
className: "flex-shrink-0 px-6 pt-6",
|
|
5135
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
4193
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.DialogTitle, { children: title }), description && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.DialogDescription, { children: description })]
|
|
5136
4194
|
}),
|
|
5137
4195
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5138
4196
|
className: "flex-1 overflow-y-auto min-h-0",
|
|
@@ -5292,11 +4350,19 @@ function normalizeDataSourceRegistration(registration) {
|
|
|
5292
4350
|
if (typeof registration === "function") return {
|
|
5293
4351
|
dependencies: [],
|
|
5294
4352
|
reset: false,
|
|
4353
|
+
search: false,
|
|
4354
|
+
debounceMs: 300,
|
|
4355
|
+
loadMore: false,
|
|
4356
|
+
pageSize: 20,
|
|
5295
4357
|
load: registration
|
|
5296
4358
|
};
|
|
5297
4359
|
return {
|
|
5298
4360
|
dependencies: Array.isArray(registration.dependencies) ? registration.dependencies : [],
|
|
5299
4361
|
reset: registration.reset === true,
|
|
4362
|
+
search: registration.search === true,
|
|
4363
|
+
debounceMs: typeof registration.debounceMs === "number" && registration.debounceMs >= 0 ? registration.debounceMs : 300,
|
|
4364
|
+
loadMore: registration.loadMore === true,
|
|
4365
|
+
pageSize: typeof registration.pageSize === "number" && registration.pageSize > 0 ? registration.pageSize : 20,
|
|
5300
4366
|
load: registration.load
|
|
5301
4367
|
};
|
|
5302
4368
|
}
|
|
@@ -5323,37 +4389,90 @@ function normalizeOptions(result) {
|
|
|
5323
4389
|
value: String(option.value)
|
|
5324
4390
|
}));
|
|
5325
4391
|
}
|
|
4392
|
+
function normalizeHasMore(result) {
|
|
4393
|
+
return !Array.isArray(result) && result?.hasMore === true;
|
|
4394
|
+
}
|
|
4395
|
+
|
|
4396
|
+
//#endregion
|
|
4397
|
+
//#region src/lib/field-config.ts
|
|
4398
|
+
function normalizeFieldOptions$1(options) {
|
|
4399
|
+
if (!options || options.length === 0) return void 0;
|
|
4400
|
+
return options.map((option) => ({
|
|
4401
|
+
...option,
|
|
4402
|
+
value: String(option.value)
|
|
4403
|
+
}));
|
|
4404
|
+
}
|
|
4405
|
+
/**
|
|
4406
|
+
* 从统一字段配置生成 Formily overrides。
|
|
4407
|
+
* `legacyOverrides` 保持兼容旧 API,字段级 `form` 配置优先级最高。
|
|
4408
|
+
*/
|
|
4409
|
+
function buildFormOverrides(fields, legacyOverrides, denyFields) {
|
|
4410
|
+
const result = { ...legacyOverrides };
|
|
4411
|
+
if (denyFields) for (const field of denyFields) result[field] = {
|
|
4412
|
+
...result[field],
|
|
4413
|
+
"x-hidden": true
|
|
4414
|
+
};
|
|
4415
|
+
if (fields) for (const [key, config] of Object.entries(fields)) {
|
|
4416
|
+
const fieldOptions = normalizeFieldOptions$1((config.form && typeof config.form === "object" ? config.form : void 0)?.enum) ?? normalizeFieldOptions$1(config.enum);
|
|
4417
|
+
const fieldDataSource = fieldOptions || !config.dataSource ? void 0 : normalizeDataSourceConfig(config.dataSource);
|
|
4418
|
+
if (config.label) result[key] = {
|
|
4419
|
+
...result[key],
|
|
4420
|
+
title: config.label
|
|
4421
|
+
};
|
|
4422
|
+
if (config.hidden) result[key] = {
|
|
4423
|
+
...result[key],
|
|
4424
|
+
"x-hidden": true
|
|
4425
|
+
};
|
|
4426
|
+
if (fieldOptions) result[key] = {
|
|
4427
|
+
...result[key],
|
|
4428
|
+
enum: fieldOptions
|
|
4429
|
+
};
|
|
4430
|
+
if (fieldDataSource) result[key] = {
|
|
4431
|
+
...result[key],
|
|
4432
|
+
"x-data-source": config.dataSource
|
|
4433
|
+
};
|
|
4434
|
+
if (config.form === false) result[key] = {
|
|
4435
|
+
...result[key],
|
|
4436
|
+
"x-hidden": true
|
|
4437
|
+
};
|
|
4438
|
+
else if (config.form && typeof config.form === "object") result[key] = {
|
|
4439
|
+
...result[key],
|
|
4440
|
+
...config.form
|
|
4441
|
+
};
|
|
4442
|
+
}
|
|
4443
|
+
return result;
|
|
4444
|
+
}
|
|
5326
4445
|
|
|
5327
4446
|
//#endregion
|
|
5328
4447
|
//#region src/components/auto-crud/auto-form.tsx
|
|
5329
|
-
const COMBOBOX_LIST_CLASS = "[&_[
|
|
5330
|
-
const FormilySwitch = (0,
|
|
4448
|
+
const COMBOBOX_LIST_CLASS = "[&_[data-multi-combobox-viewport]]:max-h-[360px] [&_[data-multi-combobox-viewport]]:overflow-x-hidden [&_[data-multi-combobox-viewport]]:overflow-y-auto";
|
|
4449
|
+
const FormilySwitch = (0, __wordrhyme_formily_shadcn.connect)(__wordrhyme_shadcn.Switch, (0, __wordrhyme_formily_shadcn.mapProps)({
|
|
5331
4450
|
value: "checked",
|
|
5332
4451
|
onInput: "onCheckedChange"
|
|
5333
4452
|
}));
|
|
5334
|
-
const FormilyCombobox = (0,
|
|
5335
|
-
const FormilyMultiCombobox = (0,
|
|
4453
|
+
const FormilyCombobox = (0, __wordrhyme_formily_shadcn.connect)(AutoCrudCombobox, (0, __wordrhyme_formily_shadcn.mapProps)({ dataSource: "options" }));
|
|
4454
|
+
const FormilyMultiCombobox = (0, __wordrhyme_formily_shadcn.connect)(AutoCrudMultiCombobox, (0, __wordrhyme_formily_shadcn.mapProps)({
|
|
5336
4455
|
dataSource: "options",
|
|
5337
4456
|
onInput: "onChange"
|
|
5338
4457
|
}, (props, field) => {
|
|
5339
|
-
const fieldValue = field.value;
|
|
4458
|
+
const fieldValue = field && typeof field === "object" && "value" in field ? field.value : props.value;
|
|
5340
4459
|
return {
|
|
5341
4460
|
...props,
|
|
5342
4461
|
value: Array.isArray(fieldValue) ? fieldValue.map(String) : []
|
|
5343
4462
|
};
|
|
5344
4463
|
}));
|
|
5345
4464
|
function AutoCrudCombobox({ options = [], className, value, onChange,...props }) {
|
|
5346
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MultiCombobox, {
|
|
4465
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn_ui.MultiCombobox, {
|
|
5347
4466
|
...props,
|
|
5348
4467
|
value: value ? [value] : [],
|
|
5349
4468
|
options,
|
|
5350
4469
|
selectionMode: "single",
|
|
5351
4470
|
onChange: (nextValues) => onChange?.(nextValues[0] ?? ""),
|
|
5352
|
-
className: (0,
|
|
4471
|
+
className: (0, __wordrhyme_shadcn.cn)(COMBOBOX_LIST_CLASS, className)
|
|
5353
4472
|
});
|
|
5354
4473
|
}
|
|
5355
4474
|
function AutoCrudMultiCombobox({ options = [],...props }) {
|
|
5356
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MultiCombobox, {
|
|
4475
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn_ui.MultiCombobox, {
|
|
5357
4476
|
...props,
|
|
5358
4477
|
options
|
|
5359
4478
|
});
|
|
@@ -5372,99 +4491,280 @@ const defaultFieldComponents = {
|
|
|
5372
4491
|
decorator: "FormItem"
|
|
5373
4492
|
}
|
|
5374
4493
|
};
|
|
5375
|
-
|
|
4494
|
+
const AUTO_CRUD_DATA_SOURCE_SCOPE_KEY = "$autoCrudDataSource";
|
|
4495
|
+
const POPUP_SCROLL_LOAD_THRESHOLD$1 = 24;
|
|
4496
|
+
const dataSourceReactionStates = /* @__PURE__ */ new WeakMap();
|
|
4497
|
+
function createBoundAction(callback) {
|
|
4498
|
+
return __formily_reactive.action.bound?.(callback) ?? ((...args) => (0, __formily_reactive.action)(() => callback(...args)));
|
|
4499
|
+
}
|
|
4500
|
+
function useRegistryVersion$1(subscribe, onChange) {
|
|
5376
4501
|
const [version$1, setVersion] = (0, react.useState)(0);
|
|
5377
|
-
(0, react.useEffect)(() => subscribe(() =>
|
|
4502
|
+
(0, react.useEffect)(() => subscribe(() => {
|
|
4503
|
+
onChange?.();
|
|
4504
|
+
setVersion((current) => current + 1);
|
|
4505
|
+
}), [onChange, subscribe]);
|
|
5378
4506
|
return version$1;
|
|
5379
4507
|
}
|
|
5380
4508
|
function isDataSourceConfig(value) {
|
|
5381
4509
|
return typeof value === "string" && value.length > 0;
|
|
5382
4510
|
}
|
|
5383
|
-
function
|
|
4511
|
+
function getSchemaDataSourceConfig(schema) {
|
|
4512
|
+
const customDataSource = schema["x-data-source"];
|
|
4513
|
+
const schemaDataSource = schema.dataSource;
|
|
4514
|
+
return isDataSourceConfig(customDataSource) ? customDataSource : isDataSourceConfig(schemaDataSource) ? schemaDataSource : void 0;
|
|
4515
|
+
}
|
|
4516
|
+
function mergeReactions(existing, reaction) {
|
|
4517
|
+
if (existing == null) return reaction;
|
|
4518
|
+
if (existing === reaction) return existing;
|
|
4519
|
+
if (Array.isArray(existing)) return existing.includes(reaction) ? existing : [...existing, reaction];
|
|
4520
|
+
return [existing, reaction];
|
|
4521
|
+
}
|
|
4522
|
+
function applyDataSourceReactions(schema) {
|
|
4523
|
+
const dataSourceConfig = getSchemaDataSourceConfig(schema);
|
|
4524
|
+
if (dataSourceConfig) {
|
|
4525
|
+
const reaction = `{{${AUTO_CRUD_DATA_SOURCE_SCOPE_KEY}(${JSON.stringify(dataSourceConfig)})}}`;
|
|
4526
|
+
schema["x-reactions"] = mergeReactions(schema["x-reactions"], reaction);
|
|
4527
|
+
}
|
|
5384
4528
|
const properties = schema.properties;
|
|
5385
|
-
if (
|
|
5386
|
-
|
|
5387
|
-
if (!property || typeof property !== "object" || Array.isArray(property)) continue;
|
|
5388
|
-
const record = property;
|
|
5389
|
-
const customDataSource = record["x-data-source"];
|
|
5390
|
-
const schemaDataSource = record.dataSource;
|
|
5391
|
-
const dataSourceConfig = isDataSourceConfig(customDataSource) ? customDataSource : isDataSourceConfig(schemaDataSource) ? schemaDataSource : void 0;
|
|
5392
|
-
if (dataSourceConfig) result[key] = dataSourceConfig;
|
|
5393
|
-
collectDataSourceConfigs(record, result);
|
|
4529
|
+
if (properties && typeof properties === "object" && !Array.isArray(properties)) {
|
|
4530
|
+
for (const property of Object.values(properties)) if (property && typeof property === "object" && !Array.isArray(property)) applyDataSourceReactions(property);
|
|
5394
4531
|
}
|
|
5395
|
-
|
|
4532
|
+
const items = schema.items;
|
|
4533
|
+
if (Array.isArray(items)) {
|
|
4534
|
+
for (const item of items) if (item && typeof item === "object") applyDataSourceReactions(item);
|
|
4535
|
+
} else if (items && typeof items === "object") applyDataSourceReactions(items);
|
|
4536
|
+
}
|
|
4537
|
+
function getDataSourceReactionState(field) {
|
|
4538
|
+
const existing = dataSourceReactionStates.get(field);
|
|
4539
|
+
if (existing) return existing;
|
|
4540
|
+
const next = {
|
|
4541
|
+
hasMore: false,
|
|
4542
|
+
initialized: false,
|
|
4543
|
+
appendLoading: false,
|
|
4544
|
+
options: [],
|
|
4545
|
+
page: 0,
|
|
4546
|
+
requestVersion: 0
|
|
4547
|
+
};
|
|
4548
|
+
dataSourceReactionStates.set(field, next);
|
|
4549
|
+
return next;
|
|
4550
|
+
}
|
|
4551
|
+
function mergeDataSourceOptions(current, incoming) {
|
|
4552
|
+
const optionsByValue = new Map(current.map((option) => [option.value, option]));
|
|
4553
|
+
for (const option of incoming) optionsByValue.set(option.value, option);
|
|
4554
|
+
return Array.from(optionsByValue.values());
|
|
4555
|
+
}
|
|
4556
|
+
function isNearPopupScrollBottom$1(target) {
|
|
4557
|
+
return target.scrollHeight - target.scrollTop - target.clientHeight <= POPUP_SCROLL_LOAD_THRESHOLD$1;
|
|
4558
|
+
}
|
|
4559
|
+
function getDataSourceDependencyValues(entry, field) {
|
|
4560
|
+
return Object.fromEntries(entry.dependencies.map((dependency) => [dependency, field.form.getValuesIn(dependency)]));
|
|
4561
|
+
}
|
|
4562
|
+
function loadAutoCrudDataSource({ entry, field, registryVersion, search, sourceKey, state, append = false }) {
|
|
4563
|
+
const values = getDataSourceDependencyValues(entry, field);
|
|
4564
|
+
const dependencyKey = JSON.stringify(values);
|
|
4565
|
+
const searchValue = entry.search ? search ?? "" : void 0;
|
|
4566
|
+
const page = entry.loadMore ? append ? state.page + 1 : 1 : void 0;
|
|
4567
|
+
const loadKey = JSON.stringify({
|
|
4568
|
+
values,
|
|
4569
|
+
search: searchValue
|
|
4570
|
+
});
|
|
4571
|
+
if (!append && state.loadKey === loadKey && state.registryVersion === registryVersion) return;
|
|
4572
|
+
if (entry.reset && state.dependencyKey !== void 0 && state.dependencyKey !== dependencyKey) field.setValue(void 0);
|
|
4573
|
+
state.dependencyKey = dependencyKey;
|
|
4574
|
+
if (!append) {
|
|
4575
|
+
state.loadKey = loadKey;
|
|
4576
|
+
state.options = [];
|
|
4577
|
+
state.page = 0;
|
|
4578
|
+
state.hasMore = false;
|
|
4579
|
+
}
|
|
4580
|
+
state.registryVersion = registryVersion;
|
|
4581
|
+
state.controller?.abort();
|
|
4582
|
+
const requestVersion = state.requestVersion + 1;
|
|
4583
|
+
state.requestVersion = requestVersion;
|
|
4584
|
+
const controller = typeof AbortController === "undefined" ? void 0 : new AbortController();
|
|
4585
|
+
state.controller = controller;
|
|
4586
|
+
if (append) {
|
|
4587
|
+
state.appendLoading = true;
|
|
4588
|
+
field.setComponentProps({ loading: true });
|
|
4589
|
+
} else {
|
|
4590
|
+
field.setLoading(true);
|
|
4591
|
+
field.setComponentProps({
|
|
4592
|
+
loading: true,
|
|
4593
|
+
...entry.loadMore ? { hasMore: false } : {}
|
|
4594
|
+
});
|
|
4595
|
+
}
|
|
4596
|
+
Promise.resolve(entry.load({
|
|
4597
|
+
field: field.path.toString(),
|
|
4598
|
+
page,
|
|
4599
|
+
pageSize: entry.loadMore ? entry.pageSize : void 0,
|
|
4600
|
+
search: searchValue,
|
|
4601
|
+
values,
|
|
4602
|
+
signal: controller?.signal
|
|
4603
|
+
})).then(createBoundAction((result) => {
|
|
4604
|
+
if (dataSourceReactionStates.get(field)?.requestVersion !== requestVersion || controller?.signal.aborted) return;
|
|
4605
|
+
const options = normalizeOptions(result);
|
|
4606
|
+
const nextOptions = append ? mergeDataSourceOptions(state.options, options) : options;
|
|
4607
|
+
state.options = nextOptions;
|
|
4608
|
+
state.page = page ?? 0;
|
|
4609
|
+
state.hasMore = entry.loadMore ? normalizeHasMore(result) : false;
|
|
4610
|
+
state.appendLoading = false;
|
|
4611
|
+
field.setDataSource(nextOptions);
|
|
4612
|
+
field.setLoading(false);
|
|
4613
|
+
field.setComponentProps({
|
|
4614
|
+
loading: false,
|
|
4615
|
+
...entry.loadMore ? { hasMore: state.hasMore } : {}
|
|
4616
|
+
});
|
|
4617
|
+
}), createBoundAction((error) => {
|
|
4618
|
+
if (dataSourceReactionStates.get(field)?.requestVersion !== requestVersion || controller?.signal.aborted) return;
|
|
4619
|
+
console.warn(`[AutoCrud] Failed to load data source "${sourceKey}".`, error);
|
|
4620
|
+
if (!append) {
|
|
4621
|
+
state.options = [];
|
|
4622
|
+
state.hasMore = false;
|
|
4623
|
+
field.setDataSource([]);
|
|
4624
|
+
}
|
|
4625
|
+
state.appendLoading = false;
|
|
4626
|
+
field.setLoading(false);
|
|
4627
|
+
field.setComponentProps({
|
|
4628
|
+
loading: false,
|
|
4629
|
+
...entry.loadMore ? { hasMore: state.hasMore } : {}
|
|
4630
|
+
});
|
|
4631
|
+
}));
|
|
5396
4632
|
}
|
|
5397
|
-
function
|
|
5398
|
-
(
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
|
|
5402
|
-
|
|
5403
|
-
|
|
5404
|
-
|
|
5405
|
-
|
|
5406
|
-
|
|
5407
|
-
|
|
5408
|
-
|
|
5409
|
-
|
|
5410
|
-
|
|
5411
|
-
|
|
5412
|
-
|
|
5413
|
-
|
|
5414
|
-
|
|
5415
|
-
}
|
|
5416
|
-
|
|
5417
|
-
|
|
5418
|
-
|
|
5419
|
-
|
|
5420
|
-
|
|
5421
|
-
|
|
5422
|
-
|
|
5423
|
-
}));
|
|
5424
|
-
if (!active || loadVersions.get(fieldName) !== version$1) return;
|
|
5425
|
-
form.setFieldState(fieldName, (state) => {
|
|
5426
|
-
state.dataSource = options;
|
|
4633
|
+
function applySearchComponentProps({ entry, field, registryState, sourceKey, state }) {
|
|
4634
|
+
if (!entry.search) return;
|
|
4635
|
+
field.setComponentProps({
|
|
4636
|
+
searchValue: state.search ?? "",
|
|
4637
|
+
shouldFilter: false,
|
|
4638
|
+
onSearch: (search) => {
|
|
4639
|
+
if (state.search === search) return;
|
|
4640
|
+
state.search = search;
|
|
4641
|
+
field.setComponentProps({ searchValue: search });
|
|
4642
|
+
if (state.searchTimer) clearTimeout(state.searchTimer);
|
|
4643
|
+
state.searchTimer = setTimeout(() => {
|
|
4644
|
+
const currentEntry = dataSources.get(sourceKey);
|
|
4645
|
+
if (!currentEntry) {
|
|
4646
|
+
state.controller?.abort();
|
|
4647
|
+
field.setDataSource([]);
|
|
4648
|
+
field.setLoading(false);
|
|
4649
|
+
field.setComponentProps({ loading: false });
|
|
4650
|
+
return;
|
|
4651
|
+
}
|
|
4652
|
+
loadAutoCrudDataSource({
|
|
4653
|
+
entry: currentEntry,
|
|
4654
|
+
field,
|
|
4655
|
+
registryVersion: registryState.version,
|
|
4656
|
+
search,
|
|
4657
|
+
sourceKey,
|
|
4658
|
+
state
|
|
5427
4659
|
});
|
|
5428
|
-
}
|
|
5429
|
-
|
|
5430
|
-
|
|
5431
|
-
|
|
5432
|
-
|
|
4660
|
+
}, entry.debounceMs);
|
|
4661
|
+
}
|
|
4662
|
+
});
|
|
4663
|
+
}
|
|
4664
|
+
function applyLoadMoreComponentProps({ entry, field, registryState, sourceKey, state }) {
|
|
4665
|
+
if (!entry.loadMore) return;
|
|
4666
|
+
field.setComponentProps({
|
|
4667
|
+
hasMore: state.hasMore,
|
|
4668
|
+
loading: state.appendLoading,
|
|
4669
|
+
onPopupScroll: (event) => {
|
|
4670
|
+
if (!isNearPopupScrollBottom$1(event.currentTarget)) return;
|
|
4671
|
+
if (!state.hasMore || state.appendLoading) return;
|
|
4672
|
+
const currentEntry = dataSources.get(sourceKey);
|
|
4673
|
+
if (!currentEntry) {
|
|
4674
|
+
state.controller?.abort();
|
|
4675
|
+
state.hasMore = false;
|
|
4676
|
+
state.appendLoading = false;
|
|
4677
|
+
field.setDataSource([]);
|
|
4678
|
+
field.setLoading(false);
|
|
4679
|
+
field.setComponentProps({
|
|
4680
|
+
hasMore: false,
|
|
4681
|
+
loading: false
|
|
5433
4682
|
});
|
|
4683
|
+
return;
|
|
5434
4684
|
}
|
|
5435
|
-
|
|
5436
|
-
|
|
5437
|
-
|
|
5438
|
-
|
|
5439
|
-
|
|
5440
|
-
|
|
5441
|
-
|
|
5442
|
-
|
|
5443
|
-
|
|
5444
|
-
|
|
4685
|
+
loadAutoCrudDataSource({
|
|
4686
|
+
append: true,
|
|
4687
|
+
entry: currentEntry,
|
|
4688
|
+
field,
|
|
4689
|
+
registryVersion: registryState.version,
|
|
4690
|
+
search: state.search,
|
|
4691
|
+
sourceKey,
|
|
4692
|
+
state
|
|
4693
|
+
});
|
|
4694
|
+
}
|
|
4695
|
+
});
|
|
4696
|
+
}
|
|
4697
|
+
function createAutoCrudDataSourceReaction(config, registryState) {
|
|
4698
|
+
const source = normalizeDataSourceConfig(config);
|
|
4699
|
+
return (field) => {
|
|
4700
|
+
const registryVersion = registryState.version;
|
|
4701
|
+
const state = getDataSourceReactionState(field);
|
|
4702
|
+
if (!state.initialized) {
|
|
4703
|
+
field.disposers.push(() => {
|
|
4704
|
+
state.controller?.abort();
|
|
4705
|
+
if (state.searchTimer) clearTimeout(state.searchTimer);
|
|
5445
4706
|
});
|
|
4707
|
+
state.initialized = true;
|
|
4708
|
+
}
|
|
4709
|
+
if (!source) {
|
|
4710
|
+
field.setDataSource([]);
|
|
4711
|
+
field.setLoading(false);
|
|
4712
|
+
return;
|
|
4713
|
+
}
|
|
4714
|
+
const entry = dataSources.get(source.key);
|
|
4715
|
+
if (!entry) {
|
|
4716
|
+
state.controller?.abort();
|
|
4717
|
+
field.setDataSource([]);
|
|
4718
|
+
field.setLoading(false);
|
|
4719
|
+
return;
|
|
4720
|
+
}
|
|
4721
|
+
applySearchComponentProps({
|
|
4722
|
+
entry,
|
|
4723
|
+
field,
|
|
4724
|
+
registryState,
|
|
4725
|
+
sourceKey: source.key,
|
|
4726
|
+
state
|
|
5446
4727
|
});
|
|
5447
|
-
|
|
5448
|
-
|
|
5449
|
-
|
|
5450
|
-
|
|
5451
|
-
|
|
5452
|
-
|
|
5453
|
-
|
|
5454
|
-
|
|
5455
|
-
|
|
5456
|
-
|
|
4728
|
+
applyLoadMoreComponentProps({
|
|
4729
|
+
entry,
|
|
4730
|
+
field,
|
|
4731
|
+
registryState,
|
|
4732
|
+
sourceKey: source.key,
|
|
4733
|
+
state
|
|
4734
|
+
});
|
|
4735
|
+
loadAutoCrudDataSource({
|
|
4736
|
+
entry,
|
|
4737
|
+
field,
|
|
4738
|
+
registryVersion,
|
|
4739
|
+
search: state.search,
|
|
4740
|
+
sourceKey: source.key,
|
|
4741
|
+
state
|
|
4742
|
+
});
|
|
4743
|
+
};
|
|
5457
4744
|
}
|
|
5458
|
-
function AutoFormInner({ schema: zodSchema, initialValues, onSubmit, overrides, mode = "create", loading = false, gridColumns = 1, labelAlign = "top", labelWidth, showSubmitButton = true }, ref) {
|
|
4745
|
+
function AutoFormInner({ schema: zodSchema, initialValues, onSubmit, fields, overrides, scope: scopeProp, mode = "create", loading = false, gridColumns = 1, labelAlign = "top", labelWidth, showSubmitButton = true }, ref) {
|
|
5459
4746
|
const form = (0, react.useMemo)(() => (0, __formily_core.createForm)({ initialValues }), [JSON.stringify(initialValues)]);
|
|
5460
|
-
const
|
|
5461
|
-
|
|
5462
|
-
|
|
5463
|
-
|
|
5464
|
-
|
|
4747
|
+
const dataSourceRegistryState = (0, react.useMemo)(() => (0, __formily_reactive.observable)({ version: 0 }), []);
|
|
4748
|
+
const updateDataSourceRegistryState = (0, react.useCallback)(() => {
|
|
4749
|
+
(0, __formily_reactive.action)(() => {
|
|
4750
|
+
dataSourceRegistryState.version += 1;
|
|
4751
|
+
});
|
|
4752
|
+
}, [dataSourceRegistryState]);
|
|
4753
|
+
const dataSourceRegistryVersion = useRegistryVersion$1(dataSources.subscribe, updateDataSourceRegistryState);
|
|
4754
|
+
const formOverrides = (0, react.useMemo)(() => buildFormOverrides(fields, overrides), [fields, overrides]);
|
|
4755
|
+
const formSchema = (0, react.useMemo)(() => {
|
|
4756
|
+
const nextSchema = createEditFormSchema(zodSchema, {
|
|
4757
|
+
overrides: formOverrides,
|
|
4758
|
+
layout: "grid",
|
|
4759
|
+
gridColumns
|
|
4760
|
+
});
|
|
4761
|
+
applyDataSourceReactions(nextSchema);
|
|
4762
|
+
return nextSchema;
|
|
4763
|
+
}, [
|
|
5465
4764
|
zodSchema,
|
|
5466
|
-
|
|
5467
|
-
gridColumns
|
|
4765
|
+
formOverrides,
|
|
4766
|
+
gridColumns,
|
|
4767
|
+
dataSourceRegistryVersion
|
|
5468
4768
|
]);
|
|
5469
4769
|
const formLayout = (0, react.useMemo)(() => {
|
|
5470
4770
|
const inlineLabel = labelAlign === "left" || labelAlign === "right";
|
|
@@ -5480,21 +4780,25 @@ function AutoFormInner({ schema: zodSchema, initialValues, onSubmit, overrides,
|
|
|
5480
4780
|
...defaultFieldComponents,
|
|
5481
4781
|
...components.all()
|
|
5482
4782
|
} }), [useRegistryVersion$1(components.subscribe)]);
|
|
5483
|
-
|
|
4783
|
+
const scope = (0, react.useMemo)(() => ({
|
|
4784
|
+
...scopeProp,
|
|
4785
|
+
[AUTO_CRUD_DATA_SOURCE_SCOPE_KEY]: (config) => createAutoCrudDataSourceReaction(config, dataSourceRegistryState)
|
|
4786
|
+
}), [dataSourceRegistryState, scopeProp]);
|
|
5484
4787
|
const handleSubmit = async () => {
|
|
5485
4788
|
await form.validate();
|
|
5486
4789
|
if (form.valid) await onSubmit(form.values);
|
|
5487
4790
|
};
|
|
5488
4791
|
(0, react.useImperativeHandle)(ref, () => ({ submit: handleSubmit }));
|
|
5489
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
4792
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_formily_shadcn.Form, {
|
|
5490
4793
|
form,
|
|
5491
4794
|
layout: formLayout,
|
|
5492
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
4795
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_formily_shadcn.JsonSchemaField, {
|
|
5493
4796
|
schema: formSchema,
|
|
5494
|
-
components: fieldComponents
|
|
4797
|
+
components: fieldComponents,
|
|
4798
|
+
scope
|
|
5495
4799
|
}), showSubmitButton && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5496
4800
|
className: "flex justify-end gap-2 mt-6",
|
|
5497
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
4801
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
5498
4802
|
type: "button",
|
|
5499
4803
|
onClick: handleSubmit,
|
|
5500
4804
|
disabled: loading,
|
|
@@ -5540,6 +4844,12 @@ const zhCN = {
|
|
|
5540
4844
|
confirm: "确认删除",
|
|
5541
4845
|
confirming: "删除中..."
|
|
5542
4846
|
},
|
|
4847
|
+
bulkDeleteModal: {
|
|
4848
|
+
title: "确认批量删除",
|
|
4849
|
+
description: (count) => `此操作无法撤销。确定要删除选中的 ${count} 条记录吗?`,
|
|
4850
|
+
cancel: "取消",
|
|
4851
|
+
confirm: "确认删除"
|
|
4852
|
+
},
|
|
5543
4853
|
importDialog: {
|
|
5544
4854
|
title: "导入数据",
|
|
5545
4855
|
uploadDescription: "上传 CSV 或 JSON 文件以批量导入数据",
|
|
@@ -5600,6 +4910,12 @@ const enUS = {
|
|
|
5600
4910
|
confirm: "Delete",
|
|
5601
4911
|
confirming: "Deleting..."
|
|
5602
4912
|
},
|
|
4913
|
+
bulkDeleteModal: {
|
|
4914
|
+
title: "Confirm Bulk Delete",
|
|
4915
|
+
description: (count) => `This action cannot be undone. Are you sure you want to delete ${count} selected ${count === 1 ? "record" : "records"}?`,
|
|
4916
|
+
cancel: "Cancel",
|
|
4917
|
+
confirm: "Delete"
|
|
4918
|
+
},
|
|
5603
4919
|
importDialog: {
|
|
5604
4920
|
title: "Import Data",
|
|
5605
4921
|
uploadDescription: "Upload a CSV or JSON file to bulk import data",
|
|
@@ -5660,6 +4976,12 @@ const jaJP = {
|
|
|
5660
4976
|
confirm: "削除する",
|
|
5661
4977
|
confirming: "削除中..."
|
|
5662
4978
|
},
|
|
4979
|
+
bulkDeleteModal: {
|
|
4980
|
+
title: "一括削除の確認",
|
|
4981
|
+
description: (count) => `この操作は元に戻せません。選択した${count}件のレコードを削除してもよろしいですか?`,
|
|
4982
|
+
cancel: "キャンセル",
|
|
4983
|
+
confirm: "削除する"
|
|
4984
|
+
},
|
|
5663
4985
|
importDialog: {
|
|
5664
4986
|
title: "データのインポート",
|
|
5665
4987
|
uploadDescription: "CSVまたはJSONファイルをアップロードして一括インポート",
|
|
@@ -5720,6 +5042,12 @@ const koKR = {
|
|
|
5720
5042
|
confirm: "삭제",
|
|
5721
5043
|
confirming: "삭제 중..."
|
|
5722
5044
|
},
|
|
5045
|
+
bulkDeleteModal: {
|
|
5046
|
+
title: "일괄 삭제 확인",
|
|
5047
|
+
description: (count) => `이 작업은 취소할 수 없습니다. 선택한 ${count}개 레코드를 삭제하시겠습니까?`,
|
|
5048
|
+
cancel: "취소",
|
|
5049
|
+
confirm: "삭제"
|
|
5050
|
+
},
|
|
5723
5051
|
importDialog: {
|
|
5724
5052
|
title: "데이터 가져오기",
|
|
5725
5053
|
uploadDescription: "CSV 또는 JSON 파일을 업로드하여 일괄 가져오기",
|
|
@@ -5780,6 +5108,12 @@ const frFR = {
|
|
|
5780
5108
|
confirm: "Supprimer",
|
|
5781
5109
|
confirming: "Suppression..."
|
|
5782
5110
|
},
|
|
5111
|
+
bulkDeleteModal: {
|
|
5112
|
+
title: "Confirmer la suppression en masse",
|
|
5113
|
+
description: (count) => `Cette action est irréversible. Voulez-vous vraiment supprimer les ${count} enregistrements sélectionnés ?`,
|
|
5114
|
+
cancel: "Annuler",
|
|
5115
|
+
confirm: "Supprimer"
|
|
5116
|
+
},
|
|
5783
5117
|
importDialog: {
|
|
5784
5118
|
title: "Importer des données",
|
|
5785
5119
|
uploadDescription: "Téléchargez un fichier CSV ou JSON pour importer en masse",
|
|
@@ -5840,6 +5174,12 @@ const deDE = {
|
|
|
5840
5174
|
confirm: "Löschen",
|
|
5841
5175
|
confirming: "Wird gelöscht..."
|
|
5842
5176
|
},
|
|
5177
|
+
bulkDeleteModal: {
|
|
5178
|
+
title: "Mehrfaches Löschen bestätigen",
|
|
5179
|
+
description: (count) => `Diese Aktion kann nicht rückgängig gemacht werden. Möchten Sie die ${count} ausgewählten Datensätze wirklich löschen?`,
|
|
5180
|
+
cancel: "Abbrechen",
|
|
5181
|
+
confirm: "Löschen"
|
|
5182
|
+
},
|
|
5843
5183
|
importDialog: {
|
|
5844
5184
|
title: "Daten importieren",
|
|
5845
5185
|
uploadDescription: "CSV- oder JSON-Datei hochladen, um Daten massenweise zu importieren",
|
|
@@ -5900,6 +5240,12 @@ const esES = {
|
|
|
5900
5240
|
confirm: "Eliminar",
|
|
5901
5241
|
confirming: "Eliminando..."
|
|
5902
5242
|
},
|
|
5243
|
+
bulkDeleteModal: {
|
|
5244
|
+
title: "Confirmar eliminación masiva",
|
|
5245
|
+
description: (count) => `Esta acción no se puede deshacer. ¿Está seguro de que desea eliminar los ${count} registros seleccionados?`,
|
|
5246
|
+
cancel: "Cancelar",
|
|
5247
|
+
confirm: "Eliminar"
|
|
5248
|
+
},
|
|
5903
5249
|
importDialog: {
|
|
5904
5250
|
title: "Importar datos",
|
|
5905
5251
|
uploadDescription: "Suba un archivo CSV o JSON para importar datos de forma masiva",
|
|
@@ -5959,7 +5305,7 @@ function resolveLocale(localeProp) {
|
|
|
5959
5305
|
|
|
5960
5306
|
//#endregion
|
|
5961
5307
|
//#region src/components/auto-crud/crud-form-modal.tsx
|
|
5962
|
-
function CrudFormModal({ open, onOpenChange, mode, schema, initialValues, onSubmit, loading = false, variant = "dialog", overrides, title, locale = zhCN.formModal, gridColumns, labelAlign, labelWidth, className }) {
|
|
5308
|
+
function CrudFormModal({ open, onOpenChange, mode, schema, initialValues, onSubmit, loading = false, variant = "dialog", overrides, scope, title, locale = zhCN.formModal, gridColumns, labelAlign, labelWidth, className }) {
|
|
5963
5309
|
const defaultTitle = mode === "create" ? locale.createTitle : locale.editTitle;
|
|
5964
5310
|
const formRef = (0, react.useRef)(null);
|
|
5965
5311
|
const handleSubmit = async () => {
|
|
@@ -5973,12 +5319,12 @@ function CrudFormModal({ open, onOpenChange, mode, schema, initialValues, onSubm
|
|
|
5973
5319
|
className,
|
|
5974
5320
|
footer: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5975
5321
|
className: "flex justify-end gap-2",
|
|
5976
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
5322
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
5977
5323
|
type: "button",
|
|
5978
5324
|
variant: "outline",
|
|
5979
5325
|
onClick: () => onOpenChange(false),
|
|
5980
5326
|
children: locale.cancel
|
|
5981
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
5327
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
5982
5328
|
type: "button",
|
|
5983
5329
|
onClick: handleSubmit,
|
|
5984
5330
|
disabled: loading,
|
|
@@ -5993,6 +5339,7 @@ function CrudFormModal({ open, onOpenChange, mode, schema, initialValues, onSubm
|
|
|
5993
5339
|
loading,
|
|
5994
5340
|
onSubmit,
|
|
5995
5341
|
overrides,
|
|
5342
|
+
scope,
|
|
5996
5343
|
gridColumns,
|
|
5997
5344
|
labelAlign,
|
|
5998
5345
|
labelWidth,
|
|
@@ -6067,12 +5414,12 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title, local
|
|
|
6067
5414
|
link.click();
|
|
6068
5415
|
URL.revokeObjectURL(url);
|
|
6069
5416
|
}, [columns]);
|
|
6070
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
5417
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Dialog, {
|
|
6071
5418
|
open,
|
|
6072
5419
|
onOpenChange: handleOpenChange,
|
|
6073
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
6074
|
-
className: "sm:max-w-
|
|
6075
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
5420
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.DialogContent, {
|
|
5421
|
+
className: "w-[calc(100vw-2rem)] sm:max-w-5xl",
|
|
5422
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.DialogHeader, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.DialogTitle, { children: title ?? locale.title }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.DialogDescription, { children: [
|
|
6076
5423
|
step === "upload" && locale.uploadDescription,
|
|
6077
5424
|
step === "preview" && locale.previewDescription(parsedData?.rows.length ?? 0),
|
|
6078
5425
|
step === "importing" && locale.importingDescription,
|
|
@@ -6121,7 +5468,7 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title, local
|
|
|
6121
5468
|
className: "hidden",
|
|
6122
5469
|
onChange: handleFileInput
|
|
6123
5470
|
})]
|
|
6124
|
-
}), columns.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
5471
|
+
}), columns.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
6125
5472
|
variant: "outline",
|
|
6126
5473
|
size: "sm",
|
|
6127
5474
|
className: "w-full",
|
|
@@ -6132,41 +5479,30 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title, local
|
|
|
6132
5479
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6133
5480
|
className: "rounded-md border",
|
|
6134
5481
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6135
|
-
className: "max-h-[
|
|
5482
|
+
className: "max-h-[45vh] overflow-auto",
|
|
6136
5483
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("table", {
|
|
6137
|
-
className: "w-
|
|
5484
|
+
className: "min-w-max text-sm",
|
|
6138
5485
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("thead", {
|
|
6139
5486
|
className: "sticky top-0 bg-muted",
|
|
6140
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
|
|
6141
|
-
|
|
6142
|
-
|
|
6143
|
-
|
|
6144
|
-
|
|
6145
|
-
|
|
6146
|
-
|
|
6147
|
-
children: h
|
|
6148
|
-
}, h)),
|
|
6149
|
-
parsedData.headers.length > 6 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
|
|
6150
|
-
className: "px-3 py-2 text-left font-medium text-muted-foreground",
|
|
6151
|
-
children: locale.moreColumns(parsedData.headers.length - 6)
|
|
6152
|
-
})
|
|
6153
|
-
] })
|
|
5487
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
|
|
5488
|
+
className: "sticky left-0 z-10 bg-muted px-3 py-2 text-left font-medium text-muted-foreground",
|
|
5489
|
+
children: "#"
|
|
5490
|
+
}), parsedData.headers.map((h) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
|
|
5491
|
+
className: "max-w-[180px] whitespace-nowrap px-3 py-2 text-left font-medium text-muted-foreground",
|
|
5492
|
+
children: h
|
|
5493
|
+
}, h))] })
|
|
6154
5494
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tbody", { children: parsedData.rows.slice(0, 10).map((row, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", {
|
|
6155
5495
|
className: "border-t",
|
|
6156
|
-
children: [
|
|
6157
|
-
|
|
6158
|
-
|
|
6159
|
-
|
|
6160
|
-
|
|
6161
|
-
|
|
6162
|
-
|
|
5496
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
|
|
5497
|
+
className: "sticky left-0 bg-background px-3 py-2 text-muted-foreground",
|
|
5498
|
+
children: i + 1
|
|
5499
|
+
}), parsedData.headers.map((h) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
|
|
5500
|
+
className: "max-w-[180px] truncate px-3 py-2",
|
|
5501
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5502
|
+
title: String(row[h] ?? ""),
|
|
6163
5503
|
children: String(row[h] ?? "")
|
|
6164
|
-
}, h)),
|
|
6165
|
-
parsedData.headers.length > 6 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
|
|
6166
|
-
className: "px-3 py-2 text-muted-foreground",
|
|
6167
|
-
children: "..."
|
|
6168
5504
|
})
|
|
6169
|
-
]
|
|
5505
|
+
}, h))]
|
|
6170
5506
|
}, i)) })]
|
|
6171
5507
|
})
|
|
6172
5508
|
})
|
|
@@ -6177,11 +5513,11 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title, local
|
|
|
6177
5513
|
}),
|
|
6178
5514
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6179
5515
|
className: "flex gap-2 justify-end",
|
|
6180
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
5516
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
6181
5517
|
variant: "outline",
|
|
6182
5518
|
onClick: reset,
|
|
6183
5519
|
children: locale.reselect
|
|
6184
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
5520
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
6185
5521
|
onClick: handleImport,
|
|
6186
5522
|
children: locale.confirmImport
|
|
6187
5523
|
})]
|
|
@@ -6270,11 +5606,11 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title, local
|
|
|
6270
5606
|
})]
|
|
6271
5607
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6272
5608
|
className: "flex gap-2 justify-end",
|
|
6273
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
5609
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
6274
5610
|
variant: "outline",
|
|
6275
5611
|
onClick: () => handleOpenChange(false),
|
|
6276
5612
|
children: locale.close
|
|
6277
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
5613
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
6278
5614
|
variant: "outline",
|
|
6279
5615
|
onClick: reset,
|
|
6280
5616
|
children: locale.continueImport
|
|
@@ -6298,12 +5634,12 @@ const listeners = /* @__PURE__ */ new Set();
|
|
|
6298
5634
|
let seq = 0;
|
|
6299
5635
|
let version = 0;
|
|
6300
5636
|
let notifyScheduled = false;
|
|
6301
|
-
function actionKey(registration, action, index$1) {
|
|
5637
|
+
function actionKey(registration, action$1, index$1) {
|
|
6302
5638
|
return [
|
|
6303
5639
|
registration.ownerId,
|
|
6304
5640
|
registration.targetId,
|
|
6305
5641
|
registration.zone,
|
|
6306
|
-
action.id ?? action.type,
|
|
5642
|
+
action$1.id ?? action$1.type,
|
|
6307
5643
|
index$1
|
|
6308
5644
|
].join(":");
|
|
6309
5645
|
}
|
|
@@ -6351,15 +5687,15 @@ function sortEntries(left, right) {
|
|
|
6351
5687
|
if (ownerDiff !== 0) return ownerDiff;
|
|
6352
5688
|
return left.seq - right.seq;
|
|
6353
5689
|
}
|
|
6354
|
-
function withoutRegistryMeta(action) {
|
|
6355
|
-
const { id, order,...rest } = action;
|
|
5690
|
+
function withoutRegistryMeta(action$1) {
|
|
5691
|
+
const { id, order,...rest } = action$1;
|
|
6356
5692
|
return rest;
|
|
6357
5693
|
}
|
|
6358
|
-
function isCustomAction$1(action) {
|
|
6359
|
-
return action.type === "custom";
|
|
5694
|
+
function isCustomAction$1(action$1) {
|
|
5695
|
+
return action$1.type === "custom";
|
|
6360
5696
|
}
|
|
6361
5697
|
function resolveActions$1(targetId, zone, ownerActions) {
|
|
6362
|
-
const baseActions = ownerActions.filter((action) => !action.hidden).map((action) => withoutRegistryMeta(action));
|
|
5698
|
+
const baseActions = ownerActions.filter((action$1) => !action$1.hidden).map((action$1) => withoutRegistryMeta(action$1));
|
|
6363
5699
|
if (!targetId) return baseActions;
|
|
6364
5700
|
const registered = crudActions.get(targetId, zone);
|
|
6365
5701
|
if (registered.length === 0) return baseActions;
|
|
@@ -6367,20 +5703,20 @@ function resolveActions$1(targetId, zone, ownerActions) {
|
|
|
6367
5703
|
const startCustomActions = [];
|
|
6368
5704
|
const endCustomActions = [];
|
|
6369
5705
|
for (const entry of registered) {
|
|
6370
|
-
const action = entry.action;
|
|
6371
|
-
if (action.hidden && isCustomAction$1(action)) continue;
|
|
6372
|
-
if (isCustomAction$1(action)) {
|
|
6373
|
-
const custom = withoutRegistryMeta(action);
|
|
5706
|
+
const action$1 = entry.action;
|
|
5707
|
+
if (action$1.hidden && isCustomAction$1(action$1)) continue;
|
|
5708
|
+
if (isCustomAction$1(action$1)) {
|
|
5709
|
+
const custom = withoutRegistryMeta(action$1);
|
|
6374
5710
|
if (custom.position === "start") startCustomActions.push(custom);
|
|
6375
5711
|
else endCustomActions.push(custom);
|
|
6376
5712
|
continue;
|
|
6377
5713
|
}
|
|
6378
|
-
const existingIndex = nextActions.findIndex((item) => item.type === action.type);
|
|
6379
|
-
if (action.hidden) {
|
|
5714
|
+
const existingIndex = nextActions.findIndex((item) => item.type === action$1.type);
|
|
5715
|
+
if (action$1.hidden) {
|
|
6380
5716
|
if (existingIndex >= 0) nextActions.splice(existingIndex, 1);
|
|
6381
5717
|
continue;
|
|
6382
5718
|
}
|
|
6383
|
-
const builtin = withoutRegistryMeta(action);
|
|
5719
|
+
const builtin = withoutRegistryMeta(action$1);
|
|
6384
5720
|
if (existingIndex >= 0) nextActions[existingIndex] = {
|
|
6385
5721
|
...nextActions[existingIndex],
|
|
6386
5722
|
...builtin
|
|
@@ -6399,14 +5735,14 @@ const crudActions = {
|
|
|
6399
5735
|
targetId: registration.targetId,
|
|
6400
5736
|
zone: registration.zone
|
|
6401
5737
|
}, false);
|
|
6402
|
-
registration.actions.forEach((action, index$1) => {
|
|
6403
|
-
const key = actionKey(registration, action, index$1);
|
|
5738
|
+
registration.actions.forEach((action$1, index$1) => {
|
|
5739
|
+
const key = actionKey(registration, action$1, index$1);
|
|
6404
5740
|
const entry = {
|
|
6405
5741
|
targetId: registration.targetId,
|
|
6406
5742
|
zone: registration.zone,
|
|
6407
5743
|
ownerId: registration.ownerId,
|
|
6408
|
-
action,
|
|
6409
|
-
order: action.order ?? 100,
|
|
5744
|
+
action: action$1,
|
|
5745
|
+
order: action$1.order ?? 100,
|
|
6410
5746
|
seq: seq++
|
|
6411
5747
|
};
|
|
6412
5748
|
entries.set(key, entry);
|
|
@@ -6461,8 +5797,8 @@ function getDefaultRowActions() {
|
|
|
6461
5797
|
function getDefaultBatchActions() {
|
|
6462
5798
|
return [{ type: "batchUpdate" }, { type: "delete" }];
|
|
6463
5799
|
}
|
|
6464
|
-
function isCustomAction(action) {
|
|
6465
|
-
return action.type === "custom";
|
|
5800
|
+
function isCustomAction(action$1) {
|
|
5801
|
+
return action$1.type === "custom";
|
|
6466
5802
|
}
|
|
6467
5803
|
function resolveOwnerActions(config, defaults) {
|
|
6468
5804
|
const resolved = typeof config === "function" ? config([...defaults]) : config;
|
|
@@ -6510,7 +5846,7 @@ function haveSameRowSelection(left, right, idKey) {
|
|
|
6510
5846
|
return left.every((row, index$1) => row === right[index$1]);
|
|
6511
5847
|
}
|
|
6512
5848
|
function readCreateAction(actions) {
|
|
6513
|
-
return actions.find((action) => action.type === "create");
|
|
5849
|
+
return actions.find((action$1) => action$1.type === "create");
|
|
6514
5850
|
}
|
|
6515
5851
|
function resolveToolbarActionsWithResolver(targetId, ownerActions, context) {
|
|
6516
5852
|
const resolver = autoCrudToolbarResolver;
|
|
@@ -6562,6 +5898,15 @@ function toBatchOptions(options) {
|
|
|
6562
5898
|
value
|
|
6563
5899
|
}));
|
|
6564
5900
|
}
|
|
5901
|
+
const POPUP_SCROLL_LOAD_THRESHOLD = 24;
|
|
5902
|
+
function isNearPopupScrollBottom(target) {
|
|
5903
|
+
return target.scrollHeight - target.scrollTop - target.clientHeight <= POPUP_SCROLL_LOAD_THRESHOLD;
|
|
5904
|
+
}
|
|
5905
|
+
function mergeFilterOptions(current, incoming) {
|
|
5906
|
+
const optionsByValue = new Map((current ?? []).map((option) => [option.value, option]));
|
|
5907
|
+
for (const option of incoming) optionsByValue.set(option.value, option);
|
|
5908
|
+
return Array.from(optionsByValue.values());
|
|
5909
|
+
}
|
|
6565
5910
|
function getFilterDataSource(config) {
|
|
6566
5911
|
if (config.filter && typeof config.filter === "object") return config.filter.dataSource ?? config.dataSource;
|
|
6567
5912
|
return config.dataSource;
|
|
@@ -6585,7 +5930,20 @@ function useCrudActionsVersion() {
|
|
|
6585
5930
|
}
|
|
6586
5931
|
function useDynamicFilterOptions(fields) {
|
|
6587
5932
|
const registryVersion = useRegistryVersion(dataSources.subscribe);
|
|
5933
|
+
const [searchValues, setSearchValues] = react.useState({});
|
|
5934
|
+
const [hasMoreByField, setHasMoreByField] = react.useState({});
|
|
5935
|
+
const [labelOptionsByField, setLabelOptionsByField] = react.useState({});
|
|
5936
|
+
const [loadingByField, setLoadingByField] = react.useState({});
|
|
6588
5937
|
const [optionsByField, setOptionsByField] = react.useState({});
|
|
5938
|
+
const controllersRef = react.useRef({});
|
|
5939
|
+
const hasMoreByFieldRef = react.useRef({});
|
|
5940
|
+
const loadingByFieldRef = react.useRef({});
|
|
5941
|
+
const optionsByFieldRef = react.useRef({});
|
|
5942
|
+
const pageByFieldRef = react.useRef({});
|
|
5943
|
+
const requestVersionsRef = react.useRef({});
|
|
5944
|
+
const searchValuesRef = react.useRef({});
|
|
5945
|
+
const sourceEntriesByFieldRef = react.useRef({});
|
|
5946
|
+
const timersRef = react.useRef({});
|
|
6589
5947
|
const sourceEntries = react.useMemo(() => {
|
|
6590
5948
|
if (!fields) return [];
|
|
6591
5949
|
return Object.entries(fields).flatMap(([field, config]) => {
|
|
@@ -6597,36 +5955,185 @@ function useDynamicFilterOptions(fields) {
|
|
|
6597
5955
|
}] : [];
|
|
6598
5956
|
});
|
|
6599
5957
|
}, [fields]);
|
|
5958
|
+
const sourceEntriesByField = react.useMemo(() => Object.fromEntries(sourceEntries.map(({ field, source }) => [field, source])), [sourceEntries]);
|
|
6600
5959
|
react.useEffect(() => {
|
|
6601
|
-
|
|
6602
|
-
|
|
5960
|
+
searchValuesRef.current = searchValues;
|
|
5961
|
+
}, [searchValues]);
|
|
5962
|
+
react.useEffect(() => {
|
|
5963
|
+
sourceEntriesByFieldRef.current = sourceEntriesByField;
|
|
5964
|
+
}, [sourceEntriesByField]);
|
|
5965
|
+
const registeredByField = react.useMemo(() => Object.fromEntries(sourceEntries.map(({ field, source }) => [field, dataSources.get(source.key) !== void 0])), [sourceEntries, registryVersion]);
|
|
5966
|
+
const searchableByField = react.useMemo(() => Object.fromEntries(sourceEntries.map(({ field, source }) => [field, dataSources.get(source.key)?.search === true])), [sourceEntries, registryVersion]);
|
|
5967
|
+
const setFieldState = react.useCallback((setter, ref, field, value) => {
|
|
5968
|
+
ref.current = {
|
|
5969
|
+
...ref.current,
|
|
5970
|
+
[field]: value
|
|
5971
|
+
};
|
|
5972
|
+
setter(ref.current);
|
|
5973
|
+
}, []);
|
|
5974
|
+
const removeInactiveFieldState = react.useCallback((setter, ref, activeFields) => {
|
|
5975
|
+
const nextEntries = Object.entries(ref.current).filter(([field]) => activeFields.has(field));
|
|
5976
|
+
if (nextEntries.length === Object.keys(ref.current).length) return;
|
|
5977
|
+
ref.current = Object.fromEntries(nextEntries);
|
|
5978
|
+
setter(ref.current);
|
|
5979
|
+
}, []);
|
|
5980
|
+
const setFieldOptions = react.useCallback((field, options) => {
|
|
5981
|
+
optionsByFieldRef.current = {
|
|
5982
|
+
...optionsByFieldRef.current,
|
|
5983
|
+
[field]: options
|
|
5984
|
+
};
|
|
5985
|
+
setOptionsByField(optionsByFieldRef.current);
|
|
5986
|
+
}, []);
|
|
5987
|
+
const setFieldLoading = react.useCallback((field, loading) => {
|
|
5988
|
+
setFieldState(setLoadingByField, loadingByFieldRef, field, loading);
|
|
5989
|
+
}, [setFieldState]);
|
|
5990
|
+
const setFieldHasMore = react.useCallback((field, hasMore) => {
|
|
5991
|
+
setFieldState(setHasMoreByField, hasMoreByFieldRef, field, hasMore);
|
|
5992
|
+
}, [setFieldState]);
|
|
5993
|
+
const clearFieldRequest = react.useCallback((field) => {
|
|
5994
|
+
const timer = timersRef.current[field];
|
|
5995
|
+
if (timer) clearTimeout(timer);
|
|
5996
|
+
timersRef.current[field] = void 0;
|
|
5997
|
+
controllersRef.current[field]?.abort();
|
|
5998
|
+
controllersRef.current[field] = void 0;
|
|
5999
|
+
}, []);
|
|
6000
|
+
const resetField = react.useCallback((field, { clearLabels = false } = {}) => {
|
|
6001
|
+
clearFieldRequest(field);
|
|
6002
|
+
setFieldOptions(field, []);
|
|
6003
|
+
setFieldLoading(field, false);
|
|
6004
|
+
setFieldHasMore(field, false);
|
|
6005
|
+
pageByFieldRef.current = {
|
|
6006
|
+
...pageByFieldRef.current,
|
|
6007
|
+
[field]: 0
|
|
6008
|
+
};
|
|
6009
|
+
if (clearLabels) setLabelOptionsByField((current) => {
|
|
6010
|
+
const { [field]: _,...rest } = current;
|
|
6011
|
+
return rest;
|
|
6012
|
+
});
|
|
6013
|
+
}, [
|
|
6014
|
+
clearFieldRequest,
|
|
6015
|
+
setFieldHasMore,
|
|
6016
|
+
setFieldLoading,
|
|
6017
|
+
setFieldOptions
|
|
6018
|
+
]);
|
|
6019
|
+
const loadFieldOptions = react.useCallback((field, append = false) => {
|
|
6020
|
+
if (append) {
|
|
6021
|
+
if (loadingByFieldRef.current[field] || !hasMoreByFieldRef.current[field]) return;
|
|
6022
|
+
}
|
|
6023
|
+
const source = sourceEntriesByFieldRef.current[field];
|
|
6024
|
+
const entry = source ? dataSources.get(source.key) : void 0;
|
|
6025
|
+
if (!source || !entry) {
|
|
6026
|
+
resetField(field);
|
|
6603
6027
|
return;
|
|
6604
6028
|
}
|
|
6605
|
-
|
|
6029
|
+
const requestVersion = (requestVersionsRef.current[field] ?? 0) + 1;
|
|
6030
|
+
requestVersionsRef.current = {
|
|
6031
|
+
...requestVersionsRef.current,
|
|
6032
|
+
[field]: requestVersion
|
|
6033
|
+
};
|
|
6034
|
+
clearFieldRequest(field);
|
|
6606
6035
|
const controller = typeof AbortController === "undefined" ? void 0 : new AbortController();
|
|
6607
|
-
|
|
6608
|
-
|
|
6609
|
-
|
|
6610
|
-
|
|
6611
|
-
|
|
6612
|
-
|
|
6613
|
-
|
|
6614
|
-
|
|
6615
|
-
|
|
6616
|
-
|
|
6617
|
-
|
|
6618
|
-
|
|
6619
|
-
|
|
6620
|
-
|
|
6621
|
-
|
|
6622
|
-
|
|
6623
|
-
|
|
6624
|
-
|
|
6625
|
-
|
|
6626
|
-
|
|
6036
|
+
controllersRef.current[field] = controller;
|
|
6037
|
+
const search = entry.search ? searchValuesRef.current[field] ?? "" : void 0;
|
|
6038
|
+
const page = entry.loadMore ? append ? (pageByFieldRef.current[field] ?? 0) + 1 : 1 : void 0;
|
|
6039
|
+
setFieldLoading(field, true);
|
|
6040
|
+
if (!append) setFieldHasMore(field, false);
|
|
6041
|
+
const timer = setTimeout(() => {
|
|
6042
|
+
Promise.resolve(entry.load({
|
|
6043
|
+
field,
|
|
6044
|
+
page,
|
|
6045
|
+
pageSize: entry.loadMore ? entry.pageSize : void 0,
|
|
6046
|
+
search,
|
|
6047
|
+
values: {},
|
|
6048
|
+
signal: controller?.signal
|
|
6049
|
+
})).then((result) => {
|
|
6050
|
+
if (requestVersionsRef.current[field] !== requestVersion || controller?.signal.aborted) return;
|
|
6051
|
+
const options = normalizeOptions(result);
|
|
6052
|
+
const nextOptions = append ? mergeFilterOptions(optionsByFieldRef.current[field], options) : options;
|
|
6053
|
+
const hasMore = normalizeHasMore(result);
|
|
6054
|
+
setFieldOptions(field, nextOptions);
|
|
6055
|
+
setLabelOptionsByField((current) => ({
|
|
6056
|
+
...current,
|
|
6057
|
+
[field]: mergeFilterOptions(current[field], nextOptions)
|
|
6058
|
+
}));
|
|
6059
|
+
pageByFieldRef.current = {
|
|
6060
|
+
...pageByFieldRef.current,
|
|
6061
|
+
[field]: page ?? 0
|
|
6062
|
+
};
|
|
6063
|
+
setFieldHasMore(field, hasMore);
|
|
6064
|
+
setFieldLoading(field, false);
|
|
6065
|
+
}, (error) => {
|
|
6066
|
+
if (controller?.signal.aborted) return;
|
|
6067
|
+
console.warn(`[AutoCrud] Failed to load filter data source "${source.key}".`, error);
|
|
6068
|
+
if (!append) {
|
|
6069
|
+
setFieldOptions(field, []);
|
|
6070
|
+
setFieldHasMore(field, false);
|
|
6071
|
+
pageByFieldRef.current = {
|
|
6072
|
+
...pageByFieldRef.current,
|
|
6073
|
+
[field]: 0
|
|
6074
|
+
};
|
|
6075
|
+
}
|
|
6076
|
+
setFieldLoading(field, false);
|
|
6077
|
+
});
|
|
6078
|
+
}, !append && entry.search ? entry.debounceMs : 0);
|
|
6079
|
+
timersRef.current[field] = timer;
|
|
6080
|
+
}, [
|
|
6081
|
+
clearFieldRequest,
|
|
6082
|
+
resetField,
|
|
6083
|
+
setFieldHasMore,
|
|
6084
|
+
setFieldLoading,
|
|
6085
|
+
setFieldOptions
|
|
6086
|
+
]);
|
|
6087
|
+
const setSearchValue = react.useCallback((field, value) => {
|
|
6088
|
+
searchValuesRef.current = {
|
|
6089
|
+
...searchValuesRef.current,
|
|
6090
|
+
[field]: value
|
|
6627
6091
|
};
|
|
6628
|
-
|
|
6629
|
-
|
|
6092
|
+
setSearchValues((current) => current[field] === value ? current : {
|
|
6093
|
+
...current,
|
|
6094
|
+
[field]: value
|
|
6095
|
+
});
|
|
6096
|
+
}, []);
|
|
6097
|
+
react.useEffect(() => {
|
|
6098
|
+
if (sourceEntries.length === 0) {
|
|
6099
|
+
hasMoreByFieldRef.current = {};
|
|
6100
|
+
loadingByFieldRef.current = {};
|
|
6101
|
+
optionsByFieldRef.current = {};
|
|
6102
|
+
pageByFieldRef.current = {};
|
|
6103
|
+
Object.keys(controllersRef.current).forEach(clearFieldRequest);
|
|
6104
|
+
setHasMoreByField({});
|
|
6105
|
+
setLoadingByField({});
|
|
6106
|
+
setOptionsByField({});
|
|
6107
|
+
return;
|
|
6108
|
+
}
|
|
6109
|
+
const activeFields = new Set(sourceEntries.map(({ field }) => field));
|
|
6110
|
+
removeInactiveFieldState(setHasMoreByField, hasMoreByFieldRef, activeFields);
|
|
6111
|
+
removeInactiveFieldState(setLoadingByField, loadingByFieldRef, activeFields);
|
|
6112
|
+
removeInactiveFieldState(setOptionsByField, optionsByFieldRef, activeFields);
|
|
6113
|
+
for (const field of Object.keys(controllersRef.current)) if (!activeFields.has(field)) clearFieldRequest(field);
|
|
6114
|
+
for (const { field } of sourceEntries) loadFieldOptions(field);
|
|
6115
|
+
}, [
|
|
6116
|
+
clearFieldRequest,
|
|
6117
|
+
loadFieldOptions,
|
|
6118
|
+
removeInactiveFieldState,
|
|
6119
|
+
sourceEntries,
|
|
6120
|
+
registryVersion,
|
|
6121
|
+
searchValues
|
|
6122
|
+
]);
|
|
6123
|
+
react.useEffect(() => () => {
|
|
6124
|
+
for (const field of Object.keys(controllersRef.current)) clearFieldRequest(field);
|
|
6125
|
+
}, [clearFieldRequest]);
|
|
6126
|
+
return {
|
|
6127
|
+
hasMoreByField,
|
|
6128
|
+
labelOptionsByField,
|
|
6129
|
+
loadingByField,
|
|
6130
|
+
optionsByField,
|
|
6131
|
+
registeredByField,
|
|
6132
|
+
searchValues,
|
|
6133
|
+
searchableByField,
|
|
6134
|
+
loadMore: (field) => loadFieldOptions(field, true),
|
|
6135
|
+
setSearchValue
|
|
6136
|
+
};
|
|
6630
6137
|
}
|
|
6631
6138
|
function getOptionLabel(value, options) {
|
|
6632
6139
|
const stringValue = String(value);
|
|
@@ -6636,12 +6143,15 @@ function getOptionLabel(value, options) {
|
|
|
6636
6143
|
* 从统一配置生成表格 overrides
|
|
6637
6144
|
* 当 filter 配置存在时,合并到 meta 中(不影响列隐藏)
|
|
6638
6145
|
*/
|
|
6639
|
-
function buildTableOverrides(fields, legacyOverrides,
|
|
6146
|
+
function buildTableOverrides(fields, legacyOverrides, dynamicFilterState) {
|
|
6640
6147
|
const result = { ...legacyOverrides };
|
|
6641
6148
|
if (fields) for (const [key, config] of Object.entries(fields)) {
|
|
6642
6149
|
const fieldOptions = normalizeFieldOptions(config.enum);
|
|
6643
6150
|
const tableOptions = toTableOptions(fieldOptions);
|
|
6644
|
-
const
|
|
6151
|
+
const filterDataSourceRegistered = dynamicFilterState?.registeredByField[key];
|
|
6152
|
+
const filterDataSourceSearchable = dynamicFilterState?.searchableByField[key];
|
|
6153
|
+
const currentDynamicOptions = !fieldOptions && filterDataSourceRegistered ? toTableOptions(dynamicFilterState?.optionsByField[key] ?? []) : void 0;
|
|
6154
|
+
const dynamicOptions = !fieldOptions && filterDataSourceRegistered ? toTableOptions(dynamicFilterState?.labelOptionsByField[key] ?? dynamicFilterState?.optionsByField[key] ?? []) : void 0;
|
|
6645
6155
|
const tableMeta = config.table !== false && typeof config.table === "object" ? config.table.meta : void 0;
|
|
6646
6156
|
const fieldEnumMeta = tableOptions ? {
|
|
6647
6157
|
options: tableOptions,
|
|
@@ -6649,7 +6159,19 @@ function buildTableOverrides(fields, legacyOverrides, dynamicFilterOptions) {
|
|
|
6649
6159
|
} : void 0;
|
|
6650
6160
|
const fieldDataSourceMeta = dynamicOptions ? {
|
|
6651
6161
|
options: dynamicOptions,
|
|
6652
|
-
|
|
6162
|
+
autoCrudFilterOptions: currentDynamicOptions ?? dynamicOptions,
|
|
6163
|
+
autoCrudFilterHasMore: dynamicFilterState?.hasMoreByField[key] ?? false,
|
|
6164
|
+
autoCrudFilterLoading: dynamicFilterState?.loadingByField[key] ?? false,
|
|
6165
|
+
autoCrudFilterOnPopupScroll: (event) => {
|
|
6166
|
+
if (!isNearPopupScrollBottom(event.currentTarget)) return;
|
|
6167
|
+
dynamicFilterState?.loadMore(key);
|
|
6168
|
+
},
|
|
6169
|
+
variant: "multiSelect",
|
|
6170
|
+
...filterDataSourceSearchable ? {
|
|
6171
|
+
autoCrudFilterSearchValue: dynamicFilterState?.searchValues[key] ?? "",
|
|
6172
|
+
autoCrudFilterOnSearch: (value) => dynamicFilterState?.setSearchValue(key, value),
|
|
6173
|
+
autoCrudFilterShouldFilter: false
|
|
6174
|
+
} : void 0
|
|
6653
6175
|
} : void 0;
|
|
6654
6176
|
let filterMeta;
|
|
6655
6177
|
if (config.filter && typeof config.filter === "object") {
|
|
@@ -6701,46 +6223,6 @@ function buildTableOverrides(fields, legacyOverrides, dynamicFilterOptions) {
|
|
|
6701
6223
|
return result;
|
|
6702
6224
|
}
|
|
6703
6225
|
/**
|
|
6704
|
-
* 从统一配置生成表单 overrides
|
|
6705
|
-
* Critical #2: 支持 denyFields 隐藏敏感字段
|
|
6706
|
-
*/
|
|
6707
|
-
function buildFormOverrides(fields, legacyOverrides, denyFields) {
|
|
6708
|
-
const result = { ...legacyOverrides };
|
|
6709
|
-
if (denyFields) for (const field of denyFields) result[field] = {
|
|
6710
|
-
...result[field],
|
|
6711
|
-
"x-hidden": true
|
|
6712
|
-
};
|
|
6713
|
-
if (fields) for (const [key, config] of Object.entries(fields)) {
|
|
6714
|
-
const fieldOptions = normalizeFieldOptions((config.form && typeof config.form === "object" ? config.form : void 0)?.enum) ?? normalizeFieldOptions(config.enum);
|
|
6715
|
-
const fieldDataSource = fieldOptions || !config.dataSource ? void 0 : normalizeDataSourceConfig(config.dataSource);
|
|
6716
|
-
if (config.label) result[key] = {
|
|
6717
|
-
...result[key],
|
|
6718
|
-
title: config.label
|
|
6719
|
-
};
|
|
6720
|
-
if (config.hidden) result[key] = {
|
|
6721
|
-
...result[key],
|
|
6722
|
-
"x-hidden": true
|
|
6723
|
-
};
|
|
6724
|
-
if (fieldOptions) result[key] = {
|
|
6725
|
-
...result[key],
|
|
6726
|
-
enum: fieldOptions
|
|
6727
|
-
};
|
|
6728
|
-
if (fieldDataSource) result[key] = {
|
|
6729
|
-
...result[key],
|
|
6730
|
-
"x-data-source": config.dataSource
|
|
6731
|
-
};
|
|
6732
|
-
if (config.form === false) result[key] = {
|
|
6733
|
-
...result[key],
|
|
6734
|
-
"x-hidden": true
|
|
6735
|
-
};
|
|
6736
|
-
else if (config.form && typeof config.form === "object") result[key] = {
|
|
6737
|
-
...result[key],
|
|
6738
|
-
...config.form
|
|
6739
|
-
};
|
|
6740
|
-
}
|
|
6741
|
-
return result;
|
|
6742
|
-
}
|
|
6743
|
-
/**
|
|
6744
6226
|
* 从统一配置生成隐藏列列表
|
|
6745
6227
|
*/
|
|
6746
6228
|
function buildHiddenColumns(fields, legacyHidden, denyFields) {
|
|
@@ -6804,15 +6286,15 @@ function renderFieldValue(value, type, booleanLocale, options) {
|
|
|
6804
6286
|
if (options && options.length > 0) {
|
|
6805
6287
|
if (Array.isArray(value)) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6806
6288
|
className: "flex gap-1 flex-wrap",
|
|
6807
|
-
children: [value.slice(0, 5).map((v, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
6289
|
+
children: [value.slice(0, 5).map((v, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Badge, {
|
|
6808
6290
|
variant: "secondary",
|
|
6809
6291
|
children: getOptionLabel(v, options)
|
|
6810
|
-
}, i)), value.length > 5 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
6292
|
+
}, i)), value.length > 5 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Badge, {
|
|
6811
6293
|
variant: "outline",
|
|
6812
6294
|
children: ["+", value.length - 5]
|
|
6813
6295
|
})]
|
|
6814
6296
|
});
|
|
6815
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
6297
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Badge, {
|
|
6816
6298
|
variant: "outline",
|
|
6817
6299
|
className: "capitalize",
|
|
6818
6300
|
children: getOptionLabel(value, options)
|
|
@@ -6821,17 +6303,17 @@ function renderFieldValue(value, type, booleanLocale, options) {
|
|
|
6821
6303
|
switch (type) {
|
|
6822
6304
|
case "boolean": return value ? booleanLocale.true : booleanLocale.false;
|
|
6823
6305
|
case "date": return formatDate(value);
|
|
6824
|
-
case "enum": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
6306
|
+
case "enum": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Badge, {
|
|
6825
6307
|
variant: "outline",
|
|
6826
6308
|
className: "capitalize",
|
|
6827
6309
|
children: String(value)
|
|
6828
6310
|
});
|
|
6829
6311
|
case "array": return Array.isArray(value) ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6830
6312
|
className: "flex gap-1 flex-wrap",
|
|
6831
|
-
children: [value.slice(0, 5).map((v, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
6313
|
+
children: [value.slice(0, 5).map((v, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Badge, {
|
|
6832
6314
|
variant: "secondary",
|
|
6833
6315
|
children: String(v)
|
|
6834
|
-
}, i)), value.length > 5 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
6316
|
+
}, i)), value.length > 5 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Badge, {
|
|
6835
6317
|
variant: "outline",
|
|
6836
6318
|
children: ["+", value.length - 5]
|
|
6837
6319
|
})]
|
|
@@ -6868,18 +6350,18 @@ function ViewModal({ open, onOpenChange, variant, data, schema, fields: fieldCon
|
|
|
6868
6350
|
}, key);
|
|
6869
6351
|
})
|
|
6870
6352
|
});
|
|
6871
|
-
if (variant === "sheet") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
6353
|
+
if (variant === "sheet") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Sheet, {
|
|
6872
6354
|
open,
|
|
6873
6355
|
onOpenChange,
|
|
6874
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
6356
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.SheetContent, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.SheetHeader, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.SheetTitle, { children: locale.viewModal.title }) }), content] })
|
|
6875
6357
|
});
|
|
6876
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
6358
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Dialog, {
|
|
6877
6359
|
open,
|
|
6878
6360
|
onOpenChange,
|
|
6879
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
6361
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.DialogContent, {
|
|
6880
6362
|
"aria-describedby": void 0,
|
|
6881
6363
|
className: "max-w-2xl max-h-[80vh] overflow-y-auto",
|
|
6882
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
6364
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.DialogHeader, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.DialogTitle, { children: locale.viewModal.title }) }), content]
|
|
6883
6365
|
})
|
|
6884
6366
|
});
|
|
6885
6367
|
}
|
|
@@ -7167,20 +6649,20 @@ function AutoCrudTable({ id, title, description, schema, resource, fields, table
|
|
|
7167
6649
|
className: "flex items-center justify-end gap-4",
|
|
7168
6650
|
children: (() => {
|
|
7169
6651
|
const renderBuiltinButton = (type, overrides) => {
|
|
7170
|
-
if (type === "import" && canImport) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
6652
|
+
if (type === "import" && canImport) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
7171
6653
|
variant: "outline",
|
|
7172
6654
|
size: "sm",
|
|
7173
6655
|
onClick: overrides?.onClick ?? (() => setImportOpen(true)),
|
|
7174
6656
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Download, { className: "mr-2 h-4 w-4" }), overrides?.label ?? locale.toolbar.import]
|
|
7175
6657
|
}, "import");
|
|
7176
|
-
if (type === "export" && canExport) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
6658
|
+
if (type === "export" && canExport) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
7177
6659
|
variant: "outline",
|
|
7178
6660
|
size: "sm",
|
|
7179
6661
|
onClick: overrides?.onClick ?? handleExportClick,
|
|
7180
6662
|
disabled: exporting || selectedCount === 0 && !resource.handlers.export,
|
|
7181
6663
|
children: [exporting ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Loader2, { className: "mr-2 h-4 w-4 animate-spin" }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Upload, { className: "mr-2 h-4 w-4" }), overrides?.label ?? (selectedCount > 0 ? locale.toolbar.exportSelected(selectedCount) : locale.toolbar.export)]
|
|
7182
6664
|
}, "export");
|
|
7183
|
-
if (type === "create" && can.create) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
6665
|
+
if (type === "create" && can.create) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
7184
6666
|
onClick: overrides?.onClick ?? onCreate ?? resource.handlers.openCreate,
|
|
7185
6667
|
children: overrides?.label ?? locale.toolbar.create
|
|
7186
6668
|
}, "create");
|
|
@@ -7204,13 +6686,13 @@ function AutoCrudTable({ id, title, description, schema, resource, fields, table
|
|
|
7204
6686
|
}
|
|
7205
6687
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7206
6688
|
className: "flex items-center gap-2",
|
|
7207
|
-
children: resolvedToolbarActions.map((action, index$1) => {
|
|
7208
|
-
if (action.type === "custom") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children: renderToolbarComponent(action.component) }, `custom-${index$1}`);
|
|
7209
|
-
if (!(action.type === "import" ? canImport : action.type === "export" ? canExport : can.create)) return null;
|
|
7210
|
-
if (action.component) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children: renderToolbarComponent(action.component) }, action.type);
|
|
7211
|
-
return renderBuiltinButton(action.type, {
|
|
7212
|
-
onClick: action.onClick,
|
|
7213
|
-
label: action.label
|
|
6689
|
+
children: resolvedToolbarActions.map((action$1, index$1) => {
|
|
6690
|
+
if (action$1.type === "custom") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children: renderToolbarComponent(action$1.component) }, `custom-${index$1}`);
|
|
6691
|
+
if (!(action$1.type === "import" ? canImport : action$1.type === "export" ? canExport : can.create)) return null;
|
|
6692
|
+
if (action$1.component) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children: renderToolbarComponent(action$1.component) }, action$1.type);
|
|
6693
|
+
return renderBuiltinButton(action$1.type, {
|
|
6694
|
+
onClick: action$1.onClick,
|
|
6695
|
+
label: action$1.label
|
|
7214
6696
|
});
|
|
7215
6697
|
})
|
|
7216
6698
|
});
|
|
@@ -7229,6 +6711,7 @@ function AutoCrudTable({ id, title, description, schema, resource, fields, table
|
|
|
7229
6711
|
onUpdateSelected: can.update ? resource.handlers.updateMany : void 0,
|
|
7230
6712
|
batchUpdateFields: can.update ? batchFields : void 0,
|
|
7231
6713
|
actionBarActions: registryBatchActions,
|
|
6714
|
+
deleteConfirmation: locale.bulkDeleteModal,
|
|
7232
6715
|
enableExport: canExport,
|
|
7233
6716
|
showDefaultExport: false,
|
|
7234
6717
|
initialSorting: tableConfig?.defaultSort,
|
|
@@ -7248,6 +6731,7 @@ function AutoCrudTable({ id, title, description, schema, resource, fields, table
|
|
|
7248
6731
|
loading: resource.mutations.isCreating || resource.mutations.isUpdating,
|
|
7249
6732
|
variant: resource.modal.variant,
|
|
7250
6733
|
overrides: formOverrides,
|
|
6734
|
+
scope: formConfig?.scope,
|
|
7251
6735
|
locale: locale.formModal,
|
|
7252
6736
|
gridColumns: formConfig?.columns,
|
|
7253
6737
|
className: formConfig?.className
|
|
@@ -7259,14 +6743,14 @@ function AutoCrudTable({ id, title, description, schema, resource, fields, table
|
|
|
7259
6743
|
data: resource.modal.selected,
|
|
7260
6744
|
schema: resolvedSchema,
|
|
7261
6745
|
fields: resolvedFields,
|
|
7262
|
-
dynamicOptions: dynamicFilterOptions,
|
|
6746
|
+
dynamicOptions: dynamicFilterOptions.optionsByField,
|
|
7263
6747
|
denyFields,
|
|
7264
6748
|
locale
|
|
7265
6749
|
}),
|
|
7266
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
6750
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.AlertDialog, {
|
|
7267
6751
|
open: resource.modal.deleteOpen,
|
|
7268
6752
|
onOpenChange: (open) => !open && resource.handlers.closeModals(),
|
|
7269
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
6753
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.AlertDialogContent, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.AlertDialogHeader, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.AlertDialogTitle, { children: locale.deleteModal.title }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.AlertDialogDescription, { children: locale.deleteModal.description })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.AlertDialogFooter, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.AlertDialogCancel, { children: locale.deleteModal.cancel }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.AlertDialogAction, {
|
|
7270
6754
|
onClick: resource.handlers.confirmDelete,
|
|
7271
6755
|
disabled: resource.mutations.isDeleting,
|
|
7272
6756
|
children: resource.mutations.isDeleting ? locale.deleteModal.confirming : locale.deleteModal.confirm
|
|
@@ -7307,12 +6791,12 @@ function ExportDialog({ open, onOpenChange, selectedCount, onExport, canExportFi
|
|
|
7307
6791
|
}
|
|
7308
6792
|
}, [onExport, handleOpenChange]);
|
|
7309
6793
|
const hasSelected = selectedCount > 0;
|
|
7310
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
6794
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Dialog, {
|
|
7311
6795
|
open,
|
|
7312
6796
|
onOpenChange: handleOpenChange,
|
|
7313
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
6797
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.DialogContent, {
|
|
7314
6798
|
className: "sm:max-w-[400px]",
|
|
7315
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
6799
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.DialogHeader, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.DialogTitle, { children: "导出数据" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.DialogDescription, { children: "选择导出范围" })] }), done ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7316
6800
|
className: "flex flex-col items-center gap-3 py-6",
|
|
7317
6801
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.CheckCircle2, { className: "h-10 w-10 text-green-500" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
7318
6802
|
className: "text-sm text-muted-foreground",
|
|
@@ -7320,7 +6804,7 @@ function ExportDialog({ open, onOpenChange, selectedCount, onExport, canExportFi
|
|
|
7320
6804
|
})]
|
|
7321
6805
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7322
6806
|
className: "grid gap-3 py-2",
|
|
7323
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
6807
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
7324
6808
|
variant: "outline",
|
|
7325
6809
|
className: "h-auto justify-start gap-3 px-4 py-3",
|
|
7326
6810
|
disabled: !hasSelected || exporting !== null,
|
|
@@ -7335,7 +6819,7 @@ function ExportDialog({ open, onOpenChange, selectedCount, onExport, canExportFi
|
|
|
7335
6819
|
children: hasSelected ? "导出当前勾选的数据行" : "请先在表格中勾选数据行"
|
|
7336
6820
|
})]
|
|
7337
6821
|
})]
|
|
7338
|
-
}), canExportFiltered && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
6822
|
+
}), canExportFiltered && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
7339
6823
|
variant: "outline",
|
|
7340
6824
|
className: "h-auto justify-start gap-3 px-4 py-3",
|
|
7341
6825
|
disabled: exporting !== null,
|
|
@@ -7382,19 +6866,29 @@ function DataTableAdvancedToolbar({ table, children, className,...props }) {
|
|
|
7382
6866
|
function DataTableFacetedFilter({ column, title, options, multiple }) {
|
|
7383
6867
|
const columnFilterValue = column?.getFilterValue();
|
|
7384
6868
|
const selectedValues = Array.isArray(columnFilterValue) ? columnFilterValue.filter((value) => typeof value === "string") : [];
|
|
6869
|
+
const currentOptions = column?.columnDef.meta?.autoCrudFilterOptions ?? options;
|
|
6870
|
+
const currentOptionValues = new Set(currentOptions.map((option) => option.value));
|
|
6871
|
+
const selectedOptionValues = new Set(selectedValues);
|
|
6872
|
+
const comboboxOptions = currentOptions === options ? currentOptions : [...options.filter((option) => selectedOptionValues.has(option.value) && !currentOptionValues.has(option.value)), ...currentOptions];
|
|
7385
6873
|
const onChange = (nextValues) => {
|
|
7386
6874
|
column?.setFilterValue(nextValues.length ? nextValues : void 0);
|
|
7387
6875
|
};
|
|
7388
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MultiCombobox, {
|
|
6876
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn_ui.MultiCombobox, {
|
|
7389
6877
|
value: selectedValues,
|
|
7390
6878
|
onChange,
|
|
7391
|
-
options,
|
|
6879
|
+
options: comboboxOptions,
|
|
7392
6880
|
selectionMode: multiple ? "multiple" : "single",
|
|
7393
6881
|
searchPlaceholder: title,
|
|
6882
|
+
hasMore: column?.columnDef.meta?.autoCrudFilterHasMore,
|
|
6883
|
+
loading: column?.columnDef.meta?.autoCrudFilterLoading,
|
|
6884
|
+
searchValue: column?.columnDef.meta?.autoCrudFilterSearchValue,
|
|
6885
|
+
shouldFilter: column?.columnDef.meta?.autoCrudFilterShouldFilter,
|
|
6886
|
+
onPopupScroll: column?.columnDef.meta?.autoCrudFilterOnPopupScroll,
|
|
6887
|
+
onSearch: column?.columnDef.meta?.autoCrudFilterOnSearch,
|
|
7394
6888
|
contentClassName: "w-50",
|
|
7395
6889
|
matchTriggerWidth: false,
|
|
7396
6890
|
clearText: "Clear filters",
|
|
7397
|
-
renderTrigger: ({ selectedOptions, selectedValues: selectedValues$1, clearSelection }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
6891
|
+
renderTrigger: ({ selectedOptions, selectedValues: selectedValues$1, clearSelection }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
7398
6892
|
type: "button",
|
|
7399
6893
|
variant: "outline",
|
|
7400
6894
|
size: "sm",
|
|
@@ -7411,22 +6905,22 @@ function DataTableFacetedFilter({ column, title, options, multiple }) {
|
|
|
7411
6905
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.PlusCircle, {}),
|
|
7412
6906
|
title,
|
|
7413
6907
|
selectedValues$1.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
7414
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
6908
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Separator, {
|
|
7415
6909
|
orientation: "vertical",
|
|
7416
6910
|
className: "mx-0.5 data-[orientation=vertical]:h-4"
|
|
7417
6911
|
}),
|
|
7418
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
6912
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Badge, {
|
|
7419
6913
|
variant: "secondary",
|
|
7420
6914
|
className: "rounded-sm px-1 font-normal lg:hidden",
|
|
7421
6915
|
children: selectedValues$1.length
|
|
7422
6916
|
}),
|
|
7423
6917
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7424
6918
|
className: "hidden items-center gap-1 lg:flex",
|
|
7425
|
-
children: selectedValues$1.length > 2 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
6919
|
+
children: selectedValues$1.length > 2 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Badge, {
|
|
7426
6920
|
variant: "secondary",
|
|
7427
6921
|
className: "rounded-sm px-1 font-normal",
|
|
7428
6922
|
children: [selectedValues$1.length, " selected"]
|
|
7429
|
-
}) : selectedOptions.map((option) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
6923
|
+
}) : selectedOptions.map((option) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Badge, {
|
|
7430
6924
|
variant: "secondary",
|
|
7431
6925
|
className: "rounded-sm px-1 font-normal",
|
|
7432
6926
|
children: option.label
|
|
@@ -7566,7 +7060,7 @@ function DataTableDateFilter({ column, title, multiple }) {
|
|
|
7566
7060
|
const dateText$1 = hasSelectedDates ? formatDateRange(selectedDates) : "Select date range";
|
|
7567
7061
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
7568
7062
|
className: "flex items-center gap-2",
|
|
7569
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: title }), hasSelectedDates && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
7063
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: title }), hasSelectedDates && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Separator, {
|
|
7570
7064
|
orientation: "vertical",
|
|
7571
7065
|
className: "mx-0.5 data-[orientation=vertical]:h-4"
|
|
7572
7066
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: dateText$1 })] })]
|
|
@@ -7577,7 +7071,7 @@ function DataTableDateFilter({ column, title, multiple }) {
|
|
|
7577
7071
|
const dateText = hasSelectedDate ? formatDate(selectedDates[0]) : "Select date";
|
|
7578
7072
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
7579
7073
|
className: "flex items-center gap-2",
|
|
7580
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: title }), hasSelectedDate && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
7074
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: title }), hasSelectedDate && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Separator, {
|
|
7581
7075
|
orientation: "vertical",
|
|
7582
7076
|
className: "mx-0.5 data-[orientation=vertical]:h-4"
|
|
7583
7077
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: dateText })] })]
|
|
@@ -7588,9 +7082,9 @@ function DataTableDateFilter({ column, title, multiple }) {
|
|
|
7588
7082
|
formatDateRange,
|
|
7589
7083
|
title
|
|
7590
7084
|
]);
|
|
7591
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
7085
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Popover, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.PopoverTrigger, {
|
|
7592
7086
|
asChild: true,
|
|
7593
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
7087
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
7594
7088
|
variant: "outline",
|
|
7595
7089
|
size: "sm",
|
|
7596
7090
|
className: "border-dashed font-normal",
|
|
@@ -7603,16 +7097,16 @@ function DataTableDateFilter({ column, title, multiple }) {
|
|
|
7603
7097
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.XCircle, {})
|
|
7604
7098
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.CalendarIcon, {}), label]
|
|
7605
7099
|
})
|
|
7606
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
7100
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.PopoverContent, {
|
|
7607
7101
|
className: "w-auto p-0",
|
|
7608
7102
|
align: "start",
|
|
7609
|
-
children: multiple ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
7103
|
+
children: multiple ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Calendar, {
|
|
7610
7104
|
autoFocus: true,
|
|
7611
7105
|
captionLayout: "dropdown",
|
|
7612
7106
|
mode: "range",
|
|
7613
7107
|
selected: localRange,
|
|
7614
7108
|
onSelect
|
|
7615
|
-
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
7109
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Calendar, {
|
|
7616
7110
|
captionLayout: "dropdown",
|
|
7617
7111
|
mode: "single",
|
|
7618
7112
|
selected: !getIsDateRange(selectedDates) ? selectedDates[0] : void 0,
|
|
@@ -7701,9 +7195,9 @@ function DataTableSliderFilter({ column, title }) {
|
|
|
7701
7195
|
if (event.target instanceof HTMLDivElement) event.stopPropagation();
|
|
7702
7196
|
column.setFilterValue(void 0);
|
|
7703
7197
|
}, [column]);
|
|
7704
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
7198
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Popover, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.PopoverTrigger, {
|
|
7705
7199
|
asChild: true,
|
|
7706
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
7200
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
7707
7201
|
variant: "outline",
|
|
7708
7202
|
size: "sm",
|
|
7709
7203
|
className: "border-dashed font-normal",
|
|
@@ -7718,7 +7212,7 @@ function DataTableSliderFilter({ column, title }) {
|
|
|
7718
7212
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.PlusCircle, {}),
|
|
7719
7213
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: title }),
|
|
7720
7214
|
columnFilterValue ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
7721
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
7215
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Separator, {
|
|
7722
7216
|
orientation: "vertical",
|
|
7723
7217
|
className: "mx-0.5 data-[orientation=vertical]:h-4"
|
|
7724
7218
|
}),
|
|
@@ -7730,7 +7224,7 @@ function DataTableSliderFilter({ column, title }) {
|
|
|
7730
7224
|
] }) : null
|
|
7731
7225
|
]
|
|
7732
7226
|
})
|
|
7733
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
7227
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.PopoverContent, {
|
|
7734
7228
|
align: "start",
|
|
7735
7229
|
className: "flex w-auto flex-col gap-4",
|
|
7736
7230
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -7743,14 +7237,14 @@ function DataTableSliderFilter({ column, title }) {
|
|
|
7743
7237
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7744
7238
|
className: "flex items-center gap-4",
|
|
7745
7239
|
children: [
|
|
7746
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
7240
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Label, {
|
|
7747
7241
|
htmlFor: `${id}-from`,
|
|
7748
7242
|
className: "sr-only",
|
|
7749
7243
|
children: "From"
|
|
7750
7244
|
}),
|
|
7751
7245
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7752
7246
|
className: "relative",
|
|
7753
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
7247
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Input, {
|
|
7754
7248
|
id: `${id}-from`,
|
|
7755
7249
|
type: "number",
|
|
7756
7250
|
"aria-valuemin": min,
|
|
@@ -7768,14 +7262,14 @@ function DataTableSliderFilter({ column, title }) {
|
|
|
7768
7262
|
children: unit
|
|
7769
7263
|
})]
|
|
7770
7264
|
}),
|
|
7771
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
7265
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Label, {
|
|
7772
7266
|
htmlFor: `${id}-to`,
|
|
7773
7267
|
className: "sr-only",
|
|
7774
7268
|
children: "to"
|
|
7775
7269
|
}),
|
|
7776
7270
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7777
7271
|
className: "relative",
|
|
7778
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
7272
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Input, {
|
|
7779
7273
|
id: `${id}-to`,
|
|
7780
7274
|
type: "number",
|
|
7781
7275
|
"aria-valuemin": min,
|
|
@@ -7795,12 +7289,12 @@ function DataTableSliderFilter({ column, title }) {
|
|
|
7795
7289
|
})
|
|
7796
7290
|
]
|
|
7797
7291
|
}),
|
|
7798
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
7292
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Label, {
|
|
7799
7293
|
htmlFor: `${id}-slider`,
|
|
7800
7294
|
className: "sr-only",
|
|
7801
7295
|
children: [title, " slider"]
|
|
7802
7296
|
}),
|
|
7803
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
7297
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Slider, {
|
|
7804
7298
|
id: `${id}-slider`,
|
|
7805
7299
|
min,
|
|
7806
7300
|
max,
|
|
@@ -7810,7 +7304,7 @@ function DataTableSliderFilter({ column, title }) {
|
|
|
7810
7304
|
onValueCommit: onSliderValueCommit
|
|
7811
7305
|
})
|
|
7812
7306
|
]
|
|
7813
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
7307
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
7814
7308
|
"aria-label": `Clear ${title} filter`,
|
|
7815
7309
|
variant: "outline",
|
|
7816
7310
|
size: "sm",
|
|
@@ -7835,7 +7329,7 @@ function DataTableToolbar({ table, children, className,...props }) {
|
|
|
7835
7329
|
...props,
|
|
7836
7330
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7837
7331
|
className: "flex flex-1 flex-wrap items-center gap-2",
|
|
7838
|
-
children: [columns.map((column) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DataTableToolbarFilter, { column }, column.id)), isFiltered && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
7332
|
+
children: [columns.map((column) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DataTableToolbarFilter, { column }, column.id)), isFiltered && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
7839
7333
|
"aria-label": "Reset filters",
|
|
7840
7334
|
variant: "outline",
|
|
7841
7335
|
size: "sm",
|
|
@@ -7860,7 +7354,7 @@ function DataTableToolbarFilter({ column }) {
|
|
|
7860
7354
|
const modes = columnMeta.modes;
|
|
7861
7355
|
if (modes && !modes.includes("advanced")) return null;
|
|
7862
7356
|
switch (columnMeta.variant) {
|
|
7863
|
-
case "text": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
7357
|
+
case "text": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Input, {
|
|
7864
7358
|
placeholder: columnMeta.placeholder ?? columnMeta.label,
|
|
7865
7359
|
value: column.getFilterValue() ?? "",
|
|
7866
7360
|
onChange: (event) => column.setFilterValue(event.target.value),
|
|
@@ -7868,7 +7362,7 @@ function DataTableToolbarFilter({ column }) {
|
|
|
7868
7362
|
});
|
|
7869
7363
|
case "number": return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7870
7364
|
className: "relative",
|
|
7871
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
7365
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Input, {
|
|
7872
7366
|
type: "number",
|
|
7873
7367
|
inputMode: "numeric",
|
|
7874
7368
|
placeholder: columnMeta.placeholder ?? columnMeta.label,
|
|
@@ -7969,8 +7463,8 @@ function readMetadataFields(fields) {
|
|
|
7969
7463
|
/**
|
|
7970
7464
|
* Modal 状态 Reducer
|
|
7971
7465
|
*/
|
|
7972
|
-
function modalReducer(state, action) {
|
|
7973
|
-
switch (action.type) {
|
|
7466
|
+
function modalReducer(state, action$1) {
|
|
7467
|
+
switch (action$1.type) {
|
|
7974
7468
|
case "OPEN_CREATE": return {
|
|
7975
7469
|
...state,
|
|
7976
7470
|
createOpen: true,
|
|
@@ -7981,22 +7475,22 @@ function modalReducer(state, action) {
|
|
|
7981
7475
|
...state,
|
|
7982
7476
|
createOpen: true,
|
|
7983
7477
|
selected: null,
|
|
7984
|
-
copySource: action.payload
|
|
7478
|
+
copySource: action$1.payload
|
|
7985
7479
|
};
|
|
7986
7480
|
case "OPEN_EDIT": return {
|
|
7987
7481
|
...state,
|
|
7988
7482
|
editOpen: true,
|
|
7989
|
-
selected: action.payload
|
|
7483
|
+
selected: action$1.payload
|
|
7990
7484
|
};
|
|
7991
7485
|
case "OPEN_DELETE": return {
|
|
7992
7486
|
...state,
|
|
7993
7487
|
deleteOpen: true,
|
|
7994
|
-
selected: action.payload
|
|
7488
|
+
selected: action$1.payload
|
|
7995
7489
|
};
|
|
7996
7490
|
case "OPEN_VIEW": return {
|
|
7997
7491
|
...state,
|
|
7998
7492
|
viewOpen: true,
|
|
7999
|
-
selected: action.payload
|
|
7493
|
+
selected: action$1.payload
|
|
8000
7494
|
};
|
|
8001
7495
|
case "CLOSE_ALL": return {
|
|
8002
7496
|
...state,
|
|
@@ -8009,7 +7503,7 @@ function modalReducer(state, action) {
|
|
|
8009
7503
|
};
|
|
8010
7504
|
case "SET_VARIANT": return {
|
|
8011
7505
|
...state,
|
|
8012
|
-
variant: action.payload
|
|
7506
|
+
variant: action$1.payload
|
|
8013
7507
|
};
|
|
8014
7508
|
default: return state;
|
|
8015
7509
|
}
|
|
@@ -8662,7 +8156,12 @@ exports.DataTableToolbar = DataTableToolbar;
|
|
|
8662
8156
|
exports.DataTableViewOptions = DataTableViewOptions;
|
|
8663
8157
|
exports.ExportDialog = ExportDialog;
|
|
8664
8158
|
exports.ImportDialog = ImportDialog;
|
|
8665
|
-
exports
|
|
8159
|
+
Object.defineProperty(exports, 'MultiCombobox', {
|
|
8160
|
+
enumerable: true,
|
|
8161
|
+
get: function () {
|
|
8162
|
+
return __wordrhyme_shadcn_ui.MultiCombobox;
|
|
8163
|
+
}
|
|
8164
|
+
});
|
|
8666
8165
|
exports.SchemaAdapter = SchemaAdapter;
|
|
8667
8166
|
exports.cn = cn;
|
|
8668
8167
|
exports.coerceRowValues = coerceRowValues;
|