Support tool: Remove layer from item
Heck yeah, let's clean these fuckers up!
This commit is contained in:
parent
c94e94538e
commit
6821c2b734
3 changed files with 176 additions and 0 deletions
|
@ -15,6 +15,7 @@ GRANT SELECT ON openneo_impress.zone_translations TO impress2020;
|
|||
-- Public data tables: write
|
||||
GRANT UPDATE ON openneo_impress.items TO impress2020;
|
||||
GRANT UPDATE ON openneo_impress.swf_assets TO impress2020;
|
||||
GRANT DELETE ON openneo_impress.parents_swf_assets TO impress2020;
|
||||
|
||||
-- User data tables
|
||||
GRANT SELECT ON openneo_impress.item_outfit_relationships TO impress2020;
|
||||
|
|
|
@ -19,6 +19,7 @@ import {
|
|||
Radio,
|
||||
RadioGroup,
|
||||
Spinner,
|
||||
useDisclosure,
|
||||
useToast,
|
||||
} from "@chakra-ui/core";
|
||||
import { ChevronRightIcon, ExternalLinkIcon } from "@chakra-ui/icons";
|
||||
|
@ -209,10 +210,18 @@ function ItemLayerSupportModal({
|
|||
/>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<ItemLayerSupportModalRemoveButton
|
||||
item={item}
|
||||
itemLayer={itemLayer}
|
||||
outfitState={outfitState}
|
||||
onRemoveSuccess={onClose}
|
||||
/>
|
||||
<Box flex="1 0 0" />
|
||||
{mutationError && (
|
||||
<Box
|
||||
color="red.400"
|
||||
fontSize="sm"
|
||||
marginLeft="8"
|
||||
marginRight="2"
|
||||
textAlign="right"
|
||||
>
|
||||
|
@ -223,6 +232,7 @@ function ItemLayerSupportModal({
|
|||
isLoading={mutationLoading}
|
||||
colorScheme="green"
|
||||
onClick={mutate}
|
||||
flex="0 0 auto"
|
||||
>
|
||||
Save changes
|
||||
</Button>
|
||||
|
@ -344,4 +354,133 @@ function ItemLayerSupportPetCompatibilityFields({
|
|||
);
|
||||
}
|
||||
|
||||
function ItemLayerSupportModalRemoveButton({
|
||||
item,
|
||||
itemLayer,
|
||||
outfitState,
|
||||
onRemoveSuccess,
|
||||
}) {
|
||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||
const toast = useToast();
|
||||
const supportSecret = useSupportSecret();
|
||||
|
||||
const [mutate, { loading, error }] = useMutation(
|
||||
gql`
|
||||
mutation ItemLayerSupportRemoveButton(
|
||||
$layerId: ID!
|
||||
$itemId: ID!
|
||||
$outfitSpeciesId: ID!
|
||||
$outfitColorId: ID!
|
||||
$supportSecret: String!
|
||||
) {
|
||||
removeLayerFromItem(
|
||||
layerId: $layerId
|
||||
itemId: $itemId
|
||||
supportSecret: $supportSecret
|
||||
) {
|
||||
# This mutation returns the affected layer, and the affected item.
|
||||
# Fetch the updated appearance for the current outfit, which should
|
||||
# no longer include this layer. This means you should be able to see
|
||||
# your changes immediately!
|
||||
item {
|
||||
id
|
||||
appearanceOn(speciesId: $outfitSpeciesId, colorId: $outfitColorId) {
|
||||
...ItemAppearanceForOutfitPreview
|
||||
}
|
||||
}
|
||||
|
||||
# The layer's item should be null now, fetch to confirm and update!
|
||||
layer {
|
||||
id
|
||||
item {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
${itemAppearanceFragment}
|
||||
`,
|
||||
{
|
||||
variables: {
|
||||
layerId: itemLayer.id,
|
||||
itemId: item.id,
|
||||
outfitSpeciesId: outfitState.speciesId,
|
||||
outfitColorId: outfitState.colorId,
|
||||
supportSecret,
|
||||
},
|
||||
onCompleted: () => {
|
||||
onClose();
|
||||
onRemoveSuccess();
|
||||
toast({
|
||||
status: "success",
|
||||
title: `Removed layer ${itemLayer.id} from ${item.name}`,
|
||||
});
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button colorScheme="red" flex="0 0 auto" onClick={onOpen}>
|
||||
Remove
|
||||
</Button>
|
||||
<Modal isOpen={isOpen} onClose={onClose} size="xl" isCentered>
|
||||
<ModalOverlay>
|
||||
<ModalContent>
|
||||
<ModalCloseButton />
|
||||
<ModalHeader>
|
||||
Remove Layer {itemLayer.id} ({itemLayer.zone.label}) from{" "}
|
||||
{item.name}?
|
||||
</ModalHeader>
|
||||
<ModalBody>
|
||||
<Box as="p" marginBottom="4">
|
||||
This will permanently-ish remove Layer {itemLayer.id} (
|
||||
{itemLayer.zone.label}) from this item.
|
||||
</Box>
|
||||
<Box as="p" marginBottom="4">
|
||||
If you remove a correct layer by mistake, re-modeling should fix
|
||||
it, or Matchu can restore it if you write down the layer ID
|
||||
before proceeding!
|
||||
</Box>
|
||||
<Box as="p" marginBottom="4">
|
||||
Are you sure you want to remove Layer {itemLayer.id} from this
|
||||
item?
|
||||
</Box>
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button flex="0 0 auto" onClick={onClose}>
|
||||
Close
|
||||
</Button>
|
||||
<Box flex="1 0 0" />
|
||||
{error && (
|
||||
<Box
|
||||
color="red.400"
|
||||
fontSize="sm"
|
||||
marginLeft="8"
|
||||
marginRight="2"
|
||||
textAlign="right"
|
||||
>
|
||||
{error.message}
|
||||
</Box>
|
||||
)}
|
||||
<Button
|
||||
colorScheme="red"
|
||||
flex="0 0 auto"
|
||||
onClick={() =>
|
||||
mutate().catch((e) => {
|
||||
/* Discard errors here; we'll show them in the UI! */
|
||||
})
|
||||
}
|
||||
isLoading={loading}
|
||||
>
|
||||
Yes, remove permanently
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</ModalContent>
|
||||
</ModalOverlay>
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default ItemLayerSupportModal;
|
||||
|
|
|
@ -210,6 +210,11 @@ const typeDefs = gql`
|
|||
petOnNeopetsDotCom(petName: String!): Outfit
|
||||
}
|
||||
|
||||
type RemoveLayerFromItemMutationResult {
|
||||
layer: AppearanceLayer!
|
||||
item: Item!
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
setManualSpecialColor(
|
||||
itemId: ID!
|
||||
|
@ -228,6 +233,12 @@ const typeDefs = gql`
|
|||
bodyId: ID!
|
||||
supportSecret: String!
|
||||
): AppearanceLayer!
|
||||
|
||||
removeLayerFromItem(
|
||||
layerId: ID!
|
||||
itemId: ID!
|
||||
supportSecret: String!
|
||||
): RemoveLayerFromItemMutationResult!
|
||||
}
|
||||
`;
|
||||
|
||||
|
@ -672,6 +683,31 @@ const resolvers = {
|
|||
|
||||
return { id: layerId };
|
||||
},
|
||||
|
||||
removeLayerFromItem: async (
|
||||
_,
|
||||
{ layerId, itemId, supportSecret },
|
||||
{ db }
|
||||
) => {
|
||||
if (supportSecret !== process.env["SUPPORT_SECRET"]) {
|
||||
throw new Error(`Support secret is incorrect. Try setting up again?`);
|
||||
}
|
||||
|
||||
const [result] = await db.execute(
|
||||
`DELETE FROM parents_swf_assets ` +
|
||||
`WHERE swf_asset_id = ? AND parent_type = "Item" AND parent_id = ? ` +
|
||||
`LIMIT 1`,
|
||||
[layerId, itemId]
|
||||
);
|
||||
|
||||
if (result.affectedRows !== 1) {
|
||||
throw new Error(
|
||||
`Expected to affect 1 layer, but affected ${result.affectedRows}`
|
||||
);
|
||||
}
|
||||
|
||||
return { layer: { id: layerId }, item: { id: itemId } };
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue