Add in-app document preview
Adds an inline preview for stored document files alongside download.
- API Server: GET /api/documents/{id}/file honours ?inline=1, serving an
inline Content-Disposition so the browser renders the file instead of
forcing a download (default stays attachment).
- Web App: BFF forwards the inline flag; documentPreviewUrl() helper; an eye
icon; and a preview modal (Teleported to body) that picks a viewer from the
file extension — images -> <img>, PDFs/text -> <iframe>, else a
download-instead fallback. Closes on backdrop click or Escape.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
52f84ad6cf
commit
28291e27d7
@@ -518,6 +518,8 @@ func (s *Server) handleDeleteDocument(w http.ResponseWriter, r *http.Request) {
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// GET /api/documents/{id}/file — stream the stored blob for a document.
|
||||
// By default the response is an attachment (download); `?inline=1` serves it
|
||||
// with an inline disposition so the browser renders it in-place (preview).
|
||||
func (s *Server) handleDownloadDocument(w http.ResponseWriter, r *http.Request) {
|
||||
who := caller(r)
|
||||
id := r.PathValue("id")
|
||||
@@ -554,7 +556,11 @@ func (s *Server) handleDownloadDocument(w http.ResponseWriter, r *http.Request)
|
||||
if cl := resp.Header.Get("Content-Length"); cl != "" {
|
||||
w.Header().Set("Content-Length", cl)
|
||||
}
|
||||
w.Header().Set("Content-Disposition", "attachment; filename=\""+sanitizeFilename(rec.File)+"\"")
|
||||
disposition := "attachment"
|
||||
if r.URL.Query().Get("inline") == "1" {
|
||||
disposition = "inline"
|
||||
}
|
||||
w.Header().Set("Content-Disposition", disposition+"; filename=\""+sanitizeFilename(rec.File)+"\"")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, _ = io.Copy(w, resp.Body)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user