@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.
Files changed (131) hide show
  1. package/dist/bigconsole/BigConsoleRoutes.d.ts.map +1 -1
  2. package/dist/bigconsole/BigConsoleRoutes.js +136 -127
  3. package/dist/bigconsole/BigConsoleRoutes.js.map +1 -1
  4. package/dist/bigconsole/assistant/assistantProduct.d.ts.map +1 -1
  5. package/dist/bigconsole/assistant/assistantProduct.js +3 -1
  6. package/dist/bigconsole/assistant/assistantProduct.js.map +1 -1
  7. package/dist/bigconsole/components/builder/inspector/DataBindingSection.js +31 -31
  8. package/dist/bigconsole/components/dashboard/CreateDashboardDialog.js +44 -44
  9. package/dist/bigconsole/components/dashboard/CreateDashboardDialog.js.map +1 -1
  10. package/dist/bigconsole/components/dashboard/DashboardCanvas.js +36 -36
  11. package/dist/bigconsole/components/dashboard/DashboardCanvas.js.map +1 -1
  12. package/dist/bigconsole/components/dashboard/DashboardToolbar.js +59 -59
  13. package/dist/bigconsole/components/dashboard/DrilldownBreadcrumb.js +15 -15
  14. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterChip.js +30 -30
  15. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.js +41 -41
  16. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterPresetSelector.js +34 -34
  17. package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.js +34 -34
  18. package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js +110 -110
  19. package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js.map +1 -1
  20. package/dist/bigconsole/components/dashboard/PublishToStoreDialog.js +21 -21
  21. package/dist/bigconsole/components/dashboard/SavedViewsDropdown/SavedViewsDropdown.js +46 -46
  22. package/dist/bigconsole/components/dashboard/ShareDialog/EmbedTab.js +91 -91
  23. package/dist/bigconsole/components/dashboard/ShareDialog/EmbedTab.js.map +1 -1
  24. package/dist/bigconsole/components/dashboard/ShareDialog/ShareDialog.js +101 -101
  25. package/dist/bigconsole/components/dashboard/ShareDialog/ShareDialog.js.map +1 -1
  26. package/dist/bigconsole/components/dashboard/TemplateInstallOptions.js +31 -31
  27. package/dist/bigconsole/components/dashboard/TemplateLayoutPreview.js +15 -15
  28. package/dist/bigconsole/components/dashboard/TemplatePicker/TemplatePicker.js +1 -1
  29. package/dist/bigconsole/components/dashboard/WidgetPalette.js +46 -46
  30. package/dist/bigconsole/components/datasink/AlertExecutionHistory.js +37 -37
  31. package/dist/bigconsole/components/datasink/AlertRuleEditor.js +66 -66
  32. package/dist/bigconsole/components/datasink/CacheTTLSelector.js +35 -35
  33. package/dist/bigconsole/components/datasink/DataSinkCard.js +29 -29
  34. package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js +18 -18
  35. package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js +20 -20
  36. package/dist/bigconsole/components/datasink/ImportDataGuideDialog.js +47 -47
  37. package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js +91 -91
  38. package/dist/bigconsole/components/datasink/RefreshTypeSelector.js +35 -35
  39. package/dist/bigconsole/components/parser/DataSinkSelector.js +40 -40
  40. package/dist/bigconsole/components/parser/ImportParserDialog.js +120 -120
  41. package/dist/bigconsole/components/parser/ImportParserDialog.js.map +1 -1
  42. package/dist/bigconsole/components/parser/ParserSelector.js +51 -51
  43. package/dist/bigconsole/components/pipeline/PipelineScopePicker.js +10 -10
  44. package/dist/bigconsole/components/preview/AiPreviewMiniPanel.js +27 -27
  45. package/dist/bigconsole/components/preview/AiPreviewPanel.js +30 -30
  46. package/dist/bigconsole/components/widgets/ActionConfigDialog.js +4 -4
  47. package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js +93 -93
  48. package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js.map +1 -1
  49. package/dist/bigconsole/components/widgets/PropertiesPanel.d.ts.map +1 -1
  50. package/dist/bigconsole/components/widgets/PropertiesPanel.js +280 -273
  51. package/dist/bigconsole/components/widgets/PropertiesPanel.js.map +1 -1
  52. package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js +4 -4
  53. package/dist/bigconsole/components/widgets/chart/ChartConfig.js +48 -48
  54. package/dist/bigconsole/components/widgets/comments/WidgetComments.js +46 -46
  55. package/dist/bigconsole/components/widgets/event-logs/EventLogViewer.js +61 -61
  56. package/dist/bigconsole/components/widgets/form/FormWidget.js +36 -36
  57. package/dist/bigconsole/components/widgets/gauge/GaugeConfig.js +42 -42
  58. package/dist/bigconsole/components/widgets/heatmap/HeatmapConfig.js +25 -25
  59. package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js +4 -4
  60. package/dist/bigconsole/components/widgets/list/ListConfig.js +30 -30
  61. package/dist/bigconsole/components/widgets/metric-card/MetricCardConfig.js +38 -38
  62. package/dist/bigconsole/components/widgets/metric-card/SparklineChart.js +9 -9
  63. package/dist/bigconsole/components/widgets/metric-card/TrendIndicator.js +9 -9
  64. package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js +49 -49
  65. package/dist/bigconsole/components/widgets/progress/ProgressConfig.js +39 -39
  66. package/dist/bigconsole/components/widgets/table/TableConfig.js +73 -73
  67. package/dist/bigconsole/components/widgets/webhook-config/WebhookConfigPanel.js +64 -64
  68. package/dist/bigconsole/components/workflow/WorkflowOpenGuard.js +15 -15
  69. package/dist/bigconsole/components/workflow/WorkflowSinkLinkForm.js +15 -15
  70. package/dist/bigconsole/customWidget/CustomWidgetBuilderSheet.js +9 -9
  71. package/dist/bigconsole/customWidget/CustomWidgetProposalPanel.js +67 -67
  72. package/dist/bigconsole/customWidget/CustomWidgetProposalPanel.js.map +1 -1
  73. package/dist/bigconsole/hooks/useDashboardLayoutBaseline.d.ts +15 -0
  74. package/dist/bigconsole/hooks/useDashboardLayoutBaseline.d.ts.map +1 -0
  75. package/dist/bigconsole/hooks/useDashboardLayoutBaseline.js +34 -0
  76. package/dist/bigconsole/hooks/useDashboardLayoutBaseline.js.map +1 -0
  77. package/dist/bigconsole/hooks/useDrilldown.js +3 -3
  78. package/dist/bigconsole/hooks/useGlobalFilters.js +3 -3
  79. package/dist/bigconsole/pages/AdminPage.js +130 -130
  80. package/dist/bigconsole/pages/DashboardBuilderPage.d.ts.map +1 -1
  81. package/dist/bigconsole/pages/DashboardBuilderPage.js +72 -60
  82. package/dist/bigconsole/pages/DashboardBuilderPage.js.map +1 -1
  83. package/dist/bigconsole/pages/DashboardViewPage.js +1 -1
  84. package/dist/bigconsole/pages/DataSinkAlertsPage.d.ts.map +1 -1
  85. package/dist/bigconsole/pages/DataSinkAlertsPage.js +30 -23
  86. package/dist/bigconsole/pages/DataSinkAlertsPage.js.map +1 -1
  87. package/dist/bigconsole/pages/DataSinkBuilderPage.d.ts.map +1 -1
  88. package/dist/bigconsole/pages/DataSinkBuilderPage.js +272 -263
  89. package/dist/bigconsole/pages/DataSinkBuilderPage.js.map +1 -1
  90. package/dist/bigconsole/pages/DataSinkViewPage.js +1 -1
  91. package/dist/bigconsole/pages/DataSinksPage.js +1 -1
  92. package/dist/bigconsole/pages/DataSourcesPage.js +5 -5
  93. package/dist/bigconsole/pages/InsightsPage.js +181 -181
  94. package/dist/bigconsole/pages/InsightsPage.js.map +1 -1
  95. package/dist/bigconsole/pages/OverviewPage.js +47 -47
  96. package/dist/bigconsole/pages/OverviewPage.js.map +1 -1
  97. package/dist/bigconsole/pages/ParserBuilderPage.d.ts.map +1 -1
  98. package/dist/bigconsole/pages/ParserBuilderPage.js +227 -211
  99. package/dist/bigconsole/pages/ParserBuilderPage.js.map +1 -1
  100. package/dist/bigconsole/pages/ParserViewPage.js +97 -97
  101. package/dist/bigconsole/pages/PipelineBuilderPage.d.ts.map +1 -1
  102. package/dist/bigconsole/pages/PipelineBuilderPage.js +256 -214
  103. package/dist/bigconsole/pages/PipelineBuilderPage.js.map +1 -1
  104. package/dist/bigconsole/pages/PipelineViewPage.js +146 -146
  105. package/dist/bigconsole/pages/PipelinesPage.js +88 -88
  106. package/dist/bigconsole/pages/PipelinesPage.js.map +1 -1
  107. package/dist/bigconsole/pages/SettingsPage.d.ts.map +1 -1
  108. package/dist/bigconsole/pages/SettingsPage.js +179 -173
  109. package/dist/bigconsole/pages/SettingsPage.js.map +1 -1
  110. package/dist/bigconsole/pages/WidgetDemoPage.js +42 -42
  111. package/dist/bigconsole/pages/WorkflowViewPage.js +1 -1
  112. package/dist/bigconsole/pages/WorkflowsPage.js +141 -141
  113. package/dist/bigconsole/pages/WorkflowsPage.js.map +1 -1
  114. package/dist/bigconsole/providers/BigConsoleQuotaProvider.js +12 -12
  115. package/dist/bigconsole/renderers/adapters/AdaptiveCardRenderer.js +34 -34
  116. package/dist/bigconsole/renderers/adapters/BlockKitRenderer.js +79 -79
  117. package/dist/bigconsole/renderers/adapters/CustomRenderer.js +46 -46
  118. package/dist/bigconsole/store/widgetStore.d.ts +12 -0
  119. package/dist/bigconsole/store/widgetStore.d.ts.map +1 -1
  120. package/dist/bigconsole/store/widgetStore.js +3 -1
  121. package/dist/bigconsole/store/widgetStore.js.map +1 -1
  122. package/dist/bigconsole/utils/formDirty.d.ts +83 -0
  123. package/dist/bigconsole/utils/formDirty.d.ts.map +1 -0
  124. package/dist/bigconsole/utils/formDirty.js +23 -0
  125. package/dist/bigconsole/utils/formDirty.js.map +1 -0
  126. package/dist/bigconsole/utils/layoutBaseline.d.ts +131 -0
  127. package/dist/bigconsole/utils/layoutBaseline.d.ts.map +1 -0
  128. package/dist/bigconsole/utils/layoutBaseline.js +98 -0
  129. package/dist/bigconsole/utils/layoutBaseline.js.map +1 -0
  130. package/dist/translations/en.d.ts.map +1 -1
  131. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"SettingsPage.js","names":[],"sources":["../../../src/bigconsole/pages/SettingsPage.tsx"],"sourcesContent":["/**\n * SettingsPage\n *\n * BigConsole workspace settings and preferences.\n * Settings are persisted to localStorage until a backend settings API is available.\n */\n\nimport { type FC, memo, useState, useCallback, useEffect } from 'react';\nimport { AuroraBackground, GradientText, PagePurpose, EmphasisPanel } from '@burdenoff/fe-libs/ui';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { Settings, Save, RotateCcw } from 'lucide-react';\n\nimport {\n type BigConsoleSettings,\n DEFAULT_SETTINGS,\n loadBigConsoleSettings,\n saveBigConsoleSettings,\n} from '../hooks/useBigConsoleSettings';\n\n// ============================================================================\n// COMPONENT\n// ============================================================================\n\nexport const SettingsPage: FC = memo(function SettingsPage() {\n const { t } = useI18n();\n const [settings, setSettings] = useState<BigConsoleSettings>(loadBigConsoleSettings);\n const [saved, setSaved] = useState(false);\n const [saveError, setSaveError] = useState(false);\n\n useEffect(() => {\n if (saved) {\n const timer = setTimeout(() => setSaved(false), 2000);\n return () => clearTimeout(timer);\n }\n }, [saved]);\n\n const handleChange = useCallback(<K extends keyof BigConsoleSettings>(key: K, value: BigConsoleSettings[K]) => {\n setSettings((prev) => ({ ...prev, [key]: value }));\n }, []);\n\n const handleSave = useCallback(() => {\n const success = saveBigConsoleSettings(settings);\n setSaved(success);\n setSaveError(!success);\n }, [settings]);\n\n const handleReset = useCallback(() => {\n setSettings({ ...DEFAULT_SETTINGS });\n const success = saveBigConsoleSettings(DEFAULT_SETTINGS);\n setSaved(success);\n setSaveError(!success);\n }, []);\n\n const inputStyle: React.CSSProperties = {\n width: '100%',\n padding: '8px 12px',\n borderRadius: 'var(--radius-button)',\n border: '1px solid var(--color-border)',\n backgroundColor: 'var(--color-bg-canvas)',\n color: 'var(--color-text-primary)',\n fontSize: 'var(--font-size-body-sm)',\n };\n\n const labelStyle: React.CSSProperties = {\n display: 'block',\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-medium)',\n color: 'var(--color-text-primary)',\n marginBottom: 4,\n };\n\n const descStyle: React.CSSProperties = {\n fontSize: 'var(--font-size-body-sm)',\n color: 'var(--color-text-muted)',\n marginTop: 4,\n };\n\n const sectionStyle: React.CSSProperties = {\n backgroundColor: 'var(--color-bg-surface)',\n border: '1px solid var(--color-border-seam)',\n borderRadius: 'var(--radius-card)',\n padding: 'var(--space-cardPadding)',\n marginBottom: 'var(--space-sectionGap)',\n boxShadow: 'var(--shadow-pop)',\n };\n\n return (\n <div style={{ minHeight: '100vh', backgroundColor: 'var(--color-bg-canvas)' }}>\n <div style={{ padding: 'var(--space-pagePadding)', maxWidth: 1440, margin: '0 auto' }}>\n {/* Header */}\n <div\n className=\"relative overflow-hidden rounded-card border border-border-seam bg-gloss-card p-6\"\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n marginBottom: 'var(--space-sectionGap)',\n flexWrap: 'wrap',\n gap: 'var(--space-formGap)',\n }}\n >\n <AuroraBackground intensity=\"subtle\" />\n <div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-iconGap)' }}>\n <Settings size={24} style={{ color: 'var(--color-text-primary)' }} />\n <h1\n style={{\n fontSize: 'var(--font-size-heading-h4)',\n fontWeight: 'var(--font-weight-bold)',\n color: 'var(--color-text-primary)',\n }}\n >\n <GradientText>{t('bigconsole.settings.header.title', 'Settings')}</GradientText>\n </h1>\n </div>\n <p style={{ fontSize: 'var(--font-size-body-md)', color: 'var(--color-text-secondary)', marginTop: 4 }}>\n {t('bigconsole.settings.header.subtitle', 'Configure BigConsole preferences')}\n </p>\n </div>\n <div style={{ display: 'flex', gap: 8 }}>\n <button\n onClick={handleReset}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n padding: '8px 12px',\n borderRadius: 'var(--radius-button)',\n border: '1px solid var(--color-border)',\n backgroundColor: 'transparent',\n color: 'var(--color-text-secondary)',\n fontSize: 'var(--font-size-body-sm)',\n cursor: 'pointer',\n }}\n >\n <RotateCcw size={14} /> {t('bigconsole.settings.actions.reset', 'Reset')}\n </button>\n <button\n onClick={handleSave}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n padding: '8px 16px',\n borderRadius: 'var(--radius-button)',\n backgroundColor: saved ? 'var(--color-status-success-bg)' : 'var(--color-action-primary-bg)',\n color: 'var(--color-action-primary-text)',\n fontWeight: 'var(--font-weight-medium)',\n fontSize: 'var(--font-size-body-sm)',\n border: 'none',\n cursor: 'pointer',\n transition: 'background-color 200ms',\n }}\n >\n <Save size={14} />{' '}\n {saved\n ? t('bigconsole.settings.actions.savedLocally', 'Saved locally')\n : t('bigconsole.settings.actions.saveLocally', 'Save locally')}\n </button>\n </div>\n </div>\n\n {saveError && (\n <p role=\"alert\" className=\"mb-form-gap text-status-error-text\">\n {t('bigconsole.settings.actions.saveError', 'Your browser could not save these preferences. Try again.')}\n </p>\n )}\n <PagePurpose className=\"mb-[var(--space-sectionGap)]\">\n {t(\n 'bigconsole.settings.localDefaultsPurpose',\n 'These browser-local defaults apply when you add dashboard pages, widgets and data sinks. Display preferences update existing widgets in this browser. They do not change existing page layouts, widget refresh schedules or data sink cache settings, and are not shared with your team.'\n )}\n </PagePurpose>\n\n {/* Dashboard Defaults — primary emphasis zone */}\n <EmphasisPanel className=\"mb-[var(--space-sectionGap)] p-[var(--space-cardPadding)]\">\n <h2\n style={{\n fontSize: 'var(--font-size-body-md)',\n fontWeight: 'var(--font-weight-semibold)',\n color: 'var(--color-text-primary)',\n marginBottom: 16,\n }}\n >\n {t('bigconsole.settings.dashboardDefaults.title', 'Dashboard Defaults')}\n </h2>\n <div className=\"grid gap-form-gap md:grid-cols-3\">\n <div>\n <label htmlFor=\"grid-cols\" style={labelStyle}>\n {t('bigconsole.settings.dashboardDefaults.gridColumns.label', 'Grid Columns')}\n </label>\n <input\n id=\"grid-cols\"\n type=\"number\"\n min={4}\n max={24}\n value={settings.defaultGridColumns}\n onChange={(e) =>\n handleChange('defaultGridColumns', Math.min(24, Math.max(4, Number(e.target.value) || 12)))\n }\n style={inputStyle}\n />\n <p style={descStyle}>\n {t(\n 'bigconsole.settings.dashboardDefaults.gridColumns.help',\n 'Number of columns in the dashboard grid (4-24)'\n )}\n </p>\n </div>\n <div>\n <label htmlFor=\"widget-height\" style={labelStyle}>\n {t('bigconsole.settings.dashboardDefaults.widgetHeight.label', 'Default Widget Height')}\n </label>\n <input\n id=\"widget-height\"\n type=\"number\"\n min={2}\n max={12}\n value={settings.defaultWidgetHeight}\n onChange={(e) =>\n handleChange('defaultWidgetHeight', Math.min(12, Math.max(1, Number(e.target.value) || 4)))\n }\n style={inputStyle}\n />\n <p style={descStyle}>\n {t(\n 'bigconsole.settings.dashboardDefaults.widgetHeight.help',\n 'Default height units for new widgets (2-12)'\n )}\n </p>\n </div>\n <div>\n <label htmlFor=\"refresh-interval\" style={labelStyle}>\n {t('bigconsole.settings.dashboardDefaults.refreshInterval.label', 'Auto-Refresh Interval (seconds)')}\n </label>\n <select\n id=\"refresh-interval\"\n value={settings.defaultRefreshInterval}\n onChange={(e) => handleChange('defaultRefreshInterval', parseInt(e.target.value))}\n style={inputStyle}\n >\n <option value={0}>\n {t('bigconsole.settings.dashboardDefaults.refreshInterval.disabled', 'Disabled')}\n </option>\n <option value={10}>\n {t('bigconsole.settings.dashboardDefaults.refreshInterval.seconds10', '10 seconds')}\n </option>\n <option value={30}>\n {t('bigconsole.settings.dashboardDefaults.refreshInterval.seconds30', '30 seconds')}\n </option>\n <option value={60}>\n {t('bigconsole.settings.dashboardDefaults.refreshInterval.minute1', '1 minute')}\n </option>\n <option value={300}>\n {t('bigconsole.settings.dashboardDefaults.refreshInterval.minutes5', '5 minutes')}\n </option>\n <option value={600}>\n {t('bigconsole.settings.dashboardDefaults.refreshInterval.minutes10', '10 minutes')}\n </option>\n </select>\n <p style={descStyle}>\n {t(\n 'bigconsole.settings.dashboardDefaults.refreshInterval.help',\n 'How often widgets refresh their data automatically'\n )}\n </p>\n </div>\n </div>\n </EmphasisPanel>\n\n {/* Cache Settings */}\n <div style={sectionStyle}>\n <h2\n style={{\n fontSize: 'var(--font-size-body-md)',\n fontWeight: 'var(--font-weight-semibold)',\n color: 'var(--color-text-primary)',\n marginBottom: 16,\n }}\n >\n {t('bigconsole.settings.cache.title', 'Cache')}\n </h2>\n <div className=\"grid gap-form-gap md:grid-cols-2\">\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>\n <div>\n <label style={labelStyle}>{t('bigconsole.settings.cache.enable.label', 'Enable Cache')}</label>\n <p style={descStyle}>\n {t('bigconsole.settings.cache.newSinkHelp', 'Enable caching by default for new data sinks')}\n </p>\n </div>\n <button\n onClick={() => handleChange('cacheEnabled', !settings.cacheEnabled)}\n role=\"switch\"\n aria-checked={settings.cacheEnabled}\n aria-label={t('bigconsole.settings.cache.enable.label', 'Enable Cache')}\n style={{\n width: 44,\n flexShrink: 0,\n height: 24,\n borderRadius: 12,\n backgroundColor: settings.cacheEnabled ? 'var(--color-action-primary-bg)' : 'var(--color-bg-sunken)',\n border: 'none',\n cursor: 'pointer',\n position: 'relative',\n transition: 'background-color 200ms',\n }}\n >\n <div\n style={{\n width: 18,\n height: 18,\n borderRadius: '50%',\n backgroundColor: 'var(--color-action-primary-text)',\n position: 'absolute',\n top: 3,\n left: settings.cacheEnabled ? 23 : 3,\n transition: 'left 200ms',\n }}\n />\n </button>\n </div>\n {settings.cacheEnabled && (\n <div>\n <label htmlFor=\"cache-ttl\" style={labelStyle}>\n {t('bigconsole.settings.cache.ttl.label', 'Cache TTL (seconds)')}\n </label>\n <input\n id=\"cache-ttl\"\n type=\"number\"\n min={30}\n max={3600}\n value={settings.cacheTTLSeconds}\n onChange={(e) =>\n handleChange('cacheTTLSeconds', Math.min(86400, Math.max(0, Number(e.target.value))))\n }\n style={inputStyle}\n />\n <p style={descStyle}>\n {t('bigconsole.settings.cache.ttl.help', 'How long cached data is considered fresh (30-3600)')}\n </p>\n </div>\n )}\n </div>\n </div>\n\n {/* Display Settings */}\n <div style={sectionStyle}>\n <h2\n style={{\n fontSize: 'var(--font-size-body-md)',\n fontWeight: 'var(--font-weight-semibold)',\n color: 'var(--color-text-primary)',\n marginBottom: 16,\n }}\n >\n {t('bigconsole.settings.display.title', 'Display')}\n </h2>\n <div className=\"grid gap-form-gap md:grid-cols-3\">\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>\n <div>\n <label style={labelStyle}>\n {t('bigconsole.settings.display.widgetBorders.label', 'Show Widget Borders')}\n </label>\n <p style={descStyle}>\n {t('bigconsole.settings.display.widgetBorders.help', 'Display borders around widgets in dashboards')}\n </p>\n </div>\n <button\n onClick={() => handleChange('showWidgetBorders', !settings.showWidgetBorders)}\n role=\"switch\"\n aria-checked={settings.showWidgetBorders}\n aria-label={t('bigconsole.settings.display.widgetBorders.label', 'Show Widget Borders')}\n style={{\n width: 44,\n flexShrink: 0,\n height: 24,\n borderRadius: 12,\n backgroundColor: settings.showWidgetBorders\n ? 'var(--color-action-primary-bg)'\n : 'var(--color-bg-sunken)',\n border: 'none',\n cursor: 'pointer',\n position: 'relative',\n transition: 'background-color 200ms',\n }}\n >\n <div\n style={{\n width: 18,\n height: 18,\n borderRadius: '50%',\n backgroundColor: 'var(--color-action-primary-text)',\n position: 'absolute',\n top: 3,\n left: settings.showWidgetBorders ? 23 : 3,\n transition: 'left 200ms',\n }}\n />\n </button>\n </div>\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>\n <div>\n <label style={labelStyle}>{t('bigconsole.settings.display.compactMode.label', 'Compact Mode')}</label>\n <p style={descStyle}>\n {t('bigconsole.settings.display.compactMode.help', 'Reduce padding and spacing for more content')}\n </p>\n </div>\n <button\n onClick={() => handleChange('compactMode', !settings.compactMode)}\n role=\"switch\"\n aria-checked={settings.compactMode}\n aria-label={t('bigconsole.settings.display.compactMode.label', 'Compact Mode')}\n style={{\n width: 44,\n flexShrink: 0,\n height: 24,\n borderRadius: 12,\n backgroundColor: settings.compactMode ? 'var(--color-action-primary-bg)' : 'var(--color-bg-sunken)',\n border: 'none',\n cursor: 'pointer',\n position: 'relative',\n transition: 'background-color 200ms',\n }}\n >\n <div\n style={{\n width: 18,\n height: 18,\n borderRadius: '50%',\n backgroundColor: 'var(--color-action-primary-text)',\n position: 'absolute',\n top: 3,\n left: settings.compactMode ? 23 : 3,\n transition: 'left 200ms',\n }}\n />\n </button>\n </div>\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>\n <div>\n <label style={labelStyle}>{t('bigconsole.settings.display.animations.label', 'Animations')}</label>\n <p style={descStyle}>\n {t('bigconsole.settings.display.animations.help', 'Enable transition animations and effects')}\n </p>\n </div>\n <button\n onClick={() => handleChange('animationsEnabled', !settings.animationsEnabled)}\n role=\"switch\"\n aria-checked={settings.animationsEnabled}\n aria-label={t('bigconsole.settings.display.animations.label', 'Animations')}\n style={{\n width: 44,\n flexShrink: 0,\n height: 24,\n borderRadius: 12,\n backgroundColor: settings.animationsEnabled\n ? 'var(--color-action-primary-bg)'\n : 'var(--color-bg-sunken)',\n border: 'none',\n cursor: 'pointer',\n position: 'relative',\n transition: 'background-color 200ms',\n }}\n >\n <div\n style={{\n width: 18,\n height: 18,\n borderRadius: '50%',\n backgroundColor: 'var(--color-action-primary-text)',\n position: 'absolute',\n top: 3,\n left: settings.animationsEnabled ? 23 : 3,\n transition: 'left 200ms',\n }}\n />\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n );\n});\n\nexport default SettingsPage;\n"],"mappings":"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"}
1
+ {"version":3,"file":"SettingsPage.js","names":[],"sources":["../../../src/bigconsole/pages/SettingsPage.tsx"],"sourcesContent":["/**\n * SettingsPage\n *\n * BigConsole workspace settings and preferences.\n * Settings are persisted to localStorage until a backend settings API is available.\n */\n\nimport { type FC, memo, useState, useCallback, useEffect } from 'react';\nimport { AuroraBackground, GradientText, PagePurpose, EmphasisPanel } from '@burdenoff/fe-libs/ui';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { useUnsavedChanges } from '@burdenoff/fe-libs/shared/hooks';\nimport { Settings, Save, RotateCcw } from 'lucide-react';\n\nimport {\n type BigConsoleSettings,\n DEFAULT_SETTINGS,\n loadBigConsoleSettings,\n saveBigConsoleSettings,\n} from '../hooks/useBigConsoleSettings';\nimport { isDirty } from '../utils/formDirty';\n\n// ============================================================================\n// COMPONENT\n// ============================================================================\n\nexport const SettingsPage: FC = memo(function SettingsPage() {\n const { t } = useI18n();\n const [settings, setSettings] = useState<BigConsoleSettings>(loadBigConsoleSettings);\n const [saved, setSaved] = useState(false);\n const [saveError, setSaveError] = useState(false);\n // What is persisted (loaded, or last saved successfully); a failed save leaves it, so the draft stays dirty.\n const [savedSettings, setSavedSettings] = useState<BigConsoleSettings>(settings);\n useUnsavedChanges({\n id: 'bigconsole-settings',\n label: t('bigconsole.assistant.unsaved.settingsPage', 'the settings page'),\n dirty: isDirty(settings, savedSettings),\n });\n\n useEffect(() => {\n if (saved) {\n const timer = setTimeout(() => setSaved(false), 2000);\n return () => clearTimeout(timer);\n }\n }, [saved]);\n\n const handleChange = useCallback(<K extends keyof BigConsoleSettings>(key: K, value: BigConsoleSettings[K]) => {\n setSettings((prev) => ({ ...prev, [key]: value }));\n }, []);\n\n const handleSave = useCallback(() => {\n const success = saveBigConsoleSettings(settings);\n setSaved(success);\n setSaveError(!success);\n if (success) setSavedSettings(settings);\n }, [settings]);\n\n const handleReset = useCallback(() => {\n setSettings({ ...DEFAULT_SETTINGS });\n const success = saveBigConsoleSettings(DEFAULT_SETTINGS);\n setSaved(success);\n setSaveError(!success);\n if (success) setSavedSettings({ ...DEFAULT_SETTINGS });\n }, []);\n\n const inputStyle: React.CSSProperties = {\n width: '100%',\n padding: '8px 12px',\n borderRadius: 'var(--radius-button)',\n border: '1px solid var(--color-border)',\n backgroundColor: 'var(--color-bg-canvas)',\n color: 'var(--color-text-primary)',\n fontSize: 'var(--font-size-body-sm)',\n };\n\n const labelStyle: React.CSSProperties = {\n display: 'block',\n fontSize: 'var(--font-size-body-sm)',\n fontWeight: 'var(--font-weight-medium)',\n color: 'var(--color-text-primary)',\n marginBottom: 4,\n };\n\n const descStyle: React.CSSProperties = {\n fontSize: 'var(--font-size-body-sm)',\n color: 'var(--color-text-muted)',\n marginTop: 4,\n };\n\n const sectionStyle: React.CSSProperties = {\n backgroundColor: 'var(--color-bg-surface)',\n border: '1px solid var(--color-border-seam)',\n borderRadius: 'var(--radius-card)',\n padding: 'var(--space-cardPadding)',\n marginBottom: 'var(--space-sectionGap)',\n boxShadow: 'var(--shadow-pop)',\n };\n\n return (\n <div style={{ minHeight: '100vh', backgroundColor: 'var(--color-bg-canvas)' }}>\n <div style={{ padding: 'var(--space-pagePadding)', maxWidth: 1440, margin: '0 auto' }}>\n {/* Header */}\n <div\n className=\"relative overflow-hidden rounded-card border border-border-seam bg-gloss-card p-6\"\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n marginBottom: 'var(--space-sectionGap)',\n flexWrap: 'wrap',\n gap: 'var(--space-formGap)',\n }}\n >\n <AuroraBackground intensity=\"subtle\" />\n <div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-iconGap)' }}>\n <Settings size={24} style={{ color: 'var(--color-text-primary)' }} />\n <h1\n style={{\n fontSize: 'var(--font-size-heading-h4)',\n fontWeight: 'var(--font-weight-bold)',\n color: 'var(--color-text-primary)',\n }}\n >\n <GradientText>{t('bigconsole.settings.header.title', 'Settings')}</GradientText>\n </h1>\n </div>\n <p style={{ fontSize: 'var(--font-size-body-md)', color: 'var(--color-text-secondary)', marginTop: 4 }}>\n {t('bigconsole.settings.header.subtitle', 'Configure BigConsole preferences')}\n </p>\n </div>\n <div style={{ display: 'flex', gap: 8 }}>\n <button\n onClick={handleReset}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n padding: '8px 12px',\n borderRadius: 'var(--radius-button)',\n border: '1px solid var(--color-border)',\n backgroundColor: 'transparent',\n color: 'var(--color-text-secondary)',\n fontSize: 'var(--font-size-body-sm)',\n cursor: 'pointer',\n }}\n >\n <RotateCcw size={14} /> {t('bigconsole.settings.actions.reset', 'Reset')}\n </button>\n <button\n onClick={handleSave}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n padding: '8px 16px',\n borderRadius: 'var(--radius-button)',\n backgroundColor: saved ? 'var(--color-status-success-bg)' : 'var(--color-action-primary-bg)',\n color: 'var(--color-action-primary-text)',\n fontWeight: 'var(--font-weight-medium)',\n fontSize: 'var(--font-size-body-sm)',\n border: 'none',\n cursor: 'pointer',\n transition: 'background-color 200ms',\n }}\n >\n <Save size={14} />{' '}\n {saved\n ? t('bigconsole.settings.actions.savedLocally', 'Saved locally')\n : t('bigconsole.settings.actions.saveLocally', 'Save locally')}\n </button>\n </div>\n </div>\n\n {saveError && (\n <p role=\"alert\" className=\"mb-form-gap text-status-error-text\">\n {t('bigconsole.settings.actions.saveError', 'Your browser could not save these preferences. Try again.')}\n </p>\n )}\n <PagePurpose className=\"mb-[var(--space-sectionGap)]\">\n {t(\n 'bigconsole.settings.localDefaultsPurpose',\n 'These browser-local defaults apply when you add dashboard pages, widgets and data sinks. Display preferences update existing widgets in this browser. They do not change existing page layouts, widget refresh schedules or data sink cache settings, and are not shared with your team.'\n )}\n </PagePurpose>\n\n {/* Dashboard Defaults — primary emphasis zone */}\n <EmphasisPanel className=\"mb-[var(--space-sectionGap)] p-[var(--space-cardPadding)]\">\n <h2\n style={{\n fontSize: 'var(--font-size-body-md)',\n fontWeight: 'var(--font-weight-semibold)',\n color: 'var(--color-text-primary)',\n marginBottom: 16,\n }}\n >\n {t('bigconsole.settings.dashboardDefaults.title', 'Dashboard Defaults')}\n </h2>\n <div className=\"grid gap-form-gap md:grid-cols-3\">\n <div>\n <label htmlFor=\"grid-cols\" style={labelStyle}>\n {t('bigconsole.settings.dashboardDefaults.gridColumns.label', 'Grid Columns')}\n </label>\n <input\n id=\"grid-cols\"\n type=\"number\"\n min={4}\n max={24}\n value={settings.defaultGridColumns}\n onChange={(e) =>\n handleChange('defaultGridColumns', Math.min(24, Math.max(4, Number(e.target.value) || 12)))\n }\n style={inputStyle}\n />\n <p style={descStyle}>\n {t(\n 'bigconsole.settings.dashboardDefaults.gridColumns.help',\n 'Number of columns in the dashboard grid (4-24)'\n )}\n </p>\n </div>\n <div>\n <label htmlFor=\"widget-height\" style={labelStyle}>\n {t('bigconsole.settings.dashboardDefaults.widgetHeight.label', 'Default Widget Height')}\n </label>\n <input\n id=\"widget-height\"\n type=\"number\"\n min={2}\n max={12}\n value={settings.defaultWidgetHeight}\n onChange={(e) =>\n handleChange('defaultWidgetHeight', Math.min(12, Math.max(1, Number(e.target.value) || 4)))\n }\n style={inputStyle}\n />\n <p style={descStyle}>\n {t(\n 'bigconsole.settings.dashboardDefaults.widgetHeight.help',\n 'Default height units for new widgets (2-12)'\n )}\n </p>\n </div>\n <div>\n <label htmlFor=\"refresh-interval\" style={labelStyle}>\n {t('bigconsole.settings.dashboardDefaults.refreshInterval.label', 'Auto-Refresh Interval (seconds)')}\n </label>\n <select\n id=\"refresh-interval\"\n value={settings.defaultRefreshInterval}\n onChange={(e) => handleChange('defaultRefreshInterval', parseInt(e.target.value))}\n style={inputStyle}\n >\n <option value={0}>\n {t('bigconsole.settings.dashboardDefaults.refreshInterval.disabled', 'Disabled')}\n </option>\n <option value={10}>\n {t('bigconsole.settings.dashboardDefaults.refreshInterval.seconds10', '10 seconds')}\n </option>\n <option value={30}>\n {t('bigconsole.settings.dashboardDefaults.refreshInterval.seconds30', '30 seconds')}\n </option>\n <option value={60}>\n {t('bigconsole.settings.dashboardDefaults.refreshInterval.minute1', '1 minute')}\n </option>\n <option value={300}>\n {t('bigconsole.settings.dashboardDefaults.refreshInterval.minutes5', '5 minutes')}\n </option>\n <option value={600}>\n {t('bigconsole.settings.dashboardDefaults.refreshInterval.minutes10', '10 minutes')}\n </option>\n </select>\n <p style={descStyle}>\n {t(\n 'bigconsole.settings.dashboardDefaults.refreshInterval.help',\n 'How often widgets refresh their data automatically'\n )}\n </p>\n </div>\n </div>\n </EmphasisPanel>\n\n {/* Cache Settings */}\n <div style={sectionStyle}>\n <h2\n style={{\n fontSize: 'var(--font-size-body-md)',\n fontWeight: 'var(--font-weight-semibold)',\n color: 'var(--color-text-primary)',\n marginBottom: 16,\n }}\n >\n {t('bigconsole.settings.cache.title', 'Cache')}\n </h2>\n <div className=\"grid gap-form-gap md:grid-cols-2\">\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>\n <div>\n <label style={labelStyle}>{t('bigconsole.settings.cache.enable.label', 'Enable Cache')}</label>\n <p style={descStyle}>\n {t('bigconsole.settings.cache.newSinkHelp', 'Enable caching by default for new data sinks')}\n </p>\n </div>\n <button\n onClick={() => handleChange('cacheEnabled', !settings.cacheEnabled)}\n role=\"switch\"\n aria-checked={settings.cacheEnabled}\n aria-label={t('bigconsole.settings.cache.enable.label', 'Enable Cache')}\n style={{\n width: 44,\n flexShrink: 0,\n height: 24,\n borderRadius: 12,\n backgroundColor: settings.cacheEnabled ? 'var(--color-action-primary-bg)' : 'var(--color-bg-sunken)',\n border: 'none',\n cursor: 'pointer',\n position: 'relative',\n transition: 'background-color 200ms',\n }}\n >\n <div\n style={{\n width: 18,\n height: 18,\n borderRadius: '50%',\n backgroundColor: 'var(--color-action-primary-text)',\n position: 'absolute',\n top: 3,\n left: settings.cacheEnabled ? 23 : 3,\n transition: 'left 200ms',\n }}\n />\n </button>\n </div>\n {settings.cacheEnabled && (\n <div>\n <label htmlFor=\"cache-ttl\" style={labelStyle}>\n {t('bigconsole.settings.cache.ttl.label', 'Cache TTL (seconds)')}\n </label>\n <input\n id=\"cache-ttl\"\n type=\"number\"\n min={30}\n max={3600}\n value={settings.cacheTTLSeconds}\n onChange={(e) =>\n handleChange('cacheTTLSeconds', Math.min(86400, Math.max(0, Number(e.target.value))))\n }\n style={inputStyle}\n />\n <p style={descStyle}>\n {t('bigconsole.settings.cache.ttl.help', 'How long cached data is considered fresh (30-3600)')}\n </p>\n </div>\n )}\n </div>\n </div>\n\n {/* Display Settings */}\n <div style={sectionStyle}>\n <h2\n style={{\n fontSize: 'var(--font-size-body-md)',\n fontWeight: 'var(--font-weight-semibold)',\n color: 'var(--color-text-primary)',\n marginBottom: 16,\n }}\n >\n {t('bigconsole.settings.display.title', 'Display')}\n </h2>\n <div className=\"grid gap-form-gap md:grid-cols-3\">\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>\n <div>\n <label style={labelStyle}>\n {t('bigconsole.settings.display.widgetBorders.label', 'Show Widget Borders')}\n </label>\n <p style={descStyle}>\n {t('bigconsole.settings.display.widgetBorders.help', 'Display borders around widgets in dashboards')}\n </p>\n </div>\n <button\n onClick={() => handleChange('showWidgetBorders', !settings.showWidgetBorders)}\n role=\"switch\"\n aria-checked={settings.showWidgetBorders}\n aria-label={t('bigconsole.settings.display.widgetBorders.label', 'Show Widget Borders')}\n style={{\n width: 44,\n flexShrink: 0,\n height: 24,\n borderRadius: 12,\n backgroundColor: settings.showWidgetBorders\n ? 'var(--color-action-primary-bg)'\n : 'var(--color-bg-sunken)',\n border: 'none',\n cursor: 'pointer',\n position: 'relative',\n transition: 'background-color 200ms',\n }}\n >\n <div\n style={{\n width: 18,\n height: 18,\n borderRadius: '50%',\n backgroundColor: 'var(--color-action-primary-text)',\n position: 'absolute',\n top: 3,\n left: settings.showWidgetBorders ? 23 : 3,\n transition: 'left 200ms',\n }}\n />\n </button>\n </div>\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>\n <div>\n <label style={labelStyle}>{t('bigconsole.settings.display.compactMode.label', 'Compact Mode')}</label>\n <p style={descStyle}>\n {t('bigconsole.settings.display.compactMode.help', 'Reduce padding and spacing for more content')}\n </p>\n </div>\n <button\n onClick={() => handleChange('compactMode', !settings.compactMode)}\n role=\"switch\"\n aria-checked={settings.compactMode}\n aria-label={t('bigconsole.settings.display.compactMode.label', 'Compact Mode')}\n style={{\n width: 44,\n flexShrink: 0,\n height: 24,\n borderRadius: 12,\n backgroundColor: settings.compactMode ? 'var(--color-action-primary-bg)' : 'var(--color-bg-sunken)',\n border: 'none',\n cursor: 'pointer',\n position: 'relative',\n transition: 'background-color 200ms',\n }}\n >\n <div\n style={{\n width: 18,\n height: 18,\n borderRadius: '50%',\n backgroundColor: 'var(--color-action-primary-text)',\n position: 'absolute',\n top: 3,\n left: settings.compactMode ? 23 : 3,\n transition: 'left 200ms',\n }}\n />\n </button>\n </div>\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>\n <div>\n <label style={labelStyle}>{t('bigconsole.settings.display.animations.label', 'Animations')}</label>\n <p style={descStyle}>\n {t('bigconsole.settings.display.animations.help', 'Enable transition animations and effects')}\n </p>\n </div>\n <button\n onClick={() => handleChange('animationsEnabled', !settings.animationsEnabled)}\n role=\"switch\"\n aria-checked={settings.animationsEnabled}\n aria-label={t('bigconsole.settings.display.animations.label', 'Animations')}\n style={{\n width: 44,\n flexShrink: 0,\n height: 24,\n borderRadius: 12,\n backgroundColor: settings.animationsEnabled\n ? 'var(--color-action-primary-bg)'\n : 'var(--color-bg-sunken)',\n border: 'none',\n cursor: 'pointer',\n position: 'relative',\n transition: 'background-color 200ms',\n }}\n >\n <div\n style={{\n width: 18,\n height: 18,\n borderRadius: '50%',\n backgroundColor: 'var(--color-action-primary-text)',\n position: 'absolute',\n top: 3,\n left: settings.animationsEnabled ? 23 : 3,\n transition: 'left 200ms',\n }}\n />\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n );\n});\n\nexport default SettingsPage;\n"],"mappings":"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"}
@@ -8,8 +8,8 @@ import a from "../components/widgets/WidgetWrapper.js";
8
8
  import "../components/widgets/index.js";
9
9
  import { useMemo as o, useState as s } from "react";
10
10
  import { Button as c, IllustratedEmptyState as l, PagePurpose as u } from "@burdenoff/fe-libs/ui";
11
- import { jsx as d, jsxs as f } from "react/jsx-runtime";
12
- import { useI18n as p } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
11
+ import { useI18n as d } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
12
+ import { jsx as f, jsxs as p } from "react/jsx-runtime";
13
13
  //#region src/bigconsole/pages/WidgetDemoPage.tsx
14
14
  var m = [
15
15
  {
@@ -171,7 +171,7 @@ var m = [
171
171
  Temporal: "Widgets organised by date, schedule or workflow stage.",
172
172
  Custom: "Widgets whose body you define yourself."
173
173
  }, _ = () => {
174
- let { t: _ } = p(), v = e(), [y, b] = s(""), [x, S] = s("grid"), C = o(() => (y ? m.filter((e) => [
174
+ let { t: _ } = d(), v = e(), [y, b] = s(""), [x, S] = s("grid"), C = o(() => (y ? m.filter((e) => [
175
175
  e.type,
176
176
  _(e.titleKey, e.title),
177
177
  _(e.descriptionKey, e.description)
@@ -214,35 +214,35 @@ var m = [
214
214
  widgets: e.get(t) ?? []
215
215
  }));
216
216
  }, [C]), T = x === "grid" ? "grid grid-cols-1 gap-form-gap sm:grid-cols-2 xl:grid-cols-3" : "flex flex-col gap-form-gap";
217
- return /* @__PURE__ */ f("div", {
217
+ return /* @__PURE__ */ p("div", {
218
218
  className: "flex h-full min-w-0 flex-col bg-bg-canvas",
219
219
  children: [
220
- /* @__PURE__ */ d("section", {
220
+ /* @__PURE__ */ f("section", {
221
221
  "aria-label": "Widget demo header",
222
222
  className: `${t("bare", "neutral", "none")} flex-shrink-0 border-b border-[var(--color-border-subtle)] bg-bg-surface px-4 py-3 sm:px-6 sm:py-4`,
223
- children: /* @__PURE__ */ f("div", {
223
+ children: /* @__PURE__ */ p("div", {
224
224
  className: "flex flex-col gap-control-gap lg:flex-row lg:items-center lg:justify-between",
225
- children: [/* @__PURE__ */ f("div", {
225
+ children: [/* @__PURE__ */ p("div", {
226
226
  className: "min-w-0",
227
- children: [/* @__PURE__ */ d("h1", {
227
+ children: [/* @__PURE__ */ f("h1", {
228
228
  className: "text-xl font-semibold text-text-primary",
229
229
  children: _("bigconsole.widgetDemo.header.title", "Widget Demo")
230
- }), /* @__PURE__ */ d("p", {
230
+ }), /* @__PURE__ */ f("p", {
231
231
  className: "mt-1 text-sm text-text-secondary",
232
232
  children: _("bigconsole.widgetDemo.header.subtitle", "All 18 widget types - connect a DataSink for real data")
233
233
  })]
234
- }), /* @__PURE__ */ f("div", {
234
+ }), /* @__PURE__ */ p("div", {
235
235
  className: "flex flex-wrap items-center gap-control-gap",
236
236
  children: [
237
- /* @__PURE__ */ f("div", {
237
+ /* @__PURE__ */ p("div", {
238
238
  className: "relative min-w-0 flex-1 sm:flex-none",
239
239
  children: [
240
- /* @__PURE__ */ d("label", {
240
+ /* @__PURE__ */ f("label", {
241
241
  htmlFor: "widget-demo-filter",
242
242
  className: "sr-only",
243
243
  children: "Filter widget types"
244
244
  }),
245
- /* @__PURE__ */ d("input", {
245
+ /* @__PURE__ */ f("input", {
246
246
  id: "widget-demo-filter",
247
247
  type: "text",
248
248
  placeholder: _("bigconsole.widgetDemo.filter.placeholder", "Filter widgets..."),
@@ -250,13 +250,13 @@ var m = [
250
250
  onChange: (e) => b(e.target.value),
251
251
  className: "h-control-md w-full min-w-0 rounded-input border border-[var(--color-border-subtle)] bg-bg-sunken py-2 pl-[3.25rem] pr-3 text-sm text-text-primary placeholder:text-text-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-bg-surface sm:w-64"
252
252
  }),
253
- /* @__PURE__ */ d("svg", {
253
+ /* @__PURE__ */ f("svg", {
254
254
  "aria-hidden": "true",
255
255
  className: "pointer-events-none absolute left-3 top-1/2 h-icon-sm w-icon-sm -translate-y-1/2 text-text-secondary",
256
256
  fill: "none",
257
257
  stroke: "currentColor",
258
258
  viewBox: "0 0 24 24",
259
- children: /* @__PURE__ */ d("path", {
259
+ children: /* @__PURE__ */ f("path", {
260
260
  strokeLinecap: "round",
261
261
  strokeLinejoin: "round",
262
262
  strokeWidth: 2,
@@ -265,17 +265,17 @@ var m = [
265
265
  })
266
266
  ]
267
267
  }),
268
- /* @__PURE__ */ f("div", {
268
+ /* @__PURE__ */ p("div", {
269
269
  className: "flex shrink-0 items-center gap-1 rounded-button bg-bg-sunken p-1",
270
270
  role: "group",
271
271
  "aria-label": "Gallery layout",
272
- children: [/* @__PURE__ */ d("button", {
272
+ children: [/* @__PURE__ */ f("button", {
273
273
  type: "button",
274
274
  onClick: () => S("grid"),
275
275
  "aria-pressed": x === "grid",
276
276
  className: `min-h-control-md rounded-button px-3 text-sm font-medium motion-safe:transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-bg-surface ${x === "grid" ? "bg-bg-surface text-text-primary shadow-[var(--shadow-elevation-1)]" : "text-text-secondary hover:text-text-primary"}`,
277
277
  children: _("bigconsole.widgetDemo.viewToggle.grid", "Grid")
278
- }), /* @__PURE__ */ d("button", {
278
+ }), /* @__PURE__ */ f("button", {
279
279
  type: "button",
280
280
  onClick: () => S("list"),
281
281
  "aria-pressed": x === "list",
@@ -283,7 +283,7 @@ var m = [
283
283
  children: _("bigconsole.widgetDemo.viewToggle.list", "List")
284
284
  })]
285
285
  }),
286
- /* @__PURE__ */ d(c, {
286
+ /* @__PURE__ */ f(c, {
287
287
  variant: "secondary",
288
288
  onClick: () => v("/dashboards"),
289
289
  children: _("bigconsole.widgetDemo.openDashboards", "Open dashboards")
@@ -292,20 +292,20 @@ var m = [
292
292
  })]
293
293
  })
294
294
  }),
295
- /* @__PURE__ */ d("div", {
295
+ /* @__PURE__ */ f("div", {
296
296
  className: "min-w-0 flex-1 overflow-y-auto overflow-x-hidden p-4 sm:p-6",
297
- children: /* @__PURE__ */ f(r, { children: [
298
- /* @__PURE__ */ d("section", {
297
+ children: /* @__PURE__ */ p(r, { children: [
298
+ /* @__PURE__ */ f("section", {
299
299
  "aria-label": "What this gallery is for",
300
300
  className: t("muted", "neutral", "compact"),
301
- children: /* @__PURE__ */ d(u, { children: _("bigconsole.widgetDemo.pagePurpose", "This gallery previews every widget type BigConsole can render on a dashboard — metrics, charts, tables, maps, kanban boards and more. Use it to see what each widget looks like and pick the right one before wiring it to a real DataSink in the dashboard builder.") })
301
+ children: /* @__PURE__ */ f(u, { children: _("bigconsole.widgetDemo.pagePurpose", "This gallery previews every widget type BigConsole can render on a dashboard — metrics, charts, tables, maps, kanban boards and more. Use it to see what each widget looks like and pick the right one before wiring it to a real DataSink in the dashboard builder.") })
302
302
  }),
303
- w.length > 0 && /* @__PURE__ */ d(n, {
303
+ w.length > 0 && /* @__PURE__ */ f(n, {
304
304
  emphasis: "primary",
305
305
  headingLevel: 2,
306
306
  title: "Widget gallery",
307
307
  description: "Every widget renders its unconnected state here — the card chrome, header and empty copy are exactly what a dashboard will show before a DataSink is bound.",
308
- meta: /* @__PURE__ */ f("span", {
308
+ meta: /* @__PURE__ */ p("span", {
309
309
  className: "rounded-pill bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-secondary",
310
310
  children: [
311
311
  C.length,
@@ -313,15 +313,15 @@ var m = [
313
313
  m.length
314
314
  ]
315
315
  }),
316
- children: /* @__PURE__ */ d("div", {
316
+ children: /* @__PURE__ */ f("div", {
317
317
  className: "flex flex-col gap-section-gap",
318
- children: w.map((e) => /* @__PURE__ */ d(n, {
318
+ children: w.map((e) => /* @__PURE__ */ f(n, {
319
319
  emphasis: "bare",
320
320
  padding: "none",
321
321
  headingLevel: 3,
322
322
  title: e.label,
323
323
  description: e.blurb,
324
- meta: /* @__PURE__ */ f("span", {
324
+ meta: /* @__PURE__ */ p("span", {
325
325
  className: "text-xs font-medium text-text-muted",
326
326
  children: [
327
327
  e.widgets.length,
@@ -329,28 +329,28 @@ var m = [
329
329
  e.widgets.length === 1 ? "type" : "types"
330
330
  ]
331
331
  }),
332
- children: /* @__PURE__ */ d("div", {
332
+ children: /* @__PURE__ */ f("div", {
333
333
  className: T,
334
334
  children: e.widgets.map((e) => {
335
335
  let t = m.find((t) => t.type === e.type);
336
- return /* @__PURE__ */ f("figure", {
336
+ return /* @__PURE__ */ p("figure", {
337
337
  className: `m-0 flex min-w-0 flex-col ${x === "grid" ? "h-80" : "h-64"}`,
338
- children: [/* @__PURE__ */ f("figcaption", {
338
+ children: [/* @__PURE__ */ p("figcaption", {
339
339
  className: "mb-2 flex flex-shrink-0 flex-wrap items-baseline gap-x-2 gap-y-0.5 text-xs text-text-secondary",
340
- children: [/* @__PURE__ */ f("span", { children: [
340
+ children: [/* @__PURE__ */ p("span", { children: [
341
341
  _("bigconsole.widgetDemo.widgetCard.typeLabel", "Type:"),
342
342
  " ",
343
- /* @__PURE__ */ d("code", {
343
+ /* @__PURE__ */ f("code", {
344
344
  className: "font-mono text-text-link",
345
345
  children: e.type
346
346
  })
347
- ] }), t && /* @__PURE__ */ d("span", {
347
+ ] }), t && /* @__PURE__ */ f("span", {
348
348
  className: "text-text-muted",
349
349
  children: _(t.descriptionKey, t.description)
350
350
  })]
351
- }), /* @__PURE__ */ d("div", {
351
+ }), /* @__PURE__ */ f("div", {
352
352
  className: "min-h-0 min-w-0 flex-1",
353
- children: /* @__PURE__ */ d(a, {
353
+ children: /* @__PURE__ */ f(a, {
354
354
  previewOnly: !0,
355
355
  widget: e
356
356
  })
@@ -361,13 +361,13 @@ var m = [
361
361
  }, e.category))
362
362
  })
363
363
  }),
364
- C.length === 0 && /* @__PURE__ */ d(n, {
364
+ C.length === 0 && /* @__PURE__ */ f(n, {
365
365
  emphasis: "standard",
366
366
  tone: "info",
367
367
  title: _("bigconsole.widgetDemo.emptyState.title", "No widgets match your filter"),
368
368
  headingLevel: 2,
369
369
  "data-testid": "widget-demo-empty",
370
- children: /* @__PURE__ */ d(l, {
370
+ children: /* @__PURE__ */ f(l, {
371
371
  illustration: "empty-search",
372
372
  title: _("bigconsole.widgetDemo.emptyState.description", "Try a different search term to preview a widget type."),
373
373
  description: "The filter matches a widget's name and its one-line description."
@@ -375,15 +375,15 @@ var m = [
375
375
  })
376
376
  ] })
377
377
  }),
378
- /* @__PURE__ */ d("section", {
378
+ /* @__PURE__ */ f("section", {
379
379
  "aria-label": "Gallery summary",
380
380
  className: `${t("bare", "neutral", "none")} flex-shrink-0 border-t border-[var(--color-border-subtle)] bg-bg-sunken px-4 py-2 sm:px-6`,
381
- children: /* @__PURE__ */ f("div", {
381
+ children: /* @__PURE__ */ p("div", {
382
382
  className: "flex flex-wrap items-center justify-between gap-x-4 gap-y-1 text-xs text-text-secondary",
383
- children: [/* @__PURE__ */ d("span", { children: _("bigconsole.widgetDemo.footer.showing", "Showing {{shown}} of {{total}} widget types", {
383
+ children: [/* @__PURE__ */ f("span", { children: _("bigconsole.widgetDemo.footer.showing", "Showing {{shown}} of {{total}} widget types", {
384
384
  shown: C.length,
385
385
  total: m.length
386
- }) }), /* @__PURE__ */ d("span", {
386
+ }) }), /* @__PURE__ */ f("span", {
387
387
  className: "text-text-muted",
388
388
  children: _("bigconsole.widgetDemo.footer.hint", "Widgets show empty state until connected to DataSink + Parser")
389
389
  })]
@@ -16,8 +16,8 @@ import { useParams as se } from "react-router";
16
16
  import { AccessDenied as ce, PermissionButton as p } from "@burdenoff/fe-libs/shared/components";
17
17
  import { usePermissions as le } from "@burdenoff/fe-libs/shared/providers/shell";
18
18
  import { Button as m, IllustratedEmptyState as h, NextSteps as ue, PagePurpose as de, Spinner as g } from "@burdenoff/fe-libs/ui";
19
- import { Fragment as _, jsx as v, jsxs as y } from "react/jsx-runtime";
20
19
  import { useI18n as fe } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
20
+ import { Fragment as _, jsx as v, jsxs as y } from "react/jsx-runtime";
21
21
  import { useLazyWorkflowDefinition as pe } from "@burdenoff/fluidgrids-fe-sdk";
22
22
  import { formatDistanceToNow as b } from "date-fns";
23
23
  //#region src/bigconsole/pages/WorkflowViewPage.tsx