From 1bb8c8874d081423807dad45d792f2ed339a68dd Mon Sep 17 00:00:00 2001
From: Tomasz Knapik <hi@tmkn.org>
Date: Tue, 15 Jan 2019 10:12:36 +0000
Subject: [PATCH] Add loading and errors to submissions by round

---
 .../src/app/src/components/Listing/index.js   | 11 ++++++-
 .../src/app/src/containers/ByStatusListing.js | 12 +++++--
 .../src/app/src/redux/actions/submissions.js  | 31 ++++++++++++++-----
 .../src/app/src/redux/reducers/submissions.js | 25 +++++++++++++--
 .../app/src/redux/selectors/submissions.js    |  6 ++++
 5 files changed, 72 insertions(+), 13 deletions(-)

diff --git a/opentech/static_src/src/app/src/components/Listing/index.js b/opentech/static_src/src/app/src/components/Listing/index.js
index dd8550bba..42a5186f6 100644
--- a/opentech/static_src/src/app/src/components/Listing/index.js
+++ b/opentech/static_src/src/app/src/components/Listing/index.js
@@ -8,6 +8,12 @@ import './style.scss';
 
 export default class Listing extends React.Component {
     renderListItems() {
+        if (this.props.isLoading) {
+            return <ListingItem title={"Loading..."} />;
+        } else if (this.props.isError) {
+            return <ListingItem title={"Something went wrong. Please try again later."} />;
+        }
+
         const listItems = [];
         for (const item of this.props.items) {
             listItems.push(
@@ -31,6 +37,7 @@ export default class Listing extends React.Component {
     }
 
     render() {
+        const { isLoading, isError } = this.props;
         return (
             <div className="listing">
                 <div className="listing__header">
@@ -43,7 +50,7 @@ export default class Listing extends React.Component {
                 </form>
                 </div>
                 <ul className="listing__list">
-                    {this.renderListItems()}
+                {this.renderListItems()}
                 </ul>
             </div>
         );
@@ -59,4 +66,6 @@ Listing.propTypes = {
             id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
         })),
     })),
+    isLoading: PropTypes.bool,
+    isError: PropTypes.bool,
 };
diff --git a/opentech/static_src/src/app/src/containers/ByStatusListing.js b/opentech/static_src/src/app/src/containers/ByStatusListing.js
index 6e4c26e68..58aaf392d 100644
--- a/opentech/static_src/src/app/src/containers/ByStatusListing.js
+++ b/opentech/static_src/src/app/src/containers/ByStatusListing.js
@@ -3,7 +3,12 @@ import PropTypes from 'prop-types';
 import { connect } from 'react-redux'
 
 import Listing from '@components/Listing';
-import { getCurrentRound, getCurrentRoundSubmissionsByStatus } from '@selectors/submissions';
+import {
+    getCurrentRound,
+    getCurrentRoundSubmissionsByStatus,
+    getSubmissionsByRoundErrorState,
+    getSubmissionsByRoundLoadingState,
+} from '@selectors/submissions';
 import { setCurrentSubmissionRound, fetchSubmissionsByRound } from '@actions/submissions';
 
 
@@ -25,7 +30,8 @@ class ByStatusListing extends React.Component {
     }
 
     render() {
-        return <Listing items={this.getListingItems()} />;
+        const { isLoading, isError } = this.props;
+        return <Listing isLoading={isLoading} isError={isError} items={this.getListingItems()} />;
     }
 
     getListingItems() {
@@ -43,6 +49,8 @@ class ByStatusListing extends React.Component {
 const mapStateToProps = state => ({
     items: getCurrentRoundSubmissionsByStatus(state),
     roundId: getCurrentRound(state),
+    isError: getSubmissionsByRoundErrorState(state),
+    isLoading: getSubmissionsByRoundLoadingState(state),
 });
 
 const mapDispatchToProps = dispatch => ({
diff --git a/opentech/static_src/src/app/src/redux/actions/submissions.js b/opentech/static_src/src/app/src/redux/actions/submissions.js
index fc6f8203d..b2e5ad27a 100644
--- a/opentech/static_src/src/app/src/redux/actions/submissions.js
+++ b/opentech/static_src/src/app/src/redux/actions/submissions.js
@@ -1,28 +1,30 @@
 import api from '@api';
 
 
+// Submissions by round
 export const SET_CURRENT_SUBMISSION_ROUND = 'SET_CURRENT_SUBMISSION_ROUND';
-
 export const UPDATE_SUBMISSIONS_BY_ROUND = 'UPDATE_SUBMISSIONS_BY_ROUND';
+export const START_LOADING_SUBMISSIONS_BY_ROUND = 'START_LOADING_SUBMISSIONS_BY_ROUND';
+export const FAIL_LOADING_SUBMISSIONS_BY_ROUND = 'FAIL_LOADING_SUBMISSIONS_BY_ROUND';
+
 
 export const setCurrentSubmissionRound = id => ({
     type: SET_CURRENT_SUBMISSION_ROUND,
     id,
 });
 
-export const fetchSubmissionsByRound = id => {
+export const fetchSubmissionsByRound = roundId => {
     return async function(dispatch) {
-        //dispatch(fetchSubmissionsByRoundBegin());
+        dispatch(startLoadingSubmissionsByRound(roundId));
         try {
-            const response = await api.fetchSubmissionsByRound(id);
+            const response = await api.fetchSubmissionsByRound(roundId);
             const json = await response.json();
             if (!response.ok) {
-                // handle error
+                dispatch(failLoadingSubmissionsByRound(roundId));
             }
-            dispatch(updateSubmissionsByRound(id, json));
+            dispatch(updateSubmissionsByRound(roundId, json));
         } catch (e) {
-            console.error(e);
-            // handle error
+            dispatch(failLoadingSubmissionsByRound(roundId));
         }
     };
 };
@@ -33,3 +35,16 @@ export const updateSubmissionsByRound = (roundId, data) => ({
     roundId,
     data,
 });
+
+
+const startLoadingSubmissionsByRound = roundId => ({
+    type: START_LOADING_SUBMISSIONS_BY_ROUND,
+    roundId,
+});
+
+
+
+const failLoadingSubmissionsByRound = roundId => ({
+    type: FAIL_LOADING_SUBMISSIONS_BY_ROUND,
+    roundId,
+});
diff --git a/opentech/static_src/src/app/src/redux/reducers/submissions.js b/opentech/static_src/src/app/src/redux/reducers/submissions.js
index 2f82a4ff2..3497bf910 100644
--- a/opentech/static_src/src/app/src/redux/reducers/submissions.js
+++ b/opentech/static_src/src/app/src/redux/reducers/submissions.js
@@ -1,8 +1,15 @@
-import { SET_CURRENT_SUBMISSION_ROUND, UPDATE_SUBMISSIONS_BY_ROUND } from '@actions/submissions';
+import {
+    FAIL_LOADING_SUBMISSIONS_BY_ROUND,
+    SET_CURRENT_SUBMISSION_ROUND,
+    START_LOADING_SUBMISSIONS_BY_ROUND,
+    UPDATE_SUBMISSIONS_BY_ROUND,
+} from '@actions/submissions';
 
 const initialState = {
     currentRound: null,
-    itemsByRound: {}
+    itemsByRound: {},
+    itemsByRoundLoadingError: false,
+    itemsByRoundLoading: false,
 };
 
 export default function submissions(state = initialState, action) {
@@ -22,6 +29,20 @@ export default function submissions(state = initialState, action) {
                     ...state.itemsByRound,
                     ...newData,
                 },
+                itemsByRoundLoading: false,
+                itemsByRoundLoadingError: false,
+            };
+        case FAIL_LOADING_SUBMISSIONS_BY_ROUND:
+            return {
+                ...state,
+                itemsByRoundLoading: false,
+                itemsByRoundLoadingError: true,
+            };
+        case START_LOADING_SUBMISSIONS_BY_ROUND:
+            return {
+                ...state,
+                itemsByRoundLoading: true,
+                itemsByRoundLoadingError: false,
             };
         default:
             return state;
diff --git a/opentech/static_src/src/app/src/redux/selectors/submissions.js b/opentech/static_src/src/app/src/redux/selectors/submissions.js
index b5f45db34..5a995e997 100644
--- a/opentech/static_src/src/app/src/redux/selectors/submissions.js
+++ b/opentech/static_src/src/app/src/redux/selectors/submissions.js
@@ -31,8 +31,14 @@ const getCurrentRoundSubmissionsByStatus = createSelector(
     }
 );
 
+const getSubmissionsByRoundErrorState = state => state.submissions.itemsByRoundLoadingError;
+
+const getSubmissionsByRoundLoadingState = state => state.submissions.itemsByRoundLoading;
+
 export {
     getCurrentRound,
     getCurrentRoundSubmissions,
     getCurrentRoundSubmissionsByStatus,
+    getSubmissionsByRoundErrorState,
+    getSubmissionsByRoundLoadingState,
 };
-- 
GitLab