diff --git a/frontend/src/components/maps/LocationMapBottomSheet.jsx b/frontend/src/components/maps/LocationMapBottomSheet.jsx index 8b5982d..1ecdbe0 100644 --- a/frontend/src/components/maps/LocationMapBottomSheet.jsx +++ b/frontend/src/components/maps/LocationMapBottomSheet.jsx @@ -92,27 +92,33 @@ export default function LocationMapBottomSheet({ showCompleted: true, })); }; + const primaryDraftActions = showEditorControls ? ( +
+ + +
+ ) : null; + const secondaryDraftActions = showEditorControls ? ( +
+ + + + +
+ ) : null; const editorActions = showEditorControls ? (
-
- - -
-
- - - - -
+ {primaryDraftActions} + {secondaryDraftActions}
) : canManage && mapState?.published_map ? (
@@ -176,7 +182,15 @@ export default function LocationMapBottomSheet({
) : null} - {showSelectedObjectForm ? null : editorActions} + {showSelectedObjectForm && primaryDraftActions ? ( +
+ {primaryDraftActions} +
+ ) : editorActions} {showEditorControls ? (
@@ -332,7 +346,15 @@ export default function LocationMapBottomSheet({

)} - {showSelectedObjectForm ? editorActions : null} + {showSelectedObjectForm && secondaryDraftActions ? ( +
+ {secondaryDraftActions} +
+ ) : null} {filters.showUnmapped && visibleUnmappedItems.length > 0 ? (
diff --git a/frontend/src/styles/pages/LocationMapManager.css b/frontend/src/styles/pages/LocationMapManager.css index bec0a69..e4d8ec0 100644 --- a/frontend/src/styles/pages/LocationMapManager.css +++ b/frontend/src/styles/pages/LocationMapManager.css @@ -492,6 +492,15 @@ margin-bottom: 0.75rem; } +.location-map-selected-primary-actions { + margin-bottom: 0.55rem; +} + +.location-map-selected-secondary-actions { + margin-top: 0.55rem; + margin-bottom: 0; +} + .location-map-primary-actions button { flex: 1 1 140px; } diff --git a/frontend/tests/location-map-manager.spec.ts b/frontend/tests/location-map-manager.spec.ts index 83fe247..c0ff775 100644 --- a/frontend/tests/location-map-manager.spec.ts +++ b/frontend/tests/location-map-manager.spec.ts @@ -1371,8 +1371,23 @@ test("mobile editor uses bottom sheet controls instead of desktop object toolbar await page.getByRole("button", { name: "Objects" }).click(); await expect(page.getByRole("button", { name: "Objects" })).toHaveClass(/active/); await page.locator(".location-map-object", { hasText: "Bakery" }).locator("rect").first().click(); - await expect(page.getByRole("textbox", { name: "Label" })).toBeVisible(); + const labelInput = page.getByRole("textbox", { name: "Label" }); + await expect(labelInput).toBeVisible(); await expect(page.locator(".location-map-sheet-header strong")).toHaveText("Bakery"); + const selectedPrimaryActions = page.locator(".location-map-selected-primary-actions"); + const selectedSecondaryActions = page.locator(".location-map-selected-secondary-actions"); + await expect(selectedPrimaryActions.getByRole("button", { name: "Save Draft" })).toBeVisible(); + await expect(selectedPrimaryActions.getByRole("button", { name: "Publish" })).toBeVisible(); + await expect(selectedSecondaryActions.getByRole("button", { name: "Add Area" })).toBeVisible(); + await expect(selectedSecondaryActions.getByRole("button", { name: "Preview Draft" })).toBeVisible(); + const selectedPrimaryBox = await selectedPrimaryActions.boundingBox(); + const labelBox = await labelInput.boundingBox(); + expect(selectedPrimaryBox).not.toBeNull(); + expect(labelBox).not.toBeNull(); + if (!selectedPrimaryBox || !labelBox) { + throw new Error("Selected object draft actions were not measurable"); + } + expect(selectedPrimaryBox.y).toBeLessThan(labelBox.y); await page.getByRole("button", { name: "Done" }).click(); await expect(page.getByRole("textbox", { name: "Label" })).toHaveCount(0); await expect(page.locator(".location-map-sheet-header strong")).toHaveText("Edit Objects");