@fayz-ai/ui 0.18.0 → 0.21.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/derive.d.ts +1 -9
- package/dist/analytics/derive.d.ts.map +1 -1
- package/dist/chunk-AIUHVTVK.js +205 -0
- package/dist/chunk-AIUHVTVK.js.map +1 -0
- package/dist/{chunk-OBIU37AX.js → chunk-EGHEU3U5.js} +156 -48
- package/dist/chunk-EGHEU3U5.js.map +1 -0
- package/dist/{chunk-3OVZ5JJQ.js → chunk-GLRLWBBF.js} +4 -3
- package/dist/chunk-GLRLWBBF.js.map +1 -0
- package/dist/{chunk-ZLPYNHXH.js → chunk-MBGTFL4I.js} +3 -3
- package/dist/{chunk-ZLPYNHXH.js.map → chunk-MBGTFL4I.js.map} +1 -1
- package/dist/{chunk-AASANYXN.js → chunk-OB2ULDBD.js} +6 -4
- package/dist/chunk-OB2ULDBD.js.map +1 -0
- package/dist/{chunk-Z2ITFPGL.js → chunk-OYH7CEMB.js} +609 -173
- package/dist/chunk-OYH7CEMB.js.map +1 -0
- package/dist/{chunk-DFOAKWYB.js → chunk-P3YTL3MF.js} +140 -16
- package/dist/chunk-P3YTL3MF.js.map +1 -0
- package/dist/dashboard/index.js +2 -2
- package/dist/icons.d.ts.map +1 -1
- package/dist/icons.js +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -25
- package/dist/index.js.map +1 -1
- package/dist/layout/AppShell.d.ts +9 -1
- package/dist/layout/AppShell.d.ts.map +1 -1
- package/dist/layout/ModulePage.d.ts +13 -0
- package/dist/layout/ModulePage.d.ts.map +1 -1
- package/dist/layout/SaveBar.d.ts +10 -1
- package/dist/layout/SaveBar.d.ts.map +1 -1
- package/dist/layout/Sidebar.d.ts +7 -1
- package/dist/layout/Sidebar.d.ts.map +1 -1
- package/dist/layout/Takeover.d.ts +31 -0
- package/dist/layout/Takeover.d.ts.map +1 -0
- package/dist/layout/index.d.ts +1 -0
- package/dist/layout/index.d.ts.map +1 -1
- package/dist/layout/index.js +3 -3
- package/dist/lib/error-message.d.ts +2 -0
- package/dist/lib/error-message.d.ts.map +1 -0
- package/dist/primitives/brand-marks.d.ts +11 -0
- package/dist/primitives/brand-marks.d.ts.map +1 -0
- package/dist/primitives/button.d.ts +1 -1
- package/dist/primitives/dot-badge.d.ts +27 -0
- package/dist/primitives/dot-badge.d.ts.map +1 -0
- package/dist/primitives/draft-commit-bar.d.ts +27 -0
- package/dist/primitives/draft-commit-bar.d.ts.map +1 -0
- package/dist/primitives/filter-check-list.d.ts +65 -0
- package/dist/primitives/filter-check-list.d.ts.map +1 -0
- package/dist/primitives/header-tabs.d.ts +35 -0
- package/dist/primitives/header-tabs.d.ts.map +1 -1
- package/dist/primitives/image-drop.d.ts.map +1 -1
- package/dist/primitives/index.d.ts +6 -0
- package/dist/primitives/index.d.ts.map +1 -1
- package/dist/primitives/index.js +4 -4
- package/dist/primitives/list-chrome.d.ts +5 -1
- package/dist/primitives/list-chrome.d.ts.map +1 -1
- package/dist/primitives/list-view.d.ts.map +1 -1
- package/dist/primitives/mini-calendar.d.ts +36 -0
- package/dist/primitives/mini-calendar.d.ts.map +1 -0
- package/dist/primitives/multi-select.d.ts +21 -0
- package/dist/primitives/multi-select.d.ts.map +1 -0
- package/dist/primitives/page-actions.d.ts.map +1 -1
- package/dist/primitives/refresh-button.d.ts.map +1 -1
- package/dist/primitives/row-actions.d.ts.map +1 -1
- package/dist/primitives/select.d.ts.map +1 -1
- package/dist/primitives/stock-entry-form.d.ts +52 -0
- package/dist/primitives/stock-entry-form.d.ts.map +1 -0
- package/dist/styles.css +124 -0
- package/dist/tailwind.cjs +1 -1
- package/dist/tailwind.cjs.map +1 -1
- package/dist/tailwind.js +1 -1
- package/dist/tailwind.js.map +1 -1
- package/dist/wizard/index.js +2 -2
- package/dist/wizard/useWizard.d.ts.map +1 -1
- package/package.json +2 -2
- package/dist/chunk-3OVZ5JJQ.js.map +0 -1
- package/dist/chunk-4GK6IHOI.js +0 -177
- package/dist/chunk-4GK6IHOI.js.map +0 -1
- package/dist/chunk-AASANYXN.js.map +0 -1
- package/dist/chunk-DFOAKWYB.js.map +0 -1
- package/dist/chunk-OBIU37AX.js.map +0 -1
- package/dist/chunk-Z2ITFPGL.js.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { useSaveBarVisible, useCrossModuleBack, useBackHandler, PageHeaderActions } from './chunk-
|
|
2
|
-
import { useIsWide, Dropdown, DropdownTrigger, DropdownContent, DropdownSeparator, DropdownItem, Card, DataTable } from './chunk-E44WOPCR.js';
|
|
1
|
+
import { useSaveBarVisible, useCrossModuleBack, useBackHandler, PageHeaderActions, SegmentedControl } from './chunk-EGHEU3U5.js';
|
|
2
|
+
import { useIsWide, Dropdown, DropdownTrigger, DropdownContent, DropdownSeparator, DropdownItem, Card, DataTable, Checkbox } from './chunk-E44WOPCR.js';
|
|
3
3
|
import { cn, Button } from './chunk-OKZ6WQB3.js';
|
|
4
|
-
import * as
|
|
5
|
-
import { useState, useRef, useEffect, useMemo, useCallback } from 'react';
|
|
4
|
+
import * as React18 from 'react';
|
|
5
|
+
import React18__default, { useState, useRef, useEffect, useMemo, useCallback } from 'react';
|
|
6
6
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
7
7
|
import { cva } from 'class-variance-authority';
|
|
8
8
|
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
@@ -17,9 +17,9 @@ import { createPortal } from 'react-dom';
|
|
|
17
17
|
import { useTranslation, getCountry, unmaskPhone, maskPhone, getCurrentLocale } from '@fayz-ai/core';
|
|
18
18
|
import * as PopoverPrimitive from '@radix-ui/react-popover';
|
|
19
19
|
|
|
20
|
-
var Input =
|
|
20
|
+
var Input = React18.forwardRef(
|
|
21
21
|
({ className, type, error, description, id, ...props }, ref) => {
|
|
22
|
-
const inputId = id ??
|
|
22
|
+
const inputId = id ?? React18.useId();
|
|
23
23
|
const descriptionId = description ? `${inputId}-description` : void 0;
|
|
24
24
|
const errorId = error ? `${inputId}-error` : void 0;
|
|
25
25
|
return /* @__PURE__ */ jsxs("div", { className: "w-full", children: [
|
|
@@ -107,7 +107,7 @@ var Modal = DialogPrimitive.Root;
|
|
|
107
107
|
var ModalTrigger = DialogPrimitive.Trigger;
|
|
108
108
|
var ModalClose = DialogPrimitive.Close;
|
|
109
109
|
var ModalPortal = DialogPrimitive.Portal;
|
|
110
|
-
var ModalOverlay =
|
|
110
|
+
var ModalOverlay = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
111
111
|
DialogPrimitive.Overlay,
|
|
112
112
|
{
|
|
113
113
|
ref,
|
|
@@ -120,7 +120,7 @@ var ModalOverlay = React16.forwardRef(({ className, ...props }, ref) => /* @__PU
|
|
|
120
120
|
}
|
|
121
121
|
));
|
|
122
122
|
ModalOverlay.displayName = "ModalOverlay";
|
|
123
|
-
var ModalContent =
|
|
123
|
+
var ModalContent = React18.forwardRef(({ className, children, size = "lg", hideClose, noPadding, onPointerDownOutside, onInteractOutside, onCloseAutoFocus, ...props }, ref) => /* @__PURE__ */ jsx(ModalPortal, { children: /* @__PURE__ */ jsx(ModalOverlay, { children: /* @__PURE__ */ jsxs(
|
|
124
124
|
DialogPrimitive.Content,
|
|
125
125
|
{
|
|
126
126
|
ref,
|
|
@@ -175,14 +175,14 @@ function ModalBody({ className, ...props }) {
|
|
|
175
175
|
function ModalFooter({ className, ...props }) {
|
|
176
176
|
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
177
|
}
|
|
178
|
-
var ModalTitle =
|
|
178
|
+
var ModalTitle = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Title, { ref, className: cn("text-lg font-semibold leading-none tracking-tight", className), ...props }));
|
|
179
179
|
ModalTitle.displayName = "ModalTitle";
|
|
180
|
-
var ModalDescription =
|
|
180
|
+
var ModalDescription = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Description, { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
|
|
181
181
|
ModalDescription.displayName = "ModalDescription";
|
|
182
182
|
var Select = SelectPrimitive.Root;
|
|
183
183
|
var SelectGroup = SelectPrimitive.Group;
|
|
184
184
|
var SelectValue = SelectPrimitive.Value;
|
|
185
|
-
var SelectTrigger =
|
|
185
|
+
var SelectTrigger = React18.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
186
186
|
SelectPrimitive.Trigger,
|
|
187
187
|
{
|
|
188
188
|
ref,
|
|
@@ -198,7 +198,7 @@ var SelectTrigger = React16.forwardRef(({ className, children, ...props }, ref)
|
|
|
198
198
|
}
|
|
199
199
|
));
|
|
200
200
|
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
|
|
201
|
-
var SelectScrollUpButton =
|
|
201
|
+
var SelectScrollUpButton = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
202
202
|
SelectPrimitive.ScrollUpButton,
|
|
203
203
|
{
|
|
204
204
|
ref,
|
|
@@ -211,7 +211,7 @@ var SelectScrollUpButton = React16.forwardRef(({ className, ...props }, ref) =>
|
|
|
211
211
|
}
|
|
212
212
|
));
|
|
213
213
|
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
|
|
214
|
-
var SelectScrollDownButton =
|
|
214
|
+
var SelectScrollDownButton = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
215
215
|
SelectPrimitive.ScrollDownButton,
|
|
216
216
|
{
|
|
217
217
|
ref,
|
|
@@ -224,7 +224,7 @@ var SelectScrollDownButton = React16.forwardRef(({ className, ...props }, ref) =
|
|
|
224
224
|
}
|
|
225
225
|
));
|
|
226
226
|
SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
|
|
227
|
-
var SelectContent =
|
|
227
|
+
var SelectContent = React18.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
|
|
228
228
|
SelectPrimitive.Content,
|
|
229
229
|
{
|
|
230
230
|
ref,
|
|
@@ -252,16 +252,19 @@ var SelectContent = React16.forwardRef(({ className, children, position = "poppe
|
|
|
252
252
|
}
|
|
253
253
|
) }));
|
|
254
254
|
SelectContent.displayName = SelectPrimitive.Content.displayName;
|
|
255
|
-
var SelectLabel =
|
|
255
|
+
var SelectLabel = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
256
256
|
SelectPrimitive.Label,
|
|
257
257
|
{
|
|
258
258
|
ref,
|
|
259
|
-
className: cn(
|
|
259
|
+
className: cn(
|
|
260
|
+
"mt-1.5 px-2 py-1 text-[11px] font-medium uppercase tracking-wide text-muted-foreground first:mt-0",
|
|
261
|
+
className
|
|
262
|
+
),
|
|
260
263
|
...props
|
|
261
264
|
}
|
|
262
265
|
));
|
|
263
266
|
SelectLabel.displayName = SelectPrimitive.Label.displayName;
|
|
264
|
-
var SelectItem =
|
|
267
|
+
var SelectItem = React18.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
265
268
|
SelectPrimitive.Item,
|
|
266
269
|
{
|
|
267
270
|
ref,
|
|
@@ -277,7 +280,7 @@ var SelectItem = React16.forwardRef(({ className, children, ...props }, ref) =>
|
|
|
277
280
|
}
|
|
278
281
|
));
|
|
279
282
|
SelectItem.displayName = SelectPrimitive.Item.displayName;
|
|
280
|
-
var SelectSeparator =
|
|
283
|
+
var SelectSeparator = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
281
284
|
SelectPrimitive.Separator,
|
|
282
285
|
{
|
|
283
286
|
ref,
|
|
@@ -315,7 +318,7 @@ function ToastProvider({
|
|
|
315
318
|
);
|
|
316
319
|
}
|
|
317
320
|
var Tabs = TabsPrimitive.Root;
|
|
318
|
-
var TabsList =
|
|
321
|
+
var TabsList = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
319
322
|
TabsPrimitive.List,
|
|
320
323
|
{
|
|
321
324
|
ref,
|
|
@@ -329,7 +332,7 @@ var TabsList = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__
|
|
|
329
332
|
}
|
|
330
333
|
));
|
|
331
334
|
TabsList.displayName = TabsPrimitive.List.displayName;
|
|
332
|
-
var TabsTrigger =
|
|
335
|
+
var TabsTrigger = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
333
336
|
TabsPrimitive.Trigger,
|
|
334
337
|
{
|
|
335
338
|
ref,
|
|
@@ -341,7 +344,7 @@ var TabsTrigger = React16.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
341
344
|
}
|
|
342
345
|
));
|
|
343
346
|
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
|
|
344
|
-
var TabsContent =
|
|
347
|
+
var TabsContent = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
345
348
|
TabsPrimitive.Content,
|
|
346
349
|
{
|
|
347
350
|
ref,
|
|
@@ -353,7 +356,7 @@ var TabsContent = React16.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
353
356
|
}
|
|
354
357
|
));
|
|
355
358
|
TabsContent.displayName = TabsPrimitive.Content.displayName;
|
|
356
|
-
var Separator2 =
|
|
359
|
+
var Separator2 = React18.forwardRef(
|
|
357
360
|
({ className, orientation = "horizontal", decorative = true, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
358
361
|
SeparatorPrimitive.Root,
|
|
359
362
|
{
|
|
@@ -404,7 +407,7 @@ function formatPhone(digits, fallback, countryCode) {
|
|
|
404
407
|
const tail = rest.length === 9 ? rest.slice(5) : rest.slice(4);
|
|
405
408
|
return `+55 (${ddd}) ${head}-${tail}`;
|
|
406
409
|
}
|
|
407
|
-
var PhoneLink =
|
|
410
|
+
var PhoneLink = React18.forwardRef(
|
|
408
411
|
({ phone, message, countryCode, raw, className, children, ...props }, ref) => {
|
|
409
412
|
const { e164, display } = normalizePhone(phone, countryCode);
|
|
410
413
|
const label = children ?? (raw ? phone ?? "" : display);
|
|
@@ -467,7 +470,7 @@ function Breadcrumb({ parent, current, onBack }) {
|
|
|
467
470
|
var TooltipProvider = TooltipPrimitive.Provider;
|
|
468
471
|
var Tooltip = TooltipPrimitive.Root;
|
|
469
472
|
var TooltipTrigger = TooltipPrimitive.Trigger;
|
|
470
|
-
var TooltipContent =
|
|
473
|
+
var TooltipContent = React18.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
471
474
|
TooltipPrimitive.Content,
|
|
472
475
|
{
|
|
473
476
|
ref,
|
|
@@ -480,6 +483,13 @@ var TooltipContent = React16.forwardRef(({ className, sideOffset = 4, ...props }
|
|
|
480
483
|
}
|
|
481
484
|
));
|
|
482
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
|
+
});
|
|
483
493
|
function iconOf(action, className) {
|
|
484
494
|
const Icon2 = action.icon;
|
|
485
495
|
return Icon2 ? /* @__PURE__ */ jsx(Icon2, { className }) : null;
|
|
@@ -517,20 +527,24 @@ function PageActionBar({ actions, className }) {
|
|
|
517
527
|
const head = primary[0];
|
|
518
528
|
const menu = [...secondary, ...danger];
|
|
519
529
|
return /* @__PURE__ */ jsxs("div", { className: cn("flex shrink-0 items-center gap-2", className), children: [
|
|
520
|
-
utility.map((a) =>
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
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)
|
|
534
548
|
)),
|
|
535
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: [
|
|
536
550
|
iconOf(head, "mr-1.5 h-4 w-4"),
|
|
@@ -542,7 +556,7 @@ function PageActionBar({ actions, className }) {
|
|
|
542
556
|
head.label
|
|
543
557
|
] }),
|
|
544
558
|
/* @__PURE__ */ jsxs(Dropdown, { children: [
|
|
545
|
-
/* @__PURE__ */ jsx(DropdownTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
559
|
+
/* @__PURE__ */ jsx(DropdownTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Hint, { label: `${head.label}\u2026`, children: /* @__PURE__ */ jsx(
|
|
546
560
|
Button,
|
|
547
561
|
{
|
|
548
562
|
className: "-ml-px rounded-l-none px-2",
|
|
@@ -550,12 +564,12 @@ function PageActionBar({ actions, className }) {
|
|
|
550
564
|
"data-tour": menu.map((a) => `action.${a.id}`).join(" "),
|
|
551
565
|
children: /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4" })
|
|
552
566
|
}
|
|
553
|
-
) }),
|
|
567
|
+
) }) }),
|
|
554
568
|
/* @__PURE__ */ jsx(DropdownContent, { align: "end", className: "w-56", children: /* @__PURE__ */ jsx(ActionItems, { actions: menu }) })
|
|
555
569
|
] })
|
|
556
570
|
] }),
|
|
557
571
|
!head && menu.length > 0 && /* @__PURE__ */ jsxs(Dropdown, { children: [
|
|
558
|
-
/* @__PURE__ */ jsx(DropdownTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: "outline", size: "icon", "aria-label": "A\xE7\xF5es", children: /* @__PURE__ */ jsx(MoreHorizontal, { className: "h-4 w-4" }) }) }),
|
|
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" }) }) }) }),
|
|
559
573
|
/* @__PURE__ */ jsx(DropdownContent, { align: "end", className: "w-56", children: /* @__PURE__ */ jsx(ActionItems, { actions: menu }) })
|
|
560
574
|
] })
|
|
561
575
|
] });
|
|
@@ -601,9 +615,9 @@ function PageActionFab({ actions }) {
|
|
|
601
615
|
] });
|
|
602
616
|
}
|
|
603
617
|
function useScrim(open) {
|
|
604
|
-
const [mounted, setMounted] =
|
|
605
|
-
const [visible, setVisible] =
|
|
606
|
-
|
|
618
|
+
const [mounted, setMounted] = React18.useState(open);
|
|
619
|
+
const [visible, setVisible] = React18.useState(open);
|
|
620
|
+
React18.useEffect(() => {
|
|
607
621
|
if (open) {
|
|
608
622
|
setMounted(true);
|
|
609
623
|
const frame = requestAnimationFrame(() => setVisible(true));
|
|
@@ -617,7 +631,7 @@ function useScrim(open) {
|
|
|
617
631
|
}
|
|
618
632
|
var SCRIM_MS = 200;
|
|
619
633
|
function FabButton({ actions, tone, mini }) {
|
|
620
|
-
const [open, setOpen] =
|
|
634
|
+
const [open, setOpen] = React18.useState(false);
|
|
621
635
|
const scrim = useScrim(open);
|
|
622
636
|
if (actions.length === 0) return null;
|
|
623
637
|
const isCreate = tone === "primary";
|
|
@@ -698,24 +712,25 @@ function RowActions({
|
|
|
698
712
|
return /* @__PURE__ */ jsxs("div", { className: cn("flex shrink-0 items-center justify-end gap-0.5", className), onClick: stop, children: [
|
|
699
713
|
inline.map((a) => {
|
|
700
714
|
const Icon2 = a.icon;
|
|
701
|
-
return
|
|
702
|
-
|
|
703
|
-
{
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
+
return (
|
|
716
|
+
// Uma linha de tabela com três ícones cinza é três adivinhações.
|
|
717
|
+
/* @__PURE__ */ jsx(Hint, { label: a.label, children: /* @__PURE__ */ jsx(
|
|
718
|
+
Button,
|
|
719
|
+
{
|
|
720
|
+
variant: "ghost",
|
|
721
|
+
size: "icon",
|
|
722
|
+
className: "fz-tap text-muted-foreground",
|
|
723
|
+
onClick: () => void a.onSelect(),
|
|
724
|
+
disabled: a.disabled,
|
|
725
|
+
"aria-label": a.label,
|
|
726
|
+
"data-testid": a.testId,
|
|
727
|
+
children: Icon2 ? /* @__PURE__ */ jsx(Icon2, { className: "h-4 w-4" }) : null
|
|
728
|
+
}
|
|
729
|
+
) }, a.id)
|
|
715
730
|
);
|
|
716
731
|
}),
|
|
717
732
|
overflow.length > 0 && /* @__PURE__ */ jsxs(Dropdown, { children: [
|
|
718
|
-
/* @__PURE__ */ jsx(DropdownTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
733
|
+
/* @__PURE__ */ jsx(DropdownTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Hint, { label: rowActionsLabel, children: /* @__PURE__ */ jsx(
|
|
719
734
|
Button,
|
|
720
735
|
{
|
|
721
736
|
variant: "ghost",
|
|
@@ -724,12 +739,12 @@ function RowActions({
|
|
|
724
739
|
"aria-label": rowActionsLabel,
|
|
725
740
|
children: /* @__PURE__ */ jsx(MoreHorizontal, { className: "h-4 w-4" })
|
|
726
741
|
}
|
|
727
|
-
) }),
|
|
742
|
+
) }) }),
|
|
728
743
|
/* @__PURE__ */ jsx(DropdownContent, { align: "end", className: "w-52", children: overflow.map((a, i) => {
|
|
729
744
|
const Icon2 = a.icon;
|
|
730
745
|
const isDanger = a.intent === "danger";
|
|
731
746
|
const prevSafe = i > 0 && overflow[i - 1].intent !== "danger";
|
|
732
|
-
return /* @__PURE__ */ jsxs(
|
|
747
|
+
return /* @__PURE__ */ jsxs(React18.Fragment, { children: [
|
|
733
748
|
isDanger && prevSafe && /* @__PURE__ */ jsx(DropdownSeparator, {}),
|
|
734
749
|
/* @__PURE__ */ jsxs(
|
|
735
750
|
DropdownItem,
|
|
@@ -753,8 +768,8 @@ var rowActionsLabel = "A\xE7\xF5es";
|
|
|
753
768
|
function setRowActionsLabel(label) {
|
|
754
769
|
rowActionsLabel = label;
|
|
755
770
|
}
|
|
756
|
-
function SearchField({ value, onChange, placeholder, ...rest }) {
|
|
757
|
-
return /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
771
|
+
function SearchField({ value, onChange, placeholder, className, ...rest }) {
|
|
772
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("relative", className), children: [
|
|
758
773
|
/* @__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" }),
|
|
759
774
|
/* @__PURE__ */ jsx(
|
|
760
775
|
"input",
|
|
@@ -897,6 +912,46 @@ function BulkActionBar({
|
|
|
897
912
|
);
|
|
898
913
|
}
|
|
899
914
|
BulkActionBar.displayName = "BulkActionBar";
|
|
915
|
+
function DraftCommitBar({
|
|
916
|
+
open,
|
|
917
|
+
title,
|
|
918
|
+
hint,
|
|
919
|
+
icon: Icon2,
|
|
920
|
+
commitLabel,
|
|
921
|
+
onCommit,
|
|
922
|
+
discardLabel,
|
|
923
|
+
onDiscard,
|
|
924
|
+
busy,
|
|
925
|
+
commitDisabledReason,
|
|
926
|
+
className
|
|
927
|
+
}) {
|
|
928
|
+
if (!open) return null;
|
|
929
|
+
return /* @__PURE__ */ jsxs(
|
|
930
|
+
"div",
|
|
931
|
+
{
|
|
932
|
+
role: "region",
|
|
933
|
+
"aria-label": title,
|
|
934
|
+
className: cn(
|
|
935
|
+
"sticky bottom-3 z-10 flex flex-wrap items-center gap-3 rounded-card border bg-card px-4 py-2.5 shadow-lg",
|
|
936
|
+
className
|
|
937
|
+
),
|
|
938
|
+
children: [
|
|
939
|
+
Icon2 && /* @__PURE__ */ jsx(Icon2, { className: "h-4 w-4 shrink-0 text-primary" }),
|
|
940
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
941
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: title }),
|
|
942
|
+
(commitDisabledReason || hint) && /* @__PURE__ */ jsx("p", { className: cn("text-[11px]", commitDisabledReason ? "text-warning" : "text-muted-foreground"), children: commitDisabledReason || hint })
|
|
943
|
+
] }),
|
|
944
|
+
onDiscard && discardLabel && /* @__PURE__ */ jsx(Button, { variant: "outline", size: "sm", onClick: onDiscard, disabled: busy, children: discardLabel }),
|
|
945
|
+
/* @__PURE__ */ jsxs(Button, { size: "sm", onClick: onCommit, disabled: busy || Boolean(commitDisabledReason), children: [
|
|
946
|
+
/* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5" }),
|
|
947
|
+
" ",
|
|
948
|
+
commitLabel
|
|
949
|
+
] })
|
|
950
|
+
]
|
|
951
|
+
}
|
|
952
|
+
);
|
|
953
|
+
}
|
|
954
|
+
DraftCommitBar.displayName = "DraftCommitBar";
|
|
900
955
|
var SIZE_CLASSES = {
|
|
901
956
|
sm: "h-8 w-8 rounded",
|
|
902
957
|
md: "h-9 w-9 rounded",
|
|
@@ -908,8 +963,8 @@ var ICON_CLASSES = {
|
|
|
908
963
|
lg: "h-5 w-5"
|
|
909
964
|
};
|
|
910
965
|
function Thumbnail({ src, alt = "", size = "md", icon: Icon2 = ImageIcon, className }) {
|
|
911
|
-
const [failed, setFailed] =
|
|
912
|
-
|
|
966
|
+
const [failed, setFailed] = React18.useState(false);
|
|
967
|
+
React18.useEffect(() => {
|
|
913
968
|
setFailed(false);
|
|
914
969
|
}, [src]);
|
|
915
970
|
const base = cn("shrink-0 overflow-hidden", SIZE_CLASSES[size], className);
|
|
@@ -936,9 +991,9 @@ function Thumbnail({ src, alt = "", size = "md", icon: Icon2 = ImageIcon, classN
|
|
|
936
991
|
}
|
|
937
992
|
Thumbnail.displayName = "Thumbnail";
|
|
938
993
|
function RefreshButton({ onRefresh, fromCache, label, labelCached, className, ...rest }) {
|
|
939
|
-
const [phase, setPhase] =
|
|
940
|
-
const alive =
|
|
941
|
-
|
|
994
|
+
const [phase, setPhase] = React18.useState("idle");
|
|
995
|
+
const alive = React18.useRef(true);
|
|
996
|
+
React18.useEffect(() => () => {
|
|
942
997
|
alive.current = false;
|
|
943
998
|
}, []);
|
|
944
999
|
const title = fromCache ? labelCached ?? label : label;
|
|
@@ -955,28 +1010,31 @@ function RefreshButton({ onRefresh, fromCache, label, labelCached, className, ..
|
|
|
955
1010
|
if (alive.current) setPhase((p) => p === "done" ? "idle" : p);
|
|
956
1011
|
}, 1400);
|
|
957
1012
|
}
|
|
958
|
-
return
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
1013
|
+
return (
|
|
1014
|
+
// Só o ícone: sem o tooltip do design system, o que este botão faz depende
|
|
1015
|
+
// de o usuário arriscar um clique. `title=` não conta — ver Hint.
|
|
1016
|
+
/* @__PURE__ */ jsx(Hint, { label: title, children: /* @__PURE__ */ jsx(
|
|
1017
|
+
Button,
|
|
1018
|
+
{
|
|
1019
|
+
type: "button",
|
|
1020
|
+
variant: "ghost",
|
|
1021
|
+
size: "icon",
|
|
1022
|
+
"aria-label": title,
|
|
1023
|
+
onClick: () => {
|
|
1024
|
+
void run();
|
|
1025
|
+
},
|
|
1026
|
+
className: cn(
|
|
1027
|
+
// The state colours are the point of this control, so they stay; what
|
|
1028
|
+
// it was missing is the shared button underneath them.
|
|
1029
|
+
"transition",
|
|
1030
|
+
fromCache && phase !== "done" && "text-amber-600 hover:text-amber-700 dark:text-amber-500 dark:hover:text-amber-400",
|
|
1031
|
+
phase === "done" && "text-emerald-600 dark:text-emerald-500",
|
|
1032
|
+
className
|
|
1033
|
+
),
|
|
1034
|
+
...rest,
|
|
1035
|
+
children: phase === "done" ? /* @__PURE__ */ jsx(Check, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx(RefreshCw, { className: cn("h-4 w-4", phase === "busy" && "animate-spin") })
|
|
1036
|
+
}
|
|
1037
|
+
) })
|
|
980
1038
|
);
|
|
981
1039
|
}
|
|
982
1040
|
RefreshButton.displayName = "RefreshButton";
|
|
@@ -1032,13 +1090,6 @@ function StatTiles({ tiles, loading, className }) {
|
|
|
1032
1090
|
] }, tile.id);
|
|
1033
1091
|
}) });
|
|
1034
1092
|
}
|
|
1035
|
-
var Hint = React16.forwardRef(function Hint2({ label, children, side = "top", delayDuration = 0, ...rest }, ref) {
|
|
1036
|
-
if (!label) return React16.cloneElement(children, { ...rest, ref });
|
|
1037
|
-
return /* @__PURE__ */ jsx(TooltipPrimitive.Provider, { delayDuration, children: /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
1038
|
-
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, ...rest, ref, children }),
|
|
1039
|
-
/* @__PURE__ */ jsx(TooltipContent, { side, className: "px-2 py-1 text-xs font-medium", children: label })
|
|
1040
|
-
] }) });
|
|
1041
|
-
});
|
|
1042
1093
|
function formatTime12(h, m) {
|
|
1043
1094
|
const period = h >= 12 ? "pm" : "am";
|
|
1044
1095
|
const h12 = h % 12 || 12;
|
|
@@ -1160,27 +1211,27 @@ function useRowSelection({
|
|
|
1160
1211
|
getRowId,
|
|
1161
1212
|
enabled = true
|
|
1162
1213
|
}) {
|
|
1163
|
-
const identify =
|
|
1214
|
+
const identify = React18.useCallback(
|
|
1164
1215
|
(row) => getRowId ? getRowId(row) : String(row?.id ?? ""),
|
|
1165
1216
|
[getRowId]
|
|
1166
1217
|
);
|
|
1167
|
-
const visible =
|
|
1168
|
-
const [rawSelection, setRawSelection] =
|
|
1169
|
-
const visibleIds =
|
|
1170
|
-
const selectedIds =
|
|
1218
|
+
const visible = React18.useMemo(() => rows ?? [], [rows]);
|
|
1219
|
+
const [rawSelection, setRawSelection] = React18.useState([]);
|
|
1220
|
+
const visibleIds = React18.useMemo(() => new Set(visible.map(identify)), [visible, identify]);
|
|
1221
|
+
const selectedIds = React18.useMemo(
|
|
1171
1222
|
() => rawSelection.filter((id) => visibleIds.has(id)),
|
|
1172
1223
|
[rawSelection, visibleIds]
|
|
1173
1224
|
);
|
|
1174
|
-
const selectedRows =
|
|
1225
|
+
const selectedRows = React18.useMemo(() => {
|
|
1175
1226
|
const picked = new Set(selectedIds);
|
|
1176
1227
|
return visible.filter((row) => picked.has(identify(row)));
|
|
1177
1228
|
}, [visible, selectedIds, identify]);
|
|
1178
|
-
const clear =
|
|
1179
|
-
const selectAll =
|
|
1229
|
+
const clear = React18.useCallback(() => setRawSelection([]), []);
|
|
1230
|
+
const selectAll = React18.useCallback(
|
|
1180
1231
|
() => setRawSelection(visible.map(identify)),
|
|
1181
1232
|
[visible, identify]
|
|
1182
1233
|
);
|
|
1183
|
-
const barActions =
|
|
1234
|
+
const barActions = React18.useMemo(
|
|
1184
1235
|
() => (actions ?? []).map((action) => ({
|
|
1185
1236
|
id: action.id,
|
|
1186
1237
|
label: action.label,
|
|
@@ -1356,8 +1407,8 @@ function ListView({
|
|
|
1356
1407
|
(tagFilter || filters || onRefresh || onExport) && /* @__PURE__ */ jsxs("div", { className: "ml-auto flex flex-wrap items-center justify-end gap-2", children: [
|
|
1357
1408
|
tagFilter,
|
|
1358
1409
|
filters,
|
|
1359
|
-
onRefresh && /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon", "aria-label": refreshLabel,
|
|
1360
|
-
onExport && /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon", "aria-label": exportLabel,
|
|
1410
|
+
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
|
+
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" }) }) })
|
|
1361
1412
|
] })
|
|
1362
1413
|
] }) }),
|
|
1363
1414
|
/* @__PURE__ */ jsx(
|
|
@@ -1595,7 +1646,180 @@ function DatePicker({ value, onChange, className, variant = "input", defaultOpen
|
|
|
1595
1646
|
)
|
|
1596
1647
|
] });
|
|
1597
1648
|
}
|
|
1598
|
-
var
|
|
1649
|
+
var DAY_LABELS2 = {
|
|
1650
|
+
en: ["S", "M", "T", "W", "T", "F", "S"],
|
|
1651
|
+
"pt-BR": ["D", "S", "T", "Q", "Q", "S", "S"]
|
|
1652
|
+
};
|
|
1653
|
+
function isSameDay2(a, b) {
|
|
1654
|
+
return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
1655
|
+
}
|
|
1656
|
+
function isToday2(d) {
|
|
1657
|
+
return isSameDay2(d, /* @__PURE__ */ new Date());
|
|
1658
|
+
}
|
|
1659
|
+
function toDateLocale2(locale) {
|
|
1660
|
+
if (locale === "pt-BR") return "pt-BR";
|
|
1661
|
+
return "en-US";
|
|
1662
|
+
}
|
|
1663
|
+
function toLocalISODate(d) {
|
|
1664
|
+
const month = String(d.getMonth() + 1).padStart(2, "0");
|
|
1665
|
+
const day = String(d.getDate()).padStart(2, "0");
|
|
1666
|
+
return `${d.getFullYear()}-${month}-${day}`;
|
|
1667
|
+
}
|
|
1668
|
+
function MiniCalendar({ selectedDate, onDateSelect, onMonthChange, markers }) {
|
|
1669
|
+
const locale = getCurrentLocale();
|
|
1670
|
+
const [viewMonth, setViewMonth] = React18__default.useState(() => new Date(selectedDate.getFullYear(), selectedDate.getMonth(), 1));
|
|
1671
|
+
const monthLabel = viewMonth.toLocaleDateString(toDateLocale2(locale), { month: "long", year: "numeric" });
|
|
1672
|
+
const dayLabels = DAY_LABELS2[locale] ?? DAY_LABELS2.en;
|
|
1673
|
+
const weeks = useMemo(() => {
|
|
1674
|
+
const year = viewMonth.getFullYear();
|
|
1675
|
+
const month = viewMonth.getMonth();
|
|
1676
|
+
const firstDay = new Date(year, month, 1);
|
|
1677
|
+
const startOffset = firstDay.getDay();
|
|
1678
|
+
const daysInMonth = new Date(year, month + 1, 0).getDate();
|
|
1679
|
+
const cells = [];
|
|
1680
|
+
for (let i = 0; i < startOffset; i++) cells.push(null);
|
|
1681
|
+
for (let d = 1; d <= daysInMonth; d++) cells.push(new Date(year, month, d));
|
|
1682
|
+
while (cells.length % 7 !== 0) cells.push(null);
|
|
1683
|
+
const rows = [];
|
|
1684
|
+
for (let i = 0; i < cells.length; i += 7) rows.push(cells.slice(i, i + 7));
|
|
1685
|
+
return rows;
|
|
1686
|
+
}, [viewMonth]);
|
|
1687
|
+
function prevMonth() {
|
|
1688
|
+
const d = new Date(viewMonth.getFullYear(), viewMonth.getMonth() - 1, 1);
|
|
1689
|
+
setViewMonth(d);
|
|
1690
|
+
onMonthChange?.(d);
|
|
1691
|
+
}
|
|
1692
|
+
function nextMonth() {
|
|
1693
|
+
const d = new Date(viewMonth.getFullYear(), viewMonth.getMonth() + 1, 1);
|
|
1694
|
+
setViewMonth(d);
|
|
1695
|
+
onMonthChange?.(d);
|
|
1696
|
+
}
|
|
1697
|
+
const hasMarkers = !!markers;
|
|
1698
|
+
return /* @__PURE__ */ jsxs("div", { className: "select-none", children: [
|
|
1699
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-2", children: [
|
|
1700
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium capitalize", children: monthLabel }),
|
|
1701
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-0.5", children: [
|
|
1702
|
+
/* @__PURE__ */ jsx("button", { onClick: prevMonth, "aria-label": "Previous month", className: "flex h-6 w-6 items-center justify-center rounded-full hover:bg-muted transition-colors", children: /* @__PURE__ */ jsx(ChevronLeft, { className: "h-3.5 w-3.5" }) }),
|
|
1703
|
+
/* @__PURE__ */ jsx("button", { onClick: nextMonth, "aria-label": "Next month", className: "flex h-6 w-6 items-center justify-center rounded-full hover:bg-muted transition-colors", children: /* @__PURE__ */ jsx(ChevronRight, { className: "h-3.5 w-3.5" }) })
|
|
1704
|
+
] })
|
|
1705
|
+
] }),
|
|
1706
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-7 mb-0.5", children: dayLabels.map((label, i) => /* @__PURE__ */ jsx("div", { className: "flex h-6 w-6 items-center justify-center text-[10px] font-medium text-muted-foreground mx-auto", children: label }, i)) }),
|
|
1707
|
+
weeks.map((week, wi) => /* @__PURE__ */ jsx("div", { className: "grid grid-cols-7", children: week.map((date, di) => {
|
|
1708
|
+
if (!date) return /* @__PURE__ */ jsx("div", { className: hasMarkers ? "h-9 w-6 mx-auto" : "h-6 w-6 mx-auto" }, di);
|
|
1709
|
+
const selected = isSameDay2(date, selectedDate);
|
|
1710
|
+
const today = isToday2(date);
|
|
1711
|
+
const dots = markers?.[toLocalISODate(date)] ?? [];
|
|
1712
|
+
return /* @__PURE__ */ jsxs("div", { className: hasMarkers ? "flex h-9 flex-col items-center" : "contents", children: [
|
|
1713
|
+
/* @__PURE__ */ jsx(
|
|
1714
|
+
"button",
|
|
1715
|
+
{
|
|
1716
|
+
onClick: () => onDateSelect(date),
|
|
1717
|
+
"aria-label": dots.length ? dots.map((m) => m.label).filter(Boolean).join(", ") || void 0 : void 0,
|
|
1718
|
+
className: `flex h-6 w-6 items-center justify-center rounded-full text-[11px] mx-auto transition-colors ${selected ? "bg-primary text-primary-foreground" : today ? "bg-primary/10 text-primary font-semibold" : "hover:bg-muted text-foreground"}`,
|
|
1719
|
+
children: date.getDate()
|
|
1720
|
+
}
|
|
1721
|
+
),
|
|
1722
|
+
hasMarkers && /* @__PURE__ */ jsx("div", { className: "flex h-2 items-center gap-[2px]", children: dots.slice(0, 3).map((m, i) => /* @__PURE__ */ jsx("span", { className: "h-1 w-1 rounded-full", style: { backgroundColor: m.color } }, i)) })
|
|
1723
|
+
] }, di);
|
|
1724
|
+
}) }, wi))
|
|
1725
|
+
] });
|
|
1726
|
+
}
|
|
1727
|
+
function DotBadge({ label, color, hideDot, className }) {
|
|
1728
|
+
return /* @__PURE__ */ jsxs(
|
|
1729
|
+
"span",
|
|
1730
|
+
{
|
|
1731
|
+
className: `inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-xs font-medium whitespace-nowrap ${className ?? ""}`,
|
|
1732
|
+
style: {
|
|
1733
|
+
backgroundColor: `${color}15`,
|
|
1734
|
+
color,
|
|
1735
|
+
border: `1px solid ${color}30`
|
|
1736
|
+
},
|
|
1737
|
+
children: [
|
|
1738
|
+
!hideDot && /* @__PURE__ */ jsx("span", { className: "h-1.5 w-1.5 shrink-0 rounded-full", style: { backgroundColor: color } }),
|
|
1739
|
+
label
|
|
1740
|
+
]
|
|
1741
|
+
}
|
|
1742
|
+
);
|
|
1743
|
+
}
|
|
1744
|
+
function FilterSection({
|
|
1745
|
+
title,
|
|
1746
|
+
defaultOpen = true,
|
|
1747
|
+
children
|
|
1748
|
+
}) {
|
|
1749
|
+
const [open, setOpen] = React18__default.useState(defaultOpen);
|
|
1750
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1751
|
+
/* @__PURE__ */ jsxs(
|
|
1752
|
+
"button",
|
|
1753
|
+
{
|
|
1754
|
+
type: "button",
|
|
1755
|
+
onClick: () => setOpen((p) => !p),
|
|
1756
|
+
"aria-expanded": open,
|
|
1757
|
+
className: "flex items-center justify-between w-full text-xs font-medium text-muted-foreground hover:text-foreground py-1 transition-colors",
|
|
1758
|
+
children: [
|
|
1759
|
+
/* @__PURE__ */ jsx("span", { children: title }),
|
|
1760
|
+
/* @__PURE__ */ jsx(ChevronDown, { className: `h-3.5 w-3.5 transition-transform ${open ? "" : "-rotate-90"}` })
|
|
1761
|
+
]
|
|
1762
|
+
}
|
|
1763
|
+
),
|
|
1764
|
+
open && /* @__PURE__ */ jsx("div", { className: "mt-1.5 space-y-0.5", children })
|
|
1765
|
+
] });
|
|
1766
|
+
}
|
|
1767
|
+
function CheckMark({ className }) {
|
|
1768
|
+
return /* @__PURE__ */ jsx("svg", { className, viewBox: "0 0 12 12", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M2 6l3 3 5-5", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) });
|
|
1769
|
+
}
|
|
1770
|
+
function FilterCheckBox({ checked, color }) {
|
|
1771
|
+
if (!color) {
|
|
1772
|
+
return /* @__PURE__ */ jsx("span", { className: `flex h-4 w-4 shrink-0 items-center justify-center rounded-sm border-2 transition-colors ${checked ? "border-primary bg-primary" : "border-muted-foreground/30"}`, children: checked && /* @__PURE__ */ jsx(CheckMark, { className: "h-2.5 w-2.5 text-primary-foreground" }) });
|
|
1773
|
+
}
|
|
1774
|
+
return /* @__PURE__ */ jsx(
|
|
1775
|
+
"span",
|
|
1776
|
+
{
|
|
1777
|
+
className: "flex h-4 w-4 shrink-0 items-center justify-center rounded-sm border-2 transition-colors",
|
|
1778
|
+
style: { borderColor: checked ? color : color + "40", backgroundColor: checked ? color : "transparent" },
|
|
1779
|
+
children: checked && /* @__PURE__ */ jsx(CheckMark, { className: "h-2.5 w-2.5 text-white" })
|
|
1780
|
+
}
|
|
1781
|
+
);
|
|
1782
|
+
}
|
|
1783
|
+
function FilterCheckRow({
|
|
1784
|
+
option,
|
|
1785
|
+
checked,
|
|
1786
|
+
onToggle
|
|
1787
|
+
}) {
|
|
1788
|
+
return /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2.5 rounded px-1 py-1 cursor-pointer hover:bg-muted/50 transition-colors", children: [
|
|
1789
|
+
/* @__PURE__ */ jsx(FilterCheckBox, { checked, color: option.color }),
|
|
1790
|
+
option.adornment,
|
|
1791
|
+
/* @__PURE__ */ jsx("span", { className: `min-w-0 flex-1 truncate text-xs ${checked ? "text-foreground" : "text-muted-foreground"}`, children: option.label }),
|
|
1792
|
+
option.count != null && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-xs tabular-nums text-muted-foreground", children: option.count }),
|
|
1793
|
+
/* @__PURE__ */ jsx("input", { type: "checkbox", className: "sr-only", checked, onChange: onToggle })
|
|
1794
|
+
] });
|
|
1795
|
+
}
|
|
1796
|
+
function FilterCheckList({
|
|
1797
|
+
label,
|
|
1798
|
+
options,
|
|
1799
|
+
selected,
|
|
1800
|
+
onChange,
|
|
1801
|
+
className
|
|
1802
|
+
}) {
|
|
1803
|
+
const all = selected.length === 0;
|
|
1804
|
+
function toggle(value) {
|
|
1805
|
+
const next = selected.includes(value) ? selected.filter((v) => v !== value) : [...selected, value];
|
|
1806
|
+
onChange(next.length === options.length ? [] : next);
|
|
1807
|
+
}
|
|
1808
|
+
const rows = options.map((option) => /* @__PURE__ */ jsx(
|
|
1809
|
+
FilterCheckRow,
|
|
1810
|
+
{
|
|
1811
|
+
option,
|
|
1812
|
+
checked: all || selected.includes(option.value),
|
|
1813
|
+
onToggle: () => toggle(option.value)
|
|
1814
|
+
},
|
|
1815
|
+
option.value
|
|
1816
|
+
));
|
|
1817
|
+
if (label) {
|
|
1818
|
+
return /* @__PURE__ */ jsx("div", { className, children: /* @__PURE__ */ jsx(FilterSection, { title: label, children: rows }) });
|
|
1819
|
+
}
|
|
1820
|
+
return /* @__PURE__ */ jsx("div", { className: className ? `${className} space-y-0.5` : "space-y-0.5", children: rows });
|
|
1821
|
+
}
|
|
1822
|
+
var useIsomorphicLayoutEffect = typeof window !== "undefined" ? React18.useLayoutEffect : React18.useEffect;
|
|
1599
1823
|
function SearchSelect({
|
|
1600
1824
|
value,
|
|
1601
1825
|
displayValue,
|
|
@@ -1618,18 +1842,18 @@ function SearchSelect({
|
|
|
1618
1842
|
disabled
|
|
1619
1843
|
}) {
|
|
1620
1844
|
const canCreate = !!onCreate && allowCreate !== false;
|
|
1621
|
-
const [open, setOpen] =
|
|
1622
|
-
const [query, setQuery] =
|
|
1623
|
-
const [results, setResults] =
|
|
1624
|
-
const [loading, setLoading] =
|
|
1625
|
-
const [creating, setCreating] =
|
|
1626
|
-
const [selectedLabel, setSelectedLabel] =
|
|
1627
|
-
const containerRef =
|
|
1628
|
-
const inputRef =
|
|
1629
|
-
const timerRef =
|
|
1630
|
-
const [rect, setRect] =
|
|
1631
|
-
const dropdownRef =
|
|
1632
|
-
|
|
1845
|
+
const [open, setOpen] = React18.useState(false);
|
|
1846
|
+
const [query, setQuery] = React18.useState("");
|
|
1847
|
+
const [results, setResults] = React18.useState([]);
|
|
1848
|
+
const [loading, setLoading] = React18.useState(false);
|
|
1849
|
+
const [creating, setCreating] = React18.useState(false);
|
|
1850
|
+
const [selectedLabel, setSelectedLabel] = React18.useState(displayValue ?? "");
|
|
1851
|
+
const containerRef = React18.useRef(null);
|
|
1852
|
+
const inputRef = React18.useRef(null);
|
|
1853
|
+
const timerRef = React18.useRef();
|
|
1854
|
+
const [rect, setRect] = React18.useState(null);
|
|
1855
|
+
const dropdownRef = React18.useRef(null);
|
|
1856
|
+
React18.useEffect(() => {
|
|
1633
1857
|
function handler(e) {
|
|
1634
1858
|
const target = e.target;
|
|
1635
1859
|
if (containerRef.current?.contains(target)) return;
|
|
@@ -1639,10 +1863,10 @@ function SearchSelect({
|
|
|
1639
1863
|
document.addEventListener("mousedown", handler);
|
|
1640
1864
|
return () => document.removeEventListener("mousedown", handler);
|
|
1641
1865
|
}, []);
|
|
1642
|
-
|
|
1866
|
+
React18.useEffect(() => {
|
|
1643
1867
|
if (displayValue !== void 0) setSelectedLabel(displayValue);
|
|
1644
1868
|
}, [displayValue]);
|
|
1645
|
-
|
|
1869
|
+
React18.useEffect(() => {
|
|
1646
1870
|
if (open && loadOnOpen && query.length === 0 && results.length === 0 && !loading) {
|
|
1647
1871
|
setLoading(true);
|
|
1648
1872
|
Promise.resolve(onSearch("")).then(setResults).catch(() => setResults([])).finally(() => setLoading(false));
|
|
@@ -1700,7 +1924,7 @@ function SearchSelect({
|
|
|
1700
1924
|
setResults([]);
|
|
1701
1925
|
setTimeout(() => inputRef.current?.focus(), 0);
|
|
1702
1926
|
}
|
|
1703
|
-
const groups =
|
|
1927
|
+
const groups = React18.useMemo(() => {
|
|
1704
1928
|
const map = /* @__PURE__ */ new Map();
|
|
1705
1929
|
for (const opt of results) {
|
|
1706
1930
|
const group = opt.group ?? "";
|
|
@@ -1795,7 +2019,7 @@ function SearchSelect({
|
|
|
1795
2019
|
/* @__PURE__ */ jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin" }),
|
|
1796
2020
|
" ",
|
|
1797
2021
|
searchingLabel
|
|
1798
|
-
] }) : 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(
|
|
2022
|
+
] }) : 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(React18.Fragment, { children: [
|
|
1799
2023
|
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 }),
|
|
1800
2024
|
options.map((opt) => /* @__PURE__ */ jsx(
|
|
1801
2025
|
"button",
|
|
@@ -1857,9 +2081,9 @@ function CurrencyInput({
|
|
|
1857
2081
|
className,
|
|
1858
2082
|
disabled
|
|
1859
2083
|
}) {
|
|
1860
|
-
const inputRef =
|
|
1861
|
-
const [focused, setFocused] =
|
|
1862
|
-
const format =
|
|
2084
|
+
const inputRef = React18.useRef(null);
|
|
2085
|
+
const [focused, setFocused] = React18.useState(false);
|
|
2086
|
+
const format = React18.useCallback((v) => {
|
|
1863
2087
|
return new Intl.NumberFormat(locale, {
|
|
1864
2088
|
minimumFractionDigits: 2,
|
|
1865
2089
|
maximumFractionDigits: 2
|
|
@@ -1932,7 +2156,7 @@ function CurrencyInput({
|
|
|
1932
2156
|
var Popover = PopoverPrimitive.Root;
|
|
1933
2157
|
var PopoverTrigger = PopoverPrimitive.Trigger;
|
|
1934
2158
|
var PopoverAnchor = PopoverPrimitive.Anchor;
|
|
1935
|
-
var PopoverContent =
|
|
2159
|
+
var PopoverContent = React18.forwardRef(({ className, align = "start", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(
|
|
1936
2160
|
PopoverPrimitive.Content,
|
|
1937
2161
|
{
|
|
1938
2162
|
ref,
|
|
@@ -1947,50 +2171,100 @@ var PopoverContent = React16.forwardRef(({ className, align = "start", sideOffse
|
|
|
1947
2171
|
}
|
|
1948
2172
|
) }));
|
|
1949
2173
|
PopoverContent.displayName = PopoverPrimitive.Content.displayName;
|
|
1950
|
-
|
|
1951
|
-
sm: { container: "h-[26px]", segment: "px-2.5 text-xs" },
|
|
1952
|
-
md: { container: "h-[30px]", segment: "px-3 text-sm" }
|
|
1953
|
-
};
|
|
1954
|
-
function SegmentedControl({
|
|
2174
|
+
function MultiSelect({
|
|
1955
2175
|
options,
|
|
1956
2176
|
value,
|
|
1957
2177
|
onChange,
|
|
1958
|
-
|
|
2178
|
+
allLabel = "Todos",
|
|
2179
|
+
searchPlaceholder = "Buscar\u2026",
|
|
2180
|
+
emptyLabel = "Nada encontrado",
|
|
2181
|
+
disabled,
|
|
1959
2182
|
className,
|
|
1960
|
-
|
|
2183
|
+
searchThreshold = 8
|
|
1961
2184
|
}) {
|
|
1962
|
-
const
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
2185
|
+
const [query, setQuery] = React18.useState("");
|
|
2186
|
+
const selected = React18.useMemo(() => new Set(value), [value]);
|
|
2187
|
+
const filtered = React18.useMemo(() => {
|
|
2188
|
+
const q = query.trim().toLowerCase();
|
|
2189
|
+
if (!q) return options;
|
|
2190
|
+
return options.filter((o) => o.label.toLowerCase().includes(q));
|
|
2191
|
+
}, [options, query]);
|
|
2192
|
+
function toggle(v) {
|
|
2193
|
+
onChange(selected.has(v) ? value.filter((x) => x !== v) : [...value, v]);
|
|
2194
|
+
}
|
|
2195
|
+
const label = value.length === 0 ? allLabel : value.length === 1 ? options.find((o) => o.value === value[0])?.label ?? "1 selecionado" : `${value.length} selecionados`;
|
|
2196
|
+
return /* @__PURE__ */ jsxs(Dropdown, { children: [
|
|
2197
|
+
/* @__PURE__ */ jsx(DropdownTrigger, { asChild: true, disabled, children: /* @__PURE__ */ jsxs(
|
|
2198
|
+
"button",
|
|
2199
|
+
{
|
|
2200
|
+
type: "button",
|
|
2201
|
+
disabled,
|
|
2202
|
+
className: cn(
|
|
2203
|
+
"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",
|
|
2204
|
+
"shadow-[inset_0_1px_0_rgb(0_0_0_/0.06)] transition-colors hover:bg-muted/40",
|
|
2205
|
+
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
2206
|
+
value.length === 0 && "text-muted-foreground",
|
|
2207
|
+
className
|
|
2208
|
+
),
|
|
2209
|
+
children: [
|
|
2210
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: label }),
|
|
2211
|
+
/* @__PURE__ */ jsxs("span", { className: "flex shrink-0 items-center gap-1", children: [
|
|
2212
|
+
value.length > 0 && // Limpar dentro do gatilho: a alternativa é desmarcar cinco itens
|
|
2213
|
+
// um a um para voltar a "todos", e é o caminho de volta mais
|
|
2214
|
+
// comum de todos.
|
|
2215
|
+
/* @__PURE__ */ jsx(
|
|
2216
|
+
"span",
|
|
2217
|
+
{
|
|
2218
|
+
role: "button",
|
|
2219
|
+
tabIndex: -1,
|
|
2220
|
+
"aria-label": "Limpar sele\xE7\xE3o",
|
|
2221
|
+
onClick: (e) => {
|
|
2222
|
+
e.preventDefault();
|
|
2223
|
+
e.stopPropagation();
|
|
2224
|
+
onChange([]);
|
|
2225
|
+
},
|
|
2226
|
+
className: "rounded-full p-0.5 text-muted-foreground hover:bg-muted hover:text-foreground",
|
|
2227
|
+
children: /* @__PURE__ */ jsx(X, { className: "h-3 w-3" })
|
|
2228
|
+
}
|
|
1986
2229
|
),
|
|
1987
|
-
|
|
2230
|
+
/* @__PURE__ */ jsx(ChevronDown, { className: "h-3.5 w-3.5 shrink-0 opacity-50" })
|
|
2231
|
+
] })
|
|
2232
|
+
]
|
|
2233
|
+
}
|
|
2234
|
+
) }),
|
|
2235
|
+
/* @__PURE__ */ jsxs(DropdownContent, { align: "start", className: "w-[--radix-dropdown-menu-trigger-width] p-0", children: [
|
|
2236
|
+
options.length >= searchThreshold && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 border-b px-2 py-1.5", children: [
|
|
2237
|
+
/* @__PURE__ */ jsx(Search, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
|
|
2238
|
+
/* @__PURE__ */ jsx(
|
|
2239
|
+
"input",
|
|
2240
|
+
{
|
|
2241
|
+
value: query,
|
|
2242
|
+
onChange: (e) => setQuery(e.target.value),
|
|
2243
|
+
placeholder: searchPlaceholder,
|
|
2244
|
+
onKeyDown: (e) => e.stopPropagation(),
|
|
2245
|
+
className: "w-full bg-transparent text-xs outline-none placeholder:text-muted-foreground"
|
|
2246
|
+
}
|
|
2247
|
+
)
|
|
2248
|
+
] }),
|
|
2249
|
+
/* @__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(
|
|
2250
|
+
"button",
|
|
2251
|
+
{
|
|
2252
|
+
type: "button",
|
|
2253
|
+
onClick: (e) => {
|
|
2254
|
+
e.preventDefault();
|
|
2255
|
+
toggle(o.value);
|
|
1988
2256
|
},
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
2257
|
+
className: "flex w-full items-center gap-2 px-3 py-1.5 text-left text-xs transition-colors hover:bg-muted",
|
|
2258
|
+
children: [
|
|
2259
|
+
/* @__PURE__ */ jsx(Checkbox, { checked: selected.has(o.value), onChange: () => toggle(o.value) }),
|
|
2260
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: o.label }),
|
|
2261
|
+
o.hint && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-[10px] text-muted-foreground", children: o.hint })
|
|
2262
|
+
]
|
|
2263
|
+
},
|
|
2264
|
+
o.value
|
|
2265
|
+
)) })
|
|
2266
|
+
] })
|
|
2267
|
+
] });
|
|
1994
2268
|
}
|
|
1995
2269
|
var INLINE_TOKEN = /(\*\*[^*]+\*\*|\*[^*]+\*|`[^`]+`)/g;
|
|
1996
2270
|
function renderInline(text, keyPrefix) {
|
|
@@ -2005,7 +2279,7 @@ function renderInline(text, keyPrefix) {
|
|
|
2005
2279
|
if (part.startsWith("`") && part.endsWith("`") && part.length > 2) {
|
|
2006
2280
|
return /* @__PURE__ */ jsx("code", { className: "rounded bg-muted px-1 py-0.5 font-mono text-[0.85em]", children: part.slice(1, -1) }, key);
|
|
2007
2281
|
}
|
|
2008
|
-
return part === "" ? null : /* @__PURE__ */ jsx(
|
|
2282
|
+
return part === "" ? null : /* @__PURE__ */ jsx(React18.Fragment, { children: part }, key);
|
|
2009
2283
|
});
|
|
2010
2284
|
}
|
|
2011
2285
|
function parseBlocks(source) {
|
|
@@ -2089,7 +2363,7 @@ function renderMarkdown(source) {
|
|
|
2089
2363
|
case "ol":
|
|
2090
2364
|
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);
|
|
2091
2365
|
case "p":
|
|
2092
|
-
return /* @__PURE__ */ jsx("p", { children: block.lines.map((l, li) => /* @__PURE__ */ jsxs(
|
|
2366
|
+
return /* @__PURE__ */ jsx("p", { children: block.lines.map((l, li) => /* @__PURE__ */ jsxs(React18.Fragment, { children: [
|
|
2093
2367
|
li > 0 && /* @__PURE__ */ jsx("br", {}),
|
|
2094
2368
|
renderInline(l, `${key}-${li}`)
|
|
2095
2369
|
] }, `${key}-${li}`)) }, key);
|
|
@@ -2110,7 +2384,7 @@ function MarkdownEditor({
|
|
|
2110
2384
|
renderPreview,
|
|
2111
2385
|
className
|
|
2112
2386
|
}) {
|
|
2113
|
-
const [mode, setMode] =
|
|
2387
|
+
const [mode, setMode] = React18.useState(
|
|
2114
2388
|
defaultMode === "preview" && value.trim() === "" ? "edit" : defaultMode
|
|
2115
2389
|
);
|
|
2116
2390
|
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-2", className), children: [
|
|
@@ -2370,7 +2644,169 @@ function SearchCombobox({
|
|
|
2370
2644
|
)
|
|
2371
2645
|
] });
|
|
2372
2646
|
}
|
|
2647
|
+
var DEFAULT_LABELS = {
|
|
2648
|
+
title: "Lan\xE7ar movimento",
|
|
2649
|
+
description: "O raz\xE3o n\xE3o se edita: um erro se corrige com o movimento contr\xE1rio.",
|
|
2650
|
+
quantity: "Quantidade",
|
|
2651
|
+
reason: "Motivo",
|
|
2652
|
+
reasonDefault: "Padr\xE3o",
|
|
2653
|
+
whenArrived: "Chegou em",
|
|
2654
|
+
when: "Quando",
|
|
2655
|
+
note: "Observa\xE7\xE3o",
|
|
2656
|
+
notePlaceholder: "Nota fiscal, quem entregou\u2026",
|
|
2657
|
+
addNote: "+ observa\xE7\xE3o",
|
|
2658
|
+
staysAt: "Fica em",
|
|
2659
|
+
notEnough: "n\xE3o h\xE1 tudo isso",
|
|
2660
|
+
sayHowMany: "Diga quantas unidades",
|
|
2661
|
+
cancel: "Cancelar",
|
|
2662
|
+
submit: "Lan\xE7ar",
|
|
2663
|
+
submitting: "Lan\xE7ando\u2026"
|
|
2664
|
+
};
|
|
2665
|
+
var field = "mt-1 w-full rounded-md border bg-background px-2.5 py-1.5 text-sm outline-none focus:border-primary";
|
|
2666
|
+
var todayISO = () => (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
2667
|
+
function StockEntryForm({
|
|
2668
|
+
verb,
|
|
2669
|
+
onVerbChange,
|
|
2670
|
+
onClose,
|
|
2671
|
+
verbs,
|
|
2672
|
+
reasons = [],
|
|
2673
|
+
available,
|
|
2674
|
+
saving = false,
|
|
2675
|
+
onSubmit,
|
|
2676
|
+
labels: overrides
|
|
2677
|
+
}) {
|
|
2678
|
+
const labels = { ...DEFAULT_LABELS, ...overrides };
|
|
2679
|
+
const [quantity, setQuantity] = React18.useState("");
|
|
2680
|
+
const [reasonCode, setReasonCode] = React18.useState("");
|
|
2681
|
+
const [occurredOn, setOccurredOn] = React18.useState(todayISO());
|
|
2682
|
+
const [note, setNote] = React18.useState("");
|
|
2683
|
+
const [noteOpen, setNoteOpen] = React18.useState(false);
|
|
2684
|
+
const quantityRef = React18.useRef(null);
|
|
2685
|
+
React18.useEffect(() => {
|
|
2686
|
+
if (verb === null) return;
|
|
2687
|
+
setQuantity("");
|
|
2688
|
+
setReasonCode("");
|
|
2689
|
+
setOccurredOn(todayISO());
|
|
2690
|
+
setNote("");
|
|
2691
|
+
setNoteOpen(false);
|
|
2692
|
+
const timer = setTimeout(() => quantityRef.current?.focus(), 30);
|
|
2693
|
+
return () => clearTimeout(timer);
|
|
2694
|
+
}, [verb]);
|
|
2695
|
+
const amount = Math.max(0, Math.trunc(Number(quantity) || 0));
|
|
2696
|
+
const spec = verbs.find((v) => v.value === verb);
|
|
2697
|
+
const effect = spec?.effect ?? "increase";
|
|
2698
|
+
const nextBalance = amount === 0 ? null : effect === "set" ? amount : effect === "decrease" ? available - amount : available + amount;
|
|
2699
|
+
const submit = () => {
|
|
2700
|
+
if (amount === 0 || saving) return;
|
|
2701
|
+
void onSubmit({ verb, quantity: amount, reasonCode, occurredOn, note });
|
|
2702
|
+
};
|
|
2703
|
+
return /* @__PURE__ */ jsx(Modal, { open: verb !== null, onOpenChange: (open) => {
|
|
2704
|
+
if (!open) onClose();
|
|
2705
|
+
}, children: /* @__PURE__ */ jsxs(ModalContent, { className: "sm:max-w-lg", children: [
|
|
2706
|
+
/* @__PURE__ */ jsxs(ModalHeader, { children: [
|
|
2707
|
+
/* @__PURE__ */ jsx(ModalTitle, { children: labels.title }),
|
|
2708
|
+
/* @__PURE__ */ jsx(ModalDescription, { children: labels.description })
|
|
2709
|
+
] }),
|
|
2710
|
+
/* @__PURE__ */ jsxs("div", { className: "p-1", children: [
|
|
2711
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1", children: verbs.map((v) => /* @__PURE__ */ jsx(
|
|
2712
|
+
"button",
|
|
2713
|
+
{
|
|
2714
|
+
type: "button",
|
|
2715
|
+
onClick: () => onVerbChange(v.value),
|
|
2716
|
+
className: `fz-tap rounded-button px-3 py-1.5 text-xs font-medium transition-colors ${verb === v.value ? "bg-primary text-primary-foreground" : "text-muted-foreground hover:bg-muted hover:text-foreground"}`,
|
|
2717
|
+
children: v.label
|
|
2718
|
+
},
|
|
2719
|
+
v.value
|
|
2720
|
+
)) }),
|
|
2721
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-3 space-y-3", children: [
|
|
2722
|
+
/* @__PURE__ */ jsxs("label", { className: "block", children: [
|
|
2723
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-muted-foreground", children: labels.quantity }),
|
|
2724
|
+
/* @__PURE__ */ jsx(
|
|
2725
|
+
"input",
|
|
2726
|
+
{
|
|
2727
|
+
ref: quantityRef,
|
|
2728
|
+
type: "number",
|
|
2729
|
+
inputMode: "numeric",
|
|
2730
|
+
min: effect === "set" ? 0 : 1,
|
|
2731
|
+
value: quantity,
|
|
2732
|
+
onChange: (e) => setQuantity(e.target.value),
|
|
2733
|
+
onKeyDown: (e) => {
|
|
2734
|
+
if (e.key === "Enter") {
|
|
2735
|
+
e.preventDefault();
|
|
2736
|
+
submit();
|
|
2737
|
+
}
|
|
2738
|
+
if (e.key === "Escape") {
|
|
2739
|
+
e.preventDefault();
|
|
2740
|
+
onClose();
|
|
2741
|
+
}
|
|
2742
|
+
},
|
|
2743
|
+
placeholder: "0",
|
|
2744
|
+
className: `${field} font-semibold tabular-nums`
|
|
2745
|
+
}
|
|
2746
|
+
),
|
|
2747
|
+
/* @__PURE__ */ jsx("span", { "aria-live": "polite", className: "mt-1 block text-xs text-muted-foreground", children: nextBalance === null ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2748
|
+
labels.staysAt,
|
|
2749
|
+
" ",
|
|
2750
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium tabular-nums text-foreground", children: available })
|
|
2751
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2752
|
+
/* @__PURE__ */ jsx("span", { className: "tabular-nums", children: available }),
|
|
2753
|
+
/* @__PURE__ */ jsx("span", { className: "mx-1.5", children: "\u2192" }),
|
|
2754
|
+
/* @__PURE__ */ jsx("span", { className: `text-base font-semibold tabular-nums ${nextBalance < 0 ? "text-destructive" : "text-foreground"}`, children: nextBalance }),
|
|
2755
|
+
nextBalance < 0 && /* @__PURE__ */ jsx("span", { className: "ml-2 text-destructive", children: labels.notEnough })
|
|
2756
|
+
] }) })
|
|
2757
|
+
] }),
|
|
2758
|
+
reasons.length > 0 && /* @__PURE__ */ jsxs("label", { className: "block", children: [
|
|
2759
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-muted-foreground", children: labels.reason }),
|
|
2760
|
+
/* @__PURE__ */ jsxs("select", { value: reasonCode, onChange: (e) => setReasonCode(e.target.value), className: field, children: [
|
|
2761
|
+
/* @__PURE__ */ jsx("option", { value: "", children: labels.reasonDefault }),
|
|
2762
|
+
reasons.map((r) => /* @__PURE__ */ jsx("option", { value: r.key, children: r.label }, r.key))
|
|
2763
|
+
] })
|
|
2764
|
+
] }),
|
|
2765
|
+
/* @__PURE__ */ jsxs("label", { className: "block", children: [
|
|
2766
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-muted-foreground", children: effect === "increase" ? labels.whenArrived : labels.when }),
|
|
2767
|
+
/* @__PURE__ */ jsx(
|
|
2768
|
+
"input",
|
|
2769
|
+
{
|
|
2770
|
+
type: "date",
|
|
2771
|
+
value: occurredOn,
|
|
2772
|
+
max: todayISO(),
|
|
2773
|
+
onChange: (e) => setOccurredOn(e.target.value || todayISO()),
|
|
2774
|
+
className: field
|
|
2775
|
+
}
|
|
2776
|
+
)
|
|
2777
|
+
] })
|
|
2778
|
+
] }),
|
|
2779
|
+
noteOpen ? /* @__PURE__ */ jsxs("label", { className: "mt-3 block", children: [
|
|
2780
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-muted-foreground", children: labels.note }),
|
|
2781
|
+
/* @__PURE__ */ jsx(
|
|
2782
|
+
"input",
|
|
2783
|
+
{
|
|
2784
|
+
autoFocus: true,
|
|
2785
|
+
value: note,
|
|
2786
|
+
onChange: (e) => setNote(e.target.value),
|
|
2787
|
+
className: field,
|
|
2788
|
+
placeholder: labels.notePlaceholder
|
|
2789
|
+
}
|
|
2790
|
+
)
|
|
2791
|
+
] }) : /* @__PURE__ */ jsx(
|
|
2792
|
+
"button",
|
|
2793
|
+
{
|
|
2794
|
+
type: "button",
|
|
2795
|
+
onClick: () => setNoteOpen(true),
|
|
2796
|
+
className: "mt-2 text-xs font-medium text-muted-foreground underline-offset-2 hover:text-foreground hover:underline",
|
|
2797
|
+
children: labels.addNote
|
|
2798
|
+
}
|
|
2799
|
+
)
|
|
2800
|
+
] }),
|
|
2801
|
+
/* @__PURE__ */ jsxs(ModalFooter, { children: [
|
|
2802
|
+
amount === 0 && // Why the button is dim, next to the button.
|
|
2803
|
+
/* @__PURE__ */ jsx("span", { className: "mr-auto text-xs text-muted-foreground", children: labels.sayHowMany }),
|
|
2804
|
+
/* @__PURE__ */ jsx(Button, { variant: "ghost", onClick: onClose, disabled: saving, children: labels.cancel }),
|
|
2805
|
+
/* @__PURE__ */ jsx(Button, { onClick: submit, disabled: saving || amount === 0, children: saving ? labels.submitting : labels.submit })
|
|
2806
|
+
] })
|
|
2807
|
+
] }) });
|
|
2808
|
+
}
|
|
2373
2809
|
|
|
2374
|
-
export { Badge, Breadcrumb, BulkActionBar, ChevronPager, CurrencyInput, DatePicker, FilterChip, Hint, Input, ListView, Markdown, MarkdownEditor, Modal, ModalBody, ModalClose, ModalContent, ModalDescription, ModalFooter, ModalHeader, ModalOverlay, ModalPortal, ModalTitle, ModalTrigger, PageActionBar, PhoneField, PhoneLink, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, RefreshButton, RowActions, SearchCombobox, SearchField, SearchSelect,
|
|
2375
|
-
//# sourceMappingURL=chunk-
|
|
2376
|
-
//# sourceMappingURL=chunk-
|
|
2810
|
+
export { Badge, Breadcrumb, BulkActionBar, ChevronPager, CurrencyInput, DatePicker, DotBadge, DraftCommitBar, FilterCheckBox, FilterCheckList, FilterCheckRow, FilterChip, FilterSection, Hint, Input, ListView, Markdown, MarkdownEditor, MiniCalendar, Modal, ModalBody, ModalClose, ModalContent, ModalDescription, ModalFooter, ModalHeader, ModalOverlay, ModalPortal, ModalTitle, ModalTrigger, MultiSelect, PageActionBar, PhoneField, PhoneLink, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, 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, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, WHATSAPP_BRAND_COLOR, WhatsAppIcon, badgeVariants, formatPhone2 as formatPhone, normalizePhone, renderMarkdown, setActionsMenuLabel, setRowActionsLabel, toLocalISODate, useRowSelection };
|
|
2811
|
+
//# sourceMappingURL=chunk-OYH7CEMB.js.map
|
|
2812
|
+
//# sourceMappingURL=chunk-OYH7CEMB.js.map
|