@instructure/quiz-grading
Version:
The Quiz React SDK by Instructure Inc.
140 lines (123 loc) • 4.75 kB
JavaScript
/** @jsx jsx */
import {Component} from 'react'
import PropTypes from 'prop-types'
import partial from 'lodash/partial'
import ImmutablePropTypes from 'react-immutable-proptypes'
import {jsx} from '@instructure/emotion'
import {View} from '@instructure/ui-view'
import {IconArrowOpenEndLine} from '@instructure/ui-icons'
import {ResultStimulus} from '@instructure/quiz-core/common/components/resources/sessionItemResult/ResultStimulus/index'
import {generateDisplayPositions} from '@instructure/quiz-core/common/util/generateDisplayPositions'
import {Flex} from '@instructure/quiz-common/components/Flex/index'
import {GRADE_BY_QUESTION_NEXT} from '@instructure/quiz-common/constants'
import {withStyleOverrides} from '@instructure/quiz-common/util/withStyleOverrides'
import SessionItemResultWrapper from '../SessionItemResultWrapper'
import generateStyle from './styles'
import t from '@instructure/quiz-i18n/format-message'
class BaseSessionItemResultList extends Component {
static displayName = 'SessionItemResultList'
static componentId = `Quizzes${this.displayName}`
static propTypes = {
activeItemId: PropTypes.string,
gradeByQuestionEnabled: PropTypes.bool,
handleChangePoints: PropTypes.func.isRequired,
handleChangeFeedback: PropTypes.func.isRequired,
handleChangeGradeStatus: PropTypes.func.isRequired,
postToParent: PropTypes.func.isRequired,
quizSessionId: PropTypes.string.isRequired,
regradingIdentifier: PropTypes.string.isRequired,
renderUpdateButton: PropTypes.func.isRequired,
scrollToItem: PropTypes.func.isRequired,
sessionItems: ImmutablePropTypes.list.isRequired,
withConfirm: PropTypes.func.isRequired,
styles: PropTypes.object,
}
static defaultProps = {
activeItemId: null,
gradeByQuestionEnabled: false,
}
componentDidMount() {
this.scrollToActiveItem()
}
componentDidUpdate(prevProps) {
if (prevProps.quizSessionId !== this.props.quizSessionId) {
this.scrollToActiveItem()
}
}
scrollToActiveItem() {
const {activeItemId, gradeByQuestionEnabled, sessionItems} = this.props
if (gradeByQuestionEnabled && activeItemId) {
const sessionItem = sessionItems.find(si => si.itemRecord.id === activeItemId)
if (sessionItem) {
this.props.scrollToItem(sessionItem.id)
} else {
const continueText = (
<Flex alignItems="center">
<View margin="0 x-small 0 0">{t('Next Student')}</View>
<IconArrowOpenEndLine />
</Flex>
)
this.props.withConfirm(this.nextStudent, {
continueText,
text: t(
'The active student does not have this question. Please use the Next Student button to proceed.',
),
title: t('Question Not Available'),
})
}
}
}
nextStudent = () => {
this.props.postToParent({subject: GRADE_BY_QUESTION_NEXT})
}
renderSessionItemResultWrapper = (sessionItem, shouldRenderTopBorder) => {
const {
handleChangePoints,
handleChangeFeedback,
handleChangeGradeStatus,
quizSessionId,
regradingIdentifier,
renderUpdateButton,
} = this.props
const result = sessionItem.sessionItemResult
const item = sessionItem.getItem()
return (
<SessionItemResultWrapper
handleChangeFeedback={handleChangeFeedback}
handleChangeGradeStatus={partial(handleChangeGradeStatus, result.id, item.id)}
handleChangePoints={partial(handleChangePoints, result.id, item.id)}
item={item}
key={sessionItem.id}
quizSessionId={quizSessionId}
isRegrading={sessionItem.id === regradingIdentifier}
regradingKey={sessionItem.id}
renderUpdateButton={renderUpdateButton}
sessionItem={sessionItem}
shouldRenderTopBorder={shouldRenderTopBorder}
/>
)
}
renderItem(sessionItem) {
if (sessionItem.stimulus) {
return (
<ResultStimulus
key={sessionItem.id}
stimulus={sessionItem.stimulusRecord}
renderItem={this.renderSessionItemResultWrapper}
sessionItem={sessionItem}
// This prop is necessary to rerender the child items when we enter regrading mode
regradingIdentifier={this.props.regradingIdentifier}
/>
)
}
return this.renderSessionItemResultWrapper(sessionItem, true)
}
renderItems() {
return generateDisplayPositions(this.props.sessionItems).map(si => this.renderItem(si.record))
}
render() {
return <div css={this.props.styles.root}>{this.renderItems()}</div>
}
}
export const SessionItemResultList = withStyleOverrides(generateStyle)(BaseSessionItemResultList)
export default SessionItemResultList