From ef063100f2c7fb5ab59f2a437c02159c75fde586 Mon Sep 17 00:00:00 2001 From: Jocadbz Date: Tue, 9 Jun 2026 20:15:18 -0300 Subject: [PATCH] Model clone button on model list Each model row now has a Clone button that duplicates the model with all its ports, flags, and images, appending '(copy)' to the name. Saves re-creating 48 ports when making a sibling switch model. --- internal/handlers/models.go | 36 ++++++++++++++++++++++++++++++++++++ main.go | 1 + templates/model_list.html | 3 +++ 3 files changed, 40 insertions(+) diff --git a/internal/handlers/models.go b/internal/handlers/models.go index 57ecdc1..463c6e2 100644 --- a/internal/handlers/models.go +++ b/internal/handlers/models.go @@ -163,6 +163,42 @@ func (h *Handlers) ModelDelete(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, "/models", http.StatusSeeOther) } +func (h *Handlers) ModelClone(w http.ResponseWriter, r *http.Request) { + idStr := r.PathValue("id") + id, _ := strconv.ParseInt(idStr, 10, 64) + + orig, err := h.Store.ModelGetByID(id) + if err != nil || orig == nil { + h.renderModelListError(w, "Model not found.") + return + } + + clone := &models.DeviceModel{ + Name: orig.Name + " (copy)", + Manufacturer: orig.Manufacturer, + IsRackMountable: orig.IsRackMountable, + HeightUnits: orig.HeightUnits, + FrontImage: orig.FrontImage, + BackImage: orig.BackImage, + IsPatchPanel: orig.IsPatchPanel, + IsWallSocket: orig.IsWallSocket, + IsPowerStrip: orig.IsPowerStrip, + Ports: orig.Ports, + } + + _, err = h.Store.ModelCreate(clone, "uploads") + if err != nil { + msg := err.Error() + if strings.Contains(strings.ToLower(msg), "unique") { + msg = "A model named '" + clone.Name + "' already exists, onii-chan." + } + h.renderModelListError(w, msg) + return + } + + http.Redirect(w, r, "/models", http.StatusSeeOther) +} + func (h *Handlers) renderModelListError(w http.ResponseWriter, msg string) { list, _ := h.Store.ModelGetAll() if list == nil { diff --git a/main.go b/main.go index 7883a71..34a60e0 100644 --- a/main.go +++ b/main.go @@ -45,6 +45,7 @@ func main() { mux.HandleFunc("GET /models/{id}/edit", h.ModelEditForm) mux.HandleFunc("POST /models/{id}/update", h.ModelUpdate) mux.HandleFunc("POST /models/{id}/delete", h.ModelDelete) + mux.HandleFunc("POST /models/{id}/clone", h.ModelClone) mux.HandleFunc("GET /connections/{portId}", h.ConnectionModal) mux.HandleFunc("GET /connections/connect-form", h.ConnectionConnectForm) mux.HandleFunc("POST /connections/create", h.ConnectionCreate) diff --git a/templates/model_list.html b/templates/model_list.html index 1fd3b52..0de9036 100644 --- a/templates/model_list.html +++ b/templates/model_list.html @@ -20,6 +20,9 @@ {{if .IsWallSocket}}yes{{end}} Edit +
+ +