@burdenoff/microfe-bigconsole 2026.804.2 → 2026.805.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/bigconsole/AdminRoot.js +21 -16
  2. package/dist/bigconsole/AdminRoot.js.map +1 -1
  3. package/dist/bigconsole/BigConsoleRoot.js +44 -39
  4. package/dist/bigconsole/BigConsoleRoot.js.map +1 -1
  5. package/dist/bigconsole/components/dashboard/DashboardToolbar.js +115 -100
  6. package/dist/bigconsole/components/dashboard/DashboardToolbar.js.map +1 -1
  7. package/dist/bigconsole/components/dashboard/PageTabsManager/PageTabsManager.js +100 -98
  8. package/dist/bigconsole/components/dashboard/PageTabsManager/PageTabsManager.js.map +1 -1
  9. package/dist/bigconsole/components/dashboard/ShareDialog/EmbedTab.js +164 -161
  10. package/dist/bigconsole/components/dashboard/ShareDialog/EmbedTab.js.map +1 -1
  11. package/dist/bigconsole/components/datasink/DataSinkCard.js +20 -20
  12. package/dist/bigconsole/components/datasink/DataSinkCard.js.map +1 -1
  13. package/dist/bigconsole/components/datasink/ImportDataGuideDialog.js +216 -49
  14. package/dist/bigconsole/components/datasink/ImportDataGuideDialog.js.map +1 -1
  15. package/dist/bigconsole/components/widgets/ActionConfigDialog.js +96 -90
  16. package/dist/bigconsole/components/widgets/ActionConfigDialog.js.map +1 -1
  17. package/dist/bigconsole/components/widgets/WidgetMenu.js +87 -76
  18. package/dist/bigconsole/components/widgets/WidgetMenu.js.map +1 -1
  19. package/dist/bigconsole/components/widgets/widget-actions/WidgetActions.js +120 -118
  20. package/dist/bigconsole/components/widgets/widget-actions/WidgetActions.js.map +1 -1
  21. package/dist/bigconsole/pages/DashboardBuilderPage.js +113 -104
  22. package/dist/bigconsole/pages/DashboardBuilderPage.js.map +1 -1
  23. package/dist/bigconsole/pages/DashboardViewPage.js +208 -199
  24. package/dist/bigconsole/pages/DashboardViewPage.js.map +1 -1
  25. package/dist/bigconsole/pages/DashboardsPage.js +376 -325
  26. package/dist/bigconsole/pages/DashboardsPage.js.map +1 -1
  27. package/dist/bigconsole/pages/DataParsersPage.js +135 -125
  28. package/dist/bigconsole/pages/DataParsersPage.js.map +1 -1
  29. package/dist/bigconsole/pages/DataSinkBuilderPage.js +182 -172
  30. package/dist/bigconsole/pages/DataSinkBuilderPage.js.map +1 -1
  31. package/dist/bigconsole/pages/DataSinkViewPage.js +233 -198
  32. package/dist/bigconsole/pages/DataSinkViewPage.js.map +1 -1
  33. package/dist/bigconsole/pages/DataSinksPage.js +281 -268
  34. package/dist/bigconsole/pages/DataSinksPage.js.map +1 -1
  35. package/dist/bigconsole/pages/ParserBuilderPage.js +238 -223
  36. package/dist/bigconsole/pages/ParserBuilderPage.js.map +1 -1
  37. package/dist/bigconsole/pages/ParserViewPage.js +162 -144
  38. package/dist/bigconsole/pages/ParserViewPage.js.map +1 -1
  39. package/dist/bigconsole/pages/PipelineBuilderPage.js +212 -204
  40. package/dist/bigconsole/pages/PipelineBuilderPage.js.map +1 -1
  41. package/dist/bigconsole/pages/PipelineViewPage.js +191 -183
  42. package/dist/bigconsole/pages/PipelineViewPage.js.map +1 -1
  43. package/dist/bigconsole/pages/PipelinesPage.js +128 -103
  44. package/dist/bigconsole/pages/PipelinesPage.js.map +1 -1
  45. package/dist/bigconsole/pages/WorkflowViewPage.js +238 -217
  46. package/dist/bigconsole/pages/WorkflowViewPage.js.map +1 -1
  47. package/dist/bigconsole/pages/WorkflowsPage.js +116 -102
  48. package/dist/bigconsole/pages/WorkflowsPage.js.map +1 -1
  49. package/dist/bigconsole/utils/csv.js +91 -0
  50. package/dist/bigconsole/utils/csv.js.map +1 -0
  51. package/dist/constants/permissions.js +83 -0
  52. package/dist/constants/permissions.js.map +1 -0
  53. package/package.json +2 -2
@@ -1,137 +1,139 @@
1
- import { SEMANTIC_COLORS as e } from "../../../utils/semanticTokens.js";
2
- import { useCallback as t, useEffect as n, useRef as r, useState as i } from "react";
3
- import { Fragment as a, jsx as o, jsxs as s } from "react/jsx-runtime";
4
- import { createPortal as c } from "react-dom";
1
+ import { BIGCONSOLE_PERMISSIONS as e } from "../../../../constants/permissions.js";
2
+ import { SEMANTIC_COLORS as t } from "../../../utils/semanticTokens.js";
3
+ import { useCallback as n, useEffect as r, useRef as i, useState as a } from "react";
4
+ import { usePermissions as o } from "@burdenoff/fe-libs/shared/providers/shell";
5
+ import { Fragment as s, jsx as c, jsxs as l } from "react/jsx-runtime";
6
+ import { createPortal as u } from "react-dom";
5
7
  //#region src/bigconsole/components/dashboard/PageTabsManager/PageTabsManager.tsx
6
- function l({ pages: l, activePageId: u, onPageSelect: d, onPageCreate: f, onPageRename: p, onPageDuplicate: m, onPageDelete: h, onPagesReorder: g, editable: _ = !0, className: v = "" }) {
7
- let [y, b] = i(null), [x, S] = i(null), [C, w] = i(null), [T, E] = i(""), [D, O] = i(null), [k, A] = i({
8
+ function d({ pages: d, activePageId: f, onPageSelect: p, onPageCreate: m, onPageRename: h, onPageDuplicate: g, onPageDelete: _, onPagesReorder: v, editable: y = !0, className: b = "" }) {
9
+ let { hasPermission: x } = o(), S = x(e.DASHBOARD_PAGE_CREATE), C = x(e.DASHBOARD_PAGE_UPDATE), w = x(e.DASHBOARD_PAGE_DELETE), [T, E] = a(null), [D, O] = a(null), [k, A] = a(null), [j, M] = a(""), [N, P] = a(null), [F, I] = a({
8
10
  x: 0,
9
11
  y: 0
10
- }), j = r(null), M = r(null);
11
- n(() => {
12
- C && j.current && (j.current.focus(), j.current.select());
13
- }, [C]), n(() => {
12
+ }), L = i(null), R = i(null);
13
+ r(() => {
14
+ k && L.current && (L.current.focus(), L.current.select());
15
+ }, [k]), r(() => {
14
16
  function e(e) {
15
- M.current && !M.current.contains(e.target) && O(null);
17
+ R.current && !R.current.contains(e.target) && P(null);
16
18
  }
17
19
  return document.addEventListener("mousedown", e), () => document.removeEventListener("mousedown", e);
18
20
  }, []);
19
- let N = t((e, t) => {
20
- b(t), e.dataTransfer.effectAllowed = "move";
21
- }, []), P = t((e, t) => {
22
- e.preventDefault(), e.dataTransfer.dropEffect = "move", y && y !== t && S(t);
23
- }, [y]), F = t(() => {
24
- if (y && x && y !== x && g) {
25
- let e = [...l], t = e.findIndex((e) => e.id === y), n = e.findIndex((e) => e.id === x);
21
+ let z = n((e, t) => {
22
+ E(t), e.dataTransfer.effectAllowed = "move";
23
+ }, []), B = n((e, t) => {
24
+ e.preventDefault(), e.dataTransfer.dropEffect = "move", T && T !== t && O(t);
25
+ }, [T]), V = n(() => {
26
+ if (T && D && T !== D && v) {
27
+ let e = [...d], t = e.findIndex((e) => e.id === T), n = e.findIndex((e) => e.id === D);
26
28
  if (t !== -1 && n !== -1) {
27
29
  let [r] = e.splice(t, 1);
28
- e.splice(n, 0, r), g(e.map((e) => e.id));
30
+ e.splice(n, 0, r), v(e.map((e) => e.id));
29
31
  }
30
32
  }
31
- b(null), S(null);
33
+ E(null), O(null);
32
34
  }, [
33
- y,
34
- x,
35
- l,
36
- g
37
- ]), I = t((e, t) => {
38
- e.preventDefault(), O(t), A({
35
+ T,
36
+ D,
37
+ d,
38
+ v
39
+ ]), H = n((e, t) => {
40
+ e.preventDefault(), P(t), I({
39
41
  x: e.clientX,
40
42
  y: e.clientY
41
43
  });
42
- }, []), L = t((e, t) => {
43
- w(e), E(t), O(null);
44
- }, []), R = t(() => {
45
- C && T.trim() && p && p(C, T.trim()), w(null), E("");
44
+ }, []), U = n((e, t) => {
45
+ A(e), M(t), P(null);
46
+ }, []), W = n(() => {
47
+ k && j.trim() && h && h(k, j.trim()), A(null), M("");
46
48
  }, [
47
- C,
48
- T,
49
- p
50
- ]), z = t(() => {
51
- w(null), E("");
52
- }, []), B = t((e) => {
53
- e.key === "Enter" ? R() : e.key === "Escape" && z();
54
- }, [R, z]);
55
- return /* @__PURE__ */ s("div", {
56
- ref: M,
57
- className: v,
49
+ k,
50
+ j,
51
+ h
52
+ ]), G = n(() => {
53
+ A(null), M("");
54
+ }, []), K = n((e) => {
55
+ e.key === "Enter" ? W() : e.key === "Escape" && G();
56
+ }, [W, G]);
57
+ return /* @__PURE__ */ l("div", {
58
+ ref: R,
59
+ className: b,
58
60
  style: {
59
61
  display: "flex",
60
62
  alignItems: "center",
61
63
  gap: "4px",
62
64
  padding: "0 8px",
63
65
  overflowX: "auto",
64
- backgroundColor: e.bgSecondary,
65
- borderBottom: `1px solid ${e.borderDefault}`,
66
+ backgroundColor: t.bgSecondary,
67
+ borderBottom: `1px solid ${t.borderDefault}`,
66
68
  minHeight: "40px"
67
69
  },
68
70
  children: [
69
- l.sort((e, t) => e.order - t.order).map((t) => /* @__PURE__ */ o("div", {
70
- draggable: _ && !C,
71
- onDragStart: (e) => N(e, t.id),
72
- onDragOver: (e) => P(e, t.id),
73
- onDragEnd: F,
74
- onContextMenu: (e) => _ && I(e, t.id),
75
- onClick: () => !C && d(t.id),
76
- onDoubleClick: () => _ && L(t.id, t.name),
71
+ d.sort((e, t) => e.order - t.order).map((e) => /* @__PURE__ */ c("div", {
72
+ draggable: y && C && !k,
73
+ onDragStart: (t) => z(t, e.id),
74
+ onDragOver: (t) => B(t, e.id),
75
+ onDragEnd: V,
76
+ onContextMenu: (t) => y && (C || w || !!g) && H(t, e.id),
77
+ onClick: () => !k && p(e.id),
78
+ onDoubleClick: () => y && C && U(e.id, e.name),
77
79
  style: {
78
80
  position: "relative",
79
81
  display: "flex",
80
82
  alignItems: "center",
81
83
  gap: "6px",
82
84
  padding: "8px 12px",
83
- backgroundColor: u === t.id ? e.bgPrimary : "transparent",
84
- borderBottom: u === t.id ? `2px solid ${e.actionPrimaryBg}` : "2px solid transparent",
85
- cursor: C === t.id ? "text" : "pointer",
86
- opacity: y === t.id ? .5 : 1,
87
- borderLeft: x === t.id ? `2px solid ${e.actionPrimaryBg}` : "none",
85
+ backgroundColor: f === e.id ? t.bgPrimary : "transparent",
86
+ borderBottom: f === e.id ? `2px solid ${t.actionPrimaryBg}` : "2px solid transparent",
87
+ cursor: k === e.id ? "text" : "pointer",
88
+ opacity: T === e.id ? .5 : 1,
89
+ borderLeft: D === e.id ? `2px solid ${t.actionPrimaryBg}` : "none",
88
90
  flexShrink: 0,
89
91
  transition: "background-color 0.15s, border-color 0.15s"
90
92
  },
91
- children: C === t.id ? /* @__PURE__ */ o("input", {
92
- ref: j,
93
+ children: k === e.id ? /* @__PURE__ */ c("input", {
94
+ ref: L,
93
95
  type: "text",
94
- value: T,
95
- onChange: (e) => E(e.target.value),
96
- onKeyDown: B,
97
- onBlur: R,
96
+ value: j,
97
+ onChange: (e) => M(e.target.value),
98
+ onKeyDown: K,
99
+ onBlur: W,
98
100
  style: {
99
101
  width: "100px",
100
102
  padding: "2px 4px",
101
- border: `1px solid ${e.actionPrimaryBg}`,
103
+ border: `1px solid ${t.actionPrimaryBg}`,
102
104
  borderRadius: "2px",
103
105
  fontSize: "13px",
104
106
  outline: "none",
105
- backgroundColor: e.bgPrimary,
106
- color: e.textPrimary
107
+ backgroundColor: t.bgPrimary,
108
+ color: t.textPrimary
107
109
  },
108
110
  onClick: (e) => e.stopPropagation()
109
- }) : /* @__PURE__ */ s(a, { children: [/* @__PURE__ */ o("span", {
111
+ }) : /* @__PURE__ */ l(s, { children: [/* @__PURE__ */ c("span", {
110
112
  style: {
111
113
  fontSize: "13px",
112
- fontWeight: u === t.id ? 600 : 400,
113
- color: u === t.id ? e.textPrimary : e.textSecondary
114
+ fontWeight: f === e.id ? 600 : 400,
115
+ color: f === e.id ? t.textPrimary : t.textSecondary
114
116
  },
115
- children: t.name
116
- }), t.widgetCount !== void 0 && /* @__PURE__ */ o("span", {
117
+ children: e.name
118
+ }), e.widgetCount !== void 0 && /* @__PURE__ */ c("span", {
117
119
  style: {
118
120
  fontSize: "10px",
119
- color: e.textTertiary,
120
- backgroundColor: e.borderDefault,
121
+ color: t.textTertiary,
122
+ backgroundColor: t.borderDefault,
121
123
  padding: "1px 4px",
122
124
  borderRadius: "8px"
123
125
  },
124
- children: t.widgetCount
126
+ children: e.widgetCount
125
127
  })] })
126
- }, t.id)),
127
- _ && f && /* @__PURE__ */ o("button", {
128
- onClick: f,
128
+ }, e.id)),
129
+ y && m && S && /* @__PURE__ */ c("button", {
130
+ onClick: m,
129
131
  style: {
130
132
  display: "flex",
131
133
  alignItems: "center",
132
134
  justifyContent: "center",
133
135
  padding: "6px 12px",
134
- backgroundColor: e.actionPrimaryBg,
136
+ backgroundColor: t.actionPrimaryBg,
135
137
  border: "none",
136
138
  borderRadius: "4px",
137
139
  cursor: "pointer",
@@ -143,13 +145,13 @@ function l({ pages: l, activePageId: u, onPageSelect: d, onPageCreate: f, onPage
143
145
  },
144
146
  children: "+ Add Page"
145
147
  }),
146
- D && c(/* @__PURE__ */ s("div", {
148
+ N && u(/* @__PURE__ */ l("div", {
147
149
  style: {
148
150
  position: "fixed",
149
- left: k.x,
150
- top: k.y,
151
- backgroundColor: e.bgPrimary,
152
- border: `1px solid ${e.borderDefault}`,
151
+ left: F.x,
152
+ top: F.y,
153
+ backgroundColor: t.bgPrimary,
154
+ border: `1px solid ${t.borderDefault}`,
153
155
  borderRadius: "6px",
154
156
  boxShadow: "0 8px 24px rgba(0,0,0,0.2)",
155
157
  zIndex: 99999,
@@ -157,59 +159,59 @@ function l({ pages: l, activePageId: u, onPageSelect: d, onPageCreate: f, onPage
157
159
  },
158
160
  onClick: (e) => e.stopPropagation(),
159
161
  children: [
160
- /* @__PURE__ */ o("button", {
162
+ C && /* @__PURE__ */ c("button", {
161
163
  onClick: () => {
162
- let e = l.find((e) => e.id === D);
163
- e && L(D, e.name);
164
+ let e = d.find((e) => e.id === N);
165
+ e && U(N, e.name);
164
166
  },
165
167
  style: {
166
168
  display: "block",
167
169
  width: "100%",
168
170
  padding: "8px 12px",
169
171
  textAlign: "left",
170
- backgroundColor: e.bgPrimary,
172
+ backgroundColor: t.bgPrimary,
171
173
  border: "none",
172
174
  cursor: "pointer",
173
175
  fontSize: "13px",
174
- color: e.textPrimary
176
+ color: t.textPrimary
175
177
  },
176
178
  children: "Rename"
177
179
  }),
178
- m && /* @__PURE__ */ o("button", {
180
+ g && S && /* @__PURE__ */ c("button", {
179
181
  onClick: () => {
180
- m(D), O(null);
182
+ g(N), P(null);
181
183
  },
182
184
  style: {
183
185
  display: "block",
184
186
  width: "100%",
185
187
  padding: "8px 12px",
186
188
  textAlign: "left",
187
- backgroundColor: e.bgPrimary,
189
+ backgroundColor: t.bgPrimary,
188
190
  border: "none",
189
191
  cursor: "pointer",
190
192
  fontSize: "13px",
191
- color: e.textPrimary
193
+ color: t.textPrimary
192
194
  },
193
195
  children: "Duplicate"
194
196
  }),
195
- h && l.length > 1 && /* @__PURE__ */ s(a, { children: [/* @__PURE__ */ o("div", { style: {
197
+ _ && w && d.length > 1 && /* @__PURE__ */ l(s, { children: [/* @__PURE__ */ c("div", { style: {
196
198
  height: "1px",
197
- backgroundColor: e.borderDefault,
199
+ backgroundColor: t.borderDefault,
198
200
  margin: "4px 0"
199
- } }), /* @__PURE__ */ o("button", {
201
+ } }), /* @__PURE__ */ c("button", {
200
202
  onClick: () => {
201
- window.confirm("Are you sure you want to delete this page?") && h(D), O(null);
203
+ window.confirm("Are you sure you want to delete this page?") && _(N), P(null);
202
204
  },
203
205
  style: {
204
206
  display: "block",
205
207
  width: "100%",
206
208
  padding: "8px 12px",
207
209
  textAlign: "left",
208
- backgroundColor: e.bgPrimary,
210
+ backgroundColor: t.bgPrimary,
209
211
  border: "none",
210
212
  cursor: "pointer",
211
213
  fontSize: "13px",
212
- color: e.statusErrorText
214
+ color: t.statusErrorText
213
215
  },
214
216
  children: "Delete"
215
217
  })] })
@@ -219,6 +221,6 @@ function l({ pages: l, activePageId: u, onPageSelect: d, onPageCreate: f, onPage
219
221
  });
220
222
  }
221
223
  //#endregion
222
- export { l as default };
224
+ export { d as default };
223
225
 
224
226
  //# 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 { SEMANTIC_COLORS } from '../../../utils/semanticTokens';\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 [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 && !editingId}\n onDragStart={(e) => handleDragStart(e, page.id)}\n onDragOver={(e) => handleDragOver(e, page.id)}\n onDragEnd={handleDragEnd}\n onContextMenu={(e) => editable && handleContextMenu(e, page.id)}\n onClick={() => !editingId && onPageSelect(page.id)}\n onDoubleClick={() => editable && 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 && (\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 <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 {onPageDuplicate && (\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 && 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';\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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"}