@nextclaw/ui 0.15.3 → 0.15.4
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/CHANGELOG.md +21 -0
- package/dist/assets/aiden0z-pptx-renderer.es-Bd99vut2.js +94 -0
- package/dist/assets/api-BOXOrpcJ.js +13 -0
- package/dist/assets/app-presenter-provider-CkHLbvZQ.js +106 -0
- package/dist/assets/app-presenter-provider-D3BuuOyZ.css +1 -0
- package/dist/assets/appearance-settings-page-fLIJbx1C.js +1 -0
- package/dist/assets/{book-open-C3mJGwiy.js → book-open-DWUjS6aW.js} +1 -1
- package/dist/assets/channels-list-page-CvCTJraa.js +8 -0
- package/dist/assets/chat-page-B42UUIFR.js +1 -0
- package/dist/assets/chunk-DseTPa7n.js +1 -0
- package/dist/assets/config-split-page-DBgt9S8b.js +1 -0
- package/dist/assets/confirm-dialog-GSXIvoRU.js +5 -0
- package/dist/assets/desktop-update-config-7bmNeWIC.js +1 -0
- package/dist/assets/dist-DC7f4TJH.js +41 -0
- package/dist/assets/doc-browser-CgdoLUT92.js +1 -0
- package/dist/assets/doc-browser-D0monHjG.js +1 -0
- package/dist/assets/doc-browser-context-CGwEOhBy.js +1 -0
- package/dist/assets/docx-preview-eFH9DRsS.js +20 -0
- package/dist/assets/download-DiP9zx-J.js +1 -0
- package/dist/assets/{external-link-CU0kzzIP.js → external-link-C6ZeSPef.js} +1 -1
- package/dist/assets/eye-suvKmtwn.js +1 -0
- package/dist/assets/folder-CMELbQGG.js +1 -0
- package/dist/assets/{form-actions-BvCp_0lS.js → form-actions-CUAzpNe_.js} +1 -1
- package/dist/assets/index-BFeNDQ4R.css +1 -0
- package/dist/assets/index-D_6U-M94.js +2 -0
- package/dist/assets/jszip.min-Das2IAnb.js +2 -0
- package/dist/assets/loader-circle-tYHStefV.js +1 -0
- package/dist/assets/logo-badge-Cu5UGH_4.js +1 -0
- package/dist/assets/mcp-marketplace-page-BUzHDwW6.js +9 -0
- package/dist/assets/mcp-marketplace-page-ohUAdfqJ.js +1 -0
- package/dist/assets/model-config-page-CWP6pyBm.js +1 -0
- package/dist/assets/plus-tywizkeY.js +1 -0
- package/dist/assets/popover-DImguRok.js +1 -0
- package/dist/assets/provider-models-C_yOh6DE.js +1 -0
- package/dist/assets/provider-scoped-model-input-CE7p4SbJ.js +1 -0
- package/dist/assets/providers-config-page-BKPo8SjH.js +1 -0
- package/dist/assets/react-5sjAT_6d.js +8 -0
- package/dist/assets/{refresh-cw-CILd1vAP.js → refresh-cw-CHLBzWWj.js} +1 -1
- package/dist/assets/remote-DXJryUxB.js +1 -0
- package/dist/assets/rotate-cw-BefO5brU.js +1 -0
- package/dist/assets/runtime-config-page-1Axv4QGu.js +1 -0
- package/dist/assets/{save-ByJqcPTP.js → save-BABzyrjB.js} +1 -1
- package/dist/assets/{search-DVIV6pfD.js → search-BTqxG3ZG.js} +1 -1
- package/dist/assets/search-config-page-BkKKmxmS.js +1 -0
- package/dist/assets/secrets-config-page-CWJMyu-k.js +3 -0
- package/dist/assets/security-config-DeQUIXfi.js +1 -0
- package/dist/assets/select-TYZDBNmq.js +1 -0
- package/dist/assets/setting-row-DR23Z_5I.js +1 -0
- package/dist/assets/{settings-2-CH5shGg_.js → settings-2-D8WWcBnw.js} +1 -1
- package/dist/assets/{skeleton-DeX1FKw7.js → skeleton-CloHeg0S.js} +1 -1
- package/dist/assets/tabs-CX-ckWoo.js +1 -0
- package/dist/assets/tag-chip-mCc23Rhb.js +1 -0
- package/dist/assets/trash-2-SAW1Z4Po.js +1 -0
- package/dist/assets/use-config-BucdaK23.js +1 -0
- package/dist/assets/use-confirm-dialog-C95F6sT1.js +1 -0
- package/dist/assets/use-viewport-layout-C6m3Nte7.js +1 -0
- package/dist/assets/x-DtCPHwCu.js +1 -0
- package/dist/assets/xlsx-B6zVt1RK.js +64 -0
- package/dist/index.html +34 -28
- package/package.json +11 -6
- package/src/features/chat/components/__tests__/chat-popover-content.test.tsx +41 -0
- package/src/features/chat/components/chat-popover-content.tsx +26 -0
- package/src/features/chat/components/conversation/__tests__/chat-conversation-content.test.tsx +13 -0
- package/src/features/chat/components/conversation/__tests__/chat-conversation-header-section.test.tsx +21 -11
- package/src/features/chat/components/conversation/__tests__/chat-conversation-header.test.tsx +2 -2
- package/src/features/chat/components/conversation/__tests__/chat-conversation-workspace-section.test.tsx +28 -1
- package/src/features/chat/components/conversation/chat-conversation-content.tsx +5 -4
- package/src/features/chat/components/conversation/chat-conversation-header-section.tsx +9 -18
- package/src/features/chat/components/conversation/chat-conversation-track.tsx +35 -0
- package/src/features/chat/components/conversation/chat-conversation-workspace-section.tsx +1 -0
- package/src/features/chat/components/layout/chat-sidebar-toolbar.tsx +7 -7
- package/src/features/chat/components/layout/chat-sidebar-utility-menu.tsx +3 -14
- package/src/features/chat/features/conversation/components/__tests__/session-conversation-input.streaming.test.tsx +20 -1
- package/src/features/chat/features/conversation/components/session-conversation-input.tsx +69 -54
- package/src/features/chat/features/message/components/chat-message-list.container.tsx +16 -1
- package/src/features/chat/features/message/utils/__tests__/chat-message-file-operation.utils.test.ts +30 -0
- package/src/features/chat/features/session/components/__tests__/chat-sidebar-session-item.test.tsx +37 -0
- package/src/features/chat/features/session/components/chat-sidebar-project-groups.tsx +4 -3
- package/src/features/chat/features/session/components/chat-sidebar-session-item.tsx +3 -8
- package/src/features/chat/features/session/components/session-header/__tests__/chat-session-header-actions.test.tsx +65 -20
- package/src/features/chat/features/session/components/session-header/chat-session-header-actions.tsx +26 -28
- package/src/features/chat/features/session/components/session-header/chat-session-project-badge.tsx +3 -3
- package/src/features/chat/features/session/components/session-header/chat-session-title-switcher.tsx +3 -3
- package/src/features/chat/features/welcome/components/chat-welcome-project-picker.tsx +3 -3
- package/src/features/chat/features/welcome/components/chat-welcome-session-type-picker.tsx +3 -3
- package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-file-preview.test.tsx +403 -106
- package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-panel-content.test.tsx +113 -2
- package/src/features/chat/features/workspace/components/__tests__/chat-session-workspace-panel.test.tsx +1 -0
- package/src/features/chat/features/workspace/components/chat-session-workspace-directory-browser.tsx +197 -44
- package/src/features/chat/features/workspace/components/chat-session-workspace-file-breadcrumb-browser.tsx +9 -3
- package/src/features/chat/features/workspace/components/chat-session-workspace-file-breadcrumbs.tsx +7 -5
- package/src/features/chat/features/workspace/components/chat-session-workspace-file-preview.tsx +57 -177
- package/src/features/chat/features/workspace/components/chat-session-workspace-panel-content.tsx +239 -1
- package/src/features/chat/features/workspace/components/chat-session-workspace-panel-nav.tsx +56 -6
- package/src/features/chat/features/workspace/components/chat-session-workspace-panel.tsx +29 -7
- package/src/features/chat/features/workspace/components/file-content-preview/use-workspace-file-buffer.ts +42 -0
- package/src/features/chat/features/workspace/components/file-content-preview/workspace-document-preview-state.tsx +18 -0
- package/src/features/chat/features/workspace/components/file-content-preview/workspace-docx-preview.css +89 -0
- package/src/features/chat/features/workspace/components/file-content-preview/workspace-docx-preview.tsx +87 -0
- package/src/features/chat/features/workspace/components/file-content-preview/workspace-presentation-preview.tsx +82 -0
- package/src/features/chat/features/workspace/components/file-content-preview/workspace-spreadsheet-preview.tsx +180 -0
- package/src/features/chat/features/workspace/components/workspace-file-content-preview.tsx +191 -0
- package/src/features/chat/features/workspace/hooks/use-chat-conversation-workspace-state.ts +1 -4
- package/src/features/chat/features/workspace/utils/__tests__/chat-workspace-panel-view-model.utils.test.ts +53 -10
- package/src/features/chat/features/workspace/utils/chat-thread-workspace-session.utils.ts +68 -2
- package/src/features/chat/features/workspace/utils/chat-workspace-file-tab-persistence.utils.ts +17 -0
- package/src/features/chat/features/workspace/utils/chat-workspace-file-tab.utils.ts +63 -0
- package/src/features/chat/features/workspace/utils/chat-workspace-file-viewer.utils.ts +49 -0
- package/src/features/chat/features/workspace/utils/chat-workspace-panel-layout.utils.ts +13 -0
- package/src/features/chat/features/workspace/utils/chat-workspace-panel-view-model.utils.ts +120 -38
- package/src/features/chat/index.ts +1 -0
- package/src/features/chat/managers/__tests__/chat-thread-workspace.manager.test.ts +76 -0
- package/src/features/chat/managers/__tests__/chat-thread.manager.test.ts +44 -60
- package/src/features/chat/managers/chat-thread.manager.ts +123 -126
- package/src/features/chat/pages/ncp-chat-page.tsx +1 -2
- package/src/features/chat/stores/__tests__/chat-thread.store.test.ts +78 -1
- package/src/features/chat/stores/chat-message-layout.store.test.ts +37 -0
- package/src/features/chat/stores/chat-message-layout.store.ts +41 -0
- package/src/features/chat/stores/chat-thread.store.ts +70 -13
- package/src/features/settings/pages/__tests__/appearance-settings-page.test.tsx +25 -8
- package/src/features/settings/pages/appearance-settings-page.tsx +92 -13
- package/src/index.css +36 -2
- package/src/shared/components/__tests__/file-type-icon.test.tsx +61 -0
- package/src/shared/components/doc-browser/__tests__/doc-browser-context.test.tsx +19 -0
- package/src/shared/components/doc-browser/__tests__/doc-browser.test.tsx +16 -0
- package/src/shared/components/doc-browser/doc-browser-context.tsx +1 -0
- package/src/shared/components/doc-browser/doc-browser.tsx +11 -3
- package/src/shared/components/doc-browser/managers/doc-browser.manager.ts +5 -0
- package/src/shared/components/doc-browser/stores/doc-browser.store.ts +6 -1
- package/src/shared/components/doc-browser/types/doc-browser.types.ts +2 -0
- package/src/shared/components/doc-browser/utils/doc-browser-state.utils.ts +11 -0
- package/src/shared/components/file-type-icon.tsx +272 -0
- package/src/shared/components/resizable-right-panel/__tests__/resizable-right-panel.test.tsx +22 -0
- package/src/shared/components/resizable-right-panel/resizable-right-panel.tsx +17 -2
- package/src/shared/components/ui/tab-strip/__tests__/compact-tab-strip.test.tsx +38 -0
- package/src/shared/components/ui/tab-strip/compact-tab-strip.tsx +82 -2
- package/src/shared/lib/api/__tests__/server-path.utils.test.ts +28 -0
- package/src/shared/lib/api/utils/server-path.utils.ts +19 -20
- package/src/shared/lib/i18n/locales/en-US/chat.json +17 -1
- package/src/shared/lib/i18n/locales/en-US/core.json +6 -0
- package/src/shared/lib/i18n/locales/zh-CN/chat.json +17 -1
- package/src/shared/lib/i18n/locales/zh-CN/core.json +6 -0
- package/dist/assets/api-iNBpppzj.js +0 -13
- package/dist/assets/appearance-settings-page-DMffQFR3.js +0 -1
- package/dist/assets/channels-list-page-CCtp0BRS.js +0 -8
- package/dist/assets/chat-page-H5a0dWvO.js +0 -1
- package/dist/assets/config-split-page-CrOJgB-Y.js +0 -1
- package/dist/assets/confirm-dialog-Chv50USy.js +0 -5
- package/dist/assets/desktop-update-config-KzTuXRf_.js +0 -1
- package/dist/assets/dist-BunzmC4B.js +0 -1
- package/dist/assets/dist-ChmGwvtK.js +0 -1
- package/dist/assets/doc-browser-DNRL4Zvd.js +0 -1
- package/dist/assets/doc-browser-Dg0pmkOg.js +0 -1
- package/dist/assets/doc-browser-context-BHY-0FSD.js +0 -1
- package/dist/assets/es2015-DQZ5JWwK.js +0 -41
- package/dist/assets/i18n-provider-Cu8XyZb_.js +0 -1
- package/dist/assets/index-CzfBdvK1.css +0 -1
- package/dist/assets/index-DGqHne1Q.js +0 -104
- package/dist/assets/loader-circle-CDSFuzmk.js +0 -1
- package/dist/assets/mcp-marketplace-page-BeEQK0DL.js +0 -9
- package/dist/assets/mcp-marketplace-page-D6idOTLp.js +0 -1
- package/dist/assets/model-config-page-bNNo-XyG.js +0 -1
- package/dist/assets/plus-D4DsdLN-.js +0 -1
- package/dist/assets/provider-scoped-model-input-IlgQCsoT.js +0 -1
- package/dist/assets/providers-config-page-wLo6CAJw.js +0 -1
- package/dist/assets/react-BPIsQIlO.js +0 -8
- package/dist/assets/remote-uKEYp7AR.js +0 -1
- package/dist/assets/rotate-cw-wPFPg1kH.js +0 -1
- package/dist/assets/runtime-config-page-DDn1sP4G.js +0 -1
- package/dist/assets/search-config-page-B-Cf4iiB.js +0 -1
- package/dist/assets/secrets-config-page-DPKsY8Iw.js +0 -3
- package/dist/assets/security-config-e9SSBlKr.js +0 -1
- package/dist/assets/select-BdgczSNw.js +0 -1
- package/dist/assets/setting-row-BkTVUTKx.js +0 -1
- package/dist/assets/side-dock-BsBvcJ9i.js +0 -3
- package/dist/assets/switch-Cv8Ekb3x.js +0 -1
- package/dist/assets/tag-chip-RB9uKcoC.js +0 -1
- package/dist/assets/tooltip-oQlEN-l6.js +0 -1
- package/dist/assets/use-config-l3W7y8Qz.js +0 -1
- package/dist/assets/use-confirm-dialog-BAxaVOJI.js +0 -1
- package/dist/assets/x-BBMffEN0.js +0 -1
- /package/dist/assets/{config-hints-C_iP1zl_.js → config-hints-fDrYfl0l.js} +0 -0
- /package/dist/assets/{host-capabilities-9bB_998Z.js → host-capabilities-zZvY9U63.js} +0 -0
- /package/dist/assets/{middleware-BILWbJE4.js → middleware-BLMHv9YF.js} +0 -0
package/src/features/chat/features/workspace/components/chat-session-workspace-file-preview.tsx
CHANGED
|
@@ -2,7 +2,6 @@ import { useMemo } from "react";
|
|
|
2
2
|
import type {
|
|
3
3
|
ChatFileOpenActionViewModel,
|
|
4
4
|
ChatFileOperationBlockViewModel,
|
|
5
|
-
ChatFilePreviewViewer,
|
|
6
5
|
} from "@nextclaw/agent-chat-ui";
|
|
7
6
|
import {
|
|
8
7
|
ChatMessageMarkdown,
|
|
@@ -11,6 +10,11 @@ import {
|
|
|
11
10
|
import type { ChatWorkspaceFileTab } from "@/features/chat/stores/chat-thread.store";
|
|
12
11
|
import { ChatSessionWorkspaceDirectoryBrowser } from "./chat-session-workspace-directory-browser";
|
|
13
12
|
import { ChatSessionWorkspaceFileBreadcrumbs } from "./chat-session-workspace-file-breadcrumbs";
|
|
13
|
+
import {
|
|
14
|
+
resolveWorkspaceFileContentKind,
|
|
15
|
+
WorkspaceFileContentPreview,
|
|
16
|
+
type WorkspaceFileContentKind,
|
|
17
|
+
} from "./workspace-file-content-preview";
|
|
14
18
|
import { useServerPathBrowse } from "@/shared/hooks/use-server-path-browse";
|
|
15
19
|
import { useServerPathRead } from "@/shared/hooks/use-server-path-read";
|
|
16
20
|
import { buildServerPathContentUrl } from "@/shared/lib/api";
|
|
@@ -21,6 +25,7 @@ import {
|
|
|
21
25
|
import { t } from "@/shared/lib/i18n";
|
|
22
26
|
import { buildWorkspaceFileBreadcrumb } from "@/shared/lib/session-project";
|
|
23
27
|
import { cn } from "@/shared/lib/utils";
|
|
28
|
+
import { resolveWorkspaceFileViewer } from "@/features/chat/features/workspace/utils/chat-workspace-file-viewer.utils";
|
|
24
29
|
|
|
25
30
|
function inferPreviewKind(params: {
|
|
26
31
|
path: string;
|
|
@@ -32,40 +37,10 @@ function inferPreviewKind(params: {
|
|
|
32
37
|
return /\.mdx?$/i.test(params.path) ? "markdown" : "text";
|
|
33
38
|
}
|
|
34
39
|
|
|
35
|
-
function
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
return params.viewer === "rendered" && /\.html?$/i.test(params.path) ? "rendered" : "source";
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
type ContentUrlPreviewKind = "image" | "audio" | "video" | "pdf" | "html" | "other";
|
|
43
|
-
|
|
44
|
-
function resolveContentUrlPreviewKind(params: {
|
|
45
|
-
path: string;
|
|
46
|
-
mimeType?: string | null;
|
|
47
|
-
}): ContentUrlPreviewKind {
|
|
48
|
-
const mime = params.mimeType?.trim().toLowerCase() ?? "";
|
|
49
|
-
const path = params.path.trim().toLowerCase();
|
|
50
|
-
if (mime.startsWith("image/") || /\.(avif|bmp|gif|heic|heif|ico|jpe?g|png|svg|tiff?|webp)$/i.test(path)) {
|
|
51
|
-
return "image";
|
|
52
|
-
}
|
|
53
|
-
if (mime.startsWith("audio/") || /\.(aac|flac|m4a|mp3|ogg|opus|wav|weba)$/i.test(path)) {
|
|
54
|
-
return "audio";
|
|
55
|
-
}
|
|
56
|
-
if (mime.startsWith("video/") || /\.(avi|m4v|mkv|mov|mp4|webm|wmv)$/i.test(path)) {
|
|
57
|
-
return "video";
|
|
58
|
-
}
|
|
59
|
-
if (mime.includes("pdf") || path.endsWith(".pdf")) {
|
|
60
|
-
return "pdf";
|
|
61
|
-
}
|
|
62
|
-
if (mime.includes("html") || /\.html?$/i.test(path)) {
|
|
63
|
-
return "html";
|
|
64
|
-
}
|
|
65
|
-
return "other";
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
function appendPreviewRefreshVersion(url: string, refreshVersion: number): string {
|
|
40
|
+
function appendPreviewRefreshVersion(
|
|
41
|
+
url: string,
|
|
42
|
+
refreshVersion: number,
|
|
43
|
+
): string {
|
|
69
44
|
if (refreshVersion <= 0) {
|
|
70
45
|
return url;
|
|
71
46
|
}
|
|
@@ -182,119 +157,9 @@ function WorkspaceCodeSurface({
|
|
|
182
157
|
}: {
|
|
183
158
|
block: ChatFileOperationBlockViewModel;
|
|
184
159
|
}) {
|
|
185
|
-
return <div className="h-full overflow-auto custom-scrollbar bg-white"><FileOperationCodeSurface block={block} layout="workspace" /></div>;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
function WorkspaceHtmlRenderedPreview({
|
|
189
|
-
src,
|
|
190
|
-
}: {
|
|
191
|
-
src: string;
|
|
192
|
-
}) {
|
|
193
|
-
return (
|
|
194
|
-
<iframe
|
|
195
|
-
allowFullScreen
|
|
196
|
-
className="h-full w-full border-0 bg-white"
|
|
197
|
-
data-testid="workspace-html-preview"
|
|
198
|
-
src={src}
|
|
199
|
-
title={t("chatWorkspaceHtmlPreviewTitle")}
|
|
200
|
-
/>
|
|
201
|
-
);
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
function WorkspaceContentUrlPreview({
|
|
205
|
-
contentUrl,
|
|
206
|
-
kind,
|
|
207
|
-
label,
|
|
208
|
-
}: {
|
|
209
|
-
contentUrl: string;
|
|
210
|
-
kind: ContentUrlPreviewKind;
|
|
211
|
-
label: string;
|
|
212
|
-
}) {
|
|
213
|
-
if (kind === "image") {
|
|
214
|
-
return (
|
|
215
|
-
<div className="flex h-full items-center justify-center overflow-auto custom-scrollbar bg-white p-4">
|
|
216
|
-
<img
|
|
217
|
-
src={contentUrl}
|
|
218
|
-
alt={label}
|
|
219
|
-
className="max-h-full max-w-full object-contain"
|
|
220
|
-
data-testid="workspace-content-image"
|
|
221
|
-
/>
|
|
222
|
-
</div>
|
|
223
|
-
);
|
|
224
|
-
}
|
|
225
|
-
if (kind === "audio") {
|
|
226
|
-
return (
|
|
227
|
-
<div className="flex h-full items-center justify-center bg-white px-6">
|
|
228
|
-
<audio
|
|
229
|
-
controls
|
|
230
|
-
preload="metadata"
|
|
231
|
-
aria-label={label}
|
|
232
|
-
className="w-full max-w-xl"
|
|
233
|
-
data-testid="workspace-content-audio"
|
|
234
|
-
src={contentUrl}
|
|
235
|
-
/>
|
|
236
|
-
</div>
|
|
237
|
-
);
|
|
238
|
-
}
|
|
239
|
-
if (kind === "video") {
|
|
240
|
-
return (
|
|
241
|
-
<div className="flex h-full items-center justify-center bg-black">
|
|
242
|
-
<video
|
|
243
|
-
controls
|
|
244
|
-
playsInline
|
|
245
|
-
preload="metadata"
|
|
246
|
-
aria-label={label}
|
|
247
|
-
className="max-h-full max-w-full"
|
|
248
|
-
data-testid="workspace-content-video"
|
|
249
|
-
src={contentUrl}
|
|
250
|
-
/>
|
|
251
|
-
</div>
|
|
252
|
-
);
|
|
253
|
-
}
|
|
254
|
-
if (kind === "pdf" || kind === "html") {
|
|
255
|
-
return (
|
|
256
|
-
<iframe
|
|
257
|
-
allowFullScreen
|
|
258
|
-
className="h-full w-full border-0 bg-white"
|
|
259
|
-
data-testid={kind === "pdf" ? "workspace-content-pdf" : "workspace-html-preview"}
|
|
260
|
-
src={contentUrl}
|
|
261
|
-
title={label}
|
|
262
|
-
/>
|
|
263
|
-
);
|
|
264
|
-
}
|
|
265
160
|
return (
|
|
266
|
-
<div
|
|
267
|
-
|
|
268
|
-
data-testid="workspace-content-unsupported"
|
|
269
|
-
>
|
|
270
|
-
<div className="max-w-sm space-y-1.5">
|
|
271
|
-
<p className="truncate text-sm font-medium text-foreground" title={label}>
|
|
272
|
-
{label}
|
|
273
|
-
</p>
|
|
274
|
-
<p className="text-sm text-muted-foreground">
|
|
275
|
-
{t("chatWorkspacePreviewUnsupported")}
|
|
276
|
-
</p>
|
|
277
|
-
<p className="text-xs leading-5 text-muted-foreground/80">
|
|
278
|
-
{t("chatWorkspacePreviewUnsupportedHint")}
|
|
279
|
-
</p>
|
|
280
|
-
</div>
|
|
281
|
-
<div className="flex flex-wrap items-center justify-center gap-2">
|
|
282
|
-
<a
|
|
283
|
-
href={contentUrl}
|
|
284
|
-
download={label}
|
|
285
|
-
className="inline-flex h-8 items-center rounded-lg border border-border bg-card px-3 text-xs font-medium text-foreground transition-colors hover:bg-muted"
|
|
286
|
-
>
|
|
287
|
-
{t("chatWorkspacePreviewDownload")}
|
|
288
|
-
</a>
|
|
289
|
-
<a
|
|
290
|
-
href={contentUrl}
|
|
291
|
-
target="_blank"
|
|
292
|
-
rel="noreferrer"
|
|
293
|
-
className="inline-flex h-8 items-center rounded-lg bg-primary px-3 text-xs font-medium text-primary-foreground transition-colors hover:bg-primary/90"
|
|
294
|
-
>
|
|
295
|
-
{t("chatWorkspacePreviewOpenExternally")}
|
|
296
|
-
</a>
|
|
297
|
-
</div>
|
|
161
|
+
<div className="h-full overflow-auto custom-scrollbar bg-white">
|
|
162
|
+
<FileOperationCodeSurface block={block} layout="workspace" />
|
|
298
163
|
</div>
|
|
299
164
|
);
|
|
300
165
|
}
|
|
@@ -304,29 +169,29 @@ function WorkspacePreviewBody({
|
|
|
304
169
|
contentUrlKind,
|
|
305
170
|
contentLabel,
|
|
306
171
|
directoryQuery,
|
|
172
|
+
fileBasePath,
|
|
307
173
|
onFileOpen,
|
|
308
174
|
previewBlock,
|
|
309
175
|
previewKind,
|
|
176
|
+
previewViewer,
|
|
310
177
|
previewQuery,
|
|
311
178
|
previewText,
|
|
312
|
-
previewUrl,
|
|
313
|
-
previewViewer,
|
|
314
179
|
}: {
|
|
315
180
|
contentUrl: string | null;
|
|
316
|
-
contentUrlKind:
|
|
181
|
+
contentUrlKind: WorkspaceFileContentKind | null;
|
|
317
182
|
contentLabel: string;
|
|
318
183
|
directoryQuery: ReturnType<typeof useServerPathBrowse> | null | undefined;
|
|
184
|
+
fileBasePath: string | null;
|
|
319
185
|
onFileOpen: (action: ChatFileOpenActionViewModel) => void;
|
|
320
186
|
previewBlock: ChatFileOperationBlockViewModel | null;
|
|
321
187
|
previewKind: "text" | "markdown" | "binary";
|
|
188
|
+
previewViewer: "source" | "rendered" | null;
|
|
322
189
|
previewQuery: ReturnType<typeof useServerPathRead> | null | undefined;
|
|
323
190
|
previewText: string | null;
|
|
324
|
-
previewUrl: string | null;
|
|
325
|
-
previewViewer: "source" | "rendered";
|
|
326
191
|
}) {
|
|
327
192
|
if (contentUrl && contentUrlKind) {
|
|
328
193
|
return (
|
|
329
|
-
<
|
|
194
|
+
<WorkspaceFileContentPreview
|
|
330
195
|
contentUrl={contentUrl}
|
|
331
196
|
kind={contentUrlKind}
|
|
332
197
|
label={contentLabel}
|
|
@@ -375,11 +240,7 @@ function WorkspacePreviewBody({
|
|
|
375
240
|
);
|
|
376
241
|
}
|
|
377
242
|
|
|
378
|
-
if (
|
|
379
|
-
return <WorkspaceHtmlRenderedPreview src={previewUrl} />;
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
if (previewKind === "markdown" && previewText) {
|
|
243
|
+
if (previewKind === "markdown" && previewViewer !== "source" && previewText) {
|
|
383
244
|
return (
|
|
384
245
|
<div className="h-full overflow-auto custom-scrollbar px-5 py-4">
|
|
385
246
|
<ChatMessageMarkdown
|
|
@@ -390,6 +251,9 @@ function WorkspacePreviewBody({
|
|
|
390
251
|
copiedCodeLabel: t("chatCodeCopied"),
|
|
391
252
|
}}
|
|
392
253
|
onFileOpen={onFileOpen}
|
|
254
|
+
resolveFileContentUrl={(action) =>
|
|
255
|
+
buildServerPathContentUrl(action.path, fileBasePath)
|
|
256
|
+
}
|
|
393
257
|
/>
|
|
394
258
|
</div>
|
|
395
259
|
);
|
|
@@ -418,8 +282,8 @@ export function ChatSessionWorkspaceFilePreview({
|
|
|
418
282
|
onFileOpen,
|
|
419
283
|
}: ChatSessionWorkspaceFilePreviewProps) {
|
|
420
284
|
const isPreviewMode = file.viewMode === "preview";
|
|
421
|
-
const
|
|
422
|
-
const usesServerPath = isPreviewMode && !
|
|
285
|
+
const suppliedContentUrl = file.contentUrl?.trim() || null;
|
|
286
|
+
const usesServerPath = isPreviewMode && !suppliedContentUrl;
|
|
423
287
|
const previewQuery = useServerPathRead({
|
|
424
288
|
path: file.path,
|
|
425
289
|
basePath: sessionWorkingDir,
|
|
@@ -435,14 +299,15 @@ export function ChatSessionWorkspaceFilePreview({
|
|
|
435
299
|
() => (file.viewMode === "diff" ? buildDiffBlock(file) : null),
|
|
436
300
|
[file],
|
|
437
301
|
);
|
|
438
|
-
const previewText =
|
|
439
|
-
|
|
302
|
+
const previewText = isPreviewMode
|
|
303
|
+
? (previewQuery?.data?.text ?? file.rawText ?? null)
|
|
304
|
+
: null;
|
|
440
305
|
const previewKind = inferPreviewKind({
|
|
441
306
|
path: previewQuery?.data?.resolvedPath ?? file.path,
|
|
442
307
|
serverKind: previewQuery?.data?.kind,
|
|
443
308
|
});
|
|
444
|
-
const
|
|
445
|
-
?
|
|
309
|
+
const suppliedContentKind = suppliedContentUrl
|
|
310
|
+
? resolveWorkspaceFileContentKind({
|
|
446
311
|
path: file.path,
|
|
447
312
|
mimeType: file.mimeType,
|
|
448
313
|
})
|
|
@@ -452,17 +317,32 @@ export function ChatSessionWorkspaceFilePreview({
|
|
|
452
317
|
previewQuery?.data?.resolvedPath ??
|
|
453
318
|
file.path;
|
|
454
319
|
const previewPathKind = directoryQuery?.data ? "directory" : "file";
|
|
455
|
-
const previewViewer =
|
|
320
|
+
const previewViewer = resolveWorkspaceFileViewer(
|
|
321
|
+
resolvedPath,
|
|
322
|
+
file.previewViewer,
|
|
323
|
+
);
|
|
324
|
+
const localContentKind = resolveWorkspaceFileContentKind({
|
|
456
325
|
path: resolvedPath,
|
|
457
|
-
viewer: file.previewViewer,
|
|
458
326
|
});
|
|
459
|
-
const
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
327
|
+
const localContentUrlCandidate = buildServerPathContentUrl(
|
|
328
|
+
file.path,
|
|
329
|
+
sessionWorkingDir,
|
|
330
|
+
);
|
|
331
|
+
const shouldRenderLocalContent = Boolean(
|
|
332
|
+
!suppliedContentUrl &&
|
|
333
|
+
isPreviewMode &&
|
|
334
|
+
localContentUrlCandidate &&
|
|
335
|
+
file.previewViewer !== "source" &&
|
|
336
|
+
localContentKind !== "other" &&
|
|
337
|
+
(localContentKind !== "html" || previewViewer === "rendered"),
|
|
338
|
+
);
|
|
339
|
+
const localContentUrl =
|
|
340
|
+
shouldRenderLocalContent && localContentUrlCandidate
|
|
341
|
+
? appendPreviewRefreshVersion(localContentUrlCandidate, refreshVersion)
|
|
465
342
|
: null;
|
|
343
|
+
const contentUrl = suppliedContentUrl ?? localContentUrl;
|
|
344
|
+
const contentUrlKind =
|
|
345
|
+
suppliedContentKind ?? (localContentUrl ? localContentKind : null);
|
|
466
346
|
const previewBlock = useMemo(() => {
|
|
467
347
|
if (!isPreviewMode || !previewText || contentUrl) {
|
|
468
348
|
return null;
|
|
@@ -482,7 +362,7 @@ export function ChatSessionWorkspaceFilePreview({
|
|
|
482
362
|
previewQuery?.data?.resolvedPath,
|
|
483
363
|
previewText,
|
|
484
364
|
]);
|
|
485
|
-
const
|
|
365
|
+
const isTextPreviewTruncated = !contentUrl && Boolean(previewQuery?.data?.truncated);
|
|
486
366
|
const breadcrumbBasePath = sessionProjectRoot ?? sessionWorkingDir;
|
|
487
367
|
const breadcrumb = useMemo(
|
|
488
368
|
() =>
|
|
@@ -492,13 +372,13 @@ export function ChatSessionWorkspaceFilePreview({
|
|
|
492
372
|
sessionProjectRoot: breadcrumbBasePath,
|
|
493
373
|
line: file.line,
|
|
494
374
|
column: file.column,
|
|
495
|
-
truncated:
|
|
375
|
+
truncated: isTextPreviewTruncated,
|
|
496
376
|
}),
|
|
497
377
|
[
|
|
498
378
|
breadcrumbBasePath,
|
|
499
379
|
file.column,
|
|
500
380
|
file.line,
|
|
501
|
-
|
|
381
|
+
isTextPreviewTruncated,
|
|
502
382
|
previewPathKind,
|
|
503
383
|
resolvedPath,
|
|
504
384
|
],
|
|
@@ -520,13 +400,13 @@ export function ChatSessionWorkspaceFilePreview({
|
|
|
520
400
|
contentUrlKind={contentUrlKind}
|
|
521
401
|
contentLabel={file.label?.trim() || resolvedPath}
|
|
522
402
|
directoryQuery={directoryQuery}
|
|
403
|
+
fileBasePath={sessionWorkingDir}
|
|
523
404
|
onFileOpen={onFileOpen}
|
|
524
405
|
previewBlock={previewBlock}
|
|
525
406
|
previewKind={previewKind}
|
|
407
|
+
previewViewer={previewViewer}
|
|
526
408
|
previewQuery={previewQuery}
|
|
527
409
|
previewText={previewText}
|
|
528
|
-
previewUrl={previewUrl}
|
|
529
|
-
previewViewer={previewViewer}
|
|
530
410
|
/>
|
|
531
411
|
)}
|
|
532
412
|
</div>
|
package/src/features/chat/features/workspace/components/chat-session-workspace-panel-content.tsx
CHANGED
|
@@ -1,21 +1,234 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import {
|
|
3
|
+
AlarmClock,
|
|
4
|
+
ChevronRight,
|
|
5
|
+
FolderTree,
|
|
6
|
+
GitBranch,
|
|
7
|
+
MessageSquarePlus,
|
|
8
|
+
} from "lucide-react";
|
|
2
9
|
import type { CronJobView } from "@/shared/lib/api";
|
|
3
10
|
import { usePresenter } from "@/features/chat/components/providers/chat-presenter.provider";
|
|
4
11
|
import { SessionConversationArea } from "@/features/chat/features/conversation/components/session-conversation-area";
|
|
5
12
|
import { ChatSessionWorkspaceFilePreview } from "@/features/chat/features/workspace/components/chat-session-workspace-file-preview";
|
|
13
|
+
import { ChatSessionWorkspaceDirectoryBrowser } from "@/features/chat/features/workspace/components/chat-session-workspace-directory-browser";
|
|
6
14
|
import { SessionCronJobContent } from "@/features/chat/features/workspace/components/session-cron-job-content";
|
|
7
15
|
import type { ResolvedChildSessionTab } from "@/features/chat/features/ncp/hooks/use-ncp-child-session-tabs-view";
|
|
8
16
|
import type { WorkspaceSelection } from "@/features/chat/features/workspace/utils/chat-workspace-panel-view-model.utils";
|
|
17
|
+
import { useServerPathBrowse } from "@/shared/hooks/use-server-path-browse";
|
|
9
18
|
import { t } from "@/shared/lib/i18n";
|
|
19
|
+
import { cn } from "@/shared/lib/utils";
|
|
10
20
|
|
|
11
21
|
type ChatSessionWorkspacePanelContentProps = {
|
|
12
22
|
activeSelection: WorkspaceSelection;
|
|
23
|
+
childSessionTabs: readonly ResolvedChildSessionTab[];
|
|
13
24
|
filePreviewRefreshVersion: number;
|
|
25
|
+
sessionKey: string | null;
|
|
14
26
|
sessionCronJobs: readonly CronJobView[];
|
|
15
27
|
sessionProjectRoot: string | null;
|
|
16
28
|
sessionWorkingDir: string | null;
|
|
17
29
|
};
|
|
18
30
|
|
|
31
|
+
function WorkspaceOverviewEntry({
|
|
32
|
+
count,
|
|
33
|
+
description,
|
|
34
|
+
icon,
|
|
35
|
+
onClick,
|
|
36
|
+
title,
|
|
37
|
+
}: {
|
|
38
|
+
count?: number;
|
|
39
|
+
description: string;
|
|
40
|
+
icon: ReactNode;
|
|
41
|
+
onClick: () => void;
|
|
42
|
+
title: string;
|
|
43
|
+
}) {
|
|
44
|
+
return (
|
|
45
|
+
<button
|
|
46
|
+
type="button"
|
|
47
|
+
className="group flex w-full items-center gap-3 rounded-lg border border-gray-200/80 bg-white px-3 py-3 text-left transition-colors hover:border-gray-300 hover:bg-gray-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/25"
|
|
48
|
+
onClick={onClick}
|
|
49
|
+
>
|
|
50
|
+
<span className="inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-gray-100 text-gray-600">
|
|
51
|
+
{icon}
|
|
52
|
+
</span>
|
|
53
|
+
<span className="min-w-0 flex-1">
|
|
54
|
+
<span className="flex items-center gap-2 text-sm font-medium text-gray-900">
|
|
55
|
+
<span className="truncate">{title}</span>
|
|
56
|
+
{typeof count === "number" ? (
|
|
57
|
+
<span className="rounded-full bg-gray-100 px-1.5 py-0.5 text-[10px] font-semibold tabular-nums text-gray-500">
|
|
58
|
+
{count}
|
|
59
|
+
</span>
|
|
60
|
+
) : null}
|
|
61
|
+
</span>
|
|
62
|
+
<span className="mt-0.5 block text-xs leading-5 text-gray-500">
|
|
63
|
+
{description}
|
|
64
|
+
</span>
|
|
65
|
+
</span>
|
|
66
|
+
<ChevronRight className="h-4 w-4 shrink-0 text-gray-300 transition-transform group-hover:translate-x-0.5 group-hover:text-gray-500" />
|
|
67
|
+
</button>
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function WorkspaceOverview({
|
|
72
|
+
childSessionTabs,
|
|
73
|
+
sessionCronJobs,
|
|
74
|
+
sessionKey,
|
|
75
|
+
}: {
|
|
76
|
+
childSessionTabs: readonly ResolvedChildSessionTab[];
|
|
77
|
+
sessionCronJobs: readonly CronJobView[];
|
|
78
|
+
sessionKey: string | null;
|
|
79
|
+
}) {
|
|
80
|
+
const presenter = usePresenter();
|
|
81
|
+
|
|
82
|
+
return (
|
|
83
|
+
<div className="h-full overflow-auto bg-gray-50/45 px-4 py-5 custom-scrollbar">
|
|
84
|
+
<div className="mx-auto max-w-xl">
|
|
85
|
+
<h2 className="text-base font-semibold text-gray-900">
|
|
86
|
+
{t("chatWorkspaceOverview")}
|
|
87
|
+
</h2>
|
|
88
|
+
<p className="mt-1 text-xs leading-5 text-gray-500">
|
|
89
|
+
{t("chatWorkspaceOverviewDescription")}
|
|
90
|
+
</p>
|
|
91
|
+
<div className="mt-4 space-y-2">
|
|
92
|
+
<WorkspaceOverviewEntry
|
|
93
|
+
count={childSessionTabs.length}
|
|
94
|
+
description={t("chatWorkspaceChildSessionsDescription")}
|
|
95
|
+
icon={<GitBranch className="h-4 w-4" />}
|
|
96
|
+
title={t("chatWorkspaceChildSessions")}
|
|
97
|
+
onClick={() => {
|
|
98
|
+
if (sessionKey) {
|
|
99
|
+
presenter.chatThreadManager.openChildSessions(sessionKey);
|
|
100
|
+
}
|
|
101
|
+
}}
|
|
102
|
+
/>
|
|
103
|
+
<WorkspaceOverviewEntry
|
|
104
|
+
count={sessionCronJobs.length}
|
|
105
|
+
description={t("chatWorkspaceSessionCronJobsDescription")}
|
|
106
|
+
icon={<AlarmClock className="h-4 w-4" />}
|
|
107
|
+
title={t("chatWorkspaceSessionCronJobs")}
|
|
108
|
+
onClick={() => {
|
|
109
|
+
if (sessionKey) {
|
|
110
|
+
presenter.chatThreadManager.openSessionCronPanel(sessionKey);
|
|
111
|
+
}
|
|
112
|
+
}}
|
|
113
|
+
/>
|
|
114
|
+
<WorkspaceOverviewEntry
|
|
115
|
+
description={t("chatWorkspaceProjectFilesDescription")}
|
|
116
|
+
icon={<FolderTree className="h-4 w-4" />}
|
|
117
|
+
title={t("chatWorkspaceProjectFiles")}
|
|
118
|
+
onClick={() => {
|
|
119
|
+
if (sessionKey) {
|
|
120
|
+
presenter.chatThreadManager.openProjectFiles(sessionKey);
|
|
121
|
+
}
|
|
122
|
+
}}
|
|
123
|
+
/>
|
|
124
|
+
</div>
|
|
125
|
+
</div>
|
|
126
|
+
</div>
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function WorkspaceChildSessions({
|
|
131
|
+
childSessionTabs,
|
|
132
|
+
}: {
|
|
133
|
+
childSessionTabs: readonly ResolvedChildSessionTab[];
|
|
134
|
+
}) {
|
|
135
|
+
const presenter = usePresenter();
|
|
136
|
+
|
|
137
|
+
return (
|
|
138
|
+
<div className="h-full overflow-auto bg-gray-50/45 px-4 py-5 custom-scrollbar">
|
|
139
|
+
<div className="mx-auto max-w-xl">
|
|
140
|
+
<div className="flex items-center gap-2">
|
|
141
|
+
<h2 className="text-base font-semibold text-gray-900">
|
|
142
|
+
{t("chatWorkspaceChildSessions")}
|
|
143
|
+
</h2>
|
|
144
|
+
<span className="rounded-full bg-gray-100 px-1.5 py-0.5 text-[10px] font-semibold tabular-nums text-gray-500">
|
|
145
|
+
{childSessionTabs.length}
|
|
146
|
+
</span>
|
|
147
|
+
</div>
|
|
148
|
+
{childSessionTabs.length === 0 ? (
|
|
149
|
+
<div className="py-10 text-center text-sm text-gray-500">
|
|
150
|
+
{t("chatWorkspaceChildSessionsEmpty")}
|
|
151
|
+
</div>
|
|
152
|
+
) : (
|
|
153
|
+
<div className="mt-4 space-y-2">
|
|
154
|
+
{childSessionTabs.map((tab) => (
|
|
155
|
+
<button
|
|
156
|
+
key={tab.sessionKey}
|
|
157
|
+
type="button"
|
|
158
|
+
className="group flex w-full items-center gap-3 rounded-lg border border-gray-200/80 bg-white px-3 py-3 text-left transition-colors hover:border-gray-300 hover:bg-gray-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/25"
|
|
159
|
+
onClick={() =>
|
|
160
|
+
presenter.chatThreadManager.selectChildSessionDetail(
|
|
161
|
+
tab.sessionKey,
|
|
162
|
+
)
|
|
163
|
+
}
|
|
164
|
+
>
|
|
165
|
+
<span className="inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-gray-100 text-gray-600">
|
|
166
|
+
<GitBranch className="h-4 w-4" />
|
|
167
|
+
</span>
|
|
168
|
+
<span className="min-w-0 flex-1">
|
|
169
|
+
<span className="block truncate text-sm font-medium text-gray-900">
|
|
170
|
+
{tab.title}
|
|
171
|
+
</span>
|
|
172
|
+
{tab.projectName || tab.sessionTypeLabel ? (
|
|
173
|
+
<span className="mt-0.5 block truncate text-xs text-gray-500">
|
|
174
|
+
{[tab.sessionTypeLabel, tab.projectName]
|
|
175
|
+
.filter(Boolean)
|
|
176
|
+
.join(" · ")}
|
|
177
|
+
</span>
|
|
178
|
+
) : null}
|
|
179
|
+
</span>
|
|
180
|
+
<ChevronRight className="h-4 w-4 shrink-0 text-gray-300 transition-transform group-hover:translate-x-0.5 group-hover:text-gray-500" />
|
|
181
|
+
</button>
|
|
182
|
+
))}
|
|
183
|
+
</div>
|
|
184
|
+
)}
|
|
185
|
+
</div>
|
|
186
|
+
</div>
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function WorkspaceProjectFiles({
|
|
191
|
+
projectRoot,
|
|
192
|
+
workingDir,
|
|
193
|
+
}: {
|
|
194
|
+
projectRoot: string | null;
|
|
195
|
+
workingDir: string | null;
|
|
196
|
+
}) {
|
|
197
|
+
const presenter = usePresenter();
|
|
198
|
+
const rootPath = projectRoot ?? workingDir;
|
|
199
|
+
const browseQuery = useServerPathBrowse({
|
|
200
|
+
path: rootPath,
|
|
201
|
+
includeFiles: true,
|
|
202
|
+
enabled: Boolean(rootPath),
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
if (!rootPath) {
|
|
206
|
+
return (
|
|
207
|
+
<div className="flex h-full items-center justify-center px-6 text-center text-sm text-gray-500">
|
|
208
|
+
{t("chatWorkspaceProjectFilesUnavailable")}
|
|
209
|
+
</div>
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return (
|
|
214
|
+
<ChatSessionWorkspaceDirectoryBrowser
|
|
215
|
+
browseQuery={browseQuery}
|
|
216
|
+
onFileOpen={presenter.chatThreadManager.openFilePreview}
|
|
217
|
+
renderStatus={({ text, tone = "muted" }) => (
|
|
218
|
+
<div
|
|
219
|
+
className={cn(
|
|
220
|
+
"flex h-full items-center justify-center px-6 text-center text-sm",
|
|
221
|
+
tone === "error" ? "text-rose-600" : "text-gray-500",
|
|
222
|
+
)}
|
|
223
|
+
>
|
|
224
|
+
{text}
|
|
225
|
+
</div>
|
|
226
|
+
)}
|
|
227
|
+
showRoot
|
|
228
|
+
/>
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
|
|
19
232
|
function ChildSessionMetaChip({ value }: { value: string }) {
|
|
20
233
|
return (
|
|
21
234
|
<span className="inline-flex max-w-full shrink-0 items-center rounded border border-gray-200 bg-gray-50 px-1.5 py-0.5 text-[10px] font-medium text-gray-600">
|
|
@@ -68,13 +281,38 @@ function WorkspaceSideChatDraftHeader() {
|
|
|
68
281
|
|
|
69
282
|
export function ChatSessionWorkspacePanelContent({
|
|
70
283
|
activeSelection,
|
|
284
|
+
childSessionTabs,
|
|
71
285
|
filePreviewRefreshVersion,
|
|
286
|
+
sessionKey,
|
|
72
287
|
sessionCronJobs,
|
|
73
288
|
sessionProjectRoot,
|
|
74
289
|
sessionWorkingDir,
|
|
75
290
|
}: ChatSessionWorkspacePanelContentProps) {
|
|
76
291
|
const presenter = usePresenter();
|
|
77
292
|
|
|
293
|
+
if (activeSelection.kind === "overview") {
|
|
294
|
+
return (
|
|
295
|
+
<WorkspaceOverview
|
|
296
|
+
childSessionTabs={childSessionTabs}
|
|
297
|
+
sessionCronJobs={sessionCronJobs}
|
|
298
|
+
sessionKey={sessionKey}
|
|
299
|
+
/>
|
|
300
|
+
);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
if (activeSelection.kind === "project-files") {
|
|
304
|
+
return (
|
|
305
|
+
<WorkspaceProjectFiles
|
|
306
|
+
projectRoot={sessionProjectRoot}
|
|
307
|
+
workingDir={sessionWorkingDir}
|
|
308
|
+
/>
|
|
309
|
+
);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
if (activeSelection.kind === "child-sessions") {
|
|
313
|
+
return <WorkspaceChildSessions childSessionTabs={childSessionTabs} />;
|
|
314
|
+
}
|
|
315
|
+
|
|
78
316
|
if (activeSelection.kind === "side-chat-draft") {
|
|
79
317
|
return (
|
|
80
318
|
<>
|