UNPKG

@instructure/quiz-interactions

Version:

A React UI component Library for quiz interaction types.

153 lines (136 loc) 4.11 kB
import React from 'react' import times from 'lodash/times' import {v4 as uuid} from 'uuid' import {rule, each, onSelf} from 'instructure-validations' import {Text} from '@instructure/ui-text' import {CATEGORIZATION_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 CategorizationInteractionType extends InteractionType { constructor(obj) { super() super.initializeProps(obj) } slug = CATEGORIZATION_SLUG translatedName = t('Categorization') defaultProperties = {} getDefaultScoringData = (intData, scoreMethod = 'all_or_nothing') => { let i = 0 const categories = Object.keys(intData.categories).map(uuid => { const matchingDistractorId = Object.keys(intData.distractors)[i] i++ return { id: uuid, scoringAlgorithm: 'AllOrNothing', scoringData: { value: [matchingDistractorId], }, } }) return { scoreMethod: scoreMethod, value: categories, } } getDefaultInteractionData = () => { const [categoryIdA, categoryIdB, distractorIdA, distractorIdB] = times(4, uuid) return { categoryOrder: [categoryIdA, categoryIdB], categories: { [categoryIdA]: {id: categoryIdA, itemBody: ''}, [categoryIdB]: {id: categoryIdB, itemBody: ''}, }, distractors: { [distractorIdA]: {id: distractorIdA, itemBody: ''}, [distractorIdB]: {id: distractorIdB, itemBody: ''}, }, } } getRenderedResponse = (responseValue, interactionData) => { const distractors = interactionData.distractors return ( <Text color="primary"> {responseValue .map(category => { const c = interactionData.categories[category.id] const categoryValue = c ? c.itemBody : '' const categoryDistractors = category.value .map(distractorId => { const distractorValue = distractors[distractorId] return distractorValue ? distractorValue.itemBody : '' }) .join(', ') return t('Category: {categoryValue} | Distractors: {categoryDistractors}', { categoryValue, categoryDistractors, }) }) .join(', ')} </Text> ) } static useNewValidations = true static validations = data => { const scoringDataValue = data.scoringData.value const categoryAnswers = scoringDataValue.reduce((list, v) => { return list.concat(v.scoringData.value || []) }, []) return { interactionData: { categories: [ each({ itemBody: [ rule('presence', { message: presenceMessage(t('Category')), }), ], }), rule('noDuplicates', { field: 'itemBody', message: noDuplicatesMessage(t('Category')), }), ], distractors: [ each({ itemBody: [ rule('presence', { message: presenceMessage(t('Distractor')), }), ], }), rule('noDuplicates', { field: 'itemBody', message: noDuplicatesMessage(t('Distractor')), }), ], }, scoringData: { value: [ onSelf( rule('listSize', { listOverride: categoryAnswers, min: 1, minMessage: t('You must have at least one answer in a category'), }), ), ], }, } } getDefaultUserResponse(intData) { const categories = Object.keys(intData.categories).map(uuid => { return { id: uuid, value: [], type: 'ArrayText', } }) return {value: categories} } hasResponse(resp) { return resp.some(category => { return category.value.length > 0 }) } }