feat: move git toolbar to top bar with proper styling
- Move GitToolbar from sidebar to top bar below workspace header - Remove GitToolbar from sidebar layout - Add comprehensive CSS styles for git toolbar: - Flex layout with proper spacing - Styled buttons with hover effects - Branch selector styling - Badge styling for ahead/behind counts - Status badges for modified/added/deleted/untracked - Error message styling - New branch form styling - Quality gates: typecheck ✓ lint ✓ build ✓
This commit is contained in:
@@ -172,48 +172,51 @@ export const RepoWorkspace = () => {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{status === "ready" && repositories.length > 0 && (
|
{status === "ready" && repositories.length > 0 && (
|
||||||
<div className="workspace-layout">
|
<>
|
||||||
<aside className="workspace-sidebar">
|
{selectedRepoId && (
|
||||||
<div className="sidebar-section">
|
<GitToolbar
|
||||||
<label className="form-field">
|
projectId={projectId!}
|
||||||
Repository
|
repoId={selectedRepoId}
|
||||||
<select
|
currentBranch={currentBranch}
|
||||||
value={selectedRepoId || ""}
|
branches={branches}
|
||||||
onChange={(e) => handleRepoChange(e.target.value)}
|
onBranchChange={(branch) => {
|
||||||
>
|
setCurrentBranch(branch);
|
||||||
{repositories.map((repo) => (
|
const newParams = new URLSearchParams(searchParams);
|
||||||
<option key={repo.id} value={repo.id}>
|
newParams.set("branch", branch);
|
||||||
{repo.name}
|
setSearchParams(newParams);
|
||||||
</option>
|
}}
|
||||||
))}
|
onRefresh={() => {
|
||||||
</select>
|
void loadBranches();
|
||||||
</label>
|
void loadGitStatus();
|
||||||
</div>
|
window.dispatchEvent(new CustomEvent("refresh-file-tree"));
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<div className="workspace-layout">
|
||||||
|
<aside className="workspace-sidebar">
|
||||||
|
<div className="sidebar-section">
|
||||||
|
<label className="form-field">
|
||||||
|
Repository
|
||||||
|
<select
|
||||||
|
value={selectedRepoId || ""}
|
||||||
|
onChange={(e) => handleRepoChange(e.target.value)}
|
||||||
|
>
|
||||||
|
{repositories.map((repo) => (
|
||||||
|
<option key={repo.id} value={repo.id}>
|
||||||
|
{repo.name}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
{selectedRepoId && (
|
{selectedRepoId && (
|
||||||
<>
|
<>
|
||||||
<GitToolbar
|
<FileBrowser
|
||||||
projectId={projectId!}
|
projectId={projectId!}
|
||||||
repoId={selectedRepoId}
|
repoId={selectedRepoId}
|
||||||
currentBranch={currentBranch}
|
gitStatus={gitStatus}
|
||||||
branches={branches}
|
/>
|
||||||
onBranchChange={(branch) => {
|
|
||||||
setCurrentBranch(branch);
|
|
||||||
const newParams = new URLSearchParams(searchParams);
|
|
||||||
newParams.set("branch", branch);
|
|
||||||
setSearchParams(newParams);
|
|
||||||
}}
|
|
||||||
onRefresh={() => {
|
|
||||||
void loadBranches();
|
|
||||||
void loadGitStatus();
|
|
||||||
window.dispatchEvent(new CustomEvent("refresh-file-tree"));
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<FileBrowser
|
|
||||||
projectId={projectId!}
|
|
||||||
repoId={selectedRepoId}
|
|
||||||
gitStatus={gitStatus}
|
|
||||||
/>
|
|
||||||
{gitStatus && (
|
{gitStatus && (
|
||||||
<CommitPanel
|
<CommitPanel
|
||||||
projectId={projectId!}
|
projectId={projectId!}
|
||||||
@@ -238,6 +241,7 @@ export const RepoWorkspace = () => {
|
|||||||
)}
|
)}
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1238,3 +1238,142 @@ a {
|
|||||||
color: white;
|
color: white;
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Git Toolbar - Top Bar Styles */
|
||||||
|
.git-toolbar {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
padding: 0.5rem 1.5rem;
|
||||||
|
background: var(--bg);
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
min-height: 48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.75rem;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar-group {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar-button {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.35rem;
|
||||||
|
padding: 0.4rem 0.75rem;
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: 6px;
|
||||||
|
background: var(--panel);
|
||||||
|
color: var(--ink);
|
||||||
|
font-size: 0.85rem;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar-button:hover:not(:disabled) {
|
||||||
|
background: var(--brand);
|
||||||
|
color: white;
|
||||||
|
border-color: var(--brand);
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar-button:disabled {
|
||||||
|
opacity: 0.5;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar-button.primary {
|
||||||
|
background: var(--brand);
|
||||||
|
color: white;
|
||||||
|
border-color: var(--brand);
|
||||||
|
}
|
||||||
|
|
||||||
|
.branch-select {
|
||||||
|
padding: 0.4rem 0.75rem;
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: 6px;
|
||||||
|
background: var(--panel);
|
||||||
|
color: var(--ink);
|
||||||
|
font-size: 0.85rem;
|
||||||
|
cursor: pointer;
|
||||||
|
min-width: 140px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
padding: 0 4px;
|
||||||
|
background: var(--brand);
|
||||||
|
color: white;
|
||||||
|
font-size: 0.7rem;
|
||||||
|
font-weight: 600;
|
||||||
|
border-radius: 999px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar-error {
|
||||||
|
color: #ef4444;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
padding: 0.25rem 0.5rem;
|
||||||
|
background: rgba(239, 68, 68, 0.1);
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar-input {
|
||||||
|
padding: 0.4rem 0.75rem;
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: 6px;
|
||||||
|
background: var(--panel);
|
||||||
|
color: var(--ink);
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.new-branch-form {
|
||||||
|
padding: 0.75rem;
|
||||||
|
background: var(--panel);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: 8px;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-summary {
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-badge {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.25rem;
|
||||||
|
padding: 0.2rem 0.5rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-badge.modified {
|
||||||
|
background: rgba(245, 158, 11, 0.1);
|
||||||
|
color: #d97706;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-badge.added {
|
||||||
|
background: rgba(16, 185, 129, 0.1);
|
||||||
|
color: #059669;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-badge.deleted {
|
||||||
|
background: rgba(239, 68, 68, 0.1);
|
||||||
|
color: #dc2626;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-badge.untracked {
|
||||||
|
background: rgba(107, 114, 128, 0.1);
|
||||||
|
color: #4b5563;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user