buxfix-2
All checks were successful
release-tag / release-image (push) Successful in 1m26s

This commit is contained in:
2025-09-27 17:52:10 +02:00
parent 43f1d01a8a
commit 92e222f648
2 changed files with 56 additions and 17 deletions

View File

@@ -187,7 +187,7 @@ func Register(mux *http.ServeMux, d Deps) {
})
})
// Actions (HTMX POSTs)
// CREATE
mux.HandleFunc("/admin/items/create", func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
@@ -196,12 +196,13 @@ func Register(mux *http.ServeMux, d Deps) {
name := strings.TrimSpace(r.FormValue("name"))
if name != "" {
_, _ = d.Store.Create(r.Context(), name)
_ = d.Mesh.SyncNow(r.Context()) // prompt push (best effort)
_ = d.Mesh.SyncNow(r.Context())
}
// Nach Aktion Items partial zurückgeben (HTMX swap)
http.Redirect(w, r, "/admin", http.StatusSeeOther)
// statt Redirect:
renderItemsPartial(w, r, d)
})
// RENAME
mux.HandleFunc("/admin/items/rename", func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
@@ -213,21 +214,22 @@ func Register(mux *http.ServeMux, d Deps) {
_, _ = d.Store.Rename(r.Context(), filesvc.ID(id), newName)
_ = d.Mesh.SyncNow(r.Context())
}
http.Redirect(w, r, "/admin", http.StatusSeeOther) //hier test nicht mehr /admin/items
renderItemsPartial(w, r, d)
})
// DELETE
mux.HandleFunc("/admin/items/delete", func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
return
}
if id64, err := strconv.ParseInt(r.FormValue("id"), 10, 64); err == nil {
id64, err := strconv.ParseInt(r.FormValue("id"), 10, 64)
if err == nil {
_, _ = d.Store.Delete(r.Context(), filesvc.ID(id64))
_ = d.Blob.Delete(r.Context(), id64) // <— Blob löschen
_ = d.Blob.Delete(r.Context(), id64) // Blob wirklich löschen
_ = d.Mesh.SyncNow(r.Context())
}
http.Redirect(w, r, "/admin", http.StatusSeeOther)
renderItemsPartial(w, r, d)
})
mux.HandleFunc("/admin/mesh/syncnow", func(w http.ResponseWriter, r *http.Request) {
@@ -258,3 +260,40 @@ func BasicAuth(user, pass string, next http.Handler) http.Handler {
next.ServeHTTP(w, r)
})
}
// rebuild & render items partial for HTMX swaps
func renderItemsPartial(w http.ResponseWriter, r *http.Request, d Deps) {
type row struct {
ID int64
Name string
UpdatedAt int64
HasBlob bool
Size int64
}
nextQ := strings.TrimSpace(r.URL.Query().Get("next"))
var nextID filesvc.ID
if nextQ != "" {
if n, err := strconv.ParseInt(nextQ, 10, 64); err == nil {
nextID = filesvc.ID(n)
}
}
items, nextOut, _ := d.Store.List(r.Context(), nextID, 100)
rows := make([]row, 0, len(items))
for _, it := range items {
meta, ok, _ := d.Blob.Stat(r.Context(), int64(it.ID))
rows = append(rows, row{
ID: int64(it.ID),
Name: it.Name,
UpdatedAt: it.UpdatedAt,
HasBlob: ok,
Size: meta.Size,
})
}
w.Header().Set("Content-Type", "text/html; charset=utf-8")
_ = tplItems.Execute(w, map[string]any{
"Items": rows,
"Next": nextOut,
})
}

View File

@@ -1,6 +1,6 @@
<div class="row">
<div style="flex: 1 1 360px">
<form hx-post="/admin/items/create" hx-target="#items" hx-get="/admin/items" hx-swap="outerHTML">
<form hx-post="/admin/items/create" hx-target="#items" hx-swap="outerHTML">
<label>Neue leere Datei (nur Metadaten)</label>
<div style="display:flex; gap:8px; margin-top:6px">
<input type="text" name="name" placeholder="z.B. notes.txt" required>
@@ -42,17 +42,17 @@
{{ end }}
</td>
<td>
<form style="display:inline-flex; gap:6px"
hx-post="/admin/items/rename"
hx-target="#items" hx-get="/admin/items" hx-swap="outerHTML">
<form style="display:inline-flex; gap:6px"
hx-post="/admin/items/rename"
hx-target="#items" hx-swap="outerHTML">
<input type="hidden" name="id" value="{{ .ID }}">
<input type="text" name="name" placeholder="Neuer Name">
<button class="btn" type="submit">Rename</button>
</form>
<form style="display:inline"
hx-post="/admin/items/delete"
hx-target="#items" hx-get="/admin/items" hx-swap="outerHTML"
onsubmit="return confirm('Wirklich löschen (inkl. Blob)?');">
<form style="display:inline"
hx-post="/admin/items/delete"
hx-target="#items" hx-swap="outerHTML"
onsubmit="return confirm('Wirklich löschen (inkl. Blob)?');">
<input type="hidden" name="id" value="{{ .ID }}">
<button class="btn" type="submit">Delete</button>
</form>