fix: compact map sheet empty states
This commit is contained in:
parent
913d458fd6
commit
b96cb65d6f
@ -108,6 +108,20 @@ export function LocationMapOverview({ ariaLabel, rows }) {
|
||||
);
|
||||
}
|
||||
|
||||
function InlineStateAction({ label, value, actionLabel, actionText = "Show", onAction }) {
|
||||
return (
|
||||
<div className="location-map-inline-state">
|
||||
<span>{label}</span>
|
||||
<strong>{value}</strong>
|
||||
{onAction ? (
|
||||
<button type="button" onClick={onAction} aria-label={actionLabel}>
|
||||
{actionText}
|
||||
</button>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function SelectedMapObjectForm({
|
||||
selectedObject,
|
||||
zones = [],
|
||||
@ -180,16 +194,16 @@ export function SelectedZoneItemsPanel({
|
||||
return (
|
||||
<div className="location-map-zone-items">
|
||||
<div className="location-map-zone-empty">
|
||||
<p className="location-map-muted">
|
||||
{hasHiddenSelectedItems
|
||||
? "Items are assigned here, but hidden by layer filters."
|
||||
: "No items assigned to this zone yet."}
|
||||
</p>
|
||||
{hasHiddenSelectedItems ? (
|
||||
<button type="button" onClick={onShowSelectedZoneItems}>
|
||||
Show Zone Items
|
||||
</button>
|
||||
) : null}
|
||||
<InlineStateAction
|
||||
label="Hidden"
|
||||
value={hiddenSelectedItemCount}
|
||||
actionLabel="Show Zone Items"
|
||||
onAction={onShowSelectedZoneItems}
|
||||
/>
|
||||
) : (
|
||||
<InlineStateAction label="Items" value="0" />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@ -204,12 +218,13 @@ export function SelectedZoneItemsPanel({
|
||||
/>
|
||||
{hasHiddenSelectedItems ? (
|
||||
<div className="location-map-zone-hidden-note">
|
||||
<p className="location-map-muted">
|
||||
{hiddenSelectedItemCount} more hidden by layer filters.
|
||||
</p>
|
||||
<button type="button" onClick={onShowSelectedZoneItems}>
|
||||
Show All Zone Items
|
||||
</button>
|
||||
<InlineStateAction
|
||||
label="Hidden"
|
||||
value={hiddenSelectedItemCount}
|
||||
actionLabel="Show All Zone Items"
|
||||
actionText="Show All"
|
||||
onAction={onShowSelectedZoneItems}
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
@ -228,12 +243,12 @@ export function UnmappedItemsPanel({
|
||||
<div className="location-map-unmapped-list">
|
||||
<strong>Unmapped Items</strong>
|
||||
<div className="location-map-zone-empty">
|
||||
<p className="location-map-muted">
|
||||
Unmapped items are hidden by layer filters.
|
||||
</p>
|
||||
<button type="button" onClick={onShowUnmappedItems}>
|
||||
Show Unmapped Items
|
||||
</button>
|
||||
<InlineStateAction
|
||||
label="Hidden"
|
||||
value={hiddenUnmappedItemCount}
|
||||
actionLabel="Show Unmapped Items"
|
||||
onAction={onShowUnmappedItems}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@ -253,12 +268,13 @@ export function UnmappedItemsPanel({
|
||||
/>
|
||||
{hiddenUnmappedItemCount > 0 ? (
|
||||
<div className="location-map-zone-hidden-note">
|
||||
<p className="location-map-muted">
|
||||
{hiddenUnmappedItemCount} more hidden by layer filters.
|
||||
</p>
|
||||
<button type="button" onClick={onShowUnmappedItems}>
|
||||
Show All Unmapped Items
|
||||
</button>
|
||||
<InlineStateAction
|
||||
label="Hidden"
|
||||
value={hiddenUnmappedItemCount}
|
||||
actionLabel="Show All Unmapped Items"
|
||||
actionText="Show All"
|
||||
onAction={onShowUnmappedItems}
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
@ -717,37 +717,45 @@
|
||||
|
||||
.location-map-zone-empty {
|
||||
display: grid;
|
||||
gap: 0.55rem;
|
||||
}
|
||||
|
||||
.location-map-zone-empty button {
|
||||
min-height: 40px;
|
||||
width: fit-content;
|
||||
padding: 0.45rem 0.7rem;
|
||||
border: 1px solid var(--color-border-light);
|
||||
border-radius: 8px;
|
||||
background: #15283b;
|
||||
color: #f8fafc;
|
||||
font-weight: 800;
|
||||
cursor: pointer;
|
||||
gap: 0.35rem;
|
||||
}
|
||||
|
||||
.location-map-zone-hidden-note {
|
||||
display: grid;
|
||||
gap: 0.45rem;
|
||||
margin-top: 0.55rem;
|
||||
}
|
||||
|
||||
.location-map-zone-hidden-note p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.location-map-zone-hidden-note button {
|
||||
min-height: 40px;
|
||||
width: fit-content;
|
||||
padding: 0.45rem 0.7rem;
|
||||
.location-map-inline-state {
|
||||
min-height: 42px;
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) auto auto;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
padding: 0.25rem 0.35rem 0.25rem 0.55rem;
|
||||
border: 1px solid var(--color-border-light);
|
||||
border-radius: 8px;
|
||||
background: rgba(15, 23, 34, 0.56);
|
||||
color: #f8fafc;
|
||||
}
|
||||
|
||||
.location-map-inline-state span {
|
||||
min-width: 0;
|
||||
color: #9fb3c8;
|
||||
font-size: 0.82rem;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.location-map-inline-state strong {
|
||||
color: #f8fafc;
|
||||
font-weight: 900;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.location-map-inline-state button {
|
||||
min-height: 34px;
|
||||
min-width: 64px;
|
||||
padding: 0.35rem 0.6rem;
|
||||
border: 1px solid var(--color-border-light);
|
||||
border-radius: 999px;
|
||||
background: #15283b;
|
||||
color: #f8fafc;
|
||||
font-weight: 800;
|
||||
|
||||
@ -2914,7 +2914,10 @@ test("viewer can buy selected zone items from the map", async ({ page }) => {
|
||||
await expect(page.locator(".confirm-buy-modal")).toHaveCount(0);
|
||||
await expect(page.locator(".location-map-sheet-count")).toHaveText("0 shown");
|
||||
await expect(bakeryArea.locator(".location-map-count")).toHaveText("0 shown");
|
||||
await expect(page.getByText("Items are assigned here, but hidden by layer filters.")).toBeVisible();
|
||||
const hiddenZoneState = page.locator(".location-map-zone-items .location-map-inline-state", { hasText: "Hidden" });
|
||||
await expect(hiddenZoneState).toContainText("2");
|
||||
await expect(hiddenZoneState.getByRole("button", { name: "Show Zone Items" })).toHaveText("Show");
|
||||
await expect(page.getByText("Items are assigned here, but hidden by layer filters.")).toHaveCount(0);
|
||||
|
||||
await page.getByRole("button", { name: "Layers" }).click();
|
||||
await page.getByRole("button", { name: "Bought" }).click();
|
||||
@ -3196,7 +3199,7 @@ test("viewer shows completed zone items without rebuy actions", async ({ page })
|
||||
await expect(newlyBoughtRow.locator("small")).toHaveText("Bought");
|
||||
});
|
||||
|
||||
test("viewer explains when unmapped items are hidden by filters", async ({ page }) => {
|
||||
test("viewer shows compact state when unmapped items are hidden by filters", async ({ page }) => {
|
||||
await mockMapShell(page);
|
||||
|
||||
const mapState = {
|
||||
@ -3228,13 +3231,15 @@ test("viewer explains when unmapped items are hidden by filters", async ({ page
|
||||
await page.getByRole("button", { name: "Unmapped" }).click();
|
||||
|
||||
await expect(page.getByText("other batteries")).toHaveCount(0);
|
||||
await expect(page.getByText("Unmapped items are hidden by layer filters.")).toBeVisible();
|
||||
await expect(page.getByRole("button", { name: "Show Unmapped Items" })).toBeVisible();
|
||||
const hiddenUnmappedState = page.locator(".location-map-unmapped-list .location-map-inline-state", { hasText: "Hidden" });
|
||||
await expect(hiddenUnmappedState).toContainText("1");
|
||||
await expect(hiddenUnmappedState.getByRole("button", { name: "Show Unmapped Items" })).toHaveText("Show");
|
||||
await expect(page.getByText("Unmapped items are hidden by layer filters.")).toHaveCount(0);
|
||||
|
||||
await page.getByRole("button", { name: "Show Unmapped Items" }).click();
|
||||
|
||||
await expect(page.getByText("other batteries")).toBeVisible();
|
||||
await expect(page.getByText("Unmapped items are hidden by layer filters.")).toHaveCount(0);
|
||||
await expect(hiddenUnmappedState).toHaveCount(0);
|
||||
await expect(page.getByRole("button", { name: "Layers, 3 changed" })).toBeVisible();
|
||||
});
|
||||
|
||||
@ -3280,16 +3285,18 @@ test("viewer marks partial unmapped counts when filters hide some items", async
|
||||
|
||||
await expect(page.getByText("visible batteries")).toBeVisible();
|
||||
await expect(page.getByText("hidden batteries")).toHaveCount(0);
|
||||
await expect(page.getByText("1 more hidden by layer filters.")).toBeVisible();
|
||||
await expect(page.getByRole("button", { name: "Show All Unmapped Items" })).toBeVisible();
|
||||
const hiddenUnmappedState = page.locator(".location-map-unmapped-list .location-map-inline-state", { hasText: "Hidden" });
|
||||
await expect(hiddenUnmappedState).toContainText("1");
|
||||
await expect(hiddenUnmappedState.getByRole("button", { name: "Show All Unmapped Items" })).toHaveText("Show All");
|
||||
await expect(page.getByText("1 more hidden by layer filters.")).toHaveCount(0);
|
||||
|
||||
await page.getByRole("button", { name: "Show All Unmapped Items" }).click();
|
||||
|
||||
await expect(page.getByText("hidden batteries")).toBeVisible();
|
||||
await expect(page.getByText("1 more hidden by layer filters.")).toHaveCount(0);
|
||||
await expect(hiddenUnmappedState).toHaveCount(0);
|
||||
});
|
||||
|
||||
test("viewer explains when selected zone items are hidden by filters", async ({ page }) => {
|
||||
test("viewer shows compact state when selected zone items are hidden by filters", async ({ page }) => {
|
||||
await mockMapShell(page);
|
||||
|
||||
const mapState = publishedMapState([
|
||||
@ -3327,7 +3334,10 @@ test("viewer explains when selected zone items are hidden by filters", async ({
|
||||
|
||||
await frozenArea.locator("rect").first().click();
|
||||
await expect(page.locator(".location-map-sheet-count")).toHaveText("0 shown");
|
||||
await expect(page.getByText("Items are assigned here, but hidden by layer filters.")).toBeVisible();
|
||||
const hiddenZoneState = page.locator(".location-map-zone-items .location-map-inline-state", { hasText: "Hidden" });
|
||||
await expect(hiddenZoneState).toContainText("1");
|
||||
await expect(hiddenZoneState.getByRole("button", { name: "Show Zone Items" })).toHaveText("Show");
|
||||
await expect(page.getByText("Items are assigned here, but hidden by layer filters.")).toHaveCount(0);
|
||||
await expect(page.getByText("frozen salmon")).toHaveCount(0);
|
||||
|
||||
await page.getByRole("button", { name: "Show Zone Items" }).click();
|
||||
@ -3398,8 +3408,10 @@ test("viewer marks partial zone counts when filters hide some items", async ({ p
|
||||
await expect(page.locator(".location-map-sheet-count")).toHaveText("1 shown");
|
||||
await expect(page.getByText("visible bread")).toBeVisible();
|
||||
await expect(page.getByText("hidden baguette")).toHaveCount(0);
|
||||
await expect(page.getByText("1 more hidden by layer filters.")).toBeVisible();
|
||||
await expect(page.getByRole("button", { name: "Show All Zone Items" })).toBeVisible();
|
||||
const hiddenZoneState = page.locator(".location-map-zone-items .location-map-inline-state", { hasText: "Hidden" });
|
||||
await expect(hiddenZoneState).toContainText("1");
|
||||
await expect(hiddenZoneState.getByRole("button", { name: "Show All Zone Items" })).toHaveText("Show All");
|
||||
await expect(page.getByText("1 more hidden by layer filters.")).toHaveCount(0);
|
||||
|
||||
await page.getByRole("button", { name: "Show All Zone Items" }).click();
|
||||
|
||||
@ -3472,7 +3484,10 @@ test("viewer handles empty and many-item zone panels without default pins", asyn
|
||||
|
||||
await page.locator('[data-object-key="1562"]').locator("rect").first().click();
|
||||
await expect(page.locator(".location-map-sheet-count")).toHaveText("0 items");
|
||||
await expect(page.getByText("No items assigned to this zone yet.")).toBeVisible();
|
||||
const emptyZoneState = page.locator(".location-map-zone-items .location-map-inline-state", { hasText: "Items" });
|
||||
await expect(emptyZoneState).toContainText("0");
|
||||
await expect(emptyZoneState.getByRole("button")).toHaveCount(0);
|
||||
await expect(page.getByText("No items assigned to this zone yet.")).toHaveCount(0);
|
||||
|
||||
await page.locator('[data-object-key="1561"]').locator("rect").first().click();
|
||||
await expect(page.locator(".location-map-sheet-count")).toHaveText("14 items");
|
||||
|
||||
Loading…
Reference in New Issue
Block a user