hazo_ui 2.11.0 → 2.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGE_LOG.md +181 -0
- package/README.md +244 -0
- package/dist/index.cjs +2149 -494
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +358 -1
- package/dist/index.d.ts +358 -1
- package/dist/index.js +2102 -459
- package/dist/index.js.map +1 -1
- package/dist/styles.css +8 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import * as
|
|
3
|
-
import
|
|
2
|
+
import * as React25 from 'react';
|
|
3
|
+
import React25__default, { useRef, useState, useCallback, useEffect, useMemo, Fragment } from 'react';
|
|
4
4
|
import { Slot } from '@radix-ui/react-slot';
|
|
5
5
|
import { cva } from 'class-variance-authority';
|
|
6
6
|
import { clsx } from 'clsx';
|
|
7
7
|
import { twMerge } from 'tailwind-merge';
|
|
8
8
|
import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime';
|
|
9
9
|
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
10
|
-
import { X, ChevronDown, ChevronUp, Check, Circle, ChevronRight, ChevronLeft, Filter, Plus,
|
|
10
|
+
import { X, ChevronDown, ChevronUp, Check, Circle, ChevronRight, ChevronLeft, Filter, Plus, ArrowUpDown, Loader2, AlertTriangle, OctagonAlert, CheckCircle2, ChevronsUpDown, GripVertical, ArrowUp, ArrowDown, Pencil, Calendar as Calendar$1 } from 'lucide-react';
|
|
11
11
|
import * as PopoverPrimitive from '@radix-ui/react-popover';
|
|
12
12
|
import * as SelectPrimitive from '@radix-ui/react-select';
|
|
13
13
|
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
|
|
14
14
|
import { DayPicker } from 'react-day-picker';
|
|
15
15
|
import { format } from 'date-fns';
|
|
16
|
-
import
|
|
17
|
-
import { useSensors, useSensor, PointerSensor, KeyboardSensor, DndContext, closestCenter } from '@dnd-kit/core';
|
|
16
|
+
import { useSensors, useSensor, PointerSensor, KeyboardSensor, DndContext, closestCenter, closestCorners, DragOverlay, useDroppable } from '@dnd-kit/core';
|
|
18
17
|
import { sortableKeyboardCoordinates, SortableContext, verticalListSortingStrategy, arrayMove, useSortable } from '@dnd-kit/sortable';
|
|
19
18
|
import { CSS } from '@dnd-kit/utilities';
|
|
20
19
|
import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
|
|
@@ -61,6 +60,7 @@ import * as AccordionPrimitive from '@radix-ui/react-accordion';
|
|
|
61
60
|
import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
|
|
62
61
|
import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
|
|
63
62
|
import * as HoverCardPrimitive from '@radix-ui/react-hover-card';
|
|
63
|
+
import * as SwitchPrimitives from '@radix-ui/react-switch';
|
|
64
64
|
import * as SeparatorPrimitive from '@radix-ui/react-separator';
|
|
65
65
|
import * as CollapsiblePrimitive from '@radix-ui/react-collapsible';
|
|
66
66
|
import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
|
|
@@ -207,7 +207,7 @@ var variant_styles = {
|
|
|
207
207
|
color: "hsl(var(--secondary-foreground))"
|
|
208
208
|
}
|
|
209
209
|
};
|
|
210
|
-
var Button =
|
|
210
|
+
var Button = React25.forwardRef(
|
|
211
211
|
({ className, variant, size, asChild = false, style, ...props }, ref) => {
|
|
212
212
|
const Comp = asChild ? Slot : "button";
|
|
213
213
|
const fallback_styles = variant_styles[variant ?? "default"] ?? {};
|
|
@@ -227,7 +227,7 @@ var Dialog = DialogPrimitive.Root;
|
|
|
227
227
|
var DialogTrigger = DialogPrimitive.Trigger;
|
|
228
228
|
var DialogPortal = DialogPrimitive.Portal;
|
|
229
229
|
var DialogClose = DialogPrimitive.Close;
|
|
230
|
-
var DialogOverlay =
|
|
230
|
+
var DialogOverlay = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
231
231
|
DialogPrimitive.Overlay,
|
|
232
232
|
{
|
|
233
233
|
ref,
|
|
@@ -239,14 +239,14 @@ var DialogOverlay = React27.forwardRef(({ className, ...props }, ref) => /* @__P
|
|
|
239
239
|
}
|
|
240
240
|
));
|
|
241
241
|
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
|
242
|
-
var DialogContent =
|
|
242
|
+
var DialogContent = React25.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(DialogPortal, { children: [
|
|
243
243
|
/* @__PURE__ */ jsx(DialogOverlay, {}),
|
|
244
244
|
/* @__PURE__ */ jsxs(
|
|
245
245
|
DialogPrimitive.Content,
|
|
246
246
|
{
|
|
247
247
|
ref,
|
|
248
248
|
className: cn(
|
|
249
|
-
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95
|
|
249
|
+
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 sm:rounded-lg",
|
|
250
250
|
className
|
|
251
251
|
),
|
|
252
252
|
...props,
|
|
@@ -289,7 +289,7 @@ var DialogFooter = ({
|
|
|
289
289
|
}
|
|
290
290
|
);
|
|
291
291
|
DialogFooter.displayName = "DialogFooter";
|
|
292
|
-
var DialogTitle =
|
|
292
|
+
var DialogTitle = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
293
293
|
DialogPrimitive.Title,
|
|
294
294
|
{
|
|
295
295
|
ref,
|
|
@@ -302,7 +302,7 @@ var DialogTitle = React27.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
302
302
|
}
|
|
303
303
|
));
|
|
304
304
|
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
|
305
|
-
var DialogDescription =
|
|
305
|
+
var DialogDescription = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
306
306
|
DialogPrimitive.Description,
|
|
307
307
|
{
|
|
308
308
|
ref,
|
|
@@ -311,7 +311,7 @@ var DialogDescription = React27.forwardRef(({ className, ...props }, ref) => /*
|
|
|
311
311
|
}
|
|
312
312
|
));
|
|
313
313
|
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
314
|
-
var Command =
|
|
314
|
+
var Command = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
315
315
|
"div",
|
|
316
316
|
{
|
|
317
317
|
ref,
|
|
@@ -323,7 +323,7 @@ var Command = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__
|
|
|
323
323
|
}
|
|
324
324
|
));
|
|
325
325
|
Command.displayName = "Command";
|
|
326
|
-
var CommandInput =
|
|
326
|
+
var CommandInput = React25.forwardRef(({ className, onValueChange, onChange, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
327
327
|
"input",
|
|
328
328
|
{
|
|
329
329
|
ref,
|
|
@@ -339,7 +339,7 @@ var CommandInput = React27.forwardRef(({ className, onValueChange, onChange, ...
|
|
|
339
339
|
}
|
|
340
340
|
));
|
|
341
341
|
CommandInput.displayName = "CommandInput";
|
|
342
|
-
var CommandList =
|
|
342
|
+
var CommandList = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
343
343
|
"div",
|
|
344
344
|
{
|
|
345
345
|
ref,
|
|
@@ -348,7 +348,7 @@ var CommandList = React27.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
348
348
|
}
|
|
349
349
|
));
|
|
350
350
|
CommandList.displayName = "CommandList";
|
|
351
|
-
var CommandEmpty =
|
|
351
|
+
var CommandEmpty = React25.forwardRef((props, ref) => /* @__PURE__ */ jsx(
|
|
352
352
|
"div",
|
|
353
353
|
{
|
|
354
354
|
ref,
|
|
@@ -357,7 +357,7 @@ var CommandEmpty = React27.forwardRef((props, ref) => /* @__PURE__ */ jsx(
|
|
|
357
357
|
}
|
|
358
358
|
));
|
|
359
359
|
CommandEmpty.displayName = "CommandEmpty";
|
|
360
|
-
var CommandGroup =
|
|
360
|
+
var CommandGroup = React25.forwardRef(({ className, heading, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
361
361
|
"div",
|
|
362
362
|
{
|
|
363
363
|
ref,
|
|
@@ -373,7 +373,7 @@ var CommandGroup = React27.forwardRef(({ className, heading, children, ...props
|
|
|
373
373
|
}
|
|
374
374
|
));
|
|
375
375
|
CommandGroup.displayName = "CommandGroup";
|
|
376
|
-
var CommandItem =
|
|
376
|
+
var CommandItem = React25.forwardRef(({ className, onSelect, value, selected, style, ...props }, ref) => {
|
|
377
377
|
const handleClick = () => {
|
|
378
378
|
if (onSelect && value) {
|
|
379
379
|
onSelect(value);
|
|
@@ -404,7 +404,7 @@ var CommandItem = React27.forwardRef(({ className, onSelect, value, selected, st
|
|
|
404
404
|
CommandItem.displayName = "CommandItem";
|
|
405
405
|
var Popover = PopoverPrimitive.Root;
|
|
406
406
|
var PopoverTrigger = PopoverPrimitive.Trigger;
|
|
407
|
-
var PopoverContent =
|
|
407
|
+
var PopoverContent = React25.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(
|
|
408
408
|
PopoverPrimitive.Content,
|
|
409
409
|
{
|
|
410
410
|
ref,
|
|
@@ -418,7 +418,7 @@ var PopoverContent = React27.forwardRef(({ className, align = "center", sideOffs
|
|
|
418
418
|
}
|
|
419
419
|
) }));
|
|
420
420
|
PopoverContent.displayName = PopoverPrimitive.Content.displayName;
|
|
421
|
-
var Input =
|
|
421
|
+
var Input = React25.forwardRef(
|
|
422
422
|
({ className, type, ...props }, ref) => {
|
|
423
423
|
return /* @__PURE__ */ jsx(
|
|
424
424
|
"input",
|
|
@@ -438,7 +438,7 @@ Input.displayName = "Input";
|
|
|
438
438
|
var Select = SelectPrimitive.Root;
|
|
439
439
|
var SelectGroup = SelectPrimitive.Group;
|
|
440
440
|
var SelectValue = SelectPrimitive.Value;
|
|
441
|
-
var SelectTrigger =
|
|
441
|
+
var SelectTrigger = React25.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
442
442
|
SelectPrimitive.Trigger,
|
|
443
443
|
{
|
|
444
444
|
ref,
|
|
@@ -454,7 +454,7 @@ var SelectTrigger = React27.forwardRef(({ className, children, ...props }, ref)
|
|
|
454
454
|
}
|
|
455
455
|
));
|
|
456
456
|
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
|
|
457
|
-
var SelectScrollUpButton =
|
|
457
|
+
var SelectScrollUpButton = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
458
458
|
SelectPrimitive.ScrollUpButton,
|
|
459
459
|
{
|
|
460
460
|
ref,
|
|
@@ -467,7 +467,7 @@ var SelectScrollUpButton = React27.forwardRef(({ className, ...props }, ref) =>
|
|
|
467
467
|
}
|
|
468
468
|
));
|
|
469
469
|
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
|
|
470
|
-
var SelectScrollDownButton =
|
|
470
|
+
var SelectScrollDownButton = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
471
471
|
SelectPrimitive.ScrollDownButton,
|
|
472
472
|
{
|
|
473
473
|
ref,
|
|
@@ -480,7 +480,7 @@ var SelectScrollDownButton = React27.forwardRef(({ className, ...props }, ref) =
|
|
|
480
480
|
}
|
|
481
481
|
));
|
|
482
482
|
SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
|
|
483
|
-
var SelectContent =
|
|
483
|
+
var SelectContent = React25.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
|
|
484
484
|
SelectPrimitive.Content,
|
|
485
485
|
{
|
|
486
486
|
ref,
|
|
@@ -508,7 +508,7 @@ var SelectContent = React27.forwardRef(({ className, children, position = "poppe
|
|
|
508
508
|
}
|
|
509
509
|
) }));
|
|
510
510
|
SelectContent.displayName = SelectPrimitive.Content.displayName;
|
|
511
|
-
var SelectLabel =
|
|
511
|
+
var SelectLabel = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
512
512
|
SelectPrimitive.Label,
|
|
513
513
|
{
|
|
514
514
|
ref,
|
|
@@ -517,7 +517,7 @@ var SelectLabel = React27.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
517
517
|
}
|
|
518
518
|
));
|
|
519
519
|
SelectLabel.displayName = SelectPrimitive.Label.displayName;
|
|
520
|
-
var SelectItem =
|
|
520
|
+
var SelectItem = React25.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
521
521
|
SelectPrimitive.Item,
|
|
522
522
|
{
|
|
523
523
|
ref,
|
|
@@ -533,7 +533,7 @@ var SelectItem = React27.forwardRef(({ className, children, ...props }, ref) =>
|
|
|
533
533
|
}
|
|
534
534
|
));
|
|
535
535
|
SelectItem.displayName = SelectPrimitive.Item.displayName;
|
|
536
|
-
var SelectSeparator =
|
|
536
|
+
var SelectSeparator = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
537
537
|
SelectPrimitive.Separator,
|
|
538
538
|
{
|
|
539
539
|
ref,
|
|
@@ -545,7 +545,7 @@ SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
|
|
|
545
545
|
var TooltipProvider = TooltipPrimitive.Provider;
|
|
546
546
|
var Tooltip = TooltipPrimitive.Root;
|
|
547
547
|
var TooltipTrigger = TooltipPrimitive.Trigger;
|
|
548
|
-
var TooltipContent =
|
|
548
|
+
var TooltipContent = React25.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
549
549
|
TooltipPrimitive.Content,
|
|
550
550
|
{
|
|
551
551
|
ref,
|
|
@@ -632,27 +632,27 @@ function FilterFieldItem({
|
|
|
632
632
|
placeholder: "Enter text...",
|
|
633
633
|
minLength: fieldConfig.textConfig?.minLength,
|
|
634
634
|
maxLength: fieldConfig.textConfig?.maxLength,
|
|
635
|
-
className: "cls_filter_text_input w-full min-w-0"
|
|
635
|
+
className: "cls_filter_text_input h-8 w-full min-w-0 text-sm"
|
|
636
636
|
}
|
|
637
637
|
);
|
|
638
|
-
case "number":
|
|
638
|
+
case "number": {
|
|
639
639
|
const numberOperators = [
|
|
640
|
-
{ value: "equals", label: "
|
|
641
|
-
{ value: "not_equals", label: "
|
|
642
|
-
{ value: "greater_than", label: "
|
|
643
|
-
{ value: "less_than", label: "
|
|
644
|
-
{ value: "greater_equal", label: "
|
|
645
|
-
{ value: "less_equal", label: "
|
|
640
|
+
{ value: "equals", label: "=" },
|
|
641
|
+
{ value: "not_equals", label: "\u2260" },
|
|
642
|
+
{ value: "greater_than", label: ">" },
|
|
643
|
+
{ value: "less_than", label: "<" },
|
|
644
|
+
{ value: "greater_equal", label: "\u2265" },
|
|
645
|
+
{ value: "less_equal", label: "\u2264" }
|
|
646
646
|
];
|
|
647
|
-
return /* @__PURE__ */ jsxs("div", { className: "cls_number_filter_container flex
|
|
647
|
+
return /* @__PURE__ */ jsxs("div", { className: "cls_number_filter_container flex w-full items-center gap-1.5", children: [
|
|
648
648
|
/* @__PURE__ */ jsxs(
|
|
649
649
|
Select,
|
|
650
650
|
{
|
|
651
651
|
value: filterConfig.operator || "equals",
|
|
652
652
|
onValueChange: (value) => onOperatorChange?.(value),
|
|
653
653
|
children: [
|
|
654
|
-
/* @__PURE__ */ jsx(SelectTrigger, { className: "cls_operator_select
|
|
655
|
-
/* @__PURE__ */ jsx(SelectContent, { children: numberOperators.map((op) => /* @__PURE__ */ jsx(SelectItem, { value: op.value, children: op.label }, op.value)) })
|
|
654
|
+
/* @__PURE__ */ jsx(SelectTrigger, { className: "cls_operator_select h-8 w-[60px] shrink-0 text-sm", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
|
|
655
|
+
/* @__PURE__ */ jsx(SelectContent, { children: numberOperators.map((op) => /* @__PURE__ */ jsx(SelectItem, { value: op.value, children: /* @__PURE__ */ jsx("span", { className: "font-mono", children: op.label }) }, op.value)) })
|
|
656
656
|
]
|
|
657
657
|
}
|
|
658
658
|
),
|
|
@@ -668,14 +668,10 @@ function FilterFieldItem({
|
|
|
668
668
|
return;
|
|
669
669
|
}
|
|
670
670
|
let numValue = fieldConfig.numberConfig?.allowDecimal ? parseFloat(value) : parseInt(value, 10);
|
|
671
|
-
if (isNaN(numValue))
|
|
672
|
-
return;
|
|
673
|
-
}
|
|
671
|
+
if (isNaN(numValue)) return;
|
|
674
672
|
if (fieldConfig.numberConfig?.allowDecimal && fieldConfig.numberConfig?.decimalLength) {
|
|
675
673
|
const decimalPlaces = value.split(".")[1]?.length || 0;
|
|
676
|
-
if (decimalPlaces > fieldConfig.numberConfig.decimalLength)
|
|
677
|
-
return;
|
|
678
|
-
}
|
|
674
|
+
if (decimalPlaces > fieldConfig.numberConfig.decimalLength) return;
|
|
679
675
|
}
|
|
680
676
|
if (fieldConfig.numberConfig?.min !== void 0 && numValue < fieldConfig.numberConfig.min) {
|
|
681
677
|
numValue = fieldConfig.numberConfig.min;
|
|
@@ -685,14 +681,15 @@ function FilterFieldItem({
|
|
|
685
681
|
}
|
|
686
682
|
onValueChange(numValue);
|
|
687
683
|
},
|
|
688
|
-
placeholder: "
|
|
684
|
+
placeholder: "Value",
|
|
689
685
|
min: fieldConfig.numberConfig?.min,
|
|
690
686
|
max: fieldConfig.numberConfig?.max,
|
|
691
687
|
step: fieldConfig.numberConfig?.allowDecimal ? 0.01 : 1,
|
|
692
|
-
className: "cls_filter_number_input flex-1 min-w-0"
|
|
688
|
+
className: "cls_filter_number_input h-8 flex-1 min-w-0 text-sm tabular-nums"
|
|
693
689
|
}
|
|
694
690
|
)
|
|
695
691
|
] });
|
|
692
|
+
}
|
|
696
693
|
case "combobox":
|
|
697
694
|
return /* @__PURE__ */ jsxs(
|
|
698
695
|
Select,
|
|
@@ -700,12 +697,12 @@ function FilterFieldItem({
|
|
|
700
697
|
value: filterConfig.value || "",
|
|
701
698
|
onValueChange: (value) => onValueChange(value),
|
|
702
699
|
children: [
|
|
703
|
-
/* @__PURE__ */ jsx(SelectTrigger, { className: "cls_filter_combobox_select w-full min-w-0", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select option..." }) }),
|
|
700
|
+
/* @__PURE__ */ jsx(SelectTrigger, { className: "cls_filter_combobox_select h-8 w-full min-w-0 text-sm", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select option..." }) }),
|
|
704
701
|
/* @__PURE__ */ jsx(SelectContent, { children: fieldConfig.comboboxOptions?.map((option) => /* @__PURE__ */ jsx(SelectItem, { value: option.value, children: option.label }, option.value)) })
|
|
705
702
|
]
|
|
706
703
|
}
|
|
707
704
|
);
|
|
708
|
-
case "boolean":
|
|
705
|
+
case "boolean": {
|
|
709
706
|
const trueLabel = fieldConfig.booleanLabels?.trueLabel || "On";
|
|
710
707
|
const falseLabel = fieldConfig.booleanLabels?.falseLabel || "Off";
|
|
711
708
|
return /* @__PURE__ */ jsxs(
|
|
@@ -714,7 +711,7 @@ function FilterFieldItem({
|
|
|
714
711
|
value: filterConfig.value !== void 0 && filterConfig.value !== null ? String(filterConfig.value) : "",
|
|
715
712
|
onValueChange: (value) => onValueChange(value === "true"),
|
|
716
713
|
children: [
|
|
717
|
-
/* @__PURE__ */ jsx(SelectTrigger, { className: "cls_filter_boolean_select w-full min-w-0", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select..." }) }),
|
|
714
|
+
/* @__PURE__ */ jsx(SelectTrigger, { className: "cls_filter_boolean_select h-8 w-full min-w-0 text-sm", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select..." }) }),
|
|
718
715
|
/* @__PURE__ */ jsxs(SelectContent, { children: [
|
|
719
716
|
/* @__PURE__ */ jsx(SelectItem, { value: "true", children: trueLabel }),
|
|
720
717
|
/* @__PURE__ */ jsx(SelectItem, { value: "false", children: falseLabel })
|
|
@@ -722,25 +719,26 @@ function FilterFieldItem({
|
|
|
722
719
|
]
|
|
723
720
|
}
|
|
724
721
|
);
|
|
725
|
-
|
|
722
|
+
}
|
|
723
|
+
case "date": {
|
|
726
724
|
const dateOperators = [
|
|
727
|
-
{ value: "equals", label: "
|
|
728
|
-
{ value: "not_equals", label: "
|
|
729
|
-
{ value: "greater_than", label: "
|
|
730
|
-
{ value: "less_than", label: "
|
|
731
|
-
{ value: "greater_equal", label: "
|
|
732
|
-
{ value: "less_equal", label: "
|
|
725
|
+
{ value: "equals", label: "=" },
|
|
726
|
+
{ value: "not_equals", label: "\u2260" },
|
|
727
|
+
{ value: "greater_than", label: ">" },
|
|
728
|
+
{ value: "less_than", label: "<" },
|
|
729
|
+
{ value: "greater_equal", label: "\u2265" },
|
|
730
|
+
{ value: "less_equal", label: "\u2264" }
|
|
733
731
|
];
|
|
734
732
|
const selectedDate = filterConfig.value ? typeof filterConfig.value === "string" ? new Date(filterConfig.value) : filterConfig.value : void 0;
|
|
735
|
-
return /* @__PURE__ */ jsxs("div", { className: "cls_date_filter_container flex
|
|
733
|
+
return /* @__PURE__ */ jsxs("div", { className: "cls_date_filter_container flex w-full items-center gap-1.5", children: [
|
|
736
734
|
/* @__PURE__ */ jsxs(
|
|
737
735
|
Select,
|
|
738
736
|
{
|
|
739
737
|
value: filterConfig.operator || "equals",
|
|
740
738
|
onValueChange: (value) => onOperatorChange?.(value),
|
|
741
739
|
children: [
|
|
742
|
-
/* @__PURE__ */ jsx(SelectTrigger, { className: "cls_operator_select
|
|
743
|
-
/* @__PURE__ */ jsx(SelectContent, { children: dateOperators.map((op) => /* @__PURE__ */ jsx(SelectItem, { value: op.value, children: op.label }, op.value)) })
|
|
740
|
+
/* @__PURE__ */ jsx(SelectTrigger, { className: "cls_operator_select h-8 w-[60px] shrink-0 text-sm", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
|
|
741
|
+
/* @__PURE__ */ jsx(SelectContent, { children: dateOperators.map((op) => /* @__PURE__ */ jsx(SelectItem, { value: op.value, children: /* @__PURE__ */ jsx("span", { className: "font-mono", children: op.label }) }, op.value)) })
|
|
744
742
|
]
|
|
745
743
|
}
|
|
746
744
|
),
|
|
@@ -750,11 +748,11 @@ function FilterFieldItem({
|
|
|
750
748
|
{
|
|
751
749
|
variant: "outline",
|
|
752
750
|
className: cn(
|
|
753
|
-
"cls_date_picker_trigger
|
|
751
|
+
"cls_date_picker_trigger h-8 flex-1 justify-start gap-2 px-2.5 text-left text-sm font-normal min-w-0",
|
|
754
752
|
!selectedDate && "text-muted-foreground"
|
|
755
753
|
),
|
|
756
754
|
children: [
|
|
757
|
-
/* @__PURE__ */ jsx(Calendar$1, { className: "cls_calendar_icon
|
|
755
|
+
/* @__PURE__ */ jsx(Calendar$1, { className: "cls_calendar_icon h-3.5 w-3.5 shrink-0" }),
|
|
758
756
|
/* @__PURE__ */ jsx("span", { className: "cls_date_text truncate", children: selectedDate ? format(selectedDate, "MMM d, yyyy") : "Pick a date" })
|
|
759
757
|
]
|
|
760
758
|
}
|
|
@@ -773,24 +771,27 @@ function FilterFieldItem({
|
|
|
773
771
|
) })
|
|
774
772
|
] })
|
|
775
773
|
] });
|
|
774
|
+
}
|
|
776
775
|
default:
|
|
777
776
|
return null;
|
|
778
777
|
}
|
|
779
778
|
};
|
|
780
|
-
return /* @__PURE__ */ jsxs("div", { className: "cls_filter_field_item flex flex-col
|
|
781
|
-
/* @__PURE__ */ jsx("span", { className: "cls_field_label text-
|
|
782
|
-
/* @__PURE__ */
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
779
|
+
return /* @__PURE__ */ jsxs("div", { className: "cls_filter_field_item group flex flex-col gap-2 rounded-lg border border-border/70 bg-card px-3 py-2.5 transition-colors hover:border-border sm:flex-row sm:items-center sm:gap-3", children: [
|
|
780
|
+
/* @__PURE__ */ jsx("span", { className: "cls_field_label w-full shrink-0 truncate text-xs font-semibold uppercase tracking-wide text-muted-foreground sm:w-[110px] sm:text-sm sm:normal-case sm:font-medium sm:text-foreground sm:tracking-normal", children: fieldConfig.label }),
|
|
781
|
+
/* @__PURE__ */ jsxs("div", { className: "cls_field_input_container flex min-w-0 flex-1 items-center gap-2", children: [
|
|
782
|
+
/* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1", children: renderInput() }),
|
|
783
|
+
/* @__PURE__ */ jsx(
|
|
784
|
+
Button,
|
|
785
|
+
{
|
|
786
|
+
variant: "ghost",
|
|
787
|
+
size: "sm",
|
|
788
|
+
onClick: onDelete,
|
|
789
|
+
className: "cls_delete_btn h-7 w-7 shrink-0 p-0 text-muted-foreground/60 hover:bg-destructive/10 hover:text-destructive",
|
|
790
|
+
"aria-label": `Remove ${fieldConfig.label} filter`,
|
|
791
|
+
children: /* @__PURE__ */ jsx(X, { className: "cls_delete_icon h-3.5 w-3.5" })
|
|
792
|
+
}
|
|
793
|
+
)
|
|
794
|
+
] })
|
|
794
795
|
] });
|
|
795
796
|
}
|
|
796
797
|
function HazoUiMultiFilterDialog({
|
|
@@ -798,7 +799,7 @@ function HazoUiMultiFilterDialog({
|
|
|
798
799
|
onFilterChange,
|
|
799
800
|
initialFilters = [],
|
|
800
801
|
title = "Filter",
|
|
801
|
-
description = "Add
|
|
802
|
+
description = "Add fields to filter by. Select a field and set its value.",
|
|
802
803
|
headerBackgroundColor,
|
|
803
804
|
headerTextColor,
|
|
804
805
|
submitButtonBackgroundColor,
|
|
@@ -848,13 +849,9 @@ function HazoUiMultiFilterDialog({
|
|
|
848
849
|
}
|
|
849
850
|
}, [isOpen, initialFilters]);
|
|
850
851
|
const handleAddField = (fieldValue) => {
|
|
851
|
-
if (filterFields.some((ff) => ff.field === fieldValue))
|
|
852
|
-
return;
|
|
853
|
-
}
|
|
852
|
+
if (filterFields.some((ff) => ff.field === fieldValue)) return;
|
|
854
853
|
const fieldConfig = availableFields.find((af) => af.value === fieldValue);
|
|
855
|
-
if (!fieldConfig)
|
|
856
|
-
return;
|
|
857
|
-
}
|
|
854
|
+
if (!fieldConfig) return;
|
|
858
855
|
let defaultValue = "";
|
|
859
856
|
if (fieldConfig.type === "boolean") {
|
|
860
857
|
defaultValue = false;
|
|
@@ -907,7 +904,7 @@ function HazoUiMultiFilterDialog({
|
|
|
907
904
|
};
|
|
908
905
|
const hasActiveFilters = initialFilters.length > 0;
|
|
909
906
|
const tooltipContent = hasActiveFilters ? /* @__PURE__ */ jsxs("div", { className: "cls_filter_tooltip_content space-y-1", children: [
|
|
910
|
-
/* @__PURE__ */ jsx("div", { className: "cls_tooltip_title text-xs font-semibold mb-1", children: "Active
|
|
907
|
+
/* @__PURE__ */ jsx("div", { className: "cls_tooltip_title text-xs font-semibold mb-1", children: "Active filters" }),
|
|
911
908
|
initialFilters.map((filterConfig) => {
|
|
912
909
|
const fieldConfig = getFieldConfig(filterConfig.field);
|
|
913
910
|
if (!fieldConfig) return null;
|
|
@@ -951,152 +948,114 @@ function HazoUiMultiFilterDialog({
|
|
|
951
948
|
)
|
|
952
949
|
}
|
|
953
950
|
),
|
|
954
|
-
"Filter"
|
|
951
|
+
"Filter",
|
|
952
|
+
hasActiveFilters && /* @__PURE__ */ jsx("span", { className: "cls_filter_count ml-2 inline-flex h-4 min-w-4 items-center justify-center rounded-full bg-blue-600 px-1 text-[10px] font-semibold text-white", children: initialFilters.length })
|
|
955
953
|
]
|
|
956
954
|
}
|
|
957
955
|
) }) }),
|
|
958
956
|
/* @__PURE__ */ jsx(TooltipContent, { children: tooltipContent })
|
|
959
957
|
] }) }),
|
|
960
|
-
/* @__PURE__ */ jsxs(DialogContent, { className: "cls_filter_dialog_content max-w-lg
|
|
961
|
-
/* @__PURE__ */ jsxs(
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
958
|
+
/* @__PURE__ */ jsxs(DialogContent, { className: "cls_filter_dialog_content max-w-lg gap-0 p-0 sm:rounded-xl max-h-[90vh]", children: [
|
|
959
|
+
/* @__PURE__ */ jsxs(
|
|
960
|
+
DialogHeader,
|
|
961
|
+
{
|
|
962
|
+
className: "cls_filter_dialog_header space-y-1 border-b px-5 py-4 text-left",
|
|
963
|
+
style: headerStyles,
|
|
964
|
+
children: [
|
|
965
|
+
/* @__PURE__ */ jsx(DialogTitle, { className: "text-base font-semibold", children: title }),
|
|
966
|
+
/* @__PURE__ */ jsx(DialogDescription, { className: "text-xs leading-relaxed text-muted-foreground", children: description })
|
|
967
|
+
]
|
|
968
|
+
}
|
|
969
|
+
),
|
|
970
|
+
/* @__PURE__ */ jsxs("div", { className: "cls_filter_dialog_body space-y-3 overflow-y-auto px-5 py-4", children: [
|
|
971
|
+
filterFields.length > 0 ? /* @__PURE__ */ jsx("div", { className: "cls_filter_fields_list space-y-1.5", children: filterFields.map((filterConfig) => {
|
|
972
|
+
const fieldConfig = getFieldConfig(filterConfig.field);
|
|
973
|
+
if (!fieldConfig) return null;
|
|
974
|
+
return /* @__PURE__ */ jsx(
|
|
975
|
+
FilterFieldItem,
|
|
976
|
+
{
|
|
977
|
+
filterConfig,
|
|
978
|
+
fieldConfig,
|
|
979
|
+
onValueChange: (value) => handleValueChange(filterConfig.field, value),
|
|
980
|
+
onOperatorChange: (operator) => handleOperatorChange(filterConfig.field, operator),
|
|
981
|
+
onDelete: () => handleDeleteField(filterConfig.field)
|
|
982
|
+
},
|
|
983
|
+
filterConfig.field
|
|
984
|
+
);
|
|
985
|
+
}) }) : /* @__PURE__ */ jsx("div", { className: "cls_empty_filter_fields rounded-lg border border-dashed border-border/70 bg-muted/20 px-4 py-6 text-center text-xs text-muted-foreground", children: "No filters yet. Add one below to narrow down the results." }),
|
|
966
986
|
/* @__PURE__ */ jsx("div", { className: "cls_add_field_section", children: /* @__PURE__ */ jsxs(Popover, { open: isComboboxOpen, onOpenChange: setIsComboboxOpen, children: [
|
|
967
987
|
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
968
988
|
Button,
|
|
969
989
|
{
|
|
970
|
-
variant: "
|
|
990
|
+
variant: "ghost",
|
|
971
991
|
role: "combobox",
|
|
972
992
|
"aria-expanded": isComboboxOpen,
|
|
973
|
-
|
|
993
|
+
disabled: availableFieldsToAdd.length === 0,
|
|
994
|
+
className: "cls_add_field_combobox w-full justify-start gap-2 border border-dashed border-border/70 text-sm font-medium text-muted-foreground hover:border-border hover:bg-muted/40 hover:text-foreground",
|
|
974
995
|
children: [
|
|
975
|
-
/* @__PURE__ */
|
|
976
|
-
|
|
977
|
-
/* @__PURE__ */ jsx("span", { children: "Add field" })
|
|
978
|
-
] }),
|
|
979
|
-
/* @__PURE__ */ jsx(ChevronsUpDown, { className: "cls_chevron_icon ml-2 h-4 w-4 shrink-0 opacity-50" })
|
|
996
|
+
/* @__PURE__ */ jsx(Plus, { className: "cls_plus_icon h-4 w-4" }),
|
|
997
|
+
/* @__PURE__ */ jsx("span", { children: availableFieldsToAdd.length === 0 ? "All fields added" : "Add filter field" })
|
|
980
998
|
]
|
|
981
999
|
}
|
|
982
1000
|
) }),
|
|
983
|
-
/* @__PURE__ */ jsx(PopoverContent, { className: "cls_combobox_popover w-
|
|
1001
|
+
/* @__PURE__ */ jsx(PopoverContent, { className: "cls_combobox_popover w-[var(--radix-popover-trigger-width)] p-0", align: "start", children: /* @__PURE__ */ jsxs(Command, { children: [
|
|
984
1002
|
/* @__PURE__ */ jsx(CommandInput, { placeholder: "Search fields...", className: "cls_command_input" }),
|
|
985
|
-
/* @__PURE__ */ jsx(CommandList, { children: availableFieldsToAdd.length === 0 ? /* @__PURE__ */ jsx(CommandEmpty, { children: "No fields
|
|
1003
|
+
/* @__PURE__ */ jsx(CommandList, { children: availableFieldsToAdd.length === 0 ? /* @__PURE__ */ jsx(CommandEmpty, { children: "No fields available." }) : /* @__PURE__ */ jsx(CommandGroup, { children: availableFieldsToAdd.map((field) => /* @__PURE__ */ jsx(
|
|
986
1004
|
CommandItem,
|
|
987
1005
|
{
|
|
988
1006
|
value: field.label,
|
|
989
1007
|
onSelect: () => handleAddField(field.value),
|
|
990
1008
|
className: "cls_command_item",
|
|
991
|
-
children:
|
|
992
|
-
/* @__PURE__ */ jsx(
|
|
993
|
-
Check,
|
|
994
|
-
{
|
|
995
|
-
className: cn(
|
|
996
|
-
"cls_check_icon mr-2 h-4 w-4",
|
|
997
|
-
"opacity-0"
|
|
998
|
-
)
|
|
999
|
-
}
|
|
1000
|
-
),
|
|
1001
|
-
field.label
|
|
1002
|
-
]
|
|
1009
|
+
children: field.label
|
|
1003
1010
|
},
|
|
1004
1011
|
field.value
|
|
1005
1012
|
)) }) })
|
|
1006
1013
|
] }) })
|
|
1007
|
-
] }) })
|
|
1008
|
-
filterFields.length > 0 ? /* @__PURE__ */ jsx("div", { className: "cls_filter_fields_list space-y-2", children: filterFields.map((filterConfig) => {
|
|
1009
|
-
const fieldConfig = getFieldConfig(filterConfig.field);
|
|
1010
|
-
if (!fieldConfig) return null;
|
|
1011
|
-
return /* @__PURE__ */ jsx(
|
|
1012
|
-
FilterFieldItem,
|
|
1013
|
-
{
|
|
1014
|
-
filterConfig,
|
|
1015
|
-
fieldConfig,
|
|
1016
|
-
onValueChange: (value) => handleValueChange(filterConfig.field, value),
|
|
1017
|
-
onOperatorChange: (operator) => handleOperatorChange(filterConfig.field, operator),
|
|
1018
|
-
onDelete: () => handleDeleteField(filterConfig.field)
|
|
1019
|
-
},
|
|
1020
|
-
filterConfig.field
|
|
1021
|
-
);
|
|
1022
|
-
}) }) : /* @__PURE__ */ jsx("div", { className: "cls_empty_filter_fields text-center py-8 text-sm text-muted-foreground", children: 'No filter fields added. Click "Add field" to add filtering criteria.' })
|
|
1014
|
+
] }) })
|
|
1023
1015
|
] }),
|
|
1024
|
-
/* @__PURE__ */ jsxs(DialogFooter, { children: [
|
|
1025
|
-
filterFields.length > 0 && /* @__PURE__ */
|
|
1016
|
+
/* @__PURE__ */ jsxs(DialogFooter, { className: "cls_filter_dialog_footer flex flex-row items-center justify-between gap-2 border-t bg-muted/20 px-5 py-3 sm:justify-between sm:space-x-0", children: [
|
|
1017
|
+
/* @__PURE__ */ jsx("div", { className: "cls_footer_left", children: filterFields.length > 0 && /* @__PURE__ */ jsx(
|
|
1026
1018
|
Button,
|
|
1027
1019
|
{
|
|
1028
|
-
variant: "
|
|
1020
|
+
variant: "ghost",
|
|
1021
|
+
size: "sm",
|
|
1029
1022
|
onClick: handleClearAll,
|
|
1030
|
-
className: "cls_clear_all_btn",
|
|
1023
|
+
className: "cls_clear_all_btn text-muted-foreground hover:text-foreground",
|
|
1031
1024
|
style: clearButtonStyles,
|
|
1032
|
-
children:
|
|
1033
|
-
/* @__PURE__ */ jsx(X, { className: "cls_clear_all_icon h-4 w-4 mr-2" }),
|
|
1034
|
-
"Clear All"
|
|
1035
|
-
]
|
|
1036
|
-
}
|
|
1037
|
-
),
|
|
1038
|
-
/* @__PURE__ */ jsx(
|
|
1039
|
-
Button,
|
|
1040
|
-
{
|
|
1041
|
-
onClick: handleApply,
|
|
1042
|
-
className: "cls_apply_btn",
|
|
1043
|
-
style: submitButtonStyles,
|
|
1044
|
-
children: "Apply"
|
|
1045
|
-
}
|
|
1046
|
-
),
|
|
1047
|
-
/* @__PURE__ */ jsx(
|
|
1048
|
-
Button,
|
|
1049
|
-
{
|
|
1050
|
-
variant: "outline",
|
|
1051
|
-
onClick: handleCancel,
|
|
1052
|
-
className: "cls_cancel_btn",
|
|
1053
|
-
style: cancelButtonStyles,
|
|
1054
|
-
children: "Cancel"
|
|
1025
|
+
children: "Clear all"
|
|
1055
1026
|
}
|
|
1056
|
-
)
|
|
1027
|
+
) }),
|
|
1028
|
+
/* @__PURE__ */ jsxs("div", { className: "cls_footer_right flex items-center gap-2", children: [
|
|
1029
|
+
/* @__PURE__ */ jsx(
|
|
1030
|
+
Button,
|
|
1031
|
+
{
|
|
1032
|
+
variant: "outline",
|
|
1033
|
+
size: "sm",
|
|
1034
|
+
onClick: handleCancel,
|
|
1035
|
+
className: "cls_cancel_btn",
|
|
1036
|
+
style: cancelButtonStyles,
|
|
1037
|
+
children: "Cancel"
|
|
1038
|
+
}
|
|
1039
|
+
),
|
|
1040
|
+
/* @__PURE__ */ jsx(
|
|
1041
|
+
Button,
|
|
1042
|
+
{
|
|
1043
|
+
size: "sm",
|
|
1044
|
+
onClick: handleApply,
|
|
1045
|
+
className: "cls_apply_btn",
|
|
1046
|
+
style: submitButtonStyles,
|
|
1047
|
+
children: "Apply"
|
|
1048
|
+
}
|
|
1049
|
+
)
|
|
1050
|
+
] })
|
|
1057
1051
|
] })
|
|
1058
1052
|
] })
|
|
1059
1053
|
] });
|
|
1060
1054
|
}
|
|
1061
|
-
var Switch = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
1062
|
-
SwitchPrimitives.Root,
|
|
1063
|
-
{
|
|
1064
|
-
className: cn(
|
|
1065
|
-
"peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",
|
|
1066
|
-
className
|
|
1067
|
-
),
|
|
1068
|
-
...props,
|
|
1069
|
-
ref,
|
|
1070
|
-
children: /* @__PURE__ */ jsx(
|
|
1071
|
-
SwitchPrimitives.Thumb,
|
|
1072
|
-
{
|
|
1073
|
-
className: cn(
|
|
1074
|
-
"pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0"
|
|
1075
|
-
)
|
|
1076
|
-
}
|
|
1077
|
-
)
|
|
1078
|
-
}
|
|
1079
|
-
));
|
|
1080
|
-
Switch.displayName = SwitchPrimitives.Root.displayName;
|
|
1081
|
-
var Label2 = React27.forwardRef(
|
|
1082
|
-
({ className, ...props }, ref) => {
|
|
1083
|
-
return /* @__PURE__ */ jsx(
|
|
1084
|
-
"label",
|
|
1085
|
-
{
|
|
1086
|
-
ref,
|
|
1087
|
-
className: cn(
|
|
1088
|
-
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
|
|
1089
|
-
className
|
|
1090
|
-
),
|
|
1091
|
-
...props
|
|
1092
|
-
}
|
|
1093
|
-
);
|
|
1094
|
-
}
|
|
1095
|
-
);
|
|
1096
|
-
Label2.displayName = "Label";
|
|
1097
1055
|
function SortableSortFieldItem({
|
|
1098
1056
|
sortConfig,
|
|
1099
1057
|
fieldLabel,
|
|
1058
|
+
priority,
|
|
1100
1059
|
onDirectionChange,
|
|
1101
1060
|
onDelete
|
|
1102
1061
|
}) {
|
|
@@ -1111,46 +1070,88 @@ function SortableSortFieldItem({
|
|
|
1111
1070
|
const style = {
|
|
1112
1071
|
transform: CSS.Transform.toString(transform),
|
|
1113
1072
|
transition,
|
|
1114
|
-
opacity: isDragging ? 0.
|
|
1073
|
+
opacity: isDragging ? 0.6 : 1,
|
|
1074
|
+
zIndex: isDragging ? 10 : void 0
|
|
1115
1075
|
};
|
|
1116
1076
|
return /* @__PURE__ */ jsxs(
|
|
1117
1077
|
"div",
|
|
1118
1078
|
{
|
|
1119
1079
|
ref: setNodeRef,
|
|
1120
1080
|
style,
|
|
1121
|
-
className:
|
|
1081
|
+
className: cn(
|
|
1082
|
+
"cls_sortable_sort_field_item group flex items-center gap-2.5 rounded-lg border border-border/70 bg-card pl-1.5 pr-2 py-2 transition-shadow",
|
|
1083
|
+
isDragging ? "shadow-md" : "hover:border-border"
|
|
1084
|
+
),
|
|
1122
1085
|
children: [
|
|
1123
1086
|
/* @__PURE__ */ jsx(
|
|
1124
|
-
"
|
|
1087
|
+
"button",
|
|
1125
1088
|
{
|
|
1089
|
+
type: "button",
|
|
1126
1090
|
...attributes,
|
|
1127
1091
|
...listeners,
|
|
1128
|
-
className: "cls_drag_handle cursor-grab
|
|
1092
|
+
className: "cls_drag_handle flex h-7 w-5 shrink-0 cursor-grab items-center justify-center rounded text-muted-foreground/60 hover:text-foreground active:cursor-grabbing",
|
|
1093
|
+
"aria-label": `Reorder ${fieldLabel}`,
|
|
1129
1094
|
children: /* @__PURE__ */ jsx(GripVertical, { className: "cls_drag_icon h-4 w-4" })
|
|
1130
1095
|
}
|
|
1131
1096
|
),
|
|
1132
|
-
/* @__PURE__ */ jsx(
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1097
|
+
/* @__PURE__ */ jsx(
|
|
1098
|
+
"span",
|
|
1099
|
+
{
|
|
1100
|
+
className: "cls_priority_badge inline-flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-muted text-[10px] font-semibold tabular-nums text-muted-foreground",
|
|
1101
|
+
"aria-label": `Sort priority ${priority}`,
|
|
1102
|
+
children: priority
|
|
1103
|
+
}
|
|
1104
|
+
),
|
|
1105
|
+
/* @__PURE__ */ jsx("span", { className: "cls_field_label flex-1 truncate text-sm font-medium text-foreground", children: fieldLabel }),
|
|
1106
|
+
/* @__PURE__ */ jsxs(
|
|
1107
|
+
"div",
|
|
1108
|
+
{
|
|
1109
|
+
role: "radiogroup",
|
|
1110
|
+
"aria-label": `Sort direction for ${fieldLabel}`,
|
|
1111
|
+
className: "cls_direction_control inline-flex shrink-0 items-center rounded-md border border-border/70 bg-muted/40 p-0.5",
|
|
1112
|
+
children: [
|
|
1113
|
+
/* @__PURE__ */ jsxs(
|
|
1114
|
+
"button",
|
|
1115
|
+
{
|
|
1116
|
+
type: "button",
|
|
1117
|
+
role: "radio",
|
|
1118
|
+
"aria-checked": sortConfig.direction === "asc",
|
|
1119
|
+
"data-active": sortConfig.direction === "asc",
|
|
1120
|
+
onClick: () => onDirectionChange("asc"),
|
|
1121
|
+
className: "cls_dir_asc inline-flex items-center gap-1 rounded px-2 py-1 text-xs font-medium text-muted-foreground transition-colors data-[active=true]:bg-background data-[active=true]:text-foreground data-[active=true]:shadow-sm hover:text-foreground",
|
|
1122
|
+
children: [
|
|
1123
|
+
/* @__PURE__ */ jsx(ArrowUp, { className: "h-3 w-3" }),
|
|
1124
|
+
"Asc"
|
|
1125
|
+
]
|
|
1126
|
+
}
|
|
1127
|
+
),
|
|
1128
|
+
/* @__PURE__ */ jsxs(
|
|
1129
|
+
"button",
|
|
1130
|
+
{
|
|
1131
|
+
type: "button",
|
|
1132
|
+
role: "radio",
|
|
1133
|
+
"aria-checked": sortConfig.direction === "desc",
|
|
1134
|
+
"data-active": sortConfig.direction === "desc",
|
|
1135
|
+
onClick: () => onDirectionChange("desc"),
|
|
1136
|
+
className: "cls_dir_desc inline-flex items-center gap-1 rounded px-2 py-1 text-xs font-medium text-muted-foreground transition-colors data-[active=true]:bg-background data-[active=true]:text-foreground data-[active=true]:shadow-sm hover:text-foreground",
|
|
1137
|
+
children: [
|
|
1138
|
+
/* @__PURE__ */ jsx(ArrowDown, { className: "h-3 w-3" }),
|
|
1139
|
+
"Desc"
|
|
1140
|
+
]
|
|
1141
|
+
}
|
|
1142
|
+
)
|
|
1143
|
+
]
|
|
1144
|
+
}
|
|
1145
|
+
),
|
|
1145
1146
|
/* @__PURE__ */ jsx(
|
|
1146
1147
|
Button,
|
|
1147
1148
|
{
|
|
1148
1149
|
variant: "ghost",
|
|
1149
1150
|
size: "sm",
|
|
1150
1151
|
onClick: onDelete,
|
|
1151
|
-
className: "cls_delete_btn h-
|
|
1152
|
+
className: "cls_delete_btn h-7 w-7 shrink-0 p-0 text-muted-foreground/60 hover:bg-destructive/10 hover:text-destructive",
|
|
1152
1153
|
"aria-label": `Remove ${fieldLabel} from sort`,
|
|
1153
|
-
children: /* @__PURE__ */ jsx(
|
|
1154
|
+
children: /* @__PURE__ */ jsx(X, { className: "cls_delete_icon h-3.5 w-3.5" })
|
|
1154
1155
|
}
|
|
1155
1156
|
)
|
|
1156
1157
|
]
|
|
@@ -1162,7 +1163,7 @@ function HazoUiMultiSortDialog({
|
|
|
1162
1163
|
onSortChange,
|
|
1163
1164
|
initialSortFields = [],
|
|
1164
1165
|
title = "Sort",
|
|
1165
|
-
description = "Add
|
|
1166
|
+
description = "Add fields to sort by, drag to reorder, toggle ascending or descending.",
|
|
1166
1167
|
headerBackgroundColor,
|
|
1167
1168
|
headerTextColor,
|
|
1168
1169
|
submitButtonBackgroundColor,
|
|
@@ -1207,7 +1208,7 @@ function HazoUiMultiSortDialog({
|
|
|
1207
1208
|
const [sortFields, setSortFields] = useState(initialSortFields);
|
|
1208
1209
|
const [isComboboxOpen, setIsComboboxOpen] = useState(false);
|
|
1209
1210
|
const sensors = useSensors(
|
|
1210
|
-
useSensor(PointerSensor),
|
|
1211
|
+
useSensor(PointerSensor, { activationConstraint: { distance: 4 } }),
|
|
1211
1212
|
useSensor(KeyboardSensor, {
|
|
1212
1213
|
coordinateGetter: sortableKeyboardCoordinates
|
|
1213
1214
|
})
|
|
@@ -1221,11 +1222,7 @@ function HazoUiMultiSortDialog({
|
|
|
1221
1222
|
if (sortFields.some((sf) => sf.field === fieldValue)) {
|
|
1222
1223
|
return;
|
|
1223
1224
|
}
|
|
1224
|
-
|
|
1225
|
-
field: fieldValue,
|
|
1226
|
-
direction: "asc"
|
|
1227
|
-
};
|
|
1228
|
-
setSortFields([...sortFields, newField]);
|
|
1225
|
+
setSortFields([...sortFields, { field: fieldValue, direction: "asc" }]);
|
|
1229
1226
|
setIsComboboxOpen(false);
|
|
1230
1227
|
};
|
|
1231
1228
|
const handleDeleteField = (fieldValue) => {
|
|
@@ -1240,9 +1237,7 @@ function HazoUiMultiSortDialog({
|
|
|
1240
1237
|
};
|
|
1241
1238
|
const handleDragEnd = (event) => {
|
|
1242
1239
|
const { active, over } = event;
|
|
1243
|
-
if (!over || active.id === over.id)
|
|
1244
|
-
return;
|
|
1245
|
-
}
|
|
1240
|
+
if (!over || active.id === over.id) return;
|
|
1246
1241
|
const oldIndex = sortFields.findIndex((sf) => sf.field === active.id);
|
|
1247
1242
|
const newIndex = sortFields.findIndex((sf) => sf.field === over.id);
|
|
1248
1243
|
if (oldIndex !== -1 && newIndex !== -1) {
|
|
@@ -1268,7 +1263,7 @@ function HazoUiMultiSortDialog({
|
|
|
1268
1263
|
};
|
|
1269
1264
|
const hasActiveSorts = initialSortFields.length > 0;
|
|
1270
1265
|
const tooltipContent = hasActiveSorts ? /* @__PURE__ */ jsxs("div", { className: "cls_sort_tooltip_content space-y-1", children: [
|
|
1271
|
-
/* @__PURE__ */ jsx("div", { className: "cls_tooltip_title text-xs font-semibold mb-1", children: "Active
|
|
1266
|
+
/* @__PURE__ */ jsx("div", { className: "cls_tooltip_title text-xs font-semibold mb-1", children: "Active sorts" }),
|
|
1272
1267
|
initialSortFields.map((sortConfig, index) => /* @__PURE__ */ jsxs("div", { className: "cls_tooltip_item text-xs", children: [
|
|
1273
1268
|
index + 1,
|
|
1274
1269
|
". ",
|
|
@@ -1297,61 +1292,27 @@ function HazoUiMultiSortDialog({
|
|
|
1297
1292
|
)
|
|
1298
1293
|
}
|
|
1299
1294
|
),
|
|
1300
|
-
"Sort"
|
|
1295
|
+
"Sort",
|
|
1296
|
+
hasActiveSorts && /* @__PURE__ */ jsx("span", { className: "cls_sort_count ml-2 inline-flex h-4 min-w-4 items-center justify-center rounded-full bg-blue-600 px-1 text-[10px] font-semibold text-white", children: initialSortFields.length })
|
|
1301
1297
|
]
|
|
1302
1298
|
}
|
|
1303
1299
|
) }) }),
|
|
1304
1300
|
/* @__PURE__ */ jsx(TooltipContent, { children: tooltipContent })
|
|
1305
1301
|
] }) }),
|
|
1306
|
-
/* @__PURE__ */ jsxs(DialogContent, { className: "cls_sort_dialog_content max-w-lg", children: [
|
|
1307
|
-
/* @__PURE__ */ jsxs(
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
children: [
|
|
1321
|
-
/* @__PURE__ */ jsxs("div", { className: "cls_combobox_content flex items-center", children: [
|
|
1322
|
-
/* @__PURE__ */ jsx(Plus, { className: "cls_plus_icon h-4 w-4 mr-2" }),
|
|
1323
|
-
/* @__PURE__ */ jsx("span", { children: "Add field" })
|
|
1324
|
-
] }),
|
|
1325
|
-
/* @__PURE__ */ jsx(ChevronsUpDown, { className: "cls_chevron_icon ml-2 h-4 w-4 shrink-0 opacity-50" })
|
|
1326
|
-
]
|
|
1327
|
-
}
|
|
1328
|
-
) }),
|
|
1329
|
-
/* @__PURE__ */ jsx(PopoverContent, { className: "cls_combobox_popover w-full p-0", children: /* @__PURE__ */ jsxs(Command, { children: [
|
|
1330
|
-
/* @__PURE__ */ jsx(CommandInput, { placeholder: "Search fields...", className: "cls_command_input" }),
|
|
1331
|
-
/* @__PURE__ */ jsx(CommandList, { children: availableFieldsToAdd.length === 0 ? /* @__PURE__ */ jsx(CommandEmpty, { children: "No fields found." }) : /* @__PURE__ */ jsx(CommandGroup, { children: availableFieldsToAdd.map((field) => /* @__PURE__ */ jsxs(
|
|
1332
|
-
CommandItem,
|
|
1333
|
-
{
|
|
1334
|
-
value: field.label,
|
|
1335
|
-
onSelect: () => handleAddField(field.value),
|
|
1336
|
-
className: "cls_command_item",
|
|
1337
|
-
children: [
|
|
1338
|
-
/* @__PURE__ */ jsx(
|
|
1339
|
-
Check,
|
|
1340
|
-
{
|
|
1341
|
-
className: cn(
|
|
1342
|
-
"cls_check_icon mr-2 h-4 w-4",
|
|
1343
|
-
"opacity-0"
|
|
1344
|
-
)
|
|
1345
|
-
}
|
|
1346
|
-
),
|
|
1347
|
-
field.label
|
|
1348
|
-
]
|
|
1349
|
-
},
|
|
1350
|
-
field.value
|
|
1351
|
-
)) }) })
|
|
1352
|
-
] }) })
|
|
1353
|
-
] }) }),
|
|
1354
|
-
sortFields.length > 0 ? /* @__PURE__ */ jsx("div", { className: "cls_sort_fields_list space-y-2", children: /* @__PURE__ */ jsx(
|
|
1302
|
+
/* @__PURE__ */ jsxs(DialogContent, { className: "cls_sort_dialog_content max-w-lg gap-0 p-0 sm:rounded-xl", children: [
|
|
1303
|
+
/* @__PURE__ */ jsxs(
|
|
1304
|
+
DialogHeader,
|
|
1305
|
+
{
|
|
1306
|
+
className: "cls_sort_dialog_header space-y-1 border-b px-5 py-4 text-left",
|
|
1307
|
+
style: headerStyles,
|
|
1308
|
+
children: [
|
|
1309
|
+
/* @__PURE__ */ jsx(DialogTitle, { className: "text-base font-semibold", children: title }),
|
|
1310
|
+
/* @__PURE__ */ jsx(DialogDescription, { className: "text-xs leading-relaxed text-muted-foreground", children: description })
|
|
1311
|
+
]
|
|
1312
|
+
}
|
|
1313
|
+
),
|
|
1314
|
+
/* @__PURE__ */ jsxs("div", { className: "cls_sort_dialog_body space-y-3 px-5 py-4", children: [
|
|
1315
|
+
sortFields.length > 0 ? /* @__PURE__ */ jsx("div", { className: "cls_sort_fields_list space-y-1.5", children: /* @__PURE__ */ jsx(
|
|
1355
1316
|
DndContext,
|
|
1356
1317
|
{
|
|
1357
1318
|
sensors,
|
|
@@ -1362,11 +1323,12 @@ function HazoUiMultiSortDialog({
|
|
|
1362
1323
|
{
|
|
1363
1324
|
items: sortFields.map((sf) => sf.field),
|
|
1364
1325
|
strategy: verticalListSortingStrategy,
|
|
1365
|
-
children: sortFields.map((sortConfig) => /* @__PURE__ */ jsx(
|
|
1326
|
+
children: sortFields.map((sortConfig, idx) => /* @__PURE__ */ jsx(
|
|
1366
1327
|
SortableSortFieldItem,
|
|
1367
1328
|
{
|
|
1368
1329
|
sortConfig,
|
|
1369
1330
|
fieldLabel: getFieldLabel(sortConfig.field),
|
|
1331
|
+
priority: idx + 1,
|
|
1370
1332
|
onDirectionChange: (direction) => handleDirectionChange(sortConfig.field, direction),
|
|
1371
1333
|
onDelete: () => handleDeleteField(sortConfig.field)
|
|
1372
1334
|
},
|
|
@@ -1375,46 +1337,77 @@ function HazoUiMultiSortDialog({
|
|
|
1375
1337
|
}
|
|
1376
1338
|
)
|
|
1377
1339
|
}
|
|
1378
|
-
) }) : /* @__PURE__ */ jsx("div", { className: "cls_empty_sort_fields
|
|
1340
|
+
) }) : /* @__PURE__ */ jsx("div", { className: "cls_empty_sort_fields rounded-lg border border-dashed border-border/70 bg-muted/20 px-4 py-6 text-center text-xs text-muted-foreground", children: "No sort fields yet. Add one below to start ordering rows." }),
|
|
1341
|
+
/* @__PURE__ */ jsx("div", { className: "cls_add_field_section", children: /* @__PURE__ */ jsxs(Popover, { open: isComboboxOpen, onOpenChange: setIsComboboxOpen, children: [
|
|
1342
|
+
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
1343
|
+
Button,
|
|
1344
|
+
{
|
|
1345
|
+
variant: "ghost",
|
|
1346
|
+
role: "combobox",
|
|
1347
|
+
"aria-expanded": isComboboxOpen,
|
|
1348
|
+
disabled: availableFieldsToAdd.length === 0,
|
|
1349
|
+
className: "cls_add_field_combobox w-full justify-start gap-2 border border-dashed border-border/70 text-sm font-medium text-muted-foreground hover:border-border hover:bg-muted/40 hover:text-foreground",
|
|
1350
|
+
children: [
|
|
1351
|
+
/* @__PURE__ */ jsx(Plus, { className: "cls_plus_icon h-4 w-4" }),
|
|
1352
|
+
/* @__PURE__ */ jsx("span", { children: availableFieldsToAdd.length === 0 ? "All fields added" : "Add sort field" })
|
|
1353
|
+
]
|
|
1354
|
+
}
|
|
1355
|
+
) }),
|
|
1356
|
+
/* @__PURE__ */ jsx(PopoverContent, { className: "cls_combobox_popover w-[var(--radix-popover-trigger-width)] p-0", align: "start", children: /* @__PURE__ */ jsxs(Command, { children: [
|
|
1357
|
+
/* @__PURE__ */ jsx(CommandInput, { placeholder: "Search fields...", className: "cls_command_input" }),
|
|
1358
|
+
/* @__PURE__ */ jsx(CommandList, { children: availableFieldsToAdd.length === 0 ? /* @__PURE__ */ jsx(CommandEmpty, { children: "No fields available." }) : /* @__PURE__ */ jsx(CommandGroup, { children: availableFieldsToAdd.map((field) => /* @__PURE__ */ jsx(
|
|
1359
|
+
CommandItem,
|
|
1360
|
+
{
|
|
1361
|
+
value: field.label,
|
|
1362
|
+
onSelect: () => handleAddField(field.value),
|
|
1363
|
+
className: "cls_command_item",
|
|
1364
|
+
children: field.label
|
|
1365
|
+
},
|
|
1366
|
+
field.value
|
|
1367
|
+
)) }) })
|
|
1368
|
+
] }) })
|
|
1369
|
+
] }) })
|
|
1379
1370
|
] }),
|
|
1380
|
-
/* @__PURE__ */ jsxs(DialogFooter, { children: [
|
|
1381
|
-
sortFields.length > 0 && /* @__PURE__ */
|
|
1371
|
+
/* @__PURE__ */ jsxs(DialogFooter, { className: "cls_sort_dialog_footer flex flex-row items-center justify-between gap-2 border-t bg-muted/20 px-5 py-3 sm:justify-between sm:space-x-0", children: [
|
|
1372
|
+
/* @__PURE__ */ jsx("div", { className: "cls_footer_left", children: sortFields.length > 0 && /* @__PURE__ */ jsx(
|
|
1382
1373
|
Button,
|
|
1383
1374
|
{
|
|
1384
|
-
variant: "
|
|
1375
|
+
variant: "ghost",
|
|
1376
|
+
size: "sm",
|
|
1385
1377
|
onClick: handleClearAll,
|
|
1386
|
-
className: "cls_clear_all_btn",
|
|
1378
|
+
className: "cls_clear_all_btn text-muted-foreground hover:text-foreground",
|
|
1387
1379
|
style: clearButtonStyles,
|
|
1388
|
-
children:
|
|
1389
|
-
/* @__PURE__ */ jsx(Trash2, { className: "cls_clear_all_icon h-4 w-4 mr-2" }),
|
|
1390
|
-
"Clear All"
|
|
1391
|
-
]
|
|
1392
|
-
}
|
|
1393
|
-
),
|
|
1394
|
-
/* @__PURE__ */ jsx(
|
|
1395
|
-
Button,
|
|
1396
|
-
{
|
|
1397
|
-
onClick: handleApply,
|
|
1398
|
-
className: "cls_apply_btn",
|
|
1399
|
-
style: submitButtonStyles,
|
|
1400
|
-
children: "Apply"
|
|
1401
|
-
}
|
|
1402
|
-
),
|
|
1403
|
-
/* @__PURE__ */ jsx(
|
|
1404
|
-
Button,
|
|
1405
|
-
{
|
|
1406
|
-
variant: "outline",
|
|
1407
|
-
onClick: handleCancel,
|
|
1408
|
-
className: "cls_cancel_btn",
|
|
1409
|
-
style: cancelButtonStyles,
|
|
1410
|
-
children: "Cancel"
|
|
1380
|
+
children: "Clear all"
|
|
1411
1381
|
}
|
|
1412
|
-
)
|
|
1382
|
+
) }),
|
|
1383
|
+
/* @__PURE__ */ jsxs("div", { className: "cls_footer_right flex items-center gap-2", children: [
|
|
1384
|
+
/* @__PURE__ */ jsx(
|
|
1385
|
+
Button,
|
|
1386
|
+
{
|
|
1387
|
+
variant: "outline",
|
|
1388
|
+
size: "sm",
|
|
1389
|
+
onClick: handleCancel,
|
|
1390
|
+
className: "cls_cancel_btn",
|
|
1391
|
+
style: cancelButtonStyles,
|
|
1392
|
+
children: "Cancel"
|
|
1393
|
+
}
|
|
1394
|
+
),
|
|
1395
|
+
/* @__PURE__ */ jsx(
|
|
1396
|
+
Button,
|
|
1397
|
+
{
|
|
1398
|
+
size: "sm",
|
|
1399
|
+
onClick: handleApply,
|
|
1400
|
+
className: "cls_apply_btn",
|
|
1401
|
+
style: submitButtonStyles,
|
|
1402
|
+
children: "Apply"
|
|
1403
|
+
}
|
|
1404
|
+
)
|
|
1405
|
+
] })
|
|
1413
1406
|
] })
|
|
1414
1407
|
] })
|
|
1415
1408
|
] });
|
|
1416
1409
|
}
|
|
1417
|
-
var RadioGroup =
|
|
1410
|
+
var RadioGroup = React25.forwardRef(({ className, ...props }, ref) => {
|
|
1418
1411
|
return /* @__PURE__ */ jsx(
|
|
1419
1412
|
RadioGroupPrimitive.Root,
|
|
1420
1413
|
{
|
|
@@ -1425,7 +1418,7 @@ var RadioGroup = React27.forwardRef(({ className, ...props }, ref) => {
|
|
|
1425
1418
|
);
|
|
1426
1419
|
});
|
|
1427
1420
|
RadioGroup.displayName = RadioGroupPrimitive.Root.displayName;
|
|
1428
|
-
var RadioGroupItem =
|
|
1421
|
+
var RadioGroupItem = React25.forwardRef(({ className, ...props }, ref) => {
|
|
1429
1422
|
return /* @__PURE__ */ jsx(
|
|
1430
1423
|
RadioGroupPrimitive.Item,
|
|
1431
1424
|
{
|
|
@@ -1882,7 +1875,7 @@ function filterInputValue(value, input_type, num_decimals) {
|
|
|
1882
1875
|
}
|
|
1883
1876
|
}
|
|
1884
1877
|
}
|
|
1885
|
-
var HazoUiFlexInput =
|
|
1878
|
+
var HazoUiFlexInput = React25.forwardRef(
|
|
1886
1879
|
({
|
|
1887
1880
|
className,
|
|
1888
1881
|
input_type = "mixed",
|
|
@@ -1899,13 +1892,13 @@ var HazoUiFlexInput = React27.forwardRef(
|
|
|
1899
1892
|
onBlur,
|
|
1900
1893
|
...props
|
|
1901
1894
|
}, ref) => {
|
|
1902
|
-
const [internalValue, setInternalValue] =
|
|
1895
|
+
const [internalValue, setInternalValue] = React25.useState(
|
|
1903
1896
|
typeof controlledValue === "string" ? controlledValue : typeof controlledValue === "number" ? String(controlledValue) : ""
|
|
1904
1897
|
);
|
|
1905
|
-
const [errorMessage, setErrorMessage] =
|
|
1898
|
+
const [errorMessage, setErrorMessage] = React25.useState();
|
|
1906
1899
|
const isControlled = controlledValue !== void 0;
|
|
1907
1900
|
const currentValue = isControlled ? typeof controlledValue === "string" ? controlledValue : String(controlledValue || "") : internalValue;
|
|
1908
|
-
|
|
1901
|
+
React25.useEffect(() => {
|
|
1909
1902
|
if (isControlled) {
|
|
1910
1903
|
const newValue = typeof controlledValue === "string" ? controlledValue : String(controlledValue || "");
|
|
1911
1904
|
if (newValue !== internalValue) {
|
|
@@ -1985,7 +1978,7 @@ var HazoUiFlexInput = React27.forwardRef(
|
|
|
1985
1978
|
}
|
|
1986
1979
|
);
|
|
1987
1980
|
HazoUiFlexInput.displayName = "HazoUiFlexInput";
|
|
1988
|
-
var ToolbarButton =
|
|
1981
|
+
var ToolbarButton = React25.forwardRef(
|
|
1989
1982
|
({ onClick, is_active = false, disabled = false, tooltip, className, children }, ref) => {
|
|
1990
1983
|
const button = /* @__PURE__ */ jsx(
|
|
1991
1984
|
"button",
|
|
@@ -2304,7 +2297,7 @@ var getRelativePosition = (node, event) => {
|
|
|
2304
2297
|
};
|
|
2305
2298
|
};
|
|
2306
2299
|
var _excluded = ["prefixCls", "className", "onMove", "onDown"];
|
|
2307
|
-
var Interactive = /* @__PURE__ */
|
|
2300
|
+
var Interactive = /* @__PURE__ */ React25__default.forwardRef((props, ref) => {
|
|
2308
2301
|
var {
|
|
2309
2302
|
prefixCls = "w-color-interactive",
|
|
2310
2303
|
className,
|
|
@@ -2403,7 +2396,7 @@ var Pointer = (_ref) => {
|
|
|
2403
2396
|
}), [top, left, color2, className, prefixCls]);
|
|
2404
2397
|
};
|
|
2405
2398
|
var _excluded2 = ["prefixCls", "radius", "pointer", "className", "hue", "style", "hsva", "onChange"];
|
|
2406
|
-
var Saturation = /* @__PURE__ */
|
|
2399
|
+
var Saturation = /* @__PURE__ */ React25__default.forwardRef((props, ref) => {
|
|
2407
2400
|
var _hsva$h;
|
|
2408
2401
|
var {
|
|
2409
2402
|
prefixCls = "w-color-saturation",
|
|
@@ -2555,7 +2548,7 @@ var Pointer2 = (_ref) => {
|
|
|
2555
2548
|
};
|
|
2556
2549
|
var _excluded4 = ["prefixCls", "className", "hsva", "background", "bgProps", "innerProps", "pointerProps", "radius", "width", "height", "direction", "style", "onChange", "pointer"];
|
|
2557
2550
|
var BACKGROUND_IMG = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAMUlEQVQ4T2NkYGAQYcAP3uCTZhw1gGGYhAGBZIA/nYDCgBDAm9BGDWAAJyRCgLaBCAAgXwixzAS0pgAAAABJRU5ErkJggg==";
|
|
2558
|
-
var Alpha = /* @__PURE__ */
|
|
2551
|
+
var Alpha = /* @__PURE__ */ React25__default.forwardRef((props, ref) => {
|
|
2559
2552
|
var {
|
|
2560
2553
|
prefixCls = "w-color-alpha",
|
|
2561
2554
|
className,
|
|
@@ -2689,7 +2682,7 @@ var import_objectWithoutPropertiesLoose5 = __toESM(require_objectWithoutProperti
|
|
|
2689
2682
|
var _excluded5 = ["prefixCls", "placement", "label", "value", "className", "style", "labelStyle", "inputStyle", "onChange", "onBlur", "renderInput"];
|
|
2690
2683
|
var validHex2 = (hex) => /^#?([A-Fa-f0-9]{3,4}){1,2}$/.test(hex);
|
|
2691
2684
|
var getNumberValue = (value) => Number(String(value).replace(/%/g, ""));
|
|
2692
|
-
var EditableInput = /* @__PURE__ */
|
|
2685
|
+
var EditableInput = /* @__PURE__ */ React25__default.forwardRef((props, ref) => {
|
|
2693
2686
|
var {
|
|
2694
2687
|
prefixCls = "w-color-editable-input",
|
|
2695
2688
|
placement = "bottom",
|
|
@@ -2794,7 +2787,7 @@ var esm_default4 = EditableInput;
|
|
|
2794
2787
|
var import_extends7 = __toESM(require_extends());
|
|
2795
2788
|
var import_objectWithoutPropertiesLoose6 = __toESM(require_objectWithoutPropertiesLoose());
|
|
2796
2789
|
var _excluded6 = ["prefixCls", "hsva", "placement", "rProps", "gProps", "bProps", "aProps", "className", "style", "onChange"];
|
|
2797
|
-
var EditableInputRGBA = /* @__PURE__ */
|
|
2790
|
+
var EditableInputRGBA = /* @__PURE__ */ React25__default.forwardRef((props, ref) => {
|
|
2798
2791
|
var {
|
|
2799
2792
|
prefixCls = "w-color-editable-input-rgba",
|
|
2800
2793
|
hsva,
|
|
@@ -2917,7 +2910,7 @@ var esm_default5 = EditableInputRGBA;
|
|
|
2917
2910
|
var import_extends8 = __toESM(require_extends());
|
|
2918
2911
|
var import_objectWithoutPropertiesLoose7 = __toESM(require_objectWithoutPropertiesLoose());
|
|
2919
2912
|
var _excluded7 = ["prefixCls", "className", "hue", "onChange", "direction"];
|
|
2920
|
-
var Hue = /* @__PURE__ */
|
|
2913
|
+
var Hue = /* @__PURE__ */ React25__default.forwardRef((props, ref) => {
|
|
2921
2914
|
var {
|
|
2922
2915
|
prefixCls = "w-color-hue",
|
|
2923
2916
|
className,
|
|
@@ -2951,7 +2944,7 @@ var esm_default6 = Hue;
|
|
|
2951
2944
|
var import_extends9 = __toESM(require_extends());
|
|
2952
2945
|
var import_objectWithoutPropertiesLoose8 = __toESM(require_objectWithoutPropertiesLoose());
|
|
2953
2946
|
var _excluded8 = ["prefixCls", "className", "color", "colors", "style", "rectProps", "onChange", "addonAfter", "addonBefore", "rectRender"];
|
|
2954
|
-
var Swatch = /* @__PURE__ */
|
|
2947
|
+
var Swatch = /* @__PURE__ */ React25__default.forwardRef((props, ref) => {
|
|
2955
2948
|
var {
|
|
2956
2949
|
prefixCls = "w-color-swatch",
|
|
2957
2950
|
className,
|
|
@@ -2988,7 +2981,7 @@ var Swatch = /* @__PURE__ */ React27__default.forwardRef((props, ref) => {
|
|
|
2988
2981
|
flexWrap: "wrap",
|
|
2989
2982
|
position: "relative"
|
|
2990
2983
|
}, style),
|
|
2991
|
-
children: [addonBefore && /* @__PURE__ */
|
|
2984
|
+
children: [addonBefore && /* @__PURE__ */ React25__default.isValidElement(addonBefore) && addonBefore, colors && Array.isArray(colors) && colors.map((item, idx) => {
|
|
2992
2985
|
var title = "";
|
|
2993
2986
|
var background = "";
|
|
2994
2987
|
if (typeof item === "string") {
|
|
@@ -3014,7 +3007,7 @@ var Swatch = /* @__PURE__ */ React27__default.forwardRef((props, ref) => {
|
|
|
3014
3007
|
children: render
|
|
3015
3008
|
}, idx);
|
|
3016
3009
|
}
|
|
3017
|
-
var child = rectProps.children && /* @__PURE__ */
|
|
3010
|
+
var child = rectProps.children && /* @__PURE__ */ React25__default.isValidElement(rectProps.children) ? /* @__PURE__ */ React25__default.cloneElement(rectProps.children, {
|
|
3018
3011
|
color: background,
|
|
3019
3012
|
checked
|
|
3020
3013
|
}) : null;
|
|
@@ -3028,7 +3021,7 @@ var Swatch = /* @__PURE__ */ React27__default.forwardRef((props, ref) => {
|
|
|
3028
3021
|
background
|
|
3029
3022
|
})
|
|
3030
3023
|
}), idx);
|
|
3031
|
-
}), addonAfter && /* @__PURE__ */
|
|
3024
|
+
}), addonAfter && /* @__PURE__ */ React25__default.isValidElement(addonAfter) && addonAfter]
|
|
3032
3025
|
}));
|
|
3033
3026
|
});
|
|
3034
3027
|
Swatch.displayName = "Swatch";
|
|
@@ -3047,7 +3040,7 @@ var Bar = (props) => /* @__PURE__ */ jsx("div", {
|
|
|
3047
3040
|
backgroundColor: "#fff"
|
|
3048
3041
|
}
|
|
3049
3042
|
});
|
|
3050
|
-
var Sketch = /* @__PURE__ */
|
|
3043
|
+
var Sketch = /* @__PURE__ */ React25__default.forwardRef((props, ref) => {
|
|
3051
3044
|
var {
|
|
3052
3045
|
prefixCls = "w-color-sketch",
|
|
3053
3046
|
className,
|
|
@@ -3298,19 +3291,19 @@ var Toolbar = ({
|
|
|
3298
3291
|
on_attachments_change,
|
|
3299
3292
|
disabled = false
|
|
3300
3293
|
}) => {
|
|
3301
|
-
const [link_url, set_link_url] =
|
|
3302
|
-
const [link_popover_open, set_link_popover_open] =
|
|
3303
|
-
const [text_color_open, set_text_color_open] =
|
|
3304
|
-
const [highlight_color_open, set_highlight_color_open] =
|
|
3305
|
-
const [variables_menu_open, set_variables_menu_open] =
|
|
3306
|
-
const [table_menu_open, set_table_menu_open] =
|
|
3307
|
-
const [text_color, set_text_color] =
|
|
3308
|
-
const [highlight_color, set_highlight_color] =
|
|
3309
|
-
const [table_rows, set_table_rows] =
|
|
3310
|
-
const [table_cols, set_table_cols] =
|
|
3311
|
-
const [hovered_cell, set_hovered_cell] =
|
|
3312
|
-
const file_input_ref =
|
|
3313
|
-
const image_input_ref =
|
|
3294
|
+
const [link_url, set_link_url] = React25.useState("https://");
|
|
3295
|
+
const [link_popover_open, set_link_popover_open] = React25.useState(false);
|
|
3296
|
+
const [text_color_open, set_text_color_open] = React25.useState(false);
|
|
3297
|
+
const [highlight_color_open, set_highlight_color_open] = React25.useState(false);
|
|
3298
|
+
const [variables_menu_open, set_variables_menu_open] = React25.useState(false);
|
|
3299
|
+
const [table_menu_open, set_table_menu_open] = React25.useState(false);
|
|
3300
|
+
const [text_color, set_text_color] = React25.useState("#000000");
|
|
3301
|
+
const [highlight_color, set_highlight_color] = React25.useState("#ffff00");
|
|
3302
|
+
const [table_rows, set_table_rows] = React25.useState(3);
|
|
3303
|
+
const [table_cols, set_table_cols] = React25.useState(3);
|
|
3304
|
+
const [hovered_cell, set_hovered_cell] = React25.useState(null);
|
|
3305
|
+
const file_input_ref = React25.useRef(null);
|
|
3306
|
+
const image_input_ref = React25.useRef(null);
|
|
3314
3307
|
if (!editor) {
|
|
3315
3308
|
return null;
|
|
3316
3309
|
}
|
|
@@ -4243,7 +4236,7 @@ var VariableExtension = Node.create({
|
|
|
4243
4236
|
}
|
|
4244
4237
|
});
|
|
4245
4238
|
var Tabs = TabsPrimitive.Root;
|
|
4246
|
-
var TabsList =
|
|
4239
|
+
var TabsList = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
4247
4240
|
TabsPrimitive.List,
|
|
4248
4241
|
{
|
|
4249
4242
|
ref,
|
|
@@ -4255,7 +4248,7 @@ var TabsList = React27.forwardRef(({ className, ...props }, ref) => /* @__PURE__
|
|
|
4255
4248
|
}
|
|
4256
4249
|
));
|
|
4257
4250
|
TabsList.displayName = TabsPrimitive.List.displayName;
|
|
4258
|
-
var TabsTrigger =
|
|
4251
|
+
var TabsTrigger = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
4259
4252
|
TabsPrimitive.Trigger,
|
|
4260
4253
|
{
|
|
4261
4254
|
ref,
|
|
@@ -4267,7 +4260,7 @@ var TabsTrigger = React27.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
4267
4260
|
}
|
|
4268
4261
|
));
|
|
4269
4262
|
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
|
|
4270
|
-
var TabsContent =
|
|
4263
|
+
var TabsContent = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
4271
4264
|
TabsPrimitive.Content,
|
|
4272
4265
|
{
|
|
4273
4266
|
ref,
|
|
@@ -4302,14 +4295,14 @@ var HazoUiRte = ({
|
|
|
4302
4295
|
className,
|
|
4303
4296
|
show_output_viewer = false
|
|
4304
4297
|
}) => {
|
|
4305
|
-
const [attachments, set_attachments] =
|
|
4298
|
+
const [attachments, set_attachments] = React25.useState(
|
|
4306
4299
|
initial_attachments
|
|
4307
4300
|
);
|
|
4308
|
-
const [active_tab, set_active_tab] =
|
|
4301
|
+
const [active_tab, set_active_tab] = React25.useState("html");
|
|
4309
4302
|
const is_view_only = active_tab !== "html";
|
|
4310
|
-
const attachments_ref =
|
|
4303
|
+
const attachments_ref = React25.useRef(attachments);
|
|
4311
4304
|
attachments_ref.current = attachments;
|
|
4312
|
-
const debounced_on_change =
|
|
4305
|
+
const debounced_on_change = React25.useMemo(
|
|
4313
4306
|
() => debounce_fn((output) => {
|
|
4314
4307
|
if (on_change) {
|
|
4315
4308
|
on_change(output);
|
|
@@ -4408,7 +4401,7 @@ var HazoUiRte = ({
|
|
|
4408
4401
|
debounced_on_change(output);
|
|
4409
4402
|
}
|
|
4410
4403
|
});
|
|
4411
|
-
|
|
4404
|
+
React25.useEffect(() => {
|
|
4412
4405
|
if (editor && html !== void 0) {
|
|
4413
4406
|
const current_html = editor.getHTML();
|
|
4414
4407
|
if (html !== current_html && !editor.isFocused) {
|
|
@@ -4416,21 +4409,21 @@ var HazoUiRte = ({
|
|
|
4416
4409
|
}
|
|
4417
4410
|
}
|
|
4418
4411
|
}, [html, editor]);
|
|
4419
|
-
|
|
4412
|
+
React25.useEffect(() => {
|
|
4420
4413
|
if (editor) {
|
|
4421
4414
|
editor.setEditable(!disabled);
|
|
4422
4415
|
}
|
|
4423
4416
|
}, [disabled, editor]);
|
|
4424
|
-
const attachments_from_props_ref =
|
|
4425
|
-
const prev_initial_attachments_ref =
|
|
4426
|
-
|
|
4417
|
+
const attachments_from_props_ref = React25.useRef(false);
|
|
4418
|
+
const prev_initial_attachments_ref = React25.useRef(initial_attachments);
|
|
4419
|
+
React25.useEffect(() => {
|
|
4427
4420
|
if (JSON.stringify(initial_attachments) !== JSON.stringify(prev_initial_attachments_ref.current)) {
|
|
4428
4421
|
prev_initial_attachments_ref.current = initial_attachments;
|
|
4429
4422
|
attachments_from_props_ref.current = true;
|
|
4430
4423
|
set_attachments(initial_attachments);
|
|
4431
4424
|
}
|
|
4432
4425
|
}, [initial_attachments]);
|
|
4433
|
-
|
|
4426
|
+
React25.useEffect(() => {
|
|
4434
4427
|
if (attachments_from_props_ref.current) {
|
|
4435
4428
|
attachments_from_props_ref.current = false;
|
|
4436
4429
|
return;
|
|
@@ -4932,12 +4925,12 @@ var CommandPopover = ({
|
|
|
4932
4925
|
on_selection_change: _on_selection_change,
|
|
4933
4926
|
prefix_color
|
|
4934
4927
|
}) => {
|
|
4935
|
-
const container_ref =
|
|
4936
|
-
const grouped_commands =
|
|
4928
|
+
const container_ref = React25.useRef(null);
|
|
4929
|
+
const grouped_commands = React25.useMemo(
|
|
4937
4930
|
() => group_commands(commands),
|
|
4938
4931
|
[commands]
|
|
4939
4932
|
);
|
|
4940
|
-
|
|
4933
|
+
React25.useEffect(() => {
|
|
4941
4934
|
const handle_click_outside = (e) => {
|
|
4942
4935
|
if (container_ref.current && !container_ref.current.contains(e.target)) {
|
|
4943
4936
|
on_close();
|
|
@@ -4950,8 +4943,8 @@ var CommandPopover = ({
|
|
|
4950
4943
|
};
|
|
4951
4944
|
}
|
|
4952
4945
|
}, [is_open, on_close]);
|
|
4953
|
-
const [mounted, set_mounted] =
|
|
4954
|
-
|
|
4946
|
+
const [mounted, set_mounted] = React25.useState(false);
|
|
4947
|
+
React25.useEffect(() => {
|
|
4955
4948
|
set_mounted(true);
|
|
4956
4949
|
}, []);
|
|
4957
4950
|
if (!is_open || !mounted) return null;
|
|
@@ -5261,21 +5254,21 @@ var HazoUiTextbox = ({
|
|
|
5261
5254
|
on_command_change,
|
|
5262
5255
|
on_command_remove
|
|
5263
5256
|
}) => {
|
|
5264
|
-
const generated_instance_id =
|
|
5257
|
+
const generated_instance_id = React25.useId();
|
|
5265
5258
|
const instance_id = provided_instance_id || generated_instance_id;
|
|
5266
|
-
const [suggestion_state, set_suggestion_state] =
|
|
5267
|
-
const [selected_index, set_selected_index] =
|
|
5268
|
-
const [popover_position, set_popover_position] =
|
|
5269
|
-
const [edit_context, set_edit_context] =
|
|
5270
|
-
const [edit_selected_index, set_edit_selected_index] =
|
|
5259
|
+
const [suggestion_state, set_suggestion_state] = React25.useState(null);
|
|
5260
|
+
const [selected_index, set_selected_index] = React25.useState(0);
|
|
5261
|
+
const [popover_position, set_popover_position] = React25.useState({ top: 0, left: 0 });
|
|
5262
|
+
const [edit_context, set_edit_context] = React25.useState(null);
|
|
5263
|
+
const [edit_selected_index, set_edit_selected_index] = React25.useState(0);
|
|
5271
5264
|
const is_controlled = value !== void 0;
|
|
5272
|
-
const editor_container_ref =
|
|
5273
|
-
const edit_popover_ref =
|
|
5274
|
-
const [mounted, set_mounted] =
|
|
5275
|
-
|
|
5265
|
+
const editor_container_ref = React25.useRef(null);
|
|
5266
|
+
const edit_popover_ref = React25.useRef(null);
|
|
5267
|
+
const [mounted, set_mounted] = React25.useState(false);
|
|
5268
|
+
React25.useEffect(() => {
|
|
5276
5269
|
set_mounted(true);
|
|
5277
5270
|
}, []);
|
|
5278
|
-
const suggestion_extensions =
|
|
5271
|
+
const suggestion_extensions = React25.useMemo(() => {
|
|
5279
5272
|
return create_command_suggestion_extension({
|
|
5280
5273
|
prefixes,
|
|
5281
5274
|
instance_id,
|
|
@@ -5326,7 +5319,7 @@ var HazoUiTextbox = ({
|
|
|
5326
5319
|
}
|
|
5327
5320
|
}
|
|
5328
5321
|
});
|
|
5329
|
-
|
|
5322
|
+
React25.useEffect(() => {
|
|
5330
5323
|
if (suggestion_state?.is_active && editor) {
|
|
5331
5324
|
requestAnimationFrame(() => {
|
|
5332
5325
|
const { from } = suggestion_state.range;
|
|
@@ -5350,7 +5343,7 @@ var HazoUiTextbox = ({
|
|
|
5350
5343
|
});
|
|
5351
5344
|
}
|
|
5352
5345
|
}, [suggestion_state, editor]);
|
|
5353
|
-
|
|
5346
|
+
React25.useEffect(() => {
|
|
5354
5347
|
if (is_controlled && editor && !editor.isFocused) {
|
|
5355
5348
|
const current_text = editor.getText();
|
|
5356
5349
|
if (value !== current_text) {
|
|
@@ -5359,12 +5352,12 @@ var HazoUiTextbox = ({
|
|
|
5359
5352
|
}
|
|
5360
5353
|
}
|
|
5361
5354
|
}, [value, editor, is_controlled, prefixes, pill_variant]);
|
|
5362
|
-
|
|
5355
|
+
React25.useEffect(() => {
|
|
5363
5356
|
if (editor) {
|
|
5364
5357
|
editor.setEditable(!disabled);
|
|
5365
5358
|
}
|
|
5366
5359
|
}, [disabled, editor]);
|
|
5367
|
-
const handle_command_select =
|
|
5360
|
+
const handle_command_select = React25.useCallback(
|
|
5368
5361
|
(command) => {
|
|
5369
5362
|
if (!editor || !suggestion_state) return;
|
|
5370
5363
|
const prefix_config = prefixes.find((p) => p.char === suggestion_state.prefix);
|
|
@@ -5384,15 +5377,15 @@ var HazoUiTextbox = ({
|
|
|
5384
5377
|
},
|
|
5385
5378
|
[editor, suggestion_state, pill_variant, on_command_insert, prefixes]
|
|
5386
5379
|
);
|
|
5387
|
-
const handle_popover_close =
|
|
5380
|
+
const handle_popover_close = React25.useCallback(() => {
|
|
5388
5381
|
set_suggestion_state(null);
|
|
5389
5382
|
editor?.commands.focus();
|
|
5390
5383
|
}, [editor]);
|
|
5391
|
-
const handle_edit_close =
|
|
5384
|
+
const handle_edit_close = React25.useCallback(() => {
|
|
5392
5385
|
set_edit_context(null);
|
|
5393
5386
|
editor?.commands.focus();
|
|
5394
5387
|
}, [editor]);
|
|
5395
|
-
const handle_command_update =
|
|
5388
|
+
const handle_command_update = React25.useCallback(
|
|
5396
5389
|
(new_command) => {
|
|
5397
5390
|
if (!editor || !edit_context) return;
|
|
5398
5391
|
const old_command = edit_context.command;
|
|
@@ -5408,7 +5401,7 @@ var HazoUiTextbox = ({
|
|
|
5408
5401
|
},
|
|
5409
5402
|
[editor, edit_context, on_command_change]
|
|
5410
5403
|
);
|
|
5411
|
-
const handle_command_remove =
|
|
5404
|
+
const handle_command_remove = React25.useCallback(() => {
|
|
5412
5405
|
if (!editor || !edit_context) return;
|
|
5413
5406
|
const command = edit_context.command;
|
|
5414
5407
|
editor.state.doc.descendants((node, pos) => {
|
|
@@ -5422,7 +5415,7 @@ var HazoUiTextbox = ({
|
|
|
5422
5415
|
}
|
|
5423
5416
|
set_edit_context(null);
|
|
5424
5417
|
}, [editor, edit_context, on_command_remove]);
|
|
5425
|
-
const filtered_commands =
|
|
5418
|
+
const filtered_commands = React25.useMemo(() => {
|
|
5426
5419
|
if (!suggestion_state) return [];
|
|
5427
5420
|
const query = suggestion_state.query.toLowerCase();
|
|
5428
5421
|
if (!query) return suggestion_state.commands;
|
|
@@ -5430,7 +5423,7 @@ var HazoUiTextbox = ({
|
|
|
5430
5423
|
(cmd) => cmd.action_label.toLowerCase().includes(query) || cmd.action.toLowerCase().includes(query) || cmd.action_description?.toLowerCase().includes(query)
|
|
5431
5424
|
);
|
|
5432
5425
|
}, [suggestion_state]);
|
|
5433
|
-
|
|
5426
|
+
React25.useEffect(() => {
|
|
5434
5427
|
if (!suggestion_state?.is_active) return;
|
|
5435
5428
|
const handle_keydown = (e) => {
|
|
5436
5429
|
switch (e.key) {
|
|
@@ -5465,7 +5458,7 @@ var HazoUiTextbox = ({
|
|
|
5465
5458
|
handle_command_select,
|
|
5466
5459
|
handle_popover_close
|
|
5467
5460
|
]);
|
|
5468
|
-
|
|
5461
|
+
React25.useEffect(() => {
|
|
5469
5462
|
if (!edit_context) return;
|
|
5470
5463
|
const handle_click_outside = (e) => {
|
|
5471
5464
|
if (edit_popover_ref.current && !edit_popover_ref.current.contains(e.target)) {
|
|
@@ -5480,12 +5473,12 @@ var HazoUiTextbox = ({
|
|
|
5480
5473
|
document.removeEventListener("mousedown", handle_click_outside);
|
|
5481
5474
|
};
|
|
5482
5475
|
}, [edit_context]);
|
|
5483
|
-
const edit_commands =
|
|
5476
|
+
const edit_commands = React25.useMemo(() => {
|
|
5484
5477
|
if (!edit_context) return [];
|
|
5485
5478
|
const prefix_config = prefixes.find((p) => p.char === edit_context.command.prefix);
|
|
5486
5479
|
return prefix_config?.commands || [];
|
|
5487
5480
|
}, [edit_context, prefixes]);
|
|
5488
|
-
|
|
5481
|
+
React25.useEffect(() => {
|
|
5489
5482
|
if (!edit_context) return;
|
|
5490
5483
|
const handle_keydown = (e) => {
|
|
5491
5484
|
switch (e.key) {
|
|
@@ -5523,7 +5516,7 @@ var HazoUiTextbox = ({
|
|
|
5523
5516
|
handle_command_remove,
|
|
5524
5517
|
handle_edit_close
|
|
5525
5518
|
]);
|
|
5526
|
-
|
|
5519
|
+
React25.useEffect(() => {
|
|
5527
5520
|
const handle_pill_click = (e) => {
|
|
5528
5521
|
const detail = e.detail;
|
|
5529
5522
|
const { id, prefix, action, action_label, node_pos } = detail;
|
|
@@ -5806,22 +5799,22 @@ var HazoUiTextarea = ({
|
|
|
5806
5799
|
on_command_change,
|
|
5807
5800
|
on_command_remove
|
|
5808
5801
|
}) => {
|
|
5809
|
-
const generated_instance_id =
|
|
5802
|
+
const generated_instance_id = React25.useId();
|
|
5810
5803
|
const instance_id = provided_instance_id || generated_instance_id;
|
|
5811
|
-
const [suggestion_state, set_suggestion_state] =
|
|
5812
|
-
const [selected_index, set_selected_index] =
|
|
5813
|
-
const [popover_position, set_popover_position] =
|
|
5814
|
-
const [edit_context, set_edit_context] =
|
|
5815
|
-
const [edit_selected_index, set_edit_selected_index] =
|
|
5804
|
+
const [suggestion_state, set_suggestion_state] = React25.useState(null);
|
|
5805
|
+
const [selected_index, set_selected_index] = React25.useState(0);
|
|
5806
|
+
const [popover_position, set_popover_position] = React25.useState({ top: 0, left: 0 });
|
|
5807
|
+
const [edit_context, set_edit_context] = React25.useState(null);
|
|
5808
|
+
const [edit_selected_index, set_edit_selected_index] = React25.useState(0);
|
|
5816
5809
|
const is_controlled = value !== void 0;
|
|
5817
|
-
const editor_container_ref =
|
|
5818
|
-
const edit_popover_ref =
|
|
5819
|
-
const [mounted, set_mounted] =
|
|
5820
|
-
|
|
5810
|
+
const editor_container_ref = React25.useRef(null);
|
|
5811
|
+
const edit_popover_ref = React25.useRef(null);
|
|
5812
|
+
const [mounted, set_mounted] = React25.useState(false);
|
|
5813
|
+
React25.useEffect(() => {
|
|
5821
5814
|
set_mounted(true);
|
|
5822
5815
|
}, []);
|
|
5823
5816
|
const calculated_min_height = rows ? `${rows * 1.5}em` : min_height;
|
|
5824
|
-
const suggestion_extensions =
|
|
5817
|
+
const suggestion_extensions = React25.useMemo(() => {
|
|
5825
5818
|
return create_command_suggestion_extension({
|
|
5826
5819
|
prefixes,
|
|
5827
5820
|
instance_id,
|
|
@@ -5870,7 +5863,7 @@ var HazoUiTextarea = ({
|
|
|
5870
5863
|
}
|
|
5871
5864
|
}
|
|
5872
5865
|
});
|
|
5873
|
-
|
|
5866
|
+
React25.useEffect(() => {
|
|
5874
5867
|
if (suggestion_state?.is_active && editor) {
|
|
5875
5868
|
requestAnimationFrame(() => {
|
|
5876
5869
|
const { from } = suggestion_state.range;
|
|
@@ -5894,7 +5887,7 @@ var HazoUiTextarea = ({
|
|
|
5894
5887
|
});
|
|
5895
5888
|
}
|
|
5896
5889
|
}, [suggestion_state, editor]);
|
|
5897
|
-
|
|
5890
|
+
React25.useEffect(() => {
|
|
5898
5891
|
if (is_controlled && editor && !editor.isFocused) {
|
|
5899
5892
|
const current_text = editor.getText();
|
|
5900
5893
|
if (value !== current_text) {
|
|
@@ -5907,12 +5900,12 @@ var HazoUiTextarea = ({
|
|
|
5907
5900
|
}
|
|
5908
5901
|
}
|
|
5909
5902
|
}, [value, editor, is_controlled, prefixes, pill_variant]);
|
|
5910
|
-
|
|
5903
|
+
React25.useEffect(() => {
|
|
5911
5904
|
if (editor) {
|
|
5912
5905
|
editor.setEditable(!disabled);
|
|
5913
5906
|
}
|
|
5914
5907
|
}, [disabled, editor]);
|
|
5915
|
-
const handle_command_select =
|
|
5908
|
+
const handle_command_select = React25.useCallback(
|
|
5916
5909
|
(command) => {
|
|
5917
5910
|
if (!editor || !suggestion_state) return;
|
|
5918
5911
|
const prefix_config = prefixes.find((p) => p.char === suggestion_state.prefix);
|
|
@@ -5932,15 +5925,15 @@ var HazoUiTextarea = ({
|
|
|
5932
5925
|
},
|
|
5933
5926
|
[editor, suggestion_state, pill_variant, on_command_insert, prefixes]
|
|
5934
5927
|
);
|
|
5935
|
-
const handle_popover_close =
|
|
5928
|
+
const handle_popover_close = React25.useCallback(() => {
|
|
5936
5929
|
set_suggestion_state(null);
|
|
5937
5930
|
editor?.commands.focus();
|
|
5938
5931
|
}, [editor]);
|
|
5939
|
-
const handle_edit_close =
|
|
5932
|
+
const handle_edit_close = React25.useCallback(() => {
|
|
5940
5933
|
set_edit_context(null);
|
|
5941
5934
|
editor?.commands.focus();
|
|
5942
5935
|
}, [editor]);
|
|
5943
|
-
const handle_command_update =
|
|
5936
|
+
const handle_command_update = React25.useCallback(
|
|
5944
5937
|
(new_command) => {
|
|
5945
5938
|
if (!editor || !edit_context) return;
|
|
5946
5939
|
const old_command = edit_context.command;
|
|
@@ -5956,7 +5949,7 @@ var HazoUiTextarea = ({
|
|
|
5956
5949
|
},
|
|
5957
5950
|
[editor, edit_context, on_command_change]
|
|
5958
5951
|
);
|
|
5959
|
-
const handle_command_remove =
|
|
5952
|
+
const handle_command_remove = React25.useCallback(() => {
|
|
5960
5953
|
if (!editor || !edit_context) return;
|
|
5961
5954
|
const command = edit_context.command;
|
|
5962
5955
|
editor.state.doc.descendants((node, pos) => {
|
|
@@ -5970,7 +5963,7 @@ var HazoUiTextarea = ({
|
|
|
5970
5963
|
}
|
|
5971
5964
|
set_edit_context(null);
|
|
5972
5965
|
}, [editor, edit_context, on_command_remove]);
|
|
5973
|
-
const filtered_commands =
|
|
5966
|
+
const filtered_commands = React25.useMemo(() => {
|
|
5974
5967
|
if (!suggestion_state) return [];
|
|
5975
5968
|
const query = suggestion_state.query.toLowerCase();
|
|
5976
5969
|
if (!query) return suggestion_state.commands;
|
|
@@ -5978,7 +5971,7 @@ var HazoUiTextarea = ({
|
|
|
5978
5971
|
(cmd) => cmd.action_label.toLowerCase().includes(query) || cmd.action.toLowerCase().includes(query) || cmd.action_description?.toLowerCase().includes(query)
|
|
5979
5972
|
);
|
|
5980
5973
|
}, [suggestion_state]);
|
|
5981
|
-
|
|
5974
|
+
React25.useEffect(() => {
|
|
5982
5975
|
if (!suggestion_state?.is_active) return;
|
|
5983
5976
|
const handle_keydown = (e) => {
|
|
5984
5977
|
switch (e.key) {
|
|
@@ -6013,7 +6006,7 @@ var HazoUiTextarea = ({
|
|
|
6013
6006
|
handle_command_select,
|
|
6014
6007
|
handle_popover_close
|
|
6015
6008
|
]);
|
|
6016
|
-
|
|
6009
|
+
React25.useEffect(() => {
|
|
6017
6010
|
if (!edit_context) return;
|
|
6018
6011
|
const handle_click_outside = (e) => {
|
|
6019
6012
|
if (edit_popover_ref.current && !edit_popover_ref.current.contains(e.target)) {
|
|
@@ -6028,12 +6021,12 @@ var HazoUiTextarea = ({
|
|
|
6028
6021
|
document.removeEventListener("mousedown", handle_click_outside);
|
|
6029
6022
|
};
|
|
6030
6023
|
}, [edit_context]);
|
|
6031
|
-
const edit_commands =
|
|
6024
|
+
const edit_commands = React25.useMemo(() => {
|
|
6032
6025
|
if (!edit_context) return [];
|
|
6033
6026
|
const prefix_config = prefixes.find((p) => p.char === edit_context.command.prefix);
|
|
6034
6027
|
return prefix_config?.commands || [];
|
|
6035
6028
|
}, [edit_context, prefixes]);
|
|
6036
|
-
|
|
6029
|
+
React25.useEffect(() => {
|
|
6037
6030
|
if (!edit_context) return;
|
|
6038
6031
|
const handle_keydown = (e) => {
|
|
6039
6032
|
switch (e.key) {
|
|
@@ -6071,7 +6064,7 @@ var HazoUiTextarea = ({
|
|
|
6071
6064
|
handle_command_remove,
|
|
6072
6065
|
handle_edit_close
|
|
6073
6066
|
]);
|
|
6074
|
-
|
|
6067
|
+
React25.useEffect(() => {
|
|
6075
6068
|
const handle_pill_click = (e) => {
|
|
6076
6069
|
const detail = e.detail;
|
|
6077
6070
|
const { id, prefix, action, action_label, node_pos } = detail;
|
|
@@ -6618,7 +6611,7 @@ function HazoUiConfirmDialog({
|
|
|
6618
6611
|
openAnimation = "zoom",
|
|
6619
6612
|
closeAnimation = "zoom"
|
|
6620
6613
|
}) {
|
|
6621
|
-
const [internal_loading, set_internal_loading] =
|
|
6614
|
+
const [internal_loading, set_internal_loading] = React25.useState(false);
|
|
6622
6615
|
const config = get_hazo_ui_config();
|
|
6623
6616
|
const variant_preset = variant !== "default" ? CONFIRM_VARIANT_PRESETS[variant] : void 0;
|
|
6624
6617
|
const is_loading = external_loading ?? internal_loading;
|
|
@@ -6655,7 +6648,7 @@ function HazoUiConfirmDialog({
|
|
|
6655
6648
|
onCancel?.();
|
|
6656
6649
|
onOpenChange(false);
|
|
6657
6650
|
};
|
|
6658
|
-
const cancel_ref =
|
|
6651
|
+
const cancel_ref = React25.useRef(null);
|
|
6659
6652
|
return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs(DialogPortal, { children: [
|
|
6660
6653
|
/* @__PURE__ */ jsx(
|
|
6661
6654
|
DialogOverlay,
|
|
@@ -6740,7 +6733,7 @@ Drawer.displayName = "Drawer";
|
|
|
6740
6733
|
var DrawerTrigger = Drawer$1.Trigger;
|
|
6741
6734
|
var DrawerPortal = Drawer$1.Portal;
|
|
6742
6735
|
var DrawerClose = Drawer$1.Close;
|
|
6743
|
-
var DrawerOverlay =
|
|
6736
|
+
var DrawerOverlay = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
6744
6737
|
Drawer$1.Overlay,
|
|
6745
6738
|
{
|
|
6746
6739
|
ref,
|
|
@@ -6752,7 +6745,7 @@ var DrawerOverlay = React27.forwardRef(({ className, ...props }, ref) => /* @__P
|
|
|
6752
6745
|
}
|
|
6753
6746
|
));
|
|
6754
6747
|
DrawerOverlay.displayName = "DrawerOverlay";
|
|
6755
|
-
var DrawerContent =
|
|
6748
|
+
var DrawerContent = React25.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(DrawerPortal, { children: [
|
|
6756
6749
|
/* @__PURE__ */ jsx(DrawerOverlay, {}),
|
|
6757
6750
|
/* @__PURE__ */ jsxs(
|
|
6758
6751
|
Drawer$1.Content,
|
|
@@ -6793,7 +6786,7 @@ var DrawerFooter = ({
|
|
|
6793
6786
|
}
|
|
6794
6787
|
);
|
|
6795
6788
|
DrawerFooter.displayName = "DrawerFooter";
|
|
6796
|
-
var DrawerTitle =
|
|
6789
|
+
var DrawerTitle = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
6797
6790
|
Drawer$1.Title,
|
|
6798
6791
|
{
|
|
6799
6792
|
ref,
|
|
@@ -6805,7 +6798,7 @@ var DrawerTitle = React27.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
6805
6798
|
}
|
|
6806
6799
|
));
|
|
6807
6800
|
DrawerTitle.displayName = "DrawerTitle";
|
|
6808
|
-
var DrawerDescription =
|
|
6801
|
+
var DrawerDescription = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
6809
6802
|
Drawer$1.Description,
|
|
6810
6803
|
{
|
|
6811
6804
|
ref,
|
|
@@ -6815,14 +6808,14 @@ var DrawerDescription = React27.forwardRef(({ className, ...props }, ref) => /*
|
|
|
6815
6808
|
));
|
|
6816
6809
|
DrawerDescription.displayName = "DrawerDescription";
|
|
6817
6810
|
function useMediaQuery(query) {
|
|
6818
|
-
const get_match =
|
|
6811
|
+
const get_match = React25.useCallback(() => {
|
|
6819
6812
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") {
|
|
6820
6813
|
return false;
|
|
6821
6814
|
}
|
|
6822
6815
|
return window.matchMedia(query).matches;
|
|
6823
6816
|
}, [query]);
|
|
6824
|
-
const [matches, set_matches] =
|
|
6825
|
-
|
|
6817
|
+
const [matches, set_matches] = React25.useState(false);
|
|
6818
|
+
React25.useEffect(() => {
|
|
6826
6819
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") {
|
|
6827
6820
|
return;
|
|
6828
6821
|
}
|
|
@@ -6839,7 +6832,7 @@ function useMediaQuery(query) {
|
|
|
6839
6832
|
return matches;
|
|
6840
6833
|
}
|
|
6841
6834
|
var Accordion = AccordionPrimitive.Root;
|
|
6842
|
-
var AccordionItem =
|
|
6835
|
+
var AccordionItem = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
6843
6836
|
AccordionPrimitive.Item,
|
|
6844
6837
|
{
|
|
6845
6838
|
ref,
|
|
@@ -6848,7 +6841,7 @@ var AccordionItem = React27.forwardRef(({ className, ...props }, ref) => /* @__P
|
|
|
6848
6841
|
}
|
|
6849
6842
|
));
|
|
6850
6843
|
AccordionItem.displayName = "AccordionItem";
|
|
6851
|
-
var AccordionTrigger =
|
|
6844
|
+
var AccordionTrigger = React25.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx(AccordionPrimitive.Header, { className: "flex", children: /* @__PURE__ */ jsxs(
|
|
6852
6845
|
AccordionPrimitive.Trigger,
|
|
6853
6846
|
{
|
|
6854
6847
|
ref,
|
|
@@ -6864,7 +6857,7 @@ var AccordionTrigger = React27.forwardRef(({ className, children, ...props }, re
|
|
|
6864
6857
|
}
|
|
6865
6858
|
) }));
|
|
6866
6859
|
AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName;
|
|
6867
|
-
var AccordionContent =
|
|
6860
|
+
var AccordionContent = React25.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
6868
6861
|
AccordionPrimitive.Content,
|
|
6869
6862
|
{
|
|
6870
6863
|
ref,
|
|
@@ -6874,7 +6867,7 @@ var AccordionContent = React27.forwardRef(({ className, children, ...props }, re
|
|
|
6874
6867
|
}
|
|
6875
6868
|
));
|
|
6876
6869
|
AccordionContent.displayName = AccordionPrimitive.Content.displayName;
|
|
6877
|
-
var Checkbox =
|
|
6870
|
+
var Checkbox = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
6878
6871
|
CheckboxPrimitive.Root,
|
|
6879
6872
|
{
|
|
6880
6873
|
ref,
|
|
@@ -6899,7 +6892,7 @@ var DropdownMenuGroup = DropdownMenuPrimitive.Group;
|
|
|
6899
6892
|
var DropdownMenuPortal = DropdownMenuPrimitive.Portal;
|
|
6900
6893
|
var DropdownMenuSub = DropdownMenuPrimitive.Sub;
|
|
6901
6894
|
var DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
|
|
6902
|
-
var DropdownMenuSubTrigger =
|
|
6895
|
+
var DropdownMenuSubTrigger = React25.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
6903
6896
|
DropdownMenuPrimitive.SubTrigger,
|
|
6904
6897
|
{
|
|
6905
6898
|
ref,
|
|
@@ -6916,7 +6909,7 @@ var DropdownMenuSubTrigger = React27.forwardRef(({ className, inset, children, .
|
|
|
6916
6909
|
}
|
|
6917
6910
|
));
|
|
6918
6911
|
DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
|
|
6919
|
-
var DropdownMenuSubContent =
|
|
6912
|
+
var DropdownMenuSubContent = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
6920
6913
|
DropdownMenuPrimitive.SubContent,
|
|
6921
6914
|
{
|
|
6922
6915
|
ref,
|
|
@@ -6928,7 +6921,7 @@ var DropdownMenuSubContent = React27.forwardRef(({ className, ...props }, ref) =
|
|
|
6928
6921
|
}
|
|
6929
6922
|
));
|
|
6930
6923
|
DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
|
|
6931
|
-
var DropdownMenuContent =
|
|
6924
|
+
var DropdownMenuContent = React25.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(
|
|
6932
6925
|
DropdownMenuPrimitive.Content,
|
|
6933
6926
|
{
|
|
6934
6927
|
ref,
|
|
@@ -6941,7 +6934,7 @@ var DropdownMenuContent = React27.forwardRef(({ className, sideOffset = 4, ...pr
|
|
|
6941
6934
|
}
|
|
6942
6935
|
) }));
|
|
6943
6936
|
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
|
|
6944
|
-
var DropdownMenuItem =
|
|
6937
|
+
var DropdownMenuItem = React25.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
6945
6938
|
DropdownMenuPrimitive.Item,
|
|
6946
6939
|
{
|
|
6947
6940
|
ref,
|
|
@@ -6954,7 +6947,7 @@ var DropdownMenuItem = React27.forwardRef(({ className, inset, ...props }, ref)
|
|
|
6954
6947
|
}
|
|
6955
6948
|
));
|
|
6956
6949
|
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
|
|
6957
|
-
var DropdownMenuCheckboxItem =
|
|
6950
|
+
var DropdownMenuCheckboxItem = React25.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
6958
6951
|
DropdownMenuPrimitive.CheckboxItem,
|
|
6959
6952
|
{
|
|
6960
6953
|
ref,
|
|
@@ -6971,7 +6964,7 @@ var DropdownMenuCheckboxItem = React27.forwardRef(({ className, children, checke
|
|
|
6971
6964
|
}
|
|
6972
6965
|
));
|
|
6973
6966
|
DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
|
|
6974
|
-
var DropdownMenuRadioItem =
|
|
6967
|
+
var DropdownMenuRadioItem = React25.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
6975
6968
|
DropdownMenuPrimitive.RadioItem,
|
|
6976
6969
|
{
|
|
6977
6970
|
ref,
|
|
@@ -6987,7 +6980,7 @@ var DropdownMenuRadioItem = React27.forwardRef(({ className, children, ...props
|
|
|
6987
6980
|
}
|
|
6988
6981
|
));
|
|
6989
6982
|
DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
|
|
6990
|
-
var DropdownMenuLabel =
|
|
6983
|
+
var DropdownMenuLabel = React25.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
6991
6984
|
DropdownMenuPrimitive.Label,
|
|
6992
6985
|
{
|
|
6993
6986
|
ref,
|
|
@@ -7000,7 +6993,7 @@ var DropdownMenuLabel = React27.forwardRef(({ className, inset, ...props }, ref)
|
|
|
7000
6993
|
}
|
|
7001
6994
|
));
|
|
7002
6995
|
DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
|
|
7003
|
-
var DropdownMenuSeparator =
|
|
6996
|
+
var DropdownMenuSeparator = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
7004
6997
|
DropdownMenuPrimitive.Separator,
|
|
7005
6998
|
{
|
|
7006
6999
|
ref,
|
|
@@ -7024,7 +7017,7 @@ var DropdownMenuShortcut = ({
|
|
|
7024
7017
|
DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
|
|
7025
7018
|
var HoverCard = HoverCardPrimitive.Root;
|
|
7026
7019
|
var HoverCardTrigger = HoverCardPrimitive.Trigger;
|
|
7027
|
-
var HoverCardContent =
|
|
7020
|
+
var HoverCardContent = React25.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
7028
7021
|
HoverCardPrimitive.Content,
|
|
7029
7022
|
{
|
|
7030
7023
|
ref,
|
|
@@ -7038,31 +7031,67 @@ var HoverCardContent = React27.forwardRef(({ className, align = "center", sideOf
|
|
|
7038
7031
|
}
|
|
7039
7032
|
));
|
|
7040
7033
|
HoverCardContent.displayName = HoverCardPrimitive.Content.displayName;
|
|
7041
|
-
var
|
|
7034
|
+
var Label3 = React25.forwardRef(
|
|
7042
7035
|
({ className, ...props }, ref) => {
|
|
7043
7036
|
return /* @__PURE__ */ jsx(
|
|
7044
|
-
"
|
|
7037
|
+
"label",
|
|
7045
7038
|
{
|
|
7039
|
+
ref,
|
|
7046
7040
|
className: cn(
|
|
7047
|
-
"
|
|
7048
|
-
"text-sm ring-offset-background",
|
|
7049
|
-
"placeholder:text-muted-foreground",
|
|
7050
|
-
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
7051
|
-
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
7041
|
+
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
|
|
7052
7042
|
className
|
|
7053
7043
|
),
|
|
7054
|
-
ref,
|
|
7055
7044
|
...props
|
|
7056
7045
|
}
|
|
7057
7046
|
);
|
|
7058
7047
|
}
|
|
7059
7048
|
);
|
|
7060
|
-
|
|
7061
|
-
var
|
|
7062
|
-
|
|
7049
|
+
Label3.displayName = "Label";
|
|
7050
|
+
var Switch = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
7051
|
+
SwitchPrimitives.Root,
|
|
7063
7052
|
{
|
|
7064
|
-
|
|
7065
|
-
|
|
7053
|
+
className: cn(
|
|
7054
|
+
"peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",
|
|
7055
|
+
className
|
|
7056
|
+
),
|
|
7057
|
+
...props,
|
|
7058
|
+
ref,
|
|
7059
|
+
children: /* @__PURE__ */ jsx(
|
|
7060
|
+
SwitchPrimitives.Thumb,
|
|
7061
|
+
{
|
|
7062
|
+
className: cn(
|
|
7063
|
+
"pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0"
|
|
7064
|
+
)
|
|
7065
|
+
}
|
|
7066
|
+
)
|
|
7067
|
+
}
|
|
7068
|
+
));
|
|
7069
|
+
Switch.displayName = SwitchPrimitives.Root.displayName;
|
|
7070
|
+
var Textarea = React25.forwardRef(
|
|
7071
|
+
({ className, ...props }, ref) => {
|
|
7072
|
+
return /* @__PURE__ */ jsx(
|
|
7073
|
+
"textarea",
|
|
7074
|
+
{
|
|
7075
|
+
className: cn(
|
|
7076
|
+
"flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2",
|
|
7077
|
+
"text-sm ring-offset-background",
|
|
7078
|
+
"placeholder:text-muted-foreground",
|
|
7079
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
7080
|
+
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
7081
|
+
className
|
|
7082
|
+
),
|
|
7083
|
+
ref,
|
|
7084
|
+
...props
|
|
7085
|
+
}
|
|
7086
|
+
);
|
|
7087
|
+
}
|
|
7088
|
+
);
|
|
7089
|
+
Textarea.displayName = "Textarea";
|
|
7090
|
+
var Separator3 = React25.forwardRef(({ className, orientation = "horizontal", decorative = true, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
7091
|
+
SeparatorPrimitive.Root,
|
|
7092
|
+
{
|
|
7093
|
+
ref,
|
|
7094
|
+
decorative,
|
|
7066
7095
|
orientation,
|
|
7067
7096
|
className: cn(
|
|
7068
7097
|
"shrink-0 bg-border",
|
|
@@ -7076,7 +7105,7 @@ Separator3.displayName = SeparatorPrimitive.Root.displayName;
|
|
|
7076
7105
|
var Collapsible = CollapsiblePrimitive.Root;
|
|
7077
7106
|
var CollapsibleTrigger2 = CollapsiblePrimitive.CollapsibleTrigger;
|
|
7078
7107
|
var CollapsibleContent2 = CollapsiblePrimitive.CollapsibleContent;
|
|
7079
|
-
var ScrollArea =
|
|
7108
|
+
var ScrollArea = React25.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
7080
7109
|
ScrollAreaPrimitive.Root,
|
|
7081
7110
|
{
|
|
7082
7111
|
ref,
|
|
@@ -7090,7 +7119,7 @@ var ScrollArea = React27.forwardRef(({ className, children, ...props }, ref) =>
|
|
|
7090
7119
|
}
|
|
7091
7120
|
));
|
|
7092
7121
|
ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
|
|
7093
|
-
var ScrollBar =
|
|
7122
|
+
var ScrollBar = React25.forwardRef(({ className, orientation = "vertical", ...props }, ref) => /* @__PURE__ */ jsx(
|
|
7094
7123
|
ScrollAreaPrimitive.ScrollAreaScrollbar,
|
|
7095
7124
|
{
|
|
7096
7125
|
ref,
|
|
@@ -7106,27 +7135,27 @@ var ScrollBar = React27.forwardRef(({ className, orientation = "vertical", ...pr
|
|
|
7106
7135
|
}
|
|
7107
7136
|
));
|
|
7108
7137
|
ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;
|
|
7109
|
-
var Card =
|
|
7138
|
+
var Card = React25.forwardRef(
|
|
7110
7139
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("rounded-lg border bg-card text-card-foreground shadow-sm", className), ...props })
|
|
7111
7140
|
);
|
|
7112
7141
|
Card.displayName = "Card";
|
|
7113
|
-
var CardHeader =
|
|
7142
|
+
var CardHeader = React25.forwardRef(
|
|
7114
7143
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("flex flex-col space-y-1.5 p-6", className), ...props })
|
|
7115
7144
|
);
|
|
7116
7145
|
CardHeader.displayName = "CardHeader";
|
|
7117
|
-
var CardTitle =
|
|
7146
|
+
var CardTitle = React25.forwardRef(
|
|
7118
7147
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx("h3", { ref, className: cn("text-2xl font-semibold leading-none tracking-tight", className), ...props })
|
|
7119
7148
|
);
|
|
7120
7149
|
CardTitle.displayName = "CardTitle";
|
|
7121
|
-
var CardDescription =
|
|
7150
|
+
var CardDescription = React25.forwardRef(
|
|
7122
7151
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx("p", { ref, className: cn("text-sm text-muted-foreground", className), ...props })
|
|
7123
7152
|
);
|
|
7124
7153
|
CardDescription.displayName = "CardDescription";
|
|
7125
|
-
var CardContent =
|
|
7154
|
+
var CardContent = React25.forwardRef(
|
|
7126
7155
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("p-6 pt-0", className), ...props })
|
|
7127
7156
|
);
|
|
7128
7157
|
CardContent.displayName = "CardContent";
|
|
7129
|
-
var CardFooter =
|
|
7158
|
+
var CardFooter = React25.forwardRef(
|
|
7130
7159
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("flex items-center p-6 pt-0", className), ...props })
|
|
7131
7160
|
);
|
|
7132
7161
|
CardFooter.displayName = "CardFooter";
|
|
@@ -7159,16 +7188,16 @@ var toggleVariants = cva(
|
|
|
7159
7188
|
defaultVariants: { variant: "default", size: "default" }
|
|
7160
7189
|
}
|
|
7161
7190
|
);
|
|
7162
|
-
var Toggle =
|
|
7191
|
+
var Toggle = React25.forwardRef(({ className, variant, size, ...props }, ref) => /* @__PURE__ */ jsx(TogglePrimitive.Root, { ref, className: cn(toggleVariants({ variant, size, className })), ...props }));
|
|
7163
7192
|
Toggle.displayName = TogglePrimitive.Root.displayName;
|
|
7164
|
-
var ToggleGroupContext =
|
|
7193
|
+
var ToggleGroupContext = React25.createContext({
|
|
7165
7194
|
size: "default",
|
|
7166
7195
|
variant: "default"
|
|
7167
7196
|
});
|
|
7168
|
-
var ToggleGroup =
|
|
7197
|
+
var ToggleGroup = React25.forwardRef(({ className, variant, size, children, ...props }, ref) => /* @__PURE__ */ jsx(ToggleGroupPrimitive.Root, { ref, className: cn("flex items-center justify-center gap-1", className), ...props, children: /* @__PURE__ */ jsx(ToggleGroupContext.Provider, { value: { variant, size }, children }) }));
|
|
7169
7198
|
ToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName;
|
|
7170
|
-
var ToggleGroupItem =
|
|
7171
|
-
const context =
|
|
7199
|
+
var ToggleGroupItem = React25.forwardRef(({ className, children, variant, size, ...props }, ref) => {
|
|
7200
|
+
const context = React25.useContext(ToggleGroupContext);
|
|
7172
7201
|
return /* @__PURE__ */ jsx(
|
|
7173
7202
|
ToggleGroupPrimitive.Item,
|
|
7174
7203
|
{
|
|
@@ -7183,7 +7212,7 @@ ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName;
|
|
|
7183
7212
|
var AlertDialog = AlertDialogPrimitive.Root;
|
|
7184
7213
|
var AlertDialogTrigger = AlertDialogPrimitive.Trigger;
|
|
7185
7214
|
var AlertDialogPortal = AlertDialogPrimitive.Portal;
|
|
7186
|
-
var AlertDialogOverlay =
|
|
7215
|
+
var AlertDialogOverlay = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
7187
7216
|
AlertDialogPrimitive.Overlay,
|
|
7188
7217
|
{
|
|
7189
7218
|
ref,
|
|
@@ -7192,7 +7221,7 @@ var AlertDialogOverlay = React27.forwardRef(({ className, ...props }, ref) => /*
|
|
|
7192
7221
|
}
|
|
7193
7222
|
));
|
|
7194
7223
|
AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName;
|
|
7195
|
-
var AlertDialogContent =
|
|
7224
|
+
var AlertDialogContent = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxs(AlertDialogPortal, { children: [
|
|
7196
7225
|
/* @__PURE__ */ jsx(AlertDialogOverlay, {}),
|
|
7197
7226
|
/* @__PURE__ */ jsx(
|
|
7198
7227
|
AlertDialogPrimitive.Content,
|
|
@@ -7208,13 +7237,13 @@ var AlertDialogHeader = ({ className, ...props }) => /* @__PURE__ */ jsx("div",
|
|
|
7208
7237
|
AlertDialogHeader.displayName = "AlertDialogHeader";
|
|
7209
7238
|
var AlertDialogFooter = ({ className, ...props }) => /* @__PURE__ */ jsx("div", { className: cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className), ...props });
|
|
7210
7239
|
AlertDialogFooter.displayName = "AlertDialogFooter";
|
|
7211
|
-
var AlertDialogTitle =
|
|
7240
|
+
var AlertDialogTitle = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(AlertDialogPrimitive.Title, { ref, className: cn("text-lg font-semibold", className), ...props }));
|
|
7212
7241
|
AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName;
|
|
7213
|
-
var AlertDialogDescription =
|
|
7242
|
+
var AlertDialogDescription = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(AlertDialogPrimitive.Description, { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
|
|
7214
7243
|
AlertDialogDescription.displayName = AlertDialogPrimitive.Description.displayName;
|
|
7215
|
-
var AlertDialogAction =
|
|
7244
|
+
var AlertDialogAction = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(AlertDialogPrimitive.Action, { ref, className: cn(buttonVariants(), className), ...props }));
|
|
7216
7245
|
AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName;
|
|
7217
|
-
var AlertDialogCancel =
|
|
7246
|
+
var AlertDialogCancel = React25.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(AlertDialogPrimitive.Cancel, { ref, className: cn(buttonVariants({ variant: "outline" }), "mt-2 sm:mt-0", className), ...props }));
|
|
7218
7247
|
AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName;
|
|
7219
7248
|
var buttonGroupVariants = cva(
|
|
7220
7249
|
"flex w-fit items-stretch [&>*]:focus-visible:relative [&>*]:focus-visible:z-10",
|
|
@@ -7242,7 +7271,7 @@ function ButtonGroupText({ className, asChild = false, ...props }) {
|
|
|
7242
7271
|
function ButtonGroupSeparator({ className, orientation = "vertical", ...props }) {
|
|
7243
7272
|
return /* @__PURE__ */ jsx(Separator3, { orientation, className: cn("bg-input relative !m-0 self-stretch data-[orientation=vertical]:h-auto", className), ...props });
|
|
7244
7273
|
}
|
|
7245
|
-
var SkeletonBase =
|
|
7274
|
+
var SkeletonBase = React25.forwardRef(
|
|
7246
7275
|
({ className, ...rest }, ref) => /* @__PURE__ */ jsx(
|
|
7247
7276
|
"div",
|
|
7248
7277
|
{
|
|
@@ -7418,8 +7447,8 @@ function LoadingTimeout({
|
|
|
7418
7447
|
firm: thresholds?.firm ?? 15e3,
|
|
7419
7448
|
expired: thresholds?.expired ?? 3e4
|
|
7420
7449
|
};
|
|
7421
|
-
const [phase, setPhase] =
|
|
7422
|
-
|
|
7450
|
+
const [phase, setPhase] = React25.useState(active ? "silent" : "idle");
|
|
7451
|
+
React25.useEffect(() => {
|
|
7423
7452
|
if (!active) {
|
|
7424
7453
|
setPhase("idle");
|
|
7425
7454
|
return;
|
|
@@ -7478,7 +7507,7 @@ function ProgressiveImage({
|
|
|
7478
7507
|
onLoad,
|
|
7479
7508
|
onError
|
|
7480
7509
|
}) {
|
|
7481
|
-
const [loaded, setLoaded] =
|
|
7510
|
+
const [loaded, setLoaded] = React25.useState(false);
|
|
7482
7511
|
return /* @__PURE__ */ jsxs(
|
|
7483
7512
|
"div",
|
|
7484
7513
|
{
|
|
@@ -7590,7 +7619,1621 @@ function useErrorDisplay() {
|
|
|
7590
7619
|
const clearError = useCallback(() => setRaw(null), []);
|
|
7591
7620
|
return { error, setError, clearError };
|
|
7592
7621
|
}
|
|
7622
|
+
function KanbanCard({
|
|
7623
|
+
item,
|
|
7624
|
+
renderCard,
|
|
7625
|
+
dragging = false,
|
|
7626
|
+
cardClassName,
|
|
7627
|
+
showEdit = false,
|
|
7628
|
+
onEditRequest
|
|
7629
|
+
}) {
|
|
7630
|
+
const {
|
|
7631
|
+
attributes,
|
|
7632
|
+
listeners,
|
|
7633
|
+
setNodeRef,
|
|
7634
|
+
transform,
|
|
7635
|
+
transition,
|
|
7636
|
+
isDragging
|
|
7637
|
+
} = useSortable({ id: item.id, data: { columnKey: item.columnKey } });
|
|
7638
|
+
const priority_var = item.priority ? `--hazo-kanban-priority-${String(item.priority).toLowerCase()}` : null;
|
|
7639
|
+
const style = {
|
|
7640
|
+
transform: CSS.Transform.toString(transform),
|
|
7641
|
+
transition,
|
|
7642
|
+
backgroundColor: "hsl(var(--hazo-kanban-card-bg))",
|
|
7643
|
+
border: `1px solid hsl(var(--hazo-kanban-card-border))`,
|
|
7644
|
+
borderLeft: priority_var ? `4px solid hsl(var(${priority_var}))` : `1px solid hsl(var(--hazo-kanban-card-border))`,
|
|
7645
|
+
opacity: isDragging && !dragging ? 0.4 : 1,
|
|
7646
|
+
cursor: "grab"
|
|
7647
|
+
};
|
|
7648
|
+
return /* @__PURE__ */ jsxs(
|
|
7649
|
+
"div",
|
|
7650
|
+
{
|
|
7651
|
+
ref: setNodeRef,
|
|
7652
|
+
style,
|
|
7653
|
+
className: cn(
|
|
7654
|
+
"cls_hazo_kanban_card group relative rounded-md p-3 mb-2 select-none",
|
|
7655
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
7656
|
+
dragging && "cls_hazo_kanban_card_overlay shadow-lg",
|
|
7657
|
+
cardClassName
|
|
7658
|
+
),
|
|
7659
|
+
...attributes,
|
|
7660
|
+
...listeners,
|
|
7661
|
+
role: "button",
|
|
7662
|
+
tabIndex: 0,
|
|
7663
|
+
"aria-roledescription": "draggable card",
|
|
7664
|
+
"aria-grabbed": isDragging,
|
|
7665
|
+
children: [
|
|
7666
|
+
showEdit && onEditRequest && !dragging && /* @__PURE__ */ jsx(
|
|
7667
|
+
"button",
|
|
7668
|
+
{
|
|
7669
|
+
type: "button",
|
|
7670
|
+
onPointerDown: (e) => e.stopPropagation(),
|
|
7671
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
7672
|
+
onKeyDown: (e) => e.stopPropagation(),
|
|
7673
|
+
onClick: (e) => {
|
|
7674
|
+
e.stopPropagation();
|
|
7675
|
+
onEditRequest(item);
|
|
7676
|
+
},
|
|
7677
|
+
"aria-label": `Edit ${item.id}`,
|
|
7678
|
+
className: cn(
|
|
7679
|
+
"cls_hazo_kanban_card_edit absolute top-1.5 right-1.5",
|
|
7680
|
+
"p-1 rounded-md text-muted-foreground hover:text-foreground hover:bg-accent",
|
|
7681
|
+
"opacity-0 group-hover:opacity-100 group-focus-within:opacity-100",
|
|
7682
|
+
"focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
7683
|
+
"transition-opacity duration-150"
|
|
7684
|
+
),
|
|
7685
|
+
tabIndex: 0,
|
|
7686
|
+
children: /* @__PURE__ */ jsx(Pencil, { className: "h-3.5 w-3.5" })
|
|
7687
|
+
}
|
|
7688
|
+
),
|
|
7689
|
+
renderCard(item)
|
|
7690
|
+
]
|
|
7691
|
+
}
|
|
7692
|
+
);
|
|
7693
|
+
}
|
|
7694
|
+
function KanbanColumn({
|
|
7695
|
+
column,
|
|
7696
|
+
items,
|
|
7697
|
+
renderCard,
|
|
7698
|
+
emptyColumn,
|
|
7699
|
+
cardClassName,
|
|
7700
|
+
showEdit,
|
|
7701
|
+
onEditRequest
|
|
7702
|
+
}) {
|
|
7703
|
+
const { setNodeRef, isOver } = useDroppable({
|
|
7704
|
+
id: `column:${column.key}`,
|
|
7705
|
+
data: { columnKey: column.key, isColumn: true }
|
|
7706
|
+
});
|
|
7707
|
+
return /* @__PURE__ */ jsxs(
|
|
7708
|
+
"div",
|
|
7709
|
+
{
|
|
7710
|
+
ref: setNodeRef,
|
|
7711
|
+
className: cn(
|
|
7712
|
+
"cls_hazo_kanban_column flex flex-col rounded-md p-2",
|
|
7713
|
+
isOver && "cls_hazo_kanban_column_over bg-accent/30 ring-2 ring-ring/40"
|
|
7714
|
+
),
|
|
7715
|
+
children: [
|
|
7716
|
+
/* @__PURE__ */ jsxs("div", { className: "cls_hazo_kanban_column_head flex items-center justify-between mb-2 px-1 text-xs uppercase tracking-wider text-muted-foreground", children: [
|
|
7717
|
+
/* @__PURE__ */ jsx("span", { className: "cls_hazo_kanban_column_title", children: column.title }),
|
|
7718
|
+
/* @__PURE__ */ jsx("span", { className: "cls_hazo_kanban_column_count rounded-full bg-muted px-2 py-0.5 text-foreground", children: items.length })
|
|
7719
|
+
] }),
|
|
7720
|
+
/* @__PURE__ */ jsx(
|
|
7721
|
+
SortableContext,
|
|
7722
|
+
{
|
|
7723
|
+
items: items.map((i) => i.id),
|
|
7724
|
+
strategy: verticalListSortingStrategy,
|
|
7725
|
+
children: /* @__PURE__ */ jsx("div", { className: "cls_hazo_kanban_column_body flex-1 min-h-[40px]", children: items.length === 0 ? /* @__PURE__ */ jsx("div", { className: "cls_hazo_kanban_column_empty text-xs text-muted-foreground py-2 px-1", children: emptyColumn }) : items.map((item) => /* @__PURE__ */ jsx(
|
|
7726
|
+
KanbanCard,
|
|
7727
|
+
{
|
|
7728
|
+
item,
|
|
7729
|
+
renderCard,
|
|
7730
|
+
cardClassName,
|
|
7731
|
+
showEdit,
|
|
7732
|
+
onEditRequest
|
|
7733
|
+
},
|
|
7734
|
+
item.id
|
|
7735
|
+
)) })
|
|
7736
|
+
}
|
|
7737
|
+
)
|
|
7738
|
+
]
|
|
7739
|
+
}
|
|
7740
|
+
);
|
|
7741
|
+
}
|
|
7742
|
+
var DEFAULT_PRIORITIES = ["P0", "P1", "P2", "P3"];
|
|
7743
|
+
function humanize(key) {
|
|
7744
|
+
return key.replace(/[_\-]+/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2").replace(/\s+/g, " ").trim().split(" ").map((w) => w ? w[0].toUpperCase() + w.slice(1) : w).join(" ");
|
|
7745
|
+
}
|
|
7746
|
+
function auto_detect_fields(item, columns) {
|
|
7747
|
+
const skip = /* @__PURE__ */ new Set(["id", "columnKey", "priority"]);
|
|
7748
|
+
const out = [];
|
|
7749
|
+
for (const [key, value] of Object.entries(item)) {
|
|
7750
|
+
if (skip.has(key)) continue;
|
|
7751
|
+
if (typeof value === "string") {
|
|
7752
|
+
out.push({ key, type: "text" });
|
|
7753
|
+
}
|
|
7754
|
+
}
|
|
7755
|
+
if (columns.length > 0) {
|
|
7756
|
+
out.push({ key: "columnKey", type: "status", label: "Status" });
|
|
7757
|
+
}
|
|
7758
|
+
return out;
|
|
7759
|
+
}
|
|
7760
|
+
function KanbanEditor({
|
|
7761
|
+
item,
|
|
7762
|
+
columns,
|
|
7763
|
+
fields,
|
|
7764
|
+
priorities,
|
|
7765
|
+
titleFn,
|
|
7766
|
+
renderBody,
|
|
7767
|
+
hideFooter = false,
|
|
7768
|
+
onSave,
|
|
7769
|
+
onClose
|
|
7770
|
+
}) {
|
|
7771
|
+
const [draft, set_draft] = React25.useState(item);
|
|
7772
|
+
const [saving, set_saving] = React25.useState(false);
|
|
7773
|
+
const [error, set_error] = React25.useState(null);
|
|
7774
|
+
const item_id = item?.id ?? null;
|
|
7775
|
+
React25.useEffect(() => {
|
|
7776
|
+
set_draft(item);
|
|
7777
|
+
set_error(null);
|
|
7778
|
+
set_saving(false);
|
|
7779
|
+
}, [item_id]);
|
|
7780
|
+
const resolved_columns = columns ?? [];
|
|
7781
|
+
const resolved_priorities = priorities ?? DEFAULT_PRIORITIES;
|
|
7782
|
+
const resolved_fields = React25.useMemo(() => {
|
|
7783
|
+
if (fields) return fields;
|
|
7784
|
+
if (!item) return [];
|
|
7785
|
+
return auto_detect_fields(item, resolved_columns);
|
|
7786
|
+
}, [fields, item, resolved_columns]);
|
|
7787
|
+
const required_keys = React25.useMemo(
|
|
7788
|
+
() => resolved_fields.filter(
|
|
7789
|
+
(f) => f.required && (f.type === "text" || f.type === "textarea" || f.type === "number")
|
|
7790
|
+
).map((f) => f.key),
|
|
7791
|
+
[resolved_fields]
|
|
7792
|
+
);
|
|
7793
|
+
const all_required_filled = React25.useMemo(() => {
|
|
7794
|
+
if (!draft) return false;
|
|
7795
|
+
for (const key of required_keys) {
|
|
7796
|
+
const v = draft[key];
|
|
7797
|
+
if (v === void 0 || v === null || v === "") return false;
|
|
7798
|
+
if (typeof v === "string" && v.trim() === "") return false;
|
|
7799
|
+
}
|
|
7800
|
+
return true;
|
|
7801
|
+
}, [draft, required_keys]);
|
|
7802
|
+
const is_dirty = React25.useMemo(() => {
|
|
7803
|
+
if (!draft || !item) return false;
|
|
7804
|
+
try {
|
|
7805
|
+
return JSON.stringify(draft) !== JSON.stringify(item);
|
|
7806
|
+
} catch {
|
|
7807
|
+
return draft !== item;
|
|
7808
|
+
}
|
|
7809
|
+
}, [draft, item]);
|
|
7810
|
+
const handle_save = React25.useCallback(async () => {
|
|
7811
|
+
if (!draft || !item) return;
|
|
7812
|
+
if (saving) return;
|
|
7813
|
+
set_error(null);
|
|
7814
|
+
if (!onSave) {
|
|
7815
|
+
onClose();
|
|
7816
|
+
return;
|
|
7817
|
+
}
|
|
7818
|
+
const result = onSave({ itemId: item.id, item, next: draft });
|
|
7819
|
+
if (result && typeof result.then === "function") {
|
|
7820
|
+
set_saving(true);
|
|
7821
|
+
try {
|
|
7822
|
+
await result;
|
|
7823
|
+
set_saving(false);
|
|
7824
|
+
onClose();
|
|
7825
|
+
} catch (err) {
|
|
7826
|
+
set_saving(false);
|
|
7827
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
7828
|
+
set_error(message);
|
|
7829
|
+
}
|
|
7830
|
+
} else {
|
|
7831
|
+
onClose();
|
|
7832
|
+
}
|
|
7833
|
+
}, [draft, item, onSave, onClose, saving]);
|
|
7834
|
+
const ctx = {
|
|
7835
|
+
draft: draft ?? item,
|
|
7836
|
+
setDraft: (next) => {
|
|
7837
|
+
set_draft((prev) => {
|
|
7838
|
+
const base = prev ?? item;
|
|
7839
|
+
if (!base) return prev;
|
|
7840
|
+
if (typeof next === "function") {
|
|
7841
|
+
return next(base);
|
|
7842
|
+
}
|
|
7843
|
+
return next;
|
|
7844
|
+
});
|
|
7845
|
+
},
|
|
7846
|
+
save: handle_save,
|
|
7847
|
+
close: onClose,
|
|
7848
|
+
saving,
|
|
7849
|
+
error,
|
|
7850
|
+
isDirty: is_dirty
|
|
7851
|
+
};
|
|
7852
|
+
const open = item !== null;
|
|
7853
|
+
const title = item && titleFn ? titleFn(item) : item ? `Edit ${item.id}` : "";
|
|
7854
|
+
const priority_var = item?.priority ? `--hazo-kanban-priority-${String(item.priority).toLowerCase()}` : null;
|
|
7855
|
+
const header_bar_color = priority_var ? `hsl(var(${priority_var}))` : void 0;
|
|
7856
|
+
const use_default_footer = !(renderBody && hideFooter);
|
|
7857
|
+
return /* @__PURE__ */ jsx(
|
|
7858
|
+
HazoUiDialog,
|
|
7859
|
+
{
|
|
7860
|
+
open,
|
|
7861
|
+
onOpenChange: (o) => {
|
|
7862
|
+
if (!o && !saving) onClose();
|
|
7863
|
+
},
|
|
7864
|
+
title,
|
|
7865
|
+
description: "Update card details below.",
|
|
7866
|
+
sizeWidth: "min(90vw, 480px)",
|
|
7867
|
+
openAnimation: "none",
|
|
7868
|
+
closeAnimation: "none",
|
|
7869
|
+
headerBar: !!priority_var,
|
|
7870
|
+
headerBarColor: header_bar_color,
|
|
7871
|
+
contentClassName: cn("cls_hazo_kanban_editor", priority_var && "pt-0"),
|
|
7872
|
+
actionButtonText: saving ? "Saving\u2026" : "Save",
|
|
7873
|
+
actionButtonIcon: saving ? void 0 : /* @__PURE__ */ jsx(Check, { className: "h-4 w-4 mr-2" }),
|
|
7874
|
+
actionButtonLoading: saving,
|
|
7875
|
+
actionButtonDisabled: !is_dirty || !all_required_filled || saving,
|
|
7876
|
+
cancelButtonText: "Cancel",
|
|
7877
|
+
showCancelButton: true,
|
|
7878
|
+
onConfirm: handle_save,
|
|
7879
|
+
onCancel: onClose,
|
|
7880
|
+
footerContent: use_default_footer ? void 0 : /* @__PURE__ */ jsx("span", {}),
|
|
7881
|
+
children: /* @__PURE__ */ jsxs("div", { className: "cls_hazo_kanban_editor_body flex flex-col gap-4", children: [
|
|
7882
|
+
item && draft && renderBody ? renderBody(item, ctx) : draft ? resolved_fields.map((field) => /* @__PURE__ */ jsx(
|
|
7883
|
+
KanbanEditorFieldRow,
|
|
7884
|
+
{
|
|
7885
|
+
field,
|
|
7886
|
+
draft,
|
|
7887
|
+
setDraft: (updater) => set_draft(
|
|
7888
|
+
(prev) => prev ? updater(prev) : prev
|
|
7889
|
+
),
|
|
7890
|
+
priorities: resolved_priorities,
|
|
7891
|
+
columns: resolved_columns
|
|
7892
|
+
},
|
|
7893
|
+
field.key
|
|
7894
|
+
)) : null,
|
|
7895
|
+
error && /* @__PURE__ */ jsx(
|
|
7896
|
+
"div",
|
|
7897
|
+
{
|
|
7898
|
+
className: "cls_hazo_kanban_editor_error mt-1 rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-sm text-destructive",
|
|
7899
|
+
role: "alert",
|
|
7900
|
+
children: error
|
|
7901
|
+
}
|
|
7902
|
+
)
|
|
7903
|
+
] })
|
|
7904
|
+
}
|
|
7905
|
+
);
|
|
7906
|
+
}
|
|
7907
|
+
function KanbanEditorFieldRow({
|
|
7908
|
+
field,
|
|
7909
|
+
draft,
|
|
7910
|
+
setDraft,
|
|
7911
|
+
priorities,
|
|
7912
|
+
columns
|
|
7913
|
+
}) {
|
|
7914
|
+
const id = `kanban-editor-${field.key}`;
|
|
7915
|
+
const label = field.label ?? humanize(field.key);
|
|
7916
|
+
const value = draft[field.key];
|
|
7917
|
+
const set_value = (next_value) => {
|
|
7918
|
+
setDraft((prev) => ({ ...prev, [field.key]: next_value }));
|
|
7919
|
+
};
|
|
7920
|
+
const required_marker_shown = field.required && (field.type === "text" || field.type === "textarea" || field.type === "number");
|
|
7921
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("cls_hazo_kanban_editor_field flex flex-col gap-1.5"), children: [
|
|
7922
|
+
/* @__PURE__ */ jsxs(Label3, { htmlFor: id, className: "text-xs font-medium text-muted-foreground", children: [
|
|
7923
|
+
label,
|
|
7924
|
+
required_marker_shown && /* @__PURE__ */ jsx("span", { className: "text-destructive ml-0.5", children: "*" })
|
|
7925
|
+
] }),
|
|
7926
|
+
field.type === "text" && /* @__PURE__ */ jsx(
|
|
7927
|
+
Input,
|
|
7928
|
+
{
|
|
7929
|
+
id,
|
|
7930
|
+
value: typeof value === "string" ? value : "",
|
|
7931
|
+
placeholder: field.placeholder,
|
|
7932
|
+
onChange: (e) => set_value(e.target.value)
|
|
7933
|
+
}
|
|
7934
|
+
),
|
|
7935
|
+
field.type === "textarea" && /* @__PURE__ */ jsx(
|
|
7936
|
+
Textarea,
|
|
7937
|
+
{
|
|
7938
|
+
id,
|
|
7939
|
+
value: typeof value === "string" ? value : "",
|
|
7940
|
+
placeholder: field.placeholder,
|
|
7941
|
+
rows: 3,
|
|
7942
|
+
onChange: (e) => set_value(e.target.value)
|
|
7943
|
+
}
|
|
7944
|
+
),
|
|
7945
|
+
field.type === "number" && /* @__PURE__ */ jsx(
|
|
7946
|
+
Input,
|
|
7947
|
+
{
|
|
7948
|
+
id,
|
|
7949
|
+
type: "number",
|
|
7950
|
+
value: typeof value === "number" ? value : value === "" || value == null ? "" : Number(value) || 0,
|
|
7951
|
+
placeholder: field.placeholder,
|
|
7952
|
+
onChange: (e) => set_value(e.target.value === "" ? void 0 : Number(e.target.value))
|
|
7953
|
+
}
|
|
7954
|
+
),
|
|
7955
|
+
field.type === "checkbox" && /* @__PURE__ */ jsx(
|
|
7956
|
+
Checkbox,
|
|
7957
|
+
{
|
|
7958
|
+
id,
|
|
7959
|
+
checked: !!value,
|
|
7960
|
+
onCheckedChange: (checked) => set_value(checked === true)
|
|
7961
|
+
}
|
|
7962
|
+
),
|
|
7963
|
+
field.type === "select" && /* @__PURE__ */ jsxs(
|
|
7964
|
+
Select,
|
|
7965
|
+
{
|
|
7966
|
+
value: typeof value === "string" ? value : "",
|
|
7967
|
+
onValueChange: set_value,
|
|
7968
|
+
children: [
|
|
7969
|
+
/* @__PURE__ */ jsx(SelectTrigger, { id, children: /* @__PURE__ */ jsx(
|
|
7970
|
+
SelectValue,
|
|
7971
|
+
{
|
|
7972
|
+
placeholder: field.placeholder ?? `Select ${label}\u2026`
|
|
7973
|
+
}
|
|
7974
|
+
) }),
|
|
7975
|
+
/* @__PURE__ */ jsx(SelectContent, { children: (field.options ?? []).map((opt) => /* @__PURE__ */ jsx(SelectItem, { value: opt, children: opt }, opt)) })
|
|
7976
|
+
]
|
|
7977
|
+
}
|
|
7978
|
+
),
|
|
7979
|
+
field.type === "priority" && /* @__PURE__ */ jsxs(
|
|
7980
|
+
Select,
|
|
7981
|
+
{
|
|
7982
|
+
value: typeof value === "string" ? value : "",
|
|
7983
|
+
onValueChange: set_value,
|
|
7984
|
+
children: [
|
|
7985
|
+
/* @__PURE__ */ jsx(SelectTrigger, { id, children: /* @__PURE__ */ jsx(
|
|
7986
|
+
SelectValue,
|
|
7987
|
+
{
|
|
7988
|
+
placeholder: field.placeholder ?? "Select priority\u2026"
|
|
7989
|
+
}
|
|
7990
|
+
) }),
|
|
7991
|
+
/* @__PURE__ */ jsx(SelectContent, { children: priorities.map((p) => /* @__PURE__ */ jsx(SelectItem, { value: p, children: p }, p)) })
|
|
7992
|
+
]
|
|
7993
|
+
}
|
|
7994
|
+
),
|
|
7995
|
+
field.type === "status" && /* @__PURE__ */ jsxs(
|
|
7996
|
+
Select,
|
|
7997
|
+
{
|
|
7998
|
+
value: typeof value === "string" ? value : "",
|
|
7999
|
+
onValueChange: set_value,
|
|
8000
|
+
children: [
|
|
8001
|
+
/* @__PURE__ */ jsx(SelectTrigger, { id, children: /* @__PURE__ */ jsx(
|
|
8002
|
+
SelectValue,
|
|
8003
|
+
{
|
|
8004
|
+
placeholder: field.placeholder ?? "Select status\u2026"
|
|
8005
|
+
}
|
|
8006
|
+
) }),
|
|
8007
|
+
/* @__PURE__ */ jsx(SelectContent, { children: columns.map((col) => /* @__PURE__ */ jsx(SelectItem, { value: col.key, children: col.title }, col.key)) })
|
|
8008
|
+
]
|
|
8009
|
+
}
|
|
8010
|
+
)
|
|
8011
|
+
] });
|
|
8012
|
+
}
|
|
8013
|
+
var EMPTY_FILTER = {
|
|
8014
|
+
search: "",
|
|
8015
|
+
categories: [],
|
|
8016
|
+
priority: null
|
|
8017
|
+
};
|
|
8018
|
+
function HazoUiKanbanFilter({
|
|
8019
|
+
search = true,
|
|
8020
|
+
searchPlaceholder = "Search...",
|
|
8021
|
+
categories,
|
|
8022
|
+
priorities,
|
|
8023
|
+
value,
|
|
8024
|
+
defaultValue,
|
|
8025
|
+
onChange,
|
|
8026
|
+
className
|
|
8027
|
+
}) {
|
|
8028
|
+
const is_controlled = value !== void 0;
|
|
8029
|
+
const [internal, set_internal] = React25.useState(
|
|
8030
|
+
defaultValue ?? EMPTY_FILTER
|
|
8031
|
+
);
|
|
8032
|
+
const current = is_controlled ? value : internal;
|
|
8033
|
+
const update = React25.useCallback(
|
|
8034
|
+
(next) => {
|
|
8035
|
+
if (!is_controlled) set_internal(next);
|
|
8036
|
+
onChange?.(next);
|
|
8037
|
+
},
|
|
8038
|
+
[is_controlled, onChange]
|
|
8039
|
+
);
|
|
8040
|
+
const has_active = current.search.length > 0 || current.categories.length > 0 || current.priority !== null;
|
|
8041
|
+
return /* @__PURE__ */ jsxs(
|
|
8042
|
+
"div",
|
|
8043
|
+
{
|
|
8044
|
+
className: cn(
|
|
8045
|
+
"cls_hazo_kanban_filter flex flex-wrap items-center gap-3 p-2",
|
|
8046
|
+
className
|
|
8047
|
+
),
|
|
8048
|
+
children: [
|
|
8049
|
+
search && /* @__PURE__ */ jsx(
|
|
8050
|
+
Input,
|
|
8051
|
+
{
|
|
8052
|
+
value: current.search,
|
|
8053
|
+
onChange: (e) => update({ ...current, search: e.target.value }),
|
|
8054
|
+
placeholder: searchPlaceholder,
|
|
8055
|
+
className: "cls_hazo_kanban_filter_search w-full sm:w-64"
|
|
8056
|
+
}
|
|
8057
|
+
),
|
|
8058
|
+
categories && categories.length > 0 && /* @__PURE__ */ jsx(
|
|
8059
|
+
ToggleGroup,
|
|
8060
|
+
{
|
|
8061
|
+
type: "multiple",
|
|
8062
|
+
value: current.categories,
|
|
8063
|
+
onValueChange: (cats) => update({ ...current, categories: cats }),
|
|
8064
|
+
className: "cls_hazo_kanban_filter_categories flex flex-wrap gap-1",
|
|
8065
|
+
children: categories.map((cat) => /* @__PURE__ */ jsx(
|
|
8066
|
+
ToggleGroupItem,
|
|
8067
|
+
{
|
|
8068
|
+
value: cat,
|
|
8069
|
+
size: "sm",
|
|
8070
|
+
className: "cls_hazo_kanban_filter_category_chip",
|
|
8071
|
+
children: cat
|
|
8072
|
+
},
|
|
8073
|
+
cat
|
|
8074
|
+
))
|
|
8075
|
+
}
|
|
8076
|
+
),
|
|
8077
|
+
priorities && priorities.length > 0 && /* @__PURE__ */ jsx(
|
|
8078
|
+
ToggleGroup,
|
|
8079
|
+
{
|
|
8080
|
+
type: "single",
|
|
8081
|
+
value: current.priority ?? "",
|
|
8082
|
+
onValueChange: (p) => update({
|
|
8083
|
+
...current,
|
|
8084
|
+
priority: p ? p : null
|
|
8085
|
+
}),
|
|
8086
|
+
className: "cls_hazo_kanban_filter_priority flex gap-1",
|
|
8087
|
+
children: priorities.map((p) => /* @__PURE__ */ jsx(
|
|
8088
|
+
ToggleGroupItem,
|
|
8089
|
+
{
|
|
8090
|
+
value: p,
|
|
8091
|
+
size: "sm",
|
|
8092
|
+
className: "cls_hazo_kanban_filter_priority_chip",
|
|
8093
|
+
children: p
|
|
8094
|
+
},
|
|
8095
|
+
p
|
|
8096
|
+
))
|
|
8097
|
+
}
|
|
8098
|
+
),
|
|
8099
|
+
has_active && /* @__PURE__ */ jsxs(
|
|
8100
|
+
Button,
|
|
8101
|
+
{
|
|
8102
|
+
variant: "ghost",
|
|
8103
|
+
size: "sm",
|
|
8104
|
+
onClick: () => update(EMPTY_FILTER),
|
|
8105
|
+
className: "cls_hazo_kanban_filter_clear",
|
|
8106
|
+
children: [
|
|
8107
|
+
/* @__PURE__ */ jsx(X, { className: "h-4 w-4 mr-1" }),
|
|
8108
|
+
"Clear"
|
|
8109
|
+
]
|
|
8110
|
+
}
|
|
8111
|
+
)
|
|
8112
|
+
]
|
|
8113
|
+
}
|
|
8114
|
+
);
|
|
8115
|
+
}
|
|
8116
|
+
|
|
8117
|
+
// src/components/hazo_ui_kanban/apply_kanban_filter.ts
|
|
8118
|
+
function applyKanbanFilter(items, filter) {
|
|
8119
|
+
const search = filter.search.trim().toLowerCase();
|
|
8120
|
+
return items.filter((item) => {
|
|
8121
|
+
if (filter.priority && item.priority !== filter.priority) {
|
|
8122
|
+
return false;
|
|
8123
|
+
}
|
|
8124
|
+
if (filter.categories.length > 0) {
|
|
8125
|
+
const cat = item.category;
|
|
8126
|
+
if (typeof cat !== "string" || !filter.categories.includes(cat)) {
|
|
8127
|
+
return false;
|
|
8128
|
+
}
|
|
8129
|
+
}
|
|
8130
|
+
if (search) {
|
|
8131
|
+
const haystack = Object.values(item).filter((v) => typeof v === "string").join(" ").toLowerCase();
|
|
8132
|
+
if (!haystack.includes(search)) {
|
|
8133
|
+
return false;
|
|
8134
|
+
}
|
|
8135
|
+
}
|
|
8136
|
+
return true;
|
|
8137
|
+
});
|
|
8138
|
+
}
|
|
8139
|
+
function default_announcements(itemLabel) {
|
|
8140
|
+
return {
|
|
8141
|
+
onDragStart: ({ item, fromColumn }) => `Picked up ${itemLabel(item)}. Currently in ${fromColumn}. Use arrow keys to choose a different column. Press space to drop, escape to cancel.`,
|
|
8142
|
+
onDragOver: ({ item, overColumn }) => overColumn ? `${itemLabel(item)} over ${overColumn}.` : "",
|
|
8143
|
+
onDragEnd: ({ item, fromColumn, toColumn, newIndex }) => fromColumn === toColumn ? `${itemLabel(item)} reordered to position ${newIndex + 1} in ${toColumn}.` : `${itemLabel(item)} dropped in ${toColumn}, position ${newIndex + 1}.`,
|
|
8144
|
+
onDragCancel: ({ item, fromColumn }) => `Movement cancelled. ${itemLabel(item)} returned to ${fromColumn}.`
|
|
8145
|
+
};
|
|
8146
|
+
}
|
|
8147
|
+
function group_items_by_column(items, overlay, columns) {
|
|
8148
|
+
const out = /* @__PURE__ */ new Map();
|
|
8149
|
+
for (const col of columns) out.set(col.key, []);
|
|
8150
|
+
const overlay_inserts = /* @__PURE__ */ new Map();
|
|
8151
|
+
for (const col of columns) overlay_inserts.set(col.key, []);
|
|
8152
|
+
for (const item of items) {
|
|
8153
|
+
const ov = overlay.get(item.id);
|
|
8154
|
+
if (ov) {
|
|
8155
|
+
const bucket = overlay_inserts.get(ov.columnKey);
|
|
8156
|
+
if (bucket) {
|
|
8157
|
+
bucket.push({ item, index: ov.index });
|
|
8158
|
+
}
|
|
8159
|
+
} else {
|
|
8160
|
+
const bucket = out.get(item.columnKey);
|
|
8161
|
+
if (bucket) bucket.push(item);
|
|
8162
|
+
}
|
|
8163
|
+
}
|
|
8164
|
+
for (const col of columns) {
|
|
8165
|
+
const inserts = overlay_inserts.get(col.key) ?? [];
|
|
8166
|
+
inserts.sort((a, b) => a.index - b.index);
|
|
8167
|
+
const arr = out.get(col.key) ?? [];
|
|
8168
|
+
for (const { item, index } of inserts) {
|
|
8169
|
+
const at = Math.max(0, Math.min(index, arr.length));
|
|
8170
|
+
arr.splice(at, 0, item);
|
|
8171
|
+
}
|
|
8172
|
+
out.set(col.key, arr);
|
|
8173
|
+
}
|
|
8174
|
+
return out;
|
|
8175
|
+
}
|
|
8176
|
+
function HazoUiKanban({
|
|
8177
|
+
columns,
|
|
8178
|
+
items,
|
|
8179
|
+
renderCard,
|
|
8180
|
+
onMove,
|
|
8181
|
+
onReorder,
|
|
8182
|
+
mobileBreakpoint = 640,
|
|
8183
|
+
announcements,
|
|
8184
|
+
emptyColumn = "\u2014",
|
|
8185
|
+
className,
|
|
8186
|
+
cardClassName,
|
|
8187
|
+
itemLabel,
|
|
8188
|
+
editorFields,
|
|
8189
|
+
editorPriorities,
|
|
8190
|
+
editorTitle,
|
|
8191
|
+
renderCardEditor,
|
|
8192
|
+
hideEditorFooter,
|
|
8193
|
+
onCardSave,
|
|
8194
|
+
disableEdit = false
|
|
8195
|
+
}) {
|
|
8196
|
+
const label_fn = React25.useCallback(
|
|
8197
|
+
(item) => itemLabel ? itemLabel(item) : item.id,
|
|
8198
|
+
[itemLabel]
|
|
8199
|
+
);
|
|
8200
|
+
const dnd_context_id = React25.useId();
|
|
8201
|
+
const [overlay, set_overlay] = React25.useState(
|
|
8202
|
+
/* @__PURE__ */ new Map()
|
|
8203
|
+
);
|
|
8204
|
+
const [active_id, set_active_id] = React25.useState(null);
|
|
8205
|
+
const [active_tab, set_active_tab] = React25.useState(columns[0]?.key ?? "");
|
|
8206
|
+
const [editing_item, set_editing_item] = React25.useState(null);
|
|
8207
|
+
const show_edit = !disableEdit && typeof onCardSave === "function";
|
|
8208
|
+
const handle_edit_request = React25.useCallback(
|
|
8209
|
+
(it) => {
|
|
8210
|
+
const typed = items.find((x) => x.id === it.id);
|
|
8211
|
+
if (typed) set_editing_item(typed);
|
|
8212
|
+
},
|
|
8213
|
+
[items]
|
|
8214
|
+
);
|
|
8215
|
+
const handle_editor_close = React25.useCallback(() => {
|
|
8216
|
+
set_editing_item(null);
|
|
8217
|
+
}, []);
|
|
8218
|
+
React25.useEffect(() => {
|
|
8219
|
+
if (overlay.size === 0) return;
|
|
8220
|
+
set_overlay((prev) => {
|
|
8221
|
+
let changed = false;
|
|
8222
|
+
const next = new Map(prev);
|
|
8223
|
+
for (const [item_id, pos] of prev.entries()) {
|
|
8224
|
+
const item = items.find((i) => i.id === item_id);
|
|
8225
|
+
if (item && item.columnKey === pos.columnKey) {
|
|
8226
|
+
next.delete(item_id);
|
|
8227
|
+
changed = true;
|
|
8228
|
+
}
|
|
8229
|
+
}
|
|
8230
|
+
return changed ? next : prev;
|
|
8231
|
+
});
|
|
8232
|
+
}, [items, overlay]);
|
|
8233
|
+
const grouped = React25.useMemo(
|
|
8234
|
+
() => group_items_by_column(items, overlay, columns),
|
|
8235
|
+
[items, overlay, columns]
|
|
8236
|
+
);
|
|
8237
|
+
const find_item = React25.useCallback(
|
|
8238
|
+
(id) => items.find((i) => i.id === id),
|
|
8239
|
+
[items]
|
|
8240
|
+
);
|
|
8241
|
+
const sensors = useSensors(
|
|
8242
|
+
useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),
|
|
8243
|
+
useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates })
|
|
8244
|
+
);
|
|
8245
|
+
const merged_announcements = React25.useMemo(() => {
|
|
8246
|
+
const defaults = default_announcements(label_fn);
|
|
8247
|
+
return {
|
|
8248
|
+
onDragStart: announcements?.onDragStart ?? defaults.onDragStart,
|
|
8249
|
+
onDragOver: announcements?.onDragOver ?? defaults.onDragOver,
|
|
8250
|
+
onDragEnd: announcements?.onDragEnd ?? defaults.onDragEnd,
|
|
8251
|
+
onDragCancel: announcements?.onDragCancel ?? defaults.onDragCancel
|
|
8252
|
+
};
|
|
8253
|
+
}, [announcements, label_fn]);
|
|
8254
|
+
const dnd_announcements = React25.useMemo(
|
|
8255
|
+
() => ({
|
|
8256
|
+
onDragStart({ active }) {
|
|
8257
|
+
const id = String(active.id);
|
|
8258
|
+
const item = find_item(id);
|
|
8259
|
+
if (!item) return "";
|
|
8260
|
+
const col = columns.find((c) => c.key === item.columnKey);
|
|
8261
|
+
return merged_announcements.onDragStart({
|
|
8262
|
+
item,
|
|
8263
|
+
fromColumn: col?.title ?? item.columnKey
|
|
8264
|
+
});
|
|
8265
|
+
},
|
|
8266
|
+
onDragOver({
|
|
8267
|
+
active,
|
|
8268
|
+
over
|
|
8269
|
+
}) {
|
|
8270
|
+
const id = String(active.id);
|
|
8271
|
+
const item = find_item(id);
|
|
8272
|
+
if (!item) return "";
|
|
8273
|
+
const over_col_key = over ? over.data?.current?.columnKey ?? String(over.id).replace(/^column:/, "") : null;
|
|
8274
|
+
const col = over_col_key ? columns.find((c) => c.key === over_col_key) : null;
|
|
8275
|
+
return merged_announcements.onDragOver({
|
|
8276
|
+
item,
|
|
8277
|
+
overColumn: col?.title ?? null
|
|
8278
|
+
});
|
|
8279
|
+
},
|
|
8280
|
+
onDragEnd({
|
|
8281
|
+
active,
|
|
8282
|
+
over
|
|
8283
|
+
}) {
|
|
8284
|
+
const id = String(active.id);
|
|
8285
|
+
const item = find_item(id);
|
|
8286
|
+
if (!item) return "";
|
|
8287
|
+
const from_col = columns.find((c) => c.key === item.columnKey);
|
|
8288
|
+
const over_col_key = over ? over.data?.current?.columnKey ?? String(over.id).replace(/^column:/, "") : null;
|
|
8289
|
+
const to_col = over_col_key ? columns.find((c) => c.key === over_col_key) ?? from_col : from_col;
|
|
8290
|
+
const target = over_col_key ? grouped.get(over_col_key) ?? [] : grouped.get(item.columnKey) ?? [];
|
|
8291
|
+
const new_index = over && String(over.id) !== `column:${over_col_key}` ? target.findIndex((it) => it.id === String(over.id)) : target.length;
|
|
8292
|
+
return merged_announcements.onDragEnd({
|
|
8293
|
+
item,
|
|
8294
|
+
fromColumn: from_col?.title ?? item.columnKey,
|
|
8295
|
+
toColumn: to_col?.title ?? item.columnKey,
|
|
8296
|
+
newIndex: Math.max(0, new_index)
|
|
8297
|
+
});
|
|
8298
|
+
},
|
|
8299
|
+
onDragCancel({ active }) {
|
|
8300
|
+
const id = String(active.id);
|
|
8301
|
+
const item = find_item(id);
|
|
8302
|
+
if (!item) return "";
|
|
8303
|
+
const col = columns.find((c) => c.key === item.columnKey);
|
|
8304
|
+
return merged_announcements.onDragCancel({
|
|
8305
|
+
item,
|
|
8306
|
+
fromColumn: col?.title ?? item.columnKey
|
|
8307
|
+
});
|
|
8308
|
+
}
|
|
8309
|
+
}),
|
|
8310
|
+
[find_item, columns, grouped, merged_announcements]
|
|
8311
|
+
);
|
|
8312
|
+
const handle_drag_start = React25.useCallback((event) => {
|
|
8313
|
+
set_active_id(String(event.active.id));
|
|
8314
|
+
}, []);
|
|
8315
|
+
const make_revert_handle = React25.useCallback(
|
|
8316
|
+
(item_id) => ({
|
|
8317
|
+
revert: () => {
|
|
8318
|
+
set_overlay((prev) => {
|
|
8319
|
+
if (!prev.has(item_id)) return prev;
|
|
8320
|
+
const next = new Map(prev);
|
|
8321
|
+
next.delete(item_id);
|
|
8322
|
+
return next;
|
|
8323
|
+
});
|
|
8324
|
+
}
|
|
8325
|
+
}),
|
|
8326
|
+
[]
|
|
8327
|
+
);
|
|
8328
|
+
const handle_drag_end = React25.useCallback(
|
|
8329
|
+
(event) => {
|
|
8330
|
+
const active_id_str = String(event.active.id);
|
|
8331
|
+
set_active_id(null);
|
|
8332
|
+
const item = find_item(active_id_str);
|
|
8333
|
+
if (!item) return;
|
|
8334
|
+
if (!event.over) return;
|
|
8335
|
+
const over_id = String(event.over.id);
|
|
8336
|
+
const over_data = event.over.data?.current;
|
|
8337
|
+
const dest_column_key = over_data?.columnKey ?? over_id.replace(/^column:/, "");
|
|
8338
|
+
const dest_column = columns.find((c) => c.key === dest_column_key);
|
|
8339
|
+
if (!dest_column) return;
|
|
8340
|
+
if (dest_column.accepts && !dest_column.accepts(item)) return;
|
|
8341
|
+
const dest_items_pre_overlay = grouped.get(dest_column_key) ?? [];
|
|
8342
|
+
let new_index;
|
|
8343
|
+
if (over_data?.isColumn) {
|
|
8344
|
+
new_index = dest_items_pre_overlay.length;
|
|
8345
|
+
} else {
|
|
8346
|
+
const idx = dest_items_pre_overlay.findIndex((i) => i.id === over_id);
|
|
8347
|
+
new_index = idx === -1 ? dest_items_pre_overlay.length : idx;
|
|
8348
|
+
}
|
|
8349
|
+
const handle = make_revert_handle(active_id_str);
|
|
8350
|
+
if (item.columnKey === dest_column_key) {
|
|
8351
|
+
if (active_id_str === over_id) return;
|
|
8352
|
+
set_overlay((prev) => {
|
|
8353
|
+
const next = new Map(prev);
|
|
8354
|
+
next.set(active_id_str, {
|
|
8355
|
+
columnKey: dest_column_key,
|
|
8356
|
+
index: new_index
|
|
8357
|
+
});
|
|
8358
|
+
return next;
|
|
8359
|
+
});
|
|
8360
|
+
const reorder_event = {
|
|
8361
|
+
itemId: active_id_str,
|
|
8362
|
+
item,
|
|
8363
|
+
columnKey: dest_column_key,
|
|
8364
|
+
newIndex: new_index,
|
|
8365
|
+
revert: handle.revert
|
|
8366
|
+
};
|
|
8367
|
+
onReorder?.(reorder_event);
|
|
8368
|
+
return;
|
|
8369
|
+
}
|
|
8370
|
+
set_overlay((prev) => {
|
|
8371
|
+
const next = new Map(prev);
|
|
8372
|
+
next.set(active_id_str, {
|
|
8373
|
+
columnKey: dest_column_key,
|
|
8374
|
+
index: new_index
|
|
8375
|
+
});
|
|
8376
|
+
return next;
|
|
8377
|
+
});
|
|
8378
|
+
const move_event = {
|
|
8379
|
+
itemId: active_id_str,
|
|
8380
|
+
item,
|
|
8381
|
+
fromColumn: item.columnKey,
|
|
8382
|
+
toColumn: dest_column_key,
|
|
8383
|
+
newIndex: new_index,
|
|
8384
|
+
revert: handle.revert
|
|
8385
|
+
};
|
|
8386
|
+
onMove?.(move_event);
|
|
8387
|
+
},
|
|
8388
|
+
[find_item, columns, grouped, onMove, onReorder, make_revert_handle]
|
|
8389
|
+
);
|
|
8390
|
+
const handle_drag_cancel = React25.useCallback(() => {
|
|
8391
|
+
set_active_id(null);
|
|
8392
|
+
}, []);
|
|
8393
|
+
const active_item = active_id ? find_item(active_id) : null;
|
|
8394
|
+
const is_custom_breakpoint = mobileBreakpoint !== 640;
|
|
8395
|
+
const is_mobile_via_query = useMediaQuery(
|
|
8396
|
+
`(max-width: ${Math.max(0, mobileBreakpoint - 1)}px)`
|
|
8397
|
+
);
|
|
8398
|
+
const mobile_classes = is_custom_breakpoint ? is_mobile_via_query ? "block" : "hidden" : "sm:hidden";
|
|
8399
|
+
const desktop_classes = is_custom_breakpoint ? is_mobile_via_query ? "hidden" : "grid" : "hidden sm:grid";
|
|
8400
|
+
return /* @__PURE__ */ jsxs(
|
|
8401
|
+
DndContext,
|
|
8402
|
+
{
|
|
8403
|
+
id: dnd_context_id,
|
|
8404
|
+
sensors,
|
|
8405
|
+
collisionDetection: closestCorners,
|
|
8406
|
+
onDragStart: handle_drag_start,
|
|
8407
|
+
onDragEnd: handle_drag_end,
|
|
8408
|
+
onDragCancel: handle_drag_cancel,
|
|
8409
|
+
accessibility: { announcements: dnd_announcements },
|
|
8410
|
+
children: [
|
|
8411
|
+
/* @__PURE__ */ jsxs("div", { className: cn("cls_hazo_kanban w-full", className), children: [
|
|
8412
|
+
/* @__PURE__ */ jsx("div", { className: cn("cls_hazo_kanban_mobile", mobile_classes), children: /* @__PURE__ */ jsxs(Tabs, { value: active_tab, onValueChange: set_active_tab, children: [
|
|
8413
|
+
/* @__PURE__ */ jsx(TabsList, { className: "grid w-full", style: { gridTemplateColumns: `repeat(${columns.length}, 1fr)` }, children: columns.map((col) => {
|
|
8414
|
+
const count = (grouped.get(col.key) ?? []).length;
|
|
8415
|
+
return /* @__PURE__ */ jsxs(TabsTrigger, { value: col.key, className: "flex flex-col gap-0.5", children: [
|
|
8416
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs", children: col.title }),
|
|
8417
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] text-muted-foreground", children: count })
|
|
8418
|
+
] }, col.key);
|
|
8419
|
+
}) }),
|
|
8420
|
+
columns.map((col) => /* @__PURE__ */ jsx(TabsContent, { value: col.key, className: "mt-3", children: /* @__PURE__ */ jsx(
|
|
8421
|
+
KanbanColumn,
|
|
8422
|
+
{
|
|
8423
|
+
column: col,
|
|
8424
|
+
items: grouped.get(col.key) ?? [],
|
|
8425
|
+
renderCard,
|
|
8426
|
+
emptyColumn,
|
|
8427
|
+
cardClassName,
|
|
8428
|
+
showEdit: show_edit,
|
|
8429
|
+
onEditRequest: handle_edit_request
|
|
8430
|
+
}
|
|
8431
|
+
) }, col.key))
|
|
8432
|
+
] }) }),
|
|
8433
|
+
/* @__PURE__ */ jsx(
|
|
8434
|
+
"div",
|
|
8435
|
+
{
|
|
8436
|
+
className: cn("cls_hazo_kanban_desktop gap-3", desktop_classes),
|
|
8437
|
+
style: { gridTemplateColumns: `repeat(${columns.length}, minmax(0, 1fr))` },
|
|
8438
|
+
children: columns.map((col) => /* @__PURE__ */ jsx(
|
|
8439
|
+
KanbanColumn,
|
|
8440
|
+
{
|
|
8441
|
+
column: col,
|
|
8442
|
+
items: grouped.get(col.key) ?? [],
|
|
8443
|
+
renderCard,
|
|
8444
|
+
emptyColumn,
|
|
8445
|
+
cardClassName,
|
|
8446
|
+
showEdit: show_edit,
|
|
8447
|
+
onEditRequest: handle_edit_request
|
|
8448
|
+
},
|
|
8449
|
+
col.key
|
|
8450
|
+
))
|
|
8451
|
+
}
|
|
8452
|
+
),
|
|
8453
|
+
/* @__PURE__ */ jsx(DragOverlay, { children: active_item ? /* @__PURE__ */ jsx(
|
|
8454
|
+
KanbanCard,
|
|
8455
|
+
{
|
|
8456
|
+
item: active_item,
|
|
8457
|
+
renderCard,
|
|
8458
|
+
dragging: true,
|
|
8459
|
+
cardClassName
|
|
8460
|
+
}
|
|
8461
|
+
) : null })
|
|
8462
|
+
] }),
|
|
8463
|
+
/* @__PURE__ */ jsx(
|
|
8464
|
+
KanbanEditor,
|
|
8465
|
+
{
|
|
8466
|
+
item: editing_item,
|
|
8467
|
+
columns,
|
|
8468
|
+
fields: editorFields,
|
|
8469
|
+
priorities: editorPriorities,
|
|
8470
|
+
titleFn: editorTitle,
|
|
8471
|
+
renderBody: renderCardEditor,
|
|
8472
|
+
hideFooter: hideEditorFooter,
|
|
8473
|
+
onSave: onCardSave,
|
|
8474
|
+
onClose: handle_editor_close
|
|
8475
|
+
}
|
|
8476
|
+
)
|
|
8477
|
+
]
|
|
8478
|
+
}
|
|
8479
|
+
);
|
|
8480
|
+
}
|
|
8481
|
+
var Table2 = React25.forwardRef(
|
|
8482
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { className: "cls_table_wrap relative w-full overflow-auto", children: /* @__PURE__ */ jsx(
|
|
8483
|
+
"table",
|
|
8484
|
+
{
|
|
8485
|
+
ref,
|
|
8486
|
+
className: cn("w-full caption-bottom text-sm", className),
|
|
8487
|
+
...props
|
|
8488
|
+
}
|
|
8489
|
+
) })
|
|
8490
|
+
);
|
|
8491
|
+
Table2.displayName = "Table";
|
|
8492
|
+
var TableHeader2 = React25.forwardRef(
|
|
8493
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx("thead", { ref, className: cn("[&_tr]:border-b", className), ...props })
|
|
8494
|
+
);
|
|
8495
|
+
TableHeader2.displayName = "TableHeader";
|
|
8496
|
+
var TableBody = React25.forwardRef(
|
|
8497
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
8498
|
+
"tbody",
|
|
8499
|
+
{
|
|
8500
|
+
ref,
|
|
8501
|
+
className: cn("[&_tr:last-child]:border-0", className),
|
|
8502
|
+
...props
|
|
8503
|
+
}
|
|
8504
|
+
)
|
|
8505
|
+
);
|
|
8506
|
+
TableBody.displayName = "TableBody";
|
|
8507
|
+
var TableFooter = React25.forwardRef(
|
|
8508
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
8509
|
+
"tfoot",
|
|
8510
|
+
{
|
|
8511
|
+
ref,
|
|
8512
|
+
className: cn("bg-muted/50 font-medium [&>tr]:last:border-b-0", className),
|
|
8513
|
+
...props
|
|
8514
|
+
}
|
|
8515
|
+
)
|
|
8516
|
+
);
|
|
8517
|
+
TableFooter.displayName = "TableFooter";
|
|
8518
|
+
var TableRow2 = React25.forwardRef(
|
|
8519
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
8520
|
+
"tr",
|
|
8521
|
+
{
|
|
8522
|
+
ref,
|
|
8523
|
+
className: cn(
|
|
8524
|
+
"border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",
|
|
8525
|
+
className
|
|
8526
|
+
),
|
|
8527
|
+
...props
|
|
8528
|
+
}
|
|
8529
|
+
)
|
|
8530
|
+
);
|
|
8531
|
+
TableRow2.displayName = "TableRow";
|
|
8532
|
+
var TableHead = React25.forwardRef(
|
|
8533
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
8534
|
+
"th",
|
|
8535
|
+
{
|
|
8536
|
+
ref,
|
|
8537
|
+
className: cn(
|
|
8538
|
+
"h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0",
|
|
8539
|
+
className
|
|
8540
|
+
),
|
|
8541
|
+
...props
|
|
8542
|
+
}
|
|
8543
|
+
)
|
|
8544
|
+
);
|
|
8545
|
+
TableHead.displayName = "TableHead";
|
|
8546
|
+
var TableCell2 = React25.forwardRef(
|
|
8547
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
8548
|
+
"td",
|
|
8549
|
+
{
|
|
8550
|
+
ref,
|
|
8551
|
+
className: cn("p-4 align-middle [&:has([role=checkbox])]:pr-0", className),
|
|
8552
|
+
...props
|
|
8553
|
+
}
|
|
8554
|
+
)
|
|
8555
|
+
);
|
|
8556
|
+
TableCell2.displayName = "TableCell";
|
|
8557
|
+
var TableCaption = React25.forwardRef(
|
|
8558
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
8559
|
+
"caption",
|
|
8560
|
+
{
|
|
8561
|
+
ref,
|
|
8562
|
+
className: cn("mt-4 text-sm text-muted-foreground", className),
|
|
8563
|
+
...props
|
|
8564
|
+
}
|
|
8565
|
+
)
|
|
8566
|
+
);
|
|
8567
|
+
TableCaption.displayName = "TableCaption";
|
|
8568
|
+
function TableMobileCards(props) {
|
|
8569
|
+
const { columns, rows, getRowKey, onRowClick, renderCell: renderCell2 } = props;
|
|
8570
|
+
const [titleCol, ...restCols] = columns;
|
|
8571
|
+
if (!titleCol) return null;
|
|
8572
|
+
return /* @__PURE__ */ jsx("div", { className: "cls_hazo_ui_table_mobile_cards flex flex-col gap-3", children: rows.map((row, i) => {
|
|
8573
|
+
const interactionProps = onRowClick ? {
|
|
8574
|
+
role: "button",
|
|
8575
|
+
tabIndex: 0,
|
|
8576
|
+
className: "cls_hazo_ui_table_mobile_card_clickable cursor-pointer",
|
|
8577
|
+
onClick: () => onRowClick(row, i),
|
|
8578
|
+
onKeyDown: (e) => {
|
|
8579
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
8580
|
+
e.preventDefault();
|
|
8581
|
+
onRowClick(row, i);
|
|
8582
|
+
}
|
|
8583
|
+
}
|
|
8584
|
+
} : {};
|
|
8585
|
+
return /* @__PURE__ */ jsxs(
|
|
8586
|
+
Card,
|
|
8587
|
+
{
|
|
8588
|
+
...interactionProps,
|
|
8589
|
+
children: [
|
|
8590
|
+
/* @__PURE__ */ jsx(CardHeader, { className: "pb-2", children: /* @__PURE__ */ jsx(CardTitle, { className: "text-base", children: renderCell2(titleCol, row, i) }) }),
|
|
8591
|
+
/* @__PURE__ */ jsx(CardContent, { className: "pt-0 space-y-1.5", children: restCols.map((c) => /* @__PURE__ */ jsxs(
|
|
8592
|
+
"div",
|
|
8593
|
+
{
|
|
8594
|
+
className: cn(
|
|
8595
|
+
"cls_hazo_ui_table_mobile_row flex items-center justify-between gap-3 text-sm"
|
|
8596
|
+
),
|
|
8597
|
+
children: [
|
|
8598
|
+
/* @__PURE__ */ jsx("span", { className: "cls_hazo_ui_table_mobile_label text-muted-foreground", children: c.label }),
|
|
8599
|
+
/* @__PURE__ */ jsx("span", { className: cn("cls_hazo_ui_table_mobile_value", c.className), children: renderCell2(c, row, i) })
|
|
8600
|
+
]
|
|
8601
|
+
},
|
|
8602
|
+
c.key
|
|
8603
|
+
)) })
|
|
8604
|
+
]
|
|
8605
|
+
},
|
|
8606
|
+
getRowKey ? getRowKey(row, i) : i
|
|
8607
|
+
);
|
|
8608
|
+
}) });
|
|
8609
|
+
}
|
|
8610
|
+
var DEFAULT_DEBOUNCE_MS = 200;
|
|
8611
|
+
function useTableState(props) {
|
|
8612
|
+
const [sortInternal, setSortInternal] = useState(
|
|
8613
|
+
() => normalizeSortProp(props.defaultSort)
|
|
8614
|
+
);
|
|
8615
|
+
const isSortControlled = props.sort !== void 0;
|
|
8616
|
+
const sort = isSortControlled ? normalizeSortProp(props.sort) : sortInternal;
|
|
8617
|
+
const setSort = useCallback(
|
|
8618
|
+
(next) => {
|
|
8619
|
+
if (!isSortControlled) setSortInternal(next);
|
|
8620
|
+
props.onSortChange?.(next);
|
|
8621
|
+
},
|
|
8622
|
+
[isSortControlled, props.onSortChange]
|
|
8623
|
+
);
|
|
8624
|
+
const cycleHeaderSort = useCallback(
|
|
8625
|
+
(key, append) => {
|
|
8626
|
+
const next = append ? cycleAppendColumn(sort, key) : cycleSingleColumn(sort, key);
|
|
8627
|
+
setSort(next);
|
|
8628
|
+
},
|
|
8629
|
+
[sort, setSort]
|
|
8630
|
+
);
|
|
8631
|
+
const [filterInternal, setFilterInternal] = useState(
|
|
8632
|
+
() => props.defaultFilter ?? {}
|
|
8633
|
+
);
|
|
8634
|
+
const isFilterControlled = props.filter !== void 0;
|
|
8635
|
+
const filter = isFilterControlled ? props.filter : filterInternal;
|
|
8636
|
+
const setFilter = useCallback(
|
|
8637
|
+
(next) => {
|
|
8638
|
+
if (!isFilterControlled) setFilterInternal(next);
|
|
8639
|
+
props.onFilterChange?.(next);
|
|
8640
|
+
},
|
|
8641
|
+
[isFilterControlled, props.onFilterChange]
|
|
8642
|
+
);
|
|
8643
|
+
const [searchDraft, setSearchDraft] = useState(
|
|
8644
|
+
filter.search ?? ""
|
|
8645
|
+
);
|
|
8646
|
+
const debounceMs = props.searchDebounceMs ?? DEFAULT_DEBOUNCE_MS;
|
|
8647
|
+
useEffect(() => {
|
|
8648
|
+
const handle = setTimeout(() => {
|
|
8649
|
+
if (searchDraft === (filter.search ?? "")) return;
|
|
8650
|
+
setFilter({ ...filter, search: searchDraft || void 0 });
|
|
8651
|
+
}, debounceMs);
|
|
8652
|
+
return () => clearTimeout(handle);
|
|
8653
|
+
}, [searchDraft, debounceMs]);
|
|
8654
|
+
const setSearch = useCallback((s) => setSearchDraft(s), []);
|
|
8655
|
+
const [pageInternal, setPageInternal] = useState(
|
|
8656
|
+
() => props.defaultPage ?? 0
|
|
8657
|
+
);
|
|
8658
|
+
const isPageControlled = props.page !== void 0;
|
|
8659
|
+
const page = isPageControlled ? props.page : pageInternal;
|
|
8660
|
+
const setPage = useCallback(
|
|
8661
|
+
(next) => {
|
|
8662
|
+
if (!isPageControlled) setPageInternal(next);
|
|
8663
|
+
props.onPageChange?.(next);
|
|
8664
|
+
},
|
|
8665
|
+
[isPageControlled, props.onPageChange]
|
|
8666
|
+
);
|
|
8667
|
+
const prevSortKey = useRef(serializeSort(sort));
|
|
8668
|
+
const prevFilterKey = useRef(serializeFilter(filter));
|
|
8669
|
+
useEffect(() => {
|
|
8670
|
+
const sk = serializeSort(sort);
|
|
8671
|
+
const fk = serializeFilter(filter);
|
|
8672
|
+
if (sk !== prevSortKey.current || fk !== prevFilterKey.current) {
|
|
8673
|
+
if (!isPageControlled) setPageInternal(0);
|
|
8674
|
+
prevSortKey.current = sk;
|
|
8675
|
+
prevFilterKey.current = fk;
|
|
8676
|
+
}
|
|
8677
|
+
}, [sort, filter, isPageControlled]);
|
|
8678
|
+
const pageSize = props.pagination && typeof props.pagination === "object" ? props.pagination.pageSize : 0;
|
|
8679
|
+
const isServerMode = typeof props.onLoad === "function";
|
|
8680
|
+
const filtered = useMemo(
|
|
8681
|
+
() => isServerMode ? props.rows : applyFilter(props.rows, filter, props.columns),
|
|
8682
|
+
[props.rows, filter, props.columns, isServerMode]
|
|
8683
|
+
);
|
|
8684
|
+
const sorted = useMemo(
|
|
8685
|
+
() => isServerMode ? filtered : applySort(filtered, sort),
|
|
8686
|
+
[filtered, sort, isServerMode]
|
|
8687
|
+
);
|
|
8688
|
+
const pagedInMemory = useMemo(() => {
|
|
8689
|
+
if (isServerMode || pageSize <= 0) return sorted;
|
|
8690
|
+
const start = page * pageSize;
|
|
8691
|
+
return sorted.slice(start, start + pageSize);
|
|
8692
|
+
}, [sorted, page, pageSize, isServerMode]);
|
|
8693
|
+
const [serverRows, setServerRows] = useState([]);
|
|
8694
|
+
const [serverTotal, setServerTotal] = useState(0);
|
|
8695
|
+
const [serverError, setServerError] = useState(null);
|
|
8696
|
+
const reqIdRef = useRef(0);
|
|
8697
|
+
useEffect(() => {
|
|
8698
|
+
if (!isServerMode) return;
|
|
8699
|
+
const myId = ++reqIdRef.current;
|
|
8700
|
+
let cancelled = false;
|
|
8701
|
+
setServerError(null);
|
|
8702
|
+
Promise.resolve(
|
|
8703
|
+
props.onLoad({ page, sort, filter })
|
|
8704
|
+
).then((res) => {
|
|
8705
|
+
if (cancelled || myId !== reqIdRef.current) return;
|
|
8706
|
+
setServerRows(res.rows);
|
|
8707
|
+
setServerTotal(res.total);
|
|
8708
|
+
}).catch((err) => {
|
|
8709
|
+
if (cancelled || myId !== reqIdRef.current) return;
|
|
8710
|
+
console.warn("[HazoUiTable] onLoad rejected:", err);
|
|
8711
|
+
setServerRows([]);
|
|
8712
|
+
setServerTotal(0);
|
|
8713
|
+
setServerError(err ?? new Error("onLoad rejected"));
|
|
8714
|
+
});
|
|
8715
|
+
return () => {
|
|
8716
|
+
cancelled = true;
|
|
8717
|
+
};
|
|
8718
|
+
}, [isServerMode, page, sort, filter, props.onLoad]);
|
|
8719
|
+
const displayed = isServerMode ? serverRows : pagedInMemory;
|
|
8720
|
+
const totalAfterFilter = isServerMode ? serverTotal : filtered.length;
|
|
8721
|
+
return {
|
|
8722
|
+
sort,
|
|
8723
|
+
setSort,
|
|
8724
|
+
cycleHeaderSort,
|
|
8725
|
+
filter,
|
|
8726
|
+
setFilter,
|
|
8727
|
+
setSearch,
|
|
8728
|
+
page,
|
|
8729
|
+
setPage,
|
|
8730
|
+
displayed,
|
|
8731
|
+
totalAfterFilter,
|
|
8732
|
+
pageSize,
|
|
8733
|
+
serverError: isServerMode ? serverError : null
|
|
8734
|
+
};
|
|
8735
|
+
}
|
|
8736
|
+
function normalizeSortProp(p) {
|
|
8737
|
+
if (!p) return [];
|
|
8738
|
+
if (Array.isArray(p)) return p;
|
|
8739
|
+
return [p];
|
|
8740
|
+
}
|
|
8741
|
+
function cycleSingleColumn(current, key) {
|
|
8742
|
+
if (current.length !== 1) return [{ key, dir: "asc" }];
|
|
8743
|
+
const only = current[0];
|
|
8744
|
+
if (only.key !== key) return [{ key, dir: "asc" }];
|
|
8745
|
+
if (only.dir === "asc") return [{ key, dir: "desc" }];
|
|
8746
|
+
return [];
|
|
8747
|
+
}
|
|
8748
|
+
function cycleAppendColumn(current, key) {
|
|
8749
|
+
const idx = current.findIndex((s) => s.key === key);
|
|
8750
|
+
if (idx === -1) return [...current, { key, dir: "asc" }];
|
|
8751
|
+
const entry = current[idx];
|
|
8752
|
+
if (entry.dir === "asc") {
|
|
8753
|
+
const next = current.slice();
|
|
8754
|
+
next[idx] = { key, dir: "desc" };
|
|
8755
|
+
return next;
|
|
8756
|
+
}
|
|
8757
|
+
return current.filter((_, i) => i !== idx);
|
|
8758
|
+
}
|
|
8759
|
+
function applyFilter(rows, filter, columns) {
|
|
8760
|
+
let result = rows;
|
|
8761
|
+
if (filter.fields && filter.fields.length > 0) {
|
|
8762
|
+
result = result.filter(
|
|
8763
|
+
(row) => filter.fields.every((f) => matchesFieldFilter(row, f, columns))
|
|
8764
|
+
);
|
|
8765
|
+
}
|
|
8766
|
+
const needle = (filter.search ?? "").trim().toLowerCase();
|
|
8767
|
+
if (needle.length > 0) {
|
|
8768
|
+
const searchKeys = columns.filter(isSearchable).map((c) => c.key);
|
|
8769
|
+
if (searchKeys.length > 0) {
|
|
8770
|
+
result = result.filter(
|
|
8771
|
+
(row) => searchKeys.some(
|
|
8772
|
+
(k) => String(row[k] ?? "").toLowerCase().includes(needle)
|
|
8773
|
+
)
|
|
8774
|
+
);
|
|
8775
|
+
}
|
|
8776
|
+
}
|
|
8777
|
+
return result;
|
|
8778
|
+
}
|
|
8779
|
+
function isSearchable(c) {
|
|
8780
|
+
if (c.searchable !== void 0) return c.searchable;
|
|
8781
|
+
switch (c.formatter) {
|
|
8782
|
+
case "number":
|
|
8783
|
+
case "currency":
|
|
8784
|
+
case "percent":
|
|
8785
|
+
case "date":
|
|
8786
|
+
return false;
|
|
8787
|
+
default:
|
|
8788
|
+
return true;
|
|
8789
|
+
}
|
|
8790
|
+
}
|
|
8791
|
+
function matchesFieldFilter(row, f, columns) {
|
|
8792
|
+
const col = columns.find((c) => c.key === f.field);
|
|
8793
|
+
if (!col || !col.filterType) return true;
|
|
8794
|
+
const value = row[f.field];
|
|
8795
|
+
const op = f.operator || "equals";
|
|
8796
|
+
switch (col.filterType) {
|
|
8797
|
+
case "text": {
|
|
8798
|
+
if (f.value === void 0 || f.value === "") return true;
|
|
8799
|
+
return String(value ?? "").toLowerCase().includes(String(f.value).toLowerCase());
|
|
8800
|
+
}
|
|
8801
|
+
case "number": {
|
|
8802
|
+
const v = Number(value);
|
|
8803
|
+
const fv = Number(f.value);
|
|
8804
|
+
if (Number.isNaN(v) || Number.isNaN(fv)) return false;
|
|
8805
|
+
return numberOp(v, fv, op);
|
|
8806
|
+
}
|
|
8807
|
+
case "date": {
|
|
8808
|
+
const v = value instanceof Date ? value : new Date(value);
|
|
8809
|
+
const fv = f.value instanceof Date ? f.value : new Date(f.value);
|
|
8810
|
+
if (Number.isNaN(v.getTime()) || Number.isNaN(fv.getTime())) return false;
|
|
8811
|
+
const ta = new Date(v).setHours(0, 0, 0, 0);
|
|
8812
|
+
const tb = new Date(fv).setHours(0, 0, 0, 0);
|
|
8813
|
+
return numberOp(ta, tb, op);
|
|
8814
|
+
}
|
|
8815
|
+
case "combobox":
|
|
8816
|
+
return String(value) === String(f.value);
|
|
8817
|
+
case "boolean":
|
|
8818
|
+
return Boolean(value) === Boolean(f.value);
|
|
8819
|
+
default:
|
|
8820
|
+
return true;
|
|
8821
|
+
}
|
|
8822
|
+
}
|
|
8823
|
+
function numberOp(a, b, op) {
|
|
8824
|
+
switch (op) {
|
|
8825
|
+
case "equals":
|
|
8826
|
+
return a === b;
|
|
8827
|
+
case "not_equals":
|
|
8828
|
+
return a !== b;
|
|
8829
|
+
case "greater_than":
|
|
8830
|
+
return a > b;
|
|
8831
|
+
case "less_than":
|
|
8832
|
+
return a < b;
|
|
8833
|
+
case "greater_equal":
|
|
8834
|
+
return a >= b;
|
|
8835
|
+
case "less_equal":
|
|
8836
|
+
return a <= b;
|
|
8837
|
+
default:
|
|
8838
|
+
return true;
|
|
8839
|
+
}
|
|
8840
|
+
}
|
|
8841
|
+
function applySort(rows, sort) {
|
|
8842
|
+
if (sort.length === 0) return rows;
|
|
8843
|
+
return [...rows].map((row, idx) => ({ row, idx })).sort((a, b) => {
|
|
8844
|
+
for (const entry of sort) {
|
|
8845
|
+
const va = a.row[entry.key];
|
|
8846
|
+
const vb = b.row[entry.key];
|
|
8847
|
+
const cmp = compareValues(va, vb);
|
|
8848
|
+
if (cmp !== 0) return entry.dir === "asc" ? cmp : -cmp;
|
|
8849
|
+
}
|
|
8850
|
+
return a.idx - b.idx;
|
|
8851
|
+
}).map((x) => x.row);
|
|
8852
|
+
}
|
|
8853
|
+
function compareValues(a, b) {
|
|
8854
|
+
if (a == null && b == null) return 0;
|
|
8855
|
+
if (a == null) return 1;
|
|
8856
|
+
if (b == null) return -1;
|
|
8857
|
+
if (a instanceof Date && b instanceof Date)
|
|
8858
|
+
return a.getTime() - b.getTime();
|
|
8859
|
+
if (typeof a === "number" && typeof b === "number") return a - b;
|
|
8860
|
+
return String(a).localeCompare(String(b));
|
|
8861
|
+
}
|
|
8862
|
+
function serializeSort(sort) {
|
|
8863
|
+
return sort.map((s) => `${s.key}:${s.dir}`).join(",");
|
|
8864
|
+
}
|
|
8865
|
+
function serializeFilter(filter) {
|
|
8866
|
+
const fields = (filter.fields ?? []).map((f) => `${f.field}:${f.operator ?? ""}:${String(f.value)}`).join(",");
|
|
8867
|
+
return `${filter.search ?? ""}|${fields}`;
|
|
8868
|
+
}
|
|
8869
|
+
function HazoUiTable(props) {
|
|
8870
|
+
const state = useTableState(props);
|
|
8871
|
+
const { columns, rows, getRowKey, className, caption } = props;
|
|
8872
|
+
const mobileBreakpoint = props.mobileBreakpoint ?? 768;
|
|
8873
|
+
const mobileEnabled = props.mobileCardFallback !== false;
|
|
8874
|
+
const isNarrow = useMediaQuery(`(max-width: ${mobileBreakpoint - 1}px)`);
|
|
8875
|
+
const renderAsCards = mobileEnabled && isNarrow;
|
|
8876
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("cls_hazo_ui_table_root space-y-3", className), children: [
|
|
8877
|
+
(props.enableSearch || props.enableSortDialog || props.enableFilterDialog) && /* @__PURE__ */ jsx(
|
|
8878
|
+
Toolbar2,
|
|
8879
|
+
{
|
|
8880
|
+
columns,
|
|
8881
|
+
sort: state.sort,
|
|
8882
|
+
onSortChange: state.setSort,
|
|
8883
|
+
filter: state.filter,
|
|
8884
|
+
onSearchChange: state.setSearch,
|
|
8885
|
+
onFilterFieldsChange: (fields) => state.setFilter({ ...state.filter, fields }),
|
|
8886
|
+
enableSearch: props.enableSearch,
|
|
8887
|
+
enableSortDialog: props.enableSortDialog,
|
|
8888
|
+
enableFilterDialog: props.enableFilterDialog,
|
|
8889
|
+
searchPlaceholder: props.searchPlaceholder
|
|
8890
|
+
}
|
|
8891
|
+
),
|
|
8892
|
+
renderAsCards ? props.loading ? /* @__PURE__ */ jsx("div", { className: "cls_hazo_ui_table_mobile_loading flex flex-col gap-3", children: Array.from({ length: Math.max(state.pageSize || 5, 3) }).map(
|
|
8893
|
+
(_, i) => /* @__PURE__ */ jsxs(Card, { children: [
|
|
8894
|
+
/* @__PURE__ */ jsx(CardHeader, { className: "pb-2", children: /* @__PURE__ */ jsx(SkeletonBar, { className: "w-2/3" }) }),
|
|
8895
|
+
/* @__PURE__ */ jsxs(CardContent, { className: "pt-0 space-y-2", children: [
|
|
8896
|
+
/* @__PURE__ */ jsx(SkeletonBar, { className: "w-full" }),
|
|
8897
|
+
/* @__PURE__ */ jsx(SkeletonBar, { className: "w-1/2" })
|
|
8898
|
+
] })
|
|
8899
|
+
] }, `mloader-${i}`)
|
|
8900
|
+
) }) : state.serverError != null ? /* @__PURE__ */ jsx("div", { className: "cls_hazo_ui_table_mobile_error py-6", children: renderErrorState(props.error, state.serverError) }) : state.displayed.length === 0 ? /* @__PURE__ */ jsx("div", { className: "cls_hazo_ui_table_mobile_empty py-6", children: noActiveFilters(state.filter) && rows.length === 0 ? typeof props.empty === "string" || props.empty === void 0 ? /* @__PURE__ */ jsx(
|
|
8901
|
+
EmptyState,
|
|
8902
|
+
{
|
|
8903
|
+
title: typeof props.empty === "string" && props.empty || "No items"
|
|
8904
|
+
}
|
|
8905
|
+
) : props.empty : typeof props.noResults === "string" || props.noResults === void 0 ? /* @__PURE__ */ jsx(
|
|
8906
|
+
EmptyState,
|
|
8907
|
+
{
|
|
8908
|
+
title: typeof props.noResults === "string" && props.noResults || "No matches \u2014 adjust your filters"
|
|
8909
|
+
}
|
|
8910
|
+
) : props.noResults }) : /* @__PURE__ */ jsx(
|
|
8911
|
+
TableMobileCards,
|
|
8912
|
+
{
|
|
8913
|
+
columns,
|
|
8914
|
+
rows: state.displayed,
|
|
8915
|
+
getRowKey,
|
|
8916
|
+
onRowClick: props.onRowClick,
|
|
8917
|
+
renderCell
|
|
8918
|
+
}
|
|
8919
|
+
) : /* @__PURE__ */ jsxs(Table2, { children: [
|
|
8920
|
+
caption && /* @__PURE__ */ jsx(TableCaption, { children: caption }),
|
|
8921
|
+
/* @__PURE__ */ jsx(TableHeader2, { children: /* @__PURE__ */ jsx(TableRow2, { children: columns.map((c) => /* @__PURE__ */ jsx(
|
|
8922
|
+
TableHead,
|
|
8923
|
+
{
|
|
8924
|
+
className: cn(headerAlignClass(c), c.headerClassName),
|
|
8925
|
+
"aria-sort": ariaSortFor(state.sort, c.key),
|
|
8926
|
+
children: c.sortable ? /* @__PURE__ */ jsxs(
|
|
8927
|
+
"button",
|
|
8928
|
+
{
|
|
8929
|
+
type: "button",
|
|
8930
|
+
onClick: (e) => state.cycleHeaderSort(c.key, e.shiftKey),
|
|
8931
|
+
title: "Click to sort; shift-click to append a secondary sort",
|
|
8932
|
+
className: "cls_hazo_ui_table_sort_btn inline-flex items-center gap-1 hover:text-foreground",
|
|
8933
|
+
children: [
|
|
8934
|
+
/* @__PURE__ */ jsx("span", { children: c.label }),
|
|
8935
|
+
/* @__PURE__ */ jsx(SortIndicator, { sort: state.sort, columnKey: c.key })
|
|
8936
|
+
]
|
|
8937
|
+
}
|
|
8938
|
+
) : c.label
|
|
8939
|
+
},
|
|
8940
|
+
c.key
|
|
8941
|
+
)) }) }),
|
|
8942
|
+
/* @__PURE__ */ jsx(TableBody, { children: props.loading ? /* @__PURE__ */ jsx(
|
|
8943
|
+
LoadingRows,
|
|
8944
|
+
{
|
|
8945
|
+
columns,
|
|
8946
|
+
count: Math.max(state.pageSize || 5, 3)
|
|
8947
|
+
}
|
|
8948
|
+
) : state.serverError != null ? /* @__PURE__ */ jsx(TableRow2, { children: /* @__PURE__ */ jsx(
|
|
8949
|
+
TableCell2,
|
|
8950
|
+
{
|
|
8951
|
+
colSpan: columns.length,
|
|
8952
|
+
className: "cls_hazo_ui_table_error_cell p-0",
|
|
8953
|
+
children: /* @__PURE__ */ jsx("div", { className: "cls_hazo_ui_table_error_wrap py-6", children: renderErrorState(props.error, state.serverError) })
|
|
8954
|
+
}
|
|
8955
|
+
) }) : state.displayed.length === 0 ? /* @__PURE__ */ jsx(TableRow2, { children: /* @__PURE__ */ jsx(
|
|
8956
|
+
TableCell2,
|
|
8957
|
+
{
|
|
8958
|
+
colSpan: columns.length,
|
|
8959
|
+
className: "cls_hazo_ui_table_empty_cell p-0",
|
|
8960
|
+
children: noActiveFilters(state.filter) && rows.length === 0 ? /* @__PURE__ */ jsx("div", { className: "cls_hazo_ui_table_empty_wrap py-6", children: typeof props.empty === "string" || props.empty === void 0 ? /* @__PURE__ */ jsx(
|
|
8961
|
+
EmptyState,
|
|
8962
|
+
{
|
|
8963
|
+
title: typeof props.empty === "string" && props.empty || "No items"
|
|
8964
|
+
}
|
|
8965
|
+
) : props.empty }) : /* @__PURE__ */ jsx("div", { className: "cls_hazo_ui_table_no_results_wrap py-6", children: typeof props.noResults === "string" || props.noResults === void 0 ? /* @__PURE__ */ jsx(
|
|
8966
|
+
EmptyState,
|
|
8967
|
+
{
|
|
8968
|
+
title: typeof props.noResults === "string" && props.noResults || "No matches \u2014 adjust your filters"
|
|
8969
|
+
}
|
|
8970
|
+
) : props.noResults })
|
|
8971
|
+
}
|
|
8972
|
+
) }) : state.displayed.map((row, i) => /* @__PURE__ */ jsx(
|
|
8973
|
+
TableRow2,
|
|
8974
|
+
{
|
|
8975
|
+
...buildRowProps(row, i, props.onRowClick),
|
|
8976
|
+
children: columns.map((c) => /* @__PURE__ */ jsx(
|
|
8977
|
+
TableCell2,
|
|
8978
|
+
{
|
|
8979
|
+
className: cn(cellAlignClass(c), c.className),
|
|
8980
|
+
children: renderCell(c, row, i)
|
|
8981
|
+
},
|
|
8982
|
+
c.key
|
|
8983
|
+
))
|
|
8984
|
+
},
|
|
8985
|
+
getRowKey ? getRowKey(row, i) : i
|
|
8986
|
+
)) })
|
|
8987
|
+
] }),
|
|
8988
|
+
state.pageSize > 0 && /* @__PURE__ */ jsx(
|
|
8989
|
+
PaginationFooter,
|
|
8990
|
+
{
|
|
8991
|
+
page: state.page,
|
|
8992
|
+
pageSize: state.pageSize,
|
|
8993
|
+
total: state.totalAfterFilter,
|
|
8994
|
+
onPageChange: state.setPage
|
|
8995
|
+
}
|
|
8996
|
+
)
|
|
8997
|
+
] });
|
|
8998
|
+
}
|
|
8999
|
+
function renderCell(c, row, i) {
|
|
9000
|
+
if (c.cell) return c.cell(row, i);
|
|
9001
|
+
const raw = row[c.key];
|
|
9002
|
+
return formatValue(raw, c.formatter, c.currency, c.locale);
|
|
9003
|
+
}
|
|
9004
|
+
var DEFAULT_NUMBER_LOCALE = "en-US";
|
|
9005
|
+
function formatValue(value, formatter, currency, locale) {
|
|
9006
|
+
if (value === null || value === void 0 || value === "") return "\u2014";
|
|
9007
|
+
const lc = locale ?? DEFAULT_NUMBER_LOCALE;
|
|
9008
|
+
switch (formatter) {
|
|
9009
|
+
case "date": {
|
|
9010
|
+
const d = value instanceof Date ? value : new Date(value);
|
|
9011
|
+
if (Number.isNaN(d.getTime())) return String(value);
|
|
9012
|
+
return format(d, "MMM d, yyyy");
|
|
9013
|
+
}
|
|
9014
|
+
case "number":
|
|
9015
|
+
return new Intl.NumberFormat(lc).format(Number(value));
|
|
9016
|
+
case "currency":
|
|
9017
|
+
return new Intl.NumberFormat(lc, {
|
|
9018
|
+
style: "currency",
|
|
9019
|
+
currency: currency ?? "USD"
|
|
9020
|
+
}).format(Number(value));
|
|
9021
|
+
case "percent":
|
|
9022
|
+
return new Intl.NumberFormat(lc, {
|
|
9023
|
+
style: "percent",
|
|
9024
|
+
maximumFractionDigits: 2
|
|
9025
|
+
}).format(Number(value));
|
|
9026
|
+
default:
|
|
9027
|
+
return String(value);
|
|
9028
|
+
}
|
|
9029
|
+
}
|
|
9030
|
+
function headerAlignClass(c) {
|
|
9031
|
+
switch (c.align) {
|
|
9032
|
+
case "right":
|
|
9033
|
+
return "text-right";
|
|
9034
|
+
case "center":
|
|
9035
|
+
return "text-center";
|
|
9036
|
+
default:
|
|
9037
|
+
return "text-left";
|
|
9038
|
+
}
|
|
9039
|
+
}
|
|
9040
|
+
function cellAlignClass(c) {
|
|
9041
|
+
switch (c.align) {
|
|
9042
|
+
case "right":
|
|
9043
|
+
return "text-right";
|
|
9044
|
+
case "center":
|
|
9045
|
+
return "text-center";
|
|
9046
|
+
default:
|
|
9047
|
+
return "";
|
|
9048
|
+
}
|
|
9049
|
+
}
|
|
9050
|
+
function ariaSortFor(sort, key) {
|
|
9051
|
+
const entry = sort.find((s) => s.key === key);
|
|
9052
|
+
if (!entry) return "none";
|
|
9053
|
+
return entry.dir === "asc" ? "ascending" : "descending";
|
|
9054
|
+
}
|
|
9055
|
+
function deriveSortFields(columns) {
|
|
9056
|
+
return columns.filter((c) => c.sortable).map((c) => ({ value: c.key, label: c.label }));
|
|
9057
|
+
}
|
|
9058
|
+
function deriveFilterFields(columns) {
|
|
9059
|
+
return columns.filter((c) => c.filterType).map((c) => ({
|
|
9060
|
+
value: c.key,
|
|
9061
|
+
label: c.label,
|
|
9062
|
+
type: c.filterType,
|
|
9063
|
+
...c.filterConfig ?? {}
|
|
9064
|
+
}));
|
|
9065
|
+
}
|
|
9066
|
+
function sortToDialogConfig(sort) {
|
|
9067
|
+
return sort.map((s) => ({ field: s.key, direction: s.dir }));
|
|
9068
|
+
}
|
|
9069
|
+
function dialogConfigToSort(configs) {
|
|
9070
|
+
return configs.map((c) => ({ key: c.field, dir: c.direction }));
|
|
9071
|
+
}
|
|
9072
|
+
function PaginationFooter({
|
|
9073
|
+
page,
|
|
9074
|
+
pageSize,
|
|
9075
|
+
total,
|
|
9076
|
+
onPageChange
|
|
9077
|
+
}) {
|
|
9078
|
+
const start = total === 0 ? 0 : page * pageSize + 1;
|
|
9079
|
+
const end = Math.min((page + 1) * pageSize, total);
|
|
9080
|
+
const lastPage = Math.max(0, Math.ceil(total / pageSize) - 1);
|
|
9081
|
+
return /* @__PURE__ */ jsxs("div", { className: "cls_hazo_ui_table_pagination flex items-center justify-between gap-3 pt-2 text-sm", children: [
|
|
9082
|
+
/* @__PURE__ */ jsxs("span", { className: "cls_hazo_ui_table_page_counter text-muted-foreground", children: [
|
|
9083
|
+
"Showing ",
|
|
9084
|
+
start,
|
|
9085
|
+
"\u2013",
|
|
9086
|
+
end,
|
|
9087
|
+
" of ",
|
|
9088
|
+
total
|
|
9089
|
+
] }),
|
|
9090
|
+
/* @__PURE__ */ jsxs("div", { className: "cls_hazo_ui_table_page_buttons flex items-center gap-2", children: [
|
|
9091
|
+
/* @__PURE__ */ jsx(
|
|
9092
|
+
Button,
|
|
9093
|
+
{
|
|
9094
|
+
variant: "outline",
|
|
9095
|
+
size: "sm",
|
|
9096
|
+
onClick: () => onPageChange(Math.max(0, page - 1)),
|
|
9097
|
+
disabled: page === 0,
|
|
9098
|
+
"aria-label": "Previous page",
|
|
9099
|
+
children: "\u2039 Prev"
|
|
9100
|
+
}
|
|
9101
|
+
),
|
|
9102
|
+
/* @__PURE__ */ jsx(
|
|
9103
|
+
Button,
|
|
9104
|
+
{
|
|
9105
|
+
variant: "outline",
|
|
9106
|
+
size: "sm",
|
|
9107
|
+
onClick: () => onPageChange(Math.min(lastPage, page + 1)),
|
|
9108
|
+
disabled: page >= lastPage,
|
|
9109
|
+
"aria-label": "Next page",
|
|
9110
|
+
children: "Next \u203A"
|
|
9111
|
+
}
|
|
9112
|
+
)
|
|
9113
|
+
] })
|
|
9114
|
+
] });
|
|
9115
|
+
}
|
|
9116
|
+
function Toolbar2(props) {
|
|
9117
|
+
const {
|
|
9118
|
+
columns,
|
|
9119
|
+
sort,
|
|
9120
|
+
onSortChange,
|
|
9121
|
+
filter,
|
|
9122
|
+
onSearchChange,
|
|
9123
|
+
onFilterFieldsChange,
|
|
9124
|
+
enableSearch,
|
|
9125
|
+
enableSortDialog,
|
|
9126
|
+
enableFilterDialog,
|
|
9127
|
+
searchPlaceholder
|
|
9128
|
+
} = props;
|
|
9129
|
+
const sortFields = React25.useMemo(
|
|
9130
|
+
() => deriveSortFields(columns),
|
|
9131
|
+
[columns]
|
|
9132
|
+
);
|
|
9133
|
+
const filterFields = React25.useMemo(
|
|
9134
|
+
() => deriveFilterFields(columns),
|
|
9135
|
+
[columns]
|
|
9136
|
+
);
|
|
9137
|
+
const [searchValue, setSearchValue] = React25.useState(
|
|
9138
|
+
filter.search ?? ""
|
|
9139
|
+
);
|
|
9140
|
+
React25.useEffect(() => {
|
|
9141
|
+
setSearchValue(filter.search ?? "");
|
|
9142
|
+
}, [filter.search]);
|
|
9143
|
+
return /* @__PURE__ */ jsxs("div", { className: "cls_hazo_ui_table_toolbar flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between", children: [
|
|
9144
|
+
enableSearch ? /* @__PURE__ */ jsx(
|
|
9145
|
+
Input,
|
|
9146
|
+
{
|
|
9147
|
+
type: "text",
|
|
9148
|
+
value: searchValue,
|
|
9149
|
+
onChange: (e) => {
|
|
9150
|
+
const v = e.target.value;
|
|
9151
|
+
setSearchValue(v);
|
|
9152
|
+
onSearchChange(v);
|
|
9153
|
+
},
|
|
9154
|
+
placeholder: searchPlaceholder ?? "Search...",
|
|
9155
|
+
className: "cls_hazo_ui_table_search w-full sm:max-w-xs"
|
|
9156
|
+
}
|
|
9157
|
+
) : /* @__PURE__ */ jsx("div", {}),
|
|
9158
|
+
/* @__PURE__ */ jsxs("div", { className: "cls_hazo_ui_table_toolbar_right flex items-center gap-2", children: [
|
|
9159
|
+
enableFilterDialog && filterFields.length > 0 && /* @__PURE__ */ jsx(
|
|
9160
|
+
HazoUiMultiFilterDialog,
|
|
9161
|
+
{
|
|
9162
|
+
availableFields: filterFields,
|
|
9163
|
+
initialFilters: filter.fields ?? [],
|
|
9164
|
+
onFilterChange: onFilterFieldsChange
|
|
9165
|
+
}
|
|
9166
|
+
),
|
|
9167
|
+
enableSortDialog && sortFields.length > 0 && /* @__PURE__ */ jsx(
|
|
9168
|
+
HazoUiMultiSortDialog,
|
|
9169
|
+
{
|
|
9170
|
+
availableFields: sortFields,
|
|
9171
|
+
initialSortFields: sortToDialogConfig(sort),
|
|
9172
|
+
onSortChange: (configs) => onSortChange(dialogConfigToSort(configs))
|
|
9173
|
+
}
|
|
9174
|
+
)
|
|
9175
|
+
] })
|
|
9176
|
+
] });
|
|
9177
|
+
}
|
|
9178
|
+
function LoadingRows({
|
|
9179
|
+
columns,
|
|
9180
|
+
count
|
|
9181
|
+
}) {
|
|
9182
|
+
return /* @__PURE__ */ jsx(Fragment$1, { children: Array.from({ length: count }).map((_, rowIdx) => /* @__PURE__ */ jsx(TableRow2, { children: columns.map((c) => /* @__PURE__ */ jsx(TableCell2, { className: cellAlignClass(c), children: /* @__PURE__ */ jsx(
|
|
9183
|
+
SkeletonBar,
|
|
9184
|
+
{
|
|
9185
|
+
className: cn(
|
|
9186
|
+
"cls_hazo_ui_table_skeleton",
|
|
9187
|
+
c.align === "right" ? "w-16 ml-auto" : "w-full"
|
|
9188
|
+
)
|
|
9189
|
+
}
|
|
9190
|
+
) }, c.key)) }, `skeleton-${rowIdx}`)) });
|
|
9191
|
+
}
|
|
9192
|
+
function noActiveFilters(filter) {
|
|
9193
|
+
return !filter.search && (!filter.fields || filter.fields.length === 0);
|
|
9194
|
+
}
|
|
9195
|
+
function renderErrorState(error, serverError) {
|
|
9196
|
+
if (typeof error === "function") return error(serverError);
|
|
9197
|
+
if (error !== void 0 && error !== null) return error;
|
|
9198
|
+
const msg = serverError instanceof Error ? serverError.message : String(serverError);
|
|
9199
|
+
return /* @__PURE__ */ jsx(
|
|
9200
|
+
EmptyState,
|
|
9201
|
+
{
|
|
9202
|
+
title: "Couldn't load data",
|
|
9203
|
+
description: msg || "The data source rejected the request."
|
|
9204
|
+
}
|
|
9205
|
+
);
|
|
9206
|
+
}
|
|
9207
|
+
function buildRowProps(row, index, onRowClick) {
|
|
9208
|
+
if (!onRowClick) return {};
|
|
9209
|
+
return {
|
|
9210
|
+
role: "button",
|
|
9211
|
+
tabIndex: 0,
|
|
9212
|
+
className: "cls_hazo_ui_table_row_clickable cursor-pointer",
|
|
9213
|
+
onClick: () => onRowClick(row, index),
|
|
9214
|
+
onKeyDown: (e) => {
|
|
9215
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
9216
|
+
e.preventDefault();
|
|
9217
|
+
onRowClick(row, index);
|
|
9218
|
+
}
|
|
9219
|
+
}
|
|
9220
|
+
};
|
|
9221
|
+
}
|
|
9222
|
+
function SortIndicator({
|
|
9223
|
+
sort,
|
|
9224
|
+
columnKey
|
|
9225
|
+
}) {
|
|
9226
|
+
const idx = sort.findIndex((s) => s.key === columnKey);
|
|
9227
|
+
if (idx === -1) {
|
|
9228
|
+
return /* @__PURE__ */ jsx(ChevronsUpDown, { className: "cls_hazo_ui_table_sort_idle h-3.5 w-3.5 opacity-30" });
|
|
9229
|
+
}
|
|
9230
|
+
const entry = sort[idx];
|
|
9231
|
+
return /* @__PURE__ */ jsxs("span", { className: "cls_hazo_ui_table_sort_active inline-flex items-center gap-0.5", children: [
|
|
9232
|
+
entry.dir === "asc" ? /* @__PURE__ */ jsx(ChevronUp, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx(ChevronDown, { className: "h-3.5 w-3.5" }),
|
|
9233
|
+
sort.length > 1 && /* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium", children: idx + 1 })
|
|
9234
|
+
] });
|
|
9235
|
+
}
|
|
7593
9236
|
|
|
7594
|
-
export { ANIMATION_PRESETS, Accordion, AccordionContent, AccordionItem, AccordionTrigger, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, Calendar, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Collapsible, CollapsibleContent2 as CollapsibleContent, CollapsibleTrigger2 as CollapsibleTrigger, CommandNodeExtension, CommandPill, CommandPopover, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, ErrorBanner, ErrorPage, HazoUiConfirmDialog, HazoUiDialog, DialogClose as HazoUiDialogClose, DialogContent as HazoUiDialogContent, DialogDescription as HazoUiDialogDescription, DialogFooter as HazoUiDialogFooter, DialogHeader as HazoUiDialogHeader, DialogOverlay as HazoUiDialogOverlay, DialogPortal as HazoUiDialogPortal, Dialog as HazoUiDialogRoot, DialogTitle as HazoUiDialogTitle, DialogTrigger as HazoUiDialogTrigger, HazoUiFlexInput, HazoUiFlexRadio, HazoUiMultiFilterDialog, HazoUiMultiSortDialog, HazoUiPillRadio, HazoUiRte, HazoUiTextarea, HazoUiTextbox, HazoUiToaster, HoverCard, HoverCardContent, HoverCardTrigger, Input,
|
|
9237
|
+
export { ANIMATION_PRESETS, Accordion, AccordionContent, AccordionItem, AccordionTrigger, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, Calendar, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Collapsible, CollapsibleContent2 as CollapsibleContent, CollapsibleTrigger2 as CollapsibleTrigger, CommandNodeExtension, CommandPill, CommandPopover, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, ErrorBanner, ErrorPage, HazoUiConfirmDialog, HazoUiDialog, DialogClose as HazoUiDialogClose, DialogContent as HazoUiDialogContent, DialogDescription as HazoUiDialogDescription, DialogFooter as HazoUiDialogFooter, DialogHeader as HazoUiDialogHeader, DialogOverlay as HazoUiDialogOverlay, DialogPortal as HazoUiDialogPortal, Dialog as HazoUiDialogRoot, DialogTitle as HazoUiDialogTitle, DialogTrigger as HazoUiDialogTrigger, HazoUiFlexInput, HazoUiFlexRadio, HazoUiKanban, HazoUiKanbanFilter, HazoUiMultiFilterDialog, HazoUiMultiSortDialog, HazoUiPillRadio, HazoUiRte, HazoUiTable, HazoUiTextarea, HazoUiTextbox, HazoUiToaster, HoverCard, HoverCardContent, HoverCardTrigger, Input, Label3 as Label, LoadingTimeout, Popover, PopoverContent, PopoverTrigger, ProgressiveImage, RadioGroup, RadioGroupItem, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator3 as Separator, Command as ShadcnCommand, CommandEmpty as ShadcnCommandEmpty, CommandGroup as ShadcnCommandGroup, CommandInput as ShadcnCommandInput, CommandItem as ShadcnCommandItem, CommandList as ShadcnCommandList, Skeleton, SkeletonBar, SkeletonCircle, SkeletonGroup, SkeletonRect, Spinner, Switch, Table2 as Table, TableBody, TableCaption, TableCell2 as TableCell, TableFooter, TableHead, TableHeader2 as TableHeader, TableRow2 as TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, applyKanbanFilter, buttonGroupVariants, create_command_suggestion_extension, errorToast, get_hazo_ui_config, parse_commands_from_text, reset_hazo_ui_config, resolve_animation_classes, set_hazo_ui_config, successToast, text_to_tiptap_content, toggleVariants, useErrorDisplay, useLoadingState, useMediaQuery };
|
|
7595
9238
|
//# sourceMappingURL=index.js.map
|
|
7596
9239
|
//# sourceMappingURL=index.js.map
|