Add upload progress bar with SSE extraction status
ISO uploads now show a progress bar during file transfer (via XHR upload.onprogress) and real-time extraction status (via SSE events through the existing Hub). Falls back to plain form POST if JS is disabled. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+38
-8
@@ -167,34 +167,64 @@ func (u *UI) NewImageForm(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func (u *UI) UploadImage(w http.ResponseWriter, r *http.Request) {
|
||||
isXHR := r.Header.Get("X-Requested-With") == "XMLHttpRequest"
|
||||
|
||||
if err := r.ParseMultipartForm(0); err != nil {
|
||||
renderHTML(w, imageUploadForm("Invalid form submission"))
|
||||
if isXHR {
|
||||
writeJSON(w, http.StatusBadRequest, map[string]any{"ok": false, "error": "Invalid form submission"})
|
||||
} else {
|
||||
renderHTML(w, imageUploadForm("Invalid form submission"))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
name := strings.TrimSpace(r.FormValue("name"))
|
||||
version := strings.TrimSpace(r.FormValue("version"))
|
||||
kind := strings.TrimSpace(r.FormValue("kind"))
|
||||
uploadID := strings.TrimSpace(r.FormValue("upload_id"))
|
||||
|
||||
file, _, err := r.FormFile("iso")
|
||||
if err != nil {
|
||||
renderHTML(w, imageUploadForm("ISO file is required"))
|
||||
if isXHR {
|
||||
writeJSON(w, http.StatusBadRequest, map[string]any{"ok": false, "error": "ISO file is required"})
|
||||
} else {
|
||||
renderHTML(w, imageUploadForm("ISO file is required"))
|
||||
}
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
var progressFn image.ProgressFunc
|
||||
if uploadID != "" {
|
||||
progressFn = func(stage, detail string) {
|
||||
u.Hub.Publish(events.Event{
|
||||
Name: "image.upload_progress",
|
||||
Payload: fmt.Sprintf(`{"upload_id":%q,"stage":%q,"detail":%q}`, uploadID, stage, detail),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
_, err = u.ImageSvc.Upload(r.Context(), image.UploadParams{
|
||||
Name: name,
|
||||
Kind: kind,
|
||||
Version: version,
|
||||
ISO: file,
|
||||
Name: name,
|
||||
Kind: kind,
|
||||
Version: version,
|
||||
ISO: file,
|
||||
OnProgress: progressFn,
|
||||
})
|
||||
if err != nil {
|
||||
renderHTML(w, imageUploadForm(err.Error()))
|
||||
if isXHR {
|
||||
writeJSON(w, http.StatusInternalServerError, map[string]any{"ok": false, "error": err.Error()})
|
||||
} else {
|
||||
renderHTML(w, imageUploadForm(err.Error()))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
http.Redirect(w, r, "/images", http.StatusSeeOther)
|
||||
if isXHR {
|
||||
writeJSON(w, http.StatusOK, map[string]any{"ok": true})
|
||||
} else {
|
||||
http.Redirect(w, r, "/images", http.StatusSeeOther)
|
||||
}
|
||||
}
|
||||
|
||||
func (u *UI) SetDefaultImage(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
Reference in New Issue
Block a user