UNPKG

@instructure/quiz-interactions

Version:

A React UI component Library for quiz interaction types.

137 lines (125 loc) 4.12 kB
/** @jsx jsx */ import {Component} from 'react' import PropTypes from 'prop-types' import get from 'lodash/get' import {Text} from '@instructure/ui-text' import {jsx} from '@instructure/emotion' import t from '@instructure/quiz-i18n/format-message' import {ItemBodyWrapper} from '@instructure/quiz-rce/components/ItemBodyWrapper/index' import {RichContentRenderer} from '@instructure/quiz-rce/components/RichContentRenderer/index' import {SubjectiveFeedback} from '@instructure/quiz-results-feedback' import {WordCount} from '../helpers/WordCount' import generateStyle from './styles' import generateComponentTheme from './theme' import {withStyleOverrides} from '@instructure/quiz-common/util/withStyleOverrides' /** --- category: Essay --- Essay Result component ```jsx_example <SettingsSwitcher locales={LOCALES}> <EssayResult itemBody="Why did the Roman Empire fall?" interactionData={{ rce: true, spellCheck: true, wordCount: true, wordLimitEnabled: true, wordLimitMax: 10, wordLimitMin: 1 }} scoredData={{ value: 'goths and food shortage', gradeStatus: 'waiting' }} scoringData={{ value: 'these are the grading notes' }} /> </SettingsSwitcher> ``` **/ @withStyleOverrides(generateStyle, generateComponentTheme) export default class EssayResult extends Component { static displayName = 'EssayResult' static componentId = `Quizzes${this.displayName}` static propTypes = { interactionData: PropTypes.object.isRequired, itemBody: PropTypes.string.isRequired, scoredData: PropTypes.shape({ gradeStatus: PropTypes.oneOf(['waiting', 'graded', 'correct', 'incorrect']), value: PropTypes.string, }).isRequired, scoringData: PropTypes.object, styles: PropTypes.object, } static defaultProps = { scoredData: {value: 'waiting'}, scoringData: void 0, itemResultsModifications: void 0, } getGradeStatus() { const workingGradeStatus = get(this.props, [ 'itemResultsModifications', 'scoredData', 'gradeStatus', ]) return workingGradeStatus || this.props.scoredData.gradeStatus } renderGradingNotes() { const gradingNotes = this.props.scoringData && this.props.scoringData.value if (gradingNotes) { return ( <div css={this.props.styles.gradingNotesWrapper}> <Text color="primary" size="small" weight="bold"> {t('Grading Notes')} </Text> <div> <Text color="primary" size="small"> {gradingNotes} </Text> </div> </div> ) } } renderEssay() { const {value} = this.props.scoredData const rceEnabled = this.props?.interactionData?.rce === true let content if (typeof value === 'undefined') { content = t('(response not displayed)') } else if (!value || (typeof value === 'object' && Object.keys(value).length === 0)) { content = t('(no answer)') } else { content = value } if (this.props.interactionData.rce) { return <RichContentRenderer customStyles={this.props.styles.userResponse} content={content} /> } return ( <div css={{...this.props.styles.userResponse, whiteSpace: !rceEnabled ? 'pre-wrap' : undefined}} > <Text color="primary" size="small"> {content} </Text> </div> ) } render() { const gradeStatus = this.getGradeStatus() const {interactionData} = this.props return ( <ItemBodyWrapper itemBody={this.props.itemBody}> <SubjectiveFeedback gradeStatus={gradeStatus}>{this.renderEssay()}</SubjectiveFeedback> <WordCount rce={interactionData.rce} isEditing={false} essay={this.props.scoredData.value} wordCount={interactionData.wordCount} wordLimitEnabled={interactionData.wordLimitEnabled} wordLimitMin={interactionData.wordLimitMin} wordLimitMax={interactionData.wordLimitMax} /> {this.renderGradingNotes()} </ItemBodyWrapper> ) } }