Add zone restrict to item page, too
I knew I was forgetting something! lol
This commit is contained in:
parent
7421f41e58
commit
7183f0725c
3 changed files with 91 additions and 31 deletions
|
@ -7,7 +7,7 @@ describe("ItemZonesInfo", () => {
|
||||||
cy.visit("/items/37375");
|
cy.visit("/items/37375");
|
||||||
cy.get("[data-test-id='item-zones-info']", networkTimeout).should(
|
cy.get("[data-test-id='item-zones-info']", networkTimeout).should(
|
||||||
"have.text",
|
"have.text",
|
||||||
"Zone: Background"
|
"Occupies: Background" + "Restricts: N/A"
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ describe("ItemZonesInfo", () => {
|
||||||
cy.visit("/items/34985");
|
cy.visit("/items/34985");
|
||||||
cy.get("[data-test-id='item-zones-info']", networkTimeout).should(
|
cy.get("[data-test-id='item-zones-info']", networkTimeout).should(
|
||||||
"have.text",
|
"have.text",
|
||||||
"Zone: Hat"
|
"Occupies: Hat" + "Restricts: N/A"
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -23,7 +23,9 @@ describe("ItemZonesInfo", () => {
|
||||||
cy.visit("/items/43397");
|
cy.visit("/items/43397");
|
||||||
cy.get("[data-test-id='item-zones-info']", networkTimeout).should(
|
cy.get("[data-test-id='item-zones-info']", networkTimeout).should(
|
||||||
"have.text",
|
"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();
|
cy.contains("(52 species)").focus();
|
||||||
|
@ -39,7 +41,15 @@ describe("ItemZonesInfo", () => {
|
||||||
cy.visit("/items/70564");
|
cy.visit("/items/70564");
|
||||||
cy.get("[data-test-id='item-zones-info']", networkTimeout).should(
|
cy.get("[data-test-id='item-zones-info']", networkTimeout).should(
|
||||||
"have.text",
|
"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"
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -574,6 +574,10 @@ function ItemPageOutfitPreview({ itemId }) {
|
||||||
item(id: $itemId) {
|
item(id: $itemId) {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
|
restrictedZones {
|
||||||
|
id
|
||||||
|
label @client
|
||||||
|
}
|
||||||
compatibleBodiesAndTheirZones {
|
compatibleBodiesAndTheirZones {
|
||||||
body {
|
body {
|
||||||
id
|
id
|
||||||
|
@ -751,7 +755,7 @@ function ItemPageOutfitPreview({ itemId }) {
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
</AspectRatio>
|
</AspectRatio>
|
||||||
<Box gridArea="speciesColorPicker" display="flex" alignItems="center">
|
<Flex gridArea="speciesColorPicker" alignSelf="start" align="center">
|
||||||
<Box
|
<Box
|
||||||
// This box grows at the same rate as the box on the right, so the
|
// This box grows at the same rate as the box on the right, so the
|
||||||
// middle box will be centered, if there's space!
|
// middle box will be centered, if there's space!
|
||||||
|
@ -803,7 +807,7 @@ function ItemPageOutfitPreview({ itemId }) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Flex>
|
||||||
<Box
|
<Box
|
||||||
gridArea="speciesFacesPicker"
|
gridArea="speciesFacesPicker"
|
||||||
paddingTop="2"
|
paddingTop="2"
|
||||||
|
@ -833,9 +837,10 @@ function ItemPageOutfitPreview({ itemId }) {
|
||||||
{compatibleBodiesAndTheirZones.length > 0 && (
|
{compatibleBodiesAndTheirZones.length > 0 && (
|
||||||
<ItemZonesInfo
|
<ItemZonesInfo
|
||||||
compatibleBodiesAndTheirZones={compatibleBodiesAndTheirZones}
|
compatibleBodiesAndTheirZones={compatibleBodiesAndTheirZones}
|
||||||
|
restrictedZones={data?.item?.restrictedZones || []}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<Box width="4" />
|
<Box width="6" />
|
||||||
<Flex
|
<Flex
|
||||||
// Avoid layout shift while loading
|
// Avoid layout shift while loading
|
||||||
minWidth="54px"
|
minWidth="54px"
|
||||||
|
@ -1276,7 +1281,7 @@ function SpeciesFaceOption({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function ItemZonesInfo({ compatibleBodiesAndTheirZones }) {
|
function ItemZonesInfo({ compatibleBodiesAndTheirZones, restrictedZones }) {
|
||||||
// Reorganize the body-and-zones data, into zone-and-bodies data. Also, we're
|
// Reorganize the body-and-zones data, into zone-and-bodies data. Also, we're
|
||||||
// merging zones with the same label, because that's how user-facing zone UI
|
// merging zones with the same label, because that's how user-facing zone UI
|
||||||
// generally works!
|
// generally works!
|
||||||
|
@ -1300,6 +1305,10 @@ function ItemZonesInfo({ compatibleBodiesAndTheirZones }) {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const restrictedZoneLabels = [
|
||||||
|
...new Set(restrictedZones.map((z) => z.label)),
|
||||||
|
].sort();
|
||||||
|
|
||||||
// We only show body info if there's more than one group of bodies to talk
|
// 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
|
// 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.
|
// preview available in the list has the zones listed here.
|
||||||
|
@ -1311,9 +1320,18 @@ function ItemZonesInfo({ compatibleBodiesAndTheirZones }) {
|
||||||
const showBodyInfo = bodyGroups.size > 1;
|
const showBodyInfo = bodyGroups.size > 1;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box fontSize="sm" textAlign="center" data-test-id="item-zones-info">
|
<Flex
|
||||||
|
fontSize="sm"
|
||||||
|
textAlign="center"
|
||||||
|
// If the text gets too long, wrap Restricts onto another line, and center
|
||||||
|
// them relative to each other.
|
||||||
|
wrap="wrap"
|
||||||
|
justify="center"
|
||||||
|
data-test-id="item-zones-info"
|
||||||
|
>
|
||||||
|
<Box flex="0 0 auto" maxWidth="100%">
|
||||||
<Box as="header" fontWeight="bold" display="inline">
|
<Box as="header" fontWeight="bold" display="inline">
|
||||||
{sortedZonesAndTheirBodies.length > 1 ? "Zones" : "Zone"}:
|
Occupies:
|
||||||
</Box>{" "}
|
</Box>{" "}
|
||||||
<Box as="ul" listStyleType="none" display="inline">
|
<Box as="ul" listStyleType="none" display="inline">
|
||||||
{sortedZonesAndTheirBodies.map(({ zoneLabel, bodies }) => (
|
{sortedZonesAndTheirBodies.map(({ zoneLabel, bodies }) => (
|
||||||
|
@ -1332,6 +1350,31 @@ function ItemZonesInfo({ compatibleBodiesAndTheirZones }) {
|
||||||
))}
|
))}
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
<Box width="4" flex="0 0 auto" />
|
||||||
|
<Box flex="0 0 auto" maxWidth="100%">
|
||||||
|
<Box as="header" fontWeight="bold" display="inline">
|
||||||
|
Restricts:
|
||||||
|
</Box>{" "}
|
||||||
|
{restrictedZoneLabels.length > 0 ? (
|
||||||
|
<Box as="ul" listStyleType="none" display="inline">
|
||||||
|
{restrictedZoneLabels.map((zoneLabel) => (
|
||||||
|
<Box
|
||||||
|
key={zoneLabel}
|
||||||
|
as="li"
|
||||||
|
display="inline"
|
||||||
|
_notLast={{ _after: { content: '", "' } }}
|
||||||
|
>
|
||||||
|
{zoneLabel}
|
||||||
|
</Box>
|
||||||
|
))}
|
||||||
|
</Box>
|
||||||
|
) : (
|
||||||
|
<Box as="span" fontStyle="italic" opacity="0.8">
|
||||||
|
N/A
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
</Flex>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1385,9 +1428,6 @@ function buildSortKeyForZoneLabelsAndTheirBodies({ zoneLabel, bodies }) {
|
||||||
// Hacky but solid!
|
// Hacky but solid!
|
||||||
const inverseBodyCount = (9999 - bodies.length).toString().padStart(4, "0");
|
const inverseBodyCount = (9999 - bodies.length).toString().padStart(4, "0");
|
||||||
|
|
||||||
console.log(
|
|
||||||
`${representsAllBodies ? "A" : "Z"}-${inverseBodyCount}-${zoneLabel}`
|
|
||||||
);
|
|
||||||
return `${representsAllBodies ? "A" : "Z"}-${inverseBodyCount}-${zoneLabel}`;
|
return `${representsAllBodies ? "A" : "Z"}-${inverseBodyCount}-${zoneLabel}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -83,6 +83,10 @@ const typeDefs = gql`
|
||||||
# info about the item.
|
# info about the item.
|
||||||
allOccupiedZones: [Zone!]! @cacheControl(maxAge: ${oneHour})
|
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
|
# 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!
|
# the special representsAllPets body, e.g. if this is just a Background!
|
||||||
# Deprecated: Impress 2020 now uses compatibleBodiesAndTheirZones.
|
# Deprecated: Impress 2020 now uses compatibleBodiesAndTheirZones.
|
||||||
|
@ -397,6 +401,12 @@ const resolvers = {
|
||||||
const zones = zoneIds.map((id) => ({ id }));
|
const zones = zoneIds.map((id) => ({ id }));
|
||||||
return zones;
|
return zones;
|
||||||
},
|
},
|
||||||
|
restrictedZones: async ({ id }, _, { itemLoader }) => {
|
||||||
|
const item = await itemLoader.load(id);
|
||||||
|
return getRestrictedZoneIds(item.zonesRestrict).map((zoneId) => ({
|
||||||
|
id: zoneId,
|
||||||
|
}));
|
||||||
|
},
|
||||||
compatibleBodies: async ({ id }, _, { db }) => {
|
compatibleBodies: async ({ id }, _, { db }) => {
|
||||||
const [rows, __] = await db.query(
|
const [rows, __] = await db.query(
|
||||||
`
|
`
|
||||||
|
|
Loading…
Reference in a new issue