drives initial plan
This commit is contained in:
1 parent
75dac1e459
commit
6ad0a461e4
5 files changed
+534
No files matched your search
@@ -0,0 +1,75 @@
|
||||
# Phase 4: Frontend Integration
|
||||
|
||||
## Objective
|
||||
Build the Vue3 components that consume the drive API for listing, uploading, and downloading files. Integration is minimal and relies on established Vue3 patterns.
|
||||
|
||||
## Concepts
|
||||
|
||||
### Minimal Frontend Design
|
||||
- **Drives View**: Fetches drives on mount. Clicking a drive triggers `list-files` via WebSocket.
|
||||
- **Upload Handling**: Standard drag-and-drop zone. On drop, initiates WS upload sequence. Updates local store immediately upon receiving `fileId`.
|
||||
- **Downloads**: Uses dedicated REST endpoint `/files/<id>` secured by QuartAuth bearer token. Constructs `<a href="/files/{id}" download>Download</a>` rather than streaming binary over WebSocket.
|
||||
|
||||
### Download Strategy
|
||||
Files require server-side resolution (ownership verification + path generation). Therefore:
|
||||
- The frontend never requests raw file bytes over WebSocket.
|
||||
- Instead, a direct anchor link to the secured REST endpoint handles downloads.
|
||||
- This avoids memory bloat on both client and server sides.
|
||||
|
||||
## Tasks
|
||||
|
||||
### 4.1 Drives View Component
|
||||
|
||||
Create a component (`src/views/DrivesView.vue`) that:
|
||||
- Fetches available drives on mount using the `list-drives` WebSocket action.
|
||||
- Renders a list/table of drives with clickable names/IDs.
|
||||
- On click, stores selected drive name and emits an event to show the files list.
|
||||
|
||||
### 4.2 Files List View
|
||||
|
||||
Create or update the files view component to:
|
||||
- Call `list-files` with the selected `{driveName}` when the view mounts or drive changes.
|
||||
- Render a simple table displaying `filename` and `size` for each row.
|
||||
- Provide a "Download" button/link per row that navigates to `/files/{id}`.
|
||||
|
||||
```vue
|
||||
<!-- Example file list item -->
|
||||
<a :href="`/files/${file.id}`" :download="file.name">
|
||||
{{ file.name }} ({{ file.size }})
|
||||
</a>
|
||||
```
|
||||
|
||||
### 4.3 Upload Zone
|
||||
|
||||
Implement a drag-and-drop zone (`components/FileUploadZone.vue`):
|
||||
- Listen for `drop` events on supported file types.
|
||||
- On drop, initiate the WebSocket upload sequence:
|
||||
|
||||
```javascript
|
||||
// 1. Send metadata header
|
||||
ws.send(JSON.stringify({
|
||||
action: "upload-file",
|
||||
nonce: crypto.randomUUID(),
|
||||
body: {
|
||||
driveName: currentDrive.value,
|
||||
fileName: droppedFile.name,
|
||||
mime: droppedFile.type
|
||||
}
|
||||
}));
|
||||
|
||||
// 2. Immediately follow with binary payload
|
||||
ws.send(droppedFile); // File object sent directly as binary
|
||||
|
||||
// 3. Wait for server response
|
||||
// On receiving {action: "file-updated", fileId: ..., nonce: ...}:
|
||||
// - Update local store to add the new file record
|
||||
// - Optionally show a success toast
|
||||
```
|
||||
|
||||
- Store uploaded files in local Vuex/Pinia store immediately after `fileId` receipt to reflect progress/success instantly without waiting for another poll cycle.
|
||||
|
||||
### 4.4 Store Updates
|
||||
|
||||
Extend your application store (Pinia/Vuex) to:
|
||||
- Hold state for `drives: []`, `currentDrive`, and `files: []`.
|
||||
- Handle incoming `file-uploaded` messages from WebSocket by inserting new records into the active drive's file array.
|
||||
Reference in new issue
Block a user