Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions packages/image-cloze-association/src/evaluation-icon.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import Close from '@material-ui/icons/Close';
import { color } from '@pie-lib/pie-toolbox/render-ui';

const getCorrectnessClass = (isCorrect, filled) => {
if (filled) {
return isCorrect ? 'correctFilled' : 'incorrectFilled';
}
return isCorrect ? 'correctEmpty' : 'incorrectEmpty';
const correctness = isCorrect ? 'correct' : 'incorrect';
const fillState = filled ? 'Filled' : 'Empty';

return `${correctness}${fillState}`;
};

const EvaluationIcon = ({ classes, containerStyle, isCorrect, filled }) => {
Expand Down
8 changes: 2 additions & 6 deletions packages/image-cloze-association/src/possible-response.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import classNames from 'classnames';
import { withStyles } from '@material-ui/core/styles';
import { DragSource } from '@pie-lib/pie-toolbox/drag';
import { color } from '@pie-lib/pie-toolbox/render-ui';
import { PreviewPrompt } from '@pie-lib/pie-toolbox/render-ui';

import EvaluationIcon from './evaluation-icon';
import c from './constants';
import StaticHTMLSpan from './static-html-span';

export class PossibleResponse extends React.Component {
render() {
Expand Down Expand Up @@ -40,11 +40,7 @@ export class PossibleResponse extends React.Component {

return connectDragSource(
<div className={containerClassNames} style={containerStyle}>
<PreviewPrompt
defaultClassName={promptClassNames}
prompt={data.value}
tagName="span"
/>
<StaticHTMLSpan html={data.value} className={promptClassNames} />
<EvaluationIcon isCorrect={data.isCorrect} containerStyle={evaluationStyle} />
</div>,
);
Expand Down
140 changes: 69 additions & 71 deletions packages/image-cloze-association/src/root.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,18 +86,8 @@ export class ImageClozeAssociationComponent extends React.Component {
});
};

filterPossibleAnswers = (possibleResponses, answer) => {
const index = possibleResponses.findIndex((response) => response.value === answer.value);

if (index >= 0) {
return [
...possibleResponses.slice(0, index), // Elements before the found item
...possibleResponses.slice(index + 1), // Elements after the found item
];
}

return possibleResponses;
};
filterPossibleAnswers = (possibleResponses, answer) =>
possibleResponses.filter(response => response.value !== answer.value);

handleOnAnswerSelect = (answer, responseContainerIndex) => {
const {
Expand All @@ -108,10 +98,18 @@ export class ImageClozeAssociationComponent extends React.Component {
let { possibleResponses } = this.state;
let answersToStore;

if (maxResponsePerZone === answers.filter((a) => a.containerIndex === responseContainerIndex).length) {
const answersInThisContainer = answers.filter((a) => a.containerIndex === responseContainerIndex);
const answersInOtherContainers = answers.filter((b) => b.containerIndex !== responseContainerIndex);
const answersInThisContainer = [];
const answersInOtherContainers = [];

answers.forEach((a) => {
if (a.containerIndex === responseContainerIndex) {
answersInThisContainer.push(a);
} else {
answersInOtherContainers.push(a);
}
});

if (maxResponsePerZone === answersInThisContainer.length) {
const shiftedItem = answersInThisContainer[0];
if (maxResponsePerZone === 1) {
answersInThisContainer.shift(); // FIFO
Expand Down Expand Up @@ -270,6 +268,55 @@ export class ImageClozeAssociationComponent extends React.Component {
answersToShow = [...answersToShow, ...getUnansweredAnswers(answersToShow, validation)];
}

const sharedImageProps = {
draggingElement,
duplicateResponses,
image,
onAnswerSelect: this.handleOnAnswerSelect,
onDragAnswerBegin: this.beginDrag,
onDragAnswerEnd: this.handleOnDragEnd,
responseContainers,
showDashedBorder,
responseAreaFill,
responseContainerPadding,
imageDropTargetPadding,
maxResponsePerZone,
};

const renderImage = () => (
<Image
{...sharedImageProps}
canDrag={showCorrect && showToggle ? false : !disabled}
answers={showCorrect && showToggle ? correctAnswers : answersToShow}
answerChoiceTransparency={
!(showCorrect && showToggle) ? answerChoiceTransparency : undefined
}
/>
);

const renderPossibleResponses = () => {
if (showCorrect && showToggle) return null;

return (
<React.Fragment>
{maxResponsePerZoneWarning && <WarningInfo message={warningMessage} />}
<PossibleResponses
canDrag={!disabled}
data={possibleResponses}
onAnswerRemove={this.handleOnAnswerRemove}
onDragBegin={this.beginDrag}
onDragEnd={this.handleOnDragEnd}
answerChoiceTransparency={answerChoiceTransparency}
customStyle={{
minWidth: isVertical ? '130px' : image?.width || 'fit-content',
}}
isVertical={isVertical}
minHeight={isVertical ? image?.height : undefined}
/>
</React.Fragment>
);
};

return (
<UiLayout extraCSSRules={extraCSSRules} id={'main-container'} className={classes.main} fontSizeFactor={fontSizeFactor}>
{teacherInstructions && hasText(teacherInstructions) && (
Expand Down Expand Up @@ -300,62 +347,13 @@ export class ImageClozeAssociationComponent extends React.Component {
language={language}
/>

{showCorrect && showToggle ? (
<InteractiveSection responseCorrect={true} uiStyle={uiStyle}>
<Image
canDrag={false}
answers={correctAnswers}
draggingElement={draggingElement}
duplicateResponses={duplicateResponses}
image={image}
onAnswerSelect={this.handleOnAnswerSelect}
onDragAnswerBegin={this.beginDrag}
onDragAnswerEnd={this.handleOnDragEnd}
responseContainers={responseContainers}
showDashedBorder={showDashedBorder}
responseAreaFill={responseAreaFill}
responseContainerPadding={responseContainerPadding}
imageDropTargetPadding={imageDropTargetPadding}
maxResponsePerZone={maxResponsePerZone}
/>
</InteractiveSection>
) : (
<InteractiveSection responseCorrect={responseCorrect} uiStyle={uiStyle}>
<Image
canDrag={!disabled}
answers={answersToShow}
draggingElement={draggingElement}
duplicateResponses={duplicateResponses}
image={image}
onAnswerSelect={this.handleOnAnswerSelect}
onDragAnswerBegin={this.beginDrag}
onDragAnswerEnd={this.handleOnDragEnd}
responseContainers={responseContainers}
showDashedBorder={showDashedBorder}
responseAreaFill={responseAreaFill}
answerChoiceTransparency={answerChoiceTransparency}
responseContainerPadding={responseContainerPadding}
imageDropTargetPadding={imageDropTargetPadding}
maxResponsePerZone={maxResponsePerZone}
/>

{maxResponsePerZoneWarning && <WarningInfo message={warningMessage} />}

<PossibleResponses
canDrag={!disabled}
data={possibleResponses}
onAnswerRemove={this.handleOnAnswerRemove}
onDragBegin={this.beginDrag}
onDragEnd={this.handleOnDragEnd}
answerChoiceTransparency={answerChoiceTransparency}
customStyle={{
minWidth: isVertical ? '130px' : image?.width || 'fit-content',
}}
isVertical={isVertical}
minHeight={isVertical ? image?.height : undefined}
/>
</InteractiveSection>
)}
<InteractiveSection
responseCorrect={showCorrect && showToggle ? true : responseCorrect}
uiStyle={uiStyle}
>
{renderImage()}
{renderPossibleResponses()}
</InteractiveSection>

{rationale && hasText(rationale) && (
<Collapsible
Expand Down
30 changes: 30 additions & 0 deletions packages/image-cloze-association/src/static-html-span.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react';
import PropTypes from 'prop-types';

class StaticHTMLSpan extends React.PureComponent {
shouldComponentUpdate() {
return false;
}

render() {
const { html, className } = this.props;

return (
<span
className={className}
dangerouslySetInnerHTML={{ __html: html }}
/>
);
}
}

StaticHTMLSpan.propTypes = {
html: PropTypes.string.isRequired,
className: PropTypes.string,
};

StaticHTMLSpan.defaultProps = {
className: '',
};

export default StaticHTMLSpan;