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