@fayz-ai/ui 0.22.0 → 0.24.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/dist/analytics/AnalyticsCard.d.ts.map +1 -1
- package/dist/analytics/AnalyticsControls.d.ts.map +1 -1
- package/dist/analytics/DateRangeControl.d.ts +14 -0
- package/dist/analytics/DateRangeControl.d.ts.map +1 -0
- package/dist/analytics/StatementTable.d.ts +22 -0
- package/dist/analytics/StatementTable.d.ts.map +1 -0
- package/dist/analytics/context.d.ts +8 -0
- package/dist/analytics/context.d.ts.map +1 -1
- package/dist/analytics/derive.d.ts +13 -0
- package/dist/analytics/derive.d.ts.map +1 -1
- package/dist/analytics/index.d.ts +7 -1
- package/dist/analytics/index.d.ts.map +1 -1
- package/dist/analytics/statement.d.ts +58 -0
- package/dist/analytics/statement.d.ts.map +1 -0
- package/dist/{chunk-E44WOPCR.js → chunk-HO2P2XB4.js} +428 -58
- package/dist/chunk-HO2P2XB4.js.map +1 -0
- package/dist/{chunk-7G3O54CC.js → chunk-L4TXDKMN.js} +5 -5
- package/dist/chunk-L4TXDKMN.js.map +1 -0
- package/dist/{chunk-ZSOT7KTE.js → chunk-NXFVYZY7.js} +467 -405
- package/dist/chunk-NXFVYZY7.js.map +1 -0
- package/dist/{chunk-DHNUZF2X.js → chunk-OWN3GFDG.js} +4 -3
- package/dist/chunk-OWN3GFDG.js.map +1 -0
- package/dist/{chunk-PQUS22JE.js → chunk-RRNMNFLF.js} +483 -794
- package/dist/chunk-RRNMNFLF.js.map +1 -0
- package/dist/chunk-UP7WVKSU.js +631 -0
- package/dist/chunk-UP7WVKSU.js.map +1 -0
- package/dist/{chunk-SUSW4LSW.js → chunk-XKFYX3DG.js} +5 -5
- package/dist/{chunk-SUSW4LSW.js.map → chunk-XKFYX3DG.js.map} +1 -1
- package/dist/dashboard/index.js +4 -4
- package/dist/icons.js +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +672 -87
- package/dist/index.js.map +1 -1
- package/dist/layout/AppShell.d.ts +7 -1
- package/dist/layout/AppShell.d.ts.map +1 -1
- package/dist/layout/ShellSearch.d.ts +53 -0
- package/dist/layout/ShellSearch.d.ts.map +1 -0
- package/dist/layout/Sidebar.d.ts +10 -6
- package/dist/layout/Sidebar.d.ts.map +1 -1
- package/dist/layout/Takeover.d.ts.map +1 -1
- package/dist/layout/index.d.ts +1 -0
- package/dist/layout/index.d.ts.map +1 -1
- package/dist/layout/index.js +4 -4
- package/dist/primitives/data-table.d.ts.map +1 -1
- package/dist/primitives/date-range-chip.d.ts +32 -0
- package/dist/primitives/date-range-chip.d.ts.map +1 -0
- package/dist/primitives/header-tabs.d.ts.map +1 -1
- package/dist/primitives/index.d.ts +2 -1
- package/dist/primitives/index.d.ts.map +1 -1
- package/dist/primitives/index.js +5 -5
- package/dist/primitives/list-chrome.d.ts +22 -1
- package/dist/primitives/list-chrome.d.ts.map +1 -1
- package/dist/primitives/list-view.d.ts +56 -1
- package/dist/primitives/list-view.d.ts.map +1 -1
- package/dist/primitives/modal.d.ts +2 -0
- package/dist/primitives/modal.d.ts.map +1 -1
- package/dist/primitives/multi-select.d.ts +18 -1
- package/dist/primitives/multi-select.d.ts.map +1 -1
- package/dist/primitives/page-actions.d.ts +14 -0
- package/dist/primitives/page-actions.d.ts.map +1 -1
- package/dist/primitives/page-toolbar.d.ts +16 -1
- package/dist/primitives/page-toolbar.d.ts.map +1 -1
- package/dist/primitives/segmented-control.d.ts.map +1 -1
- package/dist/stores/layout.store.d.ts +20 -1
- package/dist/stores/layout.store.d.ts.map +1 -1
- package/dist/styles.css +58 -0
- package/package.json +2 -2
- package/dist/chunk-7G3O54CC.js.map +0 -1
- package/dist/chunk-DHNUZF2X.js.map +0 -1
- package/dist/chunk-E44WOPCR.js.map +0 -1
- package/dist/chunk-HKGTF2YA.js +0 -117
- package/dist/chunk-HKGTF2YA.js.map +0 -1
- package/dist/chunk-PQUS22JE.js.map +0 -1
- package/dist/chunk-ZSOT7KTE.js.map +0 -1
|
@@ -1,25 +1,24 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { PageHeaderActions, SegmentedControl } from './chunk-UP7WVKSU.js';
|
|
2
|
+
import { Hint, Dropdown, DropdownTrigger, DropdownContent, DropdownSeparator, DropdownItem, Card, PageActionBar, DataTable, Popover, PopoverTrigger, PopoverContent, Checkbox, useIsWide } from './chunk-HO2P2XB4.js';
|
|
3
|
+
import { useSaveBarVisible, useCrossModuleBack, useBackHandler } from './chunk-RRNMNFLF.js';
|
|
3
4
|
import { cn, Button } from './chunk-OKZ6WQB3.js';
|
|
4
|
-
import * as
|
|
5
|
-
import
|
|
5
|
+
import * as React15 from 'react';
|
|
6
|
+
import React15__default, { useState, useRef, useEffect, useMemo, useCallback } from 'react';
|
|
6
7
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
7
8
|
import { cva } from 'class-variance-authority';
|
|
8
9
|
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
9
|
-
import { X, ChevronDown, ChevronUp, Check, ArrowLeft, MoreHorizontal,
|
|
10
|
+
import { X, ChevronDown, ChevronUp, Check, ArrowLeft, MoreHorizontal, Search, ChevronsLeft, ChevronLeft, ChevronRight, ChevronsRight, ImageIcon, RefreshCw, Clock, Plus, Download, Calendar, Loader2, CalendarDays, SlidersHorizontal } from 'lucide-react';
|
|
10
11
|
import * as SelectPrimitive from '@radix-ui/react-select';
|
|
11
12
|
import { Toaster } from 'sonner';
|
|
12
13
|
export { toast } from 'sonner';
|
|
13
14
|
import * as TabsPrimitive from '@radix-ui/react-tabs';
|
|
14
15
|
import * as SeparatorPrimitive from '@radix-ui/react-separator';
|
|
15
|
-
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
|
|
16
|
-
import { createPortal } from 'react-dom';
|
|
17
16
|
import { useTranslation, getCountry, unmaskPhone, maskPhone, getCurrentLocale } from '@fayz-ai/core';
|
|
18
|
-
import
|
|
17
|
+
import { createPortal } from 'react-dom';
|
|
19
18
|
|
|
20
|
-
var Input =
|
|
19
|
+
var Input = React15.forwardRef(
|
|
21
20
|
({ className, type, error, description, id, ...props }, ref) => {
|
|
22
|
-
const inputId = id ??
|
|
21
|
+
const inputId = id ?? React15.useId();
|
|
23
22
|
const descriptionId = description ? `${inputId}-description` : void 0;
|
|
24
23
|
const errorId = error ? `${inputId}-error` : void 0;
|
|
25
24
|
return /* @__PURE__ */ jsxs("div", { className: "w-full", children: [
|
|
@@ -101,13 +100,18 @@ var SIZE_MAP = {
|
|
|
101
100
|
xl: "sm:max-w-xl",
|
|
102
101
|
"2xl": "sm:max-w-2xl",
|
|
103
102
|
"3xl": "sm:max-w-3xl",
|
|
103
|
+
// Duas colunas de trabalho lado a lado (ficha + linha do tempo) não cabem em
|
|
104
|
+
// 3xl: a coluna da direita fica com 20rem e o texto de cada anotação quebra
|
|
105
|
+
// a cada quatro palavras.
|
|
106
|
+
"4xl": "sm:max-w-4xl",
|
|
107
|
+
"5xl": "sm:max-w-5xl",
|
|
104
108
|
full: "sm:max-w-[calc(100vw-4rem)]"
|
|
105
109
|
};
|
|
106
110
|
var Modal = DialogPrimitive.Root;
|
|
107
111
|
var ModalTrigger = DialogPrimitive.Trigger;
|
|
108
112
|
var ModalClose = DialogPrimitive.Close;
|
|
109
113
|
var ModalPortal = DialogPrimitive.Portal;
|
|
110
|
-
var ModalOverlay =
|
|
114
|
+
var ModalOverlay = React15.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
111
115
|
DialogPrimitive.Overlay,
|
|
112
116
|
{
|
|
113
117
|
ref,
|
|
@@ -120,7 +124,7 @@ var ModalOverlay = React18.forwardRef(({ className, ...props }, ref) => /* @__PU
|
|
|
120
124
|
}
|
|
121
125
|
));
|
|
122
126
|
ModalOverlay.displayName = "ModalOverlay";
|
|
123
|
-
var ModalContent =
|
|
127
|
+
var ModalContent = React15.forwardRef(({ className, children, size = "lg", hideClose, noPadding, onPointerDownOutside, onInteractOutside, onCloseAutoFocus, ...props }, ref) => /* @__PURE__ */ jsx(ModalPortal, { children: /* @__PURE__ */ jsx(ModalOverlay, { children: /* @__PURE__ */ jsxs(
|
|
124
128
|
DialogPrimitive.Content,
|
|
125
129
|
{
|
|
126
130
|
ref,
|
|
@@ -175,14 +179,14 @@ function ModalBody({ className, ...props }) {
|
|
|
175
179
|
function ModalFooter({ className, ...props }) {
|
|
176
180
|
return /* @__PURE__ */ jsx("div", { className: cn("mt-auto flex flex-col-reverse gap-2 sm:mt-0 sm:flex-row sm:justify-end sm:gap-0 sm:space-x-2 shrink-0", className), ...props });
|
|
177
181
|
}
|
|
178
|
-
var ModalTitle =
|
|
182
|
+
var ModalTitle = React15.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Title, { ref, className: cn("text-lg font-semibold leading-none tracking-tight", className), ...props }));
|
|
179
183
|
ModalTitle.displayName = "ModalTitle";
|
|
180
|
-
var ModalDescription =
|
|
184
|
+
var ModalDescription = React15.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Description, { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
|
|
181
185
|
ModalDescription.displayName = "ModalDescription";
|
|
182
186
|
var Select = SelectPrimitive.Root;
|
|
183
187
|
var SelectGroup = SelectPrimitive.Group;
|
|
184
188
|
var SelectValue = SelectPrimitive.Value;
|
|
185
|
-
var SelectTrigger =
|
|
189
|
+
var SelectTrigger = React15.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
186
190
|
SelectPrimitive.Trigger,
|
|
187
191
|
{
|
|
188
192
|
ref,
|
|
@@ -198,7 +202,7 @@ var SelectTrigger = React18.forwardRef(({ className, children, ...props }, ref)
|
|
|
198
202
|
}
|
|
199
203
|
));
|
|
200
204
|
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
|
|
201
|
-
var SelectScrollUpButton =
|
|
205
|
+
var SelectScrollUpButton = React15.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
202
206
|
SelectPrimitive.ScrollUpButton,
|
|
203
207
|
{
|
|
204
208
|
ref,
|
|
@@ -211,7 +215,7 @@ var SelectScrollUpButton = React18.forwardRef(({ className, ...props }, ref) =>
|
|
|
211
215
|
}
|
|
212
216
|
));
|
|
213
217
|
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
|
|
214
|
-
var SelectScrollDownButton =
|
|
218
|
+
var SelectScrollDownButton = React15.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
215
219
|
SelectPrimitive.ScrollDownButton,
|
|
216
220
|
{
|
|
217
221
|
ref,
|
|
@@ -224,7 +228,7 @@ var SelectScrollDownButton = React18.forwardRef(({ className, ...props }, ref) =
|
|
|
224
228
|
}
|
|
225
229
|
));
|
|
226
230
|
SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
|
|
227
|
-
var SelectContent =
|
|
231
|
+
var SelectContent = React15.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
|
|
228
232
|
SelectPrimitive.Content,
|
|
229
233
|
{
|
|
230
234
|
ref,
|
|
@@ -252,7 +256,7 @@ var SelectContent = React18.forwardRef(({ className, children, position = "poppe
|
|
|
252
256
|
}
|
|
253
257
|
) }));
|
|
254
258
|
SelectContent.displayName = SelectPrimitive.Content.displayName;
|
|
255
|
-
var SelectLabel =
|
|
259
|
+
var SelectLabel = React15.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
256
260
|
SelectPrimitive.Label,
|
|
257
261
|
{
|
|
258
262
|
ref,
|
|
@@ -264,7 +268,7 @@ var SelectLabel = React18.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
264
268
|
}
|
|
265
269
|
));
|
|
266
270
|
SelectLabel.displayName = SelectPrimitive.Label.displayName;
|
|
267
|
-
var SelectItem =
|
|
271
|
+
var SelectItem = React15.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
268
272
|
SelectPrimitive.Item,
|
|
269
273
|
{
|
|
270
274
|
ref,
|
|
@@ -280,7 +284,7 @@ var SelectItem = React18.forwardRef(({ className, children, ...props }, ref) =>
|
|
|
280
284
|
}
|
|
281
285
|
));
|
|
282
286
|
SelectItem.displayName = SelectPrimitive.Item.displayName;
|
|
283
|
-
var SelectSeparator =
|
|
287
|
+
var SelectSeparator = React15.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
284
288
|
SelectPrimitive.Separator,
|
|
285
289
|
{
|
|
286
290
|
ref,
|
|
@@ -318,7 +322,7 @@ function ToastProvider({
|
|
|
318
322
|
);
|
|
319
323
|
}
|
|
320
324
|
var Tabs = TabsPrimitive.Root;
|
|
321
|
-
var TabsList =
|
|
325
|
+
var TabsList = React15.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
322
326
|
TabsPrimitive.List,
|
|
323
327
|
{
|
|
324
328
|
ref,
|
|
@@ -332,7 +336,7 @@ var TabsList = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__
|
|
|
332
336
|
}
|
|
333
337
|
));
|
|
334
338
|
TabsList.displayName = TabsPrimitive.List.displayName;
|
|
335
|
-
var TabsTrigger =
|
|
339
|
+
var TabsTrigger = React15.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
336
340
|
TabsPrimitive.Trigger,
|
|
337
341
|
{
|
|
338
342
|
ref,
|
|
@@ -344,7 +348,7 @@ var TabsTrigger = React18.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
344
348
|
}
|
|
345
349
|
));
|
|
346
350
|
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
|
|
347
|
-
var TabsContent =
|
|
351
|
+
var TabsContent = React15.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
348
352
|
TabsPrimitive.Content,
|
|
349
353
|
{
|
|
350
354
|
ref,
|
|
@@ -356,7 +360,7 @@ var TabsContent = React18.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
356
360
|
}
|
|
357
361
|
));
|
|
358
362
|
TabsContent.displayName = TabsPrimitive.Content.displayName;
|
|
359
|
-
var Separator2 =
|
|
363
|
+
var Separator2 = React15.forwardRef(
|
|
360
364
|
({ className, orientation = "horizontal", decorative = true, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
361
365
|
SeparatorPrimitive.Root,
|
|
362
366
|
{
|
|
@@ -407,7 +411,7 @@ function formatPhone(digits, fallback, countryCode) {
|
|
|
407
411
|
const tail = rest.length === 9 ? rest.slice(5) : rest.slice(4);
|
|
408
412
|
return `+55 (${ddd}) ${head}-${tail}`;
|
|
409
413
|
}
|
|
410
|
-
var PhoneLink =
|
|
414
|
+
var PhoneLink = React15.forwardRef(
|
|
411
415
|
({ phone, message, countryCode, raw, className, children, ...props }, ref) => {
|
|
412
416
|
const { e164, display } = normalizePhone(phone, countryCode);
|
|
413
417
|
const label = children ?? (raw ? phone ?? "" : display);
|
|
@@ -467,235 +471,6 @@ function Breadcrumb({ parent, current, onBack }) {
|
|
|
467
471
|
] })
|
|
468
472
|
] });
|
|
469
473
|
}
|
|
470
|
-
var TooltipProvider = TooltipPrimitive.Provider;
|
|
471
|
-
var Tooltip = TooltipPrimitive.Root;
|
|
472
|
-
var TooltipTrigger = TooltipPrimitive.Trigger;
|
|
473
|
-
var TooltipContent = React18.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
474
|
-
TooltipPrimitive.Content,
|
|
475
|
-
{
|
|
476
|
-
ref,
|
|
477
|
-
sideOffset,
|
|
478
|
-
className: cn(
|
|
479
|
-
"fayz-glass-surface z-[120] overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
|
480
|
-
className
|
|
481
|
-
),
|
|
482
|
-
...props
|
|
483
|
-
}
|
|
484
|
-
));
|
|
485
|
-
TooltipContent.displayName = TooltipPrimitive.Content.displayName;
|
|
486
|
-
var Hint = React18.forwardRef(function Hint2({ label, children, side = "top", delayDuration = 0, ...rest }, ref) {
|
|
487
|
-
if (!label) return React18.cloneElement(children, { ...rest, ref });
|
|
488
|
-
return /* @__PURE__ */ jsx(TooltipPrimitive.Provider, { delayDuration, children: /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
489
|
-
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, ...rest, ref, children }),
|
|
490
|
-
/* @__PURE__ */ jsx(TooltipContent, { side, className: "px-2 py-1 text-xs font-medium", children: label })
|
|
491
|
-
] }) });
|
|
492
|
-
});
|
|
493
|
-
function iconOf(action, className) {
|
|
494
|
-
const Icon2 = action.icon;
|
|
495
|
-
return Icon2 ? /* @__PURE__ */ jsx(Icon2, { className }) : null;
|
|
496
|
-
}
|
|
497
|
-
function PageActionBar({ actions, className }) {
|
|
498
|
-
const wide = useIsWide();
|
|
499
|
-
const visible = actions.filter((a) => !a.hidden);
|
|
500
|
-
if (visible.length === 0) return null;
|
|
501
|
-
if (!wide) {
|
|
502
|
-
const usable = visible.filter((a) => !a.desktopOnly);
|
|
503
|
-
return usable.length > 0 ? /* @__PURE__ */ jsx(PageActionFab, { actions: usable }) : null;
|
|
504
|
-
}
|
|
505
|
-
let seenPrimary = false;
|
|
506
|
-
const primary = [];
|
|
507
|
-
const secondary = [];
|
|
508
|
-
const utility = [];
|
|
509
|
-
const danger = [];
|
|
510
|
-
for (const a of visible) {
|
|
511
|
-
const intent = a.intent ?? "secondary";
|
|
512
|
-
if (intent === "primary" && !seenPrimary) {
|
|
513
|
-
seenPrimary = true;
|
|
514
|
-
primary.push(a);
|
|
515
|
-
continue;
|
|
516
|
-
}
|
|
517
|
-
if (intent === "danger") {
|
|
518
|
-
danger.push(a);
|
|
519
|
-
continue;
|
|
520
|
-
}
|
|
521
|
-
if (intent === "utility") {
|
|
522
|
-
utility.push(a);
|
|
523
|
-
continue;
|
|
524
|
-
}
|
|
525
|
-
secondary.push(a);
|
|
526
|
-
}
|
|
527
|
-
const head = primary[0];
|
|
528
|
-
const menu = [...secondary, ...danger];
|
|
529
|
-
return /* @__PURE__ */ jsxs("div", { className: cn("flex shrink-0 items-center gap-2", className), children: [
|
|
530
|
-
utility.map((a) => (
|
|
531
|
-
// Um botão só de ícone não diz o que faz. `title=` parecia resolver e
|
|
532
|
-
// não resolve: espera ~1s que ninguém controla, sai na pintura do
|
|
533
|
-
// sistema operacional, nunca aparece no toque e vários leitores de tela
|
|
534
|
-
// pulam. Hint é o tooltip do design system, e o texto é ANUNCIADO.
|
|
535
|
-
/* @__PURE__ */ jsx(Hint, { label: a.label, children: /* @__PURE__ */ jsx(
|
|
536
|
-
Button,
|
|
537
|
-
{
|
|
538
|
-
variant: "outline",
|
|
539
|
-
size: "icon",
|
|
540
|
-
onClick: () => void a.onSelect(),
|
|
541
|
-
disabled: a.disabled,
|
|
542
|
-
"aria-label": a.label,
|
|
543
|
-
"data-testid": a.testId,
|
|
544
|
-
"data-tour": `action.${a.id}`,
|
|
545
|
-
children: iconOf(a, "h-4 w-4")
|
|
546
|
-
}
|
|
547
|
-
) }, a.id)
|
|
548
|
-
)),
|
|
549
|
-
head && menu.length === 0 && /* @__PURE__ */ jsxs(Button, { onClick: () => void head.onSelect(), disabled: head.disabled, "data-testid": head.testId, "data-tour": `action.${head.id}`, children: [
|
|
550
|
-
iconOf(head, "mr-1.5 h-4 w-4"),
|
|
551
|
-
head.label
|
|
552
|
-
] }),
|
|
553
|
-
head && menu.length > 0 && /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
|
|
554
|
-
/* @__PURE__ */ jsxs(Button, { className: "rounded-r-none", onClick: () => void head.onSelect(), disabled: head.disabled, "data-testid": head.testId, "data-tour": `action.${head.id}`, children: [
|
|
555
|
-
iconOf(head, "mr-1.5 h-4 w-4"),
|
|
556
|
-
head.label
|
|
557
|
-
] }),
|
|
558
|
-
/* @__PURE__ */ jsxs(Dropdown, { children: [
|
|
559
|
-
/* @__PURE__ */ jsx(DropdownTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Hint, { label: `${head.label}\u2026`, children: /* @__PURE__ */ jsx(
|
|
560
|
-
Button,
|
|
561
|
-
{
|
|
562
|
-
className: "-ml-px rounded-l-none px-2",
|
|
563
|
-
"aria-label": `${head.label}\u2026`,
|
|
564
|
-
"data-tour": menu.map((a) => `action.${a.id}`).join(" "),
|
|
565
|
-
children: /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4" })
|
|
566
|
-
}
|
|
567
|
-
) }) }),
|
|
568
|
-
/* @__PURE__ */ jsx(DropdownContent, { align: "end", className: "w-56", children: /* @__PURE__ */ jsx(ActionItems, { actions: menu }) })
|
|
569
|
-
] })
|
|
570
|
-
] }),
|
|
571
|
-
!head && menu.length > 0 && /* @__PURE__ */ jsxs(Dropdown, { children: [
|
|
572
|
-
/* @__PURE__ */ jsx(DropdownTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Hint, { label: "A\xE7\xF5es", children: /* @__PURE__ */ jsx(Button, { variant: "outline", size: "icon", "aria-label": "A\xE7\xF5es", children: /* @__PURE__ */ jsx(MoreHorizontal, { className: "h-4 w-4" }) }) }) }),
|
|
573
|
-
/* @__PURE__ */ jsx(DropdownContent, { align: "end", className: "w-56", children: /* @__PURE__ */ jsx(ActionItems, { actions: menu }) })
|
|
574
|
-
] })
|
|
575
|
-
] });
|
|
576
|
-
}
|
|
577
|
-
function ActionItems({ actions, stagger }) {
|
|
578
|
-
const out = [];
|
|
579
|
-
actions.forEach((a, i) => {
|
|
580
|
-
const isDanger = a.intent === "danger";
|
|
581
|
-
const prevSafe = i > 0 && actions[i - 1].intent !== "danger";
|
|
582
|
-
if (isDanger && prevSafe) out.push(/* @__PURE__ */ jsx(DropdownSeparator, {}, `${a.id}-sep`));
|
|
583
|
-
out.push(
|
|
584
|
-
/* @__PURE__ */ jsxs(
|
|
585
|
-
DropdownItem,
|
|
586
|
-
{
|
|
587
|
-
disabled: a.disabled,
|
|
588
|
-
onSelect: () => void a.onSelect(),
|
|
589
|
-
"data-testid": a.testId,
|
|
590
|
-
style: stagger ? { ["--i"]: i } : void 0,
|
|
591
|
-
className: cn("gap-2", stagger && "fz-fab-item", isDanger && "text-destructive focus:text-destructive"),
|
|
592
|
-
children: [
|
|
593
|
-
iconOf(a, "h-4 w-4 shrink-0"),
|
|
594
|
-
/* @__PURE__ */ jsxs("span", { className: "min-w-0", children: [
|
|
595
|
-
/* @__PURE__ */ jsx("span", { className: "block truncate", children: a.label }),
|
|
596
|
-
a.description && /* @__PURE__ */ jsx("span", { className: "block truncate text-xs text-muted-foreground", children: a.description })
|
|
597
|
-
] })
|
|
598
|
-
]
|
|
599
|
-
},
|
|
600
|
-
a.id
|
|
601
|
-
)
|
|
602
|
-
);
|
|
603
|
-
});
|
|
604
|
-
return /* @__PURE__ */ jsx(Fragment, { children: out });
|
|
605
|
-
}
|
|
606
|
-
function PageActionFab({ actions }) {
|
|
607
|
-
const byIntent = (i) => actions.filter((a) => (a.intent ?? "secondary") === i);
|
|
608
|
-
const utility = byIntent("utility");
|
|
609
|
-
const main = [...byIntent("primary"), ...byIntent("secondary"), ...byIntent("danger")];
|
|
610
|
-
if (main.length === 0) return /* @__PURE__ */ jsx(FabButton, { actions: utility, tone: "neutral" });
|
|
611
|
-
const isCreate = main.every((a) => a.creates ?? a.icon === Plus);
|
|
612
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
613
|
-
utility.length > 0 && /* @__PURE__ */ jsx(FabButton, { actions: utility, tone: "neutral", mini: true }),
|
|
614
|
-
/* @__PURE__ */ jsx(FabButton, { actions: main, tone: isCreate ? "primary" : "neutral" })
|
|
615
|
-
] });
|
|
616
|
-
}
|
|
617
|
-
function useScrim(open) {
|
|
618
|
-
const [mounted, setMounted] = React18.useState(open);
|
|
619
|
-
const [visible, setVisible] = React18.useState(open);
|
|
620
|
-
React18.useEffect(() => {
|
|
621
|
-
if (open) {
|
|
622
|
-
setMounted(true);
|
|
623
|
-
const frame = requestAnimationFrame(() => setVisible(true));
|
|
624
|
-
return () => cancelAnimationFrame(frame);
|
|
625
|
-
}
|
|
626
|
-
setVisible(false);
|
|
627
|
-
const timer = window.setTimeout(() => setMounted(false), SCRIM_MS);
|
|
628
|
-
return () => window.clearTimeout(timer);
|
|
629
|
-
}, [open]);
|
|
630
|
-
return { mounted, visible };
|
|
631
|
-
}
|
|
632
|
-
var SCRIM_MS = 200;
|
|
633
|
-
function FabButton({ actions, tone, mini }) {
|
|
634
|
-
const [open, setOpen] = React18.useState(false);
|
|
635
|
-
const scrim = useScrim(open);
|
|
636
|
-
if (actions.length === 0) return null;
|
|
637
|
-
const isCreate = tone === "primary";
|
|
638
|
-
const FabIcon = isCreate ? Plus : MoreVertical;
|
|
639
|
-
const style = {
|
|
640
|
-
bottom: mini ? "calc(var(--fz-bottom-bar, 0px) + 4.75rem)" : "calc(var(--fz-bottom-bar, 0px) + 1rem)"
|
|
641
|
-
};
|
|
642
|
-
const shell = cn(
|
|
643
|
-
"fz-tap fixed z-40 flex items-center justify-center rounded-full",
|
|
644
|
-
"transition-transform active:scale-95 md:hidden",
|
|
645
|
-
// Centred on the main circle's column, so the two read as one stack.
|
|
646
|
-
mini ? "right-5 h-12 w-12" : "right-4 h-14 w-14",
|
|
647
|
-
isCreate ? "bg-primary text-primary-foreground shadow-lg shadow-primary/30 ring-4 ring-background" : "bg-card text-foreground shadow-lg ring-1 ring-border"
|
|
648
|
-
);
|
|
649
|
-
if (actions.length === 1) {
|
|
650
|
-
const only = actions[0];
|
|
651
|
-
const Icon2 = only.icon ?? FabIcon;
|
|
652
|
-
return /* @__PURE__ */ jsx(
|
|
653
|
-
"button",
|
|
654
|
-
{
|
|
655
|
-
type: "button",
|
|
656
|
-
style,
|
|
657
|
-
className: shell,
|
|
658
|
-
onClick: () => void only.onSelect(),
|
|
659
|
-
disabled: only.disabled,
|
|
660
|
-
"aria-label": only.label,
|
|
661
|
-
"data-testid": only.testId,
|
|
662
|
-
children: /* @__PURE__ */ jsx(Icon2, { className: mini ? "h-5 w-5" : "h-6 w-6" })
|
|
663
|
-
}
|
|
664
|
-
);
|
|
665
|
-
}
|
|
666
|
-
return /* @__PURE__ */ jsxs(Dropdown, { open, onOpenChange: setOpen, children: [
|
|
667
|
-
scrim.mounted && typeof document !== "undefined" && createPortal(
|
|
668
|
-
/* @__PURE__ */ jsx(
|
|
669
|
-
"div",
|
|
670
|
-
{
|
|
671
|
-
"aria-hidden": true,
|
|
672
|
-
onClick: () => setOpen(false),
|
|
673
|
-
className: cn(
|
|
674
|
-
"fixed inset-0 z-[100] bg-foreground/40 transition-opacity duration-200 md:hidden",
|
|
675
|
-
"motion-reduce:transition-none",
|
|
676
|
-
scrim.visible ? "opacity-100" : "opacity-0"
|
|
677
|
-
)
|
|
678
|
-
}
|
|
679
|
-
),
|
|
680
|
-
document.body
|
|
681
|
-
),
|
|
682
|
-
/* @__PURE__ */ jsx(DropdownTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
683
|
-
"button",
|
|
684
|
-
{
|
|
685
|
-
type: "button",
|
|
686
|
-
style,
|
|
687
|
-
className: cn(shell, open && "z-[105]", isCreate && "fz-fab-trigger"),
|
|
688
|
-
"aria-label": actionsMenuLabel,
|
|
689
|
-
children: /* @__PURE__ */ jsx(FabIcon, { className: mini ? "h-5 w-5" : "h-6 w-6" })
|
|
690
|
-
}
|
|
691
|
-
) }),
|
|
692
|
-
/* @__PURE__ */ jsx(DropdownContent, { side: "top", align: "end", sideOffset: 12, className: "fz-fab-menu w-60 md:hidden", children: /* @__PURE__ */ jsx(ActionItems, { actions, stagger: true }) })
|
|
693
|
-
] });
|
|
694
|
-
}
|
|
695
|
-
var actionsMenuLabel = "A\xE7\xF5es";
|
|
696
|
-
function setActionsMenuLabel(label) {
|
|
697
|
-
actionsMenuLabel = label;
|
|
698
|
-
}
|
|
699
474
|
var INLINE_LIMIT = 2;
|
|
700
475
|
function RowActions({
|
|
701
476
|
actions,
|
|
@@ -744,7 +519,7 @@ function RowActions({
|
|
|
744
519
|
const Icon2 = a.icon;
|
|
745
520
|
const isDanger = a.intent === "danger";
|
|
746
521
|
const prevSafe = i > 0 && overflow[i - 1].intent !== "danger";
|
|
747
|
-
return /* @__PURE__ */ jsxs(
|
|
522
|
+
return /* @__PURE__ */ jsxs(React15.Fragment, { children: [
|
|
748
523
|
isDanger && prevSafe && /* @__PURE__ */ jsx(DropdownSeparator, {}),
|
|
749
524
|
/* @__PURE__ */ jsxs(
|
|
750
525
|
DropdownItem,
|
|
@@ -789,6 +564,9 @@ function ChevronPager({ page, pageSize, total, onPageChange, noun }) {
|
|
|
789
564
|
const from = total === 0 ? 0 : (page - 1) * pageSize + 1;
|
|
790
565
|
const to = Math.min(page * pageSize, total);
|
|
791
566
|
const button = "flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground disabled:pointer-events-none disabled:opacity-40";
|
|
567
|
+
const JANELA = 5;
|
|
568
|
+
const inicio = Math.max(1, Math.min(page - Math.floor(JANELA / 2), pages - JANELA + 1));
|
|
569
|
+
const numeros = Array.from({ length: Math.min(JANELA, pages) }, (_, i) => inicio + i);
|
|
792
570
|
return /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2 border-t border-border px-3 py-2", children: [
|
|
793
571
|
/* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", children: [
|
|
794
572
|
from.toLocaleString(),
|
|
@@ -799,6 +577,17 @@ function ChevronPager({ page, pageSize, total, onPageChange, noun }) {
|
|
|
799
577
|
noun ? ` ${noun}` : ""
|
|
800
578
|
] }),
|
|
801
579
|
pages > 1 && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
580
|
+
pages > JANELA && /* @__PURE__ */ jsx(
|
|
581
|
+
"button",
|
|
582
|
+
{
|
|
583
|
+
type: "button",
|
|
584
|
+
"aria-label": "Primeira p\xE1gina",
|
|
585
|
+
className: button,
|
|
586
|
+
disabled: page <= 1,
|
|
587
|
+
onClick: () => onPageChange(1),
|
|
588
|
+
children: /* @__PURE__ */ jsx(ChevronsLeft, { className: "h-4 w-4" })
|
|
589
|
+
}
|
|
590
|
+
),
|
|
802
591
|
/* @__PURE__ */ jsx(
|
|
803
592
|
"button",
|
|
804
593
|
{
|
|
@@ -810,11 +599,18 @@ function ChevronPager({ page, pageSize, total, onPageChange, noun }) {
|
|
|
810
599
|
children: /* @__PURE__ */ jsx(ChevronLeft, { className: "h-4 w-4" })
|
|
811
600
|
}
|
|
812
601
|
),
|
|
813
|
-
/* @__PURE__ */
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
602
|
+
numeros.map((n) => /* @__PURE__ */ jsx(
|
|
603
|
+
"button",
|
|
604
|
+
{
|
|
605
|
+
type: "button",
|
|
606
|
+
"aria-label": `P\xE1gina ${n}`,
|
|
607
|
+
"aria-current": n === page ? "page" : void 0,
|
|
608
|
+
onClick: () => onPageChange(n),
|
|
609
|
+
className: n === page ? "flex h-7 min-w-7 items-center justify-center rounded-md bg-primary px-1.5 text-xs font-medium tabular-nums text-primary-foreground" : "flex h-7 min-w-7 items-center justify-center rounded-md px-1.5 text-xs tabular-nums text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
|
|
610
|
+
children: n.toLocaleString()
|
|
611
|
+
},
|
|
612
|
+
n
|
|
613
|
+
)),
|
|
818
614
|
/* @__PURE__ */ jsx(
|
|
819
615
|
"button",
|
|
820
616
|
{
|
|
@@ -825,6 +621,17 @@ function ChevronPager({ page, pageSize, total, onPageChange, noun }) {
|
|
|
825
621
|
onClick: () => onPageChange(page + 1),
|
|
826
622
|
children: /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4" })
|
|
827
623
|
}
|
|
624
|
+
),
|
|
625
|
+
pages > JANELA && /* @__PURE__ */ jsx(
|
|
626
|
+
"button",
|
|
627
|
+
{
|
|
628
|
+
type: "button",
|
|
629
|
+
"aria-label": "\xDAltima p\xE1gina",
|
|
630
|
+
className: button,
|
|
631
|
+
disabled: page >= pages,
|
|
632
|
+
onClick: () => onPageChange(pages),
|
|
633
|
+
children: /* @__PURE__ */ jsx(ChevronsRight, { className: "h-4 w-4" })
|
|
634
|
+
}
|
|
828
635
|
)
|
|
829
636
|
] })
|
|
830
637
|
] });
|
|
@@ -963,8 +770,8 @@ var ICON_CLASSES = {
|
|
|
963
770
|
lg: "h-5 w-5"
|
|
964
771
|
};
|
|
965
772
|
function Thumbnail({ src, alt = "", size = "md", icon: Icon2 = ImageIcon, className }) {
|
|
966
|
-
const [failed, setFailed] =
|
|
967
|
-
|
|
773
|
+
const [failed, setFailed] = React15.useState(false);
|
|
774
|
+
React15.useEffect(() => {
|
|
968
775
|
setFailed(false);
|
|
969
776
|
}, [src]);
|
|
970
777
|
const base = cn("shrink-0 overflow-hidden", SIZE_CLASSES[size], className);
|
|
@@ -991,9 +798,9 @@ function Thumbnail({ src, alt = "", size = "md", icon: Icon2 = ImageIcon, classN
|
|
|
991
798
|
}
|
|
992
799
|
Thumbnail.displayName = "Thumbnail";
|
|
993
800
|
function RefreshButton({ onRefresh, fromCache, label, labelCached, className, ...rest }) {
|
|
994
|
-
const [phase, setPhase] =
|
|
995
|
-
const alive =
|
|
996
|
-
|
|
801
|
+
const [phase, setPhase] = React15.useState("idle");
|
|
802
|
+
const alive = React15.useRef(true);
|
|
803
|
+
React15.useEffect(() => () => {
|
|
997
804
|
alive.current = false;
|
|
998
805
|
}, []);
|
|
999
806
|
const title = fromCache ? labelCached ?? label : label;
|
|
@@ -1211,27 +1018,27 @@ function useRowSelection({
|
|
|
1211
1018
|
getRowId,
|
|
1212
1019
|
enabled = true
|
|
1213
1020
|
}) {
|
|
1214
|
-
const identify =
|
|
1021
|
+
const identify = React15.useCallback(
|
|
1215
1022
|
(row) => getRowId ? getRowId(row) : String(row?.id ?? ""),
|
|
1216
1023
|
[getRowId]
|
|
1217
1024
|
);
|
|
1218
|
-
const visible =
|
|
1219
|
-
const [rawSelection, setRawSelection] =
|
|
1220
|
-
const visibleIds =
|
|
1221
|
-
const selectedIds =
|
|
1025
|
+
const visible = React15.useMemo(() => rows ?? [], [rows]);
|
|
1026
|
+
const [rawSelection, setRawSelection] = React15.useState([]);
|
|
1027
|
+
const visibleIds = React15.useMemo(() => new Set(visible.map(identify)), [visible, identify]);
|
|
1028
|
+
const selectedIds = React15.useMemo(
|
|
1222
1029
|
() => rawSelection.filter((id) => visibleIds.has(id)),
|
|
1223
1030
|
[rawSelection, visibleIds]
|
|
1224
1031
|
);
|
|
1225
|
-
const selectedRows =
|
|
1032
|
+
const selectedRows = React15.useMemo(() => {
|
|
1226
1033
|
const picked = new Set(selectedIds);
|
|
1227
1034
|
return visible.filter((row) => picked.has(identify(row)));
|
|
1228
1035
|
}, [visible, selectedIds, identify]);
|
|
1229
|
-
const clear =
|
|
1230
|
-
const selectAll =
|
|
1036
|
+
const clear = React15.useCallback(() => setRawSelection([]), []);
|
|
1037
|
+
const selectAll = React15.useCallback(
|
|
1231
1038
|
() => setRawSelection(visible.map(identify)),
|
|
1232
1039
|
[visible, identify]
|
|
1233
1040
|
);
|
|
1234
|
-
const barActions =
|
|
1041
|
+
const barActions = React15.useMemo(
|
|
1235
1042
|
() => (actions ?? []).map((action) => ({
|
|
1236
1043
|
id: action.id,
|
|
1237
1044
|
label: action.label,
|
|
@@ -1291,14 +1098,65 @@ function FilterChip({ allLabel, options, value, onChange, label, icon: Icon2, cl
|
|
|
1291
1098
|
] });
|
|
1292
1099
|
}
|
|
1293
1100
|
var ICON_BTN = "fz-tap text-muted-foreground";
|
|
1101
|
+
function ListFilters({ tagFilter, filters, advanced, label, count, wideCount }) {
|
|
1102
|
+
const wide = useIsWide();
|
|
1103
|
+
const [open, setOpen] = useState(false);
|
|
1104
|
+
if (!tagFilter && !filters && !advanced) return null;
|
|
1105
|
+
const inPanel = wide ? advanced : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1106
|
+
tagFilter,
|
|
1107
|
+
filters,
|
|
1108
|
+
advanced
|
|
1109
|
+
] });
|
|
1110
|
+
const badge = wide ? wideCount : count;
|
|
1111
|
+
const trigger = wide && !advanced ? null : /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
|
|
1112
|
+
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
1113
|
+
"button",
|
|
1114
|
+
{
|
|
1115
|
+
type: "button",
|
|
1116
|
+
"aria-label": label,
|
|
1117
|
+
className: cn(
|
|
1118
|
+
"inline-flex shrink-0 items-center gap-1.5 rounded-full border px-2.5 py-1 text-xs font-medium transition-colors",
|
|
1119
|
+
badge > 0 ? "border-primary/30 bg-primary/10 text-primary hover:bg-primary/15" : "border-transparent bg-muted/70 text-muted-foreground hover:bg-muted hover:text-foreground"
|
|
1120
|
+
),
|
|
1121
|
+
children: [
|
|
1122
|
+
/* @__PURE__ */ jsx(SlidersHorizontal, { className: "h-3 w-3 shrink-0 opacity-70" }),
|
|
1123
|
+
/* @__PURE__ */ jsx("span", { className: "hidden sm:inline", children: label }),
|
|
1124
|
+
badge > 0 && /* @__PURE__ */ jsx("span", { className: "rounded-full bg-primary/20 px-1.5 text-[10px] font-semibold tabular-nums", children: badge })
|
|
1125
|
+
]
|
|
1126
|
+
}
|
|
1127
|
+
) }),
|
|
1128
|
+
/* @__PURE__ */ jsx(
|
|
1129
|
+
PopoverContent,
|
|
1130
|
+
{
|
|
1131
|
+
align: "end",
|
|
1132
|
+
sideOffset: 8,
|
|
1133
|
+
className: "flex max-h-[70vh] w-[min(18rem,calc(100vw-1.5rem))] flex-col gap-3 overflow-y-auto p-3 [&_button]:w-full [&_button]:justify-between",
|
|
1134
|
+
children: inPanel
|
|
1135
|
+
}
|
|
1136
|
+
)
|
|
1137
|
+
] });
|
|
1138
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1139
|
+
wide && tagFilter,
|
|
1140
|
+
wide && filters,
|
|
1141
|
+
trigger
|
|
1142
|
+
] });
|
|
1143
|
+
}
|
|
1144
|
+
var PAGER_BTN = "flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground disabled:pointer-events-none disabled:opacity-40";
|
|
1294
1145
|
function ListView({
|
|
1295
1146
|
columns,
|
|
1296
1147
|
data,
|
|
1297
1148
|
loading = false,
|
|
1298
1149
|
searchPlaceholder = "Search...",
|
|
1150
|
+
filtersLabel = "Filtros",
|
|
1151
|
+
advancedFilters,
|
|
1152
|
+
activeFilterCount = 0,
|
|
1153
|
+
advancedFilterCount,
|
|
1154
|
+
onClearFilters,
|
|
1155
|
+
clearFiltersLabel = "Clear",
|
|
1299
1156
|
search: controlledSearch,
|
|
1300
1157
|
onSearchChange,
|
|
1301
1158
|
searchDebounce = 300,
|
|
1159
|
+
searchOwnRow,
|
|
1302
1160
|
tags,
|
|
1303
1161
|
allTagLabel = "All",
|
|
1304
1162
|
tagsLabel,
|
|
@@ -1316,6 +1174,12 @@ function ListView({
|
|
|
1316
1174
|
total,
|
|
1317
1175
|
page = 1,
|
|
1318
1176
|
pageSize = 25,
|
|
1177
|
+
rangeOfLabel = "of",
|
|
1178
|
+
firstPageLabel = "First page",
|
|
1179
|
+
prevPageLabel = "Previous page",
|
|
1180
|
+
nextPageLabel = "Next page",
|
|
1181
|
+
lastPageLabel = "Last page",
|
|
1182
|
+
pageLabel = "Page",
|
|
1319
1183
|
onPageChange,
|
|
1320
1184
|
toolbar,
|
|
1321
1185
|
filters,
|
|
@@ -1343,6 +1207,9 @@ function ListView({
|
|
|
1343
1207
|
}, [onSearchChange, searchDebounce]);
|
|
1344
1208
|
const totalItems = total ?? data.length;
|
|
1345
1209
|
const totalPages = Math.max(1, Math.ceil(totalItems / pageSize));
|
|
1210
|
+
const PAGE_WINDOW = 5;
|
|
1211
|
+
const windowStart = Math.max(1, Math.min(page - Math.floor(PAGE_WINDOW / 2), totalPages - PAGE_WINDOW + 1));
|
|
1212
|
+
const pageWindow = Array.from({ length: Math.min(PAGE_WINDOW, totalPages) }, (_, i) => windowStart + i);
|
|
1346
1213
|
const showPagination = onPageChange && totalItems > pageSize;
|
|
1347
1214
|
const showSearch = !!onSearchChange;
|
|
1348
1215
|
const showTags = tags && tags.length > 0 && onTagChange;
|
|
@@ -1391,7 +1258,11 @@ function ListView({
|
|
|
1391
1258
|
actions: selection.barActions
|
|
1392
1259
|
}
|
|
1393
1260
|
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1394
|
-
showSearch &&
|
|
1261
|
+
showSearch && // `basis-full` e não uma segunda `div`: o contentor já é
|
|
1262
|
+
// `flex-wrap`, então uma primeira cria que ocupa a linha
|
|
1263
|
+
// inteira empurra o resto para baixo sozinha. Sem filtros,
|
|
1264
|
+
// a busca volta a partilhar a linha com atualizar/exportar.
|
|
1265
|
+
/* @__PURE__ */ jsxs("div", { className: cn("relative min-w-0 flex-1", searchOwnRow && "basis-full"), children: [
|
|
1395
1266
|
/* @__PURE__ */ jsx(Search, { className: "pointer-events-none absolute left-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground" }),
|
|
1396
1267
|
/* @__PURE__ */ jsx(
|
|
1397
1268
|
"input",
|
|
@@ -1404,9 +1275,34 @@ function ListView({
|
|
|
1404
1275
|
}
|
|
1405
1276
|
)
|
|
1406
1277
|
] }),
|
|
1407
|
-
(tagFilter || filters || onRefresh || onExport) &&
|
|
1408
|
-
|
|
1409
|
-
|
|
1278
|
+
(tagFilter || filters || advancedFilters || onRefresh || onExport) && // `flex-nowrap`: envolvendo, cada filtro a mais abria uma
|
|
1279
|
+
// linha nova sob a busca, e quatro deles gastavam três linhas
|
|
1280
|
+
// antes da primeira linha da tabela. No celular eles se
|
|
1281
|
+
// recolhem num gatilho (abaixo) e a linha volta a ser uma.
|
|
1282
|
+
/* @__PURE__ */ jsxs("div", { className: "ml-auto flex flex-nowrap items-center justify-end gap-2 md:flex-wrap", children: [
|
|
1283
|
+
/* @__PURE__ */ jsx(
|
|
1284
|
+
ListFilters,
|
|
1285
|
+
{
|
|
1286
|
+
tagFilter,
|
|
1287
|
+
filters,
|
|
1288
|
+
advanced: advancedFilters,
|
|
1289
|
+
label: filtersLabel,
|
|
1290
|
+
count: activeFilterCount,
|
|
1291
|
+
wideCount: advancedFilterCount ?? activeFilterCount
|
|
1292
|
+
}
|
|
1293
|
+
),
|
|
1294
|
+
onClearFilters && activeFilterCount > 0 && /* @__PURE__ */ jsxs(
|
|
1295
|
+
"button",
|
|
1296
|
+
{
|
|
1297
|
+
type: "button",
|
|
1298
|
+
onClick: onClearFilters,
|
|
1299
|
+
className: "inline-flex shrink-0 items-center gap-1 rounded-full px-2 py-1 text-xs font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
|
|
1300
|
+
children: [
|
|
1301
|
+
/* @__PURE__ */ jsx(X, { className: "h-3 w-3 shrink-0" }),
|
|
1302
|
+
clearFiltersLabel
|
|
1303
|
+
]
|
|
1304
|
+
}
|
|
1305
|
+
),
|
|
1410
1306
|
onRefresh && /* @__PURE__ */ jsx(Hint, { label: refreshLabel, children: /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon", "aria-label": refreshLabel, onClick: onRefresh, className: ICON_BTN, children: /* @__PURE__ */ jsx(RefreshCw, { className: "h-4 w-4" }) }) }),
|
|
1411
1307
|
onExport && /* @__PURE__ */ jsx(Hint, { label: exportLabel, children: /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon", "aria-label": exportLabel, onClick: onExport, className: ICON_BTN, children: /* @__PURE__ */ jsx(Download, { className: "h-4 w-4" }) }) })
|
|
1412
1308
|
] })
|
|
@@ -1426,40 +1322,75 @@ function ListView({
|
|
|
1426
1322
|
onSelectedIdsChange: selection.setSelectedIds,
|
|
1427
1323
|
getRowId
|
|
1428
1324
|
}
|
|
1429
|
-
)
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
1440
|
-
/* @__PURE__ */ jsx(
|
|
1441
|
-
"button",
|
|
1442
|
-
{
|
|
1443
|
-
onClick: () => onPageChange(page - 1),
|
|
1444
|
-
disabled: page <= 1,
|
|
1445
|
-
className: "flex h-7 w-7 items-center justify-center rounded-md border hover:bg-muted bg-card shadow-button active:shadow-button-inset transition-colors disabled:opacity-30 disabled:cursor-not-allowed",
|
|
1446
|
-
children: /* @__PURE__ */ jsx(ChevronLeft, { className: "h-3.5 w-3.5" })
|
|
1447
|
-
}
|
|
1448
|
-
),
|
|
1449
|
-
/* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground px-2", children: [
|
|
1450
|
-
page,
|
|
1451
|
-
" / ",
|
|
1452
|
-
totalPages
|
|
1325
|
+
),
|
|
1326
|
+
showPagination && /* @__PURE__ */ jsxs("div", { className: "-mt-px flex min-h-9 flex-col items-center gap-2 rounded-b-card border-t border-border px-3 py-2 sm:grid sm:grid-cols-[1fr_auto_1fr] sm:gap-3", children: [
|
|
1327
|
+
/* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground sm:justify-self-start", children: [
|
|
1328
|
+
(page - 1) * pageSize + 1,
|
|
1329
|
+
"\u2013",
|
|
1330
|
+
Math.min(page * pageSize, totalItems),
|
|
1331
|
+
" ",
|
|
1332
|
+
rangeOfLabel,
|
|
1333
|
+
" ",
|
|
1334
|
+
totalItems.toLocaleString()
|
|
1453
1335
|
] }),
|
|
1454
|
-
/* @__PURE__ */
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1336
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
1337
|
+
totalPages > PAGE_WINDOW && /* @__PURE__ */ jsx(
|
|
1338
|
+
"button",
|
|
1339
|
+
{
|
|
1340
|
+
type: "button",
|
|
1341
|
+
onClick: () => onPageChange(1),
|
|
1342
|
+
disabled: page <= 1,
|
|
1343
|
+
"aria-label": firstPageLabel,
|
|
1344
|
+
className: PAGER_BTN,
|
|
1345
|
+
children: /* @__PURE__ */ jsx(ChevronsLeft, { className: "h-4 w-4" })
|
|
1346
|
+
}
|
|
1347
|
+
),
|
|
1348
|
+
/* @__PURE__ */ jsx(
|
|
1349
|
+
"button",
|
|
1350
|
+
{
|
|
1351
|
+
type: "button",
|
|
1352
|
+
onClick: () => onPageChange(page - 1),
|
|
1353
|
+
disabled: page <= 1,
|
|
1354
|
+
"aria-label": prevPageLabel,
|
|
1355
|
+
className: PAGER_BTN,
|
|
1356
|
+
children: /* @__PURE__ */ jsx(ChevronLeft, { className: "h-4 w-4" })
|
|
1357
|
+
}
|
|
1358
|
+
),
|
|
1359
|
+
pageWindow.map((n) => /* @__PURE__ */ jsx(
|
|
1360
|
+
"button",
|
|
1361
|
+
{
|
|
1362
|
+
type: "button",
|
|
1363
|
+
onClick: () => onPageChange(n),
|
|
1364
|
+
"aria-label": `${pageLabel} ${n}`,
|
|
1365
|
+
"aria-current": n === page ? "page" : void 0,
|
|
1366
|
+
className: n === page ? "flex h-7 min-w-7 items-center justify-center rounded-md bg-primary px-1.5 text-xs font-medium tabular-nums text-primary-foreground" : "flex h-7 min-w-7 items-center justify-center rounded-md px-1.5 text-xs tabular-nums text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
|
|
1367
|
+
children: n
|
|
1368
|
+
},
|
|
1369
|
+
n
|
|
1370
|
+
)),
|
|
1371
|
+
/* @__PURE__ */ jsx(
|
|
1372
|
+
"button",
|
|
1373
|
+
{
|
|
1374
|
+
type: "button",
|
|
1375
|
+
onClick: () => onPageChange(page + 1),
|
|
1376
|
+
disabled: page >= totalPages,
|
|
1377
|
+
"aria-label": nextPageLabel,
|
|
1378
|
+
className: PAGER_BTN,
|
|
1379
|
+
children: /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4" })
|
|
1380
|
+
}
|
|
1381
|
+
),
|
|
1382
|
+
totalPages > PAGE_WINDOW && /* @__PURE__ */ jsx(
|
|
1383
|
+
"button",
|
|
1384
|
+
{
|
|
1385
|
+
type: "button",
|
|
1386
|
+
onClick: () => onPageChange(totalPages),
|
|
1387
|
+
disabled: page >= totalPages,
|
|
1388
|
+
"aria-label": lastPageLabel,
|
|
1389
|
+
className: PAGER_BTN,
|
|
1390
|
+
children: /* @__PURE__ */ jsx(ChevronsRight, { className: "h-4 w-4" })
|
|
1391
|
+
}
|
|
1392
|
+
)
|
|
1393
|
+
] })
|
|
1463
1394
|
] })
|
|
1464
1395
|
] })
|
|
1465
1396
|
] });
|
|
@@ -1667,7 +1598,7 @@ function toLocalISODate(d) {
|
|
|
1667
1598
|
}
|
|
1668
1599
|
function MiniCalendar({ selectedDate, onDateSelect, onMonthChange, markers }) {
|
|
1669
1600
|
const locale = getCurrentLocale();
|
|
1670
|
-
const [viewMonth, setViewMonth] =
|
|
1601
|
+
const [viewMonth, setViewMonth] = React15__default.useState(() => new Date(selectedDate.getFullYear(), selectedDate.getMonth(), 1));
|
|
1671
1602
|
const monthLabel = viewMonth.toLocaleDateString(toDateLocale2(locale), { month: "long", year: "numeric" });
|
|
1672
1603
|
const dayLabels = DAY_LABELS2[locale] ?? DAY_LABELS2.en;
|
|
1673
1604
|
const weeks = useMemo(() => {
|
|
@@ -1746,7 +1677,7 @@ function FilterSection({
|
|
|
1746
1677
|
defaultOpen = true,
|
|
1747
1678
|
children
|
|
1748
1679
|
}) {
|
|
1749
|
-
const [open, setOpen] =
|
|
1680
|
+
const [open, setOpen] = React15__default.useState(defaultOpen);
|
|
1750
1681
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1751
1682
|
/* @__PURE__ */ jsxs(
|
|
1752
1683
|
"button",
|
|
@@ -1819,7 +1750,7 @@ function FilterCheckList({
|
|
|
1819
1750
|
}
|
|
1820
1751
|
return /* @__PURE__ */ jsx("div", { className: className ? `${className} space-y-0.5` : "space-y-0.5", children: rows });
|
|
1821
1752
|
}
|
|
1822
|
-
var useIsomorphicLayoutEffect = typeof window !== "undefined" ?
|
|
1753
|
+
var useIsomorphicLayoutEffect = typeof window !== "undefined" ? React15.useLayoutEffect : React15.useEffect;
|
|
1823
1754
|
function SearchSelect({
|
|
1824
1755
|
value,
|
|
1825
1756
|
displayValue,
|
|
@@ -1843,18 +1774,18 @@ function SearchSelect({
|
|
|
1843
1774
|
"data-tour": dataTour
|
|
1844
1775
|
}) {
|
|
1845
1776
|
const canCreate = !!onCreate && allowCreate !== false;
|
|
1846
|
-
const [open, setOpen] =
|
|
1847
|
-
const [query, setQuery] =
|
|
1848
|
-
const [results, setResults] =
|
|
1849
|
-
const [loading, setLoading] =
|
|
1850
|
-
const [creating, setCreating] =
|
|
1851
|
-
const [selectedLabel, setSelectedLabel] =
|
|
1852
|
-
const containerRef =
|
|
1853
|
-
const inputRef =
|
|
1854
|
-
const timerRef =
|
|
1855
|
-
const [rect, setRect] =
|
|
1856
|
-
const dropdownRef =
|
|
1857
|
-
|
|
1777
|
+
const [open, setOpen] = React15.useState(false);
|
|
1778
|
+
const [query, setQuery] = React15.useState("");
|
|
1779
|
+
const [results, setResults] = React15.useState([]);
|
|
1780
|
+
const [loading, setLoading] = React15.useState(false);
|
|
1781
|
+
const [creating, setCreating] = React15.useState(false);
|
|
1782
|
+
const [selectedLabel, setSelectedLabel] = React15.useState(displayValue ?? "");
|
|
1783
|
+
const containerRef = React15.useRef(null);
|
|
1784
|
+
const inputRef = React15.useRef(null);
|
|
1785
|
+
const timerRef = React15.useRef();
|
|
1786
|
+
const [rect, setRect] = React15.useState(null);
|
|
1787
|
+
const dropdownRef = React15.useRef(null);
|
|
1788
|
+
React15.useEffect(() => {
|
|
1858
1789
|
function handler(e) {
|
|
1859
1790
|
const target = e.target;
|
|
1860
1791
|
if (containerRef.current?.contains(target)) return;
|
|
@@ -1864,10 +1795,10 @@ function SearchSelect({
|
|
|
1864
1795
|
document.addEventListener("mousedown", handler);
|
|
1865
1796
|
return () => document.removeEventListener("mousedown", handler);
|
|
1866
1797
|
}, []);
|
|
1867
|
-
|
|
1798
|
+
React15.useEffect(() => {
|
|
1868
1799
|
if (displayValue !== void 0) setSelectedLabel(displayValue);
|
|
1869
1800
|
}, [displayValue]);
|
|
1870
|
-
|
|
1801
|
+
React15.useEffect(() => {
|
|
1871
1802
|
if (open && loadOnOpen && query.length === 0 && results.length === 0 && !loading) {
|
|
1872
1803
|
setLoading(true);
|
|
1873
1804
|
Promise.resolve(onSearch("")).then(setResults).catch(() => setResults([])).finally(() => setLoading(false));
|
|
@@ -1925,7 +1856,7 @@ function SearchSelect({
|
|
|
1925
1856
|
setResults([]);
|
|
1926
1857
|
setTimeout(() => inputRef.current?.focus(), 0);
|
|
1927
1858
|
}
|
|
1928
|
-
const groups =
|
|
1859
|
+
const groups = React15.useMemo(() => {
|
|
1929
1860
|
const map = /* @__PURE__ */ new Map();
|
|
1930
1861
|
for (const opt of results) {
|
|
1931
1862
|
const group = opt.group ?? "";
|
|
@@ -2020,7 +1951,7 @@ function SearchSelect({
|
|
|
2020
1951
|
/* @__PURE__ */ jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin" }),
|
|
2021
1952
|
" ",
|
|
2022
1953
|
searchingLabel
|
|
2023
|
-
] }) : results.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-4 py-4 text-center", children: /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: noResultsLabel ?? (query ? `No results for "${query}"` : "No results") }) }) : /* @__PURE__ */ jsx("div", { className: "max-h-64 overflow-auto py-1", children: [...groups.entries()].map(([group, options]) => /* @__PURE__ */ jsxs(
|
|
1954
|
+
] }) : results.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-4 py-4 text-center", children: /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: noResultsLabel ?? (query ? `No results for "${query}"` : "No results") }) }) : /* @__PURE__ */ jsx("div", { className: "max-h-64 overflow-auto py-1", children: [...groups.entries()].map(([group, options]) => /* @__PURE__ */ jsxs(React15.Fragment, { children: [
|
|
2024
1955
|
group && /* @__PURE__ */ jsx("div", { className: "sticky top-0 bg-muted/50 px-3 py-1 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground", children: group }),
|
|
2025
1956
|
options.map((opt) => /* @__PURE__ */ jsx(
|
|
2026
1957
|
"button",
|
|
@@ -2082,9 +2013,9 @@ function CurrencyInput({
|
|
|
2082
2013
|
className,
|
|
2083
2014
|
disabled
|
|
2084
2015
|
}) {
|
|
2085
|
-
const inputRef =
|
|
2086
|
-
const [focused, setFocused] =
|
|
2087
|
-
const format =
|
|
2016
|
+
const inputRef = React15.useRef(null);
|
|
2017
|
+
const [focused, setFocused] = React15.useState(false);
|
|
2018
|
+
const format = React15.useCallback((v) => {
|
|
2088
2019
|
return new Intl.NumberFormat(locale, {
|
|
2089
2020
|
minimumFractionDigits: 2,
|
|
2090
2021
|
maximumFractionDigits: 2
|
|
@@ -2154,24 +2085,125 @@ function CurrencyInput({
|
|
|
2154
2085
|
)
|
|
2155
2086
|
] });
|
|
2156
2087
|
}
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
)
|
|
2171
|
-
...props
|
|
2088
|
+
function formatRange(from, to, locale) {
|
|
2089
|
+
const parse = (s) => {
|
|
2090
|
+
const [y, m, d] = s.split("-").map(Number);
|
|
2091
|
+
return new Date(y, (m ?? 1) - 1, d ?? 1);
|
|
2092
|
+
};
|
|
2093
|
+
const day = (d) => String(d.getDate());
|
|
2094
|
+
const dayMonth = (d) => d.toLocaleDateString(locale, { day: "numeric", month: "short" }).replace(/\.$/, "");
|
|
2095
|
+
if (from && to) {
|
|
2096
|
+
const a = parse(from);
|
|
2097
|
+
const b = parse(to);
|
|
2098
|
+
if (a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth()) {
|
|
2099
|
+
return a.getDate() === b.getDate() ? dayMonth(a) : `${day(a)}\u2013${dayMonth(b)}`;
|
|
2100
|
+
}
|
|
2101
|
+
return `${dayMonth(a)} \u2013 ${dayMonth(b)}`;
|
|
2172
2102
|
}
|
|
2173
|
-
|
|
2174
|
-
|
|
2103
|
+
return dayMonth(parse(from || to));
|
|
2104
|
+
}
|
|
2105
|
+
function DateRangeChip({
|
|
2106
|
+
from,
|
|
2107
|
+
to,
|
|
2108
|
+
onChange,
|
|
2109
|
+
presets = [],
|
|
2110
|
+
preset,
|
|
2111
|
+
onPresetChange,
|
|
2112
|
+
allLabel,
|
|
2113
|
+
labels,
|
|
2114
|
+
label,
|
|
2115
|
+
className
|
|
2116
|
+
}) {
|
|
2117
|
+
const [open, setOpen] = React15.useState(false);
|
|
2118
|
+
const active = !!(from || to);
|
|
2119
|
+
const locale = typeof navigator !== "undefined" ? navigator.language : "en";
|
|
2120
|
+
const presetLabel = presets.find((p) => p.value === preset)?.label;
|
|
2121
|
+
const text = !active ? allLabel : presetLabel ?? formatRange(from, to, locale);
|
|
2122
|
+
return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
|
|
2123
|
+
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
2124
|
+
"button",
|
|
2125
|
+
{
|
|
2126
|
+
type: "button",
|
|
2127
|
+
"aria-label": label,
|
|
2128
|
+
className: cn(
|
|
2129
|
+
"inline-flex shrink-0 items-center gap-1 rounded-full border px-2.5 py-1 text-xs font-medium transition-colors",
|
|
2130
|
+
active ? "border-primary/30 bg-primary/10 text-primary hover:bg-primary/15" : "border-transparent bg-muted/70 text-muted-foreground hover:bg-muted hover:text-foreground",
|
|
2131
|
+
className
|
|
2132
|
+
),
|
|
2133
|
+
children: [
|
|
2134
|
+
/* @__PURE__ */ jsx(CalendarDays, { className: "h-3 w-3 shrink-0 opacity-70" }),
|
|
2135
|
+
/* @__PURE__ */ jsx("span", { className: "max-w-[12rem] truncate", children: text })
|
|
2136
|
+
]
|
|
2137
|
+
}
|
|
2138
|
+
) }),
|
|
2139
|
+
/* @__PURE__ */ jsxs(PopoverContent, { align: "start", sideOffset: 6, className: "w-60 p-1.5", children: [
|
|
2140
|
+
/* @__PURE__ */ jsxs(
|
|
2141
|
+
"button",
|
|
2142
|
+
{
|
|
2143
|
+
type: "button",
|
|
2144
|
+
onClick: () => {
|
|
2145
|
+
onPresetChange?.("all");
|
|
2146
|
+
onChange({ from: "", to: "" });
|
|
2147
|
+
setOpen(false);
|
|
2148
|
+
},
|
|
2149
|
+
className: "flex w-full items-center rounded-md px-2 py-1.5 text-sm transition-colors hover:bg-muted",
|
|
2150
|
+
children: [
|
|
2151
|
+
allLabel,
|
|
2152
|
+
!active && /* @__PURE__ */ jsx(Check, { className: "ml-auto h-3.5 w-3.5 shrink-0" })
|
|
2153
|
+
]
|
|
2154
|
+
}
|
|
2155
|
+
),
|
|
2156
|
+
presets.map((p) => /* @__PURE__ */ jsxs(
|
|
2157
|
+
"button",
|
|
2158
|
+
{
|
|
2159
|
+
type: "button",
|
|
2160
|
+
onClick: () => {
|
|
2161
|
+
onPresetChange?.(p.value);
|
|
2162
|
+
setOpen(false);
|
|
2163
|
+
},
|
|
2164
|
+
className: "flex w-full items-center rounded-md px-2 py-1.5 text-sm transition-colors hover:bg-muted",
|
|
2165
|
+
children: [
|
|
2166
|
+
p.label,
|
|
2167
|
+
active && preset === p.value && /* @__PURE__ */ jsx(Check, { className: "ml-auto h-3.5 w-3.5 shrink-0" })
|
|
2168
|
+
]
|
|
2169
|
+
},
|
|
2170
|
+
p.value
|
|
2171
|
+
)),
|
|
2172
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-1 space-y-1.5 border-t border-border px-2 pb-1 pt-2", children: [
|
|
2173
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
|
|
2174
|
+
/* @__PURE__ */ jsx("span", { className: "w-8 shrink-0", children: labels?.from ?? "From" }),
|
|
2175
|
+
/* @__PURE__ */ jsx(
|
|
2176
|
+
DatePicker,
|
|
2177
|
+
{
|
|
2178
|
+
value: from,
|
|
2179
|
+
onChange: (next) => {
|
|
2180
|
+
onPresetChange?.("custom");
|
|
2181
|
+
onChange({ from: next, to });
|
|
2182
|
+
},
|
|
2183
|
+
variant: "toolbar",
|
|
2184
|
+
className: "min-w-0 flex-1"
|
|
2185
|
+
}
|
|
2186
|
+
)
|
|
2187
|
+
] }),
|
|
2188
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
|
|
2189
|
+
/* @__PURE__ */ jsx("span", { className: "w-8 shrink-0", children: labels?.to ?? "To" }),
|
|
2190
|
+
/* @__PURE__ */ jsx(
|
|
2191
|
+
DatePicker,
|
|
2192
|
+
{
|
|
2193
|
+
value: to,
|
|
2194
|
+
onChange: (next) => {
|
|
2195
|
+
onPresetChange?.("custom");
|
|
2196
|
+
onChange({ from, to: next });
|
|
2197
|
+
},
|
|
2198
|
+
variant: "toolbar",
|
|
2199
|
+
className: "min-w-0 flex-1"
|
|
2200
|
+
}
|
|
2201
|
+
)
|
|
2202
|
+
] })
|
|
2203
|
+
] })
|
|
2204
|
+
] })
|
|
2205
|
+
] });
|
|
2206
|
+
}
|
|
2175
2207
|
function MultiSelect({
|
|
2176
2208
|
options,
|
|
2177
2209
|
value,
|
|
@@ -2181,11 +2213,13 @@ function MultiSelect({
|
|
|
2181
2213
|
emptyLabel = "Nada encontrado",
|
|
2182
2214
|
disabled,
|
|
2183
2215
|
className,
|
|
2184
|
-
searchThreshold = 8
|
|
2216
|
+
searchThreshold = 8,
|
|
2217
|
+
variant = "field",
|
|
2218
|
+
icon: Icon2
|
|
2185
2219
|
}) {
|
|
2186
|
-
const [query, setQuery] =
|
|
2187
|
-
const selected =
|
|
2188
|
-
const filtered =
|
|
2220
|
+
const [query, setQuery] = React15.useState("");
|
|
2221
|
+
const selected = React15.useMemo(() => new Set(value), [value]);
|
|
2222
|
+
const filtered = React15.useMemo(() => {
|
|
2189
2223
|
const q = query.trim().toLowerCase();
|
|
2190
2224
|
if (!q) return options;
|
|
2191
2225
|
return options.filter((o) => o.label.toLowerCase().includes(q));
|
|
@@ -2200,15 +2234,22 @@ function MultiSelect({
|
|
|
2200
2234
|
{
|
|
2201
2235
|
type: "button",
|
|
2202
2236
|
disabled,
|
|
2237
|
+
"aria-label": allLabel,
|
|
2203
2238
|
className: cn(
|
|
2204
|
-
"flex h-9 w-full items-center justify-between gap-2 rounded-input border border-input bg-card px-3 py-1.5 text-xs",
|
|
2205
|
-
"shadow-[inset_0_1px_0_rgb(0_0_0_/0.06)] transition-colors hover:bg-muted/40",
|
|
2206
2239
|
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
2207
|
-
|
|
2240
|
+
variant === "chip" ? cn(
|
|
2241
|
+
"inline-flex shrink-0 items-center gap-1 rounded-full border px-2.5 py-1 text-xs font-medium transition-colors",
|
|
2242
|
+
value.length > 0 ? "border-primary/30 bg-primary/10 text-primary hover:bg-primary/15" : "border-transparent bg-muted/70 text-muted-foreground hover:bg-muted hover:text-foreground"
|
|
2243
|
+
) : cn(
|
|
2244
|
+
"flex h-9 w-full items-center justify-between gap-2 rounded-input border border-input bg-card px-3 py-1.5 text-xs",
|
|
2245
|
+
"shadow-[inset_0_1px_0_rgb(0_0_0_/0.06)] transition-colors hover:bg-muted/40",
|
|
2246
|
+
value.length === 0 && "text-muted-foreground"
|
|
2247
|
+
),
|
|
2208
2248
|
className
|
|
2209
2249
|
),
|
|
2210
2250
|
children: [
|
|
2211
|
-
/* @__PURE__ */ jsx(
|
|
2251
|
+
variant === "chip" && Icon2 && /* @__PURE__ */ jsx(Icon2, { className: "h-3 w-3 shrink-0 opacity-70" }),
|
|
2252
|
+
/* @__PURE__ */ jsx("span", { className: cn("min-w-0 truncate", variant === "chip" && "max-w-[12rem]"), children: label }),
|
|
2212
2253
|
/* @__PURE__ */ jsxs("span", { className: "flex shrink-0 items-center gap-1", children: [
|
|
2213
2254
|
value.length > 0 && // Limpar dentro do gatilho: a alternativa é desmarcar cinco itens
|
|
2214
2255
|
// um a um para voltar a "todos", e é o caminho de volta mais
|
|
@@ -2228,43 +2269,64 @@ function MultiSelect({
|
|
|
2228
2269
|
children: /* @__PURE__ */ jsx(X, { className: "h-3 w-3" })
|
|
2229
2270
|
}
|
|
2230
2271
|
),
|
|
2231
|
-
/* @__PURE__ */ jsx(ChevronDown, { className: "h-3.5 w-3.5
|
|
2272
|
+
/* @__PURE__ */ jsx(ChevronDown, { className: cn("shrink-0", variant === "chip" ? "h-3 w-3 opacity-60" : "h-3.5 w-3.5 opacity-50") })
|
|
2232
2273
|
] })
|
|
2233
2274
|
]
|
|
2234
2275
|
}
|
|
2235
2276
|
) }),
|
|
2236
|
-
/* @__PURE__ */ jsxs(
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2277
|
+
/* @__PURE__ */ jsxs(
|
|
2278
|
+
DropdownContent,
|
|
2279
|
+
{
|
|
2280
|
+
align: "start",
|
|
2281
|
+
className: cn(
|
|
2282
|
+
"p-0",
|
|
2283
|
+
// Em `field` o painel casa com o campo, que é largo. Em `chip` a
|
|
2284
|
+
// largura do gatilho é a do rótulo — herdá-la daria uma lista de
|
|
2285
|
+
// dois dedos. Aqui ele ganha a sua própria medida de leitura.
|
|
2286
|
+
variant === "chip" ? "w-[min(16rem,calc(100vw-1.5rem))]" : "w-[--radix-dropdown-menu-trigger-width]"
|
|
2287
|
+
),
|
|
2288
|
+
children: [
|
|
2289
|
+
options.length >= searchThreshold && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 border-b px-2 py-1.5", children: [
|
|
2290
|
+
/* @__PURE__ */ jsx(Search, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
|
|
2291
|
+
/* @__PURE__ */ jsx(
|
|
2292
|
+
"input",
|
|
2293
|
+
{
|
|
2294
|
+
value: query,
|
|
2295
|
+
onChange: (e) => setQuery(e.target.value),
|
|
2296
|
+
placeholder: searchPlaceholder,
|
|
2297
|
+
onKeyDown: (e) => e.stopPropagation(),
|
|
2298
|
+
className: "w-full bg-transparent text-xs outline-none placeholder:text-muted-foreground"
|
|
2299
|
+
}
|
|
2300
|
+
)
|
|
2301
|
+
] }),
|
|
2302
|
+
/* @__PURE__ */ jsx("div", { className: "max-h-64 overflow-y-auto py-1", children: filtered.length === 0 ? /* @__PURE__ */ jsx("p", { className: "px-3 py-4 text-center text-xs text-muted-foreground", children: emptyLabel }) : filtered.map((o) => /* @__PURE__ */ jsxs(
|
|
2303
|
+
"button",
|
|
2304
|
+
{
|
|
2305
|
+
type: "button",
|
|
2306
|
+
onClick: (e) => {
|
|
2307
|
+
e.preventDefault();
|
|
2308
|
+
toggle(o.value);
|
|
2309
|
+
},
|
|
2310
|
+
className: "flex w-full items-center gap-2 px-3 py-1.5 text-left text-xs transition-colors hover:bg-muted",
|
|
2311
|
+
children: [
|
|
2312
|
+
/* @__PURE__ */ jsx(Checkbox, { checked: selected.has(o.value), onChange: () => toggle(o.value) }),
|
|
2313
|
+
o.color && /* @__PURE__ */ jsx(
|
|
2314
|
+
"span",
|
|
2315
|
+
{
|
|
2316
|
+
"aria-hidden": true,
|
|
2317
|
+
className: "h-2 w-2 shrink-0 rounded-full ring-1 ring-inset ring-black/10",
|
|
2318
|
+
style: { backgroundColor: o.color }
|
|
2319
|
+
}
|
|
2320
|
+
),
|
|
2321
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: o.label }),
|
|
2322
|
+
o.hint && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-[10px] text-muted-foreground", children: o.hint })
|
|
2323
|
+
]
|
|
2324
|
+
},
|
|
2325
|
+
o.value
|
|
2326
|
+
)) })
|
|
2327
|
+
]
|
|
2328
|
+
}
|
|
2329
|
+
)
|
|
2268
2330
|
] });
|
|
2269
2331
|
}
|
|
2270
2332
|
var INLINE_TOKEN = /(\*\*[^*]+\*\*|\*[^*]+\*|`[^`]+`)/g;
|
|
@@ -2280,7 +2342,7 @@ function renderInline(text, keyPrefix) {
|
|
|
2280
2342
|
if (part.startsWith("`") && part.endsWith("`") && part.length > 2) {
|
|
2281
2343
|
return /* @__PURE__ */ jsx("code", { className: "rounded bg-muted px-1 py-0.5 font-mono text-[0.85em]", children: part.slice(1, -1) }, key);
|
|
2282
2344
|
}
|
|
2283
|
-
return part === "" ? null : /* @__PURE__ */ jsx(
|
|
2345
|
+
return part === "" ? null : /* @__PURE__ */ jsx(React15.Fragment, { children: part }, key);
|
|
2284
2346
|
});
|
|
2285
2347
|
}
|
|
2286
2348
|
function parseBlocks(source) {
|
|
@@ -2364,7 +2426,7 @@ function renderMarkdown(source) {
|
|
|
2364
2426
|
case "ol":
|
|
2365
2427
|
return /* @__PURE__ */ jsx("ol", { className: "list-decimal space-y-1 pl-5", children: block.items.map((item, li) => /* @__PURE__ */ jsx("li", { children: renderInline(item, `${key}-${li}`) }, `${key}-${li}`)) }, key);
|
|
2366
2428
|
case "p":
|
|
2367
|
-
return /* @__PURE__ */ jsx("p", { children: block.lines.map((l, li) => /* @__PURE__ */ jsxs(
|
|
2429
|
+
return /* @__PURE__ */ jsx("p", { children: block.lines.map((l, li) => /* @__PURE__ */ jsxs(React15.Fragment, { children: [
|
|
2368
2430
|
li > 0 && /* @__PURE__ */ jsx("br", {}),
|
|
2369
2431
|
renderInline(l, `${key}-${li}`)
|
|
2370
2432
|
] }, `${key}-${li}`)) }, key);
|
|
@@ -2385,7 +2447,7 @@ function MarkdownEditor({
|
|
|
2385
2447
|
renderPreview,
|
|
2386
2448
|
className
|
|
2387
2449
|
}) {
|
|
2388
|
-
const [mode, setMode] =
|
|
2450
|
+
const [mode, setMode] = React15.useState(
|
|
2389
2451
|
defaultMode === "preview" && value.trim() === "" ? "edit" : defaultMode
|
|
2390
2452
|
);
|
|
2391
2453
|
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-2", className), children: [
|
|
@@ -2679,13 +2741,13 @@ function StockEntryForm({
|
|
|
2679
2741
|
labels: overrides
|
|
2680
2742
|
}) {
|
|
2681
2743
|
const labels = { ...DEFAULT_LABELS, ...overrides };
|
|
2682
|
-
const [quantity, setQuantity] =
|
|
2683
|
-
const [reasonCode, setReasonCode] =
|
|
2684
|
-
const [occurredOn, setOccurredOn] =
|
|
2685
|
-
const [note, setNote] =
|
|
2686
|
-
const [noteOpen, setNoteOpen] =
|
|
2687
|
-
const quantityRef =
|
|
2688
|
-
|
|
2744
|
+
const [quantity, setQuantity] = React15.useState("");
|
|
2745
|
+
const [reasonCode, setReasonCode] = React15.useState("");
|
|
2746
|
+
const [occurredOn, setOccurredOn] = React15.useState(todayISO());
|
|
2747
|
+
const [note, setNote] = React15.useState("");
|
|
2748
|
+
const [noteOpen, setNoteOpen] = React15.useState(false);
|
|
2749
|
+
const quantityRef = React15.useRef(null);
|
|
2750
|
+
React15.useEffect(() => {
|
|
2689
2751
|
if (verb === null) return;
|
|
2690
2752
|
setQuantity("");
|
|
2691
2753
|
setReasonCode("");
|
|
@@ -2811,6 +2873,6 @@ function StockEntryForm({
|
|
|
2811
2873
|
] }) });
|
|
2812
2874
|
}
|
|
2813
2875
|
|
|
2814
|
-
export { Badge, Breadcrumb, BulkActionBar, ChevronPager, CurrencyInput, DatePicker, DotBadge, DraftCommitBar, FilterCheckBox, FilterCheckList, FilterCheckRow, FilterChip, FilterSection,
|
|
2815
|
-
//# sourceMappingURL=chunk-
|
|
2816
|
-
//# sourceMappingURL=chunk-
|
|
2876
|
+
export { Badge, Breadcrumb, BulkActionBar, ChevronPager, CurrencyInput, DatePicker, DateRangeChip, DotBadge, DraftCommitBar, FilterCheckBox, FilterCheckList, FilterCheckRow, FilterChip, FilterSection, Input, ListView, Markdown, MarkdownEditor, MiniCalendar, Modal, ModalBody, ModalClose, ModalContent, ModalDescription, ModalFooter, ModalHeader, ModalOverlay, ModalPortal, ModalTitle, ModalTrigger, MultiSelect, PhoneField, PhoneLink, RefreshButton, RowActions, SearchCombobox, SearchField, SearchSelect, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator2 as Separator, StatTiles, StockEntryForm, Tabs, TabsContent, TabsList, TabsTrigger, Thumbnail, TimePicker, ToastProvider, WHATSAPP_BRAND_COLOR, WhatsAppIcon, badgeVariants, formatPhone2 as formatPhone, normalizePhone, renderMarkdown, setRowActionsLabel, toLocalISODate, useRowSelection };
|
|
2877
|
+
//# sourceMappingURL=chunk-NXFVYZY7.js.map
|
|
2878
|
+
//# sourceMappingURL=chunk-NXFVYZY7.js.map
|