@wordrhyme/auto-crud 1.3.0 → 1.3.2
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 +1225 -1675
- package/dist/index.d.cts +70 -50
- package/dist/index.d.ts +86 -66
- package/dist/index.js +959 -1414
- 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,27 @@ function AutoTableSimpleFilters({ table, shallow = false, filters: externalFilte
|
|
|
3161
2543
|
]
|
|
3162
2544
|
});
|
|
3163
2545
|
}
|
|
3164
|
-
function SimpleFacetedFilter({ title, options, multiple, value, onChange }) {
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
2546
|
+
function SimpleFacetedFilter({ title, options, multiple, value, hasMore, loading, searchValue, shouldFilter, onChange, onPopupScroll, onSearch }) {
|
|
2547
|
+
const onSelectChange = (nextValue) => {
|
|
2548
|
+
onChange(Array.isArray(nextValue) ? nextValue : nextValue ? [nextValue] : []);
|
|
2549
|
+
};
|
|
2550
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn_ui.Select, {
|
|
2551
|
+
mode: "searchable",
|
|
2552
|
+
multiple: Boolean(multiple),
|
|
2553
|
+
value: multiple ? value : value[0] ?? "",
|
|
2554
|
+
onChange: onSelectChange,
|
|
3168
2555
|
options,
|
|
3169
|
-
selectionMode: multiple ? "multiple" : "single",
|
|
3170
2556
|
searchPlaceholder: title,
|
|
2557
|
+
hasMore,
|
|
2558
|
+
loading,
|
|
2559
|
+
searchValue,
|
|
2560
|
+
shouldFilter,
|
|
2561
|
+
onPopupScroll,
|
|
2562
|
+
onSearch,
|
|
3171
2563
|
contentClassName: "w-50",
|
|
3172
2564
|
matchTriggerWidth: false,
|
|
3173
2565
|
clearText: "Clear filters",
|
|
3174
|
-
renderTrigger: ({ selectedOptions, selectedValues, clearSelection }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2566
|
+
renderTrigger: ({ selectedOptions, selectedValues, clearSelection }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
3175
2567
|
variant: "outline",
|
|
3176
2568
|
size: "sm",
|
|
3177
2569
|
className: "border-dashed font-normal",
|
|
@@ -3191,22 +2583,22 @@ function SimpleFacetedFilter({ title, options, multiple, value, onChange }) {
|
|
|
3191
2583
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.PlusCircle, {}),
|
|
3192
2584
|
title,
|
|
3193
2585
|
selectedValues.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
3194
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2586
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Separator, {
|
|
3195
2587
|
orientation: "vertical",
|
|
3196
2588
|
className: "mx-0.5 h-4"
|
|
3197
2589
|
}),
|
|
3198
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2590
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Badge, {
|
|
3199
2591
|
variant: "secondary",
|
|
3200
2592
|
className: "rounded-sm px-1 font-normal lg:hidden",
|
|
3201
2593
|
children: selectedValues.length
|
|
3202
2594
|
}),
|
|
3203
2595
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3204
2596
|
className: "hidden items-center gap-1 lg:flex",
|
|
3205
|
-
children: selectedValues.length > 2 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2597
|
+
children: selectedValues.length > 2 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Badge, {
|
|
3206
2598
|
variant: "secondary",
|
|
3207
2599
|
className: "rounded-sm px-1 font-normal",
|
|
3208
2600
|
children: [selectedValues.length, " selected"]
|
|
3209
|
-
}) : selectedOptions.map((option) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2601
|
+
}) : selectedOptions.map((option) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Badge, {
|
|
3210
2602
|
variant: "secondary",
|
|
3211
2603
|
className: "rounded-sm px-1 font-normal",
|
|
3212
2604
|
children: option.label
|
|
@@ -3243,9 +2635,9 @@ function SimpleSliderFilter({ title, range, unit, value, onChange }) {
|
|
|
3243
2635
|
setLocalRange(nextRange);
|
|
3244
2636
|
onChange(nextRange);
|
|
3245
2637
|
};
|
|
3246
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2638
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Popover, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.PopoverTrigger, {
|
|
3247
2639
|
asChild: true,
|
|
3248
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2640
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
3249
2641
|
variant: "outline",
|
|
3250
2642
|
size: "sm",
|
|
3251
2643
|
className: "border-dashed font-normal",
|
|
@@ -3265,7 +2657,7 @@ function SimpleSliderFilter({ title, range, unit, value, onChange }) {
|
|
|
3265
2657
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.PlusCircle, {}),
|
|
3266
2658
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: title }),
|
|
3267
2659
|
value && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
3268
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2660
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Separator, {
|
|
3269
2661
|
orientation: "vertical",
|
|
3270
2662
|
className: "mx-0.5 h-4"
|
|
3271
2663
|
}),
|
|
@@ -3276,7 +2668,7 @@ function SimpleSliderFilter({ title, range, unit, value, onChange }) {
|
|
|
3276
2668
|
] })
|
|
3277
2669
|
]
|
|
3278
2670
|
})
|
|
3279
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2671
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.PopoverContent, {
|
|
3280
2672
|
align: "start",
|
|
3281
2673
|
className: "flex w-auto flex-col gap-4",
|
|
3282
2674
|
children: [
|
|
@@ -3287,14 +2679,14 @@ function SimpleSliderFilter({ title, range, unit, value, onChange }) {
|
|
|
3287
2679
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3288
2680
|
className: "flex items-center gap-4",
|
|
3289
2681
|
children: [
|
|
3290
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2682
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Label, {
|
|
3291
2683
|
htmlFor: `${id}-from`,
|
|
3292
2684
|
className: "sr-only",
|
|
3293
2685
|
children: "From"
|
|
3294
2686
|
}),
|
|
3295
2687
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3296
2688
|
className: "relative",
|
|
3297
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2689
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Input, {
|
|
3298
2690
|
id: `${id}-from`,
|
|
3299
2691
|
type: "number",
|
|
3300
2692
|
min,
|
|
@@ -3307,14 +2699,14 @@ function SimpleSliderFilter({ title, range, unit, value, onChange }) {
|
|
|
3307
2699
|
children: unit
|
|
3308
2700
|
})]
|
|
3309
2701
|
}),
|
|
3310
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2702
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Label, {
|
|
3311
2703
|
htmlFor: `${id}-to`,
|
|
3312
2704
|
className: "sr-only",
|
|
3313
2705
|
children: "To"
|
|
3314
2706
|
}),
|
|
3315
2707
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3316
2708
|
className: "relative",
|
|
3317
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2709
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Input, {
|
|
3318
2710
|
id: `${id}-to`,
|
|
3319
2711
|
type: "number",
|
|
3320
2712
|
min,
|
|
@@ -3329,14 +2721,14 @@ function SimpleSliderFilter({ title, range, unit, value, onChange }) {
|
|
|
3329
2721
|
})
|
|
3330
2722
|
]
|
|
3331
2723
|
}),
|
|
3332
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2724
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Slider, {
|
|
3333
2725
|
min,
|
|
3334
2726
|
max,
|
|
3335
2727
|
value: localRange,
|
|
3336
2728
|
onValueChange: (v) => setLocalRange(v),
|
|
3337
2729
|
onValueCommit: (v) => onChange(v)
|
|
3338
2730
|
}),
|
|
3339
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2731
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
3340
2732
|
variant: "outline",
|
|
3341
2733
|
size: "sm",
|
|
3342
2734
|
onClick: onReset,
|
|
@@ -3372,9 +2764,9 @@ function SimpleDateFilter({ title, multiple, value, onChange }) {
|
|
|
3372
2764
|
onChange(void 0);
|
|
3373
2765
|
};
|
|
3374
2766
|
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)(
|
|
2767
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Popover, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.PopoverTrigger, {
|
|
3376
2768
|
asChild: true,
|
|
3377
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2769
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
3378
2770
|
variant: "outline",
|
|
3379
2771
|
size: "sm",
|
|
3380
2772
|
className: "border-dashed font-normal",
|
|
@@ -3393,16 +2785,16 @@ function SimpleDateFilter({ title, multiple, value, onChange }) {
|
|
|
3393
2785
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.XCircle, {})
|
|
3394
2786
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.CalendarIcon, {}),
|
|
3395
2787
|
/* @__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)(
|
|
2788
|
+
label && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Separator, {
|
|
3397
2789
|
orientation: "vertical",
|
|
3398
2790
|
className: "mx-0.5 h-4"
|
|
3399
2791
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: label })] })
|
|
3400
2792
|
]
|
|
3401
2793
|
})
|
|
3402
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2794
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.PopoverContent, {
|
|
3403
2795
|
className: "w-auto p-0",
|
|
3404
2796
|
align: "start",
|
|
3405
|
-
children: multiple ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2797
|
+
children: multiple ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Calendar, {
|
|
3406
2798
|
autoFocus: true,
|
|
3407
2799
|
captionLayout: "dropdown",
|
|
3408
2800
|
mode: "range",
|
|
@@ -3456,7 +2848,7 @@ function SimpleDateFilter({ title, multiple, value, onChange }) {
|
|
|
3456
2848
|
return;
|
|
3457
2849
|
}
|
|
3458
2850
|
}
|
|
3459
|
-
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2851
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Calendar, {
|
|
3460
2852
|
captionLayout: "dropdown",
|
|
3461
2853
|
mode: "single",
|
|
3462
2854
|
selected: fromDate,
|
|
@@ -3465,386 +2857,6 @@ function SimpleDateFilter({ title, multiple, value, onChange }) {
|
|
|
3465
2857
|
})] });
|
|
3466
2858
|
}
|
|
3467
2859
|
|
|
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
2860
|
//#endregion
|
|
3849
2861
|
//#region src/components/data-table/data-table-column-header.tsx
|
|
3850
2862
|
function DataTableColumnHeader({ column, label, className,...props }) {
|
|
@@ -3852,32 +2864,32 @@ function DataTableColumnHeader({ column, label, className,...props }) {
|
|
|
3852
2864
|
className: cn(className),
|
|
3853
2865
|
children: label
|
|
3854
2866
|
});
|
|
3855
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2867
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.DropdownMenu, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.DropdownMenuTrigger, {
|
|
3856
2868
|
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
2869
|
...props,
|
|
3858
2870
|
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)(
|
|
2871
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.DropdownMenuContent, {
|
|
3860
2872
|
align: "start",
|
|
3861
2873
|
className: "w-28",
|
|
3862
2874
|
children: [column.getCanSort() && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
3863
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2875
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.DropdownMenuCheckboxItem, {
|
|
3864
2876
|
className: "relative pr-8 pl-2 [&>span:first-child]:right-2 [&>span:first-child]:left-auto [&_svg]:text-muted-foreground",
|
|
3865
2877
|
checked: column.getIsSorted() === "asc",
|
|
3866
2878
|
onClick: () => column.toggleSorting(false),
|
|
3867
2879
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronUp, {}), "Asc"]
|
|
3868
2880
|
}),
|
|
3869
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2881
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.DropdownMenuCheckboxItem, {
|
|
3870
2882
|
className: "relative pr-8 pl-2 [&>span:first-child]:right-2 [&>span:first-child]:left-auto [&_svg]:text-muted-foreground",
|
|
3871
2883
|
checked: column.getIsSorted() === "desc",
|
|
3872
2884
|
onClick: () => column.toggleSorting(true),
|
|
3873
2885
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronDown, {}), "Desc"]
|
|
3874
2886
|
}),
|
|
3875
|
-
column.getIsSorted() && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2887
|
+
column.getIsSorted() && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.DropdownMenuItem, {
|
|
3876
2888
|
className: "pl-2 [&_svg]:text-muted-foreground",
|
|
3877
2889
|
onClick: () => column.clearSorting(),
|
|
3878
2890
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.X, {}), "Reset"]
|
|
3879
2891
|
})
|
|
3880
|
-
] }), column.getCanHide() && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
2892
|
+
] }), column.getCanHide() && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.DropdownMenuCheckboxItem, {
|
|
3881
2893
|
className: "relative pr-8 pl-2 [&>span:first-child]:right-2 [&>span:first-child]:left-auto [&_svg]:text-muted-foreground",
|
|
3882
2894
|
checked: !column.getIsVisible(),
|
|
3883
2895
|
onClick: () => column.toggleVisibility(false),
|
|
@@ -4137,15 +3149,15 @@ function renderCell(value, type, options) {
|
|
|
4137
3149
|
if (options && options.length > 0) {
|
|
4138
3150
|
if (Array.isArray(value)) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4139
3151
|
className: "flex gap-1 flex-wrap",
|
|
4140
|
-
children: [value.slice(0, 3).map((v, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
3152
|
+
children: [value.slice(0, 3).map((v, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Badge, {
|
|
4141
3153
|
variant: "secondary",
|
|
4142
3154
|
children: formatOptionValue(v)
|
|
4143
|
-
}, i)), value.length > 3 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
3155
|
+
}, i)), value.length > 3 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Badge, {
|
|
4144
3156
|
variant: "outline",
|
|
4145
3157
|
children: ["+", value.length - 3]
|
|
4146
3158
|
})]
|
|
4147
3159
|
});
|
|
4148
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
3160
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Badge, {
|
|
4149
3161
|
variant: "outline",
|
|
4150
3162
|
className: "capitalize",
|
|
4151
3163
|
children: formatOptionValue(value)
|
|
@@ -4154,17 +3166,17 @@ function renderCell(value, type, options) {
|
|
|
4154
3166
|
switch (type) {
|
|
4155
3167
|
case "boolean": return value ? "✓" : "✗";
|
|
4156
3168
|
case "date": return formatDate(value);
|
|
4157
|
-
case "enum": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
3169
|
+
case "enum": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Badge, {
|
|
4158
3170
|
variant: "outline",
|
|
4159
3171
|
className: "capitalize",
|
|
4160
3172
|
children: String(value)
|
|
4161
3173
|
});
|
|
4162
3174
|
case "array": return Array.isArray(value) ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4163
3175
|
className: "flex gap-1 flex-wrap",
|
|
4164
|
-
children: [value.slice(0, 3).map((v, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
3176
|
+
children: [value.slice(0, 3).map((v, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Badge, {
|
|
4165
3177
|
variant: "secondary",
|
|
4166
3178
|
children: String(v)
|
|
4167
|
-
}, i)), value.length > 3 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
3179
|
+
}, i)), value.length > 3 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Badge, {
|
|
4168
3180
|
variant: "outline",
|
|
4169
3181
|
children: ["+", value.length - 3]
|
|
4170
3182
|
})]
|
|
@@ -4245,13 +3257,13 @@ function createTableSchema(schema, options) {
|
|
|
4245
3257
|
function createSelectColumn() {
|
|
4246
3258
|
return {
|
|
4247
3259
|
id: "select",
|
|
4248
|
-
header: ({ table }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
3260
|
+
header: ({ table }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Checkbox, {
|
|
4249
3261
|
"aria-label": "Select all",
|
|
4250
3262
|
className: "translate-y-0.5",
|
|
4251
3263
|
checked: table.getIsAllPageRowsSelected() || table.getIsSomePageRowsSelected() && "indeterminate",
|
|
4252
3264
|
onCheckedChange: (value) => table.toggleAllPageRowsSelected(!!value)
|
|
4253
3265
|
}),
|
|
4254
|
-
cell: ({ row }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
3266
|
+
cell: ({ row }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Checkbox, {
|
|
4255
3267
|
"aria-label": "Select row",
|
|
4256
3268
|
className: "translate-y-0.5",
|
|
4257
3269
|
checked: row.getIsSelected(),
|
|
@@ -4272,18 +3284,18 @@ function createActionsColumn(items) {
|
|
|
4272
3284
|
};
|
|
4273
3285
|
return {
|
|
4274
3286
|
id: "actions",
|
|
4275
|
-
cell: ({ row }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
3287
|
+
cell: ({ row }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.DropdownMenu, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.DropdownMenuTrigger, {
|
|
4276
3288
|
asChild: true,
|
|
4277
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
3289
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
4278
3290
|
"aria-label": "Open menu",
|
|
4279
3291
|
variant: "ghost",
|
|
4280
3292
|
className: "flex size-8 p-0 data-[state=open]:bg-muted",
|
|
4281
3293
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Ellipsis, { className: "size-4" })
|
|
4282
3294
|
})
|
|
4283
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
3295
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.DropdownMenuContent, {
|
|
4284
3296
|
align: "end",
|
|
4285
3297
|
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)(
|
|
3298
|
+
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
3299
|
className: item.variant === "destructive" ? "text-destructive" : "",
|
|
4288
3300
|
onClick: () => item.onClick?.(row.original),
|
|
4289
3301
|
children: item.label
|
|
@@ -4505,12 +3517,22 @@ function downloadCSV(csvContent, filename) {
|
|
|
4505
3517
|
|
|
4506
3518
|
//#endregion
|
|
4507
3519
|
//#region src/components/auto-crud/auto-table-action-bar.tsx
|
|
4508
|
-
|
|
4509
|
-
|
|
3520
|
+
const DEFAULT_DELETE_CONFIRMATION = {
|
|
3521
|
+
title: "确认批量删除",
|
|
3522
|
+
description: (count) => `此操作无法撤销。确定要删除选中的 ${count} 条记录吗?`,
|
|
3523
|
+
cancel: "取消",
|
|
3524
|
+
confirm: "确认删除"
|
|
3525
|
+
};
|
|
3526
|
+
function isBatchCustomAction(action$1) {
|
|
3527
|
+
return action$1.type === "custom";
|
|
4510
3528
|
}
|
|
4511
|
-
function AutoTableActionBar({ table, onDeleteSelected, onUpdateSelected, batchUpdateFields, enableExport = true, showDefaultExport = true, enableDelete = true, extraActions, actions }) {
|
|
3529
|
+
function AutoTableActionBar({ table, onDeleteSelected, onUpdateSelected, batchUpdateFields, enableExport = true, showDefaultExport = true, enableDelete = true, extraActions, actions, deleteConfirmation = DEFAULT_DELETE_CONFIRMATION }) {
|
|
4512
3530
|
const rows = table.getFilteredSelectedRowModel().rows;
|
|
4513
3531
|
const selectedRows = react.useMemo(() => rows.map((row) => row.original), [rows]);
|
|
3532
|
+
const [deleteDialogOpen, setDeleteDialogOpen] = react.useState(false);
|
|
3533
|
+
react.useEffect(() => {
|
|
3534
|
+
if (selectedRows.length === 0) setDeleteDialogOpen(false);
|
|
3535
|
+
}, [selectedRows.length]);
|
|
4514
3536
|
const clearSelection = react.useCallback(() => {
|
|
4515
3537
|
table.toggleAllRowsSelected(false);
|
|
4516
3538
|
}, [table]);
|
|
@@ -4533,8 +3555,34 @@ function AutoTableActionBar({ table, onDeleteSelected, onUpdateSelected, batchUp
|
|
|
4533
3555
|
});
|
|
4534
3556
|
}, [table]);
|
|
4535
3557
|
const onDelete = react.useCallback(() => {
|
|
4536
|
-
if (onDeleteSelected
|
|
4537
|
-
|
|
3558
|
+
if (onDeleteSelected && selectedRows.length > 0) {
|
|
3559
|
+
onDeleteSelected(selectedRows);
|
|
3560
|
+
clearSelection();
|
|
3561
|
+
}
|
|
3562
|
+
setDeleteDialogOpen(false);
|
|
3563
|
+
}, [
|
|
3564
|
+
selectedRows,
|
|
3565
|
+
onDeleteSelected,
|
|
3566
|
+
clearSelection
|
|
3567
|
+
]);
|
|
3568
|
+
const runDeleteAction = react.useCallback((action$1, event) => {
|
|
3569
|
+
if (selectedRows.length === 0) {
|
|
3570
|
+
setDeleteDialogOpen(false);
|
|
3571
|
+
return;
|
|
3572
|
+
}
|
|
3573
|
+
if (action$1.onClick) {
|
|
3574
|
+
action$1.onClick(selectedRows, actionContext, event);
|
|
3575
|
+
clearSelection();
|
|
3576
|
+
setDeleteDialogOpen(false);
|
|
3577
|
+
return;
|
|
3578
|
+
}
|
|
3579
|
+
onDelete();
|
|
3580
|
+
}, [
|
|
3581
|
+
actionContext,
|
|
3582
|
+
clearSelection,
|
|
3583
|
+
onDelete,
|
|
3584
|
+
selectedRows
|
|
3585
|
+
]);
|
|
4538
3586
|
const handleBatchUpdate = react.useCallback((field, value) => {
|
|
4539
3587
|
if (onUpdateSelected) {
|
|
4540
3588
|
onUpdateSelected(selectedRows, { [field]: value });
|
|
@@ -4546,33 +3594,43 @@ function AutoTableActionBar({ table, onDeleteSelected, onUpdateSelected, batchUp
|
|
|
4546
3594
|
clearSelection
|
|
4547
3595
|
]);
|
|
4548
3596
|
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)(
|
|
3597
|
+
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
3598
|
asChild: true,
|
|
4551
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
3599
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
4552
3600
|
variant: "ghost",
|
|
4553
3601
|
size: "sm",
|
|
4554
3602
|
className: "h-7 gap-1 px-2",
|
|
4555
3603
|
children: [fieldConfig.label, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronDown, { className: "size-3.5" })]
|
|
4556
3604
|
})
|
|
4557
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
3605
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.DropdownMenuContent, {
|
|
4558
3606
|
align: "start",
|
|
4559
|
-
children: fieldConfig.options.map((option) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
3607
|
+
children: fieldConfig.options.map((option) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.DropdownMenuItem, {
|
|
4560
3608
|
onClick: () => handleBatchUpdate(fieldConfig.field, option.value),
|
|
4561
3609
|
children: option.label
|
|
4562
3610
|
}, option.value))
|
|
4563
3611
|
})] }, `${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"]
|
|
3612
|
+
const renderBuiltinAction = react.useCallback((action$1) => {
|
|
3613
|
+
if (!(action$1.type === "batchUpdate" ? !!onUpdateSelected && !!batchUpdateFields?.length : action$1.type === "export" ? enableExport : enableDelete && !!onDeleteSelected)) return null;
|
|
3614
|
+
if (action$1.component) return renderComponent(action$1.component);
|
|
3615
|
+
if (action$1.type === "batchUpdate") return renderBatchUpdate(action$1.type);
|
|
3616
|
+
if (action$1.type === "export") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn_ui.ActionBarItem, {
|
|
3617
|
+
onClick: (event) => action$1.onClick ? action$1.onClick(selectedRows, actionContext, event) : onExport(),
|
|
3618
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Download, {}), action$1.label ?? "Export"]
|
|
4571
3619
|
}, "export");
|
|
4572
|
-
if (action.type === "delete") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.
|
|
3620
|
+
if (action$1.type === "delete") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.AlertDialog, {
|
|
3621
|
+
open: deleteDialogOpen,
|
|
3622
|
+
onOpenChange: setDeleteDialogOpen,
|
|
3623
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn_ui.ActionBarItem, {
|
|
3624
|
+
variant: "destructive",
|
|
3625
|
+
onClick: () => setDeleteDialogOpen(true),
|
|
3626
|
+
onSelect: (event) => event.preventDefault(),
|
|
3627
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Trash2, {}), action$1.label ?? "Delete"]
|
|
3628
|
+
}), /* @__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, {
|
|
3629
|
+
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",
|
|
3630
|
+
disabled: selectedRows.length === 0,
|
|
3631
|
+
onClick: (event) => runDeleteAction(action$1, event),
|
|
3632
|
+
children: deleteConfirmation.confirm
|
|
3633
|
+
})] })] })]
|
|
4576
3634
|
}, "delete");
|
|
4577
3635
|
return null;
|
|
4578
3636
|
}, [
|
|
@@ -4580,21 +3638,24 @@ function AutoTableActionBar({ table, onDeleteSelected, onUpdateSelected, batchUp
|
|
|
4580
3638
|
batchUpdateFields?.length,
|
|
4581
3639
|
enableDelete,
|
|
4582
3640
|
enableExport,
|
|
3641
|
+
deleteConfirmation,
|
|
3642
|
+
deleteDialogOpen,
|
|
4583
3643
|
onDelete,
|
|
4584
3644
|
onDeleteSelected,
|
|
4585
3645
|
onUpdateSelected,
|
|
4586
3646
|
onExport,
|
|
4587
3647
|
renderBatchUpdate,
|
|
4588
3648
|
renderComponent,
|
|
3649
|
+
runDeleteAction,
|
|
4589
3650
|
selectedRows
|
|
4590
3651
|
]);
|
|
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
|
|
3652
|
+
const renderCustomAction = react.useCallback((action$1, index$1) => {
|
|
3653
|
+
if (action$1.component) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children: renderComponent(action$1.component) }, `custom-${index$1}`);
|
|
3654
|
+
if (!action$1.label || !action$1.onClick) return null;
|
|
3655
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn_ui.ActionBarItem, {
|
|
3656
|
+
variant: action$1.variant === "destructive" ? "destructive" : "secondary",
|
|
3657
|
+
onClick: (event) => action$1.onClick?.(selectedRows, actionContext, event),
|
|
3658
|
+
children: action$1.label
|
|
4598
3659
|
}, `custom-${index$1}`);
|
|
4599
3660
|
}, [
|
|
4600
3661
|
actionContext,
|
|
@@ -4607,7 +3668,7 @@ function AutoTableActionBar({ table, onDeleteSelected, onUpdateSelected, batchUp
|
|
|
4607
3668
|
{ type: "export" },
|
|
4608
3669
|
{ type: "delete" }
|
|
4609
3670
|
]) : actions;
|
|
4610
|
-
const resolvedActions = configuredActions?.filter((action) => !action.hidden);
|
|
3671
|
+
const resolvedActions = configuredActions?.filter((action$1) => !action$1.hidden);
|
|
4611
3672
|
if (configuredActions === void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
4612
3673
|
renderBuiltinAction({ type: "batchUpdate" }),
|
|
4613
3674
|
extraActions,
|
|
@@ -4615,9 +3676,9 @@ function AutoTableActionBar({ table, onDeleteSelected, onUpdateSelected, batchUp
|
|
|
4615
3676
|
renderBuiltinAction({ type: "delete" })
|
|
4616
3677
|
] });
|
|
4617
3678
|
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));
|
|
3679
|
+
if (!resolvedActions.some((action$1) => action$1.type !== "custom")) {
|
|
3680
|
+
const startNodes = resolvedActions.filter(isBatchCustomAction).filter((action$1) => action$1.position === "start").map((action$1, index$1) => renderCustomAction(action$1, index$1));
|
|
3681
|
+
const endNodes = resolvedActions.filter(isBatchCustomAction).filter((action$1) => action$1.position !== "start").map((action$1, index$1) => renderCustomAction(action$1, index$1));
|
|
4621
3682
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
4622
3683
|
startNodes,
|
|
4623
3684
|
renderBuiltinAction({ type: "batchUpdate" }),
|
|
@@ -4627,9 +3688,9 @@ function AutoTableActionBar({ table, onDeleteSelected, onUpdateSelected, batchUp
|
|
|
4627
3688
|
endNodes
|
|
4628
3689
|
] });
|
|
4629
3690
|
}
|
|
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);
|
|
3691
|
+
return resolvedActions.map((action$1, index$1) => {
|
|
3692
|
+
if (action$1.type === "custom") return renderCustomAction(action$1, index$1);
|
|
3693
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children: renderBuiltinAction(action$1) }, action$1.type);
|
|
4633
3694
|
});
|
|
4634
3695
|
}, [
|
|
4635
3696
|
actions,
|
|
@@ -4638,21 +3699,21 @@ function AutoTableActionBar({ table, onDeleteSelected, onUpdateSelected, batchUp
|
|
|
4638
3699
|
renderCustomAction,
|
|
4639
3700
|
showDefaultExport
|
|
4640
3701
|
]);
|
|
4641
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(ActionBar, {
|
|
3702
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn_ui.ActionBar, {
|
|
4642
3703
|
open: rows.length > 0,
|
|
4643
3704
|
onOpenChange,
|
|
4644
3705
|
children: [
|
|
4645
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(ActionBarSelection, { children: [
|
|
3706
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn_ui.ActionBarSelection, { children: [
|
|
4646
3707
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4647
3708
|
className: "font-medium",
|
|
4648
3709
|
children: rows.length
|
|
4649
3710
|
}),
|
|
4650
3711
|
/* @__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, {}) })
|
|
3712
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn_ui.ActionBarSeparator, {}),
|
|
3713
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn_ui.ActionBarClose, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.X, {}) })
|
|
4653
3714
|
] }),
|
|
4654
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ActionBarSeparator, {}),
|
|
4655
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ActionBarGroup, { children: renderedActions })
|
|
3715
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn_ui.ActionBarSeparator, {}),
|
|
3716
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn_ui.ActionBarGroup, { children: renderedActions })
|
|
4656
3717
|
]
|
|
4657
3718
|
});
|
|
4658
3719
|
}
|
|
@@ -4913,7 +3974,7 @@ const filterModeConfig = {
|
|
|
4913
3974
|
tooltip: "Linear-style command filters"
|
|
4914
3975
|
}
|
|
4915
3976
|
};
|
|
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 }) {
|
|
3977
|
+
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
3978
|
const modes = filterMode ? Array.isArray(filterMode) ? filterMode : [filterMode] : DEFAULT_MODES;
|
|
4918
3979
|
const [currentMode, setCurrentMode] = useQueryState("filterMode", parseAsStringEnum(modes).withDefault(modes[0] ?? "simple"));
|
|
4919
3980
|
const showToggle = modes.length > 1;
|
|
@@ -4984,9 +4045,9 @@ function AutoTable({ schema, data, pageCount = 1, overrides, enableRowSelection
|
|
|
4984
4045
|
(0, react.useEffect)(() => {
|
|
4985
4046
|
onSelectedRowsChange?.(selectedRows);
|
|
4986
4047
|
}, [selectedRows, onSelectedRowsChange]);
|
|
4987
|
-
const FilterModeSelect = showToggle ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
4048
|
+
const FilterModeSelect = showToggle ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.DropdownMenu, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.DropdownMenuTrigger, {
|
|
4988
4049
|
asChild: true,
|
|
4989
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
4050
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
4990
4051
|
variant: "outline",
|
|
4991
4052
|
size: "sm",
|
|
4992
4053
|
className: "h-8 w-8 p-0",
|
|
@@ -4996,21 +4057,21 @@ function AutoTable({ schema, data, pageCount = 1, overrides, enableRowSelection
|
|
|
4996
4057
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, { className: "size-4 text-muted-foreground" });
|
|
4997
4058
|
})()
|
|
4998
4059
|
})
|
|
4999
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
4060
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.DropdownMenuContent, {
|
|
5000
4061
|
align: "end",
|
|
5001
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
4062
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.DropdownMenuRadioGroup, {
|
|
5002
4063
|
value: currentMode,
|
|
5003
4064
|
onValueChange: (v) => setCurrentMode(v),
|
|
5004
4065
|
children: modes.map((mode) => {
|
|
5005
4066
|
const config = filterModeConfig[mode];
|
|
5006
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
4067
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.DropdownMenuRadioItem, {
|
|
5007
4068
|
value: mode,
|
|
5008
4069
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(config.icon, { className: "size-4" }), config.label]
|
|
5009
4070
|
}, mode);
|
|
5010
4071
|
})
|
|
5011
4072
|
})
|
|
5012
4073
|
})] }) : null;
|
|
5013
|
-
const searchInput = search ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
4074
|
+
const searchInput = search ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Input, {
|
|
5014
4075
|
value: searchValue,
|
|
5015
4076
|
onChange: (event) => {
|
|
5016
4077
|
setSearchValue(event.target.value);
|
|
@@ -5090,7 +4151,8 @@ function AutoTable({ schema, data, pageCount = 1, overrides, enableRowSelection
|
|
|
5090
4151
|
enableExport,
|
|
5091
4152
|
showDefaultExport,
|
|
5092
4153
|
extraActions: actionBarExtra,
|
|
5093
|
-
actions: actionBarActions
|
|
4154
|
+
actions: actionBarActions,
|
|
4155
|
+
deleteConfirmation
|
|
5094
4156
|
})
|
|
5095
4157
|
]
|
|
5096
4158
|
});
|
|
@@ -5099,16 +4161,16 @@ function AutoTable({ schema, data, pageCount = 1, overrides, enableRowSelection
|
|
|
5099
4161
|
//#endregion
|
|
5100
4162
|
//#region src/components/auto-crud/form-modal.tsx
|
|
5101
4163
|
function FormModal({ open, onOpenChange, title, description, children, variant = "dialog", side = "right", className, footer }) {
|
|
5102
|
-
if (variant === "sheet") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
4164
|
+
if (variant === "sheet") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Sheet, {
|
|
5103
4165
|
open,
|
|
5104
4166
|
onOpenChange,
|
|
5105
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
4167
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.SheetContent, {
|
|
5106
4168
|
side,
|
|
5107
4169
|
className: cn("sm:max-w-lg flex flex-col p-0", className),
|
|
5108
4170
|
children: [
|
|
5109
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
4171
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.SheetHeader, {
|
|
5110
4172
|
className: "flex-shrink-0 px-6 pt-6",
|
|
5111
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
4173
|
+
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
4174
|
}),
|
|
5113
4175
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5114
4176
|
className: "flex-1 overflow-y-auto min-h-0",
|
|
@@ -5124,15 +4186,15 @@ function FormModal({ open, onOpenChange, title, description, children, variant =
|
|
|
5124
4186
|
]
|
|
5125
4187
|
})
|
|
5126
4188
|
});
|
|
5127
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
4189
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Dialog, {
|
|
5128
4190
|
open,
|
|
5129
4191
|
onOpenChange,
|
|
5130
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
4192
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.DialogContent, {
|
|
5131
4193
|
className: cn("max-w-2xl sm:max-w-2xl flex flex-col max-h-[85vh] overflow-hidden p-0", className),
|
|
5132
4194
|
children: [
|
|
5133
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
4195
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.DialogHeader, {
|
|
5134
4196
|
className: "flex-shrink-0 px-6 pt-6",
|
|
5135
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
4197
|
+
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
4198
|
}),
|
|
5137
4199
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5138
4200
|
className: "flex-1 overflow-y-auto min-h-0",
|
|
@@ -5292,11 +4354,19 @@ function normalizeDataSourceRegistration(registration) {
|
|
|
5292
4354
|
if (typeof registration === "function") return {
|
|
5293
4355
|
dependencies: [],
|
|
5294
4356
|
reset: false,
|
|
4357
|
+
search: false,
|
|
4358
|
+
debounceMs: 300,
|
|
4359
|
+
loadMore: false,
|
|
4360
|
+
pageSize: 20,
|
|
5295
4361
|
load: registration
|
|
5296
4362
|
};
|
|
5297
4363
|
return {
|
|
5298
4364
|
dependencies: Array.isArray(registration.dependencies) ? registration.dependencies : [],
|
|
5299
4365
|
reset: registration.reset === true,
|
|
4366
|
+
search: registration.search === true,
|
|
4367
|
+
debounceMs: typeof registration.debounceMs === "number" && registration.debounceMs >= 0 ? registration.debounceMs : 300,
|
|
4368
|
+
loadMore: registration.loadMore === true,
|
|
4369
|
+
pageSize: typeof registration.pageSize === "number" && registration.pageSize > 0 ? registration.pageSize : 20,
|
|
5300
4370
|
load: registration.load
|
|
5301
4371
|
};
|
|
5302
4372
|
}
|
|
@@ -5323,38 +4393,93 @@ function normalizeOptions(result) {
|
|
|
5323
4393
|
value: String(option.value)
|
|
5324
4394
|
}));
|
|
5325
4395
|
}
|
|
4396
|
+
function normalizeHasMore(result) {
|
|
4397
|
+
return !Array.isArray(result) && result?.hasMore === true;
|
|
4398
|
+
}
|
|
4399
|
+
|
|
4400
|
+
//#endregion
|
|
4401
|
+
//#region src/lib/field-config.ts
|
|
4402
|
+
function normalizeFieldOptions$1(options) {
|
|
4403
|
+
if (!options || options.length === 0) return void 0;
|
|
4404
|
+
return options.map((option) => ({
|
|
4405
|
+
...option,
|
|
4406
|
+
value: String(option.value)
|
|
4407
|
+
}));
|
|
4408
|
+
}
|
|
4409
|
+
/**
|
|
4410
|
+
* 从统一字段配置生成 Formily overrides。
|
|
4411
|
+
* `legacyOverrides` 保持兼容旧 API,字段级 `form` 配置优先级最高。
|
|
4412
|
+
*/
|
|
4413
|
+
function buildFormOverrides(fields, legacyOverrides, denyFields) {
|
|
4414
|
+
const result = { ...legacyOverrides };
|
|
4415
|
+
if (denyFields) for (const field of denyFields) result[field] = {
|
|
4416
|
+
...result[field],
|
|
4417
|
+
"x-hidden": true
|
|
4418
|
+
};
|
|
4419
|
+
if (fields) for (const [key, config] of Object.entries(fields)) {
|
|
4420
|
+
const fieldOptions = normalizeFieldOptions$1((config.form && typeof config.form === "object" ? config.form : void 0)?.enum) ?? normalizeFieldOptions$1(config.enum);
|
|
4421
|
+
const fieldDataSource = fieldOptions || !config.dataSource ? void 0 : normalizeDataSourceConfig(config.dataSource);
|
|
4422
|
+
if (config.label) result[key] = {
|
|
4423
|
+
...result[key],
|
|
4424
|
+
title: config.label
|
|
4425
|
+
};
|
|
4426
|
+
if (config.hidden) result[key] = {
|
|
4427
|
+
...result[key],
|
|
4428
|
+
"x-hidden": true
|
|
4429
|
+
};
|
|
4430
|
+
if (fieldOptions) result[key] = {
|
|
4431
|
+
...result[key],
|
|
4432
|
+
enum: fieldOptions
|
|
4433
|
+
};
|
|
4434
|
+
if (fieldDataSource) result[key] = {
|
|
4435
|
+
...result[key],
|
|
4436
|
+
"x-data-source": config.dataSource
|
|
4437
|
+
};
|
|
4438
|
+
if (config.form === false) result[key] = {
|
|
4439
|
+
...result[key],
|
|
4440
|
+
"x-hidden": true
|
|
4441
|
+
};
|
|
4442
|
+
else if (config.form && typeof config.form === "object") result[key] = {
|
|
4443
|
+
...result[key],
|
|
4444
|
+
...config.form
|
|
4445
|
+
};
|
|
4446
|
+
}
|
|
4447
|
+
return result;
|
|
4448
|
+
}
|
|
5326
4449
|
|
|
5327
4450
|
//#endregion
|
|
5328
4451
|
//#region src/components/auto-crud/auto-form.tsx
|
|
5329
|
-
const COMBOBOX_LIST_CLASS = "[&_[
|
|
5330
|
-
const FormilySwitch = (0,
|
|
4452
|
+
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";
|
|
4453
|
+
const FormilySwitch = (0, __wordrhyme_formily_shadcn.connect)(__wordrhyme_shadcn.Switch, (0, __wordrhyme_formily_shadcn.mapProps)({
|
|
5331
4454
|
value: "checked",
|
|
5332
4455
|
onInput: "onCheckedChange"
|
|
5333
4456
|
}));
|
|
5334
|
-
const FormilyCombobox = (0,
|
|
5335
|
-
const FormilyMultiCombobox = (0,
|
|
4457
|
+
const FormilyCombobox = (0, __wordrhyme_formily_shadcn.connect)(AutoCrudCombobox, (0, __wordrhyme_formily_shadcn.mapProps)({ dataSource: "options" }));
|
|
4458
|
+
const FormilyMultiCombobox = (0, __wordrhyme_formily_shadcn.connect)(AutoCrudMultiCombobox, (0, __wordrhyme_formily_shadcn.mapProps)({
|
|
5336
4459
|
dataSource: "options",
|
|
5337
4460
|
onInput: "onChange"
|
|
5338
4461
|
}, (props, field) => {
|
|
5339
|
-
const fieldValue = field.value;
|
|
4462
|
+
const fieldValue = field && typeof field === "object" && "value" in field ? field.value : props.value;
|
|
5340
4463
|
return {
|
|
5341
4464
|
...props,
|
|
5342
4465
|
value: Array.isArray(fieldValue) ? fieldValue.map(String) : []
|
|
5343
4466
|
};
|
|
5344
4467
|
}));
|
|
5345
4468
|
function AutoCrudCombobox({ options = [], className, value, onChange,...props }) {
|
|
5346
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
4469
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn_ui.Select, {
|
|
5347
4470
|
...props,
|
|
5348
|
-
|
|
4471
|
+
mode: "searchable",
|
|
4472
|
+
value: value ?? "",
|
|
5349
4473
|
options,
|
|
5350
|
-
|
|
5351
|
-
|
|
5352
|
-
className: (0, __pixpilot_shadcn.cn)(COMBOBOX_LIST_CLASS, className)
|
|
4474
|
+
onChange: (nextValue) => onChange?.(nextValue),
|
|
4475
|
+
className: (0, __wordrhyme_shadcn.cn)(COMBOBOX_LIST_CLASS, className)
|
|
5353
4476
|
});
|
|
5354
4477
|
}
|
|
5355
4478
|
function AutoCrudMultiCombobox({ options = [],...props }) {
|
|
5356
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
4479
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn_ui.Select, {
|
|
5357
4480
|
...props,
|
|
4481
|
+
mode: "searchable",
|
|
4482
|
+
multiple: true,
|
|
5358
4483
|
options
|
|
5359
4484
|
});
|
|
5360
4485
|
}
|
|
@@ -5372,99 +4497,280 @@ const defaultFieldComponents = {
|
|
|
5372
4497
|
decorator: "FormItem"
|
|
5373
4498
|
}
|
|
5374
4499
|
};
|
|
5375
|
-
|
|
4500
|
+
const AUTO_CRUD_DATA_SOURCE_SCOPE_KEY = "$autoCrudDataSource";
|
|
4501
|
+
const POPUP_SCROLL_LOAD_THRESHOLD$1 = 24;
|
|
4502
|
+
const dataSourceReactionStates = /* @__PURE__ */ new WeakMap();
|
|
4503
|
+
function createBoundAction(callback) {
|
|
4504
|
+
return __formily_reactive.action.bound?.(callback) ?? ((...args) => (0, __formily_reactive.action)(() => callback(...args)));
|
|
4505
|
+
}
|
|
4506
|
+
function useRegistryVersion$1(subscribe, onChange) {
|
|
5376
4507
|
const [version$1, setVersion] = (0, react.useState)(0);
|
|
5377
|
-
(0, react.useEffect)(() => subscribe(() =>
|
|
4508
|
+
(0, react.useEffect)(() => subscribe(() => {
|
|
4509
|
+
onChange?.();
|
|
4510
|
+
setVersion((current) => current + 1);
|
|
4511
|
+
}), [onChange, subscribe]);
|
|
5378
4512
|
return version$1;
|
|
5379
4513
|
}
|
|
5380
4514
|
function isDataSourceConfig(value) {
|
|
5381
4515
|
return typeof value === "string" && value.length > 0;
|
|
5382
4516
|
}
|
|
5383
|
-
function
|
|
4517
|
+
function getSchemaDataSourceConfig(schema) {
|
|
4518
|
+
const customDataSource = schema["x-data-source"];
|
|
4519
|
+
const schemaDataSource = schema.dataSource;
|
|
4520
|
+
return isDataSourceConfig(customDataSource) ? customDataSource : isDataSourceConfig(schemaDataSource) ? schemaDataSource : void 0;
|
|
4521
|
+
}
|
|
4522
|
+
function mergeReactions(existing, reaction) {
|
|
4523
|
+
if (existing == null) return reaction;
|
|
4524
|
+
if (existing === reaction) return existing;
|
|
4525
|
+
if (Array.isArray(existing)) return existing.includes(reaction) ? existing : [...existing, reaction];
|
|
4526
|
+
return [existing, reaction];
|
|
4527
|
+
}
|
|
4528
|
+
function applyDataSourceReactions(schema) {
|
|
4529
|
+
const dataSourceConfig = getSchemaDataSourceConfig(schema);
|
|
4530
|
+
if (dataSourceConfig) {
|
|
4531
|
+
const reaction = `{{${AUTO_CRUD_DATA_SOURCE_SCOPE_KEY}(${JSON.stringify(dataSourceConfig)})}}`;
|
|
4532
|
+
schema["x-reactions"] = mergeReactions(schema["x-reactions"], reaction);
|
|
4533
|
+
}
|
|
5384
4534
|
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);
|
|
4535
|
+
if (properties && typeof properties === "object" && !Array.isArray(properties)) {
|
|
4536
|
+
for (const property of Object.values(properties)) if (property && typeof property === "object" && !Array.isArray(property)) applyDataSourceReactions(property);
|
|
5394
4537
|
}
|
|
5395
|
-
|
|
4538
|
+
const items = schema.items;
|
|
4539
|
+
if (Array.isArray(items)) {
|
|
4540
|
+
for (const item of items) if (item && typeof item === "object") applyDataSourceReactions(item);
|
|
4541
|
+
} else if (items && typeof items === "object") applyDataSourceReactions(items);
|
|
4542
|
+
}
|
|
4543
|
+
function getDataSourceReactionState(field) {
|
|
4544
|
+
const existing = dataSourceReactionStates.get(field);
|
|
4545
|
+
if (existing) return existing;
|
|
4546
|
+
const next = {
|
|
4547
|
+
hasMore: false,
|
|
4548
|
+
initialized: false,
|
|
4549
|
+
appendLoading: false,
|
|
4550
|
+
options: [],
|
|
4551
|
+
page: 0,
|
|
4552
|
+
requestVersion: 0
|
|
4553
|
+
};
|
|
4554
|
+
dataSourceReactionStates.set(field, next);
|
|
4555
|
+
return next;
|
|
4556
|
+
}
|
|
4557
|
+
function mergeDataSourceOptions(current, incoming) {
|
|
4558
|
+
const optionsByValue = new Map(current.map((option) => [option.value, option]));
|
|
4559
|
+
for (const option of incoming) optionsByValue.set(option.value, option);
|
|
4560
|
+
return Array.from(optionsByValue.values());
|
|
4561
|
+
}
|
|
4562
|
+
function isNearPopupScrollBottom$1(target) {
|
|
4563
|
+
return target.scrollHeight - target.scrollTop - target.clientHeight <= POPUP_SCROLL_LOAD_THRESHOLD$1;
|
|
4564
|
+
}
|
|
4565
|
+
function getDataSourceDependencyValues(entry, field) {
|
|
4566
|
+
return Object.fromEntries(entry.dependencies.map((dependency) => [dependency, field.form.getValuesIn(dependency)]));
|
|
4567
|
+
}
|
|
4568
|
+
function loadAutoCrudDataSource({ entry, field, registryVersion, search, sourceKey, state, append = false }) {
|
|
4569
|
+
const values = getDataSourceDependencyValues(entry, field);
|
|
4570
|
+
const dependencyKey = JSON.stringify(values);
|
|
4571
|
+
const searchValue = entry.search ? search ?? "" : void 0;
|
|
4572
|
+
const page = entry.loadMore ? append ? state.page + 1 : 1 : void 0;
|
|
4573
|
+
const loadKey = JSON.stringify({
|
|
4574
|
+
values,
|
|
4575
|
+
search: searchValue
|
|
4576
|
+
});
|
|
4577
|
+
if (!append && state.loadKey === loadKey && state.registryVersion === registryVersion) return;
|
|
4578
|
+
if (entry.reset && state.dependencyKey !== void 0 && state.dependencyKey !== dependencyKey) field.setValue(void 0);
|
|
4579
|
+
state.dependencyKey = dependencyKey;
|
|
4580
|
+
if (!append) {
|
|
4581
|
+
state.loadKey = loadKey;
|
|
4582
|
+
state.options = [];
|
|
4583
|
+
state.page = 0;
|
|
4584
|
+
state.hasMore = false;
|
|
4585
|
+
}
|
|
4586
|
+
state.registryVersion = registryVersion;
|
|
4587
|
+
state.controller?.abort();
|
|
4588
|
+
const requestVersion = state.requestVersion + 1;
|
|
4589
|
+
state.requestVersion = requestVersion;
|
|
4590
|
+
const controller = typeof AbortController === "undefined" ? void 0 : new AbortController();
|
|
4591
|
+
state.controller = controller;
|
|
4592
|
+
if (append) {
|
|
4593
|
+
state.appendLoading = true;
|
|
4594
|
+
field.setComponentProps({ loading: true });
|
|
4595
|
+
} else {
|
|
4596
|
+
field.setLoading(true);
|
|
4597
|
+
field.setComponentProps({
|
|
4598
|
+
loading: true,
|
|
4599
|
+
...entry.loadMore ? { hasMore: false } : {}
|
|
4600
|
+
});
|
|
4601
|
+
}
|
|
4602
|
+
Promise.resolve(entry.load({
|
|
4603
|
+
field: field.path.toString(),
|
|
4604
|
+
page,
|
|
4605
|
+
pageSize: entry.loadMore ? entry.pageSize : void 0,
|
|
4606
|
+
search: searchValue,
|
|
4607
|
+
values,
|
|
4608
|
+
signal: controller?.signal
|
|
4609
|
+
})).then(createBoundAction((result) => {
|
|
4610
|
+
if (dataSourceReactionStates.get(field)?.requestVersion !== requestVersion || controller?.signal.aborted) return;
|
|
4611
|
+
const options = normalizeOptions(result);
|
|
4612
|
+
const nextOptions = append ? mergeDataSourceOptions(state.options, options) : options;
|
|
4613
|
+
state.options = nextOptions;
|
|
4614
|
+
state.page = page ?? 0;
|
|
4615
|
+
state.hasMore = entry.loadMore ? normalizeHasMore(result) : false;
|
|
4616
|
+
state.appendLoading = false;
|
|
4617
|
+
field.setDataSource(nextOptions);
|
|
4618
|
+
field.setLoading(false);
|
|
4619
|
+
field.setComponentProps({
|
|
4620
|
+
loading: false,
|
|
4621
|
+
...entry.loadMore ? { hasMore: state.hasMore } : {}
|
|
4622
|
+
});
|
|
4623
|
+
}), createBoundAction((error) => {
|
|
4624
|
+
if (dataSourceReactionStates.get(field)?.requestVersion !== requestVersion || controller?.signal.aborted) return;
|
|
4625
|
+
console.warn(`[AutoCrud] Failed to load data source "${sourceKey}".`, error);
|
|
4626
|
+
if (!append) {
|
|
4627
|
+
state.options = [];
|
|
4628
|
+
state.hasMore = false;
|
|
4629
|
+
field.setDataSource([]);
|
|
4630
|
+
}
|
|
4631
|
+
state.appendLoading = false;
|
|
4632
|
+
field.setLoading(false);
|
|
4633
|
+
field.setComponentProps({
|
|
4634
|
+
loading: false,
|
|
4635
|
+
...entry.loadMore ? { hasMore: state.hasMore } : {}
|
|
4636
|
+
});
|
|
4637
|
+
}));
|
|
5396
4638
|
}
|
|
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;
|
|
4639
|
+
function applySearchComponentProps({ entry, field, registryState, sourceKey, state }) {
|
|
4640
|
+
if (!entry.search) return;
|
|
4641
|
+
field.setComponentProps({
|
|
4642
|
+
searchValue: state.search ?? "",
|
|
4643
|
+
shouldFilter: false,
|
|
4644
|
+
onSearch: (search) => {
|
|
4645
|
+
if (state.search === search) return;
|
|
4646
|
+
state.search = search;
|
|
4647
|
+
field.setComponentProps({ searchValue: search });
|
|
4648
|
+
if (state.searchTimer) clearTimeout(state.searchTimer);
|
|
4649
|
+
state.searchTimer = setTimeout(() => {
|
|
4650
|
+
const currentEntry = dataSources.get(sourceKey);
|
|
4651
|
+
if (!currentEntry) {
|
|
4652
|
+
state.controller?.abort();
|
|
4653
|
+
field.setDataSource([]);
|
|
4654
|
+
field.setLoading(false);
|
|
4655
|
+
field.setComponentProps({ loading: false });
|
|
4656
|
+
return;
|
|
4657
|
+
}
|
|
4658
|
+
loadAutoCrudDataSource({
|
|
4659
|
+
entry: currentEntry,
|
|
4660
|
+
field,
|
|
4661
|
+
registryVersion: registryState.version,
|
|
4662
|
+
search,
|
|
4663
|
+
sourceKey,
|
|
4664
|
+
state
|
|
5427
4665
|
});
|
|
5428
|
-
}
|
|
5429
|
-
|
|
5430
|
-
|
|
5431
|
-
|
|
5432
|
-
|
|
4666
|
+
}, entry.debounceMs);
|
|
4667
|
+
}
|
|
4668
|
+
});
|
|
4669
|
+
}
|
|
4670
|
+
function applyLoadMoreComponentProps({ entry, field, registryState, sourceKey, state }) {
|
|
4671
|
+
if (!entry.loadMore) return;
|
|
4672
|
+
field.setComponentProps({
|
|
4673
|
+
hasMore: state.hasMore,
|
|
4674
|
+
loading: state.appendLoading,
|
|
4675
|
+
onPopupScroll: (event) => {
|
|
4676
|
+
if (!isNearPopupScrollBottom$1(event.currentTarget)) return;
|
|
4677
|
+
if (!state.hasMore || state.appendLoading) return;
|
|
4678
|
+
const currentEntry = dataSources.get(sourceKey);
|
|
4679
|
+
if (!currentEntry) {
|
|
4680
|
+
state.controller?.abort();
|
|
4681
|
+
state.hasMore = false;
|
|
4682
|
+
state.appendLoading = false;
|
|
4683
|
+
field.setDataSource([]);
|
|
4684
|
+
field.setLoading(false);
|
|
4685
|
+
field.setComponentProps({
|
|
4686
|
+
hasMore: false,
|
|
4687
|
+
loading: false
|
|
5433
4688
|
});
|
|
4689
|
+
return;
|
|
5434
4690
|
}
|
|
5435
|
-
|
|
5436
|
-
|
|
5437
|
-
|
|
5438
|
-
|
|
5439
|
-
|
|
5440
|
-
|
|
5441
|
-
|
|
5442
|
-
|
|
5443
|
-
loadFieldOptions(fieldName, source);
|
|
5444
|
-
}
|
|
4691
|
+
loadAutoCrudDataSource({
|
|
4692
|
+
append: true,
|
|
4693
|
+
entry: currentEntry,
|
|
4694
|
+
field,
|
|
4695
|
+
registryVersion: registryState.version,
|
|
4696
|
+
search: state.search,
|
|
4697
|
+
sourceKey,
|
|
4698
|
+
state
|
|
5445
4699
|
});
|
|
4700
|
+
}
|
|
4701
|
+
});
|
|
4702
|
+
}
|
|
4703
|
+
function createAutoCrudDataSourceReaction(config, registryState) {
|
|
4704
|
+
const source = normalizeDataSourceConfig(config);
|
|
4705
|
+
return (field) => {
|
|
4706
|
+
const registryVersion = registryState.version;
|
|
4707
|
+
const state = getDataSourceReactionState(field);
|
|
4708
|
+
if (!state.initialized) {
|
|
4709
|
+
field.disposers.push(() => {
|
|
4710
|
+
state.controller?.abort();
|
|
4711
|
+
if (state.searchTimer) clearTimeout(state.searchTimer);
|
|
4712
|
+
});
|
|
4713
|
+
state.initialized = true;
|
|
4714
|
+
}
|
|
4715
|
+
if (!source) {
|
|
4716
|
+
field.setDataSource([]);
|
|
4717
|
+
field.setLoading(false);
|
|
4718
|
+
return;
|
|
4719
|
+
}
|
|
4720
|
+
const entry = dataSources.get(source.key);
|
|
4721
|
+
if (!entry) {
|
|
4722
|
+
state.controller?.abort();
|
|
4723
|
+
field.setDataSource([]);
|
|
4724
|
+
field.setLoading(false);
|
|
4725
|
+
return;
|
|
4726
|
+
}
|
|
4727
|
+
applySearchComponentProps({
|
|
4728
|
+
entry,
|
|
4729
|
+
field,
|
|
4730
|
+
registryState,
|
|
4731
|
+
sourceKey: source.key,
|
|
4732
|
+
state
|
|
5446
4733
|
});
|
|
5447
|
-
|
|
5448
|
-
|
|
5449
|
-
|
|
5450
|
-
|
|
5451
|
-
|
|
5452
|
-
|
|
5453
|
-
|
|
5454
|
-
|
|
5455
|
-
|
|
5456
|
-
|
|
4734
|
+
applyLoadMoreComponentProps({
|
|
4735
|
+
entry,
|
|
4736
|
+
field,
|
|
4737
|
+
registryState,
|
|
4738
|
+
sourceKey: source.key,
|
|
4739
|
+
state
|
|
4740
|
+
});
|
|
4741
|
+
loadAutoCrudDataSource({
|
|
4742
|
+
entry,
|
|
4743
|
+
field,
|
|
4744
|
+
registryVersion,
|
|
4745
|
+
search: state.search,
|
|
4746
|
+
sourceKey: source.key,
|
|
4747
|
+
state
|
|
4748
|
+
});
|
|
4749
|
+
};
|
|
5457
4750
|
}
|
|
5458
|
-
function AutoFormInner({ schema: zodSchema, initialValues, onSubmit, overrides, mode = "create", loading = false, gridColumns = 1, labelAlign = "top", labelWidth, showSubmitButton = true }, ref) {
|
|
4751
|
+
function AutoFormInner({ schema: zodSchema, initialValues, onSubmit, fields, overrides, scope: scopeProp, mode = "create", loading = false, gridColumns = 1, labelAlign = "top", labelWidth, showSubmitButton = true }, ref) {
|
|
5459
4752
|
const form = (0, react.useMemo)(() => (0, __formily_core.createForm)({ initialValues }), [JSON.stringify(initialValues)]);
|
|
5460
|
-
const
|
|
5461
|
-
|
|
5462
|
-
|
|
5463
|
-
|
|
5464
|
-
|
|
4753
|
+
const dataSourceRegistryState = (0, react.useMemo)(() => (0, __formily_reactive.observable)({ version: 0 }), []);
|
|
4754
|
+
const updateDataSourceRegistryState = (0, react.useCallback)(() => {
|
|
4755
|
+
(0, __formily_reactive.action)(() => {
|
|
4756
|
+
dataSourceRegistryState.version += 1;
|
|
4757
|
+
});
|
|
4758
|
+
}, [dataSourceRegistryState]);
|
|
4759
|
+
const dataSourceRegistryVersion = useRegistryVersion$1(dataSources.subscribe, updateDataSourceRegistryState);
|
|
4760
|
+
const formOverrides = (0, react.useMemo)(() => buildFormOverrides(fields, overrides), [fields, overrides]);
|
|
4761
|
+
const formSchema = (0, react.useMemo)(() => {
|
|
4762
|
+
const nextSchema = createEditFormSchema(zodSchema, {
|
|
4763
|
+
overrides: formOverrides,
|
|
4764
|
+
layout: "grid",
|
|
4765
|
+
gridColumns
|
|
4766
|
+
});
|
|
4767
|
+
applyDataSourceReactions(nextSchema);
|
|
4768
|
+
return nextSchema;
|
|
4769
|
+
}, [
|
|
5465
4770
|
zodSchema,
|
|
5466
|
-
|
|
5467
|
-
gridColumns
|
|
4771
|
+
formOverrides,
|
|
4772
|
+
gridColumns,
|
|
4773
|
+
dataSourceRegistryVersion
|
|
5468
4774
|
]);
|
|
5469
4775
|
const formLayout = (0, react.useMemo)(() => {
|
|
5470
4776
|
const inlineLabel = labelAlign === "left" || labelAlign === "right";
|
|
@@ -5480,21 +4786,25 @@ function AutoFormInner({ schema: zodSchema, initialValues, onSubmit, overrides,
|
|
|
5480
4786
|
...defaultFieldComponents,
|
|
5481
4787
|
...components.all()
|
|
5482
4788
|
} }), [useRegistryVersion$1(components.subscribe)]);
|
|
5483
|
-
|
|
4789
|
+
const scope = (0, react.useMemo)(() => ({
|
|
4790
|
+
...scopeProp,
|
|
4791
|
+
[AUTO_CRUD_DATA_SOURCE_SCOPE_KEY]: (config) => createAutoCrudDataSourceReaction(config, dataSourceRegistryState)
|
|
4792
|
+
}), [dataSourceRegistryState, scopeProp]);
|
|
5484
4793
|
const handleSubmit = async () => {
|
|
5485
4794
|
await form.validate();
|
|
5486
4795
|
if (form.valid) await onSubmit(form.values);
|
|
5487
4796
|
};
|
|
5488
4797
|
(0, react.useImperativeHandle)(ref, () => ({ submit: handleSubmit }));
|
|
5489
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
4798
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_formily_shadcn.Form, {
|
|
5490
4799
|
form,
|
|
5491
4800
|
layout: formLayout,
|
|
5492
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
4801
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_formily_shadcn.JsonSchemaField, {
|
|
5493
4802
|
schema: formSchema,
|
|
5494
|
-
components: fieldComponents
|
|
4803
|
+
components: fieldComponents,
|
|
4804
|
+
scope
|
|
5495
4805
|
}), showSubmitButton && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5496
4806
|
className: "flex justify-end gap-2 mt-6",
|
|
5497
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
4807
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
5498
4808
|
type: "button",
|
|
5499
4809
|
onClick: handleSubmit,
|
|
5500
4810
|
disabled: loading,
|
|
@@ -5509,6 +4819,7 @@ const AutoForm = (0, react.forwardRef)(AutoFormInner);
|
|
|
5509
4819
|
//#region src/i18n/locale.ts
|
|
5510
4820
|
const zhCN = {
|
|
5511
4821
|
toolbar: {
|
|
4822
|
+
refresh: "刷新",
|
|
5512
4823
|
create: "新建",
|
|
5513
4824
|
import: "导入",
|
|
5514
4825
|
export: "导出",
|
|
@@ -5540,6 +4851,12 @@ const zhCN = {
|
|
|
5540
4851
|
confirm: "确认删除",
|
|
5541
4852
|
confirming: "删除中..."
|
|
5542
4853
|
},
|
|
4854
|
+
bulkDeleteModal: {
|
|
4855
|
+
title: "确认批量删除",
|
|
4856
|
+
description: (count) => `此操作无法撤销。确定要删除选中的 ${count} 条记录吗?`,
|
|
4857
|
+
cancel: "取消",
|
|
4858
|
+
confirm: "确认删除"
|
|
4859
|
+
},
|
|
5543
4860
|
importDialog: {
|
|
5544
4861
|
title: "导入数据",
|
|
5545
4862
|
uploadDescription: "上传 CSV 或 JSON 文件以批量导入数据",
|
|
@@ -5569,6 +4886,7 @@ const zhCN = {
|
|
|
5569
4886
|
};
|
|
5570
4887
|
const enUS = {
|
|
5571
4888
|
toolbar: {
|
|
4889
|
+
refresh: "Refresh",
|
|
5572
4890
|
create: "New",
|
|
5573
4891
|
import: "Import",
|
|
5574
4892
|
export: "Export",
|
|
@@ -5600,6 +4918,12 @@ const enUS = {
|
|
|
5600
4918
|
confirm: "Delete",
|
|
5601
4919
|
confirming: "Deleting..."
|
|
5602
4920
|
},
|
|
4921
|
+
bulkDeleteModal: {
|
|
4922
|
+
title: "Confirm Bulk Delete",
|
|
4923
|
+
description: (count) => `This action cannot be undone. Are you sure you want to delete ${count} selected ${count === 1 ? "record" : "records"}?`,
|
|
4924
|
+
cancel: "Cancel",
|
|
4925
|
+
confirm: "Delete"
|
|
4926
|
+
},
|
|
5603
4927
|
importDialog: {
|
|
5604
4928
|
title: "Import Data",
|
|
5605
4929
|
uploadDescription: "Upload a CSV or JSON file to bulk import data",
|
|
@@ -5629,6 +4953,7 @@ const enUS = {
|
|
|
5629
4953
|
};
|
|
5630
4954
|
const jaJP = {
|
|
5631
4955
|
toolbar: {
|
|
4956
|
+
refresh: "更新",
|
|
5632
4957
|
create: "新規作成",
|
|
5633
4958
|
import: "インポート",
|
|
5634
4959
|
export: "エクスポート",
|
|
@@ -5660,6 +4985,12 @@ const jaJP = {
|
|
|
5660
4985
|
confirm: "削除する",
|
|
5661
4986
|
confirming: "削除中..."
|
|
5662
4987
|
},
|
|
4988
|
+
bulkDeleteModal: {
|
|
4989
|
+
title: "一括削除の確認",
|
|
4990
|
+
description: (count) => `この操作は元に戻せません。選択した${count}件のレコードを削除してもよろしいですか?`,
|
|
4991
|
+
cancel: "キャンセル",
|
|
4992
|
+
confirm: "削除する"
|
|
4993
|
+
},
|
|
5663
4994
|
importDialog: {
|
|
5664
4995
|
title: "データのインポート",
|
|
5665
4996
|
uploadDescription: "CSVまたはJSONファイルをアップロードして一括インポート",
|
|
@@ -5689,6 +5020,7 @@ const jaJP = {
|
|
|
5689
5020
|
};
|
|
5690
5021
|
const koKR = {
|
|
5691
5022
|
toolbar: {
|
|
5023
|
+
refresh: "새로고침",
|
|
5692
5024
|
create: "새로 만들기",
|
|
5693
5025
|
import: "가져오기",
|
|
5694
5026
|
export: "내보내기",
|
|
@@ -5720,6 +5052,12 @@ const koKR = {
|
|
|
5720
5052
|
confirm: "삭제",
|
|
5721
5053
|
confirming: "삭제 중..."
|
|
5722
5054
|
},
|
|
5055
|
+
bulkDeleteModal: {
|
|
5056
|
+
title: "일괄 삭제 확인",
|
|
5057
|
+
description: (count) => `이 작업은 취소할 수 없습니다. 선택한 ${count}개 레코드를 삭제하시겠습니까?`,
|
|
5058
|
+
cancel: "취소",
|
|
5059
|
+
confirm: "삭제"
|
|
5060
|
+
},
|
|
5723
5061
|
importDialog: {
|
|
5724
5062
|
title: "데이터 가져오기",
|
|
5725
5063
|
uploadDescription: "CSV 또는 JSON 파일을 업로드하여 일괄 가져오기",
|
|
@@ -5749,6 +5087,7 @@ const koKR = {
|
|
|
5749
5087
|
};
|
|
5750
5088
|
const frFR = {
|
|
5751
5089
|
toolbar: {
|
|
5090
|
+
refresh: "Actualiser",
|
|
5752
5091
|
create: "Nouveau",
|
|
5753
5092
|
import: "Importer",
|
|
5754
5093
|
export: "Exporter",
|
|
@@ -5780,6 +5119,12 @@ const frFR = {
|
|
|
5780
5119
|
confirm: "Supprimer",
|
|
5781
5120
|
confirming: "Suppression..."
|
|
5782
5121
|
},
|
|
5122
|
+
bulkDeleteModal: {
|
|
5123
|
+
title: "Confirmer la suppression en masse",
|
|
5124
|
+
description: (count) => `Cette action est irréversible. Voulez-vous vraiment supprimer les ${count} enregistrements sélectionnés ?`,
|
|
5125
|
+
cancel: "Annuler",
|
|
5126
|
+
confirm: "Supprimer"
|
|
5127
|
+
},
|
|
5783
5128
|
importDialog: {
|
|
5784
5129
|
title: "Importer des données",
|
|
5785
5130
|
uploadDescription: "Téléchargez un fichier CSV ou JSON pour importer en masse",
|
|
@@ -5809,6 +5154,7 @@ const frFR = {
|
|
|
5809
5154
|
};
|
|
5810
5155
|
const deDE = {
|
|
5811
5156
|
toolbar: {
|
|
5157
|
+
refresh: "Aktualisieren",
|
|
5812
5158
|
create: "Neu",
|
|
5813
5159
|
import: "Importieren",
|
|
5814
5160
|
export: "Exportieren",
|
|
@@ -5840,6 +5186,12 @@ const deDE = {
|
|
|
5840
5186
|
confirm: "Löschen",
|
|
5841
5187
|
confirming: "Wird gelöscht..."
|
|
5842
5188
|
},
|
|
5189
|
+
bulkDeleteModal: {
|
|
5190
|
+
title: "Mehrfaches Löschen bestätigen",
|
|
5191
|
+
description: (count) => `Diese Aktion kann nicht rückgängig gemacht werden. Möchten Sie die ${count} ausgewählten Datensätze wirklich löschen?`,
|
|
5192
|
+
cancel: "Abbrechen",
|
|
5193
|
+
confirm: "Löschen"
|
|
5194
|
+
},
|
|
5843
5195
|
importDialog: {
|
|
5844
5196
|
title: "Daten importieren",
|
|
5845
5197
|
uploadDescription: "CSV- oder JSON-Datei hochladen, um Daten massenweise zu importieren",
|
|
@@ -5869,6 +5221,7 @@ const deDE = {
|
|
|
5869
5221
|
};
|
|
5870
5222
|
const esES = {
|
|
5871
5223
|
toolbar: {
|
|
5224
|
+
refresh: "Actualizar",
|
|
5872
5225
|
create: "Nuevo",
|
|
5873
5226
|
import: "Importar",
|
|
5874
5227
|
export: "Exportar",
|
|
@@ -5900,6 +5253,12 @@ const esES = {
|
|
|
5900
5253
|
confirm: "Eliminar",
|
|
5901
5254
|
confirming: "Eliminando..."
|
|
5902
5255
|
},
|
|
5256
|
+
bulkDeleteModal: {
|
|
5257
|
+
title: "Confirmar eliminación masiva",
|
|
5258
|
+
description: (count) => `Esta acción no se puede deshacer. ¿Está seguro de que desea eliminar los ${count} registros seleccionados?`,
|
|
5259
|
+
cancel: "Cancelar",
|
|
5260
|
+
confirm: "Eliminar"
|
|
5261
|
+
},
|
|
5903
5262
|
importDialog: {
|
|
5904
5263
|
title: "Importar datos",
|
|
5905
5264
|
uploadDescription: "Suba un archivo CSV o JSON para importar datos de forma masiva",
|
|
@@ -5959,7 +5318,7 @@ function resolveLocale(localeProp) {
|
|
|
5959
5318
|
|
|
5960
5319
|
//#endregion
|
|
5961
5320
|
//#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 }) {
|
|
5321
|
+
function CrudFormModal({ open, onOpenChange, mode, schema, initialValues, onSubmit, loading = false, variant = "dialog", overrides, scope, title, locale = zhCN.formModal, gridColumns, labelAlign, labelWidth, className }) {
|
|
5963
5322
|
const defaultTitle = mode === "create" ? locale.createTitle : locale.editTitle;
|
|
5964
5323
|
const formRef = (0, react.useRef)(null);
|
|
5965
5324
|
const handleSubmit = async () => {
|
|
@@ -5973,12 +5332,12 @@ function CrudFormModal({ open, onOpenChange, mode, schema, initialValues, onSubm
|
|
|
5973
5332
|
className,
|
|
5974
5333
|
footer: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5975
5334
|
className: "flex justify-end gap-2",
|
|
5976
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
5335
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
5977
5336
|
type: "button",
|
|
5978
5337
|
variant: "outline",
|
|
5979
5338
|
onClick: () => onOpenChange(false),
|
|
5980
5339
|
children: locale.cancel
|
|
5981
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
5340
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
5982
5341
|
type: "button",
|
|
5983
5342
|
onClick: handleSubmit,
|
|
5984
5343
|
disabled: loading,
|
|
@@ -5993,6 +5352,7 @@ function CrudFormModal({ open, onOpenChange, mode, schema, initialValues, onSubm
|
|
|
5993
5352
|
loading,
|
|
5994
5353
|
onSubmit,
|
|
5995
5354
|
overrides,
|
|
5355
|
+
scope,
|
|
5996
5356
|
gridColumns,
|
|
5997
5357
|
labelAlign,
|
|
5998
5358
|
labelWidth,
|
|
@@ -6067,12 +5427,12 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title, local
|
|
|
6067
5427
|
link.click();
|
|
6068
5428
|
URL.revokeObjectURL(url);
|
|
6069
5429
|
}, [columns]);
|
|
6070
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
5430
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Dialog, {
|
|
6071
5431
|
open,
|
|
6072
5432
|
onOpenChange: handleOpenChange,
|
|
6073
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
6074
|
-
className: "sm:max-w-
|
|
6075
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
5433
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.DialogContent, {
|
|
5434
|
+
className: "w-[calc(100vw-2rem)] sm:max-w-5xl",
|
|
5435
|
+
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
5436
|
step === "upload" && locale.uploadDescription,
|
|
6077
5437
|
step === "preview" && locale.previewDescription(parsedData?.rows.length ?? 0),
|
|
6078
5438
|
step === "importing" && locale.importingDescription,
|
|
@@ -6121,7 +5481,7 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title, local
|
|
|
6121
5481
|
className: "hidden",
|
|
6122
5482
|
onChange: handleFileInput
|
|
6123
5483
|
})]
|
|
6124
|
-
}), columns.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
5484
|
+
}), columns.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
6125
5485
|
variant: "outline",
|
|
6126
5486
|
size: "sm",
|
|
6127
5487
|
className: "w-full",
|
|
@@ -6132,41 +5492,30 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title, local
|
|
|
6132
5492
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6133
5493
|
className: "rounded-md border",
|
|
6134
5494
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6135
|
-
className: "max-h-[
|
|
5495
|
+
className: "max-h-[45vh] overflow-auto",
|
|
6136
5496
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("table", {
|
|
6137
|
-
className: "w-
|
|
5497
|
+
className: "min-w-max text-sm",
|
|
6138
5498
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("thead", {
|
|
6139
5499
|
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
|
-
] })
|
|
5500
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
|
|
5501
|
+
className: "sticky left-0 z-10 bg-muted px-3 py-2 text-left font-medium text-muted-foreground",
|
|
5502
|
+
children: "#"
|
|
5503
|
+
}), parsedData.headers.map((h) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
|
|
5504
|
+
className: "max-w-[180px] whitespace-nowrap px-3 py-2 text-left font-medium text-muted-foreground",
|
|
5505
|
+
children: h
|
|
5506
|
+
}, h))] })
|
|
6154
5507
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tbody", { children: parsedData.rows.slice(0, 10).map((row, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", {
|
|
6155
5508
|
className: "border-t",
|
|
6156
|
-
children: [
|
|
6157
|
-
|
|
6158
|
-
|
|
6159
|
-
|
|
6160
|
-
|
|
6161
|
-
|
|
6162
|
-
|
|
5509
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
|
|
5510
|
+
className: "sticky left-0 bg-background px-3 py-2 text-muted-foreground",
|
|
5511
|
+
children: i + 1
|
|
5512
|
+
}), parsedData.headers.map((h) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
|
|
5513
|
+
className: "max-w-[180px] truncate px-3 py-2",
|
|
5514
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5515
|
+
title: String(row[h] ?? ""),
|
|
6163
5516
|
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
5517
|
})
|
|
6169
|
-
]
|
|
5518
|
+
}, h))]
|
|
6170
5519
|
}, i)) })]
|
|
6171
5520
|
})
|
|
6172
5521
|
})
|
|
@@ -6177,11 +5526,11 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title, local
|
|
|
6177
5526
|
}),
|
|
6178
5527
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6179
5528
|
className: "flex gap-2 justify-end",
|
|
6180
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
5529
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
6181
5530
|
variant: "outline",
|
|
6182
5531
|
onClick: reset,
|
|
6183
5532
|
children: locale.reselect
|
|
6184
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
5533
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
6185
5534
|
onClick: handleImport,
|
|
6186
5535
|
children: locale.confirmImport
|
|
6187
5536
|
})]
|
|
@@ -6270,11 +5619,11 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title, local
|
|
|
6270
5619
|
})]
|
|
6271
5620
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6272
5621
|
className: "flex gap-2 justify-end",
|
|
6273
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
5622
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
6274
5623
|
variant: "outline",
|
|
6275
5624
|
onClick: () => handleOpenChange(false),
|
|
6276
5625
|
children: locale.close
|
|
6277
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
5626
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
6278
5627
|
variant: "outline",
|
|
6279
5628
|
onClick: reset,
|
|
6280
5629
|
children: locale.continueImport
|
|
@@ -6298,12 +5647,12 @@ const listeners = /* @__PURE__ */ new Set();
|
|
|
6298
5647
|
let seq = 0;
|
|
6299
5648
|
let version = 0;
|
|
6300
5649
|
let notifyScheduled = false;
|
|
6301
|
-
function actionKey(registration, action, index$1) {
|
|
5650
|
+
function actionKey(registration, action$1, index$1) {
|
|
6302
5651
|
return [
|
|
6303
5652
|
registration.ownerId,
|
|
6304
5653
|
registration.targetId,
|
|
6305
5654
|
registration.zone,
|
|
6306
|
-
action.id ?? action.type,
|
|
5655
|
+
action$1.id ?? action$1.type,
|
|
6307
5656
|
index$1
|
|
6308
5657
|
].join(":");
|
|
6309
5658
|
}
|
|
@@ -6351,15 +5700,15 @@ function sortEntries(left, right) {
|
|
|
6351
5700
|
if (ownerDiff !== 0) return ownerDiff;
|
|
6352
5701
|
return left.seq - right.seq;
|
|
6353
5702
|
}
|
|
6354
|
-
function withoutRegistryMeta(action) {
|
|
6355
|
-
const { id, order,...rest } = action;
|
|
5703
|
+
function withoutRegistryMeta(action$1) {
|
|
5704
|
+
const { id, order,...rest } = action$1;
|
|
6356
5705
|
return rest;
|
|
6357
5706
|
}
|
|
6358
|
-
function isCustomAction$1(action) {
|
|
6359
|
-
return action.type === "custom";
|
|
5707
|
+
function isCustomAction$1(action$1) {
|
|
5708
|
+
return action$1.type === "custom";
|
|
6360
5709
|
}
|
|
6361
5710
|
function resolveActions$1(targetId, zone, ownerActions) {
|
|
6362
|
-
const baseActions = ownerActions.filter((action) => !action.hidden).map((action) => withoutRegistryMeta(action));
|
|
5711
|
+
const baseActions = ownerActions.filter((action$1) => !action$1.hidden).map((action$1) => withoutRegistryMeta(action$1));
|
|
6363
5712
|
if (!targetId) return baseActions;
|
|
6364
5713
|
const registered = crudActions.get(targetId, zone);
|
|
6365
5714
|
if (registered.length === 0) return baseActions;
|
|
@@ -6367,20 +5716,20 @@ function resolveActions$1(targetId, zone, ownerActions) {
|
|
|
6367
5716
|
const startCustomActions = [];
|
|
6368
5717
|
const endCustomActions = [];
|
|
6369
5718
|
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);
|
|
5719
|
+
const action$1 = entry.action;
|
|
5720
|
+
if (action$1.hidden && isCustomAction$1(action$1)) continue;
|
|
5721
|
+
if (isCustomAction$1(action$1)) {
|
|
5722
|
+
const custom = withoutRegistryMeta(action$1);
|
|
6374
5723
|
if (custom.position === "start") startCustomActions.push(custom);
|
|
6375
5724
|
else endCustomActions.push(custom);
|
|
6376
5725
|
continue;
|
|
6377
5726
|
}
|
|
6378
|
-
const existingIndex = nextActions.findIndex((item) => item.type === action.type);
|
|
6379
|
-
if (action.hidden) {
|
|
5727
|
+
const existingIndex = nextActions.findIndex((item) => item.type === action$1.type);
|
|
5728
|
+
if (action$1.hidden) {
|
|
6380
5729
|
if (existingIndex >= 0) nextActions.splice(existingIndex, 1);
|
|
6381
5730
|
continue;
|
|
6382
5731
|
}
|
|
6383
|
-
const builtin = withoutRegistryMeta(action);
|
|
5732
|
+
const builtin = withoutRegistryMeta(action$1);
|
|
6384
5733
|
if (existingIndex >= 0) nextActions[existingIndex] = {
|
|
6385
5734
|
...nextActions[existingIndex],
|
|
6386
5735
|
...builtin
|
|
@@ -6399,14 +5748,14 @@ const crudActions = {
|
|
|
6399
5748
|
targetId: registration.targetId,
|
|
6400
5749
|
zone: registration.zone
|
|
6401
5750
|
}, false);
|
|
6402
|
-
registration.actions.forEach((action, index$1) => {
|
|
6403
|
-
const key = actionKey(registration, action, index$1);
|
|
5751
|
+
registration.actions.forEach((action$1, index$1) => {
|
|
5752
|
+
const key = actionKey(registration, action$1, index$1);
|
|
6404
5753
|
const entry = {
|
|
6405
5754
|
targetId: registration.targetId,
|
|
6406
5755
|
zone: registration.zone,
|
|
6407
5756
|
ownerId: registration.ownerId,
|
|
6408
|
-
action,
|
|
6409
|
-
order: action.order ?? 100,
|
|
5757
|
+
action: action$1,
|
|
5758
|
+
order: action$1.order ?? 100,
|
|
6410
5759
|
seq: seq++
|
|
6411
5760
|
};
|
|
6412
5761
|
entries.set(key, entry);
|
|
@@ -6445,6 +5794,7 @@ function setToolbarResolver(resolver) {
|
|
|
6445
5794
|
}
|
|
6446
5795
|
function getDefaultToolbarActions() {
|
|
6447
5796
|
return [
|
|
5797
|
+
{ type: "refresh" },
|
|
6448
5798
|
{ type: "import" },
|
|
6449
5799
|
{ type: "export" },
|
|
6450
5800
|
{ type: "create" }
|
|
@@ -6461,8 +5811,8 @@ function getDefaultRowActions() {
|
|
|
6461
5811
|
function getDefaultBatchActions() {
|
|
6462
5812
|
return [{ type: "batchUpdate" }, { type: "delete" }];
|
|
6463
5813
|
}
|
|
6464
|
-
function isCustomAction(action) {
|
|
6465
|
-
return action.type === "custom";
|
|
5814
|
+
function isCustomAction(action$1) {
|
|
5815
|
+
return action$1.type === "custom";
|
|
6466
5816
|
}
|
|
6467
5817
|
function resolveOwnerActions(config, defaults) {
|
|
6468
5818
|
const resolved = typeof config === "function" ? config([...defaults]) : config;
|
|
@@ -6510,7 +5860,7 @@ function haveSameRowSelection(left, right, idKey) {
|
|
|
6510
5860
|
return left.every((row, index$1) => row === right[index$1]);
|
|
6511
5861
|
}
|
|
6512
5862
|
function readCreateAction(actions) {
|
|
6513
|
-
return actions.find((action) => action.type === "create");
|
|
5863
|
+
return actions.find((action$1) => action$1.type === "create");
|
|
6514
5864
|
}
|
|
6515
5865
|
function resolveToolbarActionsWithResolver(targetId, ownerActions, context) {
|
|
6516
5866
|
const resolver = autoCrudToolbarResolver;
|
|
@@ -6562,6 +5912,15 @@ function toBatchOptions(options) {
|
|
|
6562
5912
|
value
|
|
6563
5913
|
}));
|
|
6564
5914
|
}
|
|
5915
|
+
const POPUP_SCROLL_LOAD_THRESHOLD = 24;
|
|
5916
|
+
function isNearPopupScrollBottom(target) {
|
|
5917
|
+
return target.scrollHeight - target.scrollTop - target.clientHeight <= POPUP_SCROLL_LOAD_THRESHOLD;
|
|
5918
|
+
}
|
|
5919
|
+
function mergeFilterOptions(current, incoming) {
|
|
5920
|
+
const optionsByValue = new Map((current ?? []).map((option) => [option.value, option]));
|
|
5921
|
+
for (const option of incoming) optionsByValue.set(option.value, option);
|
|
5922
|
+
return Array.from(optionsByValue.values());
|
|
5923
|
+
}
|
|
6565
5924
|
function getFilterDataSource(config) {
|
|
6566
5925
|
if (config.filter && typeof config.filter === "object") return config.filter.dataSource ?? config.dataSource;
|
|
6567
5926
|
return config.dataSource;
|
|
@@ -6585,7 +5944,20 @@ function useCrudActionsVersion() {
|
|
|
6585
5944
|
}
|
|
6586
5945
|
function useDynamicFilterOptions(fields) {
|
|
6587
5946
|
const registryVersion = useRegistryVersion(dataSources.subscribe);
|
|
5947
|
+
const [searchValues, setSearchValues] = react.useState({});
|
|
5948
|
+
const [hasMoreByField, setHasMoreByField] = react.useState({});
|
|
5949
|
+
const [labelOptionsByField, setLabelOptionsByField] = react.useState({});
|
|
5950
|
+
const [loadingByField, setLoadingByField] = react.useState({});
|
|
6588
5951
|
const [optionsByField, setOptionsByField] = react.useState({});
|
|
5952
|
+
const controllersRef = react.useRef({});
|
|
5953
|
+
const hasMoreByFieldRef = react.useRef({});
|
|
5954
|
+
const loadingByFieldRef = react.useRef({});
|
|
5955
|
+
const optionsByFieldRef = react.useRef({});
|
|
5956
|
+
const pageByFieldRef = react.useRef({});
|
|
5957
|
+
const requestVersionsRef = react.useRef({});
|
|
5958
|
+
const searchValuesRef = react.useRef({});
|
|
5959
|
+
const sourceEntriesByFieldRef = react.useRef({});
|
|
5960
|
+
const timersRef = react.useRef({});
|
|
6589
5961
|
const sourceEntries = react.useMemo(() => {
|
|
6590
5962
|
if (!fields) return [];
|
|
6591
5963
|
return Object.entries(fields).flatMap(([field, config]) => {
|
|
@@ -6597,36 +5969,185 @@ function useDynamicFilterOptions(fields) {
|
|
|
6597
5969
|
}] : [];
|
|
6598
5970
|
});
|
|
6599
5971
|
}, [fields]);
|
|
5972
|
+
const sourceEntriesByField = react.useMemo(() => Object.fromEntries(sourceEntries.map(({ field, source }) => [field, source])), [sourceEntries]);
|
|
6600
5973
|
react.useEffect(() => {
|
|
6601
|
-
|
|
6602
|
-
|
|
5974
|
+
searchValuesRef.current = searchValues;
|
|
5975
|
+
}, [searchValues]);
|
|
5976
|
+
react.useEffect(() => {
|
|
5977
|
+
sourceEntriesByFieldRef.current = sourceEntriesByField;
|
|
5978
|
+
}, [sourceEntriesByField]);
|
|
5979
|
+
const registeredByField = react.useMemo(() => Object.fromEntries(sourceEntries.map(({ field, source }) => [field, dataSources.get(source.key) !== void 0])), [sourceEntries, registryVersion]);
|
|
5980
|
+
const searchableByField = react.useMemo(() => Object.fromEntries(sourceEntries.map(({ field, source }) => [field, dataSources.get(source.key)?.search === true])), [sourceEntries, registryVersion]);
|
|
5981
|
+
const setFieldState = react.useCallback((setter, ref, field, value) => {
|
|
5982
|
+
ref.current = {
|
|
5983
|
+
...ref.current,
|
|
5984
|
+
[field]: value
|
|
5985
|
+
};
|
|
5986
|
+
setter(ref.current);
|
|
5987
|
+
}, []);
|
|
5988
|
+
const removeInactiveFieldState = react.useCallback((setter, ref, activeFields) => {
|
|
5989
|
+
const nextEntries = Object.entries(ref.current).filter(([field]) => activeFields.has(field));
|
|
5990
|
+
if (nextEntries.length === Object.keys(ref.current).length) return;
|
|
5991
|
+
ref.current = Object.fromEntries(nextEntries);
|
|
5992
|
+
setter(ref.current);
|
|
5993
|
+
}, []);
|
|
5994
|
+
const setFieldOptions = react.useCallback((field, options) => {
|
|
5995
|
+
optionsByFieldRef.current = {
|
|
5996
|
+
...optionsByFieldRef.current,
|
|
5997
|
+
[field]: options
|
|
5998
|
+
};
|
|
5999
|
+
setOptionsByField(optionsByFieldRef.current);
|
|
6000
|
+
}, []);
|
|
6001
|
+
const setFieldLoading = react.useCallback((field, loading) => {
|
|
6002
|
+
setFieldState(setLoadingByField, loadingByFieldRef, field, loading);
|
|
6003
|
+
}, [setFieldState]);
|
|
6004
|
+
const setFieldHasMore = react.useCallback((field, hasMore) => {
|
|
6005
|
+
setFieldState(setHasMoreByField, hasMoreByFieldRef, field, hasMore);
|
|
6006
|
+
}, [setFieldState]);
|
|
6007
|
+
const clearFieldRequest = react.useCallback((field) => {
|
|
6008
|
+
const timer = timersRef.current[field];
|
|
6009
|
+
if (timer) clearTimeout(timer);
|
|
6010
|
+
timersRef.current[field] = void 0;
|
|
6011
|
+
controllersRef.current[field]?.abort();
|
|
6012
|
+
controllersRef.current[field] = void 0;
|
|
6013
|
+
}, []);
|
|
6014
|
+
const resetField = react.useCallback((field, { clearLabels = false } = {}) => {
|
|
6015
|
+
clearFieldRequest(field);
|
|
6016
|
+
setFieldOptions(field, []);
|
|
6017
|
+
setFieldLoading(field, false);
|
|
6018
|
+
setFieldHasMore(field, false);
|
|
6019
|
+
pageByFieldRef.current = {
|
|
6020
|
+
...pageByFieldRef.current,
|
|
6021
|
+
[field]: 0
|
|
6022
|
+
};
|
|
6023
|
+
if (clearLabels) setLabelOptionsByField((current) => {
|
|
6024
|
+
const { [field]: _,...rest } = current;
|
|
6025
|
+
return rest;
|
|
6026
|
+
});
|
|
6027
|
+
}, [
|
|
6028
|
+
clearFieldRequest,
|
|
6029
|
+
setFieldHasMore,
|
|
6030
|
+
setFieldLoading,
|
|
6031
|
+
setFieldOptions
|
|
6032
|
+
]);
|
|
6033
|
+
const loadFieldOptions = react.useCallback((field, append = false) => {
|
|
6034
|
+
if (append) {
|
|
6035
|
+
if (loadingByFieldRef.current[field] || !hasMoreByFieldRef.current[field]) return;
|
|
6036
|
+
}
|
|
6037
|
+
const source = sourceEntriesByFieldRef.current[field];
|
|
6038
|
+
const entry = source ? dataSources.get(source.key) : void 0;
|
|
6039
|
+
if (!source || !entry) {
|
|
6040
|
+
resetField(field);
|
|
6603
6041
|
return;
|
|
6604
6042
|
}
|
|
6605
|
-
|
|
6043
|
+
const requestVersion = (requestVersionsRef.current[field] ?? 0) + 1;
|
|
6044
|
+
requestVersionsRef.current = {
|
|
6045
|
+
...requestVersionsRef.current,
|
|
6046
|
+
[field]: requestVersion
|
|
6047
|
+
};
|
|
6048
|
+
clearFieldRequest(field);
|
|
6606
6049
|
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
|
-
|
|
6050
|
+
controllersRef.current[field] = controller;
|
|
6051
|
+
const search = entry.search ? searchValuesRef.current[field] ?? "" : void 0;
|
|
6052
|
+
const page = entry.loadMore ? append ? (pageByFieldRef.current[field] ?? 0) + 1 : 1 : void 0;
|
|
6053
|
+
setFieldLoading(field, true);
|
|
6054
|
+
if (!append) setFieldHasMore(field, false);
|
|
6055
|
+
const timer = setTimeout(() => {
|
|
6056
|
+
Promise.resolve(entry.load({
|
|
6057
|
+
field,
|
|
6058
|
+
page,
|
|
6059
|
+
pageSize: entry.loadMore ? entry.pageSize : void 0,
|
|
6060
|
+
search,
|
|
6061
|
+
values: {},
|
|
6062
|
+
signal: controller?.signal
|
|
6063
|
+
})).then((result) => {
|
|
6064
|
+
if (requestVersionsRef.current[field] !== requestVersion || controller?.signal.aborted) return;
|
|
6065
|
+
const options = normalizeOptions(result);
|
|
6066
|
+
const nextOptions = append ? mergeFilterOptions(optionsByFieldRef.current[field], options) : options;
|
|
6067
|
+
const hasMore = normalizeHasMore(result);
|
|
6068
|
+
setFieldOptions(field, nextOptions);
|
|
6069
|
+
setLabelOptionsByField((current) => ({
|
|
6070
|
+
...current,
|
|
6071
|
+
[field]: mergeFilterOptions(current[field], nextOptions)
|
|
6072
|
+
}));
|
|
6073
|
+
pageByFieldRef.current = {
|
|
6074
|
+
...pageByFieldRef.current,
|
|
6075
|
+
[field]: page ?? 0
|
|
6076
|
+
};
|
|
6077
|
+
setFieldHasMore(field, hasMore);
|
|
6078
|
+
setFieldLoading(field, false);
|
|
6079
|
+
}, (error) => {
|
|
6080
|
+
if (controller?.signal.aborted) return;
|
|
6081
|
+
console.warn(`[AutoCrud] Failed to load filter data source "${source.key}".`, error);
|
|
6082
|
+
if (!append) {
|
|
6083
|
+
setFieldOptions(field, []);
|
|
6084
|
+
setFieldHasMore(field, false);
|
|
6085
|
+
pageByFieldRef.current = {
|
|
6086
|
+
...pageByFieldRef.current,
|
|
6087
|
+
[field]: 0
|
|
6088
|
+
};
|
|
6089
|
+
}
|
|
6090
|
+
setFieldLoading(field, false);
|
|
6091
|
+
});
|
|
6092
|
+
}, !append && entry.search ? entry.debounceMs : 0);
|
|
6093
|
+
timersRef.current[field] = timer;
|
|
6094
|
+
}, [
|
|
6095
|
+
clearFieldRequest,
|
|
6096
|
+
resetField,
|
|
6097
|
+
setFieldHasMore,
|
|
6098
|
+
setFieldLoading,
|
|
6099
|
+
setFieldOptions
|
|
6100
|
+
]);
|
|
6101
|
+
const setSearchValue = react.useCallback((field, value) => {
|
|
6102
|
+
searchValuesRef.current = {
|
|
6103
|
+
...searchValuesRef.current,
|
|
6104
|
+
[field]: value
|
|
6627
6105
|
};
|
|
6628
|
-
|
|
6629
|
-
|
|
6106
|
+
setSearchValues((current) => current[field] === value ? current : {
|
|
6107
|
+
...current,
|
|
6108
|
+
[field]: value
|
|
6109
|
+
});
|
|
6110
|
+
}, []);
|
|
6111
|
+
react.useEffect(() => {
|
|
6112
|
+
if (sourceEntries.length === 0) {
|
|
6113
|
+
hasMoreByFieldRef.current = {};
|
|
6114
|
+
loadingByFieldRef.current = {};
|
|
6115
|
+
optionsByFieldRef.current = {};
|
|
6116
|
+
pageByFieldRef.current = {};
|
|
6117
|
+
Object.keys(controllersRef.current).forEach(clearFieldRequest);
|
|
6118
|
+
setHasMoreByField({});
|
|
6119
|
+
setLoadingByField({});
|
|
6120
|
+
setOptionsByField({});
|
|
6121
|
+
return;
|
|
6122
|
+
}
|
|
6123
|
+
const activeFields = new Set(sourceEntries.map(({ field }) => field));
|
|
6124
|
+
removeInactiveFieldState(setHasMoreByField, hasMoreByFieldRef, activeFields);
|
|
6125
|
+
removeInactiveFieldState(setLoadingByField, loadingByFieldRef, activeFields);
|
|
6126
|
+
removeInactiveFieldState(setOptionsByField, optionsByFieldRef, activeFields);
|
|
6127
|
+
for (const field of Object.keys(controllersRef.current)) if (!activeFields.has(field)) clearFieldRequest(field);
|
|
6128
|
+
for (const { field } of sourceEntries) loadFieldOptions(field);
|
|
6129
|
+
}, [
|
|
6130
|
+
clearFieldRequest,
|
|
6131
|
+
loadFieldOptions,
|
|
6132
|
+
removeInactiveFieldState,
|
|
6133
|
+
sourceEntries,
|
|
6134
|
+
registryVersion,
|
|
6135
|
+
searchValues
|
|
6136
|
+
]);
|
|
6137
|
+
react.useEffect(() => () => {
|
|
6138
|
+
for (const field of Object.keys(controllersRef.current)) clearFieldRequest(field);
|
|
6139
|
+
}, [clearFieldRequest]);
|
|
6140
|
+
return {
|
|
6141
|
+
hasMoreByField,
|
|
6142
|
+
labelOptionsByField,
|
|
6143
|
+
loadingByField,
|
|
6144
|
+
optionsByField,
|
|
6145
|
+
registeredByField,
|
|
6146
|
+
searchValues,
|
|
6147
|
+
searchableByField,
|
|
6148
|
+
loadMore: (field) => loadFieldOptions(field, true),
|
|
6149
|
+
setSearchValue
|
|
6150
|
+
};
|
|
6630
6151
|
}
|
|
6631
6152
|
function getOptionLabel(value, options) {
|
|
6632
6153
|
const stringValue = String(value);
|
|
@@ -6636,12 +6157,15 @@ function getOptionLabel(value, options) {
|
|
|
6636
6157
|
* 从统一配置生成表格 overrides
|
|
6637
6158
|
* 当 filter 配置存在时,合并到 meta 中(不影响列隐藏)
|
|
6638
6159
|
*/
|
|
6639
|
-
function buildTableOverrides(fields, legacyOverrides,
|
|
6160
|
+
function buildTableOverrides(fields, legacyOverrides, dynamicFilterState) {
|
|
6640
6161
|
const result = { ...legacyOverrides };
|
|
6641
6162
|
if (fields) for (const [key, config] of Object.entries(fields)) {
|
|
6642
6163
|
const fieldOptions = normalizeFieldOptions(config.enum);
|
|
6643
6164
|
const tableOptions = toTableOptions(fieldOptions);
|
|
6644
|
-
const
|
|
6165
|
+
const filterDataSourceRegistered = dynamicFilterState?.registeredByField[key];
|
|
6166
|
+
const filterDataSourceSearchable = dynamicFilterState?.searchableByField[key];
|
|
6167
|
+
const currentDynamicOptions = !fieldOptions && filterDataSourceRegistered ? toTableOptions(dynamicFilterState?.optionsByField[key] ?? []) : void 0;
|
|
6168
|
+
const dynamicOptions = !fieldOptions && filterDataSourceRegistered ? toTableOptions(dynamicFilterState?.labelOptionsByField[key] ?? dynamicFilterState?.optionsByField[key] ?? []) : void 0;
|
|
6645
6169
|
const tableMeta = config.table !== false && typeof config.table === "object" ? config.table.meta : void 0;
|
|
6646
6170
|
const fieldEnumMeta = tableOptions ? {
|
|
6647
6171
|
options: tableOptions,
|
|
@@ -6649,7 +6173,19 @@ function buildTableOverrides(fields, legacyOverrides, dynamicFilterOptions) {
|
|
|
6649
6173
|
} : void 0;
|
|
6650
6174
|
const fieldDataSourceMeta = dynamicOptions ? {
|
|
6651
6175
|
options: dynamicOptions,
|
|
6652
|
-
|
|
6176
|
+
autoCrudFilterOptions: currentDynamicOptions ?? dynamicOptions,
|
|
6177
|
+
autoCrudFilterHasMore: dynamicFilterState?.hasMoreByField[key] ?? false,
|
|
6178
|
+
autoCrudFilterLoading: dynamicFilterState?.loadingByField[key] ?? false,
|
|
6179
|
+
autoCrudFilterOnPopupScroll: (event) => {
|
|
6180
|
+
if (!isNearPopupScrollBottom(event.currentTarget)) return;
|
|
6181
|
+
dynamicFilterState?.loadMore(key);
|
|
6182
|
+
},
|
|
6183
|
+
variant: "multiSelect",
|
|
6184
|
+
...filterDataSourceSearchable ? {
|
|
6185
|
+
autoCrudFilterSearchValue: dynamicFilterState?.searchValues[key] ?? "",
|
|
6186
|
+
autoCrudFilterOnSearch: (value) => dynamicFilterState?.setSearchValue(key, value),
|
|
6187
|
+
autoCrudFilterShouldFilter: false
|
|
6188
|
+
} : void 0
|
|
6653
6189
|
} : void 0;
|
|
6654
6190
|
let filterMeta;
|
|
6655
6191
|
if (config.filter && typeof config.filter === "object") {
|
|
@@ -6701,46 +6237,6 @@ function buildTableOverrides(fields, legacyOverrides, dynamicFilterOptions) {
|
|
|
6701
6237
|
return result;
|
|
6702
6238
|
}
|
|
6703
6239
|
/**
|
|
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
6240
|
* 从统一配置生成隐藏列列表
|
|
6745
6241
|
*/
|
|
6746
6242
|
function buildHiddenColumns(fields, legacyHidden, denyFields) {
|
|
@@ -6804,15 +6300,15 @@ function renderFieldValue(value, type, booleanLocale, options) {
|
|
|
6804
6300
|
if (options && options.length > 0) {
|
|
6805
6301
|
if (Array.isArray(value)) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6806
6302
|
className: "flex gap-1 flex-wrap",
|
|
6807
|
-
children: [value.slice(0, 5).map((v, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
6303
|
+
children: [value.slice(0, 5).map((v, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Badge, {
|
|
6808
6304
|
variant: "secondary",
|
|
6809
6305
|
children: getOptionLabel(v, options)
|
|
6810
|
-
}, i)), value.length > 5 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
6306
|
+
}, i)), value.length > 5 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Badge, {
|
|
6811
6307
|
variant: "outline",
|
|
6812
6308
|
children: ["+", value.length - 5]
|
|
6813
6309
|
})]
|
|
6814
6310
|
});
|
|
6815
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
6311
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Badge, {
|
|
6816
6312
|
variant: "outline",
|
|
6817
6313
|
className: "capitalize",
|
|
6818
6314
|
children: getOptionLabel(value, options)
|
|
@@ -6821,17 +6317,17 @@ function renderFieldValue(value, type, booleanLocale, options) {
|
|
|
6821
6317
|
switch (type) {
|
|
6822
6318
|
case "boolean": return value ? booleanLocale.true : booleanLocale.false;
|
|
6823
6319
|
case "date": return formatDate(value);
|
|
6824
|
-
case "enum": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
6320
|
+
case "enum": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Badge, {
|
|
6825
6321
|
variant: "outline",
|
|
6826
6322
|
className: "capitalize",
|
|
6827
6323
|
children: String(value)
|
|
6828
6324
|
});
|
|
6829
6325
|
case "array": return Array.isArray(value) ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6830
6326
|
className: "flex gap-1 flex-wrap",
|
|
6831
|
-
children: [value.slice(0, 5).map((v, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
6327
|
+
children: [value.slice(0, 5).map((v, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Badge, {
|
|
6832
6328
|
variant: "secondary",
|
|
6833
6329
|
children: String(v)
|
|
6834
|
-
}, i)), value.length > 5 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
6330
|
+
}, i)), value.length > 5 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Badge, {
|
|
6835
6331
|
variant: "outline",
|
|
6836
6332
|
children: ["+", value.length - 5]
|
|
6837
6333
|
})]
|
|
@@ -6868,18 +6364,18 @@ function ViewModal({ open, onOpenChange, variant, data, schema, fields: fieldCon
|
|
|
6868
6364
|
}, key);
|
|
6869
6365
|
})
|
|
6870
6366
|
});
|
|
6871
|
-
if (variant === "sheet") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
6367
|
+
if (variant === "sheet") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Sheet, {
|
|
6872
6368
|
open,
|
|
6873
6369
|
onOpenChange,
|
|
6874
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
6370
|
+
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
6371
|
});
|
|
6876
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
6372
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Dialog, {
|
|
6877
6373
|
open,
|
|
6878
6374
|
onOpenChange,
|
|
6879
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
6375
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.DialogContent, {
|
|
6880
6376
|
"aria-describedby": void 0,
|
|
6881
6377
|
className: "max-w-2xl max-h-[80vh] overflow-y-auto",
|
|
6882
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
6378
|
+
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
6379
|
})
|
|
6884
6380
|
});
|
|
6885
6381
|
}
|
|
@@ -7047,6 +6543,8 @@ function AutoCrudTable({ id, title, description, schema, resource, fields, table
|
|
|
7047
6543
|
rowIds,
|
|
7048
6544
|
selectedRowIds,
|
|
7049
6545
|
selectedCount,
|
|
6546
|
+
isRefreshing: resource.tableData.isFetching,
|
|
6547
|
+
...resource.handlers.refresh ? { refresh: resource.handlers.refresh } : {},
|
|
7050
6548
|
...toolbarOpenCreate ? { openCreate: toolbarOpenCreate } : {}
|
|
7051
6549
|
}), [
|
|
7052
6550
|
id,
|
|
@@ -7054,6 +6552,8 @@ function AutoCrudTable({ id, title, description, schema, resource, fields, table
|
|
|
7054
6552
|
rowIds,
|
|
7055
6553
|
selectedRowIds,
|
|
7056
6554
|
selectedCount,
|
|
6555
|
+
resource.handlers.refresh,
|
|
6556
|
+
resource.tableData.isFetching,
|
|
7057
6557
|
toolbarOpenCreate
|
|
7058
6558
|
]);
|
|
7059
6559
|
const resolvedToolbarActions = resolveToolbarActionsWithResolver(id, registryToolbarActions, toolbarContext);
|
|
@@ -7167,20 +6667,31 @@ function AutoCrudTable({ id, title, description, schema, resource, fields, table
|
|
|
7167
6667
|
className: "flex items-center justify-end gap-4",
|
|
7168
6668
|
children: (() => {
|
|
7169
6669
|
const renderBuiltinButton = (type, overrides) => {
|
|
7170
|
-
if (type === "
|
|
6670
|
+
if (type === "refresh") {
|
|
6671
|
+
const onRefresh = overrides?.onClick ?? resource.handlers.refresh;
|
|
6672
|
+
if (!onRefresh) return null;
|
|
6673
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
6674
|
+
variant: "outline",
|
|
6675
|
+
size: "sm",
|
|
6676
|
+
onClick: onRefresh,
|
|
6677
|
+
disabled: resource.tableData.isFetching,
|
|
6678
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.RefreshCw, { className: resource.tableData.isFetching ? "mr-2 h-4 w-4 animate-spin" : "mr-2 h-4 w-4" }), overrides?.label ?? locale.toolbar.refresh]
|
|
6679
|
+
}, "refresh");
|
|
6680
|
+
}
|
|
6681
|
+
if (type === "import" && canImport) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
7171
6682
|
variant: "outline",
|
|
7172
6683
|
size: "sm",
|
|
7173
6684
|
onClick: overrides?.onClick ?? (() => setImportOpen(true)),
|
|
7174
6685
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Download, { className: "mr-2 h-4 w-4" }), overrides?.label ?? locale.toolbar.import]
|
|
7175
6686
|
}, "import");
|
|
7176
|
-
if (type === "export" && canExport) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
6687
|
+
if (type === "export" && canExport) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
7177
6688
|
variant: "outline",
|
|
7178
6689
|
size: "sm",
|
|
7179
6690
|
onClick: overrides?.onClick ?? handleExportClick,
|
|
7180
6691
|
disabled: exporting || selectedCount === 0 && !resource.handlers.export,
|
|
7181
6692
|
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
6693
|
}, "export");
|
|
7183
|
-
if (type === "create" && can.create) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
6694
|
+
if (type === "create" && can.create) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
7184
6695
|
onClick: overrides?.onClick ?? onCreate ?? resource.handlers.openCreate,
|
|
7185
6696
|
children: overrides?.label ?? locale.toolbar.create
|
|
7186
6697
|
}, "create");
|
|
@@ -7195,6 +6706,7 @@ function AutoCrudTable({ id, title, description, schema, resource, fields, table
|
|
|
7195
6706
|
className: "flex items-center gap-2",
|
|
7196
6707
|
children: [
|
|
7197
6708
|
startNodes,
|
|
6709
|
+
renderBuiltinButton("refresh"),
|
|
7198
6710
|
renderBuiltinButton("import"),
|
|
7199
6711
|
renderBuiltinButton("export"),
|
|
7200
6712
|
renderBuiltinButton("create"),
|
|
@@ -7204,13 +6716,20 @@ function AutoCrudTable({ id, title, description, schema, resource, fields, table
|
|
|
7204
6716
|
}
|
|
7205
6717
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7206
6718
|
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 (!(
|
|
7210
|
-
|
|
7211
|
-
|
|
7212
|
-
|
|
7213
|
-
|
|
6719
|
+
children: resolvedToolbarActions.map((action$1, index$1) => {
|
|
6720
|
+
if (action$1.type === "custom") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children: renderToolbarComponent(action$1.component) }, `custom-${index$1}`);
|
|
6721
|
+
if (!(() => {
|
|
6722
|
+
switch (action$1.type) {
|
|
6723
|
+
case "refresh": return !!(resource.handlers.refresh || action$1.onClick || action$1.component);
|
|
6724
|
+
case "import": return canImport;
|
|
6725
|
+
case "export": return canExport;
|
|
6726
|
+
case "create": return can.create;
|
|
6727
|
+
}
|
|
6728
|
+
})()) return null;
|
|
6729
|
+
if (action$1.component) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children: renderToolbarComponent(action$1.component) }, action$1.type);
|
|
6730
|
+
return renderBuiltinButton(action$1.type, {
|
|
6731
|
+
onClick: action$1.onClick,
|
|
6732
|
+
label: action$1.label
|
|
7214
6733
|
});
|
|
7215
6734
|
})
|
|
7216
6735
|
});
|
|
@@ -7229,6 +6748,7 @@ function AutoCrudTable({ id, title, description, schema, resource, fields, table
|
|
|
7229
6748
|
onUpdateSelected: can.update ? resource.handlers.updateMany : void 0,
|
|
7230
6749
|
batchUpdateFields: can.update ? batchFields : void 0,
|
|
7231
6750
|
actionBarActions: registryBatchActions,
|
|
6751
|
+
deleteConfirmation: locale.bulkDeleteModal,
|
|
7232
6752
|
enableExport: canExport,
|
|
7233
6753
|
showDefaultExport: false,
|
|
7234
6754
|
initialSorting: tableConfig?.defaultSort,
|
|
@@ -7248,6 +6768,7 @@ function AutoCrudTable({ id, title, description, schema, resource, fields, table
|
|
|
7248
6768
|
loading: resource.mutations.isCreating || resource.mutations.isUpdating,
|
|
7249
6769
|
variant: resource.modal.variant,
|
|
7250
6770
|
overrides: formOverrides,
|
|
6771
|
+
scope: formConfig?.scope,
|
|
7251
6772
|
locale: locale.formModal,
|
|
7252
6773
|
gridColumns: formConfig?.columns,
|
|
7253
6774
|
className: formConfig?.className
|
|
@@ -7259,14 +6780,14 @@ function AutoCrudTable({ id, title, description, schema, resource, fields, table
|
|
|
7259
6780
|
data: resource.modal.selected,
|
|
7260
6781
|
schema: resolvedSchema,
|
|
7261
6782
|
fields: resolvedFields,
|
|
7262
|
-
dynamicOptions: dynamicFilterOptions,
|
|
6783
|
+
dynamicOptions: dynamicFilterOptions.optionsByField,
|
|
7263
6784
|
denyFields,
|
|
7264
6785
|
locale
|
|
7265
6786
|
}),
|
|
7266
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
6787
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.AlertDialog, {
|
|
7267
6788
|
open: resource.modal.deleteOpen,
|
|
7268
6789
|
onOpenChange: (open) => !open && resource.handlers.closeModals(),
|
|
7269
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
6790
|
+
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
6791
|
onClick: resource.handlers.confirmDelete,
|
|
7271
6792
|
disabled: resource.mutations.isDeleting,
|
|
7272
6793
|
children: resource.mutations.isDeleting ? locale.deleteModal.confirming : locale.deleteModal.confirm
|
|
@@ -7307,12 +6828,12 @@ function ExportDialog({ open, onOpenChange, selectedCount, onExport, canExportFi
|
|
|
7307
6828
|
}
|
|
7308
6829
|
}, [onExport, handleOpenChange]);
|
|
7309
6830
|
const hasSelected = selectedCount > 0;
|
|
7310
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
6831
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Dialog, {
|
|
7311
6832
|
open,
|
|
7312
6833
|
onOpenChange: handleOpenChange,
|
|
7313
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
6834
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.DialogContent, {
|
|
7314
6835
|
className: "sm:max-w-[400px]",
|
|
7315
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
6836
|
+
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
6837
|
className: "flex flex-col items-center gap-3 py-6",
|
|
7317
6838
|
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
6839
|
className: "text-sm text-muted-foreground",
|
|
@@ -7320,7 +6841,7 @@ function ExportDialog({ open, onOpenChange, selectedCount, onExport, canExportFi
|
|
|
7320
6841
|
})]
|
|
7321
6842
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7322
6843
|
className: "grid gap-3 py-2",
|
|
7323
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
6844
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
7324
6845
|
variant: "outline",
|
|
7325
6846
|
className: "h-auto justify-start gap-3 px-4 py-3",
|
|
7326
6847
|
disabled: !hasSelected || exporting !== null,
|
|
@@ -7335,7 +6856,7 @@ function ExportDialog({ open, onOpenChange, selectedCount, onExport, canExportFi
|
|
|
7335
6856
|
children: hasSelected ? "导出当前勾选的数据行" : "请先在表格中勾选数据行"
|
|
7336
6857
|
})]
|
|
7337
6858
|
})]
|
|
7338
|
-
}), canExportFiltered && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
6859
|
+
}), canExportFiltered && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
7339
6860
|
variant: "outline",
|
|
7340
6861
|
className: "h-auto justify-start gap-3 px-4 py-3",
|
|
7341
6862
|
disabled: exporting !== null,
|
|
@@ -7382,19 +6903,33 @@ function DataTableAdvancedToolbar({ table, children, className,...props }) {
|
|
|
7382
6903
|
function DataTableFacetedFilter({ column, title, options, multiple }) {
|
|
7383
6904
|
const columnFilterValue = column?.getFilterValue();
|
|
7384
6905
|
const selectedValues = Array.isArray(columnFilterValue) ? columnFilterValue.filter((value) => typeof value === "string") : [];
|
|
6906
|
+
const currentOptions = column?.columnDef.meta?.autoCrudFilterOptions ?? options;
|
|
6907
|
+
const currentOptionValues = new Set(currentOptions.map((option) => option.value));
|
|
6908
|
+
const selectedOptionValues = new Set(selectedValues);
|
|
6909
|
+
const comboboxOptions = currentOptions === options ? currentOptions : [...options.filter((option) => selectedOptionValues.has(option.value) && !currentOptionValues.has(option.value)), ...currentOptions];
|
|
7385
6910
|
const onChange = (nextValues) => {
|
|
7386
6911
|
column?.setFilterValue(nextValues.length ? nextValues : void 0);
|
|
7387
6912
|
};
|
|
7388
|
-
|
|
7389
|
-
|
|
7390
|
-
|
|
7391
|
-
|
|
7392
|
-
|
|
6913
|
+
const onSelectChange = (nextValue) => {
|
|
6914
|
+
onChange(Array.isArray(nextValue) ? nextValue : nextValue ? [nextValue] : []);
|
|
6915
|
+
};
|
|
6916
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn_ui.Select, {
|
|
6917
|
+
mode: "searchable",
|
|
6918
|
+
multiple: Boolean(multiple),
|
|
6919
|
+
value: multiple ? selectedValues : selectedValues[0] ?? "",
|
|
6920
|
+
onChange: onSelectChange,
|
|
6921
|
+
options: comboboxOptions,
|
|
7393
6922
|
searchPlaceholder: title,
|
|
6923
|
+
hasMore: column?.columnDef.meta?.autoCrudFilterHasMore,
|
|
6924
|
+
loading: column?.columnDef.meta?.autoCrudFilterLoading,
|
|
6925
|
+
searchValue: column?.columnDef.meta?.autoCrudFilterSearchValue,
|
|
6926
|
+
shouldFilter: column?.columnDef.meta?.autoCrudFilterShouldFilter,
|
|
6927
|
+
onPopupScroll: column?.columnDef.meta?.autoCrudFilterOnPopupScroll,
|
|
6928
|
+
onSearch: column?.columnDef.meta?.autoCrudFilterOnSearch,
|
|
7394
6929
|
contentClassName: "w-50",
|
|
7395
6930
|
matchTriggerWidth: false,
|
|
7396
6931
|
clearText: "Clear filters",
|
|
7397
|
-
renderTrigger: ({ selectedOptions, selectedValues: selectedValues$1, clearSelection }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
6932
|
+
renderTrigger: ({ selectedOptions, selectedValues: selectedValues$1, clearSelection }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
7398
6933
|
type: "button",
|
|
7399
6934
|
variant: "outline",
|
|
7400
6935
|
size: "sm",
|
|
@@ -7411,22 +6946,22 @@ function DataTableFacetedFilter({ column, title, options, multiple }) {
|
|
|
7411
6946
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.PlusCircle, {}),
|
|
7412
6947
|
title,
|
|
7413
6948
|
selectedValues$1.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
7414
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
6949
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Separator, {
|
|
7415
6950
|
orientation: "vertical",
|
|
7416
6951
|
className: "mx-0.5 data-[orientation=vertical]:h-4"
|
|
7417
6952
|
}),
|
|
7418
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
6953
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Badge, {
|
|
7419
6954
|
variant: "secondary",
|
|
7420
6955
|
className: "rounded-sm px-1 font-normal lg:hidden",
|
|
7421
6956
|
children: selectedValues$1.length
|
|
7422
6957
|
}),
|
|
7423
6958
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7424
6959
|
className: "hidden items-center gap-1 lg:flex",
|
|
7425
|
-
children: selectedValues$1.length > 2 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
6960
|
+
children: selectedValues$1.length > 2 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Badge, {
|
|
7426
6961
|
variant: "secondary",
|
|
7427
6962
|
className: "rounded-sm px-1 font-normal",
|
|
7428
6963
|
children: [selectedValues$1.length, " selected"]
|
|
7429
|
-
}) : selectedOptions.map((option) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
6964
|
+
}) : selectedOptions.map((option) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Badge, {
|
|
7430
6965
|
variant: "secondary",
|
|
7431
6966
|
className: "rounded-sm px-1 font-normal",
|
|
7432
6967
|
children: option.label
|
|
@@ -7566,7 +7101,7 @@ function DataTableDateFilter({ column, title, multiple }) {
|
|
|
7566
7101
|
const dateText$1 = hasSelectedDates ? formatDateRange(selectedDates) : "Select date range";
|
|
7567
7102
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
7568
7103
|
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)(
|
|
7104
|
+
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
7105
|
orientation: "vertical",
|
|
7571
7106
|
className: "mx-0.5 data-[orientation=vertical]:h-4"
|
|
7572
7107
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: dateText$1 })] })]
|
|
@@ -7577,7 +7112,7 @@ function DataTableDateFilter({ column, title, multiple }) {
|
|
|
7577
7112
|
const dateText = hasSelectedDate ? formatDate(selectedDates[0]) : "Select date";
|
|
7578
7113
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
7579
7114
|
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)(
|
|
7115
|
+
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
7116
|
orientation: "vertical",
|
|
7582
7117
|
className: "mx-0.5 data-[orientation=vertical]:h-4"
|
|
7583
7118
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: dateText })] })]
|
|
@@ -7588,9 +7123,9 @@ function DataTableDateFilter({ column, title, multiple }) {
|
|
|
7588
7123
|
formatDateRange,
|
|
7589
7124
|
title
|
|
7590
7125
|
]);
|
|
7591
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
7126
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Popover, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.PopoverTrigger, {
|
|
7592
7127
|
asChild: true,
|
|
7593
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
7128
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
7594
7129
|
variant: "outline",
|
|
7595
7130
|
size: "sm",
|
|
7596
7131
|
className: "border-dashed font-normal",
|
|
@@ -7603,16 +7138,16 @@ function DataTableDateFilter({ column, title, multiple }) {
|
|
|
7603
7138
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.XCircle, {})
|
|
7604
7139
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.CalendarIcon, {}), label]
|
|
7605
7140
|
})
|
|
7606
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
7141
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.PopoverContent, {
|
|
7607
7142
|
className: "w-auto p-0",
|
|
7608
7143
|
align: "start",
|
|
7609
|
-
children: multiple ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
7144
|
+
children: multiple ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Calendar, {
|
|
7610
7145
|
autoFocus: true,
|
|
7611
7146
|
captionLayout: "dropdown",
|
|
7612
7147
|
mode: "range",
|
|
7613
7148
|
selected: localRange,
|
|
7614
7149
|
onSelect
|
|
7615
|
-
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
7150
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Calendar, {
|
|
7616
7151
|
captionLayout: "dropdown",
|
|
7617
7152
|
mode: "single",
|
|
7618
7153
|
selected: !getIsDateRange(selectedDates) ? selectedDates[0] : void 0,
|
|
@@ -7701,9 +7236,9 @@ function DataTableSliderFilter({ column, title }) {
|
|
|
7701
7236
|
if (event.target instanceof HTMLDivElement) event.stopPropagation();
|
|
7702
7237
|
column.setFilterValue(void 0);
|
|
7703
7238
|
}, [column]);
|
|
7704
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
7239
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Popover, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.PopoverTrigger, {
|
|
7705
7240
|
asChild: true,
|
|
7706
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
7241
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
7707
7242
|
variant: "outline",
|
|
7708
7243
|
size: "sm",
|
|
7709
7244
|
className: "border-dashed font-normal",
|
|
@@ -7718,7 +7253,7 @@ function DataTableSliderFilter({ column, title }) {
|
|
|
7718
7253
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.PlusCircle, {}),
|
|
7719
7254
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: title }),
|
|
7720
7255
|
columnFilterValue ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
7721
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
7256
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Separator, {
|
|
7722
7257
|
orientation: "vertical",
|
|
7723
7258
|
className: "mx-0.5 data-[orientation=vertical]:h-4"
|
|
7724
7259
|
}),
|
|
@@ -7730,7 +7265,7 @@ function DataTableSliderFilter({ column, title }) {
|
|
|
7730
7265
|
] }) : null
|
|
7731
7266
|
]
|
|
7732
7267
|
})
|
|
7733
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
7268
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.PopoverContent, {
|
|
7734
7269
|
align: "start",
|
|
7735
7270
|
className: "flex w-auto flex-col gap-4",
|
|
7736
7271
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -7743,14 +7278,14 @@ function DataTableSliderFilter({ column, title }) {
|
|
|
7743
7278
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7744
7279
|
className: "flex items-center gap-4",
|
|
7745
7280
|
children: [
|
|
7746
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
7281
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Label, {
|
|
7747
7282
|
htmlFor: `${id}-from`,
|
|
7748
7283
|
className: "sr-only",
|
|
7749
7284
|
children: "From"
|
|
7750
7285
|
}),
|
|
7751
7286
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7752
7287
|
className: "relative",
|
|
7753
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
7288
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Input, {
|
|
7754
7289
|
id: `${id}-from`,
|
|
7755
7290
|
type: "number",
|
|
7756
7291
|
"aria-valuemin": min,
|
|
@@ -7768,14 +7303,14 @@ function DataTableSliderFilter({ column, title }) {
|
|
|
7768
7303
|
children: unit
|
|
7769
7304
|
})]
|
|
7770
7305
|
}),
|
|
7771
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
7306
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Label, {
|
|
7772
7307
|
htmlFor: `${id}-to`,
|
|
7773
7308
|
className: "sr-only",
|
|
7774
7309
|
children: "to"
|
|
7775
7310
|
}),
|
|
7776
7311
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7777
7312
|
className: "relative",
|
|
7778
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
7313
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Input, {
|
|
7779
7314
|
id: `${id}-to`,
|
|
7780
7315
|
type: "number",
|
|
7781
7316
|
"aria-valuemin": min,
|
|
@@ -7795,12 +7330,12 @@ function DataTableSliderFilter({ column, title }) {
|
|
|
7795
7330
|
})
|
|
7796
7331
|
]
|
|
7797
7332
|
}),
|
|
7798
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
7333
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Label, {
|
|
7799
7334
|
htmlFor: `${id}-slider`,
|
|
7800
7335
|
className: "sr-only",
|
|
7801
7336
|
children: [title, " slider"]
|
|
7802
7337
|
}),
|
|
7803
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
7338
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Slider, {
|
|
7804
7339
|
id: `${id}-slider`,
|
|
7805
7340
|
min,
|
|
7806
7341
|
max,
|
|
@@ -7810,7 +7345,7 @@ function DataTableSliderFilter({ column, title }) {
|
|
|
7810
7345
|
onValueCommit: onSliderValueCommit
|
|
7811
7346
|
})
|
|
7812
7347
|
]
|
|
7813
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
7348
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Button, {
|
|
7814
7349
|
"aria-label": `Clear ${title} filter`,
|
|
7815
7350
|
variant: "outline",
|
|
7816
7351
|
size: "sm",
|
|
@@ -7835,7 +7370,7 @@ function DataTableToolbar({ table, children, className,...props }) {
|
|
|
7835
7370
|
...props,
|
|
7836
7371
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7837
7372
|
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)(
|
|
7373
|
+
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
7374
|
"aria-label": "Reset filters",
|
|
7840
7375
|
variant: "outline",
|
|
7841
7376
|
size: "sm",
|
|
@@ -7860,7 +7395,7 @@ function DataTableToolbarFilter({ column }) {
|
|
|
7860
7395
|
const modes = columnMeta.modes;
|
|
7861
7396
|
if (modes && !modes.includes("advanced")) return null;
|
|
7862
7397
|
switch (columnMeta.variant) {
|
|
7863
|
-
case "text": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
7398
|
+
case "text": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Input, {
|
|
7864
7399
|
placeholder: columnMeta.placeholder ?? columnMeta.label,
|
|
7865
7400
|
value: column.getFilterValue() ?? "",
|
|
7866
7401
|
onChange: (event) => column.setFilterValue(event.target.value),
|
|
@@ -7868,7 +7403,7 @@ function DataTableToolbarFilter({ column }) {
|
|
|
7868
7403
|
});
|
|
7869
7404
|
case "number": return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7870
7405
|
className: "relative",
|
|
7871
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
7406
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Input, {
|
|
7872
7407
|
type: "number",
|
|
7873
7408
|
inputMode: "numeric",
|
|
7874
7409
|
placeholder: columnMeta.placeholder ?? columnMeta.label,
|
|
@@ -7969,8 +7504,8 @@ function readMetadataFields(fields) {
|
|
|
7969
7504
|
/**
|
|
7970
7505
|
* Modal 状态 Reducer
|
|
7971
7506
|
*/
|
|
7972
|
-
function modalReducer(state, action) {
|
|
7973
|
-
switch (action.type) {
|
|
7507
|
+
function modalReducer(state, action$1) {
|
|
7508
|
+
switch (action$1.type) {
|
|
7974
7509
|
case "OPEN_CREATE": return {
|
|
7975
7510
|
...state,
|
|
7976
7511
|
createOpen: true,
|
|
@@ -7981,22 +7516,22 @@ function modalReducer(state, action) {
|
|
|
7981
7516
|
...state,
|
|
7982
7517
|
createOpen: true,
|
|
7983
7518
|
selected: null,
|
|
7984
|
-
copySource: action.payload
|
|
7519
|
+
copySource: action$1.payload
|
|
7985
7520
|
};
|
|
7986
7521
|
case "OPEN_EDIT": return {
|
|
7987
7522
|
...state,
|
|
7988
7523
|
editOpen: true,
|
|
7989
|
-
selected: action.payload
|
|
7524
|
+
selected: action$1.payload
|
|
7990
7525
|
};
|
|
7991
7526
|
case "OPEN_DELETE": return {
|
|
7992
7527
|
...state,
|
|
7993
7528
|
deleteOpen: true,
|
|
7994
|
-
selected: action.payload
|
|
7529
|
+
selected: action$1.payload
|
|
7995
7530
|
};
|
|
7996
7531
|
case "OPEN_VIEW": return {
|
|
7997
7532
|
...state,
|
|
7998
7533
|
viewOpen: true,
|
|
7999
|
-
selected: action.payload
|
|
7534
|
+
selected: action$1.payload
|
|
8000
7535
|
};
|
|
8001
7536
|
case "CLOSE_ALL": return {
|
|
8002
7537
|
...state,
|
|
@@ -8009,7 +7544,7 @@ function modalReducer(state, action) {
|
|
|
8009
7544
|
};
|
|
8010
7545
|
case "SET_VARIANT": return {
|
|
8011
7546
|
...state,
|
|
8012
|
-
variant: action.payload
|
|
7547
|
+
variant: action$1.payload
|
|
8013
7548
|
};
|
|
8014
7549
|
default: return state;
|
|
8015
7550
|
}
|
|
@@ -8306,6 +7841,9 @@ function useAutoCrudResource({ router, schema, query: queryTransform, options =
|
|
|
8306
7841
|
queryInput
|
|
8307
7842
|
]);
|
|
8308
7843
|
const canExport = !!(exportFetcher || exportQuery);
|
|
7844
|
+
const refresh = (0, react.useCallback)(async () => {
|
|
7845
|
+
return listQuery.refetch();
|
|
7846
|
+
}, [listQuery]);
|
|
8309
7847
|
return {
|
|
8310
7848
|
idKey,
|
|
8311
7849
|
tableData: {
|
|
@@ -8336,6 +7874,7 @@ function useAutoCrudResource({ router, schema, query: queryTransform, options =
|
|
|
8336
7874
|
deleteMany,
|
|
8337
7875
|
updateMany,
|
|
8338
7876
|
setVariant,
|
|
7877
|
+
refresh,
|
|
8339
7878
|
import: importMutation ? handleImport : null,
|
|
8340
7879
|
export: canExport ? handleExport : null
|
|
8341
7880
|
}
|
|
@@ -8662,8 +8201,19 @@ exports.DataTableToolbar = DataTableToolbar;
|
|
|
8662
8201
|
exports.DataTableViewOptions = DataTableViewOptions;
|
|
8663
8202
|
exports.ExportDialog = ExportDialog;
|
|
8664
8203
|
exports.ImportDialog = ImportDialog;
|
|
8665
|
-
exports
|
|
8204
|
+
Object.defineProperty(exports, 'MultiCombobox', {
|
|
8205
|
+
enumerable: true,
|
|
8206
|
+
get: function () {
|
|
8207
|
+
return __wordrhyme_shadcn_ui.MultiCombobox;
|
|
8208
|
+
}
|
|
8209
|
+
});
|
|
8666
8210
|
exports.SchemaAdapter = SchemaAdapter;
|
|
8211
|
+
Object.defineProperty(exports, 'Select', {
|
|
8212
|
+
enumerable: true,
|
|
8213
|
+
get: function () {
|
|
8214
|
+
return __wordrhyme_shadcn_ui.Select;
|
|
8215
|
+
}
|
|
8216
|
+
});
|
|
8667
8217
|
exports.cn = cn;
|
|
8668
8218
|
exports.coerceRowValues = coerceRowValues;
|
|
8669
8219
|
exports.components = components;
|