@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.
- package/dist/bigconsole/AdminRoot.js +21 -16
- package/dist/bigconsole/AdminRoot.js.map +1 -1
- package/dist/bigconsole/BigConsoleRoot.js +44 -39
- package/dist/bigconsole/BigConsoleRoot.js.map +1 -1
- package/dist/bigconsole/components/dashboard/DashboardToolbar.js +115 -100
- package/dist/bigconsole/components/dashboard/DashboardToolbar.js.map +1 -1
- package/dist/bigconsole/components/dashboard/PageTabsManager/PageTabsManager.js +100 -98
- package/dist/bigconsole/components/dashboard/PageTabsManager/PageTabsManager.js.map +1 -1
- package/dist/bigconsole/components/dashboard/ShareDialog/EmbedTab.js +164 -161
- package/dist/bigconsole/components/dashboard/ShareDialog/EmbedTab.js.map +1 -1
- package/dist/bigconsole/components/datasink/DataSinkCard.js +20 -20
- package/dist/bigconsole/components/datasink/DataSinkCard.js.map +1 -1
- package/dist/bigconsole/components/datasink/ImportDataGuideDialog.js +216 -49
- package/dist/bigconsole/components/datasink/ImportDataGuideDialog.js.map +1 -1
- package/dist/bigconsole/components/widgets/ActionConfigDialog.js +96 -90
- package/dist/bigconsole/components/widgets/ActionConfigDialog.js.map +1 -1
- package/dist/bigconsole/components/widgets/WidgetMenu.js +87 -76
- package/dist/bigconsole/components/widgets/WidgetMenu.js.map +1 -1
- package/dist/bigconsole/components/widgets/widget-actions/WidgetActions.js +120 -118
- package/dist/bigconsole/components/widgets/widget-actions/WidgetActions.js.map +1 -1
- package/dist/bigconsole/pages/DashboardBuilderPage.js +113 -104
- package/dist/bigconsole/pages/DashboardBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/DashboardViewPage.js +208 -199
- package/dist/bigconsole/pages/DashboardViewPage.js.map +1 -1
- package/dist/bigconsole/pages/DashboardsPage.js +376 -325
- package/dist/bigconsole/pages/DashboardsPage.js.map +1 -1
- package/dist/bigconsole/pages/DataParsersPage.js +135 -125
- package/dist/bigconsole/pages/DataParsersPage.js.map +1 -1
- package/dist/bigconsole/pages/DataSinkBuilderPage.js +182 -172
- package/dist/bigconsole/pages/DataSinkBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/DataSinkViewPage.js +233 -198
- package/dist/bigconsole/pages/DataSinkViewPage.js.map +1 -1
- package/dist/bigconsole/pages/DataSinksPage.js +281 -268
- package/dist/bigconsole/pages/DataSinksPage.js.map +1 -1
- package/dist/bigconsole/pages/ParserBuilderPage.js +238 -223
- package/dist/bigconsole/pages/ParserBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/ParserViewPage.js +162 -144
- package/dist/bigconsole/pages/ParserViewPage.js.map +1 -1
- package/dist/bigconsole/pages/PipelineBuilderPage.js +212 -204
- package/dist/bigconsole/pages/PipelineBuilderPage.js.map +1 -1
- package/dist/bigconsole/pages/PipelineViewPage.js +191 -183
- package/dist/bigconsole/pages/PipelineViewPage.js.map +1 -1
- package/dist/bigconsole/pages/PipelinesPage.js +128 -103
- package/dist/bigconsole/pages/PipelinesPage.js.map +1 -1
- package/dist/bigconsole/pages/WorkflowViewPage.js +238 -217
- package/dist/bigconsole/pages/WorkflowViewPage.js.map +1 -1
- package/dist/bigconsole/pages/WorkflowsPage.js +116 -102
- package/dist/bigconsole/pages/WorkflowsPage.js.map +1 -1
- package/dist/bigconsole/utils/csv.js +91 -0
- package/dist/bigconsole/utils/csv.js.map +1 -0
- package/dist/constants/permissions.js +83 -0
- package/dist/constants/permissions.js.map +1 -0
- package/package.json +2 -2
|
@@ -1,137 +1,139 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
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
|
|
7
|
-
let [
|
|
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
|
-
}),
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}, [
|
|
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
|
-
|
|
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
|
|
20
|
-
|
|
21
|
-
}, []),
|
|
22
|
-
e.preventDefault(), e.dataTransfer.dropEffect = "move",
|
|
23
|
-
}, [
|
|
24
|
-
if (
|
|
25
|
-
let e = [...
|
|
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),
|
|
30
|
+
e.splice(n, 0, r), v(e.map((e) => e.id));
|
|
29
31
|
}
|
|
30
32
|
}
|
|
31
|
-
|
|
33
|
+
E(null), O(null);
|
|
32
34
|
}, [
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
]),
|
|
38
|
-
e.preventDefault(),
|
|
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
|
-
}, []),
|
|
43
|
-
|
|
44
|
-
}, []),
|
|
45
|
-
|
|
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
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
]),
|
|
51
|
-
|
|
52
|
-
}, []),
|
|
53
|
-
e.key === "Enter" ?
|
|
54
|
-
}, [
|
|
55
|
-
return /* @__PURE__ */
|
|
56
|
-
ref:
|
|
57
|
-
className:
|
|
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:
|
|
65
|
-
borderBottom: `1px solid ${
|
|
66
|
+
backgroundColor: t.bgSecondary,
|
|
67
|
+
borderBottom: `1px solid ${t.borderDefault}`,
|
|
66
68
|
minHeight: "40px"
|
|
67
69
|
},
|
|
68
70
|
children: [
|
|
69
|
-
|
|
70
|
-
draggable:
|
|
71
|
-
onDragStart: (
|
|
72
|
-
onDragOver: (
|
|
73
|
-
onDragEnd:
|
|
74
|
-
onContextMenu: (
|
|
75
|
-
onClick: () => !
|
|
76
|
-
onDoubleClick: () =>
|
|
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:
|
|
84
|
-
borderBottom:
|
|
85
|
-
cursor:
|
|
86
|
-
opacity:
|
|
87
|
-
borderLeft:
|
|
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:
|
|
92
|
-
ref:
|
|
93
|
+
children: k === e.id ? /* @__PURE__ */ c("input", {
|
|
94
|
+
ref: L,
|
|
93
95
|
type: "text",
|
|
94
|
-
value:
|
|
95
|
-
onChange: (e) =>
|
|
96
|
-
onKeyDown:
|
|
97
|
-
onBlur:
|
|
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 ${
|
|
103
|
+
border: `1px solid ${t.actionPrimaryBg}`,
|
|
102
104
|
borderRadius: "2px",
|
|
103
105
|
fontSize: "13px",
|
|
104
106
|
outline: "none",
|
|
105
|
-
backgroundColor:
|
|
106
|
-
color:
|
|
107
|
+
backgroundColor: t.bgPrimary,
|
|
108
|
+
color: t.textPrimary
|
|
107
109
|
},
|
|
108
110
|
onClick: (e) => e.stopPropagation()
|
|
109
|
-
}) : /* @__PURE__ */ s
|
|
111
|
+
}) : /* @__PURE__ */ l(s, { children: [/* @__PURE__ */ c("span", {
|
|
110
112
|
style: {
|
|
111
113
|
fontSize: "13px",
|
|
112
|
-
fontWeight:
|
|
113
|
-
color:
|
|
114
|
+
fontWeight: f === e.id ? 600 : 400,
|
|
115
|
+
color: f === e.id ? t.textPrimary : t.textSecondary
|
|
114
116
|
},
|
|
115
|
-
children:
|
|
116
|
-
}),
|
|
117
|
+
children: e.name
|
|
118
|
+
}), e.widgetCount !== void 0 && /* @__PURE__ */ c("span", {
|
|
117
119
|
style: {
|
|
118
120
|
fontSize: "10px",
|
|
119
|
-
color:
|
|
120
|
-
backgroundColor:
|
|
121
|
+
color: t.textTertiary,
|
|
122
|
+
backgroundColor: t.borderDefault,
|
|
121
123
|
padding: "1px 4px",
|
|
122
124
|
borderRadius: "8px"
|
|
123
125
|
},
|
|
124
|
-
children:
|
|
126
|
+
children: e.widgetCount
|
|
125
127
|
})] })
|
|
126
|
-
},
|
|
127
|
-
|
|
128
|
-
onClick:
|
|
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:
|
|
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
|
-
|
|
148
|
+
N && u(/* @__PURE__ */ l("div", {
|
|
147
149
|
style: {
|
|
148
150
|
position: "fixed",
|
|
149
|
-
left:
|
|
150
|
-
top:
|
|
151
|
-
backgroundColor:
|
|
152
|
-
border: `1px solid ${
|
|
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__ */
|
|
162
|
+
C && /* @__PURE__ */ c("button", {
|
|
161
163
|
onClick: () => {
|
|
162
|
-
let e =
|
|
163
|
-
e &&
|
|
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:
|
|
172
|
+
backgroundColor: t.bgPrimary,
|
|
171
173
|
border: "none",
|
|
172
174
|
cursor: "pointer",
|
|
173
175
|
fontSize: "13px",
|
|
174
|
-
color:
|
|
176
|
+
color: t.textPrimary
|
|
175
177
|
},
|
|
176
178
|
children: "Rename"
|
|
177
179
|
}),
|
|
178
|
-
|
|
180
|
+
g && S && /* @__PURE__ */ c("button", {
|
|
179
181
|
onClick: () => {
|
|
180
|
-
|
|
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:
|
|
189
|
+
backgroundColor: t.bgPrimary,
|
|
188
190
|
border: "none",
|
|
189
191
|
cursor: "pointer",
|
|
190
192
|
fontSize: "13px",
|
|
191
|
-
color:
|
|
193
|
+
color: t.textPrimary
|
|
192
194
|
},
|
|
193
195
|
children: "Duplicate"
|
|
194
196
|
}),
|
|
195
|
-
|
|
197
|
+
_ && w && d.length > 1 && /* @__PURE__ */ l(s, { children: [/* @__PURE__ */ c("div", { style: {
|
|
196
198
|
height: "1px",
|
|
197
|
-
backgroundColor:
|
|
199
|
+
backgroundColor: t.borderDefault,
|
|
198
200
|
margin: "4px 0"
|
|
199
|
-
} }), /* @__PURE__ */
|
|
201
|
+
} }), /* @__PURE__ */ c("button", {
|
|
200
202
|
onClick: () => {
|
|
201
|
-
window.confirm("Are you sure you want to delete this page?") &&
|
|
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:
|
|
210
|
+
backgroundColor: t.bgPrimary,
|
|
209
211
|
border: "none",
|
|
210
212
|
cursor: "pointer",
|
|
211
213
|
fontSize: "13px",
|
|
212
|
-
color:
|
|
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 {
|
|
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":";;;;;;;AAwCA,SAAgB,EAAgB,EAC9B,UACA,iBACA,iBACA,iBACA,iBACA,oBACA,iBACA,mBACA,cAAW,IACX,eAAY,MACW;CACvB,IAAM,EAAE,qBAAkB,GAAgB,EACpC,IAAgB,EAAc,EAAuB,sBAAsB,EAC3E,IAAgB,EAAc,EAAuB,sBAAsB,EAC3E,IAAgB,EAAc,EAAuB,sBAAsB,EAE3E,CAAC,GAAW,KAAgB,EAAwB,KAAK,EACzD,CAAC,GAAY,KAAiB,EAAwB,KAAK,EAC3D,CAAC,GAAW,KAAgB,EAAwB,KAAK,EACzD,CAAC,GAAa,KAAkB,EAAS,GAAG,EAC5C,CAAC,GAAe,KAAoB,EAAwB,KAAK,EACjE,CAAC,GAAgB,KAAqB,EAAS;EAAE,GAAG;EAAG,GAAG;EAAG,CAAC,EAE9D,IAAe,EAAyB,KAAK,EAC7C,IAAe,EAAuB,KAAK;AAWjD,CARA,QAAgB;AACd,EAAI,KAAa,EAAa,YAC5B,EAAa,QAAQ,OAAO,EAC5B,EAAa,QAAQ,QAAQ;IAE9B,CAAC,EAAU,CAAC,EAGf,QAAgB;EACd,SAAS,EAAmB,GAAmB;AAC7C,GAAI,EAAa,WAAW,CAAC,EAAa,QAAQ,SAAS,EAAM,OAAe,IAC9E,EAAiB,KAAK;;AAK1B,SADA,SAAS,iBAAiB,aAAa,EAAmB,QAC7C,SAAS,oBAAoB,aAAa,EAAmB;IACzE,EAAE,CAAC;CAGN,IAAM,IAAkB,GAAa,GAAoB,MAAmB;AAE1E,EADA,EAAa,EAAO,EACpB,EAAE,aAAa,gBAAgB;IAC9B,EAAE,CAAC,EAEA,IAAiB,GACpB,GAAoB,MAAmB;AAGtC,EAFA,EAAE,gBAAgB,EAClB,EAAE,aAAa,aAAa,QACxB,KAAa,MAAc,KAC7B,EAAc,EAAO;IAGzB,CAAC,EAAU,CACZ,EAEK,IAAgB,QAAkB;AACtC,MAAI,KAAa,KAAc,MAAc,KAAc,GAAgB;GACzE,IAAM,IAAe,CAAC,GAAG,EAAM,EACzB,IAAe,EAAa,WAAW,MAAM,EAAE,OAAO,EAAU,EAChE,IAAc,EAAa,WAAW,MAAM,EAAE,OAAO,EAAW;AAEtE,OAAI,MAAiB,MAAM,MAAgB,IAAI;IAC7C,IAAM,CAAC,KAAe,EAAa,OAAO,GAAc,EAAE;AAE1D,IADA,EAAa,OAAO,GAAa,GAAG,EAAY,EAChD,EAAe,EAAa,KAAK,MAAM,EAAE,GAAG,CAAC;;;AAKjD,EADA,EAAa,KAAK,EAClB,EAAc,KAAK;IAClB;EAAC;EAAW;EAAY;EAAO;EAAe,CAAC,EAG5C,IAAoB,GAAa,GAAqB,MAAmB;AAG7E,EAFA,EAAE,gBAAgB,EAClB,EAAiB,EAAO,EACxB,EAAkB;GAAE,GAAG,EAAE;GAAS,GAAG,EAAE;GAAS,CAAC;IAChD,EAAE,CAAC,EAGA,IAAkB,GAAa,GAAgB,MAAwB;AAG3E,EAFA,EAAa,EAAO,EACpB,EAAe,EAAY,EAC3B,EAAiB,KAAK;IACrB,EAAE,CAAC,EAGA,IAAiB,QAAkB;AAKvC,EAJI,KAAa,EAAY,MAAM,IAAI,KACrC,EAAa,GAAW,EAAY,MAAM,CAAC,EAE7C,EAAa,KAAK,EAClB,EAAe,GAAG;IACjB;EAAC;EAAW;EAAa;EAAa,CAAC,EAGpC,IAAmB,QAAkB;AAEzC,EADA,EAAa,KAAK,EAClB,EAAe,GAAG;IACjB,EAAE,CAAC,EAGA,IAAoB,GACvB,MAA2B;AAC1B,EAAI,EAAE,QAAQ,UACZ,GAAgB,GACP,EAAE,QAAQ,YACnB,GAAkB;IAGtB,CAAC,GAAgB,EAAiB,CACnC;AAED,QACE,kBAAC,OAAD;EACE,KAAK;EACM;EACX,OAAO;GACL,SAAS;GACT,YAAY;GACZ,KAAK;GACL,SAAS;GACT,WAAW;GACX,iBAAiB,EAAgB;GACjC,cAAc,aAAa,EAAgB;GAC3C,WAAW;GACZ;YAZH;GAeG,EACE,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,MAAM,CACjC,KAAK,MACJ,kBAAC,OAAD;IAEE,WAAW,KAAY,KAAiB,CAAC;IACzC,cAAc,MAAM,EAAgB,GAAG,EAAK,GAAG;IAC/C,aAAa,MAAM,EAAe,GAAG,EAAK,GAAG;IAC7C,WAAW;IACX,gBAAgB,MACd,MAAa,KAAiB,KAAiB,CAAC,CAAC,MAAoB,EAAkB,GAAG,EAAK,GAAG;IAEpG,eAAe,CAAC,KAAa,EAAa,EAAK,GAAG;IAClD,qBAAqB,KAAY,KAAiB,EAAgB,EAAK,IAAI,EAAK,KAAK;IACrF,OAAO;KACL,UAAU;KACV,SAAS;KACT,YAAY;KACZ,KAAK;KACL,SAAS;KACT,iBAAiB,MAAiB,EAAK,KAAK,EAAgB,YAAY;KACxE,cACE,MAAiB,EAAK,KAAK,aAAa,EAAgB,oBAAoB;KAC9E,QAAQ,MAAc,EAAK,KAAK,SAAS;KACzC,SAAS,MAAc,EAAK,KAAK,KAAM;KACvC,YAAY,MAAe,EAAK,KAAK,aAAa,EAAgB,oBAAoB;KACtF,YAAY;KACZ,YAAY;KACb;cAEA,MAAc,EAAK,KAClB,kBAAC,SAAD;KACE,KAAK;KACL,MAAK;KACL,OAAO;KACP,WAAW,MAAM,EAAe,EAAE,OAAO,MAAM;KAC/C,WAAW;KACX,QAAQ;KACR,OAAO;MACL,OAAO;MACP,SAAS;MACT,QAAQ,aAAa,EAAgB;MACrC,cAAc;MACd,UAAU;MACV,SAAS;MACT,iBAAiB,EAAgB;MACjC,OAAO,EAAgB;MACxB;KACD,UAAU,MAAM,EAAE,iBAAiB;KACnC,CAAA,GAEF,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,QAAD;KACE,OAAO;MACL,UAAU;MACV,YAAY,MAAiB,EAAK,KAAK,MAAM;MAC7C,OAAO,MAAiB,EAAK,KAAK,EAAgB,cAAc,EAAgB;MACjF;eAEA,EAAK;KACD,CAAA,EACN,EAAK,gBAAgB,KAAA,KACpB,kBAAC,QAAD;KACE,OAAO;MACL,UAAU;MACV,OAAO,EAAgB;MACvB,iBAAiB,EAAgB;MACjC,SAAS;MACT,cAAc;MACf;eAEA,EAAK;KACD,CAAA,CAER,EAAA,CAAA;IAED,EAxEC,EAAK,GAwEN,CACN;GAGH,KAAY,KAAgB,KAC3B,kBAAC,UAAD;IACE,SAAS;IACT,OAAO;KACL,SAAS;KACT,YAAY;KACZ,gBAAgB;KAChB,SAAS;KACT,iBAAiB,EAAgB;KACjC,QAAQ;KACR,cAAc;KACd,QAAQ;KACR,OAAO;KACP,UAAU;KACV,YAAY;KACZ,YAAY;KACZ,YAAY;KACb;cACF;IAEQ,CAAA;GAIV,KACC,EACE,kBAAC,OAAD;IACE,OAAO;KACL,UAAU;KACV,MAAM,EAAe;KACrB,KAAK,EAAe;KACpB,iBAAiB,EAAgB;KACjC,QAAQ,aAAa,EAAgB;KACrC,cAAc;KACd,WAAW;KACX,QAAQ;KACR,UAAU;KACX;IACD,UAAU,MAAM,EAAE,iBAAiB;cAZrC;KAcG,KACC,kBAAC,UAAD;MACE,eAAe;OACb,IAAM,IAAO,EAAM,MAAM,MAAM,EAAE,OAAO,EAAc;AACtD,OAAI,KAAM,EAAgB,GAAe,EAAK,KAAK;;MAErD,OAAO;OACL,SAAS;OACT,OAAO;OACP,SAAS;OACT,WAAW;OACX,iBAAiB,EAAgB;OACjC,QAAQ;OACR,QAAQ;OACR,UAAU;OACV,OAAO,EAAgB;OACxB;gBACF;MAEQ,CAAA;KAEV,KAAmB,KAClB,kBAAC,UAAD;MACE,eAAe;AAEb,OADA,EAAgB,EAAc,EAC9B,EAAiB,KAAK;;MAExB,OAAO;OACL,SAAS;OACT,OAAO;OACP,SAAS;OACT,WAAW;OACX,iBAAiB,EAAgB;OACjC,QAAQ;OACR,QAAQ;OACR,UAAU;OACV,OAAO,EAAgB;OACxB;gBACF;MAEQ,CAAA;KAEV,KAAgB,KAAiB,EAAM,SAAS,KAC/C,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,OAAD,EAAK,OAAO;MAAE,QAAQ;MAAO,iBAAiB,EAAgB;MAAe,QAAQ;MAAS,EAAI,CAAA,EAClG,kBAAC,UAAD;MACE,eAAe;AAIb,OAHI,OAAO,QAAQ,6CAA6C,IAC9D,EAAa,EAAc,EAE7B,EAAiB,KAAK;;MAExB,OAAO;OACL,SAAS;OACT,OAAO;OACP,SAAS;OACT,WAAW;OACX,iBAAiB,EAAgB;OACjC,QAAQ;OACR,QAAQ;OACR,UAAU;OACV,OAAO,EAAgB;OACxB;gBACF;MAEQ,CAAA,CACR,EAAA,CAAA;KAED;OACN,SAAS,KACV;GACC"}
|