Skip to content

Commit 2a40a04

Browse files
committed
style: flatten review dock shell
1 parent d00165e commit 2a40a04

6 files changed

Lines changed: 328 additions & 69 deletions

File tree

apps/web/src/components/workspace/WorkspaceEditorPanel.tsx

Lines changed: 14 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { KeyboardEventHandler, ReactNode, RefObject } from "react";
22
import type { Locale, Translator } from "../../i18n";
3-
import { MaximizeIcon, MinimizeIcon, SearchIcon, WorkspaceChangesIcon, WorkspaceFolderIcon } from "../icons";
3+
import { MaximizeIcon, MinimizeIcon, SearchIcon } from "../icons";
44

55
type WorkspaceEditorPanelProps = {
66
locale: Locale;
@@ -16,7 +16,6 @@ type WorkspaceEditorPanelProps = {
1616
fileSearchInputRef: RefObject<HTMLInputElement | null>;
1717
editorContent: ReactNode;
1818
sidebarContent: ReactNode;
19-
onSetSidebarView: (view: "files" | "git") => void;
2019
onFileSearchChange: (value: string) => void;
2120
onFileSearchFocus: (currentValue: string) => void;
2221
onFileSearchBlur: () => void;
@@ -39,7 +38,6 @@ export const WorkspaceEditorPanel = ({
3938
fileSearchInputRef,
4039
editorContent,
4140
sidebarContent,
42-
onSetSidebarView,
4341
onFileSearchChange,
4442
onFileSearchFocus,
4543
onFileSearchBlur,
@@ -56,32 +54,10 @@ export const WorkspaceEditorPanel = ({
5654
<div className="workspace-panel-title-block workspace-code-title-block">
5755
<span className="section-kicker">{t("codePanel")}</span>
5856
<strong>{previewFileName || t("selectFileFromNavigator")}</strong>
59-
</div>
60-
<div className="workspace-code-modes">
61-
{isExpanded ? (
62-
<>
63-
<button
64-
type="button"
65-
className={`workspace-panel-toggle ${codeSidebarView === "files" ? "active" : ""}`}
66-
onClick={() => onSetSidebarView("files")}
67-
>
68-
<WorkspaceFolderIcon />
69-
<span>{t("files")}</span>
70-
</button>
71-
<button
72-
type="button"
73-
className={`workspace-panel-toggle ${codeSidebarView === "git" ? "active" : ""}`}
74-
onClick={() => onSetSidebarView("git")}
75-
>
76-
<WorkspaceChangesIcon />
77-
<span>Git Diff</span>
78-
</button>
79-
{previewPathLabel && (
80-
<span className="workspace-code-current-path" title={previewPathLabel}>
81-
{previewPathLabel}
82-
</span>
83-
)}
84-
</>
57+
{isExpanded && previewPathLabel ? (
58+
<span className="workspace-code-current-path" title={previewPathLabel}>
59+
{previewPathLabel}
60+
</span>
8561
) : null}
8662
</div>
8763
<div className="workspace-code-actions">
@@ -118,7 +94,15 @@ export const WorkspaceEditorPanel = ({
11894

11995
<div className={`workspace-code-body ${isExpanded ? "expanded" : "collapsed"}`}>
12096
<div className="workspace-code-editor">{editorContent}</div>
121-
{isExpanded && <aside className="workspace-code-sidebar">{sidebarContent}</aside>}
97+
{isExpanded && (
98+
<aside
99+
className="workspace-code-sidebar workspace-review-dock"
100+
data-testid="workspace-review-dock"
101+
data-view={codeSidebarView}
102+
>
103+
{sidebarContent}
104+
</aside>
105+
)}
122106
</div>
123107
</div>
124108
</section>

apps/web/src/components/workspace/WorkspaceSidebar.tsx

Lines changed: 87 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
11
import type { Locale, Translator } from "../../i18n";
2+
import { displayPathName } from "../../shared/utils/path";
23
import type { TreeNode } from "../../state/workbench";
34
import type { GitChangeAction, GitChangeEntry } from "../../types/app";
4-
import { AgentSendIcon, GitDiscardIcon, GitStageIcon, GitUnstageIcon, RefreshIcon, getFileIcon } from "../icons";
5+
import {
6+
AgentSendIcon,
7+
GitDiscardIcon,
8+
GitStageIcon,
9+
GitUnstageIcon,
10+
RefreshIcon,
11+
WorkspaceBranchIcon,
12+
WorkspaceChangesIcon,
13+
WorkspaceFolderIcon,
14+
getFileIcon,
15+
} from "../icons";
516
import { TreeView } from "../TreeView";
617

718
type ChangeGroup = {
@@ -15,6 +26,7 @@ type WorkspaceSidebarProps = {
1526
view: "files" | "git";
1627
fileTree: TreeNode[];
1728
rootPath?: string;
29+
branchName?: string;
1830
selectedPath?: string;
1931
repoCollapsedPaths: Set<string>;
2032
gitChangeGroups: ChangeGroup[];
@@ -30,6 +42,7 @@ type WorkspaceSidebarProps = {
3042
onCommit: () => void;
3143
onGitChangeSelect: (change: GitChangeEntry) => void;
3244
onGitChangeAction: (change: GitChangeEntry, action: GitChangeAction) => void;
45+
onSetView: (view: "files" | "git") => void;
3346
t: Translator;
3447
};
3548

@@ -38,6 +51,7 @@ export const WorkspaceSidebar = ({
3851
view,
3952
fileTree,
4053
rootPath,
54+
branchName,
4155
selectedPath,
4256
repoCollapsedPaths,
4357
gitChangeGroups,
@@ -53,17 +67,79 @@ export const WorkspaceSidebar = ({
5367
onCommit,
5468
onGitChangeSelect,
5569
onGitChangeAction,
70+
onSetView,
5671
t
5772
}: WorkspaceSidebarProps) => {
58-
if (view === "files") {
59-
return (
60-
<>
61-
<div className="workspace-code-sidebar-head">
62-
<span className="section-kicker">{t("repositoryNavigator")}</span>
63-
<button className="workspace-icon-button bare" type="button" onClick={onRefresh} title={t("refresh")} aria-label={t("refresh")}>
64-
<RefreshIcon />
73+
const rootLabel = displayPathName(rootPath) || rootPath || "";
74+
const dockMeta = view === "git"
75+
? (branchName && branchName !== "—" ? branchName : "")
76+
: rootLabel;
77+
78+
const dockActions = view === "git" ? (
79+
<div className="git-toolbar-actions">
80+
<button className="workspace-icon-button bare" type="button" onClick={onRefresh} title={t("refresh")} aria-label={t("refresh")}>
81+
<RefreshIcon />
82+
</button>
83+
<button className="workspace-icon-button bare" type="button" onClick={onStageAll} title={t("stageAll")} aria-label={t("stageAll")}>
84+
<GitStageIcon />
85+
</button>
86+
<button className="workspace-icon-button bare" type="button" onClick={onUnstageAll} title={t("unstageAll")} aria-label={t("unstageAll")}>
87+
<GitUnstageIcon />
88+
</button>
89+
<button className="workspace-icon-button bare" type="button" onClick={onDiscardAll} title={t("discardAll")} aria-label={t("discardAll")}>
90+
<GitDiscardIcon />
91+
</button>
92+
<button className="workspace-icon-button bare" type="button" onClick={onCommit} disabled={!commitMessage.trim()} title={t("commit")} aria-label={t("commit")}>
93+
<AgentSendIcon />
94+
</button>
95+
</div>
96+
) : (
97+
<button className="workspace-icon-button bare" type="button" onClick={onRefresh} title={t("refresh")} aria-label={t("refresh")}>
98+
<RefreshIcon />
99+
</button>
100+
);
101+
102+
const dockHeader = (
103+
<div className="workspace-review-dock-header" data-testid="workspace-review-dock-toolbar">
104+
<div className="workspace-review-dock-topline">
105+
<span className="section-kicker">{view === "files" ? t("repositoryNavigator") : t("sourceControl")}</span>
106+
{dockMeta ? (
107+
<span className="workspace-review-dock-chip" title={dockMeta}>
108+
{view === "git" ? <WorkspaceBranchIcon /> : <WorkspaceFolderIcon />}
109+
<span>{dockMeta}</span>
110+
</span>
111+
) : null}
112+
</div>
113+
<div className="workspace-review-dock-bar">
114+
<div className="workspace-review-dock-tabs" data-testid="workspace-review-dock-tabs">
115+
<button
116+
type="button"
117+
className={`workspace-review-dock-tab ${view === "files" ? "active" : ""}`}
118+
onClick={() => onSetView("files")}
119+
aria-pressed={view === "files"}
120+
>
121+
<WorkspaceFolderIcon />
122+
<span>{t("files")}</span>
123+
</button>
124+
<button
125+
type="button"
126+
className={`workspace-review-dock-tab ${view === "git" ? "active" : ""}`}
127+
onClick={() => onSetView("git")}
128+
aria-pressed={view === "git"}
129+
>
130+
<WorkspaceChangesIcon />
131+
<span>Git Diff</span>
65132
</button>
66133
</div>
134+
{dockActions}
135+
</div>
136+
</div>
137+
);
138+
139+
if (view === "files") {
140+
return (
141+
<div className="workspace-review-dock-section workspace-review-dock-section-files">
142+
{dockHeader}
67143
{fileTree.length === 0 ? (
68144
<div className="tree-empty">{t("selectProjectToLoadFiles")}</div>
69145
) : (
@@ -77,32 +153,13 @@ export const WorkspaceSidebar = ({
77153
onToggleCollapse={onToggleRepoCollapse}
78154
/>
79155
)}
80-
</>
156+
</div>
81157
);
82158
}
83159

84160
return (
85-
<div className="workspace-git-sidebar">
86-
<div className="workspace-code-sidebar-head git-sidebar-head">
87-
<span className="section-kicker">{t("sourceControl")}</span>
88-
<div className="git-toolbar-actions">
89-
<button className="workspace-icon-button bare" type="button" onClick={onRefresh} title={t("refresh")} aria-label={t("refresh")}>
90-
<RefreshIcon />
91-
</button>
92-
<button className="workspace-icon-button bare" type="button" onClick={onStageAll} title={t("stageAll")} aria-label={t("stageAll")}>
93-
<GitStageIcon />
94-
</button>
95-
<button className="workspace-icon-button bare" type="button" onClick={onUnstageAll} title={t("unstageAll")} aria-label={t("unstageAll")}>
96-
<GitUnstageIcon />
97-
</button>
98-
<button className="workspace-icon-button bare" type="button" onClick={onDiscardAll} title={t("discardAll")} aria-label={t("discardAll")}>
99-
<GitDiscardIcon />
100-
</button>
101-
<button className="workspace-icon-button bare" type="button" onClick={onCommit} disabled={!commitMessage.trim()} title={t("commit")} aria-label={t("commit")}>
102-
<AgentSendIcon />
103-
</button>
104-
</div>
105-
</div>
161+
<div className="workspace-git-sidebar workspace-review-dock-section workspace-review-dock-section-git">
162+
{dockHeader}
106163
<div className="workspace-git-compose">
107164
<div className="form-row">
108165
<input

apps/web/src/features/editor/WorkspaceCodeFeature.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ type SidebarViewModel = {
3939
view: "files" | "git";
4040
fileTree: TreeNode[];
4141
rootPath?: string;
42+
branchName?: string;
4243
selectedPath?: string;
4344
repoCollapsedPaths: Set<string>;
4445
gitChangeGroups: ChangeGroup[];
@@ -95,6 +96,7 @@ export const WorkspaceCodeFeature = ({
9596
view={sidebar.view}
9697
fileTree={sidebar.fileTree}
9798
rootPath={sidebar.rootPath}
99+
branchName={sidebar.branchName}
98100
selectedPath={sidebar.selectedPath}
99101
repoCollapsedPaths={sidebar.repoCollapsedPaths}
100102
gitChangeGroups={sidebar.gitChangeGroups}
@@ -110,6 +112,7 @@ export const WorkspaceCodeFeature = ({
110112
onCommit={sidebar.onCommit}
111113
onGitChangeSelect={sidebar.onGitChangeSelect}
112114
onGitChangeAction={sidebar.onGitChangeAction}
115+
onSetView={onSetSidebarView}
113116
t={t}
114117
/>
115118
);
@@ -130,7 +133,6 @@ export const WorkspaceCodeFeature = ({
130133
fileSearchInputRef={fileSearch.inputRef}
131134
editorContent={editorContent}
132135
sidebarContent={sidebarContent}
133-
onSetSidebarView={onSetSidebarView}
134136
onFileSearchChange={fileSearch.onChange}
135137
onFileSearchFocus={fileSearch.onFocus}
136138
onFileSearchBlur={fileSearch.onBlur}

apps/web/src/features/workspace/WorkspaceScreen.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2437,6 +2437,7 @@ export default function WorkspaceScreen({ locale, appSettings, onOpenSettings }:
24372437
view: codeSidebarView,
24382438
fileTree: activeTab.fileTree,
24392439
rootPath: activeTab.project?.path,
2440+
branchName: activeTab.git.branch,
24402441
selectedPath: activeTab.filePreview.path,
24412442
repoCollapsedPaths,
24422443
gitChangeGroups,

0 commit comments

Comments
 (0)