@loopstack/loopstack-studio 0.25.2 → 0.26.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.
- package/dist/api/environments.js +4 -0
- package/dist/api/index.js +13 -9
- package/dist/app/EnvironmentEmbedRoot.js +29 -19
- package/dist/components/data-table/DataList.js +93 -91
- package/dist/components/data-table/DataTable.js +128 -126
- package/dist/components/feedback/Snackbar.js +1 -1
- package/dist/components/layout/StudioSidebar.js +124 -131
- package/dist/components/ui/sidebar.js +2 -2
- package/dist/components/ui/slider.js +37 -26
- package/dist/components/ui-widgets/widgets/SandboxRun.js +16 -14
- package/dist/features/code-explorer/components/CodeExplorerTree.js +1 -0
- package/dist/features/code-explorer/components/FileContentViewer.js +1 -1
- package/dist/features/dashboard/RunItem.js +39 -37
- package/dist/features/debug/lib/flow-utils.js +1 -1
- package/dist/features/documents/DocumentRenderer.js +59 -58
- package/dist/features/documents/renderers/useDocumentTransition.js +29 -24
- package/dist/features/feature-registry/FeatureRegistryProvider.js +17 -0
- package/dist/features/feature-registry/index.js +1 -0
- package/dist/features/file-explorer/api/files.js +7 -0
- package/dist/features/file-explorer/components/FileExplorerPanel.js +95 -0
- package/dist/features/{workbench/components/RemoteFileTabsBar.js → file-explorer/components/FileTabsBar.js} +4 -4
- package/dist/features/{workbench/components/RemoteFileTree.js → file-explorer/components/FileTree.js} +6 -6
- package/dist/features/file-explorer/file-explorer-feature.js +12 -0
- package/dist/features/file-explorer/hooks/useFileExplorer.js +44 -0
- package/dist/features/file-explorer/index.js +2 -0
- package/dist/features/file-explorer/providers/FileExplorerProvider.js +112 -0
- package/dist/features/oauth/OAuthPromptRenderer.js +162 -132
- package/dist/features/runs/Runs.js +1 -1
- package/dist/features/secrets/components/WorkbenchSecretsPanel.js +178 -0
- package/dist/features/secrets/index.js +1 -0
- package/dist/features/{documents → secrets}/renderers/SecretInputRenderer.js +17 -17
- package/dist/features/secrets/secrets-feature.js +14 -0
- package/dist/features/workbench/Workbench.js +32 -82
- package/dist/features/workbench/WorkflowList.js +109 -46
- package/dist/features/workbench/components/SidebarPanel.js +155 -0
- package/dist/features/workbench/components/WorkbenchEnvironmentPanel.js +82 -0
- package/dist/features/workbench/components/WorkbenchIconSidebar.js +128 -60
- package/dist/features/workbench/components/WorkbenchPreviewPanel.js +127 -114
- package/dist/features/workbench/components/WorkbenchRunsPanel.js +32 -0
- package/dist/features/workbench/components/WorkbenchSidebarShell.js +80 -0
- package/dist/features/workbench/hooks/useWorkflowData.js +3 -3
- package/dist/features/workbench/index.js +3 -2
- package/dist/features/workbench/providers/WorkbenchLayoutProvider.js +60 -62
- package/dist/features/workspaces/Workspaces.js +1 -1
- package/dist/features/workspaces/components/EnvironmentSlotSelector.js +68 -51
- package/dist/features/workspaces/components/WorkflowRunForm.js +1 -1
- package/dist/features/workspaces/components/WorkspaceHomePage.js +1 -1
- package/dist/hooks/useEnvironmentPreviewUrl.js +13 -0
- package/dist/hooks/useEnvironments.js +8 -0
- package/dist/hooks/useWorkflows.js +28 -26
- package/dist/hooks/useWorkspaces.js +28 -26
- package/dist/index.d.ts +98 -7
- package/dist/index.js +8 -1
- package/dist/loopstack-studio.css +1 -1
- package/dist/node_modules/@shikijs/core/dist/index.js +105 -643
- package/dist/node_modules/@shikijs/engine-oniguruma/dist/index.js +135 -122
- package/dist/node_modules/@shikijs/langs/dist/bird2.js +1 -1
- package/dist/node_modules/@shikijs/langs/dist/cobol.js +1 -1
- package/dist/node_modules/@shikijs/langs/dist/css.js +1 -1
- package/dist/node_modules/@shikijs/langs/dist/dart.js +1 -1
- package/dist/node_modules/@shikijs/langs/dist/emacs-lisp.js +1 -1
- package/dist/node_modules/@shikijs/langs/dist/es-tag-sql.js +1 -1
- package/dist/node_modules/@shikijs/langs/dist/go.js +1 -1
- package/dist/node_modules/@shikijs/langs/dist/kusto.js +1 -1
- package/dist/node_modules/@shikijs/langs/dist/nextflow-groovy.js +1 -1
- package/dist/node_modules/@shikijs/langs/dist/php.js +1 -1
- package/dist/node_modules/@shikijs/langs/dist/ruby.js +1 -1
- package/dist/node_modules/@shikijs/langs/dist/typespec.js +1 -1
- package/dist/node_modules/@shikijs/primitive/dist/index.js +538 -0
- package/dist/node_modules/@shikijs/themes/dist/horizon-bright.js +1 -1
- package/dist/node_modules/@xyflow/react/dist/esm/index.js +1 -1
- package/dist/node_modules/shiki/dist/bundle-full.js +6 -5
- package/dist/node_modules/shiki/dist/chunk-CtajNgzt.js +15 -0
- package/dist/node_modules/shiki/dist/engine-oniguruma.js +5 -0
- package/dist/node_modules/shiki/dist/{langs.js → langs-bundle-full-DfKZStlK.js} +1 -1
- package/dist/node_modules/shiki/dist/themes.js +1 -1
- package/dist/pages/DashboardPage.js +54 -79
- package/dist/pages/DebugWorkflowDetailsPage.js +41 -55
- package/dist/pages/DebugWorkflowsPage.js +151 -112
- package/dist/pages/EmbedWorkbenchPage.js +2 -1
- package/dist/pages/PreviewWorkbenchPage.js +77 -59
- package/dist/pages/RunsListPage.js +27 -41
- package/dist/pages/RunsPage.js +21 -36
- package/dist/pages/WorkbenchPage.js +48 -70
- package/dist/pages/WorkflowDebugPage.js +65 -79
- package/dist/pages/WorkspacePage.js +59 -86
- package/dist/pages/WorkspaceRunsPage.js +59 -54
- package/dist/pages/WorkspacesPage.js +11 -27
- package/dist/providers/StudioPreferencesProvider.js +54 -0
- package/package.json +29 -29
- package/dist/features/workbench/components/WorkbenchFilesPanel.js +0 -67
- package/dist/features/workbench/components/WorkbenchFloatingPanel.js +0 -57
- package/dist/features/workbench/components/WorkbenchFlowPanel.js +0 -47
- package/dist/features/workbench/components/WorkbenchSecretsPanel.js +0 -182
- package/dist/features/workbench/providers/RemoteFileExplorerProvider.js +0 -160
- /package/dist/{node_modules → frontend/studio/node_modules}/@dagrejs/dagre/dist/dagre.esm.js +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { MarkerType, Position } from "../../../node_modules/@xyflow/system/dist/esm/index.js";
|
|
2
|
-
import dagre_esm_default from "../../../node_modules/@dagrejs/dagre/dist/dagre.esm.js";
|
|
2
|
+
import dagre_esm_default from "../../../frontend/studio/node_modules/@dagrejs/dagre/dist/dagre.esm.js";
|
|
3
3
|
var NODE_WIDTH = 130, NODE_HEIGHT = 70, CONDITION_OPERATORS = {
|
|
4
4
|
gt: ">",
|
|
5
5
|
lt: "<",
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import CompletionMessagePaper_default from "../../components/messages/CompletionMessagePaper.js";
|
|
2
|
+
import { useFeatureRegistry } from "../feature-registry/FeatureRegistryProvider.js";
|
|
3
|
+
import "../feature-registry/index.js";
|
|
2
4
|
import OAuthPromptRenderer_default from "../oauth/OAuthPromptRenderer.js";
|
|
3
5
|
import "../oauth/index.js";
|
|
4
6
|
import AiMessage_default from "./renderers/AiMessage.js";
|
|
@@ -12,83 +14,82 @@ import ErrorMessageRenderer_default from "./renderers/ErrorMessageRenderer.js";
|
|
|
12
14
|
import LinkMessageRenderer_default from "./renderers/LinkMessageRenderer.js";
|
|
13
15
|
import MarkdownMessageRenderer_default from "./renderers/MarkdownMessageRenderer.js";
|
|
14
16
|
import PlainMessageRenderer_default from "./renderers/PlainMessageRenderer.js";
|
|
15
|
-
import SecretInputRenderer_default from "./renderers/SecretInputRenderer.js";
|
|
16
17
|
import TextPromptRenderer_default from "./renderers/TextPromptRenderer.js";
|
|
17
18
|
import { c } from "react/compiler-runtime";
|
|
18
|
-
import React from "react";
|
|
19
|
+
import React, { useMemo } from "react";
|
|
19
20
|
import { Fragment as Fragment$1, jsx } from "react/jsx-runtime";
|
|
20
|
-
var
|
|
21
|
-
["ai-message", ({ document:
|
|
22
|
-
document:
|
|
23
|
-
isLastItem:
|
|
21
|
+
var coreRendererRegistry = new Map([
|
|
22
|
+
["ai-message", ({ document: e, isLastItem: _ }) => /* @__PURE__ */ jsx(AiMessage_default, {
|
|
23
|
+
document: e,
|
|
24
|
+
isLastItem: _
|
|
24
25
|
})],
|
|
25
|
-
["claude-message", ({ document:
|
|
26
|
-
document:
|
|
27
|
-
isLastItem:
|
|
26
|
+
["claude-message", ({ document: e, isLastItem: _ }) => /* @__PURE__ */ jsx(ClaudeMessage_default, {
|
|
27
|
+
document: e,
|
|
28
|
+
isLastItem: _
|
|
28
29
|
})],
|
|
29
|
-
["debug", ({ document:
|
|
30
|
+
["debug", ({ document: e }) => /* @__PURE__ */ jsx("div", {
|
|
30
31
|
className: "mb-4 flex",
|
|
31
|
-
children: /* @__PURE__ */ jsx(DocumentDebugRenderer_default, { document:
|
|
32
|
+
children: /* @__PURE__ */ jsx(DocumentDebugRenderer_default, { document: e })
|
|
32
33
|
})],
|
|
33
|
-
["form", ({ parentWorkflow:
|
|
34
|
+
["form", ({ parentWorkflow: _, workflow: v, document: y, isActive: b }) => /* @__PURE__ */ jsx(CompletionMessagePaper_default, {
|
|
34
35
|
role: "document",
|
|
35
36
|
fullWidth: !0,
|
|
36
|
-
timestamp: new Date(
|
|
37
|
+
timestamp: new Date(y.createdAt),
|
|
37
38
|
children: /* @__PURE__ */ jsx(DocumentFormRenderer_default, {
|
|
38
|
-
parentWorkflow:
|
|
39
|
-
workflow:
|
|
40
|
-
document:
|
|
41
|
-
enabled:
|
|
42
|
-
viewOnly: !
|
|
39
|
+
parentWorkflow: _,
|
|
40
|
+
workflow: v,
|
|
41
|
+
document: y,
|
|
42
|
+
enabled: b,
|
|
43
|
+
viewOnly: !b
|
|
43
44
|
})
|
|
44
45
|
})],
|
|
45
|
-
["message", ({ document:
|
|
46
|
-
["error", ({ document:
|
|
47
|
-
["plain", ({ document:
|
|
48
|
-
["markdown", ({ document:
|
|
49
|
-
["link", ({ document:
|
|
50
|
-
["oauth-prompt", ({ parentWorkflow:
|
|
51
|
-
parentWorkflow:
|
|
52
|
-
workflow:
|
|
53
|
-
document: b,
|
|
54
|
-
isActive: x
|
|
55
|
-
})],
|
|
56
|
-
["text-prompt", ({ parentWorkflow: t, workflow: v, document: y, isActive: b }) => /* @__PURE__ */ jsx(TextPromptRenderer_default, {
|
|
57
|
-
parentWorkflow: t,
|
|
58
|
-
workflow: v,
|
|
46
|
+
["message", ({ document: e }) => /* @__PURE__ */ jsx(DocumentMessageRenderer_default, { document: e })],
|
|
47
|
+
["error", ({ document: e }) => /* @__PURE__ */ jsx(ErrorMessageRenderer_default, { document: e })],
|
|
48
|
+
["plain", ({ document: e }) => /* @__PURE__ */ jsx(PlainMessageRenderer_default, { document: e })],
|
|
49
|
+
["markdown", ({ document: e }) => /* @__PURE__ */ jsx(MarkdownMessageRenderer_default, { document: e })],
|
|
50
|
+
["link", ({ document: e }) => /* @__PURE__ */ jsx(LinkMessageRenderer_default, { document: e })],
|
|
51
|
+
["oauth-prompt", ({ parentWorkflow: e, workflow: _, document: y, isActive: b }) => /* @__PURE__ */ jsx(OAuthPromptRenderer_default, {
|
|
52
|
+
parentWorkflow: e,
|
|
53
|
+
workflow: _,
|
|
59
54
|
document: y,
|
|
60
55
|
isActive: b
|
|
61
56
|
})],
|
|
62
|
-
["
|
|
63
|
-
parentWorkflow:
|
|
64
|
-
workflow:
|
|
65
|
-
document:
|
|
66
|
-
isActive:
|
|
57
|
+
["text-prompt", ({ parentWorkflow: e, workflow: _, document: v, isActive: y }) => /* @__PURE__ */ jsx(TextPromptRenderer_default, {
|
|
58
|
+
parentWorkflow: e,
|
|
59
|
+
workflow: _,
|
|
60
|
+
document: v,
|
|
61
|
+
isActive: y
|
|
67
62
|
})],
|
|
68
|
-
["
|
|
69
|
-
parentWorkflow:
|
|
70
|
-
workflow:
|
|
71
|
-
document:
|
|
72
|
-
isActive:
|
|
63
|
+
["choices", ({ parentWorkflow: e, workflow: _, document: v, isActive: y }) => /* @__PURE__ */ jsx(ChoicesRenderer_default, {
|
|
64
|
+
parentWorkflow: e,
|
|
65
|
+
workflow: _,
|
|
66
|
+
document: v,
|
|
67
|
+
isActive: y
|
|
73
68
|
})],
|
|
74
|
-
["
|
|
75
|
-
parentWorkflow:
|
|
76
|
-
workflow:
|
|
77
|
-
document:
|
|
78
|
-
isActive:
|
|
69
|
+
["confirm-prompt", ({ parentWorkflow: e, workflow: _, document: v, isActive: y }) => /* @__PURE__ */ jsx(ConfirmPromptRenderer_default, {
|
|
70
|
+
parentWorkflow: e,
|
|
71
|
+
workflow: _,
|
|
72
|
+
document: v,
|
|
73
|
+
isActive: y
|
|
79
74
|
})]
|
|
80
75
|
]);
|
|
81
|
-
function resolveDocumentWidget(
|
|
82
|
-
let
|
|
83
|
-
return
|
|
76
|
+
function resolveDocumentWidget(e) {
|
|
77
|
+
let _ = e;
|
|
78
|
+
return _?.widgets?.[0]?.widget ? _.widgets[0].widget : _?.form?.widget ? _.form.widget : "form";
|
|
84
79
|
}
|
|
85
|
-
var DocumentRenderer_default = (
|
|
86
|
-
let v = c(
|
|
87
|
-
if (v[0] !==
|
|
88
|
-
let
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
80
|
+
var DocumentRenderer_default = (e) => {
|
|
81
|
+
let v = c(8), y = useFeatureRegistry(), b = e.document, x;
|
|
82
|
+
if (v[0] !== b.ui || v[1] !== y) {
|
|
83
|
+
let e = resolveDocumentWidget(b.ui), _;
|
|
84
|
+
if (v[3] !== y) {
|
|
85
|
+
_ = /* @__PURE__ */ new Map();
|
|
86
|
+
for (let e of y) if (e.documentRenderers) for (let [v, y] of Object.entries(e.documentRenderers)) _.set(v, y);
|
|
87
|
+
v[3] = y, v[4] = _;
|
|
88
|
+
} else _ = v[4];
|
|
89
|
+
let S = _;
|
|
90
|
+
x = coreRendererRegistry.get(e) ?? S.get(e), v[0] = b.ui, v[1] = y, v[2] = x;
|
|
91
|
+
} else x = v[2];
|
|
92
|
+
let S = x, C;
|
|
93
|
+
return v[5] !== S || v[6] !== e ? (C = /* @__PURE__ */ jsx("div", { children: S ? /* @__PURE__ */ jsx(S, { ...e }) : /* @__PURE__ */ jsx(Fragment$1, { children: "unknown document type" }) }), v[5] = S, v[6] = e, v[7] = C) : C = v[7], C;
|
|
93
94
|
};
|
|
94
95
|
export { DocumentRenderer_default as default };
|
|
@@ -1,30 +1,35 @@
|
|
|
1
1
|
import { useRunWorkflow } from "../../../hooks/useProcessor.js";
|
|
2
|
+
import { c } from "react/compiler-runtime";
|
|
2
3
|
import { useCallback } from "react";
|
|
3
4
|
function resolveTransition(e) {
|
|
4
|
-
let
|
|
5
|
-
return
|
|
5
|
+
let r = e, i = r?.widgets;
|
|
6
|
+
return i?.[0]?.options?.transition ? i[0].options.transition : (r?.actions)?.map((e) => e.options?.transition).find((e) => !!e);
|
|
6
7
|
}
|
|
7
|
-
function useDocumentTransition(
|
|
8
|
-
let
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
8
|
+
function useDocumentTransition(i, a, o) {
|
|
9
|
+
let s = c(14), l = useRunWorkflow(), u, d;
|
|
10
|
+
if (s[0] !== o || s[1] !== a.availableTransitions) {
|
|
11
|
+
let e = a.availableTransitions?.map(_temp) ?? [];
|
|
12
|
+
d = resolveTransition(o), u = !!d && e.includes(d), s[0] = o, s[1] = a.availableTransitions, s[2] = u, s[3] = d;
|
|
13
|
+
} else u = s[2], d = s[3];
|
|
14
|
+
let f = u, p;
|
|
15
|
+
s[4] !== f || s[5] !== i.id || s[6] !== l || s[7] !== d || s[8] !== a.id ? (p = (e) => {
|
|
16
|
+
!d || !f || l.mutate({
|
|
17
|
+
workflowId: i.id,
|
|
18
|
+
runWorkflowPayloadDto: { transition: {
|
|
19
|
+
id: d,
|
|
20
|
+
workflowId: a.id,
|
|
21
|
+
payload: e
|
|
22
|
+
} }
|
|
23
|
+
});
|
|
24
|
+
}, s[4] = f, s[5] = i.id, s[6] = l, s[7] = d, s[8] = a.id, s[9] = p) : p = s[9];
|
|
25
|
+
let m = p, h;
|
|
26
|
+
return s[10] !== f || s[11] !== l.isPending || s[12] !== m ? (h = {
|
|
27
|
+
submit: m,
|
|
28
|
+
canSubmit: f,
|
|
29
|
+
isLoading: l.isPending
|
|
30
|
+
}, s[10] = f, s[11] = l.isPending, s[12] = m, s[13] = h) : h = s[13], h;
|
|
31
|
+
}
|
|
32
|
+
function _temp(e) {
|
|
33
|
+
return e.id;
|
|
29
34
|
}
|
|
30
35
|
export { useDocumentTransition };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { c } from "react/compiler-runtime";
|
|
2
|
+
import { createContext, useContext, useMemo } from "react";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
var FeatureRegistryContext = createContext([]);
|
|
5
|
+
function FeatureRegistryProvider(r) {
|
|
6
|
+
let i = c(5), { features: a, children: o } = r, s;
|
|
7
|
+
i[0] === a ? s = i[1] : (s = a === void 0 ? [] : a, i[0] = a, i[1] = s);
|
|
8
|
+
let l = s, u;
|
|
9
|
+
return i[2] !== o || i[3] !== l ? (u = /* @__PURE__ */ jsx(FeatureRegistryContext.Provider, {
|
|
10
|
+
value: l,
|
|
11
|
+
children: o
|
|
12
|
+
}), i[2] = o, i[3] = l, i[4] = u) : u = i[4], u;
|
|
13
|
+
}
|
|
14
|
+
function useFeatureRegistry() {
|
|
15
|
+
return useContext(FeatureRegistryContext);
|
|
16
|
+
}
|
|
17
|
+
export { FeatureRegistryProvider, useFeatureRegistry };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import { FeatureRegistryProvider, useFeatureRegistry } from "./FeatureRegistryProvider.js";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
function createFilesApi(e) {
|
|
2
|
+
return {
|
|
3
|
+
getTree: (t) => e.get(`/api/v1/workspaces/${t.workspaceId}/files/tree`, { params: t.path ? { path: t.path } : void 0 }).then((e) => e.data),
|
|
4
|
+
readFile: (t) => e.get(`/api/v1/workspaces/${t.workspaceId}/files/read`, { params: { path: t.path } }).then((e) => e.data)
|
|
5
|
+
};
|
|
6
|
+
}
|
|
7
|
+
export { createFilesApi };
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { useWorkbenchLayout } from "../../workbench/providers/WorkbenchLayoutProvider.js";
|
|
2
|
+
import { SidebarPanel } from "../../workbench/components/SidebarPanel.js";
|
|
3
|
+
import "../../workbench/index.js";
|
|
4
|
+
import { FileContentViewer } from "../../code-explorer/components/FileContentViewer.js";
|
|
5
|
+
import "../../code-explorer/index.js";
|
|
6
|
+
import { FileExplorerProvider, useOptionalFileExplorer } from "../providers/FileExplorerProvider.js";
|
|
7
|
+
import { FileTabsBar } from "./FileTabsBar.js";
|
|
8
|
+
import { FileTree } from "./FileTree.js";
|
|
9
|
+
import { c } from "react/compiler-runtime";
|
|
10
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
+
import { Files } from "lucide-react";
|
|
12
|
+
function FileExplorerContent() {
|
|
13
|
+
let e = c(7), r = useOptionalFileExplorer();
|
|
14
|
+
if (!r) {
|
|
15
|
+
let r;
|
|
16
|
+
return e[0] === Symbol.for("react.memo_cache_sentinel") ? (r = /* @__PURE__ */ jsx("div", {
|
|
17
|
+
className: "flex flex-1 items-center justify-center p-4",
|
|
18
|
+
children: /* @__PURE__ */ jsx("p", {
|
|
19
|
+
className: "text-muted-foreground text-sm",
|
|
20
|
+
children: "File explorer is not available for this workspace."
|
|
21
|
+
})
|
|
22
|
+
}), e[0] = r) : r = e[0], r;
|
|
23
|
+
}
|
|
24
|
+
let a;
|
|
25
|
+
e[1] === Symbol.for("react.memo_cache_sentinel") ? (a = /* @__PURE__ */ jsx("div", {
|
|
26
|
+
className: "w-52 shrink-0 overflow-auto border-r bg-muted/40",
|
|
27
|
+
children: /* @__PURE__ */ jsx(FileTree, {})
|
|
28
|
+
}), e[1] = a) : a = e[1];
|
|
29
|
+
let d;
|
|
30
|
+
e[2] === Symbol.for("react.memo_cache_sentinel") ? (d = /* @__PURE__ */ jsx(FileTabsBar, {}), e[2] = d) : d = e[2];
|
|
31
|
+
let f;
|
|
32
|
+
return e[3] !== r.fileContent || e[4] !== r.isContentLoading || e[5] !== r.selectedFile ? (f = /* @__PURE__ */ jsxs("div", {
|
|
33
|
+
className: "flex h-full",
|
|
34
|
+
children: [a, /* @__PURE__ */ jsxs("div", {
|
|
35
|
+
className: "flex min-w-0 flex-1 flex-col",
|
|
36
|
+
children: [d, /* @__PURE__ */ jsx("div", {
|
|
37
|
+
className: "flex-1 overflow-hidden p-3 pt-2",
|
|
38
|
+
children: /* @__PURE__ */ jsx(FileContentViewer, {
|
|
39
|
+
selectedFile: r.selectedFile,
|
|
40
|
+
content: r.fileContent,
|
|
41
|
+
isLoading: r.isContentLoading,
|
|
42
|
+
className: "h-full"
|
|
43
|
+
})
|
|
44
|
+
})]
|
|
45
|
+
})]
|
|
46
|
+
}), e[3] = r.fileContent, e[4] = r.isContentLoading, e[5] = r.selectedFile, e[6] = f) : f = e[6], f;
|
|
47
|
+
}
|
|
48
|
+
function FileExplorerPanel(i) {
|
|
49
|
+
let o = c(20), { workspaceId: s } = i, { closePanel: l, panelSize: u, setPanelSize: p, workspaceConfig: m, environments: h } = useWorkbenchLayout(), g;
|
|
50
|
+
o[0] !== h?.[0]?.slotId || o[1] !== m?.features?.fileExplorer?.enabled || o[2] !== m?.features?.fileExplorer?.environments ? (g = (m?.features?.fileExplorer?.enabled && m?.features?.fileExplorer?.environments?.includes(h?.[0]?.slotId ?? "")) ?? !1, o[0] = h?.[0]?.slotId, o[1] = m?.features?.fileExplorer?.enabled, o[2] = m?.features?.fileExplorer?.environments, o[3] = g) : g = o[3];
|
|
51
|
+
let _ = g;
|
|
52
|
+
if (!_) {
|
|
53
|
+
let e;
|
|
54
|
+
o[4] === Symbol.for("react.memo_cache_sentinel") ? (e = /* @__PURE__ */ jsx(Files, { className: "h-4 w-4" }), o[4] = e) : e = o[4];
|
|
55
|
+
let i;
|
|
56
|
+
o[5] === Symbol.for("react.memo_cache_sentinel") ? (i = /* @__PURE__ */ jsx("div", {
|
|
57
|
+
className: "flex flex-1 items-center justify-center p-4",
|
|
58
|
+
children: /* @__PURE__ */ jsx("p", {
|
|
59
|
+
className: "text-muted-foreground text-sm",
|
|
60
|
+
children: "File explorer is not available for this environment."
|
|
61
|
+
})
|
|
62
|
+
}), o[5] = i) : i = o[5];
|
|
63
|
+
let a;
|
|
64
|
+
return o[6] !== l || o[7] !== u || o[8] !== p ? (a = /* @__PURE__ */ jsx(SidebarPanel, {
|
|
65
|
+
icon: e,
|
|
66
|
+
title: "Files",
|
|
67
|
+
description: "Browse remote files.",
|
|
68
|
+
size: u,
|
|
69
|
+
onSizeChange: p,
|
|
70
|
+
onClose: l,
|
|
71
|
+
children: i
|
|
72
|
+
}), o[6] = l, o[7] = u, o[8] = p, o[9] = a) : a = o[9], a;
|
|
73
|
+
}
|
|
74
|
+
let v;
|
|
75
|
+
o[10] === Symbol.for("react.memo_cache_sentinel") ? (v = /* @__PURE__ */ jsx(Files, { className: "h-4 w-4" }), o[10] = v) : v = o[10];
|
|
76
|
+
let y;
|
|
77
|
+
o[11] === Symbol.for("react.memo_cache_sentinel") ? (y = /* @__PURE__ */ jsx(FileExplorerContent, {}), o[11] = y) : y = o[11];
|
|
78
|
+
let b;
|
|
79
|
+
o[12] !== _ || o[13] !== s ? (b = /* @__PURE__ */ jsx(FileExplorerProvider, {
|
|
80
|
+
workspaceId: s,
|
|
81
|
+
enabled: _,
|
|
82
|
+
children: y
|
|
83
|
+
}), o[12] = _, o[13] = s, o[14] = b) : b = o[14];
|
|
84
|
+
let x;
|
|
85
|
+
return o[15] !== l || o[16] !== u || o[17] !== p || o[18] !== b ? (x = /* @__PURE__ */ jsx(SidebarPanel, {
|
|
86
|
+
icon: v,
|
|
87
|
+
title: "Files",
|
|
88
|
+
description: "Browse and view files.",
|
|
89
|
+
size: u,
|
|
90
|
+
onSizeChange: p,
|
|
91
|
+
onClose: l,
|
|
92
|
+
children: b
|
|
93
|
+
}), o[15] = l, o[16] = u, o[17] = p, o[18] = b, o[19] = x) : x = o[19], x;
|
|
94
|
+
}
|
|
95
|
+
export { FileExplorerPanel };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { FileTabsBarBase } from "../../code-explorer/components/FileTabsBarBase.js";
|
|
2
|
-
import {
|
|
2
|
+
import { useFileExplorer } from "../providers/FileExplorerProvider.js";
|
|
3
3
|
import { c } from "react/compiler-runtime";
|
|
4
4
|
import { jsx } from "react/jsx-runtime";
|
|
5
|
-
function
|
|
6
|
-
let i = c(9), { openFiles: a, selectedFile: o, selectFile: s, closeFile: l, closeAll: u, closeOthers: d, closeToLeft: f, closeToRight: p } =
|
|
5
|
+
function FileTabsBar() {
|
|
6
|
+
let i = c(9), { openFiles: a, selectedFile: o, selectFile: s, closeFile: l, closeAll: u, closeOthers: d, closeToLeft: f, closeToRight: p } = useFileExplorer(), m;
|
|
7
7
|
return i[0] !== u || i[1] !== l || i[2] !== d || i[3] !== f || i[4] !== p || i[5] !== a || i[6] !== s || i[7] !== o ? (m = /* @__PURE__ */ jsx(FileTabsBarBase, {
|
|
8
8
|
openFiles: a,
|
|
9
9
|
selectedFile: o,
|
|
@@ -15,4 +15,4 @@ function RemoteFileTabsBar() {
|
|
|
15
15
|
closeToRight: p
|
|
16
16
|
}), i[0] = u, i[1] = l, i[2] = d, i[3] = f, i[4] = p, i[5] = a, i[6] = s, i[7] = o, i[8] = m) : m = i[8], m;
|
|
17
17
|
}
|
|
18
|
-
export {
|
|
18
|
+
export { FileTabsBar };
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Button } from "../../../components/ui/button.js";
|
|
2
2
|
import { ScrollArea } from "../../../components/ui/scroll-area.js";
|
|
3
3
|
import { CodeExplorerTreeNode } from "../../code-explorer/components/CodeExplorerTreeNode.js";
|
|
4
|
-
import {
|
|
4
|
+
import { useFileExplorer } from "../providers/FileExplorerProvider.js";
|
|
5
5
|
import { c } from "react/compiler-runtime";
|
|
6
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
7
|
import { AlertCircle, Loader2, RefreshCw } from "lucide-react";
|
|
8
|
-
|
|
9
|
-
let d = c(35), { nodes: f, isTreeLoading: p, treeError: m, isFetchingTree: h, expandedFolders: g, toggleFolder: _, selectFile: v, closeFile: y, selectedFile: b, refreshTree: x } =
|
|
8
|
+
function FileTree() {
|
|
9
|
+
let d = c(35), { nodes: f, isTreeLoading: p, treeError: m, isFetchingTree: h, expandedFolders: g, toggleFolder: _, selectFile: v, closeFile: y, selectedFile: b, refreshTree: x } = useFileExplorer();
|
|
10
10
|
if (p) {
|
|
11
11
|
let e;
|
|
12
12
|
return d[0] === Symbol.for("react.memo_cache_sentinel") ? (e = /* @__PURE__ */ jsxs("div", {
|
|
@@ -77,7 +77,7 @@ var RemoteFileTree_default = () => {
|
|
|
77
77
|
children: /* @__PURE__ */ jsx("div", {
|
|
78
78
|
className: "w-full py-1",
|
|
79
79
|
role: "tree",
|
|
80
|
-
"aria-label": "
|
|
80
|
+
"aria-label": "File tree",
|
|
81
81
|
children: T
|
|
82
82
|
})
|
|
83
83
|
}), d[30] = T, d[31] = E);
|
|
@@ -86,5 +86,5 @@ var RemoteFileTree_default = () => {
|
|
|
86
86
|
className: "flex h-full flex-col gap-1.5",
|
|
87
87
|
children: [w, E]
|
|
88
88
|
}), d[32] = w, d[33] = E, d[34] = D) : D = d[34], D;
|
|
89
|
-
}
|
|
90
|
-
export {
|
|
89
|
+
}
|
|
90
|
+
export { FileTree };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { FileExplorerPanel } from "./components/FileExplorerPanel.js";
|
|
2
|
+
import { Files } from "lucide-react";
|
|
3
|
+
const fileExplorerFeature = {
|
|
4
|
+
id: "file-explorer",
|
|
5
|
+
sidebarPanel: {
|
|
6
|
+
id: "files",
|
|
7
|
+
label: "Files",
|
|
8
|
+
icon: Files,
|
|
9
|
+
component: FileExplorerPanel
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
export { fileExplorerFeature };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { useApiClient } from "../../../hooks/useApi.js";
|
|
2
|
+
import { c } from "react/compiler-runtime";
|
|
3
|
+
import { useQuery } from "@tanstack/react-query";
|
|
4
|
+
function useFileTree(r, i) {
|
|
5
|
+
let a = c(10), o = i === void 0 ? !0 : i, { envKey: s, api: l } = useApiClient(), u;
|
|
6
|
+
a[0] !== s || a[1] !== r ? (u = [
|
|
7
|
+
"file-explorer-tree",
|
|
8
|
+
s,
|
|
9
|
+
r
|
|
10
|
+
], a[0] = s, a[1] = r, a[2] = u) : u = a[2];
|
|
11
|
+
let d;
|
|
12
|
+
a[3] !== l || a[4] !== r ? (d = () => l.files.getTree({ workspaceId: r }), a[3] = l, a[4] = r, a[5] = d) : d = a[5];
|
|
13
|
+
let f = !!r && o, p;
|
|
14
|
+
return a[6] !== u || a[7] !== d || a[8] !== f ? (p = {
|
|
15
|
+
queryKey: u,
|
|
16
|
+
queryFn: d,
|
|
17
|
+
enabled: f,
|
|
18
|
+
staleTime: 3e4,
|
|
19
|
+
retry: !1
|
|
20
|
+
}, a[6] = u, a[7] = d, a[8] = f, a[9] = p) : p = a[9], useQuery(p);
|
|
21
|
+
}
|
|
22
|
+
function useFileContent(r, i, a) {
|
|
23
|
+
let o = c(12), s = a === void 0 ? !0 : a, { envKey: l, api: u } = useApiClient(), d;
|
|
24
|
+
o[0] !== l || o[1] !== i || o[2] !== r ? (d = [
|
|
25
|
+
"file-explorer-content",
|
|
26
|
+
l,
|
|
27
|
+
r,
|
|
28
|
+
i
|
|
29
|
+
], o[0] = l, o[1] = i, o[2] = r, o[3] = d) : d = o[3];
|
|
30
|
+
let f;
|
|
31
|
+
o[4] !== u || o[5] !== i || o[6] !== r ? (f = () => u.files.readFile({
|
|
32
|
+
workspaceId: r,
|
|
33
|
+
path: i
|
|
34
|
+
}), o[4] = u, o[5] = i, o[6] = r, o[7] = f) : f = o[7];
|
|
35
|
+
let p = !!r && !!i && s, m;
|
|
36
|
+
return o[8] !== d || o[9] !== f || o[10] !== p ? (m = {
|
|
37
|
+
queryKey: d,
|
|
38
|
+
queryFn: f,
|
|
39
|
+
enabled: p,
|
|
40
|
+
staleTime: 15e3,
|
|
41
|
+
retry: !1
|
|
42
|
+
}, o[8] = d, o[9] = f, o[10] = p, o[11] = m) : m = o[11], useQuery(m);
|
|
43
|
+
}
|
|
44
|
+
export { useFileContent, useFileTree };
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { useFileContent, useFileTree } from "../hooks/useFileExplorer.js";
|
|
2
|
+
import { c } from "react/compiler-runtime";
|
|
3
|
+
import { createContext, useCallback, useContext, useMemo, useState } from "react";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
import { useQueryClient } from "@tanstack/react-query";
|
|
6
|
+
var FileExplorerContext = createContext(null);
|
|
7
|
+
function FileExplorerProvider(s) {
|
|
8
|
+
let l = c(36), { workspaceId: u, enabled: d, children: f } = s, p = d === void 0 ? !0 : d, m = useQueryClient(), h;
|
|
9
|
+
l[0] === Symbol.for("react.memo_cache_sentinel") ? (h = /* @__PURE__ */ new Set(), l[0] = h) : h = l[0];
|
|
10
|
+
let [g, _] = useState(h), v;
|
|
11
|
+
l[1] === Symbol.for("react.memo_cache_sentinel") ? (v = [], l[1] = v) : v = l[1];
|
|
12
|
+
let [y, b] = useState(v), [x, S] = useState(null), C = useFileTree(u, p), w = useFileContent(u, x?.type === "file" ? x.path : void 0, p), T;
|
|
13
|
+
l[2] === Symbol.for("react.memo_cache_sentinel") ? (T = (e) => {
|
|
14
|
+
_((a) => {
|
|
15
|
+
let o = new Set(a);
|
|
16
|
+
return o.has(e) ? o.delete(e) : o.add(e), o;
|
|
17
|
+
});
|
|
18
|
+
}, l[2] = T) : T = l[2];
|
|
19
|
+
let E = T, D;
|
|
20
|
+
l[3] === Symbol.for("react.memo_cache_sentinel") ? (D = (e) => {
|
|
21
|
+
e.type === "file" && (S(e), b((a) => a.some((a) => a.path === e.path) ? a : [...a, e]));
|
|
22
|
+
}, l[3] = D) : D = l[3];
|
|
23
|
+
let O = D, k;
|
|
24
|
+
l[4] === x?.path ? k = l[5] : (k = (e) => {
|
|
25
|
+
b((a) => {
|
|
26
|
+
let o = a.filter((a) => a.path !== e.path);
|
|
27
|
+
if (x?.path === e.path) if (o.length > 0) {
|
|
28
|
+
let s = a.findIndex((a) => a.path === e.path);
|
|
29
|
+
S(o[Math.max(0, s - 1)]);
|
|
30
|
+
} else S(null);
|
|
31
|
+
return o;
|
|
32
|
+
});
|
|
33
|
+
}, l[4] = x?.path, l[5] = k);
|
|
34
|
+
let A = k, j;
|
|
35
|
+
l[6] === x ? j = l[7] : (j = () => {
|
|
36
|
+
x && b((e) => {
|
|
37
|
+
let a = e.filter((e) => e.path !== x.path);
|
|
38
|
+
if (a.length > 0) {
|
|
39
|
+
let o = e.findIndex((e) => e.path === x.path);
|
|
40
|
+
S(a[Math.max(0, o - 1)]);
|
|
41
|
+
} else S(null);
|
|
42
|
+
return a;
|
|
43
|
+
});
|
|
44
|
+
}, l[6] = x, l[7] = j);
|
|
45
|
+
let M = j, N;
|
|
46
|
+
l[8] === Symbol.for("react.memo_cache_sentinel") ? (N = () => {
|
|
47
|
+
b([]), S(null);
|
|
48
|
+
}, l[8] = N) : N = l[8];
|
|
49
|
+
let P = N, F;
|
|
50
|
+
l[9] === Symbol.for("react.memo_cache_sentinel") ? (F = (e) => {
|
|
51
|
+
b([e]), S(e);
|
|
52
|
+
}, l[9] = F) : F = l[9];
|
|
53
|
+
let I = F, L;
|
|
54
|
+
l[10] === x ? L = l[11] : (L = (e) => {
|
|
55
|
+
b((a) => {
|
|
56
|
+
let o = a.findIndex((a) => a.path === e.path);
|
|
57
|
+
if (o <= 0) return a;
|
|
58
|
+
let s = a.slice(o);
|
|
59
|
+
return x && a.findIndex((e) => e.path === x.path) < o && S(e), s;
|
|
60
|
+
});
|
|
61
|
+
}, l[10] = x, l[11] = L);
|
|
62
|
+
let R = L, z;
|
|
63
|
+
l[12] === x ? z = l[13] : (z = (e) => {
|
|
64
|
+
b((a) => {
|
|
65
|
+
let o = a.findIndex((a) => a.path === e.path);
|
|
66
|
+
if (o < 0 || o >= a.length - 1) return a;
|
|
67
|
+
let s = a.slice(0, o + 1);
|
|
68
|
+
return x && a.findIndex((e) => e.path === x.path) > o && S(e), s;
|
|
69
|
+
});
|
|
70
|
+
}, l[12] = x, l[13] = z);
|
|
71
|
+
let B = z, V;
|
|
72
|
+
l[14] === m ? V = l[15] : (V = () => {
|
|
73
|
+
m.invalidateQueries({ queryKey: ["file-explorer-tree"] });
|
|
74
|
+
}, l[14] = m, l[15] = V);
|
|
75
|
+
let H = V, U;
|
|
76
|
+
l[16] === C.data ? U = l[17] : (U = C.data ?? [], l[16] = C.data, l[17] = U);
|
|
77
|
+
let W = C.isLoading && !C.data, G = w.data?.content ?? null, K = w.isLoading && !!x, q;
|
|
78
|
+
l[18] !== M || l[19] !== A || l[20] !== R || l[21] !== B || l[22] !== g || l[23] !== y || l[24] !== H || l[25] !== x || l[26] !== U || l[27] !== W || l[28] !== G || l[29] !== K || l[30] !== C.error || l[31] !== C.isFetching ? (q = {
|
|
79
|
+
nodes: U,
|
|
80
|
+
isTreeLoading: W,
|
|
81
|
+
treeError: C.error,
|
|
82
|
+
isFetchingTree: C.isFetching,
|
|
83
|
+
openFiles: y,
|
|
84
|
+
selectedFile: x,
|
|
85
|
+
fileContent: G,
|
|
86
|
+
isContentLoading: K,
|
|
87
|
+
expandedFolders: g,
|
|
88
|
+
toggleFolder: E,
|
|
89
|
+
selectFile: O,
|
|
90
|
+
closeFile: A,
|
|
91
|
+
closeAll: P,
|
|
92
|
+
closeOthers: I,
|
|
93
|
+
closeToLeft: R,
|
|
94
|
+
closeToRight: B,
|
|
95
|
+
clearSelection: M,
|
|
96
|
+
refreshTree: H
|
|
97
|
+
}, l[18] = M, l[19] = A, l[20] = R, l[21] = B, l[22] = g, l[23] = y, l[24] = H, l[25] = x, l[26] = U, l[27] = W, l[28] = G, l[29] = K, l[30] = C.error, l[31] = C.isFetching, l[32] = q) : q = l[32];
|
|
98
|
+
let J = q, Y;
|
|
99
|
+
return l[33] !== f || l[34] !== J ? (Y = /* @__PURE__ */ jsx(FileExplorerContext.Provider, {
|
|
100
|
+
value: J,
|
|
101
|
+
children: f
|
|
102
|
+
}), l[33] = f, l[34] = J, l[35] = Y) : Y = l[35], Y;
|
|
103
|
+
}
|
|
104
|
+
function useFileExplorer() {
|
|
105
|
+
let e = useContext(FileExplorerContext);
|
|
106
|
+
if (!e) throw Error("useFileExplorer must be used within FileExplorerProvider");
|
|
107
|
+
return e;
|
|
108
|
+
}
|
|
109
|
+
function useOptionalFileExplorer() {
|
|
110
|
+
return useContext(FileExplorerContext);
|
|
111
|
+
}
|
|
112
|
+
export { FileExplorerProvider, useFileExplorer, useOptionalFileExplorer };
|