diff --git a/cypress/integration/ItemPage/ItemZonesInfo.spec.js b/cypress/integration/ItemPage/ItemZonesInfo.spec.js index 97e5dbf..03a1bce 100644 --- a/cypress/integration/ItemPage/ItemZonesInfo.spec.js +++ b/cypress/integration/ItemPage/ItemZonesInfo.spec.js @@ -7,7 +7,7 @@ describe("ItemZonesInfo", () => { cy.visit("/items/37375"); cy.get("[data-test-id='item-zones-info']", networkTimeout).should( "have.text", - "Zone: Background" + "Occupies: Background" + "Restricts: N/A" ); }); @@ -15,7 +15,7 @@ describe("ItemZonesInfo", () => { cy.visit("/items/34985"); cy.get("[data-test-id='item-zones-info']", networkTimeout).should( "have.text", - "Zone: Hat" + "Occupies: Hat" + "Restricts: N/A" ); }); @@ -23,7 +23,9 @@ describe("ItemZonesInfo", () => { cy.visit("/items/43397"); cy.get("[data-test-id='item-zones-info']", networkTimeout).should( "have.text", - "Zones: Right-hand Item (52 species)" + "Left-hand Item (2 species)" + "Occupies: Right-hand Item (52 species)" + + "Left-hand Item (2 species)" + + "Restricts: N/A" ); cy.contains("(52 species)").focus(); @@ -39,7 +41,15 @@ describe("ItemZonesInfo", () => { cy.visit("/items/70564"); cy.get("[data-test-id='item-zones-info']", networkTimeout).should( "have.text", - "Zone: Shirt/Dress" + "Occupies: Shirt/Dress" + "Restricts: N/A" + ); + }); + + it("shows zone restrict data for a simple hood", () => { + cy.visit("/items/38911"); + cy.get("[data-test-id='item-zones-info']", networkTimeout).should( + "have.text", + "Occupies: Hat" + "Restricts: Hair Front" + "Head Transient Biology" ); }); }); diff --git a/src/app/ItemPage.js b/src/app/ItemPage.js index 07aca39..2e01718 100644 --- a/src/app/ItemPage.js +++ b/src/app/ItemPage.js @@ -574,6 +574,10 @@ function ItemPageOutfitPreview({ itemId }) { item(id: $itemId) { id name + restrictedZones { + id + label @client + } compatibleBodiesAndTheirZones { body { id @@ -751,7 +755,7 @@ function ItemPageOutfitPreview({ itemId }) { )} - + - + 0 && ( )} - + z.label)), + ].sort(); + // We only show body info if there's more than one group of bodies to talk // about. If they all have the same zones, it's clear from context that any // preview available in the list has the zones listed here. @@ -1311,27 +1320,61 @@ function ItemZonesInfo({ compatibleBodiesAndTheirZones }) { const showBodyInfo = bodyGroups.size > 1; return ( - - - {sortedZonesAndTheirBodies.length > 1 ? "Zones" : "Zone"}: - {" "} - - {sortedZonesAndTheirBodies.map(({ zoneLabel, bodies }) => ( - - - - ))} + + + + Occupies: + {" "} + + {sortedZonesAndTheirBodies.map(({ zoneLabel, bodies }) => ( + + + + ))} + - + + + + Restricts: + {" "} + {restrictedZoneLabels.length > 0 ? ( + + {restrictedZoneLabels.map((zoneLabel) => ( + + {zoneLabel} + + ))} + + ) : ( + + N/A + + )} + + ); } @@ -1385,9 +1428,6 @@ function buildSortKeyForZoneLabelsAndTheirBodies({ zoneLabel, bodies }) { // Hacky but solid! const inverseBodyCount = (9999 - bodies.length).toString().padStart(4, "0"); - console.log( - `${representsAllBodies ? "A" : "Z"}-${inverseBodyCount}-${zoneLabel}` - ); return `${representsAllBodies ? "A" : "Z"}-${inverseBodyCount}-${zoneLabel}`; } diff --git a/src/server/types/Item.js b/src/server/types/Item.js index 635a793..7c0b41b 100644 --- a/src/server/types/Item.js +++ b/src/server/types/Item.js @@ -83,6 +83,10 @@ const typeDefs = gql` # info about the item. allOccupiedZones: [Zone!]! @cacheControl(maxAge: ${oneHour}) + # The zones this item restricts. Turns out, even though we offer this on + # ItemAppearance for consistency, this is static across all appearances. + restrictedZones: [Zone!]! @cacheControl(maxAge: ${oneHour}, staleWhileRevalidate: ${oneWeek}) + # All bodies that this item is compatible with. Note that this might return # the special representsAllPets body, e.g. if this is just a Background! # Deprecated: Impress 2020 now uses compatibleBodiesAndTheirZones. @@ -397,6 +401,12 @@ const resolvers = { const zones = zoneIds.map((id) => ({ id })); return zones; }, + restrictedZones: async ({ id }, _, { itemLoader }) => { + const item = await itemLoader.load(id); + return getRestrictedZoneIds(item.zonesRestrict).map((zoneId) => ({ + id: zoneId, + })); + }, compatibleBodies: async ({ id }, _, { db }) => { const [rows, __] = await db.query( `