From 3c9b0b161f2de97a31163eeaafa2c797a2209bdc Mon Sep 17 00:00:00 2001 From: Chuck McAndrew Date: Thu, 28 Jan 2021 14:43:03 -0500 Subject: [PATCH 01/35] Start adding front end styling for file upload --- frontend/src/components/FileUploader.css | 14 ++++ frontend/src/components/FileUploader.js | 73 ++++++++++++------- frontend/src/components/Navigator/index.js | 4 +- frontend/src/fetchers/File.js | 9 +++ .../ActivityReport/Pages/topicsResources.js | 8 +- frontend/src/pages/ActivityReport/index.js | 1 + 6 files changed, 77 insertions(+), 32 deletions(-) create mode 100644 frontend/src/fetchers/File.js diff --git a/frontend/src/components/FileUploader.css b/frontend/src/components/FileUploader.css index d14ce5f7ea..cf0e827586 100644 --- a/frontend/src/components/FileUploader.css +++ b/frontend/src/components/FileUploader.css @@ -23,3 +23,17 @@ .fa-stack { width: 1em; } + +.files-table { + width: 100%; + border-collapse: collapse; + /* border: 1px solid #979797; */ +} + +/* .files-table--file-name { + width: 50%; +} */ + +.files-table td { + text-align: center; +} \ No newline at end of file diff --git a/frontend/src/components/FileUploader.js b/frontend/src/components/FileUploader.js index 6c68e5eb05..d4f78a6c8e 100644 --- a/frontend/src/components/FileUploader.js +++ b/frontend/src/components/FileUploader.js @@ -10,7 +10,7 @@ import PropTypes from 'prop-types'; import { useDropzone } from 'react-dropzone'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { faTimes, faCircle } from '@fortawesome/free-solid-svg-icons'; +import { faTrash } from '@fortawesome/free-solid-svg-icons'; import { Tag, Button, Grid } from '@trussworks/react-uswds'; import './FileUploader.css'; @@ -18,6 +18,7 @@ import './FileUploader.css'; function Dropzone(props) { const { onChange } = props; const onDrop = (e) => { + console.log(e) onChange(e); }; const { getRootProps, getInputProps } = useDropzone({ onDrop }); @@ -37,30 +38,23 @@ function Dropzone(props) { }; const textStyle = { - textAlign: 'center', - fontSize: '16px', + textAlign: 'left', + fontSize: '1.25rem', + backgroundColor: "#0166AB", + color: "white", + padding: ".5rem", + borderRadius: "5px", }; - const linkStyle = { - cursor: 'pointer', - color: 'blue', - textDecoration: 'underline', - }; return (
-

- Drag and drop your files here - {' '} -
- or -
- Browse files -

+
); } @@ -81,13 +75,33 @@ const FileUploader = ({ onChange, files }) => { return ( <> - + + + + + + + + {files.map((file, index) => ( - - -
- {file.name} -
+
+ + + + + + + ))} - + +
+ Name + + Size + + Status + +
+ {file.name} + + {`${(file.size / 1000).toFixed(1) } KB`} + + Uploaded + - - +
+ ); }; diff --git a/frontend/src/components/Navigator/index.js b/frontend/src/components/Navigator/index.js index 1b7f0c2650..9a5e59a53c 100644 --- a/frontend/src/components/Navigator/index.js +++ b/frontend/src/components/Navigator/index.js @@ -29,6 +29,7 @@ function Navigator({ additionalData, onSave, autoSaveInterval, + reportId, }) { const [formData, updateFormData] = useState(initialData); const [errorMessage, updateErrorMessage] = useState(); @@ -131,6 +132,7 @@ function Navigator({ submitted, onFormSubmit, additionalData, + reportId, )} {!page.review && ( @@ -142,7 +144,7 @@ function Navigator({ onSubmit={handleSubmit(onContinue)} className="smart-hub--form-large" > - {page.render(hookForm, additionalData)} + {page.render(hookForm, additionalData, reportId)} diff --git a/frontend/src/fetchers/File.js b/frontend/src/fetchers/File.js new file mode 100644 index 0000000000..31389dca62 --- /dev/null +++ b/frontend/src/fetchers/File.js @@ -0,0 +1,9 @@ +import join from 'url-join'; +import { get, put, post } from './index'; + +const activityReportUrl = join('/', 'api', 'files'); + +export const uploadFile = async (data) => { + const res = await post(activityReportUrl, data); + return res.json(); +}; \ No newline at end of file diff --git a/frontend/src/pages/ActivityReport/Pages/topicsResources.js b/frontend/src/pages/ActivityReport/Pages/topicsResources.js index 86bc9df499..11fb22fafb 100644 --- a/frontend/src/pages/ActivityReport/Pages/topicsResources.js +++ b/frontend/src/pages/ActivityReport/Pages/topicsResources.js @@ -15,6 +15,7 @@ import { topics } from '../constants'; const TopicsResources = ({ register, control, + reportId, }) => ( <> @@ -56,7 +57,7 @@ const TopicsResources = ({ defaultValue={[]} control={control} render={({ onChange, value }) => ( - + )} /> @@ -69,7 +70,7 @@ const TopicsResources = ({ defaultValue={[]} control={control} render={({ onChange, value }) => ( - + )} /> @@ -113,12 +114,13 @@ export default { path: 'topics-resources', sections, review: false, - render: (hookForm) => { + render: (hookForm, additionalData, reportId) => { const { control, register } = hookForm; return ( ); }, diff --git a/frontend/src/pages/ActivityReport/index.js b/frontend/src/pages/ActivityReport/index.js index 63d73e048d..e37542bc44 100644 --- a/frontend/src/pages/ActivityReport/index.js +++ b/frontend/src/pages/ActivityReport/index.js @@ -137,6 +137,7 @@ function ActivityReport({ match }) {

New activity report for Region 14

Date: Thu, 28 Jan 2021 15:14:53 -0500 Subject: [PATCH 02/35] Style file upload --- frontend/src/components/FileUploader.css | 14 +++++-- frontend/src/components/FileUploader.js | 48 +++++++++++++++--------- 2 files changed, 41 insertions(+), 21 deletions(-) diff --git a/frontend/src/components/FileUploader.css b/frontend/src/components/FileUploader.css index cf0e827586..90d6710490 100644 --- a/frontend/src/components/FileUploader.css +++ b/frontend/src/components/FileUploader.css @@ -30,10 +30,16 @@ /* border: 1px solid #979797; */ } -/* .files-table--file-name { - width: 50%; -} */ +.files-table--thead th, .files-table td { + padding: .5rem; + text-align: left; + font-size: .9rem; +} +.files-table--container { + border: solid 1px #979797; + min-height: 8rem; +} -.files-table td { +.files-table--empty { text-align: center; } \ No newline at end of file diff --git a/frontend/src/components/FileUploader.js b/frontend/src/components/FileUploader.js index d4f78a6c8e..b5b78b199e 100644 --- a/frontend/src/components/FileUploader.js +++ b/frontend/src/components/FileUploader.js @@ -63,30 +63,27 @@ Dropzone.propTypes = { onChange: PropTypes.func.isRequired, }; -const FileUploader = ({ onChange, files }) => { - const onFilesAdded = (newFiles) => { - onChange([...files, ...newFiles]); - }; - - const onFileRemoved = (removedFileIndex) => { - onChange(files.filter((f, index) => (index !== removedFileIndex))); - }; - +const FileTable = ({onFileRemoved, files}) => { + let msg + if (files.length === 0) { + msg = ( +

No files uploaded

+ ) + } return ( - <> - - - -
+
+ + + - - - @@ -120,6 +117,23 @@ const FileUploader = ({ onChange, files }) => { ))}
Name + Size + Status +
+ { msg } +
+ ); +} +const FileUploader = ({ onChange, files }) => { + const onFilesAdded = (newFiles) => { + onChange([...files, ...newFiles]); + }; + + const onFileRemoved = (removedFileIndex) => { + onChange(files.filter((f, index) => (index !== removedFileIndex))); + }; + + return ( + <> + + ); From 9d688011a5a88582183eee82380412abfe77a93d Mon Sep 17 00:00:00 2001 From: Chuck McAndrew Date: Thu, 28 Jan 2021 16:26:31 -0500 Subject: [PATCH 03/35] enable file upload --- frontend/src/components/FileUploader.js | 27 ++++++++++++++++--- frontend/src/fetchers/File.js | 13 ++++++--- .../ActivityReport/Pages/topicsResources.js | 4 +-- 3 files changed, 36 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/FileUploader.js b/frontend/src/components/FileUploader.js index b5b78b199e..3582f60de9 100644 --- a/frontend/src/components/FileUploader.js +++ b/frontend/src/components/FileUploader.js @@ -8,16 +8,37 @@ import React from 'react'; import PropTypes from 'prop-types'; import { useDropzone } from 'react-dropzone'; +import * as FS from 'fs'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faTrash } from '@fortawesome/free-solid-svg-icons'; import { Tag, Button, Grid } from '@trussworks/react-uswds'; +import { uploadFile } from '../fetchers/File'; import './FileUploader.css'; function Dropzone(props) { - const { onChange } = props; + const { onChange, id, reportId } = props; const onDrop = (e) => { + let attachmentType; + if (id === 'attachments') { + attachmentType = 'ATTACHMENT'; + } else if (id === "other-resources") { + attachmentType = 'RESOURCE'; + } + e.forEach( async (file) => { + try { + const data = new FormData() + data.append("reportId", reportId) + data.append("attachmentType", attachmentType) + data.append("file", file) + await uploadFile(data) + } catch (error) { + console.log(error) + } + + }); + console.log(e) onChange(e); }; @@ -121,7 +142,7 @@ const FileTable = ({onFileRemoved, files}) => { ); } -const FileUploader = ({ onChange, files }) => { +const FileUploader = ({ onChange, files, reportId, id }) => { const onFilesAdded = (newFiles) => { onChange([...files, ...newFiles]); }; @@ -132,7 +153,7 @@ const FileUploader = ({ onChange, files }) => { return ( <> - + diff --git a/frontend/src/fetchers/File.js b/frontend/src/fetchers/File.js index 31389dca62..275d96f6c0 100644 --- a/frontend/src/fetchers/File.js +++ b/frontend/src/fetchers/File.js @@ -1,9 +1,16 @@ import join from 'url-join'; -import { get, put, post } from './index'; +import { get } from './index'; const activityReportUrl = join('/', 'api', 'files'); export const uploadFile = async (data) => { - const res = await post(activityReportUrl, data); - return res.json(); + const res = await fetch(activityReportUrl, { + method: 'POST', + credentials: 'same-origin', + body: data + }); + if (!res.ok) { + throw new Error(res.statusText); + } + return res; }; \ No newline at end of file diff --git a/frontend/src/pages/ActivityReport/Pages/topicsResources.js b/frontend/src/pages/ActivityReport/Pages/topicsResources.js index 11fb22fafb..2bc4cb9293 100644 --- a/frontend/src/pages/ActivityReport/Pages/topicsResources.js +++ b/frontend/src/pages/ActivityReport/Pages/topicsResources.js @@ -57,7 +57,7 @@ const TopicsResources = ({ defaultValue={[]} control={control} render={({ onChange, value }) => ( - + )} /> @@ -70,7 +70,7 @@ const TopicsResources = ({ defaultValue={[]} control={control} render={({ onChange, value }) => ( - + )} /> From 1932a1b3dc3679522bbc2a285dcc4ed6e5b65f5d Mon Sep 17 00:00:00 2001 From: Chuck McAndrew Date: Thu, 28 Jan 2021 14:43:03 -0500 Subject: [PATCH 04/35] Start adding front end styling for file upload --- frontend/src/components/FileUploader.css | 14 ++++ frontend/src/components/FileUploader.js | 73 ++++++++++++------- frontend/src/components/Navigator/index.js | 4 +- frontend/src/fetchers/File.js | 9 +++ .../ActivityReport/Pages/topicsResources.js | 8 +- frontend/src/pages/ActivityReport/index.js | 1 + 6 files changed, 77 insertions(+), 32 deletions(-) create mode 100644 frontend/src/fetchers/File.js diff --git a/frontend/src/components/FileUploader.css b/frontend/src/components/FileUploader.css index d14ce5f7ea..cf0e827586 100644 --- a/frontend/src/components/FileUploader.css +++ b/frontend/src/components/FileUploader.css @@ -23,3 +23,17 @@ .fa-stack { width: 1em; } + +.files-table { + width: 100%; + border-collapse: collapse; + /* border: 1px solid #979797; */ +} + +/* .files-table--file-name { + width: 50%; +} */ + +.files-table td { + text-align: center; +} \ No newline at end of file diff --git a/frontend/src/components/FileUploader.js b/frontend/src/components/FileUploader.js index 6c68e5eb05..d4f78a6c8e 100644 --- a/frontend/src/components/FileUploader.js +++ b/frontend/src/components/FileUploader.js @@ -10,7 +10,7 @@ import PropTypes from 'prop-types'; import { useDropzone } from 'react-dropzone'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { faTimes, faCircle } from '@fortawesome/free-solid-svg-icons'; +import { faTrash } from '@fortawesome/free-solid-svg-icons'; import { Tag, Button, Grid } from '@trussworks/react-uswds'; import './FileUploader.css'; @@ -18,6 +18,7 @@ import './FileUploader.css'; function Dropzone(props) { const { onChange } = props; const onDrop = (e) => { + console.log(e) onChange(e); }; const { getRootProps, getInputProps } = useDropzone({ onDrop }); @@ -37,30 +38,23 @@ function Dropzone(props) { }; const textStyle = { - textAlign: 'center', - fontSize: '16px', + textAlign: 'left', + fontSize: '1.25rem', + backgroundColor: "#0166AB", + color: "white", + padding: ".5rem", + borderRadius: "5px", }; - const linkStyle = { - cursor: 'pointer', - color: 'blue', - textDecoration: 'underline', - }; return (
-

- Drag and drop your files here - {' '} -
- or -
- Browse files -

+
); } @@ -81,13 +75,33 @@ const FileUploader = ({ onChange, files }) => { return ( <> - + + + + + + + + {files.map((file, index) => ( - - -
- {file.name} -
+
+ + + + + + + ))} - + +
+ Name + + Size + + Status + +
+ {file.name} + + {`${(file.size / 1000).toFixed(1) } KB`} + + Uploaded + - - +
+ ); }; diff --git a/frontend/src/components/Navigator/index.js b/frontend/src/components/Navigator/index.js index 1b7f0c2650..9a5e59a53c 100644 --- a/frontend/src/components/Navigator/index.js +++ b/frontend/src/components/Navigator/index.js @@ -29,6 +29,7 @@ function Navigator({ additionalData, onSave, autoSaveInterval, + reportId, }) { const [formData, updateFormData] = useState(initialData); const [errorMessage, updateErrorMessage] = useState(); @@ -131,6 +132,7 @@ function Navigator({ submitted, onFormSubmit, additionalData, + reportId, )} {!page.review && ( @@ -142,7 +144,7 @@ function Navigator({ onSubmit={handleSubmit(onContinue)} className="smart-hub--form-large" > - {page.render(hookForm, additionalData)} + {page.render(hookForm, additionalData, reportId)} diff --git a/frontend/src/fetchers/File.js b/frontend/src/fetchers/File.js new file mode 100644 index 0000000000..31389dca62 --- /dev/null +++ b/frontend/src/fetchers/File.js @@ -0,0 +1,9 @@ +import join from 'url-join'; +import { get, put, post } from './index'; + +const activityReportUrl = join('/', 'api', 'files'); + +export const uploadFile = async (data) => { + const res = await post(activityReportUrl, data); + return res.json(); +}; \ No newline at end of file diff --git a/frontend/src/pages/ActivityReport/Pages/topicsResources.js b/frontend/src/pages/ActivityReport/Pages/topicsResources.js index 86bc9df499..11fb22fafb 100644 --- a/frontend/src/pages/ActivityReport/Pages/topicsResources.js +++ b/frontend/src/pages/ActivityReport/Pages/topicsResources.js @@ -15,6 +15,7 @@ import { topics } from '../constants'; const TopicsResources = ({ register, control, + reportId, }) => ( <> @@ -56,7 +57,7 @@ const TopicsResources = ({ defaultValue={[]} control={control} render={({ onChange, value }) => ( - + )} /> @@ -69,7 +70,7 @@ const TopicsResources = ({ defaultValue={[]} control={control} render={({ onChange, value }) => ( - + )} /> @@ -113,12 +114,13 @@ export default { path: 'topics-resources', sections, review: false, - render: (hookForm) => { + render: (hookForm, additionalData, reportId) => { const { control, register } = hookForm; return ( ); }, diff --git a/frontend/src/pages/ActivityReport/index.js b/frontend/src/pages/ActivityReport/index.js index 28f471ad3d..a498320eaa 100644 --- a/frontend/src/pages/ActivityReport/index.js +++ b/frontend/src/pages/ActivityReport/index.js @@ -153,6 +153,7 @@ function ActivityReport({ match }) {

New activity report for Region 14

Date: Thu, 28 Jan 2021 15:14:53 -0500 Subject: [PATCH 05/35] Style file upload --- frontend/src/components/FileUploader.css | 14 +++++-- frontend/src/components/FileUploader.js | 48 +++++++++++++++--------- 2 files changed, 41 insertions(+), 21 deletions(-) diff --git a/frontend/src/components/FileUploader.css b/frontend/src/components/FileUploader.css index cf0e827586..90d6710490 100644 --- a/frontend/src/components/FileUploader.css +++ b/frontend/src/components/FileUploader.css @@ -30,10 +30,16 @@ /* border: 1px solid #979797; */ } -/* .files-table--file-name { - width: 50%; -} */ +.files-table--thead th, .files-table td { + padding: .5rem; + text-align: left; + font-size: .9rem; +} +.files-table--container { + border: solid 1px #979797; + min-height: 8rem; +} -.files-table td { +.files-table--empty { text-align: center; } \ No newline at end of file diff --git a/frontend/src/components/FileUploader.js b/frontend/src/components/FileUploader.js index d4f78a6c8e..b5b78b199e 100644 --- a/frontend/src/components/FileUploader.js +++ b/frontend/src/components/FileUploader.js @@ -63,30 +63,27 @@ Dropzone.propTypes = { onChange: PropTypes.func.isRequired, }; -const FileUploader = ({ onChange, files }) => { - const onFilesAdded = (newFiles) => { - onChange([...files, ...newFiles]); - }; - - const onFileRemoved = (removedFileIndex) => { - onChange(files.filter((f, index) => (index !== removedFileIndex))); - }; - +const FileTable = ({onFileRemoved, files}) => { + let msg + if (files.length === 0) { + msg = ( +

No files uploaded

+ ) + } return ( - <> - - - -
+
+ + + - - - @@ -120,6 +117,23 @@ const FileUploader = ({ onChange, files }) => { ))}
Name + Size + Status +
+ { msg } +
+ ); +} +const FileUploader = ({ onChange, files }) => { + const onFilesAdded = (newFiles) => { + onChange([...files, ...newFiles]); + }; + + const onFileRemoved = (removedFileIndex) => { + onChange(files.filter((f, index) => (index !== removedFileIndex))); + }; + + return ( + <> + + ); From c7a7af21fa8db5f220aaae3140078719a8275297 Mon Sep 17 00:00:00 2001 From: Chuck McAndrew Date: Thu, 28 Jan 2021 16:26:31 -0500 Subject: [PATCH 06/35] enable file upload --- frontend/src/components/FileUploader.js | 27 ++++++++++++++++--- frontend/src/fetchers/File.js | 13 ++++++--- .../ActivityReport/Pages/topicsResources.js | 4 +-- 3 files changed, 36 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/FileUploader.js b/frontend/src/components/FileUploader.js index b5b78b199e..3582f60de9 100644 --- a/frontend/src/components/FileUploader.js +++ b/frontend/src/components/FileUploader.js @@ -8,16 +8,37 @@ import React from 'react'; import PropTypes from 'prop-types'; import { useDropzone } from 'react-dropzone'; +import * as FS from 'fs'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faTrash } from '@fortawesome/free-solid-svg-icons'; import { Tag, Button, Grid } from '@trussworks/react-uswds'; +import { uploadFile } from '../fetchers/File'; import './FileUploader.css'; function Dropzone(props) { - const { onChange } = props; + const { onChange, id, reportId } = props; const onDrop = (e) => { + let attachmentType; + if (id === 'attachments') { + attachmentType = 'ATTACHMENT'; + } else if (id === "other-resources") { + attachmentType = 'RESOURCE'; + } + e.forEach( async (file) => { + try { + const data = new FormData() + data.append("reportId", reportId) + data.append("attachmentType", attachmentType) + data.append("file", file) + await uploadFile(data) + } catch (error) { + console.log(error) + } + + }); + console.log(e) onChange(e); }; @@ -121,7 +142,7 @@ const FileTable = ({onFileRemoved, files}) => { ); } -const FileUploader = ({ onChange, files }) => { +const FileUploader = ({ onChange, files, reportId, id }) => { const onFilesAdded = (newFiles) => { onChange([...files, ...newFiles]); }; @@ -132,7 +153,7 @@ const FileUploader = ({ onChange, files }) => { return ( <> - + diff --git a/frontend/src/fetchers/File.js b/frontend/src/fetchers/File.js index 31389dca62..275d96f6c0 100644 --- a/frontend/src/fetchers/File.js +++ b/frontend/src/fetchers/File.js @@ -1,9 +1,16 @@ import join from 'url-join'; -import { get, put, post } from './index'; +import { get } from './index'; const activityReportUrl = join('/', 'api', 'files'); export const uploadFile = async (data) => { - const res = await post(activityReportUrl, data); - return res.json(); + const res = await fetch(activityReportUrl, { + method: 'POST', + credentials: 'same-origin', + body: data + }); + if (!res.ok) { + throw new Error(res.statusText); + } + return res; }; \ No newline at end of file diff --git a/frontend/src/pages/ActivityReport/Pages/topicsResources.js b/frontend/src/pages/ActivityReport/Pages/topicsResources.js index 11fb22fafb..2bc4cb9293 100644 --- a/frontend/src/pages/ActivityReport/Pages/topicsResources.js +++ b/frontend/src/pages/ActivityReport/Pages/topicsResources.js @@ -57,7 +57,7 @@ const TopicsResources = ({ defaultValue={[]} control={control} render={({ onChange, value }) => ( - + )} /> @@ -70,7 +70,7 @@ const TopicsResources = ({ defaultValue={[]} control={control} render={({ onChange, value }) => ( - + )} /> From 84a97a6bb2498ef1cfc59d6475f8aacc8ccff7e5 Mon Sep 17 00:00:00 2001 From: Chuck McAndrew Date: Thu, 28 Jan 2021 16:52:33 -0500 Subject: [PATCH 07/35] fmt --- frontend/src/components/FileUploader.js | 84 +++++++++---------------- 1 file changed, 29 insertions(+), 55 deletions(-) diff --git a/frontend/src/components/FileUploader.js b/frontend/src/components/FileUploader.js index 3582f60de9..bb27f886bb 100644 --- a/frontend/src/components/FileUploader.js +++ b/frontend/src/components/FileUploader.js @@ -8,11 +8,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import { useDropzone } from 'react-dropzone'; -import * as FS from 'fs'; - import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faTrash } from '@fortawesome/free-solid-svg-icons'; -import { Tag, Button, Grid } from '@trussworks/react-uswds'; +import { Button } from '@trussworks/react-uswds'; import { uploadFile } from '../fetchers/File'; import './FileUploader.css'; @@ -23,57 +21,31 @@ function Dropzone(props) { let attachmentType; if (id === 'attachments') { attachmentType = 'ATTACHMENT'; - } else if (id === "other-resources") { + } else if (id === 'other-resources') { attachmentType = 'RESOURCE'; } e.forEach( async (file) => { - try { - const data = new FormData() - data.append("reportId", reportId) - data.append("attachmentType", attachmentType) - data.append("file", file) - await uploadFile(data) - } catch (error) { - console.log(error) - } - + try { + const data = new FormData(); + data.append('reportId', reportId); + data.append('attachmentType', attachmentType); + data.append('file', file) + await uploadFile(data) + } catch (error) { + // eslint-disable-next-line no-console + console.log(error); + } }); - - console.log(e) onChange(e); }; const { getRootProps, getInputProps } = useDropzone({ onDrop }); - // I tried moving these styles to a css file and applying a class to the container - // and span. The styles were not being applied, it seems like the Dropzone library - // is messing with the styles somewhere - const containerStyle = { - maxWidth: '21rem', - height: '8rem', - display: 'flex', - justifyContent: 'center', - alignItems: 'center', - borderStyle: 'dashed', - borderWidth: '0.125rem', - borderColor: '#979797', - }; - - const textStyle = { - textAlign: 'left', - fontSize: '1.25rem', - backgroundColor: "#0166AB", - color: "white", - padding: ".5rem", - borderRadius: "5px", - }; - - return (
-
@@ -82,35 +54,37 @@ function Dropzone(props) { Dropzone.propTypes = { onChange: PropTypes.func.isRequired, + reportId: PropTypes.any.isRequired, + id: PropTypes.string.isRequired, }; const FileTable = ({onFileRemoved, files}) => { let msg if (files.length === 0) { msg = ( -

No files uploaded

+

No files uploaded

) } return ( -
- - -
+
+ + + - - - {files.map((file, index) => ( - From 9a3f9f502ebc12a157da68cf1fa710cc27f77c9f Mon Sep 17 00:00:00 2001 From: Chuck McAndrew Date: Thu, 28 Jan 2021 17:25:17 -0500 Subject: [PATCH 08/35] fmt --- frontend/src/components/FileUploader.js | 118 ++++++++++-------- frontend/src/components/Navigator/index.js | 1 + frontend/src/fetchers/File.js | 7 +- .../ActivityReport/Pages/topicsResources.js | 1 + 4 files changed, 69 insertions(+), 58 deletions(-) diff --git a/frontend/src/components/FileUploader.js b/frontend/src/components/FileUploader.js index bb27f886bb..8c7deab3cf 100644 --- a/frontend/src/components/FileUploader.js +++ b/frontend/src/components/FileUploader.js @@ -10,8 +10,8 @@ import PropTypes from 'prop-types'; import { useDropzone } from 'react-dropzone'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faTrash } from '@fortawesome/free-solid-svg-icons'; -import { Button } from '@trussworks/react-uswds'; -import { uploadFile } from '../fetchers/File'; +import { Button } from '@trussworks/react-uswds'; +import uploadFile from '../fetchers/File'; import './FileUploader.css'; @@ -24,13 +24,13 @@ function Dropzone(props) { } else if (id === 'other-resources') { attachmentType = 'RESOURCE'; } - e.forEach( async (file) => { + e.forEach(async (file) => { try { const data = new FormData(); data.append('reportId', reportId); data.append('attachmentType', attachmentType); - data.append('file', file) - await uploadFile(data) + data.append('file', file); + await uploadFile(data); } catch (error) { // eslint-disable-next-line no-console console.log(error); @@ -45,7 +45,7 @@ function Dropzone(props) { {...getRootProps()} > - @@ -54,69 +54,77 @@ function Dropzone(props) { Dropzone.propTypes = { onChange: PropTypes.func.isRequired, - reportId: PropTypes.any.isRequired, + reportId: PropTypes.node.isRequired, id: PropTypes.string.isRequired, }; -const FileTable = ({onFileRemoved, files}) => { - let msg +const FileTable = ({ onFileRemoved, files }) => { + let msg; if (files.length === 0) { msg = ( -

No files uploaded

- ) +

No files uploaded

+ ); } return ( -
-
Name + Size + Status +
+ {file.name} @@ -121,14 +95,14 @@ const FileTable = ({onFileRemoved, files}) => {
- - - - - +
+
- Name - - Size - - Status - -
+ + + + + - {files.map((file, index) => ( - - - - - + {files.map((file, index) => ( + + + + + - + - ))} + ))}
+ Name + + Size + + Status +
- {file.name} - - {`${(file.size / 1000).toFixed(1) } KB`} - - Uploaded - - -
+ {file.name} + + {`${(file.size / 1000).toFixed(1)} KB`} + + Uploaded + + +
{ msg }
); -} -const FileUploader = ({ onChange, files, reportId, id }) => { +}; +FileTable.propTypes = { + onFileRemoved: PropTypes.func.isRequired, + files: PropTypes.arrayOf(PropTypes.instanceOf(File)), +}; +FileTable.defaultProps = { + files: [], +}; +const FileUploader = ({ + onChange, files, reportId, id, +}) => { const onFilesAdded = (newFiles) => { onChange([...files, ...newFiles]); }; @@ -129,7 +137,7 @@ const FileUploader = ({ onChange, files, reportId, id }) => { <> - + ); }; @@ -137,6 +145,8 @@ const FileUploader = ({ onChange, files, reportId, id }) => { FileUploader.propTypes = { onChange: PropTypes.func.isRequired, files: PropTypes.arrayOf(PropTypes.instanceOf(File)), + reportId: PropTypes.node.isRequired, + id: PropTypes.string.isRequired, }; FileUploader.defaultProps = { diff --git a/frontend/src/components/Navigator/index.js b/frontend/src/components/Navigator/index.js index 9a5e59a53c..a0cf8a44b0 100644 --- a/frontend/src/components/Navigator/index.js +++ b/frontend/src/components/Navigator/index.js @@ -172,6 +172,7 @@ Navigator.propTypes = { currentPage: PropTypes.string.isRequired, autoSaveInterval: PropTypes.number, additionalData: PropTypes.shape({}), + reportId: PropTypes.node.isRequired, }; Navigator.defaultProps = { diff --git a/frontend/src/fetchers/File.js b/frontend/src/fetchers/File.js index 275d96f6c0..a1a2f176b4 100644 --- a/frontend/src/fetchers/File.js +++ b/frontend/src/fetchers/File.js @@ -1,16 +1,15 @@ import join from 'url-join'; -import { get } from './index'; const activityReportUrl = join('/', 'api', 'files'); -export const uploadFile = async (data) => { +export default async function uploadFile(data) { const res = await fetch(activityReportUrl, { method: 'POST', credentials: 'same-origin', - body: data + body: data, }); if (!res.ok) { throw new Error(res.statusText); } return res; -}; \ No newline at end of file +} diff --git a/frontend/src/pages/ActivityReport/Pages/topicsResources.js b/frontend/src/pages/ActivityReport/Pages/topicsResources.js index 2bc4cb9293..994aacccd1 100644 --- a/frontend/src/pages/ActivityReport/Pages/topicsResources.js +++ b/frontend/src/pages/ActivityReport/Pages/topicsResources.js @@ -81,6 +81,7 @@ TopicsResources.propTypes = { register: PropTypes.func.isRequired, // eslint-disable-next-line react/forbid-prop-types control: PropTypes.object.isRequired, + reportId: PropTypes.node.isRequired, }; const sections = [ From 8a83029734c685dac555ccee4c1dd4971c8c1281 Mon Sep 17 00:00:00 2001 From: Chuck McAndrew Date: Fri, 29 Jan 2021 09:27:29 -0500 Subject: [PATCH 09/35] fix tests --- frontend/src/components/FileUploader.js | 7 +++++-- frontend/src/components/__tests__/FileUploader.js | 11 ++++++----- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/frontend/src/components/FileUploader.js b/frontend/src/components/FileUploader.js index 8c7deab3cf..a6a027e66a 100644 --- a/frontend/src/components/FileUploader.js +++ b/frontend/src/components/FileUploader.js @@ -67,8 +67,9 @@ const FileTable = ({ onFileRemoved, files }) => { } return (
- +
+ @@ -79,10 +80,12 @@ const FileTable = ({ onFileRemoved, files }) => { Status {files.map((file, index) => ( - + diff --git a/frontend/src/components/__tests__/FileUploader.js b/frontend/src/components/__tests__/FileUploader.js index e9f3ca4fc6..7498fba101 100644 --- a/frontend/src/components/__tests__/FileUploader.js +++ b/frontend/src/components/__tests__/FileUploader.js @@ -34,7 +34,7 @@ describe('FileUploader', () => { it('onDrop adds calls the onChange method', async () => { const mockOnChange = jest.fn(); const data = mockData([file('file')]); - const ui = ; + const ui = ; const { container, rerender } = render(ui); const dropzone = container.querySelector('div'); @@ -45,16 +45,17 @@ describe('FileUploader', () => { }); it('files are properly displayed', () => { - render( {}} files={[file('fileOne'), file('fileTwo')]} />); + render( {}} files={[file('fileOne'), file('fileTwo')]} />); expect(screen.getByText('fileOne')).toBeVisible(); expect(screen.getByText('fileTwo')).toBeVisible(); }); it('files can be removed', () => { const mockOnChange = jest.fn(); - render(); - const fileOne = screen.getByText('fileOne'); - fireEvent.click(fileOne.nextSibling); + render(); + const fileTwo = screen.getByText('fileTwo'); + console.log(fileTwo.parentNode.lastChild.firstChild) + fireEvent.click(fileTwo.parentNode.lastChild.firstChild); expect(mockOnChange).toHaveBeenCalledWith([file('fileTwo')]); }); From 68ba4c053b14bef566fd9e9ef5ca906d3978e570 Mon Sep 17 00:00:00 2001 From: Chuck McAndrew Date: Fri, 29 Jan 2021 17:10:16 -0500 Subject: [PATCH 10/35] update so attached files display --- frontend/src/components/FileUploader.js | 12 +++++------ .../src/components/__tests__/FileUploader.js | 4 ++-- .../ActivityReport/Pages/topicsResources.js | 8 +++---- .../20210129210854-add-fileSize-to-files.js | 14 +++++++++++++ src/models/activityReport.js | 3 ++- src/models/file.js | 4 ++++ src/routes/files/handlers.js | 15 +++++++++++-- src/routes/files/handlers.test.js | 10 +++++++++ src/services/activityReports.js | 21 ++++++++++++++++++- 9 files changed, 75 insertions(+), 16 deletions(-) create mode 100644 src/migrations/20210129210854-add-fileSize-to-files.js diff --git a/frontend/src/components/FileUploader.js b/frontend/src/components/FileUploader.js index a6a027e66a..0cb3433e8a 100644 --- a/frontend/src/components/FileUploader.js +++ b/frontend/src/components/FileUploader.js @@ -21,7 +21,7 @@ function Dropzone(props) { let attachmentType; if (id === 'attachments') { attachmentType = 'ATTACHMENT'; - } else if (id === 'other-resources') { + } else if (id === 'otherResources') { attachmentType = 'RESOURCE'; } e.forEach(async (file) => { @@ -31,12 +31,12 @@ function Dropzone(props) { data.append('attachmentType', attachmentType); data.append('file', file); await uploadFile(data); + onChange([{originalFileName: file.name, fileSize: file.size, status: "Uploaded"}]) } catch (error) { // eslint-disable-next-line no-console console.log(error); } }); - onChange(e); }; const { getRootProps, getInputProps } = useDropzone({ onDrop }); @@ -87,13 +87,13 @@ const FileTable = ({ onFileRemoved, files }) => { {files.map((file, index) => (
Name + +
{file.name}
- {file.name} + {file.originalFileName} - {`${(file.size / 1000).toFixed(1)} KB`} + {`${(file.fileSize / 1000).toFixed(1)} KB`} - Uploaded + {file.status} ); } @@ -81,13 +75,33 @@ const FileUploader = ({ onChange, files }) => { return ( <> - + + + + + + + + {files.map((file, index) => ( - - -
- {file.name} -
+
+ + + + + + + ))} - + +
+ Name + + Size + + Status + +
+ {file.name} + + {`${(file.size / 1000).toFixed(1) } KB`} + + Uploaded + - - +
+ ); }; diff --git a/frontend/src/components/Navigator/index.js b/frontend/src/components/Navigator/index.js index 1b7f0c2650..9a5e59a53c 100644 --- a/frontend/src/components/Navigator/index.js +++ b/frontend/src/components/Navigator/index.js @@ -29,6 +29,7 @@ function Navigator({ additionalData, onSave, autoSaveInterval, + reportId, }) { const [formData, updateFormData] = useState(initialData); const [errorMessage, updateErrorMessage] = useState(); @@ -131,6 +132,7 @@ function Navigator({ submitted, onFormSubmit, additionalData, + reportId, )} {!page.review && ( @@ -142,7 +144,7 @@ function Navigator({ onSubmit={handleSubmit(onContinue)} className="smart-hub--form-large" > - {page.render(hookForm, additionalData)} + {page.render(hookForm, additionalData, reportId)} diff --git a/frontend/src/fetchers/File.js b/frontend/src/fetchers/File.js new file mode 100644 index 0000000000..31389dca62 --- /dev/null +++ b/frontend/src/fetchers/File.js @@ -0,0 +1,9 @@ +import join from 'url-join'; +import { get, put, post } from './index'; + +const activityReportUrl = join('/', 'api', 'files'); + +export const uploadFile = async (data) => { + const res = await post(activityReportUrl, data); + return res.json(); +}; \ No newline at end of file diff --git a/frontend/src/pages/ActivityReport/Pages/topicsResources.js b/frontend/src/pages/ActivityReport/Pages/topicsResources.js index 86bc9df499..11fb22fafb 100644 --- a/frontend/src/pages/ActivityReport/Pages/topicsResources.js +++ b/frontend/src/pages/ActivityReport/Pages/topicsResources.js @@ -15,6 +15,7 @@ import { topics } from '../constants'; const TopicsResources = ({ register, control, + reportId, }) => ( <> @@ -56,7 +57,7 @@ const TopicsResources = ({ defaultValue={[]} control={control} render={({ onChange, value }) => ( - + )} /> @@ -69,7 +70,7 @@ const TopicsResources = ({ defaultValue={[]} control={control} render={({ onChange, value }) => ( - + )} /> @@ -113,12 +114,13 @@ export default { path: 'topics-resources', sections, review: false, - render: (hookForm) => { + render: (hookForm, additionalData, reportId) => { const { control, register } = hookForm; return ( ); }, diff --git a/frontend/src/pages/ActivityReport/index.js b/frontend/src/pages/ActivityReport/index.js index 7177a288c5..5e1157122d 100644 --- a/frontend/src/pages/ActivityReport/index.js +++ b/frontend/src/pages/ActivityReport/index.js @@ -152,6 +152,7 @@ function ActivityReport({ match }) {

New activity report for Region 14

Date: Thu, 28 Jan 2021 15:14:53 -0500 Subject: [PATCH 18/35] Style file upload --- frontend/src/components/FileUploader.css | 14 +++++-- frontend/src/components/FileUploader.js | 48 +++++++++++++++--------- 2 files changed, 41 insertions(+), 21 deletions(-) diff --git a/frontend/src/components/FileUploader.css b/frontend/src/components/FileUploader.css index cf0e827586..90d6710490 100644 --- a/frontend/src/components/FileUploader.css +++ b/frontend/src/components/FileUploader.css @@ -30,10 +30,16 @@ /* border: 1px solid #979797; */ } -/* .files-table--file-name { - width: 50%; -} */ +.files-table--thead th, .files-table td { + padding: .5rem; + text-align: left; + font-size: .9rem; +} +.files-table--container { + border: solid 1px #979797; + min-height: 8rem; +} -.files-table td { +.files-table--empty { text-align: center; } \ No newline at end of file diff --git a/frontend/src/components/FileUploader.js b/frontend/src/components/FileUploader.js index d4f78a6c8e..b5b78b199e 100644 --- a/frontend/src/components/FileUploader.js +++ b/frontend/src/components/FileUploader.js @@ -63,30 +63,27 @@ Dropzone.propTypes = { onChange: PropTypes.func.isRequired, }; -const FileUploader = ({ onChange, files }) => { - const onFilesAdded = (newFiles) => { - onChange([...files, ...newFiles]); - }; - - const onFileRemoved = (removedFileIndex) => { - onChange(files.filter((f, index) => (index !== removedFileIndex))); - }; - +const FileTable = ({onFileRemoved, files}) => { + let msg + if (files.length === 0) { + msg = ( +

No files uploaded

+ ) + } return ( - <> - - - -
+
+ + + - - - @@ -120,6 +117,23 @@ const FileUploader = ({ onChange, files }) => { ))}
Name + Size + Status +
+ { msg } +
+ ); +} +const FileUploader = ({ onChange, files }) => { + const onFilesAdded = (newFiles) => { + onChange([...files, ...newFiles]); + }; + + const onFileRemoved = (removedFileIndex) => { + onChange(files.filter((f, index) => (index !== removedFileIndex))); + }; + + return ( + <> + + ); From e09e2da057b7da5ef32443722a6307eb0a01845f Mon Sep 17 00:00:00 2001 From: Chuck McAndrew Date: Thu, 28 Jan 2021 16:26:31 -0500 Subject: [PATCH 19/35] enable file upload --- frontend/src/components/FileUploader.js | 27 ++++++++++++++++--- frontend/src/fetchers/File.js | 13 ++++++--- .../ActivityReport/Pages/topicsResources.js | 4 +-- 3 files changed, 36 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/FileUploader.js b/frontend/src/components/FileUploader.js index b5b78b199e..3582f60de9 100644 --- a/frontend/src/components/FileUploader.js +++ b/frontend/src/components/FileUploader.js @@ -8,16 +8,37 @@ import React from 'react'; import PropTypes from 'prop-types'; import { useDropzone } from 'react-dropzone'; +import * as FS from 'fs'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faTrash } from '@fortawesome/free-solid-svg-icons'; import { Tag, Button, Grid } from '@trussworks/react-uswds'; +import { uploadFile } from '../fetchers/File'; import './FileUploader.css'; function Dropzone(props) { - const { onChange } = props; + const { onChange, id, reportId } = props; const onDrop = (e) => { + let attachmentType; + if (id === 'attachments') { + attachmentType = 'ATTACHMENT'; + } else if (id === "other-resources") { + attachmentType = 'RESOURCE'; + } + e.forEach( async (file) => { + try { + const data = new FormData() + data.append("reportId", reportId) + data.append("attachmentType", attachmentType) + data.append("file", file) + await uploadFile(data) + } catch (error) { + console.log(error) + } + + }); + console.log(e) onChange(e); }; @@ -121,7 +142,7 @@ const FileTable = ({onFileRemoved, files}) => { ); } -const FileUploader = ({ onChange, files }) => { +const FileUploader = ({ onChange, files, reportId, id }) => { const onFilesAdded = (newFiles) => { onChange([...files, ...newFiles]); }; @@ -132,7 +153,7 @@ const FileUploader = ({ onChange, files }) => { return ( <> - + diff --git a/frontend/src/fetchers/File.js b/frontend/src/fetchers/File.js index 31389dca62..275d96f6c0 100644 --- a/frontend/src/fetchers/File.js +++ b/frontend/src/fetchers/File.js @@ -1,9 +1,16 @@ import join from 'url-join'; -import { get, put, post } from './index'; +import { get } from './index'; const activityReportUrl = join('/', 'api', 'files'); export const uploadFile = async (data) => { - const res = await post(activityReportUrl, data); - return res.json(); + const res = await fetch(activityReportUrl, { + method: 'POST', + credentials: 'same-origin', + body: data + }); + if (!res.ok) { + throw new Error(res.statusText); + } + return res; }; \ No newline at end of file diff --git a/frontend/src/pages/ActivityReport/Pages/topicsResources.js b/frontend/src/pages/ActivityReport/Pages/topicsResources.js index 11fb22fafb..2bc4cb9293 100644 --- a/frontend/src/pages/ActivityReport/Pages/topicsResources.js +++ b/frontend/src/pages/ActivityReport/Pages/topicsResources.js @@ -57,7 +57,7 @@ const TopicsResources = ({ defaultValue={[]} control={control} render={({ onChange, value }) => ( - + )} /> @@ -70,7 +70,7 @@ const TopicsResources = ({ defaultValue={[]} control={control} render={({ onChange, value }) => ( - + )} /> From 387a5e70601ba69f1d87a2d842e4a97be5893df9 Mon Sep 17 00:00:00 2001 From: Chuck McAndrew Date: Thu, 28 Jan 2021 14:43:03 -0500 Subject: [PATCH 20/35] rebase on main --- frontend/src/fetchers/File.js | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/fetchers/File.js b/frontend/src/fetchers/File.js index 275d96f6c0..815a012222 100644 --- a/frontend/src/fetchers/File.js +++ b/frontend/src/fetchers/File.js @@ -1,5 +1,4 @@ import join from 'url-join'; -import { get } from './index'; const activityReportUrl = join('/', 'api', 'files'); From 291fad8e203248f6e3668c910b65b477c6916b04 Mon Sep 17 00:00:00 2001 From: Chuck McAndrew Date: Thu, 28 Jan 2021 16:52:33 -0500 Subject: [PATCH 21/35] fmt --- frontend/src/components/FileUploader.js | 84 +++++++++---------------- 1 file changed, 29 insertions(+), 55 deletions(-) diff --git a/frontend/src/components/FileUploader.js b/frontend/src/components/FileUploader.js index 3582f60de9..bb27f886bb 100644 --- a/frontend/src/components/FileUploader.js +++ b/frontend/src/components/FileUploader.js @@ -8,11 +8,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import { useDropzone } from 'react-dropzone'; -import * as FS from 'fs'; - import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faTrash } from '@fortawesome/free-solid-svg-icons'; -import { Tag, Button, Grid } from '@trussworks/react-uswds'; +import { Button } from '@trussworks/react-uswds'; import { uploadFile } from '../fetchers/File'; import './FileUploader.css'; @@ -23,57 +21,31 @@ function Dropzone(props) { let attachmentType; if (id === 'attachments') { attachmentType = 'ATTACHMENT'; - } else if (id === "other-resources") { + } else if (id === 'other-resources') { attachmentType = 'RESOURCE'; } e.forEach( async (file) => { - try { - const data = new FormData() - data.append("reportId", reportId) - data.append("attachmentType", attachmentType) - data.append("file", file) - await uploadFile(data) - } catch (error) { - console.log(error) - } - + try { + const data = new FormData(); + data.append('reportId', reportId); + data.append('attachmentType', attachmentType); + data.append('file', file) + await uploadFile(data) + } catch (error) { + // eslint-disable-next-line no-console + console.log(error); + } }); - - console.log(e) onChange(e); }; const { getRootProps, getInputProps } = useDropzone({ onDrop }); - // I tried moving these styles to a css file and applying a class to the container - // and span. The styles were not being applied, it seems like the Dropzone library - // is messing with the styles somewhere - const containerStyle = { - maxWidth: '21rem', - height: '8rem', - display: 'flex', - justifyContent: 'center', - alignItems: 'center', - borderStyle: 'dashed', - borderWidth: '0.125rem', - borderColor: '#979797', - }; - - const textStyle = { - textAlign: 'left', - fontSize: '1.25rem', - backgroundColor: "#0166AB", - color: "white", - padding: ".5rem", - borderRadius: "5px", - }; - - return (
-
@@ -82,35 +54,37 @@ function Dropzone(props) { Dropzone.propTypes = { onChange: PropTypes.func.isRequired, + reportId: PropTypes.any.isRequired, + id: PropTypes.string.isRequired, }; const FileTable = ({onFileRemoved, files}) => { let msg if (files.length === 0) { msg = ( -

No files uploaded

+

No files uploaded

) } return ( -
- - -
+
+ + + - - - {files.map((file, index) => ( - From ab3b87a9f0f04426cae5a1306cf4da1612cb719c Mon Sep 17 00:00:00 2001 From: Chuck McAndrew Date: Thu, 28 Jan 2021 17:25:17 -0500 Subject: [PATCH 22/35] fmt --- frontend/src/components/FileUploader.js | 118 ++++++++++-------- frontend/src/components/Navigator/index.js | 1 + frontend/src/fetchers/File.js | 6 +- .../ActivityReport/Pages/topicsResources.js | 1 + 4 files changed, 69 insertions(+), 57 deletions(-) diff --git a/frontend/src/components/FileUploader.js b/frontend/src/components/FileUploader.js index bb27f886bb..8c7deab3cf 100644 --- a/frontend/src/components/FileUploader.js +++ b/frontend/src/components/FileUploader.js @@ -10,8 +10,8 @@ import PropTypes from 'prop-types'; import { useDropzone } from 'react-dropzone'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faTrash } from '@fortawesome/free-solid-svg-icons'; -import { Button } from '@trussworks/react-uswds'; -import { uploadFile } from '../fetchers/File'; +import { Button } from '@trussworks/react-uswds'; +import uploadFile from '../fetchers/File'; import './FileUploader.css'; @@ -24,13 +24,13 @@ function Dropzone(props) { } else if (id === 'other-resources') { attachmentType = 'RESOURCE'; } - e.forEach( async (file) => { + e.forEach(async (file) => { try { const data = new FormData(); data.append('reportId', reportId); data.append('attachmentType', attachmentType); - data.append('file', file) - await uploadFile(data) + data.append('file', file); + await uploadFile(data); } catch (error) { // eslint-disable-next-line no-console console.log(error); @@ -45,7 +45,7 @@ function Dropzone(props) { {...getRootProps()} > - @@ -54,69 +54,77 @@ function Dropzone(props) { Dropzone.propTypes = { onChange: PropTypes.func.isRequired, - reportId: PropTypes.any.isRequired, + reportId: PropTypes.node.isRequired, id: PropTypes.string.isRequired, }; -const FileTable = ({onFileRemoved, files}) => { - let msg +const FileTable = ({ onFileRemoved, files }) => { + let msg; if (files.length === 0) { msg = ( -

No files uploaded

- ) +

No files uploaded

+ ); } return ( -
-
Name + Size + Status +
+ {file.name} @@ -121,14 +95,14 @@ const FileTable = ({onFileRemoved, files}) => {
- - - - - +
+
- Name - - Size - - Status - -
+ + + + + - {files.map((file, index) => ( - - - - - + {files.map((file, index) => ( + + + + + - + - ))} + ))}
+ Name + + Size + + Status +
- {file.name} - - {`${(file.size / 1000).toFixed(1) } KB`} - - Uploaded - - -
+ {file.name} + + {`${(file.size / 1000).toFixed(1)} KB`} + + Uploaded + + +
{ msg }
); -} -const FileUploader = ({ onChange, files, reportId, id }) => { +}; +FileTable.propTypes = { + onFileRemoved: PropTypes.func.isRequired, + files: PropTypes.arrayOf(PropTypes.instanceOf(File)), +}; +FileTable.defaultProps = { + files: [], +}; +const FileUploader = ({ + onChange, files, reportId, id, +}) => { const onFilesAdded = (newFiles) => { onChange([...files, ...newFiles]); }; @@ -129,7 +137,7 @@ const FileUploader = ({ onChange, files, reportId, id }) => { <> - + ); }; @@ -137,6 +145,8 @@ const FileUploader = ({ onChange, files, reportId, id }) => { FileUploader.propTypes = { onChange: PropTypes.func.isRequired, files: PropTypes.arrayOf(PropTypes.instanceOf(File)), + reportId: PropTypes.node.isRequired, + id: PropTypes.string.isRequired, }; FileUploader.defaultProps = { diff --git a/frontend/src/components/Navigator/index.js b/frontend/src/components/Navigator/index.js index 9a5e59a53c..a0cf8a44b0 100644 --- a/frontend/src/components/Navigator/index.js +++ b/frontend/src/components/Navigator/index.js @@ -172,6 +172,7 @@ Navigator.propTypes = { currentPage: PropTypes.string.isRequired, autoSaveInterval: PropTypes.number, additionalData: PropTypes.shape({}), + reportId: PropTypes.node.isRequired, }; Navigator.defaultProps = { diff --git a/frontend/src/fetchers/File.js b/frontend/src/fetchers/File.js index 815a012222..a1a2f176b4 100644 --- a/frontend/src/fetchers/File.js +++ b/frontend/src/fetchers/File.js @@ -2,14 +2,14 @@ import join from 'url-join'; const activityReportUrl = join('/', 'api', 'files'); -export const uploadFile = async (data) => { +export default async function uploadFile(data) { const res = await fetch(activityReportUrl, { method: 'POST', credentials: 'same-origin', - body: data + body: data, }); if (!res.ok) { throw new Error(res.statusText); } return res; -}; \ No newline at end of file +} diff --git a/frontend/src/pages/ActivityReport/Pages/topicsResources.js b/frontend/src/pages/ActivityReport/Pages/topicsResources.js index 2bc4cb9293..994aacccd1 100644 --- a/frontend/src/pages/ActivityReport/Pages/topicsResources.js +++ b/frontend/src/pages/ActivityReport/Pages/topicsResources.js @@ -81,6 +81,7 @@ TopicsResources.propTypes = { register: PropTypes.func.isRequired, // eslint-disable-next-line react/forbid-prop-types control: PropTypes.object.isRequired, + reportId: PropTypes.node.isRequired, }; const sections = [ From b4c0aab31aa5d8397c8a57b77c3000600999b974 Mon Sep 17 00:00:00 2001 From: Chuck McAndrew Date: Fri, 29 Jan 2021 09:27:29 -0500 Subject: [PATCH 23/35] fix tests --- frontend/src/components/FileUploader.js | 7 +++++-- frontend/src/components/__tests__/FileUploader.js | 11 ++++++----- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/frontend/src/components/FileUploader.js b/frontend/src/components/FileUploader.js index 8c7deab3cf..a6a027e66a 100644 --- a/frontend/src/components/FileUploader.js +++ b/frontend/src/components/FileUploader.js @@ -67,8 +67,9 @@ const FileTable = ({ onFileRemoved, files }) => { } return (
- +
+ @@ -79,10 +80,12 @@ const FileTable = ({ onFileRemoved, files }) => { Status {files.map((file, index) => ( - + diff --git a/frontend/src/components/__tests__/FileUploader.js b/frontend/src/components/__tests__/FileUploader.js index e9f3ca4fc6..7498fba101 100644 --- a/frontend/src/components/__tests__/FileUploader.js +++ b/frontend/src/components/__tests__/FileUploader.js @@ -34,7 +34,7 @@ describe('FileUploader', () => { it('onDrop adds calls the onChange method', async () => { const mockOnChange = jest.fn(); const data = mockData([file('file')]); - const ui = ; + const ui = ; const { container, rerender } = render(ui); const dropzone = container.querySelector('div'); @@ -45,16 +45,17 @@ describe('FileUploader', () => { }); it('files are properly displayed', () => { - render( {}} files={[file('fileOne'), file('fileTwo')]} />); + render( {}} files={[file('fileOne'), file('fileTwo')]} />); expect(screen.getByText('fileOne')).toBeVisible(); expect(screen.getByText('fileTwo')).toBeVisible(); }); it('files can be removed', () => { const mockOnChange = jest.fn(); - render(); - const fileOne = screen.getByText('fileOne'); - fireEvent.click(fileOne.nextSibling); + render(); + const fileTwo = screen.getByText('fileTwo'); + console.log(fileTwo.parentNode.lastChild.firstChild) + fireEvent.click(fileTwo.parentNode.lastChild.firstChild); expect(mockOnChange).toHaveBeenCalledWith([file('fileTwo')]); }); From 1ecd7947a98f9407287596eec71f414d928df2a5 Mon Sep 17 00:00:00 2001 From: Chuck McAndrew Date: Fri, 29 Jan 2021 17:10:16 -0500 Subject: [PATCH 24/35] update so attached files display --- frontend/src/components/FileUploader.js | 12 +++++------ .../src/components/__tests__/FileUploader.js | 4 ++-- .../ActivityReport/Pages/topicsResources.js | 8 +++---- .../20210129210854-add-fileSize-to-files.js | 14 +++++++++++++ src/models/activityReport.js | 3 ++- src/models/file.js | 4 ++++ src/routes/files/handlers.js | 15 +++++++++++-- src/routes/files/handlers.test.js | 10 +++++++++ src/services/activityReports.js | 21 ++++++++++++++++++- 9 files changed, 75 insertions(+), 16 deletions(-) create mode 100644 src/migrations/20210129210854-add-fileSize-to-files.js diff --git a/frontend/src/components/FileUploader.js b/frontend/src/components/FileUploader.js index a6a027e66a..0cb3433e8a 100644 --- a/frontend/src/components/FileUploader.js +++ b/frontend/src/components/FileUploader.js @@ -21,7 +21,7 @@ function Dropzone(props) { let attachmentType; if (id === 'attachments') { attachmentType = 'ATTACHMENT'; - } else if (id === 'other-resources') { + } else if (id === 'otherResources') { attachmentType = 'RESOURCE'; } e.forEach(async (file) => { @@ -31,12 +31,12 @@ function Dropzone(props) { data.append('attachmentType', attachmentType); data.append('file', file); await uploadFile(data); + onChange([{originalFileName: file.name, fileSize: file.size, status: "Uploaded"}]) } catch (error) { // eslint-disable-next-line no-console console.log(error); } }); - onChange(e); }; const { getRootProps, getInputProps } = useDropzone({ onDrop }); @@ -87,13 +87,13 @@ const FileTable = ({ onFileRemoved, files }) => { {files.map((file, index) => ( {files.map((file, index) => ( - + @@ -112,8 +116,8 @@ const FileTable = ({ onFileRemoved, files }) => ( aria-label="remove file" onClick={() => { onFileRemoved(index); }} > - - + + diff --git a/src/models/file.js b/src/models/file.js index a105396655..2ab2a43b8a 100644 --- a/src/models/file.js +++ b/src/models/file.js @@ -32,6 +32,7 @@ module.exports = (sequelize, DataTypes) => { type: DataTypes.ENUM('ATTACHMENT', 'RESOURCE'), allowNull: false, }, + // File size in bytes fileSize: { type: DataTypes.INTEGER, allowNull: false, diff --git a/src/routes/files/handlers.js b/src/routes/files/handlers.js index 8927102dd7..7e34e7a513 100644 --- a/src/routes/files/handlers.js +++ b/src/routes/files/handlers.js @@ -69,7 +69,7 @@ export default async function uploadHandler(req, res) { const { path, originalFilename, size } = files.file[0]; const { reportId, attachmentType } = fields; if (!size) { - res.status(400).send({ error: 'improper file size' }); + res.status(400).send({ error: 'fileSize required' }); } if (!reportId) { res.status(400).send({ error: 'reportId required' }); From 95cdef92b66f7e8970ca3837fad2eb8fbaca73a8 Mon Sep 17 00:00:00 2001 From: Chuck McAndrew Date: Tue, 2 Feb 2021 21:31:23 -0500 Subject: [PATCH 35/35] fmt --- frontend/src/components/FileUploader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/FileUploader.js b/frontend/src/components/FileUploader.js index 647d0321b4..6239e4bc19 100644 --- a/frontend/src/components/FileUploader.js +++ b/frontend/src/components/FileUploader.js @@ -35,7 +35,7 @@ function Dropzone(props) { data.append('reportId', reportId); data.append('attachmentType', attachmentType); data.append('file', file); - res = await uploadFile(data); + await uploadFile(data); } catch (error) { setErrorMessage(`${file.name} failed to upload`); // eslint-disable-next-line no-console
Name + +
{file.name}
- {file.name} + {file.originalFileName} - {`${(file.size / 1000).toFixed(1)} KB`} + {`${(file.fileSize / 1000).toFixed(1)} KB`} - Uploaded + {file.status}
{file.originalFileName}