feat: submission files overview
chore: refactor css and file locations chore: update fake data and file props chore: create functional component for showing submission files chore: update ResponseDisplay test fix: fix bad snapshot chore: update linting because husky does do it chore: update snapshot chore: update requested change chore: update mock and snapshot
This commit is contained in:
committed by
leangseu-edx
parent
3de4dd86a3
commit
5361080bc3
43
src/containers/ResponseDisplay/ResponseDisplay.scss
Normal file
43
src/containers/ResponseDisplay/ResponseDisplay.scss
Normal file
@@ -0,0 +1,43 @@
|
||||
@import "@edx/paragon/scss/core/core";
|
||||
|
||||
.response-display {
|
||||
padding: map-get($spacers, 0);
|
||||
max-width: map-get($container-max-widths, "sm");
|
||||
overflow-y: hidden;
|
||||
height: fit-content;
|
||||
|
||||
.submission-files {
|
||||
padding: map-get($spacers, 3);
|
||||
margin-bottom: map-get($spacers, 2);
|
||||
|
||||
.submission-files-title {
|
||||
border-radius: calc(0.375rem - 1px);
|
||||
border-bottom: 1px solid transparent;
|
||||
transition: border-color 100ms ease 150ms;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
> h3 {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&.no-submissions {
|
||||
cursor: initial;
|
||||
|
||||
> h3 {
|
||||
color: $gray-300;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.submission-files-body {
|
||||
padding: map-get($spacers, 3) 0;
|
||||
|
||||
thead {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
82
src/containers/ResponseDisplay/SubmissionFiles.jsx
Normal file
82
src/containers/ResponseDisplay/SubmissionFiles.jsx
Normal file
@@ -0,0 +1,82 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import {
|
||||
Card, Collapsible, Icon, DataTable,
|
||||
} from '@edx/paragon';
|
||||
import { ArrowDropDown, ArrowDropUp } from '@edx/paragon/icons';
|
||||
|
||||
/* eslint react/prop-types: 0 */
|
||||
export const HeaderEllipsesCell = ({ value }) => (
|
||||
<div className="text-truncate">{value}</div>
|
||||
);
|
||||
|
||||
/**
|
||||
* <SubmissionFiles />
|
||||
*/
|
||||
export class SubmissionFiles extends React.Component {
|
||||
get title() {
|
||||
return `Submission Files (${this.props.files.length})`;
|
||||
}
|
||||
|
||||
renderHeaderEllipsesCell = HeaderEllipsesCell;
|
||||
|
||||
render() {
|
||||
const { files } = this.props;
|
||||
return (
|
||||
<Card className="submission-files">
|
||||
{files.length ? (
|
||||
<Collapsible.Advanced defaultOpen>
|
||||
<Collapsible.Trigger className="submission-files-title">
|
||||
<h3>{this.title}</h3>
|
||||
<Collapsible.Visible whenClosed>
|
||||
<Icon src={ArrowDropDown} />
|
||||
</Collapsible.Visible>
|
||||
<Collapsible.Visible whenOpen>
|
||||
<Icon src={ArrowDropUp} />
|
||||
</Collapsible.Visible>
|
||||
</Collapsible.Trigger>
|
||||
<Collapsible.Body className="submission-files-body">
|
||||
<DataTable
|
||||
columns={[
|
||||
{
|
||||
Header: 'Name',
|
||||
accessor: 'name',
|
||||
Cell: this.renderHeaderEllipsesCell,
|
||||
},
|
||||
{
|
||||
Header: 'Description',
|
||||
accessor: 'description',
|
||||
Cell: this.renderHeaderEllipsesCell,
|
||||
},
|
||||
]}
|
||||
data={files}
|
||||
>
|
||||
<DataTable.Table />
|
||||
</DataTable>
|
||||
</Collapsible.Body>
|
||||
</Collapsible.Advanced>
|
||||
) : (
|
||||
<div className="submission-files-title no-submissions">
|
||||
<h3>{this.title}</h3>
|
||||
</div>
|
||||
)}
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
SubmissionFiles.defaultProps = {
|
||||
files: [],
|
||||
};
|
||||
SubmissionFiles.propTypes = {
|
||||
files: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
name: PropTypes.string.isRequired,
|
||||
description: PropTypes.string,
|
||||
downloadUrl: PropTypes.string,
|
||||
}),
|
||||
),
|
||||
};
|
||||
|
||||
export default SubmissionFiles;
|
||||
96
src/containers/ResponseDisplay/SubmissionFiles.test.jsx
Normal file
96
src/containers/ResponseDisplay/SubmissionFiles.test.jsx
Normal file
@@ -0,0 +1,96 @@
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
import { SubmissionFiles, HeaderEllipsesCell } from './SubmissionFiles';
|
||||
|
||||
jest.mock('@edx/paragon', () => {
|
||||
const Card = () => 'Card';
|
||||
const Collapsible = {};
|
||||
Collapsible.Advanced = 'Collapsible.Advanced';
|
||||
Collapsible.Trigger = 'Collapsible.Trigger';
|
||||
Collapsible.Visible = 'Collapsible.Visible';
|
||||
Collapsible.Body = 'Collapsible.Body';
|
||||
|
||||
const Button = () => 'Button';
|
||||
const Icon = () => 'Icon';
|
||||
const DataTable = () => 'DataTable';
|
||||
DataTable.Table = 'DataTable.Table';
|
||||
|
||||
return {
|
||||
Card,
|
||||
Collapsible,
|
||||
Button,
|
||||
Icon,
|
||||
DataTable,
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('@edx/paragon/icons', () => ({
|
||||
ArrowDropDown: jest.fn().mockName('Icons.ArrowDropDown'),
|
||||
ArrowDropUp: jest.fn().mockName('Icons.ArrowDropUp'),
|
||||
}));
|
||||
|
||||
describe('SubmissionFiles', () => {
|
||||
describe('component', () => {
|
||||
const props = {
|
||||
files: [
|
||||
{
|
||||
name: 'some file name.jpg',
|
||||
description: 'description for the file',
|
||||
downloadUrl: '/valid-url-wink-wink',
|
||||
},
|
||||
{
|
||||
name: 'file number 2.jpg',
|
||||
description: 'description for this file',
|
||||
downloadUrl: '/url-2',
|
||||
},
|
||||
],
|
||||
};
|
||||
let el;
|
||||
beforeAll(() => {
|
||||
el = shallow(<SubmissionFiles />);
|
||||
});
|
||||
|
||||
describe('snapshot', () => {
|
||||
beforeAll(() => {
|
||||
el.instance().renderHeaderEllipsesCell = jest.fn().mockName('HeaderEllipsesCell');
|
||||
});
|
||||
test('files does not exist', () => {
|
||||
expect(el).toMatchSnapshot();
|
||||
});
|
||||
test('files exited for props', () => {
|
||||
el.setProps({ ...props });
|
||||
expect(el).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe('behavior', () => {
|
||||
test('title', () => {
|
||||
const titleEl = el.find('.submission-files-title>h3');
|
||||
expect(titleEl.text()).toEqual(`Submission Files (${props.files.length})`);
|
||||
expect(el.instance().title).toEqual(`Submission Files (${props.files.length})`);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('HeaderEllipsesCell', () => {
|
||||
describe('component', () => {
|
||||
const props = {
|
||||
value: 'some test text value',
|
||||
};
|
||||
let el;
|
||||
beforeEach(() => {
|
||||
el = shallow(<HeaderEllipsesCell {...props} />);
|
||||
});
|
||||
test('snapshot', () => {
|
||||
expect(el).toMatchSnapshot();
|
||||
});
|
||||
|
||||
describe('behavior', () => {
|
||||
test('content', () => {
|
||||
expect(el.text()).toEqual(props.value);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,91 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`HeaderEllipsesCell component snapshot 1`] = `
|
||||
<div
|
||||
className="text-truncate"
|
||||
>
|
||||
some test text value
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`SubmissionFiles component snapshot files does not exist 1`] = `
|
||||
<Card
|
||||
className="submission-files"
|
||||
>
|
||||
<div
|
||||
className="submission-files-title no-submissions"
|
||||
>
|
||||
<h3>
|
||||
Submission Files (0)
|
||||
</h3>
|
||||
</div>
|
||||
</Card>
|
||||
`;
|
||||
|
||||
exports[`SubmissionFiles component snapshot files exited for props 1`] = `
|
||||
<Card
|
||||
className="submission-files"
|
||||
>
|
||||
<Collapsible.Advanced
|
||||
defaultOpen={true}
|
||||
>
|
||||
<Collapsible.Trigger
|
||||
className="submission-files-title"
|
||||
>
|
||||
<h3>
|
||||
Submission Files (2)
|
||||
</h3>
|
||||
<Collapsible.Visible
|
||||
whenClosed={true}
|
||||
>
|
||||
<Icon
|
||||
src={[MockFunction Icons.ArrowDropDown]}
|
||||
/>
|
||||
</Collapsible.Visible>
|
||||
<Collapsible.Visible
|
||||
whenOpen={true}
|
||||
>
|
||||
<Icon
|
||||
src={[MockFunction Icons.ArrowDropUp]}
|
||||
/>
|
||||
</Collapsible.Visible>
|
||||
</Collapsible.Trigger>
|
||||
<Collapsible.Body
|
||||
className="submission-files-body"
|
||||
>
|
||||
<DataTable
|
||||
columns={
|
||||
Array [
|
||||
Object {
|
||||
"Cell": [MockFunction HeaderEllipsesCell],
|
||||
"Header": "Name",
|
||||
"accessor": "name",
|
||||
},
|
||||
Object {
|
||||
"Cell": [MockFunction HeaderEllipsesCell],
|
||||
"Header": "Description",
|
||||
"accessor": "description",
|
||||
},
|
||||
]
|
||||
}
|
||||
data={
|
||||
Array [
|
||||
Object {
|
||||
"description": "description for the file",
|
||||
"downloadUrl": "/valid-url-wink-wink",
|
||||
"name": "some file name.jpg",
|
||||
},
|
||||
Object {
|
||||
"description": "description for this file",
|
||||
"downloadUrl": "/url-2",
|
||||
"name": "file number 2.jpg",
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
<DataTable.Table />
|
||||
</DataTable>
|
||||
</Collapsible.Body>
|
||||
</Collapsible.Advanced>
|
||||
</Card>
|
||||
`;
|
||||
@@ -0,0 +1,44 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`ResponseDisplay component snapshot no response 1`] = `
|
||||
<div
|
||||
className="response-display"
|
||||
>
|
||||
<SubmissionFiles
|
||||
files={Array []}
|
||||
/>
|
||||
<Card>
|
||||
<Card.Body>
|
||||
parsed html (sanitized ())
|
||||
</Card.Body>
|
||||
</Card>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`ResponseDisplay component snapshot with valid response 1`] = `
|
||||
<div
|
||||
className="response-display"
|
||||
>
|
||||
<SubmissionFiles
|
||||
files={
|
||||
Array [
|
||||
Object {
|
||||
"description": "description for the file",
|
||||
"downloadUrl": "/valid-url-wink-wink",
|
||||
"name": "some file name.jpg",
|
||||
},
|
||||
Object {
|
||||
"description": "description for this file",
|
||||
"downloadUrl": "/url-2",
|
||||
"name": "file number 2.jpg",
|
||||
},
|
||||
]
|
||||
}
|
||||
/>
|
||||
<Card>
|
||||
<Card.Body>
|
||||
parsed html (sanitized (some text response here))
|
||||
</Card.Body>
|
||||
</Card>
|
||||
</div>
|
||||
`;
|
||||
@@ -2,9 +2,7 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import {
|
||||
Card,
|
||||
} from '@edx/paragon';
|
||||
import { Card } from '@edx/paragon';
|
||||
|
||||
import createDOMPurify from 'dompurify';
|
||||
|
||||
@@ -12,6 +10,10 @@ import parse from 'html-react-parser';
|
||||
|
||||
import selectors from 'data/selectors';
|
||||
|
||||
import SubmissionFiles from './SubmissionFiles';
|
||||
|
||||
import './ResponseDisplay.scss';
|
||||
|
||||
/**
|
||||
* <ResponseDisplay />
|
||||
*/
|
||||
@@ -25,36 +27,43 @@ export class ResponseDisplay extends React.Component {
|
||||
return parse(this.purify.sanitize(this.props.response.text));
|
||||
}
|
||||
|
||||
get hasResponse() {
|
||||
return this.props.response !== undefined;
|
||||
get submittedFiles() {
|
||||
return this.props.response.files;
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Card className="response-card">
|
||||
{this.hasResponse && (
|
||||
<Card.Body>
|
||||
{this.textContent}
|
||||
</Card.Body>
|
||||
)}
|
||||
</Card>
|
||||
<div className="response-display">
|
||||
<SubmissionFiles files={this.submittedFiles} />
|
||||
<Card>
|
||||
<Card.Body>{this.textContent}</Card.Body>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ResponseDisplay.defaultProps = {
|
||||
response: {
|
||||
text: '',
|
||||
files: [],
|
||||
},
|
||||
};
|
||||
ResponseDisplay.propTypes = {
|
||||
response: PropTypes.shape({
|
||||
text: PropTypes.string,
|
||||
}).isRequired,
|
||||
files: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
fileName: PropTypes.string,
|
||||
}),
|
||||
).isRequired,
|
||||
}),
|
||||
};
|
||||
|
||||
export const mapStateToProps = (state) => ({
|
||||
response: selectors.grading.selected.response(state),
|
||||
});
|
||||
|
||||
export const mapDispatchToProps = {
|
||||
};
|
||||
export const mapDispatchToProps = {};
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(ResponseDisplay);
|
||||
96
src/containers/ResponseDisplay/index.test.jsx
Normal file
96
src/containers/ResponseDisplay/index.test.jsx
Normal file
@@ -0,0 +1,96 @@
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
import createDOMPurify from 'dompurify';
|
||||
import parse from 'html-react-parser';
|
||||
|
||||
import selectors from 'data/selectors';
|
||||
|
||||
import { ResponseDisplay, mapStateToProps } from '.';
|
||||
|
||||
jest.mock('@edx/paragon', () => {
|
||||
const Card = () => 'Card';
|
||||
Card.Body = 'Card.Body';
|
||||
return {
|
||||
Card,
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('data/selectors', () => ({
|
||||
__esModule: true,
|
||||
default: {
|
||||
grading: {
|
||||
selected: {
|
||||
response: (state) => ({ response: state }),
|
||||
},
|
||||
},
|
||||
},
|
||||
}));
|
||||
jest.mock('./SubmissionFiles', () => 'SubmissionFiles');
|
||||
jest.mock('dompurify', () => () => ({
|
||||
sanitize: (text) => `sanitized (${text})`,
|
||||
}));
|
||||
jest.mock('html-react-parser', () => (text) => `parsed html (${text})`);
|
||||
|
||||
describe('ResponseDisplay', () => {
|
||||
describe('component', () => {
|
||||
const props = {
|
||||
response: {
|
||||
text: 'some text response here',
|
||||
files: [
|
||||
{
|
||||
name: 'some file name.jpg',
|
||||
description: 'description for the file',
|
||||
downloadUrl: '/valid-url-wink-wink',
|
||||
},
|
||||
{
|
||||
name: 'file number 2.jpg',
|
||||
description: 'description for this file',
|
||||
downloadUrl: '/url-2',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
let el;
|
||||
beforeAll(() => {
|
||||
global.window = {};
|
||||
el = shallow(<ResponseDisplay />);
|
||||
});
|
||||
|
||||
describe('snapshot', () => {
|
||||
test('no response', () => {
|
||||
expect(el).toMatchSnapshot();
|
||||
});
|
||||
test('with valid response', () => {
|
||||
el.setProps({ ...props });
|
||||
expect(el).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
describe('behavior', () => {
|
||||
test('get textContent', () => {
|
||||
expect(el.instance().textContent).toEqual(
|
||||
parse(createDOMPurify(window).sanitize(props.response.text)),
|
||||
);
|
||||
});
|
||||
|
||||
test('get submittedFiles', () => {
|
||||
expect(el.instance().submittedFiles).toEqual(props.response.files);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('mapStateToProps', () => {
|
||||
let mapped;
|
||||
const testState = {
|
||||
dummyText: 'text',
|
||||
dummyFiles: ['files', 'file-2'],
|
||||
};
|
||||
beforeEach(() => {
|
||||
mapped = mapStateToProps(testState);
|
||||
});
|
||||
test('response loads from grading.selected.response', () => {
|
||||
expect(mapped.response).toEqual(
|
||||
selectors.grading.selected.response(testState),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
37
src/containers/ReviewActions/ReviewActions.scss
Normal file
37
src/containers/ReviewActions/ReviewActions.scss
Normal file
@@ -0,0 +1,37 @@
|
||||
@import "@edx/paragon/scss/core/core";
|
||||
|
||||
// action reviews
|
||||
.review-actions {
|
||||
padding: map_get($spacers, 3);
|
||||
flex-direction: row;
|
||||
background-color: $light-200;
|
||||
|
||||
.review-actions-username {
|
||||
flex-grow: 1;
|
||||
}
|
||||
.review-actions-status {
|
||||
margin-left: map_get($spacers, 3);
|
||||
vertical-align: middle;
|
||||
}
|
||||
.review-actions-group {
|
||||
margin-left: 0;
|
||||
flex-shrink: 0;
|
||||
align-self: stretch;
|
||||
|
||||
.submission-navigation {
|
||||
float: right;
|
||||
padding: map-get($spacers, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(md) {
|
||||
.review-actions {
|
||||
flex-direction: column;
|
||||
align-items: flex-start !important;
|
||||
}
|
||||
|
||||
.review-actions-username {
|
||||
padding-bottom: map-get($spacers, 3);
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,8 @@ import StatusBadge from 'components/StatusBadge';
|
||||
import StartGradingButton from './components/StartGradingButton';
|
||||
import SubmissionNavigation from './components/SubmissionNavigation';
|
||||
|
||||
import './ReviewActions.scss';
|
||||
|
||||
export const ReviewActions = ({
|
||||
gradingStatus,
|
||||
toggleShowRubric,
|
||||
|
||||
@@ -1,41 +1,5 @@
|
||||
@import "@edx/paragon/scss/core/core";
|
||||
|
||||
// action reviews
|
||||
.review-actions {
|
||||
padding: map_get($spacers, 3);
|
||||
flex-direction: row;
|
||||
background-color: $light-200;
|
||||
|
||||
.review-actions-username {
|
||||
flex-grow: 1;
|
||||
}
|
||||
.review-actions-status {
|
||||
margin-left: map_get($spacers, 3);
|
||||
vertical-align: middle;
|
||||
}
|
||||
.review-actions-group {
|
||||
margin-left: 0;
|
||||
flex-shrink: 0;
|
||||
align-self: stretch;
|
||||
|
||||
.submission-navigation {
|
||||
float: right;
|
||||
padding: map-get($spacers, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(md) {
|
||||
.review-actions {
|
||||
flex-direction: column;
|
||||
align-items: flex-start !important;
|
||||
}
|
||||
|
||||
.review-actions-username {
|
||||
padding-bottom: map-get($spacers, 3);
|
||||
}
|
||||
}
|
||||
|
||||
.review-modal-body {
|
||||
background-color: $gray-300 !important;
|
||||
padding: inherit;
|
||||
@@ -53,14 +17,6 @@
|
||||
margin: auto;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
// text response
|
||||
.response-card {
|
||||
padding: map-get($spacers, 0);
|
||||
max-width: map-get($container-max-widths, "sm");
|
||||
overflow-y: hidden;
|
||||
height: fit-content;
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(sm) {
|
||||
@@ -68,36 +24,8 @@
|
||||
padding: 0 !important;
|
||||
overflow-y: hidden !important;
|
||||
|
||||
.response-card {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.content-block .col {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.grading-rubric-card {
|
||||
width: 320px;
|
||||
height: fit-content;
|
||||
max-height: 100%;
|
||||
|
||||
.grading-rubric-header {
|
||||
box-shadow: 0 0 0.25rem rgba(0, 0, 0, 0.3) !important;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: map-get($spacers, 3);
|
||||
}
|
||||
|
||||
.grading-rubric-body {
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.grading-rubric-footer {
|
||||
box-shadow: 0 0 0.25rem rgba(0, 0, 0, 0.3) !important;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: map-get($spacers, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
import selectors from 'data/selectors';
|
||||
import actions from 'data/actions';
|
||||
|
||||
import ResponseDisplay from 'components/ResponseDisplay';
|
||||
import ResponseDisplay from 'containers/ResponseDisplay';
|
||||
import Rubric from 'containers/Rubric';
|
||||
|
||||
import ReviewActions from 'containers/ReviewActions';
|
||||
|
||||
@@ -43,3 +43,27 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.grading-rubric-card {
|
||||
width: 320px;
|
||||
height: fit-content;
|
||||
max-height: 100%;
|
||||
|
||||
.grading-rubric-header {
|
||||
box-shadow: 0 0 0.25rem rgba(0, 0, 0, 0.3) !important;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: map-get($spacers, 3);
|
||||
}
|
||||
|
||||
.grading-rubric-body {
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.grading-rubric-footer {
|
||||
box-shadow: 0 0 0.25rem rgba(0, 0, 0, 0.3) !important;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: map-get($spacers, 3);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ exports[`Rubric Container snapshot is grading 1`] = `
|
||||
<Card
|
||||
className="grading-rubric-card"
|
||||
>
|
||||
<Component
|
||||
<Card.Body
|
||||
className="grading-rubric-body"
|
||||
>
|
||||
<h3>
|
||||
@@ -38,7 +38,7 @@ exports[`Rubric Container snapshot is grading 1`] = `
|
||||
/>
|
||||
<hr />
|
||||
<RubricFeedback />
|
||||
</Component>
|
||||
</Card.Body>
|
||||
<div
|
||||
className="grading-rubric-footer"
|
||||
>
|
||||
@@ -53,7 +53,7 @@ exports[`Rubric Container snapshot is not grading 1`] = `
|
||||
<Card
|
||||
className="grading-rubric-card"
|
||||
>
|
||||
<Component
|
||||
<Card.Body
|
||||
className="grading-rubric-body"
|
||||
>
|
||||
<h3>
|
||||
@@ -87,6 +87,6 @@ exports[`Rubric Container snapshot is not grading 1`] = `
|
||||
/>
|
||||
<hr />
|
||||
<RubricFeedback />
|
||||
</Component>
|
||||
</Card.Body>
|
||||
</Card>
|
||||
`;
|
||||
|
||||
@@ -9,7 +9,7 @@ jest.mock('./RubricFeedback', () => 'RubricFeedback');
|
||||
|
||||
jest.mock('@edx/paragon', () => {
|
||||
const Card = () => 'Card';
|
||||
Card.Body = () => 'Card.Body';
|
||||
Card.Body = 'Card.Body';
|
||||
const Button = () => 'Button';
|
||||
return { Button, Card };
|
||||
});
|
||||
|
||||
@@ -6,11 +6,36 @@ Phasellus tempor eros aliquam ipsum molestie, vitae varius lectus tempus. Morbi
|
||||
Phasellus porttitor vel magna et auctor. Nulla porttitor convallis aliquam. Donec cursus, ipsum ut egestas bibendum, purus metus dignissim est, ac condimentum leo felis eget diam. In magna mi, tincidunt id sapien id, fermentum vestibulum quam. Quisque et dui sed urna convallis rutrum pellentesque quis sapien. Cras non lectus velit. Praesent semper eros id risus mollis, quis interdum quam imperdiet. Sed nec vulputate tortor, at tristique tortor.
|
||||
</div>`;
|
||||
|
||||
const descriptiveText = (fileName) => `This is some descriptive text for (${fileName}). Phasellus tempor eros aliquam ipsum molestie, vitae varius lectus tempus. Morbi iaculis, libero euismod vehicula rutrum, nisi leo volutpat diam, quis commodo ex nunc ut odio. Pellentesque condimentum feugiat erat ac vulputate. Pellentesque porta rutrum sagittis. Curabitur vulputate tempus accumsan. Fusce bibendum gravida metus a scelerisque. Mauris fringilla orci non lobortis commodo. Quisque iaculis, quam a tincidunt vehicula, erat nisi accumsan quam, eu cursus ligula magna id odio. Nulla porttitor, lorem gravida vehicula tristique, sapien metus tristique ex, id tincidunt sapien justo nec sapien. Maecenas luctus, nisl vestibulum scelerisque pharetra, ligula orci vulputate turpis, in ultrices mauris dolor eu enim. Suspendisse quis nibh nec augue semper maximus. Morbi maximus eleifend magna.`;
|
||||
|
||||
const allFiles = [
|
||||
'presentation.pdf',
|
||||
'example.jpg',
|
||||
'diagram.png',
|
||||
'notes.doc',
|
||||
'recording.wav',
|
||||
];
|
||||
|
||||
const getFiles = (submissionId) => {
|
||||
const index = parseInt(submissionId.split('-')[1], 10);
|
||||
const numFiles = index % allFiles.length;
|
||||
const files = [];
|
||||
for (let i = 0; i < numFiles; i++) {
|
||||
const fileName = `${submissionId}_${allFiles[i]}`;
|
||||
files.push({
|
||||
name: fileName,
|
||||
description: descriptiveText(fileName),
|
||||
downloadUrl: `/download/${fileName}/`,
|
||||
});
|
||||
}
|
||||
return files;
|
||||
};
|
||||
|
||||
// eslint-disable-next-line
|
||||
export const mockSubmission = (submissionId) => ({
|
||||
response: {
|
||||
text: responseText(submissionId),
|
||||
files: [],
|
||||
files: getFiles(submissionId),
|
||||
},
|
||||
gradeStatus: submissionList[submissionId].gradeStatus,
|
||||
lockStatus: submissionList[submissionId].lockStatus,
|
||||
|
||||
Reference in New Issue
Block a user