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