-
Notifications
You must be signed in to change notification settings - Fork 58
feat: add prompt to grading screen #471
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| import React from 'react'; | ||
| import { Collapsible, Card } from '@openedx/paragon'; | ||
| import { useIntl } from '@edx/frontend-platform/i18n'; | ||
|
|
||
| import PropTypes from 'prop-types'; | ||
| import messages from './messages'; | ||
|
|
||
| const PromptDisplay = ({ | ||
| prompt, className, styling, headerTitle, | ||
| }) => { | ||
| const intl = useIntl(); | ||
| const msg = intl.formatMessage(messages.promptCollapsibleHeader); | ||
| return ( | ||
| <div className={className}> | ||
| <Collapsible | ||
| styling={styling} | ||
| title={headerTitle ? <h3>{msg}</h3> : msg} | ||
| > | ||
| { prompt } | ||
| </Collapsible> | ||
| </div> | ||
| ); | ||
| }; | ||
|
|
||
| PromptDisplay.propTypes = { | ||
| prompt: PropTypes.string.isRequired, | ||
| className: PropTypes.string.isRequired, | ||
| styling: PropTypes.string.isRequired, | ||
| headerTitle: PropTypes.bool.isRequired, | ||
| }; | ||
|
|
||
| const SinglePromptDisplay = ({ prompt }) => ( | ||
| <PromptDisplay prompt={prompt} className="prompt-display-single" styling="card-lg" headerTitle /> | ||
| ); | ||
|
|
||
| SinglePromptDisplay.propTypes = { | ||
| prompt: PropTypes.string.isRequired, | ||
jansenk marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| }; | ||
|
|
||
| const MultiplePromptDisplay = ({ prompt }) => ( | ||
| <> | ||
| <PromptDisplay prompt={prompt} className="prompt-display-multiple" styling="basic" headerTitle={false} /> | ||
| <Card.Divider /> | ||
| </> | ||
| ); | ||
|
|
||
| MultiplePromptDisplay.propTypes = { | ||
| prompt: PropTypes.string.isRequired, | ||
jansenk marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| }; | ||
|
|
||
| export { SinglePromptDisplay, MultiplePromptDisplay }; | ||
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -14,7 +14,7 @@ import { fileUploadResponseOptions } from 'data/services/lms/constants'; | |||||||
| import { getConfig } from '@edx/frontend-platform'; | ||||||||
| import SubmissionFiles from './SubmissionFiles'; | ||||||||
| import PreviewDisplay from './PreviewDisplay'; | ||||||||
|
|
||||||||
| import { SinglePromptDisplay, MultiplePromptDisplay } from './PromptDisplay'; | ||||||||
| import './ResponseDisplay.scss'; | ||||||||
|
|
||||||||
| /** | ||||||||
|
|
@@ -26,13 +26,13 @@ export class ResponseDisplay extends React.Component { | |||||||
| this.purify = createDOMPurify(window); | ||||||||
| } | ||||||||
|
|
||||||||
| get prompts() { | ||||||||
| return this.props.prompts.map((item) => this.formattedHtml(item)); | ||||||||
| } | ||||||||
|
|
||||||||
| 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))); | ||||||||
|
|
||||||||
| const formattedText = text.map((item) => this.formattedHtml(item)); | ||||||||
| return formattedText; | ||||||||
| } | ||||||||
|
|
||||||||
|
|
@@ -46,15 +46,24 @@ export class ResponseDisplay extends React.Component { | |||||||
| ); | ||||||||
| } | ||||||||
|
|
||||||||
| formattedHtml(text) { | ||||||||
| const cleanedText = text.replaceAll(/\.\.\/asset/g, `${getConfig().LMS_BASE_URL}/asset`); | ||||||||
| return parse(this.purify.sanitize(cleanedText)); | ||||||||
| } | ||||||||
|
|
||||||||
|
Comment on lines
+49
to
+53
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. NIT: this is technically a |
||||||||
| render() { | ||||||||
| const { prompts } = this; | ||||||||
| const multiPrompt = prompts.length > 1; | ||||||||
| return ( | ||||||||
| <div className="response-display"> | ||||||||
| {!multiPrompt && <SinglePromptDisplay prompt={prompts[0]} />} | ||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. NIT: add a comment as to why this styling changes.
Suggested change
|
||||||||
| {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 className="response-display-card" key={index}> | ||||||||
| {multiPrompt && <MultiplePromptDisplay prompt={prompts[index]} />} | ||||||||
jansenk marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
| <Card.Section className="response-display-text-content" data-testid="response-display-text-content">{textContent}</Card.Section> | ||||||||
| </Card> | ||||||||
| )) | ||||||||
|
|
@@ -71,6 +80,7 @@ ResponseDisplay.defaultProps = { | |||||||
| }, | ||||||||
| fileUploadResponseConfig: fileUploadResponseOptions.none, | ||||||||
| }; | ||||||||
|
|
||||||||
| ResponseDisplay.propTypes = { | ||||||||
| response: PropTypes.shape({ | ||||||||
| text: PropTypes.arrayOf(PropTypes.string), | ||||||||
|
|
@@ -83,11 +93,13 @@ ResponseDisplay.propTypes = { | |||||||
| fileUploadResponseConfig: PropTypes.oneOf( | ||||||||
| Object.values(fileUploadResponseOptions), | ||||||||
| ), | ||||||||
| prompts: PropTypes.arrayOf(PropTypes.string).isRequired, | ||||||||
| }; | ||||||||
|
|
||||||||
| export const mapStateToProps = (state) => ({ | ||||||||
| response: selectors.grading.selected.response(state), | ||||||||
| fileUploadResponseConfig: selectors.app.ora.fileUploadResponseConfig(state), | ||||||||
| prompts: selectors.app.ora.prompts(state), | ||||||||
| }); | ||||||||
|
|
||||||||
| export const mapDispatchToProps = {}; | ||||||||
|
|
||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -33,10 +33,10 @@ export const ora = { | |
| */ | ||
| name: oraMetadataSelector(data => data.name), | ||
| /** | ||
| * Returns the ORA Prompt | ||
| * @return {string} - ORA prompt | ||
| * Returns the ORA Prompts | ||
| * @return {array[string]} - ORA prompt | ||
jansenk marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| */ | ||
| prompt: oraMetadataSelector(data => data.prompt), | ||
| prompts: oraMetadataSelector(data => (data.prompts ? data.prompts.map((oraPrompt) => oraPrompt.description) : [])), | ||
|
Comment on lines
+36
to
+39
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this require backend changes? If so, can you link them? |
||
| /** | ||
| * Returns the ORA type | ||
| * @return {string} - ORA type (team vs individual) | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.