-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ff08ac5
commit b1d60c5
Showing
5 changed files
with
256 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
import FormLabel from "@mui/material/FormLabel"; | ||
import Stack from "@mui/material/Stack"; | ||
import { apolloClient } from "@/app/ApolloProvider/apolloClient"; | ||
import { ActionsButtonGroup } from "@/components/Buttons/ActionsButtonGroup"; | ||
import { QUERIES } from "@/graphql/queries"; | ||
import { MOCK_WORK_ORDERS, MOCK_INVOICES, MOCK_CONTACTS } from "@/tests/mockItems"; | ||
import { DevToolContainer } from "./DevToolContainer"; | ||
|
||
export const CacheManagerDevTool = ({ handleCloseModal }: { handleCloseModal: () => void }) => { | ||
// Shared onClick handler for the ActionsButtonGroup options: | ||
const handleManageCache = async ({ target, action }: HandleManageCacheParams) => { | ||
if (action === "Write") { | ||
if (target !== "ALL") { | ||
apolloClient.writeQuery(MOCK_CACHE_CONFIGS[target].WRITE_QUERY_ARGS as any); | ||
} else { | ||
// Write all queries to cache | ||
apolloClient.writeQuery(MOCK_CACHE_CONFIGS.WorkOrders.WRITE_QUERY_ARGS); | ||
apolloClient.writeQuery(MOCK_CACHE_CONFIGS.Invoices.WRITE_QUERY_ARGS); | ||
apolloClient.writeQuery(MOCK_CACHE_CONFIGS.Contacts.WRITE_QUERY_ARGS); | ||
} | ||
} else if (action === "Clear") { | ||
// id defaults to ROOT_QUERY; return DELETE sentinel object to remove the "field" | ||
apolloClient.cache.modify({ | ||
broadcast: true, | ||
fields: | ||
target !== "ALL" | ||
? { [MOCK_CACHE_CONFIGS[target].ROOT_QUERY_FIELD_NAME]: (_, { DELETE }) => DELETE } | ||
: { | ||
[MOCK_CACHE_CONFIGS.WorkOrders.ROOT_QUERY_FIELD_NAME]: (_, { DELETE }) => DELETE, | ||
[MOCK_CACHE_CONFIGS.Invoices.ROOT_QUERY_FIELD_NAME]: (_, { DELETE }) => DELETE, | ||
[MOCK_CACHE_CONFIGS.Contacts.ROOT_QUERY_FIELD_NAME]: (_, { DELETE }) => DELETE, | ||
}, | ||
}); | ||
// Run garbage collection to remove the single-item cache refs | ||
apolloClient.cache.gc(); | ||
await apolloClient.refetchQueries({ include: "all" }); | ||
} | ||
handleCloseModal(); | ||
}; | ||
|
||
return ( | ||
<DevToolContainer | ||
title="Manage Mocked Items in Apollo Cache" | ||
subtitle="Note: Mocked items are not persisted on the back-end." | ||
> | ||
{HANDLE_MANAGE_CACHE_ACTIONS.map((action) => ( | ||
<Stack key={action} style={{ width: "10rem" }}> | ||
<FormLabel style={{ display: "block" }}>{action} Mocks</FormLabel> | ||
<ActionsButtonGroup | ||
options={HANDLE_MANAGE_CACHE_TARGETS.map((target) => ({ | ||
label: target, | ||
handleClick: () => handleManageCache({ action, target }), | ||
isPrimary: target === "ALL", | ||
}))} | ||
/> | ||
</Stack> | ||
))} | ||
</DevToolContainer> | ||
); | ||
}; | ||
|
||
const MOCK_CACHE_CONFIGS = { | ||
WorkOrders: { | ||
ROOT_QUERY_FIELD_NAME: "myWorkOrders", | ||
WRITE_QUERY_ARGS: { | ||
query: QUERIES.MY_WORK_ORDERS, | ||
data: MOCK_WORK_ORDERS, | ||
}, | ||
}, | ||
Invoices: { | ||
ROOT_QUERY_FIELD_NAME: "myInvoices", | ||
WRITE_QUERY_ARGS: { | ||
query: QUERIES.MY_INVOICES_WITH_WORKORDER_DATA, | ||
data: MOCK_INVOICES, | ||
}, | ||
}, | ||
Contacts: { | ||
ROOT_QUERY_FIELD_NAME: "myContacts", | ||
WRITE_QUERY_ARGS: { | ||
query: QUERIES.MY_CONTACTS, | ||
data: { myContacts: Object.values(MOCK_CONTACTS) }, | ||
}, | ||
}, | ||
} as const satisfies Record< | ||
string, | ||
{ | ||
ROOT_QUERY_FIELD_NAME: string; | ||
WRITE_QUERY_ARGS: { | ||
query: object; | ||
data: Record<string, unknown>; | ||
}; | ||
} | ||
>; | ||
|
||
const HANDLE_MANAGE_CACHE_ACTIONS = ["Write", "Clear"] as const; | ||
|
||
const HANDLE_MANAGE_CACHE_TARGETS = [ | ||
"ALL", | ||
...(Object.keys(MOCK_CACHE_CONFIGS) as Array<keyof typeof MOCK_CACHE_CONFIGS>), | ||
] as const; | ||
|
||
export type CacheManagerOperationType = (typeof HANDLE_MANAGE_CACHE_ACTIONS)[number]; | ||
export type CacheManagerTarget = (typeof HANDLE_MANAGE_CACHE_TARGETS)[number]; | ||
export type HandleManageCacheParams = { | ||
action: CacheManagerOperationType; | ||
target: CacheManagerTarget; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import Box from "@mui/material/Box"; | ||
import Text, { typographyClasses } from "@mui/material/Typography"; | ||
|
||
export const DevToolContainer = ({ title, subtitle, children }: DevToolContainerProps) => ( | ||
<Box | ||
sx={({ palette }) => ({ | ||
width: "100%", | ||
display: "flex", | ||
flexDirection: "column", | ||
alignItems: "center", | ||
borderTop: `1px solid ${palette.divider}`, | ||
padding: "1rem", | ||
[`& > .${typographyClasses.body2}`]: { | ||
textAlign: "center", | ||
lineHeight: 1.4, | ||
opacity: 0.75, | ||
}, | ||
})} | ||
> | ||
<Text variant="h6">{title}</Text> | ||
{subtitle && <Text variant="body2">{subtitle}</Text>} | ||
<div | ||
style={{ | ||
width: "100%", | ||
display: "flex", | ||
justifyContent: "space-evenly", | ||
gap: "1rem", | ||
marginTop: "1rem", | ||
}} | ||
> | ||
{children} | ||
</div> | ||
</Box> | ||
); | ||
|
||
export type DevToolContainerProps = { | ||
title: string; | ||
subtitle?: string; | ||
children: React.ReactNode; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
import { useState } from "react"; | ||
import { styled, alpha } from "@mui/material/styles"; | ||
import Button from "@mui/material/Button"; | ||
import Modal from "@mui/material/Modal"; | ||
import Paper from "@mui/material/Paper"; | ||
import Text from "@mui/material/Typography"; | ||
import { RainbowBorderBox } from "@/components/Containers/RainbowBorderBox"; | ||
import { CacheManagerDevTool } from "./CacheManagerDevTool"; | ||
import { devToolsElementIDs } from "./elementIDs"; | ||
|
||
export const DevTools = () => { | ||
const [isModalOpen, setIsModalOpen] = useState(false); | ||
|
||
const handleOpenModal = () => setIsModalOpen(true); | ||
const handleCloseModal = () => setIsModalOpen(false); | ||
|
||
return ( | ||
<> | ||
<RainbowBorderBox> | ||
<Button | ||
onClick={handleOpenModal} | ||
variant="outlined" | ||
size="small" | ||
sx={({ palette, variables }) => { | ||
// Setting bg-color is necessary to ensure the rainbow-bg is not visible on the button | ||
const backgroundColor = variables.isMobilePageLayout | ||
? palette.background.default | ||
: palette.background.paper; | ||
return { | ||
// Ensure the button can be seen in light mode: | ||
...(palette.mode === "light" && { color: palette.text.primary }), | ||
backgroundColor, | ||
"&:hover": { backgroundColor: alpha(backgroundColor, 0.875) }, | ||
}; | ||
}} | ||
> | ||
Open Dev Tools | ||
</Button> | ||
</RainbowBorderBox> | ||
<Modal open={isModalOpen} onClose={handleCloseModal} aria-label="Fixit Dev Tools"> | ||
<StyledPaper id={devToolsElementIDs.modalRoot}> | ||
<Paper id={devToolsElementIDs.modalHeader} elevation={4}> | ||
<Text variant="h4" style={{ fontSize: "1.65rem" }}> | ||
✨ Fixit Dev Tools ✨ | ||
</Text> | ||
<Text variant="body2" style={{ textAlign: "center", lineHeight: 1.4, opacity: 0.75 }}> | ||
These tools will help you take Fixit for a spin - have fun! | ||
</Text> | ||
</Paper> | ||
<div id={devToolsElementIDs.modalContent}> | ||
<CacheManagerDevTool handleCloseModal={handleCloseModal} /> | ||
</div> | ||
</StyledPaper> | ||
</Modal> | ||
</> | ||
); | ||
}; | ||
|
||
// Exported as default for React lazy loading | ||
export default DevTools; | ||
|
||
const StyledPaper = styled(Paper)(({ theme: { palette } }) => ({ | ||
position: "absolute", | ||
top: "50%", | ||
left: "50%", | ||
transform: "translate(-50%, -50%)", | ||
minWidth: "clamp(328px, 35vw, 26rem)", | ||
maxWidth: "600px", | ||
border: `3px solid ${palette.divider}`, | ||
borderRadius: "0.5rem", | ||
display: "flex", | ||
flexDirection: "column", | ||
alignItems: "center", | ||
|
||
// HEADER | ||
[`& > #${devToolsElementIDs.modalHeader}`]: { | ||
width: "100%", | ||
borderRadius: "0.3rem 0.3rem 0 0", | ||
display: "flex", | ||
flexDirection: "column", | ||
alignItems: "center", | ||
gap: "1rem", | ||
padding: "1rem", | ||
borderBottom: `1px solid ${palette.divider}`, | ||
}, | ||
|
||
// CONTENT | ||
[`& > #${devToolsElementIDs.modalContent}`]: { | ||
flexGrow: 1, | ||
width: "100%", | ||
display: "flex", | ||
gap: "1rem", | ||
flexDirection: "column", | ||
alignItems: "center", | ||
padding: "0 0 0.5rem 0", | ||
}, | ||
})); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
/** | ||
* Element IDs for `DevTools` components (src/components/DevTools/). | ||
*/ | ||
export const devToolsElementIDs = { | ||
modalRoot: "dev-tools__modal-root", | ||
modalHeader: "dev-tools__modal-header", | ||
modalContent: "dev-tools__modal-content", | ||
} as const; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export * from "./DevTools"; | ||
|
||
// re-exported as default for lazy loading (see AppBar): | ||
export { DevTools as default } from "./DevTools"; |