Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix/dyad census and tie strength census #73

Merged
merged 5 commits into from
Feb 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions lib/interviewer/containers/Interfaces/DyadCensus/DyadCensus.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ const DyadCensus = ({
if (isIntroduction) {
// If there are no steps, clicking next should advance the stage
if (stepsState.totalSteps === 0) {
navigationActions.moveForward();
navigationActions.moveForward({ forceChangeStage: true });
return;
}

Expand Down Expand Up @@ -132,6 +132,10 @@ const DyadCensus = ({
}

if (stepsState.isStageStart) {
if (stepsState.totalSteps === 0) {
navigationActions.moveBackward({ forceChangeStage: true });
return;
}
navigationActions.moveBackward();
}

Expand All @@ -146,14 +150,16 @@ const DyadCensus = ({
previousStep,
stepsState.isStageStart,
stepsState.isStart,
stepsState.totalSteps,
]);

const beforeNext = useCallback(
(direction) => {
if (direction === 'backwards') {
back();
} else {
next();
}
next();

return false;
},
Expand Down Expand Up @@ -206,7 +212,7 @@ const DyadCensus = ({
>
<div className="dyad-census__prompt">
<Prompts
currentPrompt={stage.prompts[promptIndex].id}
currentPrompt={stage.prompts[promptIndex]?.id}
prompts={stage.prompts}
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const matchEntry =
(p === prompt && b === pair[0] && a === pair[1]);

export const getIsPreviouslyAnsweredNo = (state, prompt, pair) => {
if (!state || pair.length !== 2) {
if (!Array.isArray(state) || pair.length !== 2) {
return false;
}

Expand All @@ -43,6 +43,9 @@ export const getIsPreviouslyAnsweredNo = (state, prompt, pair) => {

export const stageStateReducer = (state = [], { pair, prompt, value }) => {
// Remove existing entry, if it exists, and add new one on the end
if (!Array.isArray(state) || pair.length !== 2) {
return false;
}
const newState = [
...state.filter((item) => !matchEntry(prompt, pair)(item)),
[prompt, ...pair, value],
Expand Down
98 changes: 50 additions & 48 deletions lib/interviewer/containers/Interfaces/DyadCensus/useSteps.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,44 @@ import { useState } from 'react';

/* given a map of steps, where are we given a specific 'total' step number */
const getSubStep = (steps, nextStep) => {
const [r] = steps.reduce(([result, target], step, index) => {
if (step > target && result === null) {
return [{ step: target, stage: index }];
}

if (step <= target) {
return [result, target - step];
}

return [result, target];
}, [null, nextStep]);
const [r] = steps.reduce(
([result, target], step, index) => {
if (step > target && result === null) {
return [{ step: target, stage: index }];
}

if (step <= target) {
return [result, target - step];
}

return [result, target];
},
[null, nextStep],
);

return r;
};

// state reducer for steps state
const stateReducer = ({
step,
substep,
stage,
direction,
}) => (state) => {
const progress = step > state.progress ? step : state.progress;

return ({
...state,
step,
progress,
substep,
stage,
direction,
isCompletedStep: progress > step,
isStageStart: substep === 0,
isStageEnd: substep >= state.steps[stage] - 1,
isStart: step === 0,
isEnd: step >= state.totalSteps - 1,
});
};
const stateReducer =
({ step, substep, stage, direction }) =>
(state) => {
const progress = step > state.progress ? step : state.progress;

return {
...state,
step,
progress,
substep,
stage,
direction,
isCompletedStep: progress > step,
isStageStart: substep === 0,
isStageEnd: substep >= state.steps[stage] - 1,
isStart: step === 0,
isEnd: step >= state.totalSteps - 1,
};
};

/**
* Models 'substeps' in prompts, which allows us to keep track
Expand All @@ -48,9 +48,7 @@ const stateReducer = ({
*
* @param {array} steps - map of steps per prompt, e.g. [3, 2, 1]
*/
const useSteps = (
steps = [],
) => {
const useSteps = (steps = []) => {
const totalSteps = steps.reduce((count, step) => count + step, 0);

const initialValues = {
Expand All @@ -77,12 +75,14 @@ const useSteps = (

const substep = getSubStep(steps, nextStep);

setState(stateReducer({
step: nextStep,
substep: substep.step,
stage: substep.stage,
direction: 'forward',
}));
setState(
stateReducer({
step: nextStep,
substep: substep.step,
stage: substep.stage,
direction: 'forward',
}),
);
};

const previous = () => {
Expand All @@ -94,12 +94,14 @@ const useSteps = (

const substep = getSubStep(steps, nextStep);

setState(stateReducer({
step: nextStep,
substep: substep.step,
stage: substep.stage,
direction: 'backward',
}));
setState(
stateReducer({
step: nextStep,
substep: substep.step,
stage: substep.stage,
direction: 'backward',
}),
);
};

return [state, next, previous];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ const TieStrengthCensus = (props) => {
const pair = get(pairs, stepsState.substep, null);
const [fromNode, toNode] = getNodePair(nodes, pair);

const navigateActions = useNavigationHelpers();
const navigationActions = useNavigationHelpers();

// hasEdge:
// - false: user denied
Expand All @@ -104,7 +104,7 @@ const TieStrengthCensus = (props) => {
if (isIntroduction) {
// If there are no steps, clicking next should advance the stage
if (stepsState.totalSteps === 0) {
navigateActions.moveForward();
navigationActions.moveForward({ forceChangeStage: true });
return;
}

Expand All @@ -121,7 +121,7 @@ const TieStrengthCensus = (props) => {
}

if (stepsState.isStageEnd) {
navigateActions.moveForward();
navigationActions.moveForward();
}

if (stepsState.isEnd) {
Expand All @@ -133,7 +133,7 @@ const TieStrengthCensus = (props) => {
edgeVariableValue,
hasEdge,
isIntroduction,
navigateActions,
navigationActions,
nextStep,
stepsState.isEnd,
stepsState.isStageEnd,
Expand All @@ -150,7 +150,11 @@ const TieStrengthCensus = (props) => {
}

if (stepsState.isStageStart) {
navigateActions.moveBackward();
if (stepsState.totalSteps === 0) {
navigationActions.moveBackward({ forceChangeStage: true });
return;
}
navigationActions.moveBackward();
}

if (stepsState.isStart) {
Expand All @@ -160,18 +164,20 @@ const TieStrengthCensus = (props) => {
previousStep();
}, [
isIntroduction,
navigateActions,
navigationActions,
previousStep,
stepsState.isStageStart,
stepsState.isStart,
stepsState.totalSteps,
]);

const beforeNext = useCallback(
(direction) => {
if (direction === 'backwards') {
back();
} else {
next();
}
next();

return false;
},
Expand Down Expand Up @@ -224,7 +230,7 @@ const TieStrengthCensus = (props) => {
>
<div className="tie-strength-census__prompt">
<Prompts
currentPrompt={stage.prompts[promptIndex].id}
currentPrompt={stage.prompts[promptIndex]?.id}
prompts={stage.prompts}
/>
</div>
Expand Down Expand Up @@ -259,8 +265,9 @@ const TieStrengthCensus = (props) => {
// Set the max width of the container based on the number of options
// This prevents them getting too wide, but also ensures that they
// expand to take up all available space.
maxWidth: `${(edgeVariableOptions.length + 1) * 20 + 3.6
}rem`,
maxWidth: `${
(edgeVariableOptions.length + 1) * 20 + 3.6
}rem`,
}}
>
<div className="tie-strength-census__options">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export const matchEntry =
(p === prompt && b === pair[0] && a === pair[1]);

export const getIsPreviouslyAnsweredNo = (state, prompt, pair) => {
if (!state || pair.length !== 2) {
if (!Array.isArray(state) || pair.length !== 2) {
return false;
}

Expand All @@ -50,6 +50,9 @@ export const getIsPreviouslyAnsweredNo = (state, prompt, pair) => {

export const stageStateReducer = (state = [], { pair, prompt, value }) => {
// Remove existing entry, if it exists, and add new one on the end
if (!Array.isArray(state) || pair.length !== 2) {
return false;
}
const newState = [
...state.filter((item) => !matchEntry(prompt, pair)(item)),
[prompt, ...pair, value],
Expand Down
14 changes: 10 additions & 4 deletions lib/interviewer/hooks/useNavigationHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ import { parseAsInteger, useQueryState } from 'nuqs';

export type directions = 'forwards' | 'backwards';

type NavigationOptions = {
forceChangeStage?: boolean;
};

export const useNavigationHelpers = () => {
const dispatch = useDispatch();
const skipMap = useSelector(getSkipMap);
Expand Down Expand Up @@ -94,12 +98,13 @@ export const useNavigationHelpers = () => {
[beforeNextFunction],
);

const moveForward = async () => {
const moveForward = async (options?: NavigationOptions) => {
if (!(await checkCanNavigate('forwards'))) {
return;
}

if (isLastPrompt) {
// forceChangeStage used in Dyad Census and Tie Strength Census when there are no steps
if (isLastPrompt || options?.forceChangeStage) {
const nextStage = calculateNextStage();
void setCurrentStage(nextStage);
return;
Expand All @@ -110,12 +115,13 @@ export const useNavigationHelpers = () => {
);
};

const moveBackward = async () => {
const moveBackward = async (options?: NavigationOptions) => {
if (!(await checkCanNavigate('backwards'))) {
return;
}

if (isFirstPrompt) {
// forceChangeStage used in Dyad Census and Tie Strength Census when there are no steps
if (isFirstPrompt || options?.forceChangeStage) {
const previousStage = calculatePreviousStage();
void setCurrentStage(previousStage);
return;
Expand Down
Loading