Skip to content

Commit

Permalink
Add upload progress indicator
Browse files Browse the repository at this point in the history
  • Loading branch information
adborden committed Nov 7, 2017
1 parent 476a4c7 commit a70e107
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 15 deletions.
1 change: 1 addition & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ globals:
jQuery: true
rules:
camelcase: 0
no-mixed-operators: 0
no-plusplus: 0
no-param-reassign:
- error
Expand Down
16 changes: 15 additions & 1 deletion js/actions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export const types = {
REQUEST_FORM_UPDATE: 'REQUEST_FORM_UPDATE',
REQUEST_FORM_SUBMIT: 'REQUEST_FORM_SUBMIT',
REQUEST_FORM_SUBMIT_COMPLETE: 'REQUEST_FORM_SUBMIT_COMPLETE',
REQUEST_FORM_SUBMIT_PROGRESS: 'REQUEST_FORM_SUBMIT_PROGRESS',
};

// Action creators, to dispatch actions
Expand Down Expand Up @@ -92,7 +93,11 @@ export const requestActions = {
formData,
});

return requestapi.post('/webform/submit', formData)
const options = {
onUploadProgress: requestActions.submitRequestFormProgress,
};

return requestapi.post('/webform/submit', formData, options)
.catch((error) => {
const submissionResult = {
errorMessage: 'There was a problem submitting your form.',
Expand All @@ -107,6 +112,15 @@ export const requestActions = {
.then(requestActions.completeSubmitRequestForm);
},

submitRequestFormProgress(progress) {
dispatcher.dispatch({
type: types.REQUEST_FORM_SUBMIT_PROGRESS,
progress,
});

return Promise.resolve();
},

completeSubmitRequestForm(submissionResult) {
dispatcher.dispatch({
type: types.REQUEST_FORM_SUBMIT_COMPLETE,
Expand Down
14 changes: 11 additions & 3 deletions js/components/foia_request_form.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import Form from 'react-jsonschema-form';
import { Map } from 'immutable';

import CustomFieldTemplate from 'components/request_custom_field_template';
import USWDSRadioWidget from 'components/uswds_radio_widget';
Expand All @@ -11,9 +12,10 @@ import ObjectFieldTemplate from './object_field_template';
import rf from '../util/request_form';
import FoiaFileWidget from './foia_file_widget';
import { dataUrlToAttachment, findFileFields } from '../util/attachment';
import UploadProgress from './upload_progress';


function FoiaRequestForm({ formData, isSubmitting, onSubmit, requestForm, submissionResult }) {
function FoiaRequestForm({ formData, upload, onSubmit, requestForm, submissionResult }) {
function onChange({ formData: data }) {
requestActions.updateRequestForm(data);
}
Expand Down Expand Up @@ -59,7 +61,7 @@ function FoiaRequestForm({ formData, isSubmitting, onSubmit, requestForm, submis
return (
<Form
className="foia-request-form"
disabled={isSubmitting}
disabled={upload.get('inProgress')}
FieldTemplate={CustomFieldTemplate}
formContext={formContext}
formData={formData.toJS()}
Expand Down Expand Up @@ -87,6 +89,12 @@ function FoiaRequestForm({ formData, isSubmitting, onSubmit, requestForm, submis
>
Submit request
</button>
{ upload.get('inProgress') &&
<UploadProgress
progressTotal={upload.get('progressTotal')}
progressLoaded={upload.get('progressLoaded')}
/>
}
{ submissionResult.errorMessage &&
<p>
<span className="usa-input-error-message" role="alert">
Expand All @@ -101,7 +109,7 @@ function FoiaRequestForm({ formData, isSubmitting, onSubmit, requestForm, submis

FoiaRequestForm.propTypes = {
formData: PropTypes.object.isRequired,
isSubmitting: PropTypes.bool.isRequired,
upload: PropTypes.instanceOf(Map).isRequired,
onSubmit: PropTypes.func,
requestForm: PropTypes.object.isRequired,
submissionResult: PropTypes.instanceOf(SubmissionResult).isRequired,
Expand Down
33 changes: 33 additions & 0 deletions js/components/upload_progress.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from 'react';
import PropTypes from 'prop-types';


function UploadProgress({ progressLoaded, progressTotal }) {
const percentage = Math.floor(progressLoaded / progressTotal * 100);
return (
<div>
{ progressLoaded &&
<progress
value={progressLoaded}
max={progressTotal}
>
{percentage}% uploaded…
</progress>
}
<p>Please be patient while we upload your request.</p>
</div>
);
}

UploadProgress.propTypes = {
progressLoaded: PropTypes.number,
progressTotal: PropTypes.number,
};

UploadProgress.defaultProps = {
progressTotal: 0,
progressLoaded: 0,
};


export default UploadProgress;
6 changes: 3 additions & 3 deletions js/pages/agency_component_request.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ class AgencyComponentRequestPage extends Component {
const agencyComponentId = props.match.params.agencyComponentId;
const agencyComponent = agencyComponentStore.getAgencyComponent(agencyComponentId);
const requestForm = agencyComponentRequestFormStore.getAgencyComponentForm(agencyComponentId);
const { formData, isSubmitting, submissionResult } = foiaRequestStore.getState();
const { formData, upload, submissionResult } = foiaRequestStore.getState();

return {
agencyComponent,
formData,
isSubmitting,
upload,
submissionResult,
requestForm,
};
Expand Down Expand Up @@ -92,7 +92,7 @@ class AgencyComponentRequestPage extends Component {
mainContent = (
<FoiaRequestForm
formData={this.state.formData}
isSubmitting={this.state.isSubmitting}
upload={this.state.upload}
onSubmit={onSubmit}
requestForm={requestForm}
submissionResult={this.state.submissionResult}
Expand Down
28 changes: 24 additions & 4 deletions js/stores/foia_request.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class FoiaRequestStore extends Store {

this.state = {
formData: new Map(),
isSubmitting: false,
upload: new Map(),
submissionResult: new SubmissionResult(),
};
}
Expand All @@ -40,12 +40,16 @@ class FoiaRequestStore extends Store {
}

case types.REQUEST_FORM_SUBMIT: {
if (this.state.isSubmitting) {
if (this.state.upload.get('inProgress')) {
break;
}

Object.assign(this.state, {
isSubmitting: true,
upload: this.state.upload.merge({
inProgress: true,
progressLoaded: 0,
progressTotal: 0,
}),
// Reset the previous submission results
submission_id: null,
errorMessage: null,
Expand All @@ -55,11 +59,27 @@ class FoiaRequestStore extends Store {
break;
}

case types.REQUEST_FORM_SUBMIT_PROGRESS: {
const progress = payload.progress;
if (!progress.lengthComputable) {
break;
}

Object.assign(this.state, {
upload: this.state.upload.merge({
progressLoaded: progress.loaded,
progressTotal: progress.total,
}),
});
this.__emitChange();
break;
}

case types.REQUEST_FORM_SUBMIT_COMPLETE: {
const { submissionResult } = this.state;
Object.assign(this.state, {
submissionResult: submissionResult.clear().merge(payload.submissionResult),
isSubmitting: false,
upload: this.state.upload.clear(),
});
this.__emitChange();
break;
Expand Down
10 changes: 6 additions & 4 deletions js/test/components/foia_request_form.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,11 @@ describe('FoiaRequestForm', () => {
let requestForm;
let submissionResult;
let element;
let upload;

beforeEach(() => {
formData = new Map();
upload = new Map();
submissionResult = new SubmissionResult();
requestForm = simpleSingleSectionRequestForm();
});
Expand All @@ -75,7 +77,7 @@ describe('FoiaRequestForm', () => {
element = shallow(
<FoiaRequestForm
formData={formData}
isSubmitting={false}
upload={upload}
requestForm={requestForm}
submissionResult={submissionResult}
/>,
Expand All @@ -92,7 +94,7 @@ describe('FoiaRequestForm', () => {
element = render(
<FoiaRequestForm
formData={formData}
isSubmitting={false}
upload={upload}
requestForm={requestForm}
submissionResult={submissionResult}
/>,
Expand Down Expand Up @@ -122,7 +124,7 @@ describe('FoiaRequestForm', () => {
element = shallow(
<FoiaRequestForm
formData={formData}
isSubmitting={false}
upload={upload}
onSubmit={onSubmit}
requestForm={requestForm}
submissionResult={submissionResult}
Expand Down Expand Up @@ -174,7 +176,7 @@ describe('FoiaRequestForm', () => {
element = render(
<FoiaRequestForm
formData={formData}
isSubmitting={false}
upload={upload}
requestForm={requestForm}
submissionResult={submissionResult}
/>,
Expand Down

0 comments on commit a70e107

Please sign in to comment.