Skip to content

Commit eaadf8f

Browse files
committed
feat: add loading state management for data fetching
- Add loading state tracking to Redux store with initial states for unit/service - Implement GET_RESOURCE_START action to set loading states to true - Update dataReducer to handle loading state transitions and normalize state structure - Modify Dashboard component to use loading state instead of checking for undefined data - Add setResourceFetchStart action dispatch in Main component before fetch operations
1 parent 14fad70 commit eaadf8f

4 files changed

Lines changed: 44 additions & 12 deletions

File tree

src/actions/index.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@ import _ from 'lodash';
22
import { createAction } from 'redux-actions';
33
import * as ApiClient from '../lib/municipal-services-client.js';
44

5+
export const setResourceFetchStart = createAction(
6+
'GET_RESOURCE_START',
7+
(resourceType) => resourceType,
8+
(resourceType) => ({ resourceType })
9+
);
10+
511
export const fetchUnitsWithServices = createAction(
612
'GET_RESOURCE',
713
ApiClient.fetchUnitsWithServices,

src/components/DashBoard.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { UnitListElement } from './UnitList';
88
class DashBoard extends React.Component {
99

1010
render() {
11-
if (this.props.nearest === undefined || this.props.frequent === undefined) {
11+
if (this.props.loading) {
1212
return <div>Ladataan...</div>;
1313
}
1414
let nearest;
@@ -48,14 +48,18 @@ function topUnits(n, units, unitsByUpdateCount) {
4848
function mapStateToProps(state) {
4949
if (_.keys(state.data.unit).length > 0) {
5050
return {
51+
loading: state.data.loading.unit,
5152
nearest: _.map(state.data.unitsByDistance, (u) => {
5253
return state.data.unit[u.id];
5354
}),
5455
frequent: topUnits(20, state.data.unit, state.unitsByUpdateCount),
5556
userLocation: state.userLocation
5657
};
5758
}
58-
return {};
59+
return {
60+
loading: state.data.loading.unit,
61+
userLocation: state.userLocation
62+
};
5963
}
6064

6165
function mapDispatchToProps() {

src/components/Main.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { connect } from 'react-redux';
66
import { Link, Outlet } from 'react-router-dom';
77
import _ from 'lodash';
88

9-
import { fetchUnitsWithServices, fetchResource, setUserLocation, getNearestUnits } from '../actions/index';
9+
import { fetchUnitsWithServices, fetchResource, setUserLocation, getNearestUnits, setResourceFetchStart, getResourceError } from '../actions/index';
1010
import { getCurrentSeason } from './utils';
1111
import { getInitialLocation } from '../lib/geolocation';
1212
import { withRouter } from '../hooks/index';
@@ -30,10 +30,12 @@ class AppComponent extends React.Component {
3030
let { navigate, auth } = this.props;
3131
requireAuth(navigate, auth);
3232
const services = constants.SERVICE_GROUPS[this.props.serviceGroup].services;
33+
this.props.setResourceFetchStart('service');
3334
this.props.fetchResource(
3435
'service', { id: services.join(',') },
3536
['id', 'name'], ['observable_properties']
3637
);
38+
this.props.setResourceFetchStart('unit');
3739
this.props.fetchUnitsWithServices(
3840
services, this.props.maintenanceOrganization, {
3941
selected: ['id', 'name', 'services', 'location', 'extensions'],
@@ -113,6 +115,9 @@ const mapDispatchToProps = (dispatch) => {
113115
},
114116
getNearestUnits: (...args) => {
115117
dispatch(getNearestUnits(...args));
118+
},
119+
setResourceFetchStart: (resourceType) => {
120+
dispatch(setResourceFetchStart(resourceType));
116121
}
117122
};
118123
};

src/reducers/index.js

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ const initialDataState = {
88
unitsByDistance: [],
99
observable_property: {},
1010
observation: {},
11-
service: {}
11+
service: {},
12+
loading: {}
1213
};
1314

1415
const initialAuthState = {
@@ -27,21 +28,37 @@ const serviceGroup = 'skiing';
2728

2829
function dataReducer(state = initialDataState, action) {
2930
switch (action.type) {
31+
case 'GET_RESOURCE_START':
32+
const startResourceType = action.meta.resourceType;
33+
return {
34+
...state,
35+
loading: {
36+
...state.loading,
37+
[startResourceType]: true
38+
}
39+
};
3040
case 'GET_RESOURCE':
3141
const resourceType = action.meta.resourceType;
3242
let existingResources = state[resourceType];
3343
if (action.meta.replaceAll === true) {
3444
existingResources = {};
3545
}
36-
return Object.assign(
37-
{}, state,
38-
{[resourceType]: Object.assign(
39-
existingResources,
40-
action.payload[resourceType])});
46+
return {
47+
...state,
48+
[resourceType]: {
49+
...existingResources,
50+
...action.payload[resourceType]
51+
},
52+
loading: {
53+
...state.loading,
54+
[resourceType]: false
55+
}
56+
};
4157
case 'GET_NEAREST_UNITS':
42-
return Object.assign(
43-
{}, state,
44-
{unitsByDistance: action.payload});
58+
return {
59+
...state,
60+
unitsByDistance: action.payload
61+
};
4562
}
4663
return state;
4764
}

0 commit comments

Comments
 (0)