kandimat/redaktions-app/src/backend/mutations/answer.ts
2021-01-09 12:49:28 +01:00

165 lines
3.7 KiB
TypeScript

import {
ApolloCache,
FetchResult,
gql,
Reference,
StoreObject,
} from "@apollo/client";
import {
FullAnswerFragment,
FullAnswerResponse,
QuestionAnswerResponse,
} from "../queries/answer";
import { CandidatePosition } from "../../components/CandidatePositionLegend";
export const EDIT_ANSWER = gql`
mutation UpdateAnswer($id: ID!, $position: Int, $text: String) {
updateAnswer(
input: { id: $id, answerPatch: { position: $position, text: $text } }
) {
answer {
...FullAnswerFragment
}
}
}
${FullAnswerFragment}
`;
export interface EditAnswerResponse {
updateAnswer: EditAnswerPayload | null;
}
export interface EditAnswerPayload {
answer: FullAnswerResponse;
__typename: "UpdateAnswerPayload";
}
export interface EditAnswerVariables {
id: string;
position?: CandidatePosition;
text?: string | null;
}
export const ADD_ANSWER = gql`
mutation AddAnswer(
$questionRowId: Int!
$personRowId: Int!
$position: Int!
$text: String
) {
createAnswer(
input: {
answer: {
questionRowId: $questionRowId
personRowId: $personRowId
position: $position
text: $text
}
}
) {
answer {
...FullAnswerFragment
}
}
}
${FullAnswerFragment}
`;
export interface AddAnswerResponse {
createAnswer: AddAnswerPayload | null;
}
export interface AddAnswerPayload {
answer: FullAnswerResponse;
__typename: "CreateAnswerPayload";
}
export interface AddAnswerVariables {
questionRowId: number;
personRowId: number;
position: CandidatePosition;
text?: string | null;
}
const matchesStoreFieldName = (
storeFieldName: string,
personRowId: number,
questionRowId: number
): boolean => {
const fullName = `answerByQuestionRowIdAndPersonRowId({"personRowId":${personRowId},"questionRowId":${questionRowId}})`;
return fullName === storeFieldName;
};
interface NodesCacheRefs {
nodes: Array<Reference | StoreObject>;
}
const addAnswerToQuestion = (
cache: ApolloCache<AddAnswerResponse>,
question: QuestionAnswerResponse,
newAnswerRef: Reference
) => {
cache.modify({
id: cache.identify({ ...question }),
fields: {
answersByQuestionRowId: (
answerRefs: NodesCacheRefs = { nodes: [] }
): NodesCacheRefs => {
console.log(answerRefs);
return { nodes: [...answerRefs.nodes, newAnswerRef] };
},
},
});
};
const addAnswerToRootField = (
cache: ApolloCache<AddAnswerResponse>,
newAnswerRef: Reference,
personRowId: number,
questionRowId: number
) => {
cache.modify({
fields: {
answerByQuestionRowIdAndPersonRowId: (
answerRefs: Reference | StoreObject | null = null,
{ storeFieldName }
): Reference | StoreObject | void => {
if (matchesStoreFieldName(storeFieldName, personRowId, questionRowId)) {
return newAnswerRef;
}
},
},
});
};
const writeAnswerToCache = (
cache: ApolloCache<AddAnswerResponse>,
answer: FullAnswerResponse
): Reference | undefined => {
return cache.writeFragment<FullAnswerResponse>({
data: answer,
fragment: FullAnswerFragment,
fragmentName: "FullAnswerFragment",
});
};
export const updateCacheAfterAddingAnswer = (
cache: ApolloCache<AddAnswerResponse>,
{ data }: FetchResult<AddAnswerResponse>,
question: QuestionAnswerResponse
) => {
const answer = data?.createAnswer?.answer;
if (answer) {
const newAnswerRef = writeAnswerToCache(cache, answer);
if (newAnswerRef) {
addAnswerToQuestion(cache, question, newAnswerRef);
addAnswerToRootField(
cache,
newAnswerRef,
answer.personRowId,
answer.questionRowId
);
}
}
};