#11 Refactor: Introduce apollo reactive variables for global state
Use it to streamline entangle the delete dialog(s) from the list(s)
This commit is contained in:
parent
42dc7f285d
commit
fc8bc6724b
|
@ -5,20 +5,21 @@
|
|||
"requires": true,
|
||||
"dependencies": {
|
||||
"@apollo/client": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@apollo/client/-/client-3.1.3.tgz",
|
||||
"integrity": "sha512-zXMiaj+dX0sgXIwEV5d/PI6B8SZT2bqlKNjZWcEXRY7NjESF5J3nd4v8KOsrhHe+A3YhNv63tIl35Sq7uf41Pg==",
|
||||
"version": "3.3.6",
|
||||
"resolved": "https://registry.npmjs.org/@apollo/client/-/client-3.3.6.tgz",
|
||||
"integrity": "sha512-XSm/STyNS8aHdDigLLACKNMHwI0qaQmEHWHtTP+jHe/E1wZRnn66VZMMgwKLy2V4uHISHfmiZ4KpUKDPeJAKqg==",
|
||||
"requires": {
|
||||
"@graphql-typed-document-node/core": "^3.0.0",
|
||||
"@types/zen-observable": "^0.8.0",
|
||||
"@wry/context": "^0.5.2",
|
||||
"@wry/equality": "^0.2.0",
|
||||
"@wry/equality": "^0.3.0",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
"graphql-tag": "^2.11.0",
|
||||
"hoist-non-react-statics": "^3.3.2",
|
||||
"optimism": "^0.12.1",
|
||||
"optimism": "^0.13.1",
|
||||
"prop-types": "^15.7.2",
|
||||
"symbol-observable": "^1.2.0",
|
||||
"ts-invariant": "^0.4.4",
|
||||
"symbol-observable": "^2.0.0",
|
||||
"ts-invariant": "^0.6.0",
|
||||
"tslib": "^1.10.0",
|
||||
"zen-observable": "^0.8.14"
|
||||
}
|
||||
|
@ -1171,6 +1172,11 @@
|
|||
"resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz",
|
||||
"integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow=="
|
||||
},
|
||||
"@graphql-typed-document-node/core": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.1.0.tgz",
|
||||
"integrity": "sha512-wYn6r8zVZyQJ6rQaALBEln5B1pzxb9shV5Ef97kTvn6yVGrqyXVnDqnU24MXnFubR+rZjBY9NWuxX3FB2sTsjg=="
|
||||
},
|
||||
"@hapi/address": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz",
|
||||
|
@ -2066,6 +2072,11 @@
|
|||
"@types/jest": "*"
|
||||
}
|
||||
},
|
||||
"@types/ungap__global-this": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/ungap__global-this/-/ungap__global-this-0.3.1.tgz",
|
||||
"integrity": "sha512-+/DsiV4CxXl6ZWefwHZDXSe1Slitz21tom38qPCaG0DYCS1NnDPIQDTKcmQ/tvK/edJUKkmuIDBJbmKDiB0r/g=="
|
||||
},
|
||||
"@types/yargs": {
|
||||
"version": "13.0.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.10.tgz",
|
||||
|
@ -2080,9 +2091,9 @@
|
|||
"integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw=="
|
||||
},
|
||||
"@types/zen-observable": {
|
||||
"version": "0.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/zen-observable/-/zen-observable-0.8.0.tgz",
|
||||
"integrity": "sha512-te5lMAWii1uEJ4FwLjzdlbw3+n0FZNOvFXHxQDKeT0dilh7HOzdMzV2TrJVUzq8ep7J4Na8OUYPRLSQkJHAlrg=="
|
||||
"version": "0.8.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/zen-observable/-/zen-observable-0.8.2.tgz",
|
||||
"integrity": "sha512-HrCIVMLjE1MOozVoD86622S7aunluLb2PJdPfb3nYiEtohm8mIB/vyv0Fd37AdeMFrTUQXEunw78YloMA3Qilg=="
|
||||
},
|
||||
"@typescript-eslint/eslint-plugin": {
|
||||
"version": "2.34.0",
|
||||
|
@ -2138,6 +2149,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"@ungap/global-this": {
|
||||
"version": "0.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@ungap/global-this/-/global-this-0.4.3.tgz",
|
||||
"integrity": "sha512-MuHEpDBurNVeD6mV9xBcAN2wfTwuaFQhHuhWkJuXmyVJ5P5sBCw+nnFpdfb0tAvgWkfefWCsAoAsh7MTUr3LPg=="
|
||||
},
|
||||
"@webassemblyjs/ast": {
|
||||
"version": "1.8.5",
|
||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz",
|
||||
|
@ -2297,19 +2313,33 @@
|
|||
}
|
||||
},
|
||||
"@wry/context": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@wry/context/-/context-0.5.2.tgz",
|
||||
"integrity": "sha512-B/JLuRZ/vbEKHRUiGj6xiMojST1kHhu4WcreLfNN7q9DqQFrb97cWgf/kiYsPSUCAMVN0HzfFc8XjJdzgZzfjw==",
|
||||
"version": "0.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@wry/context/-/context-0.5.3.tgz",
|
||||
"integrity": "sha512-n0uKHiWpf2ArHhmcHcUsKA+Dj0gtye/h56VmsDcoMRuK/ZPFeHKi8ck5L/ftqtF12ZbQR9l8xMPV7y+xybaRDA==",
|
||||
"requires": {
|
||||
"tslib": "^1.9.3"
|
||||
"tslib": "^1.14.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@wry/equality": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@wry/equality/-/equality-0.2.0.tgz",
|
||||
"integrity": "sha512-Y4d+WH6hs+KZJUC8YKLYGarjGekBrhslDbf/R20oV+AakHPINSitHfDRQz3EGcEWc1luXYNUvMhawWtZVWNGvQ==",
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@wry/equality/-/equality-0.3.1.tgz",
|
||||
"integrity": "sha512-8/Ftr3jUZ4EXhACfSwPIfNsE8V6WKesdjp+Dxi78Bej6qlasAxiz0/F8j0miACRj9CL4vC5Y5FsfwwEYAuhWbg==",
|
||||
"requires": {
|
||||
"tslib": "^1.9.3"
|
||||
"tslib": "^1.14.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@xtuc/ieee754": {
|
||||
|
@ -9607,7 +9637,6 @@
|
|||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/notistack/-/notistack-1.0.3.tgz",
|
||||
"integrity": "sha512-bRGF/eg2qNQ8BwagPLkHiqrz+W00PYtGY5Xl33I0Of1BTm7arksZO1JxssPTlti0qw127CxuWxm637ipn0eZ9g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"clsx": "^1.1.0",
|
||||
"hoist-non-react-statics": "^3.3.0"
|
||||
|
@ -9909,9 +9938,9 @@
|
|||
}
|
||||
},
|
||||
"optimism": {
|
||||
"version": "0.12.1",
|
||||
"resolved": "https://registry.npmjs.org/optimism/-/optimism-0.12.1.tgz",
|
||||
"integrity": "sha512-t8I7HM1dw0SECitBYAqFOVHoBAHEQBTeKjIL9y9ImHzAVkdyPK4ifTgM4VJRDtTUY4r/u5Eqxs4XcGPHaoPkeQ==",
|
||||
"version": "0.13.2",
|
||||
"resolved": "https://registry.npmjs.org/optimism/-/optimism-0.13.2.tgz",
|
||||
"integrity": "sha512-kJkpDUEs/Rp8HsAYYlDzyvQHlT6YZa95P+2GGNR8p/VvsIkt6NilAk7oeTvMRKCq7BeclB7+bmdIexog2859GQ==",
|
||||
"requires": {
|
||||
"@wry/context": "^0.5.2"
|
||||
}
|
||||
|
@ -13378,9 +13407,9 @@
|
|||
}
|
||||
},
|
||||
"symbol-observable": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz",
|
||||
"integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ=="
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-2.0.3.tgz",
|
||||
"integrity": "sha512-sQV7phh2WCYAn81oAkakC5qjq2Ml0g8ozqz03wOGnx9dDlG1de6yrF+0RAzSJD8fPUow3PTSMf2SAbOGxb93BA=="
|
||||
},
|
||||
"symbol-tree": {
|
||||
"version": "3.2.4",
|
||||
|
@ -13704,10 +13733,12 @@
|
|||
}
|
||||
},
|
||||
"ts-invariant": {
|
||||
"version": "0.4.4",
|
||||
"resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.4.4.tgz",
|
||||
"integrity": "sha512-uEtWkFM/sdZvRNNDL3Ehu4WVpwaulhwQszV8mrtcdeE8nN00BV9mAmQ88RkrBhFgl9gMgvjJLAQcZbnPXI9mlA==",
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.6.0.tgz",
|
||||
"integrity": "sha512-caoafsfgb8QxdrKzFfjKt627m4i8KTtfAiji0DYJfWI4A/S9ORNNpzYuD9br64kyKFgxn9UNaLLbSupam84mCA==",
|
||||
"requires": {
|
||||
"@types/ungap__global-this": "^0.3.1",
|
||||
"@ungap/global-this": "^0.4.2",
|
||||
"tslib": "^1.9.3"
|
||||
}
|
||||
},
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@apollo/client": "^3.1.3",
|
||||
"@apollo/client": "^3.2",
|
||||
"@material-ui/core": "^4.11.0",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
"@material-ui/lab": "^4.0.0-alpha.57",
|
||||
|
|
|
@ -19,4 +19,5 @@ const authLink = setContext((_, { headers }) => {
|
|||
export const client = new ApolloClient({
|
||||
cache: new InMemoryCache(),
|
||||
link: authLink.concat(httpLink),
|
||||
connectToDevTools: true,
|
||||
});
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import {Paper, Typography} from "@material-ui/core";
|
||||
import React, {useState} from "react";
|
||||
import {makeStyles} from "@material-ui/core/styles";
|
||||
import {Reference, useMutation, useQuery} from "@apollo/client";
|
||||
import {useMutation, useQuery} from "@apollo/client";
|
||||
import AddCard from "./AddCard";
|
||||
import AccordionWithEdit from "./AccordionWithEdit";
|
||||
import {
|
||||
|
@ -12,18 +12,19 @@ import {
|
|||
} from "../backend/queries/category";
|
||||
import ChangeCategoryDialog, {ChangeCategoryDialogContent} from "./ChangeCategoryDialog";
|
||||
import {useSnackbar} from "notistack";
|
||||
import DeleteConfirmationDialog, {DeleteConfirmationDialogContent} from "./DeleteConfirmationDialog";
|
||||
import {
|
||||
ADD_CATEGORY,
|
||||
AddCategoryResponse,
|
||||
AddCategoryVariables,
|
||||
DELETE_CATEGORY,
|
||||
DeleteCategoryResponse,
|
||||
DeleteCategoryVariables,
|
||||
EDIT_CATEGORY,
|
||||
EditCategoryResponse,
|
||||
EditCategoryVariables
|
||||
} from "../backend/mutations/category";
|
||||
import DeleteCategoryDialog, {
|
||||
deleteCategoryDialogId,
|
||||
deleteCategoryDialogOpen,
|
||||
deleteCategoryDialogTitle
|
||||
} from "./DeleteCategoryDialog";
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
root: {
|
||||
|
@ -39,19 +40,11 @@ const emptyChangeCategoryDialog: ChangeCategoryDialogContent = {
|
|||
details: "",
|
||||
}
|
||||
|
||||
const emptyDeleteConfirmationDialogContent: DeleteConfirmationDialogContent = {
|
||||
id: "",
|
||||
type: "Kategorie",
|
||||
title: "",
|
||||
}
|
||||
|
||||
export default function CategoryList() {
|
||||
const [changeDialogOpen, setChangeDialogOpen] = useState(false);
|
||||
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
||||
const [dialogTitle, setDialogTitle] = useState("");
|
||||
const [dialogConfirmButtonText, setDialogConfirmButtonText] = useState("");
|
||||
const [changeDialogContent, setChangeDialogContent] = useState(emptyChangeCategoryDialog);
|
||||
const [deleteDialogContent, setDeleteDialogContent] = useState(emptyDeleteConfirmationDialogContent);
|
||||
const { enqueueSnackbar } = useSnackbar();
|
||||
const categories = useQuery<GetAllCategoriesResponse, null>(GET_ALL_CATEGORIES).data?.allCategories.nodes;
|
||||
const [editCategory, {loading: editLoading}] = useMutation<EditCategoryResponse, EditCategoryVariables>(EDIT_CATEGORY, {
|
||||
|
@ -90,28 +83,7 @@ export default function CategoryList() {
|
|||
});
|
||||
}
|
||||
});
|
||||
const [deleteCategory, {loading: deleteLoading}] = useMutation<DeleteCategoryResponse, DeleteCategoryVariables>(DELETE_CATEGORY, {
|
||||
onError: (e) => enqueueSnackbar(`Ein Fehler ist aufgetreten: ${e.message}`, { variant: "error"}),
|
||||
onCompleted: (response) => {
|
||||
if (response.deleteCategory) {
|
||||
enqueueSnackbar("Kategorie erfolgreich gelöscht.", { variant: "success"})
|
||||
setDeleteDialogOpen(false);
|
||||
} else {
|
||||
enqueueSnackbar("Ein Fehler ist aufgetreten, versuche es erneut.", { variant: "error"})
|
||||
}
|
||||
},
|
||||
update: (cache, { data }) => {
|
||||
const idToRemove = data?.deleteCategory?.category.id;
|
||||
cache.modify({
|
||||
fields: {
|
||||
allCategories(existingCategoriesRef: { nodes: Array<Reference>} = { nodes: []}, {readField}) {
|
||||
console.log("existingCategory: ", existingCategoriesRef)
|
||||
return {nodes: existingCategoriesRef.nodes.filter(categoryRef => readField('id', categoryRef) !== idToRemove)};
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const classes = useStyles();
|
||||
|
||||
const loading = editLoading || addLoading;
|
||||
|
@ -139,12 +111,9 @@ export default function CategoryList() {
|
|||
};
|
||||
|
||||
const handleDeleteButtonClick = (category: BasicCategoryResponse) => {
|
||||
setDeleteDialogContent({
|
||||
...deleteDialogContent,
|
||||
id: category.id,
|
||||
title: category.title,
|
||||
});
|
||||
setDeleteDialogOpen(true);
|
||||
deleteCategoryDialogTitle(category.title);
|
||||
deleteCategoryDialogId(category.id);
|
||||
deleteCategoryDialogOpen(true);
|
||||
}
|
||||
|
||||
const handleDialogContentChange = (content: ChangeCategoryDialogContent) => {
|
||||
|
@ -170,14 +139,6 @@ export default function CategoryList() {
|
|||
}
|
||||
};
|
||||
|
||||
const handleDeleteConfirmButtonClick = () => {
|
||||
deleteCategory({
|
||||
variables: {
|
||||
id: deleteDialogContent.id
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
return (
|
||||
<Paper className={classes.root}>
|
||||
<Typography component={"h2"} variant="h6" color="primary" gutterBottom>Kategorien</Typography>
|
||||
|
@ -200,13 +161,7 @@ export default function CategoryList() {
|
|||
handleConfirmButtonClick={handleChangeConfirmButtonClick}
|
||||
handleClose={() => setChangeDialogOpen(false)}
|
||||
/>
|
||||
<DeleteConfirmationDialog
|
||||
content={deleteDialogContent}
|
||||
open={deleteDialogOpen}
|
||||
loading={deleteLoading}
|
||||
handleConfirmButtonClick={handleDeleteConfirmButtonClick}
|
||||
handleClose={() => setDeleteDialogOpen(false)}
|
||||
/>
|
||||
<DeleteCategoryDialog/>
|
||||
</Paper>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
import React from 'react';
|
||||
import {makeVar, Reference, useMutation, useReactiveVar} from "@apollo/client";
|
||||
import DeleteConfirmationDialog from "./DeleteConfirmationDialog";
|
||||
import {useSnackbar} from "notistack";
|
||||
import {DELETE_CATEGORY, DeleteCategoryResponse, DeleteCategoryVariables} from "../backend/mutations/category";
|
||||
|
||||
|
||||
export const deleteCategoryDialogId = makeVar<string>("");
|
||||
export const deleteCategoryDialogTitle = makeVar<string>("");
|
||||
export const deleteCategoryDialogOpen = makeVar<boolean>(false);
|
||||
|
||||
export default function DeleteCategoryDialog() {
|
||||
const {enqueueSnackbar} = useSnackbar();
|
||||
const [deleteCategory, {loading}] = useMutation<DeleteCategoryResponse, DeleteCategoryVariables>(DELETE_CATEGORY, {
|
||||
onError: (e) => enqueueSnackbar(`Ein Fehler ist aufgetreten: ${e.message}`, {variant: "error"}),
|
||||
onCompleted: (response) => {
|
||||
if (response.deleteCategory) {
|
||||
enqueueSnackbar("Kategorie erfolgreich gelöscht.", {variant: "success"})
|
||||
deleteCategoryDialogOpen(false);
|
||||
} else {
|
||||
enqueueSnackbar("Ein Fehler ist aufgetreten, versuche es erneut.", {variant: "error"})
|
||||
}
|
||||
},
|
||||
update: (cache, {data}) => {
|
||||
const idToRemove = data?.deleteCategory?.category.id;
|
||||
cache.modify({
|
||||
fields: {
|
||||
allCategories(existingCategoriesRef: { nodes: Array<Reference> } = {nodes: []}, {readField}) {
|
||||
console.log("existingCategory: ", existingCategoriesRef)
|
||||
return {nodes: existingCategoriesRef.nodes.filter(categoryRef => readField('id', categoryRef) !== idToRemove)};
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const open = useReactiveVar(deleteCategoryDialogOpen);
|
||||
const title = useReactiveVar(deleteCategoryDialogTitle);
|
||||
const id = useReactiveVar(deleteCategoryDialogId);
|
||||
|
||||
const handleConfirmButtonClick = () => {
|
||||
deleteCategory({
|
||||
variables: {
|
||||
id
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<DeleteConfirmationDialog
|
||||
open={open}
|
||||
type={"Kategorie"}
|
||||
title={title}
|
||||
onConfirmButtonClick={handleConfirmButtonClick}
|
||||
onClose={() => deleteCategoryDialogOpen(false)}
|
||||
loading={loading}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
@ -6,43 +6,38 @@ import {Button, DialogActions, DialogContentText} from "@material-ui/core";
|
|||
import ButtonWithSpinner from "./ButtonWithSpinner";
|
||||
|
||||
|
||||
export interface DeleteConfirmationDialogContent {
|
||||
id: string,
|
||||
interface DeleteConfirmationDialogProps {
|
||||
open: boolean,
|
||||
type: string,
|
||||
title: string,
|
||||
}
|
||||
|
||||
interface DeleteConfirmationDialogProps {
|
||||
content: DeleteConfirmationDialogContent,
|
||||
open: boolean,
|
||||
loading?: boolean,
|
||||
|
||||
handleConfirmButtonClick(): void,
|
||||
onConfirmButtonClick(): void,
|
||||
|
||||
handleClose(): void,
|
||||
onClose(): void,
|
||||
}
|
||||
|
||||
export default function DeleteConfirmationDialog(props: DeleteConfirmationDialogProps) {
|
||||
return (
|
||||
<Dialog
|
||||
open={props.open}
|
||||
onClose={props.handleClose}
|
||||
onClose={props.onClose}
|
||||
aria-labelledby="alert-dialog-title"
|
||||
aria-describedby="alert-dialog-description"
|
||||
>
|
||||
<DialogTitle id="alert-dialog-title">{props.content.type} löschen?</DialogTitle>
|
||||
<DialogTitle id="alert-dialog-title">{props.type} löschen?</DialogTitle>
|
||||
<DialogContent>
|
||||
<DialogContentText id="alert-dialog-description">
|
||||
Möchten Sie die {props.content.type}
|
||||
"{props.content.title}"
|
||||
Möchten Sie die {props.type}
|
||||
"{props.title}"
|
||||
wirklich löschen?
|
||||
</DialogContentText>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={props.handleClose} color="primary">
|
||||
<Button onClick={props.onClose} color="primary">
|
||||
Abbrechen
|
||||
</Button>
|
||||
<ButtonWithSpinner onClick={props.handleConfirmButtonClick} autoFocus loading={props.loading}>
|
||||
<ButtonWithSpinner onClick={props.onConfirmButtonClick} autoFocus loading={props.loading}>
|
||||
Löschen
|
||||
</ButtonWithSpinner>
|
||||
</DialogActions>
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
import React from 'react';
|
||||
import {makeVar, Reference, useMutation, useReactiveVar} from "@apollo/client";
|
||||
import DeleteConfirmationDialog from "./DeleteConfirmationDialog";
|
||||
import {DELETE_QUESTION, DeleteQuestionResponse, DeleteQuestionVariables} from "../backend/mutations/question";
|
||||
import {useSnackbar} from "notistack";
|
||||
|
||||
|
||||
export const deleteQuestionDialogId = makeVar<string>("");
|
||||
export const deleteQuestionDialogTitle = makeVar<string>("");
|
||||
export const deleteQuestionDialogOpen = makeVar<boolean>(false);
|
||||
|
||||
export default function DeleteQuestionDialog() {
|
||||
const {enqueueSnackbar} = useSnackbar();
|
||||
const [deleteQuestion, {loading}] = useMutation<DeleteQuestionResponse, DeleteQuestionVariables>(DELETE_QUESTION, {
|
||||
onError: (e) => enqueueSnackbar(`Ein Fehler ist aufgetreten: ${e.message}`, {variant: "error"}),
|
||||
onCompleted: (response) => {
|
||||
if (response.deleteQuestion) {
|
||||
enqueueSnackbar("Frage erfolgreich gelöscht.", {variant: "success"})
|
||||
deleteQuestionDialogOpen(false);
|
||||
} else {
|
||||
enqueueSnackbar("Ein Fehler ist aufgetreten, versuche es erneut.", {variant: "error"})
|
||||
}
|
||||
},
|
||||
update: (cache, {data}) => {
|
||||
const idToRemove = data?.deleteQuestion?.question.id;
|
||||
cache.modify({
|
||||
fields: {
|
||||
allQuestions(existingQuestionsRef: { nodes: Array<Reference> } = {nodes: []}, {readField}) {
|
||||
return {nodes: existingQuestionsRef.nodes.filter(questionRef => readField('id', questionRef) !== idToRemove)};
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const open = useReactiveVar(deleteQuestionDialogOpen);
|
||||
const title = useReactiveVar(deleteQuestionDialogTitle);
|
||||
const id = useReactiveVar(deleteQuestionDialogId);
|
||||
|
||||
const handleConfirmButtonClick = () => {
|
||||
deleteQuestion({
|
||||
variables: {
|
||||
id
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<DeleteConfirmationDialog
|
||||
open={open}
|
||||
type={"Frage"}
|
||||
title={title}
|
||||
onConfirmButtonClick={handleConfirmButtonClick}
|
||||
onClose={() => deleteQuestionDialogOpen(false)}
|
||||
loading={loading}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import {Paper, Typography} from "@material-ui/core";
|
||||
import React, {useState} from "react";
|
||||
import {makeStyles} from "@material-ui/core/styles";
|
||||
import {Reference, useMutation, useQuery} from "@apollo/client";
|
||||
import {useMutation, useQuery} from "@apollo/client";
|
||||
import AddCard from "./AddCard";
|
||||
import AccordionWithEdit from "./AccordionWithEdit";
|
||||
import {
|
||||
|
@ -16,15 +16,12 @@ import {
|
|||
ADD_QUESTION,
|
||||
AddQuestionResponse,
|
||||
AddQuestionVariables,
|
||||
DELETE_QUESTION,
|
||||
DeleteQuestionResponse,
|
||||
DeleteQuestionVariables,
|
||||
EDIT_QUESTION,
|
||||
EditQuestionResponse,
|
||||
EditQuestionVariables
|
||||
} from "../backend/mutations/question";
|
||||
import {useSnackbar} from 'notistack';
|
||||
import DeleteConfirmationDialog, {DeleteConfirmationDialogContent} from "./DeleteConfirmationDialog";
|
||||
import DeleteQuestionDialog, {deleteQuestionDialogId, deleteQuestionDialogOpen, deleteQuestionDialogTitle} from "./DeleteQuestionDialog";
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
root: {
|
||||
|
@ -41,47 +38,39 @@ const emptyChangeQuestionDialog: ChangeQuestionDialogContent = {
|
|||
categoryId: null,
|
||||
}
|
||||
|
||||
const emptyDeleteConfirmationDialogContent: DeleteConfirmationDialogContent = {
|
||||
id: "",
|
||||
type: "Frage",
|
||||
title: "",
|
||||
}
|
||||
|
||||
export default function QuestionList() {
|
||||
const [changeDialogOpen, setChangeDialogOpen] = useState(false);
|
||||
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
||||
const [dialogTitle, setDialogTitle] = useState("");
|
||||
const [dialogConfirmButtonText, setDialogConfirmButtonText] = useState("");
|
||||
const [changeDialogContent, setChangeDialogContent] = useState(emptyChangeQuestionDialog);
|
||||
const [deleteDialogContent, setDeleteDialogContent] = useState(emptyDeleteConfirmationDialogContent);
|
||||
const { enqueueSnackbar } = useSnackbar();
|
||||
const {enqueueSnackbar} = useSnackbar();
|
||||
const questions = useQuery<GetAllQuestionsResponse, null>(GET_ALL_QUESTIONS).data?.allQuestions.nodes;
|
||||
const categories = useQuery<GetAllCategoriesResponse, null>(GET_ALL_CATEGORIES).data?.allCategories.nodes;
|
||||
const [editQuestion, {loading: editLoading}] = useMutation<EditQuestionResponse, EditQuestionVariables>(EDIT_QUESTION, {
|
||||
onError: (e) => enqueueSnackbar(`Ein Fehler ist aufgetreten: ${e.message}`, { variant: "error"}),
|
||||
onCompleted: (response) => {
|
||||
if (response.updateQuestion) {
|
||||
enqueueSnackbar("Frage erfolgreich geändert.", { variant: "success"})
|
||||
setChangeDialogOpen(false);
|
||||
} else {
|
||||
enqueueSnackbar("Ein Fehler ist aufgetreten, versuche es erneut.", { variant: "error"})
|
||||
}
|
||||
}
|
||||
});
|
||||
const [addQuestion, {loading: addLoading}] = useMutation<AddQuestionResponse, AddQuestionVariables>(ADD_QUESTION, {
|
||||
onError: (e) => enqueueSnackbar(`Ein Fehler ist aufgetreten: ${e.message}`, { variant: "error"}),
|
||||
onError: (e) => enqueueSnackbar(`Ein Fehler ist aufgetreten: ${e.message}`, {variant: "error"}),
|
||||
onCompleted: (response) => {
|
||||
if (response.createQuestion) {
|
||||
enqueueSnackbar("Frage erfolgreich hinzugefügt.", { variant: "success"})
|
||||
if (response.updateQuestion) {
|
||||
enqueueSnackbar("Frage erfolgreich geändert.", {variant: "success"})
|
||||
setChangeDialogOpen(false);
|
||||
} else {
|
||||
enqueueSnackbar("Ein Fehler ist aufgetreten, versuche es erneut.", { variant: "error"})
|
||||
enqueueSnackbar("Ein Fehler ist aufgetreten, versuche es erneut.", {variant: "error"})
|
||||
}
|
||||
}
|
||||
});
|
||||
const [addQuestion, {loading: addLoading}] = useMutation<AddQuestionResponse, AddQuestionVariables>(ADD_QUESTION, {
|
||||
onError: (e) => enqueueSnackbar(`Ein Fehler ist aufgetreten: ${e.message}`, {variant: "error"}),
|
||||
onCompleted: (response) => {
|
||||
if (response.createQuestion) {
|
||||
enqueueSnackbar("Frage erfolgreich hinzugefügt.", {variant: "success"})
|
||||
setChangeDialogOpen(false);
|
||||
} else {
|
||||
enqueueSnackbar("Ein Fehler ist aufgetreten, versuche es erneut.", {variant: "error"})
|
||||
}
|
||||
},
|
||||
update: (cache, { data }) => {
|
||||
update: (cache, {data}) => {
|
||||
cache.modify({
|
||||
fields: {
|
||||
allQuestions(existingQuestions = { nodes: []}) {
|
||||
allQuestions(existingQuestions = {nodes: []}) {
|
||||
const newQuestionRef = cache.writeFragment<BasicQuestionResponse | undefined>({
|
||||
data: data?.createQuestion?.question,
|
||||
fragment: BasicQuestionFragment,
|
||||
|
@ -93,27 +82,6 @@ export default function QuestionList() {
|
|||
});
|
||||
}
|
||||
});
|
||||
const [deleteQuestion, {loading: deleteLoading}] = useMutation<DeleteQuestionResponse, DeleteQuestionVariables>(DELETE_QUESTION, {
|
||||
onError: (e) => enqueueSnackbar(`Ein Fehler ist aufgetreten: ${e.message}`, { variant: "error"}),
|
||||
onCompleted: (response) => {
|
||||
if (response.deleteQuestion) {
|
||||
enqueueSnackbar("Frage erfolgreich gelöscht.", { variant: "success"})
|
||||
setDeleteDialogOpen(false);
|
||||
} else {
|
||||
enqueueSnackbar("Ein Fehler ist aufgetreten, versuche es erneut.", { variant: "error"})
|
||||
}
|
||||
},
|
||||
update: (cache, { data }) => {
|
||||
const idToRemove = data?.deleteQuestion?.question.id;
|
||||
cache.modify({
|
||||
fields: {
|
||||
allQuestions(existingQuestionsRef: { nodes: Array<Reference>} = { nodes: []}, {readField}) {
|
||||
return {nodes: existingQuestionsRef.nodes.filter(questionRef => readField('id', questionRef) !== idToRemove)};
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
const classes = useStyles();
|
||||
|
||||
const loading = editLoading || addLoading;
|
||||
|
@ -142,12 +110,9 @@ export default function QuestionList() {
|
|||
};
|
||||
|
||||
const handleDeleteButtonClick = (question: BasicQuestionResponse) => {
|
||||
setDeleteDialogContent({
|
||||
...deleteDialogContent,
|
||||
id: question.id,
|
||||
title: question.title,
|
||||
});
|
||||
setDeleteDialogOpen(true);
|
||||
deleteQuestionDialogTitle(question.title);
|
||||
deleteQuestionDialogId(question.id);
|
||||
deleteQuestionDialogOpen(true);
|
||||
}
|
||||
|
||||
const handleDialogContentChange = (content: ChangeQuestionDialogContent) => {
|
||||
|
@ -175,25 +140,17 @@ export default function QuestionList() {
|
|||
}
|
||||
};
|
||||
|
||||
const handleDeleteConfirmButtonClick = () => {
|
||||
deleteQuestion({
|
||||
variables: {
|
||||
id: deleteDialogContent.id
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
return (
|
||||
<Paper className={classes.root}>
|
||||
<Typography component={"h2"} variant="h6" color="primary" gutterBottom>Fragen</Typography>
|
||||
{questions?.map(question => <AccordionWithEdit
|
||||
key={question.id}
|
||||
title={question.title}
|
||||
subTitle={question.categoryByCategoryRowId?.title}
|
||||
description={question.description}
|
||||
onEditButtonClick={() => handleEditButtonClick(question)}
|
||||
onDeleteButtonClick={() => handleDeleteButtonClick(question)}
|
||||
/>
|
||||
{questions?.map(question => <AccordionWithEdit
|
||||
key={question.id}
|
||||
title={question.title}
|
||||
subTitle={question.categoryByCategoryRowId?.title}
|
||||
description={question.description}
|
||||
onEditButtonClick={() => handleEditButtonClick(question)}
|
||||
onDeleteButtonClick={() => handleDeleteButtonClick(question)}
|
||||
/>
|
||||
)}
|
||||
<AddCard handleClick={handleAddClick}/>
|
||||
<ChangeQuestionDialog
|
||||
|
@ -207,13 +164,7 @@ export default function QuestionList() {
|
|||
handleConfirmButtonClick={handleChangeConfirmButtonClick}
|
||||
handleClose={() => setChangeDialogOpen(false)}
|
||||
/>
|
||||
<DeleteConfirmationDialog
|
||||
content={deleteDialogContent}
|
||||
open={deleteDialogOpen}
|
||||
loading={deleteLoading}
|
||||
handleConfirmButtonClick={handleDeleteConfirmButtonClick}
|
||||
handleClose={() => setDeleteDialogOpen(false)}
|
||||
/>
|
||||
<DeleteQuestionDialog/>
|
||||
</Paper>
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue