156 lines
4.0 KiB
TypeScript
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());
|
|
}
|
|
}
|
|
});
|