@loopstack/loopstack-studio 0.21.3 → 0.23.0

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 (126) hide show
  1. package/dist/api/auth.js +10 -0
  2. package/dist/api/client.js +13 -0
  3. package/dist/api/config.js +10 -0
  4. package/dist/api/dashboard.js +4 -0
  5. package/dist/api/documents.js +7 -0
  6. package/dist/api/index.js +24 -0
  7. package/dist/api/namespaces.js +7 -0
  8. package/dist/api/pipelines.js +13 -0
  9. package/dist/api/processor.js +4 -0
  10. package/dist/api/workflows.js +8 -0
  11. package/dist/api/workspaces.js +12 -0
  12. package/dist/app/EnvironmentEmbedRoot.js +35 -0
  13. package/dist/components/data-table/DataTableFilters.js +74 -63
  14. package/dist/components/feedback/ErrorBoundary.js +43 -0
  15. package/dist/components/{LoadingCentered.js → feedback/LoadingCentered.js} +1 -1
  16. package/dist/components/feedback/index.js +5 -0
  17. package/dist/components/index.js +6 -3
  18. package/dist/components/layout/MainLayout.js +36 -17
  19. package/dist/components/layout/StudioSidebar.js +165 -0
  20. package/dist/components/page/PageBreadcrumbs.js +1 -1
  21. package/dist/components/ui/sidebar.js +359 -359
  22. package/dist/components/ui-widgets/UiActions.js +22 -15
  23. package/dist/components/ui-widgets/UiWidget.js +31 -26
  24. package/dist/components/ui-widgets/widgets/AiPromptInput.js +27 -27
  25. package/dist/components/ui-widgets/widgets/ButtonFullWidth.js +12 -12
  26. package/dist/components/ui-widgets/widgets/SandboxRun.js +33 -0
  27. package/dist/components/ui-widgets/widgets/SubmitButton.js +11 -11
  28. package/dist/features/code-explorer/CodeExplorer.js +4 -67
  29. package/dist/features/code-explorer/components/CodeExplorerTree.js +3 -41
  30. package/dist/features/code-explorer/components/CodeExplorerTreeNode.js +4 -80
  31. package/dist/features/code-explorer/components/FileContentViewer.js +1 -0
  32. package/dist/features/code-explorer/components/FileTabsBar.js +1 -1
  33. package/dist/features/code-explorer/index.js +4 -0
  34. package/dist/features/code-explorer/utils/fileIcons.js +4 -7
  35. package/dist/features/debug/components/ConfigFlowViewer.js +1 -1
  36. package/dist/features/debug/components/PipelineFlowViewer.js +1 -1
  37. package/dist/features/debug/index.js +3 -0
  38. package/dist/features/documents/DocumentRenderer.js +53 -0
  39. package/dist/features/{workbench → documents}/components/DocumentItem.js +1 -1
  40. package/dist/features/documents/components/DocumentList.js +40 -0
  41. package/dist/features/{workbench → documents}/components/DocumentMetadataPills.js +2 -2
  42. package/dist/features/{workbench/components → documents}/document-details/DocumentDetails.js +3 -3
  43. package/dist/features/{workbench/components → documents}/document-details/PromptDetails.js +3 -3
  44. package/dist/features/documents/index.js +4 -0
  45. package/dist/features/{workbench/components/document-renderer → documents/renderers}/AiMessage.js +5 -5
  46. package/dist/features/{workbench/components/document-renderer → documents/renderers}/DocumentDebugRenderer.js +1 -1
  47. package/dist/features/{workbench/components/document-renderer → documents/renderers}/DocumentFormRenderer.js +9 -8
  48. package/dist/features/{workbench/components/document-renderer → documents/renderers}/DocumentMessageRenderer.js +1 -1
  49. package/dist/features/{workbench/components/document-renderer → documents/renderers}/ErrorMessageRenderer.js +1 -1
  50. package/dist/features/{workbench/components/document-renderer → documents/renderers}/LinkMessageRenderer.js +1 -1
  51. package/dist/features/{workbench/components/document-renderer → documents/renderers}/MarkdownMessageRenderer.js +2 -2
  52. package/dist/features/{workbench/components/document-renderer → documents/renderers}/PlainMessageRenderer.js +1 -1
  53. package/dist/features/health/index.js +1 -0
  54. package/dist/features/oauth/OAuthPromptRenderer.js +1 -1
  55. package/dist/features/runs/Runs.js +197 -0
  56. package/dist/features/workbench/NavigationItems.js +29 -29
  57. package/dist/features/workbench/Workbench.js +100 -78
  58. package/dist/features/workbench/WorkflowItem.js +63 -58
  59. package/dist/features/workbench/WorkflowList.js +62 -82
  60. package/dist/features/workbench/components/NewRunDialog.js +329 -0
  61. package/dist/features/workbench/components/WorkbenchFloatingPanel.js +88 -0
  62. package/dist/features/workbench/components/WorkbenchFlowPanel.js +49 -0
  63. package/dist/features/workbench/components/WorkbenchIconSidebar.js +68 -0
  64. package/dist/features/workbench/components/WorkbenchPreviewPanel.js +128 -0
  65. package/dist/features/workbench/components/WorkflowForms.js +7 -6
  66. package/dist/features/workbench/components/WorkflowHistoryItem.js +74 -69
  67. package/dist/features/workbench/components/buttons/WorkflowButtons.js +78 -61
  68. package/dist/features/workbench/hooks/useWorkflowData.js +49 -0
  69. package/dist/features/workbench/hooks/useWorkflowListState.js +50 -0
  70. package/dist/features/workbench/index.js +8 -0
  71. package/dist/features/workbench/providers/WorkbenchLayoutProvider.js +76 -0
  72. package/dist/features/workspaces/Workspaces.js +2 -2
  73. package/dist/features/workspaces/components/CreateWorkspace.js +165 -82
  74. package/dist/features/workspaces/components/EnvironmentSlotSelector.js +63 -0
  75. package/dist/features/workspaces/components/ExecutionTimeline.js +70 -69
  76. package/dist/features/workspaces/components/PipelineForm.js +4 -4
  77. package/dist/features/workspaces/index.js +3 -0
  78. package/dist/hooks/index.js +3 -0
  79. package/dist/hooks/query-keys.js +138 -0
  80. package/dist/hooks/useApi.js +9 -33
  81. package/dist/hooks/useAuth.js +37 -56
  82. package/dist/hooks/useConfig.js +27 -33
  83. package/dist/hooks/useDashboard.js +9 -16
  84. package/dist/hooks/useDebounce.js +8 -17
  85. package/dist/hooks/useDocuments.js +7 -16
  86. package/dist/hooks/useFiles.js +24 -42
  87. package/dist/hooks/useNamespaces.js +7 -16
  88. package/dist/hooks/usePipelines.js +141 -174
  89. package/dist/hooks/useProcessor.js +11 -17
  90. package/dist/hooks/useWorkflows.js +51 -89
  91. package/dist/hooks/useWorkspaces.js +97 -129
  92. package/dist/index.d.ts +364 -50
  93. package/dist/index.js +21 -6
  94. package/dist/packages/contracts/dist/enums/index.js +25 -0
  95. package/dist/packages/contracts/dist/enums/pipeline-state.js +10 -0
  96. package/dist/packages/contracts/dist/enums/registry.enum.js +20 -0
  97. package/dist/packages/contracts/dist/enums/sort-order.enum.js +10 -0
  98. package/dist/packages/contracts/dist/enums/user-type.enum.js +10 -0
  99. package/dist/packages/contracts/dist/enums/workflow-state.enum.js +10 -0
  100. package/dist/pages/DashboardPage.js +1 -1
  101. package/dist/pages/DebugPage.js +12 -14
  102. package/dist/pages/DebugWorkflowDetailsPage.js +2 -2
  103. package/dist/pages/DebugWorkflowsPage.js +3 -4
  104. package/dist/pages/EmbedWorkbenchPage.js +7 -5
  105. package/dist/pages/PipelineDebugPage.js +7 -6
  106. package/dist/pages/PreviewWorkbenchPage.js +419 -0
  107. package/dist/pages/RunsListPage.js +64 -0
  108. package/dist/pages/RunsPage.js +49 -0
  109. package/dist/pages/StudioLandingPage.js +146 -0
  110. package/dist/pages/WorkbenchPage.js +78 -53
  111. package/dist/pages/WorkspacePage.js +1 -1
  112. package/dist/providers/InvalidationEventsProvider.js +15 -17
  113. package/dist/providers/QueryProvider.js +21 -0
  114. package/dist/providers/StudioProvider.js +2 -2
  115. package/dist/routing/LocalRouter.js +20 -7
  116. package/dist/services/createApiClient.js +4 -10
  117. package/dist/services/index.js +1 -1
  118. package/package.json +2 -3
  119. package/dist/features/workbench/components/DocumentList.js +0 -40
  120. package/dist/features/workbench/components/DocumentRenderer.js +0 -54
  121. package/dist/features/workbench/components/WorkbenchSidebar.js +0 -109
  122. package/dist/features/workbench/providers/WorkbenchContextProvider.js +0 -3
  123. /package/dist/components/{content → feedback}/ErrorAlert.js +0 -0
  124. /package/dist/components/{snackbars → feedback}/ErrorSnackbar.js +0 -0
  125. /package/dist/components/{snackbars → feedback}/Snackbar.js +0 -0
  126. /package/dist/features/{workbench/components/document-renderer → documents/renderers}/AiMessageContent.js +0 -0
@@ -0,0 +1,329 @@
1
+ import { usePipelineConfig, useWorkspaceConfig } from "../../../hooks/useConfig.js";
2
+ import { useCreatePipeline } from "../../../hooks/usePipelines.js";
3
+ import { useFilterWorkspaces } from "../../../hooks/useWorkspaces.js";
4
+ import { useComponentOverrides } from "../../../providers/ComponentOverridesProvider.js";
5
+ import { Button } from "../../../components/ui/button.js";
6
+ import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "../../../components/ui/collapsible.js";
7
+ import { Dialog, DialogContent, DialogTitle } from "../../../components/ui/dialog.js";
8
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../../../components/ui/select.js";
9
+ import ErrorSnackbar_default from "../../../components/feedback/ErrorSnackbar.js";
10
+ import CreateWorkspace_default from "../../workspaces/components/CreateWorkspace.js";
11
+ import Form_default from "../../../components/dynamic-form/Form.js";
12
+ import { useRunPipeline } from "../../../hooks/useProcessor.js";
13
+ import "../../workspaces/index.js";
14
+ import { c } from "react/compiler-runtime";
15
+ import { useCallback, useEffect, useMemo, useState } from "react";
16
+ import { jsx, jsxs } from "react/jsx-runtime";
17
+ import { Check, CheckIcon, ChevronDown, Loader2, Plus } from "lucide-react";
18
+ import * as SelectPrimitive from "@radix-ui/react-select";
19
+ import { useForm } from "react-hook-form";
20
+ function NewRunDialog(e) {
21
+ let t = c(8), { open: n, onOpenChange: r, onSuccess: i } = e, a;
22
+ t[0] === Symbol.for("react.memo_cache_sentinel") ? (a = /* @__PURE__ */ jsx(DialogTitle, { children: "New Run" }), t[0] = a) : a = t[0];
23
+ let o;
24
+ t[1] !== i || t[2] !== n ? (o = /* @__PURE__ */ jsxs(DialogContent, {
25
+ className: "max-h-[80vh] min-h-[300px] !max-w-2xl",
26
+ children: [a, /* @__PURE__ */ jsx(NewRunDialogContent, {
27
+ open: n,
28
+ onSuccess: i
29
+ })]
30
+ }), t[1] = i, t[2] = n, t[3] = o) : o = t[3];
31
+ let s;
32
+ return t[4] !== r || t[5] !== n || t[6] !== o ? (s = /* @__PURE__ */ jsx(Dialog, {
33
+ open: n,
34
+ onOpenChange: r,
35
+ children: o
36
+ }), t[4] = r, t[5] = n, t[6] = o, t[7] = s) : s = t[7], s;
37
+ }
38
+ function NewRunDialogContent(o) {
39
+ let s = c(115), { open: l, onSuccess: u } = o, [d, f] = useState("workspace"), [p, g] = useState(!1), [v, me] = useState(""), [y, he] = useState(""), { CreateWorkspace: x } = useComponentOverrides(), _e = x ?? CreateWorkspace_default, ve = useWorkspaceConfig(), ye;
40
+ s[0] === Symbol.for("react.memo_cache_sentinel") ? (ye = {}, s[0] = ye) : ye = s[0];
41
+ let S = useFilterWorkspaces(void 0, ye, "title", "ASC", 0, 100), be;
42
+ s[1] === S.data?.data ? be = s[2] : (be = S.data?.data ?? [], s[1] = S.data?.data, s[2] = be);
43
+ let C = be, xe;
44
+ if (s[3] !== v || s[4] !== C) {
45
+ let e;
46
+ s[6] === v ? e = s[7] : (e = (e) => e.id === v, s[6] = v, s[7] = e), xe = C.find(e), s[3] = v, s[4] = C, s[5] = xe;
47
+ } else xe = s[5];
48
+ let Se = xe, w = usePipelineConfig(Se?.blockName), Ce;
49
+ s[8] === w.data ? Ce = s[9] : (Ce = w.data ?? [], s[8] = w.data, s[9] = Ce);
50
+ let T = Ce, E = useCreatePipeline(), D = useRunPipeline(), O = E.isPending || D.isPending, k;
51
+ s[10] === Symbol.for("react.memo_cache_sentinel") ? (k = {
52
+ defaultValues: {},
53
+ mode: "onChange"
54
+ }, s[10] = k) : k = s[10];
55
+ let A = useForm(k), we;
56
+ bb0: {
57
+ if (!y || !T.length) {
58
+ we = void 0;
59
+ break bb0;
60
+ }
61
+ let e;
62
+ if (s[11] !== T || s[12] !== y) {
63
+ let t;
64
+ s[14] === y ? t = s[15] : (t = (e) => e.blockName === y, s[14] = y, s[15] = t), e = T.find(t), s[11] = T, s[12] = y, s[13] = e;
65
+ } else e = s[13];
66
+ we = e;
67
+ }
68
+ let j = we, M = !!j?.schema, N;
69
+ s[16] !== v || s[17] !== C[0] || s[18] !== C.length ? (N = () => {
70
+ !v && C.length > 0 && me(C[0].id);
71
+ }, s[16] = v, s[17] = C[0], s[18] = C.length, s[19] = N) : N = s[19];
72
+ let P;
73
+ s[20] !== v || s[21] !== C ? (P = [C, v], s[20] = v, s[21] = C, s[22] = P) : P = s[22], useEffect(N, P);
74
+ let F, Te;
75
+ s[23] !== T || s[24] !== y ? (Te = () => {
76
+ T.length > 0 && !T.find((e) => e.blockName === y) && he(T[0].blockName);
77
+ }, F = [T, y], s[23] = T, s[24] = y, s[25] = F, s[26] = Te) : (F = s[25], Te = s[26]), useEffect(Te, F);
78
+ let Ee;
79
+ s[27] !== E || s[28] !== A || s[29] !== l || s[30] !== D ? (Ee = () => {
80
+ l || (f("workspace"), g(!1), me(""), he(""), A.reset({}), E.reset(), D.reset());
81
+ }, s[27] = E, s[28] = A, s[29] = l, s[30] = D, s[31] = Ee) : Ee = s[31];
82
+ let De;
83
+ s[32] === l ? De = s[33] : (De = [l], s[32] = l, s[33] = De), useEffect(Ee, De);
84
+ let Oe;
85
+ s[34] === Symbol.for("react.memo_cache_sentinel") ? (Oe = (e) => {
86
+ me(e), f("automation");
87
+ }, s[34] = Oe) : Oe = s[34];
88
+ let ke = Oe, Ae;
89
+ s[35] === A ? Ae = s[36] : (Ae = (e) => {
90
+ he(e), A.reset({});
91
+ }, s[35] = A, s[36] = Ae);
92
+ let je = Ae, Me, I;
93
+ s[37] !== M || s[38] !== y || s[39] !== j ? (Me = () => {
94
+ y && j && M && f("config");
95
+ }, I = [
96
+ j,
97
+ y,
98
+ M
99
+ ], s[37] = M, s[38] = y, s[39] = j, s[40] = Me, s[41] = I) : (Me = s[40], I = s[41]), useEffect(Me, I);
100
+ let Ne;
101
+ s[42] !== E || s[43] !== u || s[44] !== D || s[45] !== y || s[46] !== v ? (Ne = (e, t) => {
102
+ !v || !y || E.mutate({ pipelineCreateDto: {
103
+ blockName: y,
104
+ title: null,
105
+ workspaceId: v,
106
+ transition: e ?? null,
107
+ args: t ?? {}
108
+ } }, { onSuccess: (e) => {
109
+ D.mutate({
110
+ pipelineId: e.id,
111
+ runPipelinePayloadDto: {},
112
+ force: !0
113
+ }, { onSuccess: () => u(e.id) });
114
+ } });
115
+ }, s[42] = E, s[43] = u, s[44] = D, s[45] = y, s[46] = v, s[47] = Ne) : Ne = s[47];
116
+ let Pe = Ne, Fe;
117
+ s[48] !== Pe || s[49] !== A || s[50] !== M ? (Fe = () => {
118
+ M ? A.handleSubmit((e) => Pe("", e))() : Pe();
119
+ }, s[48] = Pe, s[49] = A, s[50] = M, s[51] = Fe) : Fe = s[51];
120
+ let Ie = Fe, Le = !!v && !!y, Re;
121
+ s[52] === Symbol.for("react.memo_cache_sentinel") ? (Re = (e) => {
122
+ f((t) => t === e ? null : e);
123
+ }, s[52] = Re) : Re = s[52];
124
+ let ze = Re, Be = !!v, L = !!y, R = Be, Ve = L && M, z;
125
+ s[53] === E.error ? z = s[54] : (z = /* @__PURE__ */ jsx(ErrorSnackbar_default, { error: E.error }), s[53] = E.error, s[54] = z);
126
+ let B;
127
+ s[55] === D.error ? B = s[56] : (B = /* @__PURE__ */ jsx(ErrorSnackbar_default, { error: D.error }), s[55] = D.error, s[56] = B);
128
+ let He = Se?.title, Ue = d === "workspace", We = Be && d !== "workspace", Ge;
129
+ s[57] === Symbol.for("react.memo_cache_sentinel") ? (Ge = () => ze("workspace"), s[57] = Ge) : Ge = s[57];
130
+ let V;
131
+ s[58] !== _e || s[59] !== ve || s[60] !== v || s[61] !== p || s[62] !== C ? (V = p ? /* @__PURE__ */ jsx("div", {
132
+ className: "pt-2",
133
+ children: /* @__PURE__ */ jsx(_e, {
134
+ types: ve.data ?? [],
135
+ onSuccess: () => {
136
+ g(!1);
137
+ }
138
+ })
139
+ }) : /* @__PURE__ */ jsxs("div", {
140
+ className: "flex gap-2 pt-2",
141
+ children: [/* @__PURE__ */ jsxs(Select, {
142
+ value: v,
143
+ onValueChange: ke,
144
+ children: [/* @__PURE__ */ jsx(SelectTrigger, {
145
+ id: "workspace",
146
+ className: "flex-1",
147
+ children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select a workspace..." })
148
+ }), /* @__PURE__ */ jsx(SelectContent, { children: C.map(_temp) })]
149
+ }), /* @__PURE__ */ jsx(Button, {
150
+ variant: "outline",
151
+ onClick: () => g(!0),
152
+ className: "px-3",
153
+ title: "Create new workspace",
154
+ children: /* @__PURE__ */ jsx(Plus, { className: "h-4 w-4" })
155
+ })]
156
+ }), s[58] = _e, s[59] = ve, s[60] = v, s[61] = p, s[62] = C, s[63] = V) : V = s[63];
157
+ let H;
158
+ s[64] !== S.isLoading || s[65] !== He || s[66] !== Ue || s[67] !== We || s[68] !== V ? (H = /* @__PURE__ */ jsx(StepSection, {
159
+ step: 1,
160
+ title: "Select Workspace",
161
+ summary: He,
162
+ isActive: Ue,
163
+ isComplete: We,
164
+ isEnabled: !0,
165
+ isLoading: S.isLoading,
166
+ onToggle: Ge,
167
+ children: V
168
+ }), s[64] = S.isLoading, s[65] = He, s[66] = Ue, s[67] = We, s[68] = V, s[69] = H) : H = s[69];
169
+ let U;
170
+ s[70] !== L || s[71] !== T || s[72] !== y ? (U = L ? T.find((e) => e.blockName === y)?.title ?? y : void 0, s[70] = L, s[71] = T, s[72] = y, s[73] = U) : U = s[73];
171
+ let Ke = d === "automation", qe = L && d !== "automation", Je = w.isLoading, W;
172
+ s[74] === R ? W = s[75] : (W = () => R && ze("automation"), s[74] = R, s[75] = W);
173
+ let Ye;
174
+ s[76] === Symbol.for("react.memo_cache_sentinel") ? (Ye = /* @__PURE__ */ jsx(SelectTrigger, {
175
+ id: "automation",
176
+ className: "w-full",
177
+ children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select a workflow..." })
178
+ }), s[76] = Ye) : Ye = s[76];
179
+ let G;
180
+ s[77] === T ? G = s[78] : (G = T.map(_temp2), s[77] = T, s[78] = G);
181
+ let K;
182
+ s[79] === G ? K = s[80] : (K = /* @__PURE__ */ jsx(SelectContent, { children: G }), s[79] = G, s[80] = K);
183
+ let q;
184
+ s[81] !== je || s[82] !== O || s[83] !== y || s[84] !== K ? (q = /* @__PURE__ */ jsx("div", {
185
+ className: "pt-2",
186
+ children: /* @__PURE__ */ jsxs(Select, {
187
+ value: y,
188
+ onValueChange: je,
189
+ disabled: O,
190
+ children: [Ye, K]
191
+ })
192
+ }), s[81] = je, s[82] = O, s[83] = y, s[84] = K, s[85] = q) : q = s[85];
193
+ let J;
194
+ s[86] !== R || s[87] !== w.isLoading || s[88] !== U || s[89] !== Ke || s[90] !== qe || s[91] !== W || s[92] !== q ? (J = /* @__PURE__ */ jsx(StepSection, {
195
+ step: 2,
196
+ title: "Select Workflow",
197
+ summary: U,
198
+ isActive: Ke,
199
+ isComplete: qe,
200
+ isEnabled: R,
201
+ isLoading: Je,
202
+ onToggle: W,
203
+ children: q
204
+ }), s[86] = R, s[87] = w.isLoading, s[88] = U, s[89] = Ke, s[90] = qe, s[91] = W, s[92] = q, s[93] = J) : J = s[93];
205
+ let Y;
206
+ s[94] !== d || s[95] !== Ve || s[96] !== A || s[97] !== M || s[98] !== j ? (Y = M && /* @__PURE__ */ jsx(StepSection, {
207
+ step: 3,
208
+ title: "Configuration",
209
+ isActive: d === "config",
210
+ isComplete: !1,
211
+ isEnabled: Ve,
212
+ onToggle: () => Ve && ze("config"),
213
+ children: /* @__PURE__ */ jsx("div", {
214
+ className: "max-h-72 overflow-y-auto pt-2",
215
+ children: j?.schema && /* @__PURE__ */ jsx(Form_default, {
216
+ form: A,
217
+ schema: j.schema,
218
+ ui: j.ui,
219
+ disabled: !1,
220
+ viewOnly: !1
221
+ })
222
+ })
223
+ }), s[94] = d, s[95] = Ve, s[96] = A, s[97] = M, s[98] = j, s[99] = Y) : Y = s[99];
224
+ let X;
225
+ s[100] !== H || s[101] !== J || s[102] !== Y ? (X = /* @__PURE__ */ jsxs("div", {
226
+ className: "space-y-2",
227
+ children: [
228
+ H,
229
+ J,
230
+ Y
231
+ ]
232
+ }), s[100] = H, s[101] = J, s[102] = Y, s[103] = X) : X = s[103];
233
+ let Xe = !Le || O, Z;
234
+ s[104] === O ? Z = s[105] : (Z = O && /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }), s[104] = O, s[105] = Z);
235
+ let Q;
236
+ s[106] !== Ie || s[107] !== Xe || s[108] !== Z ? (Q = /* @__PURE__ */ jsx("div", {
237
+ className: "mt-4 flex justify-end border-t pt-4",
238
+ children: /* @__PURE__ */ jsxs(Button, {
239
+ variant: "default",
240
+ disabled: Xe,
241
+ onClick: Ie,
242
+ size: "lg",
243
+ className: "font-medium",
244
+ children: [Z, "Run Now"]
245
+ })
246
+ }), s[106] = Ie, s[107] = Xe, s[108] = Z, s[109] = Q) : Q = s[109];
247
+ let $;
248
+ return s[110] !== z || s[111] !== B || s[112] !== X || s[113] !== Q ? ($ = /* @__PURE__ */ jsxs("div", {
249
+ className: "mt-2 overflow-y-auto",
250
+ children: [
251
+ z,
252
+ B,
253
+ X,
254
+ Q
255
+ ]
256
+ }), s[110] = z, s[111] = B, s[112] = X, s[113] = Q, s[114] = $) : $ = s[114], $;
257
+ }
258
+ function _temp2(e) {
259
+ return /* @__PURE__ */ jsxs(SelectPrimitive.Item, {
260
+ value: e.blockName,
261
+ className: "focus:bg-accent focus:text-accent-foreground relative flex w-full cursor-pointer flex-col gap-0.5 rounded-sm py-2 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
262
+ children: [
263
+ /* @__PURE__ */ jsx("span", {
264
+ className: "absolute right-2 top-2.5 flex size-3.5 items-center justify-center",
265
+ children: /* @__PURE__ */ jsx(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(CheckIcon, { className: "size-4" }) })
266
+ }),
267
+ /* @__PURE__ */ jsx(SelectPrimitive.ItemText, { children: e.title ?? e.blockName }),
268
+ e.description && /* @__PURE__ */ jsx("span", {
269
+ className: "text-muted-foreground text-xs leading-snug",
270
+ children: e.description
271
+ })
272
+ ]
273
+ }, e.blockName);
274
+ }
275
+ function _temp(e) {
276
+ return /* @__PURE__ */ jsx(SelectItem, {
277
+ value: e.id,
278
+ children: e.title
279
+ }, e.id);
280
+ }
281
+ function StepSection(e) {
282
+ let t = c(35), { step: n, title: r, summary: i, isActive: a, isComplete: u, isEnabled: d, isLoading: f, onToggle: se, children: ce } = e, p;
283
+ t[0] === se ? p = t[1] : (p = () => se(), t[0] = se, t[1] = p);
284
+ let le = `flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-left transition-colors ${d ? "hover:bg-muted/50 cursor-pointer" : "cursor-not-allowed opacity-50"}`, ue = !d, de = `flex h-7 w-7 flex-shrink-0 items-center justify-center rounded-full text-xs font-semibold ${u ? "bg-primary text-primary-foreground" : a ? "border-primary text-primary border-2" : "border-border text-muted-foreground border"}`, m;
285
+ t[2] !== u || t[3] !== n ? (m = u ? /* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5" }) : n, t[2] = u, t[3] = n, t[4] = m) : m = t[4];
286
+ let h;
287
+ t[5] !== de || t[6] !== m ? (h = /* @__PURE__ */ jsx("div", {
288
+ className: de,
289
+ children: m
290
+ }), t[5] = de, t[6] = m, t[7] = h) : h = t[7];
291
+ let fe = `flex-1 text-sm font-medium ${d ? "text-foreground" : "text-muted-foreground"}`, g;
292
+ t[8] !== fe || t[9] !== r ? (g = /* @__PURE__ */ jsx("span", {
293
+ className: fe,
294
+ children: r
295
+ }), t[8] = fe, t[9] = r, t[10] = g) : g = t[10];
296
+ let _;
297
+ t[11] !== a || t[12] !== u || t[13] !== i ? (_ = !a && u && i && /* @__PURE__ */ jsx("span", {
298
+ className: "text-muted-foreground mr-1 max-w-48 truncate text-sm",
299
+ children: i
300
+ }), t[11] = a, t[12] = u, t[13] = i, t[14] = _) : _ = t[14];
301
+ let v;
302
+ t[15] !== a || t[16] !== f ? (v = f && a && /* @__PURE__ */ jsx(Loader2, { className: "text-muted-foreground h-4 w-4 animate-spin" }), t[15] = a, t[16] = f, t[17] = v) : v = t[17];
303
+ let pe = `text-muted-foreground h-4 w-4 transition-transform ${a ? "rotate-180" : ""}`, y;
304
+ t[18] === pe ? y = t[19] : (y = /* @__PURE__ */ jsx(ChevronDown, { className: pe }), t[18] = pe, t[19] = y);
305
+ let b;
306
+ t[20] !== v || t[21] !== y || t[22] !== le || t[23] !== ue || t[24] !== h || t[25] !== g || t[26] !== _ ? (b = /* @__PURE__ */ jsxs(CollapsibleTrigger, {
307
+ className: le,
308
+ disabled: ue,
309
+ children: [
310
+ h,
311
+ g,
312
+ _,
313
+ v,
314
+ y
315
+ ]
316
+ }), t[20] = v, t[21] = y, t[22] = le, t[23] = ue, t[24] = h, t[25] = g, t[26] = _, t[27] = b) : b = t[27];
317
+ let x;
318
+ t[28] === ce ? x = t[29] : (x = /* @__PURE__ */ jsx(CollapsibleContent, {
319
+ className: "px-3 pb-3 pl-13",
320
+ children: ce
321
+ }), t[28] = ce, t[29] = x);
322
+ let ge;
323
+ return t[30] !== a || t[31] !== p || t[32] !== b || t[33] !== x ? (ge = /* @__PURE__ */ jsxs(Collapsible, {
324
+ open: a,
325
+ onOpenChange: p,
326
+ children: [b, x]
327
+ }), t[30] = a, t[31] = p, t[32] = b, t[33] = x, t[34] = ge) : ge = t[34], ge;
328
+ }
329
+ export { NewRunDialog };
@@ -0,0 +1,88 @@
1
+ import { cn } from "../../../lib/utils.js";
2
+ import { SidebarMenu, SidebarProvider } from "../../../components/ui/sidebar.js";
3
+ import { useWorkbenchLayout } from "../providers/WorkbenchLayoutProvider.js";
4
+ import { useNamespaceTree } from "../../../hooks/useNamespaceTree.js";
5
+ import WorkbenchNavigation_default from "../WorkbenchNavigation.js";
6
+ import PipelineHistoryList_default from "./PipelineHistoryList.js";
7
+ import { c } from "react/compiler-runtime";
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
+ import { X } from "lucide-react";
10
+ var PANEL_TITLES = {
11
+ navigation: "Navigate",
12
+ history: "Run Log"
13
+ };
14
+ function NavigationContent() {
15
+ let e = c(3), { pipeline: f } = useWorkbenchLayout(), p;
16
+ e[0] === Symbol.for("react.memo_cache_sentinel") ? (p = { "--sidebar-width": "100%" }, e[0] = p) : p = e[0];
17
+ let m;
18
+ return e[1] === f.id ? m = e[2] : (m = /* @__PURE__ */ jsx(SidebarProvider, {
19
+ defaultOpen: !0,
20
+ className: "min-h-0",
21
+ style: p,
22
+ children: /* @__PURE__ */ jsx("div", {
23
+ className: "w-full overflow-auto p-2",
24
+ children: /* @__PURE__ */ jsx(SidebarMenu, { children: /* @__PURE__ */ jsx(NavigationContentInner, { pipelineId: f.id }) })
25
+ })
26
+ }), e[1] = f.id, e[2] = m), m;
27
+ }
28
+ function NavigationContentInner(e) {
29
+ let l = c(3), { pipelineId: u } = e, d = useNamespaceTree(u);
30
+ if (!d || d.length === 0) {
31
+ let e;
32
+ return l[0] === Symbol.for("react.memo_cache_sentinel") ? (e = /* @__PURE__ */ jsx("div", {
33
+ className: "text-muted-foreground py-4 text-center text-sm",
34
+ children: "No navigation items"
35
+ }), l[0] = e) : e = l[0], e;
36
+ }
37
+ let m;
38
+ return l[1] === d ? m = l[2] : (m = /* @__PURE__ */ jsx(WorkbenchNavigation_default, {
39
+ namespaceTree: d,
40
+ indent: 0
41
+ }), l[1] = d, l[2] = m), m;
42
+ }
43
+ function HistoryContent() {
44
+ let e = c(2), { pipeline: l } = useWorkbenchLayout(), u;
45
+ return e[0] === l ? u = e[1] : (u = /* @__PURE__ */ jsx("div", {
46
+ className: "overflow-auto p-2",
47
+ children: /* @__PURE__ */ jsx(PipelineHistoryList_default, { pipeline: l })
48
+ }), e[0] = l, e[1] = u), u;
49
+ }
50
+ function WorkbenchFloatingPanel() {
51
+ let l = c(19), { activeFloatingPanel: u, closeFloatingPanel: f } = useWorkbenchLayout();
52
+ if (!u) return null;
53
+ let p;
54
+ l[0] === Symbol.for("react.memo_cache_sentinel") ? (p = cn("border-l bg-background absolute right-0 top-0 bottom-0 z-20 flex w-80 flex-col shadow-lg", "animate-in slide-in-from-right duration-200"), l[0] = p) : p = l[0];
55
+ let m = PANEL_TITLES[u], h;
56
+ l[1] === m ? h = l[2] : (h = /* @__PURE__ */ jsx("span", {
57
+ className: "text-sm font-medium",
58
+ children: m
59
+ }), l[1] = m, l[2] = h);
60
+ let g;
61
+ l[3] === Symbol.for("react.memo_cache_sentinel") ? (g = /* @__PURE__ */ jsx(X, { className: "h-4 w-4" }), l[3] = g) : g = l[3];
62
+ let _;
63
+ l[4] === f ? _ = l[5] : (_ = /* @__PURE__ */ jsx("button", {
64
+ onClick: f,
65
+ className: "text-muted-foreground hover:text-foreground flex h-8 w-8 items-center justify-center rounded-md transition-colors hover:cursor-pointer",
66
+ children: g
67
+ }), l[4] = f, l[5] = _);
68
+ let v;
69
+ l[6] !== h || l[7] !== _ ? (v = /* @__PURE__ */ jsxs("div", {
70
+ className: "border-b flex h-12 shrink-0 items-center justify-between px-3",
71
+ children: [h, _]
72
+ }), l[6] = h, l[7] = _, l[8] = v) : v = l[8];
73
+ let y;
74
+ l[9] === u ? y = l[10] : (y = u === "navigation" && /* @__PURE__ */ jsx(NavigationContent, {}), l[9] = u, l[10] = y);
75
+ let b;
76
+ l[11] === u ? b = l[12] : (b = u === "history" && /* @__PURE__ */ jsx(HistoryContent, {}), l[11] = u, l[12] = b);
77
+ let x;
78
+ l[13] !== y || l[14] !== b ? (x = /* @__PURE__ */ jsxs("div", {
79
+ className: "flex-1 overflow-hidden",
80
+ children: [y, b]
81
+ }), l[13] = y, l[14] = b, l[15] = x) : x = l[15];
82
+ let S;
83
+ return l[16] !== v || l[17] !== x ? (S = /* @__PURE__ */ jsxs("div", {
84
+ className: p,
85
+ children: [v, x]
86
+ }), l[16] = v, l[17] = x, l[18] = S) : S = l[18], S;
87
+ }
88
+ export { WorkbenchFloatingPanel };
@@ -0,0 +1,49 @@
1
+ import { usePipeline, usePipelineConfigByName } from "../../../hooks/usePipelines.js";
2
+ import { useWorkspace } from "../../../hooks/useWorkspaces.js";
3
+ import { ReactFlowProvider } from "../../../node_modules/@xyflow/react/dist/esm/index.js";
4
+ import { useFetchWorkflowsByPipeline } from "../../../hooks/useWorkflows.js";
5
+ import PipelineFlowViewer_default from "../../debug/components/PipelineFlowViewer.js";
6
+ import "../../debug/index.js";
7
+ import { useWorkbenchLayout } from "../providers/WorkbenchLayoutProvider.js";
8
+ import { c } from "react/compiler-runtime";
9
+ import { useMemo } from "react";
10
+ import { jsx, jsxs } from "react/jsx-runtime";
11
+ import { X } from "lucide-react";
12
+ function WorkbenchFlowPanel() {
13
+ let f = c(13), { pipeline: p, closeSidePanel: m } = useWorkbenchLayout(), h = usePipeline(p.id), g = useWorkspace(p.workspaceId), _ = useFetchWorkflowsByPipeline(p.id), v = usePipelineConfigByName(g.data?.blockName, h.data?.blockName), y;
14
+ f[0] === _.data ? y = f[1] : (y = _.data ?? [], f[0] = _.data, f[1] = y);
15
+ let b = y, x;
16
+ f[2] === Symbol.for("react.memo_cache_sentinel") ? (x = /* @__PURE__ */ jsx("span", {
17
+ className: "text-sm font-medium",
18
+ children: "Graph"
19
+ }), f[2] = x) : x = f[2];
20
+ let S;
21
+ f[3] === Symbol.for("react.memo_cache_sentinel") ? (S = /* @__PURE__ */ jsx(X, { className: "h-4 w-4" }), f[3] = S) : S = f[3];
22
+ let C;
23
+ f[4] === m ? C = f[5] : (C = /* @__PURE__ */ jsxs("div", {
24
+ className: "border-b flex h-12 shrink-0 items-center justify-between px-3",
25
+ children: [x, /* @__PURE__ */ jsx("button", {
26
+ onClick: m,
27
+ className: "text-muted-foreground hover:text-foreground flex h-8 w-8 items-center justify-center rounded-md transition-colors hover:cursor-pointer",
28
+ children: S
29
+ })]
30
+ }), f[4] = m, f[5] = C);
31
+ let w;
32
+ f[6] !== v || f[7] !== p.id || f[8] !== b ? (w = /* @__PURE__ */ jsx("div", {
33
+ className: "flex-1 overflow-hidden",
34
+ children: b.length > 0 ? /* @__PURE__ */ jsx(ReactFlowProvider, { children: /* @__PURE__ */ jsx(PipelineFlowViewer_default, {
35
+ pipelineId: p.id,
36
+ workflows: b,
37
+ pipelineConfig: v.data
38
+ }) }) : /* @__PURE__ */ jsx("div", {
39
+ className: "text-muted-foreground flex h-full items-center justify-center text-sm",
40
+ children: "No workflows found"
41
+ })
42
+ }), f[6] = v, f[7] = p.id, f[8] = b, f[9] = w) : w = f[9];
43
+ let T;
44
+ return f[10] !== C || f[11] !== w ? (T = /* @__PURE__ */ jsxs("div", {
45
+ className: "border-l bg-background flex w-1/2 shrink-0 flex-col",
46
+ children: [C, w]
47
+ }), f[10] = C, f[11] = w, f[12] = T) : T = f[12], T;
48
+ }
49
+ export { WorkbenchFlowPanel };
@@ -0,0 +1,68 @@
1
+ import { cn } from "../../../lib/utils.js";
2
+ import { Tooltip, TooltipContent, TooltipTrigger } from "../../../components/ui/tooltip.js";
3
+ import { useWorkbenchLayout } from "../providers/WorkbenchLayoutProvider.js";
4
+ import { c } from "react/compiler-runtime";
5
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
+ import { ListOrdered, MonitorPlay, Navigation, Workflow } from "lucide-react";
7
+ function IconButton(s) {
8
+ let l = c(11), { icon: u, label: d, active: f, onClick: p } = s, m = f ? "bg-foreground text-background" : "text-muted-foreground hover:bg-accent/50 hover:text-accent-foreground", h;
9
+ l[0] === m ? h = l[1] : (h = cn("flex h-10 w-10 items-center justify-center rounded-md transition-colors hover:cursor-pointer", m), l[0] = m, l[1] = h);
10
+ let g;
11
+ l[2] !== u || l[3] !== p || l[4] !== h ? (g = /* @__PURE__ */ jsx(TooltipTrigger, {
12
+ asChild: !0,
13
+ children: /* @__PURE__ */ jsx("button", {
14
+ onClick: p,
15
+ className: h,
16
+ children: u
17
+ })
18
+ }), l[2] = u, l[3] = p, l[4] = h, l[5] = g) : g = l[5];
19
+ let _;
20
+ l[6] === d ? _ = l[7] : (_ = /* @__PURE__ */ jsx(TooltipContent, {
21
+ side: "left",
22
+ children: d
23
+ }), l[6] = d, l[7] = _);
24
+ let v;
25
+ return l[8] !== g || l[9] !== _ ? (v = /* @__PURE__ */ jsxs(Tooltip, { children: [g, _] }), l[8] = g, l[9] = _, l[10] = v) : v = l[10], v;
26
+ }
27
+ function WorkbenchIconSidebar() {
28
+ let e = c(20), { previewPanelEnabled: i, isDeveloperMode: a, activeFloatingPanel: o, toggleFloatingPanel: h, activeSidePanel: g, toggleSidePanel: _ } = useWorkbenchLayout(), v;
29
+ e[0] !== g || e[1] !== i || e[2] !== _ ? (v = i && /* @__PURE__ */ jsx(IconButton, {
30
+ icon: /* @__PURE__ */ jsx(MonitorPlay, { className: "h-5 w-5" }),
31
+ label: "Preview",
32
+ active: g === "preview",
33
+ onClick: () => _("preview")
34
+ }), e[0] = g, e[1] = i, e[2] = _, e[3] = v) : v = e[3];
35
+ let y;
36
+ e[4] !== o || e[5] !== g || e[6] !== a || e[7] !== h || e[8] !== _ ? (y = a && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(IconButton, {
37
+ icon: /* @__PURE__ */ jsx(Workflow, { className: "h-5 w-5" }),
38
+ label: "Graph",
39
+ active: g === "flow",
40
+ onClick: () => _("flow")
41
+ }), /* @__PURE__ */ jsx(IconButton, {
42
+ icon: /* @__PURE__ */ jsx(ListOrdered, { className: "h-5 w-5" }),
43
+ label: "Run Log",
44
+ active: o === "history",
45
+ onClick: () => h("history")
46
+ })] }), e[4] = o, e[5] = g, e[6] = a, e[7] = h, e[8] = _, e[9] = y) : y = e[9];
47
+ let b;
48
+ e[10] === Symbol.for("react.memo_cache_sentinel") ? (b = /* @__PURE__ */ jsx(Navigation, { className: "h-5 w-5" }), e[10] = b) : b = e[10];
49
+ let x = o === "navigation", S;
50
+ e[11] === h ? S = e[12] : (S = () => h("navigation"), e[11] = h, e[12] = S);
51
+ let C;
52
+ e[13] !== x || e[14] !== S ? (C = /* @__PURE__ */ jsx(IconButton, {
53
+ icon: b,
54
+ label: "Navigate",
55
+ active: x,
56
+ onClick: S
57
+ }), e[13] = x, e[14] = S, e[15] = C) : C = e[15];
58
+ let w;
59
+ return e[16] !== v || e[17] !== y || e[18] !== C ? (w = /* @__PURE__ */ jsxs("div", {
60
+ className: "border-l bg-background flex w-12 shrink-0 flex-col items-center gap-1 py-2",
61
+ children: [
62
+ v,
63
+ y,
64
+ C
65
+ ]
66
+ }), e[16] = v, e[17] = y, e[18] = C, e[19] = w) : w = e[19], w;
67
+ }
68
+ export { WorkbenchIconSidebar };
@@ -0,0 +1,128 @@
1
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../../../components/ui/select.js";
2
+ import { Tooltip, TooltipContent, TooltipTrigger } from "../../../components/ui/tooltip.js";
3
+ import { useWorkbenchLayout } from "../providers/WorkbenchLayoutProvider.js";
4
+ import { useEffect, useMemo, useRef, useState } from "react";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ import { ExternalLink, Loader2, X } from "lucide-react";
7
+ var EMBED_NEW_RUN_MESSAGE_TYPE = "loopstack:embed:new-run";
8
+ function WorkbenchPreviewPanel() {
9
+ let { getEnvironmentPreviewUrl: y, environments: b, closeSidePanel: x, selectedSlotId: S, setSelectedSlotId: C } = useWorkbenchLayout(), w = useRef(null), T = useMemo(() => (b ?? []).filter((e) => !!e.connectionUrl && (!!e.workerId || e.local)), [b]), [E, D] = useState(null);
10
+ useEffect(() => {
11
+ !S && T.length > 0 && C(T[0].slotId);
12
+ }, [
13
+ T,
14
+ S,
15
+ C
16
+ ]);
17
+ let O = useMemo(() => T.find((e) => e.slotId === S), [T, S]), k = useMemo(() => {
18
+ if (!(!y || !O)) return y(O, E ?? void 0);
19
+ }, [
20
+ y,
21
+ O,
22
+ E
23
+ ]);
24
+ return useEffect(() => {
25
+ let e = (e) => {
26
+ if (e.origin !== window.location.origin) return;
27
+ let _ = e.data;
28
+ if (_?.type !== EMBED_NEW_RUN_MESSAGE_TYPE) return;
29
+ let v = _?.pipelineId;
30
+ typeof v == "string" && D(v);
31
+ };
32
+ return window.addEventListener("message", e), () => window.removeEventListener("message", e);
33
+ }, []), b === void 0 ? /* @__PURE__ */ jsxs("div", {
34
+ className: "border-l bg-zinc-950 flex w-1/2 shrink-0 flex-col",
35
+ children: [/* @__PURE__ */ jsxs("div", {
36
+ className: "flex h-12 shrink-0 items-center justify-between px-3",
37
+ children: [/* @__PURE__ */ jsx("span", {
38
+ className: "text-sm font-medium text-white",
39
+ children: "Preview"
40
+ }), /* @__PURE__ */ jsx("button", {
41
+ onClick: x,
42
+ className: "text-zinc-400 hover:text-white flex h-8 w-8 items-center justify-center rounded-md transition-colors hover:cursor-pointer",
43
+ children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
44
+ })]
45
+ }), /* @__PURE__ */ jsx("div", {
46
+ className: "flex flex-1 items-center justify-center",
47
+ children: /* @__PURE__ */ jsx(Loader2, { className: "h-5 w-5 animate-spin text-zinc-400" })
48
+ })]
49
+ }) : !y || T.length === 0 ? /* @__PURE__ */ jsxs("div", {
50
+ className: "border-l bg-zinc-950 flex w-1/2 shrink-0 flex-col",
51
+ children: [/* @__PURE__ */ jsxs("div", {
52
+ className: "flex h-12 shrink-0 items-center justify-between px-3",
53
+ children: [/* @__PURE__ */ jsx("span", {
54
+ className: "text-sm font-medium text-white",
55
+ children: "Preview"
56
+ }), /* @__PURE__ */ jsx("button", {
57
+ onClick: x,
58
+ className: "text-zinc-400 hover:text-white flex h-8 w-8 items-center justify-center rounded-md transition-colors hover:cursor-pointer",
59
+ children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
60
+ })]
61
+ }), /* @__PURE__ */ jsx("div", {
62
+ className: "text-zinc-400 flex flex-1 items-center justify-center text-sm",
63
+ children: "Preview not available"
64
+ })]
65
+ }) : /* @__PURE__ */ jsxs("div", {
66
+ className: "border-l bg-zinc-950 flex w-1/2 shrink-0 flex-col",
67
+ children: [/* @__PURE__ */ jsxs("div", {
68
+ className: "flex h-12 shrink-0 items-center justify-between px-3",
69
+ children: [/* @__PURE__ */ jsxs("div", {
70
+ className: "flex items-center gap-2",
71
+ children: [
72
+ /* @__PURE__ */ jsx("span", {
73
+ className: "text-sm font-medium text-white",
74
+ children: "Preview"
75
+ }),
76
+ T.length > 1 && /* @__PURE__ */ jsxs(Select, {
77
+ value: S,
78
+ onValueChange: (e) => {
79
+ C(e), D(null);
80
+ },
81
+ children: [/* @__PURE__ */ jsx(SelectTrigger, {
82
+ className: "h-7 w-40 border-zinc-700 bg-zinc-900 text-zinc-200 text-xs",
83
+ children: /* @__PURE__ */ jsx(SelectValue, {})
84
+ }), /* @__PURE__ */ jsx(SelectContent, { children: T.map((e) => /* @__PURE__ */ jsx(SelectItem, {
85
+ value: e.slotId,
86
+ children: e.envName || e.slotId
87
+ }, e.slotId)) })]
88
+ }),
89
+ T.length === 1 && O && /* @__PURE__ */ jsx("span", {
90
+ className: "text-xs text-zinc-400",
91
+ children: O.envName || O.slotId
92
+ })
93
+ ]
94
+ }), /* @__PURE__ */ jsxs("div", {
95
+ className: "flex items-center gap-1",
96
+ children: [k && /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
97
+ asChild: !0,
98
+ children: /* @__PURE__ */ jsx("a", {
99
+ href: k,
100
+ target: "_blank",
101
+ rel: "noopener noreferrer",
102
+ className: "text-zinc-400 hover:text-white flex h-8 w-8 items-center justify-center rounded-md transition-colors hover:cursor-pointer",
103
+ children: /* @__PURE__ */ jsx(ExternalLink, { className: "h-4 w-4" })
104
+ })
105
+ }), /* @__PURE__ */ jsx(TooltipContent, {
106
+ side: "bottom",
107
+ children: "Open in new tab"
108
+ })] }), /* @__PURE__ */ jsx("button", {
109
+ onClick: x,
110
+ className: "text-zinc-400 hover:text-white flex h-8 w-8 items-center justify-center rounded-md transition-colors hover:cursor-pointer",
111
+ children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
112
+ })]
113
+ })]
114
+ }), k ? /* @__PURE__ */ jsx("div", {
115
+ className: "flex-1 overflow-hidden p-3 pt-0",
116
+ children: /* @__PURE__ */ jsx("iframe", {
117
+ ref: w,
118
+ src: k,
119
+ className: "bg-background h-full w-full rounded-lg",
120
+ title: "Pipeline preview"
121
+ })
122
+ }) : /* @__PURE__ */ jsx("div", {
123
+ className: "text-zinc-400 flex flex-1 items-center justify-center text-sm",
124
+ children: "Preview not available"
125
+ })]
126
+ });
127
+ }
128
+ export { WorkbenchPreviewPanel };