@fayz-ai/ui 0.22.0 → 0.23.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-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-ZSOT7KTE.js → chunk-XEUIYSW2.js} +321 -361
- package/dist/chunk-XEUIYSW2.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-view.d.ts +43 -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/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, ChevronLeft, ChevronRight, 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,
|
|
@@ -963,8 +738,8 @@ var ICON_CLASSES = {
|
|
|
963
738
|
lg: "h-5 w-5"
|
|
964
739
|
};
|
|
965
740
|
function Thumbnail({ src, alt = "", size = "md", icon: Icon2 = ImageIcon, className }) {
|
|
966
|
-
const [failed, setFailed] =
|
|
967
|
-
|
|
741
|
+
const [failed, setFailed] = React15.useState(false);
|
|
742
|
+
React15.useEffect(() => {
|
|
968
743
|
setFailed(false);
|
|
969
744
|
}, [src]);
|
|
970
745
|
const base = cn("shrink-0 overflow-hidden", SIZE_CLASSES[size], className);
|
|
@@ -991,9 +766,9 @@ function Thumbnail({ src, alt = "", size = "md", icon: Icon2 = ImageIcon, classN
|
|
|
991
766
|
}
|
|
992
767
|
Thumbnail.displayName = "Thumbnail";
|
|
993
768
|
function RefreshButton({ onRefresh, fromCache, label, labelCached, className, ...rest }) {
|
|
994
|
-
const [phase, setPhase] =
|
|
995
|
-
const alive =
|
|
996
|
-
|
|
769
|
+
const [phase, setPhase] = React15.useState("idle");
|
|
770
|
+
const alive = React15.useRef(true);
|
|
771
|
+
React15.useEffect(() => () => {
|
|
997
772
|
alive.current = false;
|
|
998
773
|
}, []);
|
|
999
774
|
const title = fromCache ? labelCached ?? label : label;
|
|
@@ -1211,27 +986,27 @@ function useRowSelection({
|
|
|
1211
986
|
getRowId,
|
|
1212
987
|
enabled = true
|
|
1213
988
|
}) {
|
|
1214
|
-
const identify =
|
|
989
|
+
const identify = React15.useCallback(
|
|
1215
990
|
(row) => getRowId ? getRowId(row) : String(row?.id ?? ""),
|
|
1216
991
|
[getRowId]
|
|
1217
992
|
);
|
|
1218
|
-
const visible =
|
|
1219
|
-
const [rawSelection, setRawSelection] =
|
|
1220
|
-
const visibleIds =
|
|
1221
|
-
const selectedIds =
|
|
993
|
+
const visible = React15.useMemo(() => rows ?? [], [rows]);
|
|
994
|
+
const [rawSelection, setRawSelection] = React15.useState([]);
|
|
995
|
+
const visibleIds = React15.useMemo(() => new Set(visible.map(identify)), [visible, identify]);
|
|
996
|
+
const selectedIds = React15.useMemo(
|
|
1222
997
|
() => rawSelection.filter((id) => visibleIds.has(id)),
|
|
1223
998
|
[rawSelection, visibleIds]
|
|
1224
999
|
);
|
|
1225
|
-
const selectedRows =
|
|
1000
|
+
const selectedRows = React15.useMemo(() => {
|
|
1226
1001
|
const picked = new Set(selectedIds);
|
|
1227
1002
|
return visible.filter((row) => picked.has(identify(row)));
|
|
1228
1003
|
}, [visible, selectedIds, identify]);
|
|
1229
|
-
const clear =
|
|
1230
|
-
const selectAll =
|
|
1004
|
+
const clear = React15.useCallback(() => setRawSelection([]), []);
|
|
1005
|
+
const selectAll = React15.useCallback(
|
|
1231
1006
|
() => setRawSelection(visible.map(identify)),
|
|
1232
1007
|
[visible, identify]
|
|
1233
1008
|
);
|
|
1234
|
-
const barActions =
|
|
1009
|
+
const barActions = React15.useMemo(
|
|
1235
1010
|
() => (actions ?? []).map((action) => ({
|
|
1236
1011
|
id: action.id,
|
|
1237
1012
|
label: action.label,
|
|
@@ -1291,11 +1066,61 @@ function FilterChip({ allLabel, options, value, onChange, label, icon: Icon2, cl
|
|
|
1291
1066
|
] });
|
|
1292
1067
|
}
|
|
1293
1068
|
var ICON_BTN = "fz-tap text-muted-foreground";
|
|
1069
|
+
function ListFilters({ tagFilter, filters, advanced, label, count, wideCount }) {
|
|
1070
|
+
const wide = useIsWide();
|
|
1071
|
+
const [open, setOpen] = useState(false);
|
|
1072
|
+
if (!tagFilter && !filters && !advanced) return null;
|
|
1073
|
+
const inPanel = wide ? advanced : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1074
|
+
tagFilter,
|
|
1075
|
+
filters,
|
|
1076
|
+
advanced
|
|
1077
|
+
] });
|
|
1078
|
+
const badge = wide ? wideCount : count;
|
|
1079
|
+
const trigger = wide && !advanced ? null : /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
|
|
1080
|
+
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
1081
|
+
"button",
|
|
1082
|
+
{
|
|
1083
|
+
type: "button",
|
|
1084
|
+
"aria-label": label,
|
|
1085
|
+
className: cn(
|
|
1086
|
+
"inline-flex shrink-0 items-center gap-1.5 rounded-full border px-2.5 py-1 text-xs font-medium transition-colors",
|
|
1087
|
+
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"
|
|
1088
|
+
),
|
|
1089
|
+
children: [
|
|
1090
|
+
/* @__PURE__ */ jsx(SlidersHorizontal, { className: "h-3 w-3 shrink-0 opacity-70" }),
|
|
1091
|
+
/* @__PURE__ */ jsx("span", { className: "hidden sm:inline", children: label }),
|
|
1092
|
+
badge > 0 && /* @__PURE__ */ jsx("span", { className: "rounded-full bg-primary/20 px-1.5 text-[10px] font-semibold tabular-nums", children: badge })
|
|
1093
|
+
]
|
|
1094
|
+
}
|
|
1095
|
+
) }),
|
|
1096
|
+
/* @__PURE__ */ jsx(
|
|
1097
|
+
PopoverContent,
|
|
1098
|
+
{
|
|
1099
|
+
align: "end",
|
|
1100
|
+
sideOffset: 8,
|
|
1101
|
+
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",
|
|
1102
|
+
children: inPanel
|
|
1103
|
+
}
|
|
1104
|
+
)
|
|
1105
|
+
] });
|
|
1106
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1107
|
+
wide && tagFilter,
|
|
1108
|
+
wide && filters,
|
|
1109
|
+
trigger
|
|
1110
|
+
] });
|
|
1111
|
+
}
|
|
1112
|
+
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
1113
|
function ListView({
|
|
1295
1114
|
columns,
|
|
1296
1115
|
data,
|
|
1297
1116
|
loading = false,
|
|
1298
1117
|
searchPlaceholder = "Search...",
|
|
1118
|
+
filtersLabel = "Filtros",
|
|
1119
|
+
advancedFilters,
|
|
1120
|
+
activeFilterCount = 0,
|
|
1121
|
+
advancedFilterCount,
|
|
1122
|
+
onClearFilters,
|
|
1123
|
+
clearFiltersLabel = "Clear",
|
|
1299
1124
|
search: controlledSearch,
|
|
1300
1125
|
onSearchChange,
|
|
1301
1126
|
searchDebounce = 300,
|
|
@@ -1316,6 +1141,9 @@ function ListView({
|
|
|
1316
1141
|
total,
|
|
1317
1142
|
page = 1,
|
|
1318
1143
|
pageSize = 25,
|
|
1144
|
+
rangeOfLabel = "of",
|
|
1145
|
+
prevPageLabel = "Previous page",
|
|
1146
|
+
nextPageLabel = "Next page",
|
|
1319
1147
|
onPageChange,
|
|
1320
1148
|
toolbar,
|
|
1321
1149
|
filters,
|
|
@@ -1404,9 +1232,34 @@ function ListView({
|
|
|
1404
1232
|
}
|
|
1405
1233
|
)
|
|
1406
1234
|
] }),
|
|
1407
|
-
(tagFilter || filters || onRefresh || onExport) &&
|
|
1408
|
-
|
|
1409
|
-
|
|
1235
|
+
(tagFilter || filters || advancedFilters || onRefresh || onExport) && // `flex-nowrap`: envolvendo, cada filtro a mais abria uma
|
|
1236
|
+
// linha nova sob a busca, e quatro deles gastavam três linhas
|
|
1237
|
+
// antes da primeira linha da tabela. No celular eles se
|
|
1238
|
+
// recolhem num gatilho (abaixo) e a linha volta a ser uma.
|
|
1239
|
+
/* @__PURE__ */ jsxs("div", { className: "ml-auto flex flex-nowrap items-center justify-end gap-2 md:flex-wrap", children: [
|
|
1240
|
+
/* @__PURE__ */ jsx(
|
|
1241
|
+
ListFilters,
|
|
1242
|
+
{
|
|
1243
|
+
tagFilter,
|
|
1244
|
+
filters,
|
|
1245
|
+
advanced: advancedFilters,
|
|
1246
|
+
label: filtersLabel,
|
|
1247
|
+
count: activeFilterCount,
|
|
1248
|
+
wideCount: advancedFilterCount ?? activeFilterCount
|
|
1249
|
+
}
|
|
1250
|
+
),
|
|
1251
|
+
onClearFilters && activeFilterCount > 0 && /* @__PURE__ */ jsxs(
|
|
1252
|
+
"button",
|
|
1253
|
+
{
|
|
1254
|
+
type: "button",
|
|
1255
|
+
onClick: onClearFilters,
|
|
1256
|
+
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",
|
|
1257
|
+
children: [
|
|
1258
|
+
/* @__PURE__ */ jsx(X, { className: "h-3 w-3 shrink-0" }),
|
|
1259
|
+
clearFiltersLabel
|
|
1260
|
+
]
|
|
1261
|
+
}
|
|
1262
|
+
),
|
|
1410
1263
|
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
1264
|
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
1265
|
] })
|
|
@@ -1426,40 +1279,46 @@ function ListView({
|
|
|
1426
1279
|
onSelectedIdsChange: selection.setSelectedIds,
|
|
1427
1280
|
getRowId
|
|
1428
1281
|
}
|
|
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
|
|
1282
|
+
),
|
|
1283
|
+
showPagination && /* @__PURE__ */ jsxs("div", { className: "-mt-px flex flex-wrap items-center justify-between gap-2 rounded-b-card border-t border-border px-3 py-2", children: [
|
|
1284
|
+
/* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", children: [
|
|
1285
|
+
(page - 1) * pageSize + 1,
|
|
1286
|
+
"\u2013",
|
|
1287
|
+
Math.min(page * pageSize, totalItems),
|
|
1288
|
+
" ",
|
|
1289
|
+
rangeOfLabel,
|
|
1290
|
+
" ",
|
|
1291
|
+
totalItems.toLocaleString()
|
|
1453
1292
|
] }),
|
|
1454
|
-
/* @__PURE__ */
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1293
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
1294
|
+
/* @__PURE__ */ jsx(
|
|
1295
|
+
"button",
|
|
1296
|
+
{
|
|
1297
|
+
type: "button",
|
|
1298
|
+
onClick: () => onPageChange(page - 1),
|
|
1299
|
+
disabled: page <= 1,
|
|
1300
|
+
"aria-label": prevPageLabel,
|
|
1301
|
+
className: PAGER_BTN,
|
|
1302
|
+
children: /* @__PURE__ */ jsx(ChevronLeft, { className: "h-4 w-4" })
|
|
1303
|
+
}
|
|
1304
|
+
),
|
|
1305
|
+
/* @__PURE__ */ jsxs("span", { className: "px-1 text-xs tabular-nums text-muted-foreground", children: [
|
|
1306
|
+
page,
|
|
1307
|
+
" / ",
|
|
1308
|
+
totalPages
|
|
1309
|
+
] }),
|
|
1310
|
+
/* @__PURE__ */ jsx(
|
|
1311
|
+
"button",
|
|
1312
|
+
{
|
|
1313
|
+
type: "button",
|
|
1314
|
+
onClick: () => onPageChange(page + 1),
|
|
1315
|
+
disabled: page >= totalPages,
|
|
1316
|
+
"aria-label": nextPageLabel,
|
|
1317
|
+
className: PAGER_BTN,
|
|
1318
|
+
children: /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4" })
|
|
1319
|
+
}
|
|
1320
|
+
)
|
|
1321
|
+
] })
|
|
1463
1322
|
] })
|
|
1464
1323
|
] })
|
|
1465
1324
|
] });
|
|
@@ -1667,7 +1526,7 @@ function toLocalISODate(d) {
|
|
|
1667
1526
|
}
|
|
1668
1527
|
function MiniCalendar({ selectedDate, onDateSelect, onMonthChange, markers }) {
|
|
1669
1528
|
const locale = getCurrentLocale();
|
|
1670
|
-
const [viewMonth, setViewMonth] =
|
|
1529
|
+
const [viewMonth, setViewMonth] = React15__default.useState(() => new Date(selectedDate.getFullYear(), selectedDate.getMonth(), 1));
|
|
1671
1530
|
const monthLabel = viewMonth.toLocaleDateString(toDateLocale2(locale), { month: "long", year: "numeric" });
|
|
1672
1531
|
const dayLabels = DAY_LABELS2[locale] ?? DAY_LABELS2.en;
|
|
1673
1532
|
const weeks = useMemo(() => {
|
|
@@ -1746,7 +1605,7 @@ function FilterSection({
|
|
|
1746
1605
|
defaultOpen = true,
|
|
1747
1606
|
children
|
|
1748
1607
|
}) {
|
|
1749
|
-
const [open, setOpen] =
|
|
1608
|
+
const [open, setOpen] = React15__default.useState(defaultOpen);
|
|
1750
1609
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1751
1610
|
/* @__PURE__ */ jsxs(
|
|
1752
1611
|
"button",
|
|
@@ -1819,7 +1678,7 @@ function FilterCheckList({
|
|
|
1819
1678
|
}
|
|
1820
1679
|
return /* @__PURE__ */ jsx("div", { className: className ? `${className} space-y-0.5` : "space-y-0.5", children: rows });
|
|
1821
1680
|
}
|
|
1822
|
-
var useIsomorphicLayoutEffect = typeof window !== "undefined" ?
|
|
1681
|
+
var useIsomorphicLayoutEffect = typeof window !== "undefined" ? React15.useLayoutEffect : React15.useEffect;
|
|
1823
1682
|
function SearchSelect({
|
|
1824
1683
|
value,
|
|
1825
1684
|
displayValue,
|
|
@@ -1843,18 +1702,18 @@ function SearchSelect({
|
|
|
1843
1702
|
"data-tour": dataTour
|
|
1844
1703
|
}) {
|
|
1845
1704
|
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
|
-
|
|
1705
|
+
const [open, setOpen] = React15.useState(false);
|
|
1706
|
+
const [query, setQuery] = React15.useState("");
|
|
1707
|
+
const [results, setResults] = React15.useState([]);
|
|
1708
|
+
const [loading, setLoading] = React15.useState(false);
|
|
1709
|
+
const [creating, setCreating] = React15.useState(false);
|
|
1710
|
+
const [selectedLabel, setSelectedLabel] = React15.useState(displayValue ?? "");
|
|
1711
|
+
const containerRef = React15.useRef(null);
|
|
1712
|
+
const inputRef = React15.useRef(null);
|
|
1713
|
+
const timerRef = React15.useRef();
|
|
1714
|
+
const [rect, setRect] = React15.useState(null);
|
|
1715
|
+
const dropdownRef = React15.useRef(null);
|
|
1716
|
+
React15.useEffect(() => {
|
|
1858
1717
|
function handler(e) {
|
|
1859
1718
|
const target = e.target;
|
|
1860
1719
|
if (containerRef.current?.contains(target)) return;
|
|
@@ -1864,10 +1723,10 @@ function SearchSelect({
|
|
|
1864
1723
|
document.addEventListener("mousedown", handler);
|
|
1865
1724
|
return () => document.removeEventListener("mousedown", handler);
|
|
1866
1725
|
}, []);
|
|
1867
|
-
|
|
1726
|
+
React15.useEffect(() => {
|
|
1868
1727
|
if (displayValue !== void 0) setSelectedLabel(displayValue);
|
|
1869
1728
|
}, [displayValue]);
|
|
1870
|
-
|
|
1729
|
+
React15.useEffect(() => {
|
|
1871
1730
|
if (open && loadOnOpen && query.length === 0 && results.length === 0 && !loading) {
|
|
1872
1731
|
setLoading(true);
|
|
1873
1732
|
Promise.resolve(onSearch("")).then(setResults).catch(() => setResults([])).finally(() => setLoading(false));
|
|
@@ -1925,7 +1784,7 @@ function SearchSelect({
|
|
|
1925
1784
|
setResults([]);
|
|
1926
1785
|
setTimeout(() => inputRef.current?.focus(), 0);
|
|
1927
1786
|
}
|
|
1928
|
-
const groups =
|
|
1787
|
+
const groups = React15.useMemo(() => {
|
|
1929
1788
|
const map = /* @__PURE__ */ new Map();
|
|
1930
1789
|
for (const opt of results) {
|
|
1931
1790
|
const group = opt.group ?? "";
|
|
@@ -2020,7 +1879,7 @@ function SearchSelect({
|
|
|
2020
1879
|
/* @__PURE__ */ jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin" }),
|
|
2021
1880
|
" ",
|
|
2022
1881
|
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(
|
|
1882
|
+
] }) : 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
1883
|
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
1884
|
options.map((opt) => /* @__PURE__ */ jsx(
|
|
2026
1885
|
"button",
|
|
@@ -2082,9 +1941,9 @@ function CurrencyInput({
|
|
|
2082
1941
|
className,
|
|
2083
1942
|
disabled
|
|
2084
1943
|
}) {
|
|
2085
|
-
const inputRef =
|
|
2086
|
-
const [focused, setFocused] =
|
|
2087
|
-
const format =
|
|
1944
|
+
const inputRef = React15.useRef(null);
|
|
1945
|
+
const [focused, setFocused] = React15.useState(false);
|
|
1946
|
+
const format = React15.useCallback((v) => {
|
|
2088
1947
|
return new Intl.NumberFormat(locale, {
|
|
2089
1948
|
minimumFractionDigits: 2,
|
|
2090
1949
|
maximumFractionDigits: 2
|
|
@@ -2154,24 +2013,125 @@ function CurrencyInput({
|
|
|
2154
2013
|
)
|
|
2155
2014
|
] });
|
|
2156
2015
|
}
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
)
|
|
2171
|
-
...props
|
|
2016
|
+
function formatRange(from, to, locale) {
|
|
2017
|
+
const parse = (s) => {
|
|
2018
|
+
const [y, m, d] = s.split("-").map(Number);
|
|
2019
|
+
return new Date(y, (m ?? 1) - 1, d ?? 1);
|
|
2020
|
+
};
|
|
2021
|
+
const day = (d) => String(d.getDate());
|
|
2022
|
+
const dayMonth = (d) => d.toLocaleDateString(locale, { day: "numeric", month: "short" }).replace(/\.$/, "");
|
|
2023
|
+
if (from && to) {
|
|
2024
|
+
const a = parse(from);
|
|
2025
|
+
const b = parse(to);
|
|
2026
|
+
if (a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth()) {
|
|
2027
|
+
return a.getDate() === b.getDate() ? dayMonth(a) : `${day(a)}\u2013${dayMonth(b)}`;
|
|
2028
|
+
}
|
|
2029
|
+
return `${dayMonth(a)} \u2013 ${dayMonth(b)}`;
|
|
2172
2030
|
}
|
|
2173
|
-
|
|
2174
|
-
|
|
2031
|
+
return dayMonth(parse(from || to));
|
|
2032
|
+
}
|
|
2033
|
+
function DateRangeChip({
|
|
2034
|
+
from,
|
|
2035
|
+
to,
|
|
2036
|
+
onChange,
|
|
2037
|
+
presets = [],
|
|
2038
|
+
preset,
|
|
2039
|
+
onPresetChange,
|
|
2040
|
+
allLabel,
|
|
2041
|
+
labels,
|
|
2042
|
+
label,
|
|
2043
|
+
className
|
|
2044
|
+
}) {
|
|
2045
|
+
const [open, setOpen] = React15.useState(false);
|
|
2046
|
+
const active = !!(from || to);
|
|
2047
|
+
const locale = typeof navigator !== "undefined" ? navigator.language : "en";
|
|
2048
|
+
const presetLabel = presets.find((p) => p.value === preset)?.label;
|
|
2049
|
+
const text = !active ? allLabel : presetLabel ?? formatRange(from, to, locale);
|
|
2050
|
+
return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
|
|
2051
|
+
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
2052
|
+
"button",
|
|
2053
|
+
{
|
|
2054
|
+
type: "button",
|
|
2055
|
+
"aria-label": label,
|
|
2056
|
+
className: cn(
|
|
2057
|
+
"inline-flex shrink-0 items-center gap-1 rounded-full border px-2.5 py-1 text-xs font-medium transition-colors",
|
|
2058
|
+
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",
|
|
2059
|
+
className
|
|
2060
|
+
),
|
|
2061
|
+
children: [
|
|
2062
|
+
/* @__PURE__ */ jsx(CalendarDays, { className: "h-3 w-3 shrink-0 opacity-70" }),
|
|
2063
|
+
/* @__PURE__ */ jsx("span", { className: "max-w-[12rem] truncate", children: text })
|
|
2064
|
+
]
|
|
2065
|
+
}
|
|
2066
|
+
) }),
|
|
2067
|
+
/* @__PURE__ */ jsxs(PopoverContent, { align: "start", sideOffset: 6, className: "w-60 p-1.5", children: [
|
|
2068
|
+
/* @__PURE__ */ jsxs(
|
|
2069
|
+
"button",
|
|
2070
|
+
{
|
|
2071
|
+
type: "button",
|
|
2072
|
+
onClick: () => {
|
|
2073
|
+
onPresetChange?.("all");
|
|
2074
|
+
onChange({ from: "", to: "" });
|
|
2075
|
+
setOpen(false);
|
|
2076
|
+
},
|
|
2077
|
+
className: "flex w-full items-center rounded-md px-2 py-1.5 text-sm transition-colors hover:bg-muted",
|
|
2078
|
+
children: [
|
|
2079
|
+
allLabel,
|
|
2080
|
+
!active && /* @__PURE__ */ jsx(Check, { className: "ml-auto h-3.5 w-3.5 shrink-0" })
|
|
2081
|
+
]
|
|
2082
|
+
}
|
|
2083
|
+
),
|
|
2084
|
+
presets.map((p) => /* @__PURE__ */ jsxs(
|
|
2085
|
+
"button",
|
|
2086
|
+
{
|
|
2087
|
+
type: "button",
|
|
2088
|
+
onClick: () => {
|
|
2089
|
+
onPresetChange?.(p.value);
|
|
2090
|
+
setOpen(false);
|
|
2091
|
+
},
|
|
2092
|
+
className: "flex w-full items-center rounded-md px-2 py-1.5 text-sm transition-colors hover:bg-muted",
|
|
2093
|
+
children: [
|
|
2094
|
+
p.label,
|
|
2095
|
+
active && preset === p.value && /* @__PURE__ */ jsx(Check, { className: "ml-auto h-3.5 w-3.5 shrink-0" })
|
|
2096
|
+
]
|
|
2097
|
+
},
|
|
2098
|
+
p.value
|
|
2099
|
+
)),
|
|
2100
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-1 space-y-1.5 border-t border-border px-2 pb-1 pt-2", children: [
|
|
2101
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
|
|
2102
|
+
/* @__PURE__ */ jsx("span", { className: "w-8 shrink-0", children: labels?.from ?? "From" }),
|
|
2103
|
+
/* @__PURE__ */ jsx(
|
|
2104
|
+
DatePicker,
|
|
2105
|
+
{
|
|
2106
|
+
value: from,
|
|
2107
|
+
onChange: (next) => {
|
|
2108
|
+
onPresetChange?.("custom");
|
|
2109
|
+
onChange({ from: next, to });
|
|
2110
|
+
},
|
|
2111
|
+
variant: "toolbar",
|
|
2112
|
+
className: "min-w-0 flex-1"
|
|
2113
|
+
}
|
|
2114
|
+
)
|
|
2115
|
+
] }),
|
|
2116
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
|
|
2117
|
+
/* @__PURE__ */ jsx("span", { className: "w-8 shrink-0", children: labels?.to ?? "To" }),
|
|
2118
|
+
/* @__PURE__ */ jsx(
|
|
2119
|
+
DatePicker,
|
|
2120
|
+
{
|
|
2121
|
+
value: to,
|
|
2122
|
+
onChange: (next) => {
|
|
2123
|
+
onPresetChange?.("custom");
|
|
2124
|
+
onChange({ from, to: next });
|
|
2125
|
+
},
|
|
2126
|
+
variant: "toolbar",
|
|
2127
|
+
className: "min-w-0 flex-1"
|
|
2128
|
+
}
|
|
2129
|
+
)
|
|
2130
|
+
] })
|
|
2131
|
+
] })
|
|
2132
|
+
] })
|
|
2133
|
+
] });
|
|
2134
|
+
}
|
|
2175
2135
|
function MultiSelect({
|
|
2176
2136
|
options,
|
|
2177
2137
|
value,
|
|
@@ -2183,9 +2143,9 @@ function MultiSelect({
|
|
|
2183
2143
|
className,
|
|
2184
2144
|
searchThreshold = 8
|
|
2185
2145
|
}) {
|
|
2186
|
-
const [query, setQuery] =
|
|
2187
|
-
const selected =
|
|
2188
|
-
const filtered =
|
|
2146
|
+
const [query, setQuery] = React15.useState("");
|
|
2147
|
+
const selected = React15.useMemo(() => new Set(value), [value]);
|
|
2148
|
+
const filtered = React15.useMemo(() => {
|
|
2189
2149
|
const q = query.trim().toLowerCase();
|
|
2190
2150
|
if (!q) return options;
|
|
2191
2151
|
return options.filter((o) => o.label.toLowerCase().includes(q));
|
|
@@ -2280,7 +2240,7 @@ function renderInline(text, keyPrefix) {
|
|
|
2280
2240
|
if (part.startsWith("`") && part.endsWith("`") && part.length > 2) {
|
|
2281
2241
|
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
2242
|
}
|
|
2283
|
-
return part === "" ? null : /* @__PURE__ */ jsx(
|
|
2243
|
+
return part === "" ? null : /* @__PURE__ */ jsx(React15.Fragment, { children: part }, key);
|
|
2284
2244
|
});
|
|
2285
2245
|
}
|
|
2286
2246
|
function parseBlocks(source) {
|
|
@@ -2364,7 +2324,7 @@ function renderMarkdown(source) {
|
|
|
2364
2324
|
case "ol":
|
|
2365
2325
|
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
2326
|
case "p":
|
|
2367
|
-
return /* @__PURE__ */ jsx("p", { children: block.lines.map((l, li) => /* @__PURE__ */ jsxs(
|
|
2327
|
+
return /* @__PURE__ */ jsx("p", { children: block.lines.map((l, li) => /* @__PURE__ */ jsxs(React15.Fragment, { children: [
|
|
2368
2328
|
li > 0 && /* @__PURE__ */ jsx("br", {}),
|
|
2369
2329
|
renderInline(l, `${key}-${li}`)
|
|
2370
2330
|
] }, `${key}-${li}`)) }, key);
|
|
@@ -2385,7 +2345,7 @@ function MarkdownEditor({
|
|
|
2385
2345
|
renderPreview,
|
|
2386
2346
|
className
|
|
2387
2347
|
}) {
|
|
2388
|
-
const [mode, setMode] =
|
|
2348
|
+
const [mode, setMode] = React15.useState(
|
|
2389
2349
|
defaultMode === "preview" && value.trim() === "" ? "edit" : defaultMode
|
|
2390
2350
|
);
|
|
2391
2351
|
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-2", className), children: [
|
|
@@ -2679,13 +2639,13 @@ function StockEntryForm({
|
|
|
2679
2639
|
labels: overrides
|
|
2680
2640
|
}) {
|
|
2681
2641
|
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
|
-
|
|
2642
|
+
const [quantity, setQuantity] = React15.useState("");
|
|
2643
|
+
const [reasonCode, setReasonCode] = React15.useState("");
|
|
2644
|
+
const [occurredOn, setOccurredOn] = React15.useState(todayISO());
|
|
2645
|
+
const [note, setNote] = React15.useState("");
|
|
2646
|
+
const [noteOpen, setNoteOpen] = React15.useState(false);
|
|
2647
|
+
const quantityRef = React15.useRef(null);
|
|
2648
|
+
React15.useEffect(() => {
|
|
2689
2649
|
if (verb === null) return;
|
|
2690
2650
|
setQuantity("");
|
|
2691
2651
|
setReasonCode("");
|
|
@@ -2811,6 +2771,6 @@ function StockEntryForm({
|
|
|
2811
2771
|
] }) });
|
|
2812
2772
|
}
|
|
2813
2773
|
|
|
2814
|
-
export { Badge, Breadcrumb, BulkActionBar, ChevronPager, CurrencyInput, DatePicker, DotBadge, DraftCommitBar, FilterCheckBox, FilterCheckList, FilterCheckRow, FilterChip, FilterSection,
|
|
2815
|
-
//# sourceMappingURL=chunk-
|
|
2816
|
-
//# sourceMappingURL=chunk-
|
|
2774
|
+
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 };
|
|
2775
|
+
//# sourceMappingURL=chunk-XEUIYSW2.js.map
|
|
2776
|
+
//# sourceMappingURL=chunk-XEUIYSW2.js.map
|