@l3mpire/ui 2.6.0 → 2.7.1
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 +127 -0
- package/dist/index.d.mts +319 -1
- package/dist/index.d.ts +319 -1
- package/dist/index.js +2637 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2610 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -5
- package/src/styles/globals.css +33 -0
package/dist/index.js
CHANGED
|
@@ -30,6 +30,9 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
+
AdvancedChip: () => AdvancedChip,
|
|
34
|
+
AdvancedPopover: () => AdvancedPopover,
|
|
35
|
+
AdvancedRow: () => AdvancedRow,
|
|
33
36
|
Avatar: () => Avatar,
|
|
34
37
|
AvatarCell: () => AvatarCell,
|
|
35
38
|
Badge: () => Badge,
|
|
@@ -39,9 +42,19 @@ __export(index_exports, {
|
|
|
39
42
|
ButtonCell: () => ButtonCell,
|
|
40
43
|
Checkbox: () => Checkbox,
|
|
41
44
|
ChipInput: () => ChipInput,
|
|
45
|
+
DEFAULT_OPERATOR_BY_TYPE: () => DEFAULT_OPERATOR_BY_TYPE,
|
|
42
46
|
DataTable: () => DataTable,
|
|
43
47
|
DataTablePagination: () => DataTablePagination,
|
|
44
48
|
DateCell: () => DateCell,
|
|
49
|
+
DatePicker: () => DatePicker,
|
|
50
|
+
DatePickerCalendar: () => DatePickerCalendar,
|
|
51
|
+
DatePickerFooter: () => DatePickerFooter,
|
|
52
|
+
DatePickerPanel: () => DatePickerPanel,
|
|
53
|
+
DatePickerPopover: () => DatePickerPopover,
|
|
54
|
+
DatePickerRoot: () => DatePickerRoot,
|
|
55
|
+
DatePickerSelects: () => DatePickerSelects,
|
|
56
|
+
DatePickerSuggestions: () => DatePickerSuggestions,
|
|
57
|
+
DatePickerTrigger: () => DatePickerTrigger,
|
|
45
58
|
Dialog: () => Dialog,
|
|
46
59
|
DropdownMenu: () => DropdownMenu,
|
|
47
60
|
DropdownMenuClear: () => DropdownMenuClear,
|
|
@@ -55,8 +68,18 @@ __export(index_exports, {
|
|
|
55
68
|
EditableCell: () => EditableCell,
|
|
56
69
|
EmailCell: () => EmailCell,
|
|
57
70
|
EmptyState: () => EmptyState,
|
|
71
|
+
FilterBar: () => FilterBar,
|
|
72
|
+
FilterBarButton: () => FilterBarButton,
|
|
73
|
+
FilterBarLeft: () => FilterBarLeft,
|
|
74
|
+
FilterBarRight: () => FilterBarRight,
|
|
75
|
+
FilterChip: () => FilterChip,
|
|
76
|
+
FilterChipSegment: () => FilterChipSegment,
|
|
77
|
+
FilterEditor: () => FilterEditor,
|
|
78
|
+
FilterSystem: () => FilterSystem,
|
|
58
79
|
InfoMessage: () => InfoMessage,
|
|
59
80
|
InputLabel: () => InputLabel,
|
|
81
|
+
InteractiveFilterChip: () => InteractiveFilterChip,
|
|
82
|
+
KebabMenu: () => KebabMenu,
|
|
60
83
|
Link: () => Link,
|
|
61
84
|
LinkCell: () => LinkCell,
|
|
62
85
|
Modal: () => Modal,
|
|
@@ -71,8 +94,13 @@ __export(index_exports, {
|
|
|
71
94
|
ModalTrigger: () => ModalTrigger,
|
|
72
95
|
NumberCell: () => NumberCell,
|
|
73
96
|
NumberInput: () => NumberInput,
|
|
97
|
+
OPERATORS_BY_TYPE: () => OPERATORS_BY_TYPE,
|
|
98
|
+
OperatorList: () => OperatorList,
|
|
99
|
+
OperatorSelector: () => OperatorSelector,
|
|
74
100
|
ProductLogo: () => ProductLogo,
|
|
101
|
+
PropertySelector: () => PropertySelector,
|
|
75
102
|
RowActions: () => RowActions,
|
|
103
|
+
SaveViewButton: () => SaveViewButton,
|
|
76
104
|
SearchBar: () => SearchBar,
|
|
77
105
|
Select: () => Select,
|
|
78
106
|
SidePanel: () => SidePanel,
|
|
@@ -85,6 +113,7 @@ __export(index_exports, {
|
|
|
85
113
|
SidebarHeadingItem: () => SidebarHeadingItem,
|
|
86
114
|
SidebarItem: () => SidebarItem,
|
|
87
115
|
SidebarSection: () => SidebarSection,
|
|
116
|
+
SortButton: () => SortButton,
|
|
88
117
|
StatusCell: () => StatusCell,
|
|
89
118
|
Switch: () => Switch,
|
|
90
119
|
TabContent: () => TabContent,
|
|
@@ -114,14 +143,21 @@ __export(index_exports, {
|
|
|
114
143
|
UserMenu: () => UserMenu,
|
|
115
144
|
UserMenuInfoRow: () => UserMenuInfoRow,
|
|
116
145
|
UserMenuSection: () => UserMenuSection,
|
|
146
|
+
ValueInput: () => ValueInput,
|
|
117
147
|
avatarVariants: () => avatarVariants,
|
|
118
148
|
badgeVariants: () => badgeVariants,
|
|
119
149
|
buttonVariants: () => buttonVariants,
|
|
120
150
|
chipInputVariants: () => chipInputVariants,
|
|
121
151
|
cn: () => cn,
|
|
152
|
+
createFilterWithDefaults: () => createFilterWithDefaults,
|
|
122
153
|
emptyStateVariants: () => emptyStateVariants,
|
|
154
|
+
filterChipSegmentVariants: () => filterChipSegmentVariants,
|
|
123
155
|
flexRender: () => import_react_table.flexRender,
|
|
156
|
+
getDefaultOperator: () => getDefaultOperator,
|
|
157
|
+
getDefaultSuggestions: () => getDefaultSuggestions,
|
|
158
|
+
getValueInputType: () => getValueInputType,
|
|
124
159
|
infoMessageVariants: () => infoMessageVariants,
|
|
160
|
+
isNoValueOperator: () => isNoValueOperator,
|
|
125
161
|
linkVariants: () => linkVariants,
|
|
126
162
|
modalVariants: () => modalVariants,
|
|
127
163
|
productLogoVariants: () => productLogoVariants,
|
|
@@ -4799,8 +4835,2576 @@ var SidePanelContent = React33.forwardRef(({ className, overlay = true, children
|
|
|
4799
4835
|
)
|
|
4800
4836
|
] }));
|
|
4801
4837
|
SidePanelContent.displayName = "SidePanelContent";
|
|
4838
|
+
|
|
4839
|
+
// src/components/ui/filter/filter-chip-segment.tsx
|
|
4840
|
+
var React34 = __toESM(require("react"));
|
|
4841
|
+
var import_class_variance_authority19 = require("class-variance-authority");
|
|
4842
|
+
var import_icons22 = require("@l3mpire/icons");
|
|
4843
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
4844
|
+
var filterChipSegmentVariants = (0, import_class_variance_authority19.cva)(
|
|
4845
|
+
["flex items-center shrink-0 transition-colors"],
|
|
4846
|
+
{
|
|
4847
|
+
variants: {
|
|
4848
|
+
type: {
|
|
4849
|
+
property: "gap-xs px-base py-sm",
|
|
4850
|
+
operator: "gap-0 px-base py-sm",
|
|
4851
|
+
value: "gap-xs px-base py-sm",
|
|
4852
|
+
placeholder: "gap-0 px-base py-sm",
|
|
4853
|
+
button: "gap-0 p-0"
|
|
4854
|
+
},
|
|
4855
|
+
hasBorder: {
|
|
4856
|
+
true: "border-r border-filter-chip-segment-border",
|
|
4857
|
+
false: ""
|
|
4858
|
+
}
|
|
4859
|
+
},
|
|
4860
|
+
defaultVariants: {
|
|
4861
|
+
type: "property",
|
|
4862
|
+
hasBorder: false
|
|
4863
|
+
}
|
|
4864
|
+
}
|
|
4865
|
+
);
|
|
4866
|
+
var FilterChipSegment = React34.forwardRef(
|
|
4867
|
+
({
|
|
4868
|
+
className,
|
|
4869
|
+
segmentType = "property",
|
|
4870
|
+
hasBorder,
|
|
4871
|
+
icon,
|
|
4872
|
+
label,
|
|
4873
|
+
badgeCount,
|
|
4874
|
+
adornment,
|
|
4875
|
+
onKebabClick,
|
|
4876
|
+
children,
|
|
4877
|
+
...props
|
|
4878
|
+
}, ref) => {
|
|
4879
|
+
if (segmentType === "button") {
|
|
4880
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
4881
|
+
"div",
|
|
4882
|
+
{
|
|
4883
|
+
ref,
|
|
4884
|
+
className: cn(filterChipSegmentVariants({ type: "button", hasBorder: false }), className),
|
|
4885
|
+
...props,
|
|
4886
|
+
children: [
|
|
4887
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
4888
|
+
"button",
|
|
4889
|
+
{
|
|
4890
|
+
type: "button",
|
|
4891
|
+
onClick: onKebabClick,
|
|
4892
|
+
className: "flex items-center justify-center p-sm cursor-pointer hover:bg-filter-chip-segment-bg-hover active:bg-filter-chip-segment-bg-pressed transition-colors",
|
|
4893
|
+
"aria-label": "Filter actions",
|
|
4894
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "size-5 flex items-center justify-center text-sm leading-sm text-filter-chip-kebab-text", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "currentColor", children: [
|
|
4895
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("circle", { cx: "10", cy: "4.5", r: "1.5" }),
|
|
4896
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("circle", { cx: "10", cy: "10", r: "1.5" }),
|
|
4897
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("circle", { cx: "10", cy: "15.5", r: "1.5" })
|
|
4898
|
+
] }) })
|
|
4899
|
+
}
|
|
4900
|
+
),
|
|
4901
|
+
children
|
|
4902
|
+
]
|
|
4903
|
+
}
|
|
4904
|
+
);
|
|
4905
|
+
}
|
|
4906
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
4907
|
+
"div",
|
|
4908
|
+
{
|
|
4909
|
+
ref,
|
|
4910
|
+
className: cn(
|
|
4911
|
+
filterChipSegmentVariants({ type: segmentType, hasBorder }),
|
|
4912
|
+
"cursor-pointer hover:bg-filter-chip-segment-bg-hover active:bg-filter-chip-segment-bg-pressed",
|
|
4913
|
+
className
|
|
4914
|
+
),
|
|
4915
|
+
...props,
|
|
4916
|
+
children: [
|
|
4917
|
+
adornment && segmentType === "value" && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "shrink-0 size-5", children: adornment }),
|
|
4918
|
+
icon && segmentType === "property" && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
4919
|
+
import_icons22.Icon,
|
|
4920
|
+
{
|
|
4921
|
+
icon,
|
|
4922
|
+
size: "sm",
|
|
4923
|
+
className: "shrink-0 text-filter-chip-segment-icon"
|
|
4924
|
+
}
|
|
4925
|
+
),
|
|
4926
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
4927
|
+
"span",
|
|
4928
|
+
{
|
|
4929
|
+
className: cn(
|
|
4930
|
+
"text-sm font-medium leading-sm whitespace-nowrap",
|
|
4931
|
+
segmentType === "placeholder" ? "text-filter-chip-segment-placeholder" : "text-filter-chip-segment-text"
|
|
4932
|
+
),
|
|
4933
|
+
children: label
|
|
4934
|
+
}
|
|
4935
|
+
),
|
|
4936
|
+
badgeCount != null && badgeCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "flex items-center gap-2xs p-2xs rounded-xs bg-filter-chip-badge-bg", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "text-[10px] font-medium leading-2xs text-filter-chip-badge-text", children: badgeCount }) }),
|
|
4937
|
+
children
|
|
4938
|
+
]
|
|
4939
|
+
}
|
|
4940
|
+
);
|
|
4941
|
+
}
|
|
4942
|
+
);
|
|
4943
|
+
FilterChipSegment.displayName = "FilterChipSegment";
|
|
4944
|
+
|
|
4945
|
+
// src/components/ui/filter/filter-chip.tsx
|
|
4946
|
+
var React35 = __toESM(require("react"));
|
|
4947
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
4948
|
+
var FilterChip = React35.forwardRef(
|
|
4949
|
+
({
|
|
4950
|
+
className,
|
|
4951
|
+
icon,
|
|
4952
|
+
property,
|
|
4953
|
+
operator,
|
|
4954
|
+
value,
|
|
4955
|
+
badgeCount,
|
|
4956
|
+
valueAdornment,
|
|
4957
|
+
onPropertyClick,
|
|
4958
|
+
onOperatorClick,
|
|
4959
|
+
onValueClick,
|
|
4960
|
+
onKebabClick,
|
|
4961
|
+
...props
|
|
4962
|
+
}, ref) => {
|
|
4963
|
+
const hasOperator = !!operator;
|
|
4964
|
+
const hasValue = hasOperator && value != null;
|
|
4965
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
|
|
4966
|
+
"div",
|
|
4967
|
+
{
|
|
4968
|
+
ref,
|
|
4969
|
+
className: cn(
|
|
4970
|
+
"flex items-center overflow-clip",
|
|
4971
|
+
"bg-filter-chip-bg border border-filter-chip-border rounded-md",
|
|
4972
|
+
className
|
|
4973
|
+
),
|
|
4974
|
+
...props,
|
|
4975
|
+
children: [
|
|
4976
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
4977
|
+
FilterChipSegment,
|
|
4978
|
+
{
|
|
4979
|
+
segmentType: "property",
|
|
4980
|
+
hasBorder: true,
|
|
4981
|
+
icon,
|
|
4982
|
+
label: property,
|
|
4983
|
+
onClick: onPropertyClick
|
|
4984
|
+
}
|
|
4985
|
+
),
|
|
4986
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
4987
|
+
FilterChipSegment,
|
|
4988
|
+
{
|
|
4989
|
+
segmentType: hasOperator ? "operator" : "placeholder",
|
|
4990
|
+
hasBorder: true,
|
|
4991
|
+
label: hasOperator ? operator : "Select condition",
|
|
4992
|
+
onClick: onOperatorClick
|
|
4993
|
+
}
|
|
4994
|
+
),
|
|
4995
|
+
hasOperator && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
4996
|
+
FilterChipSegment,
|
|
4997
|
+
{
|
|
4998
|
+
segmentType: hasValue ? "value" : "placeholder",
|
|
4999
|
+
hasBorder: true,
|
|
5000
|
+
label: hasValue ? value : "Select condition",
|
|
5001
|
+
adornment: valueAdornment,
|
|
5002
|
+
badgeCount,
|
|
5003
|
+
onClick: onValueClick
|
|
5004
|
+
}
|
|
5005
|
+
),
|
|
5006
|
+
hasOperator && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
5007
|
+
FilterChipSegment,
|
|
5008
|
+
{
|
|
5009
|
+
segmentType: "button",
|
|
5010
|
+
onKebabClick
|
|
5011
|
+
}
|
|
5012
|
+
)
|
|
5013
|
+
]
|
|
5014
|
+
}
|
|
5015
|
+
);
|
|
5016
|
+
}
|
|
5017
|
+
);
|
|
5018
|
+
FilterChip.displayName = "FilterChip";
|
|
5019
|
+
|
|
5020
|
+
// src/components/ui/filter/utils.ts
|
|
5021
|
+
var OPERATORS_BY_TYPE = {
|
|
5022
|
+
text: [
|
|
5023
|
+
"contains",
|
|
5024
|
+
"does not contain",
|
|
5025
|
+
"is",
|
|
5026
|
+
"is not",
|
|
5027
|
+
"starts with",
|
|
5028
|
+
"ends with",
|
|
5029
|
+
"is empty",
|
|
5030
|
+
"is not empty"
|
|
5031
|
+
],
|
|
5032
|
+
number: ["=", "\u2260", ">", "<", "\u2265", "\u2264", "is between", "is empty", "is not empty"],
|
|
5033
|
+
date: [
|
|
5034
|
+
"is",
|
|
5035
|
+
"is before",
|
|
5036
|
+
"is after",
|
|
5037
|
+
"is on or before",
|
|
5038
|
+
"is on or after",
|
|
5039
|
+
"is between",
|
|
5040
|
+
"is relative",
|
|
5041
|
+
"is empty",
|
|
5042
|
+
"is not empty"
|
|
5043
|
+
],
|
|
5044
|
+
enum: ["is", "is not", "is any of", "is none of", "is empty", "is not empty"],
|
|
5045
|
+
tags: [
|
|
5046
|
+
"contains",
|
|
5047
|
+
"does not contain",
|
|
5048
|
+
"contains any of",
|
|
5049
|
+
"contains all of",
|
|
5050
|
+
"is empty",
|
|
5051
|
+
"is not empty"
|
|
5052
|
+
],
|
|
5053
|
+
boolean: ["is true", "is false"],
|
|
5054
|
+
relation: ["is", "is not", "is any of", "is none of", "is empty", "is not empty"]
|
|
5055
|
+
};
|
|
5056
|
+
var DEFAULT_OPERATOR_BY_TYPE = {
|
|
5057
|
+
text: "contains",
|
|
5058
|
+
number: "=",
|
|
5059
|
+
date: "is relative",
|
|
5060
|
+
enum: "is",
|
|
5061
|
+
tags: "contains",
|
|
5062
|
+
boolean: "is true",
|
|
5063
|
+
relation: "is"
|
|
5064
|
+
};
|
|
5065
|
+
function isNoValueOperator(operator) {
|
|
5066
|
+
return ["is empty", "is not empty", "is true", "is false"].includes(operator);
|
|
5067
|
+
}
|
|
5068
|
+
function getDefaultOperator(type) {
|
|
5069
|
+
return DEFAULT_OPERATOR_BY_TYPE[type];
|
|
5070
|
+
}
|
|
5071
|
+
function createFilterWithDefaults(propertyId, type) {
|
|
5072
|
+
const operator = getDefaultOperator(type);
|
|
5073
|
+
return {
|
|
5074
|
+
id: crypto.randomUUID(),
|
|
5075
|
+
propertyId,
|
|
5076
|
+
operator,
|
|
5077
|
+
value: type === "boolean" ? true : null
|
|
5078
|
+
};
|
|
5079
|
+
}
|
|
5080
|
+
function getValueInputType(type, operator) {
|
|
5081
|
+
if (isNoValueOperator(operator)) return null;
|
|
5082
|
+
if (type === "text") return "TextInput";
|
|
5083
|
+
if (type === "number")
|
|
5084
|
+
return operator === "is between" ? "NumberRange" : "NumberInput";
|
|
5085
|
+
if (type === "date") {
|
|
5086
|
+
if (operator === "is between") return "DateRange";
|
|
5087
|
+
if (operator === "is relative") return "PresetTags";
|
|
5088
|
+
return "DatePicker";
|
|
5089
|
+
}
|
|
5090
|
+
if (type === "enum")
|
|
5091
|
+
return ["is any of", "is none of"].includes(operator) ? "MultiSelect" : "SingleSelect";
|
|
5092
|
+
if (type === "tags")
|
|
5093
|
+
return ["contains any of", "contains all of"].includes(operator) ? "MultiSelect" : "SingleSelect";
|
|
5094
|
+
if (type === "relation")
|
|
5095
|
+
return ["is any of", "is none of"].includes(operator) ? "MultiRelationPicker" : "RelationPicker";
|
|
5096
|
+
return null;
|
|
5097
|
+
}
|
|
5098
|
+
|
|
5099
|
+
// src/components/ui/filter/filter-bar.tsx
|
|
5100
|
+
var React36 = __toESM(require("react"));
|
|
5101
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
5102
|
+
var FilterBar = React36.forwardRef(
|
|
5103
|
+
({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
5104
|
+
"div",
|
|
5105
|
+
{
|
|
5106
|
+
ref,
|
|
5107
|
+
className: cn(
|
|
5108
|
+
"flex items-center justify-between w-full",
|
|
5109
|
+
className
|
|
5110
|
+
),
|
|
5111
|
+
role: "toolbar",
|
|
5112
|
+
"aria-label": "Filters",
|
|
5113
|
+
"aria-orientation": "horizontal",
|
|
5114
|
+
...props,
|
|
5115
|
+
children
|
|
5116
|
+
}
|
|
5117
|
+
)
|
|
5118
|
+
);
|
|
5119
|
+
FilterBar.displayName = "FilterBar";
|
|
5120
|
+
var FilterBarLeft = React36.forwardRef(
|
|
5121
|
+
({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
5122
|
+
"div",
|
|
5123
|
+
{
|
|
5124
|
+
ref,
|
|
5125
|
+
className: cn("flex items-center gap-base flex-wrap", className),
|
|
5126
|
+
...props,
|
|
5127
|
+
children
|
|
5128
|
+
}
|
|
5129
|
+
)
|
|
5130
|
+
);
|
|
5131
|
+
FilterBarLeft.displayName = "FilterBarLeft";
|
|
5132
|
+
var FilterBarRight = React36.forwardRef(
|
|
5133
|
+
({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
5134
|
+
"div",
|
|
5135
|
+
{
|
|
5136
|
+
ref,
|
|
5137
|
+
className: cn("flex items-center gap-base shrink-0", className),
|
|
5138
|
+
...props,
|
|
5139
|
+
children
|
|
5140
|
+
}
|
|
5141
|
+
)
|
|
5142
|
+
);
|
|
5143
|
+
FilterBarRight.displayName = "FilterBarRight";
|
|
5144
|
+
|
|
5145
|
+
// src/components/ui/filter/sort-button.tsx
|
|
5146
|
+
var React37 = __toESM(require("react"));
|
|
5147
|
+
var PopoverPrimitive3 = __toESM(require("@radix-ui/react-popover"));
|
|
5148
|
+
var import_icons23 = require("@l3mpire/icons");
|
|
5149
|
+
var import_icons24 = require("@l3mpire/icons");
|
|
5150
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
5151
|
+
var SortButton = ({
|
|
5152
|
+
className,
|
|
5153
|
+
fields,
|
|
5154
|
+
activeField,
|
|
5155
|
+
direction,
|
|
5156
|
+
onChange,
|
|
5157
|
+
...props
|
|
5158
|
+
}) => {
|
|
5159
|
+
const [open, setOpen] = React37.useState(false);
|
|
5160
|
+
const activeFieldDef = fields.find((f) => f.id === activeField);
|
|
5161
|
+
const activeLabel = activeFieldDef?.label ?? activeField;
|
|
5162
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(PopoverPrimitive3.Root, { open, onOpenChange: setOpen, children: [
|
|
5163
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(PopoverPrimitive3.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
|
|
5164
|
+
"button",
|
|
5165
|
+
{
|
|
5166
|
+
type: "button",
|
|
5167
|
+
className: cn(
|
|
5168
|
+
"flex items-center gap-xs px-md py-sm",
|
|
5169
|
+
"min-h-[32px] max-h-[32px] min-w-[80px]",
|
|
5170
|
+
"bg-gradient-to-t from-[var(--color-btn-outlined-neutral-bg-default)] to-[var(--color-btn-outlined-neutral-bg-gradient-to-default)]",
|
|
5171
|
+
"border border-[var(--color-btn-outlined-neutral-border-default)] rounded-md shadow-sm",
|
|
5172
|
+
"cursor-pointer transition-colors",
|
|
5173
|
+
"hover:from-[var(--color-btn-outlined-neutral-bg-hover)] hover:to-[var(--color-btn-outlined-neutral-bg-gradient-to-hover)]",
|
|
5174
|
+
className
|
|
5175
|
+
),
|
|
5176
|
+
children: [
|
|
5177
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
5178
|
+
import_icons23.Icon,
|
|
5179
|
+
{
|
|
5180
|
+
icon: direction === "asc" ? import_icons24.faArrowUpSmallBigOutline : import_icons24.faArrowDownBigSmallOutline,
|
|
5181
|
+
size: "sm",
|
|
5182
|
+
className: "shrink-0 text-[var(--color-foreground)]"
|
|
5183
|
+
}
|
|
5184
|
+
),
|
|
5185
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: "text-sm font-medium leading-sm whitespace-nowrap", children: [
|
|
5186
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: "text-[var(--color-muted-foreground)]", children: [
|
|
5187
|
+
"Sort by",
|
|
5188
|
+
" "
|
|
5189
|
+
] }),
|
|
5190
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "text-[var(--color-foreground)]", children: activeLabel })
|
|
5191
|
+
] })
|
|
5192
|
+
]
|
|
5193
|
+
}
|
|
5194
|
+
) }),
|
|
5195
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(PopoverPrimitive3.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
|
|
5196
|
+
PopoverPrimitive3.Content,
|
|
5197
|
+
{
|
|
5198
|
+
sideOffset: 4,
|
|
5199
|
+
align: "start",
|
|
5200
|
+
className: cn(
|
|
5201
|
+
"z-50 flex flex-col gap-xs overflow-clip p-xs",
|
|
5202
|
+
"bg-[var(--color-dropdown-bg)] border border-[var(--color-dropdown-border)] rounded-md shadow-lg",
|
|
5203
|
+
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
5204
|
+
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
|
5205
|
+
"data-[side=bottom]:slide-in-from-top-2",
|
|
5206
|
+
"min-w-[180px]"
|
|
5207
|
+
),
|
|
5208
|
+
children: [
|
|
5209
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "flex flex-col", children: fields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
|
|
5210
|
+
"button",
|
|
5211
|
+
{
|
|
5212
|
+
type: "button",
|
|
5213
|
+
onClick: () => {
|
|
5214
|
+
onChange?.(field.id, direction);
|
|
5215
|
+
setOpen(false);
|
|
5216
|
+
},
|
|
5217
|
+
className: cn(
|
|
5218
|
+
"flex items-center gap-base p-base rounded-base cursor-pointer transition-colors",
|
|
5219
|
+
"hover:bg-[var(--color-dropdown-item-hover)]",
|
|
5220
|
+
field.id === activeField ? "bg-[var(--color-dropdown-item-hover)]" : ""
|
|
5221
|
+
),
|
|
5222
|
+
children: [
|
|
5223
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
5224
|
+
import_icons23.Icon,
|
|
5225
|
+
{
|
|
5226
|
+
icon: field.icon,
|
|
5227
|
+
size: "sm",
|
|
5228
|
+
className: cn(
|
|
5229
|
+
"shrink-0",
|
|
5230
|
+
field.id === activeField ? "text-[var(--color-foreground)]" : "text-[var(--color-dropdown-item-icon)]"
|
|
5231
|
+
)
|
|
5232
|
+
}
|
|
5233
|
+
),
|
|
5234
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
5235
|
+
"span",
|
|
5236
|
+
{
|
|
5237
|
+
className: cn(
|
|
5238
|
+
"flex-1 text-sm font-regular leading-sm text-left truncate",
|
|
5239
|
+
field.id === activeField ? "text-[var(--color-foreground)]" : "text-[var(--color-dropdown-item-icon)]"
|
|
5240
|
+
),
|
|
5241
|
+
children: field.label
|
|
5242
|
+
}
|
|
5243
|
+
)
|
|
5244
|
+
]
|
|
5245
|
+
},
|
|
5246
|
+
field.id
|
|
5247
|
+
)) }),
|
|
5248
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "h-px bg-[var(--color-border)]" }),
|
|
5249
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "flex flex-col", children: [
|
|
5250
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
|
|
5251
|
+
"button",
|
|
5252
|
+
{
|
|
5253
|
+
type: "button",
|
|
5254
|
+
onClick: () => {
|
|
5255
|
+
onChange?.(activeField, "asc");
|
|
5256
|
+
setOpen(false);
|
|
5257
|
+
},
|
|
5258
|
+
className: cn(
|
|
5259
|
+
"flex items-center gap-base p-base rounded-base cursor-pointer transition-colors",
|
|
5260
|
+
"hover:bg-[var(--color-dropdown-item-hover)]",
|
|
5261
|
+
direction === "asc" ? "bg-[var(--color-dropdown-item-hover)]" : ""
|
|
5262
|
+
),
|
|
5263
|
+
children: [
|
|
5264
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
5265
|
+
import_icons23.Icon,
|
|
5266
|
+
{
|
|
5267
|
+
icon: import_icons24.faArrowUpSmallBigOutline,
|
|
5268
|
+
size: "sm",
|
|
5269
|
+
className: cn(
|
|
5270
|
+
"shrink-0",
|
|
5271
|
+
direction === "asc" ? "text-[var(--color-foreground)]" : "text-[var(--color-dropdown-item-icon)]"
|
|
5272
|
+
)
|
|
5273
|
+
}
|
|
5274
|
+
),
|
|
5275
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
5276
|
+
"span",
|
|
5277
|
+
{
|
|
5278
|
+
className: cn(
|
|
5279
|
+
"flex-1 text-sm font-regular leading-sm text-left",
|
|
5280
|
+
direction === "asc" ? "text-[var(--color-foreground)]" : "text-[var(--color-dropdown-item-icon)]"
|
|
5281
|
+
),
|
|
5282
|
+
children: "Ascending"
|
|
5283
|
+
}
|
|
5284
|
+
)
|
|
5285
|
+
]
|
|
5286
|
+
}
|
|
5287
|
+
),
|
|
5288
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
|
|
5289
|
+
"button",
|
|
5290
|
+
{
|
|
5291
|
+
type: "button",
|
|
5292
|
+
onClick: () => {
|
|
5293
|
+
onChange?.(activeField, "desc");
|
|
5294
|
+
setOpen(false);
|
|
5295
|
+
},
|
|
5296
|
+
className: cn(
|
|
5297
|
+
"flex items-center gap-base p-base rounded-base cursor-pointer transition-colors",
|
|
5298
|
+
"hover:bg-[var(--color-dropdown-item-hover)]",
|
|
5299
|
+
direction === "desc" ? "bg-[var(--color-dropdown-item-hover)]" : ""
|
|
5300
|
+
),
|
|
5301
|
+
children: [
|
|
5302
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
5303
|
+
import_icons23.Icon,
|
|
5304
|
+
{
|
|
5305
|
+
icon: import_icons24.faArrowDownBigSmallOutline,
|
|
5306
|
+
size: "sm",
|
|
5307
|
+
className: cn(
|
|
5308
|
+
"shrink-0",
|
|
5309
|
+
direction === "desc" ? "text-[var(--color-foreground)]" : "text-[var(--color-dropdown-item-icon)]"
|
|
5310
|
+
)
|
|
5311
|
+
}
|
|
5312
|
+
),
|
|
5313
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
5314
|
+
"span",
|
|
5315
|
+
{
|
|
5316
|
+
className: cn(
|
|
5317
|
+
"flex-1 text-sm font-regular leading-sm text-left",
|
|
5318
|
+
direction === "desc" ? "text-[var(--color-foreground)]" : "text-[var(--color-dropdown-item-icon)]"
|
|
5319
|
+
),
|
|
5320
|
+
children: "Descending"
|
|
5321
|
+
}
|
|
5322
|
+
)
|
|
5323
|
+
]
|
|
5324
|
+
}
|
|
5325
|
+
)
|
|
5326
|
+
] })
|
|
5327
|
+
]
|
|
5328
|
+
}
|
|
5329
|
+
) })
|
|
5330
|
+
] });
|
|
5331
|
+
};
|
|
5332
|
+
SortButton.displayName = "SortButton";
|
|
5333
|
+
|
|
5334
|
+
// src/components/ui/filter/filter-bar-button.tsx
|
|
5335
|
+
var React38 = __toESM(require("react"));
|
|
5336
|
+
var import_icons25 = require("@l3mpire/icons");
|
|
5337
|
+
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
5338
|
+
var FilterBarButton = React38.forwardRef(({ className, count, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
5339
|
+
"button",
|
|
5340
|
+
{
|
|
5341
|
+
ref,
|
|
5342
|
+
type: "button",
|
|
5343
|
+
className: cn(
|
|
5344
|
+
"flex items-center gap-sm px-base py-sm",
|
|
5345
|
+
"min-h-[32px] max-h-[32px] min-w-[80px]",
|
|
5346
|
+
"bg-gradient-to-t from-[var(--color-btn-outlined-neutral-bg-default)] to-[var(--color-btn-outlined-neutral-bg-gradient-to-default)]",
|
|
5347
|
+
"border border-[var(--color-btn-outlined-neutral-border-default)] rounded-md shadow-sm",
|
|
5348
|
+
"cursor-pointer transition-colors",
|
|
5349
|
+
"hover:from-[var(--color-btn-outlined-neutral-bg-hover)] hover:to-[var(--color-btn-outlined-neutral-bg-gradient-to-hover)]",
|
|
5350
|
+
className
|
|
5351
|
+
),
|
|
5352
|
+
...props,
|
|
5353
|
+
children: [
|
|
5354
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
5355
|
+
import_icons25.Icon,
|
|
5356
|
+
{
|
|
5357
|
+
icon: import_icons25.faSlidersOutline,
|
|
5358
|
+
size: "sm",
|
|
5359
|
+
className: "shrink-0 text-[var(--color-foreground)]"
|
|
5360
|
+
}
|
|
5361
|
+
),
|
|
5362
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "text-sm font-medium leading-sm whitespace-nowrap text-[var(--color-foreground)]", children: children ?? "Filters" }),
|
|
5363
|
+
count != null && count > 0 && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "flex items-center p-2xs rounded-xs bg-filter-chip-badge-bg", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "text-[10px] font-medium leading-2xs text-filter-chip-badge-text", children: count }) })
|
|
5364
|
+
]
|
|
5365
|
+
}
|
|
5366
|
+
));
|
|
5367
|
+
FilterBarButton.displayName = "FilterBarButton";
|
|
5368
|
+
|
|
5369
|
+
// src/components/ui/filter/save-view-button.tsx
|
|
5370
|
+
var React39 = __toESM(require("react"));
|
|
5371
|
+
var import_icons26 = require("@l3mpire/icons");
|
|
5372
|
+
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
5373
|
+
var SaveViewButton = React39.forwardRef(
|
|
5374
|
+
({ className, label = "Save view", onSave, onDropdown, ...props }, ref) => {
|
|
5375
|
+
const sharedStyle = [
|
|
5376
|
+
"flex items-center justify-center",
|
|
5377
|
+
"min-h-[32px] max-h-[32px]",
|
|
5378
|
+
"bg-gradient-to-t from-[var(--color-btn-solid-brand-bg-default)] from-[10%] to-[var(--color-btn-solid-brand-bg-gradient-to-default)]",
|
|
5379
|
+
"border border-[var(--color-btn-solid-brand-border-default)]",
|
|
5380
|
+
"shadow-sm cursor-pointer transition-colors",
|
|
5381
|
+
"hover:from-[var(--color-btn-solid-brand-bg-hover)] hover:to-[var(--color-btn-solid-brand-bg-gradient-to-hover)]"
|
|
5382
|
+
];
|
|
5383
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
|
|
5384
|
+
"div",
|
|
5385
|
+
{
|
|
5386
|
+
ref,
|
|
5387
|
+
className: cn("flex items-center", className),
|
|
5388
|
+
...props,
|
|
5389
|
+
children: [
|
|
5390
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
|
|
5391
|
+
"button",
|
|
5392
|
+
{
|
|
5393
|
+
type: "button",
|
|
5394
|
+
onClick: onSave,
|
|
5395
|
+
className: cn(
|
|
5396
|
+
sharedStyle,
|
|
5397
|
+
"gap-sm px-base py-sm min-w-[80px]",
|
|
5398
|
+
"rounded-l-md -mr-px"
|
|
5399
|
+
),
|
|
5400
|
+
children: [
|
|
5401
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "text-sm font-medium leading-sm whitespace-nowrap text-[var(--color-btn-solid-brand-text-default)]", children: label }),
|
|
5402
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "absolute inset-0 rounded-l-[11px] border border-[var(--color-btn-solid-brand-inner-border-default)] shadow-sm pointer-events-none" })
|
|
5403
|
+
]
|
|
5404
|
+
}
|
|
5405
|
+
),
|
|
5406
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
|
|
5407
|
+
"button",
|
|
5408
|
+
{
|
|
5409
|
+
type: "button",
|
|
5410
|
+
onClick: onDropdown,
|
|
5411
|
+
className: cn(
|
|
5412
|
+
sharedStyle,
|
|
5413
|
+
"p-sm",
|
|
5414
|
+
"rounded-r-md -ml-px"
|
|
5415
|
+
),
|
|
5416
|
+
children: [
|
|
5417
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
5418
|
+
import_icons26.Icon,
|
|
5419
|
+
{
|
|
5420
|
+
icon: import_icons26.faChevronDownOutline,
|
|
5421
|
+
size: "sm",
|
|
5422
|
+
className: "text-[var(--color-btn-solid-brand-text-default)]"
|
|
5423
|
+
}
|
|
5424
|
+
),
|
|
5425
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "absolute inset-0 rounded-r-[11px] border border-[var(--color-btn-solid-brand-inner-border-default)] shadow-sm pointer-events-none" })
|
|
5426
|
+
]
|
|
5427
|
+
}
|
|
5428
|
+
)
|
|
5429
|
+
]
|
|
5430
|
+
}
|
|
5431
|
+
);
|
|
5432
|
+
}
|
|
5433
|
+
);
|
|
5434
|
+
SaveViewButton.displayName = "SaveViewButton";
|
|
5435
|
+
|
|
5436
|
+
// src/components/ui/filter/operator-selector.tsx
|
|
5437
|
+
var PopoverPrimitive4 = __toESM(require("@radix-ui/react-popover"));
|
|
5438
|
+
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
5439
|
+
var OperatorSelector = ({
|
|
5440
|
+
dataType,
|
|
5441
|
+
activeOperator,
|
|
5442
|
+
onSelect,
|
|
5443
|
+
open,
|
|
5444
|
+
onOpenChange,
|
|
5445
|
+
children
|
|
5446
|
+
}) => {
|
|
5447
|
+
const operators = OPERATORS_BY_TYPE[dataType];
|
|
5448
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(PopoverPrimitive4.Root, { open, onOpenChange, children: [
|
|
5449
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(PopoverPrimitive4.Trigger, { asChild: true, children }),
|
|
5450
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(PopoverPrimitive4.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
5451
|
+
PopoverPrimitive4.Content,
|
|
5452
|
+
{
|
|
5453
|
+
sideOffset: 4,
|
|
5454
|
+
align: "start",
|
|
5455
|
+
className: cn(
|
|
5456
|
+
"z-50 flex flex-col p-xs overflow-clip",
|
|
5457
|
+
"bg-[var(--color-dropdown-bg)] border border-[var(--color-dropdown-border)] rounded-md shadow-lg",
|
|
5458
|
+
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
5459
|
+
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
|
5460
|
+
"data-[side=bottom]:slide-in-from-top-2",
|
|
5461
|
+
"min-w-[180px]"
|
|
5462
|
+
),
|
|
5463
|
+
children: operators.map((op) => /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
5464
|
+
"button",
|
|
5465
|
+
{
|
|
5466
|
+
type: "button",
|
|
5467
|
+
onClick: () => onSelect(op),
|
|
5468
|
+
className: cn(
|
|
5469
|
+
"flex items-center gap-base p-base rounded-base cursor-pointer transition-colors text-left",
|
|
5470
|
+
"hover:bg-[var(--color-dropdown-item-hover)]",
|
|
5471
|
+
op === activeOperator && "bg-[var(--color-dropdown-item-hover)]"
|
|
5472
|
+
),
|
|
5473
|
+
children: [
|
|
5474
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
5475
|
+
"span",
|
|
5476
|
+
{
|
|
5477
|
+
className: cn(
|
|
5478
|
+
"text-sm font-regular leading-sm",
|
|
5479
|
+
op === activeOperator ? "text-[var(--color-foreground)] font-medium" : "text-[var(--color-dropdown-item-text)]"
|
|
5480
|
+
),
|
|
5481
|
+
children: op
|
|
5482
|
+
}
|
|
5483
|
+
),
|
|
5484
|
+
isNoValueOperator(op) && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "ml-auto text-xs text-[var(--color-muted-foreground)]", children: "instant" })
|
|
5485
|
+
]
|
|
5486
|
+
},
|
|
5487
|
+
op
|
|
5488
|
+
))
|
|
5489
|
+
}
|
|
5490
|
+
) })
|
|
5491
|
+
] });
|
|
5492
|
+
};
|
|
5493
|
+
OperatorSelector.displayName = "OperatorSelector";
|
|
5494
|
+
var OperatorList = ({
|
|
5495
|
+
dataType,
|
|
5496
|
+
activeOperator,
|
|
5497
|
+
onSelect
|
|
5498
|
+
}) => {
|
|
5499
|
+
const operators = OPERATORS_BY_TYPE[dataType];
|
|
5500
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "flex flex-col", children: operators.map((op) => /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
5501
|
+
"button",
|
|
5502
|
+
{
|
|
5503
|
+
type: "button",
|
|
5504
|
+
onClick: () => onSelect(op),
|
|
5505
|
+
className: cn(
|
|
5506
|
+
"flex items-center gap-base p-base rounded-base cursor-pointer transition-colors text-left",
|
|
5507
|
+
"hover:bg-[var(--color-dropdown-item-hover)]",
|
|
5508
|
+
op === activeOperator && "bg-[var(--color-dropdown-item-hover)]"
|
|
5509
|
+
),
|
|
5510
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
5511
|
+
"span",
|
|
5512
|
+
{
|
|
5513
|
+
className: cn(
|
|
5514
|
+
"text-sm font-regular leading-sm",
|
|
5515
|
+
op === activeOperator ? "text-[var(--color-foreground)] font-medium" : "text-[var(--color-dropdown-item-text)]"
|
|
5516
|
+
),
|
|
5517
|
+
children: op
|
|
5518
|
+
}
|
|
5519
|
+
)
|
|
5520
|
+
},
|
|
5521
|
+
op
|
|
5522
|
+
)) });
|
|
5523
|
+
};
|
|
5524
|
+
OperatorList.displayName = "OperatorList";
|
|
5525
|
+
|
|
5526
|
+
// src/components/ui/filter/value-input.tsx
|
|
5527
|
+
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
5528
|
+
var RELATIVE_DATE_PRESETS = [
|
|
5529
|
+
{ group: "Past", options: ["Today", "Yesterday", "Last 7 days", "Last 14 days", "Last 30 days", "Last 90 days"] },
|
|
5530
|
+
{ group: "Current", options: ["This week", "This month", "This quarter", "This year"] },
|
|
5531
|
+
{ group: "Future", options: ["Tomorrow", "Next 7 days", "Next 14 days", "Next 30 days", "Next week", "Next month", "Next quarter"] }
|
|
5532
|
+
];
|
|
5533
|
+
var ValueInput = ({
|
|
5534
|
+
dataType,
|
|
5535
|
+
operator,
|
|
5536
|
+
value,
|
|
5537
|
+
onChange,
|
|
5538
|
+
onSubmit,
|
|
5539
|
+
options = [],
|
|
5540
|
+
className
|
|
5541
|
+
}) => {
|
|
5542
|
+
const inputType = getValueInputType(dataType, operator);
|
|
5543
|
+
if (!inputType) return null;
|
|
5544
|
+
const handleKeyDown = (e) => {
|
|
5545
|
+
if (e.key === "Enter") onSubmit?.();
|
|
5546
|
+
};
|
|
5547
|
+
switch (inputType) {
|
|
5548
|
+
case "TextInput":
|
|
5549
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: cn("flex flex-col gap-base p-base", className), children: [
|
|
5550
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
5551
|
+
"input",
|
|
5552
|
+
{
|
|
5553
|
+
type: "text",
|
|
5554
|
+
value: value ?? "",
|
|
5555
|
+
onChange: (e) => onChange(e.target.value),
|
|
5556
|
+
onKeyDown: handleKeyDown,
|
|
5557
|
+
placeholder: "Enter value...",
|
|
5558
|
+
autoFocus: true,
|
|
5559
|
+
className: cn(
|
|
5560
|
+
"w-full px-base py-sm rounded-base border border-[var(--color-input)]",
|
|
5561
|
+
"bg-[var(--color-background)] text-sm font-regular leading-sm text-[var(--color-foreground)]",
|
|
5562
|
+
"placeholder:text-[var(--color-muted-foreground)]",
|
|
5563
|
+
"focus:outline-none focus:ring-2 focus:ring-[var(--color-ring)] focus:ring-offset-0"
|
|
5564
|
+
)
|
|
5565
|
+
}
|
|
5566
|
+
),
|
|
5567
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
5568
|
+
"button",
|
|
5569
|
+
{
|
|
5570
|
+
type: "button",
|
|
5571
|
+
onClick: onSubmit,
|
|
5572
|
+
className: "self-end px-md py-sm text-sm font-medium leading-sm text-[var(--color-primary-foreground)] bg-[var(--color-primary)] rounded-base cursor-pointer hover:opacity-90 transition-opacity",
|
|
5573
|
+
children: "Apply"
|
|
5574
|
+
}
|
|
5575
|
+
)
|
|
5576
|
+
] });
|
|
5577
|
+
case "NumberInput":
|
|
5578
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: cn("flex flex-col gap-base p-base", className), children: [
|
|
5579
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
5580
|
+
"input",
|
|
5581
|
+
{
|
|
5582
|
+
type: "number",
|
|
5583
|
+
value: value ?? "",
|
|
5584
|
+
onChange: (e) => onChange(e.target.value ? Number(e.target.value) : null),
|
|
5585
|
+
onKeyDown: handleKeyDown,
|
|
5586
|
+
placeholder: "Enter number...",
|
|
5587
|
+
autoFocus: true,
|
|
5588
|
+
className: cn(
|
|
5589
|
+
"w-full px-base py-sm rounded-base border border-[var(--color-input)]",
|
|
5590
|
+
"bg-[var(--color-background)] text-sm font-regular leading-sm text-[var(--color-foreground)]",
|
|
5591
|
+
"placeholder:text-[var(--color-muted-foreground)]",
|
|
5592
|
+
"focus:outline-none focus:ring-2 focus:ring-[var(--color-ring)] focus:ring-offset-0"
|
|
5593
|
+
)
|
|
5594
|
+
}
|
|
5595
|
+
),
|
|
5596
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
5597
|
+
"button",
|
|
5598
|
+
{
|
|
5599
|
+
type: "button",
|
|
5600
|
+
onClick: onSubmit,
|
|
5601
|
+
className: "self-end px-md py-sm text-sm font-medium leading-sm text-[var(--color-primary-foreground)] bg-[var(--color-primary)] rounded-base cursor-pointer hover:opacity-90 transition-opacity",
|
|
5602
|
+
children: "Apply"
|
|
5603
|
+
}
|
|
5604
|
+
)
|
|
5605
|
+
] });
|
|
5606
|
+
case "NumberRange": {
|
|
5607
|
+
const rangeVal = value ?? [0, 0];
|
|
5608
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: cn("flex flex-col gap-base p-base", className), children: [
|
|
5609
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex items-center gap-base", children: [
|
|
5610
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
5611
|
+
"input",
|
|
5612
|
+
{
|
|
5613
|
+
type: "number",
|
|
5614
|
+
value: rangeVal[0] ?? "",
|
|
5615
|
+
onChange: (e) => onChange([Number(e.target.value), rangeVal[1]]),
|
|
5616
|
+
placeholder: "Min",
|
|
5617
|
+
autoFocus: true,
|
|
5618
|
+
className: cn(
|
|
5619
|
+
"flex-1 px-base py-sm rounded-base border border-[var(--color-input)]",
|
|
5620
|
+
"bg-[var(--color-background)] text-sm font-regular leading-sm text-[var(--color-foreground)]",
|
|
5621
|
+
"focus:outline-none focus:ring-2 focus:ring-[var(--color-ring)]"
|
|
5622
|
+
)
|
|
5623
|
+
}
|
|
5624
|
+
),
|
|
5625
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "text-sm text-[var(--color-muted-foreground)]", children: "and" }),
|
|
5626
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
5627
|
+
"input",
|
|
5628
|
+
{
|
|
5629
|
+
type: "number",
|
|
5630
|
+
value: rangeVal[1] ?? "",
|
|
5631
|
+
onChange: (e) => onChange([rangeVal[0], Number(e.target.value)]),
|
|
5632
|
+
placeholder: "Max",
|
|
5633
|
+
className: cn(
|
|
5634
|
+
"flex-1 px-base py-sm rounded-base border border-[var(--color-input)]",
|
|
5635
|
+
"bg-[var(--color-background)] text-sm font-regular leading-sm text-[var(--color-foreground)]",
|
|
5636
|
+
"focus:outline-none focus:ring-2 focus:ring-[var(--color-ring)]"
|
|
5637
|
+
)
|
|
5638
|
+
}
|
|
5639
|
+
)
|
|
5640
|
+
] }),
|
|
5641
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
5642
|
+
"button",
|
|
5643
|
+
{
|
|
5644
|
+
type: "button",
|
|
5645
|
+
onClick: onSubmit,
|
|
5646
|
+
className: "self-end px-md py-sm text-sm font-medium leading-sm text-[var(--color-primary-foreground)] bg-[var(--color-primary)] rounded-base cursor-pointer hover:opacity-90 transition-opacity",
|
|
5647
|
+
children: "Apply"
|
|
5648
|
+
}
|
|
5649
|
+
)
|
|
5650
|
+
] });
|
|
5651
|
+
}
|
|
5652
|
+
case "PresetTags":
|
|
5653
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: cn("flex flex-col gap-base p-base max-w-[280px]", className), children: RELATIVE_DATE_PRESETS.map((group) => /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex flex-col gap-xs", children: [
|
|
5654
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "text-xs font-medium leading-xs text-[var(--color-muted-foreground)] uppercase px-xs", children: group.group }),
|
|
5655
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "flex flex-wrap gap-xs", children: group.options.map((preset) => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
5656
|
+
"button",
|
|
5657
|
+
{
|
|
5658
|
+
type: "button",
|
|
5659
|
+
onClick: () => {
|
|
5660
|
+
onChange(preset);
|
|
5661
|
+
onSubmit?.();
|
|
5662
|
+
},
|
|
5663
|
+
className: cn(
|
|
5664
|
+
"px-base py-2xs rounded-base border cursor-pointer transition-colors text-sm font-regular leading-sm",
|
|
5665
|
+
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)]"
|
|
5666
|
+
),
|
|
5667
|
+
children: preset
|
|
5668
|
+
},
|
|
5669
|
+
preset
|
|
5670
|
+
)) })
|
|
5671
|
+
] }, group.group)) });
|
|
5672
|
+
case "SingleSelect":
|
|
5673
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: cn("flex flex-col gap-xs p-base max-h-[250px] overflow-y-auto", className), children: options.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
5674
|
+
"button",
|
|
5675
|
+
{
|
|
5676
|
+
type: "button",
|
|
5677
|
+
onClick: () => {
|
|
5678
|
+
onChange(opt);
|
|
5679
|
+
onSubmit?.();
|
|
5680
|
+
},
|
|
5681
|
+
className: cn(
|
|
5682
|
+
"flex items-center gap-base p-base rounded-base cursor-pointer transition-colors text-left",
|
|
5683
|
+
"hover:bg-[var(--color-dropdown-item-hover)]",
|
|
5684
|
+
value === opt && "bg-[var(--color-dropdown-item-hover)]"
|
|
5685
|
+
),
|
|
5686
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "text-sm font-regular leading-sm text-[var(--color-foreground)]", children: opt })
|
|
5687
|
+
},
|
|
5688
|
+
opt
|
|
5689
|
+
)) });
|
|
5690
|
+
case "MultiSelect": {
|
|
5691
|
+
const selected = Array.isArray(value) ? value : [];
|
|
5692
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: cn("flex flex-col gap-xs p-base", className), children: [
|
|
5693
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "flex flex-col max-h-[200px] overflow-y-auto", children: options.map((opt) => {
|
|
5694
|
+
const isSelected = selected.includes(opt);
|
|
5695
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
|
|
5696
|
+
"button",
|
|
5697
|
+
{
|
|
5698
|
+
type: "button",
|
|
5699
|
+
onClick: () => {
|
|
5700
|
+
const next = isSelected ? selected.filter((s) => s !== opt) : [...selected, opt];
|
|
5701
|
+
onChange(next);
|
|
5702
|
+
},
|
|
5703
|
+
className: cn(
|
|
5704
|
+
"flex items-center gap-base p-base rounded-base cursor-pointer transition-colors text-left",
|
|
5705
|
+
"hover:bg-[var(--color-dropdown-item-hover)]"
|
|
5706
|
+
),
|
|
5707
|
+
children: [
|
|
5708
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
5709
|
+
"span",
|
|
5710
|
+
{
|
|
5711
|
+
className: cn(
|
|
5712
|
+
"flex items-center justify-center size-4 rounded-xs border transition-colors",
|
|
5713
|
+
isSelected ? "bg-[var(--color-primary)] border-[var(--color-primary)]" : "border-[var(--color-input)] bg-[var(--color-background)]"
|
|
5714
|
+
),
|
|
5715
|
+
children: isSelected && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("svg", { width: "10", height: "10", viewBox: "0 0 10 10", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("path", { d: "M2 5L4 7L8 3", stroke: "white", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) })
|
|
5716
|
+
}
|
|
5717
|
+
),
|
|
5718
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "text-sm font-regular leading-sm text-[var(--color-foreground)]", children: opt })
|
|
5719
|
+
]
|
|
5720
|
+
},
|
|
5721
|
+
opt
|
|
5722
|
+
);
|
|
5723
|
+
}) }),
|
|
5724
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
5725
|
+
"button",
|
|
5726
|
+
{
|
|
5727
|
+
type: "button",
|
|
5728
|
+
onClick: onSubmit,
|
|
5729
|
+
className: "self-end px-md py-sm text-sm font-medium leading-sm text-[var(--color-primary-foreground)] bg-[var(--color-primary)] rounded-base cursor-pointer hover:opacity-90 transition-opacity",
|
|
5730
|
+
children: "Apply"
|
|
5731
|
+
}
|
|
5732
|
+
)
|
|
5733
|
+
] });
|
|
5734
|
+
}
|
|
5735
|
+
// DatePicker, DateRange, RelationPicker, MultiRelationPicker
|
|
5736
|
+
// Stub as text inputs for now — will wire to actual DatePicker/relation components
|
|
5737
|
+
case "DatePicker":
|
|
5738
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: cn("flex flex-col gap-base p-base", className), children: [
|
|
5739
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
5740
|
+
"input",
|
|
5741
|
+
{
|
|
5742
|
+
type: "date",
|
|
5743
|
+
value: value instanceof Date ? value.toISOString().split("T")[0] : value ?? "",
|
|
5744
|
+
onChange: (e) => onChange(e.target.value ? new Date(e.target.value) : null),
|
|
5745
|
+
autoFocus: true,
|
|
5746
|
+
className: cn(
|
|
5747
|
+
"w-full px-base py-sm rounded-base border border-[var(--color-input)]",
|
|
5748
|
+
"bg-[var(--color-background)] text-sm font-regular leading-sm text-[var(--color-foreground)]",
|
|
5749
|
+
"focus:outline-none focus:ring-2 focus:ring-[var(--color-ring)]"
|
|
5750
|
+
)
|
|
5751
|
+
}
|
|
5752
|
+
),
|
|
5753
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
5754
|
+
"button",
|
|
5755
|
+
{
|
|
5756
|
+
type: "button",
|
|
5757
|
+
onClick: onSubmit,
|
|
5758
|
+
className: "self-end px-md py-sm text-sm font-medium leading-sm text-[var(--color-primary-foreground)] bg-[var(--color-primary)] rounded-base cursor-pointer hover:opacity-90 transition-opacity",
|
|
5759
|
+
children: "Apply"
|
|
5760
|
+
}
|
|
5761
|
+
)
|
|
5762
|
+
] });
|
|
5763
|
+
case "DateRange":
|
|
5764
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: cn("flex flex-col gap-base p-base", className), children: [
|
|
5765
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex items-center gap-base", children: [
|
|
5766
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
5767
|
+
"input",
|
|
5768
|
+
{
|
|
5769
|
+
type: "date",
|
|
5770
|
+
autoFocus: true,
|
|
5771
|
+
className: cn(
|
|
5772
|
+
"flex-1 px-base py-sm rounded-base border border-[var(--color-input)]",
|
|
5773
|
+
"bg-[var(--color-background)] text-sm font-regular leading-sm text-[var(--color-foreground)]",
|
|
5774
|
+
"focus:outline-none focus:ring-2 focus:ring-[var(--color-ring)]"
|
|
5775
|
+
)
|
|
5776
|
+
}
|
|
5777
|
+
),
|
|
5778
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "text-sm text-[var(--color-muted-foreground)]", children: "to" }),
|
|
5779
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
5780
|
+
"input",
|
|
5781
|
+
{
|
|
5782
|
+
type: "date",
|
|
5783
|
+
className: cn(
|
|
5784
|
+
"flex-1 px-base py-sm rounded-base border border-[var(--color-input)]",
|
|
5785
|
+
"bg-[var(--color-background)] text-sm font-regular leading-sm text-[var(--color-foreground)]",
|
|
5786
|
+
"focus:outline-none focus:ring-2 focus:ring-[var(--color-ring)]"
|
|
5787
|
+
)
|
|
5788
|
+
}
|
|
5789
|
+
)
|
|
5790
|
+
] }),
|
|
5791
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
5792
|
+
"button",
|
|
5793
|
+
{
|
|
5794
|
+
type: "button",
|
|
5795
|
+
onClick: onSubmit,
|
|
5796
|
+
className: "self-end px-md py-sm text-sm font-medium leading-sm text-[var(--color-primary-foreground)] bg-[var(--color-primary)] rounded-base cursor-pointer hover:opacity-90 transition-opacity",
|
|
5797
|
+
children: "Apply"
|
|
5798
|
+
}
|
|
5799
|
+
)
|
|
5800
|
+
] });
|
|
5801
|
+
case "RelationPicker":
|
|
5802
|
+
case "MultiRelationPicker":
|
|
5803
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: cn("flex flex-col gap-base p-base", className), children: [
|
|
5804
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
5805
|
+
"input",
|
|
5806
|
+
{
|
|
5807
|
+
type: "text",
|
|
5808
|
+
value: value ?? "",
|
|
5809
|
+
onChange: (e) => onChange(e.target.value),
|
|
5810
|
+
onKeyDown: handleKeyDown,
|
|
5811
|
+
placeholder: "Search...",
|
|
5812
|
+
autoFocus: true,
|
|
5813
|
+
className: cn(
|
|
5814
|
+
"w-full px-base py-sm rounded-base border border-[var(--color-input)]",
|
|
5815
|
+
"bg-[var(--color-background)] text-sm font-regular leading-sm text-[var(--color-foreground)]",
|
|
5816
|
+
"placeholder:text-[var(--color-muted-foreground)]",
|
|
5817
|
+
"focus:outline-none focus:ring-2 focus:ring-[var(--color-ring)]"
|
|
5818
|
+
)
|
|
5819
|
+
}
|
|
5820
|
+
),
|
|
5821
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
5822
|
+
"button",
|
|
5823
|
+
{
|
|
5824
|
+
type: "button",
|
|
5825
|
+
onClick: onSubmit,
|
|
5826
|
+
className: "self-end px-md py-sm text-sm font-medium leading-sm text-[var(--color-primary-foreground)] bg-[var(--color-primary)] rounded-base cursor-pointer hover:opacity-90 transition-opacity",
|
|
5827
|
+
children: "Apply"
|
|
5828
|
+
}
|
|
5829
|
+
)
|
|
5830
|
+
] });
|
|
5831
|
+
default:
|
|
5832
|
+
return null;
|
|
5833
|
+
}
|
|
5834
|
+
};
|
|
5835
|
+
ValueInput.displayName = "ValueInput";
|
|
5836
|
+
|
|
5837
|
+
// src/components/ui/filter/property-selector.tsx
|
|
5838
|
+
var React40 = __toESM(require("react"));
|
|
5839
|
+
var PopoverPrimitive5 = __toESM(require("@radix-ui/react-popover"));
|
|
5840
|
+
var import_icons27 = require("@l3mpire/icons");
|
|
5841
|
+
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
5842
|
+
var PropertySelector = ({
|
|
5843
|
+
properties,
|
|
5844
|
+
onSelect,
|
|
5845
|
+
open,
|
|
5846
|
+
onOpenChange,
|
|
5847
|
+
children
|
|
5848
|
+
}) => {
|
|
5849
|
+
const [activeGroup, setActiveGroup] = React40.useState(null);
|
|
5850
|
+
const [search, setSearch] = React40.useState("");
|
|
5851
|
+
React40.useEffect(() => {
|
|
5852
|
+
if (!open) {
|
|
5853
|
+
setActiveGroup(null);
|
|
5854
|
+
setSearch("");
|
|
5855
|
+
}
|
|
5856
|
+
}, [open]);
|
|
5857
|
+
const groups = React40.useMemo(() => {
|
|
5858
|
+
const map = /* @__PURE__ */ new Map();
|
|
5859
|
+
for (const prop of properties) {
|
|
5860
|
+
const existing = map.get(prop.group);
|
|
5861
|
+
if (existing) {
|
|
5862
|
+
existing.count++;
|
|
5863
|
+
} else {
|
|
5864
|
+
map.set(prop.group, {
|
|
5865
|
+
group: prop.group,
|
|
5866
|
+
groupLabel: prop.groupLabel,
|
|
5867
|
+
groupIcon: prop.icon,
|
|
5868
|
+
count: 1
|
|
5869
|
+
});
|
|
5870
|
+
}
|
|
5871
|
+
}
|
|
5872
|
+
return Array.from(map.values());
|
|
5873
|
+
}, [properties]);
|
|
5874
|
+
const filteredProperties = React40.useMemo(() => {
|
|
5875
|
+
if (!activeGroup) return [];
|
|
5876
|
+
const groupProps = properties.filter((p) => p.group === activeGroup);
|
|
5877
|
+
if (!search) return groupProps;
|
|
5878
|
+
const lower = search.toLowerCase();
|
|
5879
|
+
return groupProps.filter((p) => p.label.toLowerCase().includes(lower));
|
|
5880
|
+
}, [properties, activeGroup, search]);
|
|
5881
|
+
const activeGroupInfo = groups.find((g) => g.group === activeGroup);
|
|
5882
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(PopoverPrimitive5.Root, { open, onOpenChange, children: [
|
|
5883
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(PopoverPrimitive5.Trigger, { asChild: true, children }),
|
|
5884
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(PopoverPrimitive5.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
5885
|
+
PopoverPrimitive5.Content,
|
|
5886
|
+
{
|
|
5887
|
+
sideOffset: 4,
|
|
5888
|
+
align: "start",
|
|
5889
|
+
className: cn(
|
|
5890
|
+
"z-50 flex flex-col gap-xs overflow-clip p-xs",
|
|
5891
|
+
"bg-[var(--color-dropdown-bg)] border border-[var(--color-dropdown-border)] rounded-md shadow-lg",
|
|
5892
|
+
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
5893
|
+
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
|
5894
|
+
"data-[side=bottom]:slide-in-from-top-2",
|
|
5895
|
+
"min-w-[230px]"
|
|
5896
|
+
),
|
|
5897
|
+
children: activeGroup === null ? (
|
|
5898
|
+
/* ── Level 1: Categories ─────────────────────────────────── */
|
|
5899
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "flex flex-col", children: groups.map((g) => /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
5900
|
+
"button",
|
|
5901
|
+
{
|
|
5902
|
+
type: "button",
|
|
5903
|
+
onClick: () => setActiveGroup(g.group),
|
|
5904
|
+
className: "flex items-center gap-base p-base rounded-base cursor-pointer transition-colors hover:bg-[var(--color-dropdown-item-hover)]",
|
|
5905
|
+
children: [
|
|
5906
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
5907
|
+
import_icons27.Icon,
|
|
5908
|
+
{
|
|
5909
|
+
icon: g.groupIcon,
|
|
5910
|
+
size: "sm",
|
|
5911
|
+
className: "shrink-0 text-[var(--color-dropdown-item-icon)]"
|
|
5912
|
+
}
|
|
5913
|
+
),
|
|
5914
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "flex-1 text-sm font-regular leading-sm text-[var(--color-dropdown-item-text)] text-left truncate", children: g.groupLabel }),
|
|
5915
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "text-xs font-medium leading-xs text-[var(--color-muted-foreground)]", children: g.count }),
|
|
5916
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
5917
|
+
import_icons27.Icon,
|
|
5918
|
+
{
|
|
5919
|
+
icon: import_icons27.faChevronRightOutline,
|
|
5920
|
+
size: "xs",
|
|
5921
|
+
className: "shrink-0 text-[var(--color-dropdown-item-icon)]"
|
|
5922
|
+
}
|
|
5923
|
+
)
|
|
5924
|
+
]
|
|
5925
|
+
},
|
|
5926
|
+
g.group
|
|
5927
|
+
)) })
|
|
5928
|
+
) : (
|
|
5929
|
+
/* ── Level 2: Properties ─────────────────────────────────── */
|
|
5930
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "flex flex-col gap-xs", children: [
|
|
5931
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
5932
|
+
"button",
|
|
5933
|
+
{
|
|
5934
|
+
type: "button",
|
|
5935
|
+
onClick: () => {
|
|
5936
|
+
setActiveGroup(null);
|
|
5937
|
+
setSearch("");
|
|
5938
|
+
},
|
|
5939
|
+
className: "flex items-center gap-base p-base rounded-base cursor-pointer transition-colors hover:bg-[var(--color-dropdown-item-hover)]",
|
|
5940
|
+
children: [
|
|
5941
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
5942
|
+
import_icons27.Icon,
|
|
5943
|
+
{
|
|
5944
|
+
icon: import_icons27.faChevronLeftOutline,
|
|
5945
|
+
size: "sm",
|
|
5946
|
+
className: "shrink-0 text-[var(--color-dropdown-item-icon)]"
|
|
5947
|
+
}
|
|
5948
|
+
),
|
|
5949
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "flex-1 text-xs font-medium leading-xs text-[var(--color-muted-foreground)] text-left truncate", children: activeGroupInfo?.groupLabel })
|
|
5950
|
+
]
|
|
5951
|
+
}
|
|
5952
|
+
),
|
|
5953
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "flex items-center gap-base px-md py-base border border-[var(--color-input)] rounded-md", children: [
|
|
5954
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
5955
|
+
import_icons27.Icon,
|
|
5956
|
+
{
|
|
5957
|
+
icon: import_icons27.faMagnifyingGlassOutline,
|
|
5958
|
+
size: "sm",
|
|
5959
|
+
className: "shrink-0 text-[var(--color-muted-foreground)]"
|
|
5960
|
+
}
|
|
5961
|
+
),
|
|
5962
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
5963
|
+
"input",
|
|
5964
|
+
{
|
|
5965
|
+
type: "text",
|
|
5966
|
+
value: search,
|
|
5967
|
+
onChange: (e) => setSearch(e.target.value),
|
|
5968
|
+
placeholder: "Search...",
|
|
5969
|
+
autoFocus: true,
|
|
5970
|
+
className: "flex-1 text-sm font-regular leading-sm text-[var(--color-foreground)] bg-transparent outline-none placeholder:text-[var(--color-muted-foreground)]"
|
|
5971
|
+
}
|
|
5972
|
+
)
|
|
5973
|
+
] }),
|
|
5974
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "flex flex-col max-h-[300px] overflow-y-auto", children: [
|
|
5975
|
+
filteredProperties.map((prop) => /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
5976
|
+
"button",
|
|
5977
|
+
{
|
|
5978
|
+
type: "button",
|
|
5979
|
+
onClick: () => {
|
|
5980
|
+
onSelect(prop);
|
|
5981
|
+
onOpenChange?.(false);
|
|
5982
|
+
},
|
|
5983
|
+
className: "flex items-center gap-base p-base rounded-base cursor-pointer transition-colors hover:bg-[var(--color-dropdown-item-hover)]",
|
|
5984
|
+
children: [
|
|
5985
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
5986
|
+
import_icons27.Icon,
|
|
5987
|
+
{
|
|
5988
|
+
icon: prop.icon,
|
|
5989
|
+
size: "sm",
|
|
5990
|
+
className: "shrink-0 text-[var(--color-dropdown-item-icon)]"
|
|
5991
|
+
}
|
|
5992
|
+
),
|
|
5993
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "flex-1 text-sm font-regular leading-sm text-[var(--color-dropdown-item-text)] text-left truncate", children: prop.label })
|
|
5994
|
+
]
|
|
5995
|
+
},
|
|
5996
|
+
prop.id
|
|
5997
|
+
)),
|
|
5998
|
+
filteredProperties.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "p-base text-sm text-[var(--color-muted-foreground)]", children: "No results" })
|
|
5999
|
+
] })
|
|
6000
|
+
] })
|
|
6001
|
+
)
|
|
6002
|
+
}
|
|
6003
|
+
) })
|
|
6004
|
+
] });
|
|
6005
|
+
};
|
|
6006
|
+
PropertySelector.displayName = "PropertySelector";
|
|
6007
|
+
|
|
6008
|
+
// src/components/ui/filter/kebab-menu.tsx
|
|
6009
|
+
var PopoverPrimitive6 = __toESM(require("@radix-ui/react-popover"));
|
|
6010
|
+
var import_icons28 = require("@l3mpire/icons");
|
|
6011
|
+
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
6012
|
+
var KebabMenu = ({
|
|
6013
|
+
onConvertToAdvanced,
|
|
6014
|
+
onDelete,
|
|
6015
|
+
open,
|
|
6016
|
+
onOpenChange,
|
|
6017
|
+
children
|
|
6018
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(PopoverPrimitive6.Root, { open, onOpenChange, children: [
|
|
6019
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(PopoverPrimitive6.Trigger, { asChild: true, children }),
|
|
6020
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(PopoverPrimitive6.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
|
|
6021
|
+
PopoverPrimitive6.Content,
|
|
6022
|
+
{
|
|
6023
|
+
sideOffset: 4,
|
|
6024
|
+
align: "end",
|
|
6025
|
+
className: cn(
|
|
6026
|
+
"z-50 flex flex-col p-xs overflow-clip",
|
|
6027
|
+
"bg-[var(--color-dropdown-bg)] border border-[var(--color-dropdown-border)] rounded-md shadow-lg",
|
|
6028
|
+
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
6029
|
+
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
|
6030
|
+
"data-[side=bottom]:slide-in-from-top-2",
|
|
6031
|
+
"min-w-[210px]"
|
|
6032
|
+
),
|
|
6033
|
+
children: [
|
|
6034
|
+
onConvertToAdvanced && /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
|
|
6035
|
+
"button",
|
|
6036
|
+
{
|
|
6037
|
+
type: "button",
|
|
6038
|
+
onClick: () => {
|
|
6039
|
+
onConvertToAdvanced();
|
|
6040
|
+
onOpenChange?.(false);
|
|
6041
|
+
},
|
|
6042
|
+
className: "flex items-center gap-base p-base rounded-base cursor-pointer transition-colors hover:bg-[var(--color-dropdown-item-hover)]",
|
|
6043
|
+
children: [
|
|
6044
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
6045
|
+
import_icons28.Icon,
|
|
6046
|
+
{
|
|
6047
|
+
icon: import_icons28.faArrowRightOutline,
|
|
6048
|
+
size: "sm",
|
|
6049
|
+
className: "shrink-0 text-[var(--color-dropdown-item-icon)]"
|
|
6050
|
+
}
|
|
6051
|
+
),
|
|
6052
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "text-sm font-regular leading-sm text-[var(--color-dropdown-item-text)]", children: "Convert to advanced" })
|
|
6053
|
+
]
|
|
6054
|
+
}
|
|
6055
|
+
),
|
|
6056
|
+
onConvertToAdvanced && onDelete && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "h-px mx-base my-xs bg-[var(--color-border)]" }),
|
|
6057
|
+
onDelete && /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
|
|
6058
|
+
"button",
|
|
6059
|
+
{
|
|
6060
|
+
type: "button",
|
|
6061
|
+
onClick: () => {
|
|
6062
|
+
onDelete();
|
|
6063
|
+
onOpenChange?.(false);
|
|
6064
|
+
},
|
|
6065
|
+
className: "flex items-center gap-base p-base rounded-base cursor-pointer transition-colors hover:bg-[var(--color-dropdown-item-hover)]",
|
|
6066
|
+
children: [
|
|
6067
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
6068
|
+
import_icons28.Icon,
|
|
6069
|
+
{
|
|
6070
|
+
icon: import_icons28.faTrashOutline,
|
|
6071
|
+
size: "sm",
|
|
6072
|
+
className: "shrink-0 text-[var(--color-destructive)]"
|
|
6073
|
+
}
|
|
6074
|
+
),
|
|
6075
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "text-sm font-regular leading-sm text-[var(--color-destructive)]", children: "Delete filter" })
|
|
6076
|
+
]
|
|
6077
|
+
}
|
|
6078
|
+
)
|
|
6079
|
+
]
|
|
6080
|
+
}
|
|
6081
|
+
) })
|
|
6082
|
+
] });
|
|
6083
|
+
KebabMenu.displayName = "KebabMenu";
|
|
6084
|
+
|
|
6085
|
+
// src/components/ui/filter/filter-editor.tsx
|
|
6086
|
+
var React41 = __toESM(require("react"));
|
|
6087
|
+
var PopoverPrimitive7 = __toESM(require("@radix-ui/react-popover"));
|
|
6088
|
+
var import_icons29 = require("@l3mpire/icons");
|
|
6089
|
+
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
6090
|
+
var FilterEditor = ({
|
|
6091
|
+
propertyDef,
|
|
6092
|
+
condition,
|
|
6093
|
+
mode,
|
|
6094
|
+
onUpdate,
|
|
6095
|
+
onClose,
|
|
6096
|
+
open,
|
|
6097
|
+
onOpenChange,
|
|
6098
|
+
children
|
|
6099
|
+
}) => {
|
|
6100
|
+
const [view, setView] = React41.useState(
|
|
6101
|
+
mode === "add" ? "value" : "operator"
|
|
6102
|
+
);
|
|
6103
|
+
const [localOperator, setLocalOperator] = React41.useState(
|
|
6104
|
+
condition.operator
|
|
6105
|
+
);
|
|
6106
|
+
const [localValue, setLocalValue] = React41.useState(
|
|
6107
|
+
condition.value
|
|
6108
|
+
);
|
|
6109
|
+
React41.useEffect(() => {
|
|
6110
|
+
if (open) {
|
|
6111
|
+
setView(mode === "add" ? "value" : "operator");
|
|
6112
|
+
setLocalOperator(condition.operator);
|
|
6113
|
+
setLocalValue(condition.value);
|
|
6114
|
+
}
|
|
6115
|
+
}, [open, mode, condition.operator, condition.value]);
|
|
6116
|
+
const handleOperatorSelect = (op) => {
|
|
6117
|
+
setLocalOperator(op);
|
|
6118
|
+
if (isNoValueOperator(op)) {
|
|
6119
|
+
onUpdate({ ...condition, operator: op, value: null });
|
|
6120
|
+
onOpenChange?.(false);
|
|
6121
|
+
onClose();
|
|
6122
|
+
} else {
|
|
6123
|
+
if (op !== localOperator) {
|
|
6124
|
+
setLocalValue(null);
|
|
6125
|
+
}
|
|
6126
|
+
setView("value");
|
|
6127
|
+
}
|
|
6128
|
+
};
|
|
6129
|
+
const handleSubmit = () => {
|
|
6130
|
+
onUpdate({ ...condition, operator: localOperator, value: localValue });
|
|
6131
|
+
onOpenChange?.(false);
|
|
6132
|
+
onClose();
|
|
6133
|
+
};
|
|
6134
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(PopoverPrimitive7.Root, { open, onOpenChange, children: [
|
|
6135
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(PopoverPrimitive7.Trigger, { asChild: true, children }),
|
|
6136
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(PopoverPrimitive7.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
|
|
6137
|
+
PopoverPrimitive7.Content,
|
|
6138
|
+
{
|
|
6139
|
+
sideOffset: 4,
|
|
6140
|
+
align: "start",
|
|
6141
|
+
className: cn(
|
|
6142
|
+
"z-50 flex flex-col overflow-clip",
|
|
6143
|
+
"bg-[var(--color-dropdown-bg)] border border-[var(--color-dropdown-border)] rounded-md shadow-lg",
|
|
6144
|
+
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
6145
|
+
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
|
6146
|
+
"data-[side=bottom]:slide-in-from-top-2",
|
|
6147
|
+
"min-w-[240px]"
|
|
6148
|
+
),
|
|
6149
|
+
children: [
|
|
6150
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex items-center gap-base px-base pt-base pb-xs border-b border-[var(--color-border)]", children: [
|
|
6151
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
6152
|
+
import_icons29.Icon,
|
|
6153
|
+
{
|
|
6154
|
+
icon: propertyDef.icon,
|
|
6155
|
+
size: "sm",
|
|
6156
|
+
className: "shrink-0 text-[var(--color-dropdown-item-icon)]"
|
|
6157
|
+
}
|
|
6158
|
+
),
|
|
6159
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "text-sm font-medium leading-sm text-[var(--color-foreground)]", children: propertyDef.label }),
|
|
6160
|
+
localOperator && view === "value" && /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
|
|
6161
|
+
"button",
|
|
6162
|
+
{
|
|
6163
|
+
type: "button",
|
|
6164
|
+
onClick: () => setView("operator"),
|
|
6165
|
+
className: "ml-auto text-xs font-regular text-[var(--color-muted-foreground)] hover:text-[var(--color-foreground)] cursor-pointer transition-colors",
|
|
6166
|
+
children: [
|
|
6167
|
+
localOperator,
|
|
6168
|
+
" \u25BE"
|
|
6169
|
+
]
|
|
6170
|
+
}
|
|
6171
|
+
)
|
|
6172
|
+
] }),
|
|
6173
|
+
view === "operator" ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "p-xs", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
6174
|
+
OperatorList,
|
|
6175
|
+
{
|
|
6176
|
+
dataType: propertyDef.type,
|
|
6177
|
+
activeOperator: localOperator,
|
|
6178
|
+
onSelect: handleOperatorSelect
|
|
6179
|
+
}
|
|
6180
|
+
) }) : localOperator && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
6181
|
+
ValueInput,
|
|
6182
|
+
{
|
|
6183
|
+
dataType: propertyDef.type,
|
|
6184
|
+
operator: localOperator,
|
|
6185
|
+
value: localValue,
|
|
6186
|
+
onChange: setLocalValue,
|
|
6187
|
+
onSubmit: handleSubmit,
|
|
6188
|
+
options: propertyDef.options
|
|
6189
|
+
}
|
|
6190
|
+
)
|
|
6191
|
+
]
|
|
6192
|
+
}
|
|
6193
|
+
) })
|
|
6194
|
+
] });
|
|
6195
|
+
};
|
|
6196
|
+
FilterEditor.displayName = "FilterEditor";
|
|
6197
|
+
|
|
6198
|
+
// src/components/ui/filter/interactive-filter-chip.tsx
|
|
6199
|
+
var React42 = __toESM(require("react"));
|
|
6200
|
+
var PopoverPrimitive8 = __toESM(require("@radix-ui/react-popover"));
|
|
6201
|
+
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
6202
|
+
function formatFilterValue(value) {
|
|
6203
|
+
if (value == null) return void 0;
|
|
6204
|
+
if (typeof value === "boolean") return value ? "Yes" : "No";
|
|
6205
|
+
if (value instanceof Date) {
|
|
6206
|
+
return value.toLocaleDateString("en-US", {
|
|
6207
|
+
month: "short",
|
|
6208
|
+
day: "numeric",
|
|
6209
|
+
year: "numeric"
|
|
6210
|
+
});
|
|
6211
|
+
}
|
|
6212
|
+
if (Array.isArray(value)) {
|
|
6213
|
+
if (value.length === 0) return void 0;
|
|
6214
|
+
if (value.length === 2 && typeof value[0] === "number") {
|
|
6215
|
+
return `${value[0]} \u2013 ${value[1]}`;
|
|
6216
|
+
}
|
|
6217
|
+
return value[0];
|
|
6218
|
+
}
|
|
6219
|
+
return String(value);
|
|
6220
|
+
}
|
|
6221
|
+
function getBadgeCount(value) {
|
|
6222
|
+
if (Array.isArray(value) && value.length > 1 && typeof value[0] === "string") {
|
|
6223
|
+
return value.length;
|
|
6224
|
+
}
|
|
6225
|
+
return void 0;
|
|
6226
|
+
}
|
|
6227
|
+
var SegmentPopover = ({
|
|
6228
|
+
open,
|
|
6229
|
+
onOpenChange,
|
|
6230
|
+
trigger,
|
|
6231
|
+
children,
|
|
6232
|
+
align = "start",
|
|
6233
|
+
minWidth = "240px"
|
|
6234
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(PopoverPrimitive8.Root, { open, onOpenChange, children: [
|
|
6235
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(PopoverPrimitive8.Trigger, { asChild: true, children: trigger }),
|
|
6236
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(PopoverPrimitive8.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
6237
|
+
PopoverPrimitive8.Content,
|
|
6238
|
+
{
|
|
6239
|
+
sideOffset: 4,
|
|
6240
|
+
align,
|
|
6241
|
+
className: cn(
|
|
6242
|
+
"z-50 flex flex-col overflow-clip",
|
|
6243
|
+
"bg-[var(--color-dropdown-bg)] border border-[var(--color-dropdown-border)] rounded-md shadow-lg",
|
|
6244
|
+
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
6245
|
+
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
|
6246
|
+
"data-[side=bottom]:slide-in-from-top-2"
|
|
6247
|
+
),
|
|
6248
|
+
style: { minWidth },
|
|
6249
|
+
children
|
|
6250
|
+
}
|
|
6251
|
+
) })
|
|
6252
|
+
] });
|
|
6253
|
+
var InteractiveFilterChip = ({
|
|
6254
|
+
propertyDef,
|
|
6255
|
+
condition,
|
|
6256
|
+
properties,
|
|
6257
|
+
mode = "edit",
|
|
6258
|
+
autoOpen = false,
|
|
6259
|
+
onUpdate,
|
|
6260
|
+
onPropertyChange,
|
|
6261
|
+
onDelete,
|
|
6262
|
+
onConvertToAdvanced,
|
|
6263
|
+
className
|
|
6264
|
+
}) => {
|
|
6265
|
+
const [operatorOpen, setOperatorOpen] = React42.useState(false);
|
|
6266
|
+
const [valueOpen, setValueOpen] = React42.useState(false);
|
|
6267
|
+
const [propertyOpen, setPropertyOpen] = React42.useState(false);
|
|
6268
|
+
const [kebabOpen, setKebabOpen] = React42.useState(false);
|
|
6269
|
+
React42.useEffect(() => {
|
|
6270
|
+
if (autoOpen && condition.operator && !isNoValueOperator(condition.operator)) {
|
|
6271
|
+
const t = setTimeout(() => setValueOpen(true), 50);
|
|
6272
|
+
return () => clearTimeout(t);
|
|
6273
|
+
}
|
|
6274
|
+
}, []);
|
|
6275
|
+
const handleOperatorSelect = (op) => {
|
|
6276
|
+
if (isNoValueOperator(op)) {
|
|
6277
|
+
onUpdate({ ...condition, operator: op, value: null });
|
|
6278
|
+
setOperatorOpen(false);
|
|
6279
|
+
} else {
|
|
6280
|
+
const resetValue = op !== condition.operator ? null : condition.value;
|
|
6281
|
+
onUpdate({ ...condition, operator: op, value: resetValue });
|
|
6282
|
+
setOperatorOpen(false);
|
|
6283
|
+
if (resetValue == null) {
|
|
6284
|
+
setTimeout(() => setValueOpen(true), 100);
|
|
6285
|
+
}
|
|
6286
|
+
}
|
|
6287
|
+
};
|
|
6288
|
+
const handleValueChange = (val) => {
|
|
6289
|
+
onUpdate({ ...condition, value: val });
|
|
6290
|
+
};
|
|
6291
|
+
const handleValueSubmit = () => {
|
|
6292
|
+
setValueOpen(false);
|
|
6293
|
+
};
|
|
6294
|
+
const hasOperator = !!condition.operator;
|
|
6295
|
+
const displayValue = formatFilterValue(condition.value);
|
|
6296
|
+
const hasValue = hasOperator && displayValue != null;
|
|
6297
|
+
const badgeCount = getBadgeCount(condition.value);
|
|
6298
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
|
|
6299
|
+
"div",
|
|
6300
|
+
{
|
|
6301
|
+
className: cn(
|
|
6302
|
+
"inline-flex items-center overflow-clip",
|
|
6303
|
+
"bg-filter-chip-bg border border-filter-chip-border rounded-md",
|
|
6304
|
+
className
|
|
6305
|
+
),
|
|
6306
|
+
children: [
|
|
6307
|
+
properties ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
6308
|
+
PropertySelector,
|
|
6309
|
+
{
|
|
6310
|
+
properties,
|
|
6311
|
+
onSelect: (prop) => {
|
|
6312
|
+
onPropertyChange?.(prop);
|
|
6313
|
+
setPropertyOpen(false);
|
|
6314
|
+
},
|
|
6315
|
+
open: propertyOpen,
|
|
6316
|
+
onOpenChange: setPropertyOpen,
|
|
6317
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
6318
|
+
FilterChipSegment,
|
|
6319
|
+
{
|
|
6320
|
+
segmentType: "property",
|
|
6321
|
+
hasBorder: true,
|
|
6322
|
+
icon: propertyDef.icon,
|
|
6323
|
+
label: propertyDef.label,
|
|
6324
|
+
onClick: () => setPropertyOpen(true)
|
|
6325
|
+
}
|
|
6326
|
+
) })
|
|
6327
|
+
}
|
|
6328
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
6329
|
+
FilterChipSegment,
|
|
6330
|
+
{
|
|
6331
|
+
segmentType: "property",
|
|
6332
|
+
hasBorder: true,
|
|
6333
|
+
icon: propertyDef.icon,
|
|
6334
|
+
label: propertyDef.label
|
|
6335
|
+
}
|
|
6336
|
+
),
|
|
6337
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
6338
|
+
SegmentPopover,
|
|
6339
|
+
{
|
|
6340
|
+
open: operatorOpen,
|
|
6341
|
+
onOpenChange: setOperatorOpen,
|
|
6342
|
+
minWidth: "180px",
|
|
6343
|
+
trigger: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
6344
|
+
FilterChipSegment,
|
|
6345
|
+
{
|
|
6346
|
+
segmentType: hasOperator ? "operator" : "placeholder",
|
|
6347
|
+
hasBorder: true,
|
|
6348
|
+
label: hasOperator ? condition.operator : "Select condition",
|
|
6349
|
+
onClick: () => setOperatorOpen(true)
|
|
6350
|
+
}
|
|
6351
|
+
) }),
|
|
6352
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "p-xs", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
6353
|
+
OperatorList,
|
|
6354
|
+
{
|
|
6355
|
+
dataType: propertyDef.type,
|
|
6356
|
+
activeOperator: condition.operator,
|
|
6357
|
+
onSelect: handleOperatorSelect
|
|
6358
|
+
}
|
|
6359
|
+
) })
|
|
6360
|
+
}
|
|
6361
|
+
),
|
|
6362
|
+
hasOperator && condition.operator && !isNoValueOperator(condition.operator) && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
6363
|
+
SegmentPopover,
|
|
6364
|
+
{
|
|
6365
|
+
open: valueOpen,
|
|
6366
|
+
onOpenChange: setValueOpen,
|
|
6367
|
+
minWidth: "240px",
|
|
6368
|
+
trigger: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
6369
|
+
FilterChipSegment,
|
|
6370
|
+
{
|
|
6371
|
+
segmentType: hasValue ? "value" : "placeholder",
|
|
6372
|
+
hasBorder: true,
|
|
6373
|
+
label: hasValue ? displayValue : "Enter value",
|
|
6374
|
+
badgeCount,
|
|
6375
|
+
onClick: () => setValueOpen(true)
|
|
6376
|
+
}
|
|
6377
|
+
) }),
|
|
6378
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
6379
|
+
ValueInput,
|
|
6380
|
+
{
|
|
6381
|
+
dataType: propertyDef.type,
|
|
6382
|
+
operator: condition.operator,
|
|
6383
|
+
value: condition.value,
|
|
6384
|
+
onChange: handleValueChange,
|
|
6385
|
+
onSubmit: handleValueSubmit,
|
|
6386
|
+
options: propertyDef.options
|
|
6387
|
+
}
|
|
6388
|
+
)
|
|
6389
|
+
}
|
|
6390
|
+
),
|
|
6391
|
+
hasOperator && condition.operator && isNoValueOperator(condition.operator) && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
6392
|
+
FilterChipSegment,
|
|
6393
|
+
{
|
|
6394
|
+
segmentType: "value",
|
|
6395
|
+
hasBorder: true,
|
|
6396
|
+
label: condition.operator
|
|
6397
|
+
}
|
|
6398
|
+
),
|
|
6399
|
+
hasOperator && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
6400
|
+
KebabMenu,
|
|
6401
|
+
{
|
|
6402
|
+
open: kebabOpen,
|
|
6403
|
+
onOpenChange: setKebabOpen,
|
|
6404
|
+
onConvertToAdvanced,
|
|
6405
|
+
onDelete,
|
|
6406
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
6407
|
+
FilterChipSegment,
|
|
6408
|
+
{
|
|
6409
|
+
segmentType: "button",
|
|
6410
|
+
onKebabClick: (e) => {
|
|
6411
|
+
e.stopPropagation();
|
|
6412
|
+
setKebabOpen(true);
|
|
6413
|
+
}
|
|
6414
|
+
}
|
|
6415
|
+
) })
|
|
6416
|
+
}
|
|
6417
|
+
)
|
|
6418
|
+
]
|
|
6419
|
+
}
|
|
6420
|
+
);
|
|
6421
|
+
};
|
|
6422
|
+
InteractiveFilterChip.displayName = "InteractiveFilterChip";
|
|
6423
|
+
|
|
6424
|
+
// src/components/ui/filter/filter-system.tsx
|
|
6425
|
+
var React46 = __toESM(require("react"));
|
|
6426
|
+
|
|
6427
|
+
// src/components/ui/filter/advanced-chip.tsx
|
|
6428
|
+
var React43 = __toESM(require("react"));
|
|
6429
|
+
var import_icons30 = require("@l3mpire/icons");
|
|
6430
|
+
var import_jsx_runtime46 = require("react/jsx-runtime");
|
|
6431
|
+
var AdvancedChip = React43.forwardRef(
|
|
6432
|
+
({ className, count, onClear, onClick, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
|
|
6433
|
+
"div",
|
|
6434
|
+
{
|
|
6435
|
+
className: cn(
|
|
6436
|
+
"inline-flex items-center overflow-clip",
|
|
6437
|
+
"bg-[var(--color-primary)]/5 border border-[var(--color-primary)]/30 rounded-md",
|
|
6438
|
+
className
|
|
6439
|
+
),
|
|
6440
|
+
children: [
|
|
6441
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
|
|
6442
|
+
"button",
|
|
6443
|
+
{
|
|
6444
|
+
ref,
|
|
6445
|
+
type: "button",
|
|
6446
|
+
onClick,
|
|
6447
|
+
className: "flex items-center gap-sm px-base py-sm cursor-pointer transition-colors hover:bg-[var(--color-primary)]/10",
|
|
6448
|
+
...props,
|
|
6449
|
+
children: [
|
|
6450
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "text-sm font-medium leading-sm whitespace-nowrap text-[var(--color-primary)]", children: "Advanced filter" }),
|
|
6451
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "flex items-center p-2xs rounded-xs bg-filter-chip-badge-bg", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "text-[10px] font-medium leading-2xs text-filter-chip-badge-text", children: count }) })
|
|
6452
|
+
]
|
|
6453
|
+
}
|
|
6454
|
+
),
|
|
6455
|
+
onClear && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_jsx_runtime46.Fragment, { children: [
|
|
6456
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "w-px h-4 bg-[var(--color-primary)]/20" }),
|
|
6457
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
6458
|
+
"button",
|
|
6459
|
+
{
|
|
6460
|
+
type: "button",
|
|
6461
|
+
onClick: (e) => {
|
|
6462
|
+
e.stopPropagation();
|
|
6463
|
+
onClear();
|
|
6464
|
+
},
|
|
6465
|
+
className: "flex items-center justify-center p-sm cursor-pointer transition-colors hover:bg-[var(--color-primary)]/10",
|
|
6466
|
+
"aria-label": "Clear all advanced filters",
|
|
6467
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_icons30.Icon, { icon: import_icons30.faXmarkOutline, size: "xs", className: "text-[var(--color-primary)]" })
|
|
6468
|
+
}
|
|
6469
|
+
)
|
|
6470
|
+
] })
|
|
6471
|
+
]
|
|
6472
|
+
}
|
|
6473
|
+
)
|
|
6474
|
+
);
|
|
6475
|
+
AdvancedChip.displayName = "AdvancedChip";
|
|
6476
|
+
|
|
6477
|
+
// src/components/ui/filter/advanced-popover.tsx
|
|
6478
|
+
var React45 = __toESM(require("react"));
|
|
6479
|
+
var PopoverPrimitive10 = __toESM(require("@radix-ui/react-popover"));
|
|
6480
|
+
|
|
6481
|
+
// src/components/ui/filter/advanced-row.tsx
|
|
6482
|
+
var React44 = __toESM(require("react"));
|
|
6483
|
+
var PopoverPrimitive9 = __toESM(require("@radix-ui/react-popover"));
|
|
6484
|
+
var import_icons31 = require("@l3mpire/icons");
|
|
6485
|
+
var import_jsx_runtime47 = require("react/jsx-runtime");
|
|
6486
|
+
var AdvancedRow = ({
|
|
6487
|
+
connector,
|
|
6488
|
+
propertyDef,
|
|
6489
|
+
condition,
|
|
6490
|
+
properties,
|
|
6491
|
+
onUpdate,
|
|
6492
|
+
onPropertyChange,
|
|
6493
|
+
onDelete
|
|
6494
|
+
}) => {
|
|
6495
|
+
const [operatorOpen, setOperatorOpen] = React44.useState(false);
|
|
6496
|
+
const [valueOpen, setValueOpen] = React44.useState(false);
|
|
6497
|
+
const [propertyOpen, setPropertyOpen] = React44.useState(false);
|
|
6498
|
+
const handleOperatorSelect = (op) => {
|
|
6499
|
+
if (isNoValueOperator(op)) {
|
|
6500
|
+
onUpdate({ ...condition, operator: op, value: null });
|
|
6501
|
+
} else {
|
|
6502
|
+
const resetValue = op !== condition.operator ? null : condition.value;
|
|
6503
|
+
onUpdate({ ...condition, operator: op, value: resetValue });
|
|
6504
|
+
}
|
|
6505
|
+
setOperatorOpen(false);
|
|
6506
|
+
};
|
|
6507
|
+
const handleValueChange = (val) => {
|
|
6508
|
+
onUpdate({ ...condition, value: val });
|
|
6509
|
+
};
|
|
6510
|
+
const displayValue = condition.value == null ? "" : typeof condition.value === "string" ? condition.value : String(condition.value);
|
|
6511
|
+
const groupedProps = React44.useMemo(() => {
|
|
6512
|
+
const map = /* @__PURE__ */ new Map();
|
|
6513
|
+
for (const p of properties) {
|
|
6514
|
+
const arr = map.get(p.group) ?? [];
|
|
6515
|
+
arr.push(p);
|
|
6516
|
+
map.set(p.group, arr);
|
|
6517
|
+
}
|
|
6518
|
+
return map;
|
|
6519
|
+
}, [properties]);
|
|
6520
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "group flex items-center gap-base py-xs", children: [
|
|
6521
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
6522
|
+
"span",
|
|
6523
|
+
{
|
|
6524
|
+
className: cn(
|
|
6525
|
+
"shrink-0 w-[52px] text-xs font-medium leading-xs text-right",
|
|
6526
|
+
connector === "Where" ? "text-[var(--color-muted-foreground)]" : "text-[var(--color-muted-foreground)]"
|
|
6527
|
+
),
|
|
6528
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("span", { className: "flex items-center justify-end gap-2xs", children: [
|
|
6529
|
+
connector,
|
|
6530
|
+
connector === "And" && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_icons31.Icon, { icon: import_icons31.faRefreshOutline, size: "xs", className: "text-[var(--color-muted-foreground)]" })
|
|
6531
|
+
] })
|
|
6532
|
+
}
|
|
6533
|
+
),
|
|
6534
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(PopoverPrimitive9.Root, { open: propertyOpen, onOpenChange: setPropertyOpen, children: [
|
|
6535
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(PopoverPrimitive9.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
|
|
6536
|
+
"button",
|
|
6537
|
+
{
|
|
6538
|
+
type: "button",
|
|
6539
|
+
className: "flex items-center gap-xs px-base py-sm rounded-base border border-[var(--color-input)] bg-[var(--color-background)] cursor-pointer hover:bg-[var(--color-accent)] transition-colors",
|
|
6540
|
+
children: [
|
|
6541
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_icons31.Icon, { icon: propertyDef.icon, size: "xs", className: "text-[var(--color-muted-foreground)]" }),
|
|
6542
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("span", { className: "text-sm font-regular leading-sm text-[var(--color-foreground)] whitespace-nowrap", children: [
|
|
6543
|
+
propertyDef.groupLabel,
|
|
6544
|
+
" \u203A ",
|
|
6545
|
+
propertyDef.label
|
|
6546
|
+
] }),
|
|
6547
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("svg", { width: "10", height: "10", viewBox: "0 0 10 10", fill: "currentColor", className: "text-[var(--color-muted-foreground)]", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("path", { d: "M2.5 4L5 6.5L7.5 4", stroke: "currentColor", strokeWidth: "1.2", fill: "none", strokeLinecap: "round" }) })
|
|
6548
|
+
]
|
|
6549
|
+
}
|
|
6550
|
+
) }),
|
|
6551
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(PopoverPrimitive9.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
6552
|
+
PopoverPrimitive9.Content,
|
|
6553
|
+
{
|
|
6554
|
+
sideOffset: 4,
|
|
6555
|
+
align: "start",
|
|
6556
|
+
className: cn(
|
|
6557
|
+
"z-50 flex flex-col p-xs overflow-clip max-h-[300px] overflow-y-auto",
|
|
6558
|
+
"bg-[var(--color-dropdown-bg)] border border-[var(--color-dropdown-border)] rounded-md shadow-lg",
|
|
6559
|
+
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
6560
|
+
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0",
|
|
6561
|
+
"min-w-[200px]"
|
|
6562
|
+
),
|
|
6563
|
+
children: Array.from(groupedProps.entries()).map(([group, props]) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "flex flex-col", children: props.map((p) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
|
|
6564
|
+
"button",
|
|
6565
|
+
{
|
|
6566
|
+
type: "button",
|
|
6567
|
+
onClick: () => {
|
|
6568
|
+
onPropertyChange(p);
|
|
6569
|
+
setPropertyOpen(false);
|
|
6570
|
+
},
|
|
6571
|
+
className: cn(
|
|
6572
|
+
"flex items-center gap-base p-base rounded-base cursor-pointer transition-colors text-left",
|
|
6573
|
+
"hover:bg-[var(--color-dropdown-item-hover)]",
|
|
6574
|
+
p.id === condition.propertyId && "bg-[var(--color-dropdown-item-hover)]"
|
|
6575
|
+
),
|
|
6576
|
+
children: [
|
|
6577
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_icons31.Icon, { icon: p.icon, size: "sm", className: "shrink-0 text-[var(--color-dropdown-item-icon)]" }),
|
|
6578
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "text-sm font-regular leading-sm text-[var(--color-dropdown-item-text)] truncate", children: p.label })
|
|
6579
|
+
]
|
|
6580
|
+
},
|
|
6581
|
+
p.id
|
|
6582
|
+
)) }, group))
|
|
6583
|
+
}
|
|
6584
|
+
) })
|
|
6585
|
+
] }),
|
|
6586
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(PopoverPrimitive9.Root, { open: operatorOpen, onOpenChange: setOperatorOpen, children: [
|
|
6587
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(PopoverPrimitive9.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
|
|
6588
|
+
"button",
|
|
6589
|
+
{
|
|
6590
|
+
type: "button",
|
|
6591
|
+
className: "flex items-center gap-xs px-base py-sm rounded-base border border-[var(--color-input)] bg-[var(--color-background)] cursor-pointer hover:bg-[var(--color-accent)] transition-colors",
|
|
6592
|
+
children: [
|
|
6593
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "text-sm font-regular leading-sm text-[var(--color-foreground)] whitespace-nowrap", children: condition.operator ?? "select" }),
|
|
6594
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("svg", { width: "10", height: "10", viewBox: "0 0 10 10", fill: "currentColor", className: "text-[var(--color-muted-foreground)]", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("path", { d: "M2.5 4L5 6.5L7.5 4", stroke: "currentColor", strokeWidth: "1.2", fill: "none", strokeLinecap: "round" }) })
|
|
6595
|
+
]
|
|
6596
|
+
}
|
|
6597
|
+
) }),
|
|
6598
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(PopoverPrimitive9.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
6599
|
+
PopoverPrimitive9.Content,
|
|
6600
|
+
{
|
|
6601
|
+
sideOffset: 4,
|
|
6602
|
+
align: "start",
|
|
6603
|
+
className: cn(
|
|
6604
|
+
"z-50 flex flex-col p-xs overflow-clip",
|
|
6605
|
+
"bg-[var(--color-dropdown-bg)] border border-[var(--color-dropdown-border)] rounded-md shadow-lg",
|
|
6606
|
+
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
6607
|
+
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0",
|
|
6608
|
+
"min-w-[160px]"
|
|
6609
|
+
),
|
|
6610
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
6611
|
+
OperatorList,
|
|
6612
|
+
{
|
|
6613
|
+
dataType: propertyDef.type,
|
|
6614
|
+
activeOperator: condition.operator,
|
|
6615
|
+
onSelect: handleOperatorSelect
|
|
6616
|
+
}
|
|
6617
|
+
)
|
|
6618
|
+
}
|
|
6619
|
+
) })
|
|
6620
|
+
] }),
|
|
6621
|
+
condition.operator && !isNoValueOperator(condition.operator) && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
6622
|
+
"input",
|
|
6623
|
+
{
|
|
6624
|
+
type: "text",
|
|
6625
|
+
value: displayValue,
|
|
6626
|
+
onChange: (e) => handleValueChange(e.target.value),
|
|
6627
|
+
placeholder: "Enter value...",
|
|
6628
|
+
className: cn(
|
|
6629
|
+
"flex-1 min-w-[100px] px-base py-sm rounded-base border border-[var(--color-input)]",
|
|
6630
|
+
"bg-[var(--color-background)] text-sm font-regular leading-sm text-[var(--color-foreground)]",
|
|
6631
|
+
"placeholder:text-[var(--color-muted-foreground)]",
|
|
6632
|
+
"focus:outline-none focus:ring-2 focus:ring-[var(--color-ring)] focus:ring-offset-0"
|
|
6633
|
+
)
|
|
6634
|
+
}
|
|
6635
|
+
),
|
|
6636
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
6637
|
+
"button",
|
|
6638
|
+
{
|
|
6639
|
+
type: "button",
|
|
6640
|
+
onClick: onDelete,
|
|
6641
|
+
className: "shrink-0 flex items-center justify-center p-sm rounded-base opacity-0 group-hover:opacity-100 cursor-pointer transition-opacity hover:bg-[var(--color-accent)]",
|
|
6642
|
+
"aria-label": "Remove filter",
|
|
6643
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_icons31.Icon, { icon: import_icons31.faEllipsisVerticalOutline, size: "sm", className: "text-[var(--color-muted-foreground)]" })
|
|
6644
|
+
}
|
|
6645
|
+
)
|
|
6646
|
+
] });
|
|
6647
|
+
};
|
|
6648
|
+
AdvancedRow.displayName = "AdvancedRow";
|
|
6649
|
+
|
|
6650
|
+
// src/components/ui/filter/advanced-popover.tsx
|
|
6651
|
+
var import_jsx_runtime48 = require("react/jsx-runtime");
|
|
6652
|
+
var AdvancedPopover = ({
|
|
6653
|
+
filters,
|
|
6654
|
+
properties,
|
|
6655
|
+
onFiltersChange,
|
|
6656
|
+
open,
|
|
6657
|
+
onOpenChange,
|
|
6658
|
+
children
|
|
6659
|
+
}) => {
|
|
6660
|
+
const [addSelectorOpen, setAddSelectorOpen] = React45.useState(false);
|
|
6661
|
+
const getPropertyDef = (propertyId) => properties.find((p) => p.id === propertyId);
|
|
6662
|
+
const handleUpdateFilter = (updated) => {
|
|
6663
|
+
onFiltersChange(filters.map((f) => f.id === updated.id ? updated : f));
|
|
6664
|
+
};
|
|
6665
|
+
const handleDeleteFilter = (id) => {
|
|
6666
|
+
onFiltersChange(filters.filter((f) => f.id !== id));
|
|
6667
|
+
};
|
|
6668
|
+
const handlePropertyChange = (filterId, newProp) => {
|
|
6669
|
+
const newCondition = createFilterWithDefaults(newProp.id, newProp.type);
|
|
6670
|
+
onFiltersChange(
|
|
6671
|
+
filters.map((f) => f.id === filterId ? { ...newCondition, id: filterId } : f)
|
|
6672
|
+
);
|
|
6673
|
+
};
|
|
6674
|
+
const handleAddFilter = (property) => {
|
|
6675
|
+
const newFilter = createFilterWithDefaults(property.id, property.type);
|
|
6676
|
+
onFiltersChange([...filters, newFilter]);
|
|
6677
|
+
setAddSelectorOpen(false);
|
|
6678
|
+
};
|
|
6679
|
+
const handleClearAll = () => {
|
|
6680
|
+
onFiltersChange([]);
|
|
6681
|
+
onOpenChange?.(false);
|
|
6682
|
+
};
|
|
6683
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(PopoverPrimitive10.Root, { open, onOpenChange, children: [
|
|
6684
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(PopoverPrimitive10.Trigger, { asChild: true, children }),
|
|
6685
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(PopoverPrimitive10.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
|
|
6686
|
+
PopoverPrimitive10.Content,
|
|
6687
|
+
{
|
|
6688
|
+
sideOffset: 4,
|
|
6689
|
+
align: "start",
|
|
6690
|
+
className: cn(
|
|
6691
|
+
"z-50 flex flex-col overflow-clip",
|
|
6692
|
+
"bg-[var(--color-dropdown-bg)] border border-[var(--color-dropdown-border)] rounded-md shadow-lg",
|
|
6693
|
+
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
6694
|
+
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
|
6695
|
+
"data-[side=bottom]:slide-in-from-top-2",
|
|
6696
|
+
"min-w-[520px] max-w-[90vw]"
|
|
6697
|
+
),
|
|
6698
|
+
children: [
|
|
6699
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex flex-col px-base pt-base", children: [
|
|
6700
|
+
filters.map((filter, i) => {
|
|
6701
|
+
const propDef = getPropertyDef(filter.propertyId);
|
|
6702
|
+
if (!propDef) return null;
|
|
6703
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
6704
|
+
AdvancedRow,
|
|
6705
|
+
{
|
|
6706
|
+
connector: i === 0 ? "Where" : "And",
|
|
6707
|
+
propertyDef: propDef,
|
|
6708
|
+
condition: filter,
|
|
6709
|
+
properties,
|
|
6710
|
+
onUpdate: handleUpdateFilter,
|
|
6711
|
+
onPropertyChange: (p) => handlePropertyChange(filter.id, p),
|
|
6712
|
+
onDelete: () => handleDeleteFilter(filter.id)
|
|
6713
|
+
},
|
|
6714
|
+
filter.id
|
|
6715
|
+
);
|
|
6716
|
+
}),
|
|
6717
|
+
filters.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("p", { className: "py-base text-sm text-[var(--color-muted-foreground)]", children: "No advanced filters yet." })
|
|
6718
|
+
] }),
|
|
6719
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex items-center justify-between px-base py-base border-t border-[var(--color-border)]", children: [
|
|
6720
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
6721
|
+
PropertySelector,
|
|
6722
|
+
{
|
|
6723
|
+
properties,
|
|
6724
|
+
onSelect: handleAddFilter,
|
|
6725
|
+
open: addSelectorOpen,
|
|
6726
|
+
onOpenChange: setAddSelectorOpen,
|
|
6727
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
6728
|
+
"button",
|
|
6729
|
+
{
|
|
6730
|
+
type: "button",
|
|
6731
|
+
className: "text-sm font-regular leading-sm text-[var(--color-muted-foreground)] hover:text-[var(--color-foreground)] cursor-pointer transition-colors",
|
|
6732
|
+
children: "+ Add filter"
|
|
6733
|
+
}
|
|
6734
|
+
)
|
|
6735
|
+
}
|
|
6736
|
+
),
|
|
6737
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
6738
|
+
"button",
|
|
6739
|
+
{
|
|
6740
|
+
type: "button",
|
|
6741
|
+
onClick: handleClearAll,
|
|
6742
|
+
className: "text-sm font-regular leading-sm text-[var(--color-muted-foreground)] hover:text-[var(--color-foreground)] cursor-pointer transition-colors",
|
|
6743
|
+
children: "Clear all filters"
|
|
6744
|
+
}
|
|
6745
|
+
)
|
|
6746
|
+
] })
|
|
6747
|
+
]
|
|
6748
|
+
}
|
|
6749
|
+
) })
|
|
6750
|
+
] });
|
|
6751
|
+
};
|
|
6752
|
+
AdvancedPopover.displayName = "AdvancedPopover";
|
|
6753
|
+
|
|
6754
|
+
// src/components/ui/filter/filter-system.tsx
|
|
6755
|
+
var import_jsx_runtime49 = require("react/jsx-runtime");
|
|
6756
|
+
var FilterSystem = ({
|
|
6757
|
+
properties,
|
|
6758
|
+
filterState,
|
|
6759
|
+
onFilterStateChange,
|
|
6760
|
+
sortFields,
|
|
6761
|
+
children,
|
|
6762
|
+
actions,
|
|
6763
|
+
className
|
|
6764
|
+
}) => {
|
|
6765
|
+
const [propertySelectorOpen, setPropertySelectorOpen] = React46.useState(false);
|
|
6766
|
+
const [advancedOpen, setAdvancedOpen] = React46.useState(false);
|
|
6767
|
+
const [pendingFilterId, setPendingFilterId] = React46.useState(null);
|
|
6768
|
+
const handleAddFilter = (property) => {
|
|
6769
|
+
const newFilter = createFilterWithDefaults(property.id, property.type);
|
|
6770
|
+
if (newFilter.operator && isNoValueOperator(newFilter.operator)) {
|
|
6771
|
+
onFilterStateChange({
|
|
6772
|
+
...filterState,
|
|
6773
|
+
basicFilters: [...filterState.basicFilters, newFilter]
|
|
6774
|
+
});
|
|
6775
|
+
return;
|
|
6776
|
+
}
|
|
6777
|
+
setPendingFilterId(newFilter.id);
|
|
6778
|
+
onFilterStateChange({
|
|
6779
|
+
...filterState,
|
|
6780
|
+
basicFilters: [...filterState.basicFilters, newFilter]
|
|
6781
|
+
});
|
|
6782
|
+
};
|
|
6783
|
+
const handleUpdateFilter = (updated) => {
|
|
6784
|
+
onFilterStateChange({
|
|
6785
|
+
...filterState,
|
|
6786
|
+
basicFilters: filterState.basicFilters.map(
|
|
6787
|
+
(f) => f.id === updated.id ? updated : f
|
|
6788
|
+
)
|
|
6789
|
+
});
|
|
6790
|
+
if (pendingFilterId === updated.id) {
|
|
6791
|
+
setPendingFilterId(null);
|
|
6792
|
+
}
|
|
6793
|
+
};
|
|
6794
|
+
const handleDeleteFilter = (id) => {
|
|
6795
|
+
onFilterStateChange({
|
|
6796
|
+
...filterState,
|
|
6797
|
+
basicFilters: filterState.basicFilters.filter((f) => f.id !== id)
|
|
6798
|
+
});
|
|
6799
|
+
};
|
|
6800
|
+
const handlePropertyChange = (filterId, newProp) => {
|
|
6801
|
+
const newCondition = createFilterWithDefaults(newProp.id, newProp.type);
|
|
6802
|
+
onFilterStateChange({
|
|
6803
|
+
...filterState,
|
|
6804
|
+
basicFilters: filterState.basicFilters.map(
|
|
6805
|
+
(f) => f.id === filterId ? { ...newCondition, id: filterId } : f
|
|
6806
|
+
)
|
|
6807
|
+
});
|
|
6808
|
+
if (newCondition.operator && !isNoValueOperator(newCondition.operator)) {
|
|
6809
|
+
setPendingFilterId(filterId);
|
|
6810
|
+
}
|
|
6811
|
+
};
|
|
6812
|
+
const handleConvertToAdvanced = (id) => {
|
|
6813
|
+
const filter = filterState.basicFilters.find((f) => f.id === id);
|
|
6814
|
+
if (!filter) return;
|
|
6815
|
+
onFilterStateChange({
|
|
6816
|
+
...filterState,
|
|
6817
|
+
basicFilters: filterState.basicFilters.filter((f) => f.id !== id),
|
|
6818
|
+
advancedFilters: [...filterState.advancedFilters, filter]
|
|
6819
|
+
});
|
|
6820
|
+
};
|
|
6821
|
+
const handleAdvancedFiltersChange = (filters) => {
|
|
6822
|
+
onFilterStateChange({
|
|
6823
|
+
...filterState,
|
|
6824
|
+
advancedFilters: filters
|
|
6825
|
+
});
|
|
6826
|
+
};
|
|
6827
|
+
const handleClearAdvanced = () => {
|
|
6828
|
+
onFilterStateChange({
|
|
6829
|
+
...filterState,
|
|
6830
|
+
advancedFilters: []
|
|
6831
|
+
});
|
|
6832
|
+
};
|
|
6833
|
+
const handleSortChange = (field, direction) => {
|
|
6834
|
+
onFilterStateChange({
|
|
6835
|
+
...filterState,
|
|
6836
|
+
sort: { field, direction }
|
|
6837
|
+
});
|
|
6838
|
+
};
|
|
6839
|
+
const getPropertyDef = (propertyId) => properties.find((p) => p.id === propertyId);
|
|
6840
|
+
const hasAdvanced = filterState.advancedFilters.length > 0;
|
|
6841
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(FilterBar, { className, children: [
|
|
6842
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(FilterBarLeft, { children: [
|
|
6843
|
+
children,
|
|
6844
|
+
sortFields && filterState.sort && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
6845
|
+
SortButton,
|
|
6846
|
+
{
|
|
6847
|
+
fields: sortFields,
|
|
6848
|
+
activeField: filterState.sort.field,
|
|
6849
|
+
direction: filterState.sort.direction,
|
|
6850
|
+
onChange: handleSortChange
|
|
6851
|
+
}
|
|
6852
|
+
),
|
|
6853
|
+
hasAdvanced && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
6854
|
+
AdvancedPopover,
|
|
6855
|
+
{
|
|
6856
|
+
filters: filterState.advancedFilters,
|
|
6857
|
+
properties,
|
|
6858
|
+
onFiltersChange: handleAdvancedFiltersChange,
|
|
6859
|
+
open: advancedOpen,
|
|
6860
|
+
onOpenChange: setAdvancedOpen,
|
|
6861
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
6862
|
+
AdvancedChip,
|
|
6863
|
+
{
|
|
6864
|
+
count: filterState.advancedFilters.length,
|
|
6865
|
+
onClick: () => setAdvancedOpen(true),
|
|
6866
|
+
onClear: handleClearAdvanced
|
|
6867
|
+
}
|
|
6868
|
+
)
|
|
6869
|
+
}
|
|
6870
|
+
),
|
|
6871
|
+
filterState.basicFilters.map((filter) => {
|
|
6872
|
+
const propDef = getPropertyDef(filter.propertyId);
|
|
6873
|
+
if (!propDef) return null;
|
|
6874
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
6875
|
+
InteractiveFilterChip,
|
|
6876
|
+
{
|
|
6877
|
+
propertyDef: propDef,
|
|
6878
|
+
condition: filter,
|
|
6879
|
+
properties,
|
|
6880
|
+
mode: pendingFilterId === filter.id ? "add" : "edit",
|
|
6881
|
+
autoOpen: pendingFilterId === filter.id,
|
|
6882
|
+
onUpdate: handleUpdateFilter,
|
|
6883
|
+
onPropertyChange: (newProp) => handlePropertyChange(filter.id, newProp),
|
|
6884
|
+
onDelete: () => handleDeleteFilter(filter.id),
|
|
6885
|
+
onConvertToAdvanced: () => handleConvertToAdvanced(filter.id)
|
|
6886
|
+
},
|
|
6887
|
+
filter.id
|
|
6888
|
+
);
|
|
6889
|
+
}),
|
|
6890
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
6891
|
+
PropertySelector,
|
|
6892
|
+
{
|
|
6893
|
+
properties,
|
|
6894
|
+
onSelect: handleAddFilter,
|
|
6895
|
+
open: propertySelectorOpen,
|
|
6896
|
+
onOpenChange: setPropertySelectorOpen,
|
|
6897
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
6898
|
+
FilterBarButton,
|
|
6899
|
+
{
|
|
6900
|
+
count: filterState.basicFilters.length + filterState.advancedFilters.length || void 0
|
|
6901
|
+
}
|
|
6902
|
+
)
|
|
6903
|
+
}
|
|
6904
|
+
)
|
|
6905
|
+
] }),
|
|
6906
|
+
actions && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(FilterBarRight, { children: actions })
|
|
6907
|
+
] });
|
|
6908
|
+
};
|
|
6909
|
+
FilterSystem.displayName = "FilterSystem";
|
|
6910
|
+
|
|
6911
|
+
// src/components/ui/date-picker.tsx
|
|
6912
|
+
var React47 = __toESM(require("react"));
|
|
6913
|
+
var PopoverPrimitive11 = __toESM(require("@radix-ui/react-popover"));
|
|
6914
|
+
var import_icons32 = require("@l3mpire/icons");
|
|
6915
|
+
var import_jsx_runtime50 = require("react/jsx-runtime");
|
|
6916
|
+
function getDaysInMonth(year, month) {
|
|
6917
|
+
return new Date(year, month + 1, 0).getDate();
|
|
6918
|
+
}
|
|
6919
|
+
function getWeekdayIndex(date) {
|
|
6920
|
+
return (date.getDay() + 6) % 7;
|
|
6921
|
+
}
|
|
6922
|
+
function isSameDay(a, b) {
|
|
6923
|
+
return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
6924
|
+
}
|
|
6925
|
+
function isInRange(date, from, to) {
|
|
6926
|
+
const t = date.getTime();
|
|
6927
|
+
return t >= from.getTime() && t <= to.getTime();
|
|
6928
|
+
}
|
|
6929
|
+
function startOfDay(d) {
|
|
6930
|
+
return new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
6931
|
+
}
|
|
6932
|
+
var WEEKDAYS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
|
|
6933
|
+
var MONTH_NAMES = [
|
|
6934
|
+
"January",
|
|
6935
|
+
"February",
|
|
6936
|
+
"March",
|
|
6937
|
+
"April",
|
|
6938
|
+
"May",
|
|
6939
|
+
"June",
|
|
6940
|
+
"July",
|
|
6941
|
+
"August",
|
|
6942
|
+
"September",
|
|
6943
|
+
"October",
|
|
6944
|
+
"November",
|
|
6945
|
+
"December"
|
|
6946
|
+
];
|
|
6947
|
+
var DatePickerContext = React47.createContext(
|
|
6948
|
+
null
|
|
6949
|
+
);
|
|
6950
|
+
function useDatePickerContext() {
|
|
6951
|
+
const ctx = React47.useContext(DatePickerContext);
|
|
6952
|
+
if (!ctx)
|
|
6953
|
+
throw new Error("DatePicker compound components must be used within <DatePicker>");
|
|
6954
|
+
return ctx;
|
|
6955
|
+
}
|
|
6956
|
+
var DatePicker = React47.forwardRef(
|
|
6957
|
+
({
|
|
6958
|
+
className,
|
|
6959
|
+
mode = "single",
|
|
6960
|
+
value,
|
|
6961
|
+
onValueChange,
|
|
6962
|
+
defaultMonth,
|
|
6963
|
+
defaultYear,
|
|
6964
|
+
children,
|
|
6965
|
+
...props
|
|
6966
|
+
}, ref) => {
|
|
6967
|
+
const today = React47.useMemo(() => startOfDay(/* @__PURE__ */ new Date()), []);
|
|
6968
|
+
const initialDate = React47.useMemo(() => {
|
|
6969
|
+
if (value) {
|
|
6970
|
+
if (value instanceof Date) return value;
|
|
6971
|
+
return value.from;
|
|
6972
|
+
}
|
|
6973
|
+
return today;
|
|
6974
|
+
}, []);
|
|
6975
|
+
const [month, setMonth] = React47.useState(
|
|
6976
|
+
defaultMonth ?? initialDate.getMonth()
|
|
6977
|
+
);
|
|
6978
|
+
const [year, setYear] = React47.useState(
|
|
6979
|
+
defaultYear ?? initialDate.getFullYear()
|
|
6980
|
+
);
|
|
6981
|
+
const [hoveredDate, setHoveredDate] = React47.useState();
|
|
6982
|
+
const goToPrevMonth = React47.useCallback(() => {
|
|
6983
|
+
setMonth((m) => {
|
|
6984
|
+
if (m === 0) {
|
|
6985
|
+
setYear((y) => y - 1);
|
|
6986
|
+
return 11;
|
|
6987
|
+
}
|
|
6988
|
+
return m - 1;
|
|
6989
|
+
});
|
|
6990
|
+
}, []);
|
|
6991
|
+
const goToNextMonth = React47.useCallback(() => {
|
|
6992
|
+
setMonth((m) => {
|
|
6993
|
+
if (m === 11) {
|
|
6994
|
+
setYear((y) => y + 1);
|
|
6995
|
+
return 0;
|
|
6996
|
+
}
|
|
6997
|
+
return m + 1;
|
|
6998
|
+
});
|
|
6999
|
+
}, []);
|
|
7000
|
+
const onSelect = React47.useCallback(
|
|
7001
|
+
(date) => {
|
|
7002
|
+
if (mode === "single") {
|
|
7003
|
+
onValueChange?.(date);
|
|
7004
|
+
return;
|
|
7005
|
+
}
|
|
7006
|
+
if (!value || value instanceof Date) {
|
|
7007
|
+
onValueChange?.({ from: date });
|
|
7008
|
+
return;
|
|
7009
|
+
}
|
|
7010
|
+
const range = value;
|
|
7011
|
+
if (range.to || date.getTime() < range.from.getTime()) {
|
|
7012
|
+
onValueChange?.({ from: date });
|
|
7013
|
+
} else {
|
|
7014
|
+
onValueChange?.({ from: range.from, to: date });
|
|
7015
|
+
}
|
|
7016
|
+
},
|
|
7017
|
+
[mode, value, onValueChange]
|
|
7018
|
+
);
|
|
7019
|
+
const ctxValue = React47.useMemo(
|
|
7020
|
+
() => ({
|
|
7021
|
+
mode,
|
|
7022
|
+
selected: value,
|
|
7023
|
+
onSelect,
|
|
7024
|
+
month,
|
|
7025
|
+
year,
|
|
7026
|
+
setMonth,
|
|
7027
|
+
setYear,
|
|
7028
|
+
goToPrevMonth,
|
|
7029
|
+
goToNextMonth,
|
|
7030
|
+
today,
|
|
7031
|
+
hoveredDate,
|
|
7032
|
+
setHoveredDate
|
|
7033
|
+
}),
|
|
7034
|
+
[
|
|
7035
|
+
mode,
|
|
7036
|
+
value,
|
|
7037
|
+
onSelect,
|
|
7038
|
+
month,
|
|
7039
|
+
year,
|
|
7040
|
+
goToPrevMonth,
|
|
7041
|
+
goToNextMonth,
|
|
7042
|
+
today,
|
|
7043
|
+
hoveredDate
|
|
7044
|
+
]
|
|
7045
|
+
);
|
|
7046
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(DatePickerContext.Provider, { value: ctxValue, children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
7047
|
+
"div",
|
|
7048
|
+
{
|
|
7049
|
+
ref,
|
|
7050
|
+
className: cn(
|
|
7051
|
+
"flex flex-col overflow-clip",
|
|
7052
|
+
"bg-datepicker-bg border border-datepicker-border rounded-md shadow-lg",
|
|
7053
|
+
className
|
|
7054
|
+
),
|
|
7055
|
+
...props,
|
|
7056
|
+
children
|
|
7057
|
+
}
|
|
7058
|
+
) });
|
|
7059
|
+
}
|
|
7060
|
+
);
|
|
7061
|
+
DatePicker.displayName = "DatePicker";
|
|
7062
|
+
function defaultFormatDate(date) {
|
|
7063
|
+
return date.toLocaleDateString("en-US", {
|
|
7064
|
+
month: "short",
|
|
7065
|
+
day: "numeric",
|
|
7066
|
+
year: "numeric"
|
|
7067
|
+
});
|
|
7068
|
+
}
|
|
7069
|
+
var DatePickerSelects = React47.forwardRef(({ className, formatDate = defaultFormatDate, ...props }, ref) => {
|
|
7070
|
+
const { selected } = useDatePickerContext();
|
|
7071
|
+
const fromDate = selected instanceof Date ? selected : selected?.from;
|
|
7072
|
+
const toDate = selected instanceof Date ? void 0 : selected?.to;
|
|
7073
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
7074
|
+
"div",
|
|
7075
|
+
{
|
|
7076
|
+
ref,
|
|
7077
|
+
className: cn("flex flex-col items-start pt-lg px-lg", className),
|
|
7078
|
+
...props,
|
|
7079
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "flex items-center gap-base w-full", children: [
|
|
7080
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "flex-1 flex items-center gap-base min-w-0 px-base py-sm bg-gradient-to-t from-[var(--color-select-bg-default)] to-[var(--color-select-bg-gradient-to)] border border-[var(--color-select-border-default)] rounded-base shadow-sm", children: [
|
|
7081
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "flex-1 text-sm font-regular leading-sm text-datepicker-header-text truncate", children: fromDate ? formatDate(fromDate) : "Start date" }),
|
|
7082
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_icons32.Icon, { icon: import_icons32.faCalendarOutline, size: "sm", className: "shrink-0 text-datepicker-header-text" })
|
|
7083
|
+
] }),
|
|
7084
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
7085
|
+
import_icons32.Icon,
|
|
7086
|
+
{
|
|
7087
|
+
icon: import_icons32.faArrowRightOutline,
|
|
7088
|
+
size: "sm",
|
|
7089
|
+
className: "shrink-0 text-datepicker-header-weekday"
|
|
7090
|
+
}
|
|
7091
|
+
),
|
|
7092
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "flex-1 flex items-center gap-base min-w-0 px-base py-sm bg-gradient-to-t from-[var(--color-select-bg-default)] to-[var(--color-select-bg-gradient-to)] border border-[var(--color-select-border-default)] rounded-base shadow-sm", children: [
|
|
7093
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "flex-1 text-sm font-regular leading-sm text-datepicker-header-text truncate", children: toDate ? formatDate(toDate) : "End date" }),
|
|
7094
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_icons32.Icon, { icon: import_icons32.faCalendarOutline, size: "sm", className: "shrink-0 text-datepicker-header-text" })
|
|
7095
|
+
] })
|
|
7096
|
+
] })
|
|
7097
|
+
}
|
|
7098
|
+
);
|
|
7099
|
+
});
|
|
7100
|
+
DatePickerSelects.displayName = "DatePickerSelects";
|
|
7101
|
+
var DatePickerDay = ({ date, isOutside }) => {
|
|
7102
|
+
const { mode, selected, onSelect, today, hoveredDate, setHoveredDate } = useDatePickerContext();
|
|
7103
|
+
const isToday = isSameDay(date, today);
|
|
7104
|
+
const isSelected = selected instanceof Date ? isSameDay(date, selected) : selected?.from ? isSameDay(date, selected.from) || (selected.to ? isSameDay(date, selected.to) : false) : false;
|
|
7105
|
+
const isRangeStart = mode === "range" && selected && !(selected instanceof Date) && selected.from && isSameDay(date, selected.from);
|
|
7106
|
+
const isRangeEnd = mode === "range" && selected && !(selected instanceof Date) && selected.to && isSameDay(date, selected.to);
|
|
7107
|
+
const inRange = mode === "range" && selected && !(selected instanceof Date) && selected.from && selected.to && !isSelected && isInRange(date, selected.from, selected.to);
|
|
7108
|
+
const inPreviewRange = mode === "range" && selected && !(selected instanceof Date) && selected.from && !selected.to && hoveredDate && !isSelected && hoveredDate.getTime() > selected.from.getTime() && isInRange(date, selected.from, hoveredDate);
|
|
7109
|
+
const isInRangeOrPreview = inRange || inPreviewRange;
|
|
7110
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
|
|
7111
|
+
"button",
|
|
7112
|
+
{
|
|
7113
|
+
type: "button",
|
|
7114
|
+
onClick: () => !isOutside && onSelect(date),
|
|
7115
|
+
onMouseEnter: () => mode === "range" && setHoveredDate(date),
|
|
7116
|
+
onMouseLeave: () => mode === "range" && setHoveredDate(void 0),
|
|
7117
|
+
disabled: isOutside,
|
|
7118
|
+
className: cn(
|
|
7119
|
+
"relative flex flex-col items-center justify-center w-9 rounded-full p-2 cursor-pointer transition-colors",
|
|
7120
|
+
"text-sm font-medium leading-sm text-center",
|
|
7121
|
+
// Default
|
|
7122
|
+
!isOutside && !isSelected && !isInRangeOrPreview && "text-datepicker-day-text-default hover:bg-datepicker-day-bg-hover",
|
|
7123
|
+
// Outside month (disabled)
|
|
7124
|
+
isOutside && "text-datepicker-day-text-disabled cursor-default",
|
|
7125
|
+
// Selected
|
|
7126
|
+
isSelected && "bg-datepicker-day-bg-selected text-datepicker-day-text-selected",
|
|
7127
|
+
// In range
|
|
7128
|
+
isInRangeOrPreview && "bg-datepicker-day-bg-range text-datepicker-day-text-range",
|
|
7129
|
+
// Range start/end get full rounded; in-range items could be less rounded
|
|
7130
|
+
(isRangeStart || isRangeEnd) && "rounded-full"
|
|
7131
|
+
),
|
|
7132
|
+
children: [
|
|
7133
|
+
date.getDate(),
|
|
7134
|
+
isToday && !isOutside && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "absolute bottom-0.5 left-1/2 -translate-x-1/2 size-1.5 rounded-full bg-datepicker-day-today" })
|
|
7135
|
+
]
|
|
7136
|
+
}
|
|
7137
|
+
);
|
|
7138
|
+
};
|
|
7139
|
+
var DatePickerCalendar = React47.forwardRef(({ className, header, ...props }, ref) => {
|
|
7140
|
+
const { month, year, goToPrevMonth, goToNextMonth } = useDatePickerContext();
|
|
7141
|
+
const weeks = React47.useMemo(() => {
|
|
7142
|
+
const firstDay = new Date(year, month, 1);
|
|
7143
|
+
const startOffset = getWeekdayIndex(firstDay);
|
|
7144
|
+
const daysInMonth = getDaysInMonth(year, month);
|
|
7145
|
+
const daysInPrevMonth = getDaysInMonth(
|
|
7146
|
+
month === 0 ? year - 1 : year,
|
|
7147
|
+
month === 0 ? 11 : month - 1
|
|
7148
|
+
);
|
|
7149
|
+
const days = [];
|
|
7150
|
+
for (let i = startOffset - 1; i >= 0; i--) {
|
|
7151
|
+
const d = daysInPrevMonth - i;
|
|
7152
|
+
days.push({
|
|
7153
|
+
date: new Date(
|
|
7154
|
+
month === 0 ? year - 1 : year,
|
|
7155
|
+
month === 0 ? 11 : month - 1,
|
|
7156
|
+
d
|
|
7157
|
+
),
|
|
7158
|
+
isOutside: true
|
|
7159
|
+
});
|
|
7160
|
+
}
|
|
7161
|
+
for (let d = 1; d <= daysInMonth; d++) {
|
|
7162
|
+
days.push({ date: new Date(year, month, d), isOutside: false });
|
|
7163
|
+
}
|
|
7164
|
+
const remaining = 42 - days.length;
|
|
7165
|
+
for (let d = 1; d <= remaining; d++) {
|
|
7166
|
+
days.push({
|
|
7167
|
+
date: new Date(
|
|
7168
|
+
month === 11 ? year + 1 : year,
|
|
7169
|
+
month === 11 ? 0 : month + 1,
|
|
7170
|
+
d
|
|
7171
|
+
),
|
|
7172
|
+
isOutside: true
|
|
7173
|
+
});
|
|
7174
|
+
}
|
|
7175
|
+
const result = [];
|
|
7176
|
+
for (let i = 0; i < days.length; i += 7) {
|
|
7177
|
+
result.push(days.slice(i, i + 7));
|
|
7178
|
+
}
|
|
7179
|
+
return result;
|
|
7180
|
+
}, [month, year]);
|
|
7181
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
|
|
7182
|
+
"div",
|
|
7183
|
+
{
|
|
7184
|
+
ref,
|
|
7185
|
+
className: cn("flex flex-col", className),
|
|
7186
|
+
...props,
|
|
7187
|
+
children: [
|
|
7188
|
+
header,
|
|
7189
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "flex flex-col gap-lg p-lg", children: [
|
|
7190
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
7191
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("span", { className: "text-base font-medium leading-base text-datepicker-header-text", children: [
|
|
7192
|
+
MONTH_NAMES[month],
|
|
7193
|
+
" ",
|
|
7194
|
+
year
|
|
7195
|
+
] }),
|
|
7196
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "flex items-center gap-xs", children: [
|
|
7197
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
7198
|
+
"button",
|
|
7199
|
+
{
|
|
7200
|
+
type: "button",
|
|
7201
|
+
onClick: goToPrevMonth,
|
|
7202
|
+
className: "flex items-center justify-center p-xs rounded-base hover:bg-datepicker-day-bg-hover transition-colors cursor-pointer",
|
|
7203
|
+
"aria-label": "Previous month",
|
|
7204
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_icons32.Icon, { icon: import_icons32.faChevronLeftOutline, size: "xs", className: "text-datepicker-header-nav" })
|
|
7205
|
+
}
|
|
7206
|
+
),
|
|
7207
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
7208
|
+
"button",
|
|
7209
|
+
{
|
|
7210
|
+
type: "button",
|
|
7211
|
+
onClick: goToNextMonth,
|
|
7212
|
+
className: "flex items-center justify-center p-xs rounded-base hover:bg-datepicker-day-bg-hover transition-colors cursor-pointer",
|
|
7213
|
+
"aria-label": "Next month",
|
|
7214
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_icons32.Icon, { icon: import_icons32.faChevronRightOutline, size: "xs", className: "text-datepicker-header-nav" })
|
|
7215
|
+
}
|
|
7216
|
+
)
|
|
7217
|
+
] })
|
|
7218
|
+
] }),
|
|
7219
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "flex flex-col", children: [
|
|
7220
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "grid grid-cols-7 gap-base py-sm", children: WEEKDAYS.map((day) => /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
7221
|
+
"span",
|
|
7222
|
+
{
|
|
7223
|
+
className: "w-9 text-center text-xs font-regular leading-xs text-datepicker-header-weekday",
|
|
7224
|
+
children: day
|
|
7225
|
+
},
|
|
7226
|
+
day
|
|
7227
|
+
)) }),
|
|
7228
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "flex flex-col", children: weeks.map((week, wi) => /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "grid grid-cols-7 gap-base", children: week.map((day, di) => /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
7229
|
+
DatePickerDay,
|
|
7230
|
+
{
|
|
7231
|
+
date: day.date,
|
|
7232
|
+
isOutside: day.isOutside
|
|
7233
|
+
},
|
|
7234
|
+
di
|
|
7235
|
+
)) }, wi)) })
|
|
7236
|
+
] })
|
|
7237
|
+
] })
|
|
7238
|
+
]
|
|
7239
|
+
}
|
|
7240
|
+
);
|
|
7241
|
+
});
|
|
7242
|
+
DatePickerCalendar.displayName = "DatePickerCalendar";
|
|
7243
|
+
var DatePickerSuggestions = React47.forwardRef(
|
|
7244
|
+
({ className, suggestions, formatDate = defaultFormatDate, ...props }, ref) => {
|
|
7245
|
+
const { onSelect, mode } = useDatePickerContext();
|
|
7246
|
+
const onValueChange = React47.useContext(DatePickerContext) ? void 0 : void 0;
|
|
7247
|
+
const ctx = useDatePickerContext();
|
|
7248
|
+
const handleClick = (suggestion) => {
|
|
7249
|
+
const val = suggestion.getValue();
|
|
7250
|
+
if (val instanceof Date) {
|
|
7251
|
+
ctx.onSelect(val);
|
|
7252
|
+
} else {
|
|
7253
|
+
ctx.onSelect(val.from);
|
|
7254
|
+
if (val.to) {
|
|
7255
|
+
setTimeout(() => ctx.onSelect(val.to), 0);
|
|
7256
|
+
}
|
|
7257
|
+
}
|
|
7258
|
+
};
|
|
7259
|
+
const formatSuggestionDate = (suggestion) => {
|
|
7260
|
+
const val = suggestion.getValue();
|
|
7261
|
+
if (val instanceof Date) {
|
|
7262
|
+
return formatDate(val);
|
|
7263
|
+
}
|
|
7264
|
+
const from = formatDate(val.from);
|
|
7265
|
+
const to = val.to ? formatDate(val.to) : "";
|
|
7266
|
+
return to ? `${from} - ${to}` : from;
|
|
7267
|
+
};
|
|
7268
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
|
|
7269
|
+
"div",
|
|
7270
|
+
{
|
|
7271
|
+
ref,
|
|
7272
|
+
className: cn(
|
|
7273
|
+
"flex flex-col border-l border-datepicker-border self-stretch shrink-0",
|
|
7274
|
+
className
|
|
7275
|
+
),
|
|
7276
|
+
...props,
|
|
7277
|
+
children: [
|
|
7278
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "pt-lg px-base", children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "flex items-center p-base rounded-base", children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "flex-1 text-xs font-medium leading-xs text-datepicker-suggestion-heading uppercase truncate", children: "Suggestions" }) }) }),
|
|
7279
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "flex flex-1 flex-col p-base min-w-[222px]", children: suggestions.map((suggestion, i) => /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
|
|
7280
|
+
"button",
|
|
7281
|
+
{
|
|
7282
|
+
type: "button",
|
|
7283
|
+
onClick: () => handleClick(suggestion),
|
|
7284
|
+
className: "flex items-center gap-sm p-base rounded-base hover:bg-datepicker-suggestion-hover transition-colors cursor-pointer text-left",
|
|
7285
|
+
children: [
|
|
7286
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "text-sm font-regular leading-sm text-datepicker-suggestion-text truncate shrink-0", children: suggestion.label }),
|
|
7287
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "text-xs font-regular leading-xs text-datepicker-suggestion-date truncate", children: formatSuggestionDate(suggestion) })
|
|
7288
|
+
]
|
|
7289
|
+
},
|
|
7290
|
+
i
|
|
7291
|
+
)) })
|
|
7292
|
+
]
|
|
7293
|
+
}
|
|
7294
|
+
);
|
|
7295
|
+
}
|
|
7296
|
+
);
|
|
7297
|
+
DatePickerSuggestions.displayName = "DatePickerSuggestions";
|
|
7298
|
+
var DatePickerFooter = React47.forwardRef(
|
|
7299
|
+
({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
7300
|
+
"div",
|
|
7301
|
+
{
|
|
7302
|
+
ref,
|
|
7303
|
+
className: cn(
|
|
7304
|
+
"flex items-center justify-between p-lg",
|
|
7305
|
+
"border-t border-datepicker-footer-border",
|
|
7306
|
+
"bg-datepicker-bg",
|
|
7307
|
+
className
|
|
7308
|
+
),
|
|
7309
|
+
...props,
|
|
7310
|
+
children
|
|
7311
|
+
}
|
|
7312
|
+
)
|
|
7313
|
+
);
|
|
7314
|
+
DatePickerFooter.displayName = "DatePickerFooter";
|
|
7315
|
+
var DatePickerPanel = React47.forwardRef(
|
|
7316
|
+
({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
7317
|
+
"div",
|
|
7318
|
+
{
|
|
7319
|
+
ref,
|
|
7320
|
+
className: cn("flex items-start", className),
|
|
7321
|
+
...props,
|
|
7322
|
+
children
|
|
7323
|
+
}
|
|
7324
|
+
)
|
|
7325
|
+
);
|
|
7326
|
+
DatePickerPanel.displayName = "DatePickerPanel";
|
|
7327
|
+
var DatePickerRoot = PopoverPrimitive11.Root;
|
|
7328
|
+
var DatePickerTrigger = PopoverPrimitive11.Trigger;
|
|
7329
|
+
var DatePickerPopover = React47.forwardRef(({ className, sideOffset = 4, align = "start", children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(PopoverPrimitive11.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
7330
|
+
PopoverPrimitive11.Content,
|
|
7331
|
+
{
|
|
7332
|
+
ref,
|
|
7333
|
+
sideOffset,
|
|
7334
|
+
align,
|
|
7335
|
+
className: cn(
|
|
7336
|
+
"z-50",
|
|
7337
|
+
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
7338
|
+
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
|
7339
|
+
"data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2",
|
|
7340
|
+
className
|
|
7341
|
+
),
|
|
7342
|
+
...props,
|
|
7343
|
+
children
|
|
7344
|
+
}
|
|
7345
|
+
) }));
|
|
7346
|
+
DatePickerPopover.displayName = "DatePickerPopover";
|
|
7347
|
+
function getDefaultSuggestions(referenceDate) {
|
|
7348
|
+
const now = referenceDate ?? /* @__PURE__ */ new Date();
|
|
7349
|
+
const today = startOfDay(now);
|
|
7350
|
+
const dayOfWeek = getWeekdayIndex(today);
|
|
7351
|
+
const startOfThisWeek = new Date(today);
|
|
7352
|
+
startOfThisWeek.setDate(today.getDate() - dayOfWeek);
|
|
7353
|
+
const endOfThisWeek = new Date(startOfThisWeek);
|
|
7354
|
+
endOfThisWeek.setDate(startOfThisWeek.getDate() + 6);
|
|
7355
|
+
const startOfThisMonth = new Date(today.getFullYear(), today.getMonth(), 1);
|
|
7356
|
+
const endOfThisMonth = new Date(
|
|
7357
|
+
today.getFullYear(),
|
|
7358
|
+
today.getMonth() + 1,
|
|
7359
|
+
0
|
|
7360
|
+
);
|
|
7361
|
+
const startOfThisYear = new Date(today.getFullYear(), 0, 1);
|
|
7362
|
+
const endOfThisYear = new Date(today.getFullYear(), 11, 31);
|
|
7363
|
+
const startOfLastWeek = new Date(startOfThisWeek);
|
|
7364
|
+
startOfLastWeek.setDate(startOfThisWeek.getDate() - 7);
|
|
7365
|
+
const endOfLastWeek = new Date(startOfThisWeek);
|
|
7366
|
+
endOfLastWeek.setDate(startOfThisWeek.getDate() - 1);
|
|
7367
|
+
const startOfLastMonth = new Date(
|
|
7368
|
+
today.getFullYear(),
|
|
7369
|
+
today.getMonth() - 1,
|
|
7370
|
+
1
|
|
7371
|
+
);
|
|
7372
|
+
const endOfLastMonth = new Date(today.getFullYear(), today.getMonth(), 0);
|
|
7373
|
+
const startOfLastYear = new Date(today.getFullYear() - 1, 0, 1);
|
|
7374
|
+
const endOfLastYear = new Date(today.getFullYear() - 1, 11, 31);
|
|
7375
|
+
return [
|
|
7376
|
+
{ label: "Today", getValue: () => today },
|
|
7377
|
+
{
|
|
7378
|
+
label: "This week",
|
|
7379
|
+
getValue: () => ({ from: startOfThisWeek, to: endOfThisWeek })
|
|
7380
|
+
},
|
|
7381
|
+
{
|
|
7382
|
+
label: "This month",
|
|
7383
|
+
getValue: () => ({ from: startOfThisMonth, to: endOfThisMonth })
|
|
7384
|
+
},
|
|
7385
|
+
{
|
|
7386
|
+
label: "This year",
|
|
7387
|
+
getValue: () => ({ from: startOfThisYear, to: endOfThisYear })
|
|
7388
|
+
},
|
|
7389
|
+
{
|
|
7390
|
+
label: "Last week",
|
|
7391
|
+
getValue: () => ({ from: startOfLastWeek, to: endOfLastWeek })
|
|
7392
|
+
},
|
|
7393
|
+
{
|
|
7394
|
+
label: "Last month",
|
|
7395
|
+
getValue: () => ({ from: startOfLastMonth, to: endOfLastMonth })
|
|
7396
|
+
},
|
|
7397
|
+
{
|
|
7398
|
+
label: "Last year",
|
|
7399
|
+
getValue: () => ({ from: startOfLastYear, to: endOfLastYear })
|
|
7400
|
+
}
|
|
7401
|
+
];
|
|
7402
|
+
}
|
|
4802
7403
|
// Annotate the CommonJS export names for ESM import in node:
|
|
4803
7404
|
0 && (module.exports = {
|
|
7405
|
+
AdvancedChip,
|
|
7406
|
+
AdvancedPopover,
|
|
7407
|
+
AdvancedRow,
|
|
4804
7408
|
Avatar,
|
|
4805
7409
|
AvatarCell,
|
|
4806
7410
|
Badge,
|
|
@@ -4810,9 +7414,19 @@ SidePanelContent.displayName = "SidePanelContent";
|
|
|
4810
7414
|
ButtonCell,
|
|
4811
7415
|
Checkbox,
|
|
4812
7416
|
ChipInput,
|
|
7417
|
+
DEFAULT_OPERATOR_BY_TYPE,
|
|
4813
7418
|
DataTable,
|
|
4814
7419
|
DataTablePagination,
|
|
4815
7420
|
DateCell,
|
|
7421
|
+
DatePicker,
|
|
7422
|
+
DatePickerCalendar,
|
|
7423
|
+
DatePickerFooter,
|
|
7424
|
+
DatePickerPanel,
|
|
7425
|
+
DatePickerPopover,
|
|
7426
|
+
DatePickerRoot,
|
|
7427
|
+
DatePickerSelects,
|
|
7428
|
+
DatePickerSuggestions,
|
|
7429
|
+
DatePickerTrigger,
|
|
4816
7430
|
Dialog,
|
|
4817
7431
|
DropdownMenu,
|
|
4818
7432
|
DropdownMenuClear,
|
|
@@ -4826,8 +7440,18 @@ SidePanelContent.displayName = "SidePanelContent";
|
|
|
4826
7440
|
EditableCell,
|
|
4827
7441
|
EmailCell,
|
|
4828
7442
|
EmptyState,
|
|
7443
|
+
FilterBar,
|
|
7444
|
+
FilterBarButton,
|
|
7445
|
+
FilterBarLeft,
|
|
7446
|
+
FilterBarRight,
|
|
7447
|
+
FilterChip,
|
|
7448
|
+
FilterChipSegment,
|
|
7449
|
+
FilterEditor,
|
|
7450
|
+
FilterSystem,
|
|
4829
7451
|
InfoMessage,
|
|
4830
7452
|
InputLabel,
|
|
7453
|
+
InteractiveFilterChip,
|
|
7454
|
+
KebabMenu,
|
|
4831
7455
|
Link,
|
|
4832
7456
|
LinkCell,
|
|
4833
7457
|
Modal,
|
|
@@ -4842,8 +7466,13 @@ SidePanelContent.displayName = "SidePanelContent";
|
|
|
4842
7466
|
ModalTrigger,
|
|
4843
7467
|
NumberCell,
|
|
4844
7468
|
NumberInput,
|
|
7469
|
+
OPERATORS_BY_TYPE,
|
|
7470
|
+
OperatorList,
|
|
7471
|
+
OperatorSelector,
|
|
4845
7472
|
ProductLogo,
|
|
7473
|
+
PropertySelector,
|
|
4846
7474
|
RowActions,
|
|
7475
|
+
SaveViewButton,
|
|
4847
7476
|
SearchBar,
|
|
4848
7477
|
Select,
|
|
4849
7478
|
SidePanel,
|
|
@@ -4856,6 +7485,7 @@ SidePanelContent.displayName = "SidePanelContent";
|
|
|
4856
7485
|
SidebarHeadingItem,
|
|
4857
7486
|
SidebarItem,
|
|
4858
7487
|
SidebarSection,
|
|
7488
|
+
SortButton,
|
|
4859
7489
|
StatusCell,
|
|
4860
7490
|
Switch,
|
|
4861
7491
|
TabContent,
|
|
@@ -4885,14 +7515,21 @@ SidePanelContent.displayName = "SidePanelContent";
|
|
|
4885
7515
|
UserMenu,
|
|
4886
7516
|
UserMenuInfoRow,
|
|
4887
7517
|
UserMenuSection,
|
|
7518
|
+
ValueInput,
|
|
4888
7519
|
avatarVariants,
|
|
4889
7520
|
badgeVariants,
|
|
4890
7521
|
buttonVariants,
|
|
4891
7522
|
chipInputVariants,
|
|
4892
7523
|
cn,
|
|
7524
|
+
createFilterWithDefaults,
|
|
4893
7525
|
emptyStateVariants,
|
|
7526
|
+
filterChipSegmentVariants,
|
|
4894
7527
|
flexRender,
|
|
7528
|
+
getDefaultOperator,
|
|
7529
|
+
getDefaultSuggestions,
|
|
7530
|
+
getValueInputType,
|
|
4895
7531
|
infoMessageVariants,
|
|
7532
|
+
isNoValueOperator,
|
|
4896
7533
|
linkVariants,
|
|
4897
7534
|
modalVariants,
|
|
4898
7535
|
productLogoVariants,
|