fix: scroll enable on smaller screen (#51)

* fix: scroll enable on smaller screen

* fix: fixed review error width

* fix: make rubric and review error width align

* fix: rubric position to be sticky

* fix: remove double scroll bar at the bottom for small screen

* fix: make submission more response on small screen

* fix: rubric sticky and margin correctly on smaller screen

* chore: linting and update snapshot

* fix: make submission title resize to smaller on smaller screen

* fix: miss align rubic and submission file on the top

* fix: padding size on small screen

* feat: add optional on feedback comment for clarity

* chore: update test
This commit is contained in:
leangseu-edx
2022-02-08 10:33:42 -05:00
committed by GitHub
parent c6ed6938af
commit e8550af85d
15 changed files with 188 additions and 47 deletions

View File

@@ -12,7 +12,7 @@ import './FileCard.scss';
*/
export const FileCard = ({ file, children }) => (
<Card className="file-card" key={file.name}>
<Collapsible className="file-collapsible" defaultOpen title={<h3>{file.name}</h3>}>
<Collapsible className="file-collapsible" defaultOpen title={<h3 className="file-card-title">{file.name}</h3>}>
<div className="preview-panel">
<FileInfo><FilePopoverContent {...file} /></FileInfo>
{children}

View File

@@ -2,6 +2,12 @@
.file-card {
margin: map-get($spacers, 1) 0;
.file-card-title {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
}
.image-renderer {
@@ -18,4 +24,10 @@
.txt-renderer {
white-space: pre-wrap;
}
@include media-breakpoint-down(sm) {
.file-card-title {
width: map-get($container-max-widths, "sm")/2;
}
}

View File

@@ -29,7 +29,7 @@ describe('File Preview Card component', () => {
describe('Component', () => {
test('collapsible title is name header', () => {
const title = el.find(Collapsible).prop('title');
expect(title).toEqual(<h3>{props.file.name}</h3>);
expect(title).toEqual(<h3 className="file-card-title">{props.file.name}</h3>);
});
test('forwards children into preview-panel', () => {
const previewPanelChildren = el.find('.preview-panel').children();

View File

@@ -9,7 +9,9 @@ exports[`File Preview Card component snapshot 1`] = `
className="file-collapsible"
defaultOpen={true}
title={
<h3>
<h3
className="file-card-title"
>
test-file-name.pdf
</h3>
}

View File

@@ -25,6 +25,15 @@ export class CriterionFeedback extends React.Component {
});
}
get commentMessage() {
const { config, isGrading } = this.props;
let commentMessage = this.translate(isGrading ? messages.addComments : messages.comments);
if (config === feedbackRequirement.optional) {
commentMessage += ` ${this.translate(messages.optional)}`;
}
return commentMessage;
}
translate = (msg) => this.props.intl.formatMessage(msg);
render() {
@@ -42,9 +51,7 @@ export class CriterionFeedback extends React.Component {
<Form.Control
as="input"
className="criterion-feedback feedback-input"
floatingLabel={this.translate(
isGrading ? messages.addComments : messages.comments,
)}
floatingLabel={this.commentMessage}
value={value}
onChange={this.onChange}
disabled={!isGrading}

View File

@@ -12,6 +12,7 @@ import {
mapStateToProps,
mapDispatchToProps,
} from './CriterionFeedback';
import messages from './messages';
jest.mock('data/redux/app/selectors', () => ({
rubric: {
@@ -27,7 +28,9 @@ jest.mock('data/redux/grading/selectors', () => ({
})),
},
validation: {
criterionFeedbackIsInvalid: jest.fn((...args) => ({ selectedFeedbackIsInvalid: args })),
criterionFeedbackIsInvalid: jest.fn((...args) => ({
selectedFeedbackIsInvalid: args,
})),
},
}));
@@ -67,11 +70,13 @@ describe('Criterion Feedback', () => {
expect(el.instance().render()).toMatchSnapshot();
});
test('is configure to disabled', () => {
el.setProps({
config: feedbackRequirement.disabled,
Object.values(feedbackRequirement).forEach((requirement) => {
test(`feedback is configured to ${requirement}`, () => {
el.setProps({
config: requirement,
});
expect(el.instance().render()).toMatchSnapshot();
});
expect(el.instance().render()).toMatchSnapshot();
});
});
@@ -121,6 +126,40 @@ describe('Criterion Feedback', () => {
expect(props.setValue).toBeCalledTimes(1);
});
});
describe('getter commentMessage', () => {
test('is grading', () => {
el.setProps({ config: feedbackRequirement.optional, isGrading: true });
expect(el.instance().commentMessage).toContain(
messages.optional.defaultMessage,
);
el.setProps({ config: feedbackRequirement.required });
expect(el.instance().commentMessage).not.toContain(
messages.optional.defaultMessage,
);
expect(el.instance().commentMessage).toContain(
messages.addComments.defaultMessage,
);
});
test('is not grading', () => {
el.setProps({ config: feedbackRequirement.optional, isGrading: false });
expect(el.instance().commentMessage).toContain(
messages.optional.defaultMessage,
);
el.setProps({ config: feedbackRequirement.required });
expect(el.instance().commentMessage).not.toContain(
messages.optional.defaultMessage,
);
expect(el.instance().commentMessage).toContain(
messages.comments.defaultMessage,
);
});
});
});
describe('mapStateToProps', () => {
@@ -142,7 +181,10 @@ describe('Criterion Feedback', () => {
});
test('selector.grading.validation.criterionFeedbackIsInvalid', () => {
expect(mapped.isInvalid).toEqual(
selectors.grading.validation.criterionFeedbackIsInvalid(testState, ownProps),
selectors.grading.validation.criterionFeedbackIsInvalid(
testState,
ownProps,
),
);
});
});

View File

@@ -1,5 +1,33 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Criterion Feedback snapshot feedback is configured to disabled 1`] = `null`;
exports[`Criterion Feedback snapshot feedback is configured to optional 1`] = `
<Form.Group>
<Form.Control
as="input"
className="criterion-feedback feedback-input"
disabled={false}
floatingLabel="Add comments (Optional)"
onChange={[MockFunction this.onChange]}
value="criterion value"
/>
</Form.Group>
`;
exports[`Criterion Feedback snapshot feedback is configured to required 1`] = `
<Form.Group>
<Form.Control
as="input"
className="criterion-feedback feedback-input"
disabled={false}
floatingLabel="Add comments"
onChange={[MockFunction this.onChange]}
value="criterion value"
/>
</Form.Group>
`;
exports[`Criterion Feedback snapshot feedback value is invalid 1`] = `
<Form.Group>
<Form.Control
@@ -19,8 +47,6 @@ exports[`Criterion Feedback snapshot feedback value is invalid 1`] = `
</Form.Group>
`;
exports[`Criterion Feedback snapshot is configure to disabled 1`] = `null`;
exports[`Criterion Feedback snapshot is graded 1`] = `
<Form.Group>
<Form.Control

View File

@@ -11,6 +11,11 @@ const messages = defineMessages({
defaultMessage: 'Comments',
description: 'label for read-only feedback field',
},
optional: {
id: 'ora-grading.CriterionFeedback.optional',
defaultMessage: '(Optional)',
description: 'addtional label for optional feedback field',
},
optionPoints: {
id: 'ora-grading.RadioCriterion.optionPoints',
defaultMessage: '{points} points',

View File

@@ -47,6 +47,10 @@
@include media-breakpoint-down(sm) {
.response-display {
min-width: 100vw;
width: 100%;
.preview-display {
padding: map-get($spacers, 1) 0;
}
}
}

View File

@@ -15,15 +15,19 @@ import ReviewErrors from './ReviewErrors';
* <ReviewContent />
*/
export const ReviewContent = ({ isFailed, isLoaded, showRubric }) => (isLoaded || isFailed) && (
<div className="content-block">
<div className="content-block">
<div className="content-wrapper">
<ReviewErrors />
{ isLoaded && (
<Row className="flex-nowrap">
<Col><ResponseDisplay /></Col>
{ showRubric && <Rubric /> }
</Row>
{isLoaded && (
<Row className="flex-nowrap m-0">
<Col className="p-0">
<ResponseDisplay />
</Col>
{showRubric && <Rubric />}
</Row>
)}
</div>
</div>
);
ReviewContent.defaultProps = {
isFailed: false,
@@ -37,8 +41,12 @@ ReviewContent.propTypes = {
};
export const mapStateToProps = (state) => ({
isFailed: selectors.requests.isFailed(state, { requestKey: RequestKeys.fetchSubmission }),
isLoaded: selectors.requests.isCompleted(state, { requestKey: RequestKeys.fetchSubmission }),
isFailed: selectors.requests.isFailed(state, {
requestKey: RequestKeys.fetchSubmission,
}),
isLoaded: selectors.requests.isCompleted(state, {
requestKey: RequestKeys.fetchSubmission,
}),
showRubric: selectors.app.showRubric(state),
});

View File

@@ -17,15 +17,27 @@
margin: auto;
height: 100%;
}
.content-wrapper {
width: min-content;
}
}
@include media-breakpoint-down(sm) {
.review-modal-body {
padding: 0 !important;
overflow-y: hidden !important;
overflow: hidden !important;
& > div.pgn__modal-body-content {
overflow-y: scroll;
}
.content-block .col {
padding: 0;
}
.content-wrapper {
width: 100%;
}
}
}

View File

@@ -4,7 +4,11 @@ exports[`ReviewContent component component render tests snapshot: failed, showRu
<div
className="content-block"
>
<ReviewErrors />
<div
className="content-wrapper"
>
<ReviewErrors />
</div>
</div>
`;
@@ -12,15 +16,21 @@ exports[`ReviewContent component component render tests snapshot: hide rubric 1`
<div
className="content-block"
>
<ReviewErrors />
<Row
className="flex-nowrap"
<div
className="content-wrapper"
>
<Col>
<ResponseDisplay />
</Col>
<Rubric />
</Row>
<ReviewErrors />
<Row
className="flex-nowrap m-0"
>
<Col
className="p-0"
>
<ResponseDisplay />
</Col>
<Rubric />
</Row>
</div>
</div>
`;
@@ -28,13 +38,19 @@ exports[`ReviewContent component component render tests snapshot: show rubric 1`
<div
className="content-block"
>
<ReviewErrors />
<Row
className="flex-nowrap"
<div
className="content-wrapper"
>
<Col>
<ResponseDisplay />
</Col>
</Row>
<ReviewErrors />
<Row
className="flex-nowrap m-0"
>
<Col
className="p-0"
>
<ResponseDisplay />
</Col>
</Row>
</div>
</div>
`;

View File

@@ -31,8 +31,6 @@
}
}
}
.rubric-feedback {
}
.criterion-feedback {
margin-top: 1rem;
@@ -51,6 +49,9 @@
width: 320px;
height: fit-content;
max-height: 100%;
margin-left: map-get($spacers, 3);
position: sticky !important;
top: map-get($spacers, 1) * -1;
.grading-rubric-header {
box-shadow: 0 0 0.25rem rgba(0, 0, 0, 0.3) !important;
@@ -74,3 +75,9 @@
opacity: .4 !important;
}
}
@include media-breakpoint-down(sm) {
.grading-rubric-card {
margin-left: 0 !important;
}
}

View File

@@ -24,7 +24,7 @@ exports[`Rubric Feedback component snapshot feedback value is invalid 1`] = `
as="input"
className="rubric-feedback feedback-input"
disabled={false}
floatingLabel="Add comments"
floatingLabel="Add comments (Optional)"
onChange={[MockFunction this.onChange]}
value="some value"
/>
@@ -67,7 +67,7 @@ exports[`Rubric Feedback component snapshot is graded 1`] = `
as="input"
className="rubric-feedback feedback-input"
disabled={true}
floatingLabel="Comments"
floatingLabel="Comments (Optional)"
onChange={[MockFunction this.onChange]}
value="some value"
/>
@@ -98,7 +98,7 @@ exports[`Rubric Feedback component snapshot is grading 1`] = `
as="input"
className="rubric-feedback feedback-input"
disabled={false}
floatingLabel="Add comments"
floatingLabel="Add comments (Optional)"
onChange={[MockFunction this.onChange]}
value="some value"
/>

View File

@@ -28,12 +28,12 @@ const messages = defineMessages({
},
addComments: {
id: 'ora-grading.Rubric.addComments',
defaultMessage: 'Add comments',
defaultMessage: 'Add comments (Optional)',
description: 'Rubric comments input label',
},
comments: {
id: 'ora-grading.Rubric.comments',
defaultMessage: 'Comments',
defaultMessage: 'Comments (Optional)',
description: 'Rubric comments display label',
},
overallFeedbackError: {