diff --git a/data/furniture.json b/data/furniture.json index b509381..70289cc 100644 --- a/data/furniture.json +++ b/data/furniture.json @@ -110,7 +110,7 @@ { "id": "library-kallax-d4", "label": "D4", - "zone": "cubes", + "zone": "campaign", "width_in": 13.25, "height_in": 13.25, "depth_in": 15.4 diff --git a/src/bggpipe/templates/pages/shelves.html b/src/bggpipe/templates/pages/shelves.html index 869ecd6..4bccac5 100644 --- a/src/bggpipe/templates/pages/shelves.html +++ b/src/bggpipe/templates/pages/shelves.html @@ -35,6 +35,7 @@ +

@@ -43,6 +44,9 @@
+ @@ -93,6 +97,7 @@ function openingCell(o) { ? `${o.games}${o.unmeasured ? ` · ${o.unmeasured} unmeasured` : ""}` : "—"; return ``} `).join("") : `

Nothing here yet.

`; + document.getElementById("sheetdesc").textContent = o.description || ""; + document.getElementById("sheetdesc").hidden = !o.description; const f = document.getElementById("openingform"); f.elements.label.value = o.label; f.elements.zone.value = o.zone || ""; + f.elements.description.value = o.description || ""; f.elements.width_in.value = o.width_in ?? ""; f.elements.height_in.value = o.height_in ?? ""; f.elements.depth_in.value = o.depth_in ?? ""; @@ -347,6 +355,7 @@ document.getElementById("openingform").addEventListener("submit", e => { } post("/api/furniture/edit-opening", { id: OPEN, label: f.label.value, zone: f.zone.value, + description: f.description.value, width_in: parseFloat(f.width_in.value) || null, height_in: parseFloat(f.height_in.value) || null, depth_in: parseFloat(f.depth_in.value) || null, diff --git a/src/bggpipe/webreview.py b/src/bggpipe/webreview.py index 694dc46..d1b588d 100644 --- a/src/bggpipe/webreview.py +++ b/src/bggpipe/webreview.py @@ -247,6 +247,7 @@ class OpeningEditBody(BaseModel): id: str label: str | None = None zone: str | None = None + description: str | None = None # free text for humans; zone is the keyword # all three or none: a partial size cannot exist (see the endpoint) width_in: float | None = None height_in: float | None = None @@ -1290,6 +1291,8 @@ def create_app( real["label"] = body.label.strip() or real["label"] if body.zone is not None: real["zone"] = body.zone.strip() + if body.description is not None: + real["description"] = body.description.strip() # dims are all-or-none: three values sets, three blanks makes # it virtual, anything else is a 400 — a partial edit must # never silently strip an opening of its size limits diff --git a/tests/test_shelves.py b/tests/test_shelves.py index 44038d7..604b112 100644 --- a/tests/test_shelves.py +++ b/tests/test_shelves.py @@ -800,3 +800,23 @@ def test_reunification_outranks_tightest_fit_and_full_shelves_stop_lying(tmp_pat exp = next(g for g in state["unshelved"] if g["name"].endswith("Tower")) first = exp["suggestions"][0] assert first["id"] == ids["A1"] and first["reunites"] is True + + +def test_opening_descriptions_round_trip(tmp_path): + web, cfg = _web(tmp_path, {}) + web.post("/api/furniture/add-unit", json={"name": "Den"}) + web.post("/api/furniture/add-openings", json={"unit": "Den", "label": "top"}) + oid = web.get("/api/shelves").json()["units"][0]["openings"][0]["id"] + web.post( + "/api/furniture/edit-opening", + json={ + "id": oid, + "description": "tall bookcase by the window", + }, + ) + opening = web.get("/api/shelves").json()["units"][0]["openings"][0] + assert opening["description"] == "tall bookcase by the window" + import json as _json + + saved = _json.loads(cfg.furniture_path.read_text())["units"][0]["openings"][0] + assert saved["description"] == "tall bookcase by the window"