Added Editing of plates, items, configurations

This commit is contained in:
2026-05-26 17:15:36 +02:00
parent 66543b75d4
commit be58c5941d
6 changed files with 341 additions and 40 deletions
+63 -1
View File
@@ -22,9 +22,11 @@ func NewHandler() http.Handler {
mux.HandleFunc("GET /", root)
mux.HandleFunc("GET /plates", listPlates(plates))
mux.HandleFunc("POST /plates", savePlate(plates))
mux.HandleFunc("PUT /plates/{id}", updatePlate(plates))
mux.HandleFunc("DELETE /plates/{id}", deletePlate(plates))
mux.HandleFunc("GET /items", listItems(items))
mux.HandleFunc("POST /items", saveItem(items))
mux.HandleFunc("PUT /items/{id}", updateItem(items))
mux.HandleFunc("DELETE /items/{id}", deleteItem(items))
mux.HandleFunc("GET /items/{id}/svg", serveItemSVG(items))
registerConfigurationRoutes(mux, configs, plates, items)
@@ -34,7 +36,7 @@ func NewHandler() http.Handler {
func withCORS(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS")
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
if r.Method == http.MethodOptions {
w.WriteHeader(http.StatusNoContent)
@@ -111,6 +113,40 @@ func savePlate(s *store.PlateStore) http.HandlerFunc {
}
}
func updatePlate(s *store.PlateStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
id := r.PathValue("id")
if id == "" {
writeError(w, http.StatusBadRequest, errors.New("id required"))
return
}
var req savePlateRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
writeError(w, http.StatusBadRequest, err)
return
}
if req.WidthMM <= 0 || req.HeightMM <= 0 {
writeError(w, http.StatusBadRequest, errors.New("width_mm and height_mm must be positive"))
return
}
p := model.Plate{
Name: req.Name,
WidthMM: req.WidthMM,
HeightMM: req.HeightMM,
MarginTop: req.MarginTop,
MarginRight: req.MarginRight,
MarginBottom: req.MarginBottom,
MarginLeft: req.MarginLeft,
}
saved, err := s.Update(id, p)
if err != nil {
writeError(w, http.StatusNotFound, err)
return
}
writeJSON(w, http.StatusOK, saved)
}
}
func deletePlate(s *store.PlateStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
id := r.PathValue("id")
@@ -170,6 +206,32 @@ func saveItem(s *store.ItemStore) http.HandlerFunc {
}
}
func updateItem(s *store.ItemStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
id := r.PathValue("id")
if id == "" {
writeError(w, http.StatusBadRequest, errors.New("id required"))
return
}
var req saveItemRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
writeError(w, http.StatusBadRequest, err)
return
}
saved, err := s.Update(id, req.Name, model.ItemSpec{
SizeMM: req.SizeMM,
BleedMM: req.BleedMM,
MarginMM: req.MarginMM,
PaddingMM: req.PaddingMM,
})
if err != nil {
writeError(w, http.StatusBadRequest, err)
return
}
writeJSON(w, http.StatusOK, saved)
}
}
func deleteItem(s *store.ItemStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
id := r.PathValue("id")
+51
View File
@@ -15,6 +15,7 @@ import (
func registerConfigurationRoutes(mux *http.ServeMux, configs *store.ConfigurationStore, plates *store.PlateStore, items *store.ItemStore) {
mux.HandleFunc("GET /configurations", listConfigurations(configs, plates, items))
mux.HandleFunc("POST /configurations", saveConfiguration(configs, plates, items))
mux.HandleFunc("PUT /configurations/{id}", updateConfiguration(configs, plates, items))
mux.HandleFunc("DELETE /configurations/{id}", deleteConfiguration(configs))
mux.HandleFunc("GET /configurations/{id}/preview", previewConfiguration(configs, plates, items))
mux.HandleFunc("GET /layout/preview", layoutPreview(plates, items))
@@ -99,6 +100,56 @@ func saveConfiguration(configs *store.ConfigurationStore, plates *store.PlateSto
}
}
func updateConfiguration(configs *store.ConfigurationStore, plates *store.PlateStore, items *store.ItemStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
id := r.PathValue("id")
if id == "" {
writeError(w, http.StatusBadRequest, errors.New("id required"))
return
}
var req saveConfigurationRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
writeError(w, http.StatusBadRequest, err)
return
}
if req.PlateID == "" || req.ItemID == "" {
writeError(w, http.StatusBadRequest, errors.New("plate_id and item_id are required"))
return
}
if _, err := findPlate(plates, req.PlateID); err != nil {
writeError(w, http.StatusBadRequest, err)
return
}
if _, err := items.Get(req.ItemID); err != nil {
writeError(w, http.StatusBadRequest, err)
return
}
if req.SpacingMM < 0 {
writeError(w, http.StatusBadRequest, errors.New("spacing_mm must be non-negative"))
return
}
c := model.Configuration{
Name: req.Name,
PlateID: req.PlateID,
ItemID: req.ItemID,
SpacingMM: req.SpacingMM,
}
saved, err := configs.Update(id, c)
if err != nil {
writeError(w, http.StatusNotFound, err)
return
}
resp := configurationResponseFor(saved, plates, items)
if resp.PreviewError != "" {
writeError(w, http.StatusInternalServerError, errors.New(resp.PreviewError))
return
}
writeJSON(w, http.StatusOK, resp)
}
}
func deleteConfiguration(configs *store.ConfigurationStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
id := r.PathValue("id")