@pagamio/frontend-commons-lib 0.8.175 → 0.8.183
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/lib/api/client.d.ts +88 -0
- package/lib/api/client.js +339 -0
- package/lib/api/context.d.ts +112 -0
- package/lib/api/context.js +105 -0
- package/lib/api/index.d.ts +4 -0
- package/lib/api/index.js +4 -0
- package/lib/api/swr.d.ts +46 -0
- package/lib/api/swr.js +124 -0
- package/lib/api/types.d.ts +145 -0
- package/lib/api/types.js +10 -0
- package/lib/auth/authenticators/AuthenticatorFactory.d.ts +25 -0
- package/lib/auth/authenticators/AuthenticatorFactory.js +32 -0
- package/lib/auth/authenticators/index.d.ts +7 -0
- package/lib/auth/authenticators/index.js +7 -0
- package/lib/auth/authenticators/processors/DefaultAuthenticatorProcessor.d.ts +21 -0
- package/lib/auth/authenticators/processors/DefaultAuthenticatorProcessor.js +26 -0
- package/lib/auth/authenticators/processors/StrapiAuthenticatorProcessor.d.ts +74 -0
- package/lib/auth/authenticators/processors/StrapiAuthenticatorProcessor.js +99 -0
- package/lib/auth/authenticators/types.d.ts +26 -0
- package/lib/auth/authenticators/types.js +9 -0
- package/lib/auth/components/AppBanner.d.ts +7 -0
- package/lib/auth/components/AppBanner.js +9 -0
- package/lib/auth/components/AuthCard.d.ts +8 -0
- package/lib/auth/components/AuthCard.js +14 -0
- package/lib/auth/components/AuthFormUtils.d.ts +58 -0
- package/lib/auth/components/AuthFormUtils.js +52 -0
- package/lib/auth/components/AuthPageLayout.d.ts +45 -0
- package/lib/auth/components/AuthPageLayout.js +12 -0
- package/lib/auth/components/ChangePasswordPage.d.ts +12 -0
- package/lib/auth/components/ChangePasswordPage.js +59 -0
- package/lib/auth/components/CustomerRegistrationPage.d.ts +50 -0
- package/lib/auth/components/CustomerRegistrationPage.js +140 -0
- package/lib/auth/components/ForgotPasswordPage.d.ts +38 -0
- package/lib/auth/components/ForgotPasswordPage.js +76 -0
- package/lib/auth/components/LoginPage.d.ts +73 -0
- package/lib/auth/components/LoginPage.js +115 -0
- package/lib/auth/components/LogoutButton.d.ts +30 -0
- package/lib/auth/components/LogoutButton.js +47 -0
- package/lib/auth/components/ResetPasswordPage.d.ts +42 -0
- package/lib/auth/components/ResetPasswordPage.js +88 -0
- package/lib/auth/components/hooks/useChangeUserPassword.d.ts +26 -0
- package/lib/auth/components/hooks/useChangeUserPassword.js +63 -0
- package/lib/auth/components/index.d.ts +8 -0
- package/lib/auth/components/index.js +7 -0
- package/lib/auth/context/AuthContext.d.ts +65 -0
- package/lib/auth/context/AuthContext.js +150 -0
- package/lib/auth/context/index.d.ts +1 -0
- package/lib/auth/context/index.js +1 -0
- package/lib/auth/index.d.ts +7 -0
- package/lib/auth/index.js +7 -0
- package/lib/auth/services/AuthService.d.ts +230 -0
- package/lib/auth/services/AuthService.js +475 -0
- package/lib/auth/services/LogoutService.d.ts +27 -0
- package/lib/auth/services/LogoutService.js +98 -0
- package/lib/auth/services/index.d.ts +2 -0
- package/lib/auth/services/index.js +2 -0
- package/lib/auth/shared/index.d.ts +1 -0
- package/lib/auth/shared/index.js +1 -0
- package/lib/auth/shared/layout/AuthPageLayout.d.ts +10 -0
- package/lib/auth/shared/layout/AuthPageLayout.js +16 -0
- package/lib/auth/shared/layout/index.d.ts +1 -0
- package/lib/auth/shared/layout/index.js +1 -0
- package/lib/auth/types/auth.types.d.ts +234 -0
- package/lib/auth/types/auth.types.js +14 -0
- package/lib/auth/types/index.d.ts +1 -0
- package/lib/auth/types/index.js +1 -0
- package/lib/auth/utils/TokenManager.d.ts +43 -0
- package/lib/auth/utils/TokenManager.js +171 -0
- package/lib/auth/utils/Transformers.d.ts +158 -0
- package/lib/auth/utils/Transformers.js +263 -0
- package/lib/auth/utils/errorDetection.d.ts +22 -0
- package/lib/auth/utils/errorDetection.js +190 -0
- package/lib/auth/utils/index.d.ts +3 -0
- package/lib/auth/utils/index.js +3 -0
- package/lib/components/charts/LineGraph.d.ts +15 -0
- package/lib/components/charts/LineGraph.js +131 -0
- package/lib/components/icons/Icon.d.ts +8 -0
- package/lib/components/icons/Icon.js +13 -0
- package/lib/components/icons/index.d.ts +2 -0
- package/lib/components/icons/index.js +2 -0
- package/lib/components/icons/types.d.ts +26 -0
- package/lib/components/icons/types.js +33 -0
- package/lib/components/index.d.ts +3 -0
- package/lib/components/index.js +3 -0
- package/lib/components/layout/AppLayout.d.ts +34 -0
- package/lib/components/layout/AppLayout.js +19 -0
- package/lib/components/layout/AuthPageLayout.d.ts +13 -0
- package/lib/components/layout/AuthPageLayout.js +15 -0
- package/lib/components/layout/BreadcrumbNav.d.ts +2 -0
- package/lib/components/layout/BreadcrumbNav.js +10 -0
- package/lib/components/layout/LayoutContent.d.ts +6 -0
- package/lib/components/layout/LayoutContent.js +10 -0
- package/lib/components/layout/Navbar.d.ts +106 -0
- package/lib/components/layout/Navbar.js +66 -0
- package/lib/components/layout/PageHeader.d.ts +8 -0
- package/lib/components/layout/PageHeader.js +7 -0
- package/lib/components/layout/SessionExpiryModal.d.ts +10 -0
- package/lib/components/layout/SessionExpiryModal.js +9 -0
- package/lib/components/layout/Sidebar.d.ts +6 -0
- package/lib/components/layout/Sidebar.js +87 -0
- package/lib/components/layout/VerticalTabsLayout.d.ts +12 -0
- package/lib/components/layout/VerticalTabsLayout.js +14 -0
- package/lib/components/layout/index.d.ts +9 -0
- package/lib/components/layout/index.js +9 -0
- package/lib/components/ui/Avatar.d.ts +6 -0
- package/lib/components/ui/Avatar.js +11 -0
- package/lib/components/ui/AvatarIcon.d.ts +4 -0
- package/lib/components/ui/AvatarIcon.js +6 -0
- package/lib/components/ui/Button.d.ts +14 -0
- package/lib/components/ui/Button.js +30 -0
- package/lib/components/ui/Calendar.d.ts +9 -0
- package/lib/components/ui/Calendar.js +35 -0
- package/lib/components/ui/Card.d.ts +16 -0
- package/lib/components/ui/Card.js +6 -0
- package/lib/components/ui/Chart.d.ts +2 -0
- package/lib/components/ui/Chart.js +16 -0
- package/lib/components/ui/Checkbox.d.ts +4 -0
- package/lib/components/ui/Checkbox.js +8 -0
- package/lib/components/ui/Command.d.ts +80 -0
- package/lib/components/ui/Command.js +28 -0
- package/lib/components/ui/ContainedTab.d.ts +21 -0
- package/lib/components/ui/ContainedTab.js +37 -0
- package/lib/components/ui/DateFormat.d.ts +6 -0
- package/lib/components/ui/DateFormat.js +8 -0
- package/lib/components/ui/DatePicker.d.ts +14 -0
- package/lib/components/ui/DatePicker.js +91 -0
- package/lib/components/ui/DateRangeModal.d.ts +38 -0
- package/lib/components/ui/DateRangeModal.js +89 -0
- package/lib/components/ui/DetailsCard.d.ts +16 -0
- package/lib/components/ui/DetailsCard.js +14 -0
- package/lib/components/ui/DetailsPage.d.ts +36 -0
- package/lib/components/ui/DetailsPage.js +50 -0
- package/lib/components/ui/Dialog.d.ts +19 -0
- package/lib/components/ui/Dialog.js +22 -0
- package/lib/components/ui/EmptyState.d.ts +6 -0
- package/lib/components/ui/EmptyState.js +6 -0
- package/lib/components/ui/FilterComponent.d.ts +30 -0
- package/lib/components/ui/FilterComponent.js +80 -0
- package/lib/components/ui/FilterList.d.ts +52 -0
- package/lib/components/ui/FilterList.js +62 -0
- package/lib/components/ui/FilterSection.d.ts +31 -0
- package/lib/components/ui/FilterSection.js +21 -0
- package/lib/components/ui/FilterWrapper.d.ts +6 -0
- package/lib/components/ui/FilterWrapper.js +7 -0
- package/lib/components/ui/Form.d.ts +23 -0
- package/lib/components/ui/Form.js +62 -0
- package/lib/components/ui/HoverableValue.d.ts +7 -0
- package/lib/components/ui/HoverableValue.js +8 -0
- package/lib/components/ui/IconButton.d.ts +10 -0
- package/lib/components/ui/IconButton.js +10 -0
- package/lib/components/ui/ImageComponent.d.ts +8 -0
- package/lib/components/ui/ImageComponent.js +5 -0
- package/lib/components/ui/ImageUploader.d.ts +17 -0
- package/lib/components/ui/ImageUploader.js +144 -0
- package/lib/components/ui/Input.d.ts +4 -0
- package/lib/components/ui/Input.js +8 -0
- package/lib/components/ui/Label.d.ts +5 -0
- package/lib/components/ui/Label.js +9 -0
- package/lib/components/ui/Loader.d.ts +10 -0
- package/lib/components/ui/Loader.js +7 -0
- package/lib/components/ui/Modal.d.ts +72 -0
- package/lib/components/ui/Modal.js +31 -0
- package/lib/components/ui/MultiSelect.d.ts +16 -0
- package/lib/components/ui/MultiSelect.js +59 -0
- package/lib/components/ui/NotificationModal.d.ts +18 -0
- package/lib/components/ui/NotificationModal.js +40 -0
- package/lib/components/ui/PhoneInput.d.ts +12 -0
- package/lib/components/ui/PhoneInput.js +58 -0
- package/lib/components/ui/Popover.d.ts +7 -0
- package/lib/components/ui/Popover.js +10 -0
- package/lib/components/ui/Progress.d.ts +7 -0
- package/lib/components/ui/Progress.js +7 -0
- package/lib/components/ui/Radio.d.ts +5 -0
- package/lib/components/ui/Radio.js +14 -0
- package/lib/components/ui/RangeDatePicker.d.ts +78 -0
- package/lib/components/ui/RangeDatePicker.js +68 -0
- package/lib/components/ui/Select.d.ts +13 -0
- package/lib/components/ui/Select.js +57 -0
- package/lib/components/ui/Separator.d.ts +4 -0
- package/lib/components/ui/Separator.js +7 -0
- package/lib/components/ui/Sheet.d.ts +26 -0
- package/lib/components/ui/Sheet.js +37 -0
- package/lib/components/ui/StatusCell.d.ts +9 -0
- package/lib/components/ui/StatusCell.js +6 -0
- package/lib/components/ui/Switch.d.ts +10 -0
- package/lib/components/ui/Switch.js +22 -0
- package/lib/components/ui/Tab.d.ts +15 -0
- package/lib/components/ui/Tab.js +13 -0
- package/lib/components/ui/TableDownload.d.ts +11 -0
- package/lib/components/ui/TableDownload.js +82 -0
- package/lib/components/ui/TailwindIndicator.d.ts +1 -0
- package/lib/components/ui/TailwindIndicator.js +6 -0
- package/lib/components/ui/TextField.d.ts +60 -0
- package/lib/components/ui/TextField.js +42 -0
- package/lib/components/ui/Textarea.d.ts +5 -0
- package/lib/components/ui/Textarea.js +8 -0
- package/lib/components/ui/Toast.d.ts +12 -0
- package/lib/components/ui/Toast.js +25 -0
- package/lib/components/ui/UploadField.d.ts +15 -0
- package/lib/components/ui/UploadField.js +45 -0
- package/lib/components/ui/VerticalTab.d.ts +16 -0
- package/lib/components/ui/VerticalTab.js +13 -0
- package/lib/components/ui/index.d.ts +49 -0
- package/lib/components/ui/index.js +47 -0
- package/lib/context/BreadcrumbContext.d.ts +28 -0
- package/lib/context/BreadcrumbContext.js +238 -0
- package/lib/context/FormEngineDrawerProvider.d.ts +21 -0
- package/lib/context/FormEngineDrawerProvider.js +38 -0
- package/lib/context/MultiFormEngineDrawerProvider.d.ts +25 -0
- package/lib/context/MultiFormEngineDrawerProvider.js +89 -0
- package/lib/context/SidebarContext.d.ts +65 -0
- package/lib/context/SidebarContext.js +47 -0
- package/lib/context/ToastContext.d.ts +17 -0
- package/lib/context/ToastContext.js +29 -0
- package/lib/context/index.d.ts +5 -0
- package/lib/context/index.js +5 -0
- package/lib/dashboard-visuals/components/BaseChart.d.ts +55 -0
- package/lib/dashboard-visuals/components/BaseChart.js +201 -0
- package/lib/dashboard-visuals/components/CardWrapper.d.ts +10 -0
- package/lib/dashboard-visuals/components/CardWrapper.js +13 -0
- package/lib/dashboard-visuals/components/ChartDetailsModal.d.ts +57 -0
- package/lib/dashboard-visuals/components/ChartDetailsModal.js +27 -0
- package/lib/dashboard-visuals/components/ChartDetailsModalWrapper.d.ts +29 -0
- package/lib/dashboard-visuals/components/ChartDetailsModalWrapper.js +4 -0
- package/lib/dashboard-visuals/components/ChartFormatter.d.ts +22 -0
- package/lib/dashboard-visuals/components/ChartFormatter.js +46 -0
- package/lib/dashboard-visuals/components/ChartWrapper.d.ts +11 -0
- package/lib/dashboard-visuals/components/ChartWrapper.js +14 -0
- package/lib/dashboard-visuals/components/DashboardFilter.d.ts +8 -0
- package/lib/dashboard-visuals/components/DashboardFilter.js +17 -0
- package/lib/dashboard-visuals/components/DataTable.d.ts +3 -0
- package/lib/dashboard-visuals/components/DataTable.js +57 -0
- package/lib/dashboard-visuals/components/EmptyState.d.ts +6 -0
- package/lib/dashboard-visuals/components/EmptyState.js +6 -0
- package/lib/dashboard-visuals/components/ErrorState.d.ts +7 -0
- package/lib/dashboard-visuals/components/ErrorState.js +5 -0
- package/lib/dashboard-visuals/components/FilterComponentSkeleton.d.ts +3 -0
- package/lib/dashboard-visuals/components/FilterComponentSkeleton.js +11 -0
- package/lib/dashboard-visuals/components/Pagination.d.ts +10 -0
- package/lib/dashboard-visuals/components/Pagination.js +7 -0
- package/lib/dashboard-visuals/components/Switch.d.ts +8 -0
- package/lib/dashboard-visuals/components/Switch.js +10 -0
- package/lib/dashboard-visuals/components/TileSkeleton.d.ts +2 -0
- package/lib/dashboard-visuals/components/TileSkeleton.js +5 -0
- package/lib/dashboard-visuals/components/molecules/Analytics.d.ts +11 -0
- package/lib/dashboard-visuals/components/molecules/Analytics.js +9 -0
- package/lib/dashboard-visuals/components/molecules/DataGrid.d.ts +15 -0
- package/lib/dashboard-visuals/components/molecules/DataGrid.js +124 -0
- package/lib/dashboard-visuals/components/molecules/NoChartData.d.ts +6 -0
- package/lib/dashboard-visuals/components/molecules/NoChartData.js +6 -0
- package/lib/dashboard-visuals/components/molecules/VisualChart.d.ts +16 -0
- package/lib/dashboard-visuals/components/molecules/VisualChart.js +8 -0
- package/lib/dashboard-visuals/components/types.d.ts +62 -0
- package/lib/dashboard-visuals/components/types.js +1 -0
- package/lib/dashboard-visuals/hooks/useChartData.d.ts +15 -0
- package/lib/dashboard-visuals/hooks/useChartData.js +82 -0
- package/lib/dashboard-visuals/hooks/useTooltipFormatter.d.ts +13 -0
- package/lib/dashboard-visuals/hooks/useTooltipFormatter.js +10 -0
- package/lib/dashboard-visuals/index.d.ts +39 -0
- package/lib/dashboard-visuals/index.js +168 -0
- package/lib/dashboard-visuals/types/index.d.ts +83 -0
- package/lib/dashboard-visuals/types/index.js +1 -0
- package/lib/dashboard-visuals/types/metricDetailData.d.ts +25 -0
- package/lib/dashboard-visuals/types/metricDetailData.js +1 -0
- package/lib/dashboard-visuals/utils/api.d.ts +5 -0
- package/lib/dashboard-visuals/utils/api.js +6 -0
- package/lib/dashboard-visuals/utils/chartOptions.d.ts +481 -0
- package/lib/dashboard-visuals/utils/chartOptions.js +393 -0
- package/lib/dashboard-visuals/utils/chunkArray.d.ts +1 -0
- package/lib/dashboard-visuals/utils/chunkArray.js +7 -0
- package/lib/dashboard-visuals/utils/defaultColors.d.ts +1 -0
- package/lib/dashboard-visuals/utils/defaultColors.js +1 -0
- package/lib/dashboard-visuals/utils/formatUtil.d.ts +203 -0
- package/lib/dashboard-visuals/utils/formatUtil.js +472 -0
- package/lib/dashboard-visuals/utils/gridUtil.d.ts +11 -0
- package/lib/dashboard-visuals/utils/gridUtil.js +32 -0
- package/lib/dashboard-visuals/utils/index.d.ts +6 -0
- package/lib/dashboard-visuals/utils/index.js +6 -0
- package/lib/dashboard-visuals/utils/tooltipUtils.d.ts +11 -0
- package/lib/dashboard-visuals/utils/tooltipUtils.js +180 -0
- package/lib/dashboard-visuals/visualRegistry.d.ts +4 -0
- package/lib/dashboard-visuals/visualRegistry.js +41 -0
- package/lib/dashboard-visuals/visuals/BarChart.d.ts +58 -0
- package/lib/dashboard-visuals/visuals/BarChart.js +95 -0
- package/lib/dashboard-visuals/visuals/BarLineHybridChart.d.ts +33 -0
- package/lib/dashboard-visuals/visuals/BarLineHybridChart.js +60 -0
- package/lib/dashboard-visuals/visuals/BubbleChart.d.ts +25 -0
- package/lib/dashboard-visuals/visuals/BubbleChart.js +101 -0
- package/lib/dashboard-visuals/visuals/DistributionChart.d.ts +11 -0
- package/lib/dashboard-visuals/visuals/DistributionChart.js +48 -0
- package/lib/dashboard-visuals/visuals/DonutChart.d.ts +50 -0
- package/lib/dashboard-visuals/visuals/DonutChart.js +105 -0
- package/lib/dashboard-visuals/visuals/GaugeChart.d.ts +32 -0
- package/lib/dashboard-visuals/visuals/GaugeChart.js +53 -0
- package/lib/dashboard-visuals/visuals/GroupedBarChart.d.ts +47 -0
- package/lib/dashboard-visuals/visuals/GroupedBarChart.js +131 -0
- package/lib/dashboard-visuals/visuals/HeatmapChart.d.ts +79 -0
- package/lib/dashboard-visuals/visuals/HeatmapChart.js +146 -0
- package/lib/dashboard-visuals/visuals/HorizontalBarChart.d.ts +50 -0
- package/lib/dashboard-visuals/visuals/HorizontalBarChart.js +131 -0
- package/lib/dashboard-visuals/visuals/ItemPerformanceCard.d.ts +30 -0
- package/lib/dashboard-visuals/visuals/ItemPerformanceCard.js +31 -0
- package/lib/dashboard-visuals/visuals/LineChart.d.ts +56 -0
- package/lib/dashboard-visuals/visuals/LineChart.js +80 -0
- package/lib/dashboard-visuals/visuals/LineGraph.d.ts +50 -0
- package/lib/dashboard-visuals/visuals/LineGraph.js +189 -0
- package/lib/dashboard-visuals/visuals/MetricSummaryCard.d.ts +14 -0
- package/lib/dashboard-visuals/visuals/MetricSummaryCard.js +8 -0
- package/lib/dashboard-visuals/visuals/MultiGaugeChart.d.ts +39 -0
- package/lib/dashboard-visuals/visuals/MultiGaugeChart.js +119 -0
- package/lib/dashboard-visuals/visuals/PieChart.d.ts +59 -0
- package/lib/dashboard-visuals/visuals/PieChart.js +194 -0
- package/lib/dashboard-visuals/visuals/SelectedEventTile.d.ts +14 -0
- package/lib/dashboard-visuals/visuals/SelectedEventTile.js +35 -0
- package/lib/dashboard-visuals/visuals/SpeedometerChart.d.ts +53 -0
- package/lib/dashboard-visuals/visuals/SpeedometerChart.js +94 -0
- package/lib/dashboard-visuals/visuals/Table.d.ts +26 -0
- package/lib/dashboard-visuals/visuals/Table.js +113 -0
- package/lib/dashboard-visuals/visuals/Tile.d.ts +16 -0
- package/lib/dashboard-visuals/visuals/Tile.js +16 -0
- package/lib/dashboard-visuals/visuals/TreeMap.d.ts +25 -0
- package/lib/dashboard-visuals/visuals/TreeMap.js +45 -0
- package/lib/dashboard-visuals/visuals/WaterfallChart.d.ts +52 -0
- package/lib/dashboard-visuals/visuals/WaterfallChart.js +266 -0
- package/lib/form-engine/Form.d.ts +4 -0
- package/lib/form-engine/Form.js +14 -0
- package/lib/form-engine/FormEngine.d.ts +3 -0
- package/lib/form-engine/FormEngine.js +121 -0
- package/lib/form-engine/components/FieldWrapper.d.ts +18 -0
- package/lib/form-engine/components/FieldWrapper.js +63 -0
- package/lib/form-engine/components/index.d.ts +2 -0
- package/lib/form-engine/components/index.js +2 -0
- package/lib/form-engine/components/inputs/card-expiry-input/CardExpiryInput.d.ts +16 -0
- package/lib/form-engine/components/inputs/card-expiry-input/CardExpiryInput.js +48 -0
- package/lib/form-engine/components/inputs/checkbox-input/CheckboxInput.d.ts +4 -0
- package/lib/form-engine/components/inputs/checkbox-input/CheckboxInput.js +5 -0
- package/lib/form-engine/components/inputs/credit-card-input/CreditCardInput.d.ts +4 -0
- package/lib/form-engine/components/inputs/credit-card-input/CreditCardInput.js +82 -0
- package/lib/form-engine/components/inputs/date-input/DateInput.d.ts +4 -0
- package/lib/form-engine/components/inputs/date-input/DateInput.js +7 -0
- package/lib/form-engine/components/inputs/date-input/index.d.ts +1 -0
- package/lib/form-engine/components/inputs/date-input/index.js +1 -0
- package/lib/form-engine/components/inputs/email-input/EmailInput.d.ts +4 -0
- package/lib/form-engine/components/inputs/email-input/EmailInput.js +5 -0
- package/lib/form-engine/components/inputs/email-input/index.d.ts +1 -0
- package/lib/form-engine/components/inputs/email-input/index.js +1 -0
- package/lib/form-engine/components/inputs/index.d.ts +13 -0
- package/lib/form-engine/components/inputs/index.js +13 -0
- package/lib/form-engine/components/inputs/label-input/LabelInput.d.ts +4 -0
- package/lib/form-engine/components/inputs/label-input/LabelInput.js +7 -0
- package/lib/form-engine/components/inputs/label-input/index.d.ts +1 -0
- package/lib/form-engine/components/inputs/label-input/index.js +1 -0
- package/lib/form-engine/components/inputs/multi-select-input/MultiSelectInput.d.ts +4 -0
- package/lib/form-engine/components/inputs/multi-select-input/MultiSelectInput.js +5 -0
- package/lib/form-engine/components/inputs/number-input/NumberInput.d.ts +4 -0
- package/lib/form-engine/components/inputs/number-input/NumberInput.js +5 -0
- package/lib/form-engine/components/inputs/number-input/index.d.ts +1 -0
- package/lib/form-engine/components/inputs/number-input/index.js +1 -0
- package/lib/form-engine/components/inputs/password-input/PasswordInput.d.ts +4 -0
- package/lib/form-engine/components/inputs/password-input/PasswordInput.js +9 -0
- package/lib/form-engine/components/inputs/password-input/index.d.ts +1 -0
- package/lib/form-engine/components/inputs/password-input/index.js +1 -0
- package/lib/form-engine/components/inputs/radio-button/RadioInput.d.ts +4 -0
- package/lib/form-engine/components/inputs/radio-button/RadioInput.js +6 -0
- package/lib/form-engine/components/inputs/radio-button/index.d.ts +1 -0
- package/lib/form-engine/components/inputs/radio-button/index.js +1 -0
- package/lib/form-engine/components/inputs/select/SelectInput.d.ts +4 -0
- package/lib/form-engine/components/inputs/select/SelectInput.js +6 -0
- package/lib/form-engine/components/inputs/select/index.d.ts +1 -0
- package/lib/form-engine/components/inputs/select/index.js +1 -0
- package/lib/form-engine/components/inputs/textarea-input/TextareaInput.d.ts +4 -0
- package/lib/form-engine/components/inputs/textarea-input/TextareaInput.js +5 -0
- package/lib/form-engine/components/inputs/textarea-input/index.d.ts +1 -0
- package/lib/form-engine/components/inputs/textarea-input/index.js +1 -0
- package/lib/form-engine/components/inputs/time-input/TimeInput.d.ts +4 -0
- package/lib/form-engine/components/inputs/time-input/TimeInput.js +5 -0
- package/lib/form-engine/components/inputs/time-input/index.d.ts +1 -0
- package/lib/form-engine/components/inputs/time-input/index.js +1 -0
- package/lib/form-engine/components/inputs/toggle-switch-input/ToggleSwitchInput.d.ts +4 -0
- package/lib/form-engine/components/inputs/toggle-switch-input/ToggleSwitchInput.js +7 -0
- package/lib/form-engine/components/inputs/toggle-switch-input/index.d.ts +1 -0
- package/lib/form-engine/components/inputs/toggle-switch-input/index.js +1 -0
- package/lib/form-engine/components/inputs/upload-field/UploadFieldForm.d.ts +4 -0
- package/lib/form-engine/components/inputs/upload-field/UploadFieldForm.js +59 -0
- package/lib/form-engine/components/inputs/upload-field/index.d.ts +1 -0
- package/lib/form-engine/components/inputs/upload-field/index.js +1 -0
- package/lib/form-engine/hooks/useFormPersistence.d.ts +11 -0
- package/lib/form-engine/hooks/useFormPersistence.js +46 -0
- package/lib/form-engine/index.d.ts +5 -0
- package/lib/form-engine/index.js +5 -0
- package/lib/form-engine/registry/RegisterComponents.d.ts +1 -0
- package/lib/form-engine/registry/RegisterComponents.js +35 -0
- package/lib/form-engine/registry/Registry.d.ts +5 -0
- package/lib/form-engine/registry/Registry.js +13 -0
- package/lib/form-engine/registry/index.d.ts +2 -0
- package/lib/form-engine/registry/index.js +2 -0
- package/lib/form-engine/types/index.d.ts +311 -0
- package/lib/form-engine/types/index.js +1 -0
- package/lib/helpers/index.d.ts +2 -0
- package/lib/helpers/index.js +2 -0
- package/lib/helpers/utils.d.ts +37 -0
- package/lib/helpers/utils.js +77 -0
- package/lib/helpers/validations.d.ts +80 -0
- package/lib/helpers/validations.js +39 -0
- package/lib/index.d.ts +21 -0
- package/lib/index.js +30 -0
- package/lib/mocks/mockApiRequestsConfig.d.ts +2 -0
- package/lib/mocks/mockApiRequestsConfig.js +343 -0
- package/lib/pagamio-drawer/TopUpWalletDrawer/TopUpWalletContent.d.ts +14 -0
- package/lib/pagamio-drawer/TopUpWalletDrawer/TopUpWalletContent.js +40 -0
- package/lib/pagamio-drawer/TopUpWalletDrawer/index.d.ts +11 -0
- package/lib/pagamio-drawer/TopUpWalletDrawer/index.js +7 -0
- package/lib/pagamio-drawer/components/BaseDrawer.d.ts +11 -0
- package/lib/pagamio-drawer/components/BaseDrawer.js +10 -0
- package/lib/pagamio-drawer/components/DrawerContent.d.ts +27 -0
- package/lib/pagamio-drawer/components/DrawerContent.js +237 -0
- package/lib/pagamio-drawer/index.d.ts +22 -0
- package/lib/pagamio-drawer/index.js +133 -0
- package/lib/pagamio-table/data-table/ExportButton.d.ts +57 -0
- package/lib/pagamio-table/data-table/ExportButton.js +96 -0
- package/lib/pagamio-table/data-table/MantineCoreTable.d.ts +44 -0
- package/lib/pagamio-table/data-table/MantineCoreTable.js +129 -0
- package/lib/pagamio-table/data-table/Pagination.d.ts +10 -0
- package/lib/pagamio-table/data-table/Pagination.js +5 -0
- package/lib/pagamio-table/data-table/TableDownload.d.ts +8 -0
- package/lib/pagamio-table/data-table/TableDownload.js +81 -0
- package/lib/pagamio-table/data-table/TableToolbar.d.ts +3 -0
- package/lib/pagamio-table/data-table/TableToolbar.js +16 -0
- package/lib/pagamio-table/data-table/exportUtils.d.ts +42 -0
- package/lib/pagamio-table/data-table/exportUtils.js +782 -0
- package/lib/pagamio-table/data-table/index.d.ts +5 -0
- package/lib/pagamio-table/data-table/index.js +11 -0
- package/lib/pagamio-table/data-table/pdfExportUtils.d.ts +111 -0
- package/lib/pagamio-table/data-table/pdfExportUtils.js +113 -0
- package/lib/pagamio-table/data-table/types.d.ts +169 -0
- package/lib/pagamio-table/data-table/types.js +1 -0
- package/lib/pagamio-table/index.d.ts +4 -0
- package/lib/pagamio-table/index.js +4 -0
- package/lib/pagamio-table/utils/functionHelper.d.ts +12 -0
- package/lib/pagamio-table/utils/functionHelper.js +24 -0
- package/lib/pagamio-table/utils/index.d.ts +1 -0
- package/lib/pagamio-table/utils/index.js +1 -0
- package/lib/rbac/hooks.d.ts +39 -0
- package/lib/rbac/hooks.js +51 -0
- package/lib/rbac/index.d.ts +8 -0
- package/lib/rbac/index.js +11 -0
- package/lib/rbac/store.d.ts +24 -0
- package/lib/rbac/store.js +37 -0
- package/lib/rbac/types.d.ts +39 -0
- package/lib/rbac/types.js +4 -0
- package/lib/rbac/utils.d.ts +44 -0
- package/lib/rbac/utils.js +117 -0
- package/lib/shared/constants/index.d.ts +2 -0
- package/lib/shared/constants/index.js +2 -0
- package/lib/shared/hooks/index.d.ts +4 -0
- package/lib/shared/hooks/index.js +4 -0
- package/lib/shared/hooks/useAnyDrawerOpen.d.ts +4 -0
- package/lib/shared/hooks/useAnyDrawerOpen.js +18 -0
- package/lib/shared/hooks/useContainerWidth.d.ts +2 -0
- package/lib/shared/hooks/useContainerWidth.js +18 -0
- package/lib/shared/hooks/useImageUpload.d.ts +15 -0
- package/lib/shared/hooks/useImageUpload.js +66 -0
- package/lib/shared/hooks/useMediaQueries.d.ts +5 -0
- package/lib/shared/hooks/useMediaQueries.js +35 -0
- package/lib/shared/hooks/usePagamioTable.d.ts +158 -0
- package/lib/shared/hooks/usePagamioTable.js +475 -0
- package/lib/shared/hooks/useSessionTimer.d.ts +33 -0
- package/lib/shared/hooks/useSessionTimer.js +96 -0
- package/lib/shared/index.d.ts +4 -0
- package/lib/shared/index.js +4 -0
- package/lib/shared/types/index.d.ts +1 -0
- package/lib/shared/types/index.js +1 -0
- package/lib/shared/url/index.d.ts +9 -0
- package/lib/shared/url/index.js +20 -0
- package/lib/shared/utils/filterUtils.d.ts +5 -0
- package/lib/shared/utils/filterUtils.js +31 -0
- package/lib/shared/utils/functionHelper.d.ts +27 -0
- package/lib/shared/utils/functionHelper.js +124 -0
- package/lib/shared/utils/index.d.ts +2 -0
- package/lib/shared/utils/index.js +2 -0
- package/lib/shared/utils/localStorage.d.ts +53 -0
- package/lib/shared/utils/localStorage.js +139 -0
- package/lib/styles.css +6247 -0
- package/lib/translations/components/LocaleSwitcher.d.ts +7 -0
- package/lib/translations/components/LocaleSwitcher.js +18 -0
- package/lib/translations/components/index.d.ts +1 -0
- package/lib/translations/components/index.js +1 -0
- package/lib/translations/context/TranslationContext.d.ts +5 -0
- package/lib/translations/context/TranslationContext.js +151 -0
- package/lib/translations/context/index.d.ts +1 -0
- package/lib/translations/context/index.js +1 -0
- package/lib/translations/hooks/index.d.ts +2 -0
- package/lib/translations/hooks/index.js +2 -0
- package/lib/translations/hooks/useLibTranslations.d.ts +7 -0
- package/lib/translations/hooks/useLibTranslations.js +46 -0
- package/lib/translations/hooks/useTranslation.d.ts +7 -0
- package/lib/translations/hooks/useTranslation.js +11 -0
- package/lib/translations/index.d.ts +91 -0
- package/lib/translations/index.js +11 -0
- package/lib/translations/locales/en.json +21 -0
- package/lib/translations/locales/es.json +21 -0
- package/lib/translations/locales/fr.json +21 -0
- package/lib/translations/locales/pt.json +21 -0
- package/lib/translations/types/index.d.ts +24 -0
- package/lib/translations/types/index.js +1 -0
- package/lib/translations/utils/index.d.ts +6 -0
- package/lib/translations/utils/index.js +25 -0
- package/package.json +9 -1
|
@@ -0,0 +1,782 @@
|
|
|
1
|
+
import jsPDF from 'jspdf';
|
|
2
|
+
import 'jspdf-autotable';
|
|
3
|
+
import Papa from 'papaparse';
|
|
4
|
+
import * as XLSX from 'xlsx';
|
|
5
|
+
// Helper function to convert RGB string to RGB values
|
|
6
|
+
const parseRgbString = (rgbString) => {
|
|
7
|
+
// Handle rgb(r, g, b) format
|
|
8
|
+
const rgbRegex = /rgb\((\d+),\s*(\d+),\s*(\d+)\)/;
|
|
9
|
+
const rgbMatch = rgbRegex.exec(rgbString);
|
|
10
|
+
if (rgbMatch) {
|
|
11
|
+
return [parseInt(rgbMatch[1]), parseInt(rgbMatch[2]), parseInt(rgbMatch[3])];
|
|
12
|
+
}
|
|
13
|
+
// Handle hex format
|
|
14
|
+
if (rgbString.startsWith('#')) {
|
|
15
|
+
const hex = rgbString.slice(1);
|
|
16
|
+
const r = parseInt(hex.slice(0, 2), 16);
|
|
17
|
+
const g = parseInt(hex.slice(2, 4), 16);
|
|
18
|
+
const b = parseInt(hex.slice(4, 6), 16);
|
|
19
|
+
return [r, g, b];
|
|
20
|
+
}
|
|
21
|
+
// Default fallback
|
|
22
|
+
return [33, 37, 41]; // Dark gray
|
|
23
|
+
};
|
|
24
|
+
// Helper function to load image and convert to base64
|
|
25
|
+
const loadImageAsBase64 = async (url) => {
|
|
26
|
+
try {
|
|
27
|
+
if (url.startsWith('data:')) {
|
|
28
|
+
return url;
|
|
29
|
+
}
|
|
30
|
+
const response = await fetch(url);
|
|
31
|
+
if (!response.ok)
|
|
32
|
+
return null;
|
|
33
|
+
const blob = await response.blob();
|
|
34
|
+
return new Promise((resolve) => {
|
|
35
|
+
const reader = new FileReader();
|
|
36
|
+
reader.onload = () => resolve(reader.result);
|
|
37
|
+
reader.onerror = () => resolve(null);
|
|
38
|
+
reader.readAsDataURL(blob);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
// Helper functions for formatting different data types
|
|
46
|
+
const formatStatusObject = (value) => {
|
|
47
|
+
if ('label' in value && typeof value.label === 'string') {
|
|
48
|
+
return value.label;
|
|
49
|
+
}
|
|
50
|
+
return String(value);
|
|
51
|
+
};
|
|
52
|
+
const formatDateValue = (value) => {
|
|
53
|
+
if (value instanceof Date) {
|
|
54
|
+
return value.toLocaleDateString('en-US', {
|
|
55
|
+
year: 'numeric',
|
|
56
|
+
month: 'short',
|
|
57
|
+
day: 'numeric',
|
|
58
|
+
hour: '2-digit',
|
|
59
|
+
minute: '2-digit',
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
// Handle ISO date strings - more comprehensive regex
|
|
63
|
+
if (typeof value === 'string') {
|
|
64
|
+
// Match various ISO date formats: YYYY-MM-DDTHH:mm:ss.sssZ, YYYY-MM-DDTHH:mm:ss.sss, etc.
|
|
65
|
+
const isoDateRegex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,6})?(?:Z|[+-]\d{2}:\d{2})?$/;
|
|
66
|
+
if (isoDateRegex.test(value)) {
|
|
67
|
+
const date = new Date(value);
|
|
68
|
+
if (!isNaN(date.getTime())) {
|
|
69
|
+
return date.toLocaleDateString('en-US', {
|
|
70
|
+
year: 'numeric',
|
|
71
|
+
month: 'short',
|
|
72
|
+
day: 'numeric',
|
|
73
|
+
hour: '2-digit',
|
|
74
|
+
minute: '2-digit',
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// Also handle simple date formats like YYYY-MM-DD
|
|
79
|
+
const simpleDateRegex = /^\d{4}-\d{2}-\d{2}$/;
|
|
80
|
+
if (simpleDateRegex.test(value)) {
|
|
81
|
+
const date = new Date(value);
|
|
82
|
+
if (!isNaN(date.getTime())) {
|
|
83
|
+
return date.toLocaleDateString('en-US', {
|
|
84
|
+
year: 'numeric',
|
|
85
|
+
month: 'short',
|
|
86
|
+
day: 'numeric',
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return String(value);
|
|
92
|
+
};
|
|
93
|
+
const formatImageString = (value) => {
|
|
94
|
+
const imageExtensions = ['.jpg', '.png', '.gif', '.jpeg', '.webp'];
|
|
95
|
+
const hasImageExtension = imageExtensions.some((ext) => value.toLowerCase().includes(ext));
|
|
96
|
+
if (hasImageExtension) {
|
|
97
|
+
try {
|
|
98
|
+
const parts = value.split('/');
|
|
99
|
+
const filename = parts[parts.length - 1];
|
|
100
|
+
if (filename?.includes('.')) {
|
|
101
|
+
return `[Image: ${filename}]`;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
// Fallback to generic image label
|
|
106
|
+
}
|
|
107
|
+
return '[Image]';
|
|
108
|
+
}
|
|
109
|
+
return value;
|
|
110
|
+
};
|
|
111
|
+
const formatUrlString = (value) => {
|
|
112
|
+
if (value.startsWith('http')) {
|
|
113
|
+
try {
|
|
114
|
+
const url = new URL(value);
|
|
115
|
+
return url.pathname.split('/').pop() || url.hostname;
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
return value;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return value;
|
|
122
|
+
};
|
|
123
|
+
const formatNumberValue = (value, columnKey) => {
|
|
124
|
+
if (columnKey && (columnKey.toLowerCase().includes('amount') || columnKey.toLowerCase().includes('price'))) {
|
|
125
|
+
// Format as currency with proper symbol
|
|
126
|
+
return new Intl.NumberFormat('en-ZA', {
|
|
127
|
+
style: 'currency',
|
|
128
|
+
currency: 'ZAR',
|
|
129
|
+
minimumFractionDigits: 2,
|
|
130
|
+
maximumFractionDigits: 2,
|
|
131
|
+
}).format(value);
|
|
132
|
+
}
|
|
133
|
+
return value.toString();
|
|
134
|
+
};
|
|
135
|
+
const formatObjectValue = (value) => {
|
|
136
|
+
// Handle arrays
|
|
137
|
+
if (Array.isArray(value)) {
|
|
138
|
+
return value.map((item) => formatCellContent(item)).join(', ');
|
|
139
|
+
}
|
|
140
|
+
// Handle Date objects and date strings
|
|
141
|
+
const dateResult = formatDateValue(value);
|
|
142
|
+
if (dateResult !== String(value)) {
|
|
143
|
+
return dateResult;
|
|
144
|
+
}
|
|
145
|
+
// Handle status objects
|
|
146
|
+
const statusResult = formatStatusObject(value);
|
|
147
|
+
if (statusResult !== String(value)) {
|
|
148
|
+
return statusResult;
|
|
149
|
+
}
|
|
150
|
+
// Handle other objects
|
|
151
|
+
if (value.toString && value.toString() !== '[object Object]') {
|
|
152
|
+
return value.toString();
|
|
153
|
+
}
|
|
154
|
+
return JSON.stringify(value);
|
|
155
|
+
};
|
|
156
|
+
const formatStringValue = (value, columnKey) => {
|
|
157
|
+
const cleanText = value.replace(/<[^<>]*>/g, '');
|
|
158
|
+
// Check if this looks like a date and the column suggests it's a date
|
|
159
|
+
if (columnKey && (columnKey.toLowerCase().includes('date') || columnKey.toLowerCase().includes('time'))) {
|
|
160
|
+
const formattedDate = formatDateValue(cleanText);
|
|
161
|
+
if (formattedDate !== cleanText) {
|
|
162
|
+
return formattedDate;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
// Handle images
|
|
166
|
+
const imageResult = formatImageString(cleanText);
|
|
167
|
+
if (imageResult !== cleanText) {
|
|
168
|
+
return imageResult;
|
|
169
|
+
}
|
|
170
|
+
// Handle URLs
|
|
171
|
+
return formatUrlString(cleanText);
|
|
172
|
+
};
|
|
173
|
+
// Helper function to detect and handle different cell content types
|
|
174
|
+
const formatCellContent = (value, columnKey) => {
|
|
175
|
+
if (value === null || value === undefined)
|
|
176
|
+
return '';
|
|
177
|
+
if (typeof value === 'object' && value !== null) {
|
|
178
|
+
return formatObjectValue(value);
|
|
179
|
+
}
|
|
180
|
+
if (typeof value === 'boolean') {
|
|
181
|
+
return value ? 'Yes' : 'No';
|
|
182
|
+
}
|
|
183
|
+
if (typeof value === 'number') {
|
|
184
|
+
return formatNumberValue(value, columnKey);
|
|
185
|
+
}
|
|
186
|
+
if (typeof value === 'string') {
|
|
187
|
+
return formatStringValue(value, columnKey);
|
|
188
|
+
}
|
|
189
|
+
return String(value);
|
|
190
|
+
};
|
|
191
|
+
// Helper function to format cell content for Excel
|
|
192
|
+
const formatCellContentForExcel = (value, columnKey) => {
|
|
193
|
+
if (value === null || value === undefined)
|
|
194
|
+
return '';
|
|
195
|
+
if (typeof value === 'object' && value !== null) {
|
|
196
|
+
return formatObjectValue(value);
|
|
197
|
+
}
|
|
198
|
+
if (typeof value === 'boolean') {
|
|
199
|
+
return value ? 'Yes' : 'No';
|
|
200
|
+
}
|
|
201
|
+
if (typeof value === 'number') {
|
|
202
|
+
// Return raw number for Excel to preserve numeric type
|
|
203
|
+
return value;
|
|
204
|
+
}
|
|
205
|
+
if (typeof value === 'string') {
|
|
206
|
+
// Check if string represents a number
|
|
207
|
+
if (columnKey &&
|
|
208
|
+
(columnKey.toLowerCase().includes('amount') ||
|
|
209
|
+
columnKey.toLowerCase().includes('price') ||
|
|
210
|
+
columnKey.toLowerCase().includes('quantity') ||
|
|
211
|
+
columnKey.toLowerCase().includes('qty') ||
|
|
212
|
+
columnKey.toLowerCase().includes('count') ||
|
|
213
|
+
columnKey.toLowerCase().includes('total') ||
|
|
214
|
+
columnKey.toLowerCase().includes('sum'))) {
|
|
215
|
+
const numValue = parseFloat(value.replace(/[^\d.-]/g, ''));
|
|
216
|
+
if (!isNaN(numValue)) {
|
|
217
|
+
return numValue;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return formatStringValue(value, columnKey);
|
|
221
|
+
}
|
|
222
|
+
return String(value);
|
|
223
|
+
};
|
|
224
|
+
// CSV Export
|
|
225
|
+
export const exportToCsv = (data, columns, options = {}) => {
|
|
226
|
+
const { title = 'Data Export', includeTimestamp = true, includeHeaders = true, delimiter = ',', filename } = options;
|
|
227
|
+
const columnKeys = columns.map((col) => col.accessorKey);
|
|
228
|
+
const headers = columns.map((col) => formatHeaderText(col.header || ''));
|
|
229
|
+
// Prepare data with proper formatting
|
|
230
|
+
const formattedData = data.map((row) => columnKeys.reduce((acc, key) => {
|
|
231
|
+
const header = columns.find((col) => col.accessorKey === key)?.header || '';
|
|
232
|
+
acc[header] = formatCellContent(row[key], key);
|
|
233
|
+
return acc;
|
|
234
|
+
}, {}));
|
|
235
|
+
// Build CSV content
|
|
236
|
+
const csvRows = [];
|
|
237
|
+
// Add title as comment if provided
|
|
238
|
+
if (title) {
|
|
239
|
+
csvRows.push(`# ${title}`);
|
|
240
|
+
}
|
|
241
|
+
// Add timestamp as comment if enabled
|
|
242
|
+
if (includeTimestamp) {
|
|
243
|
+
const timestamp = `Generated on ${new Date().toLocaleDateString('en-US', {
|
|
244
|
+
year: 'numeric',
|
|
245
|
+
month: 'long',
|
|
246
|
+
day: 'numeric',
|
|
247
|
+
hour: '2-digit',
|
|
248
|
+
minute: '2-digit',
|
|
249
|
+
})}`;
|
|
250
|
+
csvRows.push(`# ${timestamp}`);
|
|
251
|
+
}
|
|
252
|
+
// Add empty comment line if we have title/timestamp
|
|
253
|
+
if (title || includeTimestamp) {
|
|
254
|
+
csvRows.push('#');
|
|
255
|
+
}
|
|
256
|
+
// Configure Papa Parse options for high-quality output
|
|
257
|
+
const papaConfig = {
|
|
258
|
+
delimiter,
|
|
259
|
+
header: includeHeaders,
|
|
260
|
+
skipEmptyLines: 'greedy',
|
|
261
|
+
quotes: true, // Always quote fields to handle special characters
|
|
262
|
+
quoteChar: '"',
|
|
263
|
+
escapeChar: '"',
|
|
264
|
+
newline: '\n',
|
|
265
|
+
};
|
|
266
|
+
// Generate CSV content using Papa Parse
|
|
267
|
+
let csvContent;
|
|
268
|
+
if (includeHeaders) {
|
|
269
|
+
// Use Papa Parse to handle proper CSV formatting
|
|
270
|
+
csvContent = Papa.unparse(formattedData, papaConfig);
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
// Generate data-only CSV
|
|
274
|
+
const dataRows = formattedData.map((row) => headers.map((header) => row[header] || ''));
|
|
275
|
+
csvContent = Papa.unparse(dataRows, papaConfig);
|
|
276
|
+
}
|
|
277
|
+
// Combine metadata comments with CSV content
|
|
278
|
+
const finalContent = csvRows.length > 0 ? csvRows.join('\n') + '\n' + csvContent : csvContent;
|
|
279
|
+
// Create and download file
|
|
280
|
+
const blob = new Blob([finalContent], { type: 'text/csv;charset=utf-8;' });
|
|
281
|
+
const link = document.createElement('a');
|
|
282
|
+
link.href = URL.createObjectURL(blob);
|
|
283
|
+
// Generate filename with timestamp if not provided
|
|
284
|
+
if (filename) {
|
|
285
|
+
link.download = filename.endsWith('.csv') ? filename : `${filename}.csv`;
|
|
286
|
+
}
|
|
287
|
+
else {
|
|
288
|
+
const timestamp = new Date()
|
|
289
|
+
.toISOString()
|
|
290
|
+
.slice(0, 19)
|
|
291
|
+
.replace(/[:\-T]/g, '');
|
|
292
|
+
link.download = `${title.replace(/\s+/g, '_').toLowerCase()}_${timestamp}.csv`;
|
|
293
|
+
}
|
|
294
|
+
link.click();
|
|
295
|
+
// Clean up
|
|
296
|
+
URL.revokeObjectURL(link.href);
|
|
297
|
+
};
|
|
298
|
+
// Helper function to calculate optimal column widths
|
|
299
|
+
const calculateColumnWidths = (headers, formattedData) => {
|
|
300
|
+
return headers.map((header) => {
|
|
301
|
+
let maxWidth = header.length;
|
|
302
|
+
// Check data rows for maximum width
|
|
303
|
+
for (const row of formattedData) {
|
|
304
|
+
const cellValue = String(row[header] || '');
|
|
305
|
+
maxWidth = Math.max(maxWidth, cellValue.length);
|
|
306
|
+
}
|
|
307
|
+
// Cap the width at reasonable limits
|
|
308
|
+
const width = Math.min(Math.max(maxWidth, 10), 50);
|
|
309
|
+
return { wch: width };
|
|
310
|
+
});
|
|
311
|
+
};
|
|
312
|
+
// Helper function to create worksheet data structure
|
|
313
|
+
const createWorksheetData = (title, subtitle, includeTimestamp, headers, formattedData) => {
|
|
314
|
+
const worksheetData = [];
|
|
315
|
+
let currentRow = 0;
|
|
316
|
+
// Add title if provided
|
|
317
|
+
if (title) {
|
|
318
|
+
worksheetData.push([title]);
|
|
319
|
+
currentRow++;
|
|
320
|
+
}
|
|
321
|
+
// Add subtitle or timestamp
|
|
322
|
+
if (subtitle) {
|
|
323
|
+
worksheetData.push([subtitle]);
|
|
324
|
+
currentRow++;
|
|
325
|
+
}
|
|
326
|
+
else if (includeTimestamp) {
|
|
327
|
+
const timestamp = `Generated on ${new Date().toLocaleDateString('en-US', {
|
|
328
|
+
year: 'numeric',
|
|
329
|
+
month: 'long',
|
|
330
|
+
day: 'numeric',
|
|
331
|
+
hour: '2-digit',
|
|
332
|
+
minute: '2-digit',
|
|
333
|
+
})}`;
|
|
334
|
+
worksheetData.push([timestamp]);
|
|
335
|
+
currentRow++;
|
|
336
|
+
}
|
|
337
|
+
// Add empty row if we have title/subtitle
|
|
338
|
+
if (currentRow > 0) {
|
|
339
|
+
worksheetData.push([]);
|
|
340
|
+
currentRow++;
|
|
341
|
+
}
|
|
342
|
+
// Add headers
|
|
343
|
+
worksheetData.push(headers);
|
|
344
|
+
const headerRowIndex = currentRow;
|
|
345
|
+
currentRow++;
|
|
346
|
+
// Add data rows
|
|
347
|
+
for (const row of formattedData) {
|
|
348
|
+
const dataRow = headers.map((header) => row[header] || '');
|
|
349
|
+
worksheetData.push(dataRow);
|
|
350
|
+
}
|
|
351
|
+
return { data: worksheetData, headerRowIndex };
|
|
352
|
+
};
|
|
353
|
+
// Helper function to get base cell style
|
|
354
|
+
const getBaseCellStyle = () => ({
|
|
355
|
+
font: { name: 'Calibri', sz: 11 },
|
|
356
|
+
alignment: { vertical: 'center' },
|
|
357
|
+
border: {
|
|
358
|
+
top: { style: 'thin', color: { rgb: 'D1D5DB' } },
|
|
359
|
+
bottom: { style: 'thin', color: { rgb: 'D1D5DB' } },
|
|
360
|
+
left: { style: 'thin', color: { rgb: 'D1D5DB' } },
|
|
361
|
+
right: { style: 'thin', color: { rgb: 'D1D5DB' } },
|
|
362
|
+
},
|
|
363
|
+
});
|
|
364
|
+
// Helper function to style title row
|
|
365
|
+
const styleTitleRow = (worksheet, colors) => {
|
|
366
|
+
if (worksheet['A1']) {
|
|
367
|
+
worksheet['A1'].s = {
|
|
368
|
+
...getBaseCellStyle(),
|
|
369
|
+
font: { name: 'Calibri', sz: 16, bold: true },
|
|
370
|
+
alignment: { horizontal: 'center', vertical: 'center' },
|
|
371
|
+
fill: colors?.primary
|
|
372
|
+
? {
|
|
373
|
+
fgColor: { rgb: colors.primary[500].replace('#', '') },
|
|
374
|
+
}
|
|
375
|
+
: { fgColor: { rgb: 'F3F4F6' } },
|
|
376
|
+
border: {},
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
// Helper function to style subtitle row
|
|
381
|
+
const styleSubtitleRow = (worksheet) => {
|
|
382
|
+
if (worksheet['A2']) {
|
|
383
|
+
worksheet['A2'].s = {
|
|
384
|
+
...getBaseCellStyle(),
|
|
385
|
+
font: { name: 'Calibri', sz: 10, italic: true },
|
|
386
|
+
alignment: { horizontal: 'center', vertical: 'center' },
|
|
387
|
+
fill: { fgColor: { rgb: 'F9FAFB' } },
|
|
388
|
+
border: {},
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
};
|
|
392
|
+
// Helper function to style header row
|
|
393
|
+
const styleHeaderRow = (worksheet, headerRowIndex, headers, colors) => {
|
|
394
|
+
for (let col = 0; col < headers.length; col++) {
|
|
395
|
+
const cellAddress = XLSX.utils.encode_cell({ r: headerRowIndex, c: col });
|
|
396
|
+
if (worksheet[cellAddress]) {
|
|
397
|
+
worksheet[cellAddress].s = {
|
|
398
|
+
...getBaseCellStyle(),
|
|
399
|
+
font: { name: 'Calibri', sz: 11, bold: true, color: { rgb: 'FFFFFF' } },
|
|
400
|
+
alignment: { horizontal: 'center', vertical: 'center' },
|
|
401
|
+
fill: colors?.primary
|
|
402
|
+
? {
|
|
403
|
+
fgColor: { rgb: colors.primary[600].replace('#', '') },
|
|
404
|
+
}
|
|
405
|
+
: { fgColor: { rgb: '6B7280' } },
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
};
|
|
410
|
+
// Helper function to style data rows
|
|
411
|
+
const styleDataRows = (worksheet, headerRowIndex, headers) => {
|
|
412
|
+
const range = XLSX.utils.decode_range(worksheet['!ref'] || 'A1');
|
|
413
|
+
for (let row = headerRowIndex + 1; row <= range.e.r; row++) {
|
|
414
|
+
for (let col = 0; col <= range.e.c; col++) {
|
|
415
|
+
const cellAddress = XLSX.utils.encode_cell({ r: row, c: col });
|
|
416
|
+
if (worksheet[cellAddress]) {
|
|
417
|
+
// Alternate row colors for better readability
|
|
418
|
+
const isEvenRow = (row - headerRowIndex - 1) % 2 === 0;
|
|
419
|
+
worksheet[cellAddress].s = {
|
|
420
|
+
...getBaseCellStyle(),
|
|
421
|
+
fill: { fgColor: { rgb: isEvenRow ? 'FFFFFF' : 'F9FAFB' } },
|
|
422
|
+
};
|
|
423
|
+
// Apply special formatting for different data types
|
|
424
|
+
const cellValue = worksheet[cellAddress].v;
|
|
425
|
+
if (typeof cellValue === 'number' &&
|
|
426
|
+
headers[col] &&
|
|
427
|
+
(headers[col].toLowerCase().includes('amount') || headers[col].toLowerCase().includes('price'))) {
|
|
428
|
+
worksheet[cellAddress].s.numFmt = '#,##0.00';
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
};
|
|
434
|
+
// Helper function to apply cell styling
|
|
435
|
+
const applyCellStyling = (worksheet, headerRowIndex, headers, colors, title, hasSubtitle) => {
|
|
436
|
+
// Style title row
|
|
437
|
+
if (title) {
|
|
438
|
+
styleTitleRow(worksheet, colors);
|
|
439
|
+
}
|
|
440
|
+
// Style subtitle/timestamp row
|
|
441
|
+
if (hasSubtitle) {
|
|
442
|
+
styleSubtitleRow(worksheet);
|
|
443
|
+
}
|
|
444
|
+
// Style header row
|
|
445
|
+
styleHeaderRow(worksheet, headerRowIndex, headers, colors);
|
|
446
|
+
// Style data rows
|
|
447
|
+
styleDataRows(worksheet, headerRowIndex, headers);
|
|
448
|
+
};
|
|
449
|
+
// Helper function to add merged cells
|
|
450
|
+
const addMergedCells = (worksheet, title, hasSubtitle, headers) => {
|
|
451
|
+
worksheet['!merges'] ??= [];
|
|
452
|
+
// Merge title cell across all columns if title exists
|
|
453
|
+
if (title && headers.length > 1) {
|
|
454
|
+
const titleMerge = {
|
|
455
|
+
s: { r: 0, c: 0 },
|
|
456
|
+
e: { r: 0, c: headers.length - 1 },
|
|
457
|
+
};
|
|
458
|
+
worksheet['!merges'].push(titleMerge);
|
|
459
|
+
}
|
|
460
|
+
// Merge subtitle cell across all columns if subtitle exists
|
|
461
|
+
if (hasSubtitle && headers.length > 1) {
|
|
462
|
+
const subtitleMerge = {
|
|
463
|
+
s: { r: 1, c: 0 },
|
|
464
|
+
e: { r: 1, c: headers.length - 1 },
|
|
465
|
+
};
|
|
466
|
+
worksheet['!merges'].push(subtitleMerge);
|
|
467
|
+
}
|
|
468
|
+
};
|
|
469
|
+
// XLSX Export
|
|
470
|
+
export const exportToXlsx = (data, columns, options = {}) => {
|
|
471
|
+
const { title = 'Data Export', subtitle, colors, sheetName = 'Data', includeTimestamp = true, autoFitColumns = true, } = options;
|
|
472
|
+
const columnKeys = columns.map((col) => col.accessorKey);
|
|
473
|
+
const headers = columns.map((col) => formatHeaderText(col.header || ''));
|
|
474
|
+
// Prepare data with proper formatting
|
|
475
|
+
const formattedData = data.map((row) => columnKeys.reduce((acc, key) => {
|
|
476
|
+
const header = columns.find((col) => col.accessorKey === key)?.header || '';
|
|
477
|
+
acc[header] = formatCellContentForExcel(row[key], key);
|
|
478
|
+
return acc;
|
|
479
|
+
}, {}));
|
|
480
|
+
// Create workbook
|
|
481
|
+
const workbook = XLSX.utils.book_new();
|
|
482
|
+
// Create worksheet data structure
|
|
483
|
+
const { data: worksheetData, headerRowIndex } = createWorksheetData(title, subtitle, includeTimestamp, headers, formattedData);
|
|
484
|
+
// Create worksheet from array
|
|
485
|
+
const worksheet = XLSX.utils.aoa_to_sheet(worksheetData);
|
|
486
|
+
// Set column widths if autoFitColumns is enabled
|
|
487
|
+
if (autoFitColumns) {
|
|
488
|
+
worksheet['!cols'] = calculateColumnWidths(headers, formattedData);
|
|
489
|
+
}
|
|
490
|
+
// Apply styling and formatting
|
|
491
|
+
const hasSubtitle = Boolean(subtitle || includeTimestamp);
|
|
492
|
+
applyCellStyling(worksheet, headerRowIndex, headers, colors, title, hasSubtitle);
|
|
493
|
+
// Add merged cells
|
|
494
|
+
addMergedCells(worksheet, title, hasSubtitle, headers);
|
|
495
|
+
// Add worksheet to workbook
|
|
496
|
+
XLSX.utils.book_append_sheet(workbook, worksheet, sheetName);
|
|
497
|
+
// Generate filename with timestamp
|
|
498
|
+
const timestamp = new Date()
|
|
499
|
+
.toISOString()
|
|
500
|
+
.slice(0, 19)
|
|
501
|
+
.replace(/[:\-T]/g, '');
|
|
502
|
+
const filename = `${title.replace(/\s+/g, '_').toLowerCase()}_${timestamp}.xlsx`;
|
|
503
|
+
// Write file
|
|
504
|
+
XLSX.writeFile(workbook, filename);
|
|
505
|
+
};
|
|
506
|
+
// Helper function to check if a column likely contains images
|
|
507
|
+
const isImageColumn = (columnKey, data) => {
|
|
508
|
+
const imageKeywords = ['image', 'photo', 'picture', 'avatar', 'logo'];
|
|
509
|
+
const keyLower = columnKey.toLowerCase();
|
|
510
|
+
// Check if column key suggests images
|
|
511
|
+
if (imageKeywords.some((keyword) => keyLower.includes(keyword))) {
|
|
512
|
+
return true;
|
|
513
|
+
}
|
|
514
|
+
// Check if sample data looks like image URLs
|
|
515
|
+
const sampleValues = data
|
|
516
|
+
.slice(0, 5)
|
|
517
|
+
.map((row) => row[columnKey])
|
|
518
|
+
.filter(Boolean);
|
|
519
|
+
if (sampleValues.length > 0) {
|
|
520
|
+
const imageExtensions = ['.jpg', '.png', '.gif', '.jpeg', '.webp'];
|
|
521
|
+
const imageUrls = sampleValues.filter((value) => typeof value === 'string' && imageExtensions.some((ext) => value.toLowerCase().includes(ext)));
|
|
522
|
+
return imageUrls.length > sampleValues.length * 0.5; // More than 50% are image URLs
|
|
523
|
+
}
|
|
524
|
+
return false;
|
|
525
|
+
};
|
|
526
|
+
// Helper function to format headers with proper word wrapping
|
|
527
|
+
const formatHeaderText = (header) => {
|
|
528
|
+
// Don't modify single words or headers that are already properly formatted
|
|
529
|
+
if (!header.includes(' ') && header.length <= 12) {
|
|
530
|
+
return header; // Keep single words as-is to prevent unnecessary wrapping
|
|
531
|
+
}
|
|
532
|
+
// Only format camelCase to space-separated if it's a compound word
|
|
533
|
+
// Use ReDoS-safe approach by avoiding greedy quantifiers in nested groups
|
|
534
|
+
let result = header;
|
|
535
|
+
// First handle camelCase: lowercase followed by uppercase
|
|
536
|
+
result = result.replace(/([a-z])([A-Z])/g, '$1 $2');
|
|
537
|
+
result = result.replace(/([A-Z])([A-Z][a-z])/g, '$1 $2');
|
|
538
|
+
return result.trim();
|
|
539
|
+
};
|
|
540
|
+
// Enhanced table data preparation with image handling
|
|
541
|
+
const prepareTableDataForPdf = async (data, columns, doc) => {
|
|
542
|
+
const columnKeys = columns.map((col) => col.accessorKey);
|
|
543
|
+
// Identify image columns
|
|
544
|
+
const imageColumns = columnKeys.filter((key) => isImageColumn(key, data));
|
|
545
|
+
// Store image information for later embedding
|
|
546
|
+
const imageInfo = new Map();
|
|
547
|
+
const tableData = await Promise.all(data.map(async (row, rowIndex) => {
|
|
548
|
+
return Promise.all(columnKeys.map(async (key, colIndex) => {
|
|
549
|
+
const value = row[key];
|
|
550
|
+
// Handle image columns specially
|
|
551
|
+
if (imageColumns.includes(key) && typeof value === 'string') {
|
|
552
|
+
try {
|
|
553
|
+
const imageBase64 = await loadImageAsBase64(value);
|
|
554
|
+
if (imageBase64) {
|
|
555
|
+
// Store image info for embedding
|
|
556
|
+
const imageKey = `img_${rowIndex}_${colIndex}`;
|
|
557
|
+
// Calculate appropriate size for table cell (small thumbnail)
|
|
558
|
+
const cellImageSize = 8; // 8mm square for table cell
|
|
559
|
+
imageInfo.set(imageKey, {
|
|
560
|
+
base64: imageBase64,
|
|
561
|
+
width: cellImageSize,
|
|
562
|
+
height: cellImageSize,
|
|
563
|
+
});
|
|
564
|
+
return imageKey; // Return the key to identify where to place the image
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
catch (error) {
|
|
568
|
+
console.warn(`Failed to load image for column ${key}:`, error);
|
|
569
|
+
}
|
|
570
|
+
return '[Image Failed]';
|
|
571
|
+
}
|
|
572
|
+
return formatCellContent(value, key);
|
|
573
|
+
}));
|
|
574
|
+
}));
|
|
575
|
+
return { tableData, imageInfo };
|
|
576
|
+
};
|
|
577
|
+
// PDF Export
|
|
578
|
+
export const exportToPdf = async (data, columns, options = {}) => {
|
|
579
|
+
const { title = 'Data Export', subtitle = `Generated on ${new Date().toLocaleDateString('en-US', {
|
|
580
|
+
year: 'numeric',
|
|
581
|
+
month: 'long',
|
|
582
|
+
day: 'numeric',
|
|
583
|
+
hour: '2-digit',
|
|
584
|
+
minute: '2-digit',
|
|
585
|
+
})}`, colors, logo, } = options;
|
|
586
|
+
// Create PDF document with better settings
|
|
587
|
+
const doc = new jsPDF({
|
|
588
|
+
orientation: 'landscape',
|
|
589
|
+
unit: 'mm',
|
|
590
|
+
format: 'a4',
|
|
591
|
+
compress: true,
|
|
592
|
+
});
|
|
593
|
+
const pageWidth = doc.internal.pageSize.getWidth();
|
|
594
|
+
const pageHeight = doc.internal.pageSize.getHeight();
|
|
595
|
+
const margin = 10;
|
|
596
|
+
// Define colors with fallbacks
|
|
597
|
+
const primaryColor = colors?.core?.primary || colors?.primary?.['500'] || '#b45dae';
|
|
598
|
+
const [primaryR, primaryG, primaryB] = parseRgbString(primaryColor);
|
|
599
|
+
let currentY = margin;
|
|
600
|
+
// Add logo if provided
|
|
601
|
+
if (logo?.url) {
|
|
602
|
+
try {
|
|
603
|
+
const logoBase64 = await loadImageAsBase64(logo.url);
|
|
604
|
+
if (logoBase64) {
|
|
605
|
+
const logoWidth = logo.width || 30;
|
|
606
|
+
const logoHeight = logo.height || 15;
|
|
607
|
+
doc.addImage(logoBase64, 'PNG', margin, currentY, logoWidth, logoHeight);
|
|
608
|
+
currentY += logoHeight + 5;
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
catch (error) {
|
|
612
|
+
console.warn('Failed to load logo for PDF export:', error);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
// Add title
|
|
616
|
+
doc.setFont('helvetica', 'bold');
|
|
617
|
+
doc.setFontSize(18);
|
|
618
|
+
doc.setTextColor(primaryR, primaryG, primaryB);
|
|
619
|
+
doc.text(title, margin, currentY);
|
|
620
|
+
currentY += 8;
|
|
621
|
+
// Add subtitle
|
|
622
|
+
doc.setFont('helvetica', 'normal');
|
|
623
|
+
doc.setFontSize(10);
|
|
624
|
+
doc.setTextColor(100, 100, 100);
|
|
625
|
+
doc.text(subtitle, margin, currentY);
|
|
626
|
+
currentY += 10;
|
|
627
|
+
// Add a decorative line
|
|
628
|
+
doc.setDrawColor(primaryR, primaryG, primaryB);
|
|
629
|
+
doc.setLineWidth(0.5);
|
|
630
|
+
doc.line(margin, currentY, pageWidth - margin, currentY);
|
|
631
|
+
currentY += 8;
|
|
632
|
+
// Prepare table data
|
|
633
|
+
const columnHeaders = columns.map((col) => formatHeaderText(col.header || String(col.accessorKey)));
|
|
634
|
+
// Format table data with enhanced handling for images, status, etc.
|
|
635
|
+
const { tableData, imageInfo } = await prepareTableDataForPdf(data, columns, doc);
|
|
636
|
+
console.log(`PDF export: Processing ${tableData.length} rows with ${imageInfo.size} images`);
|
|
637
|
+
// Calculate optimal column widths
|
|
638
|
+
const availableWidth = pageWidth - 2 * margin;
|
|
639
|
+
const numColumns = columnHeaders.length;
|
|
640
|
+
const baseColumnWidth = availableWidth / numColumns;
|
|
641
|
+
// Adjust column widths based on content
|
|
642
|
+
const columnWidths = columnHeaders.map((header, index) => {
|
|
643
|
+
// For single words, ensure minimum width to prevent wrapping
|
|
644
|
+
const isSimpleWord = !header.includes(' ') && header.length <= 12;
|
|
645
|
+
const minWordWidth = isSimpleWord ? header.length * 2.5 : 0; // Extra space for single words
|
|
646
|
+
// Calculate header length considering word boundaries
|
|
647
|
+
const headerWords = header.split(' ');
|
|
648
|
+
const longestWord = Math.max(...headerWords.map((word) => word.length));
|
|
649
|
+
const headerLength = Math.max(longestWord, header.length / 2); // Allow for wrapping
|
|
650
|
+
const maxContentLength = Math.max(...tableData.map((row) => String(row[index] || '').length));
|
|
651
|
+
const contentLength = Math.max(headerLength, maxContentLength, minWordWidth);
|
|
652
|
+
// Scale width based on content, but keep within reasonable bounds
|
|
653
|
+
const scaleFactor = Math.min(Math.max(contentLength / 12, 1.0), 2.5); // Increased minimum
|
|
654
|
+
return baseColumnWidth * scaleFactor;
|
|
655
|
+
});
|
|
656
|
+
// Normalize column widths to fit page
|
|
657
|
+
const totalWidth = columnWidths.reduce((sum, width) => sum + width, 0);
|
|
658
|
+
const normalizedWidths = columnWidths.map((width) => (width / totalWidth) * availableWidth);
|
|
659
|
+
// Configure auto-table with professional styling
|
|
660
|
+
doc.autoTable({
|
|
661
|
+
head: [columnHeaders],
|
|
662
|
+
body: tableData,
|
|
663
|
+
startY: currentY,
|
|
664
|
+
margin: { left: margin, right: margin },
|
|
665
|
+
columnStyles: normalizedWidths.reduce((styles, width, index) => {
|
|
666
|
+
styles[index] = {
|
|
667
|
+
cellWidth: width,
|
|
668
|
+
overflow: 'linebreak',
|
|
669
|
+
fontSize: 8,
|
|
670
|
+
cellPadding: 2,
|
|
671
|
+
halign: 'left',
|
|
672
|
+
};
|
|
673
|
+
return styles;
|
|
674
|
+
}, {}),
|
|
675
|
+
headStyles: {
|
|
676
|
+
fillColor: [primaryR, primaryG, primaryB],
|
|
677
|
+
textColor: [255, 255, 255],
|
|
678
|
+
fontStyle: 'bold',
|
|
679
|
+
fontSize: 9,
|
|
680
|
+
halign: 'center',
|
|
681
|
+
cellPadding: 3,
|
|
682
|
+
overflow: 'linebreak',
|
|
683
|
+
cellWidth: 'wrap',
|
|
684
|
+
},
|
|
685
|
+
bodyStyles: {
|
|
686
|
+
fontSize: 8,
|
|
687
|
+
cellPadding: 2,
|
|
688
|
+
textColor: [33, 37, 41],
|
|
689
|
+
},
|
|
690
|
+
alternateRowStyles: {
|
|
691
|
+
fillColor: [248, 249, 250],
|
|
692
|
+
},
|
|
693
|
+
styles: {
|
|
694
|
+
lineColor: [230, 230, 230],
|
|
695
|
+
lineWidth: 0.1,
|
|
696
|
+
overflow: 'linebreak',
|
|
697
|
+
cellWidth: 'wrap',
|
|
698
|
+
},
|
|
699
|
+
theme: 'grid',
|
|
700
|
+
tableLineColor: [200, 200, 200],
|
|
701
|
+
tableLineWidth: 0.1,
|
|
702
|
+
didDrawCell: function (data) {
|
|
703
|
+
// Check if this cell contains an image key
|
|
704
|
+
const cellText = data.cell.text.join('');
|
|
705
|
+
if (imageInfo.has(cellText) && cellText.startsWith('img_')) {
|
|
706
|
+
const imgData = imageInfo.get(cellText);
|
|
707
|
+
if (imgData) {
|
|
708
|
+
try {
|
|
709
|
+
// Completely clear the cell by overriding the drawing
|
|
710
|
+
const cellX = data.cell.x;
|
|
711
|
+
const cellY = data.cell.y;
|
|
712
|
+
const cellWidth = data.cell.width;
|
|
713
|
+
const cellHeight = data.cell.height;
|
|
714
|
+
// Fill the cell with white background to cover any text
|
|
715
|
+
doc.setFillColor(255, 255, 255);
|
|
716
|
+
doc.rect(cellX, cellY, cellWidth, cellHeight, 'F');
|
|
717
|
+
// Redraw cell border if needed
|
|
718
|
+
doc.setDrawColor(200, 200, 200);
|
|
719
|
+
doc.setLineWidth(0.1);
|
|
720
|
+
doc.rect(cellX, cellY, cellWidth, cellHeight, 'S');
|
|
721
|
+
// Calculate position to center the image in the cell
|
|
722
|
+
const imgX = cellX + (cellWidth - imgData.width) / 2;
|
|
723
|
+
const imgY = cellY + (cellHeight - imgData.height) / 2;
|
|
724
|
+
// Detect image format for better compatibility
|
|
725
|
+
let format = 'JPEG'; // Default
|
|
726
|
+
if (imgData.base64.includes('data:image/png')) {
|
|
727
|
+
format = 'PNG';
|
|
728
|
+
}
|
|
729
|
+
else if (imgData.base64.includes('data:image/gif')) {
|
|
730
|
+
format = 'GIF';
|
|
731
|
+
}
|
|
732
|
+
else if (imgData.base64.includes('data:image/webp')) {
|
|
733
|
+
format = 'WEBP';
|
|
734
|
+
}
|
|
735
|
+
// Add the image to the PDF
|
|
736
|
+
doc.addImage(imgData.base64, format, imgX, imgY, imgData.width, imgData.height);
|
|
737
|
+
}
|
|
738
|
+
catch (error) {
|
|
739
|
+
console.warn('Failed to embed image in PDF:', error);
|
|
740
|
+
// Clear the cell and show fallback text
|
|
741
|
+
const cellX = data.cell.x;
|
|
742
|
+
const cellY = data.cell.y;
|
|
743
|
+
const cellWidth = data.cell.width;
|
|
744
|
+
const cellHeight = data.cell.height;
|
|
745
|
+
// Fill with white background
|
|
746
|
+
doc.setFillColor(255, 255, 255);
|
|
747
|
+
doc.rect(cellX, cellY, cellWidth, cellHeight, 'F');
|
|
748
|
+
// Redraw border
|
|
749
|
+
doc.setDrawColor(200, 200, 200);
|
|
750
|
+
doc.setLineWidth(0.1);
|
|
751
|
+
doc.rect(cellX, cellY, cellWidth, cellHeight, 'S');
|
|
752
|
+
// Add fallback text
|
|
753
|
+
doc.setFont('helvetica', 'normal');
|
|
754
|
+
doc.setFontSize(8);
|
|
755
|
+
doc.setTextColor(100, 100, 100);
|
|
756
|
+
doc.text('[Image]', cellX + 2, cellY + cellHeight / 2 + 1);
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
},
|
|
761
|
+
didDrawPage: function (data) {
|
|
762
|
+
// Add footer with page numbers and branding
|
|
763
|
+
const pageCount = doc.internal.pages.length - 1;
|
|
764
|
+
const currentPage = data.pageNumber;
|
|
765
|
+
// Footer line
|
|
766
|
+
doc.setDrawColor(200, 200, 200);
|
|
767
|
+
doc.setLineWidth(0.1);
|
|
768
|
+
doc.line(margin, pageHeight - 15, pageWidth - margin, pageHeight - 15);
|
|
769
|
+
// Page number
|
|
770
|
+
doc.setFont('helvetica', 'normal');
|
|
771
|
+
doc.setFontSize(8);
|
|
772
|
+
doc.setTextColor(100, 100, 100);
|
|
773
|
+
doc.text(`Page ${currentPage} of ${pageCount}`, pageWidth - margin - 20, pageHeight - 8);
|
|
774
|
+
// Export timestamp
|
|
775
|
+
doc.text(`Exported: ${new Date().toLocaleString()}`, margin, pageHeight - 8);
|
|
776
|
+
},
|
|
777
|
+
});
|
|
778
|
+
// Save the PDF with a meaningful filename
|
|
779
|
+
const timestamp = new Date().toISOString().split('T')[0];
|
|
780
|
+
const filename = `${title.toLowerCase().replace(/\s+/g, '_')}_${timestamp}.pdf`;
|
|
781
|
+
doc.save(filename);
|
|
782
|
+
};
|