@instructure/quiz-interactions
Version:
A React UI component Library for quiz interaction types.
118 lines (100 loc) • 3.41 kB
JavaScript
import React from 'react'
import get from 'lodash/get'
import times from 'lodash/times'
import random from 'lodash/random'
import {rule, each} from 'instructure-validations'
import {Text} from '@instructure/ui-text'
import {MATCHING_SLUG} from '../../interaction_slugs'
import InteractionType from '../InteractionType'
import {presenceMessage, noDuplicatesMessage} from '../../util/validationHelpers'
import t from '@instructure/quiz-i18n/format-message'
export default class MatchingInteractionType extends InteractionType {
constructor(obj) {
super()
super.initializeProps(obj)
}
slug = MATCHING_SLUG
translatedName = t('Matching')
defaultProperties = {shuffleRules: {questions: {shuffled: false}}}
getDefaultScoringData = intData => {
const matches = intData.questions.map((question, idx) => {
return {
questionId: question.id,
questionBody: question.itemBody,
answerBody: intData.answers[idx],
}
})
const baseScoringData = {
value: {},
editData: {
matches,
distractors: [],
},
}
const defaultScoringData = intData.questions.reduce((scoringData, c) => {
scoringData.value[c.id] = '' // eslint-disable-line no-param-reassign
return scoringData
}, baseScoringData)
return defaultScoringData
}
getDefaultInteractionData = () => {
const newId = () => random(100000).toString()
const [choiceIdA, choiceIdB, choiceIdC, choiceIdD] = times(4, newId)
return {
questions: [
{id: choiceIdA, itemBody: ''},
{id: choiceIdB, itemBody: ''},
{id: choiceIdC, itemBody: ''},
{id: choiceIdD, itemBody: ''},
],
answers: ['', '', '', ''],
}
}
static validations = (data = {}) => {
const editData = get(data, 'scoringData.editData', {})
const matches = editData.matches || []
const answers = matches.map(match => match.answerBody)
const scoringData = {}
if (matches.length > 0) {
scoringData.editData = {
matches: [
each({
questionBody: [rule('presence', {message: presenceMessage(t('Question'))})],
answerBody: [rule('presence', {message: presenceMessage(t('Answer'))})],
}),
rule('noDuplicates', {
field: 'questionBody',
message: noDuplicatesMessage(t('Question')),
}),
],
distractors: [
rule('noDuplicates', {message: noDuplicatesMessage(t('Distractor'))}),
each(rule('presence', {message: presenceMessage(t('Distractor'))})),
each(rule('noneOf', {blacklist: answers, message: t('Answer is already present')})),
],
}
}
return {scoringData}
}
getDefaultUserResponse() {
return {value: {}}
}
hasResponse(resp, intData) {
const numQuestions = intData.questions.length
const numWithResponse = Object.keys(resp).length
return numQuestions === numWithResponse
}
getRenderedResponse = (responseValue, interactionData) => {
return (
<Text color="primary">
{Object.keys(responseValue)
.map(id => {
const questions = interactionData.questions
const question = questions && questions.find(q => q.id === id)
return `${question ? question.itemBody : ''} - ${responseValue[id]}`
})
.join(', ')}
</Text>
)
}
}