[feature] Better loading indicator
- Use react-topbar-progress-indicator as a global loading indicator. - Added a global reducer that only holds `isFetching` for now. - Display loading indicator on any `*_REQUEST` actions. - Closes #103
This commit is contained in:
parent
f7b74453ab
commit
188fec4529
@ -122,10 +122,11 @@
|
|||||||
"react-router-redux": "^4.0.5",
|
"react-router-redux": "^4.0.5",
|
||||||
"react-simple-dnd": "^0.1.2",
|
"react-simple-dnd": "^0.1.2",
|
||||||
"react-toolbox": "^1.2.1",
|
"react-toolbox": "^1.2.1",
|
||||||
|
"react-topbar-progress-indicator": "^1.0.0",
|
||||||
"react-waypoint": "^3.1.3",
|
"react-waypoint": "^3.1.3",
|
||||||
"redux": "^3.3.1",
|
"redux": "^3.3.1",
|
||||||
"redux-optimist": "^0.0.2",
|
|
||||||
"redux-notifications": "^2.1.1",
|
"redux-notifications": "^2.1.1",
|
||||||
|
"redux-optimist": "^0.0.2",
|
||||||
"redux-thunk": "^1.0.3",
|
"redux-thunk": "^1.0.3",
|
||||||
"selection-position": "^1.0.0",
|
"selection-position": "^1.0.0",
|
||||||
"semaphore": "^1.0.5",
|
"semaphore": "^1.0.5",
|
||||||
|
@ -6,6 +6,7 @@ import { Layout, Panel, NavDrawer } from 'react-toolbox/lib/layout';
|
|||||||
import { Navigation } from 'react-toolbox/lib/navigation';
|
import { Navigation } from 'react-toolbox/lib/navigation';
|
||||||
import { Link } from 'react-toolbox/lib/link';
|
import { Link } from 'react-toolbox/lib/link';
|
||||||
import { Notifs } from 'redux-notifications';
|
import { Notifs } from 'redux-notifications';
|
||||||
|
import TopBarProgress from 'react-topbar-progress-indicator';
|
||||||
import { loadConfig } from '../actions/config';
|
import { loadConfig } from '../actions/config';
|
||||||
import { loginUser } from '../actions/auth';
|
import { loginUser } from '../actions/auth';
|
||||||
import { currentBackend } from '../backends/backend';
|
import { currentBackend } from '../backends/backend';
|
||||||
@ -21,6 +22,14 @@ import AppHeader from '../components/AppHeader/AppHeader';
|
|||||||
import { Loader, Toast } from '../components/UI/index';
|
import { Loader, Toast } from '../components/UI/index';
|
||||||
import styles from './App.css';
|
import styles from './App.css';
|
||||||
|
|
||||||
|
TopBarProgress.config({
|
||||||
|
barColors: {
|
||||||
|
0: '#3ab7a5',
|
||||||
|
'1.0': '#3ab7a5',
|
||||||
|
},
|
||||||
|
shadowBlur: 5,
|
||||||
|
});
|
||||||
|
|
||||||
class App extends React.Component {
|
class App extends React.Component {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
@ -33,6 +42,7 @@ class App extends React.Component {
|
|||||||
navigateToCollection: PropTypes.func.isRequired,
|
navigateToCollection: PropTypes.func.isRequired,
|
||||||
user: ImmutablePropTypes.map,
|
user: ImmutablePropTypes.map,
|
||||||
runCommand: PropTypes.func.isRequired,
|
runCommand: PropTypes.func.isRequired,
|
||||||
|
isFetching: PropTypes.bool.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
static configError(config) {
|
static configError(config) {
|
||||||
@ -126,6 +136,7 @@ class App extends React.Component {
|
|||||||
runCommand,
|
runCommand,
|
||||||
navigateToCollection,
|
navigateToCollection,
|
||||||
createNewEntryInCollection,
|
createNewEntryInCollection,
|
||||||
|
isFetching,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
if (config === null) {
|
if (config === null) {
|
||||||
@ -184,6 +195,7 @@ class App extends React.Component {
|
|||||||
toggleNavDrawer={this.toggleNavDrawer}
|
toggleNavDrawer={this.toggleNavDrawer}
|
||||||
/>
|
/>
|
||||||
<Panel scrollY>
|
<Panel scrollY>
|
||||||
|
{ isFetching && <TopBarProgress /> }
|
||||||
<div className={styles.main}>
|
<div className={styles.main}>
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
@ -194,10 +206,10 @@ class App extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function mapStateToProps(state) {
|
function mapStateToProps(state) {
|
||||||
const { auth, config, collections } = state;
|
const { auth, config, collections, global } = state;
|
||||||
const user = auth && auth.get('user');
|
const user = auth && auth.get('user');
|
||||||
|
const { isFetching } = global;
|
||||||
return { auth, config, collections, user };
|
return { auth, config, collections, user, isFetching };
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapDispatchToProps(dispatch) {
|
function mapDispatchToProps(dispatch) {
|
||||||
|
17
src/reducers/global.js
Normal file
17
src/reducers/global.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
/* Reducer for some global UI state that we want to share between components
|
||||||
|
* Now being used for isFetching state to display global loading indicator
|
||||||
|
* */
|
||||||
|
|
||||||
|
const globalReducer = (state = { isFetching: false }, action) => {
|
||||||
|
if ((action.type.indexOf('REQUEST') > -1)) {
|
||||||
|
return { isFetching: true };
|
||||||
|
} else if (
|
||||||
|
(action.type.indexOf('SUCCESS') > -1) ||
|
||||||
|
(action.type.indexOf('FAILURE') > -1)
|
||||||
|
) {
|
||||||
|
return { isFetching: false };
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default globalReducer;
|
@ -7,6 +7,7 @@ import editorialWorkflow, * as fromEditorialWorkflow from './editorialWorkflow';
|
|||||||
import entryDraft from './entryDraft';
|
import entryDraft from './entryDraft';
|
||||||
import collections from './collections';
|
import collections from './collections';
|
||||||
import medias, * as fromMedias from './medias';
|
import medias, * as fromMedias from './medias';
|
||||||
|
import global from './global';
|
||||||
|
|
||||||
const reducers = {
|
const reducers = {
|
||||||
auth,
|
auth,
|
||||||
@ -18,6 +19,7 @@ const reducers = {
|
|||||||
editorialWorkflow,
|
editorialWorkflow,
|
||||||
entryDraft,
|
entryDraft,
|
||||||
medias,
|
medias,
|
||||||
|
global,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default reducers;
|
export default reducers;
|
||||||
|
10
yarn.lock
10
yarn.lock
@ -6811,6 +6811,12 @@ react-toolbox@^1.2.1:
|
|||||||
normalize.css "~5.0.0"
|
normalize.css "~5.0.0"
|
||||||
react-css-themr "~1.4.1"
|
react-css-themr "~1.4.1"
|
||||||
|
|
||||||
|
react-topbar-progress-indicator:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-topbar-progress-indicator/-/react-topbar-progress-indicator-1.0.0.tgz#3379ab2cb840c1bc1bc22fb5fc871688b9104dd4"
|
||||||
|
dependencies:
|
||||||
|
topbar "^0.1.3"
|
||||||
|
|
||||||
react-waypoint@^3.1.3:
|
react-waypoint@^3.1.3:
|
||||||
version "3.1.3"
|
version "3.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/react-waypoint/-/react-waypoint-3.1.3.tgz#1101fb8a27556a199150c7bfd34428606b5fc7e4"
|
resolved "https://registry.yarnpkg.com/react-waypoint/-/react-waypoint-3.1.3.tgz#1101fb8a27556a199150c7bfd34428606b5fc7e4"
|
||||||
@ -8043,6 +8049,10 @@ to-fast-properties@^1.0.1:
|
|||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.2.tgz#f3f5c0c3ba7299a7ef99427e44633257ade43320"
|
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.2.tgz#f3f5c0c3ba7299a7ef99427e44633257ade43320"
|
||||||
|
|
||||||
|
topbar@^0.1.3:
|
||||||
|
version "0.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/topbar/-/topbar-0.1.3.tgz#c9ef8776dc4469f7840e6416f4136ddeccf4b7c6"
|
||||||
|
|
||||||
tough-cookie@^2.3.1, tough-cookie@~2.3.0:
|
tough-cookie@^2.3.1, tough-cookie@~2.3.0:
|
||||||
version "2.3.1"
|
version "2.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.1.tgz#99c77dfbb7d804249e8a299d4cb0fd81fef083fd"
|
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.1.tgz#99c77dfbb7d804249e8a299d4cb0fd81fef083fd"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user