Skip to content

Commit 9d3586c

Browse files
Swolfeyesfergarrui
authored andcommitted
Setup redux saga (#14)
* setup redux saga and reorganise folders * create contants for new actions * add tests to sagas * move post request to redux saga and add tests * create sagas for all requests
1 parent 69f2dee commit 9d3586c

32 files changed

+10293
-6424
lines changed

.babelrc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
{
2-
"presets": ["@babel/preset-env", "@babel/preset-react"]
2+
"presets": ["@babel/preset-env", "@babel/preset-react"],
3+
"plugins": ["@babel/plugin-transform-runtime"]
34
}

package-lock.json

Lines changed: 9518 additions & 6001 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,19 @@
2020
"watch:ts": "tsc --watch",
2121
"prettier": "prettier --write 'src/**/*.{ts,json}'",
2222
"prettier:check": "prettier --list-different 'src/**/*.{ts,json}'",
23-
"test": "jest",
23+
"test": "jest client/ --watch",
2424
"test:coverage": "npm run test -- --coverage",
2525
"tsc": "$(npm bin)/tsc",
2626
"copy-index": "copyfiles ./index.html ./dist/",
2727
"routes-gen": "tsoa routes",
2828
"server-webpack": "$(npm bin)/npm-run-all -s webpack:prod copy-index start:simple",
2929
"webpack:prod": "webpack --mode production"
3030
},
31+
"resolutions": {
32+
"babel-core": "7.0.0-bridge.0"
33+
},
3134
"jest": {
35+
"verbose": true,
3236
"coverageThreshold": {
3337
"global": {
3438
"statements": 0,
@@ -53,8 +57,12 @@
5357
"<rootDir>/node_modules/"
5458
],
5559
"transform": {
56-
"^.+\\.tsx?$": "ts-jest"
60+
"^.+\\.tsx?$": "ts-jest",
61+
"^.+\\.[t|j]s?$": "babel-jest"
5762
},
63+
"transformIgnorePatterns": [
64+
"/node_modules/(?!redux-saga)/"
65+
],
5866
"testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
5967
"moduleFileExtensions": [
6068
"ts",
@@ -65,6 +73,7 @@
6573
"testEnvironment": "node"
6674
},
6775
"dependencies": {
76+
"@babel/runtime": "^7.7.7",
6877
"@types/express": "^4.16.0",
6978
"async-polling": "^0.2.1",
7079
"bn.js": "^4.11.8",
@@ -85,7 +94,9 @@
8594
"react-svg-inline": "^2.1.1",
8695
"react-transition-group": "^1.2.1",
8796
"recursive-readdir": "^2.2.2",
97+
"redux-devtools-extension": "^2.13.8",
8898
"redux-logger": "^3.0.6",
99+
"redux-saga": "^1.1.3",
89100
"redux-thunk": "^2.3.0",
90101
"reflect-metadata": "^0.1.12",
91102
"solc": "^0.5.8",
@@ -96,15 +107,18 @@
96107
},
97108
"devDependencies": {
98109
"@babel/core": "^7.1.5",
110+
"@babel/plugin-transform-runtime": "^7.7.6",
99111
"@babel/preset-env": "^7.1.5",
100112
"@babel/preset-react": "^7.0.0",
101113
"@types/jest": "^23.3.1",
102114
"@types/node": "^10.12.18",
103-
"babel-core": "^6.26.3",
104-
"babel-loader": "^8.0.4",
115+
"babel-core": "^7.0.0-bridge.0",
116+
"babel-jest": "^24.9.0",
117+
"babel-loader": "^8.0.0-beta.0",
118+
"babel-polyfill": "^6.26.0",
105119
"classnames": "^2.2.6",
106120
"css-loader": "^1.0.1",
107-
"jest": "^23.5.0",
121+
"jest": "^24.9.0",
108122
"node-sass": "^4.10.0",
109123
"nodemon": "^1.18.3",
110124
"npm-run-all": "^4.1.3",
@@ -118,6 +132,7 @@
118132
"rimraf": "^2.5.2",
119133
"sass-loader": "^7.1.0",
120134
"sass-resources-loader": "^2.0.0",
135+
"sinon": "^8.0.2",
121136
"style-loader": "^0.23.1",
122137
"ts-jest": "^22.4.6",
123138
"tslint-config-prettier": "^1.14.0",

src/client/App.js

Lines changed: 28 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@ import React from 'react';
22
import { connect } from 'react-redux';
33
import { CSSTransitionGroup } from 'react-transition-group';
44

5-
import { showLoadingMessage, showErrorMessage, hideLoadingMessage } from './components/Store/Actions.js';
6-
7-
import { baseUrl } from './utils/baseUrl';
5+
import * as actions from './_redux/actions.js';
6+
import * as selectors from './_redux/selectors';
87

98
import TopNavBar from './components/TopNavBar/TopNavBar';
109
import Form from './components/Form/Form';
@@ -17,23 +16,6 @@ import styles from './styles/App.scss';
1716
import fade from './styles/transitions/fade.scss';
1817
import scale from './styles/transitions/scale.scss';
1918

20-
const mapStateToProps = state => {
21-
return {
22-
showLoadingMessage: state.loadingMessage.isLoading,
23-
loadingMessage: state.loadingMessage.message,
24-
showErrorMessage: state.errorMessage.hasError,
25-
errorMessage: state.errorMessage.message
26-
}
27-
}
28-
29-
const mapDispatchToProps = dispatch => {
30-
return {
31-
loadingMessageOn: message => dispatch(showLoadingMessage(message)),
32-
loadingMessageOff: () => dispatch(hideLoadingMessage()),
33-
errorMessageOn: message => dispatch(showErrorMessage(message)),
34-
}
35-
}
36-
3719
class App extends React.Component {
3820
constructor(props) {
3921
super(props);
@@ -49,7 +31,7 @@ class App extends React.Component {
4931
}
5032

5133
componentDidMount() {
52-
this.fetchData(baseUrl + 'solc/list');
34+
this.props.fetchSolcVersions();
5335
}
5436

5537
handleMenuItemIconClick(index) {
@@ -79,60 +61,16 @@ class App extends React.Component {
7961
settingsVisible: false,
8062
});
8163

82-
const url = `http://localhost:9090/files/${encodeURIComponent(parameter) || ' '}?extension=sol`;
83-
this.fetchData(url);
84-
}
85-
86-
fetchData(url) {
87-
this.handleRequestPending();
88-
89-
fetch(url)
90-
.then(res => res.json())
91-
.then(data => {
92-
data.error
93-
? this.handleRequestFail(data.message)
94-
: this.handleRequestSuccess(data);
95-
})
96-
.catch(err => this.handleRequestFail(err))
97-
;
98-
}
99-
100-
handleRequestPending() {
101-
this.props.loadingMessageOn('Loading...');
102-
}
103-
104-
handleRequestSuccess(response) {
105-
106-
if(response.some(item => item.version)) {
107-
this.setState({
108-
fetchRequestStatus: 'success',
109-
versions: response,
110-
});
111-
} else {
112-
this.setState({
113-
fetchRequestStatus: 'success',
114-
contracts: response,
115-
});
116-
}
117-
118-
this.props.loadingMessageOff();
119-
}
120-
121-
handleRequestFail(message) {
122-
this.props.loadingMessageOff();
123-
this.props.errorMessageOn(message);
64+
this.props.getParameter(parameter);
65+
this.props.fetchContracts();
12466
}
12567

12668
render() {
127-
128-
const { fetchRequestStatus, contracts, versions } = this.state;
129-
const { showLoadingMessage, showErrorMessage, errorMessage, loadingMessage } = this.props;
69+
const { isLoadingMessageOn, isErrorMessageOn, errorMessage, loadingMessage, versions, contracts } = this.props;
13070

13171
return (
13272
<div className={styles['app']}>
133-
<TopNavBar
134-
fetchRequestStatus={fetchRequestStatus}
135-
versions={versions}>
73+
<TopNavBar versions={versions}>
13674
<Form
13775
submitButton={true}
13876
inputTypes={[{ name: 'contractsPath', placeholder: 'Insert contracts path'}]}
@@ -149,7 +87,7 @@ class App extends React.Component {
14987
transitionEnterTimeout={300}
15088
transitionLeaveTimeout={300}
15189
>
152-
{ showLoadingMessage &&
90+
{ isLoadingMessageOn &&
15391
<MessageComp message={loadingMessage} />
15492
}
15593
</CSSTransitionGroup>
@@ -160,7 +98,7 @@ class App extends React.Component {
16098
transitionEnterTimeout={300}
16199
transitionLeaveTimeout={300}
162100
>
163-
{ showErrorMessage &&
101+
{ isErrorMessageOn &&
164102
<MessageComp
165103
message={errorMessage}
166104
onMessageButtonClick={() => this.handleMessageButtonClick()}
@@ -175,7 +113,7 @@ class App extends React.Component {
175113
transitionEnterTimeout={300}
176114
transitionLeaveTimeout={300}
177115
>
178-
{fetchRequestStatus === 'success' && contracts.length &&
116+
{!!contracts.length &&
179117
<Tab onMenuItemIconClick={this.handleMenuItemIconClick}>
180118
{contracts.map((item, i) => {
181119
return (
@@ -203,4 +141,22 @@ class App extends React.Component {
203141

204142
App.displayName = 'App';
205143

144+
const mapStateToProps = state => ({
145+
isLoadingMessageOn: state.loadingMessage.isLoading,
146+
loadingMessage: state.loadingMessage.message,
147+
isErrorMessageOn: state.errorMessage.hasError,
148+
errorMessage: state.errorMessage.message,
149+
datafromsaga: state.contracts.contracts,
150+
versions: selectors.getVersions(state),
151+
contracts: selectors.getContracts(state)
152+
})
153+
154+
const mapDispatchToProps = {
155+
toggleLoadingMessage: actions.toggleLoadingMessage,
156+
toggleErrorMessage: actions.toggleErrorMessage,
157+
getParameter: actions.getParameter,
158+
fetchContracts: actions.fetchContracts,
159+
fetchSolcVersions: actions.fetchSolcVersions
160+
}
161+
206162
export default connect(mapStateToProps, mapDispatchToProps)(App);;

src/client/_redux/Actions.js

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
import * as ActionTypes from './Constants.js';
2+
3+
export const fetchTransactionDebugger = (url, type, body) => dispatch => {
4+
dispatch({
5+
type: ActionTypes.FETCH_TRANSACTION_DEBUGGER,
6+
payload: {
7+
url,
8+
type,
9+
body,
10+
}
11+
});
12+
}
13+
14+
export const fetchStorage = (url, type) => dispatch => {
15+
dispatch({
16+
type: ActionTypes.FETCH_STORAGE,
17+
payload: {
18+
url,
19+
type
20+
}
21+
});
22+
}
23+
24+
export const fetchDisassembler = (url, type, body) => dispatch => {
25+
dispatch({
26+
type: ActionTypes.FETCH_DISASSEMBLER,
27+
payload: {
28+
url,
29+
type,
30+
body,
31+
}
32+
});
33+
}
34+
35+
export const fetchControlFlowGraph = (url, type, body) => dispatch => {
36+
dispatch({
37+
type: ActionTypes.FETCH_GRAPH,
38+
payload: {
39+
url,
40+
type,
41+
body
42+
}
43+
});
44+
}
45+
46+
export const getParameter = parameter => dispatch => {
47+
dispatch({
48+
type: ActionTypes.GET_PARAMETER,
49+
payload: {
50+
parameter
51+
}
52+
})
53+
}
54+
55+
export const fetchContracts = () => dispatch => {
56+
dispatch({
57+
type: ActionTypes.FETCH_CONTRACTS
58+
})
59+
}
60+
61+
export const fetchSolcVersions = () => dispatch => {
62+
dispatch({
63+
type: ActionTypes.FETCH_SOLC_VERSIONS
64+
})
65+
}
66+
67+
export const postVersion = version => dispatch => {
68+
dispatch({
69+
type: ActionTypes.POST_VERSION,
70+
payload: {
71+
version
72+
}
73+
});
74+
}
75+
76+
export const selectEditorLines = lines => dispatch => {
77+
dispatch({
78+
type: ActionTypes.SELECT_EDITOR_LINES,
79+
lines,
80+
})
81+
}
82+
83+
export const toggleEVMState = (evmState) => dispatch => {
84+
dispatch({
85+
type: ActionTypes.TOGGLE_EVM_STATE,
86+
payload: {
87+
evmState
88+
}
89+
})
90+
}
91+
92+
export const toggleLoadingMessage = (isLoadingMessageOn, message) => dispatch => {
93+
dispatch({
94+
type: ActionTypes.TOGGLE_LOADING_MESSAGE,
95+
payload : {
96+
isLoadingMessageOn: isLoadingMessageOn,
97+
message: message
98+
}
99+
})
100+
}
101+
102+
export const toggleErrorMessage = (isErrorMessageOn, message) => dispatch => {
103+
dispatch({
104+
type: ActionTypes.TOGGLE_ERROR_MESSAGE,
105+
payload : {
106+
isErrorMessageOn,
107+
message
108+
}
109+
})
110+
}
111+
112+
export const getVersionNumber = versionNum => dispatch => {
113+
dispatch({
114+
type: ActionTypes.GET_VERSION_NUM,
115+
versionNum,
116+
})
117+
}
118+
119+
export const addVersion = version => dispatch => {
120+
dispatch({
121+
type: ActionTypes.ADD_VERSION,
122+
payload: {
123+
version
124+
}
125+
})
126+
}

0 commit comments

Comments
 (0)