file viewer: edit Markdown with optimistic-lock conflict detection
Nightly Build / build (push) Successful in 6m47s
Nightly Build / build (push) Successful in 6m47s
- GET /api/file returns ETag (mtime+size) + X-Writable on disk files; PUT /api/file accepts optional if_match -> 409 Conflict on stale version (last-write-wins preserved when omitted), echoes the new ETag - FileViewerBase: View | Edit tabs for .md when the caller can write; source textarea with Save/Cancel, live preview while editing - Watcher no longer clobbers the buffer mid-edit: while editing with unsaved changes it probes the server ETag and only raises a conflict when the remote actually moved on (own-save echo is ignored) - Conflict banner: Reload remote | Copy mine, then reload | Overwrite - i18n (en/it/fr) + CSS; docs/projects.md updated
This commit is contained in:
@@ -238,6 +238,13 @@ impl ApiError {
|
||||
pub fn payload_too_large(msg: impl Into<String>) -> Self {
|
||||
Self { status: StatusCode::PAYLOAD_TOO_LARGE, message: msg.into() }
|
||||
}
|
||||
|
||||
/// `409 Conflict` — used by the file editor's optimistic locking: the
|
||||
/// caller sent an `if_match` ETag that no longer matches the file on disk
|
||||
/// (someone else — another user, another tab, or an agent — wrote first).
|
||||
pub fn conflict(msg: impl Into<String>) -> Self {
|
||||
Self { status: StatusCode::CONFLICT, message: msg.into() }
|
||||
}
|
||||
}
|
||||
|
||||
/// Resolves the authenticated caller's per-user runtime context, or `401` when the
|
||||
|
||||
Reference in New Issue
Block a user