@fayz-ai/ui 0.10.2 → 0.12.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.
Files changed (75) hide show
  1. package/dist/analytics/AnalyticsCard.d.ts.map +1 -1
  2. package/dist/analytics/AnalyticsControls.d.ts.map +1 -1
  3. package/dist/analytics/batch.d.ts +19 -0
  4. package/dist/analytics/batch.d.ts.map +1 -0
  5. package/dist/analytics/context.d.ts.map +1 -1
  6. package/dist/analytics/derive.d.ts.map +1 -1
  7. package/dist/analytics/index.d.ts +2 -0
  8. package/dist/analytics/index.d.ts.map +1 -1
  9. package/dist/{chunk-SEIY2F5F.js → chunk-7BHG3XGJ.js} +317 -86
  10. package/dist/chunk-7BHG3XGJ.js.map +1 -0
  11. package/dist/{chunk-I6CPKAOD.js → chunk-7BMXN7MP.js} +215 -99
  12. package/dist/chunk-7BMXN7MP.js.map +1 -0
  13. package/dist/{chunk-6V5MGYXH.js → chunk-JGJNRNQW.js} +142 -31
  14. package/dist/chunk-JGJNRNQW.js.map +1 -0
  15. package/dist/chunk-ZBQ772DU.js +17 -0
  16. package/dist/chunk-ZBQ772DU.js.map +1 -0
  17. package/dist/{chunk-H63TOSQ7.js → chunk-ZDRHCKRK.js} +499 -142
  18. package/dist/chunk-ZDRHCKRK.js.map +1 -0
  19. package/dist/dashboard/ChartWidget.d.ts.map +1 -1
  20. package/dist/dashboard/KpiCard.d.ts.map +1 -1
  21. package/dist/dashboard/SidebarOnboarding.d.ts +16 -11
  22. package/dist/dashboard/SidebarOnboarding.d.ts.map +1 -1
  23. package/dist/dashboard/Sparkline.d.ts +13 -0
  24. package/dist/dashboard/Sparkline.d.ts.map +1 -0
  25. package/dist/dashboard/index.d.ts +1 -0
  26. package/dist/dashboard/index.d.ts.map +1 -1
  27. package/dist/dashboard/index.js +3 -2
  28. package/dist/index.d.ts +2 -2
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +237 -117
  31. package/dist/index.js.map +1 -1
  32. package/dist/layout/AppShell.d.ts +4 -1
  33. package/dist/layout/AppShell.d.ts.map +1 -1
  34. package/dist/layout/AppShellSkeleton.d.ts +23 -0
  35. package/dist/layout/AppShellSkeleton.d.ts.map +1 -0
  36. package/dist/layout/ModulePage.d.ts +5 -1
  37. package/dist/layout/ModulePage.d.ts.map +1 -1
  38. package/dist/layout/Sidebar.d.ts +19 -1
  39. package/dist/layout/Sidebar.d.ts.map +1 -1
  40. package/dist/layout/Topbar.d.ts +4 -1
  41. package/dist/layout/Topbar.d.ts.map +1 -1
  42. package/dist/layout/index.d.ts +2 -0
  43. package/dist/layout/index.d.ts.map +1 -1
  44. package/dist/layout/index.js +2 -1
  45. package/dist/layout/page-trail.d.ts +23 -0
  46. package/dist/layout/page-trail.d.ts.map +1 -0
  47. package/dist/layout/rail-flyout.d.ts +39 -0
  48. package/dist/layout/rail-flyout.d.ts.map +1 -0
  49. package/dist/primitives/bulk-action-bar.d.ts +30 -0
  50. package/dist/primitives/bulk-action-bar.d.ts.map +1 -0
  51. package/dist/primitives/checkbox.d.ts +5 -0
  52. package/dist/primitives/checkbox.d.ts.map +1 -1
  53. package/dist/primitives/data-table.d.ts +11 -1
  54. package/dist/primitives/data-table.d.ts.map +1 -1
  55. package/dist/primitives/dropdown.d.ts.map +1 -1
  56. package/dist/primitives/index.d.ts +5 -0
  57. package/dist/primitives/index.d.ts.map +1 -1
  58. package/dist/primitives/index.js +2 -2
  59. package/dist/primitives/list-chrome.d.ts +20 -0
  60. package/dist/primitives/list-chrome.d.ts.map +1 -0
  61. package/dist/primitives/modal.d.ts.map +1 -1
  62. package/dist/primitives/phone-field.d.ts +19 -0
  63. package/dist/primitives/phone-field.d.ts.map +1 -0
  64. package/dist/primitives/refresh-button.d.ts +18 -0
  65. package/dist/primitives/refresh-button.d.ts.map +1 -0
  66. package/dist/primitives/search-select.d.ts +6 -1
  67. package/dist/primitives/search-select.d.ts.map +1 -1
  68. package/dist/primitives/thumbnail.d.ts +19 -0
  69. package/dist/primitives/thumbnail.d.ts.map +1 -0
  70. package/dist/styles.css +298 -1
  71. package/package.json +2 -2
  72. package/dist/chunk-6V5MGYXH.js.map +0 -1
  73. package/dist/chunk-H63TOSQ7.js.map +0 -1
  74. package/dist/chunk-I6CPKAOD.js.map +0 -1
  75. package/dist/chunk-SEIY2F5F.js.map +0 -1
@@ -0,0 +1,13 @@
1
+ import * as React from 'react';
2
+ export interface SparklineProps {
3
+ data: number[];
4
+ color: string;
5
+ /** viewBox width/height — the aspect the path is drawn into. */
6
+ width?: number;
7
+ height?: number;
8
+ /** Inset so the stroke is not clipped at the extremes. */
9
+ padding?: number;
10
+ className?: string;
11
+ }
12
+ export declare function Sparkline({ data, color, width, height, padding, className, }: SparklineProps): React.JSX.Element | null;
13
+ //# sourceMappingURL=Sparkline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Sparkline.d.ts","sourceRoot":"","sources":["../../src/dashboard/Sparkline.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAW9B,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,gEAAgE;IAChE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,0DAA0D;IAC1D,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,SAAS,CAAC,EACxB,IAAI,EAAE,KAAK,EAAE,KAAU,EAAE,MAAW,EAAE,OAAW,EAAE,SAAgD,GACpG,EAAE,cAAc,4BA8BhB"}
@@ -8,6 +8,7 @@ export { DashboardRangeProvider, DashboardRangeControl, useDashboardRange, DEFAU
8
8
  export type { DashboardRangeOptions } from './DashboardCanvas';
9
9
  export { KpiCard, formatKpiValue, type KpiCardProps } from './KpiCard';
10
10
  export { ChartWidget, type ChartWidgetProps } from './ChartWidget';
11
+ export { Sparkline, type SparklineProps } from './Sparkline';
11
12
  export { TableWidget, type TableWidgetProps } from './TableWidget';
12
13
  export { OnboardingWidget, type OnboardingStepInput, type OnboardingWidgetProps } from './OnboardingWidget';
13
14
  export { SidebarOnboarding, type SidebarOnboardingProps } from './SidebarOnboarding';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dashboard/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,eAAe,EACf,UAAU,EACV,yBAAyB,EACzB,oBAAoB,EACpB,KAAK,oBAAoB,GAC1B,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,sBAAsB,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAA;AACrE,OAAO,EAAE,uBAAuB,EAAE,KAAK,yBAAyB,EAAE,MAAM,eAAe,CAAA;AACvF,OAAO,EAAE,sBAAsB,EAAE,KAAK,2BAA2B,EAAE,MAAM,0BAA0B,CAAA;AACnG,OAAO,EAAE,aAAa,EAAE,KAAK,iBAAiB,EAAE,KAAK,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAChG,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAA;AACzD,OAAO,EACL,sBAAsB,EACtB,qBAAqB,EACrB,iBAAiB,EACjB,qBAAqB,EACrB,KAAK,cAAc,EACnB,KAAK,2BAA2B,GACjC,MAAM,kBAAkB,CAAA;AACzB,YAAY,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAA;AAC9D,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,KAAK,YAAY,EAAE,MAAM,WAAW,CAAA;AACtE,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAClE,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAClE,OAAO,EAAE,gBAAgB,EAAE,KAAK,mBAAmB,EAAE,KAAK,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AAC3G,OAAO,EAAE,iBAAiB,EAAE,KAAK,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AACpF,OAAO,EAAE,qBAAqB,EAAE,KAAK,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AACxF,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AACnC,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,sBAAsB,EACtB,kBAAkB,EAClB,KAAK,iBAAiB,GACvB,MAAM,UAAU,CAAA;AACjB,YAAY,EACV,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,GAC5E,MAAM,SAAS,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dashboard/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,eAAe,EACf,UAAU,EACV,yBAAyB,EACzB,oBAAoB,EACpB,KAAK,oBAAoB,GAC1B,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,sBAAsB,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAA;AACrE,OAAO,EAAE,uBAAuB,EAAE,KAAK,yBAAyB,EAAE,MAAM,eAAe,CAAA;AACvF,OAAO,EAAE,sBAAsB,EAAE,KAAK,2BAA2B,EAAE,MAAM,0BAA0B,CAAA;AACnG,OAAO,EAAE,aAAa,EAAE,KAAK,iBAAiB,EAAE,KAAK,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAChG,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAA;AACzD,OAAO,EACL,sBAAsB,EACtB,qBAAqB,EACrB,iBAAiB,EACjB,qBAAqB,EACrB,KAAK,cAAc,EACnB,KAAK,2BAA2B,GACjC,MAAM,kBAAkB,CAAA;AACzB,YAAY,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAA;AAC9D,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,KAAK,YAAY,EAAE,MAAM,WAAW,CAAA;AACtE,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAClE,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5D,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAClE,OAAO,EAAE,gBAAgB,EAAE,KAAK,mBAAmB,EAAE,KAAK,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AAC3G,OAAO,EAAE,iBAAiB,EAAE,KAAK,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AACpF,OAAO,EAAE,qBAAqB,EAAE,KAAK,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AACxF,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AACnC,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,sBAAsB,EACtB,kBAAkB,EAClB,KAAK,iBAAiB,GACvB,MAAM,UAAU,CAAA;AACjB,YAAY,EACV,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,GAC5E,MAAM,SAAS,CAAA"}
@@ -1,5 +1,6 @@
1
- export { ChartWidget, DEFAULT_RANGE_OPTIONS, DashboardCanvas, DashboardCustomizeMenu, DashboardGrid, DashboardNavigateProvider, DashboardRangeControl, DashboardRangeProvider, GoldCard, KpiCard, OnboardingWidget, SidebarOnboarding, TableWidget, WidgetGrid, defineChartWidget, defineCustomWidget, defineKpiWidget, defineOnboardingWidget, defineTableWidget, formatKpiValue, renderIcon, resolveDashboardLayout, useDashboardNavigate, useDashboardPreferences, useDashboardRange, useOnboardingProgress } from '../chunk-I6CPKAOD.js';
2
- import '../chunk-6V5MGYXH.js';
1
+ export { ChartWidget, DEFAULT_RANGE_OPTIONS, DashboardCanvas, DashboardCustomizeMenu, DashboardGrid, DashboardNavigateProvider, DashboardRangeControl, DashboardRangeProvider, GoldCard, KpiCard, OnboardingWidget, SidebarOnboarding, Sparkline, TableWidget, WidgetGrid, defineChartWidget, defineCustomWidget, defineKpiWidget, defineOnboardingWidget, defineTableWidget, formatKpiValue, renderIcon, resolveDashboardLayout, useDashboardNavigate, useDashboardPreferences, useDashboardRange, useOnboardingProgress } from '../chunk-7BMXN7MP.js';
2
+ import '../chunk-JGJNRNQW.js';
3
+ import '../chunk-ZBQ772DU.js';
3
4
  import '../chunk-OKZ6WQB3.js';
4
5
  import '../chunk-22EVFMS3.js';
5
6
  //# sourceMappingURL=index.js.map
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { cn } from './lib/cn';
2
- export { Button, buttonVariants, type ButtonProps, Input, type InputProps, Badge, badgeVariants, type BadgeProps, Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent, Modal, ModalPortal, ModalOverlay, ModalClose, ModalTrigger, ModalContent, ModalHeader, ModalBody, ModalFooter, ModalTitle, ModalDescription, type ModalSize, Dropdown, DropdownTrigger, DropdownContent, DropdownItem, DropdownCheckboxItem, DropdownRadioItem, DropdownLabel, DropdownSeparator, DropdownShortcut, DropdownGroup, DropdownPortal, DropdownSub, DropdownSubContent, DropdownSubTrigger, DropdownRadioGroup, DataTable, type DataTableProps, Checkbox, type CheckboxColor, type CheckboxProps, Sheet, SheetPortal, SheetOverlay, SheetTrigger, SheetClose, SheetContent, SheetHeader, SheetBody, SheetFooter, SheetTitle, SheetDescription, Select, SelectGroup, SelectValue, SelectTrigger, SelectContent, SelectLabel, SelectItem, SelectSeparator, SelectScrollUpButton, SelectScrollDownButton, ToastProvider, toast, Tabs, TabsList, TabsTrigger, TabsContent, Separator, PhoneLink, normalizePhone, type PhoneLinkProps, type NormalizedPhone, Breadcrumb, Tooltip, TooltipTrigger, TooltipContent, TooltipProvider, PageHeader, PageHeaderCrumb, type PageHeaderProps, StatTiles, type StatTilesProps, type StatTileData, Switch, type SwitchProps, Hint, type HintProps, TimePicker, Skeleton, TableSkeleton, ListView, DatePicker, SearchSelect, type SearchSelectOption, type SearchSelectProps, CurrencyInput, ConfirmDialog, Popover, PopoverTrigger, PopoverContent, SegmentedControl, type SegmentedControlProps, type SegmentedOption, HeaderTabs, type HeaderTabsProps, type HeaderTab, FilterChip, type FilterChipProps, type FilterChipOption, Markdown, renderMarkdown, type MarkdownProps, MarkdownEditor, type MarkdownEditorProps, SearchCombobox, type ComboboxOption, } from './primitives';
3
- export { AppShell, type AppShellProps, type AppShellUser, type BottomNavItem, type BottomNavRouteItem, type BottomNavActionItem, type MobileHeaderVariant, Sidebar, type SidebarProps, type SidebarUser, type NavigationItem, ICON_MAP, Topbar, type TopbarProps, ModulePage, SubpageHeader, ContentSplit, ContentSplitTrigger, ModuleLayoutProvider, useModuleLayout, PageHeaderActions, BackStyleProvider, useBackStyle, SaveBar, SaveBarProvider, useSaveBar, useBackHandler, type SaveBarRegistration, useModuleHeaderSlot, useModuleHeaderActionsSlot, PageTransition, NavTransitionProvider, useNavTransition, type NavTransition, type ModulePageProps, type ModuleNavItem, type ModuleNavVariant, type SubpageHeaderProps, type ContentSplitProps, type ContentSplitTriggerProps, type BackButtonStyle, } from './layout';
2
+ export { Button, buttonVariants, type ButtonProps, Input, type InputProps, Badge, badgeVariants, type BadgeProps, Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent, Modal, ModalPortal, ModalOverlay, ModalClose, ModalTrigger, ModalContent, ModalHeader, ModalBody, ModalFooter, ModalTitle, ModalDescription, type ModalSize, Dropdown, DropdownTrigger, DropdownContent, DropdownItem, DropdownCheckboxItem, DropdownRadioItem, DropdownLabel, DropdownSeparator, DropdownShortcut, DropdownGroup, DropdownPortal, DropdownSub, DropdownSubContent, DropdownSubTrigger, DropdownRadioGroup, DataTable, type DataTableProps, Checkbox, type CheckboxColor, type CheckboxProps, Sheet, SheetPortal, SheetOverlay, SheetTrigger, SheetClose, SheetContent, SheetHeader, SheetBody, SheetFooter, SheetTitle, SheetDescription, Select, SelectGroup, SelectValue, SelectTrigger, SelectContent, SelectLabel, SelectItem, SelectSeparator, SelectScrollUpButton, SelectScrollDownButton, ToastProvider, toast, Tabs, TabsList, TabsTrigger, TabsContent, Separator, PhoneLink, normalizePhone, type PhoneLinkProps, type NormalizedPhone, Breadcrumb, Tooltip, TooltipTrigger, TooltipContent, TooltipProvider, PageHeader, PageHeaderCrumb, type PageHeaderProps, SearchField, ChevronPager, BulkActionBar, type BulkAction, type BulkActionBarProps, Thumbnail, type ThumbnailProps, type ThumbnailSize, PhoneField, formatPhone, type PhoneFieldProps, type SearchFieldProps, type ChevronPagerProps, StatTiles, type StatTilesProps, type StatTileData, Switch, type SwitchProps, Hint, type HintProps, TimePicker, Skeleton, TableSkeleton, ListView, DatePicker, SearchSelect, type SearchSelectOption, type SearchSelectProps, CurrencyInput, ConfirmDialog, Popover, PopoverTrigger, PopoverContent, SegmentedControl, type SegmentedControlProps, type SegmentedOption, HeaderTabs, type HeaderTabsProps, type HeaderTab, FilterChip, type FilterChipProps, type FilterChipOption, Markdown, renderMarkdown, type MarkdownProps, MarkdownEditor, type MarkdownEditorProps, SearchCombobox, type ComboboxOption, RefreshButton, type RefreshButtonProps, } from './primitives';
3
+ export { AppShell, type AppShellProps, type AppShellUser, AppShellSkeleton, type AppShellSkeletonProps, type BottomNavItem, type BottomNavRouteItem, type BottomNavActionItem, type MobileHeaderVariant, Sidebar, type SidebarProps, type SidebarUser, type NavigationItem, ICON_MAP, Topbar, type TopbarProps, ModulePage, SubpageHeader, ContentSplit, ContentSplitTrigger, ModuleLayoutProvider, useModuleLayout, PageHeaderActions, BackStyleProvider, useBackStyle, PageTrail, usePageTrail, usePageTrailParent, navigateToCrumb, type PageTrailCrumb, SaveBar, SaveBarProvider, useSaveBar, useBackHandler, type SaveBarRegistration, useModuleHeaderSlot, useModuleHeaderActionsSlot, PageTransition, NavTransitionProvider, useNavTransition, type NavTransition, type ModulePageProps, type ModuleNavItem, type ModuleNavVariant, type SubpageHeaderProps, type ContentSplitProps, type ContentSplitTriggerProps, type BackButtonStyle, } from './layout';
4
4
  export { useLayoutStore, usePageHeader, usePageHeaderSlot, usePageHeaderHost, useHasPageHeaderHost, useHasPageHeaderOutlet, PageHeaderOutlet, useThemeStore, lightTheme, darkTheme, type ThemeTokens, type SemanticColors, type UIPerceptionTokens, type CreateThemeOptions, } from './stores';
5
5
  export { ThemeProvider, useTheme, createTheme, createFayzTheme, fayzThemePresets, type ThemeProviderProps, type FayzThemePresetId, } from './theme';
6
6
  export { Avatar, AvatarImage, AvatarFallback } from './primitives/Avatar';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,19 +1,21 @@
1
- import { Popover, PopoverTrigger, PopoverContent, Input, Hint } from './chunk-SEIY2F5F.js';
2
- export { Badge, Breadcrumb, Checkbox, ConfirmDialog, CurrencyInput, DatePicker, FilterChip, Hint, Input, ListView, Markdown, MarkdownEditor, Modal, ModalBody, ModalClose, ModalContent, ModalDescription, ModalFooter, ModalHeader, ModalOverlay, ModalPortal, ModalTitle, ModalTrigger, PhoneLink, Popover, PopoverContent, PopoverTrigger, SearchCombobox, SearchSelect, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, StatTiles, Switch, Tabs, TabsContent, TabsList, TabsTrigger, TimePicker, ToastProvider, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, badgeVariants, normalizePhone, renderMarkdown, toast } from './chunk-SEIY2F5F.js';
3
- export { AppShell, BackStyleProvider, ContentSplit, ContentSplitTrigger, ModuleLayoutProvider, ModulePage, NavTransitionProvider, PageHeaderActions, PageTransition, Sidebar, SubpageHeader, Topbar, useBackStyle, useLayoutStore, useModuleHeaderActionsSlot, useModuleHeaderSlot, useModuleLayout, useNavTransition } from './chunk-H63TOSQ7.js';
1
+ import { Popover, PopoverTrigger, PopoverContent, Input, Hint, DatePicker } from './chunk-7BHG3XGJ.js';
2
+ export { Badge, Breadcrumb, BulkActionBar, ChevronPager, ConfirmDialog, CurrencyInput, DatePicker, FilterChip, Hint, Input, ListView, Markdown, MarkdownEditor, Modal, ModalBody, ModalClose, ModalContent, ModalDescription, ModalFooter, ModalHeader, ModalOverlay, ModalPortal, ModalTitle, ModalTrigger, PhoneField, PhoneLink, Popover, PopoverContent, PopoverTrigger, RefreshButton, SearchCombobox, SearchField, SearchSelect, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, StatTiles, Switch, Tabs, TabsContent, TabsList, TabsTrigger, Thumbnail, TimePicker, ToastProvider, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, badgeVariants, formatPhone, normalizePhone, renderMarkdown, toast } from './chunk-7BHG3XGJ.js';
3
+ export { AppShell, AppShellSkeleton, BackStyleProvider, ContentSplit, ContentSplitTrigger, ModuleLayoutProvider, ModulePage, NavTransitionProvider, PageHeaderActions, PageTrail, PageTransition, Sidebar, SubpageHeader, Topbar, navigateToCrumb, useBackStyle, useModuleHeaderActionsSlot, useModuleHeaderSlot, useModuleLayout, useNavTransition, usePageTrail, usePageTrailParent } from './chunk-ZDRHCKRK.js';
4
4
  export { HeaderTabs, PageHeader, PageHeaderCrumb, PageHeaderOutlet, SaveBar, SaveBarProvider, Sheet, SheetBody, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, useBackHandler, useHasPageHeaderHost, useHasPageHeaderOutlet, usePageHeader, usePageHeaderHost, usePageHeaderSlot, useSaveBar } from './chunk-VAKWUUVC.js';
5
5
  export { ThemeProvider, createFayzTheme, createTheme, darkTheme, fayzThemePresets, lightTheme, useTheme, useThemeStore } from './chunk-VDAYIQX4.js';
6
- import { ChartWidget, DashboardGrid } from './chunk-I6CPKAOD.js';
7
- export { ChartWidget, DEFAULT_RANGE_OPTIONS, DashboardCanvas, DashboardCustomizeMenu, DashboardGrid, DashboardNavigateProvider, DashboardRangeControl, DashboardRangeProvider, GoldCard, KpiCard, OnboardingWidget, SidebarOnboarding, TableWidget, WidgetGrid, defineChartWidget, defineCustomWidget, defineKpiWidget, defineOnboardingWidget, defineTableWidget, formatKpiValue, renderIcon, resolveDashboardLayout, useDashboardNavigate, useDashboardPreferences, useDashboardRange, useOnboardingProgress } from './chunk-I6CPKAOD.js';
8
- import { Skeleton, Dropdown, DropdownTrigger, DropdownContent, DropdownItem, Card, CardContent } from './chunk-6V5MGYXH.js';
9
- export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, DataTable, Dropdown, DropdownCheckboxItem, DropdownContent, DropdownGroup, DropdownItem, DropdownLabel, DropdownPortal, DropdownRadioGroup, DropdownRadioItem, DropdownSeparator, DropdownShortcut, DropdownSub, DropdownSubContent, DropdownSubTrigger, DropdownTrigger, SegmentedControl, Skeleton, TableSkeleton } from './chunk-6V5MGYXH.js';
6
+ import { ChartWidget, Sparkline, DashboardGrid } from './chunk-7BMXN7MP.js';
7
+ export { ChartWidget, DEFAULT_RANGE_OPTIONS, DashboardCanvas, DashboardCustomizeMenu, DashboardGrid, DashboardNavigateProvider, DashboardRangeControl, DashboardRangeProvider, GoldCard, KpiCard, OnboardingWidget, SidebarOnboarding, TableWidget, WidgetGrid, defineChartWidget, defineCustomWidget, defineKpiWidget, defineOnboardingWidget, defineTableWidget, formatKpiValue, renderIcon, resolveDashboardLayout, useDashboardNavigate, useDashboardPreferences, useDashboardRange, useOnboardingProgress } from './chunk-7BMXN7MP.js';
8
+ import { Skeleton, Dropdown, DropdownTrigger, DropdownContent, DropdownItem, Card, CardContent, DropdownSeparator } from './chunk-JGJNRNQW.js';
9
+ export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, DataTable, Dropdown, DropdownCheckboxItem, DropdownContent, DropdownGroup, DropdownItem, DropdownLabel, DropdownPortal, DropdownRadioGroup, DropdownRadioItem, DropdownSeparator, DropdownShortcut, DropdownSub, DropdownSubContent, DropdownSubTrigger, DropdownTrigger, SegmentedControl, Skeleton, TableSkeleton } from './chunk-JGJNRNQW.js';
10
+ export { useLayoutStore } from './chunk-ZBQ772DU.js';
10
11
  import { cn, Button } from './chunk-OKZ6WQB3.js';
11
12
  export { Button, buttonVariants, cn } from './chunk-OKZ6WQB3.js';
12
13
  export { ICON_MAP, getLucideIcon, registerIcons } from './chunk-22EVFMS3.js';
13
14
  import * as React2 from 'react';
14
15
  import * as AvatarPrimitive from '@radix-ui/react-avatar';
15
- import { jsx, jsxs } from 'react/jsx-runtime';
16
- import { Construction, DatabaseZap, AlertCircle, SlidersHorizontal, Search, ChevronRight, Calendar, GitCompareArrows, RefreshCw, X, TrendingUp, TrendingDown, Info, ArrowUpRight } from 'lucide-react';
16
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
17
+ import { ChevronDown, Construction, DatabaseZap, AlertCircle, SlidersHorizontal, Search, ChevronRight, GitCompareArrows, Check, RefreshCw, X, TrendingUp, TrendingDown, Info, ArrowUpRight, Calendar } from 'lucide-react';
18
+ import { useTranslation, getCurrentLocale } from '@fayz-ai/core';
17
19
 
18
20
  var Avatar = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
19
21
  AvatarPrimitive.Root,
@@ -154,6 +156,7 @@ function isEngineMissing(err) {
154
156
  const code = typeof e.code === "string" ? e.code : "";
155
157
  if (["42883", "42P01", "PGRST202"].includes(code)) return true;
156
158
  const message = typeof e.message === "string" ? e.message.toLowerCase() : "";
159
+ if (message.includes("permission denied") || code === "42501") return false;
157
160
  return message.includes("analytics_run") || message.includes("plg_shop_rep_");
158
161
  }
159
162
  function num(value) {
@@ -263,7 +266,7 @@ function vizMeasures(card) {
263
266
  return wanted.map((key) => all.find((m) => m.key === key)).filter((m) => Boolean(m));
264
267
  }
265
268
  function vizCategory(card) {
266
- const dims = card.query.dimensions ?? [];
269
+ const dims = (card.query.dimensions ?? []).filter((d) => !d.hidden);
267
270
  if (card.viz.categoryKey) return dims.find((d) => d.key === card.viz.categoryKey) ?? dims[0];
268
271
  return dims[0];
269
272
  }
@@ -282,6 +285,62 @@ function toSpark(result, measureKey) {
282
285
  if (!result?.rows?.length || result.rows.length < 2) return void 0;
283
286
  return result.rows.map((row) => num(row[measureKey]));
284
287
  }
288
+
289
+ // src/analytics/batch.ts
290
+ var BATCH_WINDOW_MS = 16;
291
+ function createBatchingProvider(provider, options = {}) {
292
+ const windowMs = options.windowMs ?? BATCH_WINDOW_MS;
293
+ const inflight = /* @__PURE__ */ new Map();
294
+ let queue = [];
295
+ let timer = null;
296
+ const flush = () => {
297
+ timer = null;
298
+ const batch = queue;
299
+ queue = [];
300
+ if (batch.length === 0) return;
301
+ const individually = () => {
302
+ for (const p of batch) provider.run(p.card, p.state).then(p.resolve, p.reject);
303
+ };
304
+ if (batch.length === 1 || !provider.runMany) {
305
+ individually();
306
+ return;
307
+ }
308
+ let batchCall;
309
+ try {
310
+ batchCall = provider.runMany(batch.map(({ card, state }) => ({ card, state })));
311
+ } catch {
312
+ individually();
313
+ return;
314
+ }
315
+ batchCall.then(
316
+ (results) => batch.forEach((p, i) => {
317
+ const result = results[i];
318
+ if (!result) p.reject(new Error("analytics: batch returned no result for this card"));
319
+ else if (result instanceof Error) p.reject(result);
320
+ else p.resolve(result);
321
+ }),
322
+ (error) => batch.forEach((p) => p.reject(error))
323
+ );
324
+ };
325
+ return {
326
+ run(card, state) {
327
+ const key = JSON.stringify([card.id, state, options.refreshToken ?? 0]);
328
+ const existing = inflight.get(key);
329
+ if (existing) return existing;
330
+ const promise = new Promise((resolve, reject) => {
331
+ queue.push({ card, state, resolve, reject });
332
+ if (timer == null) timer = setTimeout(flush, windowMs);
333
+ }).finally(() => {
334
+ inflight.delete(key);
335
+ });
336
+ inflight.set(key, promise);
337
+ return promise;
338
+ },
339
+ // Passed through so a caller that already has a batch of its own (an export
340
+ // of every card, say) still reaches the provider's own batching.
341
+ runMany: provider.runMany ? (requests) => provider.runMany(requests) : void 0
342
+ };
343
+ }
285
344
  var AnalyticsContext = React2.createContext(null);
286
345
  function useAnalyticsContext() {
287
346
  const ctx = React2.useContext(AnalyticsContext);
@@ -350,23 +409,12 @@ function AnalyticsContextProvider({
350
409
  setState((s) => ({ ...s, search, page: 1 }));
351
410
  }, []);
352
411
  const refresh = React2.useCallback(() => setRefreshToken((t) => t + 1), []);
353
- const deduped = React2.useMemo(() => {
354
- const inflight = /* @__PURE__ */ new Map();
355
- return {
356
- run(card, queryState) {
357
- const key = JSON.stringify([card.id, queryState, refreshToken]);
358
- const existing = inflight.get(key);
359
- if (existing) return existing;
360
- const promise = provider.run(card, queryState).finally(() => {
361
- inflight.delete(key);
362
- });
363
- inflight.set(key, promise);
364
- return promise;
365
- }
366
- };
367
- }, [provider, refreshToken]);
412
+ const batched = React2.useMemo(
413
+ () => createBatchingProvider(provider, { refreshToken }),
414
+ [provider, refreshToken]
415
+ );
368
416
  const value = React2.useMemo(() => ({
369
- provider: deduped,
417
+ provider: batched,
370
418
  currency: currency ?? { code: "BRL", locale: "pt-BR", symbol: "R$" },
371
419
  state,
372
420
  preset,
@@ -385,7 +433,7 @@ function AnalyticsContextProvider({
385
433
  onOpenCard,
386
434
  createdBy
387
435
  }), [
388
- deduped,
436
+ batched,
389
437
  currency,
390
438
  state,
391
439
  preset,
@@ -518,26 +566,6 @@ function CardChrome({
518
566
  /* @__PURE__ */ jsx(CardContent, { className: cn("flex-1", dense ? "p-4 pt-2" : "p-5 pt-2"), children })
519
567
  ] });
520
568
  }
521
- function Spark({ data, color }) {
522
- const gid = React2.useId();
523
- if (data.length < 2) return null;
524
- const W = 120, H = 28, P = 2;
525
- const min = Math.min(...data);
526
- const max = Math.max(...data);
527
- const span = max - min || 1;
528
- const step = (W - P * 2) / (data.length - 1);
529
- const pts = data.map((d, i) => [P + i * step, P + (H - P * 2) * (1 - (d - min) / span)]);
530
- const line = pts.map(([x, y], i) => `${i === 0 ? "M" : "L"}${x.toFixed(1)},${y.toFixed(1)}`).join(" ");
531
- const area = `${line} L${pts[pts.length - 1][0].toFixed(1)},${H} L${pts[0][0].toFixed(1)},${H} Z`;
532
- return /* @__PURE__ */ jsxs("svg", { viewBox: `0 0 ${W} ${H}`, className: "h-7 w-full", preserveAspectRatio: "none", "aria-hidden": true, children: [
533
- /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("linearGradient", { id: gid, x1: "0", y1: "0", x2: "0", y2: "1", children: [
534
- /* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: color, stopOpacity: "0.22" }),
535
- /* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: color, stopOpacity: "0" })
536
- ] }) }),
537
- /* @__PURE__ */ jsx("path", { d: area, fill: `url(#${gid})` }),
538
- /* @__PURE__ */ jsx("path", { d: line, fill: "none", stroke: color, strokeWidth: "1.5", vectorEffect: "non-scaling-stroke", strokeLinejoin: "round" })
539
- ] });
540
- }
541
569
  function TrendChip({ current, previous }) {
542
570
  const delta = deltaPercent(current, previous);
543
571
  const trend = trendOf(current, previous);
@@ -580,7 +608,7 @@ function MiniTable({
580
608
  currency,
581
609
  limit
582
610
  }) {
583
- const dims = card.query.dimensions ?? [];
611
+ const dims = (card.query.dimensions ?? []).filter((d) => !d.hidden);
584
612
  const measures = vizMeasures(card);
585
613
  const cols = [
586
614
  ...dims.map((d) => ({ key: d.key, label: d.label, format: d.format, align: "left" })),
@@ -640,7 +668,17 @@ function AnalyticsCard({ card, className, hideOpen }) {
640
668
  /* @__PURE__ */ jsx("span", { className: "text-2xl font-semibold tracking-tight tabular-nums", children: formatAnalyticsValue(value, measure.format, currency, { compact: true }) }),
641
669
  /* @__PURE__ */ jsx(TrendChip, { current: value, previous })
642
670
  ] }),
643
- spark ? /* @__PURE__ */ jsx(Spark, { data: spark, color: "hsl(var(--info))" }) : null
671
+ spark ? /* @__PURE__ */ jsx(
672
+ Sparkline,
673
+ {
674
+ data: spark,
675
+ color: "hsl(var(--info))",
676
+ width: 120,
677
+ height: 28,
678
+ padding: 2,
679
+ className: "h-7 w-full"
680
+ }
681
+ ) : null
644
682
  ] });
645
683
  }
646
684
  case "breakdown": {
@@ -735,28 +773,35 @@ function collectFilters(cards) {
735
773
  return [...byKey.values()];
736
774
  }
737
775
  var PRESETS = [
738
- { value: "today", label: "Today" },
739
- { value: "yesterday", label: "Yesterday" },
740
- { value: "last_7_days", label: "Last 7 days" },
741
- { value: "last_30_days", label: "Last 30 days" },
742
- { value: "last_90_days", label: "Last 90 days" },
743
- { value: "this_month", label: "This month" },
744
- { value: "last_month", label: "Last month" },
745
- { value: "this_quarter", label: "This quarter" },
746
- { value: "this_year", label: "This year" }
747
- ];
748
- var COMPARE_OPTIONS = [
749
- { value: "previous_period", label: "Previous period" },
750
- { value: "previous_year", label: "Previous year" },
751
- { value: "none", label: "No comparison" }
776
+ "today",
777
+ "yesterday",
778
+ "last_7_days",
779
+ "last_30_days",
780
+ "last_90_days",
781
+ "this_month",
782
+ "last_month",
783
+ "this_quarter",
784
+ "this_year"
752
785
  ];
753
- var UNGROUPED = "General";
754
- var ControlButton = React2.forwardRef(function ControlButton2({ icon: Icon, children, ...props }, ref) {
755
- return /* @__PURE__ */ jsxs(Button, { ref, variant: "outline", size: "sm", className: "h-8 gap-1.5 text-xs font-normal", ...props, children: [
756
- Icon ? /* @__PURE__ */ jsx(Icon, { className: "h-3.5 w-3.5" }) : null,
757
- children
786
+ var COMPARE_OPTIONS = ["previous_period", "previous_year", "none"];
787
+ var ControlButton = React2.forwardRef(function ControlButton2({ icon: Icon, children, className, ...props }, ref) {
788
+ return /* @__PURE__ */ jsxs(Button, { ref, variant: "outline", size: "sm", className: cn("gap-1.5", className), ...props, children: [
789
+ Icon ? /* @__PURE__ */ jsx(Icon, { className: "h-3 w-3 shrink-0 opacity-70" }) : null,
790
+ children,
791
+ /* @__PURE__ */ jsx(ChevronDown, { className: "h-3 w-3 shrink-0 opacity-60" })
758
792
  ] });
759
793
  });
794
+ function formatSpan(from, to, locale) {
795
+ const opts = { day: "2-digit", month: "short" };
796
+ const a = parseDay(from);
797
+ const b = parseDay(to);
798
+ const fmt = (d) => d.toLocaleDateString(locale, {
799
+ ...opts,
800
+ // The year only earns its space when the range leaves the current one.
801
+ ...d.getFullYear() === (/* @__PURE__ */ new Date()).getFullYear() ? {} : { year: "numeric" }
802
+ });
803
+ return from === to ? fmt(a) : `${fmt(a)} \u2013 ${fmt(b)}`;
804
+ }
760
805
  function useFilterOptions(filter) {
761
806
  const [options, setOptions] = React2.useState(
762
807
  Array.isArray(filter.options) ? filter.options : []
@@ -782,6 +827,7 @@ function FilterValues({
782
827
  draft,
783
828
  onChange
784
829
  }) {
830
+ const t = useTranslation();
785
831
  const options = useFilterOptions(filter);
786
832
  const current = draft[filter.key];
787
833
  if (filter.type === "text" || filter.type === "number") {
@@ -797,7 +843,7 @@ function FilterValues({
797
843
  );
798
844
  }
799
845
  if (filter.type === "boolean") {
800
- return /* @__PURE__ */ jsx("div", { className: "space-y-1", children: [{ label: "Yes", value: "true" }, { label: "No", value: "false" }].map((o) => /* @__PURE__ */ jsxs("label", { className: "flex cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-sm hover:bg-muted", children: [
846
+ return /* @__PURE__ */ jsx("div", { className: "space-y-1", children: [{ label: t("common.yes"), value: "true" }, { label: t("common.no"), value: "false" }].map((o) => /* @__PURE__ */ jsxs("label", { className: "flex cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-sm hover:bg-muted", children: [
801
847
  /* @__PURE__ */ jsx(
802
848
  "input",
803
849
  {
@@ -814,7 +860,7 @@ function FilterValues({
814
860
  const multi = filter.type === "multiselect";
815
861
  const selected = new Set(Array.isArray(current) ? current.map(String) : current != null ? [String(current)] : []);
816
862
  if (options.length === 0) {
817
- return /* @__PURE__ */ jsx("p", { className: "px-2 py-1.5 text-xs text-muted-foreground", children: "No options available" });
863
+ return /* @__PURE__ */ jsx("p", { className: "px-2 py-1.5 text-xs text-muted-foreground", children: t("analytics.filters.noOptions") });
818
864
  }
819
865
  return /* @__PURE__ */ jsx("div", { className: "max-h-56 space-y-0.5 overflow-y-auto", children: options.map((o) => /* @__PURE__ */ jsxs("label", { className: "flex cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-sm hover:bg-muted", children: [
820
866
  /* @__PURE__ */ jsx(
@@ -840,6 +886,7 @@ function FilterValues({
840
886
  ] }, o.value)) });
841
887
  }
842
888
  function AnalyticsFilterPicker({ filters }) {
889
+ const t = useTranslation();
843
890
  const { state, setFilters, clearFilters } = useAnalyticsContext();
844
891
  const [open, setOpen] = React2.useState(false);
845
892
  const [search, setSearch] = React2.useState("");
@@ -853,18 +900,18 @@ function AnalyticsFilterPicker({ filters }) {
853
900
  const matching = q ? filters.filter((f) => f.label.toLowerCase().includes(q)) : filters;
854
901
  const map = /* @__PURE__ */ new Map();
855
902
  for (const f of matching) {
856
- const key = f.group ?? UNGROUPED;
903
+ const key = f.group ?? t("analytics.filters.general");
857
904
  map.set(key, [...map.get(key) ?? [], f]);
858
905
  }
859
906
  return [...map.entries()].sort(([a], [b]) => a.localeCompare(b));
860
- }, [filters, search]);
907
+ }, [filters, search, t]);
861
908
  const activeCount = Object.keys(state.filters).length;
862
909
  if (filters.length === 0) return null;
863
910
  return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
864
- /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button, { variant: "outline", size: "sm", className: "h-8 gap-1.5 text-xs font-normal", children: [
865
- /* @__PURE__ */ jsx(SlidersHorizontal, { className: "h-3.5 w-3.5" }),
866
- "Filters",
867
- activeCount > 0 ? /* @__PURE__ */ jsx("span", { className: "ml-0.5 rounded-full bg-primary px-1.5 text-[10px] font-medium text-primary-foreground", children: activeCount }) : null
911
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button, { variant: "outline", size: "sm", className: "gap-1.5", children: [
912
+ /* @__PURE__ */ jsx(SlidersHorizontal, { className: "h-3 w-3 shrink-0 opacity-70" }),
913
+ t("analytics.filters"),
914
+ activeCount > 0 ? /* @__PURE__ */ jsx("span", { className: "ml-0.5 rounded-full bg-primary px-1.5 text-[10px] font-semibold text-primary-foreground", children: activeCount }) : null
868
915
  ] }) }),
869
916
  /* @__PURE__ */ jsxs(PopoverContent, { align: "end", className: "w-80 p-0", children: [
870
917
  /* @__PURE__ */ jsx("div", { className: "border-b p-2", children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
@@ -874,12 +921,12 @@ function AnalyticsFilterPicker({ filters }) {
874
921
  {
875
922
  value: search,
876
923
  onChange: (e) => setSearch(e.target.value),
877
- placeholder: "Search filters",
924
+ placeholder: t("analytics.filters.search"),
878
925
  className: "h-8 pl-8 text-sm"
879
926
  }
880
927
  )
881
928
  ] }) }),
882
- /* @__PURE__ */ jsx("div", { className: "max-h-80 overflow-y-auto p-1", children: groups.length === 0 ? /* @__PURE__ */ jsx("p", { className: "px-3 py-6 text-center text-sm text-muted-foreground", children: "No filters match" }) : groups.map(([group, groupFilters]) => /* @__PURE__ */ jsxs("div", { children: [
929
+ /* @__PURE__ */ jsx("div", { className: "max-h-80 overflow-y-auto p-1", children: groups.length === 0 ? /* @__PURE__ */ jsx("p", { className: "px-3 py-6 text-center text-sm text-muted-foreground", children: t("analytics.filters.none") }) : groups.map(([group, groupFilters]) => /* @__PURE__ */ jsxs("div", { children: [
883
930
  /* @__PURE__ */ jsxs(
884
931
  "button",
885
932
  {
@@ -916,81 +963,154 @@ function AnalyticsFilterPicker({ filters }) {
916
963
  {
917
964
  variant: "ghost",
918
965
  size: "sm",
919
- className: "h-8 text-xs",
920
966
  onClick: () => {
921
967
  setDraft({});
922
968
  clearFilters();
923
969
  setOpen(false);
924
970
  },
925
- children: "Clear"
971
+ children: t("analytics.filters.clear")
926
972
  }
927
973
  ),
928
- /* @__PURE__ */ jsx(Button, { size: "sm", className: "h-8 text-xs", onClick: () => {
974
+ /* @__PURE__ */ jsx(Button, { size: "sm", onClick: () => {
929
975
  setFilters(draft);
930
976
  setOpen(false);
931
- }, children: "Apply" })
977
+ }, children: t("analytics.filters.apply") })
932
978
  ] })
933
979
  ] })
934
980
  ] });
935
981
  }
936
- function AnalyticsControls({ filters = [], showCompare = true, actions, className }) {
937
- const { state, preset, setPreset, setCompare, refresh } = useAnalyticsContext();
938
- const presetLabel = PRESETS.find((p) => p.value === preset)?.label ?? `${state.dateRange.from} \u2013 ${state.dateRange.to}`;
939
- const compareLabel = COMPARE_OPTIONS.find((c) => c.value === (state.compare ?? "none"))?.label;
940
- const activeFilters = Object.entries(state.filters);
941
- const filterLabel = (key) => filters.find((f) => f.key === key)?.label ?? key;
942
- return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-wrap items-center gap-2", className), children: [
982
+ function AnalyticsRangeControl() {
983
+ const t = useTranslation();
984
+ const locale = getCurrentLocale();
985
+ const { state, preset, setPreset, setDateRange } = useAnalyticsContext();
986
+ const custom = preset === "custom";
987
+ const span = formatSpan(state.dateRange.from, state.dateRange.to, locale);
988
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
943
989
  /* @__PURE__ */ jsxs(Dropdown, { children: [
944
- /* @__PURE__ */ jsx(DropdownTrigger, { asChild: true, children: /* @__PURE__ */ jsx(ControlButton, { icon: Calendar, children: presetLabel }) }),
945
- /* @__PURE__ */ jsx(DropdownContent, { align: "start", className: "w-48", children: PRESETS.map((p) => /* @__PURE__ */ jsx(DropdownItem, { onSelect: () => setPreset(p.value), children: p.label }, p.value)) })
946
- ] }),
947
- showCompare ? /* @__PURE__ */ jsxs(Dropdown, { children: [
948
- /* @__PURE__ */ jsx(DropdownTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(ControlButton, { icon: GitCompareArrows, children: [
949
- "Compare: ",
950
- compareLabel
990
+ /* @__PURE__ */ jsx(DropdownTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(ControlButton, { icon: Calendar, children: [
991
+ custom ? t("analytics.range.custom") : t(`analytics.range.${preset}`),
992
+ !custom ? /* @__PURE__ */ jsx("span", { className: "font-normal text-muted-foreground", children: span }) : null
951
993
  ] }) }),
952
- /* @__PURE__ */ jsx(DropdownContent, { align: "start", className: "w-48", children: COMPARE_OPTIONS.map((c) => /* @__PURE__ */ jsx(DropdownItem, { onSelect: () => setCompare(c.value), children: c.label }, c.value)) })
953
- ] }) : null,
954
- /* @__PURE__ */ jsx(AnalyticsFilterPicker, { filters }),
955
- activeFilters.map(([key, value]) => /* @__PURE__ */ jsx(ActiveFilterChip, { label: filterLabel(key), value, filterKey: key }, key)),
956
- /* @__PURE__ */ jsxs("div", { className: "ml-auto flex items-center gap-2", children: [
957
- actions,
994
+ /* @__PURE__ */ jsxs(DropdownContent, { align: "start", className: "w-56", children: [
995
+ PRESETS.map((p) => /* @__PURE__ */ jsxs(DropdownItem, { onSelect: () => setPreset(p), children: [
996
+ t(`analytics.range.${p}`),
997
+ preset === p ? /* @__PURE__ */ jsx(Check, { className: "ml-auto h-3.5 w-3.5 shrink-0 pl-1" }) : null
998
+ ] }, p)),
999
+ /* @__PURE__ */ jsx(DropdownSeparator, {}),
1000
+ /* @__PURE__ */ jsxs(DropdownItem, { onSelect: () => setDateRange({ ...state.dateRange }), children: [
1001
+ t("analytics.range.custom"),
1002
+ custom ? /* @__PURE__ */ jsx(Check, { className: "ml-auto h-3.5 w-3.5 shrink-0 pl-1" }) : null
1003
+ ] })
1004
+ ] })
1005
+ ] }),
1006
+ custom ? /* @__PURE__ */ jsxs(Fragment, { children: [
1007
+ /* @__PURE__ */ jsx(
1008
+ DatePicker,
1009
+ {
1010
+ variant: "toolbar",
1011
+ value: state.dateRange.from,
1012
+ onChange: (from) => setDateRange({
1013
+ from,
1014
+ to: from > state.dateRange.to ? from : state.dateRange.to
1015
+ })
1016
+ }
1017
+ ),
1018
+ /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: "\u2013" }),
958
1019
  /* @__PURE__ */ jsx(
959
- Button,
1020
+ DatePicker,
960
1021
  {
961
- variant: "outline",
962
- size: "sm",
963
- onClick: refresh,
964
- "aria-label": "Refresh",
965
- className: "h-8 w-8 p-0",
966
- children: /* @__PURE__ */ jsx(RefreshCw, { className: "h-3.5 w-3.5" })
1022
+ variant: "toolbar",
1023
+ value: state.dateRange.to,
1024
+ onChange: (to) => setDateRange({
1025
+ from: to < state.dateRange.from ? to : state.dateRange.from,
1026
+ to
1027
+ })
967
1028
  }
968
1029
  )
969
- ] })
1030
+ ] }) : null
970
1031
  ] });
971
1032
  }
1033
+ function AnalyticsControls({ filters = [], showCompare = true, actions, className }) {
1034
+ const t = useTranslation();
1035
+ const { state, setCompare, refresh } = useAnalyticsContext();
1036
+ const compare = state.compare ?? "none";
1037
+ const activeFilters = Object.entries(state.filters);
1038
+ const filterLabel = (key) => filters.find((f) => f.key === key)?.label ?? key;
1039
+ return (
1040
+ // A surface of its own, on the same chrome as Card — rounded, hairline
1041
+ // border, soft shadow. It used to be a bare tinted strip with square edges
1042
+ // running the full content width, which on a grey page background read as a
1043
+ // seam in the layout rather than as a control that floats over the grid it
1044
+ // is filtering. It is also what makes the sticky state legible: a bar that
1045
+ // has an edge and a shadow is clearly ON TOP of the cards scrolling under
1046
+ // it, where a flat tint just smeared into them.
1047
+ /* @__PURE__ */ jsxs(
1048
+ "div",
1049
+ {
1050
+ className: cn(
1051
+ "flex flex-wrap items-center gap-2 rounded-card border bg-card/95 px-3 py-2 shadow-sm backdrop-blur",
1052
+ className
1053
+ ),
1054
+ children: [
1055
+ /* @__PURE__ */ jsx(AnalyticsRangeControl, {}),
1056
+ showCompare ? /* @__PURE__ */ jsxs(Dropdown, { children: [
1057
+ /* @__PURE__ */ jsx(DropdownTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
1058
+ ControlButton,
1059
+ {
1060
+ icon: GitCompareArrows,
1061
+ className: compare === "none" ? "text-muted-foreground" : void 0,
1062
+ children: t(`analytics.compare.${compare}`)
1063
+ }
1064
+ ) }),
1065
+ /* @__PURE__ */ jsx(DropdownContent, { align: "start", className: "w-48", children: COMPARE_OPTIONS.map((c) => /* @__PURE__ */ jsxs(DropdownItem, { onSelect: () => setCompare(c), children: [
1066
+ t(`analytics.compare.${c}`),
1067
+ compare === c ? /* @__PURE__ */ jsx(Check, { className: "ml-auto h-3.5 w-3.5 shrink-0 pl-1" }) : null
1068
+ ] }, c)) })
1069
+ ] }) : null,
1070
+ /* @__PURE__ */ jsx(AnalyticsFilterPicker, { filters }),
1071
+ activeFilters.map(([key, value]) => /* @__PURE__ */ jsx(ActiveFilterChip, { label: filterLabel(key), value, filterKey: key }, key)),
1072
+ /* @__PURE__ */ jsxs("div", { className: "ml-auto flex items-center gap-2", children: [
1073
+ actions,
1074
+ /* @__PURE__ */ jsx(
1075
+ Button,
1076
+ {
1077
+ variant: "outline",
1078
+ size: "sm",
1079
+ onClick: refresh,
1080
+ "aria-label": t("analytics.refresh"),
1081
+ className: "w-[26px] p-0",
1082
+ children: /* @__PURE__ */ jsx(RefreshCw, { className: "h-3 w-3" })
1083
+ }
1084
+ )
1085
+ ] })
1086
+ ]
1087
+ }
1088
+ )
1089
+ );
1090
+ }
972
1091
  function ActiveFilterChip({ label, value, filterKey }) {
1092
+ const t = useTranslation();
973
1093
  const { setFilter } = useAnalyticsContext();
974
- const text = Array.isArray(value) ? `${value.length} selected` : String(value);
975
- return /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 rounded-full border bg-muted/50 py-1 pl-2.5 pr-1 text-xs", children: [
976
- /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
1094
+ const text = Array.isArray(value) ? value.length === 1 ? String(value[0]) : t("analytics.filters.selected", { count: value.length }) : String(value);
1095
+ return /* @__PURE__ */ jsxs("span", { className: "inline-flex h-[26px] shrink-0 items-center gap-1 rounded-full border border-primary/30 bg-primary/10 py-1 pl-2.5 pr-1 text-xs font-medium text-primary", children: [
1096
+ /* @__PURE__ */ jsxs("span", { className: "opacity-70", children: [
977
1097
  label,
978
1098
  ":"
979
1099
  ] }),
980
- /* @__PURE__ */ jsx("span", { className: "font-medium", children: text }),
1100
+ /* @__PURE__ */ jsx("span", { className: "max-w-[10rem] truncate", children: text }),
981
1101
  /* @__PURE__ */ jsx(
982
1102
  "button",
983
1103
  {
984
1104
  type: "button",
985
1105
  onClick: () => setFilter(filterKey, void 0),
986
- "aria-label": `Remove ${label} filter`,
987
- className: "rounded-full p-0.5 hover:bg-muted",
1106
+ "aria-label": `${t("analytics.filters.remove")}: ${label}`,
1107
+ className: "rounded-full p-0.5 transition-colors hover:bg-primary/20",
988
1108
  children: /* @__PURE__ */ jsx(X, { className: "h-3 w-3" })
989
1109
  }
990
1110
  )
991
1111
  ] });
992
1112
  }
993
1113
 
994
- export { AnalyticsCard, AnalyticsContextProvider, AnalyticsControls, AnalyticsFilterPicker, AnalyticsGrid, Avatar, AvatarFallback, AvatarImage, autoGrain, collectFilters, comparisonRange, deltaPercent, errorMessage, formatAnalyticsValue, formatBucket, formatCompact, formatDuration, isEngineMissing, num, parseDay, rangeLengthDays, resolveRangePreset, resolveRatios, resolveRowRatios, toBreakdown, toChartData, toDayString, toSpark, trendOf, useAnalyticsCard, useAnalyticsContext, useAnalyticsContextOptional, vizCategory, vizMeasures };
1114
+ export { AnalyticsCard, AnalyticsContextProvider, AnalyticsControls, AnalyticsFilterPicker, AnalyticsGrid, Avatar, AvatarFallback, AvatarImage, BATCH_WINDOW_MS, autoGrain, collectFilters, comparisonRange, createBatchingProvider, deltaPercent, errorMessage, formatAnalyticsValue, formatBucket, formatCompact, formatDuration, isEngineMissing, num, parseDay, rangeLengthDays, resolveRangePreset, resolveRatios, resolveRowRatios, toBreakdown, toChartData, toDayString, toSpark, trendOf, useAnalyticsCard, useAnalyticsContext, useAnalyticsContextOptional, vizCategory, vizMeasures };
995
1115
  //# sourceMappingURL=index.js.map
996
1116
  //# sourceMappingURL=index.js.map