@instructure/quiz-interactions
Version:
A React UI component Library for quiz interaction types.
109 lines (97 loc) • 3.04 kB
JavaScript
import React from 'react'
import {rule, each, addValidator} from 'instructure-validations'
import {HOT_SPOT_SLUG} from '../../interaction_slugs'
import InteractionType from '../InteractionType'
import {presenceMessage} from '../../util/validationHelpers'
import TargetContainer from '../../components/hotspot/common/TargetContainer'
import Target from '../../components/hotspot/Take/Target'
import t from '@instructure/quiz-i18n/format-message'
import isEqual from 'lodash/isEqual'
const defaultInteractionData = {}
const defaultSoringData = {value: []}
function validateHotSpot(data = {}) {
const scoringData = data.scoringData || {}
if (scoringData.value && scoringData.value.length > 0) {
return {
interactionData: {
imageUrl: [rule('presence', {message: presenceMessage(t('Image'))})],
},
scoringData: {
value: [
rule('listSize', {
minMessage: t('You must draw a hotspot'),
min: 1,
}),
each({
type: [rule('presence', {message: t('You must select a hotspot type')})],
coordinates: [
rule('validateCoordinates', {
minMessage: t('You must draw a hotspot'),
data: scoringData,
}),
],
}),
],
},
}
} else {
const isPolygon = scoringData.value && scoringData.value.type === 'polygon'
const minCoordinates = isPolygon ? 3 : 2
return {
interactionData: {
imageUrl: [rule('presence', {message: presenceMessage(t('Image'))})],
},
scoringData: {
value: {
type: [rule('presence', {message: t('You must select a hotspot type')})],
coordinates: [
rule('listSize', {
minMessage: t('You must draw a hotspot'),
min: minCoordinates,
}),
],
},
},
}
}
}
addValidator('validateCoordinates', (coordinates, options) => {
if (!coordinates) {
return null
}
const {
minMessage,
data: {value},
} = options
let hotspots = Array.isArray(value) ? value : [value]
const matchingCoordinates = hotspots.find(value => {
return isEqual(value.coordinates, coordinates)
})
const min = matchingCoordinates?.type === 'polygon' ? 3 : 2
return coordinates?.length >= min ? null : minMessage
})
export default class HotSpotInteractionType extends InteractionType {
constructor(obj) {
super()
super.initializeProps(obj)
}
slug = HOT_SPOT_SLUG
translatedName = t('Hot Spot')
getDefaultScoringData = () => defaultSoringData
getDefaultInteractionData = () => defaultInteractionData
static validations = validateHotSpot
getDefaultUserResponse() {
return {value: {}}
}
getRenderedResponse = (responseValue, interactionData) => {
return (
<TargetContainer
disabled
coordinates={[responseValue]}
drawingType={Target}
justifyContent="left"
url={interactionData.imageUrl}
/>
)
}
}