Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Rex Dri
Rex Dri
Commits
a3cf92a7
Commit
a3cf92a7
authored
Aug 23, 2018
by
Florent Chehab
Browse files
Automatic generation of actions and reducers for Redux
parent
adc1d2fe
Changes
14
Hide whitespace changes
Inline
Side-by-side
frontend/generate/generate_frontend_files.js
0 → 100644
View file @
a3cf92a7
let
swig
=
require
(
'
swig
'
);
let
fs
=
require
(
'
fs
'
);
let
path
=
require
(
'
path
'
);
let
saving_dir
=
path
.
normalize
(
path
.
dirname
(
__filename
)
+
"
/../src/generated/
"
)
if
(
!
fs
.
existsSync
(
saving_dir
)){
fs
.
mkdirSync
(
saving_dir
);
}
let
templates_dir
=
path
.
dirname
(
__filename
)
+
'
/templates/
'
;
let
templates
=
[
'
action-types
'
,
'
actions
'
,
'
reducers
'
]
let
config
=
[
{
NAME
:
'
UNIVERSITIES
'
,
name
:
'
universities
'
},
{
NAME
:
'
COUNTRIES
'
,
name
:
'
countries
'
}
]
templates
.
forEach
(
function
(
filename
)
{
let
template
=
swig
.
compileFile
(
templates_dir
+
filename
+
'
.tpl
'
);
let
output
=
""
;
config
.
forEach
(
function
(
obj
)
{
output
+=
template
(
obj
)
+
"
\n\n
"
;
})
fs
.
writeFile
(
saving_dir
+
filename
+
"
.js
"
,
output
,
function
(
err
)
{
if
(
err
)
{
return
console
.
log
(
err
);
};
});
});
frontend/generate/templates/action-types.tpl
0 → 100644
View file @
a3cf92a7
export const {
{
NAME
}
}_HAS_ERROR = '{
{
NAME
}
}_HAS_ERROR'
export const {
{
NAME
}
}_IS_LOADING = '{
{
NAME
}
}_IS_LOADING'
export const {
{
NAME
}
}_FETCH_DATA_SUCCESS = '{
{
NAME
}
}_FETCH_DATA_SUCCESS'
export const {
{
NAME
}
}_INVALIDATED = '{
{
NAME
}
}_INVALIDATED'
frontend/
src/actions/countries.js
→
frontend/
generate/templates/actions.tpl
View file @
a3cf92a7
import {
import {
COUNTRIES
_HAS_ERROR
,
{
{
NAME
}
}
_HAS_ERROR,
COUNTRIES
_IS_LOADING
,
{
{
NAME
}
}
_IS_LOADING,
COUNTRIES
_FETCH_DATA_SUCCESS
,
{
{
NAME
}
}
_FETCH_DATA_SUCCESS,
COUNTRIES
_INVALIDATED
{
{
NAME
}
}
_INVALIDATED
}
from
"
.
./constants
/action-types
"
;
} from "./action-types";
export
function
countries
HasError
(
bool
)
{
export function
{
{
name
}
}
HasError(bool) {
return {
return {
type
:
COUNTRIES
_HAS_ERROR
,
type:
{
{
NAME
}
}
_HAS_ERROR,
hasError: bool
hasError: bool
};
};
}
}
export
function
countries
IsLoading
(
bool
)
{
export function
{
{
name
}
}
IsLoading(bool) {
return {
return {
type
:
COUNTRIES
_IS_LOADING
,
type:
{
{
NAME
}
}
_IS_LOADING,
isLoading: bool
isLoading: bool
};
};
}
}
export
function
countries
Invalidated
(
bool
)
{
export function
{
{
name
}
}
Invalidated(bool) {
return {
return {
type
:
COUNTRIES
_INVALIDATED
,
type:
{
{
NAME
}
}
_INVALIDATED,
invalidated: bool
invalidated: bool
};
};
}
}
export
function
countries
FetchDataSuccess
(
countries
)
{
export function
{
{
name
}
}
FetchDataSuccess(
{
{
name
}
}
) {
countries
Invalidated
(
false
)
{
{
name
}
}
Invalidated(false)
return {
return {
type
:
COUNTRIES
_FETCH_DATA_SUCCESS
,
type:
{
{
NAME
}
}
_FETCH_DATA_SUCCESS,
countries
,
{
{
name
}
}
,
countries
FetchedAt
:
Date
.
now
()
{
{
name
}
}
FetchedAt: Date.now()
};
};
}
}
export
function
countries
FetchData
(
url
)
{
export function
{
{
name
}
}
FetchData(url) {
return (dispatch) => {
return (dispatch) => {
dispatch
(
countries
IsLoading
(
true
));
dispatch(
{
{
name
}
}
IsLoading(true));
fetch(url)
fetch(url)
.then((response) => {
.then((response) => {
...
@@ -48,15 +48,15 @@ export function countriesFetchData(url) {
...
@@ -48,15 +48,15 @@ export function countriesFetchData(url) {
throw Error(response.statusText);
throw Error(response.statusText);
}
}
dispatch
(
countries
IsLoading
(
false
));
dispatch(
{
{
name
}
}
IsLoading(false));
return response;
return response;
})
})
.then((response) => response.json())
.then((response) => response.json())
.
then
((
countries
)
=>
{
.then((
{
{
name
}
}
) => {
dispatch
(
countries
Invalidated
(
false
));
dispatch(
{
{
name
}
}
Invalidated(false));
dispatch
(
countries
FetchDataSuccess
(
countries
));
dispatch(
{
{
name
}
}
FetchDataSuccess(
{
{
name
}
}
));
})
})
.
catch
(()
=>
dispatch
(
countries
HasError
(
true
)));
.catch(() => dispatch(
{
{
name
}
}
HasError(true)));
};
};
}
}
\ No newline at end of file
frontend/
src/reducers/countries.js
→
frontend/
generate/templates/reducers.tpl
View file @
a3cf92a7
import {
import {
COUNTRIES
_HAS_ERROR
,
{
{
NAME
}
}
_HAS_ERROR,
COUNTRIES
_IS_LOADING
,
{
{
NAME
}
}
_IS_LOADING,
COUNTRIES
_FETCH_DATA_SUCCESS
,
{
{
NAME
}
}
_FETCH_DATA_SUCCESS,
COUNTRIES
_INVALIDATED
{
{
NAME
}
}
_INVALIDATED
}
from
"
.
./constants
/action-types
"
;
} from "./action-types";
export
function
countries
HasError
(
state
=
false
,
action
)
{
export function
{
{
name
}
}
HasError(state = false, action) {
switch (action.type) {
switch (action.type) {
case
COUNTRIES
_HAS_ERROR
:
case
{
{
NAME
}
}
_HAS_ERROR:
return action.hasError;
return action.hasError;
default:
default:
...
@@ -16,9 +16,9 @@ export function countriesHasError(state = false, action) {
...
@@ -16,9 +16,9 @@ export function countriesHasError(state = false, action) {
}
}
}
}
export
function
countries
IsLoading
(
state
=
false
,
action
)
{
export function
{
{
name
}
}
IsLoading(state = false, action) {
switch (action.type) {
switch (action.type) {
case
COUNTRIES
_IS_LOADING
:
case
{
{
NAME
}
}
_IS_LOADING:
return action.isLoading;
return action.isLoading;
default:
default:
...
@@ -26,9 +26,9 @@ export function countriesIsLoading(state = false, action) {
...
@@ -26,9 +26,9 @@ export function countriesIsLoading(state = false, action) {
}
}
}
}
export
function
countries
Invalidated
(
state
=
false
,
action
)
{
export function
{
{
name
}
}
Invalidated(state = false, action) {
switch (action.type) {
switch (action.type) {
case
COUNTRIES
_INVALIDATED
:
case
{
{
NAME
}
}
_INVALIDATED:
return action.invalidated;
return action.invalidated;
default:
default:
...
@@ -36,12 +36,12 @@ export function countriesInvalidated(state = false, action) {
...
@@ -36,12 +36,12 @@ export function countriesInvalidated(state = false, action) {
}
}
}
}
export
function
countries
Fetched
(
state
=
{
countries
:
[],
countries
FetchedAt
:
null
},
action
)
{
export function
{
{
name
}
}
Fetched(state = {
{
{
name
}
}: [], {
{
name
}
}
FetchedAt: null }, action) {
switch (action.type) {
switch (action.type) {
case
COUNTRIES
_FETCH_DATA_SUCCESS
:
case
{
{
NAME
}
}
_FETCH_DATA_SUCCESS:
return {
return {
countries
:
action
.
countries
,
{
{
name
}
}: action.{
{
name
}
}
,
fetchedAt
:
action
.
countries
FetchedAt
fetchedAt: action.
{
{
name
}
}
FetchedAt
}
}
default:
default:
...
...
frontend/src/.gitignore
0 → 100644
View file @
a3cf92a7
generated
\ No newline at end of file
frontend/src/actions/universities.js
deleted
100644 → 0
View file @
adc1d2fe
import
{
UNIVERSITIES_HAS_ERROR
,
UNIVERSITIES_IS_LOADING
,
UNIVERSITIES_FETCH_DATA_SUCCESS
,
UNIVERSITIES_INVALIDATED
}
from
"
../constants/action-types
"
;
export
function
universitiesHasError
(
bool
)
{
return
{
type
:
UNIVERSITIES_HAS_ERROR
,
hasError
:
bool
};
}
export
function
universitiesIsLoading
(
bool
)
{
return
{
type
:
UNIVERSITIES_IS_LOADING
,
isLoading
:
bool
};
}
export
function
universitiesInvalidated
(
bool
)
{
return
{
type
:
UNIVERSITIES_INVALIDATED
,
invalidated
:
bool
};
}
export
function
universitiesFetchDataSuccess
(
universities
)
{
universitiesInvalidated
(
false
)
return
{
type
:
UNIVERSITIES_FETCH_DATA_SUCCESS
,
universities
,
universitiesFetchedAt
:
Date
.
now
()
};
}
export
function
universitiesFetchData
(
url
)
{
return
(
dispatch
)
=>
{
dispatch
(
universitiesIsLoading
(
true
));
fetch
(
url
)
.
then
((
response
)
=>
{
if
(
!
response
.
ok
)
{
throw
Error
(
response
.
statusText
);
}
dispatch
(
universitiesIsLoading
(
false
));
return
response
;
})
.
then
((
response
)
=>
response
.
json
())
.
then
((
universities
)
=>
{
dispatch
(
universitiesInvalidated
(
false
));
dispatch
(
universitiesFetchDataSuccess
(
universities
));
})
.
catch
(()
=>
dispatch
(
universitiesHasError
(
true
)));
};
}
\ No newline at end of file
frontend/src/components/App.js
View file @
a3cf92a7
...
@@ -28,7 +28,7 @@ import {
...
@@ -28,7 +28,7 @@ import {
import
{
import
{
countriesFetchData
,
countriesFetchData
,
}
from
'
../
actions/countrie
s
'
;
}
from
'
../
generated/action
s
'
;
import
PageMap
from
'
./pages/PageMap
'
;
import
PageMap
from
'
./pages/PageMap
'
;
...
...
frontend/src/components/map/UnivMap.js
View file @
a3cf92a7
...
@@ -6,7 +6,7 @@ import { Map, TileLayer, Marker, Popup, LayersControl, FeatureGroup, Circle, Lay
...
@@ -6,7 +6,7 @@ import { Map, TileLayer, Marker, Popup, LayersControl, FeatureGroup, Circle, Lay
import
{
import
{
universitiesFetchData
,
universitiesFetchData
,
universitiesInvalidated
universitiesInvalidated
}
from
'
../../
actions/universitie
s
'
;
}
from
'
../../
generated/action
s
'
;
...
...
frontend/src/components/map/UnivMapReloadButton.js
View file @
a3cf92a7
...
@@ -6,7 +6,7 @@ import { withStyles } from '@material-ui/core/styles';
...
@@ -6,7 +6,7 @@ import { withStyles } from '@material-ui/core/styles';
import
{
import
{
universitiesInvalidated
universitiesInvalidated
}
from
'
../../
actions/universitie
s
'
;
}
from
'
../../
generated/action
s
'
;
const
styles
=
theme
=>
({
const
styles
=
theme
=>
({
...
...
frontend/src/constants/action-types.js
View file @
a3cf92a7
export
const
UNIVERSITIES_HAS_ERROR
=
'
UNIVERSITIES_HAS_ERROR
'
export
const
UNIVERSITIES_IS_LOADING
=
'
UNIVERSITIES_IS_LOADING
'
export
const
UNIVERSITIES_FETCH_DATA_SUCCESS
=
'
UNIVERSITIES_FETCH_DATA_SUCCESS
'
export
const
UNIVERSITIES_INVALIDATED
=
'
UNIVERSITIES_INVALIDATED
'
export
const
COUNTRIES_HAS_ERROR
=
'
COUNTRIES_HAS_ERROR
'
export
const
COUNTRIES_IS_LOADING
=
'
COUNTRIES_IS_LOADING
'
export
const
COUNTRIES_FETCH_DATA_SUCCESS
=
'
COUNTRIES_FETCH_DATA_SUCCESS
'
export
const
COUNTRIES_INVALIDATED
=
'
COUNTRIES_INVALIDATED
'
frontend/src/reducers/index.js
View file @
a3cf92a7
import
{
combineReducers
}
from
'
redux
'
;
import
{
combineReducers
}
from
'
redux
'
;
import
{
import
{
universitiesFetched
,
universitiesFetched
,
universitiesHasError
,
universitiesHasError
,
universitiesIsLoading
,
universitiesIsLoading
,
universitiesInvalidated
universitiesInvalidated
,
}
from
'
./universities
'
;
import
{
countriesFetched
,
countriesFetched
,
countriesHasError
,
countriesHasError
,
countriesIsLoading
,
countriesIsLoading
,
countriesInvalidated
countriesInvalidated
}
from
'
.
/countrie
s
'
;
}
from
'
.
./generated/reducer
s
'
;
const
rootReducer
=
combineReducers
({
const
rootReducer
=
combineReducers
({
...
...
frontend/src/reducers/universities.js
deleted
100644 → 0
View file @
adc1d2fe
import
{
UNIVERSITIES_HAS_ERROR
,
UNIVERSITIES_IS_LOADING
,
UNIVERSITIES_FETCH_DATA_SUCCESS
,
UNIVERSITIES_INVALIDATED
}
from
"
../constants/action-types
"
;
export
function
universitiesHasError
(
state
=
false
,
action
)
{
switch
(
action
.
type
)
{
case
UNIVERSITIES_HAS_ERROR
:
return
action
.
hasError
;
default
:
return
state
;
}
}
export
function
universitiesIsLoading
(
state
=
false
,
action
)
{
switch
(
action
.
type
)
{
case
UNIVERSITIES_IS_LOADING
:
return
action
.
isLoading
;
default
:
return
state
;
}
}
export
function
universitiesInvalidated
(
state
=
false
,
action
)
{
switch
(
action
.
type
)
{
case
UNIVERSITIES_INVALIDATED
:
return
action
.
invalidated
;
default
:
return
state
;
}
}
export
function
universitiesFetched
(
state
=
{
universities
:
[],
universitiesFetchedAt
:
null
},
action
)
{
switch
(
action
.
type
)
{
case
UNIVERSITIES_FETCH_DATA_SUCCESS
:
return
{
universities
:
action
.
universities
,
fetchedAt
:
action
.
universitiesFetchedAt
}
default
:
return
state
;
}
}
\ No newline at end of file
package-lock.json
View file @
a3cf92a7
...
@@ -339,6 +339,12 @@
...
@@ -339,6 +339,12 @@
"integrity"
:
"sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo="
,
"integrity"
:
"sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo="
,
"dev"
:
true
"dev"
:
true
},
},
"amdefine"
:
{
"version"
:
"1.0.1"
,
"resolved"
:
"https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz"
,
"integrity"
:
"sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU="
,
"dev"
:
true
},
"ansi-escapes"
:
{
"ansi-escapes"
:
{
"version"
:
"3.1.0"
,
"version"
:
"3.1.0"
,
"resolved"
:
"https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz"
,
"resolved"
:
"https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz"
,
...
@@ -479,6 +485,12 @@
...
@@ -479,6 +485,12 @@
"integrity"
:
"sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c="
,
"integrity"
:
"sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c="
,
"dev"
:
true
"dev"
:
true
},
},
"async"
:
{
"version"
:
"0.2.10"
,
"resolved"
:
"https://registry.npmjs.org/async/-/async-0.2.10.tgz"
,
"integrity"
:
"sha1-trvgsGdLnXGXCMo43owjfLUmw9E="
,
"dev"
:
true
},
"async-each"
:
{
"async-each"
:
{
"version"
:
"1.0.1"
,
"version"
:
"1.0.1"
,
"resolved"
:
"https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz"
,
"resolved"
:
"https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz"
,
...
@@ -4928,6 +4940,24 @@
...
@@ -4928,6 +4940,24 @@
"mimic-fn"
:
"^1.0.0"
"mimic-fn"
:
"^1.0.0"
}
}
},
},
"optimist"
:
{
"version"
:
"0.6.1"
,
"resolved"
:
"https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz"
,
"integrity"
:
"sha1-2j6nRob6IaGaERwybpDrFaAZZoY="
,
"dev"
:
true
,
"requires"
:
{
"minimist"
:
"~0.0.1"
,
"wordwrap"
:
"~0.0.2"
},
"dependencies"
:
{
"wordwrap"
:
{
"version"
:
"0.0.3"
,
"resolved"
:
"https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz"
,
"integrity"
:
"sha1-o9XabNXAvAAI03I0u68b7WMFkQc="
,
"dev"
:
true
}
}
},
"optionator"
:
{
"optionator"
:
{
"version"
:
"0.8.2"
,
"version"
:
"0.8.2"
,
"resolved"
:
"https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz"
,
"resolved"
:
"https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz"
,
...
@@ -6347,6 +6377,69 @@
...
@@ -6347,6 +6377,69 @@
"has-flag"
:
"^3.0.0"
"has-flag"
:
"^3.0.0"
}
}
},
},
"swig"
:
{
"version"
:
"1.4.2"
,
"resolved"
:
"https://registry.npmjs.org/swig/-/swig-1.4.2.tgz"
,
"integrity"
:
"sha1-QIXKBFM2kQS11IPihBs5t64aq6U="
,
"dev"
:
true
,
"requires"
:
{
"optimist"
:
"~0.6"
,
"uglify-js"
:
"~2.4"
},
"dependencies"
:
{
"camelcase"
:
{
"version"
:
"1.2.1"
,
"resolved"
:
"https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz"
,
"integrity"
:
"sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk="
,
"dev"
:
true
},
"decamelize"
:
{
"version"
:
"1.2.0"
,
"resolved"
:
"https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz"
,
"integrity"
:
"sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
,
"dev"
:
true
},
"source-map"
:
{
"version"
:
"0.1.34"
,
"resolved"
:
"https://registry.npmjs.org/source-map/-/source-map-0.1.34.tgz"
,
"integrity"
:
"sha1-p8/omux7FoLDsZjQrPtH19CQVms="
,
"dev"
:
true
,
"requires"
:
{
"amdefine"
:
">=0.0.4"
}
},
"uglify-js"
:
{
"version"
:
"2.4.24"
,
"resolved"
:
"https://registry.npmjs.org/uglify-js/-/uglify-js-2.4.24.tgz"
,
"integrity"
:
"sha1-+tV1XB4Vd2WLsG/5q25UjJW+vW4="
,
"dev"
:
true
,
"requires"
:
{
"async"
:
"~0.2.6"
,
"source-map"
:
"0.1.34"
,
"uglify-to-browserify"
:
"~1.0.0"
,
"yargs"
:
"~3.5.4"
}
},
"wordwrap"
:
{
"version"
:
"0.0.2"
,
"resolved"
:
"https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz"
,
"integrity"
:
"sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8="
,
"dev"
:
true
},
"yargs"
:
{
"version"
:
"3.5.4"
,
"resolved"
:
"https://registry.npmjs.org/yargs/-/yargs-3.5.4.tgz"
,
"integrity"
:
"sha1-2K/49mXpTDS9JZvevRv68N3TU2E="
,
"dev"
:
true
,
"requires"
:
{
"camelcase"
:
"^1.0.2"
,
"decamelize"
:
"^1.0.0"
,
"window-size"
:
"0.1.0"
,
"wordwrap"
:
"0.0.2"
}
}
}
},
"symbol-observable"
:
{
"symbol-observable"
:
{
"version"
:
"1.0.4"
,
"version"
:
"1.0.4"
,
"resolved"
:
"https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.4.tgz"
,
"resolved"
:
"https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.4.tgz"
,
...
@@ -6536,6 +6629,12 @@
...
@@ -6536,6 +6629,12 @@
}
}
}
}
},
},
"uglify-to-browserify"
:
{
"version"
:
"1.0.2"
,
"resolved"
:
"https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz"
,
"integrity"
:
"sha1-bgkk1r2mta/jSeOabWMoUKD4grc="
,
"dev"
:
true
},
"uglifyjs-webpack-plugin"
:
{
"uglifyjs-webpack-plugin"
:
{
"version"
:
"1.3.0"
,
"version"
:
"1.3.0"
,
"resolved"
:
"https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.3.0.tgz"
,
"resolved"
:
"https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.3.0.tgz"
,
...
@@ -6851,6 +6950,12 @@
...
@@ -6851,6 +6950,12 @@
"integrity"
:
"sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho="
,
"integrity"
:
"sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho="
,
"dev"
:
true
"dev"
:
true
},
},
"window-size"
:
{