11import type { Locale , Translator } from "../../i18n" ;
2+ import { displayPathName } from "../../shared/utils/path" ;
23import type { TreeNode } from "../../state/workbench" ;
34import 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" ;
516import { TreeView } from "../TreeView" ;
617
718type 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
0 commit comments