The space view lists boxes, not their contents

Eric, looking at the Red Dragon Inn shelf: a game stored inside
another box doesn't need its own row in the space view — it's clutter.
Right: the shelf holds physical boxes; what's inside them is the
container's business, already listed on its game page.

The opening sheet now renders only physical residents, collapsing
contents into a "holds N inside" hint on the container's row (hover
for the names). Eric's real B2 goes from 20 rows to 5 — Speechless,
Superfight, the Character Trove ("holds 15 inside"), Smorgasbox, Throw
Throw Avocado. The exported wall page mirrors it with "(+N inside)"
after the container's link. The payload keeps every rider (with a new
via field naming its box) so the sheet's add-a-game search still
excludes games already present through containment, and riders still
never appear in the unshelved backlog.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016jXZFSTZQKzAC8fqpWSz9g
This commit is contained in:
Eric Wagoner
2026-08-09 16:21:58 -04:00
co-authored by Claude Fable 5
parent 0ed2145f80
commit 7ed21de82a
7 changed files with 480 additions and 20 deletions
+47 -9
View File
@@ -1045,9 +1045,10 @@ def test_acknowledged_overhang(tmp_path):
report = opening_report(tower, crowd, acknowledged={k for k, _ in crowd})
assert not report["overfull"]
assert report["wedged"]
assert len(report["wedged"]) + len(
[lane for lane in report["lanes"].values() if lane]
) == 9
assert (
len(report["wedged"]) + len([lane for lane in report["lanes"].values() if lane])
== 9
)
def test_import_acknowledge_column(tmp_path):
@@ -1103,7 +1104,7 @@ def test_import_acknowledge_column(tmp_path):
def test_here_anyway_wedges_the_unplaceable(tmp_path):
""""It's here anyway": acknowledging a box the lanes can't take
""" "It's here anyway": acknowledging a box the lanes can't take
marks it wedged — really there, outside the capacity math — and the
opening stops warning about it."""
web, cfg = _web(
@@ -1143,9 +1144,7 @@ def test_here_anyway_wedges_the_unplaceable(tmp_path):
squeezed = next(g for g in a1["resident_games"] if g["name"] == "Squeezed Out")
assert squeezed["laneless"] is True and squeezed["wedged"] is False
assert a1["overfull"] is True
state = web.post(
"/api/acknowledge", json={"key": "2", "acknowledged": True}
).json()
state = web.post("/api/acknowledge", json={"key": "2", "acknowledged": True}).json()
a1 = state["units"][0]["openings"][0]
squeezed = next(g for g in a1["resident_games"] if g["name"] == "Squeezed Out")
assert squeezed["wedged"] is True and squeezed["laneless"] is False
@@ -1187,8 +1186,7 @@ def test_measurements_overlay(tmp_path):
assert g["measured"] is True and g["lane"] == "flat"
# partial numbers are refused, never guessed
assert (
web.post("/api/measure", json={"key": "1", "width_in": 10.0}).status_code
== 400
web.post("/api/measure", json={"key": "1", "width_in": 10.0}).status_code == 400
)
# clearing (all empty) restores honest ignorance
state = web.post("/api/measure", json={"key": "1"}).json()
@@ -1252,3 +1250,43 @@ def test_away_whereabouts(tmp_path):
}
web.post("/api/away", json={"key": "2", "where": ""})
assert "2" not in load_locations(cfg)
def test_contained_games_collapse_in_sheet_payload(tmp_path):
"""The space view lists physical boxes; contents carry `via` so the
UI can collapse them into the container's "holds N" hint — and they
still count as located (never re-offered for shelving)."""
web, cfg = _web(
tmp_path,
{
"1": _entry("Red Dragon Inn", 12.0, 12.0, 4.0, bgg_id="4991"),
"2": _entry("RDI: Allies", 8.0, 8.0, 1.0, stored_in="4991"),
},
)
save_furniture(
cfg,
[
{
"name": "Wall",
"openings": [
{
"id": "big",
"label": "A1",
"zone": "",
"width_in": 26.5,
"height_in": 13.25,
"depth_in": 15.4,
}
],
}
],
)
save_locations(cfg, {"1": {"opening_id": "big", "note": ""}})
state = web.get("/api/shelves").json()
rows = state["units"][0]["openings"][0]["resident_games"]
box = next(g for g in rows if g["name"] == "Red Dragon Inn")
allies = next(g for g in rows if g["name"] == "RDI: Allies")
assert box["via"] == "" and allies["via"] == "1"
assert allies["inherited"] is True
# riding along is being located: never in the unshelved backlog
assert all(u["key"] != "2" for u in state["unshelved"])