@burdenoff/microfe-bigconsole 2026.805.3 → 2026.812.2
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/bigconsole/components/DrilldownDashboardRenderer.js +118 -106
- package/dist/bigconsole/components/DrilldownDashboardRenderer.js.map +1 -1
- package/dist/bigconsole/components/DrilldownModal.js +54 -50
- package/dist/bigconsole/components/DrilldownModal.js.map +1 -1
- package/dist/bigconsole/components/builder/BuilderCanvas.js +2 -2
- package/dist/bigconsole/components/builder/BuilderCanvas.js.map +1 -1
- package/dist/bigconsole/components/builder/BuilderTopbar.js +3 -3
- package/dist/bigconsole/components/builder/BuilderTopbar.js.map +1 -1
- package/dist/bigconsole/components/builder/inspector/AdvancedSection.js +24 -25
- package/dist/bigconsole/components/builder/inspector/AdvancedSection.js.map +1 -1
- package/dist/bigconsole/components/builder/inspector/AppearanceSection.js +40 -29
- package/dist/bigconsole/components/builder/inspector/AppearanceSection.js.map +1 -1
- package/dist/bigconsole/components/builder/inspector/DataBindingSection.js +135 -97
- package/dist/bigconsole/components/builder/inspector/DataBindingSection.js.map +1 -1
- package/dist/bigconsole/components/builder/inspector/GeneralSection.js +58 -44
- package/dist/bigconsole/components/builder/inspector/GeneralSection.js.map +1 -1
- package/dist/bigconsole/components/common/Section.js +70 -0
- package/dist/bigconsole/components/common/Section.js.map +1 -0
- package/dist/bigconsole/components/common/index.js +2 -0
- package/dist/bigconsole/components/common/sectionStyles.js +42 -0
- package/dist/bigconsole/components/common/sectionStyles.js.map +1 -0
- package/dist/bigconsole/components/dashboard/CreateDashboardDialog.js +209 -193
- package/dist/bigconsole/components/dashboard/CreateDashboardDialog.js.map +1 -1
- package/dist/bigconsole/components/dashboard/DashboardCanvas.js +213 -231
- package/dist/bigconsole/components/dashboard/DashboardCanvas.js.map +1 -1
- package/dist/bigconsole/components/dashboard/DashboardGrid.js +12 -18
- package/dist/bigconsole/components/dashboard/DashboardGrid.js.map +1 -1
- package/dist/bigconsole/components/dashboard/DashboardToolbar.js +109 -102
- package/dist/bigconsole/components/dashboard/DashboardToolbar.js.map +1 -1
- package/dist/bigconsole/components/dashboard/DrilldownBreadcrumb.js +81 -70
- package/dist/bigconsole/components/dashboard/DrilldownBreadcrumb.js.map +1 -1
- package/dist/bigconsole/components/dashboard/ExportDashboardDialog.js +125 -159
- package/dist/bigconsole/components/dashboard/ExportDashboardDialog.js.map +1 -1
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterChip.js +25 -23
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterChip.js.map +1 -1
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.js +3 -3
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.js.map +1 -1
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterPresetSelector.js +5 -3
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterPresetSelector.js.map +1 -1
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.js +170 -284
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.js.map +1 -1
- package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js +147 -151
- package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js.map +1 -1
- package/dist/bigconsole/components/dashboard/LiveBoardBanner.js +45 -53
- package/dist/bigconsole/components/dashboard/LiveBoardBanner.js.map +1 -1
- package/dist/bigconsole/components/dashboard/PageTabsManager/PageTabsManager.js +157 -148
- package/dist/bigconsole/components/dashboard/PageTabsManager/PageTabsManager.js.map +1 -1
- package/dist/bigconsole/components/dashboard/SavedViewsDropdown/SavedViewsDropdown.js +17 -8
- package/dist/bigconsole/components/dashboard/SavedViewsDropdown/SavedViewsDropdown.js.map +1 -1
- package/dist/bigconsole/components/dashboard/ShareDialog/ShareDialog.js +101 -95
- package/dist/bigconsole/components/dashboard/ShareDialog/ShareDialog.js.map +1 -1
- package/dist/bigconsole/components/dashboard/StoreTemplatePicker.js +20 -18
- package/dist/bigconsole/components/dashboard/StoreTemplatePicker.js.map +1 -1
- package/dist/bigconsole/components/dashboard/TemplateSetupBanner.js +26 -58
- package/dist/bigconsole/components/dashboard/TemplateSetupBanner.js.map +1 -1
- package/dist/bigconsole/components/dashboard/WidgetPalette.js +307 -231
- package/dist/bigconsole/components/dashboard/WidgetPalette.js.map +1 -1
- package/dist/bigconsole/components/datasink/CacheTTLSelector.js +29 -29
- package/dist/bigconsole/components/datasink/CacheTTLSelector.js.map +1 -1
- package/dist/bigconsole/components/datasink/DataSinkCard.js +78 -79
- package/dist/bigconsole/components/datasink/DataSinkCard.js.map +1 -1
- package/dist/bigconsole/components/datasink/DataSinkDataViewer.js +33 -34
- package/dist/bigconsole/components/datasink/DataSinkDataViewer.js.map +1 -1
- package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js +79 -56
- package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js.map +1 -1
- package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js +75 -65
- package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js.map +1 -1
- package/dist/bigconsole/components/datasink/DataSinkStatusBadge.js +1 -1
- package/dist/bigconsole/components/datasink/DataSinkStatusBadge.js.map +1 -1
- package/dist/bigconsole/components/datasink/DataSinkTableViewer.js +20 -19
- package/dist/bigconsole/components/datasink/DataSinkTableViewer.js.map +1 -1
- package/dist/bigconsole/components/datasink/ExportDataSinkDialog.js +127 -171
- package/dist/bigconsole/components/datasink/ExportDataSinkDialog.js.map +1 -1
- package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js +263 -243
- package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js.map +1 -1
- package/dist/bigconsole/components/datasink/LinkedParsersPanel.js +65 -66
- package/dist/bigconsole/components/datasink/LinkedParsersPanel.js.map +1 -1
- package/dist/bigconsole/components/datasink/LinkedWorkflowsPanel.js +121 -127
- package/dist/bigconsole/components/datasink/LinkedWorkflowsPanel.js.map +1 -1
- package/dist/bigconsole/components/datasink/RefreshTypeSelector.js +33 -26
- package/dist/bigconsole/components/datasink/RefreshTypeSelector.js.map +1 -1
- package/dist/bigconsole/components/datasink/SetupStateBadge.js +3 -3
- package/dist/bigconsole/components/datasink/SetupStateBadge.js.map +1 -1
- package/dist/bigconsole/components/datasink/WorkflowStatusPanel.js +95 -95
- package/dist/bigconsole/components/datasink/WorkflowStatusPanel.js.map +1 -1
- package/dist/bigconsole/components/parser/DataSinkSelector.js +154 -123
- package/dist/bigconsole/components/parser/DataSinkSelector.js.map +1 -1
- package/dist/bigconsole/components/parser/ExpressionEditor.js +3 -3
- package/dist/bigconsole/components/parser/ExpressionEditor.js.map +1 -1
- package/dist/bigconsole/components/parser/ImportParserDialog.js +235 -275
- package/dist/bigconsole/components/parser/ImportParserDialog.js.map +1 -1
- package/dist/bigconsole/components/parser/ParserCard.js +133 -114
- package/dist/bigconsole/components/parser/ParserCard.js.map +1 -1
- package/dist/bigconsole/components/parser/ParserSelector.js +191 -174
- package/dist/bigconsole/components/parser/ParserSelector.js.map +1 -1
- package/dist/bigconsole/components/parser/ParserStatusBadge.js +2 -2
- package/dist/bigconsole/components/parser/ParserStatusBadge.js.map +1 -1
- package/dist/bigconsole/components/parser/ParserTypeBadge.js +4 -4
- package/dist/bigconsole/components/parser/ParserTypeBadge.js.map +1 -1
- package/dist/bigconsole/components/pipeline/PipelineCard.js +134 -89
- package/dist/bigconsole/components/pipeline/PipelineCard.js.map +1 -1
- package/dist/bigconsole/components/pipeline/PipelineDeleteDialog.js +77 -64
- package/dist/bigconsole/components/pipeline/PipelineDeleteDialog.js.map +1 -1
- package/dist/bigconsole/components/pipeline/PipelineStatusBadge.js +7 -10
- package/dist/bigconsole/components/pipeline/PipelineStatusBadge.js.map +1 -1
- package/dist/bigconsole/components/preview/AiPreviewContent.js +31 -32
- package/dist/bigconsole/components/preview/AiPreviewContent.js.map +1 -1
- package/dist/bigconsole/components/preview/AiPreviewMiniPanel.js +152 -106
- package/dist/bigconsole/components/preview/AiPreviewMiniPanel.js.map +1 -1
- package/dist/bigconsole/components/preview/AiPreviewPanel.js +193 -152
- package/dist/bigconsole/components/preview/AiPreviewPanel.js.map +1 -1
- package/dist/bigconsole/components/preview/previewShared.js +41 -23
- package/dist/bigconsole/components/preview/previewShared.js.map +1 -1
- package/dist/bigconsole/components/widgets/ActionConfigDialog.js +342 -308
- package/dist/bigconsole/components/widgets/ActionConfigDialog.js.map +1 -1
- package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js +262 -238
- package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js.map +1 -1
- package/dist/bigconsole/components/widgets/PropertiesPanel.js +783 -867
- package/dist/bigconsole/components/widgets/PropertiesPanel.js.map +1 -1
- package/dist/bigconsole/components/widgets/WidgetErrorBoundary.js +7 -5
- package/dist/bigconsole/components/widgets/WidgetErrorBoundary.js.map +1 -1
- package/dist/bigconsole/components/widgets/WidgetHeader.js +7 -8
- package/dist/bigconsole/components/widgets/WidgetHeader.js.map +1 -1
- package/dist/bigconsole/components/widgets/WidgetRegistry.js +4 -4
- package/dist/bigconsole/components/widgets/WidgetRegistry.js.map +1 -1
- package/dist/bigconsole/components/widgets/WidgetWrapper.js +8 -7
- package/dist/bigconsole/components/widgets/WidgetWrapper.js.map +1 -1
- package/dist/bigconsole/components/widgets/adaptive-card/AdaptiveCardWidget.js +1 -1
- package/dist/bigconsole/components/widgets/adaptive-card/AdaptiveCardWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js +2 -2
- package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/chart/ChartConfig.js +11 -5
- package/dist/bigconsole/components/widgets/chart/ChartConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/comments/WidgetComments.js +19 -15
- package/dist/bigconsole/components/widgets/comments/WidgetComments.js.map +1 -1
- package/dist/bigconsole/components/widgets/event-logs/EventLogViewer.js +154 -102
- package/dist/bigconsole/components/widgets/event-logs/EventLogViewer.js.map +1 -1
- package/dist/bigconsole/components/widgets/gauge/CircularGauge.js +36 -32
- package/dist/bigconsole/components/widgets/gauge/CircularGauge.js.map +1 -1
- package/dist/bigconsole/components/widgets/gauge/GaugeConfig.js +85 -60
- package/dist/bigconsole/components/widgets/gauge/GaugeConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/gauge/GaugeWidget.js +64 -35
- package/dist/bigconsole/components/widgets/gauge/GaugeWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/gauge/LinearGauge.js +46 -45
- package/dist/bigconsole/components/widgets/gauge/LinearGauge.js.map +1 -1
- package/dist/bigconsole/components/widgets/heatmap/HeatmapConfig.js +35 -24
- package/dist/bigconsole/components/widgets/heatmap/HeatmapConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/iframe-widget/IframeWidget.js +2 -2
- package/dist/bigconsole/components/widgets/iframe-widget/IframeWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js +4 -4
- package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/kpi-comparison/KPIComparisonWidget.js +153 -90
- package/dist/bigconsole/components/widgets/kpi-comparison/KPIComparisonWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/list/ListConfig.js +8 -2
- package/dist/bigconsole/components/widgets/list/ListConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/list/ListItem.js +1 -1
- package/dist/bigconsole/components/widgets/list/ListItem.js.map +1 -1
- package/dist/bigconsole/components/widgets/map-widget/MapWidget.js +1 -1
- package/dist/bigconsole/components/widgets/map-widget/MapWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/metric-card/MetricCardConfig.js +14 -4
- package/dist/bigconsole/components/widgets/metric-card/MetricCardConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/metric-card/MetricCardWidget.js +112 -89
- package/dist/bigconsole/components/widgets/metric-card/MetricCardWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/metric-card/SparklineChart.js +21 -13
- package/dist/bigconsole/components/widgets/metric-card/SparklineChart.js.map +1 -1
- package/dist/bigconsole/components/widgets/metric-card/index.js +4 -4
- package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js +3 -3
- package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/progress/ProgressConfig.js +34 -25
- package/dist/bigconsole/components/widgets/progress/ProgressConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/progress/ProgressWidget.js +129 -114
- package/dist/bigconsole/components/widgets/progress/ProgressWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/retention/RetentionWidget.js +3 -3
- package/dist/bigconsole/components/widgets/retention/RetentionWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/states/EmptyState.js +6 -4
- package/dist/bigconsole/components/widgets/states/EmptyState.js.map +1 -1
- package/dist/bigconsole/components/widgets/states/ErrorState.js +7 -5
- package/dist/bigconsole/components/widgets/states/ErrorState.js.map +1 -1
- package/dist/bigconsole/components/widgets/states/LoadingState.js +5 -4
- package/dist/bigconsole/components/widgets/states/LoadingState.js.map +1 -1
- package/dist/bigconsole/components/widgets/table/TableConfig.js +10 -4
- package/dist/bigconsole/components/widgets/table/TableConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/table/TableHeader.js +1 -1
- package/dist/bigconsole/components/widgets/table/TableHeader.js.map +1 -1
- package/dist/bigconsole/components/widgets/table/TableWidget.js +1 -1
- package/dist/bigconsole/components/widgets/table/TableWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/text-widget/TextWidget.js +1 -1
- package/dist/bigconsole/components/widgets/text-widget/TextWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/timeline/TimelineWidget.js +3 -3
- package/dist/bigconsole/components/widgets/timeline/TimelineWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/utils/conditionalFormat.js +2 -2
- package/dist/bigconsole/components/widgets/utils/conditionalFormat.js.map +1 -1
- package/dist/bigconsole/components/widgets/utils/targetProgress.js +13 -0
- package/dist/bigconsole/components/widgets/utils/targetProgress.js.map +1 -0
- package/dist/bigconsole/components/widgets/webhook-config/WebhookConfigPanel.js +112 -85
- package/dist/bigconsole/components/widgets/webhook-config/WebhookConfigPanel.js.map +1 -1
- package/dist/bigconsole/components/widgets/widget-actions/WidgetActions.js +28 -20
- package/dist/bigconsole/components/widgets/widget-actions/WidgetActions.js.map +1 -1
- package/dist/bigconsole/components/workflow/WorkflowCard.js +92 -77
- package/dist/bigconsole/components/workflow/WorkflowCard.js.map +1 -1
- package/dist/bigconsole/components/workflow/WorkflowDeleteDialog.js +70 -51
- package/dist/bigconsole/components/workflow/WorkflowDeleteDialog.js.map +1 -1
- package/dist/bigconsole/components/workflow/WorkflowStatusBadge.js +16 -17
- package/dist/bigconsole/components/workflow/WorkflowStatusBadge.js.map +1 -1
- package/dist/bigconsole/customWidget/CustomWidgetBuilderSheet.js +6 -4
- package/dist/bigconsole/customWidget/CustomWidgetBuilderSheet.js.map +1 -1
- package/dist/bigconsole/customWidget/CustomWidgetProposalPanel.js +360 -338
- package/dist/bigconsole/customWidget/CustomWidgetProposalPanel.js.map +1 -1
- package/dist/bigconsole/hooks/useModalFocusTrap.js +53 -0
- package/dist/bigconsole/hooks/useModalFocusTrap.js.map +1 -0
- package/dist/bigconsole/pages/DashboardBuilderPage.js +209 -203
- package/dist/bigconsole/pages/DashboardBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/DashboardViewPage.js +126 -120
- package/dist/bigconsole/pages/DashboardViewPage.js.map +1 -1
- package/dist/bigconsole/pages/DashboardsPage.js +838 -800
- package/dist/bigconsole/pages/DashboardsPage.js.map +1 -1
- package/dist/bigconsole/pages/DataParsersPage.js +263 -315
- package/dist/bigconsole/pages/DataParsersPage.js.map +1 -1
- package/dist/bigconsole/pages/DataSinkBuilderPage.js +301 -341
- package/dist/bigconsole/pages/DataSinkBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/DataSinkViewPage.js +346 -339
- package/dist/bigconsole/pages/DataSinkViewPage.js.map +1 -1
- package/dist/bigconsole/pages/DataSinksPage.js +356 -458
- package/dist/bigconsole/pages/DataSinksPage.js.map +1 -1
- package/dist/bigconsole/pages/DataSourcesPage.js +7 -2
- package/dist/bigconsole/pages/DataSourcesPage.js.map +1 -1
- package/dist/bigconsole/pages/HomePage.js +186 -193
- package/dist/bigconsole/pages/HomePage.js.map +1 -1
- package/dist/bigconsole/pages/InsightsPage.js +887 -740
- package/dist/bigconsole/pages/InsightsPage.js.map +1 -1
- package/dist/bigconsole/pages/ParserBuilderPage.js +679 -637
- package/dist/bigconsole/pages/ParserBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/ParserViewPage.js +368 -342
- package/dist/bigconsole/pages/ParserViewPage.js.map +1 -1
- package/dist/bigconsole/pages/PipelineBuilderPage.js +537 -444
- package/dist/bigconsole/pages/PipelineBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/PipelineViewPage.js +412 -377
- package/dist/bigconsole/pages/PipelineViewPage.js.map +1 -1
- package/dist/bigconsole/pages/PipelinesPage.js +248 -298
- package/dist/bigconsole/pages/PipelinesPage.js.map +1 -1
- package/dist/bigconsole/pages/WidgetDemoPage.js +251 -153
- package/dist/bigconsole/pages/WidgetDemoPage.js.map +1 -1
- package/dist/bigconsole/pages/WorkflowViewPage.js +381 -371
- package/dist/bigconsole/pages/WorkflowViewPage.js.map +1 -1
- package/dist/bigconsole/pages/WorkflowsPage.js +171 -286
- package/dist/bigconsole/pages/WorkflowsPage.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilterChip.js","names":[],"sources":["../../../../../src/bigconsole/components/dashboard/GlobalFiltersBar/FilterChip.tsx"],"sourcesContent":["/**\n * FilterChip Component\n *\n * Individual filter chip with value display and controls.\n */\n\nimport React, { useState, useRef, useEffect } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport type { GlobalFilter, FilterType } from '../../../hooks';\n\ntype TranslateFn = (\n key: string,\n fallbackOrParams?: string | Record<string, string | number>,\n params?: Record<string, string | number>\n) => string;\n\n// Dynamic colors that respect dark mode\nconst getColors = (isDark: boolean) => ({\n bgPrimary: isDark ? '#1f2937' : '#ffffff',\n bgSecondary: isDark ? '#374151' : '#f9fafb',\n textPrimary: isDark ? '#f9fafb' : '#111827',\n textSecondary: isDark ? '#9ca3af' : '#6b7280',\n borderDefault: isDark ? '#4b5563' : '#e5e7eb',\n actionPrimaryBg: '#6366f1',\n actionPrimaryBgSubtle: isDark ? '#312e81' : '#eef2ff',\n actionPrimaryFg: '#ffffff',\n bgTertiary: isDark ? '#4b5563' : '#f3f4f6',\n textTertiary: isDark ? '#6b7280' : '#9ca3af',\n statusErrorText: '#ef4444',\n statusErrorBg: isDark ? '#991b1b' : '#fee2e2',\n actionPrimaryText: isDark ? '#c7d2fe' : '#4338ca',\n backdropBg: 'rgba(0, 0, 0, 0.5)',\n});\n\n// Hook to detect dark mode\nfunction useDarkMode() {\n const [isDark, setIsDark] = useState(false);\n\n useEffect(() => {\n const checkDarkMode = () => {\n setIsDark(document.documentElement.classList.contains('dark'));\n };\n checkDarkMode();\n\n const observer = new MutationObserver(checkDarkMode);\n observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] });\n return () => observer.disconnect();\n }, []);\n\n return isDark;\n}\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface FilterChipProps {\n filter: GlobalFilter;\n value: unknown;\n onChange: (value: unknown) => void;\n onEdit: () => void;\n onDelete: () => void;\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Format filter value for display\n * Filter types per spec: DATE_RANGE, CATEGORY, CUSTOM, NUMERIC_RANGE, TEXT_SEARCH\n */\nfunction formatFilterValue(value: unknown, type: FilterType, t: TranslateFn): string {\n if (value === undefined || value === null) {\n return t('bigconsole.filters.chip.value.all', 'All');\n }\n\n switch (type) {\n case 'DATE_RANGE': {\n const dateRange = value as Record<string, unknown>;\n if (dateRange.start && dateRange.end) {\n return `${formatDate(dateRange.start as string)} - ${formatDate(dateRange.end as string)}`;\n }\n return t('bigconsole.filters.chip.value.allDates', 'All dates');\n }\n\n case 'CATEGORY':\n // Category can be single or multiple selection\n if (Array.isArray(value) && value.length > 0) {\n if (value.length === 1) {\n const first = value[0] as Record<string, unknown> | string;\n return (\n (typeof first === 'object' && first !== null\n ? ((first as Record<string, unknown>).label as string)\n : first) || String(value[0])\n );\n }\n return t('bigconsole.filters.chip.value.countSelected', '{{count}} selected', {\n count: value.length,\n });\n }\n if (typeof value === 'object' && value !== null) {\n return ((value as Record<string, unknown>).label as string) || t('bigconsole.filters.chip.value.all', 'All');\n }\n return String(value) || t('bigconsole.filters.chip.value.all', 'All');\n\n case 'TEXT_SEARCH':\n return (value as string) || t('bigconsole.filters.chip.value.any', 'Any');\n\n case 'NUMERIC_RANGE': {\n const numRange = value as Record<string, unknown>;\n if (numRange.min !== undefined && numRange.max !== undefined) {\n return `${numRange.min} - ${numRange.max}`;\n }\n if (numRange.min !== undefined) {\n return `>= ${numRange.min}`;\n }\n if (numRange.max !== undefined) {\n return `<= ${numRange.max}`;\n }\n return t('bigconsole.filters.chip.value.any', 'Any');\n }\n\n case 'CUSTOM':\n // Custom filters may have various value formats\n if (typeof value === 'object') {\n return JSON.stringify(value).substring(0, 30) + '...';\n }\n return String(value);\n\n default:\n return String(value);\n }\n}\n\nfunction formatDate(date: string | Date): string {\n const d = new Date(date);\n return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport function FilterChip({ filter, value, onChange, onEdit, onDelete }: FilterChipProps) {\n const { t } = useI18n();\n const [isOpen, setIsOpen] = useState(false);\n const [showMenu, setShowMenu] = useState(false);\n const chipRef = useRef<HTMLDivElement>(null);\n const menuRef = useRef<HTMLDivElement>(null);\n const isDarkMode = useDarkMode();\n const SEMANTIC_COLORS = getColors(isDarkMode);\n\n const hasValue = value !== undefined && value !== null && value !== '';\n const displayValue = formatFilterValue(value, filter.type, t);\n\n // Close dropdown when clicking outside\n useEffect(() => {\n function handleClickOutside(event: MouseEvent) {\n if (chipRef.current && !chipRef.current.contains(event.target as Node)) {\n setIsOpen(false);\n setShowMenu(false);\n }\n }\n\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, []);\n\n const handleClear = (e: React.MouseEvent) => {\n e.stopPropagation();\n onChange(undefined);\n };\n\n return (\n <div\n ref={chipRef}\n style={{\n position: 'relative',\n display: 'inline-flex',\n alignItems: 'center',\n gap: '8px',\n padding: '8px 16px',\n backgroundColor: hasValue ? SEMANTIC_COLORS.actionPrimaryBgSubtle : SEMANTIC_COLORS.bgPrimary,\n border: `2px solid ${hasValue ? SEMANTIC_COLORS.actionPrimaryBg : SEMANTIC_COLORS.textTertiary}`,\n borderRadius: '24px',\n fontSize: '15px',\n cursor: 'pointer',\n userSelect: 'none',\n boxShadow: '0 2px 6px rgba(0,0,0,0.12)',\n transition: 'all 0.2s ease',\n minHeight: '36px',\n }}\n >\n {/* Filter Name */}\n <span\n style={{\n fontWeight: 700,\n color: hasValue ? SEMANTIC_COLORS.actionPrimaryText : SEMANTIC_COLORS.textPrimary,\n fontSize: '14px',\n }}\n onClick={() => setIsOpen(!isOpen)}\n >\n {filter.name}:\n </span>\n\n {/* Filter Value */}\n <span\n style={{\n color: hasValue ? SEMANTIC_COLORS.actionPrimaryBg : SEMANTIC_COLORS.textSecondary,\n maxWidth: '200px',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n fontWeight: 600,\n fontSize: '14px',\n }}\n onClick={() => setIsOpen(!isOpen)}\n >\n {displayValue}\n </span>\n\n {/* Clear button */}\n {hasValue && (\n <button\n onClick={handleClear}\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '22px',\n height: '22px',\n padding: 0,\n backgroundColor: SEMANTIC_COLORS.statusErrorBg,\n border: 'none',\n borderRadius: '50%',\n cursor: 'pointer',\n color: SEMANTIC_COLORS.actionPrimaryFg,\n fontSize: '14px',\n fontWeight: 'bold',\n marginLeft: '4px',\n boxShadow: '0 1px 3px rgba(0,0,0,0.2)',\n }}\n title={t('bigconsole.filters.chip.action.clear', 'Clear filter')}\n >\n ×\n </button>\n )}\n\n {/* Menu button */}\n <button\n onClick={(e) => {\n e.stopPropagation();\n setShowMenu(!showMenu);\n }}\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '22px',\n height: '22px',\n padding: 0,\n backgroundColor: SEMANTIC_COLORS.textTertiary,\n border: 'none',\n borderRadius: '50%',\n cursor: 'pointer',\n color: SEMANTIC_COLORS.actionPrimaryFg,\n fontSize: '16px',\n fontWeight: 'bold',\n marginLeft: '4px',\n boxShadow: '0 1px 3px rgba(0,0,0,0.2)',\n }}\n title={t('bigconsole.filters.chip.action.options', 'Filter options')}\n >\n ⋮\n </button>\n\n {/* Value Editor Dropdown */}\n {isOpen && (\n <FilterValueEditor\n filter={filter}\n value={value}\n onChange={(newValue) => {\n onChange(newValue);\n setIsOpen(false);\n }}\n onClose={() => setIsOpen(false)}\n />\n )}\n\n {/* Context Menu */}\n {showMenu && (\n <>\n {/* Backdrop */}\n <div\n style={{\n position: 'fixed',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 99998,\n }}\n onClick={(e) => {\n e.stopPropagation();\n setShowMenu(false);\n }}\n />\n <div\n ref={menuRef}\n style={{\n position: 'absolute',\n top: '100%',\n right: 0,\n marginTop: '8px',\n minWidth: '150px',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n border: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n borderRadius: '8px',\n boxShadow: '0 8px 24px rgba(0,0,0,0.2)',\n zIndex: 99999,\n overflow: 'hidden',\n }}\n >\n <button\n onClick={(e) => {\n e.stopPropagation();\n setShowMenu(false);\n onEdit();\n }}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n width: '100%',\n padding: '12px 16px',\n textAlign: 'left',\n backgroundColor: 'transparent',\n border: 'none',\n borderBottom: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n cursor: 'pointer',\n fontSize: '14px',\n color: SEMANTIC_COLORS.textPrimary,\n fontWeight: 500,\n }}\n >\n ✏️ {t('bigconsole.filters.chip.menu.edit', 'Edit Filter')}\n </button>\n <button\n onClick={(e) => {\n e.stopPropagation();\n setShowMenu(false);\n onDelete();\n }}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n width: '100%',\n padding: '12px 16px',\n textAlign: 'left',\n backgroundColor: 'transparent',\n border: 'none',\n cursor: 'pointer',\n fontSize: '14px',\n color: SEMANTIC_COLORS.statusErrorText,\n fontWeight: 500,\n }}\n >\n 🗑️ {t('bigconsole.filters.chip.menu.delete', 'Delete Filter')}\n </button>\n </div>\n </>\n )}\n </div>\n );\n}\n\n// ============================================================================\n// FilterValueEditor Sub-component\n// ============================================================================\n\ninterface FilterValueEditorProps {\n filter: GlobalFilter;\n value: unknown;\n onChange: (value: unknown) => void;\n onClose: () => void;\n}\n\nfunction FilterValueEditor({ filter, value, onChange, onClose }: FilterValueEditorProps) {\n const { t } = useI18n();\n const [localValue, setLocalValue] = useState(value);\n const isDarkMode = useDarkMode();\n const SEMANTIC_COLORS = getColors(isDarkMode);\n\n const handleApply = () => {\n onChange(localValue);\n };\n\n return (\n <>\n {/* Backdrop to capture clicks outside */}\n <div\n style={{\n position: 'fixed',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 99998,\n }}\n onClick={onClose}\n />\n <div\n style={{\n position: 'absolute',\n top: '100%',\n left: 0,\n marginTop: '8px',\n minWidth: '280px',\n padding: '16px',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n border: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n borderRadius: '12px',\n boxShadow: '0 8px 24px rgba(0,0,0,0.25)',\n zIndex: 99999,\n }}\n onClick={(e) => e.stopPropagation()}\n >\n {/* Render appropriate input based on filter type (per spec) */}\n {filter.type === 'TEXT_SEARCH' && (\n <input\n type=\"text\"\n value={(localValue as string) || ''}\n onChange={(e) => setLocalValue(e.target.value)}\n placeholder={t('bigconsole.filters.chip.editor.searchPlaceholder', 'Search...')}\n style={{\n width: '100%',\n padding: '8px',\n border: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n borderRadius: '4px',\n fontSize: '13px',\n boxSizing: 'border-box',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n color: SEMANTIC_COLORS.textPrimary,\n }}\n />\n )}\n\n {filter.type === 'CATEGORY' && (\n <select\n value={(localValue as string) || ''}\n onChange={(e) => setLocalValue(e.target.value)}\n style={{\n width: '100%',\n padding: '8px',\n border: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n borderRadius: '4px',\n fontSize: '13px',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n color: SEMANTIC_COLORS.textPrimary,\n }}\n >\n <option value=\"\">{t('bigconsole.filters.chip.editor.allOption', 'All')}</option>\n {(filter.config.options as Array<Record<string, unknown>> | undefined)?.map((opt) => (\n <option key={String(opt.value)} value={String(opt.value)}>\n {String(opt.label)}\n </option>\n ))}\n </select>\n )}\n\n {filter.type === 'DATE_RANGE' &&\n (() => {\n const dateVal = (localValue || {}) as Record<string, string>;\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n <input\n type=\"date\"\n value={dateVal.start || ''}\n onChange={(e) => setLocalValue({ ...dateVal, start: e.target.value })}\n style={{\n padding: '8px',\n border: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n borderRadius: '4px',\n fontSize: '13px',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n color: SEMANTIC_COLORS.textPrimary,\n }}\n />\n <input\n type=\"date\"\n value={dateVal.end || ''}\n onChange={(e) => setLocalValue({ ...dateVal, end: e.target.value })}\n style={{\n padding: '8px',\n border: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n borderRadius: '4px',\n fontSize: '13px',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n color: SEMANTIC_COLORS.textPrimary,\n }}\n />\n </div>\n );\n })()}\n\n {filter.type === 'NUMERIC_RANGE' &&\n (() => {\n const numVal = (localValue || {}) as Record<string, number | undefined>;\n return (\n <div style={{ display: 'flex', gap: '8px' }}>\n <input\n type=\"number\"\n value={numVal.min ?? ''}\n onChange={(e) =>\n setLocalValue({ ...numVal, min: e.target.value ? Number(e.target.value) : undefined })\n }\n placeholder={t('bigconsole.filters.chip.editor.minPlaceholder', 'Min')}\n style={{\n flex: 1,\n padding: '8px',\n border: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n borderRadius: '4px',\n fontSize: '13px',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n color: SEMANTIC_COLORS.textPrimary,\n }}\n />\n <input\n type=\"number\"\n value={numVal.max ?? ''}\n onChange={(e) =>\n setLocalValue({ ...numVal, max: e.target.value ? Number(e.target.value) : undefined })\n }\n placeholder={t('bigconsole.filters.chip.editor.maxPlaceholder', 'Max')}\n style={{\n flex: 1,\n padding: '8px',\n border: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n borderRadius: '4px',\n fontSize: '13px',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n color: SEMANTIC_COLORS.textPrimary,\n }}\n />\n </div>\n );\n })()}\n\n {filter.type === 'CUSTOM' && (\n <input\n type=\"text\"\n value={typeof localValue === 'string' ? localValue : JSON.stringify(localValue || '')}\n onChange={(e) => setLocalValue(e.target.value)}\n placeholder={t('bigconsole.filters.chip.editor.customPlaceholder', 'Custom filter value...')}\n style={{\n width: '100%',\n padding: '8px',\n border: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n borderRadius: '4px',\n fontSize: '13px',\n boxSizing: 'border-box',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n color: SEMANTIC_COLORS.textPrimary,\n }}\n />\n )}\n\n {/* Apply Button */}\n <div style={{ marginTop: '16px', display: 'flex', justifyContent: 'flex-end', gap: '10px' }}>\n <button\n onClick={onClose}\n style={{\n padding: '8px 16px',\n fontSize: '14px',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n border: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n borderRadius: '6px',\n cursor: 'pointer',\n color: SEMANTIC_COLORS.textSecondary,\n fontWeight: 500,\n }}\n >\n {t('bigconsole.filters.chip.editor.cancel', 'Cancel')}\n </button>\n <button\n onClick={handleApply}\n style={{\n padding: '8px 16px',\n fontSize: '14px',\n backgroundColor: SEMANTIC_COLORS.actionPrimaryBg,\n color: SEMANTIC_COLORS.actionPrimaryFg,\n border: 'none',\n borderRadius: '6px',\n cursor: 'pointer',\n fontWeight: 500,\n boxShadow: '0 2px 4px rgba(99, 102, 241, 0.3)',\n }}\n >\n {t('bigconsole.filters.chip.editor.apply', 'Apply')}\n </button>\n </div>\n </div>\n </>\n );\n}\n\nexport default FilterChip;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FilterChip.js","names":[],"sources":["../../../../../src/bigconsole/components/dashboard/GlobalFiltersBar/FilterChip.tsx"],"sourcesContent":["/**\n * FilterChip Component\n *\n * Individual filter chip with value display and controls.\n */\n\nimport React, { useState, useRef, useEffect } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport type { GlobalFilter, FilterType } from '../../../hooks';\n\ntype TranslateFn = (\n key: string,\n fallbackOrParams?: string | Record<string, string | number>,\n params?: Record<string, string | number>\n) => string;\n\n// Dynamic colors that respect dark mode\nconst getColors = (isDark: boolean) => ({\n bgPrimary: isDark ? '#1f2937' : '#ffffff',\n bgSecondary: isDark ? '#374151' : '#f9fafb',\n textPrimary: isDark ? '#f9fafb' : '#111827',\n textSecondary: isDark ? '#9ca3af' : '#6b7280',\n borderDefault: isDark ? '#4b5563' : '#e5e7eb',\n actionPrimaryBg: '#6366f1',\n actionPrimaryBgSubtle: isDark ? '#312e81' : '#eef2ff',\n actionPrimaryFg: '#ffffff',\n bgTertiary: isDark ? '#4b5563' : '#f3f4f6',\n textTertiary: isDark ? '#6b7280' : '#9ca3af',\n statusErrorText: '#ef4444',\n statusErrorBg: isDark ? '#991b1b' : '#fee2e2',\n actionPrimaryText: isDark ? '#c7d2fe' : '#4338ca',\n backdropBg: 'rgba(0, 0, 0, 0.5)',\n});\n\n// Hook to detect dark mode\nfunction useDarkMode() {\n const [isDark, setIsDark] = useState(false);\n\n useEffect(() => {\n const checkDarkMode = () => {\n setIsDark(document.documentElement.classList.contains('dark'));\n };\n checkDarkMode();\n\n const observer = new MutationObserver(checkDarkMode);\n observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] });\n return () => observer.disconnect();\n }, []);\n\n return isDark;\n}\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface FilterChipProps {\n filter: GlobalFilter;\n value: unknown;\n onChange: (value: unknown) => void;\n onEdit: () => void;\n onDelete: () => void;\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Format filter value for display\n * Filter types per spec: DATE_RANGE, CATEGORY, CUSTOM, NUMERIC_RANGE, TEXT_SEARCH\n */\nfunction formatFilterValue(value: unknown, type: FilterType, t: TranslateFn): string {\n if (value === undefined || value === null) {\n return t('bigconsole.filters.chip.value.all', 'All');\n }\n\n switch (type) {\n case 'DATE_RANGE': {\n const dateRange = value as Record<string, unknown>;\n if (dateRange.start && dateRange.end) {\n return `${formatDate(dateRange.start as string)} - ${formatDate(dateRange.end as string)}`;\n }\n return t('bigconsole.filters.chip.value.allDates', 'All dates');\n }\n\n case 'CATEGORY':\n // Category can be single or multiple selection\n if (Array.isArray(value) && value.length > 0) {\n if (value.length === 1) {\n const first = value[0] as Record<string, unknown> | string;\n return (\n (typeof first === 'object' && first !== null\n ? ((first as Record<string, unknown>).label as string)\n : first) || String(value[0])\n );\n }\n return t('bigconsole.filters.chip.value.countSelected', '{{count}} selected', {\n count: value.length,\n });\n }\n if (typeof value === 'object' && value !== null) {\n return ((value as Record<string, unknown>).label as string) || t('bigconsole.filters.chip.value.all', 'All');\n }\n return String(value) || t('bigconsole.filters.chip.value.all', 'All');\n\n case 'TEXT_SEARCH':\n return (value as string) || t('bigconsole.filters.chip.value.any', 'Any');\n\n case 'NUMERIC_RANGE': {\n const numRange = value as Record<string, unknown>;\n if (numRange.min !== undefined && numRange.max !== undefined) {\n return `${numRange.min} - ${numRange.max}`;\n }\n if (numRange.min !== undefined) {\n return `>= ${numRange.min}`;\n }\n if (numRange.max !== undefined) {\n return `<= ${numRange.max}`;\n }\n return t('bigconsole.filters.chip.value.any', 'Any');\n }\n\n case 'CUSTOM':\n // Custom filters may have various value formats\n if (typeof value === 'object') {\n return JSON.stringify(value).substring(0, 30) + '...';\n }\n return String(value);\n\n default:\n return String(value);\n }\n}\n\nfunction formatDate(date: string | Date): string {\n const d = new Date(date);\n return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport function FilterChip({ filter, value, onChange, onEdit, onDelete }: FilterChipProps) {\n const { t } = useI18n();\n const [isOpen, setIsOpen] = useState(false);\n const [showMenu, setShowMenu] = useState(false);\n const chipRef = useRef<HTMLDivElement>(null);\n const menuRef = useRef<HTMLDivElement>(null);\n const isDarkMode = useDarkMode();\n const SEMANTIC_COLORS = getColors(isDarkMode);\n\n const hasValue = value !== undefined && value !== null && value !== '';\n const displayValue = formatFilterValue(value, filter.type, t);\n\n // Close dropdown when clicking outside\n useEffect(() => {\n function handleClickOutside(event: MouseEvent) {\n if (chipRef.current && !chipRef.current.contains(event.target as Node)) {\n setIsOpen(false);\n setShowMenu(false);\n }\n }\n\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, []);\n\n const handleClear = (e: React.MouseEvent) => {\n e.stopPropagation();\n onChange(undefined);\n };\n\n return (\n <div\n ref={chipRef}\n style={{\n position: 'relative',\n display: 'inline-flex',\n alignItems: 'center',\n gap: 'var(--space-iconGap)',\n padding: '0 var(--space-controlGap)',\n backgroundColor: hasValue ? 'var(--color-bg-accentSubtle)' : 'var(--color-bg-surface)',\n border: `1px solid ${hasValue ? 'var(--color-action-primary-border)' : 'var(--color-border-subtle)'}`,\n borderRadius: 'var(--radius-pill)',\n fontSize: 'var(--font-size-body-sm)',\n cursor: 'pointer',\n userSelect: 'none',\n transition: 'background-color 0.15s ease, border-color 0.15s ease',\n minHeight: 'var(--size-controlHeight-md)',\n maxWidth: '100%',\n }}\n >\n {/* Filter Name */}\n <span\n style={{\n fontWeight: 'var(--font-weight-semibold)',\n color: 'var(--color-text-primary)',\n fontSize: 'var(--font-size-body-sm)',\n }}\n onClick={() => setIsOpen(!isOpen)}\n >\n {filter.name}:\n </span>\n\n {/* Filter Value */}\n <span\n style={{\n color: hasValue ? 'var(--color-text-primary)' : 'var(--color-text-secondary)',\n maxWidth: 'min(200px, 45vw)',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n fontWeight: 'var(--font-weight-medium)',\n fontSize: 'var(--font-size-body-sm)',\n }}\n onClick={() => setIsOpen(!isOpen)}\n >\n {displayValue}\n </span>\n\n {/* Clear button */}\n {hasValue && (\n <button\n onClick={handleClear}\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '22px',\n height: '22px',\n padding: 0,\n backgroundColor: SEMANTIC_COLORS.statusErrorBg,\n border: 'none',\n borderRadius: '50%',\n cursor: 'pointer',\n color: SEMANTIC_COLORS.actionPrimaryFg,\n fontSize: '14px',\n fontWeight: 'bold',\n marginLeft: '4px',\n boxShadow: 'var(--shadow-elevation-1)',\n }}\n title={t('bigconsole.filters.chip.action.clear', 'Clear filter')}\n >\n ×\n </button>\n )}\n\n {/* Menu button */}\n <button\n onClick={(e) => {\n e.stopPropagation();\n setShowMenu(!showMenu);\n }}\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '22px',\n height: '22px',\n padding: 0,\n backgroundColor: SEMANTIC_COLORS.textTertiary,\n border: 'none',\n borderRadius: '50%',\n cursor: 'pointer',\n color: SEMANTIC_COLORS.actionPrimaryFg,\n fontSize: '16px',\n fontWeight: 'bold',\n marginLeft: '4px',\n boxShadow: 'var(--shadow-elevation-1)',\n }}\n title={t('bigconsole.filters.chip.action.options', 'Filter options')}\n >\n ⋮\n </button>\n\n {/* Value Editor Dropdown */}\n {isOpen && (\n <FilterValueEditor\n filter={filter}\n value={value}\n onChange={(newValue) => {\n onChange(newValue);\n setIsOpen(false);\n }}\n onClose={() => setIsOpen(false)}\n />\n )}\n\n {/* Context Menu */}\n {showMenu && (\n <>\n {/* Backdrop */}\n <div\n style={{\n position: 'fixed',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 99998,\n }}\n onClick={(e) => {\n e.stopPropagation();\n setShowMenu(false);\n }}\n />\n <div\n ref={menuRef}\n style={{\n position: 'absolute',\n top: '100%',\n right: 0,\n marginTop: '8px',\n minWidth: 'min(150px, calc(100vw - 2rem))',\n maxWidth: 'calc(100vw - 2rem)',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n border: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n borderRadius: '8px',\n boxShadow: 'var(--shadow-elevation-3)',\n zIndex: 99999,\n overflow: 'hidden',\n }}\n >\n <button\n onClick={(e) => {\n e.stopPropagation();\n setShowMenu(false);\n onEdit();\n }}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n width: '100%',\n padding: '12px 16px',\n textAlign: 'left',\n backgroundColor: 'transparent',\n border: 'none',\n borderBottom: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n cursor: 'pointer',\n fontSize: '14px',\n color: SEMANTIC_COLORS.textPrimary,\n fontWeight: 500,\n }}\n >\n ✏️ {t('bigconsole.filters.chip.menu.edit', 'Edit Filter')}\n </button>\n <button\n onClick={(e) => {\n e.stopPropagation();\n setShowMenu(false);\n onDelete();\n }}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n width: '100%',\n padding: '12px 16px',\n textAlign: 'left',\n backgroundColor: 'transparent',\n border: 'none',\n cursor: 'pointer',\n fontSize: '14px',\n color: SEMANTIC_COLORS.statusErrorText,\n fontWeight: 500,\n }}\n >\n 🗑️ {t('bigconsole.filters.chip.menu.delete', 'Delete Filter')}\n </button>\n </div>\n </>\n )}\n </div>\n );\n}\n\n// ============================================================================\n// FilterValueEditor Sub-component\n// ============================================================================\n\ninterface FilterValueEditorProps {\n filter: GlobalFilter;\n value: unknown;\n onChange: (value: unknown) => void;\n onClose: () => void;\n}\n\nfunction FilterValueEditor({ filter, value, onChange, onClose }: FilterValueEditorProps) {\n const { t } = useI18n();\n const [localValue, setLocalValue] = useState(value);\n const isDarkMode = useDarkMode();\n const SEMANTIC_COLORS = getColors(isDarkMode);\n\n const handleApply = () => {\n onChange(localValue);\n };\n\n return (\n <>\n {/* Backdrop to capture clicks outside */}\n <div\n style={{\n position: 'fixed',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n zIndex: 99998,\n }}\n onClick={onClose}\n />\n <div\n style={{\n position: 'absolute',\n top: '100%',\n left: 0,\n marginTop: '8px',\n minWidth: 'min(280px, calc(100vw - 2rem))',\n maxWidth: 'calc(100vw - 2rem)',\n padding: '16px',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n border: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n borderRadius: '12px',\n boxShadow: 'var(--shadow-elevation-3)',\n zIndex: 99999,\n }}\n onClick={(e) => e.stopPropagation()}\n >\n {/* Render appropriate input based on filter type (per spec) */}\n {filter.type === 'TEXT_SEARCH' && (\n <input\n type=\"text\"\n value={(localValue as string) || ''}\n onChange={(e) => setLocalValue(e.target.value)}\n placeholder={t('bigconsole.filters.chip.editor.searchPlaceholder', 'Search...')}\n style={{\n width: '100%',\n padding: '8px',\n border: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n borderRadius: '4px',\n fontSize: '13px',\n boxSizing: 'border-box',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n color: SEMANTIC_COLORS.textPrimary,\n }}\n />\n )}\n\n {filter.type === 'CATEGORY' && (\n <select\n value={(localValue as string) || ''}\n onChange={(e) => setLocalValue(e.target.value)}\n style={{\n width: '100%',\n padding: '8px',\n border: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n borderRadius: '4px',\n fontSize: '13px',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n color: SEMANTIC_COLORS.textPrimary,\n }}\n >\n <option value=\"\">{t('bigconsole.filters.chip.editor.allOption', 'All')}</option>\n {(filter.config.options as Array<Record<string, unknown>> | undefined)?.map((opt) => (\n <option key={String(opt.value)} value={String(opt.value)}>\n {String(opt.label)}\n </option>\n ))}\n </select>\n )}\n\n {filter.type === 'DATE_RANGE' &&\n (() => {\n const dateVal = (localValue || {}) as Record<string, string>;\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n <input\n type=\"date\"\n value={dateVal.start || ''}\n onChange={(e) => setLocalValue({ ...dateVal, start: e.target.value })}\n style={{\n padding: '8px',\n border: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n borderRadius: '4px',\n fontSize: '13px',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n color: SEMANTIC_COLORS.textPrimary,\n }}\n />\n <input\n type=\"date\"\n value={dateVal.end || ''}\n onChange={(e) => setLocalValue({ ...dateVal, end: e.target.value })}\n style={{\n padding: '8px',\n border: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n borderRadius: '4px',\n fontSize: '13px',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n color: SEMANTIC_COLORS.textPrimary,\n }}\n />\n </div>\n );\n })()}\n\n {filter.type === 'NUMERIC_RANGE' &&\n (() => {\n const numVal = (localValue || {}) as Record<string, number | undefined>;\n return (\n <div style={{ display: 'flex', gap: '8px' }}>\n <input\n type=\"number\"\n value={numVal.min ?? ''}\n onChange={(e) =>\n setLocalValue({ ...numVal, min: e.target.value ? Number(e.target.value) : undefined })\n }\n placeholder={t('bigconsole.filters.chip.editor.minPlaceholder', 'Min')}\n style={{\n flex: 1,\n padding: '8px',\n border: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n borderRadius: '4px',\n fontSize: '13px',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n color: SEMANTIC_COLORS.textPrimary,\n }}\n />\n <input\n type=\"number\"\n value={numVal.max ?? ''}\n onChange={(e) =>\n setLocalValue({ ...numVal, max: e.target.value ? Number(e.target.value) : undefined })\n }\n placeholder={t('bigconsole.filters.chip.editor.maxPlaceholder', 'Max')}\n style={{\n flex: 1,\n padding: '8px',\n border: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n borderRadius: '4px',\n fontSize: '13px',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n color: SEMANTIC_COLORS.textPrimary,\n }}\n />\n </div>\n );\n })()}\n\n {filter.type === 'CUSTOM' && (\n <input\n type=\"text\"\n value={typeof localValue === 'string' ? localValue : JSON.stringify(localValue || '')}\n onChange={(e) => setLocalValue(e.target.value)}\n placeholder={t('bigconsole.filters.chip.editor.customPlaceholder', 'Custom filter value...')}\n style={{\n width: '100%',\n padding: '8px',\n border: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n borderRadius: '4px',\n fontSize: '13px',\n boxSizing: 'border-box',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n color: SEMANTIC_COLORS.textPrimary,\n }}\n />\n )}\n\n {/* Apply Button */}\n <div style={{ marginTop: '16px', display: 'flex', justifyContent: 'flex-end', gap: '10px' }}>\n <button\n onClick={onClose}\n style={{\n padding: '8px 16px',\n fontSize: '14px',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n border: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n borderRadius: '6px',\n cursor: 'pointer',\n color: SEMANTIC_COLORS.textSecondary,\n fontWeight: 500,\n }}\n >\n {t('bigconsole.filters.chip.editor.cancel', 'Cancel')}\n </button>\n <button\n onClick={handleApply}\n style={{\n padding: '8px 16px',\n fontSize: '14px',\n backgroundColor: SEMANTIC_COLORS.actionPrimaryBg,\n color: SEMANTIC_COLORS.actionPrimaryFg,\n border: 'none',\n borderRadius: '6px',\n cursor: 'pointer',\n fontWeight: 500,\n boxShadow: 'var(--shadow-elevation-1)',\n }}\n >\n {t('bigconsole.filters.chip.editor.apply', 'Apply')}\n </button>\n </div>\n </div>\n </>\n );\n}\n\nexport default FilterChip;\n"],"mappings":";;;;AAiBA,IAAM,KAAa,OAAqB;CACtC,WAAW,IAAS,YAAY;CAChC,aAAa,IAAS,YAAY;CAClC,aAAa,IAAS,YAAY;CAClC,eAAe,IAAS,YAAY;CACpC,eAAe,IAAS,YAAY;CACpC,iBAAiB;CACjB,uBAAuB,IAAS,YAAY;CAC5C,iBAAiB;CACjB,YAAY,IAAS,YAAY;CACjC,cAAc,IAAS,YAAY;CACnC,iBAAiB;CACjB,eAAe,IAAS,YAAY;CACpC,mBAAmB,IAAS,YAAY;CACxC,YAAY;CACb;AAGD,SAAS,IAAc;CACrB,IAAM,CAAC,GAAQ,KAAa,EAAS,GAAM;AAa3C,QAXA,QAAgB;EACd,IAAM,UAAsB;AAC1B,KAAU,SAAS,gBAAgB,UAAU,SAAS,OAAO,CAAC;;AAEhE,KAAe;EAEf,IAAM,IAAW,IAAI,iBAAiB,EAAc;AAEpD,SADA,EAAS,QAAQ,SAAS,iBAAiB;GAAE,YAAY;GAAM,iBAAiB,CAAC,QAAQ;GAAE,CAAC,QAC/E,EAAS,YAAY;IACjC,EAAE,CAAC,EAEC;;AAuBT,SAAS,EAAkB,GAAgB,GAAkB,GAAwB;AACnF,KAAI,KAAiC,KACnC,QAAO,EAAE,qCAAqC,MAAM;AAGtD,SAAQ,GAAR;EACE,KAAK,cAAc;GACjB,IAAM,IAAY;AAIlB,UAHI,EAAU,SAAS,EAAU,MACxB,GAAG,EAAW,EAAU,MAAgB,CAAC,KAAK,EAAW,EAAU,IAAc,KAEnF,EAAE,0CAA0C,YAAY;;EAGjE,KAAK;AAEH,OAAI,MAAM,QAAQ,EAAM,IAAI,EAAM,SAAS,GAAG;AAC5C,QAAI,EAAM,WAAW,GAAG;KACtB,IAAM,IAAQ,EAAM;AACpB,aACG,OAAO,KAAU,YAAY,IACxB,EAAkC,QACpC,MAAU,OAAO,EAAM,GAAG;;AAGlC,WAAO,EAAE,+CAA+C,sBAAsB,EAC5E,OAAO,EAAM,QACd,CAAC;;AAKJ,UAHI,OAAO,KAAU,YAAY,IACtB,EAAkC,SAAoB,EAAE,qCAAqC,MAAM,GAEvG,OAAO,EAAM,IAAI,EAAE,qCAAqC,MAAM;EAEvE,KAAK,cACH,QAAQ,KAAoB,EAAE,qCAAqC,MAAM;EAE3E,KAAK,iBAAiB;GACpB,IAAM,IAAW;AAUjB,UATI,EAAS,QAAQ,KAAA,KAAa,EAAS,QAAQ,KAAA,IAC1C,GAAG,EAAS,IAAI,KAAK,EAAS,QAEnC,EAAS,QAAQ,KAAA,IAGjB,EAAS,QAAQ,KAAA,IAGd,EAAE,qCAAqC,MAAM,GAF3C,MAAM,EAAS,QAHf,MAAM,EAAS;;EAQ1B,KAAK,SAKH,QAHI,OAAO,KAAU,WACZ,KAAK,UAAU,EAAM,CAAC,UAAU,GAAG,GAAG,GAAG,QAE3C,OAAO,EAAM;EAEtB,QACE,QAAO,OAAO,EAAM;;;AAI1B,SAAS,EAAW,GAA6B;AAE/C,QADU,IAAI,KAAK,EAAK,CACf,mBAAmB,SAAS;EAAE,OAAO;EAAS,KAAK;EAAW,CAAC;;AAO1E,SAAgB,EAAW,EAAE,WAAQ,UAAO,aAAU,WAAQ,eAA6B;CACzF,IAAM,EAAE,SAAM,GAAS,EACjB,CAAC,GAAQ,KAAa,EAAS,GAAM,EACrC,CAAC,GAAU,KAAe,EAAS,GAAM,EACzC,IAAU,EAAuB,KAAK,EACtC,IAAU,EAAuB,KAAK,EAEtC,IAAkB,EADL,GAAa,CACa,EAEvC,IAAW,KAAiC,QAAQ,MAAU,IAC9D,IAAe,EAAkB,GAAO,EAAO,MAAM,EAAE;AAoB7D,QAjBA,QAAgB;EACd,SAAS,EAAmB,GAAmB;AAC7C,GAAI,EAAQ,WAAW,CAAC,EAAQ,QAAQ,SAAS,EAAM,OAAe,KACpE,EAAU,GAAM,EAChB,EAAY,GAAM;;AAKtB,SADA,SAAS,iBAAiB,aAAa,EAAmB,QAC7C,SAAS,oBAAoB,aAAa,EAAmB;IACzE,EAAE,CAAC,EAQJ,kBAAC,OAAD;EACE,KAAK;EACL,OAAO;GACL,UAAU;GACV,SAAS;GACT,YAAY;GACZ,KAAK;GACL,SAAS;GACT,iBAAiB,IAAW,iCAAiC;GAC7D,QAAQ,aAAa,IAAW,uCAAuC;GACvE,cAAc;GACd,UAAU;GACV,QAAQ;GACR,YAAY;GACZ,YAAY;GACZ,WAAW;GACX,UAAU;GACX;YAjBH;GAoBE,kBAAC,QAAD;IACE,OAAO;KACL,YAAY;KACZ,OAAO;KACP,UAAU;KACX;IACD,eAAe,EAAU,CAAC,EAAO;cANnC,CAQG,EAAO,MAAK,IACR;;GAGP,kBAAC,QAAD;IACE,OAAO;KACL,OAAO,IAAW,8BAA8B;KAChD,UAAU;KACV,UAAU;KACV,cAAc;KACd,YAAY;KACZ,YAAY;KACZ,UAAU;KACX;IACD,eAAe,EAAU,CAAC,EAAO;cAEhC;IACI,CAAA;GAGN,KACC,kBAAC,UAAD;IACE,UAxDa,MAAwB;AAE3C,KADA,EAAE,iBAAiB,EACnB,EAAS,KAAA,EAAU;;IAuDb,OAAO;KACL,SAAS;KACT,YAAY;KACZ,gBAAgB;KAChB,OAAO;KACP,QAAQ;KACR,SAAS;KACT,iBAAiB,EAAgB;KACjC,QAAQ;KACR,cAAc;KACd,QAAQ;KACR,OAAO,EAAgB;KACvB,UAAU;KACV,YAAY;KACZ,YAAY;KACZ,WAAW;KACZ;IACD,OAAO,EAAE,wCAAwC,eAAe;cACjE;IAEQ,CAAA;GAIX,kBAAC,UAAD;IACE,UAAU,MAAM;AAEd,KADA,EAAE,iBAAiB,EACnB,EAAY,CAAC,EAAS;;IAExB,OAAO;KACL,SAAS;KACT,YAAY;KACZ,gBAAgB;KAChB,OAAO;KACP,QAAQ;KACR,SAAS;KACT,iBAAiB,EAAgB;KACjC,QAAQ;KACR,cAAc;KACd,QAAQ;KACR,OAAO,EAAgB;KACvB,UAAU;KACV,YAAY;KACZ,YAAY;KACZ,WAAW;KACZ;IACD,OAAO,EAAE,0CAA0C,iBAAiB;cACrE;IAEQ,CAAA;GAGR,KACC,kBAAC,GAAD;IACU;IACD;IACP,WAAW,MAAa;AAEtB,KADA,EAAS,EAAS,EAClB,EAAU,GAAM;;IAElB,eAAe,EAAU,GAAM;IAC/B,CAAA;GAIH,KACC,kBAAA,GAAA,EAAA,UAAA,CAEE,kBAAC,OAAD;IACE,OAAO;KACL,UAAU;KACV,KAAK;KACL,MAAM;KACN,OAAO;KACP,QAAQ;KACR,QAAQ;KACT;IACD,UAAU,MAAM;AAEd,KADA,EAAE,iBAAiB,EACnB,EAAY,GAAM;;IAEpB,CAAA,EACF,kBAAC,OAAD;IACE,KAAK;IACL,OAAO;KACL,UAAU;KACV,KAAK;KACL,OAAO;KACP,WAAW;KACX,UAAU;KACV,UAAU;KACV,iBAAiB,EAAgB;KACjC,QAAQ,aAAa,EAAgB;KACrC,cAAc;KACd,WAAW;KACX,QAAQ;KACR,UAAU;KACX;cAfH,CAiBE,kBAAC,UAAD;KACE,UAAU,MAAM;AAGd,MAFA,EAAE,iBAAiB,EACnB,EAAY,GAAM,EAClB,GAAQ;;KAEV,OAAO;MACL,SAAS;MACT,YAAY;MACZ,KAAK;MACL,OAAO;MACP,SAAS;MACT,WAAW;MACX,iBAAiB;MACjB,QAAQ;MACR,cAAc,aAAa,EAAgB;MAC3C,QAAQ;MACR,UAAU;MACV,OAAO,EAAgB;MACvB,YAAY;MACb;eApBH,CAqBC,OACK,EAAE,qCAAqC,cAAc,CAClD;QACT,kBAAC,UAAD;KACE,UAAU,MAAM;AAGd,MAFA,EAAE,iBAAiB,EACnB,EAAY,GAAM,EAClB,GAAU;;KAEZ,OAAO;MACL,SAAS;MACT,YAAY;MACZ,KAAK;MACL,OAAO;MACP,SAAS;MACT,WAAW;MACX,iBAAiB;MACjB,QAAQ;MACR,QAAQ;MACR,UAAU;MACV,OAAO,EAAgB;MACvB,YAAY;MACb;eAnBH,CAoBC,QACM,EAAE,uCAAuC,gBAAgB,CACvD;OACL;MACL,EAAA,CAAA;GAED;;;AAeV,SAAS,EAAkB,EAAE,WAAQ,UAAO,aAAU,cAAmC;CACvF,IAAM,EAAE,SAAM,GAAS,EACjB,CAAC,GAAY,KAAiB,EAAS,EAAM,EAE7C,IAAkB,EADL,GAAa,CACa;AAM7C,QACE,kBAAA,GAAA,EAAA,UAAA,CAEE,kBAAC,OAAD;EACE,OAAO;GACL,UAAU;GACV,KAAK;GACL,MAAM;GACN,OAAO;GACP,QAAQ;GACR,QAAQ;GACT;EACD,SAAS;EACT,CAAA,EACF,kBAAC,OAAD;EACE,OAAO;GACL,UAAU;GACV,KAAK;GACL,MAAM;GACN,WAAW;GACX,UAAU;GACV,UAAU;GACV,SAAS;GACT,iBAAiB,EAAgB;GACjC,QAAQ,aAAa,EAAgB;GACrC,cAAc;GACd,WAAW;GACX,QAAQ;GACT;EACD,UAAU,MAAM,EAAE,iBAAiB;YAfrC;GAkBG,EAAO,SAAS,iBACf,kBAAC,SAAD;IACE,MAAK;IACL,OAAQ,KAAyB;IACjC,WAAW,MAAM,EAAc,EAAE,OAAO,MAAM;IAC9C,aAAa,EAAE,oDAAoD,YAAY;IAC/E,OAAO;KACL,OAAO;KACP,SAAS;KACT,QAAQ,aAAa,EAAgB;KACrC,cAAc;KACd,UAAU;KACV,WAAW;KACX,iBAAiB,EAAgB;KACjC,OAAO,EAAgB;KACxB;IACD,CAAA;GAGH,EAAO,SAAS,cACf,kBAAC,UAAD;IACE,OAAQ,KAAyB;IACjC,WAAW,MAAM,EAAc,EAAE,OAAO,MAAM;IAC9C,OAAO;KACL,OAAO;KACP,SAAS;KACT,QAAQ,aAAa,EAAgB;KACrC,cAAc;KACd,UAAU;KACV,iBAAiB,EAAgB;KACjC,OAAO,EAAgB;KACxB;cAXH,CAaE,kBAAC,UAAD;KAAQ,OAAM;eAAI,EAAE,4CAA4C,MAAM;KAAU,CAAA,EAC9E,EAAO,OAAO,SAAwD,KAAK,MAC3E,kBAAC,UAAD;KAAgC,OAAO,OAAO,EAAI,MAAM;eACrD,OAAO,EAAI,MAAM;KACX,EAFI,OAAO,EAAI,MAAM,CAErB,CACT,CACK;;GAGV,EAAO,SAAS,uBACR;IACL,IAAM,IAAW,KAAc,EAAE;AACjC,WACE,kBAAC,OAAD;KAAK,OAAO;MAAE,SAAS;MAAQ,eAAe;MAAU,KAAK;MAAO;eAApE,CACE,kBAAC,SAAD;MACE,MAAK;MACL,OAAO,EAAQ,SAAS;MACxB,WAAW,MAAM,EAAc;OAAE,GAAG;OAAS,OAAO,EAAE,OAAO;OAAO,CAAC;MACrE,OAAO;OACL,SAAS;OACT,QAAQ,aAAa,EAAgB;OACrC,cAAc;OACd,UAAU;OACV,iBAAiB,EAAgB;OACjC,OAAO,EAAgB;OACxB;MACD,CAAA,EACF,kBAAC,SAAD;MACE,MAAK;MACL,OAAO,EAAQ,OAAO;MACtB,WAAW,MAAM,EAAc;OAAE,GAAG;OAAS,KAAK,EAAE,OAAO;OAAO,CAAC;MACnE,OAAO;OACL,SAAS;OACT,QAAQ,aAAa,EAAgB;OACrC,cAAc;OACd,UAAU;OACV,iBAAiB,EAAgB;OACjC,OAAO,EAAgB;OACxB;MACD,CAAA,CACE;;OAEN;GAEL,EAAO,SAAS,0BACR;IACL,IAAM,IAAU,KAAc,EAAE;AAChC,WACE,kBAAC,OAAD;KAAK,OAAO;MAAE,SAAS;MAAQ,KAAK;MAAO;eAA3C,CACE,kBAAC,SAAD;MACE,MAAK;MACL,OAAO,EAAO,OAAO;MACrB,WAAW,MACT,EAAc;OAAE,GAAG;OAAQ,KAAK,EAAE,OAAO,QAAQ,OAAO,EAAE,OAAO,MAAM,GAAG,KAAA;OAAW,CAAC;MAExF,aAAa,EAAE,iDAAiD,MAAM;MACtE,OAAO;OACL,MAAM;OACN,SAAS;OACT,QAAQ,aAAa,EAAgB;OACrC,cAAc;OACd,UAAU;OACV,iBAAiB,EAAgB;OACjC,OAAO,EAAgB;OACxB;MACD,CAAA,EACF,kBAAC,SAAD;MACE,MAAK;MACL,OAAO,EAAO,OAAO;MACrB,WAAW,MACT,EAAc;OAAE,GAAG;OAAQ,KAAK,EAAE,OAAO,QAAQ,OAAO,EAAE,OAAO,MAAM,GAAG,KAAA;OAAW,CAAC;MAExF,aAAa,EAAE,iDAAiD,MAAM;MACtE,OAAO;OACL,MAAM;OACN,SAAS;OACT,QAAQ,aAAa,EAAgB;OACrC,cAAc;OACd,UAAU;OACV,iBAAiB,EAAgB;OACjC,OAAO,EAAgB;OACxB;MACD,CAAA,CACE;;OAEN;GAEL,EAAO,SAAS,YACf,kBAAC,SAAD;IACE,MAAK;IACL,OAAO,OAAO,KAAe,WAAW,IAAa,KAAK,UAAU,KAAc,GAAG;IACrF,WAAW,MAAM,EAAc,EAAE,OAAO,MAAM;IAC9C,aAAa,EAAE,oDAAoD,yBAAyB;IAC5F,OAAO;KACL,OAAO;KACP,SAAS;KACT,QAAQ,aAAa,EAAgB;KACrC,cAAc;KACd,UAAU;KACV,WAAW;KACX,iBAAiB,EAAgB;KACjC,OAAO,EAAgB;KACxB;IACD,CAAA;GAIJ,kBAAC,OAAD;IAAK,OAAO;KAAE,WAAW;KAAQ,SAAS;KAAQ,gBAAgB;KAAY,KAAK;KAAQ;cAA3F,CACE,kBAAC,UAAD;KACE,SAAS;KACT,OAAO;MACL,SAAS;MACT,UAAU;MACV,iBAAiB,EAAgB;MACjC,QAAQ,aAAa,EAAgB;MACrC,cAAc;MACd,QAAQ;MACR,OAAO,EAAgB;MACvB,YAAY;MACb;eAEA,EAAE,yCAAyC,SAAS;KAC9C,CAAA,EACT,kBAAC,UAAD;KACE,eAjMgB;AACxB,QAAS,EAAW;;KAiMZ,OAAO;MACL,SAAS;MACT,UAAU;MACV,iBAAiB,EAAgB;MACjC,OAAO,EAAgB;MACvB,QAAQ;MACR,cAAc;MACd,QAAQ;MACR,YAAY;MACZ,WAAW;MACZ;eAEA,EAAE,wCAAwC,QAAQ;KAC5C,CAAA,CACL;;GACF;IACL,EAAA,CAAA"}
|
|
@@ -98,12 +98,12 @@ function s({ filter: s, onSave: c, onClose: l }) {
|
|
|
98
98
|
onClick: l,
|
|
99
99
|
children: /* @__PURE__ */ a("div", {
|
|
100
100
|
style: {
|
|
101
|
-
width: "
|
|
102
|
-
maxWidth: "
|
|
101
|
+
width: "100%",
|
|
102
|
+
maxWidth: "min(480px, calc(100vw - 2rem))",
|
|
103
103
|
maxHeight: "80vh",
|
|
104
104
|
backgroundColor: C.bgPrimary,
|
|
105
105
|
borderRadius: "8px",
|
|
106
|
-
boxShadow: "
|
|
106
|
+
boxShadow: "var(--shadow-elevation-3)",
|
|
107
107
|
overflow: "hidden",
|
|
108
108
|
position: "relative"
|
|
109
109
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilterEditor.js","names":[],"sources":["../../../../../src/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.tsx"],"sourcesContent":["/**\n * FilterEditor Component\n *\n * Modal for creating/editing global filters.\n */\n\nimport React, { useState, useEffect, useMemo } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport type { GlobalFilter, FilterType } from '../../../hooks';\n\n// Dynamic colors that respect dark mode\nconst getColors = (isDark: boolean) => ({\n bgPrimary: isDark ? '#1f2937' : '#ffffff',\n bgSecondary: isDark ? '#374151' : '#f9fafb',\n textPrimary: isDark ? '#f9fafb' : '#111827',\n textSecondary: isDark ? '#9ca3af' : '#6b7280',\n borderDefault: isDark ? '#4b5563' : '#e5e7eb',\n actionPrimaryBg: '#6366f1',\n actionPrimaryBgSubtle: isDark ? '#312e81' : '#eef2ff',\n actionPrimaryFg: '#ffffff',\n bgTertiary: isDark ? '#4b5563' : '#f3f4f6',\n textTertiary: isDark ? '#6b7280' : '#9ca3af',\n statusErrorText: '#dc2626',\n backdropBg: 'rgba(0, 0, 0, 0.5)',\n});\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface FilterEditorProps {\n filter: GlobalFilter | null;\n onSave: (data: {\n name: string;\n type: FilterType;\n config: Record<string, unknown>;\n defaultValue?: unknown;\n isRequired?: boolean;\n }) => void;\n onClose: () => void;\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport function FilterEditor({ filter, onSave, onClose }: FilterEditorProps) {\n const { t } = useI18n();\n const [name, setName] = useState(filter?.name || '');\n const [type, setType] = useState<FilterType>(filter?.type || 'CATEGORY');\n const [isRequired, setIsRequired] = useState(filter?.isRequired || false);\n const [options, setOptions] = useState<{ value: string; label: string }[]>(\n (filter?.config?.options as { value: string; label: string }[] | undefined) || [{ value: '', label: '' }]\n );\n const [placeholder, setPlaceholder] = useState((filter?.config?.placeholder as string) || '');\n const [isDarkMode, setIsDarkMode] = useState(false);\n\n // Detect dark mode\n useEffect(() => {\n const checkDarkMode = () => {\n setIsDarkMode(document.documentElement.classList.contains('dark'));\n };\n checkDarkMode();\n\n // Watch for theme changes\n const observer = new MutationObserver(checkDarkMode);\n observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] });\n return () => observer.disconnect();\n }, []);\n\n const COLORS = getColors(isDarkMode);\n const isEditing = !!filter;\n\n /**\n * Filter types as per spec (03-graphql-contract.md)\n * Spec values: date_range, category, custom, numeric_range, text_search\n */\n const FILTER_TYPES = useMemo<{ value: FilterType; label: string; description: string }[]>(\n () => [\n {\n value: 'CATEGORY',\n label: t('bigconsole.filters.editor.type.category.label', 'Category'),\n description: t('bigconsole.filters.editor.type.category.description', 'Selection from predefined categories'),\n },\n {\n value: 'DATE_RANGE',\n label: t('bigconsole.filters.editor.type.dateRange.label', 'Date Range'),\n description: t('bigconsole.filters.editor.type.dateRange.description', 'Start and end date selection'),\n },\n {\n value: 'NUMERIC_RANGE',\n label: t('bigconsole.filters.editor.type.numericRange.label', 'Numeric Range'),\n description: t('bigconsole.filters.editor.type.numericRange.description', 'Min and max number values'),\n },\n {\n value: 'TEXT_SEARCH',\n label: t('bigconsole.filters.editor.type.textSearch.label', 'Text Search'),\n description: t('bigconsole.filters.editor.type.textSearch.description', 'Free text search input'),\n },\n {\n value: 'CUSTOM',\n label: t('bigconsole.filters.editor.type.custom.label', 'Custom'),\n description: t('bigconsole.filters.editor.type.custom.description', 'Custom filter configuration'),\n },\n ],\n [t]\n );\n\n const handleAddOption = () => {\n setOptions([...options, { value: '', label: '' }]);\n };\n\n const handleRemoveOption = (index: number) => {\n setOptions(options.filter((_, i) => i !== index));\n };\n\n const handleOptionChange = (index: number, field: 'value' | 'label', value: string) => {\n setOptions(options.map((opt, i) => (i === index ? { ...opt, [field]: value } : opt)));\n };\n\n const handleSave = () => {\n const config: Record<string, unknown> = {};\n\n // CATEGORY type uses options for selection\n if (type === 'CATEGORY') {\n config.options = options.filter((opt) => opt.value && opt.label);\n }\n\n if (placeholder) {\n config.placeholder = placeholder;\n }\n\n onSave({\n name,\n type,\n config,\n isRequired,\n });\n };\n\n const isValid = name.trim() !== '' && (type !== 'CATEGORY' || options.some((opt) => opt.value && opt.label));\n\n return (\n <div\n style={{\n position: 'fixed',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n width: '100vw',\n height: '100vh',\n backgroundColor: COLORS.backdropBg,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: 10000,\n isolation: 'isolate',\n }}\n onClick={onClose}\n >\n <div\n style={{\n width: '480px',\n maxWidth: '90vw',\n maxHeight: '80vh',\n backgroundColor: COLORS.bgPrimary,\n borderRadius: '8px',\n boxShadow: '0 8px 32px rgba(0, 0, 0, 0.3)',\n overflow: 'hidden',\n position: 'relative',\n }}\n onClick={(e) => e.stopPropagation()}\n >\n {/* Header */}\n <div\n style={{\n padding: '16px 20px',\n borderBottom: `1px solid ${COLORS.borderDefault}`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n backgroundColor: COLORS.bgPrimary,\n }}\n >\n <h3 style={{ margin: 0, fontSize: '16px', fontWeight: 600, color: COLORS.textPrimary }}>\n {isEditing\n ? t('bigconsole.filters.editor.title.edit', 'Edit Filter')\n : t('bigconsole.filters.editor.title.add', 'Add Filter')}\n </h3>\n <button\n onClick={onClose}\n style={{\n background: 'none',\n border: 'none',\n fontSize: '20px',\n cursor: 'pointer',\n color: COLORS.textSecondary,\n lineHeight: 1,\n }}\n >\n ×\n </button>\n </div>\n\n {/* Content */}\n <div\n style={{\n padding: '20px',\n overflowY: 'auto',\n maxHeight: 'calc(80vh - 130px)',\n backgroundColor: COLORS.bgPrimary,\n }}\n >\n {/* Filter Name */}\n <div style={{ marginBottom: '16px' }}>\n <label\n style={{\n display: 'block',\n marginBottom: '6px',\n fontSize: '13px',\n fontWeight: 500,\n color: COLORS.textPrimary,\n }}\n >\n {t('bigconsole.filters.editor.field.name.label', 'Filter Name *')}\n </label>\n <input\n type=\"text\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder={t('bigconsole.filters.editor.field.name.placeholder', 'e.g., Status, Date Range, Category')}\n style={{\n width: '100%',\n padding: '10px 12px',\n border: `1px solid ${COLORS.borderDefault}`,\n borderRadius: '6px',\n fontSize: '14px',\n boxSizing: 'border-box',\n backgroundColor: COLORS.bgPrimary,\n color: COLORS.textPrimary,\n }}\n />\n </div>\n\n {/* Filter Type */}\n {!isEditing && (\n <div style={{ marginBottom: '16px' }}>\n <label\n style={{\n display: 'block',\n marginBottom: '8px',\n fontSize: '13px',\n fontWeight: 500,\n color: COLORS.textPrimary,\n }}\n >\n {t('bigconsole.filters.editor.field.type.label', 'Filter Type *')}\n </label>\n <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: '10px' }}>\n {FILTER_TYPES.map((ft) => (\n <button\n key={ft.value}\n onClick={() => setType(ft.value)}\n type=\"button\"\n style={{\n padding: '12px',\n textAlign: 'left',\n backgroundColor: type === ft.value ? COLORS.actionPrimaryBgSubtle : COLORS.bgSecondary,\n border: `2px solid ${type === ft.value ? COLORS.actionPrimaryBg : COLORS.borderDefault}`,\n borderRadius: '6px',\n cursor: 'pointer',\n transition: 'all 0.2s ease',\n minHeight: '60px',\n }}\n >\n <div style={{ fontWeight: 500, fontSize: '13px', color: COLORS.textPrimary }}>{ft.label}</div>\n <div\n style={{\n fontSize: '11px',\n color: COLORS.textSecondary,\n marginTop: '4px',\n lineHeight: '1.3',\n }}\n >\n {ft.description}\n </div>\n </button>\n ))}\n </div>\n </div>\n )}\n\n {/* Options (for CATEGORY type) */}\n {type === 'CATEGORY' && (\n <div style={{ marginBottom: '16px' }}>\n <label\n style={{\n display: 'block',\n marginBottom: '8px',\n fontSize: '13px',\n fontWeight: 500,\n color: COLORS.textPrimary,\n }}\n >\n {t('bigconsole.filters.editor.field.options.label', 'Options')}\n </label>\n <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n {options.map((opt, index) => (\n <div key={index} style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>\n <input\n type=\"text\"\n value={opt.value}\n onChange={(e) => handleOptionChange(index, 'value', e.target.value)}\n placeholder={t('bigconsole.filters.editor.field.options.valuePlaceholder', 'Value')}\n style={{\n flex: 1,\n padding: '8px 10px',\n border: `1px solid ${COLORS.borderDefault}`,\n borderRadius: '4px',\n fontSize: '13px',\n boxSizing: 'border-box',\n backgroundColor: COLORS.bgPrimary,\n color: COLORS.textPrimary,\n }}\n />\n <input\n type=\"text\"\n value={opt.label}\n onChange={(e) => handleOptionChange(index, 'label', e.target.value)}\n placeholder={t('bigconsole.filters.editor.field.options.labelPlaceholder', 'Label')}\n style={{\n flex: 1,\n padding: '8px 10px',\n border: `1px solid ${COLORS.borderDefault}`,\n borderRadius: '4px',\n fontSize: '13px',\n boxSizing: 'border-box',\n backgroundColor: COLORS.bgPrimary,\n color: COLORS.textPrimary,\n }}\n />\n {options.length > 1 && (\n <button\n type=\"button\"\n onClick={() => handleRemoveOption(index)}\n style={{\n padding: '6px 10px',\n backgroundColor: 'transparent',\n border: `1px solid ${COLORS.statusErrorText}`,\n borderRadius: '4px',\n cursor: 'pointer',\n color: COLORS.statusErrorText,\n fontSize: '12px',\n }}\n >\n {t('bigconsole.filters.editor.field.options.remove', 'Remove')}\n </button>\n )}\n </div>\n ))}\n <button\n type=\"button\"\n onClick={handleAddOption}\n style={{\n padding: '8px',\n backgroundColor: 'transparent',\n border: `1px dashed ${COLORS.borderDefault}`,\n borderRadius: '4px',\n cursor: 'pointer',\n color: COLORS.textSecondary,\n fontSize: '12px',\n }}\n >\n {t('bigconsole.filters.editor.field.options.add', '+ Add Option')}\n </button>\n </div>\n </div>\n )}\n\n {/* Placeholder */}\n {(type === 'TEXT_SEARCH' || type === 'CATEGORY') && (\n <div style={{ marginBottom: '16px' }}>\n <label\n style={{\n display: 'block',\n marginBottom: '8px',\n fontSize: '13px',\n fontWeight: 500,\n color: COLORS.textPrimary,\n }}\n >\n {t('bigconsole.filters.editor.field.placeholder.label', 'Placeholder Text')}\n </label>\n <input\n type=\"text\"\n value={placeholder}\n onChange={(e) => setPlaceholder(e.target.value)}\n placeholder={t('bigconsole.filters.editor.field.placeholder.placeholder', 'e.g., Select an option...')}\n style={{\n width: '100%',\n padding: '10px 12px',\n border: `1px solid ${COLORS.borderDefault}`,\n borderRadius: '6px',\n fontSize: '14px',\n boxSizing: 'border-box',\n backgroundColor: COLORS.bgPrimary,\n color: COLORS.textPrimary,\n }}\n />\n </div>\n )}\n\n {/* Required Toggle */}\n <div style={{ marginBottom: '16px' }}>\n <label\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n cursor: 'pointer',\n }}\n >\n <input\n type=\"checkbox\"\n checked={isRequired}\n onChange={(e) => setIsRequired(e.target.checked)}\n style={{ width: '16px', height: '16px' }}\n />\n <span style={{ fontSize: '13px', color: COLORS.textPrimary }}>\n {t('bigconsole.filters.editor.field.required.label', 'Required filter (must have a value)')}\n </span>\n </label>\n </div>\n </div>\n\n {/* Footer */}\n <div\n style={{\n padding: '16px 20px',\n borderTop: `1px solid ${COLORS.borderDefault}`,\n display: 'flex',\n justifyContent: 'flex-end',\n gap: '12px',\n backgroundColor: COLORS.bgPrimary,\n }}\n >\n <button\n type=\"button\"\n onClick={onClose}\n style={{\n padding: '10px 20px',\n backgroundColor: COLORS.bgPrimary,\n border: `1px solid ${COLORS.borderDefault}`,\n borderRadius: '6px',\n cursor: 'pointer',\n fontSize: '14px',\n color: COLORS.textSecondary,\n }}\n >\n {t('bigconsole.filters.editor.action.cancel', 'Cancel')}\n </button>\n <button\n type=\"button\"\n onClick={handleSave}\n disabled={!isValid}\n style={{\n padding: '10px 20px',\n backgroundColor: isValid ? COLORS.actionPrimaryBg : COLORS.bgTertiary,\n color: isValid ? COLORS.actionPrimaryFg : COLORS.textTertiary,\n border: 'none',\n borderRadius: '6px',\n cursor: isValid ? 'pointer' : 'not-allowed',\n fontSize: '14px',\n fontWeight: 500,\n }}\n >\n {isEditing\n ? t('bigconsole.filters.editor.action.saveChanges', 'Save Changes')\n : t('bigconsole.filters.editor.action.add', 'Add Filter')}\n </button>\n </div>\n </div>\n </div>\n );\n}\n\nexport default FilterEditor;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FilterEditor.js","names":[],"sources":["../../../../../src/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.tsx"],"sourcesContent":["/**\n * FilterEditor Component\n *\n * Modal for creating/editing global filters.\n */\n\nimport React, { useState, useEffect, useMemo } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport type { GlobalFilter, FilterType } from '../../../hooks';\n\n// Dynamic colors that respect dark mode\nconst getColors = (isDark: boolean) => ({\n bgPrimary: isDark ? '#1f2937' : '#ffffff',\n bgSecondary: isDark ? '#374151' : '#f9fafb',\n textPrimary: isDark ? '#f9fafb' : '#111827',\n textSecondary: isDark ? '#9ca3af' : '#6b7280',\n borderDefault: isDark ? '#4b5563' : '#e5e7eb',\n actionPrimaryBg: '#6366f1',\n actionPrimaryBgSubtle: isDark ? '#312e81' : '#eef2ff',\n actionPrimaryFg: '#ffffff',\n bgTertiary: isDark ? '#4b5563' : '#f3f4f6',\n textTertiary: isDark ? '#6b7280' : '#9ca3af',\n statusErrorText: '#dc2626',\n backdropBg: 'rgba(0, 0, 0, 0.5)',\n});\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface FilterEditorProps {\n filter: GlobalFilter | null;\n onSave: (data: {\n name: string;\n type: FilterType;\n config: Record<string, unknown>;\n defaultValue?: unknown;\n isRequired?: boolean;\n }) => void;\n onClose: () => void;\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport function FilterEditor({ filter, onSave, onClose }: FilterEditorProps) {\n const { t } = useI18n();\n const [name, setName] = useState(filter?.name || '');\n const [type, setType] = useState<FilterType>(filter?.type || 'CATEGORY');\n const [isRequired, setIsRequired] = useState(filter?.isRequired || false);\n const [options, setOptions] = useState<{ value: string; label: string }[]>(\n (filter?.config?.options as { value: string; label: string }[] | undefined) || [{ value: '', label: '' }]\n );\n const [placeholder, setPlaceholder] = useState((filter?.config?.placeholder as string) || '');\n const [isDarkMode, setIsDarkMode] = useState(false);\n\n // Detect dark mode\n useEffect(() => {\n const checkDarkMode = () => {\n setIsDarkMode(document.documentElement.classList.contains('dark'));\n };\n checkDarkMode();\n\n // Watch for theme changes\n const observer = new MutationObserver(checkDarkMode);\n observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] });\n return () => observer.disconnect();\n }, []);\n\n const COLORS = getColors(isDarkMode);\n const isEditing = !!filter;\n\n /**\n * Filter types as per spec (03-graphql-contract.md)\n * Spec values: date_range, category, custom, numeric_range, text_search\n */\n const FILTER_TYPES = useMemo<{ value: FilterType; label: string; description: string }[]>(\n () => [\n {\n value: 'CATEGORY',\n label: t('bigconsole.filters.editor.type.category.label', 'Category'),\n description: t('bigconsole.filters.editor.type.category.description', 'Selection from predefined categories'),\n },\n {\n value: 'DATE_RANGE',\n label: t('bigconsole.filters.editor.type.dateRange.label', 'Date Range'),\n description: t('bigconsole.filters.editor.type.dateRange.description', 'Start and end date selection'),\n },\n {\n value: 'NUMERIC_RANGE',\n label: t('bigconsole.filters.editor.type.numericRange.label', 'Numeric Range'),\n description: t('bigconsole.filters.editor.type.numericRange.description', 'Min and max number values'),\n },\n {\n value: 'TEXT_SEARCH',\n label: t('bigconsole.filters.editor.type.textSearch.label', 'Text Search'),\n description: t('bigconsole.filters.editor.type.textSearch.description', 'Free text search input'),\n },\n {\n value: 'CUSTOM',\n label: t('bigconsole.filters.editor.type.custom.label', 'Custom'),\n description: t('bigconsole.filters.editor.type.custom.description', 'Custom filter configuration'),\n },\n ],\n [t]\n );\n\n const handleAddOption = () => {\n setOptions([...options, { value: '', label: '' }]);\n };\n\n const handleRemoveOption = (index: number) => {\n setOptions(options.filter((_, i) => i !== index));\n };\n\n const handleOptionChange = (index: number, field: 'value' | 'label', value: string) => {\n setOptions(options.map((opt, i) => (i === index ? { ...opt, [field]: value } : opt)));\n };\n\n const handleSave = () => {\n const config: Record<string, unknown> = {};\n\n // CATEGORY type uses options for selection\n if (type === 'CATEGORY') {\n config.options = options.filter((opt) => opt.value && opt.label);\n }\n\n if (placeholder) {\n config.placeholder = placeholder;\n }\n\n onSave({\n name,\n type,\n config,\n isRequired,\n });\n };\n\n const isValid = name.trim() !== '' && (type !== 'CATEGORY' || options.some((opt) => opt.value && opt.label));\n\n return (\n <div\n style={{\n position: 'fixed',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n width: '100vw',\n height: '100vh',\n backgroundColor: COLORS.backdropBg,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n zIndex: 10000,\n isolation: 'isolate',\n }}\n onClick={onClose}\n >\n <div\n style={{\n width: '100%',\n maxWidth: 'min(480px, calc(100vw - 2rem))',\n maxHeight: '80vh',\n backgroundColor: COLORS.bgPrimary,\n borderRadius: '8px',\n boxShadow: 'var(--shadow-elevation-3)',\n overflow: 'hidden',\n position: 'relative',\n }}\n onClick={(e) => e.stopPropagation()}\n >\n {/* Header */}\n <div\n style={{\n padding: '16px 20px',\n borderBottom: `1px solid ${COLORS.borderDefault}`,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n backgroundColor: COLORS.bgPrimary,\n }}\n >\n <h3 style={{ margin: 0, fontSize: '16px', fontWeight: 600, color: COLORS.textPrimary }}>\n {isEditing\n ? t('bigconsole.filters.editor.title.edit', 'Edit Filter')\n : t('bigconsole.filters.editor.title.add', 'Add Filter')}\n </h3>\n <button\n onClick={onClose}\n style={{\n background: 'none',\n border: 'none',\n fontSize: '20px',\n cursor: 'pointer',\n color: COLORS.textSecondary,\n lineHeight: 1,\n }}\n >\n ×\n </button>\n </div>\n\n {/* Content */}\n <div\n style={{\n padding: '20px',\n overflowY: 'auto',\n maxHeight: 'calc(80vh - 130px)',\n backgroundColor: COLORS.bgPrimary,\n }}\n >\n {/* Filter Name */}\n <div style={{ marginBottom: '16px' }}>\n <label\n style={{\n display: 'block',\n marginBottom: '6px',\n fontSize: '13px',\n fontWeight: 500,\n color: COLORS.textPrimary,\n }}\n >\n {t('bigconsole.filters.editor.field.name.label', 'Filter Name *')}\n </label>\n <input\n type=\"text\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder={t('bigconsole.filters.editor.field.name.placeholder', 'e.g., Status, Date Range, Category')}\n style={{\n width: '100%',\n padding: '10px 12px',\n border: `1px solid ${COLORS.borderDefault}`,\n borderRadius: '6px',\n fontSize: '14px',\n boxSizing: 'border-box',\n backgroundColor: COLORS.bgPrimary,\n color: COLORS.textPrimary,\n }}\n />\n </div>\n\n {/* Filter Type */}\n {!isEditing && (\n <div style={{ marginBottom: '16px' }}>\n <label\n style={{\n display: 'block',\n marginBottom: '8px',\n fontSize: '13px',\n fontWeight: 500,\n color: COLORS.textPrimary,\n }}\n >\n {t('bigconsole.filters.editor.field.type.label', 'Filter Type *')}\n </label>\n <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: '10px' }}>\n {FILTER_TYPES.map((ft) => (\n <button\n key={ft.value}\n onClick={() => setType(ft.value)}\n type=\"button\"\n style={{\n padding: '12px',\n textAlign: 'left',\n backgroundColor: type === ft.value ? COLORS.actionPrimaryBgSubtle : COLORS.bgSecondary,\n border: `2px solid ${type === ft.value ? COLORS.actionPrimaryBg : COLORS.borderDefault}`,\n borderRadius: '6px',\n cursor: 'pointer',\n transition: 'all 0.2s ease',\n minHeight: '60px',\n }}\n >\n <div style={{ fontWeight: 500, fontSize: '13px', color: COLORS.textPrimary }}>{ft.label}</div>\n <div\n style={{\n fontSize: '11px',\n color: COLORS.textSecondary,\n marginTop: '4px',\n lineHeight: '1.3',\n }}\n >\n {ft.description}\n </div>\n </button>\n ))}\n </div>\n </div>\n )}\n\n {/* Options (for CATEGORY type) */}\n {type === 'CATEGORY' && (\n <div style={{ marginBottom: '16px' }}>\n <label\n style={{\n display: 'block',\n marginBottom: '8px',\n fontSize: '13px',\n fontWeight: 500,\n color: COLORS.textPrimary,\n }}\n >\n {t('bigconsole.filters.editor.field.options.label', 'Options')}\n </label>\n <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n {options.map((opt, index) => (\n <div key={index} style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>\n <input\n type=\"text\"\n value={opt.value}\n onChange={(e) => handleOptionChange(index, 'value', e.target.value)}\n placeholder={t('bigconsole.filters.editor.field.options.valuePlaceholder', 'Value')}\n style={{\n flex: 1,\n padding: '8px 10px',\n border: `1px solid ${COLORS.borderDefault}`,\n borderRadius: '4px',\n fontSize: '13px',\n boxSizing: 'border-box',\n backgroundColor: COLORS.bgPrimary,\n color: COLORS.textPrimary,\n }}\n />\n <input\n type=\"text\"\n value={opt.label}\n onChange={(e) => handleOptionChange(index, 'label', e.target.value)}\n placeholder={t('bigconsole.filters.editor.field.options.labelPlaceholder', 'Label')}\n style={{\n flex: 1,\n padding: '8px 10px',\n border: `1px solid ${COLORS.borderDefault}`,\n borderRadius: '4px',\n fontSize: '13px',\n boxSizing: 'border-box',\n backgroundColor: COLORS.bgPrimary,\n color: COLORS.textPrimary,\n }}\n />\n {options.length > 1 && (\n <button\n type=\"button\"\n onClick={() => handleRemoveOption(index)}\n style={{\n padding: '6px 10px',\n backgroundColor: 'transparent',\n border: `1px solid ${COLORS.statusErrorText}`,\n borderRadius: '4px',\n cursor: 'pointer',\n color: COLORS.statusErrorText,\n fontSize: '12px',\n }}\n >\n {t('bigconsole.filters.editor.field.options.remove', 'Remove')}\n </button>\n )}\n </div>\n ))}\n <button\n type=\"button\"\n onClick={handleAddOption}\n style={{\n padding: '8px',\n backgroundColor: 'transparent',\n border: `1px dashed ${COLORS.borderDefault}`,\n borderRadius: '4px',\n cursor: 'pointer',\n color: COLORS.textSecondary,\n fontSize: '12px',\n }}\n >\n {t('bigconsole.filters.editor.field.options.add', '+ Add Option')}\n </button>\n </div>\n </div>\n )}\n\n {/* Placeholder */}\n {(type === 'TEXT_SEARCH' || type === 'CATEGORY') && (\n <div style={{ marginBottom: '16px' }}>\n <label\n style={{\n display: 'block',\n marginBottom: '8px',\n fontSize: '13px',\n fontWeight: 500,\n color: COLORS.textPrimary,\n }}\n >\n {t('bigconsole.filters.editor.field.placeholder.label', 'Placeholder Text')}\n </label>\n <input\n type=\"text\"\n value={placeholder}\n onChange={(e) => setPlaceholder(e.target.value)}\n placeholder={t('bigconsole.filters.editor.field.placeholder.placeholder', 'e.g., Select an option...')}\n style={{\n width: '100%',\n padding: '10px 12px',\n border: `1px solid ${COLORS.borderDefault}`,\n borderRadius: '6px',\n fontSize: '14px',\n boxSizing: 'border-box',\n backgroundColor: COLORS.bgPrimary,\n color: COLORS.textPrimary,\n }}\n />\n </div>\n )}\n\n {/* Required Toggle */}\n <div style={{ marginBottom: '16px' }}>\n <label\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n cursor: 'pointer',\n }}\n >\n <input\n type=\"checkbox\"\n checked={isRequired}\n onChange={(e) => setIsRequired(e.target.checked)}\n style={{ width: '16px', height: '16px' }}\n />\n <span style={{ fontSize: '13px', color: COLORS.textPrimary }}>\n {t('bigconsole.filters.editor.field.required.label', 'Required filter (must have a value)')}\n </span>\n </label>\n </div>\n </div>\n\n {/* Footer */}\n <div\n style={{\n padding: '16px 20px',\n borderTop: `1px solid ${COLORS.borderDefault}`,\n display: 'flex',\n justifyContent: 'flex-end',\n gap: '12px',\n backgroundColor: COLORS.bgPrimary,\n }}\n >\n <button\n type=\"button\"\n onClick={onClose}\n style={{\n padding: '10px 20px',\n backgroundColor: COLORS.bgPrimary,\n border: `1px solid ${COLORS.borderDefault}`,\n borderRadius: '6px',\n cursor: 'pointer',\n fontSize: '14px',\n color: COLORS.textSecondary,\n }}\n >\n {t('bigconsole.filters.editor.action.cancel', 'Cancel')}\n </button>\n <button\n type=\"button\"\n onClick={handleSave}\n disabled={!isValid}\n style={{\n padding: '10px 20px',\n backgroundColor: isValid ? COLORS.actionPrimaryBg : COLORS.bgTertiary,\n color: isValid ? COLORS.actionPrimaryFg : COLORS.textTertiary,\n border: 'none',\n borderRadius: '6px',\n cursor: isValid ? 'pointer' : 'not-allowed',\n fontSize: '14px',\n fontWeight: 500,\n }}\n >\n {isEditing\n ? t('bigconsole.filters.editor.action.saveChanges', 'Save Changes')\n : t('bigconsole.filters.editor.action.add', 'Add Filter')}\n </button>\n </div>\n </div>\n </div>\n );\n}\n\nexport default FilterEditor;\n"],"mappings":"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"}
|
|
@@ -38,7 +38,8 @@ function s({ presets: s, activePresetId: c, onApplyPreset: l, onSavePreset: u, o
|
|
|
38
38
|
color: C ? e.statusSuccessText : e.textSecondary,
|
|
39
39
|
fontWeight: 500,
|
|
40
40
|
opacity: f ? .6 : 1,
|
|
41
|
-
minWidth: "140px",
|
|
41
|
+
minWidth: "min(140px, 100%)",
|
|
42
|
+
maxWidth: "100%",
|
|
42
43
|
justifyContent: "space-between"
|
|
43
44
|
},
|
|
44
45
|
children: [/* @__PURE__ */ o("span", {
|
|
@@ -79,11 +80,12 @@ function s({ presets: s, activePresetId: c, onApplyPreset: l, onSavePreset: u, o
|
|
|
79
80
|
top: "100%",
|
|
80
81
|
left: 0,
|
|
81
82
|
marginTop: "4px",
|
|
82
|
-
minWidth: "280px",
|
|
83
|
+
minWidth: "min(280px, calc(100vw - 2rem))",
|
|
84
|
+
maxWidth: "calc(100vw - 2rem)",
|
|
83
85
|
backgroundColor: e.bgPrimary,
|
|
84
86
|
border: `1px solid ${e.borderDefault}`,
|
|
85
87
|
borderRadius: "8px",
|
|
86
|
-
boxShadow: "
|
|
88
|
+
boxShadow: "var(--shadow-elevation-2)",
|
|
87
89
|
zIndex: 1e5,
|
|
88
90
|
overflow: "hidden"
|
|
89
91
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilterPresetSelector.js","names":[],"sources":["../../../../../src/bigconsole/components/dashboard/GlobalFiltersBar/FilterPresetSelector.tsx"],"sourcesContent":["/**\n * FilterPresetSelector Component\n *\n * Dropdown to select, save, and manage filter presets.\n */\n\nimport React, { useState, useRef, useEffect } from 'react';\nimport type { FilterPreset } from '../../../hooks/useFilterPresets';\nimport { SEMANTIC_COLORS } from '../../../utils/semanticTokens';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface FilterPresetSelectorProps {\n presets: FilterPreset[];\n activePresetId: string | null;\n onApplyPreset: (presetId: string) => void;\n onSavePreset: (name: string, description?: string) => void;\n onDeletePreset: (presetId: string) => void;\n disabled?: boolean;\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport function FilterPresetSelector({\n presets,\n activePresetId,\n onApplyPreset,\n onSavePreset,\n onDeletePreset,\n disabled = false,\n}: FilterPresetSelectorProps) {\n const { t } = useI18n();\n const [isOpen, setIsOpen] = useState(false);\n const [showSaveDialog, setShowSaveDialog] = useState(false);\n const [newPresetName, setNewPresetName] = useState('');\n const [newPresetDescription, setNewPresetDescription] = useState('');\n const dropdownRef = useRef<HTMLDivElement>(null);\n\n const activePreset = presets.find((p) => p.id === activePresetId);\n\n // Close dropdown when clicking outside\n useEffect(() => {\n function handleClickOutside(event: MouseEvent) {\n if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {\n setIsOpen(false);\n setShowSaveDialog(false);\n }\n }\n\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, []);\n\n const handleSavePreset = () => {\n if (newPresetName.trim()) {\n onSavePreset(newPresetName.trim(), newPresetDescription.trim() || undefined);\n setNewPresetName('');\n setNewPresetDescription('');\n setShowSaveDialog(false);\n setIsOpen(false);\n }\n };\n\n const handleDeletePreset = (e: React.MouseEvent, presetId: string) => {\n e.stopPropagation();\n if (window.confirm(t('bigconsole.filters.presets.deleteConfirm', 'Are you sure you want to delete this preset?'))) {\n onDeletePreset(presetId);\n }\n };\n\n return (\n <div ref={dropdownRef} style={{ position: 'relative', display: 'inline-block' }}>\n {/* Preset Button */}\n <button\n onClick={() => !disabled && setIsOpen(!isOpen)}\n disabled={disabled}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n padding: '8px 14px',\n backgroundColor: activePreset ? SEMANTIC_COLORS.statusSuccessBgSubtle : SEMANTIC_COLORS.bgPrimary,\n border: `1px solid ${activePreset ? SEMANTIC_COLORS.statusSuccessBg : SEMANTIC_COLORS.borderDefault}`,\n borderRadius: '6px',\n cursor: disabled ? 'not-allowed' : 'pointer',\n fontSize: '13px',\n color: activePreset ? SEMANTIC_COLORS.statusSuccessText : SEMANTIC_COLORS.textSecondary,\n fontWeight: 500,\n opacity: disabled ? 0.6 : 1,\n minWidth: '140px',\n justifyContent: 'space-between',\n }}\n >\n <span style={{ display: 'flex', alignItems: 'center', gap: '6px' }}>\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M19 21H5a2 2 0 01-2-2V5a2 2 0 012-2h11l5 5v11a2 2 0 01-2 2z\" />\n <polyline points=\"17,21 17,13 7,13 7,21\" />\n <polyline points=\"7,3 7,8 15,8\" />\n </svg>\n {activePreset ? activePreset.name : t('bigconsole.filters.presets.buttonLabel', 'Presets')}\n </span>\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n style={{\n transform: isOpen ? 'rotate(180deg)' : 'rotate(0deg)',\n transition: 'transform 0.2s ease',\n }}\n >\n <polyline points=\"6,9 12,15 18,9\" />\n </svg>\n </button>\n\n {/* Dropdown Menu */}\n {isOpen && (\n <div\n style={{\n position: 'absolute',\n top: '100%',\n left: 0,\n marginTop: '4px',\n minWidth: '280px',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n border: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n borderRadius: '8px',\n boxShadow: '0 4px 16px rgba(0,0,0,0.15)',\n zIndex: 100000,\n overflow: 'hidden',\n }}\n >\n {/* Header */}\n <div\n style={{\n padding: '12px 16px',\n borderBottom: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n backgroundColor: SEMANTIC_COLORS.bgSecondary,\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n }}\n >\n <span style={{ fontWeight: 600, fontSize: '13px', color: SEMANTIC_COLORS.textPrimary }}>\n {t('bigconsole.filters.presets.header', 'Filter Presets')}\n </span>\n <button\n onClick={() => setShowSaveDialog(true)}\n style={{\n padding: '4px 10px',\n fontSize: '12px',\n backgroundColor: SEMANTIC_COLORS.actionPrimaryBg,\n color: SEMANTIC_COLORS.actionPrimaryFg,\n border: 'none',\n borderRadius: '4px',\n cursor: 'pointer',\n fontWeight: 500,\n }}\n >\n {t('bigconsole.filters.presets.saveCurrent', '+ Save Current')}\n </button>\n </div>\n\n {/* Save Dialog */}\n {showSaveDialog && (\n <div\n style={{\n padding: '12px 16px',\n borderBottom: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n backgroundColor: SEMANTIC_COLORS.bgSecondary,\n }}\n >\n <input\n type=\"text\"\n value={newPresetName}\n onChange={(e) => setNewPresetName(e.target.value)}\n placeholder={t('bigconsole.filters.presets.namePlaceholder', 'Preset name...')}\n autoFocus\n style={{\n width: '100%',\n padding: '8px 10px',\n border: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n borderRadius: '4px',\n fontSize: '13px',\n marginBottom: '8px',\n boxSizing: 'border-box',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n color: SEMANTIC_COLORS.textPrimary,\n }}\n />\n <input\n type=\"text\"\n value={newPresetDescription}\n onChange={(e) => setNewPresetDescription(e.target.value)}\n placeholder={t('bigconsole.filters.presets.descriptionPlaceholder', 'Description (optional)...')}\n style={{\n width: '100%',\n padding: '8px 10px',\n border: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n borderRadius: '4px',\n fontSize: '13px',\n marginBottom: '8px',\n boxSizing: 'border-box',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n color: SEMANTIC_COLORS.textPrimary,\n }}\n />\n <div style={{ display: 'flex', gap: '8px', justifyContent: 'flex-end' }}>\n <button\n onClick={() => {\n setShowSaveDialog(false);\n setNewPresetName('');\n setNewPresetDescription('');\n }}\n style={{\n padding: '6px 12px',\n fontSize: '12px',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n border: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n borderRadius: '4px',\n cursor: 'pointer',\n color: SEMANTIC_COLORS.textSecondary,\n }}\n >\n {t('bigconsole.filters.presets.cancel', 'Cancel')}\n </button>\n <button\n onClick={handleSavePreset}\n disabled={!newPresetName.trim()}\n style={{\n padding: '6px 12px',\n fontSize: '12px',\n backgroundColor: newPresetName.trim()\n ? SEMANTIC_COLORS.statusSuccessBg\n : SEMANTIC_COLORS.bgTertiary,\n color: newPresetName.trim() ? SEMANTIC_COLORS.actionPrimaryFg : SEMANTIC_COLORS.textTertiary,\n border: 'none',\n borderRadius: '4px',\n cursor: newPresetName.trim() ? 'pointer' : 'not-allowed',\n fontWeight: 500,\n }}\n >\n {t('bigconsole.filters.presets.save', 'Save')}\n </button>\n </div>\n </div>\n )}\n\n {/* Preset List */}\n <div style={{ maxHeight: '300px', overflowY: 'auto' }}>\n {presets.map((preset) => (\n <div\n key={preset.id}\n onClick={() => {\n onApplyPreset(preset.id);\n setIsOpen(false);\n }}\n style={{\n padding: '10px 16px',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n backgroundColor: activePresetId === preset.id ? SEMANTIC_COLORS.actionPrimaryBgSubtle : 'transparent',\n borderLeft:\n activePresetId === preset.id\n ? `3px solid ${SEMANTIC_COLORS.actionPrimaryBg}`\n : '3px solid transparent',\n transition: 'background-color 0.15s ease',\n }}\n onMouseEnter={(e) => {\n if (activePresetId !== preset.id) {\n e.currentTarget.style.backgroundColor = SEMANTIC_COLORS.bgSecondary;\n }\n }}\n onMouseLeave={(e) => {\n if (activePresetId !== preset.id) {\n e.currentTarget.style.backgroundColor = 'transparent';\n }\n }}\n >\n <div style={{ flex: 1 }}>\n <div\n style={{\n fontSize: '13px',\n fontWeight: 500,\n color: SEMANTIC_COLORS.textPrimary,\n display: 'flex',\n alignItems: 'center',\n gap: '6px',\n }}\n >\n {preset.name}\n {preset.isDefault && (\n <span\n style={{\n fontSize: '10px',\n padding: '2px 6px',\n backgroundColor: SEMANTIC_COLORS.bgTertiary,\n borderRadius: '4px',\n color: SEMANTIC_COLORS.textSecondary,\n }}\n >\n {t('bigconsole.filters.presets.defaultBadge', 'Default')}\n </span>\n )}\n </div>\n {preset.description && (\n <div style={{ fontSize: '11px', color: SEMANTIC_COLORS.textTertiary, marginTop: '2px' }}>\n {preset.description}\n </div>\n )}\n </div>\n\n {/* Delete button (not for default or system presets) */}\n {!preset.isDefault && !preset.id.startsWith('preset-last') && !preset.id.startsWith('preset-this') && (\n <button\n onClick={(e) => handleDeletePreset(e, preset.id)}\n style={{\n padding: '4px',\n backgroundColor: 'transparent',\n border: 'none',\n cursor: 'pointer',\n color: SEMANTIC_COLORS.textTertiary,\n borderRadius: '4px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = SEMANTIC_COLORS.statusErrorBgSubtle;\n e.currentTarget.style.color = SEMANTIC_COLORS.statusErrorText;\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = 'transparent';\n e.currentTarget.style.color = SEMANTIC_COLORS.textTertiary;\n }}\n title={t('bigconsole.filters.presets.deletePresetTitle', 'Delete preset')}\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <polyline points=\"3,6 5,6 21,6\" />\n <path d=\"M19,6v14a2,2,0,01-2,2H7a2,2,0,01-2-2V6m3,0V4a2,2,0,012-2h4a2,2,0,012,2v2\" />\n </svg>\n </button>\n )}\n\n {/* Checkmark for active preset */}\n {activePresetId === preset.id && (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke={SEMANTIC_COLORS.actionPrimaryBg}\n strokeWidth=\"3\"\n style={{ marginLeft: '8px' }}\n >\n <polyline points=\"20,6 9,17 4,12\" />\n </svg>\n )}\n </div>\n ))}\n\n {presets.length === 0 && (\n <div\n style={{\n padding: '20px 16px',\n textAlign: 'center',\n color: SEMANTIC_COLORS.textTertiary,\n fontSize: '13px',\n }}\n >\n {t('bigconsole.filters.presets.emptyState', 'No presets saved yet')}\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n );\n}\n\nexport default FilterPresetSelector;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FilterPresetSelector.js","names":[],"sources":["../../../../../src/bigconsole/components/dashboard/GlobalFiltersBar/FilterPresetSelector.tsx"],"sourcesContent":["/**\n * FilterPresetSelector Component\n *\n * Dropdown to select, save, and manage filter presets.\n */\n\nimport React, { useState, useRef, useEffect } from 'react';\nimport type { FilterPreset } from '../../../hooks/useFilterPresets';\nimport { SEMANTIC_COLORS } from '../../../utils/semanticTokens';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface FilterPresetSelectorProps {\n presets: FilterPreset[];\n activePresetId: string | null;\n onApplyPreset: (presetId: string) => void;\n onSavePreset: (name: string, description?: string) => void;\n onDeletePreset: (presetId: string) => void;\n disabled?: boolean;\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport function FilterPresetSelector({\n presets,\n activePresetId,\n onApplyPreset,\n onSavePreset,\n onDeletePreset,\n disabled = false,\n}: FilterPresetSelectorProps) {\n const { t } = useI18n();\n const [isOpen, setIsOpen] = useState(false);\n const [showSaveDialog, setShowSaveDialog] = useState(false);\n const [newPresetName, setNewPresetName] = useState('');\n const [newPresetDescription, setNewPresetDescription] = useState('');\n const dropdownRef = useRef<HTMLDivElement>(null);\n\n const activePreset = presets.find((p) => p.id === activePresetId);\n\n // Close dropdown when clicking outside\n useEffect(() => {\n function handleClickOutside(event: MouseEvent) {\n if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {\n setIsOpen(false);\n setShowSaveDialog(false);\n }\n }\n\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, []);\n\n const handleSavePreset = () => {\n if (newPresetName.trim()) {\n onSavePreset(newPresetName.trim(), newPresetDescription.trim() || undefined);\n setNewPresetName('');\n setNewPresetDescription('');\n setShowSaveDialog(false);\n setIsOpen(false);\n }\n };\n\n const handleDeletePreset = (e: React.MouseEvent, presetId: string) => {\n e.stopPropagation();\n if (window.confirm(t('bigconsole.filters.presets.deleteConfirm', 'Are you sure you want to delete this preset?'))) {\n onDeletePreset(presetId);\n }\n };\n\n return (\n <div ref={dropdownRef} style={{ position: 'relative', display: 'inline-block' }}>\n {/* Preset Button */}\n <button\n onClick={() => !disabled && setIsOpen(!isOpen)}\n disabled={disabled}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n padding: '8px 14px',\n backgroundColor: activePreset ? SEMANTIC_COLORS.statusSuccessBgSubtle : SEMANTIC_COLORS.bgPrimary,\n border: `1px solid ${activePreset ? SEMANTIC_COLORS.statusSuccessBg : SEMANTIC_COLORS.borderDefault}`,\n borderRadius: '6px',\n cursor: disabled ? 'not-allowed' : 'pointer',\n fontSize: '13px',\n color: activePreset ? SEMANTIC_COLORS.statusSuccessText : SEMANTIC_COLORS.textSecondary,\n fontWeight: 500,\n opacity: disabled ? 0.6 : 1,\n minWidth: 'min(140px, 100%)',\n maxWidth: '100%',\n justifyContent: 'space-between',\n }}\n >\n <span style={{ display: 'flex', alignItems: 'center', gap: '6px' }}>\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M19 21H5a2 2 0 01-2-2V5a2 2 0 012-2h11l5 5v11a2 2 0 01-2 2z\" />\n <polyline points=\"17,21 17,13 7,13 7,21\" />\n <polyline points=\"7,3 7,8 15,8\" />\n </svg>\n {activePreset ? activePreset.name : t('bigconsole.filters.presets.buttonLabel', 'Presets')}\n </span>\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n style={{\n transform: isOpen ? 'rotate(180deg)' : 'rotate(0deg)',\n transition: 'transform 0.2s ease',\n }}\n >\n <polyline points=\"6,9 12,15 18,9\" />\n </svg>\n </button>\n\n {/* Dropdown Menu */}\n {isOpen && (\n <div\n style={{\n position: 'absolute',\n top: '100%',\n left: 0,\n marginTop: '4px',\n minWidth: 'min(280px, calc(100vw - 2rem))',\n maxWidth: 'calc(100vw - 2rem)',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n border: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n borderRadius: '8px',\n boxShadow: 'var(--shadow-elevation-2)',\n zIndex: 100000,\n overflow: 'hidden',\n }}\n >\n {/* Header */}\n <div\n style={{\n padding: '12px 16px',\n borderBottom: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n backgroundColor: SEMANTIC_COLORS.bgSecondary,\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n }}\n >\n <span style={{ fontWeight: 600, fontSize: '13px', color: SEMANTIC_COLORS.textPrimary }}>\n {t('bigconsole.filters.presets.header', 'Filter Presets')}\n </span>\n <button\n onClick={() => setShowSaveDialog(true)}\n style={{\n padding: '4px 10px',\n fontSize: '12px',\n backgroundColor: SEMANTIC_COLORS.actionPrimaryBg,\n color: SEMANTIC_COLORS.actionPrimaryFg,\n border: 'none',\n borderRadius: '4px',\n cursor: 'pointer',\n fontWeight: 500,\n }}\n >\n {t('bigconsole.filters.presets.saveCurrent', '+ Save Current')}\n </button>\n </div>\n\n {/* Save Dialog */}\n {showSaveDialog && (\n <div\n style={{\n padding: '12px 16px',\n borderBottom: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n backgroundColor: SEMANTIC_COLORS.bgSecondary,\n }}\n >\n <input\n type=\"text\"\n value={newPresetName}\n onChange={(e) => setNewPresetName(e.target.value)}\n placeholder={t('bigconsole.filters.presets.namePlaceholder', 'Preset name...')}\n autoFocus\n style={{\n width: '100%',\n padding: '8px 10px',\n border: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n borderRadius: '4px',\n fontSize: '13px',\n marginBottom: '8px',\n boxSizing: 'border-box',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n color: SEMANTIC_COLORS.textPrimary,\n }}\n />\n <input\n type=\"text\"\n value={newPresetDescription}\n onChange={(e) => setNewPresetDescription(e.target.value)}\n placeholder={t('bigconsole.filters.presets.descriptionPlaceholder', 'Description (optional)...')}\n style={{\n width: '100%',\n padding: '8px 10px',\n border: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n borderRadius: '4px',\n fontSize: '13px',\n marginBottom: '8px',\n boxSizing: 'border-box',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n color: SEMANTIC_COLORS.textPrimary,\n }}\n />\n <div style={{ display: 'flex', gap: '8px', justifyContent: 'flex-end' }}>\n <button\n onClick={() => {\n setShowSaveDialog(false);\n setNewPresetName('');\n setNewPresetDescription('');\n }}\n style={{\n padding: '6px 12px',\n fontSize: '12px',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n border: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n borderRadius: '4px',\n cursor: 'pointer',\n color: SEMANTIC_COLORS.textSecondary,\n }}\n >\n {t('bigconsole.filters.presets.cancel', 'Cancel')}\n </button>\n <button\n onClick={handleSavePreset}\n disabled={!newPresetName.trim()}\n style={{\n padding: '6px 12px',\n fontSize: '12px',\n backgroundColor: newPresetName.trim()\n ? SEMANTIC_COLORS.statusSuccessBg\n : SEMANTIC_COLORS.bgTertiary,\n color: newPresetName.trim() ? SEMANTIC_COLORS.actionPrimaryFg : SEMANTIC_COLORS.textTertiary,\n border: 'none',\n borderRadius: '4px',\n cursor: newPresetName.trim() ? 'pointer' : 'not-allowed',\n fontWeight: 500,\n }}\n >\n {t('bigconsole.filters.presets.save', 'Save')}\n </button>\n </div>\n </div>\n )}\n\n {/* Preset List */}\n <div style={{ maxHeight: '300px', overflowY: 'auto' }}>\n {presets.map((preset) => (\n <div\n key={preset.id}\n onClick={() => {\n onApplyPreset(preset.id);\n setIsOpen(false);\n }}\n style={{\n padding: '10px 16px',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n backgroundColor: activePresetId === preset.id ? SEMANTIC_COLORS.actionPrimaryBgSubtle : 'transparent',\n borderLeft:\n activePresetId === preset.id\n ? `3px solid ${SEMANTIC_COLORS.actionPrimaryBg}`\n : '3px solid transparent',\n transition: 'background-color 0.15s ease',\n }}\n onMouseEnter={(e) => {\n if (activePresetId !== preset.id) {\n e.currentTarget.style.backgroundColor = SEMANTIC_COLORS.bgSecondary;\n }\n }}\n onMouseLeave={(e) => {\n if (activePresetId !== preset.id) {\n e.currentTarget.style.backgroundColor = 'transparent';\n }\n }}\n >\n <div style={{ flex: 1 }}>\n <div\n style={{\n fontSize: '13px',\n fontWeight: 500,\n color: SEMANTIC_COLORS.textPrimary,\n display: 'flex',\n alignItems: 'center',\n gap: '6px',\n }}\n >\n {preset.name}\n {preset.isDefault && (\n <span\n style={{\n fontSize: '10px',\n padding: '2px 6px',\n backgroundColor: SEMANTIC_COLORS.bgTertiary,\n borderRadius: '4px',\n color: SEMANTIC_COLORS.textSecondary,\n }}\n >\n {t('bigconsole.filters.presets.defaultBadge', 'Default')}\n </span>\n )}\n </div>\n {preset.description && (\n <div style={{ fontSize: '11px', color: SEMANTIC_COLORS.textTertiary, marginTop: '2px' }}>\n {preset.description}\n </div>\n )}\n </div>\n\n {/* Delete button (not for default or system presets) */}\n {!preset.isDefault && !preset.id.startsWith('preset-last') && !preset.id.startsWith('preset-this') && (\n <button\n onClick={(e) => handleDeletePreset(e, preset.id)}\n style={{\n padding: '4px',\n backgroundColor: 'transparent',\n border: 'none',\n cursor: 'pointer',\n color: SEMANTIC_COLORS.textTertiary,\n borderRadius: '4px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = SEMANTIC_COLORS.statusErrorBgSubtle;\n e.currentTarget.style.color = SEMANTIC_COLORS.statusErrorText;\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = 'transparent';\n e.currentTarget.style.color = SEMANTIC_COLORS.textTertiary;\n }}\n title={t('bigconsole.filters.presets.deletePresetTitle', 'Delete preset')}\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <polyline points=\"3,6 5,6 21,6\" />\n <path d=\"M19,6v14a2,2,0,01-2,2H7a2,2,0,01-2-2V6m3,0V4a2,2,0,012-2h4a2,2,0,012,2v2\" />\n </svg>\n </button>\n )}\n\n {/* Checkmark for active preset */}\n {activePresetId === preset.id && (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke={SEMANTIC_COLORS.actionPrimaryBg}\n strokeWidth=\"3\"\n style={{ marginLeft: '8px' }}\n >\n <polyline points=\"20,6 9,17 4,12\" />\n </svg>\n )}\n </div>\n ))}\n\n {presets.length === 0 && (\n <div\n style={{\n padding: '20px 16px',\n textAlign: 'center',\n color: SEMANTIC_COLORS.textTertiary,\n fontSize: '13px',\n }}\n >\n {t('bigconsole.filters.presets.emptyState', 'No presets saved yet')}\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n );\n}\n\nexport default FilterPresetSelector;\n"],"mappings":"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"}
|