# 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