From bddb86d7655bd5dcdb5b5d8a719752c938280f06 Mon Sep 17 00:00:00 2001 From: Sam Date: Tue, 29 May 2018 20:08:34 +0200 Subject: [PATCH] Client: upload a zip archive containing gpx files --- mpwo_client/src/actions/activities.js | 12 +++- mpwo_client/src/actions/index.js | 4 ++ .../Activities/ActivityAddOrEdit.jsx | 12 +++- .../Activities/ActivityForms/FormWithGpx.jsx | 57 ++++++++++++------- mpwo_client/src/components/App.css | 15 +++++ mpwo_client/src/reducers/index.js | 10 ++++ mpwo_client/src/reducers/initial.js | 1 + 7 files changed, 87 insertions(+), 24 deletions(-) diff --git a/mpwo_client/src/actions/activities.js b/mpwo_client/src/actions/activities.js index 999b54ec..18ebc5ff 100644 --- a/mpwo_client/src/actions/activities.js +++ b/mpwo_client/src/actions/activities.js @@ -2,7 +2,7 @@ import mpwoGenericApi from '../mwpoApi' import mpwoApi from '../mwpoApi/activities' import { history } from '../index' import { formatChartData } from '../utils' -import { setError } from './index' +import { setError, setLoading } from './index' export const pushActivities = activities => ({ type: 'PUSH_ACTIVITIES', @@ -23,10 +23,17 @@ export const addActivity = form => dispatch => mpwoApi .addActivity(form) .then(ret => { if (ret.status === 'created') { - history.push(`/activities/${ret.data.activities[0].id}`) + if (ret.data.activities.length === 0) { + dispatch(setError('activities: no correct file')) + } else if (ret.data.activities.length === 1) { + history.push(`/activities/${ret.data.activities[0].id}`) + } else { // ret.data.activities.length > 1 + history.push('/') + } } else { dispatch(setError(`activities: ${ret.message}`)) } + dispatch(setLoading()) }) .catch(error => dispatch(setError(`activities: ${error}`))) @@ -97,6 +104,7 @@ export const editActivity = form => dispatch => mpwoGenericApi } else { dispatch(setError(`activities: ${ret.message}`)) } + dispatch(setLoading()) }) .catch(error => dispatch(setError(`activities: ${error}`))) diff --git a/mpwo_client/src/actions/index.js b/mpwo_client/src/actions/index.js index e8255a3b..7730976b 100644 --- a/mpwo_client/src/actions/index.js +++ b/mpwo_client/src/actions/index.js @@ -13,6 +13,10 @@ export const setError = message => ({ message, }) +export const setLoading = () => ({ + type: 'SET_LOADING', +}) + export const getData = (target, id = null, data = null) => dispatch => { if (id !== null && isNaN(id)) { return dispatch(setError(target, `${target}: Incorrect id`)) diff --git a/mpwo_client/src/components/Activities/ActivityAddOrEdit.jsx b/mpwo_client/src/components/Activities/ActivityAddOrEdit.jsx index 1fad5ca0..fb264a48 100644 --- a/mpwo_client/src/components/Activities/ActivityAddOrEdit.jsx +++ b/mpwo_client/src/components/Activities/ActivityAddOrEdit.jsx @@ -1,10 +1,11 @@ import React from 'react' import { Helmet } from 'react-helmet' +import { connect } from 'react-redux' import FormWithGpx from './ActivityForms/FormWithGpx' import FormWithoutGpx from './ActivityForms/FormWithoutGpx' -export default class ActivityAddEdit extends React.Component { +class ActivityAddEdit extends React.Component { constructor(props, context) { super(props, context) this.state = { @@ -21,7 +22,7 @@ export default class ActivityAddEdit extends React.Component { } render() { - const { activity, message, sports } = this.props + const { activity, loading, message, sports } = this.props const { withGpx } = this.state return (
@@ -59,6 +60,7 @@ export default class ActivityAddEdit extends React.Component { this.handleRadioChange(event)} /> @@ -70,6 +72,7 @@ export default class ActivityAddEdit extends React.Component { this.handleRadioChange(event)} /> @@ -96,3 +99,8 @@ export default class ActivityAddEdit extends React.Component { } } +export default connect( + state => ({ + loading: state.loading + }), +)(ActivityAddEdit) diff --git a/mpwo_client/src/components/Activities/ActivityForms/FormWithGpx.jsx b/mpwo_client/src/components/Activities/ActivityForms/FormWithGpx.jsx index 0c3d0466..aae64f2d 100644 --- a/mpwo_client/src/components/Activities/ActivityForms/FormWithGpx.jsx +++ b/mpwo_client/src/components/Activities/ActivityForms/FormWithGpx.jsx @@ -1,12 +1,15 @@ import React from 'react' import { connect } from 'react-redux' +import { setLoading } from '../../../actions/index' import { addActivity, editActivity } from '../../../actions/activities' import { history } from '../../../index' function FormWithGpx (props) { - const { activity, onAddActivity, onEditActivity, sports } = props + const { + activity, loading, onAddActivity, onEditActivity, sports + } = props const sportId = activity ? activity.sport_id : '' return (
@@ -39,6 +43,7 @@ function FormWithGpx (props) { @@ -46,10 +51,12 @@ function FormWithGpx (props) { ) : (
)} - activity - ? onEditActivity(event, activity) - : onAddActivity(event) - } - value="Submit" - /> - history.go(-1)} - value="Cancel" - /> + {loading ? ( +
+ ) : ( +
+ activity + ? onEditActivity(event, activity) + : onAddActivity(event) + } + value="Submit" + /> + history.go(-1)} + value="Cancel" + /> +
+ )} ) } export default connect( - () => ({ }), + state => ({ + loading: state.loading + }), dispatch => ({ onAddActivity: e => { + dispatch(setLoading()) const form = new FormData() form.append('file', e.target.form.gpxFile.files[0]) form.append( @@ -89,6 +105,7 @@ export default connect( dispatch(addActivity(form)) }, onEditActivity: (e, activity) => { + dispatch(setLoading()) dispatch(editActivity({ id: activity.id, sport_id: +e.target.form.sport.value, diff --git a/mpwo_client/src/components/App.css b/mpwo_client/src/components/App.css index 88780836..7015e898 100644 --- a/mpwo_client/src/components/App.css +++ b/mpwo_client/src/components/App.css @@ -173,3 +173,18 @@ input, textarea { .unlink { color: black; } + +.loader { + animation: spin 2s linear infinite; + border: 16px solid #f3f3f3; + border-top: 16px solid #3498db; + border-radius: 50%; + height: 120px; + margin-left: 41%; + width: 120px; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} diff --git a/mpwo_client/src/reducers/index.js b/mpwo_client/src/reducers/index.js index bc653d4e..7aa56998 100644 --- a/mpwo_client/src/reducers/index.js +++ b/mpwo_client/src/reducers/index.js @@ -93,6 +93,15 @@ const gpx = (state = initial.gpx, action) => { } } +const loading = (state = initial.loading, action) => { + switch (action.type) { + case 'SET_LOADING': + return !state + default: + return state + } +} + const message = (state = initial.message, action) => { switch (action.type) { case 'AUTH_ERROR': @@ -176,6 +185,7 @@ const reducers = combineReducers({ formData, formProfile, gpx, + loading, message, messages, records, diff --git a/mpwo_client/src/reducers/initial.js b/mpwo_client/src/reducers/initial.js index a6fcf7b7..d8a5004c 100644 --- a/mpwo_client/src/reducers/initial.js +++ b/mpwo_client/src/reducers/initial.js @@ -44,6 +44,7 @@ export default { chartData: [], // check if storing gpx content is OK gpx: null, + loading: false, records: { ...emptyData, },