From fd1dd8624a165a6c6e874c1dd5f5eb9414153fa0 Mon Sep 17 00:00:00 2001 From: nflnkr <105123049+nflnkr@users.noreply.github.com> Date: Sat, 10 Feb 2024 19:25:06 +0300 Subject: [PATCH] refactor branching logic remove result question calculation --- src/App.tsx | 4 +- src/stores/quizView/store.ts | 4 +- src/utils/hooks/useQuestionFlowControl.ts | 91 +++++++---------------- 3 files changed, 32 insertions(+), 67 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 1247bea..2db90d5 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -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; diff --git a/src/stores/quizView/store.ts b/src/stores/quizView/store.ts index 0278aab..ac92cf4 100644 --- a/src/stores/quizView/store.ts +++ b/src/stores/quizView/store.ts @@ -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; } diff --git a/src/utils/hooks/useQuestionFlowControl.ts b/src/utils/hooks/useQuestionFlowControl.ts index 33d65bd..7b59ecf 100644 --- a/src/utils/hooks/useQuestionFlowControl.ts +++ b/src/utils/hooks/useQuestionFlowControl.ts @@ -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,