refactor branching logic

remove result question calculation
This commit is contained in:
nflnkr 2024-02-10 19:25:06 +03:00
parent c1ccc5d7c5
commit fd1dd8624a
3 changed files with 32 additions and 67 deletions

@ -5,8 +5,8 @@ import QuizAnswerer from "./QuizAnswerer";
import { QuizIdContext } from "./contexts/QuizIdContext";
import { RootContainerWidthContext } from "./contexts/RootContainerWidthContext";
const defaultQuizId = "45ef7f9c-784d-4e58-badb-f6b337f08ba0";
const defaultQuizId = "45ef7f9c-784d-4e58-badb-f6b337f08ba0"; // branching
// const defaultQuizId = "a9d31460-132a-4479-a3f0-90241498b6f9"; // linear
export default function App() {
const quizId = useParams().quizId ?? defaultQuizId;

@ -6,7 +6,7 @@ import { devtools } from "zustand/middleware";
import type { Moment } from "moment";
import { QuizStep } from "@model/settingsData";
type Answer = {
type QuestionAnswer = {
questionId: string;
answer: string | string[] | Moment;
};
@ -17,7 +17,7 @@ type OwnVariant = {
};
interface QuizViewStore {
answers: Answer[];
answers: QuestionAnswer[];
ownVariants: OwnVariant[];
currentQuizStep: QuizStep;
}

@ -1,9 +1,9 @@
import { QuizQuestionResult } from "@model/questionTypes/result";
import { AnyTypedQuizQuestion } from "@model/questionTypes/shared";
import { setCurrentQuizStep, useQuizViewStore } from "@stores/quizView/store";
import { useCallback, useDebugValue, useMemo, useState } from "react";
import { isResultQuestionEmpty } from "../../pages/ViewPublicationPage/tools/checkEmptyData";
import { useQuizData } from "./useQuizData";
import moment from "moment";
export function useQuestionFlowControl() {
@ -31,41 +31,19 @@ export function useQuestionFlowControl() {
}
const nextQuestionId = useMemo(() => {
console.log("Смотрим какой вопрос будет дальше. Что у нас сегодня вкусненького? Щя покажу от какого вопроса мы ищем следующий шаг");
console.log(currentQuestion);
console.log("От вот этого /|");
const questionAnswer = answers.find(({ questionId }) => questionId === currentQuestion.id);
//вопрос обязателен, анализируем ответ и условия ветвления
if (answers.length) {
let readyBeNextQuestion = "";
const answer = answers.find(({ questionId }) => questionId === currentQuestion.id);
if (questionAnswer && !moment.isMoment(questionAnswer.answer)) {
const userAnswers = Array.isArray(questionAnswer.answer) ? questionAnswer.answer : [questionAnswer.answer];
currentQuestion.content.rule.main.forEach(({ next, rules }) => {
const longerArray = Math.max(
rules[0].answers.length,
answer?.answer && Array.isArray(answer?.answer) ? answer?.answer.length : [answer?.answer].length
);
for (let i = 0; i < longerArray; i++) {
if (Array.isArray(answer?.answer)) {
if (answer?.answer.find((item) => String(item === rules[0].answers[i]))) {
readyBeNextQuestion = next; // Ес­ли хоть один эле­мент от­ли­ча­ет­ся, мас­си­вы не рав­ны
}
return;
}
if (String(rules[0].answers[i]) === answer?.answer) {
readyBeNextQuestion = next; // Ес­ли хоть один эле­мент от­ли­ча­ет­ся, мас­си­вы не рав­ны
}
for (const branchingRule of currentQuestion.content.rule.main) {
if (userAnswers.some(answer => branchingRule.rules[0].answers.includes(answer))) {
return branchingRule.next;
}
});
if (readyBeNextQuestion) return readyBeNextQuestion;
}
}
if (!currentQuestion.required) {//вопрос не обязателен и не нашли совпадений между ответами и условиями ветвления
console.log("вопрос не обязателен ищем дальше");
const defaultNextQuestionId = currentQuestion.content.rule.default;
if (defaultNextQuestionId.length > 1 && defaultNextQuestionId !== " ") return defaultNextQuestionId;
//Вопросы типа страница, ползунок, своё поле для ввода и дата не могут иметь больше 1 ребёнка. Пользователь не может настроить там дефолт
@ -77,7 +55,6 @@ export function useQuestionFlowControl() {
}
//ничё не нашли, ищем резулт
console.log("ничё не нашли, ищем резулт ");
return questions.find(q => {
return q.type === "result" && q.content.rule.parentId === currentQuestion.content.id;
})?.id;
@ -91,42 +68,31 @@ export function useQuestionFlowControl() {
);
const nextQuestion = linearQuestionIndex !== null
? questions[linearQuestionIndex + 1]
? questions[linearQuestionIndex + 1] ?? questions.find(question =>
question.type === "result" && question.content.rule.parentId === "line"
)
: questions.find(q => q.id === nextQuestionId || q.content.id === nextQuestionId);
const resultQuestion = useMemo(() => {
let resultQuestion: QuizQuestionResult | undefined;
if (currentQuestion.type === "result") resultQuestion = currentQuestion;
if (settings.cfg.haveRoot) {
resultQuestion = questions.find((question): question is QuizQuestionResult => {
return question.type === "result" && question.content.rule.parentId === currentQuestion.content.id;
});
} else {
resultQuestion = questions.find((question): question is QuizQuestionResult => {
return question.type === "result" && question.content.rule.parentId === "line";
});
}
if (resultQuestion && !isResultQuestionEmpty(resultQuestion)) return resultQuestion;
}, [currentQuestion, questions, settings.cfg.haveRoot]);
const showResult = useCallback(() => {
if (!resultQuestion) throw new Error("Result question not found");
setCurrentQuestion(resultQuestion);
if (settings.cfg.resultInfo.showResultForm === "after") {
if (nextQuestion?.type !== "result") throw new Error("Current question is not result");
if (isResultQuestionEmpty(nextQuestion)) {
setCurrentQuizStep("contactform");
return;
}
}, [resultQuestion, settings.cfg.resultInfo.showResultForm]);
setCurrentQuestion(nextQuestion);
if (settings.cfg.resultInfo.showResultForm === "after") setCurrentQuizStep("contactform");
}, [nextQuestion, settings.cfg.resultInfo.showResultForm]);
const showResultAfterContactForm = useCallback(() => {
if (!resultQuestion) throw new Error("Result question not found");
if (resultQuestion.type !== "result") throw new Error("Current question is not a result question");
if (currentQuestion.type !== "result") throw new Error("Current question is not result");
if (isResultQuestionEmpty(currentQuestion)) {
console.warn("Result question is empty");
return;
}
setCurrentQuizStep("question");
}, [resultQuestion]);
}, [currentQuestion]);
const moveToPrevQuestion = useCallback(() => {
if (!prevQuestion) throw new Error("Previous question not found");
@ -156,15 +122,14 @@ export function useQuestionFlowControl() {
useDebugValue({
linearQuestionIndex,
currentQuestion,
prevQuestion,
nextQuestion,
resultQuestion,
currentQuestionTitle: currentQuestion.title,
prevQuestionTitle: prevQuestion?.title,
nextQuestionTitle: nextQuestion?.title,
});
return {
currentQuestion,
currentQuestionStepNumber: linearQuestionIndex && linearQuestionIndex + 1,
currentQuestionStepNumber: linearQuestionIndex === null ? null : linearQuestionIndex + 1,
isNextButtonEnabled,
isPreviousButtonEnabled,
moveToPrevQuestion,