@l3mpire/ui 2.12.0 → 2.13.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/USAGE.md +23 -0
- package/dist/index.d.mts +25 -1
- package/dist/index.d.ts +25 -1
- package/dist/index.js +2253 -2124
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2260 -2131
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -5131,7 +5131,6 @@ var OPERATORS_BY_TYPE = {
|
|
|
5131
5131
|
"is on or before",
|
|
5132
5132
|
"is on or after",
|
|
5133
5133
|
"is between",
|
|
5134
|
-
"is relative",
|
|
5135
5134
|
"is empty",
|
|
5136
5135
|
"is not empty"
|
|
5137
5136
|
],
|
|
@@ -5150,7 +5149,7 @@ var OPERATORS_BY_TYPE = {
|
|
|
5150
5149
|
var DEFAULT_OPERATOR_BY_TYPE = {
|
|
5151
5150
|
text: "contains",
|
|
5152
5151
|
number: "=",
|
|
5153
|
-
date: "is
|
|
5152
|
+
date: "is between",
|
|
5154
5153
|
enum: "is",
|
|
5155
5154
|
tags: "contains",
|
|
5156
5155
|
boolean: "is true",
|
|
@@ -5178,7 +5177,6 @@ function getValueInputType(type, operator) {
|
|
|
5178
5177
|
return operator === "is between" ? "NumberRange" : "NumberInput";
|
|
5179
5178
|
if (type === "date") {
|
|
5180
5179
|
if (operator === "is between") return "DateRange";
|
|
5181
|
-
if (operator === "is relative") return "PresetTags";
|
|
5182
5180
|
return "DatePicker";
|
|
5183
5181
|
}
|
|
5184
5182
|
if (type === "enum")
|
|
@@ -5729,2285 +5727,2416 @@ var NumberRangeValueInput = ({
|
|
|
5729
5727
|
NumberRangeValueInput.displayName = "NumberRangeValueInput";
|
|
5730
5728
|
|
|
5731
5729
|
// src/components/ui/filter/value-inputs/date-value-input.tsx
|
|
5730
|
+
var React42 = __toESM(require("react"));
|
|
5731
|
+
|
|
5732
|
+
// src/components/ui/date-picker.tsx
|
|
5733
|
+
var React41 = __toESM(require("react"));
|
|
5734
|
+
var PopoverPrimitive5 = __toESM(require("@radix-ui/react-popover"));
|
|
5735
|
+
var import_icons27 = require("@l3mpire/icons");
|
|
5732
5736
|
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
5733
|
-
|
|
5734
|
-
|
|
5735
|
-
|
|
5736
|
-
|
|
5737
|
+
function getDaysInMonth(year, month) {
|
|
5738
|
+
return new Date(year, month + 1, 0).getDate();
|
|
5739
|
+
}
|
|
5740
|
+
function getWeekdayIndex(date) {
|
|
5741
|
+
return (date.getDay() + 6) % 7;
|
|
5742
|
+
}
|
|
5743
|
+
function isSameDay(a, b) {
|
|
5744
|
+
return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
5745
|
+
}
|
|
5746
|
+
function isInRange(date, from, to) {
|
|
5747
|
+
const t = date.getTime();
|
|
5748
|
+
return t >= from.getTime() && t <= to.getTime();
|
|
5749
|
+
}
|
|
5750
|
+
function startOfDay(d) {
|
|
5751
|
+
return new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
5752
|
+
}
|
|
5753
|
+
var WEEKDAYS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
|
|
5754
|
+
var MONTH_NAMES = [
|
|
5755
|
+
"January",
|
|
5756
|
+
"February",
|
|
5757
|
+
"March",
|
|
5758
|
+
"April",
|
|
5759
|
+
"May",
|
|
5760
|
+
"June",
|
|
5761
|
+
"July",
|
|
5762
|
+
"August",
|
|
5763
|
+
"September",
|
|
5764
|
+
"October",
|
|
5765
|
+
"November",
|
|
5766
|
+
"December"
|
|
5737
5767
|
];
|
|
5738
|
-
var
|
|
5739
|
-
|
|
5740
|
-
|
|
5741
|
-
|
|
5742
|
-
|
|
5743
|
-
|
|
5744
|
-
|
|
5745
|
-
|
|
5746
|
-
{
|
|
5747
|
-
type: "date",
|
|
5748
|
-
value: value instanceof Date ? value.toISOString().split("T")[0] : value ?? "",
|
|
5749
|
-
onChange: (e) => onChange(e.target.value ? new Date(e.target.value) : null),
|
|
5750
|
-
autoFocus: true,
|
|
5751
|
-
className: inputClasses
|
|
5752
|
-
}
|
|
5753
|
-
),
|
|
5754
|
-
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("button", { type: "button", onClick: onSubmit, className: applyBtnClasses, children: "Apply" })
|
|
5755
|
-
] });
|
|
5756
|
-
DatePickerValueInput.displayName = "DatePickerValueInput";
|
|
5757
|
-
function toDateString(d) {
|
|
5758
|
-
if (!d) return "";
|
|
5759
|
-
if (d instanceof Date) return d.toISOString().split("T")[0];
|
|
5760
|
-
return String(d);
|
|
5768
|
+
var DatePickerContext = React41.createContext(
|
|
5769
|
+
null
|
|
5770
|
+
);
|
|
5771
|
+
function useDatePickerContext() {
|
|
5772
|
+
const ctx = React41.useContext(DatePickerContext);
|
|
5773
|
+
if (!ctx)
|
|
5774
|
+
throw new Error("DatePicker compound components must be used within <DatePicker>");
|
|
5775
|
+
return ctx;
|
|
5761
5776
|
}
|
|
5762
|
-
var
|
|
5763
|
-
|
|
5764
|
-
|
|
5765
|
-
|
|
5766
|
-
|
|
5767
|
-
|
|
5768
|
-
|
|
5769
|
-
|
|
5770
|
-
|
|
5771
|
-
|
|
5772
|
-
|
|
5773
|
-
|
|
5774
|
-
|
|
5775
|
-
|
|
5776
|
-
|
|
5777
|
-
|
|
5778
|
-
|
|
5779
|
-
|
|
5780
|
-
|
|
5781
|
-
|
|
5777
|
+
var DatePicker = React41.forwardRef(
|
|
5778
|
+
({
|
|
5779
|
+
className,
|
|
5780
|
+
mode = "single",
|
|
5781
|
+
value,
|
|
5782
|
+
onValueChange,
|
|
5783
|
+
defaultMonth,
|
|
5784
|
+
defaultYear,
|
|
5785
|
+
children,
|
|
5786
|
+
...props
|
|
5787
|
+
}, ref) => {
|
|
5788
|
+
const today = React41.useMemo(() => startOfDay(/* @__PURE__ */ new Date()), []);
|
|
5789
|
+
const initialDate = React41.useMemo(() => {
|
|
5790
|
+
if (value) {
|
|
5791
|
+
if (value instanceof Date) return value;
|
|
5792
|
+
return value.from;
|
|
5793
|
+
}
|
|
5794
|
+
return today;
|
|
5795
|
+
}, []);
|
|
5796
|
+
const [month, setMonth] = React41.useState(
|
|
5797
|
+
defaultMonth ?? initialDate.getMonth()
|
|
5798
|
+
);
|
|
5799
|
+
const [year, setYear] = React41.useState(
|
|
5800
|
+
defaultYear ?? initialDate.getFullYear()
|
|
5801
|
+
);
|
|
5802
|
+
const [hoveredDate, setHoveredDate] = React41.useState();
|
|
5803
|
+
const goToPrevMonth = React41.useCallback(() => {
|
|
5804
|
+
setMonth((m) => {
|
|
5805
|
+
if (m === 0) {
|
|
5806
|
+
setYear((y) => y - 1);
|
|
5807
|
+
return 11;
|
|
5782
5808
|
}
|
|
5783
|
-
|
|
5784
|
-
|
|
5785
|
-
|
|
5786
|
-
|
|
5787
|
-
|
|
5788
|
-
|
|
5789
|
-
|
|
5790
|
-
|
|
5791
|
-
const to = e.target.value ? new Date(e.target.value) : null;
|
|
5792
|
-
onChange([rangeVal[0], to]);
|
|
5793
|
-
},
|
|
5794
|
-
className: halfInputClasses
|
|
5809
|
+
return m - 1;
|
|
5810
|
+
});
|
|
5811
|
+
}, []);
|
|
5812
|
+
const goToNextMonth = React41.useCallback(() => {
|
|
5813
|
+
setMonth((m) => {
|
|
5814
|
+
if (m === 11) {
|
|
5815
|
+
setYear((y) => y + 1);
|
|
5816
|
+
return 0;
|
|
5795
5817
|
}
|
|
5796
|
-
|
|
5797
|
-
|
|
5798
|
-
|
|
5799
|
-
|
|
5800
|
-
|
|
5801
|
-
|
|
5802
|
-
|
|
5803
|
-
|
|
5804
|
-
|
|
5805
|
-
|
|
5806
|
-
|
|
5807
|
-
|
|
5808
|
-
|
|
5809
|
-
|
|
5818
|
+
return m + 1;
|
|
5819
|
+
});
|
|
5820
|
+
}, []);
|
|
5821
|
+
const onSelect = React41.useCallback(
|
|
5822
|
+
(date) => {
|
|
5823
|
+
if (mode === "single") {
|
|
5824
|
+
onValueChange?.(date);
|
|
5825
|
+
return;
|
|
5826
|
+
}
|
|
5827
|
+
if (!value || value instanceof Date) {
|
|
5828
|
+
onValueChange?.({ from: date });
|
|
5829
|
+
return;
|
|
5830
|
+
}
|
|
5831
|
+
const range = value;
|
|
5832
|
+
if (range.to || date.getTime() < range.from.getTime()) {
|
|
5833
|
+
onValueChange?.({ from: date });
|
|
5834
|
+
} else {
|
|
5835
|
+
onValueChange?.({ from: range.from, to: date });
|
|
5836
|
+
}
|
|
5837
|
+
},
|
|
5838
|
+
[mode, value, onValueChange]
|
|
5839
|
+
);
|
|
5840
|
+
const ctxValue = React41.useMemo(
|
|
5841
|
+
() => ({
|
|
5842
|
+
mode,
|
|
5843
|
+
selected: value,
|
|
5844
|
+
onSelect,
|
|
5845
|
+
month,
|
|
5846
|
+
year,
|
|
5847
|
+
setMonth,
|
|
5848
|
+
setYear,
|
|
5849
|
+
goToPrevMonth,
|
|
5850
|
+
goToNextMonth,
|
|
5851
|
+
today,
|
|
5852
|
+
hoveredDate,
|
|
5853
|
+
setHoveredDate
|
|
5854
|
+
}),
|
|
5855
|
+
[
|
|
5856
|
+
mode,
|
|
5857
|
+
value,
|
|
5858
|
+
onSelect,
|
|
5859
|
+
month,
|
|
5860
|
+
year,
|
|
5861
|
+
goToPrevMonth,
|
|
5862
|
+
goToNextMonth,
|
|
5863
|
+
today,
|
|
5864
|
+
hoveredDate
|
|
5865
|
+
]
|
|
5866
|
+
);
|
|
5867
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(DatePickerContext.Provider, { value: ctxValue, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
5868
|
+
"div",
|
|
5869
|
+
{
|
|
5870
|
+
ref,
|
|
5871
|
+
className: cn(
|
|
5872
|
+
"flex flex-col overflow-clip",
|
|
5873
|
+
"bg-datepicker-bg border border-datepicker-border rounded-md shadow-lg",
|
|
5874
|
+
className
|
|
5875
|
+
),
|
|
5876
|
+
...props,
|
|
5877
|
+
children
|
|
5878
|
+
}
|
|
5879
|
+
) });
|
|
5880
|
+
}
|
|
5881
|
+
);
|
|
5882
|
+
DatePicker.displayName = "DatePicker";
|
|
5883
|
+
function defaultFormatDate(date) {
|
|
5884
|
+
return date.toLocaleDateString("en-US", {
|
|
5885
|
+
month: "short",
|
|
5886
|
+
day: "numeric",
|
|
5887
|
+
year: "numeric"
|
|
5888
|
+
});
|
|
5889
|
+
}
|
|
5890
|
+
var DatePickerSelects = React41.forwardRef(({ className, formatDate = defaultFormatDate, ...props }, ref) => {
|
|
5891
|
+
const { selected } = useDatePickerContext();
|
|
5892
|
+
const fromDate = selected instanceof Date ? selected : selected?.from;
|
|
5893
|
+
const toDate = selected instanceof Date ? void 0 : selected?.to;
|
|
5894
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
5895
|
+
"div",
|
|
5896
|
+
{
|
|
5897
|
+
ref,
|
|
5898
|
+
className: cn("flex flex-col items-start pt-lg px-lg", className),
|
|
5899
|
+
...props,
|
|
5900
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex items-center gap-base w-full", children: [
|
|
5901
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex-1 flex items-center gap-base min-w-0 px-base py-sm bg-gradient-to-t from-[var(--color-select-bg-default)] to-[var(--color-select-bg-gradient-to)] border border-[var(--color-select-border-default)] rounded-base shadow-sm", children: [
|
|
5902
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "flex-1 text-sm font-regular leading-sm text-datepicker-header-text truncate", children: fromDate ? formatDate(fromDate) : "Start date" }),
|
|
5903
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_icons27.Icon, { icon: import_icons27.faCalendarOutline, size: "sm", className: "shrink-0 text-datepicker-header-text" })
|
|
5904
|
+
] }),
|
|
5905
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
5906
|
+
import_icons27.Icon,
|
|
5907
|
+
{
|
|
5908
|
+
icon: import_icons27.faArrowRightOutline,
|
|
5909
|
+
size: "sm",
|
|
5910
|
+
className: "shrink-0 text-datepicker-header-weekday"
|
|
5911
|
+
}
|
|
5912
|
+
),
|
|
5913
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex-1 flex items-center gap-base min-w-0 px-base py-sm bg-gradient-to-t from-[var(--color-select-bg-default)] to-[var(--color-select-bg-gradient-to)] border border-[var(--color-select-border-default)] rounded-base shadow-sm", children: [
|
|
5914
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "flex-1 text-sm font-regular leading-sm text-datepicker-header-text truncate", children: toDate ? formatDate(toDate) : "End date" }),
|
|
5915
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_icons27.Icon, { icon: import_icons27.faCalendarOutline, size: "sm", className: "shrink-0 text-datepicker-header-text" })
|
|
5916
|
+
] })
|
|
5917
|
+
] })
|
|
5918
|
+
}
|
|
5919
|
+
);
|
|
5920
|
+
});
|
|
5921
|
+
DatePickerSelects.displayName = "DatePickerSelects";
|
|
5922
|
+
var DatePickerDay = ({ date, isOutside }) => {
|
|
5923
|
+
const { mode, selected, onSelect, today, hoveredDate, setHoveredDate } = useDatePickerContext();
|
|
5924
|
+
const isToday = isSameDay(date, today);
|
|
5925
|
+
const isSelected = selected instanceof Date ? isSameDay(date, selected) : selected?.from ? isSameDay(date, selected.from) || (selected.to ? isSameDay(date, selected.to) : false) : false;
|
|
5926
|
+
const isRangeStart = mode === "range" && selected && !(selected instanceof Date) && selected.from && isSameDay(date, selected.from);
|
|
5927
|
+
const isRangeEnd = mode === "range" && selected && !(selected instanceof Date) && selected.to && isSameDay(date, selected.to);
|
|
5928
|
+
const inRange = mode === "range" && selected && !(selected instanceof Date) && selected.from && selected.to && !isSelected && isInRange(date, selected.from, selected.to);
|
|
5929
|
+
const inPreviewRange = mode === "range" && selected && !(selected instanceof Date) && selected.from && !selected.to && hoveredDate && !isSelected && hoveredDate.getTime() > selected.from.getTime() && isInRange(date, selected.from, hoveredDate);
|
|
5930
|
+
const isInRangeOrPreview = inRange || inPreviewRange;
|
|
5931
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
|
|
5810
5932
|
"button",
|
|
5811
5933
|
{
|
|
5812
5934
|
type: "button",
|
|
5813
|
-
onClick: () =>
|
|
5814
|
-
|
|
5815
|
-
|
|
5816
|
-
|
|
5935
|
+
onClick: () => !isOutside && onSelect(date),
|
|
5936
|
+
onMouseEnter: () => mode === "range" && setHoveredDate(date),
|
|
5937
|
+
onMouseLeave: () => mode === "range" && setHoveredDate(void 0),
|
|
5938
|
+
disabled: isOutside,
|
|
5817
5939
|
className: cn(
|
|
5818
|
-
"
|
|
5819
|
-
|
|
5940
|
+
"relative flex flex-col items-center justify-center w-9 rounded-full p-2 cursor-pointer transition-colors",
|
|
5941
|
+
"text-sm font-semibold leading-sm text-center",
|
|
5942
|
+
// Default
|
|
5943
|
+
!isOutside && !isSelected && !isInRangeOrPreview && "text-datepicker-day-text-default hover:bg-datepicker-day-bg-hover",
|
|
5944
|
+
// Outside month (disabled)
|
|
5945
|
+
isOutside && "text-datepicker-day-text-disabled cursor-default",
|
|
5946
|
+
// Selected
|
|
5947
|
+
isSelected && "bg-datepicker-day-bg-selected text-datepicker-day-text-selected",
|
|
5948
|
+
// In range
|
|
5949
|
+
isInRangeOrPreview && "bg-datepicker-day-bg-range text-datepicker-day-text-range",
|
|
5950
|
+
// Range start/end get full rounded; in-range items could be less rounded
|
|
5951
|
+
(isRangeStart || isRangeEnd) && "rounded-full"
|
|
5820
5952
|
),
|
|
5821
|
-
children:
|
|
5822
|
-
|
|
5823
|
-
|
|
5824
|
-
|
|
5825
|
-
|
|
5826
|
-
|
|
5827
|
-
|
|
5828
|
-
// src/components/ui/filter/value-inputs/select-value-input.tsx
|
|
5829
|
-
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
5830
|
-
var SingleSelectValueInput = ({
|
|
5831
|
-
value,
|
|
5832
|
-
onChange,
|
|
5833
|
-
onSubmit,
|
|
5834
|
-
options,
|
|
5835
|
-
className
|
|
5836
|
-
}) => /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: cn("flex flex-col gap-xs p-base max-h-[250px] overflow-y-auto", className), children: options.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
5837
|
-
"button",
|
|
5838
|
-
{
|
|
5839
|
-
type: "button",
|
|
5840
|
-
onClick: () => {
|
|
5841
|
-
onChange(opt);
|
|
5842
|
-
onSubmit?.();
|
|
5843
|
-
},
|
|
5844
|
-
className: cn(
|
|
5845
|
-
"flex items-center gap-base p-base rounded-base cursor-pointer transition-colors text-left",
|
|
5846
|
-
"hover:bg-[var(--color-dropdown-item-hover)]",
|
|
5847
|
-
value === opt && "bg-[var(--color-dropdown-item-hover)]"
|
|
5848
|
-
),
|
|
5849
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "text-sm font-regular leading-sm text-[var(--color-foreground)]", children: opt })
|
|
5850
|
-
},
|
|
5851
|
-
opt
|
|
5852
|
-
)) });
|
|
5853
|
-
SingleSelectValueInput.displayName = "SingleSelectValueInput";
|
|
5854
|
-
var MultiSelectValueInput = ({
|
|
5855
|
-
value,
|
|
5856
|
-
onChange,
|
|
5857
|
-
onSubmit,
|
|
5858
|
-
options,
|
|
5859
|
-
className
|
|
5860
|
-
}) => {
|
|
5861
|
-
const selected = Array.isArray(value) ? value : [];
|
|
5862
|
-
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: cn("flex flex-col gap-xs p-base", className), children: [
|
|
5863
|
-
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "flex flex-col max-h-[200px] overflow-y-auto", children: options.map((opt) => {
|
|
5864
|
-
const isSelected = selected.includes(opt);
|
|
5865
|
-
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
|
|
5866
|
-
"button",
|
|
5867
|
-
{
|
|
5868
|
-
type: "button",
|
|
5869
|
-
onClick: () => {
|
|
5870
|
-
const next = isSelected ? selected.filter((s) => s !== opt) : [...selected, opt];
|
|
5871
|
-
onChange(next);
|
|
5872
|
-
},
|
|
5873
|
-
className: cn(
|
|
5874
|
-
"flex items-center gap-base p-base rounded-base cursor-pointer transition-colors text-left",
|
|
5875
|
-
"hover:bg-[var(--color-dropdown-item-hover)]"
|
|
5876
|
-
),
|
|
5877
|
-
children: [
|
|
5878
|
-
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
5879
|
-
"span",
|
|
5880
|
-
{
|
|
5881
|
-
className: cn(
|
|
5882
|
-
"flex items-center justify-center size-4 rounded-xs border transition-colors",
|
|
5883
|
-
isSelected ? "bg-[var(--color-primary)] border-[var(--color-primary)]" : "border-[var(--color-input)] bg-[var(--color-background)]"
|
|
5884
|
-
),
|
|
5885
|
-
children: isSelected && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("svg", { width: "10", height: "10", viewBox: "0 0 10 10", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("path", { d: "M2 5L4 7L8 3", stroke: "white", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) })
|
|
5886
|
-
}
|
|
5887
|
-
),
|
|
5888
|
-
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "text-sm font-regular leading-sm text-[var(--color-foreground)]", children: opt })
|
|
5889
|
-
]
|
|
5890
|
-
},
|
|
5891
|
-
opt
|
|
5892
|
-
);
|
|
5893
|
-
}) }),
|
|
5894
|
-
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("button", { type: "button", onClick: onSubmit, className: applyBtnClasses, children: "Apply" })
|
|
5895
|
-
] });
|
|
5896
|
-
};
|
|
5897
|
-
MultiSelectValueInput.displayName = "MultiSelectValueInput";
|
|
5898
|
-
|
|
5899
|
-
// src/components/ui/filter/value-inputs/relation-value-input.tsx
|
|
5900
|
-
var import_jsx_runtime46 = require("react/jsx-runtime");
|
|
5901
|
-
var RelationValueInput = ({
|
|
5902
|
-
value,
|
|
5903
|
-
onChange,
|
|
5904
|
-
onSubmit,
|
|
5905
|
-
className
|
|
5906
|
-
}) => {
|
|
5907
|
-
const handleKeyDown = (e) => {
|
|
5908
|
-
if (e.key === "Enter") onSubmit?.();
|
|
5909
|
-
};
|
|
5910
|
-
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: cn("flex flex-col gap-base p-base", className), children: [
|
|
5911
|
-
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
5912
|
-
"input",
|
|
5913
|
-
{
|
|
5914
|
-
type: "text",
|
|
5915
|
-
value: value ?? "",
|
|
5916
|
-
onChange: (e) => onChange(e.target.value),
|
|
5917
|
-
onKeyDown: handleKeyDown,
|
|
5918
|
-
placeholder: "Search...",
|
|
5919
|
-
autoFocus: true,
|
|
5920
|
-
className: inputClasses
|
|
5921
|
-
}
|
|
5922
|
-
),
|
|
5923
|
-
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("button", { type: "button", onClick: onSubmit, className: applyBtnClasses, children: "Apply" })
|
|
5924
|
-
] });
|
|
5925
|
-
};
|
|
5926
|
-
RelationValueInput.displayName = "RelationValueInput";
|
|
5927
|
-
|
|
5928
|
-
// src/components/ui/filter/value-input.tsx
|
|
5929
|
-
var import_jsx_runtime47 = require("react/jsx-runtime");
|
|
5930
|
-
var ValueInput = ({
|
|
5931
|
-
dataType,
|
|
5932
|
-
operator,
|
|
5933
|
-
value,
|
|
5934
|
-
onChange,
|
|
5935
|
-
onSubmit,
|
|
5936
|
-
options = [],
|
|
5937
|
-
className
|
|
5938
|
-
}) => {
|
|
5939
|
-
const inputType = getValueInputType(dataType, operator);
|
|
5940
|
-
if (!inputType) return null;
|
|
5941
|
-
switch (inputType) {
|
|
5942
|
-
case "TextInput":
|
|
5943
|
-
return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(TextValueInput, { value, onChange, onSubmit, className });
|
|
5944
|
-
case "NumberInput":
|
|
5945
|
-
return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(NumberValueInput, { value, onChange, onSubmit, className });
|
|
5946
|
-
case "NumberRange":
|
|
5947
|
-
return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(NumberRangeValueInput, { value, onChange, onSubmit, className });
|
|
5948
|
-
case "PresetTags":
|
|
5949
|
-
return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(PresetTagsValueInput, { value, onChange, onSubmit, className });
|
|
5950
|
-
case "SingleSelect":
|
|
5951
|
-
return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(SingleSelectValueInput, { value, onChange, onSubmit, options, className });
|
|
5952
|
-
case "MultiSelect":
|
|
5953
|
-
return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(MultiSelectValueInput, { value, onChange, onSubmit, options, className });
|
|
5954
|
-
case "DatePicker":
|
|
5955
|
-
return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(DatePickerValueInput, { value, onChange, onSubmit, className });
|
|
5956
|
-
case "DateRange":
|
|
5957
|
-
return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(DateRangeValueInput, { value, onChange, onSubmit, className });
|
|
5958
|
-
case "RelationPicker":
|
|
5959
|
-
case "MultiRelationPicker":
|
|
5960
|
-
return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(RelationValueInput, { value, onChange, onSubmit, className });
|
|
5961
|
-
default:
|
|
5962
|
-
return null;
|
|
5963
|
-
}
|
|
5953
|
+
children: [
|
|
5954
|
+
date.getDate(),
|
|
5955
|
+
isToday && !isOutside && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "absolute bottom-0.5 left-1/2 -translate-x-1/2 size-1.5 rounded-full bg-datepicker-day-today" })
|
|
5956
|
+
]
|
|
5957
|
+
}
|
|
5958
|
+
);
|
|
5964
5959
|
};
|
|
5965
|
-
|
|
5966
|
-
|
|
5967
|
-
|
|
5968
|
-
|
|
5969
|
-
|
|
5970
|
-
|
|
5971
|
-
|
|
5972
|
-
|
|
5973
|
-
|
|
5974
|
-
|
|
5975
|
-
|
|
5960
|
+
var DatePickerCalendar = React41.forwardRef(({ className, header, ...props }, ref) => {
|
|
5961
|
+
const { month, year, goToPrevMonth, goToNextMonth } = useDatePickerContext();
|
|
5962
|
+
const weeks = React41.useMemo(() => {
|
|
5963
|
+
const firstDay = new Date(year, month, 1);
|
|
5964
|
+
const startOffset = getWeekdayIndex(firstDay);
|
|
5965
|
+
const daysInMonth = getDaysInMonth(year, month);
|
|
5966
|
+
const daysInPrevMonth = getDaysInMonth(
|
|
5967
|
+
month === 0 ? year - 1 : year,
|
|
5968
|
+
month === 0 ? 11 : month - 1
|
|
5969
|
+
);
|
|
5970
|
+
const days = [];
|
|
5971
|
+
for (let i = startOffset - 1; i >= 0; i--) {
|
|
5972
|
+
const d = daysInPrevMonth - i;
|
|
5973
|
+
days.push({
|
|
5974
|
+
date: new Date(
|
|
5975
|
+
month === 0 ? year - 1 : year,
|
|
5976
|
+
month === 0 ? 11 : month - 1,
|
|
5977
|
+
d
|
|
5978
|
+
),
|
|
5979
|
+
isOutside: true
|
|
5980
|
+
});
|
|
5981
|
+
}
|
|
5982
|
+
for (let d = 1; d <= daysInMonth; d++) {
|
|
5983
|
+
days.push({ date: new Date(year, month, d), isOutside: false });
|
|
5984
|
+
}
|
|
5985
|
+
const remaining = 42 - days.length;
|
|
5986
|
+
for (let d = 1; d <= remaining; d++) {
|
|
5987
|
+
days.push({
|
|
5988
|
+
date: new Date(
|
|
5989
|
+
month === 11 ? year + 1 : year,
|
|
5990
|
+
month === 11 ? 0 : month + 1,
|
|
5991
|
+
d
|
|
5992
|
+
),
|
|
5993
|
+
isOutside: true
|
|
5994
|
+
});
|
|
5995
|
+
}
|
|
5996
|
+
const result = [];
|
|
5997
|
+
for (let i = 0; i < days.length; i += 7) {
|
|
5998
|
+
result.push(days.slice(i, i + 7));
|
|
5999
|
+
}
|
|
6000
|
+
return result;
|
|
6001
|
+
}, [month, year]);
|
|
6002
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
|
|
6003
|
+
"div",
|
|
5976
6004
|
{
|
|
5977
|
-
|
|
5978
|
-
|
|
5979
|
-
|
|
5980
|
-
className: "flex items-center gap-base p-base rounded-base cursor-pointer transition-colors hover:bg-[var(--color-dropdown-item-hover)]",
|
|
6005
|
+
ref,
|
|
6006
|
+
className: cn("flex flex-col", className),
|
|
6007
|
+
...props,
|
|
5981
6008
|
children: [
|
|
5982
|
-
|
|
5983
|
-
|
|
5984
|
-
{
|
|
5985
|
-
|
|
5986
|
-
|
|
5987
|
-
|
|
5988
|
-
|
|
5989
|
-
|
|
5990
|
-
|
|
5991
|
-
|
|
5992
|
-
|
|
5993
|
-
|
|
5994
|
-
|
|
6009
|
+
header,
|
|
6010
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex flex-col gap-lg p-lg", children: [
|
|
6011
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
6012
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: "text-base font-semibold leading-base text-datepicker-header-text", children: [
|
|
6013
|
+
MONTH_NAMES[month],
|
|
6014
|
+
" ",
|
|
6015
|
+
year
|
|
6016
|
+
] }),
|
|
6017
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex items-center gap-xs", children: [
|
|
6018
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
6019
|
+
"button",
|
|
6020
|
+
{
|
|
6021
|
+
type: "button",
|
|
6022
|
+
onClick: goToPrevMonth,
|
|
6023
|
+
className: "flex items-center justify-center p-xs rounded-base hover:bg-datepicker-day-bg-hover transition-colors cursor-pointer",
|
|
6024
|
+
"aria-label": "Previous month",
|
|
6025
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_icons27.Icon, { icon: import_icons27.faChevronLeftOutline, size: "xs", className: "text-datepicker-header-nav" })
|
|
6026
|
+
}
|
|
6027
|
+
),
|
|
6028
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
6029
|
+
"button",
|
|
6030
|
+
{
|
|
6031
|
+
type: "button",
|
|
6032
|
+
onClick: goToNextMonth,
|
|
6033
|
+
className: "flex items-center justify-center p-xs rounded-base hover:bg-datepicker-day-bg-hover transition-colors cursor-pointer",
|
|
6034
|
+
"aria-label": "Next month",
|
|
6035
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_icons27.Icon, { icon: import_icons27.faChevronRightOutline, size: "xs", className: "text-datepicker-header-nav" })
|
|
6036
|
+
}
|
|
6037
|
+
)
|
|
6038
|
+
] })
|
|
6039
|
+
] }),
|
|
6040
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex flex-col", children: [
|
|
6041
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "grid grid-cols-7 gap-base py-sm", children: WEEKDAYS.map((day) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
6042
|
+
"span",
|
|
6043
|
+
{
|
|
6044
|
+
className: "w-9 text-center text-xs font-regular leading-xs text-datepicker-header-weekday",
|
|
6045
|
+
children: day
|
|
6046
|
+
},
|
|
6047
|
+
day
|
|
6048
|
+
)) }),
|
|
6049
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "flex flex-col", children: weeks.map((week, wi) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "grid grid-cols-7 gap-base", children: week.map((day, di) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
6050
|
+
DatePickerDay,
|
|
6051
|
+
{
|
|
6052
|
+
date: day.date,
|
|
6053
|
+
isOutside: day.isOutside
|
|
6054
|
+
},
|
|
6055
|
+
di
|
|
6056
|
+
)) }, wi)) })
|
|
6057
|
+
] })
|
|
5995
6058
|
] })
|
|
5996
6059
|
]
|
|
5997
6060
|
}
|
|
5998
|
-
)
|
|
5999
|
-
|
|
6000
|
-
|
|
6001
|
-
|
|
6002
|
-
|
|
6003
|
-
|
|
6004
|
-
|
|
6005
|
-
|
|
6006
|
-
|
|
6007
|
-
|
|
6008
|
-
|
|
6009
|
-
|
|
6010
|
-
e.stopPropagation();
|
|
6011
|
-
e.preventDefault();
|
|
6012
|
-
onAdvancedFilter?.();
|
|
6013
|
-
};
|
|
6014
|
-
const showAdvancedFooter = !!onAdvancedFilter;
|
|
6015
|
-
const [activeGroup, setActiveGroup] = React41.useState(null);
|
|
6016
|
-
const [search, setSearch] = React41.useState("");
|
|
6017
|
-
React41.useEffect(() => {
|
|
6018
|
-
if (!open) {
|
|
6019
|
-
setActiveGroup(null);
|
|
6020
|
-
setSearch("");
|
|
6021
|
-
}
|
|
6022
|
-
}, [open]);
|
|
6023
|
-
const groups = React41.useMemo(() => {
|
|
6024
|
-
const map = /* @__PURE__ */ new Map();
|
|
6025
|
-
for (const prop of properties) {
|
|
6026
|
-
const existing = map.get(prop.group);
|
|
6027
|
-
if (existing) {
|
|
6028
|
-
existing.count++;
|
|
6061
|
+
);
|
|
6062
|
+
});
|
|
6063
|
+
DatePickerCalendar.displayName = "DatePickerCalendar";
|
|
6064
|
+
var DatePickerSuggestions = React41.forwardRef(
|
|
6065
|
+
({ className, suggestions, formatDate = defaultFormatDate, ...props }, ref) => {
|
|
6066
|
+
const { onSelect, mode } = useDatePickerContext();
|
|
6067
|
+
const onValueChange = React41.useContext(DatePickerContext) ? void 0 : void 0;
|
|
6068
|
+
const ctx = useDatePickerContext();
|
|
6069
|
+
const handleClick = (suggestion) => {
|
|
6070
|
+
const val = suggestion.getValue();
|
|
6071
|
+
if (val instanceof Date) {
|
|
6072
|
+
ctx.onSelect(val);
|
|
6029
6073
|
} else {
|
|
6030
|
-
|
|
6031
|
-
|
|
6032
|
-
|
|
6033
|
-
|
|
6034
|
-
count: 1
|
|
6035
|
-
});
|
|
6074
|
+
ctx.onSelect(val.from);
|
|
6075
|
+
if (val.to) {
|
|
6076
|
+
setTimeout(() => ctx.onSelect(val.to), 0);
|
|
6077
|
+
}
|
|
6036
6078
|
}
|
|
6037
|
-
}
|
|
6038
|
-
|
|
6039
|
-
|
|
6040
|
-
|
|
6041
|
-
|
|
6042
|
-
|
|
6043
|
-
|
|
6044
|
-
|
|
6045
|
-
|
|
6046
|
-
|
|
6047
|
-
|
|
6048
|
-
|
|
6049
|
-
(g) => g.groupLabel.toLowerCase().includes(lower) || properties.some(
|
|
6050
|
-
(p) => p.group === g.group && p.label.toLowerCase().includes(lower)
|
|
6051
|
-
)
|
|
6052
|
-
);
|
|
6053
|
-
}, [groups, properties, search, activeGroup]);
|
|
6054
|
-
const filteredProperties = React41.useMemo(() => {
|
|
6055
|
-
if (!activeGroup) return [];
|
|
6056
|
-
const groupProps = properties.filter((p) => p.group === activeGroup);
|
|
6057
|
-
if (!search) return groupProps;
|
|
6058
|
-
const lower = search.toLowerCase();
|
|
6059
|
-
return groupProps.filter((p) => p.label.toLowerCase().includes(lower));
|
|
6060
|
-
}, [properties, activeGroup, search]);
|
|
6061
|
-
const activeGroupInfo = groups.find((g) => g.group === activeGroup);
|
|
6062
|
-
const showGlobalResults = search.length > 0 && !activeGroup && globalSearchResults.length > 0;
|
|
6063
|
-
return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(PopoverPrimitive5.Root, { open, onOpenChange, children: [
|
|
6064
|
-
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(PopoverPrimitive5.Trigger, { asChild: true, children }),
|
|
6065
|
-
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(PopoverPrimitive5.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
|
|
6066
|
-
PopoverPrimitive5.Content,
|
|
6079
|
+
};
|
|
6080
|
+
const formatSuggestionDate = (suggestion) => {
|
|
6081
|
+
const val = suggestion.getValue();
|
|
6082
|
+
if (val instanceof Date) {
|
|
6083
|
+
return formatDate(val);
|
|
6084
|
+
}
|
|
6085
|
+
const from = formatDate(val.from);
|
|
6086
|
+
const to = val.to ? formatDate(val.to) : "";
|
|
6087
|
+
return to ? `${from} - ${to}` : from;
|
|
6088
|
+
};
|
|
6089
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
|
|
6090
|
+
"div",
|
|
6067
6091
|
{
|
|
6068
|
-
|
|
6069
|
-
align: "start",
|
|
6070
|
-
onCloseAutoFocus: (e) => e.preventDefault(),
|
|
6092
|
+
ref,
|
|
6071
6093
|
className: cn(
|
|
6072
|
-
"
|
|
6073
|
-
|
|
6074
|
-
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
6075
|
-
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
|
6076
|
-
"data-[side=bottom]:slide-in-from-top-2",
|
|
6077
|
-
"min-w-[230px]"
|
|
6094
|
+
"flex flex-col border-l border-datepicker-border self-stretch shrink-0",
|
|
6095
|
+
className
|
|
6078
6096
|
),
|
|
6097
|
+
...props,
|
|
6079
6098
|
children: [
|
|
6080
|
-
|
|
6081
|
-
|
|
6082
|
-
|
|
6083
|
-
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex items-center gap-base px-md py-base border border-[var(--color-input)] rounded-md", children: [
|
|
6084
|
-
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
6085
|
-
import_icons27.Icon,
|
|
6086
|
-
{
|
|
6087
|
-
icon: import_icons27.faMagnifyingGlassOutline,
|
|
6088
|
-
size: "sm",
|
|
6089
|
-
className: "shrink-0 text-[var(--color-muted-foreground)]"
|
|
6090
|
-
}
|
|
6091
|
-
),
|
|
6092
|
-
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
6093
|
-
"input",
|
|
6094
|
-
{
|
|
6095
|
-
type: "text",
|
|
6096
|
-
value: search,
|
|
6097
|
-
onChange: (e) => setSearch(e.target.value),
|
|
6098
|
-
placeholder: "Search...",
|
|
6099
|
-
autoFocus: true,
|
|
6100
|
-
className: "flex-1 text-sm font-regular leading-sm text-[var(--color-foreground)] bg-transparent outline-none placeholder:text-[var(--color-muted-foreground)]"
|
|
6101
|
-
}
|
|
6102
|
-
)
|
|
6103
|
-
] }),
|
|
6104
|
-
showGlobalResults ? (
|
|
6105
|
-
/* ── Global search results (flat property list) ─────── */
|
|
6106
|
-
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "flex flex-col max-h-[300px] overflow-y-auto", children: globalSearchResults.map((prop) => /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
|
|
6107
|
-
"button",
|
|
6108
|
-
{
|
|
6109
|
-
type: "button",
|
|
6110
|
-
onClick: () => {
|
|
6111
|
-
onSelect(prop);
|
|
6112
|
-
onOpenChange?.(false);
|
|
6113
|
-
},
|
|
6114
|
-
className: "flex items-center gap-base p-base rounded-base cursor-pointer transition-colors hover:bg-[var(--color-dropdown-item-hover)]",
|
|
6115
|
-
children: [
|
|
6116
|
-
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
6117
|
-
import_icons27.Icon,
|
|
6118
|
-
{
|
|
6119
|
-
icon: prop.icon,
|
|
6120
|
-
size: "sm",
|
|
6121
|
-
className: "shrink-0 text-[var(--color-dropdown-item-icon)]"
|
|
6122
|
-
}
|
|
6123
|
-
),
|
|
6124
|
-
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "flex-1 text-sm font-regular leading-sm text-[var(--color-dropdown-item-text)] text-left truncate", children: prop.label }),
|
|
6125
|
-
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "text-xs font-regular leading-xs text-[var(--color-muted-foreground)]", children: prop.groupLabel })
|
|
6126
|
-
]
|
|
6127
|
-
},
|
|
6128
|
-
prop.id
|
|
6129
|
-
)) })
|
|
6130
|
-
) : (
|
|
6131
|
-
/* ── Group list ─────────────────────────────────────── */
|
|
6132
|
-
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex flex-col", children: [
|
|
6133
|
-
filteredGroups.map((g) => /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
|
|
6134
|
-
"button",
|
|
6135
|
-
{
|
|
6136
|
-
type: "button",
|
|
6137
|
-
onClick: () => {
|
|
6138
|
-
setActiveGroup(g.group);
|
|
6139
|
-
setSearch("");
|
|
6140
|
-
},
|
|
6141
|
-
className: "flex items-center gap-base p-base rounded-base cursor-pointer transition-colors hover:bg-[var(--color-dropdown-item-hover)]",
|
|
6142
|
-
children: [
|
|
6143
|
-
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
6144
|
-
import_icons27.Icon,
|
|
6145
|
-
{
|
|
6146
|
-
icon: g.groupIcon,
|
|
6147
|
-
size: "sm",
|
|
6148
|
-
className: "shrink-0 text-[var(--color-dropdown-item-icon)]"
|
|
6149
|
-
}
|
|
6150
|
-
),
|
|
6151
|
-
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "flex-1 text-sm font-regular leading-sm text-[var(--color-dropdown-item-text)] text-left truncate", children: g.groupLabel }),
|
|
6152
|
-
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "text-xs font-semibold leading-xs text-[var(--color-muted-foreground)]", children: g.count }),
|
|
6153
|
-
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
6154
|
-
import_icons27.Icon,
|
|
6155
|
-
{
|
|
6156
|
-
icon: import_icons27.faChevronRightOutline,
|
|
6157
|
-
size: "xs",
|
|
6158
|
-
className: "shrink-0 text-[var(--color-dropdown-item-icon)]"
|
|
6159
|
-
}
|
|
6160
|
-
)
|
|
6161
|
-
]
|
|
6162
|
-
},
|
|
6163
|
-
g.group
|
|
6164
|
-
)),
|
|
6165
|
-
filteredGroups.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "p-base text-sm text-[var(--color-muted-foreground)]", children: "No results" })
|
|
6166
|
-
] })
|
|
6167
|
-
)
|
|
6168
|
-
] })
|
|
6169
|
-
) : (
|
|
6170
|
-
/* ── Level 2: Properties ─────────────────────────────────── */
|
|
6171
|
-
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex flex-col gap-xs", children: [
|
|
6172
|
-
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
|
|
6173
|
-
"button",
|
|
6174
|
-
{
|
|
6175
|
-
type: "button",
|
|
6176
|
-
onClick: () => {
|
|
6177
|
-
setActiveGroup(null);
|
|
6178
|
-
setSearch("");
|
|
6179
|
-
},
|
|
6180
|
-
className: "flex items-center gap-base p-base rounded-base cursor-pointer transition-colors hover:bg-[var(--color-dropdown-item-hover)]",
|
|
6181
|
-
children: [
|
|
6182
|
-
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
6183
|
-
import_icons27.Icon,
|
|
6184
|
-
{
|
|
6185
|
-
icon: import_icons27.faChevronLeftOutline,
|
|
6186
|
-
size: "sm",
|
|
6187
|
-
className: "shrink-0 text-[var(--color-dropdown-item-icon)]"
|
|
6188
|
-
}
|
|
6189
|
-
),
|
|
6190
|
-
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "flex-1 text-xs font-semibold leading-xs text-[var(--color-muted-foreground)] text-left truncate", children: activeGroupInfo?.groupLabel })
|
|
6191
|
-
]
|
|
6192
|
-
}
|
|
6193
|
-
),
|
|
6194
|
-
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex items-center gap-base px-md py-base border border-[var(--color-input)] rounded-md", children: [
|
|
6195
|
-
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
6196
|
-
import_icons27.Icon,
|
|
6197
|
-
{
|
|
6198
|
-
icon: import_icons27.faMagnifyingGlassOutline,
|
|
6199
|
-
size: "sm",
|
|
6200
|
-
className: "shrink-0 text-[var(--color-muted-foreground)]"
|
|
6201
|
-
}
|
|
6202
|
-
),
|
|
6203
|
-
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
6204
|
-
"input",
|
|
6205
|
-
{
|
|
6206
|
-
type: "text",
|
|
6207
|
-
value: search,
|
|
6208
|
-
onChange: (e) => setSearch(e.target.value),
|
|
6209
|
-
placeholder: "Search...",
|
|
6210
|
-
autoFocus: true,
|
|
6211
|
-
className: "flex-1 text-sm font-regular leading-sm text-[var(--color-foreground)] bg-transparent outline-none placeholder:text-[var(--color-muted-foreground)]"
|
|
6212
|
-
}
|
|
6213
|
-
)
|
|
6214
|
-
] }),
|
|
6215
|
-
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex flex-col max-h-[300px] overflow-y-auto", children: [
|
|
6216
|
-
filteredProperties.map((prop) => /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
|
|
6217
|
-
"button",
|
|
6218
|
-
{
|
|
6219
|
-
type: "button",
|
|
6220
|
-
onClick: () => {
|
|
6221
|
-
onSelect(prop);
|
|
6222
|
-
onOpenChange?.(false);
|
|
6223
|
-
},
|
|
6224
|
-
className: "flex items-center gap-base p-base rounded-base cursor-pointer transition-colors hover:bg-[var(--color-dropdown-item-hover)]",
|
|
6225
|
-
children: [
|
|
6226
|
-
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
6227
|
-
import_icons27.Icon,
|
|
6228
|
-
{
|
|
6229
|
-
icon: prop.icon,
|
|
6230
|
-
size: "sm",
|
|
6231
|
-
className: "shrink-0 text-[var(--color-dropdown-item-icon)]"
|
|
6232
|
-
}
|
|
6233
|
-
),
|
|
6234
|
-
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "flex-1 text-sm font-regular leading-sm text-[var(--color-dropdown-item-text)] text-left truncate", children: prop.label })
|
|
6235
|
-
]
|
|
6236
|
-
},
|
|
6237
|
-
prop.id
|
|
6238
|
-
)),
|
|
6239
|
-
filteredProperties.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "p-base text-sm text-[var(--color-muted-foreground)]", children: "No results" })
|
|
6240
|
-
] })
|
|
6241
|
-
] })
|
|
6242
|
-
),
|
|
6243
|
-
showAdvancedFooter && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
6244
|
-
AdvancedFilterFooter,
|
|
6099
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "pt-lg px-base", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "flex items-center p-base rounded-base", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "flex-1 text-xs font-semibold leading-xs text-datepicker-suggestion-heading uppercase truncate", children: "Suggestions" }) }) }),
|
|
6100
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "flex flex-1 flex-col p-base min-w-[222px]", children: suggestions.map((suggestion, i) => /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
|
|
6101
|
+
"button",
|
|
6245
6102
|
{
|
|
6246
|
-
|
|
6247
|
-
|
|
6248
|
-
|
|
6249
|
-
|
|
6103
|
+
type: "button",
|
|
6104
|
+
onClick: () => handleClick(suggestion),
|
|
6105
|
+
className: "flex items-center gap-sm p-base rounded-base hover:bg-datepicker-suggestion-hover transition-colors cursor-pointer text-left",
|
|
6106
|
+
children: [
|
|
6107
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "text-sm font-regular leading-sm text-datepicker-suggestion-text truncate shrink-0", children: suggestion.label }),
|
|
6108
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "text-xs font-regular leading-xs text-datepicker-suggestion-date truncate", children: formatSuggestionDate(suggestion) })
|
|
6109
|
+
]
|
|
6110
|
+
},
|
|
6111
|
+
i
|
|
6112
|
+
)) })
|
|
6250
6113
|
]
|
|
6251
6114
|
}
|
|
6252
|
-
)
|
|
6253
|
-
|
|
6254
|
-
|
|
6255
|
-
|
|
6256
|
-
|
|
6257
|
-
|
|
6258
|
-
|
|
6259
|
-
var import_icons28 = require("@l3mpire/icons");
|
|
6260
|
-
var import_jsx_runtime49 = require("react/jsx-runtime");
|
|
6261
|
-
var KebabMenu = ({
|
|
6262
|
-
onConvertToAdvanced,
|
|
6263
|
-
onDelete,
|
|
6264
|
-
open,
|
|
6265
|
-
onOpenChange,
|
|
6266
|
-
children
|
|
6267
|
-
}) => /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(PopoverPrimitive6.Root, { open, onOpenChange, children: [
|
|
6268
|
-
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(PopoverPrimitive6.Trigger, { asChild: true, children }),
|
|
6269
|
-
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(PopoverPrimitive6.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
|
|
6270
|
-
PopoverPrimitive6.Content,
|
|
6115
|
+
);
|
|
6116
|
+
}
|
|
6117
|
+
);
|
|
6118
|
+
DatePickerSuggestions.displayName = "DatePickerSuggestions";
|
|
6119
|
+
var DatePickerFooter = React41.forwardRef(
|
|
6120
|
+
({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
6121
|
+
"div",
|
|
6271
6122
|
{
|
|
6272
|
-
|
|
6273
|
-
align: "end",
|
|
6123
|
+
ref,
|
|
6274
6124
|
className: cn(
|
|
6275
|
-
"
|
|
6276
|
-
"
|
|
6277
|
-
"
|
|
6278
|
-
|
|
6279
|
-
"data-[side=bottom]:slide-in-from-top-2",
|
|
6280
|
-
"min-w-[210px]"
|
|
6125
|
+
"flex items-center justify-between p-lg",
|
|
6126
|
+
"border-t border-datepicker-footer-border",
|
|
6127
|
+
"bg-datepicker-bg",
|
|
6128
|
+
className
|
|
6281
6129
|
),
|
|
6282
|
-
|
|
6283
|
-
|
|
6284
|
-
"button",
|
|
6285
|
-
{
|
|
6286
|
-
type: "button",
|
|
6287
|
-
onClick: () => {
|
|
6288
|
-
onConvertToAdvanced();
|
|
6289
|
-
onOpenChange?.(false);
|
|
6290
|
-
},
|
|
6291
|
-
className: "flex items-center gap-base p-base rounded-base cursor-pointer transition-colors hover:bg-[var(--color-dropdown-item-hover)]",
|
|
6292
|
-
children: [
|
|
6293
|
-
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
6294
|
-
import_icons28.Icon,
|
|
6295
|
-
{
|
|
6296
|
-
icon: import_icons28.faArrowRightOutline,
|
|
6297
|
-
size: "sm",
|
|
6298
|
-
className: "shrink-0 text-[var(--color-dropdown-item-icon)]"
|
|
6299
|
-
}
|
|
6300
|
-
),
|
|
6301
|
-
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "text-sm font-regular leading-sm text-[var(--color-dropdown-item-text)]", children: "Convert to advanced" })
|
|
6302
|
-
]
|
|
6303
|
-
}
|
|
6304
|
-
),
|
|
6305
|
-
onConvertToAdvanced && onDelete && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "h-px mx-base my-xs bg-[var(--color-border)]" }),
|
|
6306
|
-
onDelete && /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
|
|
6307
|
-
"button",
|
|
6308
|
-
{
|
|
6309
|
-
type: "button",
|
|
6310
|
-
onClick: () => {
|
|
6311
|
-
onDelete();
|
|
6312
|
-
onOpenChange?.(false);
|
|
6313
|
-
},
|
|
6314
|
-
className: "flex items-center gap-base p-base rounded-base cursor-pointer transition-colors hover:bg-[var(--color-dropdown-item-hover)]",
|
|
6315
|
-
children: [
|
|
6316
|
-
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
6317
|
-
import_icons28.Icon,
|
|
6318
|
-
{
|
|
6319
|
-
icon: import_icons28.faTrashOutline,
|
|
6320
|
-
size: "sm",
|
|
6321
|
-
className: "shrink-0 text-[var(--color-destructive)]"
|
|
6322
|
-
}
|
|
6323
|
-
),
|
|
6324
|
-
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "text-sm font-regular leading-sm text-[var(--color-destructive)]", children: "Delete filter" })
|
|
6325
|
-
]
|
|
6326
|
-
}
|
|
6327
|
-
)
|
|
6328
|
-
]
|
|
6130
|
+
...props,
|
|
6131
|
+
children
|
|
6329
6132
|
}
|
|
6330
|
-
)
|
|
6331
|
-
|
|
6332
|
-
|
|
6333
|
-
|
|
6334
|
-
|
|
6335
|
-
|
|
6336
|
-
|
|
6337
|
-
|
|
6338
|
-
|
|
6339
|
-
|
|
6340
|
-
|
|
6341
|
-
condition,
|
|
6342
|
-
mode,
|
|
6343
|
-
onUpdate,
|
|
6344
|
-
onClose,
|
|
6345
|
-
open,
|
|
6346
|
-
onOpenChange,
|
|
6347
|
-
children
|
|
6348
|
-
}) => {
|
|
6349
|
-
const [view, setView] = React42.useState(
|
|
6350
|
-
mode === "add" ? "value" : "operator"
|
|
6351
|
-
);
|
|
6352
|
-
const [localOperator, setLocalOperator] = React42.useState(
|
|
6353
|
-
condition.operator
|
|
6354
|
-
);
|
|
6355
|
-
const [localValue, setLocalValue] = React42.useState(
|
|
6356
|
-
condition.value
|
|
6357
|
-
);
|
|
6358
|
-
React42.useEffect(() => {
|
|
6359
|
-
if (open) {
|
|
6360
|
-
setView(mode === "add" ? "value" : "operator");
|
|
6361
|
-
setLocalOperator(condition.operator);
|
|
6362
|
-
setLocalValue(condition.value);
|
|
6363
|
-
}
|
|
6364
|
-
}, [open, mode, condition.operator, condition.value]);
|
|
6365
|
-
const handleOperatorSelect = (op) => {
|
|
6366
|
-
setLocalOperator(op);
|
|
6367
|
-
if (isNoValueOperator(op)) {
|
|
6368
|
-
onUpdate({ ...condition, operator: op, value: null });
|
|
6369
|
-
onOpenChange?.(false);
|
|
6370
|
-
onClose();
|
|
6371
|
-
} else {
|
|
6372
|
-
if (op !== localOperator) {
|
|
6373
|
-
setLocalValue(null);
|
|
6374
|
-
}
|
|
6375
|
-
setView("value");
|
|
6376
|
-
}
|
|
6377
|
-
};
|
|
6378
|
-
const handleSubmit = () => {
|
|
6379
|
-
onUpdate({ ...condition, operator: localOperator, value: localValue });
|
|
6380
|
-
onOpenChange?.(false);
|
|
6381
|
-
onClose();
|
|
6382
|
-
};
|
|
6383
|
-
return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(PopoverPrimitive7.Root, { open, onOpenChange, children: [
|
|
6384
|
-
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(PopoverPrimitive7.Trigger, { asChild: true, children }),
|
|
6385
|
-
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(PopoverPrimitive7.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
|
|
6386
|
-
PopoverPrimitive7.Content,
|
|
6387
|
-
{
|
|
6388
|
-
sideOffset: 4,
|
|
6389
|
-
align: "start",
|
|
6390
|
-
className: cn(
|
|
6391
|
-
"z-50 flex flex-col overflow-clip",
|
|
6392
|
-
"bg-[var(--color-dropdown-bg)] border border-[var(--color-dropdown-border)] rounded-md shadow-lg",
|
|
6393
|
-
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
6394
|
-
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
|
6395
|
-
"data-[side=bottom]:slide-in-from-top-2",
|
|
6396
|
-
"min-w-[240px]"
|
|
6397
|
-
),
|
|
6398
|
-
children: [
|
|
6399
|
-
/* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "flex items-center gap-base px-base pt-base pb-xs border-b border-[var(--color-border)]", children: [
|
|
6400
|
-
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
6401
|
-
import_icons29.Icon,
|
|
6402
|
-
{
|
|
6403
|
-
icon: propertyDef.icon,
|
|
6404
|
-
size: "sm",
|
|
6405
|
-
className: "shrink-0 text-[var(--color-dropdown-item-icon)]"
|
|
6406
|
-
}
|
|
6407
|
-
),
|
|
6408
|
-
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "text-sm font-semibold leading-sm text-[var(--color-foreground)]", children: propertyDef.label }),
|
|
6409
|
-
localOperator && view === "value" && /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
|
|
6410
|
-
"button",
|
|
6411
|
-
{
|
|
6412
|
-
type: "button",
|
|
6413
|
-
onClick: () => setView("operator"),
|
|
6414
|
-
className: "ml-auto text-xs font-regular text-[var(--color-muted-foreground)] hover:text-[var(--color-foreground)] cursor-pointer transition-colors",
|
|
6415
|
-
children: [
|
|
6416
|
-
localOperator,
|
|
6417
|
-
" \u25BE"
|
|
6418
|
-
]
|
|
6419
|
-
}
|
|
6420
|
-
)
|
|
6421
|
-
] }),
|
|
6422
|
-
view === "operator" ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "p-xs", children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
6423
|
-
OperatorList,
|
|
6424
|
-
{
|
|
6425
|
-
dataType: propertyDef.type,
|
|
6426
|
-
activeOperator: localOperator,
|
|
6427
|
-
onSelect: handleOperatorSelect
|
|
6428
|
-
}
|
|
6429
|
-
) }) : localOperator && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
6430
|
-
ValueInput,
|
|
6431
|
-
{
|
|
6432
|
-
dataType: propertyDef.type,
|
|
6433
|
-
operator: localOperator,
|
|
6434
|
-
value: localValue,
|
|
6435
|
-
onChange: setLocalValue,
|
|
6436
|
-
onSubmit: handleSubmit,
|
|
6437
|
-
options: propertyDef.options
|
|
6438
|
-
}
|
|
6439
|
-
)
|
|
6440
|
-
]
|
|
6441
|
-
}
|
|
6442
|
-
) })
|
|
6443
|
-
] });
|
|
6444
|
-
};
|
|
6445
|
-
FilterEditor.displayName = "FilterEditor";
|
|
6446
|
-
|
|
6447
|
-
// src/components/ui/filter/interactive-filter-chip.tsx
|
|
6448
|
-
var React43 = __toESM(require("react"));
|
|
6449
|
-
var PopoverPrimitive8 = __toESM(require("@radix-ui/react-popover"));
|
|
6450
|
-
var import_jsx_runtime51 = require("react/jsx-runtime");
|
|
6451
|
-
function formatFilterValue(value) {
|
|
6452
|
-
if (value == null) return void 0;
|
|
6453
|
-
if (typeof value === "boolean") return value ? "Yes" : "No";
|
|
6454
|
-
if (value instanceof Date) {
|
|
6455
|
-
return value.toLocaleDateString("en-US", {
|
|
6456
|
-
month: "short",
|
|
6457
|
-
day: "numeric",
|
|
6458
|
-
year: "numeric"
|
|
6459
|
-
});
|
|
6460
|
-
}
|
|
6461
|
-
if (Array.isArray(value)) {
|
|
6462
|
-
if (value.length === 0) return void 0;
|
|
6463
|
-
if (value.length === 2 && typeof value[0] === "number") {
|
|
6464
|
-
return `${value[0]} \u2013 ${value[1]}`;
|
|
6133
|
+
)
|
|
6134
|
+
);
|
|
6135
|
+
DatePickerFooter.displayName = "DatePickerFooter";
|
|
6136
|
+
var DatePickerPanel = React41.forwardRef(
|
|
6137
|
+
({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
6138
|
+
"div",
|
|
6139
|
+
{
|
|
6140
|
+
ref,
|
|
6141
|
+
className: cn("flex items-start", className),
|
|
6142
|
+
...props,
|
|
6143
|
+
children
|
|
6465
6144
|
}
|
|
6466
|
-
|
|
6467
|
-
|
|
6468
|
-
|
|
6469
|
-
|
|
6470
|
-
|
|
6471
|
-
|
|
6472
|
-
|
|
6145
|
+
)
|
|
6146
|
+
);
|
|
6147
|
+
DatePickerPanel.displayName = "DatePickerPanel";
|
|
6148
|
+
var DatePickerRoot = PopoverPrimitive5.Root;
|
|
6149
|
+
var DatePickerTrigger = PopoverPrimitive5.Trigger;
|
|
6150
|
+
var DatePickerPopover = React41.forwardRef(({ className, sideOffset = 4, align = "start", children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(PopoverPrimitive5.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
6151
|
+
PopoverPrimitive5.Content,
|
|
6152
|
+
{
|
|
6153
|
+
ref,
|
|
6154
|
+
sideOffset,
|
|
6155
|
+
align,
|
|
6156
|
+
className: cn(
|
|
6157
|
+
"z-50",
|
|
6158
|
+
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
6159
|
+
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
|
6160
|
+
"data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2",
|
|
6161
|
+
className
|
|
6162
|
+
),
|
|
6163
|
+
...props,
|
|
6164
|
+
children
|
|
6473
6165
|
}
|
|
6474
|
-
|
|
6475
|
-
|
|
6476
|
-
|
|
6477
|
-
|
|
6478
|
-
|
|
6479
|
-
|
|
6480
|
-
|
|
6481
|
-
|
|
6482
|
-
|
|
6483
|
-
|
|
6484
|
-
|
|
6485
|
-
|
|
6486
|
-
|
|
6166
|
+
) }));
|
|
6167
|
+
DatePickerPopover.displayName = "DatePickerPopover";
|
|
6168
|
+
function getDefaultSuggestions(referenceDate) {
|
|
6169
|
+
const now = referenceDate ?? /* @__PURE__ */ new Date();
|
|
6170
|
+
const today = startOfDay(now);
|
|
6171
|
+
const dayOfWeek = getWeekdayIndex(today);
|
|
6172
|
+
const startOfThisWeek = new Date(today);
|
|
6173
|
+
startOfThisWeek.setDate(today.getDate() - dayOfWeek);
|
|
6174
|
+
const endOfThisWeek = new Date(startOfThisWeek);
|
|
6175
|
+
endOfThisWeek.setDate(startOfThisWeek.getDate() + 6);
|
|
6176
|
+
const startOfThisMonth = new Date(today.getFullYear(), today.getMonth(), 1);
|
|
6177
|
+
const endOfThisMonth = new Date(
|
|
6178
|
+
today.getFullYear(),
|
|
6179
|
+
today.getMonth() + 1,
|
|
6180
|
+
0
|
|
6181
|
+
);
|
|
6182
|
+
const startOfThisYear = new Date(today.getFullYear(), 0, 1);
|
|
6183
|
+
const endOfThisYear = new Date(today.getFullYear(), 11, 31);
|
|
6184
|
+
const startOfLastWeek = new Date(startOfThisWeek);
|
|
6185
|
+
startOfLastWeek.setDate(startOfThisWeek.getDate() - 7);
|
|
6186
|
+
const endOfLastWeek = new Date(startOfThisWeek);
|
|
6187
|
+
endOfLastWeek.setDate(startOfThisWeek.getDate() - 1);
|
|
6188
|
+
const startOfLastMonth = new Date(
|
|
6189
|
+
today.getFullYear(),
|
|
6190
|
+
today.getMonth() - 1,
|
|
6191
|
+
1
|
|
6192
|
+
);
|
|
6193
|
+
const endOfLastMonth = new Date(today.getFullYear(), today.getMonth(), 0);
|
|
6194
|
+
const startOfLastYear = new Date(today.getFullYear() - 1, 0, 1);
|
|
6195
|
+
const endOfLastYear = new Date(today.getFullYear() - 1, 11, 31);
|
|
6196
|
+
return [
|
|
6197
|
+
{ label: "Today", getValue: () => today },
|
|
6487
6198
|
{
|
|
6488
|
-
|
|
6489
|
-
|
|
6490
|
-
|
|
6491
|
-
|
|
6492
|
-
|
|
6493
|
-
|
|
6494
|
-
|
|
6495
|
-
|
|
6496
|
-
|
|
6497
|
-
|
|
6498
|
-
|
|
6199
|
+
label: "This week",
|
|
6200
|
+
getValue: () => ({ from: startOfThisWeek, to: endOfThisWeek })
|
|
6201
|
+
},
|
|
6202
|
+
{
|
|
6203
|
+
label: "This month",
|
|
6204
|
+
getValue: () => ({ from: startOfThisMonth, to: endOfThisMonth })
|
|
6205
|
+
},
|
|
6206
|
+
{
|
|
6207
|
+
label: "This year",
|
|
6208
|
+
getValue: () => ({ from: startOfThisYear, to: endOfThisYear })
|
|
6209
|
+
},
|
|
6210
|
+
{
|
|
6211
|
+
label: "Last week",
|
|
6212
|
+
getValue: () => ({ from: startOfLastWeek, to: endOfLastWeek })
|
|
6213
|
+
},
|
|
6214
|
+
{
|
|
6215
|
+
label: "Last month",
|
|
6216
|
+
getValue: () => ({ from: startOfLastMonth, to: endOfLastMonth })
|
|
6217
|
+
},
|
|
6218
|
+
{
|
|
6219
|
+
label: "Last year",
|
|
6220
|
+
getValue: () => ({ from: startOfLastYear, to: endOfLastYear })
|
|
6499
6221
|
}
|
|
6500
|
-
|
|
6501
|
-
|
|
6502
|
-
|
|
6503
|
-
|
|
6504
|
-
|
|
6505
|
-
|
|
6506
|
-
|
|
6507
|
-
|
|
6508
|
-
|
|
6509
|
-
|
|
6510
|
-
|
|
6511
|
-
|
|
6222
|
+
];
|
|
6223
|
+
}
|
|
6224
|
+
|
|
6225
|
+
// src/components/ui/filter/value-inputs/date-value-input.tsx
|
|
6226
|
+
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
6227
|
+
var RELATIVE_DATE_PRESETS = [
|
|
6228
|
+
{ group: "Past", options: ["Today", "Yesterday", "Last 7 days", "Last 14 days", "Last 30 days", "Last 90 days"] },
|
|
6229
|
+
{ group: "Current", options: ["This week", "This month", "This quarter", "This year"] },
|
|
6230
|
+
{ group: "Future", options: ["Tomorrow", "Next 7 days", "Next 14 days", "Next 30 days", "Next week", "Next month", "Next quarter"] }
|
|
6231
|
+
];
|
|
6232
|
+
var DateCalendarValueInput = ({
|
|
6233
|
+
operator,
|
|
6234
|
+
value,
|
|
6235
|
+
onChange,
|
|
6236
|
+
onSubmit,
|
|
6512
6237
|
className
|
|
6513
6238
|
}) => {
|
|
6514
|
-
const
|
|
6515
|
-
const
|
|
6516
|
-
|
|
6517
|
-
|
|
6518
|
-
|
|
6519
|
-
|
|
6520
|
-
|
|
6521
|
-
|
|
6522
|
-
autoOpenHandled.current = true;
|
|
6523
|
-
setValueOpen(true);
|
|
6524
|
-
}
|
|
6525
|
-
}, [autoOpen, condition.operator]);
|
|
6526
|
-
React43.useEffect(() => {
|
|
6527
|
-
if (!operatorOpen && pendingValueOpen) {
|
|
6528
|
-
setPendingValueOpen(false);
|
|
6529
|
-
setValueOpen(true);
|
|
6239
|
+
const isRange = operator === "is between";
|
|
6240
|
+
const pickerValue = React42.useMemo(() => {
|
|
6241
|
+
if (isRange) {
|
|
6242
|
+
if (Array.isArray(value) && value.length === 2) {
|
|
6243
|
+
const [from, to] = value;
|
|
6244
|
+
return { from, to };
|
|
6245
|
+
}
|
|
6246
|
+
return void 0;
|
|
6530
6247
|
}
|
|
6531
|
-
|
|
6532
|
-
|
|
6533
|
-
|
|
6534
|
-
|
|
6535
|
-
|
|
6248
|
+
return value instanceof Date ? value : void 0;
|
|
6249
|
+
}, [value, isRange]);
|
|
6250
|
+
const handleValueChange = (v) => {
|
|
6251
|
+
if (v instanceof Date) {
|
|
6252
|
+
onChange(v);
|
|
6253
|
+
if (!isRange) onSubmit?.();
|
|
6536
6254
|
} else {
|
|
6537
|
-
const
|
|
6538
|
-
|
|
6539
|
-
|
|
6540
|
-
if (
|
|
6541
|
-
|
|
6255
|
+
const range = v;
|
|
6256
|
+
if (range.from && range.to) {
|
|
6257
|
+
onChange([range.from, range.to]);
|
|
6258
|
+
} else if (range.from) {
|
|
6259
|
+
onChange([range.from, range.from]);
|
|
6542
6260
|
}
|
|
6543
6261
|
}
|
|
6544
6262
|
};
|
|
6545
|
-
const
|
|
6546
|
-
|
|
6547
|
-
|
|
6548
|
-
|
|
6549
|
-
|
|
6550
|
-
|
|
6551
|
-
|
|
6552
|
-
|
|
6553
|
-
|
|
6554
|
-
|
|
6555
|
-
|
|
6263
|
+
const suggestions = React42.useMemo(() => getDefaultSuggestions(), []);
|
|
6264
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: cn("flex flex-col", className), children: /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
|
|
6265
|
+
DatePicker,
|
|
6266
|
+
{
|
|
6267
|
+
mode: isRange ? "range" : "single",
|
|
6268
|
+
value: pickerValue,
|
|
6269
|
+
onValueChange: handleValueChange,
|
|
6270
|
+
children: [
|
|
6271
|
+
isRange && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(DatePickerSelects, {}),
|
|
6272
|
+
isRange ? /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(DatePickerPanel, { children: [
|
|
6273
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(DatePickerCalendar, {}),
|
|
6274
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(DatePickerSuggestions, { suggestions })
|
|
6275
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(DatePickerCalendar, {}),
|
|
6276
|
+
isRange && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(DatePickerFooter, { children: [
|
|
6277
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", {}),
|
|
6278
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("button", { type: "button", onClick: onSubmit, className: applyBtnClasses, children: "Apply" })
|
|
6279
|
+
] })
|
|
6280
|
+
]
|
|
6281
|
+
}
|
|
6282
|
+
) });
|
|
6283
|
+
};
|
|
6284
|
+
DateCalendarValueInput.displayName = "DateCalendarValueInput";
|
|
6285
|
+
var PresetTagsValueInput = ({
|
|
6286
|
+
value,
|
|
6287
|
+
onChange,
|
|
6288
|
+
onSubmit,
|
|
6289
|
+
className
|
|
6290
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: cn("flex flex-col gap-base p-base max-w-[280px]", className), children: RELATIVE_DATE_PRESETS.map((group) => /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex flex-col gap-xs", children: [
|
|
6291
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "text-xs font-semibold leading-xs text-[var(--color-muted-foreground)] uppercase px-xs", children: group.group }),
|
|
6292
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "flex flex-wrap gap-xs", children: group.options.map((preset) => /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
6293
|
+
"button",
|
|
6294
|
+
{
|
|
6295
|
+
type: "button",
|
|
6296
|
+
onClick: () => {
|
|
6297
|
+
onChange(preset);
|
|
6298
|
+
onSubmit?.();
|
|
6299
|
+
},
|
|
6300
|
+
className: cn(
|
|
6301
|
+
"px-base py-2xs rounded-base border cursor-pointer transition-colors text-sm font-regular leading-sm",
|
|
6302
|
+
value === preset ? "border-[var(--color-ring)] bg-[var(--color-primary)] text-[var(--color-primary-foreground)]" : "border-[var(--color-input)] bg-[var(--color-background)] text-[var(--color-foreground)] hover:bg-[var(--color-accent)]"
|
|
6303
|
+
),
|
|
6304
|
+
children: preset
|
|
6305
|
+
},
|
|
6306
|
+
preset
|
|
6307
|
+
)) })
|
|
6308
|
+
] }, group.group)) });
|
|
6309
|
+
PresetTagsValueInput.displayName = "PresetTagsValueInput";
|
|
6310
|
+
|
|
6311
|
+
// src/components/ui/filter/value-inputs/select-value-input.tsx
|
|
6312
|
+
var import_icons28 = require("@l3mpire/icons");
|
|
6313
|
+
var import_jsx_runtime46 = require("react/jsx-runtime");
|
|
6314
|
+
var DynamicOptionRow = ({
|
|
6315
|
+
option,
|
|
6316
|
+
selected,
|
|
6317
|
+
multi,
|
|
6318
|
+
onClick
|
|
6319
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
|
|
6320
|
+
"button",
|
|
6321
|
+
{
|
|
6322
|
+
type: "button",
|
|
6323
|
+
onClick,
|
|
6324
|
+
className: cn(
|
|
6325
|
+
"flex items-start gap-base p-base rounded-base cursor-pointer transition-colors text-left",
|
|
6326
|
+
"hover:bg-[var(--color-dropdown-item-hover)]",
|
|
6327
|
+
selected && "bg-[var(--color-dropdown-item-hover)]"
|
|
6328
|
+
),
|
|
6329
|
+
children: [
|
|
6330
|
+
multi && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
6331
|
+
"span",
|
|
6332
|
+
{
|
|
6333
|
+
className: cn(
|
|
6334
|
+
"mt-[2px] flex items-center justify-center size-4 rounded-xs border transition-colors shrink-0",
|
|
6335
|
+
selected ? "bg-[var(--color-primary)] border-[var(--color-primary)]" : "border-[var(--color-input)] bg-[var(--color-background)]"
|
|
6336
|
+
),
|
|
6337
|
+
children: selected && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("svg", { width: "10", height: "10", viewBox: "0 0 10 10", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
6338
|
+
"path",
|
|
6339
|
+
{
|
|
6340
|
+
d: "M2 5L4 7L8 3",
|
|
6341
|
+
stroke: "white",
|
|
6342
|
+
strokeWidth: "1.5",
|
|
6343
|
+
strokeLinecap: "round",
|
|
6344
|
+
strokeLinejoin: "round"
|
|
6345
|
+
}
|
|
6346
|
+
) })
|
|
6347
|
+
}
|
|
6348
|
+
),
|
|
6349
|
+
option.icon && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
6350
|
+
import_icons28.Icon,
|
|
6351
|
+
{
|
|
6352
|
+
icon: option.icon,
|
|
6353
|
+
size: "sm",
|
|
6354
|
+
className: "shrink-0 mt-[1px] text-[var(--color-interactive-text-primary-dark-default,var(--color-primary))]"
|
|
6355
|
+
}
|
|
6356
|
+
),
|
|
6357
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("span", { className: "flex-1 flex flex-col gap-2xs min-w-0", children: [
|
|
6358
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "text-sm font-regular leading-sm text-[var(--color-foreground)] truncate", children: option.label }),
|
|
6359
|
+
option.description && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "text-xs font-regular leading-xs text-[var(--color-muted-foreground)]", children: option.description })
|
|
6360
|
+
] })
|
|
6361
|
+
]
|
|
6362
|
+
}
|
|
6363
|
+
);
|
|
6364
|
+
var DynamicOptionsDivider = () => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "h-px bg-[var(--color-dropdown-border)] mx-xs my-xs" });
|
|
6365
|
+
var SingleSelectValueInput = ({
|
|
6366
|
+
value,
|
|
6367
|
+
onChange,
|
|
6368
|
+
onSubmit,
|
|
6369
|
+
options,
|
|
6370
|
+
dynamicOptions,
|
|
6371
|
+
className
|
|
6372
|
+
}) => {
|
|
6373
|
+
const pick = (v) => {
|
|
6374
|
+
onChange(v);
|
|
6375
|
+
onSubmit?.();
|
|
6376
|
+
};
|
|
6377
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
|
|
6556
6378
|
"div",
|
|
6557
6379
|
{
|
|
6558
6380
|
className: cn(
|
|
6559
|
-
"
|
|
6560
|
-
"bg-filter-chip-bg border border-filter-chip-border rounded-md shadow-sm",
|
|
6381
|
+
"flex flex-col gap-xs p-base max-h-[280px] overflow-y-auto",
|
|
6561
6382
|
className
|
|
6562
6383
|
),
|
|
6563
6384
|
children: [
|
|
6564
|
-
|
|
6565
|
-
|
|
6566
|
-
{
|
|
6567
|
-
properties,
|
|
6568
|
-
onSelect: (prop) => {
|
|
6569
|
-
onPropertyChange?.(prop);
|
|
6570
|
-
setPropertyOpen(false);
|
|
6571
|
-
},
|
|
6572
|
-
open: propertyOpen,
|
|
6573
|
-
onOpenChange: setPropertyOpen,
|
|
6574
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
6575
|
-
FilterChipSegment,
|
|
6576
|
-
{
|
|
6577
|
-
segmentType: "property",
|
|
6578
|
-
hasBorder: true,
|
|
6579
|
-
icon: propertyDef.icon,
|
|
6580
|
-
label: propertyDef.label,
|
|
6581
|
-
onClick: () => setPropertyOpen(true)
|
|
6582
|
-
}
|
|
6583
|
-
) })
|
|
6584
|
-
}
|
|
6585
|
-
) : /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
6586
|
-
FilterChipSegment,
|
|
6587
|
-
{
|
|
6588
|
-
segmentType: "property",
|
|
6589
|
-
hasBorder: true,
|
|
6590
|
-
icon: propertyDef.icon,
|
|
6591
|
-
label: propertyDef.label
|
|
6592
|
-
}
|
|
6593
|
-
),
|
|
6594
|
-
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
6595
|
-
SegmentPopover,
|
|
6596
|
-
{
|
|
6597
|
-
open: operatorOpen,
|
|
6598
|
-
onOpenChange: setOperatorOpen,
|
|
6599
|
-
minWidth: "180px",
|
|
6600
|
-
trigger: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
6601
|
-
FilterChipSegment,
|
|
6602
|
-
{
|
|
6603
|
-
segmentType: hasOperator ? "operator" : "placeholder",
|
|
6604
|
-
hasBorder: true,
|
|
6605
|
-
label: hasOperator ? condition.operator : "Select condition",
|
|
6606
|
-
onClick: () => setOperatorOpen(true)
|
|
6607
|
-
}
|
|
6608
|
-
) }),
|
|
6609
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "p-xs", children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
6610
|
-
OperatorList,
|
|
6611
|
-
{
|
|
6612
|
-
dataType: propertyDef.type,
|
|
6613
|
-
activeOperator: condition.operator,
|
|
6614
|
-
onSelect: handleOperatorSelect
|
|
6615
|
-
}
|
|
6616
|
-
) })
|
|
6617
|
-
}
|
|
6618
|
-
),
|
|
6619
|
-
hasOperator && condition.operator && !isNoValueOperator(condition.operator) && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
6620
|
-
SegmentPopover,
|
|
6621
|
-
{
|
|
6622
|
-
open: valueOpen,
|
|
6623
|
-
onOpenChange: setValueOpen,
|
|
6624
|
-
minWidth: "240px",
|
|
6625
|
-
trigger: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
6626
|
-
FilterChipSegment,
|
|
6627
|
-
{
|
|
6628
|
-
segmentType: hasValue ? "value" : "placeholder",
|
|
6629
|
-
hasBorder: true,
|
|
6630
|
-
label: hasValue ? displayValue : "Enter value",
|
|
6631
|
-
badgeCount,
|
|
6632
|
-
onClick: () => setValueOpen(true)
|
|
6633
|
-
}
|
|
6634
|
-
) }),
|
|
6635
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
6636
|
-
ValueInput,
|
|
6637
|
-
{
|
|
6638
|
-
dataType: propertyDef.type,
|
|
6639
|
-
operator: condition.operator,
|
|
6640
|
-
value: condition.value,
|
|
6641
|
-
onChange: handleValueChange,
|
|
6642
|
-
onSubmit: handleValueSubmit,
|
|
6643
|
-
options: propertyDef.options
|
|
6644
|
-
}
|
|
6645
|
-
)
|
|
6646
|
-
}
|
|
6647
|
-
),
|
|
6648
|
-
hasOperator && condition.operator && isNoValueOperator(condition.operator) && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
6649
|
-
FilterChipSegment,
|
|
6385
|
+
dynamicOptions?.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
6386
|
+
DynamicOptionRow,
|
|
6650
6387
|
{
|
|
6651
|
-
|
|
6652
|
-
|
|
6653
|
-
|
|
6654
|
-
|
|
6655
|
-
|
|
6656
|
-
|
|
6657
|
-
|
|
6388
|
+
option: opt,
|
|
6389
|
+
selected: value === opt.value,
|
|
6390
|
+
multi: false,
|
|
6391
|
+
onClick: () => pick(opt.value)
|
|
6392
|
+
},
|
|
6393
|
+
opt.value
|
|
6394
|
+
)),
|
|
6395
|
+
dynamicOptions && dynamicOptions.length > 0 && options.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(DynamicOptionsDivider, {}),
|
|
6396
|
+
options.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
6397
|
+
"button",
|
|
6658
6398
|
{
|
|
6659
|
-
|
|
6660
|
-
|
|
6661
|
-
|
|
6662
|
-
|
|
6663
|
-
|
|
6664
|
-
|
|
6665
|
-
|
|
6666
|
-
|
|
6667
|
-
|
|
6668
|
-
|
|
6669
|
-
|
|
6670
|
-
}
|
|
6671
|
-
}
|
|
6672
|
-
) })
|
|
6673
|
-
}
|
|
6674
|
-
)
|
|
6399
|
+
type: "button",
|
|
6400
|
+
onClick: () => pick(opt),
|
|
6401
|
+
className: cn(
|
|
6402
|
+
"flex items-center gap-base p-base rounded-base cursor-pointer transition-colors text-left",
|
|
6403
|
+
"hover:bg-[var(--color-dropdown-item-hover)]",
|
|
6404
|
+
value === opt && "bg-[var(--color-dropdown-item-hover)]"
|
|
6405
|
+
),
|
|
6406
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "text-sm font-regular leading-sm text-[var(--color-foreground)]", children: opt })
|
|
6407
|
+
},
|
|
6408
|
+
opt
|
|
6409
|
+
))
|
|
6675
6410
|
]
|
|
6676
6411
|
}
|
|
6677
6412
|
);
|
|
6678
6413
|
};
|
|
6679
|
-
|
|
6680
|
-
|
|
6681
|
-
|
|
6682
|
-
|
|
6683
|
-
|
|
6414
|
+
SingleSelectValueInput.displayName = "SingleSelectValueInput";
|
|
6415
|
+
var MultiSelectValueInput = ({
|
|
6416
|
+
value,
|
|
6417
|
+
onChange,
|
|
6418
|
+
onSubmit,
|
|
6419
|
+
options,
|
|
6420
|
+
dynamicOptions,
|
|
6421
|
+
className
|
|
6422
|
+
}) => {
|
|
6423
|
+
const selected = Array.isArray(value) ? value : [];
|
|
6424
|
+
const toggle = (v) => {
|
|
6425
|
+
const next = selected.includes(v) ? selected.filter((s) => s !== v) : [...selected, v];
|
|
6426
|
+
onChange(next);
|
|
6427
|
+
};
|
|
6428
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: cn("flex flex-col gap-xs p-base", className), children: [
|
|
6429
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex flex-col max-h-[240px] overflow-y-auto", children: [
|
|
6430
|
+
dynamicOptions?.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
6431
|
+
DynamicOptionRow,
|
|
6432
|
+
{
|
|
6433
|
+
option: opt,
|
|
6434
|
+
selected: selected.includes(opt.value),
|
|
6435
|
+
multi: true,
|
|
6436
|
+
onClick: () => toggle(opt.value)
|
|
6437
|
+
},
|
|
6438
|
+
opt.value
|
|
6439
|
+
)),
|
|
6440
|
+
dynamicOptions && dynamicOptions.length > 0 && options.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(DynamicOptionsDivider, {}),
|
|
6441
|
+
options.map((opt) => {
|
|
6442
|
+
const isSelected = selected.includes(opt);
|
|
6443
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
|
|
6444
|
+
"button",
|
|
6445
|
+
{
|
|
6446
|
+
type: "button",
|
|
6447
|
+
onClick: () => toggle(opt),
|
|
6448
|
+
className: cn(
|
|
6449
|
+
"flex items-center gap-base p-base rounded-base cursor-pointer transition-colors text-left",
|
|
6450
|
+
"hover:bg-[var(--color-dropdown-item-hover)]"
|
|
6451
|
+
),
|
|
6452
|
+
children: [
|
|
6453
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
6454
|
+
"span",
|
|
6455
|
+
{
|
|
6456
|
+
className: cn(
|
|
6457
|
+
"flex items-center justify-center size-4 rounded-xs border transition-colors",
|
|
6458
|
+
isSelected ? "bg-[var(--color-primary)] border-[var(--color-primary)]" : "border-[var(--color-input)] bg-[var(--color-background)]"
|
|
6459
|
+
),
|
|
6460
|
+
children: isSelected && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("svg", { width: "10", height: "10", viewBox: "0 0 10 10", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
6461
|
+
"path",
|
|
6462
|
+
{
|
|
6463
|
+
d: "M2 5L4 7L8 3",
|
|
6464
|
+
stroke: "white",
|
|
6465
|
+
strokeWidth: "1.5",
|
|
6466
|
+
strokeLinecap: "round",
|
|
6467
|
+
strokeLinejoin: "round"
|
|
6468
|
+
}
|
|
6469
|
+
) })
|
|
6470
|
+
}
|
|
6471
|
+
),
|
|
6472
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "text-sm font-regular leading-sm text-[var(--color-foreground)]", children: opt })
|
|
6473
|
+
]
|
|
6474
|
+
},
|
|
6475
|
+
opt
|
|
6476
|
+
);
|
|
6477
|
+
})
|
|
6478
|
+
] }),
|
|
6479
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("button", { type: "button", onClick: onSubmit, className: applyBtnClasses, children: "Apply" })
|
|
6480
|
+
] });
|
|
6481
|
+
};
|
|
6482
|
+
MultiSelectValueInput.displayName = "MultiSelectValueInput";
|
|
6684
6483
|
|
|
6685
|
-
// src/components/ui/filter/
|
|
6686
|
-
var
|
|
6687
|
-
var
|
|
6688
|
-
|
|
6689
|
-
|
|
6690
|
-
|
|
6691
|
-
|
|
6692
|
-
|
|
6693
|
-
|
|
6694
|
-
|
|
6695
|
-
|
|
6696
|
-
|
|
6697
|
-
|
|
6698
|
-
|
|
6699
|
-
/* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(
|
|
6700
|
-
"button",
|
|
6484
|
+
// src/components/ui/filter/value-inputs/relation-value-input.tsx
|
|
6485
|
+
var import_jsx_runtime47 = require("react/jsx-runtime");
|
|
6486
|
+
var RelationValueInput = ({
|
|
6487
|
+
value,
|
|
6488
|
+
onChange,
|
|
6489
|
+
onSubmit,
|
|
6490
|
+
className
|
|
6491
|
+
}) => {
|
|
6492
|
+
const handleKeyDown = (e) => {
|
|
6493
|
+
if (e.key === "Enter") onSubmit?.();
|
|
6494
|
+
};
|
|
6495
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: cn("flex flex-col gap-base p-base", className), children: [
|
|
6496
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
6497
|
+
"input",
|
|
6701
6498
|
{
|
|
6702
|
-
|
|
6703
|
-
|
|
6704
|
-
|
|
6705
|
-
|
|
6706
|
-
|
|
6707
|
-
|
|
6708
|
-
|
|
6709
|
-
),
|
|
6710
|
-
...props,
|
|
6711
|
-
children: [
|
|
6712
|
-
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)("span", { className: "text-sm font-semibold leading-sm whitespace-nowrap text-[var(--color-foreground)]", children: "Advanced filters" }),
|
|
6713
|
-
count > 0 && /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("span", { className: "flex items-center p-2xs rounded-xs bg-filter-chip-badge-bg", children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("span", { className: "text-[10px] font-semibold leading-2xs text-filter-chip-badge-text", children: count }) })
|
|
6714
|
-
]
|
|
6499
|
+
type: "text",
|
|
6500
|
+
value: value ?? "",
|
|
6501
|
+
onChange: (e) => onChange(e.target.value),
|
|
6502
|
+
onKeyDown: handleKeyDown,
|
|
6503
|
+
placeholder: "Search...",
|
|
6504
|
+
autoFocus: true,
|
|
6505
|
+
className: inputClasses
|
|
6715
6506
|
}
|
|
6716
6507
|
),
|
|
6717
|
-
|
|
6718
|
-
|
|
6719
|
-
|
|
6720
|
-
|
|
6721
|
-
onClick: (e) => {
|
|
6722
|
-
e.stopPropagation();
|
|
6723
|
-
onClear();
|
|
6724
|
-
},
|
|
6725
|
-
className: cn(
|
|
6726
|
-
btnBase,
|
|
6727
|
-
"p-sm",
|
|
6728
|
-
"rounded-r-md -ml-px"
|
|
6729
|
-
),
|
|
6730
|
-
"aria-label": "Clear all advanced filters",
|
|
6731
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(import_icons30.Icon, { icon: import_icons30.faXmarkOutline, size: "sm", className: "text-[var(--color-foreground)]" })
|
|
6732
|
-
}
|
|
6733
|
-
)
|
|
6734
|
-
] })
|
|
6735
|
-
);
|
|
6736
|
-
AdvancedChip.displayName = "AdvancedChip";
|
|
6737
|
-
|
|
6738
|
-
// src/components/ui/filter/advanced-popover.tsx
|
|
6739
|
-
var React46 = __toESM(require("react"));
|
|
6740
|
-
var PopoverPrimitive10 = __toESM(require("@radix-ui/react-popover"));
|
|
6741
|
-
var import_icons32 = require("@l3mpire/icons");
|
|
6508
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("button", { type: "button", onClick: onSubmit, className: applyBtnClasses, children: "Apply" })
|
|
6509
|
+
] });
|
|
6510
|
+
};
|
|
6511
|
+
RelationValueInput.displayName = "RelationValueInput";
|
|
6742
6512
|
|
|
6743
|
-
// src/components/ui/filter/
|
|
6744
|
-
var
|
|
6745
|
-
var
|
|
6746
|
-
|
|
6747
|
-
|
|
6748
|
-
|
|
6749
|
-
|
|
6750
|
-
|
|
6751
|
-
|
|
6752
|
-
|
|
6753
|
-
|
|
6754
|
-
"hover:from-[var(--color-btn-outlined-neutral-bg-hover)] hover:to-[var(--color-btn-outlined-neutral-bg-gradient-to-hover)]"
|
|
6755
|
-
];
|
|
6756
|
-
var AdvancedRow = ({
|
|
6757
|
-
connector,
|
|
6758
|
-
onConnectorToggle,
|
|
6759
|
-
propertyDef,
|
|
6760
|
-
condition,
|
|
6761
|
-
properties,
|
|
6762
|
-
onUpdate,
|
|
6763
|
-
onPropertyChange,
|
|
6764
|
-
onDelete
|
|
6513
|
+
// src/components/ui/filter/value-input.tsx
|
|
6514
|
+
var import_jsx_runtime48 = require("react/jsx-runtime");
|
|
6515
|
+
var ValueInput = ({
|
|
6516
|
+
dataType,
|
|
6517
|
+
operator,
|
|
6518
|
+
value,
|
|
6519
|
+
onChange,
|
|
6520
|
+
onSubmit,
|
|
6521
|
+
options = [],
|
|
6522
|
+
dynamicOptions,
|
|
6523
|
+
className
|
|
6765
6524
|
}) => {
|
|
6766
|
-
const
|
|
6767
|
-
|
|
6768
|
-
|
|
6769
|
-
|
|
6770
|
-
|
|
6771
|
-
|
|
6772
|
-
|
|
6773
|
-
|
|
6774
|
-
|
|
6775
|
-
|
|
6776
|
-
|
|
6777
|
-
|
|
6778
|
-
onUpdate({ ...condition, value: val });
|
|
6779
|
-
};
|
|
6780
|
-
const displayValue = condition.value == null ? "" : typeof condition.value === "string" ? condition.value : String(condition.value);
|
|
6781
|
-
return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "flex items-center gap-base w-full min-w-0", children: [
|
|
6782
|
-
connector === "Where" ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "shrink-0 w-[64px] flex items-center justify-end", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "text-xs font-semibold leading-xs text-[var(--color-muted-foreground)]", children: "Where" }) }) : /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
|
|
6783
|
-
"button",
|
|
6784
|
-
{
|
|
6785
|
-
type: "button",
|
|
6786
|
-
onClick: onConnectorToggle,
|
|
6787
|
-
className: cn(
|
|
6788
|
-
"shrink-0 flex items-center justify-center gap-xs",
|
|
6789
|
-
"min-w-[64px] min-h-[24px] max-h-[24px] p-xs",
|
|
6790
|
-
"bg-gradient-to-t from-[var(--color-btn-outlined-neutral-bg-default)] from-[10%] to-[var(--color-btn-outlined-neutral-bg-gradient-to-default)]",
|
|
6791
|
-
"border border-[var(--color-btn-outlined-neutral-border-default)] rounded-base shadow-sm",
|
|
6792
|
-
"cursor-pointer transition-colors text-xs font-semibold leading-xs text-[var(--color-foreground)]",
|
|
6793
|
-
"hover:from-[var(--color-btn-outlined-neutral-bg-hover)] hover:to-[var(--color-btn-outlined-neutral-bg-gradient-to-hover)]"
|
|
6794
|
-
),
|
|
6795
|
-
children: [
|
|
6796
|
-
connector,
|
|
6797
|
-
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_icons31.Icon, { icon: import_icons31.faRefreshOutline, size: "xs", className: "text-[var(--color-foreground)]" })
|
|
6798
|
-
]
|
|
6799
|
-
}
|
|
6800
|
-
),
|
|
6801
|
-
/* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(PopoverPrimitive9.Root, { open: propertyOpen, onOpenChange: setPropertyOpen, children: [
|
|
6802
|
-
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(PopoverPrimitive9.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("button", { type: "button", className: cn(selectBtnStyle, "min-w-0"), children: [
|
|
6803
|
-
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_icons31.Icon, { icon: propertyDef.icon, size: "sm", className: "shrink-0 text-[var(--color-muted-foreground)]" }),
|
|
6804
|
-
/* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("span", { className: "text-sm font-regular leading-sm text-[var(--color-foreground)] whitespace-nowrap truncate", children: [
|
|
6805
|
-
propertyDef.groupLabel,
|
|
6806
|
-
" > ",
|
|
6807
|
-
propertyDef.label
|
|
6808
|
-
] }),
|
|
6809
|
-
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_icons31.Icon, { icon: import_icons31.faChevronDownOutline, size: "xs", className: "shrink-0 text-[var(--color-foreground)]" })
|
|
6810
|
-
] }) }),
|
|
6811
|
-
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(PopoverPrimitive9.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6812
|
-
PopoverPrimitive9.Content,
|
|
6525
|
+
const inputType = getValueInputType(dataType, operator);
|
|
6526
|
+
if (!inputType) return null;
|
|
6527
|
+
switch (inputType) {
|
|
6528
|
+
case "TextInput":
|
|
6529
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(TextValueInput, { value, onChange, onSubmit, className });
|
|
6530
|
+
case "NumberInput":
|
|
6531
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(NumberValueInput, { value, onChange, onSubmit, className });
|
|
6532
|
+
case "NumberRange":
|
|
6533
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(NumberRangeValueInput, { value, onChange, onSubmit, className });
|
|
6534
|
+
case "SingleSelect":
|
|
6535
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
6536
|
+
SingleSelectValueInput,
|
|
6813
6537
|
{
|
|
6814
|
-
|
|
6815
|
-
|
|
6816
|
-
|
|
6817
|
-
|
|
6818
|
-
|
|
6819
|
-
|
|
6820
|
-
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0",
|
|
6821
|
-
"min-w-[200px]"
|
|
6822
|
-
),
|
|
6823
|
-
children: properties.map((p) => /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
|
|
6824
|
-
"button",
|
|
6825
|
-
{
|
|
6826
|
-
type: "button",
|
|
6827
|
-
onClick: () => {
|
|
6828
|
-
onPropertyChange(p);
|
|
6829
|
-
setPropertyOpen(false);
|
|
6830
|
-
},
|
|
6831
|
-
className: cn(
|
|
6832
|
-
"flex items-center gap-base p-base rounded-base cursor-pointer transition-colors text-left",
|
|
6833
|
-
"hover:bg-[var(--color-dropdown-item-hover)]",
|
|
6834
|
-
p.id === condition.propertyId && "bg-[var(--color-dropdown-item-hover)]"
|
|
6835
|
-
),
|
|
6836
|
-
children: [
|
|
6837
|
-
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_icons31.Icon, { icon: p.icon, size: "sm", className: "shrink-0 text-[var(--color-dropdown-item-icon)]" }),
|
|
6838
|
-
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "text-sm font-regular leading-sm text-[var(--color-dropdown-item-text)] truncate", children: p.label })
|
|
6839
|
-
]
|
|
6840
|
-
},
|
|
6841
|
-
p.id
|
|
6842
|
-
))
|
|
6538
|
+
value,
|
|
6539
|
+
onChange,
|
|
6540
|
+
onSubmit,
|
|
6541
|
+
options,
|
|
6542
|
+
dynamicOptions,
|
|
6543
|
+
className
|
|
6843
6544
|
}
|
|
6844
|
-
)
|
|
6845
|
-
|
|
6846
|
-
|
|
6847
|
-
|
|
6848
|
-
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "text-sm font-regular leading-sm text-[var(--color-foreground)] whitespace-nowrap truncate text-left", children: condition.operator ?? "Select" }),
|
|
6849
|
-
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_icons31.Icon, { icon: import_icons31.faChevronDownOutline, size: "xs", className: "shrink-0 text-[var(--color-foreground)]" })
|
|
6850
|
-
] }) }),
|
|
6851
|
-
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(PopoverPrimitive9.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6852
|
-
PopoverPrimitive9.Content,
|
|
6545
|
+
);
|
|
6546
|
+
case "MultiSelect":
|
|
6547
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
6548
|
+
MultiSelectValueInput,
|
|
6853
6549
|
{
|
|
6854
|
-
|
|
6855
|
-
|
|
6856
|
-
|
|
6857
|
-
|
|
6858
|
-
|
|
6859
|
-
|
|
6860
|
-
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0",
|
|
6861
|
-
"min-w-[160px]"
|
|
6862
|
-
),
|
|
6863
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6864
|
-
OperatorList,
|
|
6865
|
-
{
|
|
6866
|
-
dataType: propertyDef.type,
|
|
6867
|
-
activeOperator: condition.operator,
|
|
6868
|
-
onSelect: handleOperatorSelect
|
|
6869
|
-
}
|
|
6870
|
-
)
|
|
6550
|
+
value,
|
|
6551
|
+
onChange,
|
|
6552
|
+
onSubmit,
|
|
6553
|
+
options,
|
|
6554
|
+
dynamicOptions,
|
|
6555
|
+
className
|
|
6871
6556
|
}
|
|
6872
|
-
)
|
|
6873
|
-
|
|
6874
|
-
|
|
6875
|
-
|
|
6876
|
-
|
|
6877
|
-
|
|
6878
|
-
|
|
6879
|
-
|
|
6880
|
-
|
|
6881
|
-
|
|
6882
|
-
|
|
6883
|
-
|
|
6884
|
-
|
|
6885
|
-
|
|
6886
|
-
|
|
6887
|
-
|
|
6888
|
-
|
|
6889
|
-
|
|
6890
|
-
|
|
6891
|
-
"button",
|
|
6892
|
-
{
|
|
6893
|
-
type: "button",
|
|
6894
|
-
onClick: onDelete,
|
|
6895
|
-
className: "ml-auto shrink-0 flex items-center justify-center p-sm rounded-md cursor-pointer transition-colors hover:bg-[var(--color-accent)]",
|
|
6896
|
-
"aria-label": "Remove filter",
|
|
6897
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_icons31.Icon, { icon: import_icons31.faXmarkOutline, size: "sm", className: "text-[var(--color-foreground)]" })
|
|
6898
|
-
}
|
|
6899
|
-
)
|
|
6900
|
-
] });
|
|
6557
|
+
);
|
|
6558
|
+
case "DatePicker":
|
|
6559
|
+
case "DateRange":
|
|
6560
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
6561
|
+
DateCalendarValueInput,
|
|
6562
|
+
{
|
|
6563
|
+
operator,
|
|
6564
|
+
value,
|
|
6565
|
+
onChange,
|
|
6566
|
+
onSubmit,
|
|
6567
|
+
className
|
|
6568
|
+
}
|
|
6569
|
+
);
|
|
6570
|
+
case "RelationPicker":
|
|
6571
|
+
case "MultiRelationPicker":
|
|
6572
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(RelationValueInput, { value, onChange, onSubmit, className });
|
|
6573
|
+
default:
|
|
6574
|
+
return null;
|
|
6575
|
+
}
|
|
6901
6576
|
};
|
|
6902
|
-
|
|
6577
|
+
ValueInput.displayName = "ValueInput";
|
|
6903
6578
|
|
|
6904
|
-
// src/components/ui/filter/
|
|
6905
|
-
var
|
|
6906
|
-
var
|
|
6907
|
-
|
|
6908
|
-
|
|
6909
|
-
|
|
6910
|
-
"
|
|
6911
|
-
|
|
6912
|
-
|
|
6913
|
-
|
|
6914
|
-
|
|
6915
|
-
|
|
6579
|
+
// src/components/ui/filter/property-selector.tsx
|
|
6580
|
+
var React43 = __toESM(require("react"));
|
|
6581
|
+
var PopoverPrimitive6 = __toESM(require("@radix-ui/react-popover"));
|
|
6582
|
+
var import_icons29 = require("@l3mpire/icons");
|
|
6583
|
+
var import_jsx_runtime49 = require("react/jsx-runtime");
|
|
6584
|
+
var AdvancedFilterFooter = ({ onClick, count }) => /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_jsx_runtime49.Fragment, { children: [
|
|
6585
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "h-px bg-[var(--color-dropdown-border)] mx-xs" }),
|
|
6586
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
|
|
6587
|
+
"button",
|
|
6588
|
+
{
|
|
6589
|
+
type: "button",
|
|
6590
|
+
onPointerDown: (e) => e.preventDefault(),
|
|
6591
|
+
onClick,
|
|
6592
|
+
className: "flex items-center gap-base p-base rounded-base cursor-pointer transition-colors hover:bg-[var(--color-dropdown-item-hover)]",
|
|
6593
|
+
children: [
|
|
6594
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
6595
|
+
import_icons29.Icon,
|
|
6596
|
+
{
|
|
6597
|
+
icon: import_icons29.faFilterOutline,
|
|
6598
|
+
size: "sm",
|
|
6599
|
+
className: "shrink-0 text-[var(--color-dropdown-item-icon)]"
|
|
6600
|
+
}
|
|
6601
|
+
),
|
|
6602
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "flex-1 text-sm font-regular leading-sm text-[var(--color-dropdown-item-text)] text-left truncate", children: "Advanced filter" }),
|
|
6603
|
+
count > 0 && /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("span", { className: "text-xs font-regular leading-xs text-[var(--color-muted-foreground)]", children: [
|
|
6604
|
+
count,
|
|
6605
|
+
" ",
|
|
6606
|
+
count === 1 ? "rule" : "rules"
|
|
6607
|
+
] })
|
|
6608
|
+
]
|
|
6609
|
+
}
|
|
6610
|
+
)
|
|
6611
|
+
] });
|
|
6612
|
+
var PropertySelector = ({
|
|
6916
6613
|
properties,
|
|
6917
|
-
|
|
6614
|
+
onSelect,
|
|
6918
6615
|
open,
|
|
6919
6616
|
onOpenChange,
|
|
6920
|
-
children
|
|
6617
|
+
children,
|
|
6618
|
+
onAdvancedFilter,
|
|
6619
|
+
advancedFilterCount = 0
|
|
6921
6620
|
}) => {
|
|
6922
|
-
const
|
|
6923
|
-
|
|
6924
|
-
|
|
6925
|
-
|
|
6926
|
-
onFiltersChange(filters.map((f) => f.id === updated.id ? updated : f));
|
|
6927
|
-
};
|
|
6928
|
-
const handleDeleteFilter = (id) => {
|
|
6929
|
-
onFiltersChange(filters.filter((f) => f.id !== id));
|
|
6930
|
-
};
|
|
6931
|
-
const handlePropertyChange = (filterId, newProp) => {
|
|
6932
|
-
const newCondition = createFilterWithDefaults(newProp.id, newProp.type);
|
|
6933
|
-
onFiltersChange(
|
|
6934
|
-
filters.map((f) => f.id === filterId ? { ...newCondition, id: filterId } : f)
|
|
6935
|
-
);
|
|
6936
|
-
};
|
|
6937
|
-
const handleAddFilter = (property) => {
|
|
6938
|
-
const newFilter = createFilterWithDefaults(property.id, property.type);
|
|
6939
|
-
onFiltersChange([...filters, newFilter]);
|
|
6940
|
-
setAddSelectorOpen(false);
|
|
6941
|
-
};
|
|
6942
|
-
const handleClearAll = () => {
|
|
6943
|
-
onFiltersChange([]);
|
|
6944
|
-
onOpenChange?.(false);
|
|
6621
|
+
const handleAdvancedClick = (e) => {
|
|
6622
|
+
e.stopPropagation();
|
|
6623
|
+
e.preventDefault();
|
|
6624
|
+
onAdvancedFilter?.();
|
|
6945
6625
|
};
|
|
6946
|
-
const
|
|
6947
|
-
|
|
6948
|
-
|
|
6949
|
-
|
|
6950
|
-
|
|
6951
|
-
|
|
6952
|
-
|
|
6953
|
-
|
|
6954
|
-
|
|
6955
|
-
|
|
6956
|
-
|
|
6626
|
+
const showAdvancedFooter = !!onAdvancedFilter;
|
|
6627
|
+
const [activeGroup, setActiveGroup] = React43.useState(null);
|
|
6628
|
+
const [search, setSearch] = React43.useState("");
|
|
6629
|
+
React43.useEffect(() => {
|
|
6630
|
+
if (!open) {
|
|
6631
|
+
setActiveGroup(null);
|
|
6632
|
+
setSearch("");
|
|
6633
|
+
}
|
|
6634
|
+
}, [open]);
|
|
6635
|
+
const groups = React43.useMemo(() => {
|
|
6636
|
+
const map = /* @__PURE__ */ new Map();
|
|
6637
|
+
for (const prop of properties) {
|
|
6638
|
+
const existing = map.get(prop.group);
|
|
6639
|
+
if (existing) {
|
|
6640
|
+
existing.count++;
|
|
6641
|
+
} else {
|
|
6642
|
+
map.set(prop.group, {
|
|
6643
|
+
group: prop.group,
|
|
6644
|
+
groupLabel: prop.groupLabel,
|
|
6645
|
+
groupIcon: prop.icon,
|
|
6646
|
+
count: 1
|
|
6647
|
+
});
|
|
6648
|
+
}
|
|
6649
|
+
}
|
|
6650
|
+
return Array.from(map.values());
|
|
6651
|
+
}, [properties]);
|
|
6652
|
+
const globalSearchResults = React43.useMemo(() => {
|
|
6653
|
+
if (!search || activeGroup) return [];
|
|
6654
|
+
const lower = search.toLowerCase();
|
|
6655
|
+
return properties.filter((p) => p.label.toLowerCase().includes(lower));
|
|
6656
|
+
}, [properties, search, activeGroup]);
|
|
6657
|
+
const filteredGroups = React43.useMemo(() => {
|
|
6658
|
+
if (!search || activeGroup) return groups;
|
|
6659
|
+
const lower = search.toLowerCase();
|
|
6660
|
+
return groups.filter(
|
|
6661
|
+
(g) => g.groupLabel.toLowerCase().includes(lower) || properties.some(
|
|
6662
|
+
(p) => p.group === g.group && p.label.toLowerCase().includes(lower)
|
|
6663
|
+
)
|
|
6664
|
+
);
|
|
6665
|
+
}, [groups, properties, search, activeGroup]);
|
|
6666
|
+
const filteredProperties = React43.useMemo(() => {
|
|
6667
|
+
if (!activeGroup) return [];
|
|
6668
|
+
const groupProps = properties.filter((p) => p.group === activeGroup);
|
|
6669
|
+
if (!search) return groupProps;
|
|
6670
|
+
const lower = search.toLowerCase();
|
|
6671
|
+
return groupProps.filter((p) => p.label.toLowerCase().includes(lower));
|
|
6672
|
+
}, [properties, activeGroup, search]);
|
|
6673
|
+
const activeGroupInfo = groups.find((g) => g.group === activeGroup);
|
|
6674
|
+
const showGlobalResults = search.length > 0 && !activeGroup && globalSearchResults.length > 0;
|
|
6675
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(PopoverPrimitive6.Root, { open, onOpenChange, children: [
|
|
6676
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(PopoverPrimitive6.Trigger, { asChild: true, children }),
|
|
6677
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(PopoverPrimitive6.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
|
|
6678
|
+
PopoverPrimitive6.Content,
|
|
6957
6679
|
{
|
|
6958
6680
|
sideOffset: 4,
|
|
6959
6681
|
align: "start",
|
|
6960
|
-
|
|
6961
|
-
onOpenAutoFocus: (e) => e.preventDefault(),
|
|
6682
|
+
onCloseAutoFocus: (e) => e.preventDefault(),
|
|
6962
6683
|
className: cn(
|
|
6963
|
-
"z-50 flex flex-col",
|
|
6964
|
-
"bg-[var(--color-
|
|
6684
|
+
"z-50 flex flex-col gap-xs overflow-clip p-xs",
|
|
6685
|
+
"bg-[var(--color-dropdown-bg)] border border-[var(--color-dropdown-border)] rounded-md shadow-lg",
|
|
6965
6686
|
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
6966
6687
|
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
|
6967
6688
|
"data-[side=bottom]:slide-in-from-top-2",
|
|
6968
|
-
"w-[
|
|
6689
|
+
"min-w-[230px]"
|
|
6969
6690
|
),
|
|
6970
6691
|
children: [
|
|
6971
|
-
|
|
6972
|
-
|
|
6973
|
-
|
|
6974
|
-
|
|
6975
|
-
|
|
6976
|
-
|
|
6977
|
-
|
|
6978
|
-
|
|
6979
|
-
|
|
6980
|
-
|
|
6981
|
-
|
|
6982
|
-
|
|
6983
|
-
|
|
6984
|
-
|
|
6985
|
-
|
|
6986
|
-
|
|
6987
|
-
|
|
6988
|
-
|
|
6989
|
-
|
|
6990
|
-
|
|
6991
|
-
|
|
6992
|
-
|
|
6993
|
-
|
|
6994
|
-
|
|
6995
|
-
|
|
6996
|
-
|
|
6997
|
-
|
|
6998
|
-
|
|
6999
|
-
|
|
7000
|
-
|
|
6692
|
+
activeGroup === null ? (
|
|
6693
|
+
/* ── Level 1: Search + Categories ───────────────────────── */
|
|
6694
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex flex-col gap-xs", children: [
|
|
6695
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex items-center gap-base px-md py-base border border-[var(--color-input)] rounded-md", children: [
|
|
6696
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
6697
|
+
import_icons29.Icon,
|
|
6698
|
+
{
|
|
6699
|
+
icon: import_icons29.faMagnifyingGlassOutline,
|
|
6700
|
+
size: "sm",
|
|
6701
|
+
className: "shrink-0 text-[var(--color-muted-foreground)]"
|
|
6702
|
+
}
|
|
6703
|
+
),
|
|
6704
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
6705
|
+
"input",
|
|
6706
|
+
{
|
|
6707
|
+
type: "text",
|
|
6708
|
+
value: search,
|
|
6709
|
+
onChange: (e) => setSearch(e.target.value),
|
|
6710
|
+
placeholder: "Search...",
|
|
6711
|
+
autoFocus: true,
|
|
6712
|
+
className: "flex-1 text-sm font-regular leading-sm text-[var(--color-foreground)] bg-transparent outline-none placeholder:text-[var(--color-muted-foreground)]"
|
|
6713
|
+
}
|
|
6714
|
+
)
|
|
6715
|
+
] }),
|
|
6716
|
+
showGlobalResults ? (
|
|
6717
|
+
/* ── Global search results (flat property list) ─────── */
|
|
6718
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "flex flex-col max-h-[300px] overflow-y-auto", children: globalSearchResults.map((prop) => /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
|
|
6719
|
+
"button",
|
|
6720
|
+
{
|
|
6721
|
+
type: "button",
|
|
6722
|
+
onClick: () => {
|
|
6723
|
+
onSelect(prop);
|
|
6724
|
+
onOpenChange?.(false);
|
|
6725
|
+
},
|
|
6726
|
+
className: "flex items-center gap-base p-base rounded-base cursor-pointer transition-colors hover:bg-[var(--color-dropdown-item-hover)]",
|
|
6727
|
+
children: [
|
|
6728
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
6729
|
+
import_icons29.Icon,
|
|
6730
|
+
{
|
|
6731
|
+
icon: prop.icon,
|
|
6732
|
+
size: "sm",
|
|
6733
|
+
className: "shrink-0 text-[var(--color-dropdown-item-icon)]"
|
|
6734
|
+
}
|
|
6735
|
+
),
|
|
6736
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "flex-1 text-sm font-regular leading-sm text-[var(--color-dropdown-item-text)] text-left truncate", children: prop.label }),
|
|
6737
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "text-xs font-regular leading-xs text-[var(--color-muted-foreground)]", children: prop.groupLabel })
|
|
6738
|
+
]
|
|
6739
|
+
},
|
|
6740
|
+
prop.id
|
|
6741
|
+
)) })
|
|
6742
|
+
) : (
|
|
6743
|
+
/* ── Group list ─────────────────────────────────────── */
|
|
6744
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex flex-col", children: [
|
|
6745
|
+
filteredGroups.map((g) => /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
|
|
7001
6746
|
"button",
|
|
7002
6747
|
{
|
|
7003
6748
|
type: "button",
|
|
7004
|
-
|
|
7005
|
-
|
|
7006
|
-
"
|
|
7007
|
-
|
|
7008
|
-
|
|
7009
|
-
"hover:from-[var(--color-btn-outlined-neutral-bg-hover)] hover:to-[var(--color-btn-outlined-neutral-bg-gradient-to-hover)]"
|
|
7010
|
-
),
|
|
6749
|
+
onClick: () => {
|
|
6750
|
+
setActiveGroup(g.group);
|
|
6751
|
+
setSearch("");
|
|
6752
|
+
},
|
|
6753
|
+
className: "flex items-center gap-base p-base rounded-base cursor-pointer transition-colors hover:bg-[var(--color-dropdown-item-hover)]",
|
|
7011
6754
|
children: [
|
|
7012
|
-
/* @__PURE__ */ (0,
|
|
7013
|
-
|
|
7014
|
-
|
|
6755
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
6756
|
+
import_icons29.Icon,
|
|
6757
|
+
{
|
|
6758
|
+
icon: g.groupIcon,
|
|
6759
|
+
size: "sm",
|
|
6760
|
+
className: "shrink-0 text-[var(--color-dropdown-item-icon)]"
|
|
6761
|
+
}
|
|
6762
|
+
),
|
|
6763
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "flex-1 text-sm font-regular leading-sm text-[var(--color-dropdown-item-text)] text-left truncate", children: g.groupLabel }),
|
|
6764
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "text-xs font-semibold leading-xs text-[var(--color-muted-foreground)]", children: g.count }),
|
|
6765
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
6766
|
+
import_icons29.Icon,
|
|
7015
6767
|
{
|
|
7016
|
-
icon:
|
|
6768
|
+
icon: import_icons29.faChevronRightOutline,
|
|
7017
6769
|
size: "xs",
|
|
7018
|
-
className: "shrink-0 text-[var(--color-
|
|
6770
|
+
className: "shrink-0 text-[var(--color-dropdown-item-icon)]"
|
|
7019
6771
|
}
|
|
7020
6772
|
)
|
|
7021
6773
|
]
|
|
7022
|
-
}
|
|
7023
|
-
|
|
7024
|
-
|
|
6774
|
+
},
|
|
6775
|
+
g.group
|
|
6776
|
+
)),
|
|
6777
|
+
filteredGroups.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "p-base text-sm text-[var(--color-muted-foreground)]", children: "No results" })
|
|
6778
|
+
] })
|
|
7025
6779
|
)
|
|
7026
6780
|
] })
|
|
7027
|
-
|
|
7028
|
-
|
|
7029
|
-
/* @__PURE__ */ (0,
|
|
7030
|
-
|
|
7031
|
-
|
|
7032
|
-
|
|
7033
|
-
|
|
7034
|
-
|
|
7035
|
-
|
|
7036
|
-
|
|
7037
|
-
|
|
7038
|
-
"
|
|
7039
|
-
|
|
7040
|
-
|
|
7041
|
-
|
|
7042
|
-
|
|
7043
|
-
|
|
7044
|
-
|
|
7045
|
-
|
|
7046
|
-
|
|
7047
|
-
|
|
7048
|
-
|
|
7049
|
-
|
|
7050
|
-
|
|
7051
|
-
|
|
6781
|
+
) : (
|
|
6782
|
+
/* ── Level 2: Properties ─────────────────────────────────── */
|
|
6783
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex flex-col gap-xs", children: [
|
|
6784
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
|
|
6785
|
+
"button",
|
|
6786
|
+
{
|
|
6787
|
+
type: "button",
|
|
6788
|
+
onClick: () => {
|
|
6789
|
+
setActiveGroup(null);
|
|
6790
|
+
setSearch("");
|
|
6791
|
+
},
|
|
6792
|
+
className: "flex items-center gap-base p-base rounded-base cursor-pointer transition-colors hover:bg-[var(--color-dropdown-item-hover)]",
|
|
6793
|
+
children: [
|
|
6794
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
6795
|
+
import_icons29.Icon,
|
|
6796
|
+
{
|
|
6797
|
+
icon: import_icons29.faChevronLeftOutline,
|
|
6798
|
+
size: "sm",
|
|
6799
|
+
className: "shrink-0 text-[var(--color-dropdown-item-icon)]"
|
|
6800
|
+
}
|
|
6801
|
+
),
|
|
6802
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "flex-1 text-xs font-semibold leading-xs text-[var(--color-muted-foreground)] text-left truncate", children: activeGroupInfo?.groupLabel })
|
|
6803
|
+
]
|
|
6804
|
+
}
|
|
6805
|
+
),
|
|
6806
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex items-center gap-base px-md py-base border border-[var(--color-input)] rounded-md", children: [
|
|
6807
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
6808
|
+
import_icons29.Icon,
|
|
6809
|
+
{
|
|
6810
|
+
icon: import_icons29.faMagnifyingGlassOutline,
|
|
6811
|
+
size: "sm",
|
|
6812
|
+
className: "shrink-0 text-[var(--color-muted-foreground)]"
|
|
6813
|
+
}
|
|
6814
|
+
),
|
|
6815
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
6816
|
+
"input",
|
|
6817
|
+
{
|
|
6818
|
+
type: "text",
|
|
6819
|
+
value: search,
|
|
6820
|
+
onChange: (e) => setSearch(e.target.value),
|
|
6821
|
+
placeholder: "Search...",
|
|
6822
|
+
autoFocus: true,
|
|
6823
|
+
className: "flex-1 text-sm font-regular leading-sm text-[var(--color-foreground)] bg-transparent outline-none placeholder:text-[var(--color-muted-foreground)]"
|
|
6824
|
+
}
|
|
6825
|
+
)
|
|
6826
|
+
] }),
|
|
6827
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex flex-col max-h-[300px] overflow-y-auto", children: [
|
|
6828
|
+
filteredProperties.map((prop) => /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
|
|
6829
|
+
"button",
|
|
6830
|
+
{
|
|
6831
|
+
type: "button",
|
|
6832
|
+
onClick: () => {
|
|
6833
|
+
onSelect(prop);
|
|
6834
|
+
onOpenChange?.(false);
|
|
6835
|
+
},
|
|
6836
|
+
className: "flex items-center gap-base p-base rounded-base cursor-pointer transition-colors hover:bg-[var(--color-dropdown-item-hover)]",
|
|
6837
|
+
children: [
|
|
6838
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
6839
|
+
import_icons29.Icon,
|
|
6840
|
+
{
|
|
6841
|
+
icon: prop.icon,
|
|
6842
|
+
size: "sm",
|
|
6843
|
+
className: "shrink-0 text-[var(--color-dropdown-item-icon)]"
|
|
6844
|
+
}
|
|
6845
|
+
),
|
|
6846
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "flex-1 text-sm font-regular leading-sm text-[var(--color-dropdown-item-text)] text-left truncate", children: prop.label })
|
|
6847
|
+
]
|
|
6848
|
+
},
|
|
6849
|
+
prop.id
|
|
6850
|
+
)),
|
|
6851
|
+
filteredProperties.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "p-base text-sm text-[var(--color-muted-foreground)]", children: "No results" })
|
|
6852
|
+
] })
|
|
6853
|
+
] })
|
|
6854
|
+
),
|
|
6855
|
+
showAdvancedFooter && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
6856
|
+
AdvancedFilterFooter,
|
|
6857
|
+
{
|
|
6858
|
+
onClick: handleAdvancedClick,
|
|
6859
|
+
count: advancedFilterCount
|
|
6860
|
+
}
|
|
6861
|
+
)
|
|
7052
6862
|
]
|
|
7053
6863
|
}
|
|
7054
6864
|
) })
|
|
7055
6865
|
] });
|
|
7056
6866
|
};
|
|
7057
|
-
|
|
6867
|
+
PropertySelector.displayName = "PropertySelector";
|
|
7058
6868
|
|
|
7059
|
-
// src/components/ui/filter/
|
|
7060
|
-
var
|
|
7061
|
-
var
|
|
7062
|
-
var
|
|
7063
|
-
var
|
|
7064
|
-
|
|
7065
|
-
|
|
7066
|
-
|
|
7067
|
-
|
|
7068
|
-
|
|
7069
|
-
|
|
7070
|
-
children,
|
|
7071
|
-
|
|
7072
|
-
|
|
7073
|
-
|
|
7074
|
-
|
|
7075
|
-
|
|
7076
|
-
|
|
7077
|
-
|
|
7078
|
-
|
|
7079
|
-
|
|
7080
|
-
|
|
7081
|
-
|
|
7082
|
-
|
|
7083
|
-
|
|
7084
|
-
|
|
7085
|
-
|
|
7086
|
-
|
|
7087
|
-
|
|
7088
|
-
|
|
7089
|
-
|
|
7090
|
-
|
|
7091
|
-
|
|
7092
|
-
|
|
7093
|
-
|
|
7094
|
-
|
|
7095
|
-
|
|
7096
|
-
|
|
7097
|
-
|
|
7098
|
-
|
|
7099
|
-
|
|
7100
|
-
|
|
7101
|
-
|
|
7102
|
-
|
|
7103
|
-
|
|
7104
|
-
|
|
7105
|
-
|
|
7106
|
-
filters.map(
|
|
7107
|
-
(f) => f.id === filterId ? { ...f, logicOperator: (f.logicOperator ?? "and") === "and" ? "or" : "and" } : f
|
|
7108
|
-
)
|
|
7109
|
-
);
|
|
7110
|
-
};
|
|
7111
|
-
return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(PopoverPrimitive11.Root, { open, onOpenChange: setOpen, children: [
|
|
7112
|
-
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(PopoverPrimitive11.Trigger, { asChild: true, children: children ?? /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
|
|
7113
|
-
"button",
|
|
7114
|
-
{
|
|
7115
|
-
type: "button",
|
|
7116
|
-
className: cn(
|
|
7117
|
-
"inline-flex items-center gap-sm px-base py-sm",
|
|
7118
|
-
"min-h-[32px] max-h-[32px]",
|
|
7119
|
-
"bg-gradient-to-t from-[var(--color-btn-outlined-neutral-bg-default)] from-[10%] to-[var(--color-btn-outlined-neutral-bg-gradient-to-default)]",
|
|
7120
|
-
"border border-[var(--color-btn-outlined-neutral-border-default)] rounded-md shadow-sm",
|
|
7121
|
-
"cursor-pointer transition-colors",
|
|
7122
|
-
"hover:from-[var(--color-btn-outlined-neutral-bg-hover)] hover:to-[var(--color-btn-outlined-neutral-bg-gradient-to-hover)]",
|
|
7123
|
-
className
|
|
6869
|
+
// src/components/ui/filter/kebab-menu.tsx
|
|
6870
|
+
var PopoverPrimitive7 = __toESM(require("@radix-ui/react-popover"));
|
|
6871
|
+
var import_icons30 = require("@l3mpire/icons");
|
|
6872
|
+
var import_jsx_runtime50 = require("react/jsx-runtime");
|
|
6873
|
+
var KebabMenu = ({
|
|
6874
|
+
onConvertToAdvanced,
|
|
6875
|
+
onDelete,
|
|
6876
|
+
open,
|
|
6877
|
+
onOpenChange,
|
|
6878
|
+
children
|
|
6879
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(PopoverPrimitive7.Root, { open, onOpenChange, children: [
|
|
6880
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(PopoverPrimitive7.Trigger, { asChild: true, children }),
|
|
6881
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(PopoverPrimitive7.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
|
|
6882
|
+
PopoverPrimitive7.Content,
|
|
6883
|
+
{
|
|
6884
|
+
sideOffset: 4,
|
|
6885
|
+
align: "end",
|
|
6886
|
+
className: cn(
|
|
6887
|
+
"z-50 flex flex-col p-xs overflow-clip",
|
|
6888
|
+
"bg-[var(--color-dropdown-bg)] border border-[var(--color-dropdown-border)] rounded-md shadow-lg",
|
|
6889
|
+
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
6890
|
+
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
|
6891
|
+
"data-[side=bottom]:slide-in-from-top-2",
|
|
6892
|
+
"min-w-[210px]"
|
|
6893
|
+
),
|
|
6894
|
+
children: [
|
|
6895
|
+
onConvertToAdvanced && /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
|
|
6896
|
+
"button",
|
|
6897
|
+
{
|
|
6898
|
+
type: "button",
|
|
6899
|
+
onClick: () => {
|
|
6900
|
+
onConvertToAdvanced();
|
|
6901
|
+
onOpenChange?.(false);
|
|
6902
|
+
},
|
|
6903
|
+
className: "flex items-center gap-base p-base rounded-base cursor-pointer transition-colors hover:bg-[var(--color-dropdown-item-hover)]",
|
|
6904
|
+
children: [
|
|
6905
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
6906
|
+
import_icons30.Icon,
|
|
6907
|
+
{
|
|
6908
|
+
icon: import_icons30.faArrowRightOutline,
|
|
6909
|
+
size: "sm",
|
|
6910
|
+
className: "shrink-0 text-[var(--color-dropdown-item-icon)]"
|
|
6911
|
+
}
|
|
6912
|
+
),
|
|
6913
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "text-sm font-regular leading-sm text-[var(--color-dropdown-item-text)]", children: "Convert to advanced" })
|
|
6914
|
+
]
|
|
6915
|
+
}
|
|
7124
6916
|
),
|
|
7125
|
-
|
|
7126
|
-
|
|
7127
|
-
|
|
7128
|
-
|
|
7129
|
-
|
|
7130
|
-
|
|
7131
|
-
|
|
7132
|
-
|
|
7133
|
-
|
|
7134
|
-
|
|
7135
|
-
|
|
7136
|
-
|
|
6917
|
+
onConvertToAdvanced && onDelete && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "h-px mx-base my-xs bg-[var(--color-border)]" }),
|
|
6918
|
+
onDelete && /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
|
|
6919
|
+
"button",
|
|
6920
|
+
{
|
|
6921
|
+
type: "button",
|
|
6922
|
+
onClick: () => {
|
|
6923
|
+
onDelete();
|
|
6924
|
+
onOpenChange?.(false);
|
|
6925
|
+
},
|
|
6926
|
+
className: "flex items-center gap-base p-base rounded-base cursor-pointer transition-colors hover:bg-[var(--color-dropdown-item-hover)]",
|
|
6927
|
+
children: [
|
|
6928
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
6929
|
+
import_icons30.Icon,
|
|
6930
|
+
{
|
|
6931
|
+
icon: import_icons30.faTrashOutline,
|
|
6932
|
+
size: "sm",
|
|
6933
|
+
className: "shrink-0 text-[var(--color-destructive)]"
|
|
6934
|
+
}
|
|
6935
|
+
),
|
|
6936
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "text-sm font-regular leading-sm text-[var(--color-destructive)]", children: "Delete filter" })
|
|
6937
|
+
]
|
|
6938
|
+
}
|
|
6939
|
+
)
|
|
6940
|
+
]
|
|
6941
|
+
}
|
|
6942
|
+
) })
|
|
6943
|
+
] });
|
|
6944
|
+
KebabMenu.displayName = "KebabMenu";
|
|
6945
|
+
|
|
6946
|
+
// src/components/ui/filter/filter-editor.tsx
|
|
6947
|
+
var React44 = __toESM(require("react"));
|
|
6948
|
+
var PopoverPrimitive8 = __toESM(require("@radix-ui/react-popover"));
|
|
6949
|
+
var import_icons31 = require("@l3mpire/icons");
|
|
6950
|
+
var import_jsx_runtime51 = require("react/jsx-runtime");
|
|
6951
|
+
var FilterEditor = ({
|
|
6952
|
+
propertyDef,
|
|
6953
|
+
condition,
|
|
6954
|
+
mode,
|
|
6955
|
+
onUpdate,
|
|
6956
|
+
onClose,
|
|
6957
|
+
open,
|
|
6958
|
+
onOpenChange,
|
|
6959
|
+
children
|
|
6960
|
+
}) => {
|
|
6961
|
+
const [view, setView] = React44.useState(
|
|
6962
|
+
mode === "add" ? "value" : "operator"
|
|
6963
|
+
);
|
|
6964
|
+
const [localOperator, setLocalOperator] = React44.useState(
|
|
6965
|
+
condition.operator
|
|
6966
|
+
);
|
|
6967
|
+
const [localValue, setLocalValue] = React44.useState(
|
|
6968
|
+
condition.value
|
|
6969
|
+
);
|
|
6970
|
+
React44.useEffect(() => {
|
|
6971
|
+
if (open) {
|
|
6972
|
+
setView(mode === "add" ? "value" : "operator");
|
|
6973
|
+
setLocalOperator(condition.operator);
|
|
6974
|
+
setLocalValue(condition.value);
|
|
6975
|
+
}
|
|
6976
|
+
}, [open, mode, condition.operator, condition.value]);
|
|
6977
|
+
const handleOperatorSelect = (op) => {
|
|
6978
|
+
setLocalOperator(op);
|
|
6979
|
+
if (isNoValueOperator(op)) {
|
|
6980
|
+
onUpdate({ ...condition, operator: op, value: null });
|
|
6981
|
+
onOpenChange?.(false);
|
|
6982
|
+
onClose();
|
|
6983
|
+
} else {
|
|
6984
|
+
if (op !== localOperator) {
|
|
6985
|
+
setLocalValue(null);
|
|
7137
6986
|
}
|
|
7138
|
-
|
|
7139
|
-
|
|
7140
|
-
|
|
6987
|
+
setView("value");
|
|
6988
|
+
}
|
|
6989
|
+
};
|
|
6990
|
+
const handleSubmit = () => {
|
|
6991
|
+
onUpdate({ ...condition, operator: localOperator, value: localValue });
|
|
6992
|
+
onOpenChange?.(false);
|
|
6993
|
+
onClose();
|
|
6994
|
+
};
|
|
6995
|
+
return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(PopoverPrimitive8.Root, { open, onOpenChange, children: [
|
|
6996
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(PopoverPrimitive8.Trigger, { asChild: true, children }),
|
|
6997
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(PopoverPrimitive8.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
|
|
6998
|
+
PopoverPrimitive8.Content,
|
|
7141
6999
|
{
|
|
7142
7000
|
sideOffset: 4,
|
|
7143
7001
|
align: "start",
|
|
7144
|
-
collisionPadding: 16,
|
|
7145
|
-
onOpenAutoFocus: (e) => e.preventDefault(),
|
|
7146
7002
|
className: cn(
|
|
7147
7003
|
"z-50 flex flex-col overflow-clip",
|
|
7148
7004
|
"bg-[var(--color-dropdown-bg)] border border-[var(--color-dropdown-border)] rounded-md shadow-lg",
|
|
7149
7005
|
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
7150
7006
|
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
|
7151
7007
|
"data-[side=bottom]:slide-in-from-top-2",
|
|
7152
|
-
"w-[
|
|
7008
|
+
"min-w-[240px]"
|
|
7153
7009
|
),
|
|
7154
7010
|
children: [
|
|
7155
|
-
/* @__PURE__ */ (0,
|
|
7156
|
-
|
|
7157
|
-
|
|
7158
|
-
if (!propDef) return null;
|
|
7159
|
-
return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
7160
|
-
AdvancedRow,
|
|
7161
|
-
{
|
|
7162
|
-
connector: i === 0 ? "Where" : (filter.logicOperator ?? "and") === "and" ? "And" : "Or",
|
|
7163
|
-
onConnectorToggle: i > 0 ? () => toggleLogicOp(filter.id) : void 0,
|
|
7164
|
-
propertyDef: propDef,
|
|
7165
|
-
condition: filter,
|
|
7166
|
-
properties,
|
|
7167
|
-
onUpdate: handleUpdateFilter,
|
|
7168
|
-
onPropertyChange: (p) => handlePropertyChange(filter.id, p),
|
|
7169
|
-
onDelete: () => handleDeleteFilter(filter.id)
|
|
7170
|
-
},
|
|
7171
|
-
filter.id
|
|
7172
|
-
);
|
|
7173
|
-
}),
|
|
7174
|
-
filters.length === 0 && /* ── Draft row: inline "Select property" placeholder ──── */
|
|
7175
|
-
/* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "flex items-center gap-base w-full min-w-0", children: [
|
|
7176
|
-
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "shrink-0 w-[64px] flex items-center justify-end", children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { className: "text-xs font-semibold leading-xs text-[var(--color-muted-foreground)]", children: "Where" }) }),
|
|
7177
|
-
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
7178
|
-
PropertySelector,
|
|
7179
|
-
{
|
|
7180
|
-
properties,
|
|
7181
|
-
onSelect: handleAddFilter,
|
|
7182
|
-
open: draftPickerOpen,
|
|
7183
|
-
onOpenChange: setDraftPickerOpen,
|
|
7184
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
|
|
7185
|
-
"button",
|
|
7186
|
-
{
|
|
7187
|
-
type: "button",
|
|
7188
|
-
className: cn(
|
|
7189
|
-
"flex items-center gap-base px-base py-sm min-w-0",
|
|
7190
|
-
"bg-gradient-to-t from-[var(--color-btn-outlined-neutral-bg-default)] to-[var(--color-btn-outlined-neutral-bg-gradient-to-default)]",
|
|
7191
|
-
"border border-[var(--color-btn-outlined-neutral-border-default)] rounded-md shadow-sm",
|
|
7192
|
-
"cursor-pointer transition-colors",
|
|
7193
|
-
"hover:from-[var(--color-btn-outlined-neutral-bg-hover)] hover:to-[var(--color-btn-outlined-neutral-bg-gradient-to-hover)]"
|
|
7194
|
-
),
|
|
7195
|
-
children: [
|
|
7196
|
-
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { className: "text-sm font-regular leading-sm text-[var(--color-muted-foreground)] whitespace-nowrap", children: "Select property" }),
|
|
7197
|
-
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
7198
|
-
import_icons33.Icon,
|
|
7199
|
-
{
|
|
7200
|
-
icon: import_icons33.faChevronDownOutline,
|
|
7201
|
-
size: "xs",
|
|
7202
|
-
className: "shrink-0 text-[var(--color-foreground)]"
|
|
7203
|
-
}
|
|
7204
|
-
)
|
|
7205
|
-
]
|
|
7206
|
-
}
|
|
7207
|
-
)
|
|
7208
|
-
}
|
|
7209
|
-
)
|
|
7210
|
-
] })
|
|
7211
|
-
] }),
|
|
7212
|
-
/* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "flex items-center justify-between p-base border-t border-[var(--color-border)]", children: [
|
|
7213
|
-
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
7214
|
-
PropertySelector,
|
|
7011
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "flex items-center gap-base px-base pt-base pb-xs border-b border-[var(--color-border)]", children: [
|
|
7012
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
7013
|
+
import_icons31.Icon,
|
|
7215
7014
|
{
|
|
7216
|
-
|
|
7217
|
-
|
|
7218
|
-
|
|
7219
|
-
onOpenChange: setAddSelectorOpen,
|
|
7220
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
|
|
7221
|
-
"button",
|
|
7222
|
-
{
|
|
7223
|
-
type: "button",
|
|
7224
|
-
className: cn(
|
|
7225
|
-
"flex items-center gap-sm px-base py-sm",
|
|
7226
|
-
"min-h-[32px] max-h-[32px] min-w-[80px]",
|
|
7227
|
-
"bg-gradient-to-t from-[var(--color-btn-outlined-neutral-bg-default)] from-[10%] to-[var(--color-btn-outlined-neutral-bg-gradient-to-default)]",
|
|
7228
|
-
"border border-[var(--color-btn-outlined-neutral-border-default)] rounded-md shadow-sm",
|
|
7229
|
-
"cursor-pointer transition-colors text-sm font-semibold leading-sm text-[var(--color-foreground)]",
|
|
7230
|
-
"hover:from-[var(--color-btn-outlined-neutral-bg-hover)] hover:to-[var(--color-btn-outlined-neutral-bg-gradient-to-hover)]"
|
|
7231
|
-
),
|
|
7232
|
-
children: [
|
|
7233
|
-
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_icons33.Icon, { icon: import_icons33.faPlusOutline, size: "sm", className: "text-[var(--color-foreground)]" }),
|
|
7234
|
-
"Add filter"
|
|
7235
|
-
]
|
|
7236
|
-
}
|
|
7237
|
-
)
|
|
7015
|
+
icon: propertyDef.icon,
|
|
7016
|
+
size: "sm",
|
|
7017
|
+
className: "shrink-0 text-[var(--color-dropdown-item-icon)]"
|
|
7238
7018
|
}
|
|
7239
7019
|
),
|
|
7240
|
-
|
|
7020
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: "text-sm font-semibold leading-sm text-[var(--color-foreground)]", children: propertyDef.label }),
|
|
7021
|
+
localOperator && view === "value" && /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
|
|
7241
7022
|
"button",
|
|
7242
7023
|
{
|
|
7243
7024
|
type: "button",
|
|
7244
|
-
onClick: () =>
|
|
7245
|
-
|
|
7246
|
-
|
|
7247
|
-
|
|
7248
|
-
|
|
7249
|
-
|
|
7025
|
+
onClick: () => setView("operator"),
|
|
7026
|
+
className: "ml-auto text-xs font-regular text-[var(--color-muted-foreground)] hover:text-[var(--color-foreground)] cursor-pointer transition-colors",
|
|
7027
|
+
children: [
|
|
7028
|
+
localOperator,
|
|
7029
|
+
" \u25BE"
|
|
7030
|
+
]
|
|
7250
7031
|
}
|
|
7251
7032
|
)
|
|
7252
|
-
] })
|
|
7253
|
-
|
|
7254
|
-
|
|
7255
|
-
|
|
7256
|
-
|
|
7257
|
-
|
|
7258
|
-
|
|
7259
|
-
|
|
7260
|
-
|
|
7261
|
-
|
|
7262
|
-
|
|
7263
|
-
|
|
7264
|
-
|
|
7265
|
-
|
|
7266
|
-
|
|
7267
|
-
|
|
7268
|
-
|
|
7269
|
-
|
|
7270
|
-
|
|
7271
|
-
|
|
7033
|
+
] }),
|
|
7034
|
+
view === "operator" ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "p-xs", children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
7035
|
+
OperatorList,
|
|
7036
|
+
{
|
|
7037
|
+
dataType: propertyDef.type,
|
|
7038
|
+
activeOperator: localOperator,
|
|
7039
|
+
onSelect: handleOperatorSelect
|
|
7040
|
+
}
|
|
7041
|
+
) }) : localOperator && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
7042
|
+
ValueInput,
|
|
7043
|
+
{
|
|
7044
|
+
dataType: propertyDef.type,
|
|
7045
|
+
operator: localOperator,
|
|
7046
|
+
value: localValue,
|
|
7047
|
+
onChange: setLocalValue,
|
|
7048
|
+
onSubmit: handleSubmit,
|
|
7049
|
+
options: propertyDef.options,
|
|
7050
|
+
dynamicOptions: propertyDef.dynamicOptions
|
|
7051
|
+
}
|
|
7052
|
+
)
|
|
7053
|
+
]
|
|
7054
|
+
}
|
|
7055
|
+
) })
|
|
7056
|
+
] });
|
|
7057
|
+
};
|
|
7058
|
+
FilterEditor.displayName = "FilterEditor";
|
|
7059
|
+
|
|
7060
|
+
// src/components/ui/filter/interactive-filter-chip.tsx
|
|
7061
|
+
var React45 = __toESM(require("react"));
|
|
7062
|
+
var PopoverPrimitive9 = __toESM(require("@radix-ui/react-popover"));
|
|
7063
|
+
var import_jsx_runtime52 = require("react/jsx-runtime");
|
|
7064
|
+
function formatFilterValue(value) {
|
|
7065
|
+
if (value == null) return void 0;
|
|
7066
|
+
if (typeof value === "boolean") return value ? "Yes" : "No";
|
|
7067
|
+
if (value instanceof Date) {
|
|
7068
|
+
return value.toLocaleDateString("en-US", {
|
|
7069
|
+
month: "short",
|
|
7070
|
+
day: "numeric",
|
|
7071
|
+
year: "numeric"
|
|
7272
7072
|
});
|
|
7273
|
-
|
|
7274
|
-
|
|
7275
|
-
|
|
7276
|
-
|
|
7073
|
+
}
|
|
7074
|
+
if (Array.isArray(value)) {
|
|
7075
|
+
if (value.length === 0) return void 0;
|
|
7076
|
+
if (value.length === 2 && typeof value[0] === "number") {
|
|
7077
|
+
return `${value[0]} \u2013 ${value[1]}`;
|
|
7078
|
+
}
|
|
7079
|
+
if (value.length === 2 && value[0] instanceof Date) {
|
|
7080
|
+
const fmt = (d) => d.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" });
|
|
7081
|
+
return `${fmt(value[0])} \u2013 ${value[1] instanceof Date ? fmt(value[1]) : "\u2026"}`;
|
|
7082
|
+
}
|
|
7083
|
+
return String(value[0]);
|
|
7084
|
+
}
|
|
7085
|
+
return String(value);
|
|
7277
7086
|
}
|
|
7278
|
-
|
|
7279
|
-
|
|
7280
|
-
|
|
7281
|
-
|
|
7282
|
-
|
|
7283
|
-
|
|
7284
|
-
|
|
7285
|
-
|
|
7286
|
-
|
|
7287
|
-
|
|
7087
|
+
function getBadgeCount(value) {
|
|
7088
|
+
if (Array.isArray(value) && value.length > 1 && typeof value[0] === "string") {
|
|
7089
|
+
return value.length;
|
|
7090
|
+
}
|
|
7091
|
+
return void 0;
|
|
7092
|
+
}
|
|
7093
|
+
var SegmentPopover = ({
|
|
7094
|
+
open,
|
|
7095
|
+
onOpenChange,
|
|
7096
|
+
trigger,
|
|
7288
7097
|
children,
|
|
7289
|
-
|
|
7098
|
+
align = "start",
|
|
7099
|
+
minWidth = "240px"
|
|
7100
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(PopoverPrimitive9.Root, { open, onOpenChange, children: [
|
|
7101
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)(PopoverPrimitive9.Trigger, { asChild: true, children: trigger }),
|
|
7102
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)(PopoverPrimitive9.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
7103
|
+
PopoverPrimitive9.Content,
|
|
7104
|
+
{
|
|
7105
|
+
sideOffset: 4,
|
|
7106
|
+
align,
|
|
7107
|
+
className: cn(
|
|
7108
|
+
"z-50 flex flex-col overflow-clip",
|
|
7109
|
+
"bg-[var(--color-dropdown-bg)] border border-[var(--color-dropdown-border)] rounded-md shadow-lg",
|
|
7110
|
+
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
7111
|
+
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
|
7112
|
+
"data-[side=bottom]:slide-in-from-top-2"
|
|
7113
|
+
),
|
|
7114
|
+
style: { minWidth },
|
|
7115
|
+
children
|
|
7116
|
+
}
|
|
7117
|
+
) })
|
|
7118
|
+
] });
|
|
7119
|
+
var InteractiveFilterChip = ({
|
|
7120
|
+
propertyDef,
|
|
7121
|
+
condition,
|
|
7122
|
+
properties,
|
|
7123
|
+
mode = "edit",
|
|
7124
|
+
autoOpen = false,
|
|
7125
|
+
onUpdate,
|
|
7126
|
+
onPropertyChange,
|
|
7127
|
+
onDelete,
|
|
7128
|
+
onConvertToAdvanced,
|
|
7290
7129
|
className
|
|
7291
7130
|
}) => {
|
|
7292
|
-
const
|
|
7293
|
-
const
|
|
7294
|
-
const [
|
|
7295
|
-
const [
|
|
7296
|
-
const [
|
|
7297
|
-
const
|
|
7298
|
-
|
|
7299
|
-
|
|
7300
|
-
|
|
7301
|
-
|
|
7302
|
-
if (newFilter.operator && isNoValueOperator(newFilter.operator)) {
|
|
7303
|
-
onFilterStateChange({
|
|
7304
|
-
...filterState,
|
|
7305
|
-
basicFilters: [...filterState.basicFilters, newFilter]
|
|
7306
|
-
});
|
|
7307
|
-
return;
|
|
7131
|
+
const [operatorOpen, setOperatorOpen] = React45.useState(false);
|
|
7132
|
+
const [valueOpen, setValueOpen] = React45.useState(false);
|
|
7133
|
+
const [propertyOpen, setPropertyOpen] = React45.useState(false);
|
|
7134
|
+
const [kebabOpen, setKebabOpen] = React45.useState(false);
|
|
7135
|
+
const [pendingValueOpen, setPendingValueOpen] = React45.useState(false);
|
|
7136
|
+
const autoOpenHandled = React45.useRef(false);
|
|
7137
|
+
React45.useEffect(() => {
|
|
7138
|
+
if (autoOpen && !autoOpenHandled.current && condition.operator && !isNoValueOperator(condition.operator)) {
|
|
7139
|
+
autoOpenHandled.current = true;
|
|
7140
|
+
setValueOpen(true);
|
|
7308
7141
|
}
|
|
7309
|
-
|
|
7310
|
-
|
|
7311
|
-
|
|
7312
|
-
|
|
7313
|
-
|
|
7314
|
-
};
|
|
7315
|
-
const handleUpdateFilter = (updated) => {
|
|
7316
|
-
onFilterStateChange({
|
|
7317
|
-
...filterState,
|
|
7318
|
-
basicFilters: filterState.basicFilters.map(
|
|
7319
|
-
(f) => f.id === updated.id ? updated : f
|
|
7320
|
-
)
|
|
7321
|
-
});
|
|
7322
|
-
if (pendingFilterId === updated.id) {
|
|
7323
|
-
setPendingFilterId(null);
|
|
7142
|
+
}, [autoOpen, condition.operator]);
|
|
7143
|
+
React45.useEffect(() => {
|
|
7144
|
+
if (!operatorOpen && pendingValueOpen) {
|
|
7145
|
+
setPendingValueOpen(false);
|
|
7146
|
+
setValueOpen(true);
|
|
7324
7147
|
}
|
|
7325
|
-
};
|
|
7326
|
-
const
|
|
7327
|
-
|
|
7328
|
-
...
|
|
7329
|
-
|
|
7330
|
-
}
|
|
7331
|
-
|
|
7332
|
-
|
|
7333
|
-
|
|
7334
|
-
|
|
7335
|
-
|
|
7336
|
-
|
|
7337
|
-
(f) => f.id === filterId ? { ...newCondition, id: filterId } : f
|
|
7338
|
-
)
|
|
7339
|
-
});
|
|
7340
|
-
if (newCondition.operator && !isNoValueOperator(newCondition.operator)) {
|
|
7341
|
-
setPendingFilterId(filterId);
|
|
7148
|
+
}, [operatorOpen, pendingValueOpen]);
|
|
7149
|
+
const handleOperatorSelect = (op) => {
|
|
7150
|
+
if (isNoValueOperator(op)) {
|
|
7151
|
+
onUpdate({ ...condition, operator: op, value: null });
|
|
7152
|
+
setOperatorOpen(false);
|
|
7153
|
+
} else {
|
|
7154
|
+
const resetValue = op !== condition.operator ? null : condition.value;
|
|
7155
|
+
onUpdate({ ...condition, operator: op, value: resetValue });
|
|
7156
|
+
setOperatorOpen(false);
|
|
7157
|
+
if (resetValue == null) {
|
|
7158
|
+
setPendingValueOpen(true);
|
|
7159
|
+
}
|
|
7342
7160
|
}
|
|
7343
7161
|
};
|
|
7344
|
-
const
|
|
7345
|
-
|
|
7346
|
-
if (!filter) return;
|
|
7347
|
-
onFilterStateChange({
|
|
7348
|
-
...filterState,
|
|
7349
|
-
basicFilters: filterState.basicFilters.filter((f) => f.id !== id),
|
|
7350
|
-
advancedFilters: [...filterState.advancedFilters, filter]
|
|
7351
|
-
});
|
|
7352
|
-
};
|
|
7353
|
-
const handleAdvancedFiltersChange = (filters) => {
|
|
7354
|
-
onFilterStateChange({ ...filterState, advancedFilters: filters });
|
|
7355
|
-
};
|
|
7356
|
-
const handleClearAdvanced = () => {
|
|
7357
|
-
onFilterStateChange({ ...filterState, advancedFilters: [] });
|
|
7358
|
-
};
|
|
7359
|
-
const handleClearAll = () => {
|
|
7360
|
-
onFilterStateChange({
|
|
7361
|
-
...filterState,
|
|
7362
|
-
basicFilters: [],
|
|
7363
|
-
advancedFilters: []
|
|
7364
|
-
});
|
|
7365
|
-
};
|
|
7366
|
-
const handleSortChange = (field, direction) => {
|
|
7367
|
-
onFilterStateChange({ ...filterState, sort: { field, direction } });
|
|
7162
|
+
const handleValueChange = (val) => {
|
|
7163
|
+
onUpdate({ ...condition, value: val });
|
|
7368
7164
|
};
|
|
7369
|
-
const
|
|
7370
|
-
|
|
7371
|
-
const isMinimal = mode === "minimal";
|
|
7372
|
-
const handleOpenAdvanced = () => {
|
|
7373
|
-
setPropertySelectorOpen(false);
|
|
7374
|
-
requestAnimationFrame(() => {
|
|
7375
|
-
if (isMinimal) {
|
|
7376
|
-
setSummaryOpen(true);
|
|
7377
|
-
} else {
|
|
7378
|
-
setAdvancedOpen(true);
|
|
7379
|
-
}
|
|
7380
|
-
});
|
|
7165
|
+
const handleValueSubmit = () => {
|
|
7166
|
+
setValueOpen(false);
|
|
7381
7167
|
};
|
|
7382
|
-
const
|
|
7383
|
-
const
|
|
7384
|
-
const
|
|
7385
|
-
|
|
7386
|
-
|
|
7387
|
-
|
|
7388
|
-
|
|
7389
|
-
|
|
7390
|
-
|
|
7391
|
-
|
|
7392
|
-
|
|
7393
|
-
direction: filterState.sort.direction,
|
|
7394
|
-
onChange: handleSortChange,
|
|
7395
|
-
iconOnly: isMinimal
|
|
7396
|
-
}
|
|
7168
|
+
const hasOperator = !!condition.operator;
|
|
7169
|
+
const displayValue = formatFilterValue(condition.value);
|
|
7170
|
+
const hasValue = hasOperator && displayValue != null;
|
|
7171
|
+
const badgeCount = getBadgeCount(condition.value);
|
|
7172
|
+
return /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(
|
|
7173
|
+
"div",
|
|
7174
|
+
{
|
|
7175
|
+
className: cn(
|
|
7176
|
+
"inline-flex items-center overflow-clip",
|
|
7177
|
+
"bg-filter-chip-bg border border-filter-chip-border rounded-md shadow-sm",
|
|
7178
|
+
className
|
|
7397
7179
|
),
|
|
7398
|
-
|
|
7399
|
-
/* @__PURE__ */ (0,
|
|
7400
|
-
"div",
|
|
7401
|
-
{
|
|
7402
|
-
className: showSummaryChip ? "inline-flex" : "inline-flex w-0 overflow-hidden opacity-0 pointer-events-none",
|
|
7403
|
-
"aria-hidden": !showSummaryChip || void 0,
|
|
7404
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
7405
|
-
SummaryChip,
|
|
7406
|
-
{
|
|
7407
|
-
count: totalCount,
|
|
7408
|
-
filters: allFilters,
|
|
7409
|
-
properties,
|
|
7410
|
-
onFiltersChange: (filters) => {
|
|
7411
|
-
onFilterStateChange({
|
|
7412
|
-
...filterState,
|
|
7413
|
-
basicFilters: filters,
|
|
7414
|
-
advancedFilters: []
|
|
7415
|
-
});
|
|
7416
|
-
},
|
|
7417
|
-
onClearAll: handleClearAll,
|
|
7418
|
-
open: summaryOpen,
|
|
7419
|
-
onOpenChange: setSummaryOpen
|
|
7420
|
-
}
|
|
7421
|
-
)
|
|
7422
|
-
}
|
|
7423
|
-
),
|
|
7424
|
-
!showSummaryChip && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
7180
|
+
children: [
|
|
7181
|
+
properties ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
7425
7182
|
PropertySelector,
|
|
7426
7183
|
{
|
|
7427
7184
|
properties,
|
|
7428
|
-
onSelect:
|
|
7429
|
-
|
|
7430
|
-
|
|
7431
|
-
|
|
7432
|
-
|
|
7433
|
-
|
|
7185
|
+
onSelect: (prop) => {
|
|
7186
|
+
onPropertyChange?.(prop);
|
|
7187
|
+
setPropertyOpen(false);
|
|
7188
|
+
},
|
|
7189
|
+
open: propertyOpen,
|
|
7190
|
+
onOpenChange: setPropertyOpen,
|
|
7191
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
7192
|
+
FilterChipSegment,
|
|
7193
|
+
{
|
|
7194
|
+
segmentType: "property",
|
|
7195
|
+
hasBorder: true,
|
|
7196
|
+
icon: propertyDef.icon,
|
|
7197
|
+
label: propertyDef.label,
|
|
7198
|
+
onClick: () => setPropertyOpen(true)
|
|
7199
|
+
}
|
|
7200
|
+
) })
|
|
7434
7201
|
}
|
|
7435
|
-
)
|
|
7436
|
-
|
|
7437
|
-
|
|
7438
|
-
|
|
7439
|
-
|
|
7440
|
-
|
|
7202
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
7203
|
+
FilterChipSegment,
|
|
7204
|
+
{
|
|
7205
|
+
segmentType: "property",
|
|
7206
|
+
hasBorder: true,
|
|
7207
|
+
icon: propertyDef.icon,
|
|
7208
|
+
label: propertyDef.label
|
|
7209
|
+
}
|
|
7210
|
+
),
|
|
7211
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
7212
|
+
SegmentPopover,
|
|
7213
|
+
{
|
|
7214
|
+
open: operatorOpen,
|
|
7215
|
+
onOpenChange: setOperatorOpen,
|
|
7216
|
+
minWidth: "180px",
|
|
7217
|
+
trigger: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
7218
|
+
FilterChipSegment,
|
|
7219
|
+
{
|
|
7220
|
+
segmentType: hasOperator ? "operator" : "placeholder",
|
|
7221
|
+
hasBorder: true,
|
|
7222
|
+
label: hasOperator ? condition.operator : "Select condition",
|
|
7223
|
+
onClick: () => setOperatorOpen(true)
|
|
7224
|
+
}
|
|
7225
|
+
) }),
|
|
7226
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: "p-xs", children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
7227
|
+
OperatorList,
|
|
7228
|
+
{
|
|
7229
|
+
dataType: propertyDef.type,
|
|
7230
|
+
activeOperator: condition.operator,
|
|
7231
|
+
onSelect: handleOperatorSelect
|
|
7232
|
+
}
|
|
7233
|
+
) })
|
|
7234
|
+
}
|
|
7235
|
+
),
|
|
7236
|
+
hasOperator && condition.operator && !isNoValueOperator(condition.operator) && (() => {
|
|
7237
|
+
const inputType = getValueInputType(propertyDef.type, condition.operator);
|
|
7238
|
+
const dateWide = inputType === "DatePicker" || inputType === "DateRange";
|
|
7239
|
+
return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
7240
|
+
SegmentPopover,
|
|
7441
7241
|
{
|
|
7442
|
-
|
|
7443
|
-
|
|
7444
|
-
|
|
7445
|
-
|
|
7446
|
-
|
|
7447
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
7448
|
-
"div",
|
|
7242
|
+
open: valueOpen,
|
|
7243
|
+
onOpenChange: setValueOpen,
|
|
7244
|
+
minWidth: dateWide ? "auto" : "240px",
|
|
7245
|
+
trigger: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
7246
|
+
FilterChipSegment,
|
|
7449
7247
|
{
|
|
7450
|
-
|
|
7451
|
-
|
|
7452
|
-
|
|
7453
|
-
|
|
7454
|
-
|
|
7455
|
-
|
|
7456
|
-
|
|
7457
|
-
|
|
7458
|
-
|
|
7459
|
-
|
|
7248
|
+
segmentType: hasValue ? "value" : "placeholder",
|
|
7249
|
+
hasBorder: true,
|
|
7250
|
+
label: hasValue ? displayValue : "Enter value",
|
|
7251
|
+
badgeCount,
|
|
7252
|
+
onClick: () => setValueOpen(true)
|
|
7253
|
+
}
|
|
7254
|
+
) }),
|
|
7255
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
7256
|
+
ValueInput,
|
|
7257
|
+
{
|
|
7258
|
+
dataType: propertyDef.type,
|
|
7259
|
+
operator: condition.operator,
|
|
7260
|
+
value: condition.value,
|
|
7261
|
+
onChange: handleValueChange,
|
|
7262
|
+
onSubmit: handleValueSubmit,
|
|
7263
|
+
options: propertyDef.options,
|
|
7264
|
+
dynamicOptions: propertyDef.dynamicOptions
|
|
7460
7265
|
}
|
|
7461
7266
|
)
|
|
7462
7267
|
}
|
|
7463
|
-
)
|
|
7464
|
-
|
|
7465
|
-
|
|
7466
|
-
|
|
7467
|
-
|
|
7468
|
-
|
|
7268
|
+
);
|
|
7269
|
+
})(),
|
|
7270
|
+
hasOperator && condition.operator && isNoValueOperator(condition.operator) && /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
7271
|
+
FilterChipSegment,
|
|
7272
|
+
{
|
|
7273
|
+
segmentType: "value",
|
|
7274
|
+
hasBorder: true,
|
|
7275
|
+
label: condition.operator
|
|
7276
|
+
}
|
|
7277
|
+
),
|
|
7278
|
+
hasOperator && /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
7279
|
+
KebabMenu,
|
|
7280
|
+
{
|
|
7281
|
+
open: kebabOpen,
|
|
7282
|
+
onOpenChange: setKebabOpen,
|
|
7283
|
+
onConvertToAdvanced,
|
|
7284
|
+
onDelete,
|
|
7285
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
7286
|
+
FilterChipSegment,
|
|
7469
7287
|
{
|
|
7470
|
-
|
|
7471
|
-
|
|
7472
|
-
|
|
7473
|
-
|
|
7474
|
-
autoOpen: pendingFilterId === filter.id,
|
|
7475
|
-
onUpdate: handleUpdateFilter,
|
|
7476
|
-
onPropertyChange: (newProp) => handlePropertyChange(filter.id, newProp),
|
|
7477
|
-
onDelete: () => handleDeleteFilter(filter.id),
|
|
7478
|
-
onConvertToAdvanced: () => handleConvertToAdvanced(filter.id)
|
|
7479
|
-
},
|
|
7480
|
-
filter.id
|
|
7481
|
-
);
|
|
7482
|
-
}),
|
|
7483
|
-
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
7484
|
-
PropertySelector,
|
|
7485
|
-
{
|
|
7486
|
-
properties,
|
|
7487
|
-
onSelect: handleAddFilter,
|
|
7488
|
-
open: propertySelectorOpen,
|
|
7489
|
-
onOpenChange: setPropertySelectorOpen,
|
|
7490
|
-
onAdvancedFilter: handleOpenAdvanced,
|
|
7491
|
-
advancedFilterCount,
|
|
7492
|
-
children: totalCount > 0 ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
7493
|
-
"button",
|
|
7494
|
-
{
|
|
7495
|
-
type: "button",
|
|
7496
|
-
className: "shrink-0 inline-flex items-center justify-center size-8 rounded-md border border-[var(--color-btn-outlined-neutral-border-default)] bg-gradient-to-t from-[var(--color-btn-outlined-neutral-bg-default)] from-[10%] to-[var(--color-btn-outlined-neutral-bg-gradient-to-default)] shadow-sm cursor-pointer transition-colors hover:from-[var(--color-btn-outlined-neutral-bg-hover)] hover:to-[var(--color-btn-outlined-neutral-bg-gradient-to-hover)]",
|
|
7497
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_icons34.Icon, { icon: import_icons34.faPlusOutline, size: "sm", className: "text-[var(--color-foreground)]" })
|
|
7288
|
+
segmentType: "button",
|
|
7289
|
+
onKebabClick: (e) => {
|
|
7290
|
+
e.stopPropagation();
|
|
7291
|
+
setKebabOpen(true);
|
|
7498
7292
|
}
|
|
7499
|
-
|
|
7500
|
-
}
|
|
7501
|
-
|
|
7502
|
-
|
|
7503
|
-
|
|
7504
|
-
|
|
7505
|
-
|
|
7506
|
-
{
|
|
7507
|
-
type: "button",
|
|
7508
|
-
onClick: handleClearAll,
|
|
7509
|
-
className: "shrink-0 flex items-center gap-sm px-base py-sm min-h-[32px] max-h-[32px] rounded-md cursor-pointer transition-colors hover:bg-[var(--color-accent)]",
|
|
7510
|
-
children: isMinimal ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_icons34.Icon, { icon: import_icons34.faXmarkOutline, size: "sm", className: "text-[var(--color-foreground)]" }) : /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "text-sm font-semibold leading-sm text-[var(--color-foreground)]", children: "Clear" })
|
|
7511
|
-
}
|
|
7512
|
-
)
|
|
7513
|
-
] }),
|
|
7514
|
-
actions && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(FilterBarRight, { className: "shrink-0 -ml-2xl pl-2xl relative z-10 bg-[linear-gradient(to_right,transparent_0px,var(--filter-bar-bg,var(--color-background,#fff))_24px)]", children: actions })
|
|
7515
|
-
] });
|
|
7293
|
+
}
|
|
7294
|
+
) })
|
|
7295
|
+
}
|
|
7296
|
+
)
|
|
7297
|
+
]
|
|
7298
|
+
}
|
|
7299
|
+
);
|
|
7516
7300
|
};
|
|
7517
|
-
|
|
7301
|
+
InteractiveFilterChip.displayName = "InteractiveFilterChip";
|
|
7518
7302
|
|
|
7519
|
-
// src/components/ui/
|
|
7520
|
-
var
|
|
7521
|
-
var
|
|
7522
|
-
|
|
7523
|
-
|
|
7524
|
-
|
|
7525
|
-
|
|
7526
|
-
|
|
7527
|
-
|
|
7528
|
-
|
|
7529
|
-
|
|
7530
|
-
|
|
7531
|
-
|
|
7532
|
-
|
|
7533
|
-
|
|
7534
|
-
const t = date.getTime();
|
|
7535
|
-
return t >= from.getTime() && t <= to.getTime();
|
|
7536
|
-
}
|
|
7537
|
-
function startOfDay(d) {
|
|
7538
|
-
return new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
7539
|
-
}
|
|
7540
|
-
var WEEKDAYS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
|
|
7541
|
-
var MONTH_NAMES = [
|
|
7542
|
-
"January",
|
|
7543
|
-
"February",
|
|
7544
|
-
"March",
|
|
7545
|
-
"April",
|
|
7546
|
-
"May",
|
|
7547
|
-
"June",
|
|
7548
|
-
"July",
|
|
7549
|
-
"August",
|
|
7550
|
-
"September",
|
|
7551
|
-
"October",
|
|
7552
|
-
"November",
|
|
7553
|
-
"December"
|
|
7303
|
+
// src/components/ui/filter/filter-system.tsx
|
|
7304
|
+
var React51 = __toESM(require("react"));
|
|
7305
|
+
var import_icons36 = require("@l3mpire/icons");
|
|
7306
|
+
|
|
7307
|
+
// src/components/ui/filter/advanced-chip.tsx
|
|
7308
|
+
var React46 = __toESM(require("react"));
|
|
7309
|
+
var import_icons32 = require("@l3mpire/icons");
|
|
7310
|
+
var import_jsx_runtime53 = require("react/jsx-runtime");
|
|
7311
|
+
var btnBase = [
|
|
7312
|
+
"flex items-center justify-center",
|
|
7313
|
+
"min-h-[32px] max-h-[32px]",
|
|
7314
|
+
"bg-gradient-to-t from-[var(--color-btn-outlined-neutral-bg-default)] from-[10%] to-[var(--color-btn-outlined-neutral-bg-gradient-to-default)]",
|
|
7315
|
+
"border border-[var(--color-btn-outlined-neutral-border-default)] shadow-sm",
|
|
7316
|
+
"cursor-pointer transition-colors",
|
|
7317
|
+
"hover:from-[var(--color-btn-outlined-neutral-bg-hover)] hover:to-[var(--color-btn-outlined-neutral-bg-gradient-to-hover)]"
|
|
7554
7318
|
];
|
|
7555
|
-
var
|
|
7556
|
-
|
|
7557
|
-
)
|
|
7558
|
-
|
|
7559
|
-
|
|
7560
|
-
|
|
7561
|
-
|
|
7562
|
-
|
|
7563
|
-
|
|
7564
|
-
|
|
7565
|
-
|
|
7566
|
-
|
|
7567
|
-
|
|
7568
|
-
|
|
7569
|
-
|
|
7570
|
-
|
|
7571
|
-
|
|
7572
|
-
|
|
7573
|
-
...props
|
|
7574
|
-
}, ref) => {
|
|
7575
|
-
const today = React50.useMemo(() => startOfDay(/* @__PURE__ */ new Date()), []);
|
|
7576
|
-
const initialDate = React50.useMemo(() => {
|
|
7577
|
-
if (value) {
|
|
7578
|
-
if (value instanceof Date) return value;
|
|
7579
|
-
return value.from;
|
|
7319
|
+
var AdvancedChip = React46.forwardRef(
|
|
7320
|
+
({ className, count, onClear, onClick, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: cn("inline-flex items-center", className), children: [
|
|
7321
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
|
|
7322
|
+
"button",
|
|
7323
|
+
{
|
|
7324
|
+
ref,
|
|
7325
|
+
type: "button",
|
|
7326
|
+
onClick,
|
|
7327
|
+
className: cn(
|
|
7328
|
+
btnBase,
|
|
7329
|
+
"gap-sm px-base py-sm min-w-[80px]",
|
|
7330
|
+
"rounded-l-md -mr-px"
|
|
7331
|
+
),
|
|
7332
|
+
...props,
|
|
7333
|
+
children: [
|
|
7334
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "text-sm font-semibold leading-sm whitespace-nowrap text-[var(--color-foreground)]", children: "Advanced filters" }),
|
|
7335
|
+
count > 0 && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "flex items-center p-2xs rounded-xs bg-filter-chip-badge-bg", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "text-[10px] font-semibold leading-2xs text-filter-chip-badge-text", children: count }) })
|
|
7336
|
+
]
|
|
7580
7337
|
}
|
|
7581
|
-
|
|
7582
|
-
|
|
7583
|
-
|
|
7584
|
-
defaultMonth ?? initialDate.getMonth()
|
|
7585
|
-
);
|
|
7586
|
-
const [year, setYear] = React50.useState(
|
|
7587
|
-
defaultYear ?? initialDate.getFullYear()
|
|
7588
|
-
);
|
|
7589
|
-
const [hoveredDate, setHoveredDate] = React50.useState();
|
|
7590
|
-
const goToPrevMonth = React50.useCallback(() => {
|
|
7591
|
-
setMonth((m) => {
|
|
7592
|
-
if (m === 0) {
|
|
7593
|
-
setYear((y) => y - 1);
|
|
7594
|
-
return 11;
|
|
7595
|
-
}
|
|
7596
|
-
return m - 1;
|
|
7597
|
-
});
|
|
7598
|
-
}, []);
|
|
7599
|
-
const goToNextMonth = React50.useCallback(() => {
|
|
7600
|
-
setMonth((m) => {
|
|
7601
|
-
if (m === 11) {
|
|
7602
|
-
setYear((y) => y + 1);
|
|
7603
|
-
return 0;
|
|
7604
|
-
}
|
|
7605
|
-
return m + 1;
|
|
7606
|
-
});
|
|
7607
|
-
}, []);
|
|
7608
|
-
const onSelect = React50.useCallback(
|
|
7609
|
-
(date) => {
|
|
7610
|
-
if (mode === "single") {
|
|
7611
|
-
onValueChange?.(date);
|
|
7612
|
-
return;
|
|
7613
|
-
}
|
|
7614
|
-
if (!value || value instanceof Date) {
|
|
7615
|
-
onValueChange?.({ from: date });
|
|
7616
|
-
return;
|
|
7617
|
-
}
|
|
7618
|
-
const range = value;
|
|
7619
|
-
if (range.to || date.getTime() < range.from.getTime()) {
|
|
7620
|
-
onValueChange?.({ from: date });
|
|
7621
|
-
} else {
|
|
7622
|
-
onValueChange?.({ from: range.from, to: date });
|
|
7623
|
-
}
|
|
7624
|
-
},
|
|
7625
|
-
[mode, value, onValueChange]
|
|
7626
|
-
);
|
|
7627
|
-
const ctxValue = React50.useMemo(
|
|
7628
|
-
() => ({
|
|
7629
|
-
mode,
|
|
7630
|
-
selected: value,
|
|
7631
|
-
onSelect,
|
|
7632
|
-
month,
|
|
7633
|
-
year,
|
|
7634
|
-
setMonth,
|
|
7635
|
-
setYear,
|
|
7636
|
-
goToPrevMonth,
|
|
7637
|
-
goToNextMonth,
|
|
7638
|
-
today,
|
|
7639
|
-
hoveredDate,
|
|
7640
|
-
setHoveredDate
|
|
7641
|
-
}),
|
|
7642
|
-
[
|
|
7643
|
-
mode,
|
|
7644
|
-
value,
|
|
7645
|
-
onSelect,
|
|
7646
|
-
month,
|
|
7647
|
-
year,
|
|
7648
|
-
goToPrevMonth,
|
|
7649
|
-
goToNextMonth,
|
|
7650
|
-
today,
|
|
7651
|
-
hoveredDate
|
|
7652
|
-
]
|
|
7653
|
-
);
|
|
7654
|
-
return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(DatePickerContext.Provider, { value: ctxValue, children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
7655
|
-
"div",
|
|
7338
|
+
),
|
|
7339
|
+
onClear && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
7340
|
+
"button",
|
|
7656
7341
|
{
|
|
7657
|
-
|
|
7342
|
+
type: "button",
|
|
7343
|
+
onClick: (e) => {
|
|
7344
|
+
e.stopPropagation();
|
|
7345
|
+
onClear();
|
|
7346
|
+
},
|
|
7658
7347
|
className: cn(
|
|
7659
|
-
|
|
7660
|
-
"
|
|
7661
|
-
|
|
7348
|
+
btnBase,
|
|
7349
|
+
"p-sm",
|
|
7350
|
+
"rounded-r-md -ml-px"
|
|
7662
7351
|
),
|
|
7663
|
-
|
|
7664
|
-
children
|
|
7352
|
+
"aria-label": "Clear all advanced filters",
|
|
7353
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_icons32.Icon, { icon: import_icons32.faXmarkOutline, size: "sm", className: "text-[var(--color-foreground)]" })
|
|
7665
7354
|
}
|
|
7666
|
-
)
|
|
7667
|
-
}
|
|
7355
|
+
)
|
|
7356
|
+
] })
|
|
7668
7357
|
);
|
|
7669
|
-
|
|
7670
|
-
|
|
7671
|
-
|
|
7672
|
-
|
|
7673
|
-
|
|
7674
|
-
|
|
7675
|
-
|
|
7676
|
-
|
|
7677
|
-
var
|
|
7678
|
-
|
|
7679
|
-
|
|
7680
|
-
|
|
7681
|
-
|
|
7682
|
-
|
|
7683
|
-
|
|
7684
|
-
|
|
7685
|
-
|
|
7686
|
-
|
|
7687
|
-
|
|
7688
|
-
|
|
7689
|
-
|
|
7690
|
-
|
|
7691
|
-
|
|
7692
|
-
|
|
7693
|
-
|
|
7694
|
-
|
|
7695
|
-
|
|
7696
|
-
|
|
7697
|
-
|
|
7698
|
-
|
|
7699
|
-
|
|
7700
|
-
|
|
7701
|
-
|
|
7702
|
-
|
|
7703
|
-
|
|
7704
|
-
|
|
7705
|
-
|
|
7706
|
-
|
|
7707
|
-
});
|
|
7708
|
-
DatePickerSelects.displayName = "DatePickerSelects";
|
|
7709
|
-
var DatePickerDay = ({ date, isOutside }) => {
|
|
7710
|
-
const { mode, selected, onSelect, today, hoveredDate, setHoveredDate } = useDatePickerContext();
|
|
7711
|
-
const isToday = isSameDay(date, today);
|
|
7712
|
-
const isSelected = selected instanceof Date ? isSameDay(date, selected) : selected?.from ? isSameDay(date, selected.from) || (selected.to ? isSameDay(date, selected.to) : false) : false;
|
|
7713
|
-
const isRangeStart = mode === "range" && selected && !(selected instanceof Date) && selected.from && isSameDay(date, selected.from);
|
|
7714
|
-
const isRangeEnd = mode === "range" && selected && !(selected instanceof Date) && selected.to && isSameDay(date, selected.to);
|
|
7715
|
-
const inRange = mode === "range" && selected && !(selected instanceof Date) && selected.from && selected.to && !isSelected && isInRange(date, selected.from, selected.to);
|
|
7716
|
-
const inPreviewRange = mode === "range" && selected && !(selected instanceof Date) && selected.from && !selected.to && hoveredDate && !isSelected && hoveredDate.getTime() > selected.from.getTime() && isInRange(date, selected.from, hoveredDate);
|
|
7717
|
-
const isInRangeOrPreview = inRange || inPreviewRange;
|
|
7718
|
-
return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(
|
|
7719
|
-
"button",
|
|
7720
|
-
{
|
|
7721
|
-
type: "button",
|
|
7722
|
-
onClick: () => !isOutside && onSelect(date),
|
|
7723
|
-
onMouseEnter: () => mode === "range" && setHoveredDate(date),
|
|
7724
|
-
onMouseLeave: () => mode === "range" && setHoveredDate(void 0),
|
|
7725
|
-
disabled: isOutside,
|
|
7726
|
-
className: cn(
|
|
7727
|
-
"relative flex flex-col items-center justify-center w-9 rounded-full p-2 cursor-pointer transition-colors",
|
|
7728
|
-
"text-sm font-semibold leading-sm text-center",
|
|
7729
|
-
// Default
|
|
7730
|
-
!isOutside && !isSelected && !isInRangeOrPreview && "text-datepicker-day-text-default hover:bg-datepicker-day-bg-hover",
|
|
7731
|
-
// Outside month (disabled)
|
|
7732
|
-
isOutside && "text-datepicker-day-text-disabled cursor-default",
|
|
7733
|
-
// Selected
|
|
7734
|
-
isSelected && "bg-datepicker-day-bg-selected text-datepicker-day-text-selected",
|
|
7735
|
-
// In range
|
|
7736
|
-
isInRangeOrPreview && "bg-datepicker-day-bg-range text-datepicker-day-text-range",
|
|
7737
|
-
// Range start/end get full rounded; in-range items could be less rounded
|
|
7738
|
-
(isRangeStart || isRangeEnd) && "rounded-full"
|
|
7739
|
-
),
|
|
7740
|
-
children: [
|
|
7741
|
-
date.getDate(),
|
|
7742
|
-
isToday && !isOutside && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "absolute bottom-0.5 left-1/2 -translate-x-1/2 size-1.5 rounded-full bg-datepicker-day-today" })
|
|
7743
|
-
]
|
|
7744
|
-
}
|
|
7745
|
-
);
|
|
7746
|
-
};
|
|
7747
|
-
var DatePickerCalendar = React50.forwardRef(({ className, header, ...props }, ref) => {
|
|
7748
|
-
const { month, year, goToPrevMonth, goToNextMonth } = useDatePickerContext();
|
|
7749
|
-
const weeks = React50.useMemo(() => {
|
|
7750
|
-
const firstDay = new Date(year, month, 1);
|
|
7751
|
-
const startOffset = getWeekdayIndex(firstDay);
|
|
7752
|
-
const daysInMonth = getDaysInMonth(year, month);
|
|
7753
|
-
const daysInPrevMonth = getDaysInMonth(
|
|
7754
|
-
month === 0 ? year - 1 : year,
|
|
7755
|
-
month === 0 ? 11 : month - 1
|
|
7756
|
-
);
|
|
7757
|
-
const days = [];
|
|
7758
|
-
for (let i = startOffset - 1; i >= 0; i--) {
|
|
7759
|
-
const d = daysInPrevMonth - i;
|
|
7760
|
-
days.push({
|
|
7761
|
-
date: new Date(
|
|
7762
|
-
month === 0 ? year - 1 : year,
|
|
7763
|
-
month === 0 ? 11 : month - 1,
|
|
7764
|
-
d
|
|
7765
|
-
),
|
|
7766
|
-
isOutside: true
|
|
7767
|
-
});
|
|
7768
|
-
}
|
|
7769
|
-
for (let d = 1; d <= daysInMonth; d++) {
|
|
7770
|
-
days.push({ date: new Date(year, month, d), isOutside: false });
|
|
7358
|
+
AdvancedChip.displayName = "AdvancedChip";
|
|
7359
|
+
|
|
7360
|
+
// src/components/ui/filter/advanced-popover.tsx
|
|
7361
|
+
var React48 = __toESM(require("react"));
|
|
7362
|
+
var PopoverPrimitive11 = __toESM(require("@radix-ui/react-popover"));
|
|
7363
|
+
var import_icons34 = require("@l3mpire/icons");
|
|
7364
|
+
|
|
7365
|
+
// src/components/ui/filter/advanced-row.tsx
|
|
7366
|
+
var React47 = __toESM(require("react"));
|
|
7367
|
+
var PopoverPrimitive10 = __toESM(require("@radix-ui/react-popover"));
|
|
7368
|
+
var import_icons33 = require("@l3mpire/icons");
|
|
7369
|
+
var import_jsx_runtime54 = require("react/jsx-runtime");
|
|
7370
|
+
var selectBtnStyle = [
|
|
7371
|
+
"flex items-center gap-base",
|
|
7372
|
+
"px-base py-sm",
|
|
7373
|
+
"bg-gradient-to-t from-[var(--color-btn-outlined-neutral-bg-default)] to-[var(--color-btn-outlined-neutral-bg-gradient-to-default)]",
|
|
7374
|
+
"border border-[var(--color-btn-outlined-neutral-border-default)] rounded-md shadow-sm",
|
|
7375
|
+
"cursor-pointer transition-colors",
|
|
7376
|
+
"hover:from-[var(--color-btn-outlined-neutral-bg-hover)] hover:to-[var(--color-btn-outlined-neutral-bg-gradient-to-hover)]"
|
|
7377
|
+
];
|
|
7378
|
+
var AdvancedRow = ({
|
|
7379
|
+
connector,
|
|
7380
|
+
onConnectorToggle,
|
|
7381
|
+
propertyDef,
|
|
7382
|
+
condition,
|
|
7383
|
+
properties,
|
|
7384
|
+
onUpdate,
|
|
7385
|
+
onPropertyChange,
|
|
7386
|
+
onDelete
|
|
7387
|
+
}) => {
|
|
7388
|
+
const [operatorOpen, setOperatorOpen] = React47.useState(false);
|
|
7389
|
+
const [propertyOpen, setPropertyOpen] = React47.useState(false);
|
|
7390
|
+
const handleOperatorSelect = (op) => {
|
|
7391
|
+
if (isNoValueOperator(op)) {
|
|
7392
|
+
onUpdate({ ...condition, operator: op, value: null });
|
|
7393
|
+
} else {
|
|
7394
|
+
const resetValue = op !== condition.operator ? null : condition.value;
|
|
7395
|
+
onUpdate({ ...condition, operator: op, value: resetValue });
|
|
7771
7396
|
}
|
|
7772
|
-
|
|
7773
|
-
|
|
7774
|
-
|
|
7775
|
-
|
|
7776
|
-
|
|
7777
|
-
|
|
7778
|
-
|
|
7397
|
+
setOperatorOpen(false);
|
|
7398
|
+
};
|
|
7399
|
+
const handleValueChange = (val) => {
|
|
7400
|
+
onUpdate({ ...condition, value: val });
|
|
7401
|
+
};
|
|
7402
|
+
const displayValue = condition.value == null ? "" : typeof condition.value === "string" ? condition.value : String(condition.value);
|
|
7403
|
+
return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "flex items-center gap-base w-full min-w-0", children: [
|
|
7404
|
+
connector === "Where" ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "shrink-0 w-[64px] flex items-center justify-end", children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: "text-xs font-semibold leading-xs text-[var(--color-muted-foreground)]", children: "Where" }) }) : /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
|
|
7405
|
+
"button",
|
|
7406
|
+
{
|
|
7407
|
+
type: "button",
|
|
7408
|
+
onClick: onConnectorToggle,
|
|
7409
|
+
className: cn(
|
|
7410
|
+
"shrink-0 flex items-center justify-center gap-xs",
|
|
7411
|
+
"min-w-[64px] min-h-[24px] max-h-[24px] p-xs",
|
|
7412
|
+
"bg-gradient-to-t from-[var(--color-btn-outlined-neutral-bg-default)] from-[10%] to-[var(--color-btn-outlined-neutral-bg-gradient-to-default)]",
|
|
7413
|
+
"border border-[var(--color-btn-outlined-neutral-border-default)] rounded-base shadow-sm",
|
|
7414
|
+
"cursor-pointer transition-colors text-xs font-semibold leading-xs text-[var(--color-foreground)]",
|
|
7415
|
+
"hover:from-[var(--color-btn-outlined-neutral-bg-hover)] hover:to-[var(--color-btn-outlined-neutral-bg-gradient-to-hover)]"
|
|
7779
7416
|
),
|
|
7780
|
-
|
|
7781
|
-
|
|
7782
|
-
|
|
7783
|
-
|
|
7784
|
-
|
|
7785
|
-
|
|
7786
|
-
|
|
7787
|
-
|
|
7788
|
-
|
|
7789
|
-
|
|
7790
|
-
|
|
7791
|
-
|
|
7792
|
-
|
|
7793
|
-
|
|
7794
|
-
|
|
7795
|
-
|
|
7796
|
-
|
|
7797
|
-
|
|
7798
|
-
|
|
7799
|
-
|
|
7800
|
-
|
|
7801
|
-
|
|
7802
|
-
|
|
7803
|
-
]
|
|
7804
|
-
|
|
7805
|
-
|
|
7806
|
-
|
|
7417
|
+
children: [
|
|
7418
|
+
connector,
|
|
7419
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_icons33.Icon, { icon: import_icons33.faRefreshOutline, size: "xs", className: "text-[var(--color-foreground)]" })
|
|
7420
|
+
]
|
|
7421
|
+
}
|
|
7422
|
+
),
|
|
7423
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(PopoverPrimitive10.Root, { open: propertyOpen, onOpenChange: setPropertyOpen, children: [
|
|
7424
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(PopoverPrimitive10.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("button", { type: "button", className: cn(selectBtnStyle, "min-w-0"), children: [
|
|
7425
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_icons33.Icon, { icon: propertyDef.icon, size: "sm", className: "shrink-0 text-[var(--color-muted-foreground)]" }),
|
|
7426
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("span", { className: "text-sm font-regular leading-sm text-[var(--color-foreground)] whitespace-nowrap truncate", children: [
|
|
7427
|
+
propertyDef.groupLabel,
|
|
7428
|
+
" > ",
|
|
7429
|
+
propertyDef.label
|
|
7430
|
+
] }),
|
|
7431
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_icons33.Icon, { icon: import_icons33.faChevronDownOutline, size: "xs", className: "shrink-0 text-[var(--color-foreground)]" })
|
|
7432
|
+
] }) }),
|
|
7433
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(PopoverPrimitive10.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
7434
|
+
PopoverPrimitive10.Content,
|
|
7435
|
+
{
|
|
7436
|
+
sideOffset: 4,
|
|
7437
|
+
align: "start",
|
|
7438
|
+
className: cn(
|
|
7439
|
+
"z-50 flex flex-col p-xs overflow-clip max-h-[300px] overflow-y-auto",
|
|
7440
|
+
"bg-[var(--color-dropdown-bg)] border border-[var(--color-dropdown-border)] rounded-md shadow-lg",
|
|
7441
|
+
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
7442
|
+
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0",
|
|
7443
|
+
"min-w-[200px]"
|
|
7444
|
+
),
|
|
7445
|
+
children: properties.map((p) => /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
|
|
7446
|
+
"button",
|
|
7447
|
+
{
|
|
7448
|
+
type: "button",
|
|
7449
|
+
onClick: () => {
|
|
7450
|
+
onPropertyChange(p);
|
|
7451
|
+
setPropertyOpen(false);
|
|
7452
|
+
},
|
|
7453
|
+
className: cn(
|
|
7454
|
+
"flex items-center gap-base p-base rounded-base cursor-pointer transition-colors text-left",
|
|
7455
|
+
"hover:bg-[var(--color-dropdown-item-hover)]",
|
|
7456
|
+
p.id === condition.propertyId && "bg-[var(--color-dropdown-item-hover)]"
|
|
7457
|
+
),
|
|
7458
|
+
children: [
|
|
7459
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_icons33.Icon, { icon: p.icon, size: "sm", className: "shrink-0 text-[var(--color-dropdown-item-icon)]" }),
|
|
7460
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: "text-sm font-regular leading-sm text-[var(--color-dropdown-item-text)] truncate", children: p.label })
|
|
7461
|
+
]
|
|
7462
|
+
},
|
|
7463
|
+
p.id
|
|
7464
|
+
))
|
|
7465
|
+
}
|
|
7466
|
+
) })
|
|
7467
|
+
] }),
|
|
7468
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(PopoverPrimitive10.Root, { open: operatorOpen, onOpenChange: setOperatorOpen, children: [
|
|
7469
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(PopoverPrimitive10.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("button", { type: "button", className: cn(selectBtnStyle, "min-w-0"), children: [
|
|
7470
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: "text-sm font-regular leading-sm text-[var(--color-foreground)] whitespace-nowrap truncate text-left", children: condition.operator ?? "Select" }),
|
|
7471
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_icons33.Icon, { icon: import_icons33.faChevronDownOutline, size: "xs", className: "shrink-0 text-[var(--color-foreground)]" })
|
|
7472
|
+
] }) }),
|
|
7473
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(PopoverPrimitive10.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
7474
|
+
PopoverPrimitive10.Content,
|
|
7475
|
+
{
|
|
7476
|
+
sideOffset: 4,
|
|
7477
|
+
align: "start",
|
|
7478
|
+
className: cn(
|
|
7479
|
+
"z-50 flex flex-col p-xs overflow-clip",
|
|
7480
|
+
"bg-[var(--color-dropdown-bg)] border border-[var(--color-dropdown-border)] rounded-md shadow-lg",
|
|
7481
|
+
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
7482
|
+
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0",
|
|
7483
|
+
"min-w-[160px]"
|
|
7484
|
+
),
|
|
7485
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
7486
|
+
OperatorList,
|
|
7487
|
+
{
|
|
7488
|
+
dataType: propertyDef.type,
|
|
7489
|
+
activeOperator: condition.operator,
|
|
7490
|
+
onSelect: handleOperatorSelect
|
|
7491
|
+
}
|
|
7492
|
+
)
|
|
7493
|
+
}
|
|
7494
|
+
) })
|
|
7495
|
+
] }),
|
|
7496
|
+
condition.operator && !isNoValueOperator(condition.operator) && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
7497
|
+
"input",
|
|
7498
|
+
{
|
|
7499
|
+
type: "text",
|
|
7500
|
+
value: displayValue,
|
|
7501
|
+
onChange: (e) => handleValueChange(e.target.value),
|
|
7502
|
+
placeholder: "Placeholder",
|
|
7503
|
+
className: cn(
|
|
7504
|
+
"flex-1 min-w-[80px] px-base py-sm rounded-md",
|
|
7505
|
+
"border border-[var(--color-input)]",
|
|
7506
|
+
"bg-[var(--color-background)] text-sm font-regular leading-sm text-[var(--color-foreground)]",
|
|
7507
|
+
"placeholder:text-[var(--color-muted-foreground)]",
|
|
7508
|
+
"focus:outline-none focus:ring-2 focus:ring-[var(--color-ring)] focus:ring-offset-0"
|
|
7509
|
+
)
|
|
7510
|
+
}
|
|
7511
|
+
),
|
|
7512
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
7513
|
+
"button",
|
|
7514
|
+
{
|
|
7515
|
+
type: "button",
|
|
7516
|
+
onClick: onDelete,
|
|
7517
|
+
className: "ml-auto shrink-0 flex items-center justify-center p-sm rounded-md cursor-pointer transition-colors hover:bg-[var(--color-accent)]",
|
|
7518
|
+
"aria-label": "Remove filter",
|
|
7519
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_icons33.Icon, { icon: import_icons33.faXmarkOutline, size: "sm", className: "text-[var(--color-foreground)]" })
|
|
7520
|
+
}
|
|
7521
|
+
)
|
|
7522
|
+
] });
|
|
7523
|
+
};
|
|
7524
|
+
AdvancedRow.displayName = "AdvancedRow";
|
|
7525
|
+
|
|
7526
|
+
// src/components/ui/filter/advanced-popover.tsx
|
|
7527
|
+
var import_jsx_runtime55 = require("react/jsx-runtime");
|
|
7528
|
+
var outlinedBtn = [
|
|
7529
|
+
"flex items-center gap-sm px-base py-sm",
|
|
7530
|
+
"min-h-[32px] max-h-[32px] min-w-[80px]",
|
|
7531
|
+
"bg-gradient-to-t from-[var(--color-btn-outlined-neutral-bg-default)] from-[10%] to-[var(--color-btn-outlined-neutral-bg-gradient-to-default)]",
|
|
7532
|
+
"border border-[var(--color-btn-outlined-neutral-border-default)] rounded-md shadow-sm",
|
|
7533
|
+
"cursor-pointer transition-colors text-sm font-semibold leading-sm text-[var(--color-foreground)]",
|
|
7534
|
+
"hover:from-[var(--color-btn-outlined-neutral-bg-hover)] hover:to-[var(--color-btn-outlined-neutral-bg-gradient-to-hover)]"
|
|
7535
|
+
];
|
|
7536
|
+
var AdvancedPopover = ({
|
|
7537
|
+
filters,
|
|
7538
|
+
properties,
|
|
7539
|
+
onFiltersChange,
|
|
7540
|
+
open,
|
|
7541
|
+
onOpenChange,
|
|
7542
|
+
children
|
|
7543
|
+
}) => {
|
|
7544
|
+
const [addSelectorOpen, setAddSelectorOpen] = React48.useState(false);
|
|
7545
|
+
const [draftPickerOpen, setDraftPickerOpen] = React48.useState(false);
|
|
7546
|
+
const getPropertyDef = (propertyId) => properties.find((p) => p.id === propertyId);
|
|
7547
|
+
const handleUpdateFilter = (updated) => {
|
|
7548
|
+
onFiltersChange(filters.map((f) => f.id === updated.id ? updated : f));
|
|
7549
|
+
};
|
|
7550
|
+
const handleDeleteFilter = (id) => {
|
|
7551
|
+
onFiltersChange(filters.filter((f) => f.id !== id));
|
|
7552
|
+
};
|
|
7553
|
+
const handlePropertyChange = (filterId, newProp) => {
|
|
7554
|
+
const newCondition = createFilterWithDefaults(newProp.id, newProp.type);
|
|
7555
|
+
onFiltersChange(
|
|
7556
|
+
filters.map((f) => f.id === filterId ? { ...newCondition, id: filterId } : f)
|
|
7557
|
+
);
|
|
7558
|
+
};
|
|
7559
|
+
const handleAddFilter = (property) => {
|
|
7560
|
+
const newFilter = createFilterWithDefaults(property.id, property.type);
|
|
7561
|
+
onFiltersChange([...filters, newFilter]);
|
|
7562
|
+
setAddSelectorOpen(false);
|
|
7563
|
+
};
|
|
7564
|
+
const handleClearAll = () => {
|
|
7565
|
+
onFiltersChange([]);
|
|
7566
|
+
onOpenChange?.(false);
|
|
7567
|
+
};
|
|
7568
|
+
const toggleLogicOp = (filterId) => {
|
|
7569
|
+
onFiltersChange(
|
|
7570
|
+
filters.map(
|
|
7571
|
+
(f) => f.id === filterId ? { ...f, logicOperator: (f.logicOperator ?? "and") === "and" ? "or" : "and" } : f
|
|
7572
|
+
)
|
|
7573
|
+
);
|
|
7574
|
+
};
|
|
7575
|
+
return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(PopoverPrimitive11.Root, { open, onOpenChange, children: [
|
|
7576
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(PopoverPrimitive11.Trigger, { asChild: true, children }),
|
|
7577
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(PopoverPrimitive11.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
|
|
7578
|
+
PopoverPrimitive11.Content,
|
|
7579
|
+
{
|
|
7580
|
+
sideOffset: 4,
|
|
7581
|
+
align: "start",
|
|
7582
|
+
collisionPadding: 16,
|
|
7583
|
+
onOpenAutoFocus: (e) => e.preventDefault(),
|
|
7584
|
+
className: cn(
|
|
7585
|
+
"z-50 flex flex-col",
|
|
7586
|
+
"bg-[var(--color-background)] rounded-md shadow-lg",
|
|
7587
|
+
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
7588
|
+
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
|
7589
|
+
"data-[side=bottom]:slide-in-from-top-2",
|
|
7590
|
+
"w-[min(520px,calc(100vw-32px))]"
|
|
7591
|
+
),
|
|
7592
|
+
children: [
|
|
7593
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "flex flex-col gap-base p-base", children: [
|
|
7594
|
+
filters.map((filter, i) => {
|
|
7595
|
+
const propDef = getPropertyDef(filter.propertyId);
|
|
7596
|
+
if (!propDef) return null;
|
|
7597
|
+
return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
7598
|
+
AdvancedRow,
|
|
7599
|
+
{
|
|
7600
|
+
connector: i === 0 ? "Where" : (filter.logicOperator ?? "and") === "and" ? "And" : "Or",
|
|
7601
|
+
onConnectorToggle: i > 0 ? () => toggleLogicOp(filter.id) : void 0,
|
|
7602
|
+
propertyDef: propDef,
|
|
7603
|
+
condition: filter,
|
|
7604
|
+
properties,
|
|
7605
|
+
onUpdate: handleUpdateFilter,
|
|
7606
|
+
onPropertyChange: (p) => handlePropertyChange(filter.id, p),
|
|
7607
|
+
onDelete: () => handleDeleteFilter(filter.id)
|
|
7608
|
+
},
|
|
7609
|
+
filter.id
|
|
7610
|
+
);
|
|
7611
|
+
}),
|
|
7612
|
+
filters.length === 0 && /* ── Draft row: inline "Select property" placeholder ──── */
|
|
7613
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "flex items-center gap-base w-full min-w-0", children: [
|
|
7614
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "shrink-0 w-[64px] flex items-center justify-end", children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { className: "text-xs font-semibold leading-xs text-[var(--color-muted-foreground)]", children: "Where" }) }),
|
|
7615
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
7616
|
+
PropertySelector,
|
|
7617
|
+
{
|
|
7618
|
+
properties,
|
|
7619
|
+
onSelect: handleAddFilter,
|
|
7620
|
+
open: draftPickerOpen,
|
|
7621
|
+
onOpenChange: setDraftPickerOpen,
|
|
7622
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
|
|
7623
|
+
"button",
|
|
7624
|
+
{
|
|
7625
|
+
type: "button",
|
|
7626
|
+
className: cn(
|
|
7627
|
+
"flex items-center gap-base px-base py-sm min-w-0",
|
|
7628
|
+
"bg-gradient-to-t from-[var(--color-btn-outlined-neutral-bg-default)] to-[var(--color-btn-outlined-neutral-bg-gradient-to-default)]",
|
|
7629
|
+
"border border-[var(--color-btn-outlined-neutral-border-default)] rounded-md shadow-sm",
|
|
7630
|
+
"cursor-pointer transition-colors",
|
|
7631
|
+
"hover:from-[var(--color-btn-outlined-neutral-bg-hover)] hover:to-[var(--color-btn-outlined-neutral-bg-gradient-to-hover)]"
|
|
7632
|
+
),
|
|
7633
|
+
children: [
|
|
7634
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { className: "text-sm font-regular leading-sm text-[var(--color-muted-foreground)] whitespace-nowrap", children: "Select property" }),
|
|
7635
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
7636
|
+
import_icons34.Icon,
|
|
7637
|
+
{
|
|
7638
|
+
icon: import_icons34.faChevronDownOutline,
|
|
7639
|
+
size: "xs",
|
|
7640
|
+
className: "shrink-0 text-[var(--color-foreground)]"
|
|
7641
|
+
}
|
|
7642
|
+
)
|
|
7643
|
+
]
|
|
7644
|
+
}
|
|
7645
|
+
)
|
|
7646
|
+
}
|
|
7647
|
+
)
|
|
7648
|
+
] })
|
|
7649
|
+
] }),
|
|
7650
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "flex items-center justify-between p-base border-t border-[var(--color-border)]", children: [
|
|
7651
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
7652
|
+
PropertySelector,
|
|
7653
|
+
{
|
|
7654
|
+
properties,
|
|
7655
|
+
onSelect: handleAddFilter,
|
|
7656
|
+
open: addSelectorOpen,
|
|
7657
|
+
onOpenChange: setAddSelectorOpen,
|
|
7658
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("button", { type: "button", className: cn(outlinedBtn), children: [
|
|
7659
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_icons34.Icon, { icon: import_icons34.faPlusOutline, size: "sm", className: "text-[var(--color-foreground)]" }),
|
|
7660
|
+
"Add filter"
|
|
7661
|
+
] })
|
|
7662
|
+
}
|
|
7663
|
+
),
|
|
7664
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
7665
|
+
"button",
|
|
7666
|
+
{
|
|
7667
|
+
type: "button",
|
|
7668
|
+
onClick: handleClearAll,
|
|
7669
|
+
className: "text-sm font-semibold leading-sm text-[var(--color-foreground)] cursor-pointer transition-colors hover:opacity-70 px-base py-sm",
|
|
7670
|
+
children: "Clear all filters"
|
|
7671
|
+
}
|
|
7672
|
+
)
|
|
7673
|
+
] })
|
|
7674
|
+
]
|
|
7675
|
+
}
|
|
7676
|
+
) })
|
|
7677
|
+
] });
|
|
7678
|
+
};
|
|
7679
|
+
AdvancedPopover.displayName = "AdvancedPopover";
|
|
7680
|
+
|
|
7681
|
+
// src/components/ui/filter/summary-chip.tsx
|
|
7682
|
+
var React49 = __toESM(require("react"));
|
|
7683
|
+
var PopoverPrimitive12 = __toESM(require("@radix-ui/react-popover"));
|
|
7684
|
+
var import_icons35 = require("@l3mpire/icons");
|
|
7685
|
+
var import_jsx_runtime56 = require("react/jsx-runtime");
|
|
7686
|
+
var SummaryChip = ({
|
|
7687
|
+
count,
|
|
7688
|
+
filters,
|
|
7689
|
+
properties,
|
|
7690
|
+
onFiltersChange,
|
|
7691
|
+
onClearAll,
|
|
7692
|
+
children,
|
|
7693
|
+
className,
|
|
7694
|
+
open: openProp,
|
|
7695
|
+
onOpenChange
|
|
7696
|
+
}) => {
|
|
7697
|
+
const [uncontrolledOpen, setUncontrolledOpen] = React49.useState(false);
|
|
7698
|
+
const isControlled = openProp !== void 0;
|
|
7699
|
+
const open = isControlled ? openProp : uncontrolledOpen;
|
|
7700
|
+
const setOpen = (v) => {
|
|
7701
|
+
if (!isControlled) setUncontrolledOpen(v);
|
|
7702
|
+
onOpenChange?.(v);
|
|
7703
|
+
};
|
|
7704
|
+
const [addSelectorOpen, setAddSelectorOpen] = React49.useState(false);
|
|
7705
|
+
const [draftPickerOpen, setDraftPickerOpen] = React49.useState(false);
|
|
7706
|
+
const getPropertyDef = (propertyId) => properties.find((p) => p.id === propertyId);
|
|
7707
|
+
const handleUpdateFilter = (updated) => {
|
|
7708
|
+
onFiltersChange(filters.map((f) => f.id === updated.id ? updated : f));
|
|
7709
|
+
};
|
|
7710
|
+
const handleDeleteFilter = (id) => {
|
|
7711
|
+
const next = filters.filter((f) => f.id !== id);
|
|
7712
|
+
onFiltersChange(next);
|
|
7713
|
+
if (next.length === 0) setOpen(false);
|
|
7714
|
+
};
|
|
7715
|
+
const handlePropertyChange = (filterId, newProp) => {
|
|
7716
|
+
const newCondition = createFilterWithDefaults(newProp.id, newProp.type);
|
|
7717
|
+
onFiltersChange(
|
|
7718
|
+
filters.map((f) => f.id === filterId ? { ...newCondition, id: filterId } : f)
|
|
7719
|
+
);
|
|
7720
|
+
};
|
|
7721
|
+
const handleAddFilter = (property) => {
|
|
7722
|
+
const newFilter = createFilterWithDefaults(property.id, property.type);
|
|
7723
|
+
onFiltersChange([...filters, newFilter]);
|
|
7724
|
+
setAddSelectorOpen(false);
|
|
7725
|
+
};
|
|
7726
|
+
const toggleLogicOp = (filterId) => {
|
|
7727
|
+
onFiltersChange(
|
|
7728
|
+
filters.map(
|
|
7729
|
+
(f) => f.id === filterId ? { ...f, logicOperator: (f.logicOperator ?? "and") === "and" ? "or" : "and" } : f
|
|
7730
|
+
)
|
|
7731
|
+
);
|
|
7732
|
+
};
|
|
7733
|
+
return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(PopoverPrimitive12.Root, { open, onOpenChange: setOpen, children: [
|
|
7734
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(PopoverPrimitive12.Trigger, { asChild: true, children: children ?? /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
|
|
7735
|
+
"button",
|
|
7736
|
+
{
|
|
7737
|
+
type: "button",
|
|
7738
|
+
className: cn(
|
|
7739
|
+
"inline-flex items-center gap-sm px-base py-sm",
|
|
7740
|
+
"min-h-[32px] max-h-[32px]",
|
|
7741
|
+
"bg-gradient-to-t from-[var(--color-btn-outlined-neutral-bg-default)] from-[10%] to-[var(--color-btn-outlined-neutral-bg-gradient-to-default)]",
|
|
7742
|
+
"border border-[var(--color-btn-outlined-neutral-border-default)] rounded-md shadow-sm",
|
|
7743
|
+
"cursor-pointer transition-colors",
|
|
7744
|
+
"hover:from-[var(--color-btn-outlined-neutral-bg-hover)] hover:to-[var(--color-btn-outlined-neutral-bg-gradient-to-hover)]",
|
|
7745
|
+
className
|
|
7746
|
+
),
|
|
7747
|
+
children: [
|
|
7748
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
7749
|
+
import_icons35.Icon,
|
|
7750
|
+
{
|
|
7751
|
+
icon: import_icons35.faSlidersOutline,
|
|
7752
|
+
size: "sm",
|
|
7753
|
+
className: "shrink-0 text-[var(--color-foreground)]"
|
|
7754
|
+
}
|
|
7755
|
+
),
|
|
7756
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "text-sm font-semibold leading-sm whitespace-nowrap text-[var(--color-foreground)]", children: "Filters" }),
|
|
7757
|
+
count > 0 && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "flex items-center p-2xs rounded-xs bg-filter-chip-badge-bg", children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "text-[10px] font-semibold leading-2xs text-filter-chip-badge-text", children: count }) })
|
|
7758
|
+
]
|
|
7759
|
+
}
|
|
7760
|
+
) }),
|
|
7761
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(PopoverPrimitive12.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
|
|
7762
|
+
PopoverPrimitive12.Content,
|
|
7763
|
+
{
|
|
7764
|
+
sideOffset: 4,
|
|
7765
|
+
align: "start",
|
|
7766
|
+
collisionPadding: 16,
|
|
7767
|
+
onOpenAutoFocus: (e) => e.preventDefault(),
|
|
7768
|
+
className: cn(
|
|
7769
|
+
"z-50 flex flex-col overflow-clip",
|
|
7770
|
+
"bg-[var(--color-dropdown-bg)] border border-[var(--color-dropdown-border)] rounded-md shadow-lg",
|
|
7771
|
+
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
7772
|
+
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
|
7773
|
+
"data-[side=bottom]:slide-in-from-top-2",
|
|
7774
|
+
"w-[min(520px,calc(100vw-32px))]"
|
|
7775
|
+
),
|
|
7776
|
+
children: [
|
|
7777
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex flex-col gap-base p-base", children: [
|
|
7778
|
+
filters.map((filter, i) => {
|
|
7779
|
+
const propDef = getPropertyDef(filter.propertyId);
|
|
7780
|
+
if (!propDef) return null;
|
|
7781
|
+
return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
7782
|
+
AdvancedRow,
|
|
7783
|
+
{
|
|
7784
|
+
connector: i === 0 ? "Where" : (filter.logicOperator ?? "and") === "and" ? "And" : "Or",
|
|
7785
|
+
onConnectorToggle: i > 0 ? () => toggleLogicOp(filter.id) : void 0,
|
|
7786
|
+
propertyDef: propDef,
|
|
7787
|
+
condition: filter,
|
|
7788
|
+
properties,
|
|
7789
|
+
onUpdate: handleUpdateFilter,
|
|
7790
|
+
onPropertyChange: (p) => handlePropertyChange(filter.id, p),
|
|
7791
|
+
onDelete: () => handleDeleteFilter(filter.id)
|
|
7792
|
+
},
|
|
7793
|
+
filter.id
|
|
7794
|
+
);
|
|
7795
|
+
}),
|
|
7796
|
+
filters.length === 0 && /* ── Draft row: inline "Select property" placeholder ──── */
|
|
7797
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex items-center gap-base w-full min-w-0", children: [
|
|
7798
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "shrink-0 w-[64px] flex items-center justify-end", children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "text-xs font-semibold leading-xs text-[var(--color-muted-foreground)]", children: "Where" }) }),
|
|
7799
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
7800
|
+
PropertySelector,
|
|
7801
|
+
{
|
|
7802
|
+
properties,
|
|
7803
|
+
onSelect: handleAddFilter,
|
|
7804
|
+
open: draftPickerOpen,
|
|
7805
|
+
onOpenChange: setDraftPickerOpen,
|
|
7806
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
|
|
7807
|
+
"button",
|
|
7808
|
+
{
|
|
7809
|
+
type: "button",
|
|
7810
|
+
className: cn(
|
|
7811
|
+
"flex items-center gap-base px-base py-sm min-w-0",
|
|
7812
|
+
"bg-gradient-to-t from-[var(--color-btn-outlined-neutral-bg-default)] to-[var(--color-btn-outlined-neutral-bg-gradient-to-default)]",
|
|
7813
|
+
"border border-[var(--color-btn-outlined-neutral-border-default)] rounded-md shadow-sm",
|
|
7814
|
+
"cursor-pointer transition-colors",
|
|
7815
|
+
"hover:from-[var(--color-btn-outlined-neutral-bg-hover)] hover:to-[var(--color-btn-outlined-neutral-bg-gradient-to-hover)]"
|
|
7816
|
+
),
|
|
7817
|
+
children: [
|
|
7818
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "text-sm font-regular leading-sm text-[var(--color-muted-foreground)] whitespace-nowrap", children: "Select property" }),
|
|
7819
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
7820
|
+
import_icons35.Icon,
|
|
7821
|
+
{
|
|
7822
|
+
icon: import_icons35.faChevronDownOutline,
|
|
7823
|
+
size: "xs",
|
|
7824
|
+
className: "shrink-0 text-[var(--color-foreground)]"
|
|
7825
|
+
}
|
|
7826
|
+
)
|
|
7827
|
+
]
|
|
7828
|
+
}
|
|
7829
|
+
)
|
|
7830
|
+
}
|
|
7831
|
+
)
|
|
7832
|
+
] })
|
|
7833
|
+
] }),
|
|
7834
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex items-center justify-between p-base border-t border-[var(--color-border)]", children: [
|
|
7835
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
7836
|
+
PropertySelector,
|
|
7837
|
+
{
|
|
7838
|
+
properties,
|
|
7839
|
+
onSelect: handleAddFilter,
|
|
7840
|
+
open: addSelectorOpen,
|
|
7841
|
+
onOpenChange: setAddSelectorOpen,
|
|
7842
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
|
|
7843
|
+
"button",
|
|
7844
|
+
{
|
|
7845
|
+
type: "button",
|
|
7846
|
+
className: cn(
|
|
7847
|
+
"flex items-center gap-sm px-base py-sm",
|
|
7848
|
+
"min-h-[32px] max-h-[32px] min-w-[80px]",
|
|
7849
|
+
"bg-gradient-to-t from-[var(--color-btn-outlined-neutral-bg-default)] from-[10%] to-[var(--color-btn-outlined-neutral-bg-gradient-to-default)]",
|
|
7850
|
+
"border border-[var(--color-btn-outlined-neutral-border-default)] rounded-md shadow-sm",
|
|
7851
|
+
"cursor-pointer transition-colors text-sm font-semibold leading-sm text-[var(--color-foreground)]",
|
|
7852
|
+
"hover:from-[var(--color-btn-outlined-neutral-bg-hover)] hover:to-[var(--color-btn-outlined-neutral-bg-gradient-to-hover)]"
|
|
7853
|
+
),
|
|
7854
|
+
children: [
|
|
7855
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_icons35.Icon, { icon: import_icons35.faPlusOutline, size: "sm", className: "text-[var(--color-foreground)]" }),
|
|
7856
|
+
"Add filter"
|
|
7857
|
+
]
|
|
7858
|
+
}
|
|
7859
|
+
)
|
|
7860
|
+
}
|
|
7861
|
+
),
|
|
7862
|
+
filters.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
7863
|
+
"button",
|
|
7864
|
+
{
|
|
7865
|
+
type: "button",
|
|
7866
|
+
onClick: () => {
|
|
7867
|
+
onClearAll();
|
|
7868
|
+
setOpen(false);
|
|
7869
|
+
},
|
|
7870
|
+
className: "text-sm font-semibold leading-sm text-[var(--color-foreground)] cursor-pointer transition-colors hover:opacity-70 px-base py-sm",
|
|
7871
|
+
children: "Clear all filters"
|
|
7872
|
+
}
|
|
7873
|
+
)
|
|
7874
|
+
] })
|
|
7875
|
+
]
|
|
7876
|
+
}
|
|
7877
|
+
) })
|
|
7878
|
+
] });
|
|
7879
|
+
};
|
|
7880
|
+
SummaryChip.displayName = "SummaryChip";
|
|
7881
|
+
|
|
7882
|
+
// src/components/ui/filter/use-filter-bar-mode.ts
|
|
7883
|
+
var React50 = __toESM(require("react"));
|
|
7884
|
+
var DEFAULT_BREAKPOINT = 600;
|
|
7885
|
+
function useFilterBarMode(ref, override, breakpoint = DEFAULT_BREAKPOINT) {
|
|
7886
|
+
const [mode, setMode] = React50.useState("default");
|
|
7887
|
+
React50.useEffect(() => {
|
|
7888
|
+
if (override) return;
|
|
7889
|
+
const el = ref.current;
|
|
7890
|
+
if (!el) return;
|
|
7891
|
+
const observer = new ResizeObserver((entries) => {
|
|
7892
|
+
const width = entries[0]?.contentRect.width ?? 0;
|
|
7893
|
+
setMode(width > breakpoint ? "default" : "minimal");
|
|
7894
|
+
});
|
|
7895
|
+
observer.observe(el);
|
|
7896
|
+
return () => observer.disconnect();
|
|
7897
|
+
}, [ref, override, breakpoint]);
|
|
7898
|
+
return override ?? mode;
|
|
7899
|
+
}
|
|
7900
|
+
|
|
7901
|
+
// src/components/ui/filter/filter-system.tsx
|
|
7902
|
+
var import_jsx_runtime57 = require("react/jsx-runtime");
|
|
7903
|
+
var FilterSystem = ({
|
|
7904
|
+
properties,
|
|
7905
|
+
filterState,
|
|
7906
|
+
onFilterStateChange,
|
|
7907
|
+
sortFields,
|
|
7908
|
+
mode: modeOverride,
|
|
7909
|
+
breakpoint,
|
|
7910
|
+
children,
|
|
7911
|
+
actions,
|
|
7912
|
+
className
|
|
7913
|
+
}) => {
|
|
7914
|
+
const containerRef = React51.useRef(null);
|
|
7915
|
+
const mode = useFilterBarMode(containerRef, modeOverride, breakpoint);
|
|
7916
|
+
const [propertySelectorOpen, setPropertySelectorOpen] = React51.useState(false);
|
|
7917
|
+
const [advancedOpen, setAdvancedOpen] = React51.useState(false);
|
|
7918
|
+
const [summaryOpen, setSummaryOpen] = React51.useState(false);
|
|
7919
|
+
const [pendingFilterId, setPendingFilterId] = React51.useState(null);
|
|
7920
|
+
const allFilters = [...filterState.basicFilters, ...filterState.advancedFilters];
|
|
7921
|
+
const totalCount = allFilters.length;
|
|
7922
|
+
const handleAddFilter = (property) => {
|
|
7923
|
+
const newFilter = createFilterWithDefaults(property.id, property.type);
|
|
7924
|
+
if (newFilter.operator && isNoValueOperator(newFilter.operator)) {
|
|
7925
|
+
onFilterStateChange({
|
|
7926
|
+
...filterState,
|
|
7927
|
+
basicFilters: [...filterState.basicFilters, newFilter]
|
|
7928
|
+
});
|
|
7929
|
+
return;
|
|
7930
|
+
}
|
|
7931
|
+
setPendingFilterId(newFilter.id);
|
|
7932
|
+
onFilterStateChange({
|
|
7933
|
+
...filterState,
|
|
7934
|
+
basicFilters: [...filterState.basicFilters, newFilter]
|
|
7935
|
+
});
|
|
7936
|
+
};
|
|
7937
|
+
const handleUpdateFilter = (updated) => {
|
|
7938
|
+
onFilterStateChange({
|
|
7939
|
+
...filterState,
|
|
7940
|
+
basicFilters: filterState.basicFilters.map(
|
|
7941
|
+
(f) => f.id === updated.id ? updated : f
|
|
7942
|
+
)
|
|
7943
|
+
});
|
|
7944
|
+
if (pendingFilterId === updated.id) {
|
|
7945
|
+
setPendingFilterId(null);
|
|
7946
|
+
}
|
|
7947
|
+
};
|
|
7948
|
+
const handleDeleteFilter = (id) => {
|
|
7949
|
+
onFilterStateChange({
|
|
7950
|
+
...filterState,
|
|
7951
|
+
basicFilters: filterState.basicFilters.filter((f) => f.id !== id)
|
|
7952
|
+
});
|
|
7953
|
+
};
|
|
7954
|
+
const handlePropertyChange = (filterId, newProp) => {
|
|
7955
|
+
const newCondition = createFilterWithDefaults(newProp.id, newProp.type);
|
|
7956
|
+
onFilterStateChange({
|
|
7957
|
+
...filterState,
|
|
7958
|
+
basicFilters: filterState.basicFilters.map(
|
|
7959
|
+
(f) => f.id === filterId ? { ...newCondition, id: filterId } : f
|
|
7960
|
+
)
|
|
7961
|
+
});
|
|
7962
|
+
if (newCondition.operator && !isNoValueOperator(newCondition.operator)) {
|
|
7963
|
+
setPendingFilterId(filterId);
|
|
7964
|
+
}
|
|
7965
|
+
};
|
|
7966
|
+
const handleConvertToAdvanced = (id) => {
|
|
7967
|
+
const filter = filterState.basicFilters.find((f) => f.id === id);
|
|
7968
|
+
if (!filter) return;
|
|
7969
|
+
onFilterStateChange({
|
|
7970
|
+
...filterState,
|
|
7971
|
+
basicFilters: filterState.basicFilters.filter((f) => f.id !== id),
|
|
7972
|
+
advancedFilters: [...filterState.advancedFilters, filter]
|
|
7973
|
+
});
|
|
7974
|
+
};
|
|
7975
|
+
const handleAdvancedFiltersChange = (filters) => {
|
|
7976
|
+
onFilterStateChange({ ...filterState, advancedFilters: filters });
|
|
7977
|
+
};
|
|
7978
|
+
const handleClearAdvanced = () => {
|
|
7979
|
+
onFilterStateChange({ ...filterState, advancedFilters: [] });
|
|
7980
|
+
};
|
|
7981
|
+
const handleClearAll = () => {
|
|
7982
|
+
onFilterStateChange({
|
|
7983
|
+
...filterState,
|
|
7984
|
+
basicFilters: [],
|
|
7985
|
+
advancedFilters: []
|
|
7986
|
+
});
|
|
7987
|
+
};
|
|
7988
|
+
const handleSortChange = (field, direction) => {
|
|
7989
|
+
onFilterStateChange({ ...filterState, sort: { field, direction } });
|
|
7990
|
+
};
|
|
7991
|
+
const getPropertyDef = (propertyId) => properties.find((p) => p.id === propertyId);
|
|
7992
|
+
const hasAdvanced = filterState.advancedFilters.length > 0;
|
|
7993
|
+
const isMinimal = mode === "minimal";
|
|
7994
|
+
const handleOpenAdvanced = () => {
|
|
7995
|
+
setPropertySelectorOpen(false);
|
|
7996
|
+
requestAnimationFrame(() => {
|
|
7997
|
+
if (isMinimal) {
|
|
7998
|
+
setSummaryOpen(true);
|
|
7999
|
+
} else {
|
|
8000
|
+
setAdvancedOpen(true);
|
|
8001
|
+
}
|
|
8002
|
+
});
|
|
8003
|
+
};
|
|
8004
|
+
const advancedFilterCount = filterState.advancedFilters.length;
|
|
8005
|
+
const showAdvancedChip = hasAdvanced || advancedOpen;
|
|
8006
|
+
const showSummaryChip = totalCount > 0 || summaryOpen;
|
|
8007
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(FilterBar, { ref: containerRef, className, children: [
|
|
8008
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(FilterBarLeft, { className: "flex-nowrap flex-1 min-w-0 overflow-x-auto scrollbar-none outline-none [&>*]:shrink-0", children: [
|
|
8009
|
+
children,
|
|
8010
|
+
sortFields && filterState.sort && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
8011
|
+
SortButton,
|
|
8012
|
+
{
|
|
8013
|
+
fields: sortFields,
|
|
8014
|
+
activeField: filterState.sort.field,
|
|
8015
|
+
direction: filterState.sort.direction,
|
|
8016
|
+
onChange: handleSortChange,
|
|
8017
|
+
iconOnly: isMinimal
|
|
8018
|
+
}
|
|
8019
|
+
),
|
|
8020
|
+
isMinimal ? /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(import_jsx_runtime57.Fragment, { children: [
|
|
8021
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
8022
|
+
"div",
|
|
8023
|
+
{
|
|
8024
|
+
className: showSummaryChip ? "inline-flex" : "inline-flex w-0 overflow-hidden opacity-0 pointer-events-none",
|
|
8025
|
+
"aria-hidden": !showSummaryChip || void 0,
|
|
8026
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
8027
|
+
SummaryChip,
|
|
8028
|
+
{
|
|
8029
|
+
count: totalCount,
|
|
8030
|
+
filters: allFilters,
|
|
8031
|
+
properties,
|
|
8032
|
+
onFiltersChange: (filters) => {
|
|
8033
|
+
onFilterStateChange({
|
|
8034
|
+
...filterState,
|
|
8035
|
+
basicFilters: filters,
|
|
8036
|
+
advancedFilters: []
|
|
8037
|
+
});
|
|
8038
|
+
},
|
|
8039
|
+
onClearAll: handleClearAll,
|
|
8040
|
+
open: summaryOpen,
|
|
8041
|
+
onOpenChange: setSummaryOpen
|
|
8042
|
+
}
|
|
8043
|
+
)
|
|
8044
|
+
}
|
|
8045
|
+
),
|
|
8046
|
+
!showSummaryChip && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
8047
|
+
PropertySelector,
|
|
8048
|
+
{
|
|
8049
|
+
properties,
|
|
8050
|
+
onSelect: handleAddFilter,
|
|
8051
|
+
open: propertySelectorOpen,
|
|
8052
|
+
onOpenChange: setPropertySelectorOpen,
|
|
8053
|
+
onAdvancedFilter: handleOpenAdvanced,
|
|
8054
|
+
advancedFilterCount,
|
|
8055
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(FilterBarButton, { iconOnly: true })
|
|
8056
|
+
}
|
|
8057
|
+
)
|
|
8058
|
+
] }) : (
|
|
8059
|
+
/* ── DEFAULT MODE ────────────────────────────────────── */
|
|
8060
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(import_jsx_runtime57.Fragment, { children: [
|
|
8061
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
8062
|
+
AdvancedPopover,
|
|
8063
|
+
{
|
|
8064
|
+
filters: filterState.advancedFilters,
|
|
8065
|
+
properties,
|
|
8066
|
+
onFiltersChange: handleAdvancedFiltersChange,
|
|
8067
|
+
open: advancedOpen,
|
|
8068
|
+
onOpenChange: setAdvancedOpen,
|
|
8069
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
8070
|
+
"div",
|
|
7807
8071
|
{
|
|
7808
|
-
|
|
7809
|
-
|
|
7810
|
-
|
|
7811
|
-
|
|
7812
|
-
|
|
8072
|
+
className: showAdvancedChip ? "inline-flex" : "inline-flex w-0 overflow-hidden opacity-0 pointer-events-none",
|
|
8073
|
+
"aria-hidden": !showAdvancedChip || void 0,
|
|
8074
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
8075
|
+
AdvancedChip,
|
|
8076
|
+
{
|
|
8077
|
+
count: filterState.advancedFilters.length,
|
|
8078
|
+
onClick: () => setAdvancedOpen(true),
|
|
8079
|
+
onClear: handleClearAdvanced
|
|
8080
|
+
}
|
|
8081
|
+
)
|
|
7813
8082
|
}
|
|
7814
|
-
)
|
|
7815
|
-
|
|
8083
|
+
)
|
|
8084
|
+
}
|
|
8085
|
+
),
|
|
8086
|
+
filterState.basicFilters.map((filter) => {
|
|
8087
|
+
const propDef = getPropertyDef(filter.propertyId);
|
|
8088
|
+
if (!propDef) return null;
|
|
8089
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
8090
|
+
InteractiveFilterChip,
|
|
8091
|
+
{
|
|
8092
|
+
propertyDef: propDef,
|
|
8093
|
+
condition: filter,
|
|
8094
|
+
properties,
|
|
8095
|
+
mode: pendingFilterId === filter.id ? "add" : "edit",
|
|
8096
|
+
autoOpen: pendingFilterId === filter.id,
|
|
8097
|
+
onUpdate: handleUpdateFilter,
|
|
8098
|
+
onPropertyChange: (newProp) => handlePropertyChange(filter.id, newProp),
|
|
8099
|
+
onDelete: () => handleDeleteFilter(filter.id),
|
|
8100
|
+
onConvertToAdvanced: () => handleConvertToAdvanced(filter.id)
|
|
8101
|
+
},
|
|
8102
|
+
filter.id
|
|
8103
|
+
);
|
|
8104
|
+
}),
|
|
8105
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
8106
|
+
PropertySelector,
|
|
8107
|
+
{
|
|
8108
|
+
properties,
|
|
8109
|
+
onSelect: handleAddFilter,
|
|
8110
|
+
open: propertySelectorOpen,
|
|
8111
|
+
onOpenChange: setPropertySelectorOpen,
|
|
8112
|
+
onAdvancedFilter: handleOpenAdvanced,
|
|
8113
|
+
advancedFilterCount,
|
|
8114
|
+
children: totalCount > 0 ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
7816
8115
|
"button",
|
|
7817
8116
|
{
|
|
7818
8117
|
type: "button",
|
|
7819
|
-
|
|
7820
|
-
|
|
7821
|
-
"aria-label": "Next month",
|
|
7822
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_icons35.Icon, { icon: import_icons35.faChevronRightOutline, size: "xs", className: "text-datepicker-header-nav" })
|
|
8118
|
+
className: "shrink-0 inline-flex items-center justify-center size-8 rounded-md border border-[var(--color-btn-outlined-neutral-border-default)] bg-gradient-to-t from-[var(--color-btn-outlined-neutral-bg-default)] from-[10%] to-[var(--color-btn-outlined-neutral-bg-gradient-to-default)] shadow-sm cursor-pointer transition-colors hover:from-[var(--color-btn-outlined-neutral-bg-hover)] hover:to-[var(--color-btn-outlined-neutral-bg-gradient-to-hover)]",
|
|
8119
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_icons36.Icon, { icon: import_icons36.faPlusOutline, size: "sm", className: "text-[var(--color-foreground)]" })
|
|
7823
8120
|
}
|
|
7824
|
-
)
|
|
7825
|
-
|
|
7826
|
-
|
|
7827
|
-
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "flex flex-col", children: [
|
|
7828
|
-
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "grid grid-cols-7 gap-base py-sm", children: WEEKDAYS.map((day) => /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
7829
|
-
"span",
|
|
7830
|
-
{
|
|
7831
|
-
className: "w-9 text-center text-xs font-regular leading-xs text-datepicker-header-weekday",
|
|
7832
|
-
children: day
|
|
7833
|
-
},
|
|
7834
|
-
day
|
|
7835
|
-
)) }),
|
|
7836
|
-
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "flex flex-col", children: weeks.map((week, wi) => /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "grid grid-cols-7 gap-base", children: week.map((day, di) => /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
7837
|
-
DatePickerDay,
|
|
7838
|
-
{
|
|
7839
|
-
date: day.date,
|
|
7840
|
-
isOutside: day.isOutside
|
|
7841
|
-
},
|
|
7842
|
-
di
|
|
7843
|
-
)) }, wi)) })
|
|
7844
|
-
] })
|
|
8121
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(FilterBarButton, {})
|
|
8122
|
+
}
|
|
8123
|
+
)
|
|
7845
8124
|
] })
|
|
7846
|
-
]
|
|
7847
|
-
}
|
|
7848
|
-
);
|
|
7849
|
-
});
|
|
7850
|
-
DatePickerCalendar.displayName = "DatePickerCalendar";
|
|
7851
|
-
var DatePickerSuggestions = React50.forwardRef(
|
|
7852
|
-
({ className, suggestions, formatDate = defaultFormatDate, ...props }, ref) => {
|
|
7853
|
-
const { onSelect, mode } = useDatePickerContext();
|
|
7854
|
-
const onValueChange = React50.useContext(DatePickerContext) ? void 0 : void 0;
|
|
7855
|
-
const ctx = useDatePickerContext();
|
|
7856
|
-
const handleClick = (suggestion) => {
|
|
7857
|
-
const val = suggestion.getValue();
|
|
7858
|
-
if (val instanceof Date) {
|
|
7859
|
-
ctx.onSelect(val);
|
|
7860
|
-
} else {
|
|
7861
|
-
ctx.onSelect(val.from);
|
|
7862
|
-
if (val.to) {
|
|
7863
|
-
setTimeout(() => ctx.onSelect(val.to), 0);
|
|
7864
|
-
}
|
|
7865
|
-
}
|
|
7866
|
-
};
|
|
7867
|
-
const formatSuggestionDate = (suggestion) => {
|
|
7868
|
-
const val = suggestion.getValue();
|
|
7869
|
-
if (val instanceof Date) {
|
|
7870
|
-
return formatDate(val);
|
|
7871
|
-
}
|
|
7872
|
-
const from = formatDate(val.from);
|
|
7873
|
-
const to = val.to ? formatDate(val.to) : "";
|
|
7874
|
-
return to ? `${from} - ${to}` : from;
|
|
7875
|
-
};
|
|
7876
|
-
return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(
|
|
7877
|
-
"div",
|
|
7878
|
-
{
|
|
7879
|
-
ref,
|
|
7880
|
-
className: cn(
|
|
7881
|
-
"flex flex-col border-l border-datepicker-border self-stretch shrink-0",
|
|
7882
|
-
className
|
|
7883
|
-
),
|
|
7884
|
-
...props,
|
|
7885
|
-
children: [
|
|
7886
|
-
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "pt-lg px-base", children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "flex items-center p-base rounded-base", children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "flex-1 text-xs font-semibold leading-xs text-datepicker-suggestion-heading uppercase truncate", children: "Suggestions" }) }) }),
|
|
7887
|
-
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "flex flex-1 flex-col p-base min-w-[222px]", children: suggestions.map((suggestion, i) => /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(
|
|
7888
|
-
"button",
|
|
7889
|
-
{
|
|
7890
|
-
type: "button",
|
|
7891
|
-
onClick: () => handleClick(suggestion),
|
|
7892
|
-
className: "flex items-center gap-sm p-base rounded-base hover:bg-datepicker-suggestion-hover transition-colors cursor-pointer text-left",
|
|
7893
|
-
children: [
|
|
7894
|
-
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "text-sm font-regular leading-sm text-datepicker-suggestion-text truncate shrink-0", children: suggestion.label }),
|
|
7895
|
-
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "text-xs font-regular leading-xs text-datepicker-suggestion-date truncate", children: formatSuggestionDate(suggestion) })
|
|
7896
|
-
]
|
|
7897
|
-
},
|
|
7898
|
-
i
|
|
7899
|
-
)) })
|
|
7900
|
-
]
|
|
7901
|
-
}
|
|
7902
|
-
);
|
|
7903
|
-
}
|
|
7904
|
-
);
|
|
7905
|
-
DatePickerSuggestions.displayName = "DatePickerSuggestions";
|
|
7906
|
-
var DatePickerFooter = React50.forwardRef(
|
|
7907
|
-
({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
7908
|
-
"div",
|
|
7909
|
-
{
|
|
7910
|
-
ref,
|
|
7911
|
-
className: cn(
|
|
7912
|
-
"flex items-center justify-between p-lg",
|
|
7913
|
-
"border-t border-datepicker-footer-border",
|
|
7914
|
-
"bg-datepicker-bg",
|
|
7915
|
-
className
|
|
7916
8125
|
),
|
|
7917
|
-
|
|
7918
|
-
|
|
7919
|
-
|
|
7920
|
-
|
|
7921
|
-
|
|
7922
|
-
|
|
7923
|
-
var
|
|
7924
|
-
|
|
7925
|
-
|
|
7926
|
-
|
|
7927
|
-
|
|
7928
|
-
|
|
7929
|
-
|
|
7930
|
-
|
|
7931
|
-
}
|
|
7932
|
-
)
|
|
7933
|
-
);
|
|
7934
|
-
DatePickerPanel.displayName = "DatePickerPanel";
|
|
7935
|
-
var DatePickerRoot = PopoverPrimitive12.Root;
|
|
7936
|
-
var DatePickerTrigger = PopoverPrimitive12.Trigger;
|
|
7937
|
-
var DatePickerPopover = React50.forwardRef(({ className, sideOffset = 4, align = "start", children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(PopoverPrimitive12.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
7938
|
-
PopoverPrimitive12.Content,
|
|
7939
|
-
{
|
|
7940
|
-
ref,
|
|
7941
|
-
sideOffset,
|
|
7942
|
-
align,
|
|
7943
|
-
className: cn(
|
|
7944
|
-
"z-50",
|
|
7945
|
-
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
7946
|
-
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
|
7947
|
-
"data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2",
|
|
7948
|
-
className
|
|
7949
|
-
),
|
|
7950
|
-
...props,
|
|
7951
|
-
children
|
|
7952
|
-
}
|
|
7953
|
-
) }));
|
|
7954
|
-
DatePickerPopover.displayName = "DatePickerPopover";
|
|
7955
|
-
function getDefaultSuggestions(referenceDate) {
|
|
7956
|
-
const now = referenceDate ?? /* @__PURE__ */ new Date();
|
|
7957
|
-
const today = startOfDay(now);
|
|
7958
|
-
const dayOfWeek = getWeekdayIndex(today);
|
|
7959
|
-
const startOfThisWeek = new Date(today);
|
|
7960
|
-
startOfThisWeek.setDate(today.getDate() - dayOfWeek);
|
|
7961
|
-
const endOfThisWeek = new Date(startOfThisWeek);
|
|
7962
|
-
endOfThisWeek.setDate(startOfThisWeek.getDate() + 6);
|
|
7963
|
-
const startOfThisMonth = new Date(today.getFullYear(), today.getMonth(), 1);
|
|
7964
|
-
const endOfThisMonth = new Date(
|
|
7965
|
-
today.getFullYear(),
|
|
7966
|
-
today.getMonth() + 1,
|
|
7967
|
-
0
|
|
7968
|
-
);
|
|
7969
|
-
const startOfThisYear = new Date(today.getFullYear(), 0, 1);
|
|
7970
|
-
const endOfThisYear = new Date(today.getFullYear(), 11, 31);
|
|
7971
|
-
const startOfLastWeek = new Date(startOfThisWeek);
|
|
7972
|
-
startOfLastWeek.setDate(startOfThisWeek.getDate() - 7);
|
|
7973
|
-
const endOfLastWeek = new Date(startOfThisWeek);
|
|
7974
|
-
endOfLastWeek.setDate(startOfThisWeek.getDate() - 1);
|
|
7975
|
-
const startOfLastMonth = new Date(
|
|
7976
|
-
today.getFullYear(),
|
|
7977
|
-
today.getMonth() - 1,
|
|
7978
|
-
1
|
|
7979
|
-
);
|
|
7980
|
-
const endOfLastMonth = new Date(today.getFullYear(), today.getMonth(), 0);
|
|
7981
|
-
const startOfLastYear = new Date(today.getFullYear() - 1, 0, 1);
|
|
7982
|
-
const endOfLastYear = new Date(today.getFullYear() - 1, 11, 31);
|
|
7983
|
-
return [
|
|
7984
|
-
{ label: "Today", getValue: () => today },
|
|
7985
|
-
{
|
|
7986
|
-
label: "This week",
|
|
7987
|
-
getValue: () => ({ from: startOfThisWeek, to: endOfThisWeek })
|
|
7988
|
-
},
|
|
7989
|
-
{
|
|
7990
|
-
label: "This month",
|
|
7991
|
-
getValue: () => ({ from: startOfThisMonth, to: endOfThisMonth })
|
|
7992
|
-
},
|
|
7993
|
-
{
|
|
7994
|
-
label: "This year",
|
|
7995
|
-
getValue: () => ({ from: startOfThisYear, to: endOfThisYear })
|
|
7996
|
-
},
|
|
7997
|
-
{
|
|
7998
|
-
label: "Last week",
|
|
7999
|
-
getValue: () => ({ from: startOfLastWeek, to: endOfLastWeek })
|
|
8000
|
-
},
|
|
8001
|
-
{
|
|
8002
|
-
label: "Last month",
|
|
8003
|
-
getValue: () => ({ from: startOfLastMonth, to: endOfLastMonth })
|
|
8004
|
-
},
|
|
8005
|
-
{
|
|
8006
|
-
label: "Last year",
|
|
8007
|
-
getValue: () => ({ from: startOfLastYear, to: endOfLastYear })
|
|
8008
|
-
}
|
|
8009
|
-
];
|
|
8010
|
-
}
|
|
8126
|
+
totalCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
8127
|
+
"button",
|
|
8128
|
+
{
|
|
8129
|
+
type: "button",
|
|
8130
|
+
onClick: handleClearAll,
|
|
8131
|
+
className: "shrink-0 flex items-center gap-sm px-base py-sm min-h-[32px] max-h-[32px] rounded-md cursor-pointer transition-colors hover:bg-[var(--color-accent)]",
|
|
8132
|
+
children: isMinimal ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_icons36.Icon, { icon: import_icons36.faXmarkOutline, size: "sm", className: "text-[var(--color-foreground)]" }) : /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "text-sm font-semibold leading-sm text-[var(--color-foreground)]", children: "Clear" })
|
|
8133
|
+
}
|
|
8134
|
+
)
|
|
8135
|
+
] }),
|
|
8136
|
+
actions && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(FilterBarRight, { className: "shrink-0 -ml-2xl pl-2xl relative z-10 bg-[linear-gradient(to_right,transparent_0px,var(--filter-bar-bg,var(--color-background,#fff))_24px)]", children: actions })
|
|
8137
|
+
] });
|
|
8138
|
+
};
|
|
8139
|
+
FilterSystem.displayName = "FilterSystem";
|
|
8011
8140
|
// Annotate the CommonJS export names for ESM import in node:
|
|
8012
8141
|
0 && (module.exports = {
|
|
8013
8142
|
AdvancedChip,
|