fix: hide unavailable map draft actions
This commit is contained in:
parent
15324c25f2
commit
0c8f18e1e5
@ -121,6 +121,10 @@ export default function LocationMapBottomSheet({
|
|||||||
showEditorControls && hiddenAreaCount > 0 && filters.showZones && !hasNoVisibleAreas;
|
showEditorControls && hiddenAreaCount > 0 && filters.showZones && !hasNoVisibleAreas;
|
||||||
const saveDraftLabel = savingAction === "save" ? "Saving..." : "Save Draft";
|
const saveDraftLabel = savingAction === "save" ? "Saving..." : "Save Draft";
|
||||||
const publishLabel = savingAction === "publish" ? "Publishing..." : "Publish";
|
const publishLabel = savingAction === "publish" ? "Publishing..." : "Publish";
|
||||||
|
const canPublishDraft = Boolean(mapState?.draft_map || hasUnsavedChanges);
|
||||||
|
const showSaveDraftAction = Boolean(savingAction === "save" || hasUnsavedChanges);
|
||||||
|
const showPublishAction = Boolean(savingAction === "publish" || canPublishDraft);
|
||||||
|
const showPreviewDraftAction = Boolean((mapState?.draft_map || hasUnsavedChanges) && !showSelectedObjectForm);
|
||||||
const mappedItemSummary = assignedItemCount === visibleAssignedItemCount
|
const mappedItemSummary = assignedItemCount === visibleAssignedItemCount
|
||||||
? String(assignedItemCount)
|
? String(assignedItemCount)
|
||||||
: `${visibleAssignedItemCount} shown`;
|
: `${visibleAssignedItemCount} shown`;
|
||||||
@ -152,25 +156,29 @@ export default function LocationMapBottomSheet({
|
|||||||
showCompleted: true,
|
showCompleted: true,
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
const primaryDraftActions = showEditorControls ? (
|
const primaryDraftActions = showEditorControls && (showSaveDraftAction || showPublishAction) ? (
|
||||||
<div className="location-map-editor-actions location-map-primary-actions">
|
<div className="location-map-editor-actions location-map-primary-actions">
|
||||||
<button type="button" className="primary" onClick={onSaveDraft} disabled={saving || !hasUnsavedChanges}>
|
{showSaveDraftAction ? (
|
||||||
{saveDraftLabel}
|
<button type="button" className="primary" onClick={onSaveDraft} disabled={saving || !hasUnsavedChanges}>
|
||||||
</button>
|
{saveDraftLabel}
|
||||||
<button
|
</button>
|
||||||
type="button"
|
) : null}
|
||||||
className="primary"
|
{showPublishAction ? (
|
||||||
onClick={onPublish}
|
<button
|
||||||
disabled={saving || (!mapState?.draft_map && !hasUnsavedChanges)}
|
type="button"
|
||||||
>
|
className="primary"
|
||||||
{publishLabel}
|
onClick={onPublish}
|
||||||
</button>
|
disabled={saving || !canPublishDraft}
|
||||||
|
>
|
||||||
|
{publishLabel}
|
||||||
|
</button>
|
||||||
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
) : null;
|
) : null;
|
||||||
const secondaryDraftActions = showEditorControls ? (
|
const secondaryDraftActions = showEditorControls ? (
|
||||||
<div className="location-map-editor-actions location-map-secondary-actions">
|
<div className="location-map-editor-actions location-map-secondary-actions">
|
||||||
<button type="button" onClick={onAddObject} disabled={saving}>Add Area</button>
|
<button type="button" onClick={onAddObject} disabled={saving}>Add Area</button>
|
||||||
{!showSelectedObjectForm ? (
|
{showPreviewDraftAction ? (
|
||||||
<button type="button" onClick={onPreviewDraft} aria-label="Preview Draft" disabled={saving}>
|
<button type="button" onClick={onPreviewDraft} aria-label="Preview Draft" disabled={saving}>
|
||||||
Preview
|
Preview
|
||||||
</button>
|
</button>
|
||||||
@ -236,14 +244,16 @@ export default function LocationMapBottomSheet({
|
|||||||
<LocationMapLayerPanel filters={filters} setFilters={setFilters} />
|
<LocationMapLayerPanel filters={filters} setFilters={setFilters} />
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
{showSelectedObjectForm && primaryDraftActions ? (
|
{showSelectedObjectForm ? (
|
||||||
<div
|
primaryDraftActions ? (
|
||||||
className="location-map-editor-action-stack location-map-selected-primary-actions"
|
<div
|
||||||
role="group"
|
className="location-map-editor-action-stack location-map-selected-primary-actions"
|
||||||
aria-label="Map draft actions"
|
role="group"
|
||||||
>
|
aria-label="Map draft actions"
|
||||||
{primaryDraftActions}
|
>
|
||||||
</div>
|
{primaryDraftActions}
|
||||||
|
</div>
|
||||||
|
) : null
|
||||||
) : editorActions}
|
) : editorActions}
|
||||||
|
|
||||||
{showHiddenAreaAction ? (
|
{showHiddenAreaAction ? (
|
||||||
|
|||||||
@ -1229,6 +1229,53 @@ test("admin status follows the visible map when a saved draft exists", async ({
|
|||||||
await expect(page.locator(".location-map-object", { hasText: "Live Bakery" })).toBeVisible();
|
await expect(page.locator(".location-map-object", { hasText: "Live Bakery" })).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("admin edit mode hides unavailable draft actions until changes exist", async ({ page }) => {
|
||||||
|
await mockMapShell(page);
|
||||||
|
|
||||||
|
const mapState = publishedMapState([
|
||||||
|
{
|
||||||
|
id: 1201,
|
||||||
|
location_map_id: 901,
|
||||||
|
zone_id: 501,
|
||||||
|
zone_name: "Bakery",
|
||||||
|
type: "zone",
|
||||||
|
label: "Live Bakery",
|
||||||
|
x: 40,
|
||||||
|
y: 40,
|
||||||
|
width: 260,
|
||||||
|
height: 160,
|
||||||
|
rotation: 0,
|
||||||
|
locked: false,
|
||||||
|
visible: true,
|
||||||
|
sort_order: 1,
|
||||||
|
},
|
||||||
|
], true);
|
||||||
|
|
||||||
|
await page.route("**/households/1/locations/10/map", async (route) => {
|
||||||
|
await route.fulfill({
|
||||||
|
status: 200,
|
||||||
|
contentType: "application/json",
|
||||||
|
body: JSON.stringify(mapState),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
await page.goto("/stores/100/locations/10/map");
|
||||||
|
await page.getByRole("button", { name: "Edit Draft" }).click();
|
||||||
|
|
||||||
|
const secondaryActions = page.locator(".location-map-secondary-actions");
|
||||||
|
await expect(page.locator(".location-map-primary-actions")).toHaveCount(0);
|
||||||
|
await expect(secondaryActions.getByRole("button", { name: "Add Area" })).toBeVisible();
|
||||||
|
await expect(secondaryActions.getByRole("button", { name: "Preview Draft" })).toHaveCount(0);
|
||||||
|
await expect(page.getByRole("button", { name: "Save Draft" })).toHaveCount(0);
|
||||||
|
await expect(page.getByRole("button", { name: "Publish", exact: true })).toHaveCount(0);
|
||||||
|
|
||||||
|
await secondaryActions.getByRole("button", { name: "Add Area" }).click();
|
||||||
|
|
||||||
|
await expect(page.locator(".location-map-status")).toHaveText("Unsaved Draft");
|
||||||
|
await expect(page.getByRole("button", { name: "Save Draft" })).toBeEnabled();
|
||||||
|
await expect(page.getByRole("button", { name: "Publish", exact: true })).toBeEnabled();
|
||||||
|
});
|
||||||
|
|
||||||
test("mode switches close open map layers without resetting filters", async ({ page }) => {
|
test("mode switches close open map layers without resetting filters", async ({ page }) => {
|
||||||
await mockMapShell(page);
|
await mockMapShell(page);
|
||||||
|
|
||||||
@ -1561,7 +1608,7 @@ test("admin selecting an object does not mark a draft dirty until it changes", a
|
|||||||
|
|
||||||
await expect(page.getByRole("textbox", { name: "Label" })).toBeVisible();
|
await expect(page.getByRole("textbox", { name: "Label" })).toBeVisible();
|
||||||
await expect(page.locator(".location-map-status")).toHaveText("Draft");
|
await expect(page.locator(".location-map-status")).toHaveText("Draft");
|
||||||
await expect(page.getByRole("button", { name: "Save Draft" })).toBeDisabled();
|
await expect(page.getByRole("button", { name: "Save Draft" })).toHaveCount(0);
|
||||||
await expect(page.getByRole("button", { name: "Undo" })).toBeDisabled();
|
await expect(page.getByRole("button", { name: "Undo" })).toBeDisabled();
|
||||||
|
|
||||||
const objectBox = await bakeryObject.boundingBox();
|
const objectBox = await bakeryObject.boundingBox();
|
||||||
@ -2098,7 +2145,7 @@ test("admin save progress locks draft controls", async ({ page }) => {
|
|||||||
|
|
||||||
releaseSave();
|
releaseSave();
|
||||||
await expect(page.locator(".location-map-status")).toHaveText("Draft");
|
await expect(page.locator(".location-map-status")).toHaveText("Draft");
|
||||||
await expect(page.getByRole("button", { name: "Save Draft" })).toBeDisabled();
|
await expect(page.getByRole("button", { name: "Save Draft" })).toHaveCount(0);
|
||||||
await expect(page.getByRole("textbox", { name: "Label" })).toBeEnabled();
|
await expect(page.getByRole("textbox", { name: "Label" })).toBeEnabled();
|
||||||
await expect(page.getByRole("textbox", { name: "Label" })).toHaveValue("Saving Bakery");
|
await expect(page.getByRole("textbox", { name: "Label" })).toHaveValue("Saving Bakery");
|
||||||
await expect(page.getByRole("button", { name: "Map area Saving Bakery" })).toHaveAttribute("aria-pressed", "true");
|
await expect(page.getByRole("button", { name: "Map area Saving Bakery" })).toHaveAttribute("aria-pressed", "true");
|
||||||
@ -2611,7 +2658,7 @@ test("admin publish failure keeps successfully saved pending edits", async ({ pa
|
|||||||
])
|
])
|
||||||
);
|
);
|
||||||
await expect(page.locator(".location-map-status")).toHaveText("Draft");
|
await expect(page.locator(".location-map-status")).toHaveText("Draft");
|
||||||
await expect(page.getByRole("button", { name: "Save Draft" })).toBeDisabled();
|
await expect(page.getByRole("button", { name: "Save Draft" })).toHaveCount(0);
|
||||||
await expect(page.getByRole("button", { name: "Map area Saved Draft Bakery" })).toBeVisible();
|
await expect(page.getByRole("button", { name: "Map area Saved Draft Bakery" })).toBeVisible();
|
||||||
await expect(page.getByRole("button", { name: "Map area Live Bakery" })).toHaveCount(0);
|
await expect(page.getByRole("button", { name: "Map area Live Bakery" })).toHaveCount(0);
|
||||||
});
|
});
|
||||||
@ -3957,7 +4004,7 @@ test("mobile editor uses bottom sheet controls instead of desktop object toolbar
|
|||||||
await expect(historyActions.getByRole("button", { name: "Redo" })).toBeDisabled();
|
await expect(historyActions.getByRole("button", { name: "Redo" })).toBeDisabled();
|
||||||
const primaryActions = page.locator(".location-map-primary-actions");
|
const primaryActions = page.locator(".location-map-primary-actions");
|
||||||
const secondaryActions = page.locator(".location-map-secondary-actions");
|
const secondaryActions = page.locator(".location-map-secondary-actions");
|
||||||
await expect(primaryActions.getByRole("button", { name: "Save Draft" })).toBeVisible();
|
await expect(primaryActions.getByRole("button", { name: "Save Draft" })).toHaveCount(0);
|
||||||
await expect(primaryActions.getByRole("button", { name: "Publish" })).toBeVisible();
|
await expect(primaryActions.getByRole("button", { name: "Publish" })).toBeVisible();
|
||||||
await expect(secondaryActions.getByRole("button", { name: "Add Area" })).toBeVisible();
|
await expect(secondaryActions.getByRole("button", { name: "Add Area" })).toBeVisible();
|
||||||
await expect(secondaryActions.getByRole("button", { name: "Preview Draft" })).toBeVisible();
|
await expect(secondaryActions.getByRole("button", { name: "Preview Draft" })).toBeVisible();
|
||||||
@ -4017,7 +4064,7 @@ test("mobile editor uses bottom sheet controls instead of desktop object toolbar
|
|||||||
await expect(page.getByRole("button", { name: "Locked" })).toHaveAttribute("aria-pressed", "false");
|
await expect(page.getByRole("button", { name: "Locked" })).toHaveAttribute("aria-pressed", "false");
|
||||||
const selectedPrimaryActions = page.locator(".location-map-selected-primary-actions");
|
const selectedPrimaryActions = page.locator(".location-map-selected-primary-actions");
|
||||||
const selectedSecondaryActions = page.locator(".location-map-selected-secondary-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: "Save Draft" })).toHaveCount(0);
|
||||||
await expect(selectedPrimaryActions.getByRole("button", { name: "Publish" })).toBeVisible();
|
await expect(selectedPrimaryActions.getByRole("button", { name: "Publish" })).toBeVisible();
|
||||||
await expect(selectedSecondaryActions.getByRole("button", { name: "Add Area" })).toBeVisible();
|
await expect(selectedSecondaryActions.getByRole("button", { name: "Add Area" })).toBeVisible();
|
||||||
await expect(selectedSecondaryActions.getByRole("button", { name: "Preview Draft" })).toHaveCount(0);
|
await expect(selectedSecondaryActions.getByRole("button", { name: "Preview Draft" })).toHaveCount(0);
|
||||||
@ -4049,7 +4096,7 @@ test("mobile editor uses bottom sheet controls instead of desktop object toolbar
|
|||||||
await closeSelectedButton.click();
|
await closeSelectedButton.click();
|
||||||
await expect(page.getByRole("textbox", { name: "Label" })).toHaveCount(0);
|
await expect(page.getByRole("textbox", { name: "Label" })).toHaveCount(0);
|
||||||
await expect(page.locator(".location-map-sheet-header strong")).toHaveText("Edit Areas");
|
await expect(page.locator(".location-map-sheet-header strong")).toHaveText("Edit Areas");
|
||||||
await expect(page.getByRole("button", { name: "Save Draft" })).toBeDisabled();
|
await expect(page.getByRole("button", { name: "Save Draft" })).toHaveCount(0);
|
||||||
await page.getByRole("button", { name: "View", exact: true }).click();
|
await page.getByRole("button", { name: "View", exact: true }).click();
|
||||||
await expect(page.getByRole("textbox", { name: "Label" })).toHaveCount(0);
|
await expect(page.getByRole("textbox", { name: "Label" })).toHaveCount(0);
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user