indas-ui 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/components/auth/ProtectedRoute.js +48 -0
- package/dist/cjs/components/auth/UnauthorizedPage.js +19 -0
- package/dist/cjs/components/auth/index.js +9 -0
- package/dist/cjs/components/chat/ai-messages.js +271 -0
- package/dist/cjs/components/chat/chat-prompt-navigator.js +110 -0
- package/dist/cjs/components/chat/chat.js +1032 -0
- package/dist/cjs/components/chat/multimodal-input.js +117 -0
- package/dist/cjs/components/dashboard/DrillDownModal.js +36 -0
- package/dist/cjs/components/dashboard/FilterBar.js +434 -0
- package/dist/cjs/components/dashboard/Tooltip.js +86 -0
- package/dist/cjs/components/dashboard/charts/Area.js +127 -0
- package/dist/cjs/components/dashboard/charts/Bar.js +111 -0
- package/dist/cjs/components/dashboard/charts/BoxPlot.js +118 -0
- package/dist/cjs/components/dashboard/charts/Bubble.js +102 -0
- package/dist/cjs/components/dashboard/charts/DashboardCard.js +12 -0
- package/dist/cjs/components/dashboard/charts/Donut.js +130 -0
- package/dist/cjs/components/dashboard/charts/FlowMap.js +238 -0
- package/dist/cjs/components/dashboard/charts/Funnel.js +38 -0
- package/dist/cjs/components/dashboard/charts/Gantt.js +271 -0
- package/dist/cjs/components/dashboard/charts/Gauge.js +143 -0
- package/dist/cjs/components/dashboard/charts/GeoMap.js +164 -0
- package/dist/cjs/components/dashboard/charts/Heatmap.js +116 -0
- package/dist/cjs/components/dashboard/charts/Line.js +75 -0
- package/dist/cjs/components/dashboard/charts/Pareto.js +110 -0
- package/dist/cjs/components/dashboard/charts/Radar.js +94 -0
- package/dist/cjs/components/dashboard/charts/Sankey.js +92 -0
- package/dist/cjs/components/dashboard/charts/Scatter.js +128 -0
- package/dist/cjs/components/dashboard/charts/Sparkline.js +134 -0
- package/dist/cjs/components/dashboard/charts/Treemap.js +104 -0
- package/dist/cjs/components/dashboard/charts/index.js +45 -0
- package/dist/cjs/components/dashboard/charts/india-map.js +464 -0
- package/dist/cjs/components/dashboard/charts/theme.js +132 -0
- package/dist/cjs/components/dashboard/config.js +118 -0
- package/dist/cjs/components/dashboard/index.js +39 -0
- package/dist/cjs/components/dashboard/kpi/KpiBeforeAfter.js +16 -0
- package/dist/cjs/components/dashboard/kpi/KpiBreakdown.js +42 -0
- package/dist/cjs/components/dashboard/kpi/KpiComparison.js +41 -0
- package/dist/cjs/components/dashboard/kpi/KpiQuickStats.js +41 -0
- package/dist/cjs/components/dashboard/kpi/KpiRating.js +38 -0
- package/dist/cjs/components/dashboard/kpi/KpiScroll.js +83 -0
- package/dist/cjs/components/dashboard/kpi/KpiTrend.js +37 -0
- package/dist/cjs/components/dashboard/kpi/index.js +22 -0
- package/dist/cjs/components/dashboard/kpi/kpi-shell.js +113 -0
- package/dist/cjs/components/dashboard/time-range.js +126 -0
- package/dist/cjs/components/datagrid/DataGrid.js +1613 -0
- package/dist/cjs/components/datagrid/cells/BooleanCell.js +42 -0
- package/dist/cjs/components/datagrid/cells/CellRenderer.js +142 -0
- package/dist/cjs/components/datagrid/cells/EditableCell.js +217 -0
- package/dist/cjs/components/datagrid/cells/SelectionCell.js +60 -0
- package/dist/cjs/components/datagrid/cells/index.js +6 -0
- package/dist/cjs/components/datagrid/columns/ActionsColumn.js +485 -0
- package/dist/cjs/components/datagrid/columns/ColumnContextMenu.js +341 -0
- package/dist/cjs/components/datagrid/columns/DraggableColumnHeader.js +150 -0
- package/dist/cjs/components/datagrid/controls/AutoResizeButton.js +10 -0
- package/dist/cjs/components/datagrid/controls/PaginationControls.js +38 -0
- package/dist/cjs/components/datagrid/controls/SummaryControls.js +30 -0
- package/dist/cjs/components/datagrid/controls/menu/ActionsMenu.js +16 -0
- package/dist/cjs/components/datagrid/controls/menu/column/ColumnChooserModal.js +25 -0
- package/dist/cjs/components/datagrid/controls/menu/column/ColumnSection.js +10 -0
- package/dist/cjs/components/datagrid/controls/menu/export/ExportSection.js +19 -0
- package/dist/cjs/components/datagrid/controls/menu/export/export.js +227 -0
- package/dist/cjs/components/datagrid/controls/menu/filter/AdvancedFilterModal.js +405 -0
- package/dist/cjs/components/datagrid/controls/menu/filter/FilterSection.js +9 -0
- package/dist/cjs/components/datagrid/controls/menu/grouping/GroupingSection.js +23 -0
- package/dist/cjs/components/datagrid/controls/menu/grouping/index.js +6 -0
- package/dist/cjs/components/datagrid/controls/menu/import/ImportSection.js +75 -0
- package/dist/cjs/components/datagrid/controls/menu/import/import.js +232 -0
- package/dist/cjs/components/datagrid/controls/menu/index.js +24 -0
- package/dist/cjs/components/datagrid/controls/menu/view/CardView.js +176 -0
- package/dist/cjs/components/datagrid/controls/menu/view/ChartView.js +401 -0
- package/dist/cjs/components/datagrid/controls/menu/view/ViewSection.js +12 -0
- package/dist/cjs/components/datagrid/hooks/useCellRangeSelection.js +127 -0
- package/dist/cjs/components/datagrid/hooks/useClipboard.js +154 -0
- package/dist/cjs/components/datagrid/hooks/useDataGridState.js +115 -0
- package/dist/cjs/components/datagrid/hooks/useKeyboardNavigation.js +120 -0
- package/dist/cjs/components/datagrid/index.js +90 -0
- package/dist/cjs/components/datagrid/rows/DraggableRow.js +34 -0
- package/dist/cjs/components/datagrid/rows/ExpandableRow.js +184 -0
- package/dist/cjs/components/datagrid/rows/FilterRow.js +188 -0
- package/dist/cjs/components/datagrid/rows/SelectColumn.js +34 -0
- package/dist/cjs/components/datagrid/rows/SummaryRow.js +34 -0
- package/dist/cjs/components/datagrid/rows/summary.js +67 -0
- package/dist/cjs/components/datagrid/search/InlineSearchCell.js +99 -0
- package/dist/cjs/components/datagrid/search/SearchHighlighter.js +133 -0
- package/dist/cjs/components/datagrid/search/SearchNavigator.js +185 -0
- package/dist/cjs/components/datagrid/search/SearchNewModal.js +238 -0
- package/dist/cjs/components/datagrid/search/advancedSearch.js +112 -0
- package/dist/cjs/components/datagrid/utils/grid-helpers.js +102 -0
- package/dist/cjs/components/datagrid/utils/grid-types.js +3 -0
- package/dist/cjs/components/draft/AutoSaveIndicator.js +70 -0
- package/dist/cjs/components/draft/DraftModal.js +220 -0
- package/dist/cjs/components/forms/date-picker/CalendarView.js +82 -0
- package/dist/cjs/components/forms/date-picker/DatePicker.js +748 -0
- package/dist/cjs/components/forms/date-picker/DateTimePicker.js +174 -0
- package/dist/cjs/components/forms/date-picker/index.js +21 -0
- package/dist/cjs/components/forms/date-picker/shared-utils.js +24 -0
- package/dist/cjs/components/forms/dropdown/Dropdown.js +427 -0
- package/dist/cjs/components/forms/dropdown/MultiSelect.js +136 -0
- package/dist/cjs/components/forms/dropdown/SingleSelect.js +254 -0
- package/dist/cjs/components/forms/dropdown/hooks/useDropdownCreate.js +88 -0
- package/dist/cjs/components/forms/dropdown/hooks/useDropdownFiltering.js +87 -0
- package/dist/cjs/components/forms/dropdown/hooks/useDropdownState.js +63 -0
- package/dist/cjs/components/forms/dropdown/index.js +6 -0
- package/dist/cjs/components/forms/dropdown/types.js +3 -0
- package/dist/cjs/components/forms/file-attachment/EmailPreview.js +419 -0
- package/dist/cjs/components/forms/file-attachment/FileAttachment.js +966 -0
- package/dist/cjs/components/forms/file-attachment/index.js +6 -0
- package/dist/cjs/components/forms/index.js +16 -0
- package/dist/cjs/components/forms/quantity-input-popup.js +135 -0
- package/dist/cjs/components/forms/remark-input/RemarkInput.js +263 -0
- package/dist/cjs/components/forms/remark-input/index.js +8 -0
- package/dist/cjs/components/forms/unified-currency-dropdown.js +202 -0
- package/dist/cjs/components/index.js +41 -0
- package/dist/cjs/components/layout/SidebarContextMenu.js +179 -0
- package/dist/cjs/components/layout/app-shell.js +81 -0
- package/dist/cjs/components/layout/bottom-nav.js +262 -0
- package/dist/cjs/components/layout/floating-action-button.js +77 -0
- package/dist/cjs/components/layout/footer.js +60 -0
- package/dist/cjs/components/layout/index.js +16 -0
- package/dist/cjs/components/layout/mobile-menu-sheet.js +195 -0
- package/dist/cjs/components/layout/side-panel.js +118 -0
- package/dist/cjs/components/layout/sidebar.js +581 -0
- package/dist/cjs/components/layout/top-header.js +270 -0
- package/dist/cjs/components/layout/userprofile-dropdown.js +100 -0
- package/dist/cjs/components/master/editable-cells/EditableCell.js +106 -0
- package/dist/cjs/components/master/editable-cells/index.js +17 -0
- package/dist/cjs/components/master/index.js +9 -0
- package/dist/cjs/components/messaging/conversation-list.js +109 -0
- package/dist/cjs/components/messaging/create-conversation-modal.js +112 -0
- package/dist/cjs/components/messaging/message-bubble.js +69 -0
- package/dist/cjs/components/messaging/message-input.js +154 -0
- package/dist/cjs/components/messaging/message-thread.js +124 -0
- package/dist/cjs/components/messaging/messaging-panel-content.js +69 -0
- package/dist/cjs/components/messaging/thread-panel.js +50 -0
- package/dist/cjs/components/modals/3DModal.js +35 -0
- package/dist/cjs/components/modals/ImageModal.js +587 -0
- package/dist/cjs/components/modals/Modal.js +311 -0
- package/dist/cjs/components/modals/StandardModal.js +28 -0
- package/dist/cjs/components/modals/api-config-modal.js +120 -0
- package/dist/cjs/components/modals/global-api-config-modal.js +127 -0
- package/dist/cjs/components/modals/index.js +17 -0
- package/dist/cjs/components/modals/logout-modal.js +45 -0
- package/dist/cjs/components/modals/modal-alert.js +295 -0
- package/dist/cjs/components/modals/password-reset-modal.js +112 -0
- package/dist/cjs/components/modals/session-expiry-warning.js +18 -0
- package/dist/cjs/components/providers/api-provider.js +19 -0
- package/dist/cjs/components/providers/query-provider.js +29 -0
- package/dist/cjs/components/providers/session-provider.js +119 -0
- package/dist/cjs/components/theme/ThemeCustomizer.js +184 -0
- package/dist/cjs/components/ui/buttons/button.js +264 -0
- package/dist/cjs/components/ui/card.js +58 -0
- package/dist/cjs/components/ui/chart.js +160 -0
- package/dist/cjs/components/ui/display/boolean-badge.js +29 -0
- package/dist/cjs/components/ui/display/card.js +20 -0
- package/dist/cjs/components/ui/display/collapsible.js +44 -0
- package/dist/cjs/components/ui/display/separator.js +44 -0
- package/dist/cjs/components/ui/display/stats-card.js +29 -0
- package/dist/cjs/components/ui/display/text.js +94 -0
- package/dist/cjs/components/ui/feedback/alert.js +61 -0
- package/dist/cjs/components/ui/feedback/badge.js +93 -0
- package/dist/cjs/components/ui/feedback/progress.js +44 -0
- package/dist/cjs/components/ui/feedback/reminder-button.js +111 -0
- package/dist/cjs/components/ui/feedback/skeleton-table.js +20 -0
- package/dist/cjs/components/ui/feedback/skeleton.js +53 -0
- package/dist/cjs/components/ui/feedback/tooltip.js +54 -0
- package/dist/cjs/components/ui/form-toggle.js +47 -0
- package/dist/cjs/components/ui/forms/checkbox.js +24 -0
- package/dist/cjs/components/ui/forms/input.js +111 -0
- package/dist/cjs/components/ui/forms/label.js +10 -0
- package/dist/cjs/components/ui/forms/switch.js +58 -0
- package/dist/cjs/components/ui/forms/textarea.js +49 -0
- package/dist/cjs/components/ui/index.js +157 -0
- package/dist/cjs/components/ui/navigation/dropdown-menu.js +84 -0
- package/dist/cjs/components/ui/navigation/header-steps.js +51 -0
- package/dist/cjs/components/ui/navigation/tabs.js +97 -0
- package/dist/cjs/components/ui/overlays/loading.js +169 -0
- package/dist/cjs/components/ui/select.js +72 -0
- package/dist/cjs/config/api.js +65 -0
- package/dist/cjs/contexts/AppConfigContext.js +37 -0
- package/dist/cjs/contexts/CurrencyContext.js +336 -0
- package/dist/cjs/contexts/DeviceContext.js +106 -0
- package/dist/cjs/contexts/EmailContext.js +727 -0
- package/dist/cjs/contexts/GlobalAlertContext.js +232 -0
- package/dist/cjs/contexts/ImpactAnalysisContext.js +60 -0
- package/dist/cjs/contexts/LanguageContext.js +104 -0
- package/dist/cjs/contexts/MessagingContext.js +726 -0
- package/dist/cjs/contexts/ModuleAuthContext.js +316 -0
- package/dist/cjs/contexts/NavigationContext.js +182 -0
- package/dist/cjs/contexts/NetworkStatusContext.js +95 -0
- package/dist/cjs/contexts/NotificationContext.js +169 -0
- package/dist/cjs/contexts/PageTitleContext.js +28 -0
- package/dist/cjs/contexts/SearchPreferencesContext.js +42 -0
- package/dist/cjs/contexts/SessionAdapterContext.js +24 -0
- package/dist/cjs/contexts/SidebarPreferencesContext.js +116 -0
- package/dist/cjs/contexts/ThemeContext.js +193 -0
- package/dist/cjs/hooks/index.js +50 -0
- package/dist/cjs/hooks/useApproval.js +250 -0
- package/dist/cjs/hooks/useBacchaSearch.js +257 -0
- package/dist/cjs/hooks/useBusinessAudit.js +54 -0
- package/dist/cjs/hooks/useColumnFreezing.js +204 -0
- package/dist/cjs/hooks/useColumnMetadata.js +48 -0
- package/dist/cjs/hooks/useConditionalFormatting.js +197 -0
- package/dist/cjs/hooks/useDebounce.js +49 -0
- package/dist/cjs/hooks/useDraft.js +181 -0
- package/dist/cjs/hooks/useFormValidation.js +68 -0
- package/dist/cjs/hooks/useGridSettings.js +85 -0
- package/dist/cjs/hooks/useGridTheme.js +204 -0
- package/dist/cjs/hooks/useId.js +21 -0
- package/dist/cjs/hooks/useIntelligentColumnSizing.js +315 -0
- package/dist/cjs/hooks/useKeyboardNavigation.js +192 -0
- package/dist/cjs/hooks/useNotifications.js +63 -0
- package/dist/cjs/hooks/usePrevious.js +20 -0
- package/dist/cjs/hooks/useRowSelection.js +150 -0
- package/dist/cjs/hooks/useSignalR.js +53 -0
- package/dist/cjs/hooks/useTheme.js +268 -0
- package/dist/cjs/hooks/useTranslation.js +20 -0
- package/dist/cjs/hooks/useUnsavedChanges.js +88 -0
- package/dist/cjs/index.js +21 -0
- package/dist/cjs/lib/api/activity/audit/audit.js +51 -0
- package/dist/cjs/lib/api/activity/audit/index.js +29 -0
- package/dist/cjs/lib/api/activity/audit/send.js +434 -0
- package/dist/cjs/lib/api/activity/email/client.js +467 -0
- package/dist/cjs/lib/api/activity/email/index.js +31 -0
- package/dist/cjs/lib/api/activity/email/password-reset.js +58 -0
- package/dist/cjs/lib/api/activity/email/templates.js +537 -0
- package/dist/cjs/lib/api/activity/email/types.js +24 -0
- package/dist/cjs/lib/api/activity/index.js +48 -0
- package/dist/cjs/lib/api/activity/messaging/messaging.js +254 -0
- package/dist/cjs/lib/api/activity/notifications/index.js +43 -0
- package/dist/cjs/lib/api/activity/notifications/notifications.js +224 -0
- package/dist/cjs/lib/api/activity/notifications/reminders.js +30 -0
- package/dist/cjs/lib/api/activity/notifications/send.js +267 -0
- package/dist/cjs/lib/api/activity/notifications/types.js +66 -0
- package/dist/cjs/lib/api/activity/notify-and-log.js +63 -0
- package/dist/cjs/lib/api/activity/remarks/index.js +6 -0
- package/dist/cjs/lib/api/activity/remarks/remarks.js +186 -0
- package/dist/cjs/lib/api/activity/storage.js +83 -0
- package/dist/cjs/lib/api/ai/chat.js +227 -0
- package/dist/cjs/lib/api/ai/types.js +6 -0
- package/dist/cjs/lib/api/approval/approvals.js +210 -0
- package/dist/cjs/lib/api/approval/index.js +13 -0
- package/dist/cjs/lib/api/auth/auth.js +154 -0
- package/dist/cjs/lib/api/auth/index.js +11 -0
- package/dist/cjs/lib/api/auth/password-reset-otp.js +192 -0
- package/dist/cjs/lib/api/auth/two-factor-auth.js +94 -0
- package/dist/cjs/lib/api/auth/two-factor.js +186 -0
- package/dist/cjs/lib/api/core/auth-helpers.js +141 -0
- package/dist/cjs/lib/api/core/client.js +305 -0
- package/dist/cjs/lib/api/core/config.js +248 -0
- package/dist/cjs/lib/api/core/index.js +43 -0
- package/dist/cjs/lib/api/core/session-validator.js +98 -0
- package/dist/cjs/lib/api/core/types.js +4 -0
- package/dist/cjs/lib/api/core/utils.js +70 -0
- package/dist/cjs/lib/api/dashboard/costing.js +15 -0
- package/dist/cjs/lib/api/dashboard/management.js +11 -0
- package/dist/cjs/lib/api/dashboard/sales.js +11 -0
- package/dist/cjs/lib/api/draft/drafts.js +279 -0
- package/dist/cjs/lib/api/draft/index.js +13 -0
- package/dist/cjs/lib/api/enquiry/enquiry.js +624 -0
- package/dist/cjs/lib/api/enquiry/index.js +20 -0
- package/dist/cjs/lib/api/enquiry/rate-enquiry.js +78 -0
- package/dist/cjs/lib/api/estimation/categories.js +113 -0
- package/dist/cjs/lib/api/estimation/category-defaults.js +47 -0
- package/dist/cjs/lib/api/estimation/company-config.js +26 -0
- package/dist/cjs/lib/api/estimation/content.js +210 -0
- package/dist/cjs/lib/api/estimation/freight.js +25 -0
- package/dist/cjs/lib/api/estimation/grid-costing-drafts.js +30 -0
- package/dist/cjs/lib/api/estimation/grid-costing.js +176 -0
- package/dist/cjs/lib/api/estimation/index.js +58 -0
- package/dist/cjs/lib/api/estimation/legacy-costing.js +51 -0
- package/dist/cjs/lib/api/estimation/machines.js +74 -0
- package/dist/cjs/lib/api/estimation/planning.js +403 -0
- package/dist/cjs/lib/api/estimation/qualities.js +245 -0
- package/dist/cjs/lib/api/estimation/quotation-load.js +52 -0
- package/dist/cjs/lib/api/estimation/quotation-save.js +109 -0
- package/dist/cjs/lib/api/estimation/quote-check.js +34 -0
- package/dist/cjs/lib/api/estimation/quotepanel.js +496 -0
- package/dist/cjs/lib/api/estimation/shipper-planning.js +220 -0
- package/dist/cjs/lib/api/estimation/wastage.js +47 -0
- package/dist/cjs/lib/api/index.js +33 -0
- package/dist/cjs/lib/api/integration/proxy.js +40 -0
- package/dist/cjs/lib/api/master/category.js +215 -0
- package/dist/cjs/lib/api/master/company.js +389 -0
- package/dist/cjs/lib/api/master/hsn.js +61 -0
- package/dist/cjs/lib/api/master/index.js +47 -0
- package/dist/cjs/lib/api/master/item.js +142 -0
- package/dist/cjs/lib/api/master/ledger.js +398 -0
- package/dist/cjs/lib/api/master/logistics.js +119 -0
- package/dist/cjs/lib/api/master/machine.js +579 -0
- package/dist/cjs/lib/api/master/material-group.js +103 -0
- package/dist/cjs/lib/api/master/other.js +63 -0
- package/dist/cjs/lib/api/master/process-types.js +5 -0
- package/dist/cjs/lib/api/master/process.js +131 -0
- package/dist/cjs/lib/api/master/production-units.js +22 -0
- package/dist/cjs/lib/api/master/rate.js +203 -0
- package/dist/cjs/lib/api/master/tool.js +88 -0
- package/dist/cjs/lib/api/master/user.js +154 -0
- package/dist/cjs/lib/api/settings/erp-parameters.js +69 -0
- package/dist/cjs/lib/api/utility/index.js +11 -0
- package/dist/cjs/lib/api/utility/menu.js +136 -0
- package/dist/cjs/lib/auth.js +10 -0
- package/dist/cjs/lib/pwa.js +59 -0
- package/dist/cjs/lib/react-query-config.js +134 -0
- package/dist/cjs/lib/security/audit-logger.js +177 -0
- package/dist/cjs/lib/security/rate-limiter.js +122 -0
- package/dist/cjs/lib/server-url.js +76 -0
- package/dist/cjs/lib/svg-utils.js +213 -0
- package/dist/cjs/lib/theme/types.js +235 -0
- package/dist/cjs/lib/theme/utils.js +363 -0
- package/dist/cjs/lib/types/index.js +3 -0
- package/dist/cjs/lib/utils/attachment-loader.js +82 -0
- package/dist/cjs/lib/utils/client-lead-utils.js +61 -0
- package/dist/cjs/lib/utils/device-detection.js +110 -0
- package/dist/cjs/lib/utils/logout-cleanup.js +312 -0
- package/dist/cjs/lib/utils/planning-prefs.js +31 -0
- package/dist/cjs/lib/utils.js +70 -0
- package/dist/cjs/lib/vision/dieline-extractor.js +321 -0
- package/dist/cjs/lib/vision/reference-grid.js +245 -0
- package/dist/cjs/locales/de.json +79 -0
- package/dist/cjs/locales/en.json +2217 -0
- package/dist/cjs/locales/es.json +79 -0
- package/dist/cjs/locales/fr.json +78 -0
- package/dist/cjs/locales/hi.json +1599 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/providers.js +43 -0
- package/dist/cjs/services/GlobalLoadingService.js +220 -0
- package/{src → dist/cjs}/styles/grid-themes.css +345 -345
- package/{src → dist/cjs}/styles/sidebar-scrollbar.css +45 -45
- package/{src → dist/cjs}/styles/tokens.css +712 -711
- package/dist/cjs/types/approval.js +22 -0
- package/dist/cjs/types/audit.js +50 -0
- package/dist/cjs/types/draft.js +22 -0
- package/dist/cjs/types/master.js +4 -0
- package/dist/cjs/types/shipper-planning.js +7 -0
- package/dist/components/auth/ProtectedRoute.d.ts +6 -0
- package/dist/components/auth/ProtectedRoute.js +45 -0
- package/dist/components/auth/UnauthorizedPage.d.ts +6 -0
- package/dist/components/auth/UnauthorizedPage.js +15 -0
- package/dist/components/auth/index.d.ts +2 -0
- package/dist/components/auth/index.js +3 -0
- package/dist/components/chat/ai-messages.d.ts +32 -0
- package/dist/components/chat/ai-messages.js +265 -0
- package/dist/components/chat/chat-prompt-navigator.d.ts +9 -0
- package/dist/components/chat/chat-prompt-navigator.js +107 -0
- package/dist/components/chat/chat.d.ts +46 -0
- package/dist/components/chat/chat.js +1029 -0
- package/dist/components/chat/multimodal-input.d.ts +12 -0
- package/dist/components/chat/multimodal-input.js +114 -0
- package/dist/components/dashboard/DrillDownModal.d.ts +15 -0
- package/dist/components/dashboard/DrillDownModal.js +33 -0
- package/dist/components/dashboard/FilterBar.d.ts +108 -0
- package/dist/components/dashboard/FilterBar.js +428 -0
- package/dist/components/dashboard/Tooltip.d.ts +24 -0
- package/dist/components/dashboard/Tooltip.js +50 -0
- package/dist/components/dashboard/charts/Area.d.ts +28 -0
- package/dist/components/dashboard/charts/Area.js +121 -0
- package/dist/components/dashboard/charts/Bar.d.ts +27 -0
- package/dist/components/dashboard/charts/Bar.js +105 -0
- package/dist/components/dashboard/charts/BoxPlot.d.ts +23 -0
- package/dist/components/dashboard/charts/BoxPlot.js +112 -0
- package/dist/components/dashboard/charts/Bubble.d.ts +36 -0
- package/dist/components/dashboard/charts/Bubble.js +96 -0
- package/dist/components/dashboard/charts/DashboardCard.d.ts +12 -0
- package/dist/components/dashboard/charts/DashboardCard.js +9 -0
- package/dist/components/dashboard/charts/Donut.d.ts +23 -0
- package/dist/components/dashboard/charts/Donut.js +124 -0
- package/dist/components/dashboard/charts/FlowMap.d.ts +38 -0
- package/dist/components/dashboard/charts/FlowMap.js +199 -0
- package/dist/components/dashboard/charts/Funnel.d.ts +30 -0
- package/dist/components/dashboard/charts/Funnel.js +35 -0
- package/dist/components/dashboard/charts/Gantt.d.ts +26 -0
- package/dist/components/dashboard/charts/Gantt.js +265 -0
- package/dist/components/dashboard/charts/Gauge.d.ts +25 -0
- package/dist/components/dashboard/charts/Gauge.js +137 -0
- package/dist/components/dashboard/charts/GeoMap.d.ts +38 -0
- package/dist/components/dashboard/charts/GeoMap.js +125 -0
- package/dist/components/dashboard/charts/Heatmap.d.ts +31 -0
- package/dist/components/dashboard/charts/Heatmap.js +110 -0
- package/dist/components/dashboard/charts/Line.d.ts +33 -0
- package/dist/components/dashboard/charts/Line.js +69 -0
- package/dist/components/dashboard/charts/Pareto.d.ts +21 -0
- package/dist/components/dashboard/charts/Pareto.js +104 -0
- package/dist/components/dashboard/charts/Radar.d.ts +32 -0
- package/dist/components/dashboard/charts/Radar.js +88 -0
- package/dist/components/dashboard/charts/Sankey.d.ts +43 -0
- package/dist/components/dashboard/charts/Sankey.js +86 -0
- package/dist/components/dashboard/charts/Scatter.d.ts +38 -0
- package/dist/components/dashboard/charts/Scatter.js +122 -0
- package/dist/components/dashboard/charts/Sparkline.d.ts +37 -0
- package/dist/components/dashboard/charts/Sparkline.js +128 -0
- package/dist/components/dashboard/charts/Treemap.d.ts +30 -0
- package/dist/components/dashboard/charts/Treemap.js +98 -0
- package/dist/components/dashboard/charts/index.d.ts +38 -0
- package/dist/components/dashboard/charts/index.js +23 -0
- package/dist/components/dashboard/charts/india-map.d.ts +22 -0
- package/dist/components/dashboard/charts/india-map.js +461 -0
- package/dist/components/dashboard/charts/theme.d.ts +107 -0
- package/dist/components/dashboard/charts/theme.js +124 -0
- package/dist/components/dashboard/config.d.ts +96 -0
- package/dist/components/dashboard/config.js +113 -0
- package/dist/components/dashboard/index.d.ts +10 -0
- package/dist/components/dashboard/index.js +13 -0
- package/dist/components/dashboard/kpi/KpiBeforeAfter.d.ts +31 -0
- package/dist/components/dashboard/kpi/KpiBeforeAfter.js +13 -0
- package/dist/components/dashboard/kpi/KpiBreakdown.d.ts +31 -0
- package/dist/components/dashboard/kpi/KpiBreakdown.js +39 -0
- package/dist/components/dashboard/kpi/KpiComparison.d.ts +36 -0
- package/dist/components/dashboard/kpi/KpiComparison.js +38 -0
- package/dist/components/dashboard/kpi/KpiQuickStats.d.ts +30 -0
- package/dist/components/dashboard/kpi/KpiQuickStats.js +38 -0
- package/dist/components/dashboard/kpi/KpiRating.d.ts +46 -0
- package/dist/components/dashboard/kpi/KpiRating.js +35 -0
- package/dist/components/dashboard/kpi/KpiScroll.d.ts +63 -0
- package/dist/components/dashboard/kpi/KpiScroll.js +80 -0
- package/dist/components/dashboard/kpi/KpiTrend.d.ts +28 -0
- package/dist/components/dashboard/kpi/KpiTrend.js +34 -0
- package/dist/components/dashboard/kpi/index.d.ts +16 -0
- package/dist/components/dashboard/kpi/index.js +10 -0
- package/dist/components/dashboard/kpi/kpi-shell.d.ts +44 -0
- package/dist/components/dashboard/kpi/kpi-shell.js +108 -0
- package/dist/components/dashboard/time-range.d.ts +12 -0
- package/dist/components/dashboard/time-range.js +118 -0
- package/dist/components/datagrid/DataGrid.d.ts +126 -0
- package/dist/components/datagrid/DataGrid.js +1577 -0
- package/dist/components/datagrid/cells/BooleanCell.d.ts +15 -0
- package/dist/components/datagrid/cells/BooleanCell.js +39 -0
- package/dist/components/datagrid/cells/CellRenderer.d.ts +25 -0
- package/dist/components/datagrid/cells/CellRenderer.js +139 -0
- package/dist/components/datagrid/cells/EditableCell.d.ts +35 -0
- package/dist/components/datagrid/cells/EditableCell.js +179 -0
- package/dist/components/datagrid/cells/SelectionCell.d.ts +11 -0
- package/dist/components/datagrid/cells/SelectionCell.js +58 -0
- package/dist/components/datagrid/cells/index.d.ts +1 -0
- package/dist/components/datagrid/cells/index.js +2 -0
- package/dist/components/datagrid/columns/ActionsColumn.d.ts +174 -0
- package/dist/components/datagrid/columns/ActionsColumn.js +448 -0
- package/dist/components/datagrid/columns/ColumnContextMenu.d.ts +16 -0
- package/dist/components/datagrid/columns/ColumnContextMenu.js +338 -0
- package/dist/components/datagrid/columns/DraggableColumnHeader.d.ts +19 -0
- package/dist/components/datagrid/columns/DraggableColumnHeader.js +147 -0
- package/dist/components/datagrid/controls/AutoResizeButton.d.ts +8 -0
- package/dist/components/datagrid/controls/AutoResizeButton.js +7 -0
- package/dist/components/datagrid/controls/PaginationControls.d.ts +13 -0
- package/dist/components/datagrid/controls/PaginationControls.js +34 -0
- package/dist/components/datagrid/controls/SummaryControls.d.ts +10 -0
- package/dist/components/datagrid/controls/SummaryControls.js +27 -0
- package/dist/components/datagrid/controls/menu/ActionsMenu.d.ts +31 -0
- package/dist/components/datagrid/controls/menu/ActionsMenu.js +13 -0
- package/dist/components/datagrid/controls/menu/column/ColumnChooserModal.d.ts +13 -0
- package/dist/components/datagrid/controls/menu/column/ColumnChooserModal.js +22 -0
- package/dist/components/datagrid/controls/menu/column/ColumnSection.d.ts +9 -0
- package/dist/components/datagrid/controls/menu/column/ColumnSection.js +7 -0
- package/dist/components/datagrid/controls/menu/export/ExportSection.d.ts +7 -0
- package/dist/components/datagrid/controls/menu/export/ExportSection.js +16 -0
- package/dist/components/datagrid/controls/menu/export/export.d.ts +21 -0
- package/dist/components/datagrid/controls/menu/export/export.js +187 -0
- package/dist/components/datagrid/controls/menu/filter/AdvancedFilterModal.d.ts +29 -0
- package/dist/components/datagrid/controls/menu/filter/AdvancedFilterModal.js +369 -0
- package/dist/components/datagrid/controls/menu/filter/FilterSection.d.ts +12 -0
- package/dist/components/datagrid/controls/menu/filter/FilterSection.js +6 -0
- package/dist/components/datagrid/controls/menu/grouping/GroupingSection.d.ts +10 -0
- package/dist/components/datagrid/controls/menu/grouping/GroupingSection.js +20 -0
- package/dist/components/datagrid/controls/menu/grouping/index.d.ts +1 -0
- package/dist/components/datagrid/controls/menu/grouping/index.js +2 -0
- package/dist/components/datagrid/controls/menu/import/ImportSection.d.ts +6 -0
- package/dist/components/datagrid/controls/menu/import/ImportSection.js +72 -0
- package/dist/components/datagrid/controls/menu/import/import.d.ts +27 -0
- package/dist/components/datagrid/controls/menu/import/import.js +193 -0
- package/dist/components/datagrid/controls/menu/index.d.ts +10 -0
- package/dist/components/datagrid/controls/menu/index.js +11 -0
- package/dist/components/datagrid/controls/menu/view/CardView.d.ts +17 -0
- package/dist/components/datagrid/controls/menu/view/CardView.js +173 -0
- package/dist/components/datagrid/controls/menu/view/ChartView.d.ts +9 -0
- package/dist/components/datagrid/controls/menu/view/ChartView.js +363 -0
- package/dist/components/datagrid/controls/menu/view/ViewSection.d.ts +7 -0
- package/dist/components/datagrid/controls/menu/view/ViewSection.js +9 -0
- package/dist/components/datagrid/hooks/useCellRangeSelection.d.ts +20 -0
- package/dist/components/datagrid/hooks/useCellRangeSelection.js +124 -0
- package/dist/components/datagrid/hooks/useClipboard.d.ts +15 -0
- package/dist/components/datagrid/hooks/useClipboard.js +151 -0
- package/dist/components/datagrid/hooks/useDataGridState.d.ts +46 -0
- package/dist/components/datagrid/hooks/useDataGridState.js +112 -0
- package/dist/components/datagrid/hooks/useKeyboardNavigation.d.ts +18 -0
- package/dist/components/datagrid/hooks/useKeyboardNavigation.js +117 -0
- package/dist/components/datagrid/index.d.ts +34 -0
- package/dist/components/datagrid/index.js +41 -0
- package/dist/components/datagrid/rows/DraggableRow.d.ts +33 -0
- package/dist/components/datagrid/rows/DraggableRow.js +31 -0
- package/dist/components/datagrid/rows/ExpandableRow.d.ts +48 -0
- package/dist/components/datagrid/rows/ExpandableRow.js +178 -0
- package/dist/components/datagrid/rows/FilterRow.d.ts +10 -0
- package/dist/components/datagrid/rows/FilterRow.js +185 -0
- package/dist/components/datagrid/rows/SelectColumn.d.ts +2 -0
- package/dist/components/datagrid/rows/SelectColumn.js +31 -0
- package/dist/components/datagrid/rows/SummaryRow.d.ts +12 -0
- package/dist/components/datagrid/rows/SummaryRow.js +31 -0
- package/dist/components/datagrid/rows/summary.d.ts +9 -0
- package/dist/components/datagrid/rows/summary.js +63 -0
- package/dist/components/datagrid/search/InlineSearchCell.d.ts +13 -0
- package/dist/components/datagrid/search/InlineSearchCell.js +96 -0
- package/dist/components/datagrid/search/SearchHighlighter.d.ts +16 -0
- package/dist/components/datagrid/search/SearchHighlighter.js +124 -0
- package/dist/components/datagrid/search/SearchNavigator.d.ts +24 -0
- package/dist/components/datagrid/search/SearchNavigator.js +148 -0
- package/dist/components/datagrid/search/SearchNewModal.d.ts +12 -0
- package/dist/components/datagrid/search/SearchNewModal.js +202 -0
- package/dist/components/datagrid/search/advancedSearch.d.ts +23 -0
- package/dist/components/datagrid/search/advancedSearch.js +109 -0
- package/dist/components/datagrid/utils/grid-helpers.d.ts +34 -0
- package/dist/components/datagrid/utils/grid-helpers.js +94 -0
- package/dist/components/datagrid/utils/grid-types.d.ts +157 -0
- package/dist/components/datagrid/utils/grid-types.js +2 -0
- package/dist/components/draft/AutoSaveIndicator.d.ts +28 -0
- package/dist/components/draft/AutoSaveIndicator.js +67 -0
- package/dist/components/draft/DraftModal.d.ts +27 -0
- package/dist/components/draft/DraftModal.js +184 -0
- package/dist/components/forms/date-picker/CalendarView.d.ts +17 -0
- package/dist/components/forms/date-picker/CalendarView.js +46 -0
- package/dist/components/forms/date-picker/DatePicker.d.ts +31 -0
- package/dist/components/forms/date-picker/DatePicker.js +712 -0
- package/dist/components/forms/date-picker/DateTimePicker.d.ts +15 -0
- package/dist/components/forms/date-picker/DateTimePicker.js +138 -0
- package/dist/components/forms/date-picker/index.d.ts +7 -0
- package/dist/components/forms/date-picker/index.js +9 -0
- package/dist/components/forms/date-picker/shared-utils.d.ts +6 -0
- package/dist/components/forms/date-picker/shared-utils.js +19 -0
- package/dist/components/forms/dropdown/Dropdown.d.ts +144 -0
- package/dist/components/forms/dropdown/Dropdown.js +384 -0
- package/dist/components/forms/dropdown/MultiSelect.d.ts +29 -0
- package/dist/components/forms/dropdown/MultiSelect.js +100 -0
- package/dist/components/forms/dropdown/SingleSelect.d.ts +39 -0
- package/dist/components/forms/dropdown/SingleSelect.js +218 -0
- package/dist/components/forms/dropdown/hooks/useDropdownCreate.d.ts +8 -0
- package/dist/components/forms/dropdown/hooks/useDropdownCreate.js +52 -0
- package/dist/components/forms/dropdown/hooks/useDropdownFiltering.d.ts +5 -0
- package/dist/components/forms/dropdown/hooks/useDropdownFiltering.js +51 -0
- package/dist/components/forms/dropdown/hooks/useDropdownState.d.ts +7 -0
- package/dist/components/forms/dropdown/hooks/useDropdownState.js +27 -0
- package/dist/components/forms/dropdown/index.d.ts +2 -0
- package/dist/components/forms/dropdown/index.js +2 -0
- package/dist/components/forms/dropdown/types.d.ts +67 -0
- package/dist/components/forms/dropdown/types.js +2 -0
- package/dist/components/forms/file-attachment/EmailPreview.d.ts +5 -0
- package/dist/components/forms/file-attachment/EmailPreview.js +383 -0
- package/dist/components/forms/file-attachment/FileAttachment.d.ts +30 -0
- package/dist/components/forms/file-attachment/FileAttachment.js +930 -0
- package/dist/components/forms/file-attachment/index.d.ts +2 -0
- package/dist/components/forms/file-attachment/index.js +2 -0
- package/dist/components/forms/index.d.ts +9 -0
- package/dist/components/forms/index.js +7 -0
- package/dist/components/forms/quantity-input-popup.d.ts +10 -0
- package/dist/components/forms/quantity-input-popup.js +99 -0
- package/dist/components/forms/remark-input/RemarkInput.d.ts +58 -0
- package/dist/components/forms/remark-input/RemarkInput.js +258 -0
- package/dist/components/forms/remark-input/index.d.ts +1 -0
- package/dist/components/forms/remark-input/index.js +2 -0
- package/dist/components/forms/unified-currency-dropdown.d.ts +26 -0
- package/dist/components/forms/unified-currency-dropdown.js +166 -0
- package/dist/components/index.d.ts +14 -0
- package/dist/components/index.js +15 -0
- package/dist/components/layout/SidebarContextMenu.d.ts +18 -0
- package/dist/components/layout/SidebarContextMenu.js +142 -0
- package/dist/components/layout/app-shell.d.ts +32 -0
- package/dist/components/layout/app-shell.js +43 -0
- package/dist/components/layout/bottom-nav.d.ts +28 -0
- package/dist/components/layout/bottom-nav.js +219 -0
- package/dist/components/layout/floating-action-button.d.ts +10 -0
- package/dist/components/layout/floating-action-button.js +74 -0
- package/dist/components/layout/footer.d.ts +37 -0
- package/dist/components/layout/footer.js +56 -0
- package/dist/components/layout/index.d.ts +8 -0
- package/dist/components/layout/index.js +6 -0
- package/dist/components/layout/mobile-menu-sheet.d.ts +7 -0
- package/dist/components/layout/mobile-menu-sheet.js +159 -0
- package/dist/components/layout/side-panel.d.ts +50 -0
- package/dist/components/layout/side-panel.js +115 -0
- package/dist/components/layout/sidebar.d.ts +12 -0
- package/dist/components/layout/sidebar.js +542 -0
- package/dist/components/layout/top-header.d.ts +8 -0
- package/dist/components/layout/top-header.js +234 -0
- package/dist/components/layout/userprofile-dropdown.d.ts +1 -0
- package/dist/components/layout/userprofile-dropdown.js +97 -0
- package/dist/components/master/editable-cells/EditableCell.d.ts +43 -0
- package/dist/components/master/editable-cells/EditableCell.js +66 -0
- package/dist/components/master/editable-cells/index.d.ts +9 -0
- package/dist/components/master/editable-cells/index.js +10 -0
- package/dist/components/master/index.d.ts +1 -0
- package/dist/components/master/index.js +3 -0
- package/dist/components/messaging/conversation-list.d.ts +13 -0
- package/dist/components/messaging/conversation-list.js +103 -0
- package/dist/components/messaging/create-conversation-modal.d.ts +9 -0
- package/dist/components/messaging/create-conversation-modal.js +109 -0
- package/dist/components/messaging/message-bubble.d.ts +15 -0
- package/dist/components/messaging/message-bubble.js +66 -0
- package/dist/components/messaging/message-input.d.ts +17 -0
- package/dist/components/messaging/message-input.js +151 -0
- package/dist/components/messaging/message-thread.d.ts +10 -0
- package/dist/components/messaging/message-thread.js +121 -0
- package/dist/components/messaging/messaging-panel-content.d.ts +5 -0
- package/dist/components/messaging/messaging-panel-content.js +66 -0
- package/dist/components/messaging/thread-panel.d.ts +10 -0
- package/dist/components/messaging/thread-panel.js +47 -0
- package/dist/components/modals/3DModal.d.ts +39 -0
- package/dist/components/modals/3DModal.js +32 -0
- package/dist/components/modals/ImageModal.d.ts +28 -0
- package/dist/components/modals/ImageModal.js +551 -0
- package/dist/components/modals/Modal.d.ts +92 -0
- package/dist/components/modals/Modal.js +264 -0
- package/dist/components/modals/StandardModal.d.ts +27 -0
- package/dist/components/modals/StandardModal.js +25 -0
- package/dist/components/modals/api-config-modal.d.ts +7 -0
- package/dist/components/modals/api-config-modal.js +117 -0
- package/dist/components/modals/global-api-config-modal.d.ts +7 -0
- package/dist/components/modals/global-api-config-modal.js +124 -0
- package/dist/components/modals/index.d.ts +7 -0
- package/dist/components/modals/index.js +8 -0
- package/dist/components/modals/logout-modal.d.ts +32 -0
- package/dist/components/modals/logout-modal.js +42 -0
- package/dist/components/modals/modal-alert.d.ts +139 -0
- package/dist/components/modals/modal-alert.js +250 -0
- package/dist/components/modals/password-reset-modal.d.ts +11 -0
- package/dist/components/modals/password-reset-modal.js +109 -0
- package/dist/components/modals/session-expiry-warning.d.ts +12 -0
- package/dist/components/modals/session-expiry-warning.js +15 -0
- package/dist/components/providers/api-provider.d.ts +10 -0
- package/dist/components/providers/api-provider.js +15 -0
- package/dist/components/providers/query-provider.d.ts +3 -0
- package/dist/components/providers/query-provider.js +26 -0
- package/dist/components/providers/session-provider.d.ts +7 -0
- package/dist/components/providers/session-provider.js +116 -0
- package/dist/components/theme/ThemeCustomizer.d.ts +37 -0
- package/dist/components/theme/ThemeCustomizer.js +178 -0
- package/dist/components/ui/buttons/button.d.ts +59 -0
- package/dist/components/ui/buttons/button.js +228 -0
- package/dist/components/ui/card.d.ts +8 -0
- package/dist/components/ui/card.js +17 -0
- package/dist/components/ui/chart.d.ts +83 -0
- package/dist/components/ui/chart.js +113 -0
- package/dist/components/ui/display/boolean-badge.d.ts +7 -0
- package/dist/components/ui/display/boolean-badge.js +23 -0
- package/dist/components/ui/display/card.d.ts +10 -0
- package/dist/components/ui/display/card.js +11 -0
- package/dist/components/ui/display/collapsible.d.ts +6 -0
- package/dist/components/ui/display/collapsible.js +6 -0
- package/dist/components/ui/display/separator.d.ts +4 -0
- package/dist/components/ui/display/separator.js +8 -0
- package/dist/components/ui/display/stats-card.d.ts +22 -0
- package/dist/components/ui/display/stats-card.js +25 -0
- package/dist/components/ui/display/text.d.ts +14 -0
- package/dist/components/ui/display/text.js +57 -0
- package/dist/components/ui/feedback/alert.d.ts +8 -0
- package/dist/components/ui/feedback/alert.js +23 -0
- package/dist/components/ui/feedback/badge.d.ts +49 -0
- package/dist/components/ui/feedback/badge.js +87 -0
- package/dist/components/ui/feedback/progress.d.ts +4 -0
- package/dist/components/ui/feedback/progress.js +8 -0
- package/dist/components/ui/feedback/reminder-button.d.ts +22 -0
- package/dist/components/ui/feedback/reminder-button.js +75 -0
- package/dist/components/ui/feedback/skeleton-table.d.ts +18 -0
- package/dist/components/ui/feedback/skeleton-table.js +17 -0
- package/dist/components/ui/feedback/skeleton.d.ts +53 -0
- package/dist/components/ui/feedback/skeleton.js +48 -0
- package/dist/components/ui/feedback/tooltip.d.ts +15 -0
- package/dist/components/ui/feedback/tooltip.js +14 -0
- package/dist/components/ui/form-toggle.d.ts +57 -0
- package/dist/components/ui/form-toggle.js +44 -0
- package/dist/components/ui/forms/checkbox.d.ts +6 -0
- package/dist/components/ui/forms/checkbox.js +17 -0
- package/dist/components/ui/forms/input.d.ts +18 -0
- package/dist/components/ui/forms/input.js +75 -0
- package/dist/components/ui/forms/label.d.ts +5 -0
- package/dist/components/ui/forms/label.js +6 -0
- package/dist/components/ui/forms/switch.d.ts +10 -0
- package/dist/components/ui/forms/switch.js +22 -0
- package/dist/components/ui/forms/textarea.d.ts +8 -0
- package/dist/components/ui/forms/textarea.js +13 -0
- package/dist/components/ui/index.d.ts +49 -0
- package/dist/components/ui/index.js +62 -0
- package/dist/components/ui/navigation/dropdown-menu.d.ts +27 -0
- package/dist/components/ui/navigation/dropdown-menu.js +34 -0
- package/dist/components/ui/navigation/header-steps.d.ts +16 -0
- package/dist/components/ui/navigation/header-steps.js +15 -0
- package/dist/components/ui/navigation/tabs.d.ts +40 -0
- package/dist/components/ui/navigation/tabs.js +59 -0
- package/dist/components/ui/overlays/loading.d.ts +47 -0
- package/dist/components/ui/overlays/loading.js +131 -0
- package/dist/components/ui/select.d.ts +13 -0
- package/dist/components/ui/select.js +27 -0
- package/dist/config/api.d.ts +30 -0
- package/dist/config/api.js +58 -0
- package/dist/contexts/AppConfigContext.d.ts +13 -0
- package/dist/contexts/AppConfigContext.js +33 -0
- package/dist/contexts/CurrencyContext.d.ts +43 -0
- package/dist/contexts/CurrencyContext.js +331 -0
- package/dist/contexts/DeviceContext.d.ts +12 -0
- package/dist/contexts/DeviceContext.js +69 -0
- package/dist/contexts/EmailContext.d.ts +112 -0
- package/dist/contexts/EmailContext.js +720 -0
- package/dist/contexts/GlobalAlertContext.d.ts +67 -0
- package/dist/contexts/GlobalAlertContext.js +192 -0
- package/dist/contexts/ImpactAnalysisContext.d.ts +11 -0
- package/dist/contexts/ImpactAnalysisContext.js +23 -0
- package/dist/contexts/LanguageContext.d.ts +21 -0
- package/dist/contexts/LanguageContext.js +66 -0
- package/dist/contexts/MessagingContext.d.ts +70 -0
- package/dist/contexts/MessagingContext.js +722 -0
- package/dist/contexts/ModuleAuthContext.d.ts +42 -0
- package/dist/contexts/ModuleAuthContext.js +278 -0
- package/dist/contexts/NavigationContext.d.ts +26 -0
- package/dist/contexts/NavigationContext.js +143 -0
- package/dist/contexts/NetworkStatusContext.d.ts +18 -0
- package/dist/contexts/NetworkStatusContext.js +87 -0
- package/dist/contexts/NotificationContext.d.ts +47 -0
- package/dist/contexts/NotificationContext.js +165 -0
- package/dist/contexts/PageTitleContext.d.ts +11 -0
- package/dist/contexts/PageTitleContext.js +23 -0
- package/dist/contexts/SearchPreferencesContext.d.ts +11 -0
- package/dist/contexts/SearchPreferencesContext.js +38 -0
- package/dist/contexts/SessionAdapterContext.d.ts +39 -0
- package/dist/contexts/SessionAdapterContext.js +20 -0
- package/dist/contexts/SidebarPreferencesContext.d.ts +19 -0
- package/dist/contexts/SidebarPreferencesContext.js +112 -0
- package/dist/contexts/ThemeContext.d.ts +63 -0
- package/dist/contexts/ThemeContext.js +153 -0
- package/dist/hooks/index.d.ts +23 -0
- package/dist/hooks/index.js +18 -0
- package/dist/hooks/useApproval.d.ts +47 -0
- package/dist/hooks/useApproval.js +247 -0
- package/dist/hooks/useBacchaSearch.d.ts +57 -0
- package/dist/hooks/useBacchaSearch.js +254 -0
- package/dist/hooks/useBusinessAudit.d.ts +24 -0
- package/dist/hooks/useBusinessAudit.js +51 -0
- package/dist/hooks/useColumnFreezing.d.ts +85 -0
- package/dist/hooks/useColumnFreezing.js +201 -0
- package/dist/hooks/useColumnMetadata.d.ts +20 -0
- package/dist/hooks/useColumnMetadata.js +44 -0
- package/dist/hooks/useConditionalFormatting.d.ts +43 -0
- package/dist/hooks/useConditionalFormatting.js +193 -0
- package/dist/hooks/useDebounce.d.ts +14 -0
- package/dist/hooks/useDebounce.js +45 -0
- package/dist/hooks/useDraft.d.ts +46 -0
- package/dist/hooks/useDraft.js +178 -0
- package/dist/hooks/useFormValidation.d.ts +37 -0
- package/dist/hooks/useFormValidation.js +65 -0
- package/dist/hooks/useGridSettings.d.ts +26 -0
- package/dist/hooks/useGridSettings.js +82 -0
- package/dist/hooks/useGridTheme.d.ts +59 -0
- package/dist/hooks/useGridTheme.js +199 -0
- package/dist/hooks/useId.d.ts +2 -0
- package/dist/hooks/useId.js +17 -0
- package/dist/hooks/useIntelligentColumnSizing.d.ts +71 -0
- package/dist/hooks/useIntelligentColumnSizing.js +310 -0
- package/dist/hooks/useKeyboardNavigation.d.ts +33 -0
- package/dist/hooks/useKeyboardNavigation.js +189 -0
- package/dist/hooks/useNotifications.d.ts +7 -0
- package/dist/hooks/useNotifications.js +56 -0
- package/dist/hooks/usePrevious.d.ts +9 -0
- package/dist/hooks/usePrevious.js +17 -0
- package/dist/hooks/useRowSelection.d.ts +45 -0
- package/dist/hooks/useRowSelection.js +147 -0
- package/dist/hooks/useSignalR.d.ts +13 -0
- package/dist/hooks/useSignalR.js +50 -0
- package/dist/hooks/useTheme.d.ts +59 -0
- package/dist/hooks/useTheme.js +261 -0
- package/dist/hooks/useTranslation.d.ts +5 -0
- package/dist/hooks/useTranslation.js +17 -0
- package/dist/hooks/useUnsavedChanges.d.ts +40 -0
- package/dist/hooks/useUnsavedChanges.js +83 -0
- package/dist/index.d.ts +2 -3173
- package/dist/index.js +4 -25937
- package/dist/lib/api/activity/audit/audit.d.ts +34 -0
- package/dist/lib/api/activity/audit/audit.js +44 -0
- package/dist/lib/api/activity/audit/index.d.ts +6 -0
- package/dist/lib/api/activity/audit/index.js +7 -0
- package/dist/lib/api/activity/audit/send.d.ts +152 -0
- package/dist/lib/api/activity/audit/send.js +403 -0
- package/dist/lib/api/activity/email/client.d.ts +167 -0
- package/dist/lib/api/activity/email/client.js +455 -0
- package/dist/lib/api/activity/email/index.d.ts +7 -0
- package/dist/lib/api/activity/email/index.js +10 -0
- package/dist/lib/api/activity/email/password-reset.d.ts +8 -0
- package/dist/lib/api/activity/email/password-reset.js +55 -0
- package/dist/lib/api/activity/email/templates.d.ts +10 -0
- package/dist/lib/api/activity/email/templates.js +531 -0
- package/dist/lib/api/activity/email/types.d.ts +237 -0
- package/dist/lib/api/activity/email/types.js +21 -0
- package/dist/lib/api/activity/index.d.ts +12 -0
- package/dist/lib/api/activity/index.js +15 -0
- package/dist/lib/api/activity/messaging/messaging.d.ts +149 -0
- package/dist/lib/api/activity/messaging/messaging.js +245 -0
- package/dist/lib/api/activity/notifications/index.d.ts +9 -0
- package/dist/lib/api/activity/notifications/index.js +9 -0
- package/dist/lib/api/activity/notifications/notifications.d.ts +59 -0
- package/dist/lib/api/activity/notifications/notifications.js +218 -0
- package/dist/lib/api/activity/notifications/reminders.d.ts +35 -0
- package/dist/lib/api/activity/notifications/reminders.js +25 -0
- package/dist/lib/api/activity/notifications/send.d.ts +122 -0
- package/dist/lib/api/activity/notifications/send.js +252 -0
- package/dist/lib/api/activity/notifications/types.d.ts +119 -0
- package/dist/lib/api/activity/notifications/types.js +62 -0
- package/dist/lib/api/activity/notify-and-log.d.ts +50 -0
- package/dist/lib/api/activity/notify-and-log.js +60 -0
- package/dist/lib/api/activity/remarks/index.d.ts +2 -0
- package/dist/lib/api/activity/remarks/index.js +2 -0
- package/dist/lib/api/activity/remarks/remarks.d.ts +83 -0
- package/dist/lib/api/activity/remarks/remarks.js +179 -0
- package/dist/lib/api/activity/storage.d.ts +28 -0
- package/dist/lib/api/activity/storage.js +79 -0
- package/dist/lib/api/ai/chat.d.ts +67 -0
- package/dist/lib/api/ai/chat.js +212 -0
- package/dist/lib/api/ai/types.d.ts +69 -0
- package/dist/lib/api/ai/types.js +5 -0
- package/dist/lib/api/approval/approvals.d.ts +66 -0
- package/dist/lib/api/approval/approvals.js +205 -0
- package/dist/lib/api/approval/index.d.ts +5 -0
- package/dist/lib/api/approval/index.js +6 -0
- package/dist/lib/api/auth/auth.d.ts +12 -0
- package/dist/lib/api/auth/auth.js +148 -0
- package/dist/lib/api/auth/index.d.ts +1 -0
- package/dist/lib/api/auth/index.js +4 -0
- package/dist/lib/api/auth/password-reset-otp.d.ts +49 -0
- package/dist/lib/api/auth/password-reset-otp.js +185 -0
- package/dist/lib/api/auth/two-factor-auth.d.ts +55 -0
- package/dist/lib/api/auth/two-factor-auth.js +84 -0
- package/dist/lib/api/auth/two-factor.d.ts +41 -0
- package/dist/lib/api/auth/two-factor.js +180 -0
- package/dist/lib/api/core/auth-helpers.d.ts +13 -0
- package/dist/lib/api/core/auth-helpers.js +137 -0
- package/dist/lib/api/core/client.d.ts +37 -0
- package/dist/lib/api/core/client.js +301 -0
- package/dist/lib/api/core/config.d.ts +46 -0
- package/dist/lib/api/core/config.js +238 -0
- package/dist/lib/api/core/index.d.ts +6 -0
- package/dist/lib/api/core/index.js +11 -0
- package/dist/lib/api/core/session-validator.d.ts +55 -0
- package/dist/lib/api/core/session-validator.js +94 -0
- package/dist/lib/api/core/types.d.ts +192 -0
- package/dist/lib/api/core/types.js +3 -0
- package/dist/lib/api/core/utils.d.ts +15 -0
- package/dist/lib/api/core/utils.js +64 -0
- package/dist/lib/api/dashboard/costing.d.ts +129 -0
- package/dist/lib/api/dashboard/costing.js +8 -0
- package/dist/lib/api/dashboard/management.d.ts +91 -0
- package/dist/lib/api/dashboard/management.js +5 -0
- package/dist/lib/api/dashboard/sales.d.ts +87 -0
- package/dist/lib/api/dashboard/sales.js +5 -0
- package/dist/lib/api/draft/drafts.d.ts +49 -0
- package/dist/lib/api/draft/drafts.js +274 -0
- package/dist/lib/api/draft/index.d.ts +5 -0
- package/dist/lib/api/draft/index.js +6 -0
- package/dist/lib/api/enquiry/enquiry.d.ts +324 -0
- package/dist/lib/api/enquiry/enquiry.js +617 -0
- package/dist/lib/api/enquiry/index.d.ts +2 -0
- package/dist/lib/api/enquiry/index.js +4 -0
- package/dist/lib/api/enquiry/rate-enquiry.d.ts +97 -0
- package/dist/lib/api/enquiry/rate-enquiry.js +69 -0
- package/dist/lib/api/estimation/categories.d.ts +28 -0
- package/dist/lib/api/estimation/categories.js +104 -0
- package/dist/lib/api/estimation/category-defaults.d.ts +56 -0
- package/dist/lib/api/estimation/category-defaults.js +41 -0
- package/dist/lib/api/estimation/company-config.d.ts +59 -0
- package/dist/lib/api/estimation/company-config.js +19 -0
- package/dist/lib/api/estimation/content.d.ts +103 -0
- package/dist/lib/api/estimation/content.js +203 -0
- package/dist/lib/api/estimation/freight.d.ts +34 -0
- package/dist/lib/api/estimation/freight.js +18 -0
- package/dist/lib/api/estimation/grid-costing-drafts.d.ts +38 -0
- package/dist/lib/api/estimation/grid-costing-drafts.js +21 -0
- package/dist/lib/api/estimation/grid-costing.d.ts +353 -0
- package/dist/lib/api/estimation/grid-costing.js +126 -0
- package/dist/lib/api/estimation/index.d.ts +10 -0
- package/dist/lib/api/estimation/index.js +22 -0
- package/dist/lib/api/estimation/legacy-costing.d.ts +42 -0
- package/dist/lib/api/estimation/legacy-costing.js +46 -0
- package/dist/lib/api/estimation/machines.d.ts +32 -0
- package/dist/lib/api/estimation/machines.js +67 -0
- package/dist/lib/api/estimation/planning.d.ts +479 -0
- package/dist/lib/api/estimation/planning.js +385 -0
- package/dist/lib/api/estimation/qualities.d.ts +128 -0
- package/dist/lib/api/estimation/qualities.js +229 -0
- package/dist/lib/api/estimation/quotation-load.d.ts +30 -0
- package/dist/lib/api/estimation/quotation-load.js +46 -0
- package/dist/lib/api/estimation/quotation-save.d.ts +88 -0
- package/dist/lib/api/estimation/quotation-save.js +101 -0
- package/dist/lib/api/estimation/quote-check.d.ts +19 -0
- package/dist/lib/api/estimation/quote-check.js +28 -0
- package/dist/lib/api/estimation/quotepanel.d.ts +304 -0
- package/dist/lib/api/estimation/quotepanel.js +489 -0
- package/dist/lib/api/estimation/shipper-planning.d.ts +71 -0
- package/dist/lib/api/estimation/shipper-planning.js +208 -0
- package/dist/lib/api/estimation/wastage.d.ts +40 -0
- package/dist/lib/api/estimation/wastage.js +40 -0
- package/dist/lib/api/index.d.ts +7 -0
- package/dist/lib/api/index.js +17 -0
- package/dist/lib/api/integration/proxy.d.ts +7 -0
- package/dist/lib/api/integration/proxy.js +34 -0
- package/dist/lib/api/master/category.d.ts +126 -0
- package/dist/lib/api/master/category.js +208 -0
- package/dist/lib/api/master/company.d.ts +167 -0
- package/dist/lib/api/master/company.js +368 -0
- package/dist/lib/api/master/hsn.d.ts +36 -0
- package/dist/lib/api/master/hsn.js +54 -0
- package/dist/lib/api/master/index.d.ts +12 -0
- package/dist/lib/api/master/index.js +27 -0
- package/dist/lib/api/master/item.d.ts +158 -0
- package/dist/lib/api/master/item.js +135 -0
- package/dist/lib/api/master/ledger.d.ts +173 -0
- package/dist/lib/api/master/ledger.js +391 -0
- package/dist/lib/api/master/logistics.d.ts +117 -0
- package/dist/lib/api/master/logistics.js +107 -0
- package/dist/lib/api/master/machine.d.ts +406 -0
- package/dist/lib/api/master/machine.js +570 -0
- package/dist/lib/api/master/material-group.d.ts +97 -0
- package/dist/lib/api/master/material-group.js +96 -0
- package/dist/lib/api/master/other.d.ts +65 -0
- package/dist/lib/api/master/other.js +56 -0
- package/dist/lib/api/master/process-types.d.ts +178 -0
- package/dist/lib/api/master/process-types.js +4 -0
- package/dist/lib/api/master/process.d.ts +94 -0
- package/dist/lib/api/master/process.js +124 -0
- package/dist/lib/api/master/production-units.d.ts +10 -0
- package/dist/lib/api/master/production-units.js +15 -0
- package/dist/lib/api/master/rate.d.ts +174 -0
- package/dist/lib/api/master/rate.js +196 -0
- package/dist/lib/api/master/tool.d.ts +48 -0
- package/dist/lib/api/master/tool.js +80 -0
- package/dist/lib/api/master/user.d.ts +473 -0
- package/dist/lib/api/master/user.js +147 -0
- package/dist/lib/api/settings/erp-parameters.d.ts +33 -0
- package/dist/lib/api/settings/erp-parameters.js +61 -0
- package/dist/lib/api/utility/index.d.ts +1 -0
- package/dist/lib/api/utility/index.js +5 -0
- package/dist/lib/api/utility/menu.d.ts +32 -0
- package/dist/lib/api/utility/menu.js +128 -0
- package/dist/lib/auth.d.ts +3 -0
- package/dist/lib/auth.js +7 -0
- package/dist/lib/pwa.d.ts +8 -0
- package/dist/lib/pwa.js +53 -0
- package/dist/lib/react-query-config.d.ts +140 -0
- package/dist/lib/react-query-config.js +131 -0
- package/dist/lib/security/audit-logger.d.ts +71 -0
- package/dist/lib/security/audit-logger.js +173 -0
- package/dist/lib/security/rate-limiter.d.ts +28 -0
- package/dist/lib/security/rate-limiter.js +118 -0
- package/dist/lib/server-url.d.ts +18 -0
- package/dist/lib/server-url.js +70 -0
- package/dist/lib/svg-utils.d.ts +62 -0
- package/dist/lib/svg-utils.js +206 -0
- package/dist/lib/theme/types.d.ts +109 -0
- package/dist/lib/theme/types.js +231 -0
- package/dist/lib/theme/utils.d.ts +73 -0
- package/dist/lib/theme/utils.js +343 -0
- package/dist/lib/types/index.d.ts +58 -0
- package/dist/lib/types/index.js +2 -0
- package/dist/lib/utils/attachment-loader.d.ts +27 -0
- package/dist/lib/utils/attachment-loader.js +79 -0
- package/dist/lib/utils/client-lead-utils.d.ts +24 -0
- package/dist/lib/utils/client-lead-utils.js +56 -0
- package/dist/lib/utils/device-detection.d.ts +19 -0
- package/dist/lib/utils/device-detection.js +105 -0
- package/dist/lib/utils/logout-cleanup.d.ts +63 -0
- package/dist/lib/utils/logout-cleanup.js +297 -0
- package/dist/lib/utils/planning-prefs.d.ts +10 -0
- package/dist/lib/utils/planning-prefs.js +27 -0
- package/dist/lib/utils.d.ts +20 -0
- package/dist/lib/utils.js +60 -0
- package/dist/lib/vision/dieline-extractor.d.ts +38 -0
- package/dist/lib/vision/dieline-extractor.js +313 -0
- package/dist/lib/vision/reference-grid.d.ts +52 -0
- package/dist/lib/vision/reference-grid.js +241 -0
- package/dist/locales/de.json +79 -0
- package/dist/locales/en.json +2217 -0
- package/dist/locales/es.json +79 -0
- package/dist/locales/fr.json +78 -0
- package/dist/locales/hi.json +1599 -0
- package/dist/providers.d.ts +14 -0
- package/dist/providers.js +15 -0
- package/dist/services/GlobalLoadingService.d.ts +216 -0
- package/dist/services/GlobalLoadingService.js +216 -0
- package/dist/styles/grid-themes.css +346 -0
- package/dist/styles/index.css +5 -0
- package/dist/{sidebar-scrollbar-NBCB2OO2.css → styles/sidebar-scrollbar.css} +45 -45
- package/dist/styles/tokens.css +713 -0
- package/dist/types/approval.d.ts +201 -0
- package/dist/types/approval.js +19 -0
- package/dist/types/audit.d.ts +87 -0
- package/dist/types/audit.js +47 -0
- package/dist/types/draft.d.ts +142 -0
- package/dist/types/draft.js +19 -0
- package/dist/types/master.d.ts +154 -0
- package/dist/types/master.js +3 -0
- package/dist/types/shipper-planning.d.ts +277 -0
- package/dist/types/shipper-planning.js +6 -0
- package/package.json +182 -119
- package/dist/chunk-4PEFU7N7.js +0 -16
- package/dist/chunk-4PEFU7N7.js.map +0 -1
- package/dist/de-EKT7SUK5.js +0 -106
- package/dist/de-EKT7SUK5.js.map +0 -1
- package/dist/en-QRFSIEHD.js +0 -1685
- package/dist/en-QRFSIEHD.js.map +0 -1
- package/dist/es-KHZMWGUI.js +0 -106
- package/dist/es-KHZMWGUI.js.map +0 -1
- package/dist/fr-X2XUXSHK.js +0 -105
- package/dist/fr-X2XUXSHK.js.map +0 -1
- package/dist/hi-YRATOE5Q.js +0 -415
- package/dist/hi-YRATOE5Q.js.map +0 -1
- package/dist/index.cjs +0 -28216
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -3173
- package/dist/index.js.map +0 -1
- /package/{src → dist/cjs}/styles/index.css +0 -0
|
@@ -0,0 +1,1577 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import React, { useState, useMemo, useCallback, useRef, useEffect } from 'react';
|
|
4
|
+
import { usePathname } from 'next/navigation';
|
|
5
|
+
import { motion, AnimatePresence } from 'framer-motion';
|
|
6
|
+
import { getCoreRowModel, getFilteredRowModel, getPaginationRowModel, getSortedRowModel, getExpandedRowModel, getGroupedRowModel, useReactTable, } from '@tanstack/react-table';
|
|
7
|
+
import { useIntelligentColumnSizing, COLUMN_SIZING_PRESETS } from '../../hooks/useIntelligentColumnSizing.js';
|
|
8
|
+
import { useDevice } from '../../contexts/DeviceContext.js';
|
|
9
|
+
import { naturalCompare } from '../../lib/utils.js';
|
|
10
|
+
// Import new pagination and selection components
|
|
11
|
+
import { PaginationControls, DEFAULT_PAGE_SIZE, DEFAULT_PAGE_SIZE_OPTIONS } from './controls/PaginationControls.js';
|
|
12
|
+
import { SelectionCell as SelectionCheckbox } from './cells/SelectionCell.js';
|
|
13
|
+
import { ActionsMenu } from './controls/menu/index.js';
|
|
14
|
+
import { AutoResizeButton } from './controls/AutoResizeButton.js';
|
|
15
|
+
// Virtual scrolling
|
|
16
|
+
import { useVirtualizer } from '@tanstack/react-virtual';
|
|
17
|
+
import { DndContext, closestCenter, KeyboardSensor, PointerSensor, useSensor, useSensors, } from '@dnd-kit/core';
|
|
18
|
+
import { arrayMove, SortableContext, sortableKeyboardCoordinates, verticalListSortingStrategy, horizontalListSortingStrategy, } from '@dnd-kit/sortable';
|
|
19
|
+
import { restrictToHorizontalAxis, restrictToVerticalAxis, } from '@dnd-kit/modifiers';
|
|
20
|
+
import { ListFilter, Mic, MicOff, Grid3X3, BarChart3, LayoutGrid, Pin, PinOff, XCircle, Layers, RefreshCw, } from 'lucide-react';
|
|
21
|
+
import { Button } from '../ui/index.js';
|
|
22
|
+
import { DatePicker } from '../forms/date-picker/DatePicker.js';
|
|
23
|
+
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from '../ui/index.js';
|
|
24
|
+
import { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from '../ui/index.js';
|
|
25
|
+
import { Skeleton } from '../ui/feedback/skeleton.js';
|
|
26
|
+
// Advanced Filter Modal
|
|
27
|
+
import { AdvancedFilterModal } from './controls/menu/filter/AdvancedFilterModal.js';
|
|
28
|
+
// Column Chooser Modal (now integrated into AdvancedFilterModal)
|
|
29
|
+
// Data Visualization Component (Chart View)
|
|
30
|
+
// Chart view pulls in ECharts; load it only when the user switches to the chart view.
|
|
31
|
+
const DataVisualization = React.lazy(() => import('./controls/menu/view/ChartView.js').then((m) => ({ default: m.ChartView })));
|
|
32
|
+
// Export/Import - Now handled via ActionsMenu (ExportSection/ImportSection)
|
|
33
|
+
// Draggable Column Header
|
|
34
|
+
import { DraggableColumnHeader } from './columns/DraggableColumnHeader.js';
|
|
35
|
+
// Draggable Row Component
|
|
36
|
+
import { DraggableRow } from './rows/DraggableRow.js';
|
|
37
|
+
import { CellRenderer } from './cells/CellRenderer.js';
|
|
38
|
+
// Card View Component
|
|
39
|
+
import { CardView } from './controls/menu/view/CardView.js';
|
|
40
|
+
// Column Context Menu Component
|
|
41
|
+
import { ColumnContextMenu } from './columns/ColumnContextMenu.js';
|
|
42
|
+
// Baccha Search Components
|
|
43
|
+
import { InlineSearchCell } from './search/InlineSearchCell.js';
|
|
44
|
+
import { SearchNavigator, useSearchNavigation } from './search/SearchNavigator.js';
|
|
45
|
+
import { SearchHighlighter } from './search/SearchHighlighter.js';
|
|
46
|
+
import { SearchNewModal } from './search/SearchNewModal.js';
|
|
47
|
+
import { useSearchPreferences } from '../../contexts/SearchPreferencesContext.js';
|
|
48
|
+
import { usePageAccess } from '../../contexts/ModuleAuthContext.js';
|
|
49
|
+
import { advancedSearch } from './search/advancedSearch.js';
|
|
50
|
+
// Expandable Row Component
|
|
51
|
+
import { ExpandableRow, ExpansionToggleCell, ExpansionToggleHeader } from './rows/ExpandableRow.js';
|
|
52
|
+
// Summary Row Component
|
|
53
|
+
import { SummaryRow } from './rows/SummaryRow.js';
|
|
54
|
+
// Filter Row Component
|
|
55
|
+
import { FilterRow } from './rows/FilterRow.js';
|
|
56
|
+
const VALUELESS_OPERATORS = new Set([
|
|
57
|
+
'is_empty', 'is_not_empty', 'is_true', 'is_false',
|
|
58
|
+
'last_7_days', 'last_30_days', 'this_month', 'this_year',
|
|
59
|
+
]);
|
|
60
|
+
function conditionHasValue(v) {
|
|
61
|
+
if (v === '' || v === null || v === undefined)
|
|
62
|
+
return false;
|
|
63
|
+
if (Array.isArray(v))
|
|
64
|
+
return v.length > 0;
|
|
65
|
+
if (typeof v === 'object')
|
|
66
|
+
return Object.values(v).some(x => x !== '' && x !== null && x !== undefined);
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Whether a cell value is worth attempting date parsing on.
|
|
71
|
+
*
|
|
72
|
+
* `new Date(297)` is a valid Date (297ms after the epoch), so passing plain numbers
|
|
73
|
+
* to the date matcher made every numeric cell resolve to 01/01/1970 — and since that
|
|
74
|
+
* string contains 0, 1, 7 and 9, filtering a number column by any of those digits
|
|
75
|
+
* matched every row. Only Date objects and date-shaped strings qualify.
|
|
76
|
+
*/
|
|
77
|
+
function looksLikeDate(value) {
|
|
78
|
+
if (value instanceof Date)
|
|
79
|
+
return true;
|
|
80
|
+
if (typeof value !== 'string')
|
|
81
|
+
return false;
|
|
82
|
+
const s = value.trim();
|
|
83
|
+
if (s === '')
|
|
84
|
+
return false;
|
|
85
|
+
// A bare number as a string ("297") is a number, not a date.
|
|
86
|
+
if (/^-?\d+(\.\d+)?$/.test(s))
|
|
87
|
+
return false;
|
|
88
|
+
// Needs a date separator or a month name to be plausibly a date.
|
|
89
|
+
return /[/-]/.test(s) || /\d{1,2}:\d{2}/.test(s) ||
|
|
90
|
+
/\b(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)/i.test(s);
|
|
91
|
+
}
|
|
92
|
+
/** Evaluate one condition against a row's cell value. Mirrors the inline advancedFilterFn operators. */
|
|
93
|
+
function evaluateCondition(cellValue, operator, value) {
|
|
94
|
+
const cellString = String(cellValue ?? '');
|
|
95
|
+
const lc = (s) => String(s ?? '').toLowerCase();
|
|
96
|
+
switch (operator) {
|
|
97
|
+
case 'contains': return lc(cellString).includes(lc(value));
|
|
98
|
+
case 'not_contains': return !lc(cellString).includes(lc(value));
|
|
99
|
+
case 'equals': return cellValue == value;
|
|
100
|
+
case 'not_equals': return cellValue != value;
|
|
101
|
+
case 'starts_with': return lc(cellString).startsWith(lc(value));
|
|
102
|
+
case 'ends_with': return lc(cellString).endsWith(lc(value));
|
|
103
|
+
case 'is_empty': return !cellValue || cellString.trim() === '';
|
|
104
|
+
case 'is_not_empty': return !!cellValue && cellString.trim() !== '';
|
|
105
|
+
case 'greater_than': return Number(cellValue) > Number(value);
|
|
106
|
+
case 'greater_than_equal': return Number(cellValue) >= Number(value);
|
|
107
|
+
case 'less_than': return Number(cellValue) < Number(value);
|
|
108
|
+
case 'less_than_equal': return Number(cellValue) <= Number(value);
|
|
109
|
+
case 'between': return Number(cellValue) >= Number(value?.min ?? value?.[0]) && Number(cellValue) <= Number(value?.max ?? value?.[1]);
|
|
110
|
+
case 'not_between': return Number(cellValue) < Number(value?.min ?? value?.[0]) || Number(cellValue) > Number(value?.max ?? value?.[1]);
|
|
111
|
+
case 'is_true': return cellValue === true || cellValue === 'true' || cellValue === 1;
|
|
112
|
+
case 'is_false': return cellValue === false || cellValue === 'false' || cellValue === 0;
|
|
113
|
+
default: return true;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Evaluate all advanced conditions against a row, honoring per-condition AND/OR connectors.
|
|
118
|
+
* Left-to-right evaluation (AND binds the same as OR — no precedence), which matches how
|
|
119
|
+
* users read a stacked condition list top to bottom.
|
|
120
|
+
*/
|
|
121
|
+
function evaluateConditions(row, conditions) {
|
|
122
|
+
const active = conditions.filter(c => c.column && (VALUELESS_OPERATORS.has(c.operator) || conditionHasValue(c.value)));
|
|
123
|
+
if (active.length === 0)
|
|
124
|
+
return true;
|
|
125
|
+
let result = evaluateCondition(row[active[0].column], active[0].operator, active[0].value);
|
|
126
|
+
for (let i = 1; i < active.length; i++) {
|
|
127
|
+
const c = active[i];
|
|
128
|
+
const matches = evaluateCondition(row[c.column], c.operator, c.value);
|
|
129
|
+
result = c.connector === 'OR' ? (result || matches) : (result && matches);
|
|
130
|
+
}
|
|
131
|
+
return result;
|
|
132
|
+
}
|
|
133
|
+
export function DataGrid({ data, columns: initialColumns, onRowClick, onRowContextMenu, onRowSelect, onImport, selectedRowIds = [], getRowId, getRowProps, enableViewToggle = false, viewMode = 'all', onViewModeChange, enableVirtualization = true, enableColumnResizing = true, enableColumnReordering = true, enableColumnFreezing = false, frozenColumns = [], rightFrozenColumns = [], enableGrouping = false, groupByColumns = [], onGroupingChange, enableExport = true, enableImport = true, enableVisualization = true, enableStickyActions = false, enableRowSelection = true, enableSorting = true, defaultSortBy, defaultSortOrder = 'asc', initialColumnVisibility, persistKey, enableSearch = true, enableFiltering = true, enableColumnVisibility = true, pageSize = 50, stickyHeader = true, className = '', title, description, headerActions, headerActionsRight, toolbarActions, onRefresh, isRefreshing: isRefreshingProp, preToggleActions, loading = false, hideHeader = false, compactHeader = true, columnResizeMode = 'onChange', style, compactMode = false, minHeight = 60, maxHeight = "calc(100vh - 300px)", // Default: standard mode, responsive to screen height
|
|
134
|
+
rowHeight = 24.75,
|
|
135
|
+
// Baccha Search props
|
|
136
|
+
mainColumns, enableBacchaSearch = true, searchType,
|
|
137
|
+
// NEW: Pagination props
|
|
138
|
+
enablePagination = true, paginationPageSize = DEFAULT_PAGE_SIZE, paginationPageSizeOptions = DEFAULT_PAGE_SIZE_OPTIONS,
|
|
139
|
+
// NEW: Circular checkboxes
|
|
140
|
+
circularCheckboxes = false,
|
|
141
|
+
// NEW: Auto-resize
|
|
142
|
+
enableAutoResize = true,
|
|
143
|
+
// NEW: Row selection modes
|
|
144
|
+
rowSelectionMode = 'multi', enableRowClickSelection = true, enableCtrlClickMultiSelect = true, enableShiftClickRange = true, singleSelectionStyle = 'radio',
|
|
145
|
+
// NEW: Row reordering
|
|
146
|
+
enableRowReordering = false, onRowOrderChange, hideSelectionInSelectedView = true,
|
|
147
|
+
// NEW: Row Expansion
|
|
148
|
+
renderSubComponent, getRowCanExpand, expandMode = 'basic', getSubData, getSubRowId, onSubRowClick, onSubRowSelect, defaultExpandAll = false,
|
|
149
|
+
// NEW: Date Filter
|
|
150
|
+
enableDateFilter = false, preDateActions,
|
|
151
|
+
// NEW: Summary/Footer row
|
|
152
|
+
enableSummary = false, summaryConfig, dateFrom, dateTo, onDateFromChange, onDateToChange,
|
|
153
|
+
// NEW: Filter Row
|
|
154
|
+
enableFilterRow = false, initialColumnFilters, }) {
|
|
155
|
+
// Persisted view prefs (show/hide, order, width, sort). Falls back to an auto key
|
|
156
|
+
// (route + column-id fingerprint) so every grid persists without an explicit persistKey.
|
|
157
|
+
const pathname = usePathname();
|
|
158
|
+
const autoPersistKey = useMemo(() => {
|
|
159
|
+
const ids = initialColumns
|
|
160
|
+
.map((c, i) => c.id || c.accessorKey || `col-${i}`)
|
|
161
|
+
.join('|');
|
|
162
|
+
// Cheap stable hash of the column-id list (djb2).
|
|
163
|
+
let hash = 5381;
|
|
164
|
+
for (let i = 0; i < ids.length; i++)
|
|
165
|
+
hash = ((hash << 5) + hash + ids.charCodeAt(i)) | 0;
|
|
166
|
+
return `${pathname || 'route'}:${(hash >>> 0).toString(36)}`;
|
|
167
|
+
}, [initialColumns, pathname]);
|
|
168
|
+
const persistStorageKey = `datagrid-view:${persistKey || autoPersistKey}`;
|
|
169
|
+
const savedView = useMemo(() => {
|
|
170
|
+
if (!persistStorageKey || typeof window === 'undefined')
|
|
171
|
+
return null;
|
|
172
|
+
try {
|
|
173
|
+
const raw = window.localStorage.getItem(persistStorageKey);
|
|
174
|
+
return raw ? JSON.parse(raw) : null;
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
}, [persistStorageKey]);
|
|
180
|
+
// Device detection for mobile-specific column behaviour
|
|
181
|
+
const { isMobile } = useDevice();
|
|
182
|
+
// Get user search preferences
|
|
183
|
+
const { defaultSearchType } = useSearchPreferences();
|
|
184
|
+
// Page-level permissions — used to gate export when enableExport is not explicitly set to false
|
|
185
|
+
const pageAccess = usePageAccess();
|
|
186
|
+
// Determine which search type to use: explicit prop > user preference > 'advanced' fallback
|
|
187
|
+
const effectiveSearchType = searchType || defaultSearchType || 'advanced';
|
|
188
|
+
// Normalize columns: ensure all columns have explicit IDs for consistent drag/drop behavior
|
|
189
|
+
// This fixes the issue where some columns have only accessorKey (auto-generated ID)
|
|
190
|
+
// and others have explicit ID, causing drag/drop to fail inconsistently
|
|
191
|
+
const normalizedColumns = useMemo(() => {
|
|
192
|
+
return initialColumns.map((col, index) => {
|
|
193
|
+
// If column already has an id, use it
|
|
194
|
+
let normalized = col;
|
|
195
|
+
if (!col.id) {
|
|
196
|
+
if (col.accessorKey) {
|
|
197
|
+
normalized = { ...col, id: col.accessorKey };
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
const header = typeof col.header === 'string' ? col.header : `column`;
|
|
201
|
+
normalized = { ...col, id: `${header.toLowerCase().replace(/\s+/g, '-')}-${index}` };
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
// On mobile, shrink the actions column to just fit the dropdown trigger
|
|
205
|
+
if (isMobile && (normalized.id === 'actions' || normalized.accessorKey === 'actions')) {
|
|
206
|
+
normalized = { ...normalized, size: 30, minSize: 30, maxSize: 30 };
|
|
207
|
+
}
|
|
208
|
+
// Auto-apply date sorting for columns with "Date" in accessor key;
|
|
209
|
+
// otherwise default to numeric-aware natural sort so "10" sorts after "9".
|
|
210
|
+
const accessorKey = normalized.accessorKey;
|
|
211
|
+
if (!normalized.sortingFn) {
|
|
212
|
+
if (accessorKey && /date/i.test(accessorKey)) {
|
|
213
|
+
normalized = { ...normalized, sortingFn: 'dateSort' };
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
normalized = { ...normalized, sortingFn: 'naturalSort' };
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return normalized;
|
|
220
|
+
});
|
|
221
|
+
}, [initialColumns, isMobile]);
|
|
222
|
+
// Create initial row selection state from selectedRowIds
|
|
223
|
+
const initialRowSelection = useMemo(() => {
|
|
224
|
+
const selection = {};
|
|
225
|
+
data.forEach((row, index) => {
|
|
226
|
+
// Use getRowId if provided, otherwise fall back to .id or index
|
|
227
|
+
const rowId = getRowId ? getRowId(row) : (row.id || index.toString());
|
|
228
|
+
if (selectedRowIds.includes(rowId)) {
|
|
229
|
+
// ✅ FIX: Use rowId as key (not index) when getRowId is provided
|
|
230
|
+
// TanStack Table expects ID-based selection when getRowId is configured
|
|
231
|
+
selection[rowId] = true;
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
return selection;
|
|
235
|
+
}, [selectedRowIds, data, getRowId]);
|
|
236
|
+
// Row reordering state - must be declared before filteredData
|
|
237
|
+
const [reorderedData, setReorderedData] = useState(null);
|
|
238
|
+
// Sync reorderedData with external data prop changes (e.g. cell edits update parent data)
|
|
239
|
+
// Preserves custom row order while reflecting updated values
|
|
240
|
+
useEffect(() => {
|
|
241
|
+
if (!reorderedData || !enableRowReordering)
|
|
242
|
+
return;
|
|
243
|
+
// Build a map of updated data by ID for O(n) lookup
|
|
244
|
+
const dataMap = new Map();
|
|
245
|
+
data.forEach(item => {
|
|
246
|
+
const id = getRowId ? getRowId(item) : item.id || '';
|
|
247
|
+
dataMap.set(String(id), item);
|
|
248
|
+
});
|
|
249
|
+
// Update reorderedData values while preserving order
|
|
250
|
+
// Also handle additions/removals
|
|
251
|
+
const synced = [];
|
|
252
|
+
const seenIds = new Set();
|
|
253
|
+
for (const item of reorderedData) {
|
|
254
|
+
const id = String(getRowId ? getRowId(item) : item.id || '');
|
|
255
|
+
const updated = dataMap.get(id);
|
|
256
|
+
if (updated) {
|
|
257
|
+
synced.push(updated);
|
|
258
|
+
seenIds.add(id);
|
|
259
|
+
}
|
|
260
|
+
// If item was removed from data, skip it
|
|
261
|
+
}
|
|
262
|
+
// Add any new items from data that weren't in reorderedData
|
|
263
|
+
for (const item of data) {
|
|
264
|
+
const id = String(getRowId ? getRowId(item) : item.id || '');
|
|
265
|
+
if (!seenIds.has(id)) {
|
|
266
|
+
synced.push(item);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
// Only update if there's an actual difference to avoid infinite loops
|
|
270
|
+
const hasChanges = synced.length !== reorderedData.length ||
|
|
271
|
+
synced.some((item, i) => item !== reorderedData[i]);
|
|
272
|
+
if (hasChanges) {
|
|
273
|
+
setReorderedData(synced);
|
|
274
|
+
}
|
|
275
|
+
}, [data, enableRowReordering]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
276
|
+
// Row Expansion state — defaultExpandAll expands every row on mount
|
|
277
|
+
const [expanded, setExpanded] = useState(defaultExpandAll ? true : {});
|
|
278
|
+
// Advanced filter conditions (from the Filters modal). Evaluated together with per-condition
|
|
279
|
+
// AND/OR connectors in `filteredData` — kept separate from column/search filters so OR works.
|
|
280
|
+
const [advancedConditions, setAdvancedConditions] = useState([]);
|
|
281
|
+
// Filter data based on view mode if view toggle is enabled
|
|
282
|
+
const filteredData = useMemo(() => {
|
|
283
|
+
// Use reordered data if available and reordering is enabled (in selected view OR when viewToggle is disabled)
|
|
284
|
+
const useReorderedData = enableRowReordering && (viewMode === 'selected' || !enableViewToggle) && reorderedData;
|
|
285
|
+
const baseData = useReorderedData ? reorderedData : data;
|
|
286
|
+
// Advanced filter pass: evaluate all conditions with their AND/OR connectors.
|
|
287
|
+
// Applied before view-toggle so it composes with both 'all' and 'selected' views.
|
|
288
|
+
const applyAdvanced = (rows) => advancedConditions.length > 0 ? rows.filter(r => evaluateConditions(r, advancedConditions)) : rows;
|
|
289
|
+
if (!enableViewToggle || viewMode === 'all') {
|
|
290
|
+
return applyAdvanced(baseData);
|
|
291
|
+
}
|
|
292
|
+
// If in 'selected' mode, filter to only show selected rows
|
|
293
|
+
if (selectedRowIds.length === 0) {
|
|
294
|
+
return []; // Show empty grid when no selections in 'selected' mode
|
|
295
|
+
}
|
|
296
|
+
// Filter for selected view
|
|
297
|
+
const selectedIdsSet = new Set(selectedRowIds);
|
|
298
|
+
const filtered = baseData.filter(item => {
|
|
299
|
+
const itemId = getRowId ? getRowId(item) : item.id || baseData.indexOf(item).toString();
|
|
300
|
+
return selectedIdsSet.has(itemId);
|
|
301
|
+
});
|
|
302
|
+
return applyAdvanced(filtered);
|
|
303
|
+
}, [enableViewToggle, viewMode, data, selectedRowIds, getRowId, enableRowReordering, reorderedData, advancedConditions]);
|
|
304
|
+
// Intelligent column sizing based on cell content only
|
|
305
|
+
const { enhancedColumns: intelligentColumns, autoResizeAllColumns } = useIntelligentColumnSizing(filteredData, normalizedColumns, COLUMN_SIZING_PRESETS.standard);
|
|
306
|
+
// State management
|
|
307
|
+
const [sorting, setSorting] = useState(() => {
|
|
308
|
+
if (savedView?.sorting) {
|
|
309
|
+
return savedView.sorting;
|
|
310
|
+
}
|
|
311
|
+
// Initialize with default sort if provided
|
|
312
|
+
if (defaultSortBy) {
|
|
313
|
+
return [{ id: defaultSortBy, desc: defaultSortOrder === 'desc' }];
|
|
314
|
+
}
|
|
315
|
+
return [];
|
|
316
|
+
});
|
|
317
|
+
const [columnFilters, setColumnFilters] = useState(initialColumnFilters || []);
|
|
318
|
+
// Re-seed column filters when the caller passes a new initialColumnFilters reference
|
|
319
|
+
// (e.g. modal reopening for a different row). Identity-based check: skip when undefined.
|
|
320
|
+
useEffect(() => {
|
|
321
|
+
if (initialColumnFilters) {
|
|
322
|
+
setColumnFilters(initialColumnFilters);
|
|
323
|
+
}
|
|
324
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
325
|
+
}, [initialColumnFilters]);
|
|
326
|
+
const [columnVisibility, setColumnVisibility] = useState(savedView?.columnVisibility || initialColumnVisibility || {});
|
|
327
|
+
const [rowSelection, setRowSelection] = useState(initialRowSelection);
|
|
328
|
+
const [globalFilter, setGlobalFilter] = useState('');
|
|
329
|
+
const [frozenColumnsState, setFrozenColumnsState] = useState(new Set(frozenColumns));
|
|
330
|
+
// Grouping state
|
|
331
|
+
const [grouping, setGrouping] = useState(groupByColumns || []);
|
|
332
|
+
// Column Pinning State
|
|
333
|
+
const [columnPinning, setColumnPinning] = useState({
|
|
334
|
+
left: frozenColumns || [],
|
|
335
|
+
right: [...(rightFrozenColumns || []), 'actions'] // Right-frozen + auto-pin actions
|
|
336
|
+
});
|
|
337
|
+
// NEW: Pagination state
|
|
338
|
+
const [pagination, setPagination] = useState({
|
|
339
|
+
pageIndex: 0,
|
|
340
|
+
pageSize: enablePagination ? paginationPageSize : filteredData.length,
|
|
341
|
+
});
|
|
342
|
+
// Sync frozen columns state with prop changes (but allow user overrides)
|
|
343
|
+
useEffect(() => {
|
|
344
|
+
if (frozenColumns && frozenColumns.length > 0) {
|
|
345
|
+
setFrozenColumnsState(prev => {
|
|
346
|
+
const newSet = new Set(prev);
|
|
347
|
+
frozenColumns.forEach(colId => newSet.add(colId));
|
|
348
|
+
return newSet;
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
}, [frozenColumns]);
|
|
352
|
+
// Sync right frozen columns with pinning state
|
|
353
|
+
useEffect(() => {
|
|
354
|
+
if (rightFrozenColumns && rightFrozenColumns.length > 0) {
|
|
355
|
+
setColumnPinning(prev => ({
|
|
356
|
+
...prev,
|
|
357
|
+
right: [...new Set([...(rightFrozenColumns || []), 'actions'])]
|
|
358
|
+
}));
|
|
359
|
+
}
|
|
360
|
+
}, [rightFrozenColumns]);
|
|
361
|
+
// Baccha Search state
|
|
362
|
+
const [columnSearches, setColumnSearches] = useState({});
|
|
363
|
+
const [isColumnSearchActive, setIsColumnSearchActive] = useState({});
|
|
364
|
+
// Voice search
|
|
365
|
+
const [isListening, setIsListening] = useState(false);
|
|
366
|
+
const [speechSupported, setSpeechSupported] = useState(false);
|
|
367
|
+
const recognitionRef = useRef(null);
|
|
368
|
+
const searchHandlerRef = useRef(null);
|
|
369
|
+
useEffect(() => {
|
|
370
|
+
setSpeechSupported(typeof window !== 'undefined' &&
|
|
371
|
+
!!(window.SpeechRecognition || window.webkitSpeechRecognition));
|
|
372
|
+
}, []);
|
|
373
|
+
const handleVoiceSearch = useCallback(() => {
|
|
374
|
+
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
|
|
375
|
+
if (!SpeechRecognition)
|
|
376
|
+
return;
|
|
377
|
+
if (isListening) {
|
|
378
|
+
recognitionRef.current?.stop();
|
|
379
|
+
setIsListening(false);
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
const recognition = new SpeechRecognition();
|
|
383
|
+
recognition.continuous = false;
|
|
384
|
+
recognition.interimResults = false;
|
|
385
|
+
recognition.lang = 'en-IN';
|
|
386
|
+
recognition.onresult = (event) => {
|
|
387
|
+
const transcript = event.results[0]?.[0]?.transcript;
|
|
388
|
+
if (transcript)
|
|
389
|
+
searchHandlerRef.current?.(transcript.trim());
|
|
390
|
+
setIsListening(false);
|
|
391
|
+
recognitionRef.current = null;
|
|
392
|
+
};
|
|
393
|
+
recognition.onerror = () => { setIsListening(false); recognitionRef.current = null; };
|
|
394
|
+
recognition.onend = () => { setIsListening(false); recognitionRef.current = null; };
|
|
395
|
+
recognitionRef.current = recognition;
|
|
396
|
+
recognition.start();
|
|
397
|
+
setIsListening(true);
|
|
398
|
+
}, [isListening]);
|
|
399
|
+
// Search navigation
|
|
400
|
+
const searchInputRef = useRef(null);
|
|
401
|
+
const { navigationState, updateSearchResults, navigate: navigateSearch, selectRow: selectSearchRow, clearNavigation } = useSearchNavigation();
|
|
402
|
+
// Parse main columns from comma-separated string
|
|
403
|
+
const mainColumnsArray = useMemo(() => {
|
|
404
|
+
if (!mainColumns)
|
|
405
|
+
return [];
|
|
406
|
+
return mainColumns.split(',').map(col => col.trim()).filter(Boolean);
|
|
407
|
+
}, [mainColumns]);
|
|
408
|
+
// ✅ DISABLED: This was causing selection to reset on every change
|
|
409
|
+
// Let the DataGrid manage its own selection state internally
|
|
410
|
+
// Parent component gets notified via onRowSelect callback
|
|
411
|
+
/*
|
|
412
|
+
React.useEffect(() => {
|
|
413
|
+
if (!selectedRowIds || selectedRowIds.length === 0) return
|
|
414
|
+
|
|
415
|
+
const newSelection: Record<string, boolean> = {}
|
|
416
|
+
data.forEach((row, index) => {
|
|
417
|
+
const rowId = (row as any).id || index.toString()
|
|
418
|
+
if (selectedRowIds.includes(rowId)) {
|
|
419
|
+
newSelection[index.toString()] = true
|
|
420
|
+
}
|
|
421
|
+
})
|
|
422
|
+
|
|
423
|
+
const newKeys = Object.keys(newSelection).sort().join(',')
|
|
424
|
+
const currentKeys = Object.keys(rowSelection).filter(k => rowSelection[k]).sort().join(',')
|
|
425
|
+
|
|
426
|
+
if (newKeys !== currentKeys) {
|
|
427
|
+
setRowSelection(newSelection)
|
|
428
|
+
}
|
|
429
|
+
}, [selectedRowIds])
|
|
430
|
+
*/
|
|
431
|
+
// Ensure toggle visibility is always stable
|
|
432
|
+
const toggleShouldBeVisible = useMemo(() => {
|
|
433
|
+
return Boolean(enableViewToggle && enableRowSelection);
|
|
434
|
+
}, [enableViewToggle, enableRowSelection]);
|
|
435
|
+
// Safe selectedRowIds count to prevent undefined errors
|
|
436
|
+
const safeSelectedCount = useMemo(() => {
|
|
437
|
+
const count = Array.isArray(selectedRowIds) ? selectedRowIds.length : 0;
|
|
438
|
+
// console.log('🔢 [DataGrid] safeSelectedCount recalculated:', {
|
|
439
|
+
// count,
|
|
440
|
+
// selectedRowIds,
|
|
441
|
+
// isArray: Array.isArray(selectedRowIds)
|
|
442
|
+
// })
|
|
443
|
+
return count;
|
|
444
|
+
}, [selectedRowIds]);
|
|
445
|
+
// Note: full selectedRowIds sync is disabled to allow internal selection state
|
|
446
|
+
// management. Removal-only sync below: when the external selectedRowIds shrink
|
|
447
|
+
// (parent removed rows), delete ONLY those keys — never rebuild or blanket-clear.
|
|
448
|
+
const prevSelectedRowIdsRef = React.useRef(selectedRowIds);
|
|
449
|
+
React.useEffect(() => {
|
|
450
|
+
if (!enableRowSelection) {
|
|
451
|
+
prevSelectedRowIdsRef.current = selectedRowIds;
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
const prev = prevSelectedRowIdsRef.current;
|
|
455
|
+
prevSelectedRowIdsRef.current = selectedRowIds;
|
|
456
|
+
const removed = prev.filter(id => !selectedRowIds.includes(id));
|
|
457
|
+
if (removed.length === 0)
|
|
458
|
+
return;
|
|
459
|
+
setRowSelection(current => {
|
|
460
|
+
const next = { ...current };
|
|
461
|
+
let changed = false;
|
|
462
|
+
for (const id of removed) {
|
|
463
|
+
if (next[id]) {
|
|
464
|
+
delete next[id];
|
|
465
|
+
changed = true;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
return changed ? next : current;
|
|
469
|
+
});
|
|
470
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
471
|
+
}, [selectedRowIds]);
|
|
472
|
+
// Preserve row selection state during view mode transitions
|
|
473
|
+
const stableRowSelection = useMemo(() => {
|
|
474
|
+
if (!enableViewToggle)
|
|
475
|
+
return rowSelection;
|
|
476
|
+
// In 'selected' mode, ensure selection state remains consistent.
|
|
477
|
+
// MUST be keyed by rowId (the table registers rows via getRowId) — keying by
|
|
478
|
+
// index made getSelectedRowModel() return [] and any internal state change
|
|
479
|
+
// fired onRowSelect([]), wiping the parent's selection.
|
|
480
|
+
if (viewMode === 'selected' && selectedRowIds.length > 0) {
|
|
481
|
+
const preservedSelection = {};
|
|
482
|
+
filteredData.forEach((item) => {
|
|
483
|
+
const itemId = getRowId ? getRowId(item) : (item.id || data.indexOf(item).toString());
|
|
484
|
+
if (selectedRowIds.includes(itemId)) {
|
|
485
|
+
preservedSelection[itemId] = true;
|
|
486
|
+
}
|
|
487
|
+
});
|
|
488
|
+
return preservedSelection;
|
|
489
|
+
}
|
|
490
|
+
return rowSelection;
|
|
491
|
+
}, [enableViewToggle, viewMode, selectedRowIds, filteredData, rowSelection, getRowId, data]);
|
|
492
|
+
// Helper function to format dates as "12 Oct, 2025"
|
|
493
|
+
const formatDateCell = (dateString) => {
|
|
494
|
+
if (!dateString)
|
|
495
|
+
return '-';
|
|
496
|
+
try {
|
|
497
|
+
const date = new Date(dateString);
|
|
498
|
+
if (isNaN(date.getTime()))
|
|
499
|
+
return dateString;
|
|
500
|
+
const day = date.getDate();
|
|
501
|
+
const month = date.toLocaleDateString('en-US', { month: 'short' });
|
|
502
|
+
const year = date.getFullYear();
|
|
503
|
+
return `${day} ${month}, ${year}`;
|
|
504
|
+
}
|
|
505
|
+
catch {
|
|
506
|
+
return dateString;
|
|
507
|
+
}
|
|
508
|
+
};
|
|
509
|
+
// Create columns with selection column if needed
|
|
510
|
+
const enhancedColumns = useMemo(() => {
|
|
511
|
+
let baseColumns = intelligentColumns || normalizedColumns;
|
|
512
|
+
// Auto-format date columns (columns ending with "Date")
|
|
513
|
+
baseColumns = baseColumns.map((col) => {
|
|
514
|
+
const accessorKey = col.accessorKey;
|
|
515
|
+
const header = col.header;
|
|
516
|
+
// Check if column name ends with "Date" or header contains "Date"
|
|
517
|
+
const isDateColumn = (accessorKey && (accessorKey.endsWith('Date') || accessorKey.toLowerCase().includes('date'))) ||
|
|
518
|
+
(typeof header === 'string' && header.toLowerCase().includes('date'));
|
|
519
|
+
// If it's a date column and doesn't have a custom cell renderer, add date formatting
|
|
520
|
+
if (isDateColumn && !col.cell) {
|
|
521
|
+
return {
|
|
522
|
+
...col,
|
|
523
|
+
cell: ({ row }) => {
|
|
524
|
+
const value = row.getValue(accessorKey);
|
|
525
|
+
const formattedValue = formatDateCell(value);
|
|
526
|
+
// Center the dash if it's an empty value
|
|
527
|
+
return (_jsx("span", { className: formattedValue === '-' ? 'flex justify-center w-full' : '', children: formattedValue }));
|
|
528
|
+
}
|
|
529
|
+
};
|
|
530
|
+
}
|
|
531
|
+
return col;
|
|
532
|
+
});
|
|
533
|
+
// Hide selection column in Selected view if hideSelectionInSelectedView is true
|
|
534
|
+
const shouldHideSelection = hideSelectionInSelectedView && viewMode === 'selected';
|
|
535
|
+
if (!enableRowSelection || shouldHideSelection)
|
|
536
|
+
return baseColumns;
|
|
537
|
+
// Check if there's already a selection column
|
|
538
|
+
const hasSelectionColumn = baseColumns.some(col => col.id === 'select' ||
|
|
539
|
+
col.accessorKey === 'select' ||
|
|
540
|
+
(col.meta && col.meta.isSelectColumn));
|
|
541
|
+
if (hasSelectionColumn) {
|
|
542
|
+
return baseColumns;
|
|
543
|
+
}
|
|
544
|
+
const selectionColumn = {
|
|
545
|
+
id: 'select',
|
|
546
|
+
header: ({ table }) => (_jsx("div", { className: "w-full h-full flex items-center justify-center", children: rowSelectionMode === 'multi' ? (_jsx(SelectionCheckbox, { checked: table.getIsAllRowsSelected(), indeterminate: table.getIsSomeRowsSelected(), onChange: (checked) => {
|
|
547
|
+
table.toggleAllRowsSelected(checked);
|
|
548
|
+
}, circular: circularCheckboxes, mode: "checkbox" })) : (_jsx("div", { className: "w-5 h-5" }) /* Empty space in single mode */) })),
|
|
549
|
+
cell: ({ row }) => (_jsx("div", { className: "w-full h-full flex items-center justify-center", children: _jsx(SelectionCheckbox, { checked: row.getIsSelected(), onChange: (checked) => {
|
|
550
|
+
row.toggleSelected(checked);
|
|
551
|
+
}, circular: circularCheckboxes, mode: rowSelectionMode === 'single' ? 'radio' : 'checkbox' }) })),
|
|
552
|
+
enableSorting: false,
|
|
553
|
+
enableHiding: false,
|
|
554
|
+
size: 30, // 1.875rem (30px ÷ 16)
|
|
555
|
+
minSize: 30,
|
|
556
|
+
maxSize: 30,
|
|
557
|
+
};
|
|
558
|
+
const result = [selectionColumn, ...baseColumns];
|
|
559
|
+
return result;
|
|
560
|
+
}, [intelligentColumns, normalizedColumns, enableRowSelection, hideSelectionInSelectedView, viewMode, rowSelectionMode, circularCheckboxes]);
|
|
561
|
+
// Auto-prepend expand column when getRowCanExpand is provided
|
|
562
|
+
const columnsWithExpand = useMemo(() => {
|
|
563
|
+
if (!getRowCanExpand)
|
|
564
|
+
return enhancedColumns;
|
|
565
|
+
// Check if there's already an expand column
|
|
566
|
+
const hasExpandColumn = enhancedColumns.some(col => col.id === 'expand');
|
|
567
|
+
if (hasExpandColumn)
|
|
568
|
+
return enhancedColumns;
|
|
569
|
+
const expandColumn = {
|
|
570
|
+
id: 'expand',
|
|
571
|
+
header: ({ table }) => (_jsx("div", { className: "w-full h-full flex items-center justify-center", children: _jsx(ExpansionToggleHeader, { table: table }) })),
|
|
572
|
+
cell: ({ row }) => _jsx(ExpansionToggleCell, { row: row }),
|
|
573
|
+
enableSorting: false,
|
|
574
|
+
enableHiding: false,
|
|
575
|
+
enableColumnFilter: false,
|
|
576
|
+
size: 36,
|
|
577
|
+
minSize: 36,
|
|
578
|
+
maxSize: 36,
|
|
579
|
+
};
|
|
580
|
+
// Insert after select column if it exists, otherwise prepend
|
|
581
|
+
const selectIndex = enhancedColumns.findIndex(col => col.id === 'select');
|
|
582
|
+
if (selectIndex >= 0) {
|
|
583
|
+
const result = [...enhancedColumns];
|
|
584
|
+
result.splice(selectIndex + 1, 0, expandColumn);
|
|
585
|
+
return result;
|
|
586
|
+
}
|
|
587
|
+
return [expandColumn, ...enhancedColumns];
|
|
588
|
+
}, [enhancedColumns, getRowCanExpand]);
|
|
589
|
+
// For column reordering, we need mutable state - but keep it simple.
|
|
590
|
+
// Lazily seed from a persisted column order (by id) when persistKey is set.
|
|
591
|
+
// Store only the ORDER (string ids), never a snapshot of column objects — otherwise
|
|
592
|
+
// the frozen snapshot keeps stale `cell` closures (over old state/props), which made
|
|
593
|
+
// edited cells render/write stale data (e.g. corrugation flute stuck "Loading", reel
|
|
594
|
+
// wiped on edit). `columns` is re-derived from the FRESH columnsWithExpand every render.
|
|
595
|
+
const colId = (col) => col.id || col.accessorKey;
|
|
596
|
+
const [columnOrderState, setColumnOrderState] = useState(() => {
|
|
597
|
+
const order = savedView?.columnOrder;
|
|
598
|
+
return order && order.length > 0 ? order : null;
|
|
599
|
+
});
|
|
600
|
+
const columns = useMemo(() => {
|
|
601
|
+
if (!columnOrderState || columnOrderState.length === 0)
|
|
602
|
+
return columnsWithExpand;
|
|
603
|
+
const currentIds = columnsWithExpand.map(colId);
|
|
604
|
+
// Only apply a saved order that matches the current column set exactly.
|
|
605
|
+
if (columnOrderState.length !== currentIds.length || !columnOrderState.every((id) => currentIds.includes(id))) {
|
|
606
|
+
return columnsWithExpand;
|
|
607
|
+
}
|
|
608
|
+
return [...columnsWithExpand].sort((a, b) => columnOrderState.indexOf(colId(a)) - columnOrderState.indexOf(colId(b)));
|
|
609
|
+
}, [columnsWithExpand, columnOrderState]);
|
|
610
|
+
// Search hook - handles all search state and logic (must be after columns definition)
|
|
611
|
+
const { searchValue, setSearchValue, currentSearchTerm, selectedDuringSearch, debouncedSearchValue, handleGlobalSearchChange, handleRowSelectionChange, clearSearch } = advancedSearch({
|
|
612
|
+
data,
|
|
613
|
+
columns,
|
|
614
|
+
mainColumnsArray,
|
|
615
|
+
enableSearch,
|
|
616
|
+
totalSearchResults: navigationState.totalResults,
|
|
617
|
+
updateSearchResults,
|
|
618
|
+
clearNavigation,
|
|
619
|
+
setGlobalFilter
|
|
620
|
+
});
|
|
621
|
+
// Keep voice search handler ref in sync
|
|
622
|
+
searchHandlerRef.current = handleGlobalSearchChange;
|
|
623
|
+
// (Column order is re-derived from fresh columns each render; no snapshot to reset.)
|
|
624
|
+
const [showAdvancedFilter, setShowAdvancedFilter] = useState(false);
|
|
625
|
+
const [settingsInitialTab, setSettingsInitialTab] = useState('filters');
|
|
626
|
+
const [currentView, setCurrentView] = useState('grid');
|
|
627
|
+
const handleViewChange = useCallback((view) => {
|
|
628
|
+
setCurrentView(view);
|
|
629
|
+
}, []);
|
|
630
|
+
// Column sizing state - initialize with explicit sizes from column definitions for SSR consistency
|
|
631
|
+
const [columnSizing, setColumnSizing] = useState(() => {
|
|
632
|
+
const initialSizing = {};
|
|
633
|
+
columns.forEach((col) => {
|
|
634
|
+
// Only set size if explicitly defined in column
|
|
635
|
+
if (col.id && col.size !== undefined) {
|
|
636
|
+
initialSizing[col.id] = col.size;
|
|
637
|
+
}
|
|
638
|
+
});
|
|
639
|
+
return { ...initialSizing, ...(savedView?.columnSizing || {}) };
|
|
640
|
+
});
|
|
641
|
+
// Persist view preferences (show/hide, order, width, sort) to localStorage when persistKey is set
|
|
642
|
+
const columnOrderIds = useMemo(() => columns.map((col) => col.id || col.accessorKey).filter(Boolean), [columns]);
|
|
643
|
+
useEffect(() => {
|
|
644
|
+
if (!persistStorageKey || typeof window === 'undefined')
|
|
645
|
+
return;
|
|
646
|
+
try {
|
|
647
|
+
window.localStorage.setItem(persistStorageKey, JSON.stringify({
|
|
648
|
+
columnVisibility,
|
|
649
|
+
columnSizing,
|
|
650
|
+
sorting,
|
|
651
|
+
columnOrder: columnOrderIds,
|
|
652
|
+
}));
|
|
653
|
+
}
|
|
654
|
+
catch {
|
|
655
|
+
// localStorage unavailable (private mode / quota) — view just won't persist
|
|
656
|
+
}
|
|
657
|
+
}, [persistStorageKey, columnVisibility, columnSizing, sorting, columnOrderIds]);
|
|
658
|
+
// Track selected rows during search - now handled by useDataGridSearch hook
|
|
659
|
+
// Track last clicked row for Shift+Click range selection
|
|
660
|
+
const [lastClickedRowIndex, setLastClickedRowIndex] = React.useState(null);
|
|
661
|
+
// Auto-sizing calculation (FIXED: Now includes summary row, borders, and proper height calculations)
|
|
662
|
+
const calculateOptimalHeight = useMemo(() => {
|
|
663
|
+
// Only enable auto-sizing in compactMode (for modals/dialogs)
|
|
664
|
+
// Default mode uses flex with minHeight/maxHeight
|
|
665
|
+
if (!compactMode)
|
|
666
|
+
return null;
|
|
667
|
+
// When search/filter is active, maintain minimum height to prevent grid collapse
|
|
668
|
+
const hasActiveSearch = globalFilter && globalFilter.trim().length > 0;
|
|
669
|
+
const minRowsForSearch = 8; // Minimum rows to show when searching to prevent collapse
|
|
670
|
+
const actualDataLength = filteredData.length;
|
|
671
|
+
const dataLength = hasActiveSearch
|
|
672
|
+
? Math.max(Math.min(actualDataLength, pageSize), minRowsForSearch)
|
|
673
|
+
: Math.min(actualDataLength, pageSize);
|
|
674
|
+
// ========================================
|
|
675
|
+
// HEIGHT COMPONENTS (All in pixels)
|
|
676
|
+
// ========================================
|
|
677
|
+
// 1. Toolbar/Header height
|
|
678
|
+
const toolbarHeight = hideHeader ? 0 : (compactHeader ? 48 : 60);
|
|
679
|
+
// 2. Table header row height
|
|
680
|
+
const headerRowHeight = 44; // From DraggableColumnHeader (h-11 = 2.75rem = 44px)
|
|
681
|
+
// 3. Filter row height (if enabled): h-8 = 32px
|
|
682
|
+
const filterRowHeight = enableFilterRow ? 32 : 0;
|
|
683
|
+
// 4. Data rows height
|
|
684
|
+
const dataRowsHeight = dataLength * rowHeight;
|
|
685
|
+
// 5. Summary row height (if enabled)
|
|
686
|
+
const summaryRowCount = (enableSummary && summaryConfig)
|
|
687
|
+
? (Array.isArray(summaryConfig) ? summaryConfig.length : 1)
|
|
688
|
+
: 0;
|
|
689
|
+
const summaryRowHeight = summaryRowCount * 24.75; // Summary rows use py-1 same as data rows (~24.75px)
|
|
690
|
+
// 6. Pagination height (if enabled)
|
|
691
|
+
const paginationHeight = enablePagination ? 56 : 0;
|
|
692
|
+
// 7. Borders and spacing
|
|
693
|
+
const borderAndSpacing = 4; // Top and bottom borders (2px each)
|
|
694
|
+
// Total content height
|
|
695
|
+
const contentHeight = toolbarHeight +
|
|
696
|
+
headerRowHeight +
|
|
697
|
+
filterRowHeight +
|
|
698
|
+
dataRowsHeight +
|
|
699
|
+
summaryRowHeight +
|
|
700
|
+
paginationHeight +
|
|
701
|
+
borderAndSpacing;
|
|
702
|
+
// ========================================
|
|
703
|
+
// HEIGHT LOGIC
|
|
704
|
+
// ========================================
|
|
705
|
+
// Special handling for no data or 1 row — let grid size naturally
|
|
706
|
+
if (dataLength <= 1) {
|
|
707
|
+
return null;
|
|
708
|
+
}
|
|
709
|
+
// Threshold: ~10 rows before scrolling kicks in
|
|
710
|
+
const compactThreshold = 10;
|
|
711
|
+
if (dataLength <= compactThreshold) {
|
|
712
|
+
// Small dataset: return null to let grid size naturally (no fixed height constraint)
|
|
713
|
+
// This prevents scrolling when actual row content is taller than estimated rowHeight
|
|
714
|
+
return null;
|
|
715
|
+
}
|
|
716
|
+
else {
|
|
717
|
+
// Use configured max height for larger datasets (allow scrolling): 500px default
|
|
718
|
+
const maxHeightValue = typeof maxHeight === 'number' ? maxHeight : 500;
|
|
719
|
+
return Math.min(contentHeight, maxHeightValue);
|
|
720
|
+
}
|
|
721
|
+
}, [compactMode, filteredData.length, pageSize, hideHeader, compactHeader, maxHeight, rowHeight, enablePagination, enableSummary, summaryConfig, globalFilter, enableFilterRow]);
|
|
722
|
+
// Column context menu state
|
|
723
|
+
const [contextMenu, setContextMenu] = useState({
|
|
724
|
+
column: null,
|
|
725
|
+
isVisible: false,
|
|
726
|
+
position: { x: 0, y: 0 }
|
|
727
|
+
});
|
|
728
|
+
// DnD sensors
|
|
729
|
+
const sensors = useSensors(useSensor(PointerSensor), useSensor(KeyboardSensor, {
|
|
730
|
+
coordinateGetter: sortableKeyboardCoordinates,
|
|
731
|
+
}));
|
|
732
|
+
// Custom filter function for advanced filters
|
|
733
|
+
const advancedFilterFn = React.useCallback((row, columnId, filterValue) => {
|
|
734
|
+
if (!filterValue)
|
|
735
|
+
return true;
|
|
736
|
+
// Handle plain string filter values (from FilterRow inline search)
|
|
737
|
+
if (typeof filterValue === 'string') {
|
|
738
|
+
const cellValue = row.getValue(columnId);
|
|
739
|
+
const cellString = String(cellValue ?? '');
|
|
740
|
+
const filterLower = filterValue.toLowerCase();
|
|
741
|
+
// Standard string matching first
|
|
742
|
+
if (cellString.toLowerCase().includes(filterLower))
|
|
743
|
+
return true;
|
|
744
|
+
// Date-aware matching: try to parse cell value as date and match against common formats
|
|
745
|
+
// This handles cases where raw value is "2026-02-14T00:00:00" but user types "14 Feb" or "Feb 2026"
|
|
746
|
+
//
|
|
747
|
+
// Only attempt this on values that actually look like dates. new Date(297) is a VALID
|
|
748
|
+
// date (297ms after epoch → 01/01/1970), so feeding plain numbers here made every
|
|
749
|
+
// numeric cell match any digit the user typed — filtering a number column did nothing.
|
|
750
|
+
if (cellValue && looksLikeDate(cellValue)) {
|
|
751
|
+
const dateObj = new Date(cellValue);
|
|
752
|
+
if (!isNaN(dateObj.getTime())) {
|
|
753
|
+
const day = dateObj.getDate();
|
|
754
|
+
const month = dateObj.getMonth(); // 0-indexed
|
|
755
|
+
const year = dateObj.getFullYear();
|
|
756
|
+
const monthNames = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'];
|
|
757
|
+
const monthFull = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'];
|
|
758
|
+
const dd = String(day).padStart(2, '0');
|
|
759
|
+
const mm = String(month + 1).padStart(2, '0');
|
|
760
|
+
// Generate searchable date strings in common formats
|
|
761
|
+
const dateFormats = [
|
|
762
|
+
`${dd}/${mm}/${year}`, // 14/02/2026
|
|
763
|
+
`${mm}/${dd}/${year}`, // 02/14/2026
|
|
764
|
+
`${dd}-${mm}-${year}`, // 14-02-2026
|
|
765
|
+
`${day} ${monthNames[month]} ${year}`, // 14 feb 2026
|
|
766
|
+
`${monthNames[month]} ${day}, ${year}`, // feb 14, 2026
|
|
767
|
+
`${day} ${monthFull[month]} ${year}`, // 14 february 2026
|
|
768
|
+
`${monthFull[month]} ${day}, ${year}`, // february 14, 2026
|
|
769
|
+
`${monthNames[month]} ${year}`, // feb 2026
|
|
770
|
+
`${monthFull[month]} ${year}`, // february 2026
|
|
771
|
+
`${dd}/${mm}`, // 14/02
|
|
772
|
+
`${day} ${monthNames[month]}`, // 14 feb
|
|
773
|
+
];
|
|
774
|
+
if (dateFormats.some(fmt => fmt.toLowerCase().includes(filterLower)))
|
|
775
|
+
return true;
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
return false;
|
|
779
|
+
}
|
|
780
|
+
if (typeof filterValue !== 'object')
|
|
781
|
+
return true;
|
|
782
|
+
const { operator, value, type } = filterValue;
|
|
783
|
+
const cellValue = row.getValue(columnId);
|
|
784
|
+
const cellString = String(cellValue || '');
|
|
785
|
+
// Handle 'type' field (from Quick Filter)
|
|
786
|
+
if (type && !operator) {
|
|
787
|
+
switch (type) {
|
|
788
|
+
case 'contains':
|
|
789
|
+
return cellString.toLowerCase().includes(String(value).toLowerCase());
|
|
790
|
+
case 'equals':
|
|
791
|
+
return cellString.toLowerCase() === String(value).toLowerCase();
|
|
792
|
+
case 'starts_with':
|
|
793
|
+
return cellString.toLowerCase().startsWith(String(value).toLowerCase());
|
|
794
|
+
case 'greater_than':
|
|
795
|
+
return Number(cellValue) > Number(value);
|
|
796
|
+
case 'less_than':
|
|
797
|
+
return Number(cellValue) < Number(value);
|
|
798
|
+
case 'in':
|
|
799
|
+
// Check if cellValue is in the array of values
|
|
800
|
+
return Array.isArray(value) && value.map(v => String(v)).includes(cellString);
|
|
801
|
+
default:
|
|
802
|
+
return true;
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
// Handle different operators (from Advanced Filter)
|
|
806
|
+
switch (operator) {
|
|
807
|
+
case 'contains':
|
|
808
|
+
return cellString.toLowerCase().includes(String(value).toLowerCase());
|
|
809
|
+
case 'not_contains':
|
|
810
|
+
return !cellString.toLowerCase().includes(String(value).toLowerCase());
|
|
811
|
+
case 'equals':
|
|
812
|
+
return cellValue == value;
|
|
813
|
+
case 'not_equals':
|
|
814
|
+
return cellValue != value;
|
|
815
|
+
case 'starts_with':
|
|
816
|
+
return cellString.toLowerCase().startsWith(String(value).toLowerCase());
|
|
817
|
+
case 'ends_with':
|
|
818
|
+
return cellString.toLowerCase().endsWith(String(value).toLowerCase());
|
|
819
|
+
case 'is_empty':
|
|
820
|
+
return !cellValue || cellString.trim() === '';
|
|
821
|
+
case 'is_not_empty':
|
|
822
|
+
return cellValue && cellString.trim() !== '';
|
|
823
|
+
case 'greater_than':
|
|
824
|
+
return Number(cellValue) > Number(value);
|
|
825
|
+
case 'greater_than_equal':
|
|
826
|
+
return Number(cellValue) >= Number(value);
|
|
827
|
+
case 'less_than':
|
|
828
|
+
return Number(cellValue) < Number(value);
|
|
829
|
+
case 'less_than_equal':
|
|
830
|
+
return Number(cellValue) <= Number(value);
|
|
831
|
+
case 'between':
|
|
832
|
+
return Number(cellValue) >= Number(value[0]) && Number(cellValue) <= Number(value[1]);
|
|
833
|
+
case 'not_between':
|
|
834
|
+
return Number(cellValue) < Number(value[0]) || Number(cellValue) > Number(value[1]);
|
|
835
|
+
case 'is_true':
|
|
836
|
+
return cellValue === true || cellValue === 'true' || cellValue === 1;
|
|
837
|
+
case 'is_false':
|
|
838
|
+
return cellValue === false || cellValue === 'false' || cellValue === 0;
|
|
839
|
+
default:
|
|
840
|
+
return true;
|
|
841
|
+
}
|
|
842
|
+
}, []);
|
|
843
|
+
// Table instance with intelligent selection handler
|
|
844
|
+
const table = useReactTable({
|
|
845
|
+
data: filteredData,
|
|
846
|
+
columns,
|
|
847
|
+
getRowId: getRowId || ((row) => row.id || data.indexOf(row).toString()),
|
|
848
|
+
defaultColumn: {
|
|
849
|
+
size: 150, // Ensure consistent default size for SSR/CSR
|
|
850
|
+
minSize: 30,
|
|
851
|
+
maxSize: 2000, // High limit allows users to drag columns wider than auto-calculated width
|
|
852
|
+
filterFn: 'advancedFilter', // Use custom filter function for all columns
|
|
853
|
+
},
|
|
854
|
+
onSortingChange: setSorting,
|
|
855
|
+
onColumnFiltersChange: setColumnFilters,
|
|
856
|
+
getCoreRowModel: getCoreRowModel(),
|
|
857
|
+
getSortedRowModel: getSortedRowModel(),
|
|
858
|
+
getFilteredRowModel: getFilteredRowModel(),
|
|
859
|
+
filterFns: {
|
|
860
|
+
advancedFilter: advancedFilterFn,
|
|
861
|
+
},
|
|
862
|
+
sortingFns: {
|
|
863
|
+
// Numeric-aware text sort so "10" sorts after "9", not after "1".
|
|
864
|
+
naturalSort: (rowA, rowB, columnId) => naturalCompare(rowA.getValue(columnId), rowB.getValue(columnId)),
|
|
865
|
+
// Date-aware sort: parses DD/MM/YYYY, ISO, and other common date formats
|
|
866
|
+
dateSort: (rowA, rowB, columnId) => {
|
|
867
|
+
const parseDate = (val) => {
|
|
868
|
+
if (!val)
|
|
869
|
+
return 0;
|
|
870
|
+
const s = String(val);
|
|
871
|
+
// DD/MM/YYYY or DD/MM/YY
|
|
872
|
+
if (s.includes('/')) {
|
|
873
|
+
const parts = s.split('/');
|
|
874
|
+
if (parts.length === 3) {
|
|
875
|
+
const y = parseInt(parts[2]);
|
|
876
|
+
return new Date(y < 100 ? 2000 + y : y, parseInt(parts[1]) - 1, parseInt(parts[0])).getTime();
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
const d = new Date(s);
|
|
880
|
+
return isNaN(d.getTime()) ? 0 : d.getTime();
|
|
881
|
+
};
|
|
882
|
+
return parseDate(rowA.getValue(columnId)) - parseDate(rowB.getValue(columnId));
|
|
883
|
+
},
|
|
884
|
+
},
|
|
885
|
+
getPaginationRowModel: enablePagination ? getPaginationRowModel() : undefined,
|
|
886
|
+
onPaginationChange: enablePagination ? setPagination : undefined,
|
|
887
|
+
autoResetPageIndex: false,
|
|
888
|
+
// Grouping
|
|
889
|
+
getGroupedRowModel: enableGrouping ? getGroupedRowModel() : undefined,
|
|
890
|
+
onGroupingChange: (updater) => {
|
|
891
|
+
const newGrouping = typeof updater === 'function' ? updater(grouping) : updater;
|
|
892
|
+
setGrouping(newGrouping);
|
|
893
|
+
onGroupingChange?.(newGrouping);
|
|
894
|
+
},
|
|
895
|
+
// Expanding (also used for grouped rows)
|
|
896
|
+
getExpandedRowModel: getExpandedRowModel(),
|
|
897
|
+
onExpandedChange: setExpanded,
|
|
898
|
+
getRowCanExpand: getRowCanExpand || ((row) => !!renderSubComponent || row.subRows?.length > 0),
|
|
899
|
+
onColumnVisibilityChange: setColumnVisibility,
|
|
900
|
+
onRowSelectionChange: (updater) => {
|
|
901
|
+
setRowSelection(updater);
|
|
902
|
+
// Track selections and deselections for intelligent search clearing
|
|
903
|
+
if (typeof updater === 'function') {
|
|
904
|
+
const newSelection = updater(rowSelection);
|
|
905
|
+
const oldKeys = Object.keys(rowSelection).filter(key => rowSelection[key]);
|
|
906
|
+
const newKeys = Object.keys(newSelection).filter(key => newSelection[key]);
|
|
907
|
+
// Find newly selected and deselected rows
|
|
908
|
+
const newlySelected = newKeys.filter(key => !oldKeys.includes(key));
|
|
909
|
+
const newlyDeselected = oldKeys.filter(key => !newKeys.includes(key));
|
|
910
|
+
if (currentSearchTerm.trim()) {
|
|
911
|
+
// Handle newly selected rows
|
|
912
|
+
newlySelected.forEach(rowIndexStr => {
|
|
913
|
+
const rowIndex = parseInt(rowIndexStr, 10);
|
|
914
|
+
const rowData = filteredData[rowIndex];
|
|
915
|
+
const rowId = rowData?.id || rowIndexStr;
|
|
916
|
+
handleRowSelectionChange(rowId, true);
|
|
917
|
+
});
|
|
918
|
+
// Handle newly deselected rows
|
|
919
|
+
newlyDeselected.forEach(rowIndexStr => {
|
|
920
|
+
const rowIndex = parseInt(rowIndexStr, 10);
|
|
921
|
+
const rowData = filteredData[rowIndex];
|
|
922
|
+
const rowId = rowData?.id || rowIndexStr;
|
|
923
|
+
handleRowSelectionChange(rowId, false);
|
|
924
|
+
});
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
},
|
|
928
|
+
onGlobalFilterChange: setGlobalFilter,
|
|
929
|
+
onColumnSizingChange: setColumnSizing,
|
|
930
|
+
globalFilterFn: 'includesString',
|
|
931
|
+
state: {
|
|
932
|
+
sorting,
|
|
933
|
+
columnFilters,
|
|
934
|
+
columnVisibility,
|
|
935
|
+
rowSelection: stableRowSelection,
|
|
936
|
+
globalFilter,
|
|
937
|
+
columnSizing,
|
|
938
|
+
expanded,
|
|
939
|
+
columnPinning,
|
|
940
|
+
grouping,
|
|
941
|
+
...(enablePagination && { pagination }),
|
|
942
|
+
},
|
|
943
|
+
onColumnPinningChange: setColumnPinning,
|
|
944
|
+
enableRowSelection: true,
|
|
945
|
+
enableMultiRowSelection: rowSelectionMode === 'multi',
|
|
946
|
+
enableColumnResizing: enableColumnResizing,
|
|
947
|
+
columnResizeMode: columnResizeMode,
|
|
948
|
+
});
|
|
949
|
+
// Table rows
|
|
950
|
+
const { rows } = table.getRowModel();
|
|
951
|
+
// Virtual scrolling setup
|
|
952
|
+
const tableContainerRef = useRef(null);
|
|
953
|
+
const headerScrollRef = useRef(null);
|
|
954
|
+
// Track if data has ever been loaded (non-empty) to distinguish initial empty vs result empty
|
|
955
|
+
const hasEverHadDataRef = useRef(false);
|
|
956
|
+
if (data.length > 0) {
|
|
957
|
+
hasEverHadDataRef.current = true;
|
|
958
|
+
}
|
|
959
|
+
// Force re-render state for virtualizer (workaround for React 19 flushSync issue)
|
|
960
|
+
const [, forceRerender] = React.useReducer((x) => x + 1, 0);
|
|
961
|
+
const rowVirtualizer = useVirtualizer({
|
|
962
|
+
count: rows.length,
|
|
963
|
+
getScrollElement: () => tableContainerRef.current,
|
|
964
|
+
estimateSize: () => rowHeight,
|
|
965
|
+
overscan: 20,
|
|
966
|
+
enabled: enableVirtualization && currentView === 'grid',
|
|
967
|
+
// React 19 fix: never allow synchronous flushSync from inside render.
|
|
968
|
+
// All virtualizer-triggered re-renders go through a microtask so they
|
|
969
|
+
// happen after the current render cycle completes.
|
|
970
|
+
onChange: (_instance, sync) => {
|
|
971
|
+
if (sync) {
|
|
972
|
+
queueMicrotask(forceRerender);
|
|
973
|
+
}
|
|
974
|
+
else {
|
|
975
|
+
forceRerender();
|
|
976
|
+
}
|
|
977
|
+
},
|
|
978
|
+
// Override the scroll offset observer to avoid flushSync during render.
|
|
979
|
+
// Default implementation calls flushSync when scroll events fire while
|
|
980
|
+
// React is already rendering. Using rAF breaks the synchronous chain.
|
|
981
|
+
observeElementOffset: (instance, cb) => {
|
|
982
|
+
const el = instance.scrollElement;
|
|
983
|
+
if (!el)
|
|
984
|
+
return;
|
|
985
|
+
let rafId;
|
|
986
|
+
const handler = () => {
|
|
987
|
+
cancelAnimationFrame(rafId);
|
|
988
|
+
rafId = requestAnimationFrame(() => cb(el.scrollTop, false));
|
|
989
|
+
};
|
|
990
|
+
cb(el.scrollTop, false);
|
|
991
|
+
el.addEventListener('scroll', handler, { passive: true });
|
|
992
|
+
return () => {
|
|
993
|
+
el.removeEventListener('scroll', handler);
|
|
994
|
+
cancelAnimationFrame(rafId);
|
|
995
|
+
};
|
|
996
|
+
},
|
|
997
|
+
});
|
|
998
|
+
// Column reordering handler
|
|
999
|
+
const handleColumnReorder = useCallback((event) => {
|
|
1000
|
+
const { active, over } = event;
|
|
1001
|
+
if (!over)
|
|
1002
|
+
return;
|
|
1003
|
+
// Use accessor keys for matching since that's what we're using as IDs
|
|
1004
|
+
const activeIndex = columns.findIndex((col) => col.accessorKey === active.id || col.id === active.id);
|
|
1005
|
+
const overIndex = columns.findIndex((col) => col.accessorKey === over.id || col.id === over.id);
|
|
1006
|
+
if (activeIndex !== overIndex && activeIndex !== -1 && overIndex !== -1) {
|
|
1007
|
+
// Persist the new ORDER (ids), not the column objects.
|
|
1008
|
+
const currentIds = columns.map(colId);
|
|
1009
|
+
setColumnOrderState(arrayMove(currentIds, activeIndex, overIndex));
|
|
1010
|
+
}
|
|
1011
|
+
}, [columns]);
|
|
1012
|
+
// Row reordering handler
|
|
1013
|
+
const handleRowReorder = useCallback((event) => {
|
|
1014
|
+
const { active, over } = event;
|
|
1015
|
+
if (!over)
|
|
1016
|
+
return;
|
|
1017
|
+
const currentData = reorderedData || filteredData;
|
|
1018
|
+
const activeIndex = currentData.findIndex(item => {
|
|
1019
|
+
const itemId = getRowId ? getRowId(item) : item.id;
|
|
1020
|
+
return itemId === active.id;
|
|
1021
|
+
});
|
|
1022
|
+
const overIndex = currentData.findIndex(item => {
|
|
1023
|
+
const itemId = getRowId ? getRowId(item) : item.id;
|
|
1024
|
+
return itemId === over.id;
|
|
1025
|
+
});
|
|
1026
|
+
if (activeIndex !== overIndex && activeIndex !== -1 && overIndex !== -1) {
|
|
1027
|
+
const newData = arrayMove(currentData, activeIndex, overIndex);
|
|
1028
|
+
setReorderedData(newData);
|
|
1029
|
+
onRowOrderChange?.(newData);
|
|
1030
|
+
}
|
|
1031
|
+
}, [filteredData, reorderedData, getRowId, onRowOrderChange]);
|
|
1032
|
+
// Selected rows data - use getSelectedRowModel() to get ALL selected rows, not just filtered ones
|
|
1033
|
+
const selectedRows = useMemo(() => {
|
|
1034
|
+
return table.getSelectedRowModel().rows.map(row => row.original);
|
|
1035
|
+
}, [table, rowSelection]);
|
|
1036
|
+
// Notify parent of selected rows
|
|
1037
|
+
React.useEffect(() => {
|
|
1038
|
+
onRowSelect?.(selectedRows);
|
|
1039
|
+
}, [selectedRows, onRowSelect]);
|
|
1040
|
+
// Filtered and sorted data for visualization
|
|
1041
|
+
const processedData = useMemo(() => {
|
|
1042
|
+
return table.getFilteredRowModel().rows.map(row => row.original);
|
|
1043
|
+
}, [table]);
|
|
1044
|
+
// Export rows: mirror what's on screen — only visible columns, in display order,
|
|
1045
|
+
// keyed by their header label, over the filtered + sorted rows.
|
|
1046
|
+
const exportRows = useMemo(() => {
|
|
1047
|
+
const exportable = table.getVisibleLeafColumns().filter((col) => col.id !== 'select' && col.id !== 'actions' && col.id !== 'expand');
|
|
1048
|
+
const headerOf = (col) => {
|
|
1049
|
+
const h = col.columnDef?.header;
|
|
1050
|
+
return typeof h === 'string' && h.trim() ? h : col.id;
|
|
1051
|
+
};
|
|
1052
|
+
return table.getSortedRowModel().rows.map((row) => {
|
|
1053
|
+
const out = {};
|
|
1054
|
+
exportable.forEach((col) => {
|
|
1055
|
+
out[headerOf(col)] = row.getValue(col.id);
|
|
1056
|
+
});
|
|
1057
|
+
return out;
|
|
1058
|
+
});
|
|
1059
|
+
// Recompute when filters, sorting, visibility, order, or data change
|
|
1060
|
+
}, [table, columnFilters, sorting, columnVisibility, columnSizing, globalFilter, data, columnOrderState]);
|
|
1061
|
+
const handleExport = (format) => {
|
|
1062
|
+
// Export functionality will be implemented in ExportImportButtons
|
|
1063
|
+
};
|
|
1064
|
+
const handleImport = (importedData) => {
|
|
1065
|
+
// Pass imported data to parent component
|
|
1066
|
+
onImport?.(importedData);
|
|
1067
|
+
};
|
|
1068
|
+
// Row click handler for selection
|
|
1069
|
+
const handleRowClick = useCallback((row, rowIndex, event) => {
|
|
1070
|
+
if (!enableRowClickSelection)
|
|
1071
|
+
return;
|
|
1072
|
+
// Prevent selection if clicking on a button or input (but allow checkbox clicks)
|
|
1073
|
+
const target = event.target;
|
|
1074
|
+
if (target.closest('button') || target.closest('a')) {
|
|
1075
|
+
return;
|
|
1076
|
+
}
|
|
1077
|
+
// Prevent selection if clicking on an editable cell (double-click area)
|
|
1078
|
+
if (target.closest('[data-editable-cell="true"]')) {
|
|
1079
|
+
return;
|
|
1080
|
+
}
|
|
1081
|
+
// ✅ FIX: Don't block row clicks in Selected view - only block if clicking the row itself (not checkbox)
|
|
1082
|
+
// The checkbox click should always work, even in Selected view
|
|
1083
|
+
if (viewMode === 'selected' && !target.closest('input[type="checkbox"]')) {
|
|
1084
|
+
return;
|
|
1085
|
+
}
|
|
1086
|
+
const isCtrlOrCmd = event.ctrlKey || event.metaKey;
|
|
1087
|
+
const isShift = event.shiftKey;
|
|
1088
|
+
if (rowSelectionMode === 'single') {
|
|
1089
|
+
// Single mode: just toggle this row
|
|
1090
|
+
row.toggleSelected();
|
|
1091
|
+
setLastClickedRowIndex(rowIndex);
|
|
1092
|
+
}
|
|
1093
|
+
else {
|
|
1094
|
+
// Multi mode
|
|
1095
|
+
if (isShift && enableShiftClickRange && lastClickedRowIndex !== null) {
|
|
1096
|
+
// Shift+Click: select range
|
|
1097
|
+
const start = Math.min(lastClickedRowIndex, rowIndex);
|
|
1098
|
+
const end = Math.max(lastClickedRowIndex, rowIndex);
|
|
1099
|
+
const allRows = table.getRowModel().rows;
|
|
1100
|
+
for (let i = start; i <= end; i++) {
|
|
1101
|
+
if (allRows[i]) {
|
|
1102
|
+
allRows[i].toggleSelected(true);
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
else if (isCtrlOrCmd && enableCtrlClickMultiSelect) {
|
|
1107
|
+
// Ctrl+Click: toggle individual row
|
|
1108
|
+
row.toggleSelected();
|
|
1109
|
+
setLastClickedRowIndex(rowIndex);
|
|
1110
|
+
}
|
|
1111
|
+
else {
|
|
1112
|
+
// Regular click: toggle this row only
|
|
1113
|
+
row.toggleSelected();
|
|
1114
|
+
setLastClickedRowIndex(rowIndex);
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
}, [enableRowClickSelection, viewMode, rowSelectionMode, enableShiftClickRange, enableCtrlClickMultiSelect, lastClickedRowIndex, table]);
|
|
1118
|
+
// Keyboard handler for Space key selection
|
|
1119
|
+
useEffect(() => {
|
|
1120
|
+
const handleKeyDown = (event) => {
|
|
1121
|
+
// Removed spacebar row selection - was causing performance issues and unwanted behavior
|
|
1122
|
+
// Ctrl+A to select all rows - but ONLY if not in an input/textarea/contenteditable
|
|
1123
|
+
if ((event.ctrlKey || event.metaKey) && event.key === 'a' && rowSelectionMode === 'multi') {
|
|
1124
|
+
const target = event.target;
|
|
1125
|
+
const isInputField = target.tagName === 'INPUT' ||
|
|
1126
|
+
target.tagName === 'TEXTAREA' ||
|
|
1127
|
+
target.isContentEditable;
|
|
1128
|
+
// Only handle Ctrl+A for grid if user is NOT in an input field
|
|
1129
|
+
// This allows standard browser Ctrl+A to work in input fields
|
|
1130
|
+
if (!isInputField) {
|
|
1131
|
+
event.preventDefault();
|
|
1132
|
+
table.toggleAllRowsSelected(true);
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
};
|
|
1136
|
+
window.addEventListener('keydown', handleKeyDown);
|
|
1137
|
+
return () => window.removeEventListener('keydown', handleKeyDown);
|
|
1138
|
+
}, [table, rowSelectionMode]);
|
|
1139
|
+
// Context menu handlers
|
|
1140
|
+
const handleColumnRightClick = useCallback((header, event) => {
|
|
1141
|
+
setContextMenu({
|
|
1142
|
+
column: header.column,
|
|
1143
|
+
isVisible: true,
|
|
1144
|
+
position: { x: event.clientX, y: event.clientY }
|
|
1145
|
+
});
|
|
1146
|
+
}, []);
|
|
1147
|
+
const handleCloseContextMenu = useCallback(() => {
|
|
1148
|
+
setContextMenu(prev => ({ ...prev, isVisible: false }));
|
|
1149
|
+
}, []);
|
|
1150
|
+
const handleApplyColumnFilter = useCallback((columnId, filterType, value) => {
|
|
1151
|
+
const column = table.getColumn(columnId);
|
|
1152
|
+
if (!column)
|
|
1153
|
+
return;
|
|
1154
|
+
switch (filterType) {
|
|
1155
|
+
case 'contains':
|
|
1156
|
+
column.setFilterValue(value);
|
|
1157
|
+
break;
|
|
1158
|
+
case 'equals':
|
|
1159
|
+
column.setFilterValue((old) => ({ type: 'equals', value }));
|
|
1160
|
+
break;
|
|
1161
|
+
case 'starts_with':
|
|
1162
|
+
column.setFilterValue((old) => ({ type: 'starts_with', value }));
|
|
1163
|
+
break;
|
|
1164
|
+
case 'greater_than':
|
|
1165
|
+
column.setFilterValue((old) => ({ type: 'greater_than', value: Number(value) }));
|
|
1166
|
+
break;
|
|
1167
|
+
case 'less_than':
|
|
1168
|
+
column.setFilterValue((old) => ({ type: 'less_than', value: Number(value) }));
|
|
1169
|
+
break;
|
|
1170
|
+
case 'in':
|
|
1171
|
+
column.setFilterValue((old) => ({ type: 'in', value }));
|
|
1172
|
+
break;
|
|
1173
|
+
default:
|
|
1174
|
+
column.setFilterValue(value);
|
|
1175
|
+
}
|
|
1176
|
+
}, [table]);
|
|
1177
|
+
const handleAdvancedFilter = (conditions) => {
|
|
1178
|
+
// Conditions are evaluated together in filteredData with their AND/OR connectors,
|
|
1179
|
+
// so OR actually works (TanStack's columnFilters can only AND independent columns).
|
|
1180
|
+
setAdvancedConditions(conditions);
|
|
1181
|
+
setShowAdvancedFilter(false);
|
|
1182
|
+
};
|
|
1183
|
+
// Baccha Search handlers
|
|
1184
|
+
const handleColumnSearch = useCallback((columnId, searchTerm) => {
|
|
1185
|
+
setColumnSearches(prev => ({
|
|
1186
|
+
...prev,
|
|
1187
|
+
[columnId]: searchTerm
|
|
1188
|
+
}));
|
|
1189
|
+
setIsColumnSearchActive(prev => ({
|
|
1190
|
+
...prev,
|
|
1191
|
+
[columnId]: searchTerm.length > 0
|
|
1192
|
+
}));
|
|
1193
|
+
// Apply column-specific filter
|
|
1194
|
+
const column = table.getColumn(columnId);
|
|
1195
|
+
if (column) {
|
|
1196
|
+
column.setFilterValue(searchTerm || undefined);
|
|
1197
|
+
}
|
|
1198
|
+
}, [table]);
|
|
1199
|
+
// Spin the refresh icon while the caller's handler is in flight. Callers that
|
|
1200
|
+
// already track their own loading state can drive it via the isRefreshing prop.
|
|
1201
|
+
const [isRefreshingInternal, setIsRefreshingInternal] = useState(false);
|
|
1202
|
+
const refreshSpinning = isRefreshingProp || isRefreshingInternal;
|
|
1203
|
+
const handleRefreshClick = useCallback(async () => {
|
|
1204
|
+
if (!onRefresh || refreshSpinning)
|
|
1205
|
+
return;
|
|
1206
|
+
try {
|
|
1207
|
+
const result = onRefresh();
|
|
1208
|
+
if (result && typeof result.then === 'function') {
|
|
1209
|
+
setIsRefreshingInternal(true);
|
|
1210
|
+
await result;
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
finally {
|
|
1214
|
+
setIsRefreshingInternal(false);
|
|
1215
|
+
}
|
|
1216
|
+
}, [onRefresh, refreshSpinning]);
|
|
1217
|
+
const handleClearColumnSearch = useCallback((columnId) => {
|
|
1218
|
+
setColumnSearches(prev => {
|
|
1219
|
+
const newSearches = { ...prev };
|
|
1220
|
+
delete newSearches[columnId];
|
|
1221
|
+
return newSearches;
|
|
1222
|
+
});
|
|
1223
|
+
setIsColumnSearchActive(prev => ({
|
|
1224
|
+
...prev,
|
|
1225
|
+
[columnId]: false
|
|
1226
|
+
}));
|
|
1227
|
+
// Clear column filter
|
|
1228
|
+
const column = table.getColumn(columnId);
|
|
1229
|
+
if (column) {
|
|
1230
|
+
column.setFilterValue(undefined);
|
|
1231
|
+
}
|
|
1232
|
+
}, [table]);
|
|
1233
|
+
// Clear ALL filters (global search + column filters)
|
|
1234
|
+
// Total active filters for the badge / clear-all visibility: column filters + advanced conditions.
|
|
1235
|
+
const totalActiveFilters = columnFilters.length + advancedConditions.length;
|
|
1236
|
+
const handleClearAllFilters = useCallback(() => {
|
|
1237
|
+
// Clear global filter/search (clearSearch also resets the debounced value,
|
|
1238
|
+
// which otherwise re-applies the old filter 300ms later)
|
|
1239
|
+
clearSearch();
|
|
1240
|
+
// Clear all column filters
|
|
1241
|
+
setColumnFilters([]);
|
|
1242
|
+
// Clear advanced filter conditions
|
|
1243
|
+
setAdvancedConditions([]);
|
|
1244
|
+
// Clear column search states
|
|
1245
|
+
setColumnSearches({});
|
|
1246
|
+
setIsColumnSearchActive({});
|
|
1247
|
+
}, [clearSearch]);
|
|
1248
|
+
// Navigation handlers
|
|
1249
|
+
const handleSearchNavigation = useCallback((direction) => {
|
|
1250
|
+
navigateSearch(direction);
|
|
1251
|
+
}, [navigateSearch]);
|
|
1252
|
+
const handleSearchSelection = useCallback((rowId) => {
|
|
1253
|
+
// Find the row in the current filtered view
|
|
1254
|
+
const filteredRows = table.getRowModel().rows;
|
|
1255
|
+
const targetRow = filteredRows.find(row => {
|
|
1256
|
+
const currentRowId = row.original.id || row.id;
|
|
1257
|
+
return currentRowId === rowId;
|
|
1258
|
+
});
|
|
1259
|
+
if (targetRow) {
|
|
1260
|
+
const isCurrentlySelected = targetRow.getIsSelected();
|
|
1261
|
+
const newSelectionState = !isCurrentlySelected;
|
|
1262
|
+
// Toggle selection - this will trigger handleRowSelectionChange via table callback
|
|
1263
|
+
targetRow.toggleSelected(newSelectionState);
|
|
1264
|
+
// Optionally call onRowClick if provided
|
|
1265
|
+
if (onRowClick) {
|
|
1266
|
+
onRowClick(targetRow.original);
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
}, [table, onRowClick]);
|
|
1270
|
+
// No default height class - rely on maxHeight style for responsiveness
|
|
1271
|
+
const hasHeightClass = className && /h-\[|h-\d|h-full|h-screen|h-auto/.test(className);
|
|
1272
|
+
const finalClassName = `border border-[rgb(var(--bd-default))] rounded-lg overflow-hidden flex flex-col ${className || ''}`;
|
|
1273
|
+
return (_jsxs(motion.div, { initial: { opacity: 0, y: 20 }, animate: { opacity: 1, y: 0 }, transition: { duration: 0.3 }, className: finalClassName, style: {
|
|
1274
|
+
...style,
|
|
1275
|
+
isolation: 'isolate',
|
|
1276
|
+
position: 'relative',
|
|
1277
|
+
zIndex: 0
|
|
1278
|
+
}, children: [!hideHeader && (_jsxs("div", { className: `flex flex-row items-center justify-between gap-1.5 sm:gap-0 py-2 sm:py-1.5 px-2 sm:px-3 border-b border-bd-default bg-bg-subtle transition-colors ${enableGrouping ? 'group-drop-zone' : ''}`, onDragOver: enableGrouping ? (e) => {
|
|
1279
|
+
e.preventDefault();
|
|
1280
|
+
e.currentTarget.classList.add('bg-[rgb(var(--color-primary))]/5', 'border-[rgb(var(--color-primary))]');
|
|
1281
|
+
} : undefined, onDragLeave: enableGrouping ? (e) => {
|
|
1282
|
+
e.currentTarget.classList.remove('bg-[rgb(var(--color-primary))]/5', 'border-[rgb(var(--color-primary))]');
|
|
1283
|
+
} : undefined, onDrop: enableGrouping ? (e) => {
|
|
1284
|
+
e.preventDefault();
|
|
1285
|
+
e.currentTarget.classList.remove('bg-[rgb(var(--color-primary))]/5', 'border-[rgb(var(--color-primary))]');
|
|
1286
|
+
const columnId = e.dataTransfer.getData('text/plain');
|
|
1287
|
+
if (columnId && !grouping.includes(columnId)) {
|
|
1288
|
+
setGrouping(prev => [...prev, columnId]);
|
|
1289
|
+
}
|
|
1290
|
+
} : undefined, children: [_jsxs("div", { className: "flex flex-nowrap sm:flex-wrap items-center gap-1.5 sm:gap-4 min-w-0 shrink sm:flex-1", children: [title && (_jsx("h3", { className: "text-sm sm:text-base font-medium text-fg-default truncate", children: title })), enableGrouping && grouping.length > 0 && (_jsxs("div", { className: "flex items-center gap-1 flex-wrap", children: [_jsx(Layers, { className: "h-3.5 w-3.5 text-[rgb(var(--fg-muted))]" }), grouping.map((columnId, index) => {
|
|
1291
|
+
const column = table.getColumn(columnId);
|
|
1292
|
+
const header = typeof column?.columnDef.header === 'string'
|
|
1293
|
+
? column.columnDef.header
|
|
1294
|
+
: columnId;
|
|
1295
|
+
return (_jsxs(React.Fragment, { children: [index > 0 && (_jsx("span", { className: "text-[rgb(var(--fg-muted))] text-xs", children: "\u2192" })), _jsxs("span", { className: "inline-flex items-center gap-1 px-2 py-0.5 rounded text-xs font-medium bg-[rgb(var(--color-primary))]/10 text-[rgb(var(--color-primary))] border border-[rgb(var(--color-primary))]/30", children: [header, _jsx("button", { onClick: () => setGrouping(prev => prev.filter(id => id !== columnId)), className: "hover:bg-[rgb(var(--color-primary))]/20 rounded p-0.5 -mr-1", "aria-label": "Remove grouping", children: _jsx(XCircle, { className: "h-3 w-3" }) })] })] }, columnId));
|
|
1296
|
+
})] })), enableGrouping && grouping.length === 0 && (_jsx("span", { className: "text-xs text-[rgb(var(--fg-muted))] italic hidden sm:inline", children: "Drag column headers here to group" })), headerActions && (_jsx("div", { className: "flex flex-wrap items-center gap-1.5 sm:gap-2", children: headerActions })), preToggleActions && (_jsx("div", { className: "flex flex-nowrap sm:flex-wrap items-center gap-1.5 sm:gap-2 min-w-0 shrink", children: preToggleActions }))] }), _jsxs("div", { className: "flex items-center gap-1.5 sm:gap-2 flex-1 min-w-0 justify-end", children: [toggleShouldBeVisible && (_jsxs("div", { className: "inline-flex items-center bg-[rgb(var(--bg-subtle))] rounded-full border border-[rgb(var(--bd-default))] p-0.5", children: [_jsx("button", { onClick: () => {
|
|
1297
|
+
try {
|
|
1298
|
+
onViewModeChange?.('all');
|
|
1299
|
+
}
|
|
1300
|
+
catch (error) {
|
|
1301
|
+
console.error('Error switching to All view:', error);
|
|
1302
|
+
}
|
|
1303
|
+
}, className: `px-2 sm:px-4 py-1 sm:py-1.5 text-[10px] sm:text-xs font-medium rounded-full transition-all duration-150 ease-in-out focus:outline-none focus:ring-2 focus:ring-primary/50 whitespace-nowrap ${viewMode === 'all'
|
|
1304
|
+
? 'bg-primary text-white shadow-sm'
|
|
1305
|
+
: 'text-[rgb(var(--fg-muted))] hover:bg-[rgb(var(--bg-hover))] hover:text-[rgb(var(--fg-default))]'}`, "aria-label": "View all items", children: "All" }), _jsxs("button", { onClick: () => {
|
|
1306
|
+
try {
|
|
1307
|
+
// Clear search/filters so the Selected view shows every selected
|
|
1308
|
+
// row, not just those matching a leftover filter
|
|
1309
|
+
handleClearAllFilters();
|
|
1310
|
+
// Always allow switching to selected mode, even with 0 selections
|
|
1311
|
+
// This prevents the toggle from becoming unresponsive
|
|
1312
|
+
onViewModeChange?.('selected');
|
|
1313
|
+
}
|
|
1314
|
+
catch (error) {
|
|
1315
|
+
console.error('Error switching to Selected view:', error);
|
|
1316
|
+
}
|
|
1317
|
+
}, className: `px-2 sm:px-4 py-1 sm:py-1.5 text-[10px] sm:text-xs font-medium rounded-full transition-all duration-150 ease-in-out focus:outline-none focus:ring-2 focus:ring-primary/50 whitespace-nowrap ${viewMode === 'selected'
|
|
1318
|
+
? 'bg-primary text-white shadow-sm'
|
|
1319
|
+
: 'text-[rgb(var(--fg-muted))] hover:bg-[rgb(var(--bg-hover))] hover:text-[rgb(var(--fg-default))]'}`, "aria-label": `View selected items (${safeSelectedCount} selected)`, children: [_jsx("span", { className: "hidden sm:inline", children: "Selected " }), "(", safeSelectedCount, ")"] })] }, "view-toggle")), preDateActions, enableSearch && (_jsxs("div", { className: "flex items-center gap-2 flex-1 min-w-0", children: [_jsx("div", { className: "min-w-0 flex-1", children: effectiveSearchType === 'advanced' ? (_jsxs(_Fragment, { children: [_jsx(TooltipProvider, { delayDuration: 100, children: _jsxs("div", { className: "flex items-center h-8 rounded-full border border-[rgb(var(--bd-default))] bg-[rgb(var(--bg-surface))] px-3 focus-within:border-[rgb(var(--color-primary))] focus-within:ring-1 focus-within:ring-[rgb(var(--color-primary)/0.2)] transition-all", children: [_jsxs("div", { className: "flex items-center gap-1.5 flex-1 min-w-0", children: [speechSupported && (_jsx("button", { type: "button", onClick: handleVoiceSearch, className: `flex-shrink-0 transition-colors ${isListening ? 'text-[rgb(var(--color-error))] animate-pulse' : 'text-[rgb(var(--fg-muted))] hover:text-[rgb(var(--fg-default))]'}`, title: isListening ? 'Stop listening' : 'Voice search', children: isListening ? _jsx(MicOff, { className: "h-3.5 w-3.5" }) : _jsx(Mic, { className: "h-3.5 w-3.5" }) })), _jsx("input", { ref: searchInputRef, placeholder: speechSupported ? 'Type or speak to search...' : 'Search...', value: searchValue, onChange: (e) => handleGlobalSearchChange(e.target.value), className: "flex-1 min-w-0 w-full bg-transparent border-none outline-none text-xs text-[rgb(var(--fg-default))] placeholder:text-[rgb(var(--fg-muted))]" })] }), _jsxs("div", { className: "flex items-center gap-2 flex-shrink-0 ml-2", children: [_jsx("div", { className: "w-px h-4 bg-[rgb(var(--bd-default))]" }), enableDateFilter && (_jsx(DatePicker, { mode: "range", value: { from: dateFrom || undefined, to: dateTo || undefined }, onChange: (range) => {
|
|
1320
|
+
if (range && typeof range === 'object' && 'from' in range) {
|
|
1321
|
+
onDateFromChange?.(range.from || null);
|
|
1322
|
+
onDateToChange?.(range.to || null);
|
|
1323
|
+
}
|
|
1324
|
+
}, iconOnly: true })), enableDateFilter && _jsx("div", { className: "w-px h-4 bg-[rgb(var(--bd-default))]" }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("button", { onClick: () => { setSettingsInitialTab('filters'); setShowAdvancedFilter(true); }, className: "relative flex items-center gap-1 text-[rgb(var(--fg-muted))] hover:text-[rgb(var(--fg-default))] transition-colors", children: [_jsx(ListFilter, { className: "h-3.5 w-3.5" }), _jsx("span", { className: "hidden sm:inline text-xs", children: "Filters" }), totalActiveFilters > 0 && (_jsx("div", { className: "absolute -top-1 -right-1 h-3 w-3 bg-[rgb(var(--color-primary))] rounded-full flex items-center justify-center", children: _jsx("span", { className: "text-[8px] text-white font-bold", children: totalActiveFilters }) }))] }) }), _jsx(TooltipContent, { children: totalActiveFilters > 0 ? `Filters (${totalActiveFilters} active)` : 'Filters' })] }), compactHeader && (_jsxs(_Fragment, { children: [_jsx("div", { className: "w-px h-4 bg-[rgb(var(--bd-default))]" }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { className: "inline-flex", children: _jsx(ActionsMenu, { enableVisualization: enableVisualization, currentView: currentView, onViewChange: handleViewChange, enableExport: enableExport && pageAccess.canExport, enableImport: enableImport, data: exportRows, filename: typeof title === 'string' && title ? title : 'data-export', onImportComplete: (importedData) => { if (onImport)
|
|
1325
|
+
onImport(importedData); }, enableColumnVisibility: enableColumnVisibility, onOpenColumnChooser: () => { setSettingsInitialTab('columns'); setShowAdvancedFilter(true); }, enableAutoResize: enableAutoResize, onAutoResize: () => { if (autoResizeAllColumns)
|
|
1326
|
+
autoResizeAllColumns(table); }, enableDateFilter: enableDateFilter, dateFrom: dateFrom, dateTo: dateTo, onDateFromChange: onDateFromChange, onDateToChange: onDateToChange, enableFiltering: enableFiltering, onOpenAdvancedFilter: () => { setSettingsInitialTab('filters'); setShowAdvancedFilter(true); }, activeFiltersCount: totalActiveFilters, enableGrouping: enableGrouping, columns: table.getAllColumns(), grouping: grouping, onGroupingChange: (columnId) => {
|
|
1327
|
+
setGrouping((prev) => prev.includes(columnId) ? prev.filter((id) => id !== columnId) : [...prev, columnId]);
|
|
1328
|
+
}, onClearGrouping: () => setGrouping([]) }) }) }), _jsx(TooltipContent, { children: "Options" })] })] })), onRefresh && (_jsxs(_Fragment, { children: [_jsx("div", { className: "w-px h-4 bg-[rgb(var(--bd-default))]" }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", onClick: handleRefreshClick, disabled: refreshSpinning, "aria-label": "Refresh", className: "flex items-center text-[rgb(var(--fg-muted))] hover:text-[rgb(var(--fg-default))] transition-colors disabled:opacity-50 disabled:cursor-not-allowed", children: _jsx(RefreshCw, { className: `h-3.5 w-3.5 ${refreshSpinning ? 'animate-spin' : ''}` }) }) }), _jsx(TooltipContent, { children: "Refresh" })] })] })), toolbarActions && (_jsxs(_Fragment, { children: [_jsx("div", { className: "w-px h-4 bg-[rgb(var(--bd-default))]" }), toolbarActions] }))] })] }) }), _jsx(SearchNavigator, { navigationState: navigationState, onNavigate: handleSearchNavigation, onSelect: handleSearchSelection, onClear: clearNavigation, searchInputRef: searchInputRef, enabled: enableSearch })] })) : (
|
|
1329
|
+
// Search New (top header modal style)
|
|
1330
|
+
_jsx(SearchNewModal, { data: processedData, columns: columns, mainColumns: mainColumns, onRowSelect: handleSearchSelection, selectedRows: new Set(Object.keys(rowSelection).filter(key => rowSelection[key])), className: "w-full" })) }), (globalFilter || totalActiveFilters > 0) && (_jsx(Button, { variant: "action-cancel", size: "xs", onClick: handleClearAllFilters, className: "h-8 rounded-full whitespace-nowrap", "aria-label": "Clear all filters", children: "Clear" }))] })), !compactHeader && (
|
|
1331
|
+
/* LEGACY FULL HEADER: Show all buttons */
|
|
1332
|
+
_jsxs(_Fragment, { children: [enableVisualization && (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsxs(Button, { variant: "outline", size: "sm", className: "w-9 h-8 p-0", children: [currentView === 'grid' && _jsx(Grid3X3, { className: "h-4 w-4" }), currentView === 'cards' && _jsx(LayoutGrid, { className: "h-4 w-4" }), currentView === 'chart' && _jsx(BarChart3, { className: "h-4 w-4" })] }) }), _jsxs(DropdownMenuContent, { align: "start", children: [_jsxs(DropdownMenuItem, { onClick: () => handleViewChange('grid'), children: [_jsx(Grid3X3, { className: "mr-2 h-4 w-4" }), _jsx("span", { children: "Grid" })] }), _jsxs(DropdownMenuItem, { onClick: () => handleViewChange('cards'), children: [_jsx(LayoutGrid, { className: "mr-2 h-4 w-4" }), _jsx("span", { children: "Cards" })] }), _jsxs(DropdownMenuItem, { onClick: () => handleViewChange('chart'), children: [_jsx(BarChart3, { className: "mr-2 h-4 w-4" }), _jsx("span", { children: "Charts" })] })] })] })), enableColumnVisibility && (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { variant: "outline", size: "sm", className: "w-9 h-8 p-0", children: _jsx(LayoutGrid, { className: "h-5 w-5" }) }) }), _jsx(DropdownMenuContent, { align: "end", className: "w-56 max-h-96 overflow-y-auto", children: (() => {
|
|
1333
|
+
const allColumns = table.getAllColumns().filter((column) => column.getCanHide());
|
|
1334
|
+
const frozenColumns = allColumns.filter((column) => frozenColumnsState.has(column.id) && column.id !== 'select');
|
|
1335
|
+
const availableColumns = allColumns.filter((column) => !frozenColumnsState.has(column.id));
|
|
1336
|
+
return (_jsxs("div", { className: "space-y-1", children: [_jsx("div", { className: "px-3 py-2 border-b border-[rgb(var(--bd-default))] bg-[rgb(var(--bg-subtle))]", children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-xs font-medium text-[rgb(var(--fg-default))]", children: "Column Management" }), _jsxs("div", { className: "flex items-center space-x-1", children: [frozenColumns.length > 0 && (_jsx(Button, { variant: "ghost", size: "sm", className: "h-6 px-2 text-xs text-[rgb(var(--fg-muted))] hover:text-[rgb(var(--fg-default))] cursor-pointer", onClick: (e) => {
|
|
1337
|
+
e.stopPropagation();
|
|
1338
|
+
setFrozenColumnsState(new Set());
|
|
1339
|
+
}, "aria-label": "Unfreeze all columns", children: "Unfreeze All" })), _jsx(Button, { variant: "ghost", size: "sm", className: "h-6 px-2 text-xs text-[rgb(var(--fg-muted))] hover:text-[rgb(var(--fg-default))] cursor-pointer", onClick: (e) => {
|
|
1340
|
+
e.stopPropagation();
|
|
1341
|
+
autoResizeAllColumns?.(table);
|
|
1342
|
+
}, "aria-label": "Auto-size all columns to fit content", children: "Auto-size" })] })] }) }), enableColumnFreezing && frozenColumns.length > 0 && (_jsx("div", { className: "px-2 py-1", children: _jsx("div", { className: "bg-[rgb(var(--color-primary-subtle))] rounded-md p-1 space-y-0.5", children: frozenColumns.map((column) => (_jsxs("div", { className: "flex items-center justify-between px-2 py-1.5 hover:bg-[rgb(var(--bg-selected))]/50 rounded group cursor-pointer", children: [_jsxs("div", { className: "flex items-center space-x-2 flex-1", children: [_jsx("input", { type: "checkbox", checked: column.getIsVisible(), onChange: (e) => {
|
|
1343
|
+
e.stopPropagation();
|
|
1344
|
+
column.toggleVisibility(e.target.checked);
|
|
1345
|
+
}, className: "w-3 h-3 rounded border-[rgb(var(--bd-default))] text-[rgb(var(--color-primary))] focus:ring-[rgb(var(--color-primary))] cursor-pointer" }), _jsx("span", { className: "text-sm font-medium text-[rgb(var(--fg-default))] capitalize truncate", children: column.id })] }), _jsx(Button, { variant: "ghost", size: "sm", className: "h-7 w-7 p-0 text-[rgb(var(--color-primary))] hover:text-[rgb(var(--color-primary-hover))] hover:bg-[rgb(var(--bg-selected))] opacity-70 group-hover:opacity-100 transition-opacity cursor-pointer", onClick: (e) => {
|
|
1346
|
+
e.stopPropagation();
|
|
1347
|
+
const newFrozenColumns = new Set(frozenColumnsState);
|
|
1348
|
+
newFrozenColumns.delete(column.id);
|
|
1349
|
+
setFrozenColumnsState(newFrozenColumns);
|
|
1350
|
+
}, "aria-label": "Unfreeze this column", children: _jsx(PinOff, { className: "h-4 w-4" }) })] }, column.id))) }) })), availableColumns.length > 0 && (_jsx("div", { className: "px-2 py-1", children: _jsx("div", { className: "space-y-0.5", children: availableColumns.map((column) => {
|
|
1351
|
+
const isSelectColumn = column.id === 'select';
|
|
1352
|
+
return (_jsxs("div", { className: "flex items-center justify-between px-2 py-1.5 hover:bg-[rgb(var(--bg-subtle))] rounded group cursor-pointer", children: [_jsxs("div", { className: "flex items-center space-x-2 flex-1", children: [_jsx("input", { type: "checkbox", checked: column.getIsVisible(), onChange: (e) => {
|
|
1353
|
+
e.stopPropagation();
|
|
1354
|
+
column.toggleVisibility(e.target.checked);
|
|
1355
|
+
}, className: "w-3 h-3 rounded border-[rgb(var(--bd-default))] text-[rgb(var(--color-primary))] focus:ring-[rgb(var(--color-primary))] cursor-pointer" }), _jsx("span", { className: "text-sm text-[rgb(var(--fg-default))] capitalize truncate", children: column.id })] }), enableColumnFreezing && !isSelectColumn && (_jsx(Button, { variant: "ghost", size: "sm", className: "h-7 w-7 p-0 text-[rgb(var(--color-icon))] hover:text-[rgb(var(--color-icon-hover))] hover:bg-[rgb(var(--bg-hover))] opacity-0 group-hover:opacity-100 transition-opacity cursor-pointer", onClick: (e) => {
|
|
1356
|
+
e.stopPropagation();
|
|
1357
|
+
const newFrozenColumns = new Set(frozenColumnsState);
|
|
1358
|
+
newFrozenColumns.add(column.id);
|
|
1359
|
+
setFrozenColumnsState(newFrozenColumns);
|
|
1360
|
+
}, "aria-label": "Freeze this column to the left", children: _jsx(Pin, { className: "h-4 w-4" }) }))] }, column.id));
|
|
1361
|
+
}) }) }))] }));
|
|
1362
|
+
})() })] }))] })), !compactHeader && enableAutoResize && (_jsx(AutoResizeButton, { onAutoResize: () => {
|
|
1363
|
+
if (autoResizeAllColumns) {
|
|
1364
|
+
autoResizeAllColumns(table);
|
|
1365
|
+
}
|
|
1366
|
+
} })), headerActionsRight && (_jsx("div", { className: "flex flex-wrap items-center gap-1.5 sm:gap-2", children: headerActionsRight }))] })] })), _jsx("div", { className: "overflow-hidden bg-bg-surface flex-1 flex flex-col", children: _jsx(AnimatePresence, { mode: "wait", children: currentView === 'grid' ? (_jsx(motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 }, transition: { duration: 0.2 }, className: "flex-1 flex flex-col min-h-0", children: _jsx("div", { className: "flex-1 flex flex-col min-h-0 overflow-hidden", children: (() => {
|
|
1367
|
+
// Determine if row reordering is active
|
|
1368
|
+
// Allow reordering when: 1) viewMode is 'selected', OR 2) viewToggle is disabled (simple mode)
|
|
1369
|
+
const isRowReorderingActive = enableRowReordering && (viewMode === 'selected' || !enableViewToggle) && !loading && table.getRowModel().rows.length > 0;
|
|
1370
|
+
return (_jsx(DndContext, { sensors: sensors, collisionDetection: closestCenter, onDragEnd: isRowReorderingActive ? handleRowReorder : handleColumnReorder, modifiers: isRowReorderingActive ? [restrictToVerticalAxis] : [restrictToHorizontalAxis], children: _jsxs("div", { ref: tableContainerRef, className: `${compactMode ? '' : 'flex-1'} scrollbar-thin relative`, style: {
|
|
1371
|
+
overscrollBehavior: 'contain',
|
|
1372
|
+
WebkitOverflowScrolling: 'touch',
|
|
1373
|
+
overflowX: 'auto',
|
|
1374
|
+
overflowY: compactMode && data.length === 0 ? 'hidden' : 'auto',
|
|
1375
|
+
// Removed scrollBehavior: 'smooth' - can cause lag with virtualization
|
|
1376
|
+
willChange: 'scroll-position',
|
|
1377
|
+
...(calculateOptimalHeight && { height: `${calculateOptimalHeight}px` }),
|
|
1378
|
+
...(!compactMode && {
|
|
1379
|
+
// Default mode: use standard minHeight/maxHeight (grid won't collapse due to flex-1)
|
|
1380
|
+
minHeight: typeof minHeight === 'number' ? `${minHeight}px` : minHeight,
|
|
1381
|
+
maxHeight: typeof maxHeight === 'number' ? `${maxHeight}px` : maxHeight
|
|
1382
|
+
})
|
|
1383
|
+
}, children: [_jsxs("table", { className: "w-full border-collapse", style: { tableLayout: 'fixed' }, children: [_jsxs("colgroup", { children: [isRowReorderingActive && (_jsx("col", { style: { width: '1.875rem', minWidth: '1.875rem', maxWidth: '1.875rem' } })), table.getHeaderGroups()[0]?.headers.map((header) => (_jsx("col", { style: { width: `${header.getSize()}px` }, suppressHydrationWarning: true }, header.id)))] }), _jsxs("thead", { className: "bg-[color-mix(in_srgb,rgb(var(--color-primary))_10%,white)] dark:bg-[color-mix(in_srgb,rgb(var(--color-primary))_10%,rgb(var(--bg-surface)))] sticky top-0 z-10", children: [table.getHeaderGroups().map((headerGroup) => {
|
|
1384
|
+
// Only use SortableContext for column reordering when row reordering is NOT active
|
|
1385
|
+
if (isRowReorderingActive) {
|
|
1386
|
+
return (_jsxs("tr", { className: "border-b border-[rgb(var(--bd-default))]", children: [_jsx("th", { className: "text-center relative after:content-[''] after:absolute after:right-0 after:top-[20%] after:bottom-[20%] after:w-[1px] after:bg-[rgb(var(--bd-medium))]", style: {
|
|
1387
|
+
width: '1.875rem',
|
|
1388
|
+
minWidth: '1.875rem',
|
|
1389
|
+
maxWidth: '1.875rem',
|
|
1390
|
+
} }), headerGroup.headers.map((header, headerIndex) => {
|
|
1391
|
+
const isFrozen = frozenColumnsState.has(header.id);
|
|
1392
|
+
const isPinnedRight = header.column.getIsPinned() === 'right';
|
|
1393
|
+
// Check if this is the last column
|
|
1394
|
+
const isLastColumn = headerIndex === headerGroup.headers.length - 1;
|
|
1395
|
+
// Check if this is the last frozen column
|
|
1396
|
+
const isLastFrozenColumn = isFrozen && (headerIndex === headerGroup.headers.length - 1 ||
|
|
1397
|
+
!frozenColumnsState.has(headerGroup.headers[headerIndex + 1]?.id));
|
|
1398
|
+
// Check if this is the first right-pinned column
|
|
1399
|
+
const isFirstPinnedRight = isPinnedRight && (headerIndex === 0 ||
|
|
1400
|
+
headerGroup.headers[headerIndex - 1]?.column.getIsPinned() !== 'right');
|
|
1401
|
+
// Calculate left position for frozen columns
|
|
1402
|
+
let leftPosition = 0;
|
|
1403
|
+
if (isFrozen) {
|
|
1404
|
+
// Add select column width if row selection is enabled
|
|
1405
|
+
if (enableRowSelection && !hideSelectionInSelectedView) {
|
|
1406
|
+
leftPosition = 30; // Select column width
|
|
1407
|
+
}
|
|
1408
|
+
// Sum up widths of all previous frozen columns (excluding select column)
|
|
1409
|
+
for (let i = 0; i < headerIndex; i++) {
|
|
1410
|
+
const prevHeader = headerGroup.headers[i];
|
|
1411
|
+
if (frozenColumnsState.has(prevHeader.id) && prevHeader.id !== 'select') {
|
|
1412
|
+
leftPosition += prevHeader.getSize();
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
// Calculate right position for right-pinned columns
|
|
1417
|
+
let rightPosition = 0;
|
|
1418
|
+
if (isPinnedRight) {
|
|
1419
|
+
for (let i = headerIndex + 1; i < headerGroup.headers.length; i++) {
|
|
1420
|
+
const nextHeader = headerGroup.headers[i];
|
|
1421
|
+
if (nextHeader.column.getIsPinned() === 'right') {
|
|
1422
|
+
rightPosition += nextHeader.getSize();
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
return (_jsx(DraggableColumnHeader, { header: header, enableReordering: enableColumnReordering, enableResizing: enableColumnResizing, enableFreezing: enableColumnFreezing, enableGrouping: enableGrouping, isGrouped: grouping.includes(header.column.id), isFrozen: isFrozen, isLastFrozen: isLastFrozenColumn, isFirstPinnedRight: isFirstPinnedRight, isLastColumn: isLastColumn, onRightClick: handleColumnRightClick, onFilterClick: handleColumnRightClick, style: {
|
|
1427
|
+
...(isFrozen && {
|
|
1428
|
+
position: 'sticky',
|
|
1429
|
+
left: `${leftPosition}px`,
|
|
1430
|
+
zIndex: 11,
|
|
1431
|
+
transform: 'translateZ(0)',
|
|
1432
|
+
willChange: 'transform'
|
|
1433
|
+
}),
|
|
1434
|
+
...(isPinnedRight && {
|
|
1435
|
+
position: 'sticky',
|
|
1436
|
+
right: `${rightPosition}px`,
|
|
1437
|
+
zIndex: 12,
|
|
1438
|
+
backgroundColor: 'color-mix(in srgb, rgb(var(--color-primary)) 10%, rgb(var(--bg-surface)))',
|
|
1439
|
+
transform: 'translateZ(0)',
|
|
1440
|
+
willChange: 'transform'
|
|
1441
|
+
})
|
|
1442
|
+
} }, header.id));
|
|
1443
|
+
})] }, headerGroup.id));
|
|
1444
|
+
}
|
|
1445
|
+
else {
|
|
1446
|
+
// Column reordering mode - use SortableContext
|
|
1447
|
+
return (_jsx(SortableContext, { items: headerGroup.headers.map(header => header.column.id), strategy: horizontalListSortingStrategy, children: _jsx("tr", { className: "border-b border-[rgb(var(--bd-default))]", children: headerGroup.headers.map((header, headerIndex) => {
|
|
1448
|
+
const isFrozen = frozenColumnsState.has(header.id);
|
|
1449
|
+
const isPinnedRight = header.column.getIsPinned() === 'right';
|
|
1450
|
+
// Check if this is the last column
|
|
1451
|
+
const isLastColumn = headerIndex === headerGroup.headers.length - 1;
|
|
1452
|
+
// Check if this is the last frozen column
|
|
1453
|
+
const isLastFrozenColumn = isFrozen && (headerIndex === headerGroup.headers.length - 1 ||
|
|
1454
|
+
!frozenColumnsState.has(headerGroup.headers[headerIndex + 1]?.id));
|
|
1455
|
+
// Check if this is the first right-pinned column
|
|
1456
|
+
const isFirstPinnedRight = isPinnedRight && (headerIndex === 0 ||
|
|
1457
|
+
headerGroup.headers[headerIndex - 1]?.column.getIsPinned() !== 'right');
|
|
1458
|
+
// Calculate left position for frozen columns
|
|
1459
|
+
let leftPosition = 0;
|
|
1460
|
+
if (isFrozen) {
|
|
1461
|
+
// Sum up widths of all previous frozen columns
|
|
1462
|
+
for (let i = 0; i < headerIndex; i++) {
|
|
1463
|
+
const prevHeader = headerGroup.headers[i];
|
|
1464
|
+
if (frozenColumnsState.has(prevHeader.id)) {
|
|
1465
|
+
leftPosition += prevHeader.getSize();
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
// Calculate right position for right-pinned columns
|
|
1470
|
+
let rightPosition = 0;
|
|
1471
|
+
if (isPinnedRight) {
|
|
1472
|
+
for (let i = headerIndex + 1; i < headerGroup.headers.length; i++) {
|
|
1473
|
+
const nextHeader = headerGroup.headers[i];
|
|
1474
|
+
if (nextHeader.column.getIsPinned() === 'right') {
|
|
1475
|
+
rightPosition += nextHeader.getSize();
|
|
1476
|
+
}
|
|
1477
|
+
}
|
|
1478
|
+
}
|
|
1479
|
+
return (_jsx(DraggableColumnHeader, { header: header, enableReordering: enableColumnReordering, enableResizing: enableColumnResizing, enableFreezing: enableColumnFreezing, enableGrouping: enableGrouping, isGrouped: grouping.includes(header.column.id), isFrozen: isFrozen, isLastFrozen: isLastFrozenColumn, isFirstPinnedRight: isFirstPinnedRight, isLastColumn: isLastColumn, onRightClick: handleColumnRightClick, onFilterClick: handleColumnRightClick, style: {
|
|
1480
|
+
...(isFrozen && {
|
|
1481
|
+
position: 'sticky',
|
|
1482
|
+
left: `${leftPosition}px`,
|
|
1483
|
+
zIndex: 11,
|
|
1484
|
+
transform: 'translateZ(0)',
|
|
1485
|
+
willChange: 'transform'
|
|
1486
|
+
}),
|
|
1487
|
+
...(isPinnedRight && {
|
|
1488
|
+
position: 'sticky',
|
|
1489
|
+
right: `${rightPosition}px`,
|
|
1490
|
+
zIndex: 12,
|
|
1491
|
+
backgroundColor: 'color-mix(in srgb, rgb(var(--color-primary)) 10%, rgb(var(--bg-surface)))',
|
|
1492
|
+
transform: 'translateZ(0)',
|
|
1493
|
+
willChange: 'transform'
|
|
1494
|
+
})
|
|
1495
|
+
} }, header.id));
|
|
1496
|
+
}) }) }, headerGroup.id));
|
|
1497
|
+
}
|
|
1498
|
+
}), enableFilterRow && (_jsx(FilterRow, { table: table, frozenColumnsState: frozenColumnsState, isRowReorderingActive: isRowReorderingActive, onColumnFilterChange: () => {
|
|
1499
|
+
// Clear global filter when column filter is used - they should work independently
|
|
1500
|
+
if (globalFilter) {
|
|
1501
|
+
setGlobalFilter('');
|
|
1502
|
+
setSearchValue('');
|
|
1503
|
+
}
|
|
1504
|
+
} }))] }), _jsx("tbody", { children: (() => {
|
|
1505
|
+
// Allow reordering when: 1) viewMode is 'selected', OR 2) viewToggle is disabled (simple mode)
|
|
1506
|
+
const isRowReorderingActive = enableRowReordering && (viewMode === 'selected' || !enableViewToggle) && !loading && table.getRowModel().rows.length > 0;
|
|
1507
|
+
const showDragHandle = isRowReorderingActive;
|
|
1508
|
+
return (_jsx(_Fragment, { children: loading ? (_jsx(_Fragment, { children: Array.from({ length: compactMode ? 3 : Math.min(pageSize || 10, 10) }).map((_, skeletonIndex) => (_jsxs("tr", { className: "hover:bg-[rgb(var(--bg-hover))] transition-colors", style: { height: `${rowHeight}px` }, children: [showDragHandle && (_jsx("td", { className: "px-1 py-1 border-b border-[rgb(var(--bd-subtle))]", style: { width: '2.5rem' }, children: _jsx(Skeleton, { width: "20px", height: "12px" }) })), table.getVisibleFlatColumns().map((column, colIndex) => (_jsx("td", { className: "px-1 py-1 border-b border-[rgb(var(--bd-subtle))]", children: _jsx(Skeleton, { width: colIndex === 0 ? '60%' : '85%', height: "12px" }) }, column.id)))] }, `skeleton-${skeletonIndex}`))) })) : table.getRowModel().rows.length === 0 ? (_jsx(_Fragment, { children: Array.from({ length: compactMode ? 3 : Math.min(pageSize || 10, 10) }).map((_, skeletonIndex) => (_jsxs("tr", { className: "transition-colors", style: { height: `${rowHeight}px` }, children: [showDragHandle && (_jsx("td", { className: "px-1 py-1 border-b border-[rgb(var(--bd-subtle))]", style: { width: '2.5rem' }, children: _jsx(Skeleton, { width: "20px", height: "12px" }) })), table.getVisibleFlatColumns().map((column, colIndex) => (_jsx("td", { className: "px-1 py-1 border-b border-[rgb(var(--bd-subtle))]", children: _jsx(Skeleton, { width: colIndex === 0 ? '60%' : '85%', height: "12px" }) }, column.id)))] }, `empty-skeleton-${skeletonIndex}`))) })) : isRowReorderingActive ? (
|
|
1509
|
+
/* Row reordering mode - DndContext is at table level */
|
|
1510
|
+
_jsx(SortableContext, { items: rows.map(row => row.original.id || row.id), strategy: verticalListSortingStrategy, children: rows.map((row, rowIndex) => {
|
|
1511
|
+
const rowId = row.original.id || row.id;
|
|
1512
|
+
const isHighlighted = navigationState.highlightedRowId === rowId;
|
|
1513
|
+
const isSelected = row.getIsSelected();
|
|
1514
|
+
return (_jsx(DraggableRow, { row: row, rowIndex: rowIndex, enableBacchaSearch: enableBacchaSearch, mainColumnsArray: mainColumnsArray, frozenColumnsState: frozenColumnsState, isHighlighted: isHighlighted, isSelected: isSelected, onRowClick: (e) => handleRowClick(row, rowIndex, e), onRowDoubleClick: () => onRowClick?.(row.original), onRowContextMenu: (e) => {
|
|
1515
|
+
if (onRowContextMenu) {
|
|
1516
|
+
e.preventDefault();
|
|
1517
|
+
onRowContextMenu(row.original, e);
|
|
1518
|
+
}
|
|
1519
|
+
}, showDragHandle: showDragHandle, navigationState: navigationState, columnSearches: columnSearches, isColumnSearchActive: isColumnSearchActive, onColumnSearch: handleColumnSearch, onClearColumnSearch: handleClearColumnSearch, SearchHighlighter: SearchHighlighter, InlineSearchCell: InlineSearchCell, className: getRowProps?.(row.original)?.className, rowStyle: getRowProps?.(row.original)?.style }, row.id));
|
|
1520
|
+
}) })) : (
|
|
1521
|
+
/* Virtualized row rendering */
|
|
1522
|
+
_jsx(_Fragment, { children: enableVirtualization && currentView === 'grid' ? (_jsxs(_Fragment, { children: [rowVirtualizer.getVirtualItems().length > 0 && (_jsx("tr", { children: _jsx("td", { colSpan: table.getVisibleFlatColumns().length, style: { height: `${rowVirtualizer.getVirtualItems()[0]?.start ?? 0}px` } }) })), rowVirtualizer.getVirtualItems().map((virtualRow) => {
|
|
1523
|
+
const row = rows[virtualRow.index];
|
|
1524
|
+
const rowIndex = virtualRow.index;
|
|
1525
|
+
const rowId = row.original.id || row.id;
|
|
1526
|
+
const isHighlighted = navigationState.highlightedRowId === rowId;
|
|
1527
|
+
const isSelected = row.getIsSelected();
|
|
1528
|
+
return (_jsx(ExpandableRow, { row: row, renderSubComponent: renderSubComponent, expandMode: expandMode, subData: getSubData && !globalFilter && columnFilters.length === 0 ? getSubData(row.original) : undefined, subColumns: columns, getSubRowId: getSubRowId, getSubRowProps: getRowProps, onSubRowClick: onSubRowClick, onSubRowSelect: onSubRowSelect, onRowClick: (e) => handleRowClick(row, rowIndex, e), onRowDoubleClick: () => onRowClick?.(row.original), onRowContextMenu: (e) => {
|
|
1529
|
+
if (onRowContextMenu) {
|
|
1530
|
+
e.preventDefault();
|
|
1531
|
+
onRowContextMenu(row.original, e);
|
|
1532
|
+
}
|
|
1533
|
+
}, style: getRowProps?.(row.original)?.style, className: `
|
|
1534
|
+
cursor-pointer group
|
|
1535
|
+
transition-colors duration-150 ease-out
|
|
1536
|
+
${isHighlighted
|
|
1537
|
+
? 'border-2 border-[rgb(var(--color-primary))] bg-gradient-to-r from-[rgb(var(--color-primary))]/10 to-[rgb(var(--color-primary))]/20 shadow-lg relative'
|
|
1538
|
+
: isSelected
|
|
1539
|
+
? 'bg-[color-mix(in_srgb,rgb(var(--color-primary))_8%,rgb(var(--bg-surface)))] shadow-sm hover:bg-[color-mix(in_srgb,rgb(var(--color-primary))_15%,rgb(var(--bg-surface)))]'
|
|
1540
|
+
: 'hover:bg-[color-mix(in_srgb,rgb(var(--color-primary))_5%,rgb(var(--bg-surface)))]'}
|
|
1541
|
+
${getRowProps?.(row.original)?.className ?? ''}
|
|
1542
|
+
`, children: row.getVisibleCells().map((cell, cellIndex) => (_jsx(CellRenderer, { cell: cell, cellIndex: cellIndex, row: row, enableBacchaSearch: enableBacchaSearch, mainColumnsArray: mainColumnsArray, frozenColumnsState: frozenColumnsState, navigationState: navigationState, columnSearches: columnSearches, isColumnSearchActive: isColumnSearchActive, onColumnSearch: handleColumnSearch, onClearColumnSearch: handleClearColumnSearch, SearchHighlighter: SearchHighlighter, InlineSearchCell: InlineSearchCell, isSelected: isSelected }, cell.id))) }, row.id));
|
|
1543
|
+
}), rowVirtualizer.getVirtualItems().length > 0 && (_jsx("tr", { children: _jsx("td", { colSpan: table.getVisibleFlatColumns().length, style: {
|
|
1544
|
+
height: `${rowVirtualizer.getTotalSize() -
|
|
1545
|
+
(rowVirtualizer.getVirtualItems()[rowVirtualizer.getVirtualItems().length - 1]?.end ?? 0)}px`,
|
|
1546
|
+
} }) }))] })) : (
|
|
1547
|
+
/* Non-virtualized rendering (fallback) */
|
|
1548
|
+
rows.map((row, rowIndex) => {
|
|
1549
|
+
const rowId = row.original.id || row.id;
|
|
1550
|
+
const isHighlighted = navigationState.highlightedRowId === rowId;
|
|
1551
|
+
const isSelected = row.getIsSelected();
|
|
1552
|
+
return (_jsx(ExpandableRow, { row: row, renderSubComponent: renderSubComponent, expandMode: expandMode, subData: getSubData && !globalFilter && columnFilters.length === 0 ? getSubData(row.original) : undefined, subColumns: columns, getSubRowId: getSubRowId, getSubRowProps: getRowProps, onSubRowClick: onSubRowClick, onSubRowSelect: onSubRowSelect, onRowClick: (e) => handleRowClick(row, rowIndex, e), onRowDoubleClick: () => onRowClick?.(row.original), onRowContextMenu: (e) => {
|
|
1553
|
+
if (onRowContextMenu) {
|
|
1554
|
+
e.preventDefault();
|
|
1555
|
+
onRowContextMenu(row.original, e);
|
|
1556
|
+
}
|
|
1557
|
+
}, rowHeight: rowHeight, style: getRowProps?.(row.original)?.style, className: `
|
|
1558
|
+
cursor-pointer group
|
|
1559
|
+
transition-colors duration-150 ease-out
|
|
1560
|
+
${isHighlighted
|
|
1561
|
+
? 'border-2 border-primary bg-gradient-to-r from-primary/10 to-primary/20 shadow-lg relative z-10'
|
|
1562
|
+
: isSelected
|
|
1563
|
+
? 'bg-[rgb(var(--bg-selected))] shadow-sm hover:bg-[rgb(var(--bg-hover))]'
|
|
1564
|
+
: 'hover:bg-[rgb(var(--bg-hover))]'}
|
|
1565
|
+
${getRowProps?.(row.original)?.className ?? ''}
|
|
1566
|
+
`, children: row.getVisibleCells().map((cell, cellIndex) => (_jsx(CellRenderer, { cell: cell, cellIndex: cellIndex, row: row, enableBacchaSearch: enableBacchaSearch, mainColumnsArray: mainColumnsArray, frozenColumnsState: frozenColumnsState, navigationState: navigationState, columnSearches: columnSearches, isColumnSearchActive: isColumnSearchActive, onColumnSearch: handleColumnSearch, onClearColumnSearch: handleClearColumnSearch, SearchHighlighter: SearchHighlighter, InlineSearchCell: InlineSearchCell, isSelected: isSelected }, cell.id))) }, row.id));
|
|
1567
|
+
})) })) }));
|
|
1568
|
+
})() }), enableSummary && summaryConfig && (_jsx(SummaryRow, { table: table, data: processedData, config: summaryConfig, enableRowSelection: enableRowSelection, showDragHandle: isRowReorderingActive }))] }), !loading && table.getRowModel().rows.length === 0 && (_jsx("div", { className: "absolute left-0 right-0 bottom-0 flex items-center justify-center pointer-events-none z-10", style: { top: '44px' }, children: _jsx("span", { className: "text-[rgb(var(--fg-muted))] text-sm", children: "No data available" }) }))] }) }));
|
|
1569
|
+
})() }) }, "grid")) : currentView === 'cards' ? (_jsx(motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 }, transition: { duration: 0.2 }, children: _jsx(CardView, { data: table.getFilteredRowModel().rows.map(row => row.original), columns: columns, onRowClick: onRowClick, selectedRows: selectedRows, cardSize: "compact", circularCheckboxes: circularCheckboxes, getCardClassName: getRowProps ? (item) => getRowProps(item).className : undefined, onRowSelect: (item, selected) => {
|
|
1570
|
+
const rowIndex = table.getFilteredRowModel().rows.findIndex(row => row.original === item);
|
|
1571
|
+
if (rowIndex !== -1) {
|
|
1572
|
+
table.getFilteredRowModel().rows[rowIndex].toggleSelected(selected);
|
|
1573
|
+
}
|
|
1574
|
+
} }) }, "cards")) : (_jsx(motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 }, transition: { duration: 0.2 }, children: _jsx(React.Suspense, { fallback: _jsx("div", { className: "flex justify-center p-6", children: _jsx("div", { className: "h-6 w-6 animate-spin rounded-full border-2 border-[rgb(var(--color-primary))] border-t-transparent" }) }), children: _jsx(DataVisualization, { data: processedData, columns: columns, title: "Data Insights" }) }) }, "chart")) }) }), _jsx(AdvancedFilterModal, { isOpen: showAdvancedFilter, onClose: () => setShowAdvancedFilter(false), onApply: handleAdvancedFilter, columns: columns, data: filteredData, initialTab: settingsInitialTab, table: table, sorting: sorting, onSortingChange: setSorting, enableGrouping: enableGrouping, grouping: grouping, onGroupingChange: (columnId) => {
|
|
1575
|
+
setGrouping((prev) => prev.includes(columnId) ? prev.filter((id) => id !== columnId) : [...prev, columnId]);
|
|
1576
|
+
}, onClearGrouping: () => setGrouping([]) }), contextMenu.column && (_jsx(ColumnContextMenu, { column: contextMenu.column, table: table, data: data, isVisible: contextMenu.isVisible, position: contextMenu.position, onClose: handleCloseContextMenu, onApplyFilter: handleApplyColumnFilter })), enablePagination && currentView === 'grid' && (_jsx(PaginationControls, { pageIndex: table.getState().pagination.pageIndex, pageSize: table.getState().pagination.pageSize, totalRows: filteredData.length, pageSizeOptions: paginationPageSizeOptions, onPageChange: (pageIndex) => table.setPageIndex(pageIndex), onPageSizeChange: (pageSize) => table.setPageSize(pageSize) }))] }));
|
|
1577
|
+
}
|