@burdenoff/microfe-bigconsole 2026.728.1 → 2026.729.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.
Files changed (111) hide show
  1. package/dist/bigconsole/components/DrilldownDashboardRenderer.js +1 -1
  2. package/dist/bigconsole/components/DrilldownDashboardRenderer.js.map +1 -1
  3. package/dist/bigconsole/components/builder/inspector/DataBindingSection.js +4 -4
  4. package/dist/bigconsole/components/builder/inspector/DataBindingSection.js.map +1 -1
  5. package/dist/bigconsole/components/datasink/CacheTTLSelector.js +5 -5
  6. package/dist/bigconsole/components/datasink/CacheTTLSelector.js.map +1 -1
  7. package/dist/bigconsole/components/datasink/DataSinkCard.js +3 -3
  8. package/dist/bigconsole/components/datasink/DataSinkCard.js.map +1 -1
  9. package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js +4 -4
  10. package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js.map +1 -1
  11. package/dist/bigconsole/components/datasink/DataSinkStatusBadge.js +6 -6
  12. package/dist/bigconsole/components/datasink/DataSinkStatusBadge.js.map +1 -1
  13. package/dist/bigconsole/components/datasink/LinkedWorkflowsPanel.js +9 -9
  14. package/dist/bigconsole/components/datasink/LinkedWorkflowsPanel.js.map +1 -1
  15. package/dist/bigconsole/components/datasink/RefreshTypeSelector.js +2 -2
  16. package/dist/bigconsole/components/datasink/RefreshTypeSelector.js.map +1 -1
  17. package/dist/bigconsole/components/datasink/SetupStateBadge.js +8 -8
  18. package/dist/bigconsole/components/datasink/SetupStateBadge.js.map +1 -1
  19. package/dist/bigconsole/components/datasink/WorkflowStatusPanel.js +13 -13
  20. package/dist/bigconsole/components/datasink/WorkflowStatusPanel.js.map +1 -1
  21. package/dist/bigconsole/components/parser/DataSinkSelector.js +2 -2
  22. package/dist/bigconsole/components/parser/DataSinkSelector.js.map +1 -1
  23. package/dist/bigconsole/components/parser/ExpressionEditor.js +1 -1
  24. package/dist/bigconsole/components/parser/ExpressionEditor.js.map +1 -1
  25. package/dist/bigconsole/components/parser/ParserCard.js +1 -1
  26. package/dist/bigconsole/components/parser/ParserCard.js.map +1 -1
  27. package/dist/bigconsole/components/parser/ParserSelector.js +2 -2
  28. package/dist/bigconsole/components/parser/ParserSelector.js.map +1 -1
  29. package/dist/bigconsole/components/parser/ParserStatusBadge.js +2 -2
  30. package/dist/bigconsole/components/parser/ParserStatusBadge.js.map +1 -1
  31. package/dist/bigconsole/components/pipeline/PipelineCard.js +2 -2
  32. package/dist/bigconsole/components/pipeline/PipelineCard.js.map +1 -1
  33. package/dist/bigconsole/components/pipeline/PipelineDeleteDialog.js +5 -5
  34. package/dist/bigconsole/components/pipeline/PipelineDeleteDialog.js.map +1 -1
  35. package/dist/bigconsole/components/pipeline/PipelineStatusBadge.js +3 -3
  36. package/dist/bigconsole/components/pipeline/PipelineStatusBadge.js.map +1 -1
  37. package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js +1 -1
  38. package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js.map +1 -1
  39. package/dist/bigconsole/components/widgets/PropertiesPanel.js +3 -3
  40. package/dist/bigconsole/components/widgets/PropertiesPanel.js.map +1 -1
  41. package/dist/bigconsole/components/widgets/WidgetErrorBoundary.js +2 -2
  42. package/dist/bigconsole/components/widgets/WidgetErrorBoundary.js.map +1 -1
  43. package/dist/bigconsole/components/widgets/WidgetMenu.js +1 -1
  44. package/dist/bigconsole/components/widgets/WidgetMenu.js.map +1 -1
  45. package/dist/bigconsole/components/widgets/adaptive-card/AdaptiveCardWidget.js +3 -3
  46. package/dist/bigconsole/components/widgets/adaptive-card/AdaptiveCardWidget.js.map +1 -1
  47. package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js +1 -1
  48. package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js.map +1 -1
  49. package/dist/bigconsole/components/widgets/gauge/GaugeConfig.js +3 -3
  50. package/dist/bigconsole/components/widgets/gauge/GaugeConfig.js.map +1 -1
  51. package/dist/bigconsole/components/widgets/heatmap/HeatmapWidget.js +52 -32
  52. package/dist/bigconsole/components/widgets/heatmap/HeatmapWidget.js.map +1 -1
  53. package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js +3 -3
  54. package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js.map +1 -1
  55. package/dist/bigconsole/components/widgets/kpi/KPIWidget.js +1 -1
  56. package/dist/bigconsole/components/widgets/kpi/KPIWidget.js.map +1 -1
  57. package/dist/bigconsole/components/widgets/kpi-comparison/KPIComparisonWidget.js +2 -2
  58. package/dist/bigconsole/components/widgets/kpi-comparison/KPIComparisonWidget.js.map +1 -1
  59. package/dist/bigconsole/components/widgets/list/ListItem.js +3 -3
  60. package/dist/bigconsole/components/widgets/list/ListItem.js.map +1 -1
  61. package/dist/bigconsole/components/widgets/metric-card/ComparisonBadge.js +1 -1
  62. package/dist/bigconsole/components/widgets/metric-card/ComparisonBadge.js.map +1 -1
  63. package/dist/bigconsole/components/widgets/metric-card/MetricCardWidget.js +1 -1
  64. package/dist/bigconsole/components/widgets/metric-card/MetricCardWidget.js.map +1 -1
  65. package/dist/bigconsole/components/widgets/metric-card/SparklineChart.js +6 -6
  66. package/dist/bigconsole/components/widgets/metric-card/SparklineChart.js.map +1 -1
  67. package/dist/bigconsole/components/widgets/metric-card/TrendIndicator.js +1 -1
  68. package/dist/bigconsole/components/widgets/metric-card/TrendIndicator.js.map +1 -1
  69. package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js +2 -2
  70. package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js.map +1 -1
  71. package/dist/bigconsole/components/widgets/progress/ProgressBar.js +4 -4
  72. package/dist/bigconsole/components/widgets/progress/ProgressBar.js.map +1 -1
  73. package/dist/bigconsole/components/widgets/progress/ProgressConfig.js +1 -1
  74. package/dist/bigconsole/components/widgets/progress/ProgressConfig.js.map +1 -1
  75. package/dist/bigconsole/components/widgets/progress/ProgressWidget.js +1 -1
  76. package/dist/bigconsole/components/widgets/progress/ProgressWidget.js.map +1 -1
  77. package/dist/bigconsole/components/widgets/retention/RetentionWidget.js +2 -2
  78. package/dist/bigconsole/components/widgets/retention/RetentionWidget.js.map +1 -1
  79. package/dist/bigconsole/components/widgets/states/ErrorState.js +2 -2
  80. package/dist/bigconsole/components/widgets/states/ErrorState.js.map +1 -1
  81. package/dist/bigconsole/components/widgets/table/TableConfig.js +2 -2
  82. package/dist/bigconsole/components/widgets/table/TableConfig.js.map +1 -1
  83. package/dist/bigconsole/components/widgets/timeline/TimelineWidget.js +1 -1
  84. package/dist/bigconsole/components/widgets/timeline/TimelineWidget.js.map +1 -1
  85. package/dist/bigconsole/components/widgets/widget-actions/WidgetActions.js +6 -6
  86. package/dist/bigconsole/components/widgets/widget-actions/WidgetActions.js.map +1 -1
  87. package/dist/bigconsole/components/workflow/WorkflowCard.js +1 -1
  88. package/dist/bigconsole/components/workflow/WorkflowCard.js.map +1 -1
  89. package/dist/bigconsole/components/workflow/WorkflowDeleteDialog.js +5 -5
  90. package/dist/bigconsole/components/workflow/WorkflowDeleteDialog.js.map +1 -1
  91. package/dist/bigconsole/components/workflow/WorkflowStatusBadge.js +6 -6
  92. package/dist/bigconsole/components/workflow/WorkflowStatusBadge.js.map +1 -1
  93. package/dist/bigconsole/pages/DataSinkBuilderPage.js +17 -17
  94. package/dist/bigconsole/pages/DataSinkBuilderPage.js.map +1 -1
  95. package/dist/bigconsole/pages/DataSinkViewPage.js +2 -2
  96. package/dist/bigconsole/pages/DataSinkViewPage.js.map +1 -1
  97. package/dist/bigconsole/pages/ParserBuilderPage.js +24 -24
  98. package/dist/bigconsole/pages/ParserBuilderPage.js.map +1 -1
  99. package/dist/bigconsole/pages/ParserViewPage.js +8 -8
  100. package/dist/bigconsole/pages/ParserViewPage.js.map +1 -1
  101. package/dist/bigconsole/pages/PipelineBuilderPage.js +9 -9
  102. package/dist/bigconsole/pages/PipelineBuilderPage.js.map +1 -1
  103. package/dist/bigconsole/pages/PipelineViewPage.js +12 -12
  104. package/dist/bigconsole/pages/PipelineViewPage.js.map +1 -1
  105. package/dist/bigconsole/pages/WorkflowViewPage.js +6 -6
  106. package/dist/bigconsole/pages/WorkflowViewPage.js.map +1 -1
  107. package/dist/bigconsole/renderers/adapters/AdaptiveCardRenderer.js +1 -1
  108. package/dist/bigconsole/renderers/adapters/AdaptiveCardRenderer.js.map +1 -1
  109. package/dist/bigconsole/renderers/adapters/BlockKitRenderer.js +2 -2
  110. package/dist/bigconsole/renderers/adapters/BlockKitRenderer.js.map +1 -1
  111. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ParserSelector.js","names":[],"sources":["../../../../src/bigconsole/components/parser/ParserSelector.tsx"],"sourcesContent":["/**\n * Parser Selector\n *\n * Dropdown component for selecting a parser.\n * Shows both dashboard-specific parsers and global parsers.\n */\n\nimport { memo, useState, useEffect, useCallback, Fragment, useMemo } from 'react';\nimport { useParserOperations } from '../../hooks/useParserOperations';\nimport { ParserTypeBadge } from './ParserTypeBadge';\nimport { ParserStatusBadge } from './ParserStatusBadge';\nimport type { ParserType, ParserStatus } from '../../types';\n\n// Default console ID for global parsers\nconst DEFAULT_CONSOLE_ID = 'default';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface ParserSelectorProps {\n /** Console ID */\n consoleId: string;\n /** Currently selected parser ID */\n value: string | null;\n /** Callback when selection changes */\n onChange: (id: string | null) => void;\n /** Filter by type */\n filterType?: ParserType;\n /** Filter by status */\n filterStatus?: ParserStatus;\n /** Filter by input DataSink key */\n filterInputSinkKey?: string | null;\n /** Placeholder text */\n placeholder?: string;\n /** Whether the selector is disabled */\n disabled?: boolean;\n /** Whether to show error state */\n error?: boolean;\n /** Error message to display */\n errorMessage?: string;\n}\n\n// ============================================================================\n// ICONS\n// ============================================================================\n\nconst ChevronDownIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 9l-7 7-7-7\" />\n </svg>\n);\n\nconst GlobeIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M12 21a9 9 0 100-18 9 9 0 000 18z\" />\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M3.6 9h16.8M3.6 15h16.8\" />\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 3a15 15 0 014 9 15 15 0 01-4 9 15 15 0 01-4-9 15 15 0 014-9z\"\n />\n </svg>\n);\n\n// ============================================================================\n// PARSER OPTION BUTTON\n// ============================================================================\n\ninterface ParserOptionButtonProps {\n parser: {\n id: string;\n name: string;\n description: string | null;\n type: 'jq' | 'jsonata';\n inputSinkKey: string;\n outputKey: string;\n status: 'active' | 'inactive';\n };\n isSelected: boolean;\n onSelect: (id: string) => void;\n isGlobal?: boolean;\n}\n\nconst ParserOptionButton = memo(function ParserOptionButton({\n parser,\n isSelected,\n onSelect,\n isGlobal = false,\n}: ParserOptionButtonProps) {\n return (\n <button\n type=\"button\"\n onClick={() => onSelect(parser.id)}\n className={`\n w-full px-3 py-2.5\n text-left\n hover:bg-bg-sunken\n transition-colors\n border-b border-border-default last:border-b-0\n ${isSelected ? 'bg-action-primary-bg/10' : ''}\n `}\n >\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"flex-1 min-w-0\">\n {/* Name and type */}\n <div className=\"flex items-center gap-2 mb-1\">\n <ParserTypeBadge type={parser.type} size=\"sm\" />\n <span className=\"text-sm font-medium text-text-primary truncate\">{parser.name}</span>\n {isGlobal && (\n <span className=\"inline-flex items-center gap-1 px-1.5 py-0.5 text-xs bg-bg-sunken text-text-secondary rounded\">\n <GlobeIcon className=\"w-3 h-3\" />\n Global\n </span>\n )}\n </div>\n\n {/* Description */}\n {parser.description && <p className=\"text-xs text-text-secondary line-clamp-1 mb-1\">{parser.description}</p>}\n\n {/* Data flow */}\n <div className=\"flex items-center gap-2 text-xs text-text-tertiary\">\n <span>\n {parser.inputSinkKey} → {parser.outputKey}\n </span>\n </div>\n </div>\n\n {/* Status badge */}\n <div>\n <ParserStatusBadge status={parser.status} size=\"sm\" showIcon={false} />\n </div>\n </div>\n </button>\n );\n});\n\n// ============================================================================\n// MAIN COMPONENT\n// ============================================================================\n\nexport const ParserSelector = memo(function ParserSelector({\n consoleId,\n value,\n onChange,\n filterType,\n filterStatus = 'active',\n filterInputSinkKey,\n placeholder = 'Select a parser...',\n disabled = false,\n error = false,\n errorMessage,\n}: ParserSelectorProps) {\n const [isOpen, setIsOpen] = useState(false);\n const [searchQuery, setSearchQuery] = useState('');\n\n // Determine if we need to fetch global parsers separately\n const isGlobalConsole = consoleId === DEFAULT_CONSOLE_ID;\n\n // Fetch dashboard-specific parsers\n const {\n parsers: dashboardParsers,\n loading: dashboardLoading,\n fetchParsers: fetchDashboardParsers,\n } = useParserOperations({\n consoleId,\n skipFetch: isGlobalConsole, // Skip if already fetching global\n });\n\n // Fetch global parsers (only if consoleId is not already 'default')\n const {\n parsers: globalParsers,\n loading: globalLoading,\n fetchParsers: fetchGlobalParsers,\n } = useParserOperations({\n consoleId: DEFAULT_CONSOLE_ID,\n skipFetch: isGlobalConsole, // Skip if consoleId is already 'default'\n });\n\n // Combine parsers: dashboard-specific + global (avoiding duplicates)\n const allParsers = useMemo(() => {\n if (isGlobalConsole) {\n // If we're already on global console, just return dashboard parsers\n return dashboardParsers;\n }\n\n // Combine both, with dashboard parsers first\n const parserIds = new Set(dashboardParsers.map((p) => p.id));\n const uniqueGlobalParsers = globalParsers.filter((p) => !parserIds.has(p.id));\n\n return [...dashboardParsers, ...uniqueGlobalParsers];\n }, [dashboardParsers, globalParsers, isGlobalConsole]);\n\n // Combined loading state\n const loading = dashboardLoading || globalLoading;\n\n // Filter parsers\n const filteredParsers = useMemo(() => {\n return allParsers.filter((p) => {\n // Filter by type if specified\n if (filterType && p.type !== filterType) return false;\n\n // Filter by status if specified\n if (filterStatus && p.status !== filterStatus) return false;\n\n // Filter by input DataSink key if specified\n if (filterInputSinkKey && p.inputSinkKey !== filterInputSinkKey) return false;\n\n // Filter by search query\n if (searchQuery) {\n const query = searchQuery.toLowerCase();\n return (\n p.name.toLowerCase().includes(query) ||\n p.description?.toLowerCase().includes(query) ||\n p.inputSinkKey.toLowerCase().includes(query) ||\n p.outputKey.toLowerCase().includes(query)\n );\n }\n\n return true;\n });\n }, [allParsers, filterType, filterStatus, filterInputSinkKey, searchQuery]);\n\n // Group parsers by scope for display\n const { dashboardScopedParsers, globalScopedParsers } = useMemo(() => {\n const dashboard = filteredParsers.filter((p) => p.consoleId !== DEFAULT_CONSOLE_ID);\n const global = filteredParsers.filter((p) => p.consoleId === DEFAULT_CONSOLE_ID);\n return { dashboardScopedParsers: dashboard, globalScopedParsers: global };\n }, [filteredParsers]);\n\n // Find selected parser\n const selectedParser = allParsers.find((p) => p.id === value);\n\n // Fetch parsers when console changes or DataSink filter changes\n useEffect(() => {\n if (consoleId) {\n fetchDashboardParsers({ type: filterType, status: filterStatus ?? undefined });\n\n // Also fetch global parsers if not already on global console\n if (!isGlobalConsole) {\n fetchGlobalParsers({ type: filterType, status: filterStatus ?? undefined });\n }\n }\n }, [\n consoleId,\n filterType,\n filterStatus,\n filterInputSinkKey,\n fetchDashboardParsers,\n fetchGlobalParsers,\n isGlobalConsole,\n ]);\n\n // Handle selection\n const handleSelect = useCallback(\n (id: string | null) => {\n onChange(id);\n setIsOpen(false);\n setSearchQuery('');\n },\n [onChange]\n );\n\n // Toggle dropdown\n const handleToggle = useCallback(() => {\n if (!disabled) {\n setIsOpen((prev) => !prev);\n }\n }, [disabled]);\n\n // Close dropdown\n const handleClose = useCallback(() => {\n setIsOpen(false);\n }, []);\n\n return (\n <div className=\"relative\">\n {/* Trigger button */}\n <button\n type=\"button\"\n onClick={handleToggle}\n disabled={disabled}\n className={`\n w-full\n px-3 py-2\n bg-bg-surface\n border rounded-md\n text-left\n flex items-center justify-between gap-2\n transition-colors\n ${disabled ? 'opacity-50 cursor-not-allowed' : 'hover:border-action-primary-bg cursor-pointer'}\n ${error ? 'border-state-error' : 'border-border-default'}\n ${isOpen ? 'border-action-primary-bg ring-2 ring-action-primary-bg/20' : ''}\n `}\n >\n <div className=\"flex-1 min-w-0\">\n {selectedParser ? (\n <div className=\"flex items-center gap-2\">\n <ParserTypeBadge type={selectedParser.type} size=\"sm\" />\n <span className=\"text-sm text-text-primary truncate\">{selectedParser.name}</span>\n </div>\n ) : (\n <span className=\"text-sm text-text-tertiary\">{placeholder}</span>\n )}\n </div>\n\n <ChevronDownIcon\n className={`w-4 h-4 text-text-secondary transition-transform ${isOpen ? 'transform rotate-180' : ''}`}\n />\n </button>\n\n {/* Error message */}\n {error && errorMessage && <p className=\"mt-1 text-xs text-state-error\">{errorMessage}</p>}\n\n {/* Dropdown */}\n {isOpen && (\n <Fragment>\n {/* Backdrop */}\n <div className=\"fixed inset-0 z-10\" onClick={handleClose} />\n\n {/* Dropdown content */}\n <div className=\"absolute left-0 right-0 top-full mt-1 z-20 bg-bg-surface border border-border-default rounded-md shadow-lg max-h-80 flex flex-col overflow-hidden\">\n {/* Search input */}\n <div className=\"p-2 border-b border-border-default\">\n <input\n type=\"text\"\n placeholder=\"Search parsers...\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className={`\n w-full px-3 py-2\n bg-bg-sunken\n border border-border-default\n rounded-md\n text-sm text-text-primary\n placeholder-text-tertiary\n focus:outline-none\n focus:border-action-primary-bg\n focus:ring-2\n focus:ring-action-primary-bg/20\n `}\n />\n </div>\n\n {/* Options list */}\n <div className=\"overflow-y-auto flex-1\">\n {loading ? (\n <div className=\"p-4 text-center text-sm text-text-secondary\">Loading parsers...</div>\n ) : filteredParsers.length === 0 ? (\n <div className=\"p-4 text-center text-sm text-text-secondary\">No parsers found</div>\n ) : (\n <Fragment>\n {/* None option */}\n <button\n type=\"button\"\n onClick={() => handleSelect(null)}\n className={`\n w-full px-3 py-2\n text-left text-sm\n hover:bg-bg-sunken\n transition-colors\n ${value === null ? 'bg-action-primary-bg/10 text-action-primary-bg' : 'text-text-secondary'}\n `}\n >\n <span className=\"italic\">None</span>\n </button>\n\n {/* Dashboard-scoped parsers section */}\n {dashboardScopedParsers.length > 0 && (\n <Fragment>\n <div className=\"px-3 py-1.5 bg-bg-sunken border-y border-border-default\">\n <span className=\"text-xs font-medium text-text-secondary uppercase tracking-wide\">\n Dashboard Parsers\n </span>\n </div>\n {dashboardScopedParsers.map((parser) => (\n <ParserOptionButton\n key={parser.id}\n parser={parser}\n isSelected={value === parser.id}\n onSelect={handleSelect}\n />\n ))}\n </Fragment>\n )}\n\n {/* Global parsers section */}\n {globalScopedParsers.length > 0 && (\n <Fragment>\n <div className=\"px-3 py-1.5 bg-bg-sunken border-y border-border-default\">\n <span className=\"text-xs font-medium text-text-secondary uppercase tracking-wide\">\n Global Parsers\n </span>\n </div>\n {globalScopedParsers.map((parser) => (\n <ParserOptionButton\n key={parser.id}\n parser={parser}\n isSelected={value === parser.id}\n onSelect={handleSelect}\n isGlobal\n />\n ))}\n </Fragment>\n )}\n </Fragment>\n )}\n </div>\n </div>\n </Fragment>\n )}\n </div>\n );\n});\n\nexport default ParserSelector;\n"],"mappings":"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"}
1
+ {"version":3,"file":"ParserSelector.js","names":[],"sources":["../../../../src/bigconsole/components/parser/ParserSelector.tsx"],"sourcesContent":["/**\n * Parser Selector\n *\n * Dropdown component for selecting a parser.\n * Shows both dashboard-specific parsers and global parsers.\n */\n\nimport { memo, useState, useEffect, useCallback, Fragment, useMemo } from 'react';\nimport { useParserOperations } from '../../hooks/useParserOperations';\nimport { ParserTypeBadge } from './ParserTypeBadge';\nimport { ParserStatusBadge } from './ParserStatusBadge';\nimport type { ParserType, ParserStatus } from '../../types';\n\n// Default console ID for global parsers\nconst DEFAULT_CONSOLE_ID = 'default';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface ParserSelectorProps {\n /** Console ID */\n consoleId: string;\n /** Currently selected parser ID */\n value: string | null;\n /** Callback when selection changes */\n onChange: (id: string | null) => void;\n /** Filter by type */\n filterType?: ParserType;\n /** Filter by status */\n filterStatus?: ParserStatus;\n /** Filter by input DataSink key */\n filterInputSinkKey?: string | null;\n /** Placeholder text */\n placeholder?: string;\n /** Whether the selector is disabled */\n disabled?: boolean;\n /** Whether to show error state */\n error?: boolean;\n /** Error message to display */\n errorMessage?: string;\n}\n\n// ============================================================================\n// ICONS\n// ============================================================================\n\nconst ChevronDownIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 9l-7 7-7-7\" />\n </svg>\n);\n\nconst GlobeIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M12 21a9 9 0 100-18 9 9 0 000 18z\" />\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M3.6 9h16.8M3.6 15h16.8\" />\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 3a15 15 0 014 9 15 15 0 01-4 9 15 15 0 01-4-9 15 15 0 014-9z\"\n />\n </svg>\n);\n\n// ============================================================================\n// PARSER OPTION BUTTON\n// ============================================================================\n\ninterface ParserOptionButtonProps {\n parser: {\n id: string;\n name: string;\n description: string | null;\n type: 'jq' | 'jsonata';\n inputSinkKey: string;\n outputKey: string;\n status: 'active' | 'inactive';\n };\n isSelected: boolean;\n onSelect: (id: string) => void;\n isGlobal?: boolean;\n}\n\nconst ParserOptionButton = memo(function ParserOptionButton({\n parser,\n isSelected,\n onSelect,\n isGlobal = false,\n}: ParserOptionButtonProps) {\n return (\n <button\n type=\"button\"\n onClick={() => onSelect(parser.id)}\n className={`\n w-full px-3 py-2.5\n text-left\n hover:bg-bg-sunken\n transition-colors\n border-b border-border-default last:border-b-0\n ${isSelected ? 'bg-action-primary-bg/10' : ''}\n `}\n >\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"flex-1 min-w-0\">\n {/* Name and type */}\n <div className=\"flex items-center gap-2 mb-1\">\n <ParserTypeBadge type={parser.type} size=\"sm\" />\n <span className=\"text-sm font-medium text-text-primary truncate\">{parser.name}</span>\n {isGlobal && (\n <span className=\"inline-flex items-center gap-1 px-1.5 py-0.5 text-xs bg-bg-sunken text-text-secondary rounded\">\n <GlobeIcon className=\"w-3 h-3\" />\n Global\n </span>\n )}\n </div>\n\n {/* Description */}\n {parser.description && <p className=\"text-xs text-text-secondary line-clamp-1 mb-1\">{parser.description}</p>}\n\n {/* Data flow */}\n <div className=\"flex items-center gap-2 text-xs text-text-tertiary\">\n <span>\n {parser.inputSinkKey} → {parser.outputKey}\n </span>\n </div>\n </div>\n\n {/* Status badge */}\n <div>\n <ParserStatusBadge status={parser.status} size=\"sm\" showIcon={false} />\n </div>\n </div>\n </button>\n );\n});\n\n// ============================================================================\n// MAIN COMPONENT\n// ============================================================================\n\nexport const ParserSelector = memo(function ParserSelector({\n consoleId,\n value,\n onChange,\n filterType,\n filterStatus = 'active',\n filterInputSinkKey,\n placeholder = 'Select a parser...',\n disabled = false,\n error = false,\n errorMessage,\n}: ParserSelectorProps) {\n const [isOpen, setIsOpen] = useState(false);\n const [searchQuery, setSearchQuery] = useState('');\n\n // Determine if we need to fetch global parsers separately\n const isGlobalConsole = consoleId === DEFAULT_CONSOLE_ID;\n\n // Fetch dashboard-specific parsers\n const {\n parsers: dashboardParsers,\n loading: dashboardLoading,\n fetchParsers: fetchDashboardParsers,\n } = useParserOperations({\n consoleId,\n skipFetch: isGlobalConsole, // Skip if already fetching global\n });\n\n // Fetch global parsers (only if consoleId is not already 'default')\n const {\n parsers: globalParsers,\n loading: globalLoading,\n fetchParsers: fetchGlobalParsers,\n } = useParserOperations({\n consoleId: DEFAULT_CONSOLE_ID,\n skipFetch: isGlobalConsole, // Skip if consoleId is already 'default'\n });\n\n // Combine parsers: dashboard-specific + global (avoiding duplicates)\n const allParsers = useMemo(() => {\n if (isGlobalConsole) {\n // If we're already on global console, just return dashboard parsers\n return dashboardParsers;\n }\n\n // Combine both, with dashboard parsers first\n const parserIds = new Set(dashboardParsers.map((p) => p.id));\n const uniqueGlobalParsers = globalParsers.filter((p) => !parserIds.has(p.id));\n\n return [...dashboardParsers, ...uniqueGlobalParsers];\n }, [dashboardParsers, globalParsers, isGlobalConsole]);\n\n // Combined loading state\n const loading = dashboardLoading || globalLoading;\n\n // Filter parsers\n const filteredParsers = useMemo(() => {\n return allParsers.filter((p) => {\n // Filter by type if specified\n if (filterType && p.type !== filterType) return false;\n\n // Filter by status if specified\n if (filterStatus && p.status !== filterStatus) return false;\n\n // Filter by input DataSink key if specified\n if (filterInputSinkKey && p.inputSinkKey !== filterInputSinkKey) return false;\n\n // Filter by search query\n if (searchQuery) {\n const query = searchQuery.toLowerCase();\n return (\n p.name.toLowerCase().includes(query) ||\n p.description?.toLowerCase().includes(query) ||\n p.inputSinkKey.toLowerCase().includes(query) ||\n p.outputKey.toLowerCase().includes(query)\n );\n }\n\n return true;\n });\n }, [allParsers, filterType, filterStatus, filterInputSinkKey, searchQuery]);\n\n // Group parsers by scope for display\n const { dashboardScopedParsers, globalScopedParsers } = useMemo(() => {\n const dashboard = filteredParsers.filter((p) => p.consoleId !== DEFAULT_CONSOLE_ID);\n const global = filteredParsers.filter((p) => p.consoleId === DEFAULT_CONSOLE_ID);\n return { dashboardScopedParsers: dashboard, globalScopedParsers: global };\n }, [filteredParsers]);\n\n // Find selected parser\n const selectedParser = allParsers.find((p) => p.id === value);\n\n // Fetch parsers when console changes or DataSink filter changes\n useEffect(() => {\n if (consoleId) {\n fetchDashboardParsers({ type: filterType, status: filterStatus ?? undefined });\n\n // Also fetch global parsers if not already on global console\n if (!isGlobalConsole) {\n fetchGlobalParsers({ type: filterType, status: filterStatus ?? undefined });\n }\n }\n }, [\n consoleId,\n filterType,\n filterStatus,\n filterInputSinkKey,\n fetchDashboardParsers,\n fetchGlobalParsers,\n isGlobalConsole,\n ]);\n\n // Handle selection\n const handleSelect = useCallback(\n (id: string | null) => {\n onChange(id);\n setIsOpen(false);\n setSearchQuery('');\n },\n [onChange]\n );\n\n // Toggle dropdown\n const handleToggle = useCallback(() => {\n if (!disabled) {\n setIsOpen((prev) => !prev);\n }\n }, [disabled]);\n\n // Close dropdown\n const handleClose = useCallback(() => {\n setIsOpen(false);\n }, []);\n\n return (\n <div className=\"relative\">\n {/* Trigger button */}\n <button\n type=\"button\"\n onClick={handleToggle}\n disabled={disabled}\n className={`\n w-full\n px-3 py-2\n bg-bg-surface\n border rounded-md\n text-left\n flex items-center justify-between gap-2\n transition-colors\n ${disabled ? 'opacity-50 cursor-not-allowed' : 'hover:border-action-primary-bg cursor-pointer'}\n ${error ? 'border-status-error-border' : 'border-border-default'}\n ${isOpen ? 'border-action-primary-bg ring-2 ring-action-primary-bg/20' : ''}\n `}\n >\n <div className=\"flex-1 min-w-0\">\n {selectedParser ? (\n <div className=\"flex items-center gap-2\">\n <ParserTypeBadge type={selectedParser.type} size=\"sm\" />\n <span className=\"text-sm text-text-primary truncate\">{selectedParser.name}</span>\n </div>\n ) : (\n <span className=\"text-sm text-text-tertiary\">{placeholder}</span>\n )}\n </div>\n\n <ChevronDownIcon\n className={`w-4 h-4 text-text-secondary transition-transform ${isOpen ? 'transform rotate-180' : ''}`}\n />\n </button>\n\n {/* Error message */}\n {error && errorMessage && <p className=\"mt-1 text-xs text-status-error-text\">{errorMessage}</p>}\n\n {/* Dropdown */}\n {isOpen && (\n <Fragment>\n {/* Backdrop */}\n <div className=\"fixed inset-0 z-10\" onClick={handleClose} />\n\n {/* Dropdown content */}\n <div className=\"absolute left-0 right-0 top-full mt-1 z-20 bg-bg-surface border border-border-default rounded-md shadow-lg max-h-80 flex flex-col overflow-hidden\">\n {/* Search input */}\n <div className=\"p-2 border-b border-border-default\">\n <input\n type=\"text\"\n placeholder=\"Search parsers...\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className={`\n w-full px-3 py-2\n bg-bg-sunken\n border border-border-default\n rounded-md\n text-sm text-text-primary\n placeholder-text-tertiary\n focus:outline-none\n focus:border-action-primary-bg\n focus:ring-2\n focus:ring-action-primary-bg/20\n `}\n />\n </div>\n\n {/* Options list */}\n <div className=\"overflow-y-auto flex-1\">\n {loading ? (\n <div className=\"p-4 text-center text-sm text-text-secondary\">Loading parsers...</div>\n ) : filteredParsers.length === 0 ? (\n <div className=\"p-4 text-center text-sm text-text-secondary\">No parsers found</div>\n ) : (\n <Fragment>\n {/* None option */}\n <button\n type=\"button\"\n onClick={() => handleSelect(null)}\n className={`\n w-full px-3 py-2\n text-left text-sm\n hover:bg-bg-sunken\n transition-colors\n ${value === null ? 'bg-action-primary-bg/10 text-action-primary-bg' : 'text-text-secondary'}\n `}\n >\n <span className=\"italic\">None</span>\n </button>\n\n {/* Dashboard-scoped parsers section */}\n {dashboardScopedParsers.length > 0 && (\n <Fragment>\n <div className=\"px-3 py-1.5 bg-bg-sunken border-y border-border-default\">\n <span className=\"text-xs font-medium text-text-secondary uppercase tracking-wide\">\n Dashboard Parsers\n </span>\n </div>\n {dashboardScopedParsers.map((parser) => (\n <ParserOptionButton\n key={parser.id}\n parser={parser}\n isSelected={value === parser.id}\n onSelect={handleSelect}\n />\n ))}\n </Fragment>\n )}\n\n {/* Global parsers section */}\n {globalScopedParsers.length > 0 && (\n <Fragment>\n <div className=\"px-3 py-1.5 bg-bg-sunken border-y border-border-default\">\n <span className=\"text-xs font-medium text-text-secondary uppercase tracking-wide\">\n Global Parsers\n </span>\n </div>\n {globalScopedParsers.map((parser) => (\n <ParserOptionButton\n key={parser.id}\n parser={parser}\n isSelected={value === parser.id}\n onSelect={handleSelect}\n isGlobal\n />\n ))}\n </Fragment>\n )}\n </Fragment>\n )}\n </div>\n </div>\n </Fragment>\n )}\n </div>\n );\n});\n\nexport default ParserSelector;\n"],"mappings":"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"}
@@ -34,8 +34,8 @@ var r = {
34
34
  }), s = e(function({ status: e, size: s = "md", showIcon: c = !0 }) {
35
35
  let l = r[s], u = i[s], d = {
36
36
  active: {
37
- bg: "bg-state-success/10",
38
- text: "text-state-success",
37
+ bg: "bg-status-success-bg/10",
38
+ text: "text-status-success-text",
39
39
  icon: /* @__PURE__ */ t(a, { className: u }),
40
40
  label: "Active"
41
41
  },
@@ -1 +1 @@
1
- {"version":3,"file":"ParserStatusBadge.js","names":[],"sources":["../../../../src/bigconsole/components/parser/ParserStatusBadge.tsx"],"sourcesContent":["/**\n * Parser Status Badge\n *\n * Badge component displaying parser status (active, inactive).\n */\n\nimport { memo } from 'react';\nimport type { ParserStatus } from '../../types';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface ParserStatusBadgeProps {\n /** Parser status */\n status: ParserStatus;\n /** Badge size */\n size?: 'sm' | 'md' | 'lg';\n /** Whether to show icon */\n showIcon?: boolean;\n}\n\n// ============================================================================\n// CONSTANTS\n// ============================================================================\n\nconst SIZE_CLASSES = {\n sm: 'px-2 py-0.5 text-xs',\n md: 'px-2.5 py-1 text-sm',\n lg: 'px-3 py-1.5 text-base',\n};\n\nconst ICON_SIZE_CLASSES = {\n sm: 'w-3 h-3',\n md: 'w-4 h-4',\n lg: 'w-5 h-5',\n};\n\n// ============================================================================\n// ICONS\n// ============================================================================\n\nconst CheckIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M5 13l4 4L19 7\" />\n </svg>\n);\n\nconst XCircleIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z\"\n />\n </svg>\n);\n\n// ============================================================================\n// COMPONENT\n// ============================================================================\n\nexport const ParserStatusBadge = memo(function ParserStatusBadge({\n status,\n size = 'md',\n showIcon = true,\n}: ParserStatusBadgeProps) {\n const sizeClass = SIZE_CLASSES[size];\n const iconSizeClass = ICON_SIZE_CLASSES[size];\n\n const config = {\n active: {\n bg: 'bg-state-success/10',\n text: 'text-state-success',\n icon: <CheckIcon className={iconSizeClass} />,\n label: 'Active',\n },\n inactive: {\n bg: 'bg-text-tertiary/10',\n text: 'text-text-tertiary',\n icon: <XCircleIcon className={iconSizeClass} />,\n label: 'Inactive',\n },\n }[status];\n\n if (!config) {\n return (\n <span\n className={`\n inline-flex items-center gap-1.5\n ${sizeClass}\n bg-bg-sunken\n text-text-secondary\n rounded-full\n font-medium\n `}\n >\n {status}\n </span>\n );\n }\n\n return (\n <span\n className={`\n inline-flex items-center gap-1.5\n ${sizeClass}\n ${config.bg}\n ${config.text}\n rounded-full\n font-medium\n `}\n >\n {showIcon && config.icon}\n <span>{config.label}</span>\n </span>\n );\n});\n\nexport default ParserStatusBadge;\n"],"mappings":";;;AA0BA,IAAM,IAAe;CACnB,IAAI;CACJ,IAAI;CACJ,IAAI;CACL,EAEK,IAAoB;CACxB,IAAI;CACJ,IAAI;CACJ,IAAI;CACL,EAMK,KAAa,EAAE,mBACnB,kBAAC,OAAD;CAAgB;CAAW,MAAK;CAAO,QAAO;CAAe,SAAQ;WACnE,kBAAC,QAAD;EAAM,eAAc;EAAQ,gBAAe;EAAQ,aAAa;EAAG,GAAE;EAAmB,CAAA;CACpF,CAAA,EAGF,KAAe,EAAE,mBACrB,kBAAC,OAAD;CAAgB;CAAW,MAAK;CAAO,QAAO;CAAe,SAAQ;WACnE,kBAAC,QAAD;EACE,eAAc;EACd,gBAAe;EACf,aAAa;EACb,GAAE;EACF,CAAA;CACE,CAAA,EAOK,IAAoB,EAAK,SAA2B,EAC/D,WACA,UAAO,MACP,cAAW,MACc;CACzB,IAAM,IAAY,EAAa,IACzB,IAAgB,EAAkB,IAElC,IAAS;EACb,QAAQ;GACN,IAAI;GACJ,MAAM;GACN,MAAM,kBAAC,GAAD,EAAW,WAAW,GAAiB,CAAA;GAC7C,OAAO;GACR;EACD,UAAU;GACR,IAAI;GACJ,MAAM;GACN,MAAM,kBAAC,GAAD,EAAa,WAAW,GAAiB,CAAA;GAC/C,OAAO;GACR;EACF,CAAC;AAmBF,QAjBK,IAkBH,kBAAC,QAAD;EACE,WAAW;;UAEP,EAAU;UACV,EAAO,GAAG;UACV,EAAO,KAAK;;;;YALlB,CAUG,KAAY,EAAO,MACpB,kBAAC,QAAD,EAAA,UAAO,EAAO,OAAa,CAAA,CACtB;MA5BL,kBAAC,QAAD;EACE,WAAW;;YAEP,EAAU;;;;;;YAOb;EACI,CAAA;EAmBX"}
1
+ {"version":3,"file":"ParserStatusBadge.js","names":[],"sources":["../../../../src/bigconsole/components/parser/ParserStatusBadge.tsx"],"sourcesContent":["/**\n * Parser Status Badge\n *\n * Badge component displaying parser status (active, inactive).\n */\n\nimport { memo } from 'react';\nimport type { ParserStatus } from '../../types';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface ParserStatusBadgeProps {\n /** Parser status */\n status: ParserStatus;\n /** Badge size */\n size?: 'sm' | 'md' | 'lg';\n /** Whether to show icon */\n showIcon?: boolean;\n}\n\n// ============================================================================\n// CONSTANTS\n// ============================================================================\n\nconst SIZE_CLASSES = {\n sm: 'px-2 py-0.5 text-xs',\n md: 'px-2.5 py-1 text-sm',\n lg: 'px-3 py-1.5 text-base',\n};\n\nconst ICON_SIZE_CLASSES = {\n sm: 'w-3 h-3',\n md: 'w-4 h-4',\n lg: 'w-5 h-5',\n};\n\n// ============================================================================\n// ICONS\n// ============================================================================\n\nconst CheckIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M5 13l4 4L19 7\" />\n </svg>\n);\n\nconst XCircleIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z\"\n />\n </svg>\n);\n\n// ============================================================================\n// COMPONENT\n// ============================================================================\n\nexport const ParserStatusBadge = memo(function ParserStatusBadge({\n status,\n size = 'md',\n showIcon = true,\n}: ParserStatusBadgeProps) {\n const sizeClass = SIZE_CLASSES[size];\n const iconSizeClass = ICON_SIZE_CLASSES[size];\n\n const config = {\n active: {\n bg: 'bg-status-success-bg/10',\n text: 'text-status-success-text',\n icon: <CheckIcon className={iconSizeClass} />,\n label: 'Active',\n },\n inactive: {\n bg: 'bg-text-tertiary/10',\n text: 'text-text-tertiary',\n icon: <XCircleIcon className={iconSizeClass} />,\n label: 'Inactive',\n },\n }[status];\n\n if (!config) {\n return (\n <span\n className={`\n inline-flex items-center gap-1.5\n ${sizeClass}\n bg-bg-sunken\n text-text-secondary\n rounded-full\n font-medium\n `}\n >\n {status}\n </span>\n );\n }\n\n return (\n <span\n className={`\n inline-flex items-center gap-1.5\n ${sizeClass}\n ${config.bg}\n ${config.text}\n rounded-full\n font-medium\n `}\n >\n {showIcon && config.icon}\n <span>{config.label}</span>\n </span>\n );\n});\n\nexport default ParserStatusBadge;\n"],"mappings":";;;AA0BA,IAAM,IAAe;CACnB,IAAI;CACJ,IAAI;CACJ,IAAI;CACL,EAEK,IAAoB;CACxB,IAAI;CACJ,IAAI;CACJ,IAAI;CACL,EAMK,KAAa,EAAE,mBACnB,kBAAC,OAAD;CAAgB;CAAW,MAAK;CAAO,QAAO;CAAe,SAAQ;WACnE,kBAAC,QAAD;EAAM,eAAc;EAAQ,gBAAe;EAAQ,aAAa;EAAG,GAAE;EAAmB,CAAA;CACpF,CAAA,EAGF,KAAe,EAAE,mBACrB,kBAAC,OAAD;CAAgB;CAAW,MAAK;CAAO,QAAO;CAAe,SAAQ;WACnE,kBAAC,QAAD;EACE,eAAc;EACd,gBAAe;EACf,aAAa;EACb,GAAE;EACF,CAAA;CACE,CAAA,EAOK,IAAoB,EAAK,SAA2B,EAC/D,WACA,UAAO,MACP,cAAW,MACc;CACzB,IAAM,IAAY,EAAa,IACzB,IAAgB,EAAkB,IAElC,IAAS;EACb,QAAQ;GACN,IAAI;GACJ,MAAM;GACN,MAAM,kBAAC,GAAD,EAAW,WAAW,GAAiB,CAAA;GAC7C,OAAO;GACR;EACD,UAAU;GACR,IAAI;GACJ,MAAM;GACN,MAAM,kBAAC,GAAD,EAAa,WAAW,GAAiB,CAAA;GAC/C,OAAO;GACR;EACF,CAAC;AAmBF,QAjBK,IAkBH,kBAAC,QAAD;EACE,WAAW;;UAEP,EAAU;UACV,EAAO,GAAG;UACV,EAAO,KAAK;;;;YALlB,CAUG,KAAY,EAAO,MACpB,kBAAC,QAAD,EAAA,UAAO,EAAO,OAAa,CAAA,CACtB;MA5BL,kBAAC,QAAD;EACE,WAAW;;YAEP,EAAU;;;;;;YAOb;EACI,CAAA;EAmBX"}
@@ -111,7 +111,7 @@ var o = ({ className: e }) => /* @__PURE__ */ r("svg", {
111
111
  p && /* @__PURE__ */ r("button", {
112
112
  type: "button",
113
113
  onClick: y,
114
- className: "\n p-1 rounded-md\n text-text-secondary\n hover:text-state-success\n hover:bg-state-success/10\n transition-colors\n ",
114
+ className: "\n p-1 rounded-md\n text-text-secondary\n hover:text-status-success-text\n hover:bg-status-success-bg/10\n transition-colors\n ",
115
115
  title: "Test Pipeline",
116
116
  children: /* @__PURE__ */ r(c, { className: "w-4 h-4" })
117
117
  }),
@@ -125,7 +125,7 @@ var o = ({ className: e }) => /* @__PURE__ */ r("svg", {
125
125
  m && /* @__PURE__ */ r("button", {
126
126
  type: "button",
127
127
  onClick: b,
128
- className: "\n p-1 rounded-md\n text-text-secondary\n hover:text-state-error\n hover:bg-state-error/10\n transition-colors\n ",
128
+ className: "\n p-1 rounded-md\n text-text-secondary\n hover:text-status-error-text\n hover:bg-status-error-bg/10\n transition-colors\n ",
129
129
  title: "Delete Pipeline",
130
130
  children: /* @__PURE__ */ r(l, { className: "w-4 h-4" })
131
131
  })
@@ -1 +1 @@
1
- {"version":3,"file":"PipelineCard.js","names":[],"sources":["../../../../src/bigconsole/components/pipeline/PipelineCard.tsx"],"sourcesContent":["/**\n * PipelineCard Component\n *\n * Card component displaying a Pipeline summary.\n * Shows name, status, stage count, and execution stats.\n */\n\nimport { memo, useCallback } from 'react';\nimport { formatDistanceToNow } from 'date-fns';\nimport { PipelineStatusBadge } from './PipelineStatusBadge';\nimport type { Pipeline } from '../../types';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface PipelineCardProps {\n pipeline: Pipeline;\n onView?: (id: string) => void;\n onEdit?: (id: string) => void;\n onTest?: (id: string) => void;\n onDelete?: (id: string) => void;\n}\n\n// ============================================================================\n// ICONS\n// ============================================================================\n\nconst PipelineIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M19.5 12c0-1.232-.046-2.453-.138-3.662a4.006 4.006 0 00-3.7-3.7 48.678 48.678 0 00-7.324 0 4.006 4.006 0 00-3.7 3.7c-.017.22-.032.441-.046.662M19.5 12l3-3m-3 3l-3-3m-12 3c0 1.232.046 2.453.138 3.662a4.006 4.006 0 003.7 3.7 48.656 48.656 0 007.324 0 4.006 4.006 0 003.7-3.7c.017-.22.032-.441.046-.662M4.5 12l3 3m-3-3l-3 3\"\n />\n </svg>\n);\n\nconst EditIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z\"\n />\n </svg>\n);\n\nconst PlayIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z\"\n />\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M21 12a9 9 0 11-18 0 9 9 0 0118 0z\" />\n </svg>\n);\n\nconst DeleteIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16\"\n />\n </svg>\n);\n\nconst LayersIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10\"\n />\n </svg>\n);\n\n// ============================================================================\n// COMPONENT\n// ============================================================================\n\nexport const PipelineCard = memo(function PipelineCard({\n pipeline,\n onView,\n onEdit,\n onTest,\n onDelete,\n}: PipelineCardProps) {\n // Calculate stage count\n const stageCount = pipeline.stages?.length ?? 0;\n\n // Format last executed time\n const formatLastExecuted = useCallback((dateStr: string | null): string => {\n if (!dateStr) return 'Never';\n try {\n const date = new Date(dateStr);\n return formatDistanceToNow(date, { addSuffix: true });\n } catch {\n return 'Unknown';\n }\n }, []);\n\n // Event handlers\n const handleCardClick = useCallback(() => {\n onView?.(pipeline.id);\n }, [onView, pipeline.id]);\n\n const handleEditClick = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation();\n onEdit?.(pipeline.id);\n },\n [onEdit, pipeline.id]\n );\n\n const handleTestClick = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation();\n onTest?.(pipeline.id);\n },\n [onTest, pipeline.id]\n );\n\n const handleDeleteClick = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation();\n onDelete?.(pipeline.id);\n },\n [onDelete, pipeline.id]\n );\n\n return (\n <div\n onClick={handleCardClick}\n className=\"\n bg-bg-surface\n border border-border-default\n rounded-lg\n overflow-hidden\n cursor-pointer\n hover:border-action-primary-bg\n transition-colors\n \"\n >\n {/* Header with Icon */}\n <div className=\"h-24 bg-bg-sunken flex items-center justify-center relative\">\n <PipelineIcon className=\"w-10 h-10 text-text-secondary/50\" />\n <div className=\"absolute top-2 right-2\">\n <PipelineStatusBadge status={pipeline.status} size=\"sm\" />\n </div>\n </div>\n\n {/* Content */}\n <div className=\"p-4\">\n {/* Title and Actions */}\n <div className=\"flex items-start justify-between mb-2\">\n <div className=\"flex-1 min-w-0\">\n <h3 className=\"text-sm font-semibold text-text-primary truncate\">{pipeline.name}</h3>\n {pipeline.description && (\n <p className=\"text-xs text-text-secondary truncate mt-0.5\">{pipeline.description}</p>\n )}\n </div>\n\n <div className=\"flex items-center gap-1 ml-2\">\n {onTest && (\n <button\n type=\"button\"\n onClick={handleTestClick}\n className=\"\n p-1 rounded-md\n text-text-secondary\n hover:text-state-success\n hover:bg-state-success/10\n transition-colors\n \"\n title=\"Test Pipeline\"\n >\n <PlayIcon className=\"w-4 h-4\" />\n </button>\n )}\n {onEdit && (\n <button\n type=\"button\"\n onClick={handleEditClick}\n className=\"\n p-1 rounded-md\n text-text-secondary\n hover:text-text-primary\n hover:bg-bg-sunken\n transition-colors\n \"\n title=\"Edit Pipeline\"\n >\n <EditIcon className=\"w-4 h-4\" />\n </button>\n )}\n {onDelete && (\n <button\n type=\"button\"\n onClick={handleDeleteClick}\n className=\"\n p-1 rounded-md\n text-text-secondary\n hover:text-state-error\n hover:bg-state-error/10\n transition-colors\n \"\n title=\"Delete Pipeline\"\n >\n <DeleteIcon className=\"w-4 h-4\" />\n </button>\n )}\n </div>\n </div>\n\n {/* Stats Footer */}\n <div className=\"flex items-center justify-between text-xs text-text-secondary mt-3\">\n <div className=\"flex items-center gap-3\">\n {/* Stage Count */}\n <span className=\"flex items-center gap-1\" title={`${stageCount} stages`}>\n <LayersIcon className=\"w-3.5 h-3.5\" />\n {stageCount} stage{stageCount !== 1 ? 's' : ''}\n </span>\n </div>\n\n {/* Last Executed */}\n <span\n title={\n pipeline.lastExecutedAt\n ? `Last executed: ${new Date(pipeline.lastExecutedAt).toLocaleString()}`\n : 'Never executed'\n }\n >\n {formatLastExecuted(pipeline.lastExecutedAt)}\n </span>\n </div>\n </div>\n </div>\n );\n});\n\nexport default PipelineCard;\n"],"mappings":"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"}
1
+ {"version":3,"file":"PipelineCard.js","names":[],"sources":["../../../../src/bigconsole/components/pipeline/PipelineCard.tsx"],"sourcesContent":["/**\n * PipelineCard Component\n *\n * Card component displaying a Pipeline summary.\n * Shows name, status, stage count, and execution stats.\n */\n\nimport { memo, useCallback } from 'react';\nimport { formatDistanceToNow } from 'date-fns';\nimport { PipelineStatusBadge } from './PipelineStatusBadge';\nimport type { Pipeline } from '../../types';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface PipelineCardProps {\n pipeline: Pipeline;\n onView?: (id: string) => void;\n onEdit?: (id: string) => void;\n onTest?: (id: string) => void;\n onDelete?: (id: string) => void;\n}\n\n// ============================================================================\n// ICONS\n// ============================================================================\n\nconst PipelineIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M19.5 12c0-1.232-.046-2.453-.138-3.662a4.006 4.006 0 00-3.7-3.7 48.678 48.678 0 00-7.324 0 4.006 4.006 0 00-3.7 3.7c-.017.22-.032.441-.046.662M19.5 12l3-3m-3 3l-3-3m-12 3c0 1.232.046 2.453.138 3.662a4.006 4.006 0 003.7 3.7 48.656 48.656 0 007.324 0 4.006 4.006 0 003.7-3.7c.017-.22.032-.441.046-.662M4.5 12l3 3m-3-3l-3 3\"\n />\n </svg>\n);\n\nconst EditIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z\"\n />\n </svg>\n);\n\nconst PlayIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z\"\n />\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M21 12a9 9 0 11-18 0 9 9 0 0118 0z\" />\n </svg>\n);\n\nconst DeleteIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16\"\n />\n </svg>\n);\n\nconst LayersIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10\"\n />\n </svg>\n);\n\n// ============================================================================\n// COMPONENT\n// ============================================================================\n\nexport const PipelineCard = memo(function PipelineCard({\n pipeline,\n onView,\n onEdit,\n onTest,\n onDelete,\n}: PipelineCardProps) {\n // Calculate stage count\n const stageCount = pipeline.stages?.length ?? 0;\n\n // Format last executed time\n const formatLastExecuted = useCallback((dateStr: string | null): string => {\n if (!dateStr) return 'Never';\n try {\n const date = new Date(dateStr);\n return formatDistanceToNow(date, { addSuffix: true });\n } catch {\n return 'Unknown';\n }\n }, []);\n\n // Event handlers\n const handleCardClick = useCallback(() => {\n onView?.(pipeline.id);\n }, [onView, pipeline.id]);\n\n const handleEditClick = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation();\n onEdit?.(pipeline.id);\n },\n [onEdit, pipeline.id]\n );\n\n const handleTestClick = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation();\n onTest?.(pipeline.id);\n },\n [onTest, pipeline.id]\n );\n\n const handleDeleteClick = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation();\n onDelete?.(pipeline.id);\n },\n [onDelete, pipeline.id]\n );\n\n return (\n <div\n onClick={handleCardClick}\n className=\"\n bg-bg-surface\n border border-border-default\n rounded-lg\n overflow-hidden\n cursor-pointer\n hover:border-action-primary-bg\n transition-colors\n \"\n >\n {/* Header with Icon */}\n <div className=\"h-24 bg-bg-sunken flex items-center justify-center relative\">\n <PipelineIcon className=\"w-10 h-10 text-text-secondary/50\" />\n <div className=\"absolute top-2 right-2\">\n <PipelineStatusBadge status={pipeline.status} size=\"sm\" />\n </div>\n </div>\n\n {/* Content */}\n <div className=\"p-4\">\n {/* Title and Actions */}\n <div className=\"flex items-start justify-between mb-2\">\n <div className=\"flex-1 min-w-0\">\n <h3 className=\"text-sm font-semibold text-text-primary truncate\">{pipeline.name}</h3>\n {pipeline.description && (\n <p className=\"text-xs text-text-secondary truncate mt-0.5\">{pipeline.description}</p>\n )}\n </div>\n\n <div className=\"flex items-center gap-1 ml-2\">\n {onTest && (\n <button\n type=\"button\"\n onClick={handleTestClick}\n className=\"\n p-1 rounded-md\n text-text-secondary\n hover:text-status-success-text\n hover:bg-status-success-bg/10\n transition-colors\n \"\n title=\"Test Pipeline\"\n >\n <PlayIcon className=\"w-4 h-4\" />\n </button>\n )}\n {onEdit && (\n <button\n type=\"button\"\n onClick={handleEditClick}\n className=\"\n p-1 rounded-md\n text-text-secondary\n hover:text-text-primary\n hover:bg-bg-sunken\n transition-colors\n \"\n title=\"Edit Pipeline\"\n >\n <EditIcon className=\"w-4 h-4\" />\n </button>\n )}\n {onDelete && (\n <button\n type=\"button\"\n onClick={handleDeleteClick}\n className=\"\n p-1 rounded-md\n text-text-secondary\n hover:text-status-error-text\n hover:bg-status-error-bg/10\n transition-colors\n \"\n title=\"Delete Pipeline\"\n >\n <DeleteIcon className=\"w-4 h-4\" />\n </button>\n )}\n </div>\n </div>\n\n {/* Stats Footer */}\n <div className=\"flex items-center justify-between text-xs text-text-secondary mt-3\">\n <div className=\"flex items-center gap-3\">\n {/* Stage Count */}\n <span className=\"flex items-center gap-1\" title={`${stageCount} stages`}>\n <LayersIcon className=\"w-3.5 h-3.5\" />\n {stageCount} stage{stageCount !== 1 ? 's' : ''}\n </span>\n </div>\n\n {/* Last Executed */}\n <span\n title={\n pipeline.lastExecutedAt\n ? `Last executed: ${new Date(pipeline.lastExecutedAt).toLocaleString()}`\n : 'Never executed'\n }\n >\n {formatLastExecuted(pipeline.lastExecutedAt)}\n </span>\n </div>\n </div>\n </div>\n );\n});\n\nexport default PipelineCard;\n"],"mappings":"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"}
@@ -29,8 +29,8 @@ var i = ({ className: e }) => /* @__PURE__ */ n("svg", {
29
29
  /* @__PURE__ */ r("div", {
30
30
  className: "flex items-center gap-3 mb-4",
31
31
  children: [/* @__PURE__ */ n("div", {
32
- className: "p-2 rounded-full bg-state-error/10",
33
- children: /* @__PURE__ */ n(i, { className: "w-6 h-6 text-state-error" })
32
+ className: "p-2 rounded-full bg-status-error-bg/10",
33
+ children: /* @__PURE__ */ n(i, { className: "w-6 h-6 text-status-error-text" })
34
34
  }), /* @__PURE__ */ n("h2", {
35
35
  className: "text-lg font-semibold text-text-primary",
36
36
  children: "Delete Pipeline"
@@ -52,9 +52,9 @@ var i = ({ className: e }) => /* @__PURE__ */ n("svg", {
52
52
  ]
53
53
  }),
54
54
  c > 0 && /* @__PURE__ */ n("div", {
55
- className: "p-3 bg-state-warning/10 rounded-md",
55
+ className: "p-3 bg-status-warning-bg/10 rounded-md",
56
56
  children: /* @__PURE__ */ r("p", {
57
- className: "text-sm text-state-warning",
57
+ className: "text-sm text-status-warning-text",
58
58
  children: [
59
59
  "This pipeline has ",
60
60
  c,
@@ -80,7 +80,7 @@ var i = ({ className: e }) => /* @__PURE__ */ n("svg", {
80
80
  }), /* @__PURE__ */ n("button", {
81
81
  type: "button",
82
82
  onClick: u,
83
- className: "\n px-4 py-2\n text-sm font-medium\n text-white\n bg-state-error\n hover:bg-state-error/90\n rounded-md\n transition-colors\n ",
83
+ className: "\n px-4 py-2\n text-sm font-medium\n text-white\n bg-status-error-bg\n hover:bg-status-error-bg/90\n rounded-md\n transition-colors\n ",
84
84
  children: "Delete Pipeline"
85
85
  })]
86
86
  })
@@ -1 +1 @@
1
- {"version":3,"file":"PipelineDeleteDialog.js","names":[],"sources":["../../../../src/bigconsole/components/pipeline/PipelineDeleteDialog.tsx"],"sourcesContent":["/**\n * PipelineDeleteDialog Component\n *\n * Confirmation dialog for deleting a Pipeline.\n * Shows warning about stages before deletion.\n */\n\nimport { memo, useCallback } from 'react';\nimport type { Pipeline } from '../../types';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface PipelineDeleteDialogProps {\n pipeline: Pipeline;\n isOpen: boolean;\n onClose: () => void;\n onConfirm: () => void | Promise<void>;\n}\n\n// ============================================================================\n// ICONS\n// ============================================================================\n\nconst WarningIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\n />\n </svg>\n);\n\n// ============================================================================\n// COMPONENT\n// ============================================================================\n\nexport const PipelineDeleteDialog = memo(function PipelineDeleteDialog({\n pipeline,\n isOpen,\n onClose,\n onConfirm,\n}: PipelineDeleteDialogProps) {\n // Calculate stage count\n const stageCount = pipeline.stages?.length ?? 0;\n\n // Event handlers\n const handleBackdropClick = useCallback(() => {\n onClose();\n }, [onClose]);\n\n const handleConfirmClick = useCallback(() => {\n onConfirm();\n }, [onConfirm]);\n\n // Don't render if not open\n if (!isOpen) {\n return null;\n }\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center\">\n {/* Backdrop */}\n <div className=\"absolute inset-0 bg-black/50\" onClick={handleBackdropClick} />\n\n {/* Dialog */}\n <div className=\"relative bg-bg-surface rounded-lg shadow-xl max-w-md w-full mx-4 p-6\">\n {/* Header */}\n <div className=\"flex items-center gap-3 mb-4\">\n <div className=\"p-2 rounded-full bg-state-error/10\">\n <WarningIcon className=\"w-6 h-6 text-state-error\" />\n </div>\n <h2 className=\"text-lg font-semibold text-text-primary\">Delete Pipeline</h2>\n </div>\n\n {/* Content */}\n <div className=\"mb-6\">\n <p className=\"text-sm text-text-secondary mb-3\">\n Are you sure you want to delete the pipeline{' '}\n <span className=\"font-medium text-text-primary\">{pipeline.name}</span>?\n </p>\n\n {/* Warning about stages */}\n {stageCount > 0 && (\n <div className=\"p-3 bg-state-warning/10 rounded-md\">\n <p className=\"text-sm text-state-warning\">\n This pipeline has {stageCount} stage{stageCount !== 1 ? 's' : ''}. All stages will be permanently\n deleted.\n </p>\n </div>\n )}\n\n <p className=\"text-sm text-text-secondary mt-3\">This action cannot be undone.</p>\n </div>\n\n {/* Actions */}\n <div className=\"flex justify-end gap-3\">\n <button\n type=\"button\"\n onClick={onClose}\n className=\"\n px-4 py-2\n text-sm font-medium\n text-text-primary\n bg-bg-sunken\n hover:bg-border-default\n rounded-md\n transition-colors\n \"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={handleConfirmClick}\n className=\"\n px-4 py-2\n text-sm font-medium\n text-white\n bg-state-error\n hover:bg-state-error/90\n rounded-md\n transition-colors\n \"\n >\n Delete Pipeline\n </button>\n </div>\n </div>\n </div>\n );\n});\n\nexport default PipelineDeleteDialog;\n"],"mappings":";;;AAyBA,IAAM,KAAe,EAAE,mBACrB,kBAAC,OAAD;CAAgB;CAAW,MAAK;CAAO,QAAO;CAAe,SAAQ;WACnE,kBAAC,QAAD;EACE,eAAc;EACd,gBAAe;EACf,aAAa;EACb,GAAE;EACF,CAAA;CACE,CAAA,EAOK,IAAuB,EAAK,SAA8B,EACrE,aACA,WACA,YACA,gBAC4B;CAE5B,IAAM,IAAa,EAAS,QAAQ,UAAU,GAGxC,IAAsB,QAAkB;AAC5C,KAAS;IACR,CAAC,EAAQ,CAAC,EAEP,IAAqB,QAAkB;AAC3C,KAAW;IACV,CAAC,EAAU,CAAC;AAOf,QAJK,IAKH,kBAAC,OAAD;EAAK,WAAU;YAAf,CAEE,kBAAC,OAAD;GAAK,WAAU;GAA+B,SAAS;GAAuB,CAAA,EAG9E,kBAAC,OAAD;GAAK,WAAU;aAAf;IAEE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,GAAD,EAAa,WAAU,4BAA6B,CAAA;MAChD,CAAA,EACN,kBAAC,MAAD;MAAI,WAAU;gBAA0C;MAAoB,CAAA,CACxE;;IAGN,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,KAAD;OAAG,WAAU;iBAAb;QAAgD;QACD;QAC7C,kBAAC,QAAD;SAAM,WAAU;mBAAiC,EAAS;SAAY,CAAA;;QACpE;;MAGH,IAAa,KACZ,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,KAAD;QAAG,WAAU;kBAAb;SAA0C;SACrB;SAAW;SAAO,MAAe,IAAU,KAAN;SAAS;SAE/D;;OACA,CAAA;MAGR,kBAAC,KAAD;OAAG,WAAU;iBAAmC;OAAiC,CAAA;MAC7E;;IAGN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,UAAD;MACE,MAAK;MACL,SAAS;MACT,WAAU;gBASX;MAEQ,CAAA,EACT,kBAAC,UAAD;MACE,MAAK;MACL,SAAS;MACT,WAAU;gBASX;MAEQ,CAAA,CACL;;IACF;KACF;MAxEC;EA0ET"}
1
+ {"version":3,"file":"PipelineDeleteDialog.js","names":[],"sources":["../../../../src/bigconsole/components/pipeline/PipelineDeleteDialog.tsx"],"sourcesContent":["/**\n * PipelineDeleteDialog Component\n *\n * Confirmation dialog for deleting a Pipeline.\n * Shows warning about stages before deletion.\n */\n\nimport { memo, useCallback } from 'react';\nimport type { Pipeline } from '../../types';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface PipelineDeleteDialogProps {\n pipeline: Pipeline;\n isOpen: boolean;\n onClose: () => void;\n onConfirm: () => void | Promise<void>;\n}\n\n// ============================================================================\n// ICONS\n// ============================================================================\n\nconst WarningIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\n />\n </svg>\n);\n\n// ============================================================================\n// COMPONENT\n// ============================================================================\n\nexport const PipelineDeleteDialog = memo(function PipelineDeleteDialog({\n pipeline,\n isOpen,\n onClose,\n onConfirm,\n}: PipelineDeleteDialogProps) {\n // Calculate stage count\n const stageCount = pipeline.stages?.length ?? 0;\n\n // Event handlers\n const handleBackdropClick = useCallback(() => {\n onClose();\n }, [onClose]);\n\n const handleConfirmClick = useCallback(() => {\n onConfirm();\n }, [onConfirm]);\n\n // Don't render if not open\n if (!isOpen) {\n return null;\n }\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center\">\n {/* Backdrop */}\n <div className=\"absolute inset-0 bg-black/50\" onClick={handleBackdropClick} />\n\n {/* Dialog */}\n <div className=\"relative bg-bg-surface rounded-lg shadow-xl max-w-md w-full mx-4 p-6\">\n {/* Header */}\n <div className=\"flex items-center gap-3 mb-4\">\n <div className=\"p-2 rounded-full bg-status-error-bg/10\">\n <WarningIcon className=\"w-6 h-6 text-status-error-text\" />\n </div>\n <h2 className=\"text-lg font-semibold text-text-primary\">Delete Pipeline</h2>\n </div>\n\n {/* Content */}\n <div className=\"mb-6\">\n <p className=\"text-sm text-text-secondary mb-3\">\n Are you sure you want to delete the pipeline{' '}\n <span className=\"font-medium text-text-primary\">{pipeline.name}</span>?\n </p>\n\n {/* Warning about stages */}\n {stageCount > 0 && (\n <div className=\"p-3 bg-status-warning-bg/10 rounded-md\">\n <p className=\"text-sm text-status-warning-text\">\n This pipeline has {stageCount} stage{stageCount !== 1 ? 's' : ''}. All stages will be permanently\n deleted.\n </p>\n </div>\n )}\n\n <p className=\"text-sm text-text-secondary mt-3\">This action cannot be undone.</p>\n </div>\n\n {/* Actions */}\n <div className=\"flex justify-end gap-3\">\n <button\n type=\"button\"\n onClick={onClose}\n className=\"\n px-4 py-2\n text-sm font-medium\n text-text-primary\n bg-bg-sunken\n hover:bg-border-default\n rounded-md\n transition-colors\n \"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={handleConfirmClick}\n className=\"\n px-4 py-2\n text-sm font-medium\n text-white\n bg-status-error-bg\n hover:bg-status-error-bg/90\n rounded-md\n transition-colors\n \"\n >\n Delete Pipeline\n </button>\n </div>\n </div>\n </div>\n );\n});\n\nexport default PipelineDeleteDialog;\n"],"mappings":";;;AAyBA,IAAM,KAAe,EAAE,mBACrB,kBAAC,OAAD;CAAgB;CAAW,MAAK;CAAO,QAAO;CAAe,SAAQ;WACnE,kBAAC,QAAD;EACE,eAAc;EACd,gBAAe;EACf,aAAa;EACb,GAAE;EACF,CAAA;CACE,CAAA,EAOK,IAAuB,EAAK,SAA8B,EACrE,aACA,WACA,YACA,gBAC4B;CAE5B,IAAM,IAAa,EAAS,QAAQ,UAAU,GAGxC,IAAsB,QAAkB;AAC5C,KAAS;IACR,CAAC,EAAQ,CAAC,EAEP,IAAqB,QAAkB;AAC3C,KAAW;IACV,CAAC,EAAU,CAAC;AAOf,QAJK,IAKH,kBAAC,OAAD;EAAK,WAAU;YAAf,CAEE,kBAAC,OAAD;GAAK,WAAU;GAA+B,SAAS;GAAuB,CAAA,EAG9E,kBAAC,OAAD;GAAK,WAAU;aAAf;IAEE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,GAAD,EAAa,WAAU,kCAAmC,CAAA;MACtD,CAAA,EACN,kBAAC,MAAD;MAAI,WAAU;gBAA0C;MAAoB,CAAA,CACxE;;IAGN,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,KAAD;OAAG,WAAU;iBAAb;QAAgD;QACD;QAC7C,kBAAC,QAAD;SAAM,WAAU;mBAAiC,EAAS;SAAY,CAAA;;QACpE;;MAGH,IAAa,KACZ,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,KAAD;QAAG,WAAU;kBAAb;SAAgD;SAC3B;SAAW;SAAO,MAAe,IAAU,KAAN;SAAS;SAE/D;;OACA,CAAA;MAGR,kBAAC,KAAD;OAAG,WAAU;iBAAmC;OAAiC,CAAA;MAC7E;;IAGN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,UAAD;MACE,MAAK;MACL,SAAS;MACT,WAAU;gBASX;MAEQ,CAAA,EACT,kBAAC,UAAD;MACE,MAAK;MACL,SAAS;MACT,WAAU;gBASX;MAEQ,CAAA,CACL;;IACF;KACF;MAxEC;EA0ET"}
@@ -8,15 +8,15 @@ var n = {
8
8
  },
9
9
  active: {
10
10
  label: "Active",
11
- className: "bg-state-success/10 text-state-success"
11
+ className: "bg-status-success-bg/10 text-status-success-text"
12
12
  },
13
13
  inactive: {
14
14
  label: "Inactive",
15
- className: "bg-state-warning/10 text-state-warning"
15
+ className: "bg-status-warning-bg/10 text-status-warning-text"
16
16
  },
17
17
  error: {
18
18
  label: "Error",
19
- className: "bg-state-error/10 text-state-error"
19
+ className: "bg-status-error-bg/10 text-status-error-text"
20
20
  }
21
21
  }, r = e(function({ status: e, size: r = "md" }) {
22
22
  let i = n[e] || n.draft;
@@ -1 +1 @@
1
- {"version":3,"file":"PipelineStatusBadge.js","names":[],"sources":["../../../../src/bigconsole/components/pipeline/PipelineStatusBadge.tsx"],"sourcesContent":["/**\n * PipelineStatusBadge Component\n *\n * Displays the status of a Pipeline with appropriate styling.\n */\n\nimport { memo } from 'react';\nimport type { PipelineStatus } from '../../types';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface PipelineStatusBadgeProps {\n status: PipelineStatus;\n size?: 'sm' | 'md';\n}\n\n// ============================================================================\n// STATUS CONFIG\n// ============================================================================\n\nconst STATUS_CONFIG: Record<PipelineStatus, { label: string; className: string }> = {\n draft: {\n label: 'Draft',\n className: 'bg-bg-sunken text-text-secondary',\n },\n active: {\n label: 'Active',\n className: 'bg-state-success/10 text-state-success',\n },\n inactive: {\n label: 'Inactive',\n className: 'bg-state-warning/10 text-state-warning',\n },\n error: {\n label: 'Error',\n className: 'bg-state-error/10 text-state-error',\n },\n};\n\n// ============================================================================\n// COMPONENT\n// ============================================================================\n\nexport const PipelineStatusBadge = memo(function PipelineStatusBadge({\n status,\n size = 'md',\n}: PipelineStatusBadgeProps) {\n const config = STATUS_CONFIG[status] || STATUS_CONFIG.draft;\n\n const sizeClasses = size === 'sm' ? 'px-1.5 py-0.5 text-xs' : 'px-2 py-1 text-xs';\n\n return (\n <span\n className={`\n inline-flex items-center\n font-medium rounded-md\n ${sizeClasses}\n ${config.className}\n `}\n >\n {config.label}\n </span>\n );\n});\n\nexport default PipelineStatusBadge;\n"],"mappings":";;;AAsBA,IAAM,IAA8E;CAClF,OAAO;EACL,OAAO;EACP,WAAW;EACZ;CACD,QAAQ;EACN,OAAO;EACP,WAAW;EACZ;CACD,UAAU;EACR,OAAO;EACP,WAAW;EACZ;CACD,OAAO;EACL,OAAO;EACP,WAAW;EACZ;CACF,EAMY,IAAsB,EAAK,SAA6B,EACnE,WACA,UAAO,QACoB;CAC3B,IAAM,IAAS,EAAc,MAAW,EAAc;AAItD,QACE,kBAAC,QAAD;EACE,WAAW;;;UAJK,MAAS,OAAO,0BAA0B,oBAO1C;UACZ,EAAO,UAAU;;YAGpB,EAAO;EACH,CAAA;EAET"}
1
+ {"version":3,"file":"PipelineStatusBadge.js","names":[],"sources":["../../../../src/bigconsole/components/pipeline/PipelineStatusBadge.tsx"],"sourcesContent":["/**\n * PipelineStatusBadge Component\n *\n * Displays the status of a Pipeline with appropriate styling.\n */\n\nimport { memo } from 'react';\nimport type { PipelineStatus } from '../../types';\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\ninterface PipelineStatusBadgeProps {\n status: PipelineStatus;\n size?: 'sm' | 'md';\n}\n\n// ============================================================================\n// STATUS CONFIG\n// ============================================================================\n\nconst STATUS_CONFIG: Record<PipelineStatus, { label: string; className: string }> = {\n draft: {\n label: 'Draft',\n className: 'bg-bg-sunken text-text-secondary',\n },\n active: {\n label: 'Active',\n className: 'bg-status-success-bg/10 text-status-success-text',\n },\n inactive: {\n label: 'Inactive',\n className: 'bg-status-warning-bg/10 text-status-warning-text',\n },\n error: {\n label: 'Error',\n className: 'bg-status-error-bg/10 text-status-error-text',\n },\n};\n\n// ============================================================================\n// COMPONENT\n// ============================================================================\n\nexport const PipelineStatusBadge = memo(function PipelineStatusBadge({\n status,\n size = 'md',\n}: PipelineStatusBadgeProps) {\n const config = STATUS_CONFIG[status] || STATUS_CONFIG.draft;\n\n const sizeClasses = size === 'sm' ? 'px-1.5 py-0.5 text-xs' : 'px-2 py-1 text-xs';\n\n return (\n <span\n className={`\n inline-flex items-center\n font-medium rounded-md\n ${sizeClasses}\n ${config.className}\n `}\n >\n {config.label}\n </span>\n );\n});\n\nexport default PipelineStatusBadge;\n"],"mappings":";;;AAsBA,IAAM,IAA8E;CAClF,OAAO;EACL,OAAO;EACP,WAAW;EACZ;CACD,QAAQ;EACN,OAAO;EACP,WAAW;EACZ;CACD,UAAU;EACR,OAAO;EACP,WAAW;EACZ;CACD,OAAO;EACL,OAAO;EACP,WAAW;EACZ;CACF,EAMY,IAAsB,EAAK,SAA6B,EACnE,WACA,UAAO,QACoB;CAC3B,IAAM,IAAS,EAAc,MAAW,EAAc;AAItD,QACE,kBAAC,QAAD;EACE,WAAW;;;UAJK,MAAS,OAAO,0BAA0B,oBAO1C;UACZ,EAAO,UAAU;;YAGpB,EAAO;EACH,CAAA;EAET"}
@@ -231,7 +231,7 @@ var d = t(function({ widget: t, onChange: d, widgetData: f }) {
231
231
  E.length > 1 && /* @__PURE__ */ c("button", {
232
232
  type: "button",
233
233
  onClick: () => L(t),
234
- className: "p-1 text-text-tertiary hover:text-state-error",
234
+ className: "p-1 text-text-tertiary hover:text-status-error-text",
235
235
  children: /* @__PURE__ */ c("svg", {
236
236
  className: "w-4 h-4",
237
237
  fill: "none",
@@ -1 +1 @@
1
- {"version":3,"file":"DrilldownConfigPanel.js","names":[],"sources":["../../../../src/bigconsole/components/widgets/DrilldownConfigPanel.tsx"],"sourcesContent":["/**\n * DrilldownConfigPanel Component\n *\n * UI for configuring widget drilldown settings.\n * Allows selecting target dashboard, navigation mode, and parameter mappings.\n *\n * v2.0 Features:\n * - passGlobalFilters: Pass current dashboard filters to target\n * - maxDepth: Limit drilldown depth (default: 3)\n * - openIn: Open in same tab or new tab\n * - Field suggestions based on widget data\n */\n\nimport { type FC, memo, useState, useEffect, useCallback, useMemo } from 'react';\nimport { useApolloClient } from '@apollo/client/react';\nimport type { Widget, NavigationMode } from '../../types';\nimport { ListDashboardsDocument } from '../../../generated/wspace-operations';\nimport { DEFAULT_MAX_DEPTH } from '../../hooks/useDrilldown';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface DrilldownConfigPanelProps {\n /** Widget to configure drilldown for */\n widget: Widget;\n /** Callback when drilldown settings change (for tracking unsaved changes) */\n onChange?: (config: DrilldownConfig) => void;\n /** Sample widget data for field suggestions */\n widgetData?: Record<string, unknown>;\n}\n\nexport interface DrilldownConfig {\n enabled: boolean;\n targetDashboardId: string;\n navigationMode: NavigationMode;\n parameterMapping: Record<string, string>;\n /** Whether to pass global filters to target dashboard */\n passGlobalFilters: boolean;\n /** Maximum drilldown depth (default: 3) */\n maxDepth: number;\n /** Open in same tab or new tab (for SAME_WINDOW mode) */\n openIn: 'same' | 'new';\n}\n\ninterface DashboardOption {\n id: string;\n name: string;\n}\n\ninterface ParameterMapping {\n key: string;\n value: string;\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Extract available fields from widget data for field suggestions\n */\nfunction extractFieldPaths(obj: unknown, prefix = ''): string[] {\n if (!obj || typeof obj !== 'object') return [];\n\n const paths: string[] = [];\n\n // Handle arrays - use first element as template\n if (Array.isArray(obj)) {\n if (obj.length > 0 && typeof obj[0] === 'object') {\n return extractFieldPaths(obj[0], prefix);\n }\n return [];\n }\n\n // Handle objects\n for (const [key, value] of Object.entries(obj as Record<string, unknown>)) {\n const path = prefix ? `${prefix}.${key}` : key;\n paths.push(path);\n\n // Recurse into nested objects (but not too deep)\n if (value && typeof value === 'object' && !Array.isArray(value) && prefix.split('.').length < 2) {\n paths.push(...extractFieldPaths(value, path));\n }\n }\n\n return paths;\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport const DrilldownConfigPanel: FC<DrilldownConfigPanelProps> = memo(function DrilldownConfigPanel({\n widget,\n onChange,\n widgetData,\n}) {\n const apolloClient = useApolloClient();\n\n // State\n const [enabled, setEnabled] = useState(widget.drilldown?.enabled ?? false);\n const [targetDashboardId, setTargetDashboardId] = useState(widget.drilldown?.targetDashboardId ?? '');\n const [navigationMode, setNavigationMode] = useState<NavigationMode>(widget.drilldown?.navigationMode ?? 'MODAL');\n const [passGlobalFilters, setPassGlobalFilters] = useState(widget.drilldown?.passGlobalFilters ?? true);\n const [maxDepth, setMaxDepth] = useState(widget.drilldown?.maxDepth ?? DEFAULT_MAX_DEPTH);\n const [openIn, setOpenIn] = useState<'same' | 'new'>(widget.drilldown?.openIn ?? 'same');\n const [parameterMappings, setParameterMappings] = useState<ParameterMapping[]>(() => {\n const mapping = widget.drilldown?.parameterMapping as Record<string, string> | undefined;\n if (mapping) {\n return Object.entries(mapping).map(([key, value]) => ({ key, value }));\n }\n return [{ key: '', value: '' }];\n });\n\n const [dashboards, setDashboards] = useState<DashboardOption[]>([]);\n const [loading, setLoading] = useState(false);\n const [showFieldSuggestions, setShowFieldSuggestions] = useState<number | null>(null);\n\n // Extract available field paths from widget data\n const availableFields = useMemo(() => {\n if (!widgetData) return [];\n\n // Common prefixes for different widget types\n const prefixes = ['row', 'item', 'point', 'selectedData'];\n const fields = extractFieldPaths(widgetData);\n\n // Generate mustache-style suggestions\n const suggestions: string[] = [];\n for (const field of fields) {\n for (const prefix of prefixes) {\n suggestions.push(`{{${prefix}.${field}}}`);\n }\n }\n\n // Add common widget data fields\n suggestions.push('{{widget.value}}', '{{widget.title}}', '{{widget.id}}');\n suggestions.push('{{globals.vars.dateFrom}}', '{{globals.vars.dateTo}}');\n\n return [...new Set(suggestions)];\n }, [widgetData]);\n\n // Notify parent of changes\n const notifyChange = useCallback(() => {\n const parameterMapping: Record<string, string> = {};\n for (const { key, value } of parameterMappings) {\n if (key.trim() && value.trim()) {\n parameterMapping[key.trim()] = value.trim();\n }\n }\n onChange?.({\n enabled,\n targetDashboardId,\n navigationMode,\n parameterMapping,\n passGlobalFilters,\n maxDepth,\n openIn,\n });\n }, [enabled, targetDashboardId, navigationMode, parameterMappings, passGlobalFilters, maxDepth, openIn, onChange]);\n\n // Call notifyChange when any value changes\n useEffect(() => {\n notifyChange();\n }, [\n enabled,\n targetDashboardId,\n navigationMode,\n parameterMappings,\n passGlobalFilters,\n maxDepth,\n openIn,\n notifyChange,\n ]);\n\n // Fetch available dashboards\n useEffect(() => {\n async function fetchDashboards() {\n setLoading(true);\n try {\n const result = await apolloClient.query<{ listDashboards: { edges: Record<string, unknown>[] } }>({\n query: ListDashboardsDocument,\n variables: { first: 100 },\n fetchPolicy: 'cache-first',\n });\n\n const edges = result.data?.listDashboards?.edges || [];\n setDashboards(\n edges.map((edge: Record<string, unknown>) => {\n const node = edge.node as Record<string, unknown>;\n return {\n id: node.id as string,\n name: node.name as string,\n };\n })\n );\n } catch (err) {\n } finally {\n setLoading(false);\n }\n }\n\n fetchDashboards();\n }, [apolloClient]);\n\n // Add parameter mapping row\n const addParameterMapping = useCallback(() => {\n setParameterMappings((prev) => [...prev, { key: '', value: '' }]);\n }, []);\n\n // Remove parameter mapping row\n const removeParameterMapping = useCallback((index: number) => {\n setParameterMappings((prev) => prev.filter((_, i) => i !== index));\n }, []);\n\n // Update parameter mapping\n const updateParameterMapping = useCallback((index: number, field: 'key' | 'value', newValue: string) => {\n setParameterMappings((prev) => prev.map((item, i) => (i === index ? { ...item, [field]: newValue } : item)));\n }, []);\n\n return (\n <div className=\"space-y-4 pb-8\">\n {/* Enable Toggle */}\n <div className=\"flex items-center justify-between p-3 rounded-lg border border-border-default bg-bg-surface\">\n <label className=\"text-sm font-medium text-text-primary\">Enable Drilldown</label>\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={enabled}\n onClick={() => setEnabled(!enabled)}\n className={`\n relative inline-flex h-6 w-11 items-center rounded-full transition-colors cursor-pointer border\n ${enabled ? 'bg-action-primary-bg border-action-primary-bg' : 'bg-gray-300 border-gray-400'}\n `}\n >\n <span\n className={`\n inline-block h-4 w-4 transform rounded-full bg-white shadow transition-transform\n ${enabled ? 'translate-x-6' : 'translate-x-1'}\n `}\n />\n </button>\n </div>\n\n {enabled && (\n <>\n {/* Target Dashboard */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">Target Dashboard</label>\n <select\n value={targetDashboardId}\n onChange={(e) => setTargetDashboardId(e.target.value)}\n disabled={loading}\n className=\"w-full px-3 py-2 rounded-md border border-border-default bg-bg-surface text-text-primary text-sm focus:outline-none focus:ring-2 focus:ring-action-primary-bg\"\n >\n <option value=\"\">Select a dashboard...</option>\n {dashboards\n .filter((d) => d.id !== widget.dashboardId) // Exclude current dashboard\n .map((dashboard) => (\n <option key={dashboard.id} value={dashboard.id}>\n {dashboard.name}\n </option>\n ))}\n </select>\n </div>\n\n {/* Navigation Mode */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">Navigation Mode</label>\n <div className=\"flex gap-2\">\n {(['MODAL', 'NEW_TAB', 'SAME_WINDOW'] as NavigationMode[]).map((mode) => (\n <button\n key={mode}\n type=\"button\"\n onClick={() => setNavigationMode(mode)}\n className={`\n flex-1 px-3 py-2 rounded-md text-sm font-medium transition-colors\n ${\n navigationMode === mode\n ? 'bg-action-primary-bg text-white'\n : 'bg-bg-sunken text-text-secondary hover:bg-bg-sunken/80'\n }\n `}\n >\n {mode === 'MODAL' && 'Modal'}\n {mode === 'NEW_TAB' && 'New Tab'}\n {mode === 'SAME_WINDOW' && 'Same Window'}\n </button>\n ))}\n </div>\n <p className=\"text-xs text-text-tertiary mt-1\">\n {navigationMode === 'MODAL' && 'Opens target dashboard in a modal overlay'}\n {navigationMode === 'NEW_TAB' && 'Opens target dashboard in a new browser tab'}\n {navigationMode === 'SAME_WINDOW' && 'Navigates to target dashboard in current window'}\n </p>\n </div>\n\n {/* Parameter Mappings */}\n <div>\n <div className=\"flex items-center justify-between mb-2\">\n <label className=\"text-sm font-medium text-text-primary\">Parameter Mappings</label>\n <button\n type=\"button\"\n onClick={addParameterMapping}\n className=\"text-xs text-action-primary-text hover:underline\"\n >\n + Add Parameter\n </button>\n </div>\n\n <div className=\"space-y-2\">\n {parameterMappings.map((mapping, index) => (\n <div key={index} className=\"relative\">\n <div className=\"flex gap-2 items-center\">\n <input\n type=\"text\"\n value={mapping.key}\n onChange={(e) => updateParameterMapping(index, 'key', e.target.value)}\n placeholder=\"Parameter name\"\n className=\"flex-1 px-2 py-1.5 rounded border border-border-default bg-bg-surface text-text-primary text-sm focus:outline-none focus:ring-1 focus:ring-action-primary-bg\"\n />\n <span className=\"text-text-tertiary\">=</span>\n <div className=\"flex-1 relative\">\n <input\n type=\"text\"\n value={mapping.value}\n onChange={(e) => updateParameterMapping(index, 'value', e.target.value)}\n onFocus={() => setShowFieldSuggestions(index)}\n onBlur={() => setTimeout(() => setShowFieldSuggestions(null), 200)}\n placeholder=\"{{row.field}} or static\"\n className=\"w-full px-2 py-1.5 rounded border border-border-default bg-bg-surface text-text-primary text-sm focus:outline-none focus:ring-1 focus:ring-action-primary-bg\"\n />\n {/* Field suggestions dropdown */}\n {showFieldSuggestions === index && availableFields.length > 0 && (\n <div className=\"absolute z-10 top-full left-0 right-0 mt-1 max-h-40 overflow-y-auto bg-bg-surface border border-border-default rounded-md shadow-lg\">\n {availableFields.slice(0, 10).map((field) => (\n <button\n key={field}\n type=\"button\"\n onClick={() => {\n updateParameterMapping(index, 'value', field);\n setShowFieldSuggestions(null);\n }}\n className=\"w-full px-3 py-1.5 text-left text-xs text-text-primary hover:bg-bg-sunken font-mono\"\n >\n {field}\n </button>\n ))}\n </div>\n )}\n </div>\n {parameterMappings.length > 1 && (\n <button\n type=\"button\"\n onClick={() => removeParameterMapping(index)}\n className=\"p-1 text-text-tertiary hover:text-state-error\"\n >\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n )}\n </div>\n </div>\n ))}\n </div>\n\n <p className=\"text-xs text-text-tertiary mt-2\">\n Use <code className=\"px-1 bg-bg-sunken rounded\">{'{{row.field}}'}</code> for dynamic values or enter\n static text.\n <br />\n Examples: <code className=\"px-1 bg-bg-sunken rounded\">{'{{row.category}}'}</code>,{' '}\n <code className=\"px-1 bg-bg-sunken rounded\">{'{{item.id}}'}</code>,{' '}\n <code className=\"px-1 bg-bg-sunken rounded\">{'{{globals.vars.dateFrom}}'}</code>\n </p>\n </div>\n\n {/* Advanced Options */}\n <div className=\"border-t border-border-default pt-4 mt-4\">\n <h4 className=\"text-sm font-medium text-text-primary mb-3\">Advanced Options</h4>\n\n {/* Pass Global Filters */}\n <div className=\"flex items-center justify-between p-2 rounded bg-bg-sunken mb-3\">\n <div>\n <label className=\"text-sm text-text-primary\">Pass Global Filters</label>\n <p className=\"text-xs text-text-tertiary\">Include current dashboard filters in drilldown</p>\n </div>\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={passGlobalFilters}\n onClick={() => setPassGlobalFilters(!passGlobalFilters)}\n className={`\n relative inline-flex h-5 w-9 items-center rounded-full transition-colors cursor-pointer border\n ${passGlobalFilters ? 'bg-action-primary-bg border-action-primary-bg' : 'bg-gray-300 border-gray-400'}\n `}\n >\n <span\n className={`\n inline-block h-3 w-3 transform rounded-full bg-white shadow transition-transform\n ${passGlobalFilters ? 'translate-x-5' : 'translate-x-1'}\n `}\n />\n </button>\n </div>\n\n {/* Max Depth */}\n <div className=\"flex items-center justify-between p-2 rounded bg-bg-sunken mb-3\">\n <div>\n <label className=\"text-sm text-text-primary\">Max Drilldown Depth</label>\n <p className=\"text-xs text-text-tertiary\">Limit nested drilldown levels</p>\n </div>\n <select\n value={maxDepth}\n onChange={(e) => setMaxDepth(Number(e.target.value))}\n className=\"w-16 px-2 py-1 rounded border border-border-default bg-bg-surface text-text-primary text-sm\"\n >\n {[1, 2, 3, 4, 5].map((n) => (\n <option key={n} value={n}>\n {n}\n </option>\n ))}\n </select>\n </div>\n\n {/* Open In (only for SAME_WINDOW mode) */}\n {navigationMode === 'SAME_WINDOW' && (\n <div className=\"flex items-center justify-between p-2 rounded bg-bg-sunken\">\n <div>\n <label className=\"text-sm text-text-primary\">Open In</label>\n <p className=\"text-xs text-text-tertiary\">Tab behavior for navigation</p>\n </div>\n <div className=\"flex gap-1\">\n <button\n type=\"button\"\n onClick={() => setOpenIn('same')}\n className={`\n px-2 py-1 rounded text-xs font-medium transition-colors\n ${\n openIn === 'same'\n ? 'bg-action-primary-bg text-white'\n : 'bg-bg-surface text-text-secondary hover:bg-bg-sunken/80 border border-border-default'\n }\n `}\n >\n Same Tab\n </button>\n <button\n type=\"button\"\n onClick={() => setOpenIn('new')}\n className={`\n px-2 py-1 rounded text-xs font-medium transition-colors\n ${\n openIn === 'new'\n ? 'bg-action-primary-bg text-white'\n : 'bg-bg-surface text-text-secondary hover:bg-bg-sunken/80 border border-border-default'\n }\n `}\n >\n New Tab\n </button>\n </div>\n </div>\n )}\n </div>\n </>\n )}\n\n {/* Info when drilldown will be removed */}\n {!enabled && widget.drilldown?.id && (\n <div className=\"p-2 rounded bg-amber-100 text-amber-800 text-sm\">\n Drilldown will be removed when you save changes.\n </div>\n )}\n </div>\n );\n});\n\nexport default DrilldownConfigPanel;\n"],"mappings":";;;;;;AA8DA,SAAS,EAAkB,GAAc,IAAS,IAAc;AAC9D,KAAI,CAAC,KAAO,OAAO,KAAQ,SAAU,QAAO,EAAE;CAE9C,IAAM,IAAkB,EAAE;AAG1B,KAAI,MAAM,QAAQ,EAAI,CAIpB,QAHI,EAAI,SAAS,KAAK,OAAO,EAAI,MAAO,WAC/B,EAAkB,EAAI,IAAI,EAAO,GAEnC,EAAE;AAIX,MAAK,IAAM,CAAC,GAAK,MAAU,OAAO,QAAQ,EAA+B,EAAE;EACzE,IAAM,IAAO,IAAS,GAAG,EAAO,GAAG,MAAQ;AAI3C,EAHA,EAAM,KAAK,EAAK,EAGZ,KAAS,OAAO,KAAU,YAAY,CAAC,MAAM,QAAQ,EAAM,IAAI,EAAO,MAAM,IAAI,CAAC,SAAS,KAC5F,EAAM,KAAK,GAAG,EAAkB,GAAO,EAAK,CAAC;;AAIjD,QAAO;;AAOT,IAAa,IAAsD,EAAK,SAA8B,EACpG,WACA,aACA,iBACC;CACD,IAAM,IAAe,GAAiB,EAGhC,CAAC,GAAS,KAAc,EAAS,EAAO,WAAW,WAAW,GAAM,EACpE,CAAC,GAAmB,KAAwB,EAAS,EAAO,WAAW,qBAAqB,GAAG,EAC/F,CAAC,GAAgB,KAAqB,EAAyB,EAAO,WAAW,kBAAkB,QAAQ,EAC3G,CAAC,GAAmB,KAAwB,EAAS,EAAO,WAAW,qBAAqB,GAAK,EACjG,CAAC,GAAU,KAAe,EAAS,EAAO,WAAW,YAAA,EAA8B,EACnF,CAAC,GAAQ,KAAa,EAAyB,EAAO,WAAW,UAAU,OAAO,EAClF,CAAC,GAAmB,KAAwB,QAAmC;EACnF,IAAM,IAAU,EAAO,WAAW;AAIlC,SAHI,IACK,OAAO,QAAQ,EAAQ,CAAC,KAAK,CAAC,GAAK,QAAY;GAAE;GAAK;GAAO,EAAE,GAEjE,CAAC;GAAE,KAAK;GAAI,OAAO;GAAI,CAAC;GAC/B,EAEI,CAAC,GAAY,KAAiB,EAA4B,EAAE,CAAC,EAC7D,CAAC,GAAS,KAAc,EAAS,GAAM,EACvC,CAAC,GAAsB,KAA2B,EAAwB,KAAK,EAG/E,IAAkB,QAAc;AACpC,MAAI,CAAC,EAAY,QAAO,EAAE;EAG1B,IAAM,IAAW;GAAC;GAAO;GAAQ;GAAS;GAAe,EACnD,IAAS,EAAkB,EAAW,EAGtC,IAAwB,EAAE;AAChC,OAAK,IAAM,KAAS,EAClB,MAAK,IAAM,KAAU,EACnB,GAAY,KAAK,KAAK,EAAO,GAAG,EAAM,IAAI;AAQ9C,SAHA,EAAY,KAAK,oBAAoB,oBAAoB,gBAAgB,EACzE,EAAY,KAAK,6BAA6B,0BAA0B,EAEjE,CAAC,GAAG,IAAI,IAAI,EAAY,CAAC;IAC/B,CAAC,EAAW,CAAC,EAGV,IAAe,QAAkB;EACrC,IAAM,IAA2C,EAAE;AACnD,OAAK,IAAM,EAAE,QAAK,cAAW,EAC3B,CAAI,EAAI,MAAM,IAAI,EAAM,MAAM,KAC5B,EAAiB,EAAI,MAAM,IAAI,EAAM,MAAM;AAG/C,MAAW;GACT;GACA;GACA;GACA;GACA;GACA;GACA;GACD,CAAC;IACD;EAAC;EAAS;EAAmB;EAAgB;EAAmB;EAAmB;EAAU;EAAQ;EAAS,CAAC;AAiBlH,CAdA,QAAgB;AACd,KAAc;IACb;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC,EAGF,QAAgB;EACd,eAAe,IAAkB;AAC/B,KAAW,GAAK;AAChB,OAAI;AAQF,QAPe,MAAM,EAAa,MAAgE;KAChG,OAAO;KACP,WAAW,EAAE,OAAO,KAAK;KACzB,aAAa;KACd,CAAC,EAEmB,MAAM,gBAAgB,SAAS,EAAE,EAE9C,KAAK,MAAkC;KAC3C,IAAM,IAAO,EAAK;AAClB,YAAO;MACL,IAAI,EAAK;MACT,MAAM,EAAK;MACZ;MACD,CACH;WACW,WACJ;AACR,MAAW,GAAM;;;AAIrB,KAAiB;IAChB,CAAC,EAAa,CAAC;CAGlB,IAAM,IAAsB,QAAkB;AAC5C,KAAsB,MAAS,CAAC,GAAG,GAAM;GAAE,KAAK;GAAI,OAAO;GAAI,CAAC,CAAC;IAChE,EAAE,CAAC,EAGA,IAAyB,GAAa,MAAkB;AAC5D,KAAsB,MAAS,EAAK,QAAQ,GAAG,MAAM,MAAM,EAAM,CAAC;IACjE,EAAE,CAAC,EAGA,IAAyB,GAAa,GAAe,GAAwB,MAAqB;AACtG,KAAsB,MAAS,EAAK,KAAK,GAAM,MAAO,MAAM,IAAQ;GAAE,GAAG;IAAO,IAAQ;GAAU,GAAG,EAAM,CAAC;IAC3G,EAAE,CAAC;AAEN,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GAEE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,SAAD;KAAO,WAAU;eAAwC;KAAwB,CAAA,EACjF,kBAAC,UAAD;KACE,MAAK;KACL,MAAK;KACL,gBAAc;KACd,eAAe,EAAW,CAAC,EAAQ;KACnC,WAAW;;gBAEL,IAAU,kDAAkD,8BAA8B;;eAGhG,kBAAC,QAAD,EACE,WAAW;;kBAEL,IAAU,kBAAkB,gBAAgB;iBAElD,CAAA;KACK,CAAA,CACL;;GAEL,KACC,kBAAA,GAAA,EAAA,UAAA;IAEE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;KAAO,WAAU;eAAmD;KAAwB,CAAA,EAC5F,kBAAC,UAAD;KACE,OAAO;KACP,WAAW,MAAM,EAAqB,EAAE,OAAO,MAAM;KACrD,UAAU;KACV,WAAU;eAJZ,CAME,kBAAC,UAAD;MAAQ,OAAM;gBAAG;MAA8B,CAAA,EAC9C,EACE,QAAQ,MAAM,EAAE,OAAO,EAAO,YAAY,CAC1C,KAAK,MACJ,kBAAC,UAAD;MAA2B,OAAO,EAAU;gBACzC,EAAU;MACJ,EAFI,EAAU,GAEd,CACT,CACG;OACL,EAAA,CAAA;IAGN,kBAAC,OAAD,EAAA,UAAA;KACE,kBAAC,SAAD;MAAO,WAAU;gBAAmD;MAAuB,CAAA;KAC3F,kBAAC,OAAD;MAAK,WAAU;gBACX;OAAC;OAAS;OAAW;OAAc,CAAsB,KAAK,MAC9D,kBAAC,UAAD;OAEE,MAAK;OACL,eAAe,EAAkB,EAAK;OACtC,WAAW;;wBAGL,MAAmB,IACf,oCACA,yDACL;;iBAVP;QAaG,MAAS,WAAW;QACpB,MAAS,aAAa;QACtB,MAAS,iBAAiB;QACpB;SAfF,EAeE,CACT;MACE,CAAA;KACN,kBAAC,KAAD;MAAG,WAAU;gBAAb;OACG,MAAmB,WAAW;OAC9B,MAAmB,aAAa;OAChC,MAAmB,iBAAiB;OACnC;;KACA,EAAA,CAAA;IAGN,kBAAC,OAAD,EAAA,UAAA;KACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,SAAD;OAAO,WAAU;iBAAwC;OAA0B,CAAA,EACnF,kBAAC,UAAD;OACE,MAAK;OACL,SAAS;OACT,WAAU;iBACX;OAEQ,CAAA,CACL;;KAEN,kBAAC,OAAD;MAAK,WAAU;gBACZ,EAAkB,KAAK,GAAS,MAC/B,kBAAC,OAAD;OAAiB,WAAU;iBACzB,kBAAC,OAAD;QAAK,WAAU;kBAAf;SACE,kBAAC,SAAD;UACE,MAAK;UACL,OAAO,EAAQ;UACf,WAAW,MAAM,EAAuB,GAAO,OAAO,EAAE,OAAO,MAAM;UACrE,aAAY;UACZ,WAAU;UACV,CAAA;SACF,kBAAC,QAAD;UAAM,WAAU;oBAAqB;UAAQ,CAAA;SAC7C,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,SAAD;WACE,MAAK;WACL,OAAO,EAAQ;WACf,WAAW,MAAM,EAAuB,GAAO,SAAS,EAAE,OAAO,MAAM;WACvE,eAAe,EAAwB,EAAM;WAC7C,cAAc,iBAAiB,EAAwB,KAAK,EAAE,IAAI;WAClE,aAAY;WACZ,WAAU;WACV,CAAA,EAED,MAAyB,KAAS,EAAgB,SAAS,KAC1D,kBAAC,OAAD;WAAK,WAAU;qBACZ,EAAgB,MAAM,GAAG,GAAG,CAAC,KAAK,MACjC,kBAAC,UAAD;YAEE,MAAK;YACL,eAAe;AAEb,aADA,EAAuB,GAAO,SAAS,EAAM,EAC7C,EAAwB,KAAK;;YAE/B,WAAU;sBAET;YACM,EATF,EASE,CACT;WACE,CAAA,CAEJ;;SACL,EAAkB,SAAS,KAC1B,kBAAC,UAAD;UACE,MAAK;UACL,eAAe,EAAuB,EAAM;UAC5C,WAAU;oBAEV,kBAAC,OAAD;WAAK,WAAU;WAAU,MAAK;WAAO,QAAO;WAAe,SAAQ;qBACjE,kBAAC,QAAD;YAAM,eAAc;YAAQ,gBAAe;YAAQ,aAAa;YAAG,GAAE;YAAyB,CAAA;WAC1F,CAAA;UACC,CAAA;SAEP;;OACF,EAnDI,EAmDJ,CACN;MACE,CAAA;KAEN,kBAAC,KAAD;MAAG,WAAU;gBAAb;OAA+C;OACzC,kBAAC,QAAD;QAAM,WAAU;kBAA6B;QAAuB,CAAA;;OAExE,kBAAC,MAAD,EAAM,CAAA;;OACI,kBAAC,QAAD;QAAM,WAAU;kBAA6B;QAA0B,CAAA;;OAAE;OACnF,kBAAC,QAAD;QAAM,WAAU;kBAA6B;QAAqB,CAAA;;OAAE;OACpE,kBAAC,QAAD;QAAM,WAAU;kBAA6B;QAAmC,CAAA;OAC9E;;KACA,EAAA,CAAA;IAGN,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,MAAD;OAAI,WAAU;iBAA6C;OAAqB,CAAA;MAGhF,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;QAAO,WAAU;kBAA4B;QAA2B,CAAA,EACxE,kBAAC,KAAD;QAAG,WAAU;kBAA6B;QAAkD,CAAA,CACxF,EAAA,CAAA,EACN,kBAAC,UAAD;QACE,MAAK;QACL,MAAK;QACL,gBAAc;QACd,eAAe,EAAqB,CAAC,EAAkB;QACvD,WAAW;;sBAEL,IAAoB,kDAAkD,8BAA8B;;kBAG1G,kBAAC,QAAD,EACE,WAAW;;wBAEL,IAAoB,kBAAkB,gBAAgB;uBAE5D,CAAA;QACK,CAAA,CACL;;MAGN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;QAAO,WAAU;kBAA4B;QAA2B,CAAA,EACxE,kBAAC,KAAD;QAAG,WAAU;kBAA6B;QAAiC,CAAA,CACvE,EAAA,CAAA,EACN,kBAAC,UAAD;QACE,OAAO;QACP,WAAW,MAAM,EAAY,OAAO,EAAE,OAAO,MAAM,CAAC;QACpD,WAAU;kBAET;SAAC;SAAG;SAAG;SAAG;SAAG;SAAE,CAAC,KAAK,MACpB,kBAAC,UAAD;SAAgB,OAAO;mBACpB;SACM,EAFI,EAEJ,CACT;QACK,CAAA,CACL;;MAGL,MAAmB,iBAClB,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;QAAO,WAAU;kBAA4B;QAAe,CAAA,EAC5D,kBAAC,KAAD;QAAG,WAAU;kBAA6B;QAA+B,CAAA,CACrE,EAAA,CAAA,EACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,UAAD;SACE,MAAK;SACL,eAAe,EAAU,OAAO;SAChC,WAAW;;0BAGL,MAAW,SACP,oCACA,uFACL;;mBAEN;SAEQ,CAAA,EACT,kBAAC,UAAD;SACE,MAAK;SACL,eAAe,EAAU,MAAM;SAC/B,WAAW;;0BAGL,MAAW,QACP,oCACA,uFACL;;mBAEN;SAEQ,CAAA,CACL;UACF;;MAEJ;;IACL,EAAA,CAAA;GAIJ,CAAC,KAAW,EAAO,WAAW,MAC7B,kBAAC,OAAD;IAAK,WAAU;cAAkD;IAE3D,CAAA;GAEJ;;EAER"}
1
+ {"version":3,"file":"DrilldownConfigPanel.js","names":[],"sources":["../../../../src/bigconsole/components/widgets/DrilldownConfigPanel.tsx"],"sourcesContent":["/**\n * DrilldownConfigPanel Component\n *\n * UI for configuring widget drilldown settings.\n * Allows selecting target dashboard, navigation mode, and parameter mappings.\n *\n * v2.0 Features:\n * - passGlobalFilters: Pass current dashboard filters to target\n * - maxDepth: Limit drilldown depth (default: 3)\n * - openIn: Open in same tab or new tab\n * - Field suggestions based on widget data\n */\n\nimport { type FC, memo, useState, useEffect, useCallback, useMemo } from 'react';\nimport { useApolloClient } from '@apollo/client/react';\nimport type { Widget, NavigationMode } from '../../types';\nimport { ListDashboardsDocument } from '../../../generated/wspace-operations';\nimport { DEFAULT_MAX_DEPTH } from '../../hooks/useDrilldown';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface DrilldownConfigPanelProps {\n /** Widget to configure drilldown for */\n widget: Widget;\n /** Callback when drilldown settings change (for tracking unsaved changes) */\n onChange?: (config: DrilldownConfig) => void;\n /** Sample widget data for field suggestions */\n widgetData?: Record<string, unknown>;\n}\n\nexport interface DrilldownConfig {\n enabled: boolean;\n targetDashboardId: string;\n navigationMode: NavigationMode;\n parameterMapping: Record<string, string>;\n /** Whether to pass global filters to target dashboard */\n passGlobalFilters: boolean;\n /** Maximum drilldown depth (default: 3) */\n maxDepth: number;\n /** Open in same tab or new tab (for SAME_WINDOW mode) */\n openIn: 'same' | 'new';\n}\n\ninterface DashboardOption {\n id: string;\n name: string;\n}\n\ninterface ParameterMapping {\n key: string;\n value: string;\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Extract available fields from widget data for field suggestions\n */\nfunction extractFieldPaths(obj: unknown, prefix = ''): string[] {\n if (!obj || typeof obj !== 'object') return [];\n\n const paths: string[] = [];\n\n // Handle arrays - use first element as template\n if (Array.isArray(obj)) {\n if (obj.length > 0 && typeof obj[0] === 'object') {\n return extractFieldPaths(obj[0], prefix);\n }\n return [];\n }\n\n // Handle objects\n for (const [key, value] of Object.entries(obj as Record<string, unknown>)) {\n const path = prefix ? `${prefix}.${key}` : key;\n paths.push(path);\n\n // Recurse into nested objects (but not too deep)\n if (value && typeof value === 'object' && !Array.isArray(value) && prefix.split('.').length < 2) {\n paths.push(...extractFieldPaths(value, path));\n }\n }\n\n return paths;\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport const DrilldownConfigPanel: FC<DrilldownConfigPanelProps> = memo(function DrilldownConfigPanel({\n widget,\n onChange,\n widgetData,\n}) {\n const apolloClient = useApolloClient();\n\n // State\n const [enabled, setEnabled] = useState(widget.drilldown?.enabled ?? false);\n const [targetDashboardId, setTargetDashboardId] = useState(widget.drilldown?.targetDashboardId ?? '');\n const [navigationMode, setNavigationMode] = useState<NavigationMode>(widget.drilldown?.navigationMode ?? 'MODAL');\n const [passGlobalFilters, setPassGlobalFilters] = useState(widget.drilldown?.passGlobalFilters ?? true);\n const [maxDepth, setMaxDepth] = useState(widget.drilldown?.maxDepth ?? DEFAULT_MAX_DEPTH);\n const [openIn, setOpenIn] = useState<'same' | 'new'>(widget.drilldown?.openIn ?? 'same');\n const [parameterMappings, setParameterMappings] = useState<ParameterMapping[]>(() => {\n const mapping = widget.drilldown?.parameterMapping as Record<string, string> | undefined;\n if (mapping) {\n return Object.entries(mapping).map(([key, value]) => ({ key, value }));\n }\n return [{ key: '', value: '' }];\n });\n\n const [dashboards, setDashboards] = useState<DashboardOption[]>([]);\n const [loading, setLoading] = useState(false);\n const [showFieldSuggestions, setShowFieldSuggestions] = useState<number | null>(null);\n\n // Extract available field paths from widget data\n const availableFields = useMemo(() => {\n if (!widgetData) return [];\n\n // Common prefixes for different widget types\n const prefixes = ['row', 'item', 'point', 'selectedData'];\n const fields = extractFieldPaths(widgetData);\n\n // Generate mustache-style suggestions\n const suggestions: string[] = [];\n for (const field of fields) {\n for (const prefix of prefixes) {\n suggestions.push(`{{${prefix}.${field}}}`);\n }\n }\n\n // Add common widget data fields\n suggestions.push('{{widget.value}}', '{{widget.title}}', '{{widget.id}}');\n suggestions.push('{{globals.vars.dateFrom}}', '{{globals.vars.dateTo}}');\n\n return [...new Set(suggestions)];\n }, [widgetData]);\n\n // Notify parent of changes\n const notifyChange = useCallback(() => {\n const parameterMapping: Record<string, string> = {};\n for (const { key, value } of parameterMappings) {\n if (key.trim() && value.trim()) {\n parameterMapping[key.trim()] = value.trim();\n }\n }\n onChange?.({\n enabled,\n targetDashboardId,\n navigationMode,\n parameterMapping,\n passGlobalFilters,\n maxDepth,\n openIn,\n });\n }, [enabled, targetDashboardId, navigationMode, parameterMappings, passGlobalFilters, maxDepth, openIn, onChange]);\n\n // Call notifyChange when any value changes\n useEffect(() => {\n notifyChange();\n }, [\n enabled,\n targetDashboardId,\n navigationMode,\n parameterMappings,\n passGlobalFilters,\n maxDepth,\n openIn,\n notifyChange,\n ]);\n\n // Fetch available dashboards\n useEffect(() => {\n async function fetchDashboards() {\n setLoading(true);\n try {\n const result = await apolloClient.query<{ listDashboards: { edges: Record<string, unknown>[] } }>({\n query: ListDashboardsDocument,\n variables: { first: 100 },\n fetchPolicy: 'cache-first',\n });\n\n const edges = result.data?.listDashboards?.edges || [];\n setDashboards(\n edges.map((edge: Record<string, unknown>) => {\n const node = edge.node as Record<string, unknown>;\n return {\n id: node.id as string,\n name: node.name as string,\n };\n })\n );\n } catch (err) {\n } finally {\n setLoading(false);\n }\n }\n\n fetchDashboards();\n }, [apolloClient]);\n\n // Add parameter mapping row\n const addParameterMapping = useCallback(() => {\n setParameterMappings((prev) => [...prev, { key: '', value: '' }]);\n }, []);\n\n // Remove parameter mapping row\n const removeParameterMapping = useCallback((index: number) => {\n setParameterMappings((prev) => prev.filter((_, i) => i !== index));\n }, []);\n\n // Update parameter mapping\n const updateParameterMapping = useCallback((index: number, field: 'key' | 'value', newValue: string) => {\n setParameterMappings((prev) => prev.map((item, i) => (i === index ? { ...item, [field]: newValue } : item)));\n }, []);\n\n return (\n <div className=\"space-y-4 pb-8\">\n {/* Enable Toggle */}\n <div className=\"flex items-center justify-between p-3 rounded-lg border border-border-default bg-bg-surface\">\n <label className=\"text-sm font-medium text-text-primary\">Enable Drilldown</label>\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={enabled}\n onClick={() => setEnabled(!enabled)}\n className={`\n relative inline-flex h-6 w-11 items-center rounded-full transition-colors cursor-pointer border\n ${enabled ? 'bg-action-primary-bg border-action-primary-bg' : 'bg-gray-300 border-gray-400'}\n `}\n >\n <span\n className={`\n inline-block h-4 w-4 transform rounded-full bg-white shadow transition-transform\n ${enabled ? 'translate-x-6' : 'translate-x-1'}\n `}\n />\n </button>\n </div>\n\n {enabled && (\n <>\n {/* Target Dashboard */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">Target Dashboard</label>\n <select\n value={targetDashboardId}\n onChange={(e) => setTargetDashboardId(e.target.value)}\n disabled={loading}\n className=\"w-full px-3 py-2 rounded-md border border-border-default bg-bg-surface text-text-primary text-sm focus:outline-none focus:ring-2 focus:ring-action-primary-bg\"\n >\n <option value=\"\">Select a dashboard...</option>\n {dashboards\n .filter((d) => d.id !== widget.dashboardId) // Exclude current dashboard\n .map((dashboard) => (\n <option key={dashboard.id} value={dashboard.id}>\n {dashboard.name}\n </option>\n ))}\n </select>\n </div>\n\n {/* Navigation Mode */}\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">Navigation Mode</label>\n <div className=\"flex gap-2\">\n {(['MODAL', 'NEW_TAB', 'SAME_WINDOW'] as NavigationMode[]).map((mode) => (\n <button\n key={mode}\n type=\"button\"\n onClick={() => setNavigationMode(mode)}\n className={`\n flex-1 px-3 py-2 rounded-md text-sm font-medium transition-colors\n ${\n navigationMode === mode\n ? 'bg-action-primary-bg text-white'\n : 'bg-bg-sunken text-text-secondary hover:bg-bg-sunken/80'\n }\n `}\n >\n {mode === 'MODAL' && 'Modal'}\n {mode === 'NEW_TAB' && 'New Tab'}\n {mode === 'SAME_WINDOW' && 'Same Window'}\n </button>\n ))}\n </div>\n <p className=\"text-xs text-text-tertiary mt-1\">\n {navigationMode === 'MODAL' && 'Opens target dashboard in a modal overlay'}\n {navigationMode === 'NEW_TAB' && 'Opens target dashboard in a new browser tab'}\n {navigationMode === 'SAME_WINDOW' && 'Navigates to target dashboard in current window'}\n </p>\n </div>\n\n {/* Parameter Mappings */}\n <div>\n <div className=\"flex items-center justify-between mb-2\">\n <label className=\"text-sm font-medium text-text-primary\">Parameter Mappings</label>\n <button\n type=\"button\"\n onClick={addParameterMapping}\n className=\"text-xs text-action-primary-text hover:underline\"\n >\n + Add Parameter\n </button>\n </div>\n\n <div className=\"space-y-2\">\n {parameterMappings.map((mapping, index) => (\n <div key={index} className=\"relative\">\n <div className=\"flex gap-2 items-center\">\n <input\n type=\"text\"\n value={mapping.key}\n onChange={(e) => updateParameterMapping(index, 'key', e.target.value)}\n placeholder=\"Parameter name\"\n className=\"flex-1 px-2 py-1.5 rounded border border-border-default bg-bg-surface text-text-primary text-sm focus:outline-none focus:ring-1 focus:ring-action-primary-bg\"\n />\n <span className=\"text-text-tertiary\">=</span>\n <div className=\"flex-1 relative\">\n <input\n type=\"text\"\n value={mapping.value}\n onChange={(e) => updateParameterMapping(index, 'value', e.target.value)}\n onFocus={() => setShowFieldSuggestions(index)}\n onBlur={() => setTimeout(() => setShowFieldSuggestions(null), 200)}\n placeholder=\"{{row.field}} or static\"\n className=\"w-full px-2 py-1.5 rounded border border-border-default bg-bg-surface text-text-primary text-sm focus:outline-none focus:ring-1 focus:ring-action-primary-bg\"\n />\n {/* Field suggestions dropdown */}\n {showFieldSuggestions === index && availableFields.length > 0 && (\n <div className=\"absolute z-10 top-full left-0 right-0 mt-1 max-h-40 overflow-y-auto bg-bg-surface border border-border-default rounded-md shadow-lg\">\n {availableFields.slice(0, 10).map((field) => (\n <button\n key={field}\n type=\"button\"\n onClick={() => {\n updateParameterMapping(index, 'value', field);\n setShowFieldSuggestions(null);\n }}\n className=\"w-full px-3 py-1.5 text-left text-xs text-text-primary hover:bg-bg-sunken font-mono\"\n >\n {field}\n </button>\n ))}\n </div>\n )}\n </div>\n {parameterMappings.length > 1 && (\n <button\n type=\"button\"\n onClick={() => removeParameterMapping(index)}\n className=\"p-1 text-text-tertiary hover:text-status-error-text\"\n >\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n )}\n </div>\n </div>\n ))}\n </div>\n\n <p className=\"text-xs text-text-tertiary mt-2\">\n Use <code className=\"px-1 bg-bg-sunken rounded\">{'{{row.field}}'}</code> for dynamic values or enter\n static text.\n <br />\n Examples: <code className=\"px-1 bg-bg-sunken rounded\">{'{{row.category}}'}</code>,{' '}\n <code className=\"px-1 bg-bg-sunken rounded\">{'{{item.id}}'}</code>,{' '}\n <code className=\"px-1 bg-bg-sunken rounded\">{'{{globals.vars.dateFrom}}'}</code>\n </p>\n </div>\n\n {/* Advanced Options */}\n <div className=\"border-t border-border-default pt-4 mt-4\">\n <h4 className=\"text-sm font-medium text-text-primary mb-3\">Advanced Options</h4>\n\n {/* Pass Global Filters */}\n <div className=\"flex items-center justify-between p-2 rounded bg-bg-sunken mb-3\">\n <div>\n <label className=\"text-sm text-text-primary\">Pass Global Filters</label>\n <p className=\"text-xs text-text-tertiary\">Include current dashboard filters in drilldown</p>\n </div>\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={passGlobalFilters}\n onClick={() => setPassGlobalFilters(!passGlobalFilters)}\n className={`\n relative inline-flex h-5 w-9 items-center rounded-full transition-colors cursor-pointer border\n ${passGlobalFilters ? 'bg-action-primary-bg border-action-primary-bg' : 'bg-gray-300 border-gray-400'}\n `}\n >\n <span\n className={`\n inline-block h-3 w-3 transform rounded-full bg-white shadow transition-transform\n ${passGlobalFilters ? 'translate-x-5' : 'translate-x-1'}\n `}\n />\n </button>\n </div>\n\n {/* Max Depth */}\n <div className=\"flex items-center justify-between p-2 rounded bg-bg-sunken mb-3\">\n <div>\n <label className=\"text-sm text-text-primary\">Max Drilldown Depth</label>\n <p className=\"text-xs text-text-tertiary\">Limit nested drilldown levels</p>\n </div>\n <select\n value={maxDepth}\n onChange={(e) => setMaxDepth(Number(e.target.value))}\n className=\"w-16 px-2 py-1 rounded border border-border-default bg-bg-surface text-text-primary text-sm\"\n >\n {[1, 2, 3, 4, 5].map((n) => (\n <option key={n} value={n}>\n {n}\n </option>\n ))}\n </select>\n </div>\n\n {/* Open In (only for SAME_WINDOW mode) */}\n {navigationMode === 'SAME_WINDOW' && (\n <div className=\"flex items-center justify-between p-2 rounded bg-bg-sunken\">\n <div>\n <label className=\"text-sm text-text-primary\">Open In</label>\n <p className=\"text-xs text-text-tertiary\">Tab behavior for navigation</p>\n </div>\n <div className=\"flex gap-1\">\n <button\n type=\"button\"\n onClick={() => setOpenIn('same')}\n className={`\n px-2 py-1 rounded text-xs font-medium transition-colors\n ${\n openIn === 'same'\n ? 'bg-action-primary-bg text-white'\n : 'bg-bg-surface text-text-secondary hover:bg-bg-sunken/80 border border-border-default'\n }\n `}\n >\n Same Tab\n </button>\n <button\n type=\"button\"\n onClick={() => setOpenIn('new')}\n className={`\n px-2 py-1 rounded text-xs font-medium transition-colors\n ${\n openIn === 'new'\n ? 'bg-action-primary-bg text-white'\n : 'bg-bg-surface text-text-secondary hover:bg-bg-sunken/80 border border-border-default'\n }\n `}\n >\n New Tab\n </button>\n </div>\n </div>\n )}\n </div>\n </>\n )}\n\n {/* Info when drilldown will be removed */}\n {!enabled && widget.drilldown?.id && (\n <div className=\"p-2 rounded bg-amber-100 text-amber-800 text-sm\">\n Drilldown will be removed when you save changes.\n </div>\n )}\n </div>\n );\n});\n\nexport default DrilldownConfigPanel;\n"],"mappings":"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"}
@@ -79,9 +79,9 @@ var Ee = [
79
79
  ], Oe = {
80
80
  PRIMARY: "bg-action-primary",
81
81
  SECONDARY: "bg-muted-foreground",
82
- SUCCESS: "bg-state-success",
83
- WARNING: "bg-state-warning",
84
- DANGER: "bg-state-error"
82
+ SUCCESS: "bg-status-success-bg",
83
+ WARNING: "bg-status-warning-bg",
84
+ DANGER: "bg-status-error-bg"
85
85
  };
86
86
  function ke(e) {
87
87
  if (!e) return {};