Skip to content
Open
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
83 changes: 64 additions & 19 deletions src/containers/ResponseDisplay/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ import parse from 'html-react-parser';

import { selectors } from 'data/redux';
import { fileUploadResponseOptions } from 'data/services/lms/constants';

import { getConfig } from '@edx/frontend-platform';
import SubmissionFiles from './SubmissionFiles';
import PreviewDisplay from './PreviewDisplay';

Expand All @@ -27,13 +25,7 @@ export class ResponseDisplay extends React.Component {
}

get textContents() {
const { text } = this.props.response;

const formattedText = text
.map((item) => item.replaceAll(/\.\.\/asset/g, `${getConfig().LMS_BASE_URL}/asset`))
.map((item) => parse(this.purify.sanitize(item)));

return formattedText;
return this.props.response.text.map(text => parse(this.purify.sanitize(text)));
}

get submittedFiles() {
Expand All @@ -46,19 +38,60 @@ export class ResponseDisplay extends React.Component {
);
}

// New getter to extract prompts
get prompts() {
const raw = this.props.oraMetadata?.prompts || [];
return raw.map(p => p.description || '');
}

// New helper method
sanitizeAndParse = (html = '') => parse(this.purify.sanitize(html));

render() {
const textResponses = this.textContents || [];
const { prompts } = this;

return (
<div className="response-display">
{this.allowFileUpload && <SubmissionFiles files={this.submittedFiles} data-testid="submission-files" />}
{this.allowFileUpload && <PreviewDisplay files={this.submittedFiles} data-testid="allow-file-upload" />}
{
/* eslint-disable react/no-array-index-key */
this.textContents.map((textContent, index) => (
<Card key={index}>
<Card.Section className="response-display-text-content" data-testid="response-display-text-content">{textContent}</Card.Section>
</Card>
))
}
{this.allowFileUpload && <SubmissionFiles files={this.submittedFiles} />}
{this.allowFileUpload && <PreviewDisplay files={this.submittedFiles} />}

{/* Prompt → Response pairs */}
{prompts.map((prompt, i) => {
const answer = textResponses[i] || '';

return (
<div key={prompt} className="prompt-response-pair my-5">
{/* Prompt */}
<Card className="mb-3">
<Card.Header title={<strong>Prompt {i + 1}</strong>} />
<Card.Section className="prompt-text">
{this.sanitizeAndParse(prompt)}
</Card.Section>
</Card>

{/* Learner Response */}
<Card>
<Card.Header title="Learner Response" />
<Card.Section className="response-display-text-content">
{answer ? (
this.sanitizeAndParse(answer)
) : (
<em className="text-muted">No response submitted for this prompt.</em>
)}
</Card.Section>
</Card>
</div>
);
})}

{/* only shows if no prompts */}
{prompts.length === 0
&& textResponses.map((text) => (
<Card key={text} className="my-3">
<Card.Section>{this.sanitizeAndParse(text)}</Card.Section>
</Card>
))}
</div>
);
}
Expand All @@ -69,6 +102,8 @@ ResponseDisplay.defaultProps = {
text: [],
files: [],
},
// Add default
oraMetadata: { prompts: [] },
fileUploadResponseConfig: fileUploadResponseOptions.none,
};
ResponseDisplay.propTypes = {
Expand All @@ -80,13 +115,23 @@ ResponseDisplay.propTypes = {
}),
).isRequired,
}),
// Add PropTypes
oraMetadata: PropTypes.shape({
prompts: PropTypes.arrayOf(
PropTypes.shape({
description: PropTypes.string,
}),
),
}),
fileUploadResponseConfig: PropTypes.oneOf(
Object.values(fileUploadResponseOptions),
),
};

export const mapStateToProps = (state) => ({
response: selectors.grading.selected.response(state),
// Add oraMetadata + use correct selector
oraMetadata: selectors.app.oraMetadata(state),
fileUploadResponseConfig: selectors.app.ora.fileUploadResponseConfig(state),
});

Expand Down
Loading