boussole-pluss/frontend/store/quiz.ts

156 lines
4.0 KiB
TypeScript

import {defineStore} from 'pinia';
import {useBundleStore} from "~/store/bundle";
import {Axe, useAxeStore} from "~/store/axe";
import type {Question} from "~/store/question";
export interface QuizResponse {
question: string;
score: number;
comment: string;
}
export interface AxeResponses {
axeIdentifier: number;
average: number;
responses: QuizResponse[];
}
export interface Quiz {
id: number;
createdDate: string;
axes: AxeResponses[]
}
export interface Response {
axeId: number;
questionId: number;
score?: number;
comment?: string;
}
export interface QuizRate { // ?
score?: number;
comment?: string;
}
export const useQuizStore = defineStore('quiz', {
state: () => ({
axes: ref<Axe[]>([]),
questions: ref<Map<number, Question[]>>(new Map()),
responses: ref<Map<number, QuizRate>>(new Map()),
questionsRatedPerAxe: ref<Map<number, Array<{ questionId: number; rated: boolean }>>>(new Map())
}),
actions: {
initialize() {
const bundle = useBundleStore().selectedBundle;
return useAxeStore().findAxes().then(axes => {
const promises: any[] = [];
this.axes = axes;
axes.forEach(axe => {
promises.push(
useApi(`/bundles/${bundle.id}/questions/search`, {
params: {
axeId: axe.id
}
})
.then((questions: Question[]) => {
return {
axeId: axe.identifier,
questions: questions
};
}));
});
Promise.all(promises).then((axeQuestions) => {
axeQuestions.forEach(axeQuestion => {
this.questions.set(axeQuestion.axeId, axeQuestion.questions)
});
this.questions.forEach((questions, axeId) => this.questionsRatedPerAxe.set(axeId, questions.map(value => {
return {
questionId: value.id,
rated: this.responses.has(value.id)
}
})));
});
});
},
resetResponses() {
this.responses.clear();
this.questionsRatedPerAxe.forEach((questions) => {
questions
.map(value => {
value.rated = false;
return value;
});
});
},
updateScoreResponse(response: Response) {
const previous = this.responses.get(response.questionId);
if (previous) {
this.responses.set(response.questionId, {
comment: previous.comment,
score: response.score
});
} else {
this.responses.set(response.questionId, {
score: response.score
});
}
const questionsRated = this.questionsRatedPerAxe.get(response.axeId);
if (questionsRated) {
questionsRated
.filter(value => value.questionId === response.questionId)
.map(value => {
value.rated = true;
return value;
});
}
// else should not happen
},
updateCommentResponse(response: Response) {
const previous = this.responses.get(response.questionId);
if (previous) {
this.responses.set(response.questionId, {
score: previous.score,
comment: response.comment
});
} else {
this.responses.set(response.questionId, {
comment: response.comment
});
}
},
findQuizzes(bundleId: number) {
return useApi("/quizzes/search", {
params: {
bundleId: bundleId,
sort: "createdDate,desc"
}
});
},
findById(quizId: number) {
return useApi(`/quizzes/${quizId}`);
},
save() {
const responses = [];
this.responses.forEach((value, key) => {
responses.push({
score: value.score ? value.score : 0,
comment: value.comment,
questionId: key
});
});
return useApi("/quizzes", {
method: "POST",
body: {responses, bundleId: useBundleStore().selectedBundle.id}
}).finally(() => this.resetResponses());
}
}
});