feat: implement file editor with syntax highlighting and editing
- Install react-simple-code-editor and prismjs dependencies - Create language detection utility with 50+ file extensions - Create SyntaxHighlighter component with Prism.js highlighting - Create CodeEditor component with syntax-highlighted editing - Create CommitDialog with diff preview and commit message - Create FileEditor component integrating view/edit/commit flow - Replace FileViewer with FileEditor in RepoWorkspace - Add comprehensive CSS styles for editor, highlighter, and dialog - Support keyboard shortcuts: Ctrl+E (toggle edit), Ctrl+S (save) - Quality gates: typecheck ✓ lint ✓ build ✓
This commit is contained in:
@@ -0,0 +1,191 @@
|
||||
# File Editor - Design
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
RepoWorkspace
|
||||
└── FileEditor (replaces FileViewer)
|
||||
├── View Mode
|
||||
│ ├── Toolbar (Edit button, file info)
|
||||
│ ├── SyntaxHighlighter (Prism.js)
|
||||
│ └── Line numbers
|
||||
└── Edit Mode
|
||||
├── Toolbar (Save, Cancel, file info)
|
||||
├── Editor (react-simple-code-editor)
|
||||
└── Line numbers
|
||||
↓ [Save clicked]
|
||||
CommitDialog
|
||||
├── Diff preview
|
||||
├── Commit message input
|
||||
└── Author info
|
||||
```
|
||||
|
||||
## Component Design
|
||||
|
||||
### FileEditor
|
||||
|
||||
**Props:**
|
||||
```typescript
|
||||
interface FileEditorProps {
|
||||
projectId: string;
|
||||
repoId: string;
|
||||
filePath: string;
|
||||
branch: string;
|
||||
}
|
||||
```
|
||||
|
||||
**State:**
|
||||
```typescript
|
||||
interface FileEditorState {
|
||||
mode: 'view' | 'edit';
|
||||
content: string;
|
||||
originalContent: string;
|
||||
language: string;
|
||||
loading: boolean;
|
||||
error: string | null;
|
||||
showCommitDialog: boolean;
|
||||
}
|
||||
```
|
||||
|
||||
**Flow:**
|
||||
1. Load file content on mount/file change
|
||||
2. Detect language from file extension
|
||||
3. Display in view mode by default
|
||||
4. Click "Edit" → switch to edit mode
|
||||
5. Make changes → click "Save"
|
||||
6. Show commit dialog with diff
|
||||
7. Enter commit message → commit
|
||||
8. Return to view mode with updated content
|
||||
|
||||
### SyntaxHighlighter (View Mode)
|
||||
|
||||
**Implementation:**
|
||||
- Use Prism.js for tokenization
|
||||
- Render highlighted tokens as HTML
|
||||
- Add line numbers via CSS counter
|
||||
- Copy-to-clipboard button
|
||||
|
||||
**Language Detection:**
|
||||
```typescript
|
||||
const detectLanguage = (filename: string): string => {
|
||||
const ext = filename.split('.').pop()?.toLowerCase();
|
||||
const langMap: Record<string, string> = {
|
||||
'js': 'javascript',
|
||||
'ts': 'typescript',
|
||||
'tsx': 'tsx',
|
||||
'jsx': 'jsx',
|
||||
'py': 'python',
|
||||
'md': 'markdown',
|
||||
// ... more mappings
|
||||
};
|
||||
return langMap[ext || ''] || 'plaintext';
|
||||
};
|
||||
```
|
||||
|
||||
### CodeEditor (Edit Mode)
|
||||
|
||||
**Implementation:**
|
||||
- react-simple-code-editor component
|
||||
- Prism.js highlighting via textarea overlay
|
||||
- Line numbers synchronized with content
|
||||
- Tab key support (inserts spaces)
|
||||
|
||||
**Features:**
|
||||
- Syntax highlighting while typing
|
||||
- Auto-indentation
|
||||
- Line numbers
|
||||
- Selection highlighting
|
||||
|
||||
### CommitDialog
|
||||
|
||||
**Props:**
|
||||
```typescript
|
||||
interface CommitDialogProps {
|
||||
isOpen: boolean;
|
||||
filePath: string;
|
||||
originalContent: string;
|
||||
newContent: string;
|
||||
onCommit: (message: string) => void;
|
||||
onCancel: () => void;
|
||||
}
|
||||
```
|
||||
|
||||
**Features:**
|
||||
- Diff preview (simple line-by-line comparison)
|
||||
- Commit message input (required)
|
||||
- Author info (from user profile)
|
||||
- Cancel button (returns to edit mode)
|
||||
|
||||
## API Integration
|
||||
|
||||
### Load File (existing)
|
||||
```
|
||||
GET /projects/{id}/repositories/{id}/files/content
|
||||
Query: branch, path
|
||||
```
|
||||
|
||||
### Save File (existing)
|
||||
```
|
||||
POST /projects/{id}/repositories/{id}/files/content
|
||||
Body: {
|
||||
path: string,
|
||||
branch: string,
|
||||
content: string,
|
||||
commit_message: string,
|
||||
author_name: string,
|
||||
author_email: string
|
||||
}
|
||||
```
|
||||
|
||||
## Styling
|
||||
|
||||
### Editor Layout
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ [file.txt] [Edit] [Raw] │ ← Toolbar
|
||||
├─────────────────────────────────────────┤
|
||||
│ 1 │ function hello() { │ ← Line numbers + content
|
||||
│ 2 │ return "world"; │
|
||||
│ 3 │ } │
|
||||
└─────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Colors
|
||||
- Match existing app theme (CSS variables)
|
||||
- Syntax colors:
|
||||
- Keywords: var(--brand)
|
||||
- Strings: #10b981
|
||||
- Comments: var(--muted)
|
||||
- Numbers: #f59e0b
|
||||
- Functions: #3b82f6
|
||||
|
||||
### Responsive
|
||||
- Editor takes full width on mobile
|
||||
- Toolbar buttons shrink to icons
|
||||
- Line numbers hidden on very small screens
|
||||
|
||||
## Implementation Order
|
||||
|
||||
1. **Install dependencies** - react-simple-code-editor, prismjs
|
||||
2. **Create SyntaxHighlighter component** - Prism.js wrapper
|
||||
3. **Create CodeEditor component** - Edit mode with highlighting
|
||||
4. **Create CommitDialog component** - Commit flow
|
||||
5. **Create FileEditor component** - Main component orchestrating modes
|
||||
6. **Replace FileViewer in RepoWorkspace**
|
||||
7. **Add CSS styles** - Editor styling, syntax colors
|
||||
8. **Test** - Various file types, commit flow
|
||||
|
||||
## Error Handling
|
||||
|
||||
- **Binary files**: Show "Cannot edit binary files" message
|
||||
- **Load errors**: Show retry button
|
||||
- **Save errors**: Show error in commit dialog
|
||||
- **Large files**: Show warning, offer to download instead
|
||||
- **Network errors**: Show offline indicator
|
||||
|
||||
## Performance
|
||||
|
||||
- **Lazy load Prism** - Load language grammars on demand
|
||||
- **Debounce edits** - Don't re-highlight on every keystroke
|
||||
- **Virtual scrolling** - For files >1000 lines
|
||||
- **Memoization** - Cache highlighted output
|
||||
Reference in New Issue
Block a user