kandimat/redaktions-app/src/components/DialogChangeQuestion.tsx
2020-12-30 22:46:26 +01:00

136 lines
4.9 KiB
TypeScript

import React, {useState} from 'react';
import Dialog from '@material-ui/core/Dialog';
import DialogContent from '@material-ui/core/DialogContent';
import DialogTitle from '@material-ui/core/DialogTitle';
import {DialogActionBar} from "./DialogActionBar";
import {DialogTitleAndDetails} from "./DialogTitleAndDetails";
import {makeVar, useMutation, useQuery, useReactiveVar} from "@apollo/client";
import {useSnackbar} from "notistack";
import {
ADD_QUESTION,
AddQuestionResponse,
AddQuestionVariables,
EDIT_QUESTION,
EditQuestionResponse,
EditQuestionVariables
} from "../backend/mutations/question";
import {
BasicQuestionFragment,
BasicQuestionResponse,
GET_QUESTION_BY_ID,
GetQuestionByIdResponse,
GetQuestionByIdVariables
} from "../backend/queries/question";
import CategorySelectionMenu from "./CategorySelectionMenu";
import {GET_ALL_CATEGORIES, GetAllCategoriesResponse} from "../backend/queries/category";
export const dialogChangeQuestionId = makeVar<string>("");
export const dialogChangeQuestionOpen = makeVar<boolean>(false);
export default function DialogChangeQuestion() {
const [addMode, setAddMode] = useState(true);
const [title, setTitle] = useState("");
const [details, setDetails] = useState("");
const [categoryRowId, setCategoryRowId] = useState<number | null>(null);
const questionId = useReactiveVar(dialogChangeQuestionId);
const open = useReactiveVar(dialogChangeQuestionOpen);
const {enqueueSnackbar} = useSnackbar();
useQuery<GetQuestionByIdResponse, GetQuestionByIdVariables>(GET_QUESTION_BY_ID, {
variables: {
id: questionId,
},
onCompleted: (data => {
setAddMode(!data.question && !questionId)
setTitle(data.question?.title || "");
setDetails(data.question?.description || "");
setCategoryRowId(data.question?.categoryByCategoryRowId?.rowId || null)
})
})
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"})
dialogChangeQuestionOpen(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"}),
onCompleted: (response) => {
if (response.createQuestion) {
enqueueSnackbar("Frage erfolgreich hinzugefügt.", {variant: "success"})
dialogChangeQuestionOpen(false);
} else {
enqueueSnackbar("Ein Fehler ist aufgetreten, versuche es erneut.", {variant: "error"})
}
},
update: (cache, {data}) => {
cache.modify({
fields: {
allQuestions(existingQuestions = {nodes: []}) {
const newQuestionRef = cache.writeFragment<BasicQuestionResponse | undefined>({
data: data?.createQuestion?.question,
fragment: BasicQuestionFragment,
fragmentName: "BasicQuestionFragment",
});
return {nodes: [...existingQuestions.nodes, newQuestionRef]};
}
}
});
}
});
const handleConfirmButtonClick = () => {
if (addMode) {
addQuestion({
variables: {
title,
description: details,
categoryRowId: categoryRowId,
}
})
} else {
editQuestion({
variables: {
id: questionId,
title: title,
description: details,
categoryRowId: categoryRowId,
}
})
}
}
return (
<Dialog open={open} onClose={() => dialogChangeQuestionOpen(false)} aria-labelledby="form-dialog-title">
<DialogTitle id="form-dialog-title">
{addMode ? "Neue Frage erstellen" : "Frage bearbeiten"}
</DialogTitle>
<DialogContent>
<DialogTitleAndDetails
title={title}
details={details}
onTitleChange={newTitle => setTitle(newTitle)}
onDetailsChange={newDetails => setDetails(newDetails)}
/>
<CategorySelectionMenu
selectedCategoryId={categoryRowId}
categories={categories}
handleCategoryChange={(categoryId) => setCategoryRowId(categoryId)}
/>
</DialogContent>
<DialogActionBar
onClose={() => dialogChangeQuestionOpen(false)}
onConfirmButtonClick={handleConfirmButtonClick}
confirmButtonText={addMode ? "Erstellen" : "Speichern"}
loading={addMode ? addLoading : editLoading}
/>
</Dialog>
);
}