kandimat/redaktions-app/src/components/CategoryList.tsx
2020-12-30 21:13:06 +01:00

169 lines
5.6 KiB
TypeScript

import {Paper, Typography} from "@material-ui/core";
import React, {useState} from "react";
import {makeStyles} from "@material-ui/core/styles";
import {useMutation, useQuery} from "@apollo/client";
import AddCard from "./AddCard";
import AccordionWithEdit from "./AccordionWithEdit";
import {
BasicCategoryFragment,
BasicCategoryResponse,
GET_ALL_CATEGORIES,
GetAllCategoriesResponse
} from "../backend/queries/category";
import DialogChangeCategory, {ChangeCategoryDialogContent} from "./DialogChangeCategory";
import {useSnackbar} from "notistack";
import {
ADD_CATEGORY,
AddCategoryResponse,
AddCategoryVariables,
EDIT_CATEGORY,
EditCategoryResponse,
EditCategoryVariables
} from "../backend/mutations/category";
import DialogDeleteCategory, {
dialogDeleteCategoryId,
dialogDeleteCategoryOpen,
dialogDeleteCategoryTitle
} from "./DialogDeleteCategory";
const useStyles = makeStyles((theme) => ({
root: {
width: '100%',
padding: theme.spacing(1),
marginBottom: theme.spacing(3),
},
}));
const emptyChangeCategoryDialog: ChangeCategoryDialogContent = {
id: "",
title: "",
details: "",
}
export default function CategoryList() {
const [changeDialogOpen, setChangeDialogOpen] = useState(false);
const [dialogTitle, setDialogTitle] = useState("");
const [dialogConfirmButtonText, setDialogConfirmButtonText] = useState("");
const [changeDialogContent, setChangeDialogContent] = useState(emptyChangeCategoryDialog);
const { enqueueSnackbar } = useSnackbar();
const categories = useQuery<GetAllCategoriesResponse, null>(GET_ALL_CATEGORIES).data?.allCategories.nodes;
const [editCategory, {loading: editLoading}] = useMutation<EditCategoryResponse, EditCategoryVariables>(EDIT_CATEGORY, {
onError: (e) => enqueueSnackbar(`Ein Fehler ist aufgetreten: ${e.message}`, { variant: "error"}),
onCompleted: (response) => {
if (response.updateCategory) {
enqueueSnackbar("Kategorie erfolgreich geändert.", { variant: "success"})
setChangeDialogOpen(false);
} else {
enqueueSnackbar("Ein Fehler ist aufgetreten, versuche es erneut.", { variant: "error"})
}
}
});
const [addCategory, {loading: addLoading}] = useMutation<AddCategoryResponse, AddCategoryVariables>(ADD_CATEGORY, {
onError: (e) => enqueueSnackbar(`Ein Fehler ist aufgetreten: ${e.message}`, { variant: "error"}),
onCompleted: (response) => {
if (response.createCategory) {
enqueueSnackbar("Kategorie erfolgreich hinzugefügt.", { variant: "success"})
setChangeDialogOpen(false);
} else {
enqueueSnackbar("Ein Fehler ist aufgetreten, versuche es erneut.", { variant: "error"})
}
},
update: (cache, { data }) => {
cache.modify({
fields: {
allCategories(existingCategories = { nodes: []}) {
const newCategoryRef = cache.writeFragment<BasicCategoryResponse | undefined>({
data: data?.createCategory?.category,
fragment: BasicCategoryFragment,
fragmentName: "BasicCategoryFragment",
});
return {nodes: [...existingCategories.nodes, newCategoryRef]};
}
}
});
}
});
const classes = useStyles();
const loading = editLoading || addLoading;
const handleAddClick = () => {
setDialogTitle("Neue Kategorie erstellen");
setDialogConfirmButtonText("Erstellen");
if (changeDialogContent.id !== "") {
setChangeDialogContent(emptyChangeCategoryDialog);
}
setChangeDialogOpen(true);
}
const handleEditButtonClick = (category: BasicCategoryResponse) => {
setDialogTitle("Kategorie bearbeiten");
setDialogConfirmButtonText("Speichern")
if (changeDialogContent.id !== category.id) {
setChangeDialogContent({
id: category.id,
title: category.title,
details: category.description,
})
}
setChangeDialogOpen(true);
};
const handleDeleteButtonClick = (category: BasicCategoryResponse) => {
dialogDeleteCategoryTitle(category.title);
dialogDeleteCategoryId(category.id);
dialogDeleteCategoryOpen(true);
}
const handleDialogContentChange = (content: ChangeCategoryDialogContent) => {
setChangeDialogContent(content)
}
const handleChangeConfirmButtonClick = () => {
if (changeDialogContent.id !== "") {
editCategory({
variables: {
id: changeDialogContent.id,
title: changeDialogContent.title,
description: changeDialogContent.details,
}
})
} else {
addCategory({
variables: {
title: changeDialogContent.title,
description: changeDialogContent.details,
}
})
}
};
return (
<Paper className={classes.root}>
<Typography component={"h2"} variant="h6" color="primary" gutterBottom>Kategorien</Typography>
{categories?.map(category => <AccordionWithEdit
key={category.id}
title={category.title}
description={category.description}
onEditButtonClick={() => handleEditButtonClick(category)}
onDeleteButtonClick={() => handleDeleteButtonClick(category)}
/>
)}
<AddCard handleClick={handleAddClick}/>
<DialogChangeCategory
title={dialogTitle}
confirmButtonText={dialogConfirmButtonText}
open={changeDialogOpen}
content={changeDialogContent}
loading={loading}
handleContentChange={handleDialogContentChange}
handleConfirmButtonClick={handleChangeConfirmButtonClick}
handleClose={() => setChangeDialogOpen(false)}
/>
<DialogDeleteCategory/>
</Paper>
)
}