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