diff --git a/web/index.html b/web/index.html index 268c135..edcae38 100644 --- a/web/index.html +++ b/web/index.html @@ -4,6 +4,7 @@ +
+ 🌱 +
+That page doesn't exist — the link may be wrong or the page moved.
+ + Back to gardens + ++ Remove all {n} {n === 1 ? 'plant' : 'plants'} from{' '} + {objectName}? They're marked removed but kept in history. +
++ {children} +
+Loading garden…
if (full.isError) return ( @@ -124,16 +224,12 @@ export function GardenEditorPage() { heightCm: g.heightCm, unitPref: g.unitPref, } - // Role-driven gating. Ownership is the authoritative ownerId==me check (so a - // missing my_role can never lock an owner out); edit access is owner or an - // editor share. - const isOwner = me.data != null && g.ownerId === me.data.id - const canEdit = isOwner || g.myRole === 'editor' const selectedObject = objects.find((o) => o.id === selectedId) ?? null const focusedObject = focusedObjectId != null ? objects.find((o) => o.id === focusedObjectId) ?? null : null // Committed selected plop; PlopInspector applies live drag geometry itself. const selectedPlop = plantings.find((p) => p.id === selectedPlantingId) ?? null + const focusedPlops = focusedObjectId != null ? plantings.filter((p) => p.objectId === focusedObjectId) : [] function onPickPlant(plantId: number) { if (!canEdit) return // defense in depth: viewers can't reach the picker anyway @@ -170,9 +266,7 @@ export function GardenEditorPage() { - - {focusedObject.name || kindDef(focusedObject.kind)?.label || 'Object'} - + {objectDisplayName(focusedObject)} {canEdit && (!focusedObject.plantable ? ( Not plantable @@ -185,9 +279,26 @@ export function GardenEditorPage() { + Add plant ))} + {canEdit && focusedObject.plantable && focusedPlops.length > 0 && ( + + )} )}