feat: show file size in file popover (#47)

* feat: show file size in file popover

* chore: update file popover content's props
This commit is contained in:
leangseu-edx
2022-01-19 11:13:39 -05:00
committed by GitHub
parent 21dcc972ed
commit b2aac6036e
15 changed files with 124 additions and 45 deletions

15
package-lock.json generated
View File

@@ -1,5 +1,5 @@
{
"name": "@edx/frontend-app-ora-enhanced-staff-grader",
"name": "@edx/frontend-app-ora-grading",
"version": "0.0.1",
"lockfileVersion": 1,
"requires": true,
@@ -9930,10 +9930,9 @@
}
},
"filesize": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/filesize/-/filesize-6.1.0.tgz",
"integrity": "sha512-LpCHtPQ3sFx67z+uh2HnSyWSLLu5Jxo21795uRDuar/EOuYWXib5EmPaGIBuSnRqH2IODiKA2k5re/K9OnN/Yg==",
"dev": true
"version": "8.0.6",
"resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.6.tgz",
"integrity": "sha512-sHvRqTiwdmcuzqet7iVwsbwF6UrV3wIgDf2SHNdY1Hgl8PC45HZg/0xtdw6U2izIV4lccnrY9ftl6wZFNdjYMg=="
},
"fill-range": {
"version": "4.0.0",
@@ -20972,6 +20971,12 @@
"integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
"dev": true
},
"filesize": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/filesize/-/filesize-6.1.0.tgz",
"integrity": "sha512-LpCHtPQ3sFx67z+uh2HnSyWSLLu5Jxo21795uRDuar/EOuYWXib5EmPaGIBuSnRqH2IODiKA2k5re/K9OnN/Yg==",
"dev": true
},
"globby": {
"version": "11.0.1",
"resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz",

View File

@@ -44,6 +44,7 @@
"enzyme": "^3.11.0",
"enzyme-to-json": "^3.6.2",
"file-saver": "^2.0.5",
"filesize": "^8.0.6",
"font-awesome": "4.7.0",
"history": "5.0.1",
"html-react-parser": "^1.3.0",

View File

@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`FilePopoverContent component snapshot 1`] = `
exports[`FilePopoverContent component snapshot default 1`] = `
<Fragment>
<div
className="help-popover-option"
@@ -28,5 +28,62 @@ exports[`FilePopoverContent component snapshot 1`] = `
<br />
long descriptive text...
</div>
<div
className="help-popover-option"
>
<strong>
<FormattedMessage
defaultMessage="File Size"
description="Popover title for file size"
id="ora-grading.FilePopoverCellContent.fileSizeTitle"
/>
</strong>
<br />
filesize(6000)
</div>
</Fragment>
`;
exports[`FilePopoverContent component snapshot invalid size 1`] = `
<Fragment>
<div
className="help-popover-option"
>
<strong>
<FormattedMessage
defaultMessage="File Name"
description="Popover title for file name"
id="ora-grading.FilePopoverContent.filePopoverNameTitle"
/>
</strong>
<br />
some file name
</div>
<div
className="help-popover-option"
>
<strong>
<FormattedMessage
defaultMessage="File Description"
description="Popover title for file description"
id="ora-grading.FilePopoverCellContent.filePopoverDescriptionTitle"
/>
</strong>
<br />
long descriptive text...
</div>
<div
className="help-popover-option"
>
<strong>
<FormattedMessage
defaultMessage="File Size"
description="Popover title for file size"
id="ora-grading.FilePopoverCellContent.fileSizeTitle"
/>
</strong>
<br />
Unknown
</div>
</Fragment>
`;

View File

@@ -2,33 +2,39 @@ import React from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage } from '@edx/frontend-platform/i18n';
import filesize from 'filesize';
import messages from './messages';
export const FilePopoverContent = ({ file }) => (
export const FilePopoverContent = ({ name, description, size }) => (
<>
<div className="help-popover-option">
<strong><FormattedMessage {...messages.filePopoverNameTitle} /></strong>
<br />
{file.name}
{name}
</div>
<div className="help-popover-option">
<strong><FormattedMessage {...messages.filePopoverDescriptionTitle} /></strong>
<br />
{file.description}
{description}
</div>
<div className="help-popover-option">
<strong><FormattedMessage {...messages.fileSizeTitle} /></strong>
<br />
{typeof (size) === 'number' ? filesize(size) : 'Unknown'}
</div>
</>
);
FilePopoverContent.defaultProps = {
description: '',
size: null,
};
FilePopoverContent.propTypes = {
file: PropTypes.shape({
name: PropTypes.string.isRequired,
description: PropTypes.string,
downloadURL: PropTypes.string,
}).isRequired,
name: PropTypes.string.isRequired,
description: PropTypes.string,
size: PropTypes.number,
};
export default FilePopoverContent;

View File

@@ -1,29 +1,38 @@
import React from 'react';
import { shallow } from 'enzyme';
import filesize from 'filesize';
import FilePopoverContent from '.';
jest.mock('filesize', () => (size) => `filesize(${size})`);
describe('FilePopoverContent', () => {
describe('component', () => {
const props = {
file: {
name: 'some file name',
description: 'long descriptive text...',
downloadURL: 'this-url-is.working',
},
name: 'some file name',
description: 'long descriptive text...',
downloadURL: 'this-url-is.working',
size: 6000,
};
let el;
beforeEach(() => {
el = shallow(<FilePopoverContent {...props} />);
});
test('snapshot', () => {
expect(el).toMatchSnapshot();
describe('snapshot', () => {
test('default', () => expect(el).toMatchSnapshot());
test('invalid size', () => {
el.setProps({
size: null,
});
expect(el).toMatchSnapshot();
});
});
describe('behavior', () => {
test('content', () => {
expect(el.text()).toContain(props.file.name);
expect(el.text()).toContain(props.file.description);
expect(el.text()).toContain(props.name);
expect(el.text()).toContain(props.description);
expect(el.text()).toContain(filesize(props.size));
});
});
});

View File

@@ -11,6 +11,11 @@ const messages = defineMessages({
defaultMessage: 'File Description',
description: 'Popover title for file description',
},
fileSizeTitle: {
id: 'ora-grading.FilePopoverCellContent.fileSizeTitle',
defaultMessage: 'File Size',
description: 'Popover title for file size',
},
});
export default messages;

View File

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

View File

@@ -19,13 +19,9 @@ exports[`File Preview Card component snapshot 1`] = `
>
<FileInfo>
<FilePopoverContent
file={
Object {
"description": "test-file description",
"downloadUrl": "destination/test-file-name.pdf",
"name": "test-file-name.pdf",
}
}
description="test-file description"
downloadUrl="destination/test-file-name.pdf"
name="test-file-name.pdf"
/>
</FileInfo>
<h1>

View File

@@ -6,7 +6,7 @@ import FilePopoverContent from 'components/FilePopoverContent';
export const FilePopoverCell = ({ row: { original } }) => (
<InfoPopover>
<FilePopoverContent file={original} />
<FilePopoverContent {...original} />
</InfoPopover>
);

View File

@@ -30,7 +30,7 @@ describe('FilePopoverCell', () => {
test('content', () => {
const { original } = props.row;
const content = el.find(FilePopoverContent);
expect(content.props()).toEqual({ file: original });
expect(content.props()).toEqual({ ...original });
});
});
});

View File

@@ -3,13 +3,9 @@
exports[`FilePopoverCell component snapshot 1`] = `
<InfoPopover>
<FilePopoverContent
file={
Object {
"description": "long descriptive text...",
"downloadURL": "this-url-is.working",
"name": "some file name",
}
}
description="long descriptive text..."
downloadURL="this-url-is.working"
name="some file name"
/>
</InfoPopover>
`;

View File

@@ -51,6 +51,7 @@ const initialState = {
* downloadURL: '',
* description: '',
* name: '',
* size: 0,
* }],
* },
*/

View File

@@ -9,11 +9,11 @@ import * as module from './download';
/**
* Generate a manifest file content based on files object
* @param {obj[]} files - list of file entries with downloadUrl, name, and description
* @param {obj[]} files - list of file entries with downloadUrl, name, description, and size
* @return {string} - manifest text file content.
*/
export const genManifest = (files) => files.map(
(file) => `Filename: ${file.name}\nDescription: ${file.description}`,
(file) => `Filename: ${file.name}\nDescription: ${file.description}\nSize: ${file.size}`,
).join('\n\n');
/**

View File

@@ -35,6 +35,7 @@ describe('download thunkActions', () => {
downloadUrl: `home/${name}`,
name,
description: `${name} description`,
size: name.length,
});
const files = [mockFile('test-file1.jpg'), mockFile('test-file2.pdf')];
const blobs = ['blob1', 'blob2'];
@@ -44,8 +45,8 @@ describe('download thunkActions', () => {
describe('genManifest', () => {
test('returns a list of strings with filename and description for each file', () => {
expect(download.genManifest(response.files)).toEqual([
`Filename: ${files[0].name}\nDescription: ${files[0].description}`,
`Filename: ${files[1].name}\nDescription: ${files[1].description}`,
`Filename: ${files[0].name}\nDescription: ${files[0].description}\nSize: ${files[0].size}`,
`Filename: ${files[1].name}\nDescription: ${files[1].description}\nSize: ${files[0].size}`,
].join('\n\n'));
});
});

View File

@@ -24,10 +24,12 @@ const getFiles = (submissionUUID) => {
const files = [];
for (let i = 0; i < numFiles; i++) {
const fileName = `${submissionUUID}_${allFiles[i]}`;
const descriptionText = descriptiveText(fileName);
files.push({
name: allFiles[i],
description: descriptiveText(fileName),
description: descriptionText,
downloadUrl: allFiles[i],
size: descriptionText.length * 1024,
});
}
return files;