@burdenoff/microfe-bigconsole 2026.1008.11 → 2026.1008.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bigconsole/BigConsoleRoutes.d.ts.map +1 -1
- package/dist/bigconsole/BigConsoleRoutes.js +136 -127
- package/dist/bigconsole/BigConsoleRoutes.js.map +1 -1
- package/dist/bigconsole/assistant/assistantProduct.d.ts.map +1 -1
- package/dist/bigconsole/assistant/assistantProduct.js +3 -1
- package/dist/bigconsole/assistant/assistantProduct.js.map +1 -1
- package/dist/bigconsole/components/builder/inspector/DataBindingSection.js +31 -31
- package/dist/bigconsole/components/dashboard/CreateDashboardDialog.js +44 -44
- package/dist/bigconsole/components/dashboard/CreateDashboardDialog.js.map +1 -1
- package/dist/bigconsole/components/dashboard/DashboardCanvas.js +36 -36
- package/dist/bigconsole/components/dashboard/DashboardCanvas.js.map +1 -1
- package/dist/bigconsole/components/dashboard/DashboardToolbar.js +59 -59
- package/dist/bigconsole/components/dashboard/DrilldownBreadcrumb.js +15 -15
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterChip.js +30 -30
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.js +41 -41
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterPresetSelector.js +34 -34
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.js +34 -34
- package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js +110 -110
- package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js.map +1 -1
- package/dist/bigconsole/components/dashboard/PublishToStoreDialog.js +21 -21
- package/dist/bigconsole/components/dashboard/SavedViewsDropdown/SavedViewsDropdown.js +46 -46
- package/dist/bigconsole/components/dashboard/ShareDialog/EmbedTab.js +91 -91
- package/dist/bigconsole/components/dashboard/ShareDialog/EmbedTab.js.map +1 -1
- package/dist/bigconsole/components/dashboard/ShareDialog/ShareDialog.js +101 -101
- package/dist/bigconsole/components/dashboard/ShareDialog/ShareDialog.js.map +1 -1
- package/dist/bigconsole/components/dashboard/TemplateInstallOptions.js +31 -31
- package/dist/bigconsole/components/dashboard/TemplateLayoutPreview.js +15 -15
- package/dist/bigconsole/components/dashboard/TemplatePicker/TemplatePicker.js +1 -1
- package/dist/bigconsole/components/dashboard/WidgetPalette.js +46 -46
- package/dist/bigconsole/components/datasink/AlertExecutionHistory.js +37 -37
- package/dist/bigconsole/components/datasink/AlertRuleEditor.js +66 -66
- package/dist/bigconsole/components/datasink/CacheTTLSelector.js +35 -35
- package/dist/bigconsole/components/datasink/DataSinkCard.js +29 -29
- package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js +18 -18
- package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js +20 -20
- package/dist/bigconsole/components/datasink/ImportDataGuideDialog.js +47 -47
- package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js +91 -91
- package/dist/bigconsole/components/datasink/RefreshTypeSelector.js +35 -35
- package/dist/bigconsole/components/parser/DataSinkSelector.js +40 -40
- package/dist/bigconsole/components/parser/ImportParserDialog.js +120 -120
- package/dist/bigconsole/components/parser/ImportParserDialog.js.map +1 -1
- package/dist/bigconsole/components/parser/ParserSelector.js +51 -51
- package/dist/bigconsole/components/pipeline/PipelineScopePicker.js +10 -10
- package/dist/bigconsole/components/preview/AiPreviewMiniPanel.js +27 -27
- package/dist/bigconsole/components/preview/AiPreviewPanel.js +30 -30
- package/dist/bigconsole/components/widgets/ActionConfigDialog.js +4 -4
- package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js +93 -93
- package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js.map +1 -1
- package/dist/bigconsole/components/widgets/PropertiesPanel.d.ts.map +1 -1
- package/dist/bigconsole/components/widgets/PropertiesPanel.js +280 -273
- package/dist/bigconsole/components/widgets/PropertiesPanel.js.map +1 -1
- package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js +4 -4
- package/dist/bigconsole/components/widgets/chart/ChartConfig.js +48 -48
- package/dist/bigconsole/components/widgets/comments/WidgetComments.js +46 -46
- package/dist/bigconsole/components/widgets/event-logs/EventLogViewer.js +61 -61
- package/dist/bigconsole/components/widgets/form/FormWidget.js +36 -36
- package/dist/bigconsole/components/widgets/gauge/GaugeConfig.js +42 -42
- package/dist/bigconsole/components/widgets/heatmap/HeatmapConfig.js +25 -25
- package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js +4 -4
- package/dist/bigconsole/components/widgets/list/ListConfig.js +30 -30
- package/dist/bigconsole/components/widgets/metric-card/MetricCardConfig.js +38 -38
- package/dist/bigconsole/components/widgets/metric-card/SparklineChart.js +9 -9
- package/dist/bigconsole/components/widgets/metric-card/TrendIndicator.js +9 -9
- package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js +49 -49
- package/dist/bigconsole/components/widgets/progress/ProgressConfig.js +39 -39
- package/dist/bigconsole/components/widgets/table/TableConfig.js +73 -73
- package/dist/bigconsole/components/widgets/webhook-config/WebhookConfigPanel.js +64 -64
- package/dist/bigconsole/components/workflow/WorkflowOpenGuard.js +15 -15
- package/dist/bigconsole/components/workflow/WorkflowSinkLinkForm.js +15 -15
- package/dist/bigconsole/customWidget/CustomWidgetBuilderSheet.js +9 -9
- package/dist/bigconsole/customWidget/CustomWidgetProposalPanel.js +67 -67
- package/dist/bigconsole/customWidget/CustomWidgetProposalPanel.js.map +1 -1
- package/dist/bigconsole/hooks/useDashboardLayoutBaseline.d.ts +15 -0
- package/dist/bigconsole/hooks/useDashboardLayoutBaseline.d.ts.map +1 -0
- package/dist/bigconsole/hooks/useDashboardLayoutBaseline.js +34 -0
- package/dist/bigconsole/hooks/useDashboardLayoutBaseline.js.map +1 -0
- package/dist/bigconsole/hooks/useDrilldown.js +3 -3
- package/dist/bigconsole/hooks/useGlobalFilters.js +3 -3
- package/dist/bigconsole/pages/AdminPage.js +130 -130
- package/dist/bigconsole/pages/DashboardBuilderPage.d.ts.map +1 -1
- package/dist/bigconsole/pages/DashboardBuilderPage.js +72 -60
- package/dist/bigconsole/pages/DashboardBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/DashboardViewPage.js +1 -1
- package/dist/bigconsole/pages/DataSinkAlertsPage.d.ts.map +1 -1
- package/dist/bigconsole/pages/DataSinkAlertsPage.js +30 -23
- package/dist/bigconsole/pages/DataSinkAlertsPage.js.map +1 -1
- package/dist/bigconsole/pages/DataSinkBuilderPage.d.ts.map +1 -1
- package/dist/bigconsole/pages/DataSinkBuilderPage.js +272 -263
- package/dist/bigconsole/pages/DataSinkBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/DataSinkViewPage.js +1 -1
- package/dist/bigconsole/pages/DataSinksPage.js +1 -1
- package/dist/bigconsole/pages/DataSourcesPage.js +5 -5
- package/dist/bigconsole/pages/InsightsPage.js +181 -181
- package/dist/bigconsole/pages/InsightsPage.js.map +1 -1
- package/dist/bigconsole/pages/OverviewPage.js +47 -47
- package/dist/bigconsole/pages/OverviewPage.js.map +1 -1
- package/dist/bigconsole/pages/ParserBuilderPage.d.ts.map +1 -1
- package/dist/bigconsole/pages/ParserBuilderPage.js +227 -211
- package/dist/bigconsole/pages/ParserBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/ParserViewPage.js +97 -97
- package/dist/bigconsole/pages/PipelineBuilderPage.d.ts.map +1 -1
- package/dist/bigconsole/pages/PipelineBuilderPage.js +256 -214
- package/dist/bigconsole/pages/PipelineBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/PipelineViewPage.js +146 -146
- package/dist/bigconsole/pages/PipelinesPage.js +88 -88
- package/dist/bigconsole/pages/PipelinesPage.js.map +1 -1
- package/dist/bigconsole/pages/SettingsPage.d.ts.map +1 -1
- package/dist/bigconsole/pages/SettingsPage.js +179 -173
- package/dist/bigconsole/pages/SettingsPage.js.map +1 -1
- package/dist/bigconsole/pages/WidgetDemoPage.js +42 -42
- package/dist/bigconsole/pages/WorkflowViewPage.js +1 -1
- package/dist/bigconsole/pages/WorkflowsPage.js +141 -141
- package/dist/bigconsole/pages/WorkflowsPage.js.map +1 -1
- package/dist/bigconsole/providers/BigConsoleQuotaProvider.js +12 -12
- package/dist/bigconsole/renderers/adapters/AdaptiveCardRenderer.js +34 -34
- package/dist/bigconsole/renderers/adapters/BlockKitRenderer.js +79 -79
- package/dist/bigconsole/renderers/adapters/CustomRenderer.js +46 -46
- package/dist/bigconsole/store/widgetStore.d.ts +12 -0
- package/dist/bigconsole/store/widgetStore.d.ts.map +1 -1
- package/dist/bigconsole/store/widgetStore.js +3 -1
- package/dist/bigconsole/store/widgetStore.js.map +1 -1
- package/dist/bigconsole/utils/formDirty.d.ts +83 -0
- package/dist/bigconsole/utils/formDirty.d.ts.map +1 -0
- package/dist/bigconsole/utils/formDirty.js +23 -0
- package/dist/bigconsole/utils/formDirty.js.map +1 -0
- package/dist/bigconsole/utils/layoutBaseline.d.ts +131 -0
- package/dist/bigconsole/utils/layoutBaseline.d.ts.map +1 -0
- package/dist/bigconsole/utils/layoutBaseline.js +98 -0
- package/dist/bigconsole/utils/layoutBaseline.js.map +1 -0
- package/dist/translations/en.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -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 the target (a page of this dashboard, or another dashboard\n * and optionally one of its pages), navigation mode, and parameter mappings.\n *\n * Features:\n * - Target page (BOFF-7625): same-dashboard drilldowns must pick another page;\n * other dashboards default to their first page\n * - Searchable dashboard picker; a saved target that was archived, deleted or\n * unshared is flagged as unavailable\n * - passGlobalFilters: Pass current dashboard filters to target\n * - maxDepth: Limit drilldown depth (default: 3)\n * - Field suggestions based on widget data\n */\n\nimport { type FC, memo, useState, useEffect, useCallback, useMemo } from 'react';\nimport { useApolloClient, useQuery } from '@apollo/client/react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport type { Widget, NavigationMode } from '../../types';\nimport {\n GetDrilldownTargetDashboardDocument,\n GetWidgetDrilldownTargetDocument,\n ListDashboardsDocument,\n type GetDrilldownTargetDashboardQuery,\n type GetDrilldownTargetDashboardQueryVariables,\n type GetWidgetDrilldownTargetQuery,\n type GetWidgetDrilldownTargetQueryVariables,\n type ListDashboardsQuery,\n type ListDashboardsQueryVariables,\n} from '../../../generated/wspace-operations';\nimport { DEFAULT_MAX_DEPTH } from '../../hooks/useDrilldown';\nimport { Section, SECTION_FOCUS_RING } from '../common';\n\n/**\n * Shared recipes for the raw controls in this panel. The panel predates the\n * fe-libs form primitives and previously used literal Tailwind palette colours\n * (`bg-gray-300`, `bg-white`, `text-white`, `bg-amber-100`), which ignore the\n * theme entirely — a white switch knob on a light track is invisible in dark\n * mode. Everything below resolves through semantic tokens (BOFF-5636).\n */\n/**\n * Chrome only — no width or horizontal padding. Those are per-call-site, because\n * appending `w-auto`/`px-2` to a recipe that already carries `w-full`/`px-3`\n * leaves the winner to Tailwind's internal utility ordering rather than to the\n * author.\n */\nconst RAW_CONTROL_CHROME =\n 'min-h-control-md rounded-input border border-[var(--color-border-subtle)] bg-bg-surface py-2 text-sm text-text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-bg-surface';\n\n/** Full-bleed form control: the common case in this panel. */\nconst RAW_CONTROL_CLASSES = `${RAW_CONTROL_CHROME} w-full px-3`;\n\nconst SWITCH_TRACK_ON = 'bg-action-primary-bg border-action-primary-bg';\nconst SWITCH_TRACK_OFF = 'bg-bg-sunken border-[var(--color-border-strong)]';\nconst SWITCH_KNOB = 'bg-bg-surface shadow-[var(--shadow-elevation-1)]';\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 /** Page of the target dashboard; null opens its first page (BOFF-7625) */\n targetPageId: string | null;\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}\n\ninterface DashboardOption {\n id: string;\n name: string;\n}\n\ninterface PageOption {\n id: string;\n name: string;\n order: number;\n}\n\n/** Page size for the searchable dashboard picker. */\nconst DASHBOARD_PICKER_PAGE_SIZE = 50;\n/** Debounce for the dashboard picker search box. */\nconst DASHBOARD_SEARCH_DEBOUNCE_MS = 250;\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 { t } = useI18n();\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 [targetPageId, setTargetPageId] = useState<string | null>(widget.drilldown?.targetPageId ?? null);\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 [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 [dashboardsError, setDashboardsError] = useState(false);\n const [dashboardSearch, setDashboardSearch] = useState('');\n const [showFieldSuggestions, setShowFieldSuggestions] = useState<number | null>(null);\n\n const currentDashboardId = widget.dashboardId ?? '';\n const isSameDashboard = !!targetDashboardId && targetDashboardId === currentDashboardId;\n\n // Saved target as the server resolves it: null means archived, deleted or no\n // longer readable by this user (BOFF-7625).\n const savedDrilldownId = widget.drilldown?.id;\n const { data: savedTargetData } = useQuery<GetWidgetDrilldownTargetQuery, GetWidgetDrilldownTargetQueryVariables>(\n GetWidgetDrilldownTargetDocument,\n {\n variables: { widgetId: widget.id },\n skip: !savedDrilldownId,\n fetchPolicy: 'cache-and-network',\n }\n );\n const savedTarget = savedTargetData?.getWidget?.drilldown;\n const savedTargetUnavailable =\n !!savedDrilldownId &&\n !!savedTargetData &&\n !savedTarget?.targetDashboard &&\n targetDashboardId === (widget.drilldown?.targetDashboardId ?? '');\n\n // Pages of the selected target, for the page picker.\n const { data: targetPagesData, loading: targetPagesLoading } = useQuery<\n GetDrilldownTargetDashboardQuery,\n GetDrilldownTargetDashboardQueryVariables\n >(GetDrilldownTargetDashboardDocument, {\n variables: { id: targetDashboardId },\n skip: !targetDashboardId,\n fetchPolicy: 'cache-first',\n });\n const targetPages = useMemo<PageOption[]>(() => {\n const edges = targetPagesData?.getDashboard?.pages?.edges ?? [];\n return edges\n .map((edge) => edge?.node)\n .filter((node): node is NonNullable<typeof node> => !!node)\n .map((node) => ({ id: node.id, name: node.name ?? '', order: node.order ?? 0 }))\n .sort((a, b) => a.order - b.order);\n }, [targetPagesData]);\n // A same-dashboard drilldown to the widget's own page would be a no-op.\n const selectablePages = useMemo(\n () => (isSameDashboard ? targetPages.filter((page) => page.id !== widget.pageId) : targetPages),\n [isSameDashboard, targetPages, widget.pageId]\n );\n const samePageMissing = enabled && isSameDashboard && !targetPageId;\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 targetPageId,\n navigationMode,\n parameterMapping,\n passGlobalFilters,\n maxDepth,\n });\n }, [\n enabled,\n targetDashboardId,\n targetPageId,\n navigationMode,\n parameterMappings,\n passGlobalFilters,\n maxDepth,\n onChange,\n ]);\n\n // Call notifyChange when any value changes\n useEffect(() => {\n notifyChange();\n }, [\n enabled,\n targetDashboardId,\n targetPageId,\n navigationMode,\n parameterMappings,\n passGlobalFilters,\n maxDepth,\n notifyChange,\n ]);\n\n // Fetch dashboards for the picker. `listDashboards` only returns dashboards\n // the caller can read, so an inaccessible dashboard can never be picked.\n useEffect(() => {\n let cancelled = false;\n const timer = setTimeout(async () => {\n setLoading(true);\n setDashboardsError(false);\n try {\n const search = dashboardSearch.trim();\n const result = await apolloClient.query<ListDashboardsQuery, ListDashboardsQueryVariables>({\n query: ListDashboardsDocument,\n variables: {\n first: DASHBOARD_PICKER_PAGE_SIZE,\n ...(search ? { search } : {}),\n },\n fetchPolicy: 'cache-first',\n });\n if (cancelled) return;\n const edges = result.data?.listDashboards?.edges ?? [];\n setDashboards(\n edges\n .map((edge) => edge?.node)\n .filter((node): node is NonNullable<typeof node> => !!node)\n .map((node) => ({ id: node.id, name: node.name }))\n );\n } catch {\n if (!cancelled) setDashboardsError(true);\n } finally {\n if (!cancelled) setLoading(false);\n }\n }, DASHBOARD_SEARCH_DEBOUNCE_MS);\n\n return () => {\n cancelled = true;\n clearTimeout(timer);\n };\n }, [apolloClient, dashboardSearch]);\n\n // Options for the dashboard select: this dashboard first, then the others,\n // plus the saved target when the current search does not include it.\n const dashboardOptions = useMemo<DashboardOption[]>(() => {\n const others = dashboards.filter((d) => d.id !== currentDashboardId);\n if (\n targetDashboardId &&\n targetDashboardId !== currentDashboardId &&\n !others.some((d) => d.id === targetDashboardId)\n ) {\n const savedName =\n savedTarget?.targetDashboard?.id === targetDashboardId ? savedTarget.targetDashboard.name : undefined;\n others.unshift({\n id: targetDashboardId,\n name: savedName ?? t('bigconsole.widget.drilldown.unavailableDashboard', 'Unavailable dashboard'),\n });\n }\n return others;\n }, [dashboards, currentDashboardId, targetDashboardId, savedTarget, t]);\n\n const handleTargetDashboardChange = useCallback((nextDashboardId: string) => {\n setTargetDashboardId(nextDashboardId);\n // A page belongs to exactly one dashboard.\n setTargetPageId(null);\n }, []);\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=\"min-w-0 space-y-form-gap\">\n {/* Enable Toggle */}\n <div className=\"flex min-w-0 flex-wrap items-center justify-between gap-2 rounded-card border border-[var(--color-border-subtle)] bg-bg-surface p-3\">\n <label htmlFor=\"drilldown-enable\" className=\"text-sm font-medium text-text-primary\">\n {t('bigconsole.widget.drilldown.enableLabel', 'Enable Drilldown')}\n </label>\n <button\n id=\"drilldown-enable\"\n type=\"button\"\n role=\"switch\"\n aria-checked={enabled}\n onClick={() => setEnabled(!enabled)}\n className={`relative inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border motion-safe:transition-colors ${SECTION_FOCUS_RING} ${\n enabled ? SWITCH_TRACK_ON : SWITCH_TRACK_OFF\n }`}\n >\n <span\n className={`inline-block h-4 w-4 transform rounded-full motion-safe:transition-transform ${SWITCH_KNOB} ${\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 htmlFor=\"drilldown-target\" className=\"mb-1 block text-sm font-medium text-text-primary\">\n {t('bigconsole.widget.drilldown.targetDashboardLabel', 'Target Dashboard')}\n </label>\n <input\n type=\"search\"\n value={dashboardSearch}\n onChange={(e) => setDashboardSearch(e.target.value)}\n placeholder={t('bigconsole.widget.drilldown.searchDashboards', 'Search dashboards...')}\n aria-label={t('bigconsole.widget.drilldown.searchDashboards', 'Search dashboards...')}\n className={`${RAW_CONTROL_CLASSES} mb-2`}\n data-testid=\"drilldown-dashboard-search\"\n />\n <select\n id=\"drilldown-target\"\n value={targetDashboardId}\n onChange={(e) => handleTargetDashboardChange(e.target.value)}\n className={RAW_CONTROL_CLASSES}\n data-testid=\"drilldown-target-dashboard\"\n >\n <option value=\"\">{t('bigconsole.widget.drilldown.selectDashboard', 'Select a dashboard...')}</option>\n {currentDashboardId && (\n <option value={currentDashboardId}>\n {t('bigconsole.widget.drilldown.thisDashboard', 'This dashboard (another page)')}\n </option>\n )}\n {dashboardOptions.map((dashboard) => (\n <option key={dashboard.id} value={dashboard.id}>\n {dashboard.name}\n </option>\n ))}\n </select>\n {loading && (\n <p className=\"mt-1 text-xs text-text-muted\" role=\"status\">\n {t('bigconsole.widget.drilldown.loadingDashboards', 'Loading dashboards...')}\n </p>\n )}\n {dashboardsError && (\n <p className=\"mt-1 text-xs text-[var(--color-status-error-text)]\" role=\"alert\">\n {t('bigconsole.widget.drilldown.dashboardsLoadError', 'Could not load dashboards. Try again.')}\n </p>\n )}\n </div>\n\n {/* Target Page */}\n {targetDashboardId && (\n <div>\n <label htmlFor=\"drilldown-target-page\" className=\"mb-1 block text-sm font-medium text-text-primary\">\n {t('bigconsole.widget.drilldown.targetPageLabel', 'Target Page')}\n </label>\n <select\n id=\"drilldown-target-page\"\n value={targetPageId ?? ''}\n onChange={(e) => setTargetPageId(e.target.value || null)}\n disabled={targetPagesLoading}\n aria-invalid={samePageMissing}\n className={RAW_CONTROL_CLASSES}\n data-testid=\"drilldown-target-page\"\n >\n <option value=\"\">\n {isSameDashboard\n ? t('bigconsole.widget.drilldown.selectPage', 'Select a page...')\n : t('bigconsole.widget.drilldown.firstPage', 'First page (default)')}\n </option>\n {selectablePages.map((page, index) => (\n <option key={page.id} value={page.id}>\n {page.name || t('bigconsole.dashboards.view.pageName', 'Page {{count}}', { count: index + 1 })}\n </option>\n ))}\n </select>\n {samePageMissing && (\n <p className=\"mt-1 text-xs text-[var(--color-status-error-text)]\" role=\"alert\">\n {selectablePages.length === 0 && !targetPagesLoading\n ? t(\n 'bigconsole.widget.drilldown.noOtherPages',\n 'This dashboard has no other page. Add a page, or pick another dashboard.'\n )\n : t('bigconsole.widget.drilldown.samePageRequired', 'Pick the page of this dashboard to open.')}\n </p>\n )}\n </div>\n )}\n\n {savedTargetUnavailable && (\n <Section\n tone=\"warning\"\n padding=\"compact\"\n headingLevel={4}\n title={t('bigconsole.widget.drilldown.unavailableTitle', 'Target unavailable')}\n data-testid=\"drilldown-target-unavailable\"\n >\n <p className=\"text-xs text-text-secondary\">\n {t(\n 'bigconsole.widget.drilldown.unavailableHelp',\n 'The target dashboard was deleted, archived, or is no longer shared with you. Viewers see a notice instead of navigating. Pick another target.'\n )}\n </p>\n </Section>\n )}\n\n {/* Navigation Mode */}\n <div>\n <p className=\"mb-1 text-sm font-medium text-text-primary\" id=\"drilldown-nav-mode-label\">\n {t('bigconsole.widget.drilldown.navigationModeLabel', 'Navigation Mode')}\n </p>\n <div className=\"flex flex-wrap gap-2\" role=\"group\" aria-labelledby=\"drilldown-nav-mode-label\">\n {(['MODAL', 'NEW_TAB', 'SAME_WINDOW'] as NavigationMode[]).map((mode) => (\n <button\n key={mode}\n type=\"button\"\n aria-pressed={navigationMode === mode}\n onClick={() => setNavigationMode(mode)}\n className={`min-h-control-md min-w-[7rem] flex-1 rounded-button px-3 text-sm font-medium motion-safe:transition-colors ${SECTION_FOCUS_RING} ${\n navigationMode === mode\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'bg-bg-sunken text-text-secondary hover:text-text-primary'\n }`}\n >\n {mode === 'MODAL' && t('bigconsole.widget.drilldown.mode.modal', 'Modal')}\n {mode === 'NEW_TAB' && t('bigconsole.widget.drilldown.mode.newTab', 'New Tab')}\n {mode === 'SAME_WINDOW' && t('bigconsole.widget.drilldown.mode.sameWindow', 'Same Window')}\n </button>\n ))}\n </div>\n <p className=\"mt-1 text-xs text-text-muted\">\n {navigationMode === 'MODAL' &&\n t('bigconsole.widget.drilldown.modeHelp.modal', 'Opens the target in a modal overlay')}\n {navigationMode === 'NEW_TAB' &&\n t('bigconsole.widget.drilldown.modeHelp.newTab', 'Opens the target in a new browser tab')}\n {navigationMode === 'SAME_WINDOW' &&\n t(\n 'bigconsole.widget.drilldown.modeHelp.sameWindow',\n 'Navigates to the target in the current window; Back returns here'\n )}\n </p>\n </div>\n\n {/* Parameter Mappings */}\n <div>\n <div className=\"mb-2 flex flex-wrap items-center justify-between gap-2\">\n <p className=\"text-sm font-medium text-text-primary\">\n {t('bigconsole.widget.drilldown.parameterMappingsLabel', 'Parameter Mappings')}\n </p>\n <button\n type=\"button\"\n onClick={addParameterMapping}\n className={`rounded-button px-1 text-xs text-text-link hover:underline ${SECTION_FOCUS_RING}`}\n >\n {t('bigconsole.widget.drilldown.addParameter', '+ 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 min-w-0 flex-wrap items-center gap-2\">\n <input\n type=\"text\"\n value={mapping.key}\n onChange={(e) => updateParameterMapping(index, 'key', e.target.value)}\n placeholder={t('bigconsole.widget.drilldown.parameterNamePlaceholder', 'Parameter name')}\n aria-label={`Parameter ${index + 1} name`}\n className={`${RAW_CONTROL_CLASSES} min-w-[7rem] flex-1`}\n />\n <span aria-hidden=\"true\" className=\"text-text-muted\">\n =\n </span>\n <div className=\"relative min-w-[7rem] flex-1\">\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={t(\n 'bigconsole.widget.drilldown.parameterValuePlaceholder',\n '{{row.field}} or static'\n )}\n aria-label={`Parameter ${index + 1} value`}\n className={RAW_CONTROL_CLASSES}\n />\n {/* Field suggestions dropdown */}\n {showFieldSuggestions === index && availableFields.length > 0 && (\n <div className=\"absolute left-0 right-0 top-full z-10 mt-1 max-h-40 overflow-y-auto rounded-input border border-[var(--color-border-subtle)] bg-bg-surface shadow-[var(--shadow-elevation-2)]\">\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 font-mono text-xs text-text-primary hover:bg-bg-sunken ${SECTION_FOCUS_RING}`}\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 aria-label={`Remove parameter ${index + 1}`}\n className={`rounded-button p-1 text-text-muted hover:text-[var(--color-status-error-text)] ${SECTION_FOCUS_RING}`}\n >\n <svg className=\"h-icon-sm w-icon-sm\" 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=\"mt-2 text-xs text-text-muted\">\n {t('bigconsole.widget.drilldown.paramHelp.usePrefix', 'Use')}{' '}\n <code className=\"px-1 bg-bg-sunken rounded\">{'{{row.field}}'}</code>{' '}\n {t('bigconsole.widget.drilldown.paramHelp.useSuffix', 'for dynamic values or enter static text.')}\n <br />\n {t('bigconsole.widget.drilldown.paramHelp.examples', 'Examples:')}{' '}\n <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 — a nested block, so it steps down to `muted` */}\n <Section\n emphasis=\"muted\"\n padding=\"compact\"\n headingLevel={4}\n title={t('bigconsole.widget.drilldown.advancedOptions', 'Advanced Options')}\n description={t(\n 'bigconsole.widget.drilldown.advancedOptionsHelp',\n 'Rarely changed. Defaults suit most drilldowns.'\n )}\n data-testid=\"drilldown-advanced\"\n >\n <div className=\"flex flex-col gap-2\">\n {/* Pass Global Filters */}\n <div className=\"flex min-w-0 flex-wrap items-center justify-between gap-2 rounded-button bg-bg-surface p-2\">\n <div className=\"min-w-0\">\n <label htmlFor=\"drilldown-pass-filters\" className=\"text-sm text-text-primary\">\n {t('bigconsole.widget.drilldown.passGlobalFiltersLabel', 'Pass Global Filters')}\n </label>\n <p className=\"text-xs text-text-muted\">\n {t(\n 'bigconsole.widget.drilldown.passGlobalFiltersHelp',\n 'Include current dashboard filters in drilldown'\n )}\n </p>\n </div>\n <button\n id=\"drilldown-pass-filters\"\n type=\"button\"\n role=\"switch\"\n aria-checked={passGlobalFilters}\n onClick={() => setPassGlobalFilters(!passGlobalFilters)}\n className={`relative inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border motion-safe:transition-colors ${SECTION_FOCUS_RING} ${\n passGlobalFilters ? SWITCH_TRACK_ON : SWITCH_TRACK_OFF\n }`}\n >\n <span\n className={`inline-block h-3 w-3 transform rounded-full motion-safe:transition-transform ${SWITCH_KNOB} ${\n passGlobalFilters ? 'translate-x-5' : 'translate-x-1'\n }`}\n />\n </button>\n </div>\n\n {/* Max Depth */}\n <div className=\"flex min-w-0 flex-wrap items-center justify-between gap-2 rounded-button bg-bg-surface p-2\">\n <div className=\"min-w-0\">\n <label htmlFor=\"drilldown-max-depth\" className=\"text-sm text-text-primary\">\n {t('bigconsole.widget.drilldown.maxDepthLabel', 'Max Drilldown Depth')}\n </label>\n <p className=\"text-xs text-text-muted\">\n {t('bigconsole.widget.drilldown.maxDepthHelp', 'Limit nested drilldown levels')}\n </p>\n </div>\n <select\n id=\"drilldown-max-depth\"\n value={maxDepth}\n onChange={(e) => setMaxDepth(Number(e.target.value))}\n className={`${RAW_CONTROL_CHROME} w-auto min-w-[4rem] shrink-0 px-2`}\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 </div>\n </Section>\n </>\n )}\n\n {/* Info when drilldown will be removed */}\n {!enabled && widget.drilldown?.id && (\n <Section\n tone=\"warning\"\n padding=\"compact\"\n headingLevel={4}\n title={t('bigconsole.widget.drilldown.removalTitle', 'Drilldown will be removed')}\n data-testid=\"drilldown-removal-notice\"\n >\n <p className=\"text-xs text-text-secondary\">\n {t('bigconsole.widget.drilldown.removalWarning', 'Drilldown will be removed when you save changes.')}\n </p>\n </Section>\n )}\n </div>\n );\n});\n\nexport default DrilldownConfigPanel;\n"],"mappings":"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"}
|
|
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 the target (a page of this dashboard, or another dashboard\n * and optionally one of its pages), navigation mode, and parameter mappings.\n *\n * Features:\n * - Target page (BOFF-7625): same-dashboard drilldowns must pick another page;\n * other dashboards default to their first page\n * - Searchable dashboard picker; a saved target that was archived, deleted or\n * unshared is flagged as unavailable\n * - passGlobalFilters: Pass current dashboard filters to target\n * - maxDepth: Limit drilldown depth (default: 3)\n * - Field suggestions based on widget data\n */\n\nimport { type FC, memo, useState, useEffect, useCallback, useMemo } from 'react';\nimport { useApolloClient, useQuery } from '@apollo/client/react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport type { Widget, NavigationMode } from '../../types';\nimport {\n GetDrilldownTargetDashboardDocument,\n GetWidgetDrilldownTargetDocument,\n ListDashboardsDocument,\n type GetDrilldownTargetDashboardQuery,\n type GetDrilldownTargetDashboardQueryVariables,\n type GetWidgetDrilldownTargetQuery,\n type GetWidgetDrilldownTargetQueryVariables,\n type ListDashboardsQuery,\n type ListDashboardsQueryVariables,\n} from '../../../generated/wspace-operations';\nimport { DEFAULT_MAX_DEPTH } from '../../hooks/useDrilldown';\nimport { Section, SECTION_FOCUS_RING } from '../common';\n\n/**\n * Shared recipes for the raw controls in this panel. The panel predates the\n * fe-libs form primitives and previously used literal Tailwind palette colours\n * (`bg-gray-300`, `bg-white`, `text-white`, `bg-amber-100`), which ignore the\n * theme entirely — a white switch knob on a light track is invisible in dark\n * mode. Everything below resolves through semantic tokens (BOFF-5636).\n */\n/**\n * Chrome only — no width or horizontal padding. Those are per-call-site, because\n * appending `w-auto`/`px-2` to a recipe that already carries `w-full`/`px-3`\n * leaves the winner to Tailwind's internal utility ordering rather than to the\n * author.\n */\nconst RAW_CONTROL_CHROME =\n 'min-h-control-md rounded-input border border-[var(--color-border-subtle)] bg-bg-surface py-2 text-sm text-text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-bg-surface';\n\n/** Full-bleed form control: the common case in this panel. */\nconst RAW_CONTROL_CLASSES = `${RAW_CONTROL_CHROME} w-full px-3`;\n\nconst SWITCH_TRACK_ON = 'bg-action-primary-bg border-action-primary-bg';\nconst SWITCH_TRACK_OFF = 'bg-bg-sunken border-[var(--color-border-strong)]';\nconst SWITCH_KNOB = 'bg-bg-surface shadow-[var(--shadow-elevation-1)]';\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 /** Page of the target dashboard; null opens its first page (BOFF-7625) */\n targetPageId: string | null;\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}\n\ninterface DashboardOption {\n id: string;\n name: string;\n}\n\ninterface PageOption {\n id: string;\n name: string;\n order: number;\n}\n\n/** Page size for the searchable dashboard picker. */\nconst DASHBOARD_PICKER_PAGE_SIZE = 50;\n/** Debounce for the dashboard picker search box. */\nconst DASHBOARD_SEARCH_DEBOUNCE_MS = 250;\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 { t } = useI18n();\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 [targetPageId, setTargetPageId] = useState<string | null>(widget.drilldown?.targetPageId ?? null);\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 [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 [dashboardsError, setDashboardsError] = useState(false);\n const [dashboardSearch, setDashboardSearch] = useState('');\n const [showFieldSuggestions, setShowFieldSuggestions] = useState<number | null>(null);\n\n const currentDashboardId = widget.dashboardId ?? '';\n const isSameDashboard = !!targetDashboardId && targetDashboardId === currentDashboardId;\n\n // Saved target as the server resolves it: null means archived, deleted or no\n // longer readable by this user (BOFF-7625).\n const savedDrilldownId = widget.drilldown?.id;\n const { data: savedTargetData } = useQuery<GetWidgetDrilldownTargetQuery, GetWidgetDrilldownTargetQueryVariables>(\n GetWidgetDrilldownTargetDocument,\n {\n variables: { widgetId: widget.id },\n skip: !savedDrilldownId,\n fetchPolicy: 'cache-and-network',\n }\n );\n const savedTarget = savedTargetData?.getWidget?.drilldown;\n const savedTargetUnavailable =\n !!savedDrilldownId &&\n !!savedTargetData &&\n !savedTarget?.targetDashboard &&\n targetDashboardId === (widget.drilldown?.targetDashboardId ?? '');\n\n // Pages of the selected target, for the page picker.\n const { data: targetPagesData, loading: targetPagesLoading } = useQuery<\n GetDrilldownTargetDashboardQuery,\n GetDrilldownTargetDashboardQueryVariables\n >(GetDrilldownTargetDashboardDocument, {\n variables: { id: targetDashboardId },\n skip: !targetDashboardId,\n fetchPolicy: 'cache-first',\n });\n const targetPages = useMemo<PageOption[]>(() => {\n const edges = targetPagesData?.getDashboard?.pages?.edges ?? [];\n return edges\n .map((edge) => edge?.node)\n .filter((node): node is NonNullable<typeof node> => !!node)\n .map((node) => ({ id: node.id, name: node.name ?? '', order: node.order ?? 0 }))\n .sort((a, b) => a.order - b.order);\n }, [targetPagesData]);\n // A same-dashboard drilldown to the widget's own page would be a no-op.\n const selectablePages = useMemo(\n () => (isSameDashboard ? targetPages.filter((page) => page.id !== widget.pageId) : targetPages),\n [isSameDashboard, targetPages, widget.pageId]\n );\n const samePageMissing = enabled && isSameDashboard && !targetPageId;\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 targetPageId,\n navigationMode,\n parameterMapping,\n passGlobalFilters,\n maxDepth,\n });\n }, [\n enabled,\n targetDashboardId,\n targetPageId,\n navigationMode,\n parameterMappings,\n passGlobalFilters,\n maxDepth,\n onChange,\n ]);\n\n // Call notifyChange when any value changes\n useEffect(() => {\n notifyChange();\n }, [\n enabled,\n targetDashboardId,\n targetPageId,\n navigationMode,\n parameterMappings,\n passGlobalFilters,\n maxDepth,\n notifyChange,\n ]);\n\n // Fetch dashboards for the picker. `listDashboards` only returns dashboards\n // the caller can read, so an inaccessible dashboard can never be picked.\n useEffect(() => {\n let cancelled = false;\n const timer = setTimeout(async () => {\n setLoading(true);\n setDashboardsError(false);\n try {\n const search = dashboardSearch.trim();\n const result = await apolloClient.query<ListDashboardsQuery, ListDashboardsQueryVariables>({\n query: ListDashboardsDocument,\n variables: {\n first: DASHBOARD_PICKER_PAGE_SIZE,\n ...(search ? { search } : {}),\n },\n fetchPolicy: 'cache-first',\n });\n if (cancelled) return;\n const edges = result.data?.listDashboards?.edges ?? [];\n setDashboards(\n edges\n .map((edge) => edge?.node)\n .filter((node): node is NonNullable<typeof node> => !!node)\n .map((node) => ({ id: node.id, name: node.name }))\n );\n } catch {\n if (!cancelled) setDashboardsError(true);\n } finally {\n if (!cancelled) setLoading(false);\n }\n }, DASHBOARD_SEARCH_DEBOUNCE_MS);\n\n return () => {\n cancelled = true;\n clearTimeout(timer);\n };\n }, [apolloClient, dashboardSearch]);\n\n // Options for the dashboard select: this dashboard first, then the others,\n // plus the saved target when the current search does not include it.\n const dashboardOptions = useMemo<DashboardOption[]>(() => {\n const others = dashboards.filter((d) => d.id !== currentDashboardId);\n if (\n targetDashboardId &&\n targetDashboardId !== currentDashboardId &&\n !others.some((d) => d.id === targetDashboardId)\n ) {\n const savedName =\n savedTarget?.targetDashboard?.id === targetDashboardId ? savedTarget.targetDashboard.name : undefined;\n others.unshift({\n id: targetDashboardId,\n name: savedName ?? t('bigconsole.widget.drilldown.unavailableDashboard', 'Unavailable dashboard'),\n });\n }\n return others;\n }, [dashboards, currentDashboardId, targetDashboardId, savedTarget, t]);\n\n const handleTargetDashboardChange = useCallback((nextDashboardId: string) => {\n setTargetDashboardId(nextDashboardId);\n // A page belongs to exactly one dashboard.\n setTargetPageId(null);\n }, []);\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=\"min-w-0 space-y-form-gap\">\n {/* Enable Toggle */}\n <div className=\"flex min-w-0 flex-wrap items-center justify-between gap-2 rounded-card border border-[var(--color-border-subtle)] bg-bg-surface p-3\">\n <label htmlFor=\"drilldown-enable\" className=\"text-sm font-medium text-text-primary\">\n {t('bigconsole.widget.drilldown.enableLabel', 'Enable Drilldown')}\n </label>\n <button\n id=\"drilldown-enable\"\n type=\"button\"\n role=\"switch\"\n aria-checked={enabled}\n onClick={() => setEnabled(!enabled)}\n className={`relative inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border motion-safe:transition-colors ${SECTION_FOCUS_RING} ${\n enabled ? SWITCH_TRACK_ON : SWITCH_TRACK_OFF\n }`}\n >\n <span\n className={`inline-block h-4 w-4 transform rounded-full motion-safe:transition-transform ${SWITCH_KNOB} ${\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 htmlFor=\"drilldown-target\" className=\"mb-1 block text-sm font-medium text-text-primary\">\n {t('bigconsole.widget.drilldown.targetDashboardLabel', 'Target Dashboard')}\n </label>\n <input\n type=\"search\"\n value={dashboardSearch}\n onChange={(e) => setDashboardSearch(e.target.value)}\n placeholder={t('bigconsole.widget.drilldown.searchDashboards', 'Search dashboards...')}\n aria-label={t('bigconsole.widget.drilldown.searchDashboards', 'Search dashboards...')}\n className={`${RAW_CONTROL_CLASSES} mb-2`}\n data-testid=\"drilldown-dashboard-search\"\n />\n <select\n id=\"drilldown-target\"\n value={targetDashboardId}\n onChange={(e) => handleTargetDashboardChange(e.target.value)}\n className={RAW_CONTROL_CLASSES}\n data-testid=\"drilldown-target-dashboard\"\n >\n <option value=\"\">{t('bigconsole.widget.drilldown.selectDashboard', 'Select a dashboard...')}</option>\n {currentDashboardId && (\n <option value={currentDashboardId}>\n {t('bigconsole.widget.drilldown.thisDashboard', 'This dashboard (another page)')}\n </option>\n )}\n {dashboardOptions.map((dashboard) => (\n <option key={dashboard.id} value={dashboard.id}>\n {dashboard.name}\n </option>\n ))}\n </select>\n {loading && (\n <p className=\"mt-1 text-xs text-text-muted\" role=\"status\">\n {t('bigconsole.widget.drilldown.loadingDashboards', 'Loading dashboards...')}\n </p>\n )}\n {dashboardsError && (\n <p className=\"mt-1 text-xs text-[var(--color-status-error-text)]\" role=\"alert\">\n {t('bigconsole.widget.drilldown.dashboardsLoadError', 'Could not load dashboards. Try again.')}\n </p>\n )}\n </div>\n\n {/* Target Page */}\n {targetDashboardId && (\n <div>\n <label htmlFor=\"drilldown-target-page\" className=\"mb-1 block text-sm font-medium text-text-primary\">\n {t('bigconsole.widget.drilldown.targetPageLabel', 'Target Page')}\n </label>\n <select\n id=\"drilldown-target-page\"\n value={targetPageId ?? ''}\n onChange={(e) => setTargetPageId(e.target.value || null)}\n disabled={targetPagesLoading}\n aria-invalid={samePageMissing}\n className={RAW_CONTROL_CLASSES}\n data-testid=\"drilldown-target-page\"\n >\n <option value=\"\">\n {isSameDashboard\n ? t('bigconsole.widget.drilldown.selectPage', 'Select a page...')\n : t('bigconsole.widget.drilldown.firstPage', 'First page (default)')}\n </option>\n {selectablePages.map((page, index) => (\n <option key={page.id} value={page.id}>\n {page.name || t('bigconsole.dashboards.view.pageName', 'Page {{count}}', { count: index + 1 })}\n </option>\n ))}\n </select>\n {samePageMissing && (\n <p className=\"mt-1 text-xs text-[var(--color-status-error-text)]\" role=\"alert\">\n {selectablePages.length === 0 && !targetPagesLoading\n ? t(\n 'bigconsole.widget.drilldown.noOtherPages',\n 'This dashboard has no other page. Add a page, or pick another dashboard.'\n )\n : t('bigconsole.widget.drilldown.samePageRequired', 'Pick the page of this dashboard to open.')}\n </p>\n )}\n </div>\n )}\n\n {savedTargetUnavailable && (\n <Section\n tone=\"warning\"\n padding=\"compact\"\n headingLevel={4}\n title={t('bigconsole.widget.drilldown.unavailableTitle', 'Target unavailable')}\n data-testid=\"drilldown-target-unavailable\"\n >\n <p className=\"text-xs text-text-secondary\">\n {t(\n 'bigconsole.widget.drilldown.unavailableHelp',\n 'The target dashboard was deleted, archived, or is no longer shared with you. Viewers see a notice instead of navigating. Pick another target.'\n )}\n </p>\n </Section>\n )}\n\n {/* Navigation Mode */}\n <div>\n <p className=\"mb-1 text-sm font-medium text-text-primary\" id=\"drilldown-nav-mode-label\">\n {t('bigconsole.widget.drilldown.navigationModeLabel', 'Navigation Mode')}\n </p>\n <div className=\"flex flex-wrap gap-2\" role=\"group\" aria-labelledby=\"drilldown-nav-mode-label\">\n {(['MODAL', 'NEW_TAB', 'SAME_WINDOW'] as NavigationMode[]).map((mode) => (\n <button\n key={mode}\n type=\"button\"\n aria-pressed={navigationMode === mode}\n onClick={() => setNavigationMode(mode)}\n className={`min-h-control-md min-w-[7rem] flex-1 rounded-button px-3 text-sm font-medium motion-safe:transition-colors ${SECTION_FOCUS_RING} ${\n navigationMode === mode\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'bg-bg-sunken text-text-secondary hover:text-text-primary'\n }`}\n >\n {mode === 'MODAL' && t('bigconsole.widget.drilldown.mode.modal', 'Modal')}\n {mode === 'NEW_TAB' && t('bigconsole.widget.drilldown.mode.newTab', 'New Tab')}\n {mode === 'SAME_WINDOW' && t('bigconsole.widget.drilldown.mode.sameWindow', 'Same Window')}\n </button>\n ))}\n </div>\n <p className=\"mt-1 text-xs text-text-muted\">\n {navigationMode === 'MODAL' &&\n t('bigconsole.widget.drilldown.modeHelp.modal', 'Opens the target in a modal overlay')}\n {navigationMode === 'NEW_TAB' &&\n t('bigconsole.widget.drilldown.modeHelp.newTab', 'Opens the target in a new browser tab')}\n {navigationMode === 'SAME_WINDOW' &&\n t(\n 'bigconsole.widget.drilldown.modeHelp.sameWindow',\n 'Navigates to the target in the current window; Back returns here'\n )}\n </p>\n </div>\n\n {/* Parameter Mappings */}\n <div>\n <div className=\"mb-2 flex flex-wrap items-center justify-between gap-2\">\n <p className=\"text-sm font-medium text-text-primary\">\n {t('bigconsole.widget.drilldown.parameterMappingsLabel', 'Parameter Mappings')}\n </p>\n <button\n type=\"button\"\n onClick={addParameterMapping}\n className={`rounded-button px-1 text-xs text-text-link hover:underline ${SECTION_FOCUS_RING}`}\n >\n {t('bigconsole.widget.drilldown.addParameter', '+ 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 min-w-0 flex-wrap items-center gap-2\">\n <input\n type=\"text\"\n value={mapping.key}\n onChange={(e) => updateParameterMapping(index, 'key', e.target.value)}\n placeholder={t('bigconsole.widget.drilldown.parameterNamePlaceholder', 'Parameter name')}\n aria-label={`Parameter ${index + 1} name`}\n className={`${RAW_CONTROL_CLASSES} min-w-[7rem] flex-1`}\n />\n <span aria-hidden=\"true\" className=\"text-text-muted\">\n =\n </span>\n <div className=\"relative min-w-[7rem] flex-1\">\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={t(\n 'bigconsole.widget.drilldown.parameterValuePlaceholder',\n '{{row.field}} or static'\n )}\n aria-label={`Parameter ${index + 1} value`}\n className={RAW_CONTROL_CLASSES}\n />\n {/* Field suggestions dropdown */}\n {showFieldSuggestions === index && availableFields.length > 0 && (\n <div className=\"absolute left-0 right-0 top-full z-10 mt-1 max-h-40 overflow-y-auto rounded-input border border-[var(--color-border-subtle)] bg-bg-surface shadow-[var(--shadow-elevation-2)]\">\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 font-mono text-xs text-text-primary hover:bg-bg-sunken ${SECTION_FOCUS_RING}`}\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 aria-label={`Remove parameter ${index + 1}`}\n className={`rounded-button p-1 text-text-muted hover:text-[var(--color-status-error-text)] ${SECTION_FOCUS_RING}`}\n >\n <svg className=\"h-icon-sm w-icon-sm\" 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=\"mt-2 text-xs text-text-muted\">\n {t('bigconsole.widget.drilldown.paramHelp.usePrefix', 'Use')}{' '}\n <code className=\"px-1 bg-bg-sunken rounded\">{'{{row.field}}'}</code>{' '}\n {t('bigconsole.widget.drilldown.paramHelp.useSuffix', 'for dynamic values or enter static text.')}\n <br />\n {t('bigconsole.widget.drilldown.paramHelp.examples', 'Examples:')}{' '}\n <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 — a nested block, so it steps down to `muted` */}\n <Section\n emphasis=\"muted\"\n padding=\"compact\"\n headingLevel={4}\n title={t('bigconsole.widget.drilldown.advancedOptions', 'Advanced Options')}\n description={t(\n 'bigconsole.widget.drilldown.advancedOptionsHelp',\n 'Rarely changed. Defaults suit most drilldowns.'\n )}\n data-testid=\"drilldown-advanced\"\n >\n <div className=\"flex flex-col gap-2\">\n {/* Pass Global Filters */}\n <div className=\"flex min-w-0 flex-wrap items-center justify-between gap-2 rounded-button bg-bg-surface p-2\">\n <div className=\"min-w-0\">\n <label htmlFor=\"drilldown-pass-filters\" className=\"text-sm text-text-primary\">\n {t('bigconsole.widget.drilldown.passGlobalFiltersLabel', 'Pass Global Filters')}\n </label>\n <p className=\"text-xs text-text-muted\">\n {t(\n 'bigconsole.widget.drilldown.passGlobalFiltersHelp',\n 'Include current dashboard filters in drilldown'\n )}\n </p>\n </div>\n <button\n id=\"drilldown-pass-filters\"\n type=\"button\"\n role=\"switch\"\n aria-checked={passGlobalFilters}\n onClick={() => setPassGlobalFilters(!passGlobalFilters)}\n className={`relative inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border motion-safe:transition-colors ${SECTION_FOCUS_RING} ${\n passGlobalFilters ? SWITCH_TRACK_ON : SWITCH_TRACK_OFF\n }`}\n >\n <span\n className={`inline-block h-3 w-3 transform rounded-full motion-safe:transition-transform ${SWITCH_KNOB} ${\n passGlobalFilters ? 'translate-x-5' : 'translate-x-1'\n }`}\n />\n </button>\n </div>\n\n {/* Max Depth */}\n <div className=\"flex min-w-0 flex-wrap items-center justify-between gap-2 rounded-button bg-bg-surface p-2\">\n <div className=\"min-w-0\">\n <label htmlFor=\"drilldown-max-depth\" className=\"text-sm text-text-primary\">\n {t('bigconsole.widget.drilldown.maxDepthLabel', 'Max Drilldown Depth')}\n </label>\n <p className=\"text-xs text-text-muted\">\n {t('bigconsole.widget.drilldown.maxDepthHelp', 'Limit nested drilldown levels')}\n </p>\n </div>\n <select\n id=\"drilldown-max-depth\"\n value={maxDepth}\n onChange={(e) => setMaxDepth(Number(e.target.value))}\n className={`${RAW_CONTROL_CHROME} w-auto min-w-[4rem] shrink-0 px-2`}\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 </div>\n </Section>\n </>\n )}\n\n {/* Info when drilldown will be removed */}\n {!enabled && widget.drilldown?.id && (\n <Section\n tone=\"warning\"\n padding=\"compact\"\n headingLevel={4}\n title={t('bigconsole.widget.drilldown.removalTitle', 'Drilldown will be removed')}\n data-testid=\"drilldown-removal-notice\"\n >\n <p className=\"text-xs text-text-secondary\">\n {t('bigconsole.widget.drilldown.removalWarning', 'Drilldown will be removed when you save changes.')}\n </p>\n </Section>\n )}\n </div>\n );\n});\n\nexport default DrilldownConfigPanel;\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PropertiesPanel.d.ts","sourceRoot":"","sources":["../../../../src/bigconsole/components/widgets/PropertiesPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAc,EAAE,KAAK,EAAE,EAA2D,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"PropertiesPanel.d.ts","sourceRoot":"","sources":["../../../../src/bigconsole/components/widgets/PropertiesPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAc,EAAE,KAAK,EAAE,EAA2D,MAAM,OAAO,CAAC;AAoJhG,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAqWD,eAAO,MAAM,eAAe,EAAE,EAAE,CAAC,oBAAoB,CAglDnD,CAAC;AAEH,eAAe,eAAe,CAAC"}
|