Skip to content
This repository has been archived by the owner on Apr 15, 2019. It is now read-only.

Migrate global loading bar to React - Closes #494 #538

Merged
merged 6 commits into from
Aug 1, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions src/actions/loading.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import actionTypes from '../constants/actions';

/**
* An action to dispatch loadingStarted
*
*/
export const loadingStarted = data => ({
data,
type: actionTypes.loadingStarted,
});

/**
* An action to dispatch loadingFinished
*
*/
export const loadingFinished = data => ({
data,
type: actionTypes.loadingFinished,
});
33 changes: 33 additions & 0 deletions src/actions/loding.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { expect } from 'chai';
import actionTypes from '../constants/actions';
import {
loadingStarted,
loadingFinished,
} from './loading';


describe('actions: loading', () => {
describe('loadingStarted', () => {
it('should create an action to show loading bar', () => {
const data = 'test';

const expectedAction = {
data,
type: actionTypes.loadingStarted,
};
expect(loadingStarted(data)).to.be.deep.equal(expectedAction);
});
});

describe('loadingFinished', () => {
it('should create an action to hide loading bar', () => {
const data = 'test';

const expectedAction = {
data,
type: actionTypes.loadingFinished,
};
expect(loadingFinished(data)).to.be.deep.equal(expectedAction);
});
});
});
3 changes: 2 additions & 1 deletion src/components/app/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import styles from './app.css';
import Metronome from '../../utils/metronome';
import Dialog from '../dialog';
import Tabs from '../tabs';
// temporary, will be deleted with #347
import LoadingBar from '../loadingBar';

// start dispatching sync ticks
const metronome = new Metronome();
Expand All @@ -33,6 +33,7 @@ const App = () => (
<Route exact path="/" component={Login} />
</main>
<Dialog />
<LoadingBar />
</section>
);

Expand Down
10 changes: 10 additions & 0 deletions src/components/loadingBar/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

import { connect } from 'react-redux';
import LoadingBar from './loadingBar';

const mapStateToProps = state => ({
loading: state.loading,
});

export default connect(mapStateToProps)(LoadingBar);

19 changes: 19 additions & 0 deletions src/components/loadingBar/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react';
import { expect } from 'chai';
import { mount } from 'enzyme';
import { Provider } from 'react-redux';
import LoadingBar from './';
import store from '../../store';


describe('LoadingBar Container', () => {
let wrapper;

beforeEach(() => {
wrapper = mount(<Provider store={store}><LoadingBar /></Provider>);
});

it('should render Send', () => {
expect(wrapper.find('LoadingBar')).to.have.lengthOf(1);
});
});
7 changes: 7 additions & 0 deletions src/components/loadingBar/loadingBar.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.fixedAtTop {
position: fixed;
top: -11px;
right: 0;
width: 100vw;
z-index: 201;
}
14 changes: 14 additions & 0 deletions src/components/loadingBar/loadingBar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from 'react';
import ProgressBar from 'react-toolbox/lib/progress_bar';
import styles from './loadingBar.css';

const LoadingBar = props => (
<div className={styles.fixedAtTop}>
{props.loading && props.loading.length ?
<ProgressBar type="linear" mode="indeterminate" /> :
null
}
</div>
);

export default LoadingBar;
17 changes: 17 additions & 0 deletions src/components/loadingBar/loadingBar.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react';
import { expect } from 'chai';
import { mount } from 'enzyme';
import LoadingBar from './loadingBar';


describe('LoadingBar Container', () => {
it('should show ProgresBar if props.loading.length is not 0', () => {
const wrapper = mount(<LoadingBar loading={['test']} />);
expect(wrapper.find('ProgressBar')).to.have.lengthOf(1);
});

it('should not show ProgresBar if props.loading.length is 0', () => {
const wrapper = mount(<LoadingBar loading={[]} />);
expect(wrapper.find('ProgressBar')).to.have.lengthOf(0);
});
});
2 changes: 2 additions & 0 deletions src/constants/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ const actionTypes = {
dialogHidden: 'DIALOG_HIDDEN',
forgedBlocksUpdated: 'FORGED_BLOCKS_UPDATED',
forgingStatsUpdated: 'FORGING_STATS_UPDATED',
loadingStarted: 'LOADING_STARTED',
loadingFinished: 'LOADING_FINISHED',
};

export default actionTypes;
1 change: 1 addition & 0 deletions src/store/reducers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ export { default as account } from './account';
export { default as peers } from './peers';
export { default as dialog } from './dialog';
export { default as forging } from './forging';
export { default as loading } from './loading';

19 changes: 19 additions & 0 deletions src/store/reducers/loading.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import actionTypes from '../../constants/actions';

/**
*
* @param {Array} state
* @param {Object} action
*/
const dialog = (state = [], action) => {
switch (action.type) {
case actionTypes.loadingStarted:
return [...state, action.data];
case actionTypes.loadingFinished:
return state.filter(item => item !== action.data);
default:
return state;
}
};

export default dialog;
34 changes: 34 additions & 0 deletions src/store/reducers/loding.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import chai, { expect } from 'chai';
import sinonChai from 'sinon-chai';
import loading from './loading';
import actionTypes from '../../constants/actions';


chai.use(sinonChai);

describe('Reducer: loading(state, action)', () => {
let state;

beforeEach(() => {
state = ['test1', 'test2'];
});

it('should return loading array with the new loading if action.type = actionTypes.loadingStarted', () => {
const action = {
type: actionTypes.loadingStarted,
data: 'test3',
};
const changedState = loading(state, action);
expect(changedState).to.deep.equal([...state, action.data]);
});

it('should return loading array without action.data if action.type = actionTypes.loadingFinished', () => {
const action = {
type: actionTypes.loadingFinished,
data: 'test1',
};
const changedState = loading(state, action);
expect(changedState).to.deep.equal(['test2']);
});
});

4 changes: 4 additions & 0 deletions src/utils/api/peers.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import { loadingStarted, loadingFinished } from '../../utils/loading';

/* eslint-disable */
export const requestToActivePeer = (activePeer, path, urlParams) =>
new Promise((resolve, reject) => {
loadingStarted(path);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should use loading actions inside our component instead of using them inside our api utils

activePeer.sendRequest(path, urlParams, (data) => {
if (data.success) {
resolve(data);
} else {
reject(data);
}
loadingFinished(path);
});
});
/* eslint-enable */
7 changes: 7 additions & 0 deletions src/utils/loading.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { loadingStarted as loadingStartedAction, loadingFinished as loadingFinishedAction } from '../actions/loading';
import store from '../store';


export const loadingStarted = data => store.dispatch(loadingStartedAction(data));

export const loadingFinished = data => store.dispatch(loadingFinishedAction(data));