@wordrhyme/auto-crud 1.5.7 → 1.6.0
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/README.md +37 -0
- package/dist/index.cjs +329 -186
- package/dist/index.d.cts +19 -5
- package/dist/index.d.ts +19 -5
- package/dist/index.js +329 -186
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -420,13 +420,15 @@ function hasValidCanonicalDateTimePrefix(value) {
|
|
|
420
420
|
const match = canonicalDateTimePrefixPattern.exec(value);
|
|
421
421
|
return !match || isValidCalendarDate(match[1], match[2], match[3]);
|
|
422
422
|
}
|
|
423
|
+
function getDateLocaleOptions() {
|
|
424
|
+
return hostDateFormatters[hostDateFormatters.length - 1]?.options;
|
|
425
|
+
}
|
|
423
426
|
/**
|
|
424
|
-
* Register the host's
|
|
425
|
-
*
|
|
426
|
-
* this registration, so overlapping registrations may be disposed out of order.
|
|
427
|
+
* Register the host's date formatter and optional calendar locale policy.
|
|
428
|
+
* Cleanup removes only this registration, including out-of-order cleanup.
|
|
427
429
|
* Passing undefined clears every registration.
|
|
428
430
|
*/
|
|
429
|
-
function setDateFormatter(formatter) {
|
|
431
|
+
function setDateFormatter(formatter, options) {
|
|
430
432
|
if (formatter === void 0) {
|
|
431
433
|
const hadFormatter = hostDateFormatters.length > 0;
|
|
432
434
|
hostDateFormatters = [];
|
|
@@ -435,15 +437,16 @@ function setDateFormatter(formatter) {
|
|
|
435
437
|
}
|
|
436
438
|
const registration = {
|
|
437
439
|
formatter,
|
|
440
|
+
...options ? { options } : {},
|
|
438
441
|
token: Symbol("date-formatter")
|
|
439
442
|
};
|
|
440
443
|
hostDateFormatters.push(registration);
|
|
441
444
|
notifyDateFormatterChange();
|
|
442
445
|
return () => {
|
|
443
|
-
const
|
|
446
|
+
const currentRegistration = hostDateFormatters[hostDateFormatters.length - 1];
|
|
444
447
|
const previousLength = hostDateFormatters.length;
|
|
445
448
|
hostDateFormatters = hostDateFormatters.filter(({ token }) => token !== registration.token);
|
|
446
|
-
if (hostDateFormatters.length !== previousLength &&
|
|
449
|
+
if (hostDateFormatters.length !== previousLength && hostDateFormatters[hostDateFormatters.length - 1] !== currentRegistration) notifyDateFormatterChange();
|
|
447
450
|
};
|
|
448
451
|
}
|
|
449
452
|
function formatDate(date, opts = {}, preset) {
|
|
@@ -1043,6 +1046,71 @@ function useDebouncedCallback(callback, delay) {
|
|
|
1043
1046
|
}, [handleCallback, delay]);
|
|
1044
1047
|
}
|
|
1045
1048
|
|
|
1049
|
+
//#endregion
|
|
1050
|
+
//#region src/lib/calendar-date.ts
|
|
1051
|
+
/** Calendar days are wall dates, never instants in the host's time zone. */
|
|
1052
|
+
function serializeCalendarDate(date) {
|
|
1053
|
+
return `${String(date.getFullYear()).padStart(4, "0")}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}`;
|
|
1054
|
+
}
|
|
1055
|
+
function parseCalendarDate(value) {
|
|
1056
|
+
if (value === void 0 || value === "") return void 0;
|
|
1057
|
+
if (typeof value === "string" && /^\d{4}-\d{2}-\d{2}$/.test(value)) {
|
|
1058
|
+
const date$1 = /* @__PURE__ */ new Date(`${value}T00:00:00`);
|
|
1059
|
+
return !Number.isNaN(date$1.getTime()) && serializeCalendarDate(date$1) === value ? date$1 : void 0;
|
|
1060
|
+
}
|
|
1061
|
+
const date = new Date(Number(value));
|
|
1062
|
+
return Number.isNaN(date.getTime()) ? void 0 : date;
|
|
1063
|
+
}
|
|
1064
|
+
function calendarPresentation() {
|
|
1065
|
+
const localeOptions = getDateLocaleOptions();
|
|
1066
|
+
const locale = localeOptions?.locale ?? "en-US";
|
|
1067
|
+
const chinese = locale.toLowerCase().startsWith("zh");
|
|
1068
|
+
const localeInfo = new Intl.Locale(locale);
|
|
1069
|
+
const firstDay = localeInfo.getWeekInfo?.().firstDay ?? localeInfo.weekInfo?.firstDay ?? (chinese ? 1 : 7);
|
|
1070
|
+
const format = (date, options) => new Intl.DateTimeFormat(locale, {
|
|
1071
|
+
...options,
|
|
1072
|
+
timeZone: "UTC"
|
|
1073
|
+
}).format(/* @__PURE__ */ new Date(`${serializeCalendarDate(date)}T00:00:00Z`));
|
|
1074
|
+
return {
|
|
1075
|
+
locale,
|
|
1076
|
+
weekStartsOn: firstDay % 7,
|
|
1077
|
+
formatDate: (date) => {
|
|
1078
|
+
if (!localeOptions) return formatDate(date);
|
|
1079
|
+
return date ? format(date, {
|
|
1080
|
+
year: "numeric",
|
|
1081
|
+
month: "long",
|
|
1082
|
+
day: "numeric"
|
|
1083
|
+
}) : "";
|
|
1084
|
+
},
|
|
1085
|
+
clearLabel: (title) => chinese ? `清除${title ?? ""}筛选` : `Clear ${title ?? ""} filter`,
|
|
1086
|
+
formatters: {
|
|
1087
|
+
formatCaption: (date) => format(date, {
|
|
1088
|
+
year: "numeric",
|
|
1089
|
+
month: "long"
|
|
1090
|
+
}),
|
|
1091
|
+
formatMonthDropdown: (date) => format(date, { month: "long" }),
|
|
1092
|
+
formatWeekdayName: (date) => format(date, { weekday: "short" })
|
|
1093
|
+
},
|
|
1094
|
+
labels: {
|
|
1095
|
+
labelNext: () => chinese ? "下个月" : "Go to the Next Month",
|
|
1096
|
+
labelPrevious: () => chinese ? "上个月" : "Go to the Previous Month",
|
|
1097
|
+
labelMonthDropdown: () => chinese ? "选择月份" : "Choose the Month",
|
|
1098
|
+
labelYearDropdown: () => chinese ? "选择年份" : "Choose the Year",
|
|
1099
|
+
labelGrid: (date) => format(date, {
|
|
1100
|
+
year: "numeric",
|
|
1101
|
+
month: "long"
|
|
1102
|
+
}),
|
|
1103
|
+
labelWeekday: (date) => format(date, { weekday: "long" }),
|
|
1104
|
+
labelDayButton: (date) => format(date, {
|
|
1105
|
+
year: "numeric",
|
|
1106
|
+
month: "long",
|
|
1107
|
+
day: "numeric",
|
|
1108
|
+
weekday: "long"
|
|
1109
|
+
})
|
|
1110
|
+
}
|
|
1111
|
+
};
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1046
1114
|
//#endregion
|
|
1047
1115
|
//#region src/components/data-table/data-table-filter-list.tsx
|
|
1048
1116
|
const DEBOUNCE_MS$2 = 300;
|
|
@@ -1214,6 +1282,7 @@ function DataTableFilterList({ table, debounceMs = DEBOUNCE_MS$2, throttleMs = T
|
|
|
1214
1282
|
});
|
|
1215
1283
|
}
|
|
1216
1284
|
function DataTableFilterItem$1({ filter, index: index$1, filterItemId, joinOperator, setJoinOperator, columns, onFilterUpdate, onFilterRemove }) {
|
|
1285
|
+
useDateFormatterVersion();
|
|
1217
1286
|
const [showFieldSelector, setShowFieldSelector] = react.useState(false);
|
|
1218
1287
|
const [showOperatorSelector, setShowOperatorSelector] = react.useState(false);
|
|
1219
1288
|
const [showValueSelector, setShowValueSelector] = react.useState(false);
|
|
@@ -1502,10 +1571,10 @@ function onFilterInputRender$1({ filter, inputId, column, columnMeta, onFilterUp
|
|
|
1502
1571
|
case "dateRange": {
|
|
1503
1572
|
const inputListboxId = `${inputId}-listbox`;
|
|
1504
1573
|
const dateValue = Array.isArray(filter.value) ? filter.value.filter(Boolean) : [filter.value, filter.value].filter(Boolean);
|
|
1505
|
-
const startDate = dateValue[0] ?
|
|
1506
|
-
const endDate = dateValue[1] ?
|
|
1574
|
+
const startDate = dateValue[0] ? parseCalendarDate(dateValue[0]) : void 0;
|
|
1575
|
+
const endDate = dateValue[1] ? parseCalendarDate(dateValue[1]) : void 0;
|
|
1507
1576
|
const isSameDate = startDate && endDate && startDate.toDateString() === endDate.toDateString();
|
|
1508
|
-
const displayValue = filter.operator === "isBetween" && dateValue.length === 2 && !isSameDate ? `${formatDate(startDate
|
|
1577
|
+
const displayValue = filter.operator === "isBetween" && dateValue.length === 2 && !isSameDate ? `${calendarPresentation().formatDate(startDate)} - ${calendarPresentation().formatDate(endDate)}` : startDate ? calendarPresentation().formatDate(startDate) : "Pick a date";
|
|
1509
1578
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Popover, {
|
|
1510
1579
|
open: showValueSelector,
|
|
1511
1580
|
onOpenChange: setShowValueSelector,
|
|
@@ -1528,28 +1597,36 @@ function onFilterInputRender$1({ filter, inputId, column, columnMeta, onFilterUp
|
|
|
1528
1597
|
align: "start",
|
|
1529
1598
|
className: "w-auto p-0",
|
|
1530
1599
|
children: filter.operator === "isBetween" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Calendar, {
|
|
1600
|
+
lang: calendarPresentation().locale,
|
|
1601
|
+
weekStartsOn: calendarPresentation().weekStartsOn,
|
|
1602
|
+
formatters: calendarPresentation().formatters,
|
|
1603
|
+
labels: calendarPresentation().labels,
|
|
1531
1604
|
"aria-label": `Select ${columnMeta?.label} date range`,
|
|
1532
1605
|
autoFocus: true,
|
|
1533
1606
|
captionLayout: "dropdown",
|
|
1534
1607
|
mode: "range",
|
|
1535
1608
|
selected: dateValue.length === 2 ? {
|
|
1536
|
-
from:
|
|
1537
|
-
to:
|
|
1609
|
+
from: parseCalendarDate(dateValue[0]),
|
|
1610
|
+
to: parseCalendarDate(dateValue[1])
|
|
1538
1611
|
} : {
|
|
1539
1612
|
from: /* @__PURE__ */ new Date(),
|
|
1540
1613
|
to: /* @__PURE__ */ new Date()
|
|
1541
1614
|
},
|
|
1542
1615
|
onSelect: (date) => {
|
|
1543
|
-
onFilterUpdate(filter.filterId, { value: date ? [(date.from
|
|
1616
|
+
onFilterUpdate(filter.filterId, { value: date ? [date.from ? serializeCalendarDate(date.from) : "", date.to ? serializeCalendarDate(date.to) : ""] : [] });
|
|
1544
1617
|
}
|
|
1545
1618
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Calendar, {
|
|
1619
|
+
lang: calendarPresentation().locale,
|
|
1620
|
+
weekStartsOn: calendarPresentation().weekStartsOn,
|
|
1621
|
+
formatters: calendarPresentation().formatters,
|
|
1622
|
+
labels: calendarPresentation().labels,
|
|
1546
1623
|
"aria-label": `Select ${columnMeta?.label} date`,
|
|
1547
1624
|
autoFocus: true,
|
|
1548
1625
|
captionLayout: "dropdown",
|
|
1549
1626
|
mode: "single",
|
|
1550
|
-
selected: dateValue[0] ?
|
|
1627
|
+
selected: dateValue[0] ? parseCalendarDate(dateValue[0]) : void 0,
|
|
1551
1628
|
onSelect: (date) => {
|
|
1552
|
-
onFilterUpdate(filter.filterId, { value: (date
|
|
1629
|
+
onFilterUpdate(filter.filterId, { value: date ? serializeCalendarDate(date) : "" });
|
|
1553
1630
|
setShowValueSelector(false);
|
|
1554
1631
|
}
|
|
1555
1632
|
})
|
|
@@ -1761,6 +1838,7 @@ function DataTableFilterMenu({ table, debounceMs = DEBOUNCE_MS$1, throttleMs = T
|
|
|
1761
1838
|
}
|
|
1762
1839
|
function DataTableFilterItem({ filter, filterItemId, columns, onFilterUpdate, onFilterRemove }) {
|
|
1763
1840
|
{
|
|
1841
|
+
useDateFormatterVersion();
|
|
1764
1842
|
const [showFieldSelector, setShowFieldSelector] = react.useState(false);
|
|
1765
1843
|
const [showOperatorSelector, setShowOperatorSelector] = react.useState(false);
|
|
1766
1844
|
const [showValueSelector, setShowValueSelector] = react.useState(false);
|
|
@@ -1871,6 +1949,7 @@ function DataTableFilterItem({ filter, filterItemId, columns, onFilterUpdate, on
|
|
|
1871
1949
|
}
|
|
1872
1950
|
}
|
|
1873
1951
|
function FilterValueSelector({ column, value, onSelect }) {
|
|
1952
|
+
useDateFormatterVersion();
|
|
1874
1953
|
switch (column.columnDef.meta?.variant ?? "text") {
|
|
1875
1954
|
case "boolean": return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.CommandGroup, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.CommandItem, {
|
|
1876
1955
|
value: "true",
|
|
@@ -1899,11 +1978,15 @@ function FilterValueSelector({ column, value, onSelect }) {
|
|
|
1899
1978
|
}, option.value)) });
|
|
1900
1979
|
case "date":
|
|
1901
1980
|
case "dateRange": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Calendar, {
|
|
1981
|
+
lang: calendarPresentation().locale,
|
|
1982
|
+
weekStartsOn: calendarPresentation().weekStartsOn,
|
|
1983
|
+
formatters: calendarPresentation().formatters,
|
|
1984
|
+
labels: calendarPresentation().labels,
|
|
1902
1985
|
autoFocus: true,
|
|
1903
1986
|
captionLayout: "dropdown",
|
|
1904
1987
|
mode: "single",
|
|
1905
|
-
selected:
|
|
1906
|
-
onSelect: (date) => onSelect(date
|
|
1988
|
+
selected: parseCalendarDate(value),
|
|
1989
|
+
onSelect: (date) => onSelect(date ? serializeCalendarDate(date) : "")
|
|
1907
1990
|
});
|
|
1908
1991
|
default: {
|
|
1909
1992
|
const isEmpty = !value.trim();
|
|
@@ -2057,10 +2140,10 @@ function onFilterInputRender({ filter, column, inputId, onFilterUpdate, showValu
|
|
|
2057
2140
|
case "dateRange": {
|
|
2058
2141
|
const inputListboxId = `${inputId}-listbox`;
|
|
2059
2142
|
const dateValue = Array.isArray(filter.value) ? filter.value.filter(Boolean) : [filter.value, filter.value].filter(Boolean);
|
|
2060
|
-
const startDate = dateValue[0] ?
|
|
2061
|
-
const endDate = dateValue[1] ?
|
|
2143
|
+
const startDate = dateValue[0] ? parseCalendarDate(dateValue[0]) : void 0;
|
|
2144
|
+
const endDate = dateValue[1] ? parseCalendarDate(dateValue[1]) : void 0;
|
|
2062
2145
|
const isSameDate = startDate && endDate && startDate.toDateString() === endDate.toDateString();
|
|
2063
|
-
const displayValue = filter.operator === "isBetween" && dateValue.length === 2 && !isSameDate ? `${formatDate(startDate
|
|
2146
|
+
const displayValue = filter.operator === "isBetween" && dateValue.length === 2 && !isSameDate ? `${calendarPresentation().formatDate(startDate)} - ${calendarPresentation().formatDate(endDate)}` : startDate ? calendarPresentation().formatDate(startDate) : "Pick date...";
|
|
2064
2147
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Popover, {
|
|
2065
2148
|
open: showValueSelector,
|
|
2066
2149
|
onOpenChange: setShowValueSelector,
|
|
@@ -2082,26 +2165,34 @@ function onFilterInputRender({ filter, column, inputId, onFilterUpdate, showValu
|
|
|
2082
2165
|
align: "start",
|
|
2083
2166
|
className: "w-auto p-0",
|
|
2084
2167
|
children: filter.operator === "isBetween" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Calendar, {
|
|
2168
|
+
lang: calendarPresentation().locale,
|
|
2169
|
+
weekStartsOn: calendarPresentation().weekStartsOn,
|
|
2170
|
+
formatters: calendarPresentation().formatters,
|
|
2171
|
+
labels: calendarPresentation().labels,
|
|
2085
2172
|
autoFocus: true,
|
|
2086
2173
|
captionLayout: "dropdown",
|
|
2087
2174
|
mode: "range",
|
|
2088
2175
|
selected: dateValue.length === 2 ? {
|
|
2089
|
-
from:
|
|
2090
|
-
to:
|
|
2176
|
+
from: parseCalendarDate(dateValue[0]),
|
|
2177
|
+
to: parseCalendarDate(dateValue[1])
|
|
2091
2178
|
} : {
|
|
2092
2179
|
from: /* @__PURE__ */ new Date(),
|
|
2093
2180
|
to: /* @__PURE__ */ new Date()
|
|
2094
2181
|
},
|
|
2095
2182
|
onSelect: (date) => {
|
|
2096
|
-
onFilterUpdate(filter.filterId, { value: date ? [(date.from
|
|
2183
|
+
onFilterUpdate(filter.filterId, { value: date ? [date.from ? serializeCalendarDate(date.from) : "", date.to ? serializeCalendarDate(date.to) : ""] : [] });
|
|
2097
2184
|
}
|
|
2098
2185
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Calendar, {
|
|
2186
|
+
lang: calendarPresentation().locale,
|
|
2187
|
+
weekStartsOn: calendarPresentation().weekStartsOn,
|
|
2188
|
+
formatters: calendarPresentation().formatters,
|
|
2189
|
+
labels: calendarPresentation().labels,
|
|
2099
2190
|
autoFocus: true,
|
|
2100
2191
|
captionLayout: "dropdown",
|
|
2101
2192
|
mode: "single",
|
|
2102
|
-
selected: dateValue[0] ?
|
|
2193
|
+
selected: dateValue[0] ? parseCalendarDate(dateValue[0]) : void 0,
|
|
2103
2194
|
onSelect: (date) => {
|
|
2104
|
-
onFilterUpdate(filter.filterId, { value: (date
|
|
2195
|
+
onFilterUpdate(filter.filterId, { value: date ? serializeCalendarDate(date) : "" });
|
|
2105
2196
|
}
|
|
2106
2197
|
})
|
|
2107
2198
|
})]
|
|
@@ -2850,11 +2941,17 @@ function SimpleSliderFilter({ title, range, unit, value, onChange }) {
|
|
|
2850
2941
|
})] });
|
|
2851
2942
|
}
|
|
2852
2943
|
function SimpleDateFilter({ title, multiple, value, onChange }) {
|
|
2944
|
+
const [open, setOpen] = react.useState(false);
|
|
2945
|
+
const commit = (next) => {
|
|
2946
|
+
setOpen(false);
|
|
2947
|
+
onChange(next);
|
|
2948
|
+
};
|
|
2949
|
+
const formatterVersion = useDateFormatterVersion();
|
|
2950
|
+
const presentation = react.useMemo(() => calendarPresentation(), [formatterVersion]);
|
|
2951
|
+
const { formatDate: formatDate$1 } = presentation;
|
|
2853
2952
|
const timestamps = Array.isArray(value) ? value : value ? [value] : [];
|
|
2854
|
-
const
|
|
2855
|
-
const
|
|
2856
|
-
const fromDate = fromTimestamp ? new Date(fromTimestamp) : void 0;
|
|
2857
|
-
const toDate = toTimestamp ? new Date(toTimestamp) : void 0;
|
|
2953
|
+
const fromDate = parseCalendarDate(timestamps[0]);
|
|
2954
|
+
const toDate = parseCalendarDate(timestamps[1]);
|
|
2858
2955
|
const [localRange, setLocalRange] = react.useState({
|
|
2859
2956
|
from: void 0,
|
|
2860
2957
|
to: void 0
|
|
@@ -2873,100 +2970,114 @@ function SimpleDateFilter({ title, multiple, value, onChange }) {
|
|
|
2873
2970
|
const hasValue = multiple ? fromDate || toDate : fromDate;
|
|
2874
2971
|
const onReset = (e) => {
|
|
2875
2972
|
e.stopPropagation();
|
|
2876
|
-
|
|
2973
|
+
commit(void 0);
|
|
2877
2974
|
};
|
|
2878
|
-
const label = multiple ? fromDate && toDate ? `${formatDate(fromDate)} - ${formatDate(toDate)}` : fromDate ? formatDate(fromDate) : void 0 : fromDate ? formatDate(fromDate) : void 0;
|
|
2879
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Popover, {
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2975
|
+
const label = multiple ? fromDate && toDate ? `${formatDate$1(fromDate)} - ${formatDate$1(toDate)}` : fromDate ? formatDate$1(fromDate) : void 0 : fromDate ? formatDate$1(fromDate) : void 0;
|
|
2976
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Popover, {
|
|
2977
|
+
open,
|
|
2978
|
+
onOpenChange: setOpen,
|
|
2979
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.PopoverTrigger, {
|
|
2980
|
+
asChild: true,
|
|
2981
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Button, {
|
|
2982
|
+
variant: "outline",
|
|
2983
|
+
size: "sm",
|
|
2984
|
+
className: "border-dashed font-normal",
|
|
2985
|
+
children: [
|
|
2986
|
+
hasValue ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2987
|
+
role: "button",
|
|
2988
|
+
tabIndex: 0,
|
|
2989
|
+
className: "rounded-sm opacity-70 hover:opacity-100",
|
|
2990
|
+
onClick: onReset,
|
|
2991
|
+
onKeyDown: (e) => {
|
|
2992
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
2993
|
+
e.preventDefault();
|
|
2994
|
+
onReset(e);
|
|
2995
|
+
}
|
|
2996
|
+
},
|
|
2997
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.XCircle, {})
|
|
2998
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.CalendarIcon, {}),
|
|
2999
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: title }),
|
|
3000
|
+
label && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Separator, {
|
|
3001
|
+
orientation: "vertical",
|
|
3002
|
+
className: "mx-0.5 h-4"
|
|
3003
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: label })] })
|
|
3004
|
+
]
|
|
3005
|
+
})
|
|
3006
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.PopoverContent, {
|
|
3007
|
+
className: "w-auto p-0",
|
|
3008
|
+
align: "start",
|
|
3009
|
+
children: multiple ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Calendar, {
|
|
3010
|
+
lang: presentation.locale,
|
|
3011
|
+
weekStartsOn: presentation.weekStartsOn,
|
|
3012
|
+
formatters: presentation.formatters,
|
|
3013
|
+
labels: presentation.labels,
|
|
3014
|
+
defaultMonth: fromDate,
|
|
3015
|
+
autoFocus: true,
|
|
3016
|
+
captionLayout: "dropdown",
|
|
3017
|
+
mode: "range",
|
|
3018
|
+
selected: localRange,
|
|
3019
|
+
onSelect: (range) => {
|
|
3020
|
+
if (!range?.from && !range?.to) {
|
|
3021
|
+
commit(void 0);
|
|
3022
|
+
setLocalRange({
|
|
3023
|
+
from: void 0,
|
|
3024
|
+
to: void 0
|
|
3025
|
+
});
|
|
3026
|
+
return;
|
|
3027
|
+
}
|
|
3028
|
+
const hadFrom = Boolean(localRange.from);
|
|
3029
|
+
const hadTo = Boolean(localRange.to);
|
|
3030
|
+
const from = range.from?.getTime();
|
|
3031
|
+
const to = range.to?.getTime();
|
|
3032
|
+
if (from != null && to != null && from === to) {
|
|
3033
|
+
if (!hadFrom || hadTo) {
|
|
3034
|
+
setLocalRange({
|
|
3035
|
+
from: range.from,
|
|
3036
|
+
to: void 0
|
|
3037
|
+
});
|
|
3038
|
+
return;
|
|
2895
3039
|
}
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
children: multiple ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Calendar, {
|
|
2910
|
-
autoFocus: true,
|
|
2911
|
-
captionLayout: "dropdown",
|
|
2912
|
-
mode: "range",
|
|
2913
|
-
selected: localRange,
|
|
2914
|
-
onSelect: (range) => {
|
|
2915
|
-
if (!range?.from && !range?.to) {
|
|
2916
|
-
onChange(void 0);
|
|
2917
|
-
setLocalRange({
|
|
2918
|
-
from: void 0,
|
|
2919
|
-
to: void 0
|
|
2920
|
-
});
|
|
2921
|
-
return;
|
|
2922
|
-
}
|
|
2923
|
-
const hadFrom = Boolean(localRange.from);
|
|
2924
|
-
const hadTo = Boolean(localRange.to);
|
|
2925
|
-
const from = range.from?.getTime();
|
|
2926
|
-
const to = range.to?.getTime();
|
|
2927
|
-
if (from != null && to != null && from === to) {
|
|
2928
|
-
if (!hadFrom || hadTo) {
|
|
3040
|
+
if (hadFrom && !hadTo && localRange.from) {
|
|
3041
|
+
const prevFrom = localRange.from;
|
|
3042
|
+
const newDate = range.from;
|
|
3043
|
+
const [finalFrom, finalTo] = prevFrom <= newDate ? [prevFrom, newDate] : [newDate, prevFrom];
|
|
3044
|
+
setLocalRange({
|
|
3045
|
+
from: finalFrom,
|
|
3046
|
+
to: finalTo
|
|
3047
|
+
});
|
|
3048
|
+
commit([serializeCalendarDate(finalFrom), serializeCalendarDate(finalTo)]);
|
|
3049
|
+
return;
|
|
3050
|
+
}
|
|
3051
|
+
}
|
|
3052
|
+
if (from != null && to != null && from !== to) {
|
|
2929
3053
|
setLocalRange({
|
|
2930
3054
|
from: range.from,
|
|
2931
|
-
to:
|
|
3055
|
+
to: range.to
|
|
2932
3056
|
});
|
|
3057
|
+
commit([serializeCalendarDate(range.from), serializeCalendarDate(range.to)]);
|
|
2933
3058
|
return;
|
|
2934
3059
|
}
|
|
2935
|
-
if (
|
|
2936
|
-
const prevFrom = localRange.from;
|
|
2937
|
-
const newDate = range.from;
|
|
2938
|
-
const [finalFrom, finalTo] = prevFrom <= newDate ? [prevFrom, newDate] : [newDate, prevFrom];
|
|
3060
|
+
if (range.from && !range.to) {
|
|
2939
3061
|
setLocalRange({
|
|
2940
|
-
from:
|
|
2941
|
-
to:
|
|
3062
|
+
from: range.from,
|
|
3063
|
+
to: void 0
|
|
2942
3064
|
});
|
|
2943
|
-
onChange([finalFrom.getTime().toString(), finalTo.getTime().toString()]);
|
|
2944
3065
|
return;
|
|
2945
3066
|
}
|
|
2946
3067
|
}
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
return;
|
|
2961
|
-
}
|
|
2962
|
-
}
|
|
2963
|
-
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Calendar, {
|
|
2964
|
-
captionLayout: "dropdown",
|
|
2965
|
-
mode: "single",
|
|
2966
|
-
selected: fromDate,
|
|
2967
|
-
onSelect: (date) => onChange(date ? date.getTime().toString() : void 0)
|
|
2968
|
-
})
|
|
2969
|
-
})] });
|
|
3068
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Calendar, {
|
|
3069
|
+
lang: presentation.locale,
|
|
3070
|
+
weekStartsOn: presentation.weekStartsOn,
|
|
3071
|
+
formatters: presentation.formatters,
|
|
3072
|
+
labels: presentation.labels,
|
|
3073
|
+
defaultMonth: fromDate,
|
|
3074
|
+
captionLayout: "dropdown",
|
|
3075
|
+
mode: "single",
|
|
3076
|
+
selected: fromDate,
|
|
3077
|
+
onSelect: (date) => commit(date ? serializeCalendarDate(date) : void 0)
|
|
3078
|
+
})
|
|
3079
|
+
})]
|
|
3080
|
+
});
|
|
2970
3081
|
}
|
|
2971
3082
|
|
|
2972
3083
|
//#endregion
|
|
@@ -3974,7 +4085,8 @@ function useDataTable(props) {
|
|
|
3974
4085
|
if (enableAdvancedFilter) return [];
|
|
3975
4086
|
return Object.entries(filterValues).reduce((filters, [key, value]) => {
|
|
3976
4087
|
if (value !== null) {
|
|
3977
|
-
const
|
|
4088
|
+
const variant = filterableColumns.find((column) => column.id === key)?.meta?.variant;
|
|
4089
|
+
const processedValue = Array.isArray(value) ? value : typeof value === "string" && (variant === "date" || variant === "dateRange") ? value.split(",").filter(Boolean) : typeof value === "string" && /[^a-zA-Z0-9]/.test(value) ? value.split(/[^a-zA-Z0-9]+/).filter(Boolean) : [value];
|
|
3978
4090
|
filters.push({
|
|
3979
4091
|
id: key,
|
|
3980
4092
|
value: processedValue
|
|
@@ -3982,7 +4094,11 @@ function useDataTable(props) {
|
|
|
3982
4094
|
}
|
|
3983
4095
|
return filters;
|
|
3984
4096
|
}, []);
|
|
3985
|
-
}, [
|
|
4097
|
+
}, [
|
|
4098
|
+
filterValues,
|
|
4099
|
+
enableAdvancedFilter,
|
|
4100
|
+
filterableColumns
|
|
4101
|
+
]);
|
|
3986
4102
|
const [columnFilters, setColumnFilters] = react.useState(initialColumnFilters);
|
|
3987
4103
|
const onColumnFiltersChange = react.useCallback((updaterOrValue) => {
|
|
3988
4104
|
if (enableAdvancedFilter) return;
|
|
@@ -6136,13 +6252,6 @@ function mergeFieldOptions(current, incoming) {
|
|
|
6136
6252
|
if ((!current || current.length === 0) && (!incoming || incoming.length === 0)) return;
|
|
6137
6253
|
return mergeFilterOptions(current, incoming ?? []);
|
|
6138
6254
|
}
|
|
6139
|
-
function mergeOptionsByField(left, right) {
|
|
6140
|
-
const keys = new Set([...Object.keys(left ?? {}), ...Object.keys(right ?? {})]);
|
|
6141
|
-
return Object.fromEntries(Array.from(keys).flatMap((key) => {
|
|
6142
|
-
const options = mergeFieldOptions(left?.[key], right?.[key]);
|
|
6143
|
-
return options ? [[key, options]] : [];
|
|
6144
|
-
}));
|
|
6145
|
-
}
|
|
6146
6255
|
function shouldResolveOptions(field, config, hiddenColumns) {
|
|
6147
6256
|
if (!config) return false;
|
|
6148
6257
|
if (hiddenColumns.has(field)) return false;
|
|
@@ -6679,7 +6788,7 @@ function buildBatchUpdateFields(schema, batchFields, fields) {
|
|
|
6679
6788
|
/**
|
|
6680
6789
|
* 渲染字段值
|
|
6681
6790
|
*/
|
|
6682
|
-
function renderFieldValue(value, type, booleanLocale, options, display = "auto") {
|
|
6791
|
+
function renderFieldValue(value, type, booleanLocale, options, display = "auto", maxItems = 5) {
|
|
6683
6792
|
if (value === null || value === void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6684
6793
|
className: "text-muted-foreground",
|
|
6685
6794
|
children: "-"
|
|
@@ -6694,12 +6803,12 @@ function renderFieldValue(value, type, booleanLocale, options, display = "auto")
|
|
|
6694
6803
|
if (display === "badge" && (!options || options.length === 0)) {
|
|
6695
6804
|
if (Array.isArray(value)) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6696
6805
|
className: "flex gap-1 flex-wrap",
|
|
6697
|
-
children: [value.slice(0,
|
|
6806
|
+
children: [value.slice(0, maxItems).map((item, index$1) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Badge, {
|
|
6698
6807
|
variant: "secondary",
|
|
6699
6808
|
children: String(item)
|
|
6700
|
-
}, index$1)), value.length >
|
|
6809
|
+
}, index$1)), value.length > maxItems && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Badge, {
|
|
6701
6810
|
variant: "outline",
|
|
6702
|
-
children: ["+", value.length -
|
|
6811
|
+
children: ["+", value.length - maxItems]
|
|
6703
6812
|
})]
|
|
6704
6813
|
});
|
|
6705
6814
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Badge, {
|
|
@@ -6711,12 +6820,12 @@ function renderFieldValue(value, type, booleanLocale, options, display = "auto")
|
|
|
6711
6820
|
if ((display === "badge" || display === "auto") && options && options.length > 0) {
|
|
6712
6821
|
if (Array.isArray(value)) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6713
6822
|
className: "flex gap-1 flex-wrap",
|
|
6714
|
-
children: [value.slice(0,
|
|
6823
|
+
children: [value.slice(0, maxItems).map((v, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Badge, {
|
|
6715
6824
|
variant: "secondary",
|
|
6716
6825
|
children: getOptionLabel(v, options)
|
|
6717
|
-
}, i)), value.length >
|
|
6826
|
+
}, i)), value.length > maxItems && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Badge, {
|
|
6718
6827
|
variant: "outline",
|
|
6719
|
-
children: ["+", value.length -
|
|
6828
|
+
children: ["+", value.length - maxItems]
|
|
6720
6829
|
})]
|
|
6721
6830
|
});
|
|
6722
6831
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Badge, {
|
|
@@ -6735,48 +6844,81 @@ function renderFieldValue(value, type, booleanLocale, options, display = "auto")
|
|
|
6735
6844
|
});
|
|
6736
6845
|
case "array": return Array.isArray(value) ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6737
6846
|
className: "flex gap-1 flex-wrap",
|
|
6738
|
-
children: [value.slice(0,
|
|
6847
|
+
children: [value.slice(0, maxItems).map((v, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Badge, {
|
|
6739
6848
|
variant: "secondary",
|
|
6740
6849
|
children: String(v)
|
|
6741
|
-
}, i)), value.length >
|
|
6850
|
+
}, i)), value.length > maxItems && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Badge, {
|
|
6742
6851
|
variant: "outline",
|
|
6743
|
-
children: ["+", value.length -
|
|
6852
|
+
children: ["+", value.length - maxItems]
|
|
6744
6853
|
})]
|
|
6745
6854
|
}) : null;
|
|
6746
6855
|
default: return String(value);
|
|
6747
6856
|
}
|
|
6748
6857
|
}
|
|
6749
|
-
|
|
6750
|
-
|
|
6751
|
-
*/
|
|
6752
|
-
|
|
6753
|
-
|
|
6754
|
-
const
|
|
6755
|
-
|
|
6858
|
+
function ViewModal(props) {
|
|
6859
|
+
if (!props.open || !props.data) return null;
|
|
6860
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ViewModalContent, { ...props });
|
|
6861
|
+
}
|
|
6862
|
+
function ViewModalContent({ open, onOpenChange, variant, data, schema, fields: fieldConfig, dynamicOptions, denyFields, locale, tableOverrides, view }) {
|
|
6863
|
+
const excluded = react.useMemo(() => {
|
|
6864
|
+
const denied = new Set(denyFields ?? []);
|
|
6865
|
+
return Object.keys(schema.shape).filter((key) => {
|
|
6866
|
+
const config = fieldConfig?.[key];
|
|
6867
|
+
return denied.has(key) || config?.hidden || view?.overrides?.[key]?.hidden || isDefaultHiddenAuditField(key) && !isFieldTableExplicitlyVisible(config) && view?.overrides?.[key]?.hidden !== false;
|
|
6868
|
+
});
|
|
6869
|
+
}, [
|
|
6870
|
+
schema,
|
|
6871
|
+
fieldConfig,
|
|
6872
|
+
denyFields,
|
|
6873
|
+
view?.overrides
|
|
6874
|
+
]);
|
|
6875
|
+
const rows = react.useMemo(() => data ? [data] : [], [data]);
|
|
6876
|
+
const resolvedOptions = useDynamicResolveOptions(fieldConfig, rows, excluded);
|
|
6756
6877
|
const content = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dl", {
|
|
6757
6878
|
className: "grid gap-4 py-4",
|
|
6758
|
-
children:
|
|
6759
|
-
|
|
6760
|
-
|
|
6761
|
-
|
|
6762
|
-
|
|
6763
|
-
|
|
6764
|
-
|
|
6765
|
-
|
|
6766
|
-
|
|
6767
|
-
|
|
6768
|
-
|
|
6769
|
-
|
|
6770
|
-
|
|
6771
|
-
|
|
6772
|
-
|
|
6773
|
-
|
|
6774
|
-
|
|
6775
|
-
|
|
6776
|
-
|
|
6777
|
-
|
|
6778
|
-
|
|
6779
|
-
|
|
6879
|
+
children: (0, __tanstack_react_table.useReactTable)({
|
|
6880
|
+
data: rows,
|
|
6881
|
+
columns: react.useMemo(() => {
|
|
6882
|
+
const overrides = {};
|
|
6883
|
+
for (const [key, fieldSchema] of Object.entries(schema.shape).filter(([fieldKey]) => !excluded.includes(fieldKey))) {
|
|
6884
|
+
const config = fieldConfig?.[key] ?? {};
|
|
6885
|
+
const tableConfig = getTableConfig(config);
|
|
6886
|
+
const listOverride = tableOverrides?.[key];
|
|
6887
|
+
const options = getTableOptions(config) ?? resolvedOptions.optionsByField[key] ?? (tableConfig?.dataSource !== void 0 ? void 0 : dynamicOptions?.[key]);
|
|
6888
|
+
overrides[key] = {
|
|
6889
|
+
label: tableConfig?.label ?? config.label ?? listOverride?.label ?? humanize(key),
|
|
6890
|
+
index: tableConfig?.index ?? listOverride?.index,
|
|
6891
|
+
cell: ({ getValue }) => renderFieldValue(getValue(), parseZodField(fieldSchema).type, locale.boolean, options, tableConfig?.display ?? "auto", Infinity),
|
|
6892
|
+
...view?.presentation === "table" ? listOverride : void 0,
|
|
6893
|
+
hidden: false,
|
|
6894
|
+
...view?.overrides?.[key]
|
|
6895
|
+
};
|
|
6896
|
+
}
|
|
6897
|
+
return createTableSchema(schema, {
|
|
6898
|
+
overrides,
|
|
6899
|
+
exclude: excluded
|
|
6900
|
+
});
|
|
6901
|
+
}, [
|
|
6902
|
+
schema,
|
|
6903
|
+
excluded,
|
|
6904
|
+
fieldConfig,
|
|
6905
|
+
tableOverrides,
|
|
6906
|
+
view,
|
|
6907
|
+
resolvedOptions.optionsByField,
|
|
6908
|
+
dynamicOptions,
|
|
6909
|
+
locale.boolean
|
|
6910
|
+
]),
|
|
6911
|
+
getCoreRowModel: (0, __tanstack_react_table.getCoreRowModel)()
|
|
6912
|
+
}).getRowModel().rows[0]?.getAllCells().map((cell) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6913
|
+
className: "grid grid-cols-3 items-start gap-4",
|
|
6914
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", {
|
|
6915
|
+
className: "text-sm font-medium text-muted-foreground",
|
|
6916
|
+
children: cell.column.columnDef.meta?.label ?? humanize(cell.column.id)
|
|
6917
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", {
|
|
6918
|
+
className: "col-span-2 min-w-0 whitespace-pre-wrap break-words text-sm",
|
|
6919
|
+
children: (0, __tanstack_react_table.flexRender)(cell.column.columnDef.cell, cell.getContext())
|
|
6920
|
+
})]
|
|
6921
|
+
}, cell.id))
|
|
6780
6922
|
});
|
|
6781
6923
|
if (variant === "sheet") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Sheet, {
|
|
6782
6924
|
open,
|
|
@@ -6897,7 +7039,7 @@ function resolveActions(actionsOrFn, defaults, rowActionsLocale, context) {
|
|
|
6897
7039
|
*
|
|
6898
7040
|
* 高级 CRUD 表格组件,封装了完整的增删改查流程
|
|
6899
7041
|
*/
|
|
6900
|
-
function AutoCrudTable({ id, title, description, schema, resource, fields, table: tableConfig, form: formConfig, permissions, actions: actionItems, toolbar, toolbarActions, locale: localeProp, onCreate }) {
|
|
7042
|
+
function AutoCrudTable({ id, title, description, schema, resource, fields, table: tableConfig, form: formConfig, view: viewConfig, permissions, actions: actionItems, toolbar, toolbarActions, locale: localeProp, onCreate }) {
|
|
6901
7043
|
const locale = resolveLocale(localeProp);
|
|
6902
7044
|
const resolvedSchema = resource.schema ?? schema;
|
|
6903
7045
|
const resolvedFields = react.useMemo(() => applyResourceTablePresentation(mergeFields(resource.fields, fields), resource.fields) ?? {}, [fields, resource.fields]);
|
|
@@ -6923,18 +7065,6 @@ function AutoCrudTable({ id, title, description, schema, resource, fields, table
|
|
|
6923
7065
|
tableConfig?.overrides
|
|
6924
7066
|
]);
|
|
6925
7067
|
const dynamicResolveOptions = useDynamicResolveOptions(resolvedFields, resource.tableData.data, hiddenColumns);
|
|
6926
|
-
const sharedResolveOptions = useDynamicResolveOptions(react.useMemo(() => Object.fromEntries(Object.entries(resolvedFields).flatMap(([field, config]) => {
|
|
6927
|
-
const table = getTableConfig(config);
|
|
6928
|
-
if (table?.options === void 0 && table?.dataSource === void 0) return [];
|
|
6929
|
-
const { table: _table,...sharedConfig } = config;
|
|
6930
|
-
return [[field, sharedConfig]];
|
|
6931
|
-
})), [resolvedFields]), resource.tableData.data, hiddenColumns);
|
|
6932
|
-
const viewDynamicOptionsByField = react.useMemo(() => mergeOptionsByField(mergeOptionsByField(dynamicFilterOptions.labelOptionsByField, sharedResolveOptions.optionsByField), Object.fromEntries(Object.entries(dynamicResolveOptions.optionsByField).filter(([field]) => !getTableConfig(resolvedFields[field] ?? {})?.dataSource))), [
|
|
6933
|
-
dynamicFilterOptions.labelOptionsByField,
|
|
6934
|
-
dynamicResolveOptions.optionsByField,
|
|
6935
|
-
sharedResolveOptions.optionsByField,
|
|
6936
|
-
resolvedFields
|
|
6937
|
-
]);
|
|
6938
7068
|
const resourceIdKey = resource.idKey ?? "id";
|
|
6939
7069
|
const actionRegistryVersion = useCrudActionsVersion();
|
|
6940
7070
|
const unifiedActions = react.useMemo(() => {
|
|
@@ -7266,9 +7396,11 @@ function AutoCrudTable({ id, title, description, schema, resource, fields, table
|
|
|
7266
7396
|
data: resource.modal.selected,
|
|
7267
7397
|
schema: resolvedSchema,
|
|
7268
7398
|
fields: resolvedFields,
|
|
7269
|
-
dynamicOptions:
|
|
7399
|
+
dynamicOptions: dynamicFilterOptions.labelOptionsByField,
|
|
7270
7400
|
denyFields,
|
|
7271
|
-
locale
|
|
7401
|
+
locale,
|
|
7402
|
+
tableOverrides,
|
|
7403
|
+
view: viewConfig
|
|
7272
7404
|
}),
|
|
7273
7405
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.AlertDialog, {
|
|
7274
7406
|
open: resource.modal.deleteOpen,
|
|
@@ -7465,10 +7597,7 @@ function getIsDateRange(value) {
|
|
|
7465
7597
|
return value && typeof value === "object" && !Array.isArray(value);
|
|
7466
7598
|
}
|
|
7467
7599
|
function parseAsDate(timestamp) {
|
|
7468
|
-
|
|
7469
|
-
const numericTimestamp = typeof timestamp === "string" ? Number(timestamp) : timestamp;
|
|
7470
|
-
const date = new Date(numericTimestamp);
|
|
7471
|
-
return !Number.isNaN(date.getTime()) ? date : void 0;
|
|
7600
|
+
return parseCalendarDate(timestamp);
|
|
7472
7601
|
}
|
|
7473
7602
|
function parseColumnFilterValue(value) {
|
|
7474
7603
|
if (value === null || value === void 0) return [];
|
|
@@ -7479,6 +7608,9 @@ function parseColumnFilterValue(value) {
|
|
|
7479
7608
|
return [];
|
|
7480
7609
|
}
|
|
7481
7610
|
function DataTableDateFilter({ column, title, multiple }) {
|
|
7611
|
+
const formatterVersion = useDateFormatterVersion();
|
|
7612
|
+
const presentation = react.useMemo(() => calendarPresentation(), [formatterVersion]);
|
|
7613
|
+
const { formatDate: formatDate$1 } = presentation;
|
|
7482
7614
|
const columnFilterValue = column.getFilterValue();
|
|
7483
7615
|
const selectedDates = react.useMemo(() => {
|
|
7484
7616
|
if (!columnFilterValue) return multiple ? {
|
|
@@ -7552,12 +7684,12 @@ function DataTableDateFilter({ column, title, multiple }) {
|
|
|
7552
7684
|
from: nextFrom,
|
|
7553
7685
|
to: nextTo
|
|
7554
7686
|
});
|
|
7555
|
-
if (nextTo) column.setFilterValue([nextFrom
|
|
7687
|
+
if (nextTo) column.setFilterValue([serializeCalendarDate(nextFrom), serializeCalendarDate(nextTo)]);
|
|
7556
7688
|
return;
|
|
7557
7689
|
}
|
|
7558
7690
|
setLocalRange(date);
|
|
7559
|
-
if (from && to) column.setFilterValue([from, to]);
|
|
7560
|
-
} else if (!multiple && "getTime" in date) column.setFilterValue(date
|
|
7691
|
+
if (from && to) column.setFilterValue([serializeCalendarDate(new Date(from)), serializeCalendarDate(new Date(to))]);
|
|
7692
|
+
} else if (!multiple && "getTime" in date) column.setFilterValue(serializeCalendarDate(date));
|
|
7561
7693
|
}, [
|
|
7562
7694
|
column,
|
|
7563
7695
|
multiple,
|
|
@@ -7577,9 +7709,9 @@ function DataTableDateFilter({ column, title, multiple }) {
|
|
|
7577
7709
|
}, [multiple, selectedDates]);
|
|
7578
7710
|
const formatDateRange = react.useCallback((range) => {
|
|
7579
7711
|
if (!range.from && !range.to) return "";
|
|
7580
|
-
if (range.from && range.to) return `${formatDate(range.from)} - ${formatDate(range.to)}`;
|
|
7581
|
-
return formatDate(range.from ?? range.to);
|
|
7582
|
-
}, []);
|
|
7712
|
+
if (range.from && range.to) return `${formatDate$1(range.from)} - ${formatDate$1(range.to)}`;
|
|
7713
|
+
return formatDate$1(range.from ?? range.to);
|
|
7714
|
+
}, [formatDate$1]);
|
|
7583
7715
|
const label = react.useMemo(() => {
|
|
7584
7716
|
if (multiple) {
|
|
7585
7717
|
if (!getIsDateRange(selectedDates)) return null;
|
|
@@ -7595,7 +7727,7 @@ function DataTableDateFilter({ column, title, multiple }) {
|
|
|
7595
7727
|
}
|
|
7596
7728
|
if (getIsDateRange(selectedDates)) return null;
|
|
7597
7729
|
const hasSelectedDate = selectedDates.length > 0;
|
|
7598
|
-
const dateText = hasSelectedDate ? formatDate(selectedDates[0]) : "Select date";
|
|
7730
|
+
const dateText = hasSelectedDate ? formatDate$1(selectedDates[0]) : "Select date";
|
|
7599
7731
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
7600
7732
|
className: "flex items-center gap-2",
|
|
7601
7733
|
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, {
|
|
@@ -7607,7 +7739,8 @@ function DataTableDateFilter({ column, title, multiple }) {
|
|
|
7607
7739
|
selectedDates,
|
|
7608
7740
|
multiple,
|
|
7609
7741
|
formatDateRange,
|
|
7610
|
-
title
|
|
7742
|
+
title,
|
|
7743
|
+
formatDate$1
|
|
7611
7744
|
]);
|
|
7612
7745
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__wordrhyme_shadcn.Popover, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.PopoverTrigger, {
|
|
7613
7746
|
asChild: true,
|
|
@@ -7617,7 +7750,7 @@ function DataTableDateFilter({ column, title, multiple }) {
|
|
|
7617
7750
|
className: "border-dashed font-normal",
|
|
7618
7751
|
children: [hasValue ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7619
7752
|
role: "button",
|
|
7620
|
-
"aria-label":
|
|
7753
|
+
"aria-label": presentation.clearLabel(title),
|
|
7621
7754
|
tabIndex: 0,
|
|
7622
7755
|
onClick: onReset,
|
|
7623
7756
|
className: "rounded-sm opacity-70 transition-opacity hover:opacity-100 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
@@ -7628,14 +7761,24 @@ function DataTableDateFilter({ column, title, multiple }) {
|
|
|
7628
7761
|
className: "w-auto p-0",
|
|
7629
7762
|
align: "start",
|
|
7630
7763
|
children: multiple ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Calendar, {
|
|
7764
|
+
lang: presentation.locale,
|
|
7765
|
+
weekStartsOn: presentation.weekStartsOn,
|
|
7766
|
+
formatters: presentation.formatters,
|
|
7767
|
+
labels: presentation.labels,
|
|
7631
7768
|
autoFocus: true,
|
|
7632
7769
|
captionLayout: "dropdown",
|
|
7633
7770
|
mode: "range",
|
|
7771
|
+
defaultMonth: localRange.from,
|
|
7634
7772
|
selected: localRange,
|
|
7635
7773
|
onSelect
|
|
7636
7774
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__wordrhyme_shadcn.Calendar, {
|
|
7775
|
+
lang: presentation.locale,
|
|
7776
|
+
weekStartsOn: presentation.weekStartsOn,
|
|
7777
|
+
formatters: presentation.formatters,
|
|
7778
|
+
labels: presentation.labels,
|
|
7637
7779
|
captionLayout: "dropdown",
|
|
7638
7780
|
mode: "single",
|
|
7781
|
+
defaultMonth: !getIsDateRange(selectedDates) ? selectedDates[0] : void 0,
|
|
7639
7782
|
selected: !getIsDateRange(selectedDates) ? selectedDates[0] : void 0,
|
|
7640
7783
|
onSelect
|
|
7641
7784
|
})
|