875594d66d
- Add CommitPanel component for viewing changed files and committing - Show file status indicators (M/A/D/?) in file tree - Integrate git status with workspace for real-time updates - Add CSS styles for commit panel and status badges Part of git-control change implementation.
270 lines
7.9 KiB
Markdown
270 lines
7.9 KiB
Markdown
# Repository Workspace - Design
|
|
|
|
## Architecture
|
|
|
|
```
|
|
Project List
|
|
↓ (click project)
|
|
Repo Workspace (default view)
|
|
├─ Sidebar (200px)
|
|
│ ├─ Repo Selector (dropdown)
|
|
│ ├─ Branch Selector (dropdown)
|
|
│ └─ File Tree (scrollable)
|
|
│ ├─ 📁 src/
|
|
│ │ └─ 📄 main.py
|
|
│ ├─ 📁 tests/
|
|
│ └─ 📄 README.md
|
|
│
|
|
└─ Main Content
|
|
├─ Breadcrumbs: src > main.py
|
|
├─ Toolbar: [Edit] [Raw] [History]
|
|
└─ Content Area
|
|
├─ File View (syntax highlighted)
|
|
└─ Edit View (textarea with save)
|
|
```
|
|
|
|
## Page Layout
|
|
|
|
### Route: `/projects/:projectId`
|
|
This replaces the current placeholder and becomes the default project view.
|
|
|
|
### Layout Structure
|
|
```
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ App Shell (Header + Nav) │
|
|
├─────────────────────────────────────────────────────────────┤
|
|
│ Project Header │
|
|
│ "My Project" [Repos] [History] [Settings]│
|
|
├─────────────────┬───────────────────────────────────────────┤
|
|
│ │ │
|
|
│ Sidebar │ Main Content │
|
|
│ ┌───────────┐ │ ┌─────────────────────────────────────┐ │
|
|
│ │ Repo ▼ │ │ │ Breadcrumbs: src > components │ │
|
|
│ ├───────────┤ │ ├─────────────────────────────────────┤ │
|
|
│ │ Branch ▼ │ │ │ [Edit] [History] [Blame] │ │
|
|
│ ├───────────┤ │ ├─────────────────────────────────────┤ │
|
|
│ │ 📁 src/ │ │ │ │ │
|
|
│ │ 📁 tests/ │ │ │ function hello() { │ │
|
|
│ │ 📄 README │ │ │ return "world"; │ │
|
|
│ │ ... │ │ │ } │ │
|
|
│ │ │ │ │ │ │
|
|
│ └───────────┘ │ └─────────────────────────────────────┘ │
|
|
│ │ │
|
|
└─────────────────┴───────────────────────────────────────────┘
|
|
```
|
|
|
|
## Data Flow
|
|
|
|
### 1. Page Load
|
|
```
|
|
Load /projects/:id
|
|
→ Fetch project details
|
|
→ Fetch repositories list
|
|
→ Fetch default branch file tree (first repo)
|
|
→ Render workspace
|
|
```
|
|
|
|
### 2. Repository Switch
|
|
```
|
|
Select repo from dropdown
|
|
→ Fetch branches list
|
|
→ Fetch default branch file tree
|
|
→ Reset file viewer
|
|
```
|
|
|
|
### 3. Branch Switch
|
|
```
|
|
Select branch from dropdown
|
|
→ Fetch file tree for branch
|
|
→ If viewing a file: re-fetch file content for branch
|
|
```
|
|
|
|
### 4. File Navigation
|
|
```
|
|
Click file in tree
|
|
→ Fetch file content (with syntax highlighting hint)
|
|
→ Show in viewer
|
|
→ Update breadcrumbs
|
|
```
|
|
|
|
## API Endpoints
|
|
|
|
### GET /projects/{project_id}/repositories/{repo_id}/files
|
|
List files at a path (like `ls` for git).
|
|
|
|
**Query Parameters:**
|
|
- `branch`: Branch name (default: repo's default branch)
|
|
- `path`: Directory path (default: root)
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"path": "src",
|
|
"branch": "main",
|
|
"entries": [
|
|
{
|
|
"name": "components",
|
|
"type": "directory",
|
|
"path": "src/components"
|
|
},
|
|
{
|
|
"name": "main.py",
|
|
"type": "file",
|
|
"path": "src/main.py",
|
|
"size": 1234,
|
|
"last_commit": {
|
|
"hash": "abc123",
|
|
"message": "Initial commit",
|
|
"date": "2024-01-01T00:00:00Z"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### GET /projects/{project_id}/repositories/{repo_id}/files/content
|
|
Get file content.
|
|
|
|
**Query Parameters:**
|
|
- `branch`: Branch name
|
|
- `path`: File path
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"path": "src/main.py",
|
|
"branch": "main",
|
|
"content": "function hello() {\n return 'world';\n}",
|
|
"size": 42,
|
|
"encoding": "utf-8",
|
|
"language": "python"
|
|
}
|
|
```
|
|
|
|
### GET /projects/{project_id}/repositories/{repo_id}/branches
|
|
List branches.
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"branches": [
|
|
{
|
|
"name": "main",
|
|
"is_default": true,
|
|
"last_commit": "abc123"
|
|
},
|
|
{
|
|
"name": "feature/new-thing",
|
|
"is_default": false,
|
|
"last_commit": "def456"
|
|
}
|
|
],
|
|
"default_branch": "main"
|
|
}
|
|
```
|
|
|
|
### POST /projects/{project_id}/repositories/{repo_id}/files/content
|
|
Update file content (for quick edits).
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"path": "src/main.py",
|
|
"branch": "main",
|
|
"content": "function hello() {\n return 'world!!!';\n}",
|
|
"commit_message": "Quick edit: update greeting",
|
|
"author_name": "User Name",
|
|
"author_email": "user@example.com"
|
|
}
|
|
```
|
|
|
|
## Components
|
|
|
|
### RepoWorkspace (Page)
|
|
- Orchestrates layout: sidebar + main content
|
|
- Manages repo/branch/file state
|
|
- Handles URL params (projectId, optional repoId)
|
|
|
|
### FileTree (Sidebar Component)
|
|
- Recursive tree view
|
|
- Expandable folders
|
|
- File icons based on extension
|
|
- Active file highlight
|
|
- Click to open file
|
|
|
|
### RepoSelector (Component)
|
|
- Dropdown of project repositories
|
|
- Shows active repo name
|
|
- Switch triggers repo change
|
|
|
|
### BranchSelector (Component)
|
|
- Dropdown of branches
|
|
- Shows active branch
|
|
- Switch triggers branch change
|
|
|
|
### FileViewer (Component)
|
|
- Syntax highlighted content
|
|
- Line numbers
|
|
- View/Edit toggle
|
|
- Breadcrumb navigation
|
|
|
|
### Breadcrumbs (Component)
|
|
- Path segments as clickable links
|
|
- Shows current file location
|
|
|
|
## State Management
|
|
|
|
### URL State
|
|
```
|
|
/projects/:projectId?repo=:repoId&branch=:branch&path=:path
|
|
```
|
|
- repo: selected repository ID
|
|
- branch: active branch name
|
|
- path: current file/directory path
|
|
|
|
### React State (per workspace)
|
|
```typescript
|
|
interface WorkspaceState {
|
|
projectId: string;
|
|
selectedRepoId: string | null;
|
|
selectedBranch: string;
|
|
currentPath: string;
|
|
selectedFile: string | null;
|
|
fileContent: string | null;
|
|
isEditing: boolean;
|
|
fileTree: FileTreeEntry[];
|
|
branches: Branch[];
|
|
repositories: Repository[];
|
|
}
|
|
```
|
|
|
|
## Implementation Order
|
|
|
|
1. **Backend file APIs** - List files, get content, list branches
|
|
2. **Backend update API** - Save file changes (commit)
|
|
3. **Project list clickable** - Link to workspace
|
|
4. **Workspace page shell** - Layout with sidebar + main
|
|
5. **File tree component** - Recursive directory listing
|
|
6. **File viewer component** - Content display
|
|
7. **Repo/branch selectors** - Dropdowns with state
|
|
8. **Edit mode** - Toggle + save
|
|
9. **URL state sync** - Sync selections to URL
|
|
10. **Polish** - Icons, syntax highlighting, error handling
|
|
|
|
## Error Handling
|
|
|
|
- **Repo not found**: Show error, allow selecting another
|
|
- **Branch not found**: Show error, default to main
|
|
- **File not found**: Show 404 in viewer
|
|
- **Permission denied**: Show auth error
|
|
- **Binary files**: Show "Binary file, cannot display" message
|
|
- **Large files**: Show warning, offer download
|
|
|
|
## Performance Considerations
|
|
|
|
- **Lazy load file tree**: Only expand directories when clicked
|
|
- **Cache file content**: Don't re-fetch if file hasn't changed
|
|
- **Debounce tree loading**: When switching branches, debounce
|
|
- **Virtual scrolling**: For large directories (100+ files)
|
|
- **Syntax highlighting**: Use lightweight highlighter, async load
|