Skip to content

Commit

Permalink
wip: allow submission of incompletely answered selection questions
Browse files Browse the repository at this point in the history
  • Loading branch information
sjschlapbach committed Jan 14, 2025
1 parent 3a74b12 commit 5909a65
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,10 @@ function GroupActivityStack({
type: ElementType.Selection,
selectionResponse: Object.values(
value.response!
).filter((entry) => typeof entry !== 'undefined'),
).filter(
(entry) =>
typeof entry !== 'undefined' && entry !== -1
),
}
} else {
return {
Expand Down
9 changes: 7 additions & 2 deletions apps/func-response-processor/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -361,14 +361,19 @@ const serviceBusTrigger = async function (
}
case 'SELECTION': {
response.selection.forEach((answerId: number) => {
// skipped input fields should not be considered
if (answerId === -1) {
return
}

redisMulti.hincrby(`${instanceKey}:results`, String(answerId), 1)
})
redisMulti.hincrby(`${instanceKey}:results`, 'participants', 1)

if (participantData) {
const pointsPercentage = gradeQuestionSelection({
numberOfInputs: parseInt(instanceInfo.numberOfInputs),
response: response.selection,
response: response.selection.filter((r: number) => r !== -1), // filter out skipped response fields
correctAnswers: parsedSolutions,
})

Expand Down Expand Up @@ -408,7 +413,7 @@ const serviceBusTrigger = async function (
redisMulti.hset(
`${instanceKey}:responses`,
participantData.sub,
response.selection
response.selection.filter((r: number) => r !== -1) // filter out skipped response fields
)
redisMulti.hincrby(
`${sessionKey}:b:${sessionBlockId}:lb`,
Expand Down
4 changes: 3 additions & 1 deletion packages/graphql/src/services/stacks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2791,7 +2791,9 @@ async function respondToElement({
{
courseId: courseId,
id: response.instanceId,
response: { selection: response.selectionResponse },
response: {
selection: response.selectionResponse?.filter((r) => r !== -1), // only forward valid responses
},
answerTime,
participation,
skipTracking,
Expand Down
12 changes: 3 additions & 9 deletions packages/shared-components/src/StudentElement.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export type InstanceStackStudentResponseType =
}
| {
type: ElementType.Selection
response?: Record<number, number | undefined>
response?: Record<number, number>
valid?: boolean
evaluation?: InstanceEvaluation
}
Expand Down Expand Up @@ -290,14 +290,8 @@ function StudentElement({
options={element.elementData.options}
response={
typeof studentResponse !== 'undefined'
? (studentResponse[element.id]?.response as Record<
number,
number | undefined
>)
: (singleStudentResponse.response as Record<
number,
number | undefined
>)
? (studentResponse[element.id]?.response as Record<number, number>)
: (singleStudentResponse.response as Record<number, number>)
}
valid={
typeof studentResponse !== 'undefined'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import Select from 'react-select'
import { twMerge } from 'tailwind-merge'

interface SELECTIONAnswerOptionsProps {
responses: Record<number, number | undefined>
onChange: (newValue: Record<number, number | undefined>) => void
responses: Record<number, number>
onChange: (newValue: Record<number, number>) => void
options: SelectionQuestionOptions
elementIx: number
disabled: boolean
Expand All @@ -24,9 +24,9 @@ function SELECTIONAnswerOptions({
}: SELECTIONAnswerOptionsProps) {
const t = useTranslations()

// get the selected options, which are not undefined
// get the selected options, which are not unselected
const selectedValues = Object.values(responses).filter(
(selectedValue) => selectedValue !== undefined
(selectedValue) => selectedValue !== -1
)

// compute selection options for the select field
Expand Down Expand Up @@ -82,7 +82,7 @@ function SELECTIONAnswerOptions({
instanceId={`selection-${elementIx + 1}-field-${Number(inputIndex) + 1}`}
isDisabled={disabled}
value={
selectedValue
typeof selectedValue !== 'undefined' && selectedValue !== -1
? { label: selectedLabel, value: selectedValue }
: undefined
}
Expand Down
9 changes: 5 additions & 4 deletions packages/shared-components/src/utils/validateResponse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,14 @@ export function validateFreeTextResponse({
export function validateSelectionResponse({
response,
}: {
response?: Record<number, number | undefined>
response?: Record<number, number>
}) {
// ensure that all select components contain a submission value and that all values are unique
// ensure that at least one option is selected and that selected answer options are unique
if (
!response ||
Object.values(response).some((value) => typeof value === 'undefined') ||
new Set(Object.values(response)).size !== Object.values(response).length
Object.values(response).every((value) => value === -1) ||
new Set(Object.values(response).filter((r) => r !== -1)).size !==
Object.values(response).filter((r) => r !== -1).length
) {
return false
}
Expand Down

0 comments on commit 5909a65

Please sign in to comment.