aboutsummaryrefslogtreecommitdiff
path: root/src/models
diff options
context:
space:
mode:
Diffstat (limited to 'src/models')
-rw-r--r--src/models/answerSlice.ts21
-rw-r--r--src/models/questionSlice.ts58
2 files changed, 50 insertions, 29 deletions
diff --git a/src/models/answerSlice.ts b/src/models/answerSlice.ts
index aada48c..cd20dbc 100644
--- a/src/models/answerSlice.ts
+++ b/src/models/answerSlice.ts
@@ -1,4 +1,6 @@
import {createSelector, createSlice, PayloadAction} from '@reduxjs/toolkit'
+import {Selector} from 'react-redux'
+
// import {Answer} from "@/models/answer.ts";
// import {stringify} from "querystring";
import {RootState} from '@/store'; // your root state type
@@ -183,24 +185,13 @@ export const {
} = answerSlice.actions;
export default answerSlice.reducer
-export const answerForQuestion = (state: RootState, question: ProfileQuestion) => state.answers[question.question_id] ?? {
- values: [],
- error_msg: "",
- complete: false,
- processing: false
-} as Answer;
-export const makeSelectChoicesByQuestion = (question: ProfileQuestion) =>
+export const selectAnswerForQuestion = (
+ question: ProfileQuestion
+): Selector<RootState, Answer | null> =>
createSelector(
(state: RootState) => state.answers,
(answers) => {
- // const question = questions.find(q => q.id === questionId);
- // return question?.choices ?? [];
- return answers[question.question_id] ?? {
- values: [],
- error_msg: "",
- complete: false,
- processing: false
- } as Answer;
+ return answers[question.question_id] || null
}
); \ No newline at end of file
diff --git a/src/models/questionSlice.ts b/src/models/questionSlice.ts
index ec9f84a..9543088 100644
--- a/src/models/questionSlice.ts
+++ b/src/models/questionSlice.ts
@@ -2,6 +2,8 @@ import {createSelector, createSlice, PayloadAction} from '@reduxjs/toolkit'
import type {RootState} from '@/store'
import {UpkQuestion} from "@/api";
import {Answer} from "@/models/answerSlice.ts";
+import {assert} from "@/lib/utils.ts"
+import {Selector} from "react-redux";
export interface ProfileQuestion extends UpkQuestion {
active: false
@@ -59,11 +61,18 @@ export const selectQuestions = (state: RootState) => state.questions
export const selectActiveQuestion = (state: RootState) => state.questions.find(i => i.active)
export const selectAnswers = (state: RootState) => state.answers
-export const selectNextAvailableQuestion = createSelector(
+export const selectFirstAvailableQuestion = createSelector(
[selectQuestions, selectAnswers],
- (questions, answers) => {
+ (questions, answers): Selector<RootState, ProfileQuestion | null> => {
+ /* This is used when the app loads up the Questions page and we
+ need to find the first Question that we'll present to
+ the Respondent.
+
+ If there are any questions marked as active, show that
+ first. However, if there are not.. go ahead and search for
+ the next Question without an Answer or an Answer that isn't complete
+ */
- // -- Check if there are any questions marked as active
const active = questions.find(q => q.active)
if (active) {
return active
@@ -71,23 +80,44 @@ export const selectNextAvailableQuestion = createSelector(
let res = questions.filter(q => {
const a: Answer | undefined = answers[q.question_id]
- return !a || a.complete === false
+ return !a || !a.complete
})
- // return res.reduce((min, q) =>
- // !min || q.order < min.order ? q : min,
- // null as typeof res[0] | null
- // )
return res[0] || null
}
)
+export const selectNextAvailableQuestion = createSelector(
+ [selectQuestions, selectAnswers],
+ (questions, answers): Selector<RootState, ProfileQuestion | null> => {
+ /* This takes the current active position and finds the next available
+ question to answer.
-export const selectQuestionById = (questionId: string) =>
- createSelector(
- (state: RootState) => state.questions,
- (questions) => {
- return questions.find(q => q.question_id === questionId);
+ Check if there are any questions marked as active. If there are not,
+ the Questions page didn't load yet and/or we don't know what the Respondent
+ is currently looking at... so we can't determine what is next. Immediately fail.
+ */
+ const active = questions.find(q => q.active)
+ assert(active, "Must have an active Question")
+ const active_index = questions.findIndex(q => q.question_id === active.question_id)
+
+ // Find any Questions without Answers, or Answers that are not complete
+ // that are positioned after the currently active Question
+ let found = questions.find((q, q_idx) => {
+ const a: Answer | undefined = answers[q.question_id]
+ return q_idx > active_index && (!a || !a.complete)
+ })
+
+ if (!found) {
+ // No eligible questions were found after the current active position, so
+ // go back and look for any before the current active position.
+ found = questions.find((q, q_idx) => {
+ const a: Answer | undefined = answers[q.question_id]
+ return q_idx < active_index && (!a || !a.complete)
+ })
}
- ); \ No newline at end of file
+
+ return found || null
+ }
+)