@burdenoff/microfe-bigconsole 2026.805.3 → 2026.812.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bigconsole/components/DrilldownDashboardRenderer.js +118 -106
- package/dist/bigconsole/components/DrilldownDashboardRenderer.js.map +1 -1
- package/dist/bigconsole/components/DrilldownModal.js +54 -50
- package/dist/bigconsole/components/DrilldownModal.js.map +1 -1
- package/dist/bigconsole/components/builder/BuilderCanvas.js +2 -2
- package/dist/bigconsole/components/builder/BuilderCanvas.js.map +1 -1
- package/dist/bigconsole/components/builder/BuilderTopbar.js +3 -3
- package/dist/bigconsole/components/builder/BuilderTopbar.js.map +1 -1
- package/dist/bigconsole/components/builder/inspector/AdvancedSection.js +24 -25
- package/dist/bigconsole/components/builder/inspector/AdvancedSection.js.map +1 -1
- package/dist/bigconsole/components/builder/inspector/AppearanceSection.js +40 -29
- package/dist/bigconsole/components/builder/inspector/AppearanceSection.js.map +1 -1
- package/dist/bigconsole/components/builder/inspector/DataBindingSection.js +135 -97
- package/dist/bigconsole/components/builder/inspector/DataBindingSection.js.map +1 -1
- package/dist/bigconsole/components/builder/inspector/GeneralSection.js +58 -44
- package/dist/bigconsole/components/builder/inspector/GeneralSection.js.map +1 -1
- package/dist/bigconsole/components/common/Section.js +70 -0
- package/dist/bigconsole/components/common/Section.js.map +1 -0
- package/dist/bigconsole/components/common/index.js +2 -0
- package/dist/bigconsole/components/common/sectionStyles.js +42 -0
- package/dist/bigconsole/components/common/sectionStyles.js.map +1 -0
- package/dist/bigconsole/components/dashboard/CreateDashboardDialog.js +209 -193
- package/dist/bigconsole/components/dashboard/CreateDashboardDialog.js.map +1 -1
- package/dist/bigconsole/components/dashboard/DashboardCanvas.js +213 -231
- package/dist/bigconsole/components/dashboard/DashboardCanvas.js.map +1 -1
- package/dist/bigconsole/components/dashboard/DashboardGrid.js +12 -18
- package/dist/bigconsole/components/dashboard/DashboardGrid.js.map +1 -1
- package/dist/bigconsole/components/dashboard/DashboardToolbar.js +109 -102
- package/dist/bigconsole/components/dashboard/DashboardToolbar.js.map +1 -1
- package/dist/bigconsole/components/dashboard/DrilldownBreadcrumb.js +81 -70
- package/dist/bigconsole/components/dashboard/DrilldownBreadcrumb.js.map +1 -1
- package/dist/bigconsole/components/dashboard/ExportDashboardDialog.js +125 -159
- package/dist/bigconsole/components/dashboard/ExportDashboardDialog.js.map +1 -1
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterChip.js +25 -23
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterChip.js.map +1 -1
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.js +3 -3
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterEditor.js.map +1 -1
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterPresetSelector.js +5 -3
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/FilterPresetSelector.js.map +1 -1
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.js +170 -284
- package/dist/bigconsole/components/dashboard/GlobalFiltersBar/GlobalFiltersBar.js.map +1 -1
- package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js +147 -151
- package/dist/bigconsole/components/dashboard/ImportDashboardDialog.js.map +1 -1
- package/dist/bigconsole/components/dashboard/LiveBoardBanner.js +45 -53
- package/dist/bigconsole/components/dashboard/LiveBoardBanner.js.map +1 -1
- package/dist/bigconsole/components/dashboard/PageTabsManager/PageTabsManager.js +157 -148
- package/dist/bigconsole/components/dashboard/PageTabsManager/PageTabsManager.js.map +1 -1
- package/dist/bigconsole/components/dashboard/SavedViewsDropdown/SavedViewsDropdown.js +17 -8
- package/dist/bigconsole/components/dashboard/SavedViewsDropdown/SavedViewsDropdown.js.map +1 -1
- package/dist/bigconsole/components/dashboard/ShareDialog/ShareDialog.js +101 -95
- package/dist/bigconsole/components/dashboard/ShareDialog/ShareDialog.js.map +1 -1
- package/dist/bigconsole/components/dashboard/StoreTemplatePicker.js +20 -18
- package/dist/bigconsole/components/dashboard/StoreTemplatePicker.js.map +1 -1
- package/dist/bigconsole/components/dashboard/TemplateSetupBanner.js +26 -58
- package/dist/bigconsole/components/dashboard/TemplateSetupBanner.js.map +1 -1
- package/dist/bigconsole/components/dashboard/WidgetPalette.js +307 -231
- package/dist/bigconsole/components/dashboard/WidgetPalette.js.map +1 -1
- package/dist/bigconsole/components/datasink/CacheTTLSelector.js +29 -29
- package/dist/bigconsole/components/datasink/CacheTTLSelector.js.map +1 -1
- package/dist/bigconsole/components/datasink/DataSinkCard.js +78 -79
- package/dist/bigconsole/components/datasink/DataSinkCard.js.map +1 -1
- package/dist/bigconsole/components/datasink/DataSinkDataViewer.js +33 -34
- package/dist/bigconsole/components/datasink/DataSinkDataViewer.js.map +1 -1
- package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js +79 -56
- package/dist/bigconsole/components/datasink/DataSinkDeleteDialog.js.map +1 -1
- package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js +75 -65
- package/dist/bigconsole/components/datasink/DataSinkRefreshDialog.js.map +1 -1
- package/dist/bigconsole/components/datasink/DataSinkStatusBadge.js +1 -1
- package/dist/bigconsole/components/datasink/DataSinkStatusBadge.js.map +1 -1
- package/dist/bigconsole/components/datasink/DataSinkTableViewer.js +20 -19
- package/dist/bigconsole/components/datasink/DataSinkTableViewer.js.map +1 -1
- package/dist/bigconsole/components/datasink/ExportDataSinkDialog.js +127 -171
- package/dist/bigconsole/components/datasink/ExportDataSinkDialog.js.map +1 -1
- package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js +263 -243
- package/dist/bigconsole/components/datasink/ImportDataSinkDialog.js.map +1 -1
- package/dist/bigconsole/components/datasink/LinkedParsersPanel.js +65 -66
- package/dist/bigconsole/components/datasink/LinkedParsersPanel.js.map +1 -1
- package/dist/bigconsole/components/datasink/LinkedWorkflowsPanel.js +121 -127
- package/dist/bigconsole/components/datasink/LinkedWorkflowsPanel.js.map +1 -1
- package/dist/bigconsole/components/datasink/RefreshTypeSelector.js +33 -26
- package/dist/bigconsole/components/datasink/RefreshTypeSelector.js.map +1 -1
- package/dist/bigconsole/components/datasink/SetupStateBadge.js +3 -3
- package/dist/bigconsole/components/datasink/SetupStateBadge.js.map +1 -1
- package/dist/bigconsole/components/datasink/WorkflowStatusPanel.js +95 -95
- package/dist/bigconsole/components/datasink/WorkflowStatusPanel.js.map +1 -1
- package/dist/bigconsole/components/parser/DataSinkSelector.js +154 -123
- package/dist/bigconsole/components/parser/DataSinkSelector.js.map +1 -1
- package/dist/bigconsole/components/parser/ExpressionEditor.js +3 -3
- package/dist/bigconsole/components/parser/ExpressionEditor.js.map +1 -1
- package/dist/bigconsole/components/parser/ImportParserDialog.js +235 -275
- package/dist/bigconsole/components/parser/ImportParserDialog.js.map +1 -1
- package/dist/bigconsole/components/parser/ParserCard.js +133 -114
- package/dist/bigconsole/components/parser/ParserCard.js.map +1 -1
- package/dist/bigconsole/components/parser/ParserSelector.js +191 -174
- package/dist/bigconsole/components/parser/ParserSelector.js.map +1 -1
- package/dist/bigconsole/components/parser/ParserStatusBadge.js +2 -2
- package/dist/bigconsole/components/parser/ParserStatusBadge.js.map +1 -1
- package/dist/bigconsole/components/parser/ParserTypeBadge.js +4 -4
- package/dist/bigconsole/components/parser/ParserTypeBadge.js.map +1 -1
- package/dist/bigconsole/components/pipeline/PipelineCard.js +134 -89
- package/dist/bigconsole/components/pipeline/PipelineCard.js.map +1 -1
- package/dist/bigconsole/components/pipeline/PipelineDeleteDialog.js +77 -64
- package/dist/bigconsole/components/pipeline/PipelineDeleteDialog.js.map +1 -1
- package/dist/bigconsole/components/pipeline/PipelineStatusBadge.js +7 -10
- package/dist/bigconsole/components/pipeline/PipelineStatusBadge.js.map +1 -1
- package/dist/bigconsole/components/preview/AiPreviewContent.js +31 -32
- package/dist/bigconsole/components/preview/AiPreviewContent.js.map +1 -1
- package/dist/bigconsole/components/preview/AiPreviewMiniPanel.js +152 -106
- package/dist/bigconsole/components/preview/AiPreviewMiniPanel.js.map +1 -1
- package/dist/bigconsole/components/preview/AiPreviewPanel.js +193 -152
- package/dist/bigconsole/components/preview/AiPreviewPanel.js.map +1 -1
- package/dist/bigconsole/components/preview/previewShared.js +41 -23
- package/dist/bigconsole/components/preview/previewShared.js.map +1 -1
- package/dist/bigconsole/components/widgets/ActionConfigDialog.js +342 -308
- package/dist/bigconsole/components/widgets/ActionConfigDialog.js.map +1 -1
- package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js +262 -238
- package/dist/bigconsole/components/widgets/DrilldownConfigPanel.js.map +1 -1
- package/dist/bigconsole/components/widgets/PropertiesPanel.js +783 -867
- package/dist/bigconsole/components/widgets/PropertiesPanel.js.map +1 -1
- package/dist/bigconsole/components/widgets/WidgetErrorBoundary.js +7 -5
- package/dist/bigconsole/components/widgets/WidgetErrorBoundary.js.map +1 -1
- package/dist/bigconsole/components/widgets/WidgetHeader.js +7 -8
- package/dist/bigconsole/components/widgets/WidgetHeader.js.map +1 -1
- package/dist/bigconsole/components/widgets/WidgetRegistry.js +4 -4
- package/dist/bigconsole/components/widgets/WidgetRegistry.js.map +1 -1
- package/dist/bigconsole/components/widgets/WidgetWrapper.js +8 -7
- package/dist/bigconsole/components/widgets/WidgetWrapper.js.map +1 -1
- package/dist/bigconsole/components/widgets/adaptive-card/AdaptiveCardWidget.js +1 -1
- package/dist/bigconsole/components/widgets/adaptive-card/AdaptiveCardWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js +2 -2
- package/dist/bigconsole/components/widgets/calendar/CalendarWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/chart/ChartConfig.js +11 -5
- package/dist/bigconsole/components/widgets/chart/ChartConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/comments/WidgetComments.js +19 -15
- package/dist/bigconsole/components/widgets/comments/WidgetComments.js.map +1 -1
- package/dist/bigconsole/components/widgets/event-logs/EventLogViewer.js +154 -102
- package/dist/bigconsole/components/widgets/event-logs/EventLogViewer.js.map +1 -1
- package/dist/bigconsole/components/widgets/gauge/CircularGauge.js +36 -32
- package/dist/bigconsole/components/widgets/gauge/CircularGauge.js.map +1 -1
- package/dist/bigconsole/components/widgets/gauge/GaugeConfig.js +85 -60
- package/dist/bigconsole/components/widgets/gauge/GaugeConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/gauge/GaugeWidget.js +64 -35
- package/dist/bigconsole/components/widgets/gauge/GaugeWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/gauge/LinearGauge.js +46 -45
- package/dist/bigconsole/components/widgets/gauge/LinearGauge.js.map +1 -1
- package/dist/bigconsole/components/widgets/heatmap/HeatmapConfig.js +35 -24
- package/dist/bigconsole/components/widgets/heatmap/HeatmapConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/iframe-widget/IframeWidget.js +2 -2
- package/dist/bigconsole/components/widgets/iframe-widget/IframeWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js +4 -4
- package/dist/bigconsole/components/widgets/kanban/KanbanWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/kpi-comparison/KPIComparisonWidget.js +153 -90
- package/dist/bigconsole/components/widgets/kpi-comparison/KPIComparisonWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/list/ListConfig.js +8 -2
- package/dist/bigconsole/components/widgets/list/ListConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/list/ListItem.js +1 -1
- package/dist/bigconsole/components/widgets/list/ListItem.js.map +1 -1
- package/dist/bigconsole/components/widgets/map-widget/MapWidget.js +1 -1
- package/dist/bigconsole/components/widgets/map-widget/MapWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/metric-card/MetricCardConfig.js +14 -4
- package/dist/bigconsole/components/widgets/metric-card/MetricCardConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/metric-card/MetricCardWidget.js +112 -89
- package/dist/bigconsole/components/widgets/metric-card/MetricCardWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/metric-card/SparklineChart.js +21 -13
- package/dist/bigconsole/components/widgets/metric-card/SparklineChart.js.map +1 -1
- package/dist/bigconsole/components/widgets/metric-card/index.js +4 -4
- package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js +3 -3
- package/dist/bigconsole/components/widgets/pivot-table/PivotTableWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/progress/ProgressConfig.js +34 -25
- package/dist/bigconsole/components/widgets/progress/ProgressConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/progress/ProgressWidget.js +129 -114
- package/dist/bigconsole/components/widgets/progress/ProgressWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/retention/RetentionWidget.js +3 -3
- package/dist/bigconsole/components/widgets/retention/RetentionWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/states/EmptyState.js +6 -4
- package/dist/bigconsole/components/widgets/states/EmptyState.js.map +1 -1
- package/dist/bigconsole/components/widgets/states/ErrorState.js +7 -5
- package/dist/bigconsole/components/widgets/states/ErrorState.js.map +1 -1
- package/dist/bigconsole/components/widgets/states/LoadingState.js +5 -4
- package/dist/bigconsole/components/widgets/states/LoadingState.js.map +1 -1
- package/dist/bigconsole/components/widgets/table/TableConfig.js +10 -4
- package/dist/bigconsole/components/widgets/table/TableConfig.js.map +1 -1
- package/dist/bigconsole/components/widgets/table/TableHeader.js +1 -1
- package/dist/bigconsole/components/widgets/table/TableHeader.js.map +1 -1
- package/dist/bigconsole/components/widgets/table/TableWidget.js +1 -1
- package/dist/bigconsole/components/widgets/table/TableWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/text-widget/TextWidget.js +1 -1
- package/dist/bigconsole/components/widgets/text-widget/TextWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/timeline/TimelineWidget.js +3 -3
- package/dist/bigconsole/components/widgets/timeline/TimelineWidget.js.map +1 -1
- package/dist/bigconsole/components/widgets/utils/conditionalFormat.js +2 -2
- package/dist/bigconsole/components/widgets/utils/conditionalFormat.js.map +1 -1
- package/dist/bigconsole/components/widgets/utils/targetProgress.js +13 -0
- package/dist/bigconsole/components/widgets/utils/targetProgress.js.map +1 -0
- package/dist/bigconsole/components/widgets/webhook-config/WebhookConfigPanel.js +112 -85
- package/dist/bigconsole/components/widgets/webhook-config/WebhookConfigPanel.js.map +1 -1
- package/dist/bigconsole/components/widgets/widget-actions/WidgetActions.js +28 -20
- package/dist/bigconsole/components/widgets/widget-actions/WidgetActions.js.map +1 -1
- package/dist/bigconsole/components/workflow/WorkflowCard.js +92 -77
- package/dist/bigconsole/components/workflow/WorkflowCard.js.map +1 -1
- package/dist/bigconsole/components/workflow/WorkflowDeleteDialog.js +70 -51
- package/dist/bigconsole/components/workflow/WorkflowDeleteDialog.js.map +1 -1
- package/dist/bigconsole/components/workflow/WorkflowStatusBadge.js +16 -17
- package/dist/bigconsole/components/workflow/WorkflowStatusBadge.js.map +1 -1
- package/dist/bigconsole/customWidget/CustomWidgetBuilderSheet.js +6 -4
- package/dist/bigconsole/customWidget/CustomWidgetBuilderSheet.js.map +1 -1
- package/dist/bigconsole/customWidget/CustomWidgetProposalPanel.js +360 -338
- package/dist/bigconsole/customWidget/CustomWidgetProposalPanel.js.map +1 -1
- package/dist/bigconsole/hooks/useModalFocusTrap.js +53 -0
- package/dist/bigconsole/hooks/useModalFocusTrap.js.map +1 -0
- package/dist/bigconsole/pages/DashboardBuilderPage.js +209 -203
- package/dist/bigconsole/pages/DashboardBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/DashboardViewPage.js +126 -120
- package/dist/bigconsole/pages/DashboardViewPage.js.map +1 -1
- package/dist/bigconsole/pages/DashboardsPage.js +838 -800
- package/dist/bigconsole/pages/DashboardsPage.js.map +1 -1
- package/dist/bigconsole/pages/DataParsersPage.js +263 -315
- package/dist/bigconsole/pages/DataParsersPage.js.map +1 -1
- package/dist/bigconsole/pages/DataSinkBuilderPage.js +301 -341
- package/dist/bigconsole/pages/DataSinkBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/DataSinkViewPage.js +346 -339
- package/dist/bigconsole/pages/DataSinkViewPage.js.map +1 -1
- package/dist/bigconsole/pages/DataSinksPage.js +356 -458
- package/dist/bigconsole/pages/DataSinksPage.js.map +1 -1
- package/dist/bigconsole/pages/DataSourcesPage.js +7 -2
- package/dist/bigconsole/pages/DataSourcesPage.js.map +1 -1
- package/dist/bigconsole/pages/HomePage.js +186 -193
- package/dist/bigconsole/pages/HomePage.js.map +1 -1
- package/dist/bigconsole/pages/InsightsPage.js +887 -740
- package/dist/bigconsole/pages/InsightsPage.js.map +1 -1
- package/dist/bigconsole/pages/ParserBuilderPage.js +679 -637
- package/dist/bigconsole/pages/ParserBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/ParserViewPage.js +368 -342
- package/dist/bigconsole/pages/ParserViewPage.js.map +1 -1
- package/dist/bigconsole/pages/PipelineBuilderPage.js +537 -444
- package/dist/bigconsole/pages/PipelineBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/PipelineViewPage.js +412 -377
- package/dist/bigconsole/pages/PipelineViewPage.js.map +1 -1
- package/dist/bigconsole/pages/PipelinesPage.js +248 -298
- package/dist/bigconsole/pages/PipelinesPage.js.map +1 -1
- package/dist/bigconsole/pages/WidgetDemoPage.js +251 -153
- package/dist/bigconsole/pages/WidgetDemoPage.js.map +1 -1
- package/dist/bigconsole/pages/WorkflowViewPage.js +381 -371
- package/dist/bigconsole/pages/WorkflowViewPage.js.map +1 -1
- package/dist/bigconsole/pages/WorkflowsPage.js +171 -286
- package/dist/bigconsole/pages/WorkflowsPage.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,217 +1,226 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
1
|
+
import { SECTION_FOCUS_RING as e } from "../../common/sectionStyles.js";
|
|
2
|
+
import "../../common/index.js";
|
|
3
|
+
import { BIGCONSOLE_PERMISSIONS as t } from "../../../../constants/permissions.js";
|
|
4
|
+
import { SEMANTIC_COLORS as n } from "../../../utils/semanticTokens.js";
|
|
5
|
+
import { useCallback as r, useEffect as i, useRef as a, useState as o } from "react";
|
|
6
|
+
import { usePermissions as s } from "@burdenoff/fe-libs/shared/providers/shell";
|
|
7
|
+
import { Fragment as c, jsx as l, jsxs as u } from "react/jsx-runtime";
|
|
8
|
+
import { createPortal as d } from "react-dom";
|
|
7
9
|
//#region src/bigconsole/components/dashboard/PageTabsManager/PageTabsManager.tsx
|
|
8
|
-
function
|
|
9
|
-
let { hasPermission:
|
|
10
|
+
function f({ pages: f, activePageId: p, onPageSelect: m, onPageCreate: h, onPageRename: g, onPageDuplicate: _, onPageDelete: v, onPagesReorder: y, editable: b = !0, className: x = "" }) {
|
|
11
|
+
let { hasPermission: S } = s(), C = S(t.DASHBOARD_PAGE_CREATE), w = S(t.DASHBOARD_PAGE_UPDATE), T = S(t.DASHBOARD_PAGE_DELETE), [E, D] = o(null), [O, k] = o(null), [A, j] = o(null), [M, N] = o(""), [P, F] = o(null), [I, L] = o({
|
|
10
12
|
x: 0,
|
|
11
13
|
y: 0
|
|
12
|
-
}),
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}, [
|
|
14
|
+
}), R = a(null), z = a(null);
|
|
15
|
+
i(() => {
|
|
16
|
+
A && R.current && (R.current.focus(), R.current.select());
|
|
17
|
+
}, [A]), i(() => {
|
|
16
18
|
function e(e) {
|
|
17
|
-
|
|
19
|
+
z.current && !z.current.contains(e.target) && F(null);
|
|
18
20
|
}
|
|
19
21
|
return document.addEventListener("mousedown", e), () => document.removeEventListener("mousedown", e);
|
|
20
22
|
}, []);
|
|
21
|
-
let
|
|
22
|
-
|
|
23
|
-
}, []),
|
|
24
|
-
e.preventDefault(), e.dataTransfer.dropEffect = "move",
|
|
25
|
-
}, [
|
|
26
|
-
if (
|
|
27
|
-
let e = [...
|
|
23
|
+
let B = r((e, t) => {
|
|
24
|
+
D(t), e.dataTransfer.effectAllowed = "move";
|
|
25
|
+
}, []), V = r((e, t) => {
|
|
26
|
+
e.preventDefault(), e.dataTransfer.dropEffect = "move", E && E !== t && k(t);
|
|
27
|
+
}, [E]), H = r(() => {
|
|
28
|
+
if (E && O && E !== O && y) {
|
|
29
|
+
let e = [...f].sort((e, t) => e.order - t.order), t = e.findIndex((e) => e.id === E), n = e.findIndex((e) => e.id === O);
|
|
28
30
|
if (t !== -1 && n !== -1) {
|
|
29
31
|
let [r] = e.splice(t, 1);
|
|
30
|
-
e.splice(n, 0, r),
|
|
32
|
+
e.splice(n, 0, r), y(e.map((e) => e.id));
|
|
31
33
|
}
|
|
32
34
|
}
|
|
33
|
-
|
|
35
|
+
D(null), k(null);
|
|
34
36
|
}, [
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
]),
|
|
40
|
-
e.preventDefault(),
|
|
37
|
+
E,
|
|
38
|
+
O,
|
|
39
|
+
f,
|
|
40
|
+
y
|
|
41
|
+
]), U = r((e, t) => {
|
|
42
|
+
e.preventDefault(), F(t), L({
|
|
41
43
|
x: e.clientX,
|
|
42
44
|
y: e.clientY
|
|
43
45
|
});
|
|
44
|
-
}, []),
|
|
45
|
-
|
|
46
|
-
}, []),
|
|
47
|
-
|
|
46
|
+
}, []), W = r((e, t) => {
|
|
47
|
+
j(e), N(t), F(null);
|
|
48
|
+
}, []), G = r(() => {
|
|
49
|
+
A && M.trim() && g && g(A, M.trim()), j(null), N("");
|
|
48
50
|
}, [
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
]),
|
|
53
|
-
|
|
54
|
-
}, []),
|
|
55
|
-
e.key === "Enter" ?
|
|
56
|
-
}, [
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
51
|
+
A,
|
|
52
|
+
M,
|
|
53
|
+
g
|
|
54
|
+
]), K = r(() => {
|
|
55
|
+
j(null), N("");
|
|
56
|
+
}, []), q = r((e) => {
|
|
57
|
+
e.key === "Enter" ? G() : e.key === "Escape" && K();
|
|
58
|
+
}, [G, K]), J = [...f].sort((e, t) => e.order - t.order), Y = r((e, t) => {
|
|
59
|
+
if (A) return;
|
|
60
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
61
|
+
e.preventDefault(), m(t);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
let n = J.findIndex((e) => e.id === t);
|
|
65
|
+
if (n === -1) return;
|
|
66
|
+
let r = null;
|
|
67
|
+
if (e.key === "ArrowRight" ? r = (n + 1) % J.length : e.key === "ArrowLeft" ? r = (n - 1 + J.length) % J.length : e.key === "Home" ? r = 0 : e.key === "End" && (r = J.length - 1), r === null) return;
|
|
68
|
+
e.preventDefault();
|
|
69
|
+
let i = J[r];
|
|
70
|
+
i && (m(i.id), (z.current?.querySelectorAll("[role=\"tab\"]"))?.[r]?.focus());
|
|
71
|
+
}, [
|
|
72
|
+
A,
|
|
73
|
+
m,
|
|
74
|
+
J
|
|
75
|
+
]);
|
|
76
|
+
return /* @__PURE__ */ u("div", {
|
|
77
|
+
ref: z,
|
|
78
|
+
className: `flex min-w-0 items-stretch gap-icon-gap border-b border-[var(--color-border-subtle)] bg-bg-surface px-2 ${x}`,
|
|
79
|
+
"data-testid": "page-tabs",
|
|
70
80
|
children: [
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
borderLeft: D === e.id ? `2px solid ${t.actionPrimaryBg}` : "none",
|
|
90
|
-
flexShrink: 0,
|
|
91
|
-
transition: "background-color 0.15s, border-color 0.15s"
|
|
92
|
-
},
|
|
93
|
-
children: k === e.id ? /* @__PURE__ */ c("input", {
|
|
94
|
-
ref: L,
|
|
95
|
-
type: "text",
|
|
96
|
-
value: j,
|
|
97
|
-
onChange: (e) => M(e.target.value),
|
|
98
|
-
onKeyDown: K,
|
|
99
|
-
onBlur: W,
|
|
100
|
-
style: {
|
|
101
|
-
width: "100px",
|
|
102
|
-
padding: "2px 4px",
|
|
103
|
-
border: `1px solid ${t.actionPrimaryBg}`,
|
|
104
|
-
borderRadius: "2px",
|
|
105
|
-
fontSize: "13px",
|
|
106
|
-
outline: "none",
|
|
107
|
-
backgroundColor: t.bgPrimary,
|
|
108
|
-
color: t.textPrimary
|
|
109
|
-
},
|
|
110
|
-
onClick: (e) => e.stopPropagation()
|
|
111
|
-
}) : /* @__PURE__ */ l(s, { children: [/* @__PURE__ */ c("span", {
|
|
112
|
-
style: {
|
|
113
|
-
fontSize: "13px",
|
|
114
|
-
fontWeight: f === e.id ? 600 : 400,
|
|
115
|
-
color: f === e.id ? t.textPrimary : t.textSecondary
|
|
116
|
-
},
|
|
117
|
-
children: e.name
|
|
118
|
-
}), e.widgetCount !== void 0 && /* @__PURE__ */ c("span", {
|
|
81
|
+
/* @__PURE__ */ l("div", {
|
|
82
|
+
role: "tablist",
|
|
83
|
+
"aria-label": "Dashboard pages",
|
|
84
|
+
className: "flex min-w-0 flex-1 items-center gap-icon-gap overflow-x-auto",
|
|
85
|
+
style: { minHeight: "var(--size-controlHeight-md)" },
|
|
86
|
+
children: J.map((t) => /* @__PURE__ */ l("div", {
|
|
87
|
+
role: "tab",
|
|
88
|
+
tabIndex: p === t.id ? 0 : -1,
|
|
89
|
+
"aria-selected": p === t.id,
|
|
90
|
+
draggable: b && w && !A,
|
|
91
|
+
onDragStart: (e) => B(e, t.id),
|
|
92
|
+
onDragOver: (e) => V(e, t.id),
|
|
93
|
+
onDragEnd: H,
|
|
94
|
+
onContextMenu: (e) => b && (w || T || !!_) && U(e, t.id),
|
|
95
|
+
onClick: () => !A && m(t.id),
|
|
96
|
+
onDoubleClick: () => b && w && W(t.id, t.name),
|
|
97
|
+
onKeyDown: (e) => Y(e, t.id),
|
|
98
|
+
className: e,
|
|
119
99
|
style: {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
100
|
+
position: "relative",
|
|
101
|
+
display: "flex",
|
|
102
|
+
alignItems: "center",
|
|
103
|
+
gap: "6px",
|
|
104
|
+
padding: "var(--space-controlGap) var(--space-formGap)",
|
|
105
|
+
minHeight: "var(--size-controlHeight-md)",
|
|
106
|
+
backgroundColor: p === t.id ? "var(--color-bg-sunken)" : "transparent",
|
|
107
|
+
borderBottom: p === t.id ? "2px solid var(--color-action-primary-bg)" : "2px solid transparent",
|
|
108
|
+
cursor: A === t.id ? "text" : "pointer",
|
|
109
|
+
opacity: E === t.id ? .5 : 1,
|
|
110
|
+
borderLeft: O === t.id ? `2px solid ${n.actionPrimaryBg}` : "none",
|
|
111
|
+
flexShrink: 0,
|
|
112
|
+
transition: "background-color 0.15s, border-color 0.15s"
|
|
125
113
|
},
|
|
126
|
-
children:
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
114
|
+
children: A === t.id ? /* @__PURE__ */ l("input", {
|
|
115
|
+
ref: R,
|
|
116
|
+
type: "text",
|
|
117
|
+
value: M,
|
|
118
|
+
onChange: (e) => N(e.target.value),
|
|
119
|
+
onKeyDown: q,
|
|
120
|
+
onBlur: G,
|
|
121
|
+
style: {
|
|
122
|
+
width: "100px",
|
|
123
|
+
padding: "2px 4px",
|
|
124
|
+
border: `1px solid ${n.actionPrimaryBg}`,
|
|
125
|
+
borderRadius: "2px",
|
|
126
|
+
fontSize: "13px",
|
|
127
|
+
outline: "none",
|
|
128
|
+
backgroundColor: n.bgPrimary,
|
|
129
|
+
color: n.textPrimary
|
|
130
|
+
},
|
|
131
|
+
onClick: (e) => e.stopPropagation()
|
|
132
|
+
}) : /* @__PURE__ */ u(c, { children: [/* @__PURE__ */ l("span", {
|
|
133
|
+
style: {
|
|
134
|
+
fontSize: "13px",
|
|
135
|
+
fontWeight: p === t.id ? 600 : 400,
|
|
136
|
+
color: p === t.id ? n.textPrimary : n.textSecondary
|
|
137
|
+
},
|
|
138
|
+
children: t.name
|
|
139
|
+
}), t.widgetCount !== void 0 && /* @__PURE__ */ l("span", {
|
|
140
|
+
style: {
|
|
141
|
+
fontSize: "10px",
|
|
142
|
+
color: n.textTertiary,
|
|
143
|
+
backgroundColor: n.borderDefault,
|
|
144
|
+
padding: "1px 4px",
|
|
145
|
+
borderRadius: "8px"
|
|
146
|
+
},
|
|
147
|
+
children: t.widgetCount
|
|
148
|
+
})] })
|
|
149
|
+
}, t.id))
|
|
150
|
+
}),
|
|
151
|
+
b && h && C && /* @__PURE__ */ l("button", {
|
|
152
|
+
type: "button",
|
|
153
|
+
onClick: h,
|
|
154
|
+
className: "my-1 inline-flex min-h-control-sm flex-shrink-0 items-center justify-center rounded-button border border-[var(--color-border-subtle)] bg-bg-surface px-3 text-xs font-medium text-text-primary motion-safe:transition-colors hover:bg-bg-accentSubtle focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-bg-surface",
|
|
146
155
|
children: "+ Add Page"
|
|
147
156
|
}),
|
|
148
|
-
|
|
157
|
+
P && d(/* @__PURE__ */ u("div", {
|
|
149
158
|
style: {
|
|
150
159
|
position: "fixed",
|
|
151
|
-
left:
|
|
152
|
-
top:
|
|
153
|
-
backgroundColor:
|
|
154
|
-
border: `1px solid ${
|
|
160
|
+
left: I.x,
|
|
161
|
+
top: I.y,
|
|
162
|
+
backgroundColor: n.bgPrimary,
|
|
163
|
+
border: `1px solid ${n.borderDefault}`,
|
|
155
164
|
borderRadius: "6px",
|
|
156
|
-
boxShadow: "
|
|
165
|
+
boxShadow: "var(--shadow-elevation-3)",
|
|
157
166
|
zIndex: 99999,
|
|
158
167
|
minWidth: "140px"
|
|
159
168
|
},
|
|
160
169
|
onClick: (e) => e.stopPropagation(),
|
|
161
170
|
children: [
|
|
162
|
-
|
|
171
|
+
w && /* @__PURE__ */ l("button", {
|
|
163
172
|
onClick: () => {
|
|
164
|
-
let e =
|
|
165
|
-
e &&
|
|
173
|
+
let e = f.find((e) => e.id === P);
|
|
174
|
+
e && W(P, e.name);
|
|
166
175
|
},
|
|
167
176
|
style: {
|
|
168
177
|
display: "block",
|
|
169
178
|
width: "100%",
|
|
170
179
|
padding: "8px 12px",
|
|
171
180
|
textAlign: "left",
|
|
172
|
-
backgroundColor:
|
|
181
|
+
backgroundColor: n.bgPrimary,
|
|
173
182
|
border: "none",
|
|
174
183
|
cursor: "pointer",
|
|
175
184
|
fontSize: "13px",
|
|
176
|
-
color:
|
|
185
|
+
color: n.textPrimary
|
|
177
186
|
},
|
|
178
187
|
children: "Rename"
|
|
179
188
|
}),
|
|
180
|
-
|
|
189
|
+
_ && C && /* @__PURE__ */ l("button", {
|
|
181
190
|
onClick: () => {
|
|
182
|
-
|
|
191
|
+
_(P), F(null);
|
|
183
192
|
},
|
|
184
193
|
style: {
|
|
185
194
|
display: "block",
|
|
186
195
|
width: "100%",
|
|
187
196
|
padding: "8px 12px",
|
|
188
197
|
textAlign: "left",
|
|
189
|
-
backgroundColor:
|
|
198
|
+
backgroundColor: n.bgPrimary,
|
|
190
199
|
border: "none",
|
|
191
200
|
cursor: "pointer",
|
|
192
201
|
fontSize: "13px",
|
|
193
|
-
color:
|
|
202
|
+
color: n.textPrimary
|
|
194
203
|
},
|
|
195
204
|
children: "Duplicate"
|
|
196
205
|
}),
|
|
197
|
-
|
|
206
|
+
v && T && f.length > 1 && /* @__PURE__ */ u(c, { children: [/* @__PURE__ */ l("div", { style: {
|
|
198
207
|
height: "1px",
|
|
199
|
-
backgroundColor:
|
|
208
|
+
backgroundColor: n.borderDefault,
|
|
200
209
|
margin: "4px 0"
|
|
201
|
-
} }), /* @__PURE__ */
|
|
210
|
+
} }), /* @__PURE__ */ l("button", {
|
|
202
211
|
onClick: () => {
|
|
203
|
-
window.confirm("Are you sure you want to delete this page?") &&
|
|
212
|
+
window.confirm("Are you sure you want to delete this page?") && v(P), F(null);
|
|
204
213
|
},
|
|
205
214
|
style: {
|
|
206
215
|
display: "block",
|
|
207
216
|
width: "100%",
|
|
208
217
|
padding: "8px 12px",
|
|
209
218
|
textAlign: "left",
|
|
210
|
-
backgroundColor:
|
|
219
|
+
backgroundColor: n.bgPrimary,
|
|
211
220
|
border: "none",
|
|
212
221
|
cursor: "pointer",
|
|
213
222
|
fontSize: "13px",
|
|
214
|
-
color:
|
|
223
|
+
color: n.statusErrorText
|
|
215
224
|
},
|
|
216
225
|
children: "Delete"
|
|
217
226
|
})] })
|
|
@@ -221,6 +230,6 @@ function d({ pages: d, activePageId: f, onPageSelect: p, onPageCreate: m, onPage
|
|
|
221
230
|
});
|
|
222
231
|
}
|
|
223
232
|
//#endregion
|
|
224
|
-
export {
|
|
233
|
+
export { f as default };
|
|
225
234
|
|
|
226
235
|
//# sourceMappingURL=PageTabsManager.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PageTabsManager.js","names":[],"sources":["../../../../../src/bigconsole/components/dashboard/PageTabsManager/PageTabsManager.tsx"],"sourcesContent":["/**\n * PageTabsManager Component\n *\n * Manages dashboard page tabs with drag-and-drop reordering.\n */\n\nimport React, { useState, useCallback, useRef, useEffect } from 'react';\nimport { createPortal } from 'react-dom';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { SEMANTIC_COLORS } from '../../../utils/semanticTokens';\nimport { BIGCONSOLE_PERMISSIONS } from '../../../../constants/permissions';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface DashboardPageTab {\n id: string;\n name: string;\n order: number;\n widgetCount?: number;\n}\n\nexport interface PageTabsManagerProps {\n pages: DashboardPageTab[];\n activePageId: string;\n onPageSelect: (pageId: string) => void;\n onPageCreate?: () => void;\n onPageRename?: (pageId: string, newName: string) => void;\n onPageDuplicate?: (pageId: string) => void;\n onPageDelete?: (pageId: string) => void;\n onPagesReorder?: (pageIds: string[]) => void;\n editable?: boolean;\n className?: string;\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport function PageTabsManager({\n pages,\n activePageId,\n onPageSelect,\n onPageCreate,\n onPageRename,\n onPageDuplicate,\n onPageDelete,\n onPagesReorder,\n editable = true,\n className = '',\n}: PageTabsManagerProps) {\n const { hasPermission } = usePermissions();\n const canCreatePage = hasPermission(BIGCONSOLE_PERMISSIONS.DASHBOARD_PAGE_CREATE);\n const canUpdatePage = hasPermission(BIGCONSOLE_PERMISSIONS.DASHBOARD_PAGE_UPDATE);\n const canDeletePage = hasPermission(BIGCONSOLE_PERMISSIONS.DASHBOARD_PAGE_DELETE);\n\n const [draggedId, setDraggedId] = useState<string | null>(null);\n const [dragOverId, setDragOverId] = useState<string | null>(null);\n const [editingId, setEditingId] = useState<string | null>(null);\n const [editingName, setEditingName] = useState('');\n const [contextMenuId, setContextMenuId] = useState<string | null>(null);\n const [contextMenuPos, setContextMenuPos] = useState({ x: 0, y: 0 });\n\n const editInputRef = useRef<HTMLInputElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n\n // Focus input when editing\n useEffect(() => {\n if (editingId && editInputRef.current) {\n editInputRef.current.focus();\n editInputRef.current.select();\n }\n }, [editingId]);\n\n // Close context menu on click outside\n useEffect(() => {\n function handleClickOutside(event: MouseEvent) {\n if (containerRef.current && !containerRef.current.contains(event.target as Node)) {\n setContextMenuId(null);\n }\n }\n\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, []);\n\n // Drag handlers\n const handleDragStart = useCallback((e: React.DragEvent, pageId: string) => {\n setDraggedId(pageId);\n e.dataTransfer.effectAllowed = 'move';\n }, []);\n\n const handleDragOver = useCallback(\n (e: React.DragEvent, pageId: string) => {\n e.preventDefault();\n e.dataTransfer.dropEffect = 'move';\n if (draggedId && draggedId !== pageId) {\n setDragOverId(pageId);\n }\n },\n [draggedId]\n );\n\n const handleDragEnd = useCallback(() => {\n if (draggedId && dragOverId && draggedId !== dragOverId && onPagesReorder) {\n const orderedPages = [...pages];\n const draggedIndex = orderedPages.findIndex((p) => p.id === draggedId);\n const targetIndex = orderedPages.findIndex((p) => p.id === dragOverId);\n\n if (draggedIndex !== -1 && targetIndex !== -1) {\n const [draggedPage] = orderedPages.splice(draggedIndex, 1);\n orderedPages.splice(targetIndex, 0, draggedPage);\n onPagesReorder(orderedPages.map((p) => p.id));\n }\n }\n\n setDraggedId(null);\n setDragOverId(null);\n }, [draggedId, dragOverId, pages, onPagesReorder]);\n\n // Context menu handler\n const handleContextMenu = useCallback((e: React.MouseEvent, pageId: string) => {\n e.preventDefault();\n setContextMenuId(pageId);\n setContextMenuPos({ x: e.clientX, y: e.clientY });\n }, []);\n\n // Start editing\n const handleStartEdit = useCallback((pageId: string, currentName: string) => {\n setEditingId(pageId);\n setEditingName(currentName);\n setContextMenuId(null);\n }, []);\n\n // Save edit\n const handleSaveEdit = useCallback(() => {\n if (editingId && editingName.trim() && onPageRename) {\n onPageRename(editingId, editingName.trim());\n }\n setEditingId(null);\n setEditingName('');\n }, [editingId, editingName, onPageRename]);\n\n // Cancel edit\n const handleCancelEdit = useCallback(() => {\n setEditingId(null);\n setEditingName('');\n }, []);\n\n // Handle key press in edit mode\n const handleEditKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === 'Enter') {\n handleSaveEdit();\n } else if (e.key === 'Escape') {\n handleCancelEdit();\n }\n },\n [handleSaveEdit, handleCancelEdit]\n );\n\n return (\n <div\n ref={containerRef}\n className={className}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n padding: '0 8px',\n overflowX: 'auto',\n backgroundColor: SEMANTIC_COLORS.bgSecondary,\n borderBottom: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n minHeight: '40px',\n }}\n >\n {/* Page Tabs */}\n {pages\n .sort((a, b) => a.order - b.order)\n .map((page) => (\n <div\n key={page.id}\n draggable={editable && canUpdatePage && !editingId}\n onDragStart={(e) => handleDragStart(e, page.id)}\n onDragOver={(e) => handleDragOver(e, page.id)}\n onDragEnd={handleDragEnd}\n onContextMenu={(e) =>\n editable && (canUpdatePage || canDeletePage || !!onPageDuplicate) && handleContextMenu(e, page.id)\n }\n onClick={() => !editingId && onPageSelect(page.id)}\n onDoubleClick={() => editable && canUpdatePage && handleStartEdit(page.id, page.name)}\n style={{\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n gap: '6px',\n padding: '8px 12px',\n backgroundColor: activePageId === page.id ? SEMANTIC_COLORS.bgPrimary : 'transparent',\n borderBottom:\n activePageId === page.id ? `2px solid ${SEMANTIC_COLORS.actionPrimaryBg}` : '2px solid transparent',\n cursor: editingId === page.id ? 'text' : 'pointer',\n opacity: draggedId === page.id ? 0.5 : 1,\n borderLeft: dragOverId === page.id ? `2px solid ${SEMANTIC_COLORS.actionPrimaryBg}` : 'none',\n flexShrink: 0,\n transition: 'background-color 0.15s, border-color 0.15s',\n }}\n >\n {editingId === page.id ? (\n <input\n ref={editInputRef}\n type=\"text\"\n value={editingName}\n onChange={(e) => setEditingName(e.target.value)}\n onKeyDown={handleEditKeyDown}\n onBlur={handleSaveEdit}\n style={{\n width: '100px',\n padding: '2px 4px',\n border: `1px solid ${SEMANTIC_COLORS.actionPrimaryBg}`,\n borderRadius: '2px',\n fontSize: '13px',\n outline: 'none',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n color: SEMANTIC_COLORS.textPrimary,\n }}\n onClick={(e) => e.stopPropagation()}\n />\n ) : (\n <>\n <span\n style={{\n fontSize: '13px',\n fontWeight: activePageId === page.id ? 600 : 400,\n color: activePageId === page.id ? SEMANTIC_COLORS.textPrimary : SEMANTIC_COLORS.textSecondary,\n }}\n >\n {page.name}\n </span>\n {page.widgetCount !== undefined && (\n <span\n style={{\n fontSize: '10px',\n color: SEMANTIC_COLORS.textTertiary,\n backgroundColor: SEMANTIC_COLORS.borderDefault,\n padding: '1px 4px',\n borderRadius: '8px',\n }}\n >\n {page.widgetCount}\n </span>\n )}\n </>\n )}\n </div>\n ))}\n\n {/* Add Page Button */}\n {editable && onPageCreate && canCreatePage && (\n <button\n onClick={onPageCreate}\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: '6px 12px',\n backgroundColor: SEMANTIC_COLORS.actionPrimaryBg,\n border: 'none',\n borderRadius: '4px',\n cursor: 'pointer',\n color: '#ffffff',\n fontSize: '12px',\n fontWeight: 500,\n flexShrink: 0,\n marginLeft: '8px',\n }}\n >\n + Add Page\n </button>\n )}\n\n {/* Context Menu - rendered via portal */}\n {contextMenuId &&\n createPortal(\n <div\n style={{\n position: 'fixed',\n left: contextMenuPos.x,\n top: contextMenuPos.y,\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n border: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n borderRadius: '6px',\n boxShadow: '0 8px 24px rgba(0,0,0,0.2)',\n zIndex: 99999,\n minWidth: '140px',\n }}\n onClick={(e) => e.stopPropagation()}\n >\n {canUpdatePage && (\n <button\n onClick={() => {\n const page = pages.find((p) => p.id === contextMenuId);\n if (page) handleStartEdit(contextMenuId, page.name);\n }}\n style={{\n display: 'block',\n width: '100%',\n padding: '8px 12px',\n textAlign: 'left',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n border: 'none',\n cursor: 'pointer',\n fontSize: '13px',\n color: SEMANTIC_COLORS.textPrimary,\n }}\n >\n Rename\n </button>\n )}\n {onPageDuplicate && canCreatePage && (\n <button\n onClick={() => {\n onPageDuplicate(contextMenuId);\n setContextMenuId(null);\n }}\n style={{\n display: 'block',\n width: '100%',\n padding: '8px 12px',\n textAlign: 'left',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n border: 'none',\n cursor: 'pointer',\n fontSize: '13px',\n color: SEMANTIC_COLORS.textPrimary,\n }}\n >\n Duplicate\n </button>\n )}\n {onPageDelete && canDeletePage && pages.length > 1 && (\n <>\n <div style={{ height: '1px', backgroundColor: SEMANTIC_COLORS.borderDefault, margin: '4px 0' }} />\n <button\n onClick={() => {\n if (window.confirm('Are you sure you want to delete this page?')) {\n onPageDelete(contextMenuId);\n }\n setContextMenuId(null);\n }}\n style={{\n display: 'block',\n width: '100%',\n padding: '8px 12px',\n textAlign: 'left',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n border: 'none',\n cursor: 'pointer',\n fontSize: '13px',\n color: SEMANTIC_COLORS.statusErrorText,\n }}\n >\n Delete\n </button>\n </>\n )}\n </div>,\n document.body\n )}\n </div>\n );\n}\n\nexport default PageTabsManager;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PageTabsManager.js","names":[],"sources":["../../../../../src/bigconsole/components/dashboard/PageTabsManager/PageTabsManager.tsx"],"sourcesContent":["/**\n * PageTabsManager Component\n *\n * Manages dashboard page tabs with drag-and-drop reordering.\n */\n\nimport React, { useState, useCallback, useRef, useEffect } from 'react';\nimport { createPortal } from 'react-dom';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { SEMANTIC_COLORS } from '../../../utils/semanticTokens';\nimport { BIGCONSOLE_PERMISSIONS } from '../../../../constants/permissions';\nimport { SECTION_FOCUS_RING } from '../../common';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface DashboardPageTab {\n id: string;\n name: string;\n order: number;\n widgetCount?: number;\n}\n\nexport interface PageTabsManagerProps {\n pages: DashboardPageTab[];\n activePageId: string;\n onPageSelect: (pageId: string) => void;\n onPageCreate?: () => void;\n onPageRename?: (pageId: string, newName: string) => void;\n onPageDuplicate?: (pageId: string) => void;\n onPageDelete?: (pageId: string) => void;\n onPagesReorder?: (pageIds: string[]) => void;\n editable?: boolean;\n className?: string;\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\nexport function PageTabsManager({\n pages,\n activePageId,\n onPageSelect,\n onPageCreate,\n onPageRename,\n onPageDuplicate,\n onPageDelete,\n onPagesReorder,\n editable = true,\n className = '',\n}: PageTabsManagerProps) {\n const { hasPermission } = usePermissions();\n const canCreatePage = hasPermission(BIGCONSOLE_PERMISSIONS.DASHBOARD_PAGE_CREATE);\n const canUpdatePage = hasPermission(BIGCONSOLE_PERMISSIONS.DASHBOARD_PAGE_UPDATE);\n const canDeletePage = hasPermission(BIGCONSOLE_PERMISSIONS.DASHBOARD_PAGE_DELETE);\n\n const [draggedId, setDraggedId] = useState<string | null>(null);\n const [dragOverId, setDragOverId] = useState<string | null>(null);\n const [editingId, setEditingId] = useState<string | null>(null);\n const [editingName, setEditingName] = useState('');\n const [contextMenuId, setContextMenuId] = useState<string | null>(null);\n const [contextMenuPos, setContextMenuPos] = useState({ x: 0, y: 0 });\n\n const editInputRef = useRef<HTMLInputElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n\n // Focus input when editing\n useEffect(() => {\n if (editingId && editInputRef.current) {\n editInputRef.current.focus();\n editInputRef.current.select();\n }\n }, [editingId]);\n\n // Close context menu on click outside\n useEffect(() => {\n function handleClickOutside(event: MouseEvent) {\n if (containerRef.current && !containerRef.current.contains(event.target as Node)) {\n setContextMenuId(null);\n }\n }\n\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, []);\n\n // Drag handlers\n const handleDragStart = useCallback((e: React.DragEvent, pageId: string) => {\n setDraggedId(pageId);\n e.dataTransfer.effectAllowed = 'move';\n }, []);\n\n const handleDragOver = useCallback(\n (e: React.DragEvent, pageId: string) => {\n e.preventDefault();\n e.dataTransfer.dropEffect = 'move';\n if (draggedId && draggedId !== pageId) {\n setDragOverId(pageId);\n }\n },\n [draggedId]\n );\n\n const handleDragEnd = useCallback(() => {\n if (draggedId && dragOverId && draggedId !== dragOverId && onPagesReorder) {\n // Sort by `order` first, exactly like the render below. Reordering from\n // the raw prop order would persist a sequence that differs from the one\n // the user just dragged whenever `pages` arrives unsorted.\n const orderedPages = [...pages].sort((a, b) => a.order - b.order);\n const draggedIndex = orderedPages.findIndex((p) => p.id === draggedId);\n const targetIndex = orderedPages.findIndex((p) => p.id === dragOverId);\n\n if (draggedIndex !== -1 && targetIndex !== -1) {\n const [draggedPage] = orderedPages.splice(draggedIndex, 1);\n orderedPages.splice(targetIndex, 0, draggedPage);\n onPagesReorder(orderedPages.map((p) => p.id));\n }\n }\n\n setDraggedId(null);\n setDragOverId(null);\n }, [draggedId, dragOverId, pages, onPagesReorder]);\n\n // Context menu handler\n const handleContextMenu = useCallback((e: React.MouseEvent, pageId: string) => {\n e.preventDefault();\n setContextMenuId(pageId);\n setContextMenuPos({ x: e.clientX, y: e.clientY });\n }, []);\n\n // Start editing\n const handleStartEdit = useCallback((pageId: string, currentName: string) => {\n setEditingId(pageId);\n setEditingName(currentName);\n setContextMenuId(null);\n }, []);\n\n // Save edit\n const handleSaveEdit = useCallback(() => {\n if (editingId && editingName.trim() && onPageRename) {\n onPageRename(editingId, editingName.trim());\n }\n setEditingId(null);\n setEditingName('');\n }, [editingId, editingName, onPageRename]);\n\n // Cancel edit\n const handleCancelEdit = useCallback(() => {\n setEditingId(null);\n setEditingName('');\n }, []);\n\n // Handle key press in edit mode\n const handleEditKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === 'Enter') {\n handleSaveEdit();\n } else if (e.key === 'Escape') {\n handleCancelEdit();\n }\n },\n [handleSaveEdit, handleCancelEdit]\n );\n\n // `pages` is a prop — sorting it in place mutates the caller's array. Copy first.\n const orderedPages = [...pages].sort((a, b) => a.order - b.order);\n\n /**\n * Keyboard support for the tablist.\n *\n * The tabs carry `role=\"tab\"` and a roving `tabIndex`, which promises the\n * standard tab-list keyboard contract: arrows move between tabs, Home/End jump\n * to the ends, and Enter/Space activate. Without this handler the roving index\n * would leave every non-active page unreachable by keyboard.\n */\n const handleTabKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLDivElement>, pageId: string) => {\n if (editingId) return;\n\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onPageSelect(pageId);\n return;\n }\n\n const currentIndex = orderedPages.findIndex((p) => p.id === pageId);\n if (currentIndex === -1) return;\n\n let nextIndex: number | null = null;\n if (e.key === 'ArrowRight') nextIndex = (currentIndex + 1) % orderedPages.length;\n else if (e.key === 'ArrowLeft') nextIndex = (currentIndex - 1 + orderedPages.length) % orderedPages.length;\n else if (e.key === 'Home') nextIndex = 0;\n else if (e.key === 'End') nextIndex = orderedPages.length - 1;\n\n if (nextIndex === null) return;\n\n e.preventDefault();\n const nextPage = orderedPages[nextIndex];\n if (!nextPage) return;\n onPageSelect(nextPage.id);\n // Roving tabindex: the newly selected tab becomes the focusable one, so\n // move focus with it or the user loses their place in the strip.\n const tabs = containerRef.current?.querySelectorAll<HTMLElement>('[role=\"tab\"]');\n tabs?.[nextIndex]?.focus();\n },\n [editingId, onPageSelect, orderedPages]\n );\n\n return (\n <div\n ref={containerRef}\n className={`flex min-w-0 items-stretch gap-icon-gap border-b border-[var(--color-border-subtle)] bg-bg-surface px-2 ${className}`}\n data-testid=\"page-tabs\"\n >\n <div\n role=\"tablist\"\n aria-label=\"Dashboard pages\"\n className=\"flex min-w-0 flex-1 items-center gap-icon-gap overflow-x-auto\"\n style={{ minHeight: 'var(--size-controlHeight-md)' }}\n >\n {/* Page Tabs */}\n {orderedPages.map((page) => (\n <div\n key={page.id}\n role=\"tab\"\n tabIndex={activePageId === page.id ? 0 : -1}\n aria-selected={activePageId === page.id}\n draggable={editable && canUpdatePage && !editingId}\n onDragStart={(e) => handleDragStart(e, page.id)}\n onDragOver={(e) => handleDragOver(e, page.id)}\n onDragEnd={handleDragEnd}\n onContextMenu={(e) =>\n editable && (canUpdatePage || canDeletePage || !!onPageDuplicate) && handleContextMenu(e, page.id)\n }\n onClick={() => !editingId && onPageSelect(page.id)}\n onDoubleClick={() => editable && canUpdatePage && handleStartEdit(page.id, page.name)}\n onKeyDown={(e) => handleTabKeyDown(e, page.id)}\n className={SECTION_FOCUS_RING}\n style={{\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n gap: '6px',\n padding: 'var(--space-controlGap) var(--space-formGap)',\n minHeight: 'var(--size-controlHeight-md)',\n backgroundColor: activePageId === page.id ? 'var(--color-bg-sunken)' : 'transparent',\n borderBottom:\n activePageId === page.id ? '2px solid var(--color-action-primary-bg)' : '2px solid transparent',\n cursor: editingId === page.id ? 'text' : 'pointer',\n opacity: draggedId === page.id ? 0.5 : 1,\n borderLeft: dragOverId === page.id ? `2px solid ${SEMANTIC_COLORS.actionPrimaryBg}` : 'none',\n flexShrink: 0,\n transition: 'background-color 0.15s, border-color 0.15s',\n }}\n >\n {editingId === page.id ? (\n <input\n ref={editInputRef}\n type=\"text\"\n value={editingName}\n onChange={(e) => setEditingName(e.target.value)}\n onKeyDown={handleEditKeyDown}\n onBlur={handleSaveEdit}\n style={{\n width: '100px',\n padding: '2px 4px',\n border: `1px solid ${SEMANTIC_COLORS.actionPrimaryBg}`,\n borderRadius: '2px',\n fontSize: '13px',\n outline: 'none',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n color: SEMANTIC_COLORS.textPrimary,\n }}\n onClick={(e) => e.stopPropagation()}\n />\n ) : (\n <>\n <span\n style={{\n fontSize: '13px',\n fontWeight: activePageId === page.id ? 600 : 400,\n color: activePageId === page.id ? SEMANTIC_COLORS.textPrimary : SEMANTIC_COLORS.textSecondary,\n }}\n >\n {page.name}\n </span>\n {page.widgetCount !== undefined && (\n <span\n style={{\n fontSize: '10px',\n color: SEMANTIC_COLORS.textTertiary,\n backgroundColor: SEMANTIC_COLORS.borderDefault,\n padding: '1px 4px',\n borderRadius: '8px',\n }}\n >\n {page.widgetCount}\n </span>\n )}\n </>\n )}\n </div>\n ))}\n </div>\n\n {/* Add Page Button — outside the scroller so a long tab list never hides it */}\n {editable && onPageCreate && canCreatePage && (\n <button\n type=\"button\"\n onClick={onPageCreate}\n className={`my-1 inline-flex min-h-control-sm flex-shrink-0 items-center justify-center rounded-button border border-[var(--color-border-subtle)] bg-bg-surface px-3 text-xs font-medium text-text-primary motion-safe:transition-colors hover:bg-bg-accentSubtle ${SECTION_FOCUS_RING}`}\n >\n + Add Page\n </button>\n )}\n\n {/* Context Menu - rendered via portal */}\n {contextMenuId &&\n createPortal(\n <div\n style={{\n position: 'fixed',\n left: contextMenuPos.x,\n top: contextMenuPos.y,\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n border: `1px solid ${SEMANTIC_COLORS.borderDefault}`,\n borderRadius: '6px',\n boxShadow: 'var(--shadow-elevation-3)',\n zIndex: 99999,\n minWidth: '140px',\n }}\n onClick={(e) => e.stopPropagation()}\n >\n {canUpdatePage && (\n <button\n onClick={() => {\n const page = pages.find((p) => p.id === contextMenuId);\n if (page) handleStartEdit(contextMenuId, page.name);\n }}\n style={{\n display: 'block',\n width: '100%',\n padding: '8px 12px',\n textAlign: 'left',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n border: 'none',\n cursor: 'pointer',\n fontSize: '13px',\n color: SEMANTIC_COLORS.textPrimary,\n }}\n >\n Rename\n </button>\n )}\n {onPageDuplicate && canCreatePage && (\n <button\n onClick={() => {\n onPageDuplicate(contextMenuId);\n setContextMenuId(null);\n }}\n style={{\n display: 'block',\n width: '100%',\n padding: '8px 12px',\n textAlign: 'left',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n border: 'none',\n cursor: 'pointer',\n fontSize: '13px',\n color: SEMANTIC_COLORS.textPrimary,\n }}\n >\n Duplicate\n </button>\n )}\n {onPageDelete && canDeletePage && pages.length > 1 && (\n <>\n <div style={{ height: '1px', backgroundColor: SEMANTIC_COLORS.borderDefault, margin: '4px 0' }} />\n <button\n onClick={() => {\n if (window.confirm('Are you sure you want to delete this page?')) {\n onPageDelete(contextMenuId);\n }\n setContextMenuId(null);\n }}\n style={{\n display: 'block',\n width: '100%',\n padding: '8px 12px',\n textAlign: 'left',\n backgroundColor: SEMANTIC_COLORS.bgPrimary,\n border: 'none',\n cursor: 'pointer',\n fontSize: '13px',\n color: SEMANTIC_COLORS.statusErrorText,\n }}\n >\n Delete\n </button>\n </>\n )}\n </div>,\n document.body\n )}\n </div>\n );\n}\n\nexport default PageTabsManager;\n"],"mappings":"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"}
|
|
@@ -101,11 +101,12 @@ function p({ dashboardId: p, currentFilters: m, currentLayout: h, onViewLoad: g,
|
|
|
101
101
|
position: "fixed",
|
|
102
102
|
top: z.top,
|
|
103
103
|
left: Math.max(16, z.left),
|
|
104
|
-
minWidth: "280px",
|
|
104
|
+
minWidth: "min(280px, calc(100vw - 2rem))",
|
|
105
|
+
maxWidth: "calc(100vw - 2rem)",
|
|
105
106
|
backgroundColor: U,
|
|
106
107
|
border: `1px solid ${n.borderDefault}`,
|
|
107
108
|
borderRadius: "8px",
|
|
108
|
-
boxShadow: "
|
|
109
|
+
boxShadow: "var(--shadow-elevation-3)",
|
|
109
110
|
zIndex: 99998,
|
|
110
111
|
overflow: "hidden"
|
|
111
112
|
},
|
|
@@ -130,7 +131,7 @@ function p({ dashboardId: p, currentFilters: m, currentLayout: h, onViewLoad: g,
|
|
|
130
131
|
style: {
|
|
131
132
|
padding: "4px 10px",
|
|
132
133
|
backgroundColor: n.actionPrimaryBg,
|
|
133
|
-
color: "
|
|
134
|
+
color: "var(--color-action-primary-text)",
|
|
134
135
|
border: "none",
|
|
135
136
|
borderRadius: "4px",
|
|
136
137
|
cursor: "pointer",
|
|
@@ -305,20 +306,27 @@ function p({ dashboardId: p, currentFilters: m, currentLayout: h, onViewLoad: g,
|
|
|
305
306
|
left: 0,
|
|
306
307
|
right: 0,
|
|
307
308
|
bottom: 0,
|
|
308
|
-
backgroundColor: "
|
|
309
|
+
backgroundColor: "var(--color-overlay-scrim)",
|
|
309
310
|
display: "flex",
|
|
310
311
|
alignItems: "center",
|
|
311
312
|
justifyContent: "center",
|
|
313
|
+
padding: "var(--space-formGap)",
|
|
312
314
|
zIndex: 99999,
|
|
313
315
|
isolation: "isolate"
|
|
314
316
|
},
|
|
315
317
|
onClick: () => M(!1),
|
|
316
318
|
children: /* @__PURE__ */ u("div", {
|
|
319
|
+
role: "dialog",
|
|
320
|
+
"aria-modal": "true",
|
|
321
|
+
"aria-labelledby": "saved-view-dialog-title",
|
|
317
322
|
style: {
|
|
318
|
-
width: "
|
|
323
|
+
width: "100%",
|
|
324
|
+
maxWidth: "400px",
|
|
325
|
+
maxHeight: "85vh",
|
|
326
|
+
overflowY: "auto",
|
|
319
327
|
backgroundColor: U,
|
|
320
|
-
borderRadius: "
|
|
321
|
-
boxShadow: "
|
|
328
|
+
borderRadius: "var(--radius-card)",
|
|
329
|
+
boxShadow: "var(--shadow-elevation-3)",
|
|
322
330
|
overflow: "hidden",
|
|
323
331
|
position: "relative",
|
|
324
332
|
zIndex: 1e5,
|
|
@@ -332,6 +340,7 @@ function p({ dashboardId: p, currentFilters: m, currentLayout: h, onViewLoad: g,
|
|
|
332
340
|
borderBottom: `1px solid ${n.borderDefault}`
|
|
333
341
|
},
|
|
334
342
|
children: /* @__PURE__ */ l("h3", {
|
|
343
|
+
id: "saved-view-dialog-title",
|
|
335
344
|
style: {
|
|
336
345
|
margin: 0,
|
|
337
346
|
fontSize: "16px",
|
|
@@ -449,7 +458,7 @@ function p({ dashboardId: p, currentFilters: m, currentLayout: h, onViewLoad: g,
|
|
|
449
458
|
style: {
|
|
450
459
|
padding: "10px 20px",
|
|
451
460
|
backgroundColor: N.trim() ? n.actionPrimaryBg : n.bgSecondary,
|
|
452
|
-
color: N.trim() ? "
|
|
461
|
+
color: N.trim() ? "var(--color-action-primary-text)" : n.textSecondary,
|
|
453
462
|
border: "none",
|
|
454
463
|
borderRadius: "6px",
|
|
455
464
|
cursor: N.trim() ? "pointer" : "not-allowed",
|