Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Julien Jerphanion
Rex Dri
Commits
3a3bbbd2
Commit
3a3bbbd2
authored
Feb 08, 2019
by
Florent Chehab
Browse files
Merge branch 'frontend_linting' into 'master'
Frontend linting Closes
#40
See merge request
!43
parents
7c509208
4acba3d0
Changes
113
Expand all
Hide whitespace changes
Inline
Side-by-side
.editorconfig
0 → 100644
View file @
3a3bbbd2
# editorconfig.org
root = true
[*]
indent_style = space
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.py]
indent_size = 4
[*.js]
indent_size = 2
[*.json]
indent_size = 2
\ No newline at end of file
.gitlab-ci.yml
View file @
3a3bbbd2
stages
:
-
test
-
syntaxe
-
linting
-
doc
-
deploy
...
...
@@ -27,7 +27,7 @@ testing:
-
docker
flake8
:
stage
:
syntaxe
stage
:
linting
image
:
python:3.6.5-jessie
script
:
-
pip install flake8
...
...
@@ -35,6 +35,14 @@ flake8:
tags
:
-
docker
eslint
:
stage
:
linting
image
:
pipelinecomponents/eslint:latest
script
:
-
cd frontend && npm run lint
tags
:
-
docker
pages
:
stage
:
doc
image
:
floawfloaw/plantuml
...
...
@@ -50,7 +58,7 @@ pages:
paths
:
-
public
expire_in
:
1 month
only
:
only
:
-
master
tags
:
-
docker
frontend/.eslintrc.js
0 → 100644
View file @
3a3bbbd2
module
.
exports
=
{
"
env
"
:
{
"
browser
"
:
true
,
"
es6
"
:
true
,
},
"
extends
"
:
[
"
eslint:recommended
"
,
"
plugin:react/recommended
"
],
"
parser
"
:
"
babel-eslint
"
,
"
parserOptions
"
:
{
"
ecmaVersion
"
:
2018
,
"
sourceType
"
:
"
module
"
,
"
ecmaFeatures
"
:
{
"
jsx
"
:
true
}
},
"
plugins
"
:
[
"
react
"
],
"
rules
"
:
{
"
indent
"
:
[
"
error
"
,
2
],
"
linebreak-style
"
:
[
"
error
"
,
"
unix
"
],
"
quotes
"
:
[
"
error
"
,
"
double
"
],
"
semi
"
:
[
"
error
"
,
"
always
"
],
"
react/no-unescaped-entities
"
:
"
warn
"
,
"
react/prop-types
"
:
"
warn
"
,
"
react/no-deprecated
"
:
"
warn
"
}
};
frontend/.eslintrc.yml
deleted
100644 → 0
View file @
7c509208
extends
:
google
frontend/package-lock.json
View file @
3a3bbbd2
This diff is collapsed.
Click to expand it.
frontend/package.json
View file @
3a3bbbd2
...
...
@@ -4,6 +4,8 @@
"description"
:
"[](https://gitlab.utc.fr/chehabfl/outgoing_rex/pipelines) [](https://chehabfl.gitlab.utc.fr/outgoing_rex/) [](https://opensource.org/licenses/BSD-2-Clause)"
,
"main"
:
"manage.py"
,
"scripts"
:
{
"lint"
:
"eslint
\"
./src/**/*.js
\"
"
,
"lint-fix"
:
"eslint
\"
./src/**/*.js
\"
--fix"
,
"dev"
:
"webpack --mode development"
,
"build"
:
"webpack --mode production"
,
"test"
:
"echo
\"
Error: no test specified
\"
&& exit 1"
,
...
...
@@ -45,6 +47,7 @@
"devDependencies"
:
{
"autoprefixer"
:
"^9.1.5"
,
"babel-core"
:
"^6.26.3"
,
"babel-eslint"
:
"^10.0.1"
,
"babel-loader"
:
"^7.1.5"
,
"babel-plugin-transform-class-properties"
:
"^6.24.1"
,
"babel-preset-env"
:
"^1.7.0"
,
...
...
@@ -52,8 +55,9 @@
"babel-preset-react"
:
"^6.24.1"
,
"babel-preset-stage-1"
:
"^6.24.1"
,
"css-loader"
:
"^1.0.0"
,
"eslint"
:
"^5.
4
.0"
,
"eslint"
:
"^5.
13
.0"
,
"eslint-config-google"
:
"^0.9.1"
,
"eslint-plugin-react"
:
"^7.12.4"
,
"file-loader"
:
"^2.0.0"
,
"js-yaml-loader"
:
"^1.0.1"
,
"mini-css-extract-plugin"
:
"^0.4.2"
,
...
...
frontend/src/actions/action-types.js
View file @
3a3bbbd2
export
const
SAVE_MAIN_MAP_POSITION
=
'
SAVE_MAIN_MAP_POSITION
'
;
export
const
SAVE_SELECTED_UNIVERSITIES
=
'
SAVE_SELECTED_UNIVERSITIES
'
;
export
const
SAVE_FILTER_CONFIG
=
'
SAVE_FILTER_CONFIG
'
;
export
const
SAVE_APP_THEME
=
'
SAVE_APP_THEME
'
;
export
const
SAVE_APP_COLOR_PICKER
=
'
SAVE_APP_COLOR_PICKER
'
;
export
const
SAVE_UNIVERSITY_BEING_VIEWED
=
'
SAVE_UNIVERSITY_BEING_VIEWED
'
;
export
const
SAVE_MAIN_MAP_POSITION
=
"
SAVE_MAIN_MAP_POSITION
"
;
export
const
SAVE_SELECTED_UNIVERSITIES
=
"
SAVE_SELECTED_UNIVERSITIES
"
;
export
const
SAVE_FILTER_CONFIG
=
"
SAVE_FILTER_CONFIG
"
;
export
const
SAVE_APP_THEME
=
"
SAVE_APP_THEME
"
;
export
const
SAVE_APP_COLOR_PICKER
=
"
SAVE_APP_COLOR_PICKER
"
;
export
const
SAVE_UNIVERSITY_BEING_VIEWED
=
"
SAVE_UNIVERSITY_BEING_VIEWED
"
;
frontend/src/actions/filter.js
View file @
3a3bbbd2
import
{
SAVE_SELECTED_UNIVERSITIES
,
SAVE_FILTER_CONFIG
SAVE_SELECTED_UNIVERSITIES
,
SAVE_FILTER_CONFIG
}
from
"
./action-types
"
;
export
function
saveSelectedUniversities
(
new_selection
)
{
return
{
type
:
SAVE_SELECTED_UNIVERSITIES
,
new_selection
};
return
{
type
:
SAVE_SELECTED_UNIVERSITIES
,
new_selection
};
}
export
function
saveFilterConfig
(
config
)
{
return
{
type
:
SAVE_FILTER_CONFIG
,
config
};
return
{
type
:
SAVE_FILTER_CONFIG
,
config
};
}
frontend/src/actions/map.js
View file @
3a3bbbd2
import
{
SAVE_MAIN_MAP_POSITION
SAVE_MAIN_MAP_POSITION
}
from
"
./action-types
"
;
export
function
saveMainMapPosition
(
new_position
)
{
return
{
type
:
SAVE_MAIN_MAP_POSITION
,
new_position
};
return
{
type
:
SAVE_MAIN_MAP_POSITION
,
new_position
};
}
frontend/src/actions/search.js
View file @
3a3bbbd2
import
{
SAVE_SELECTED_UNIVERSITIES
,
SAVE_FILTER_CONFIG
SAVE_SELECTED_UNIVERSITIES
,
SAVE_FILTER_CONFIG
}
from
"
./action-types
"
;
export
function
saveSelectedUniversities
(
new_selection
)
{
return
{
type
:
SAVE_SELECTED_UNIVERSITIES
,
new_selection
};
return
{
type
:
SAVE_SELECTED_UNIVERSITIES
,
new_selection
};
}
export
function
saveFilterConfig
(
config
)
{
return
{
type
:
SAVE_FILTER_CONFIG
,
config
};
return
{
type
:
SAVE_FILTER_CONFIG
,
config
};
}
frontend/src/actions/theme.js
View file @
3a3bbbd2
import
{
SAVE_APP_THEME
,
SAVE_APP_COLOR_PICKER
SAVE_APP_THEME
,
SAVE_APP_COLOR_PICKER
}
from
"
./action-types
"
;
export
function
saveAppTheme
(
theme
)
{
return
{
type
:
SAVE_APP_THEME
,
theme
};
return
{
type
:
SAVE_APP_THEME
,
theme
};
}
export
function
saveAppColorPicker
(
s
)
{
return
{
type
:
SAVE_APP_COLOR_PICKER
,
state
:
s
};
return
{
type
:
SAVE_APP_COLOR_PICKER
,
state
:
s
};
}
frontend/src/actions/universityPage.js
View file @
3a3bbbd2
import
{
SAVE_UNIVERSITY_BEING_VIEWED
SAVE_UNIVERSITY_BEING_VIEWED
}
from
"
./action-types
"
;
export
function
saveUniversityBeingViewed
(
univId
)
{
return
{
type
:
SAVE_UNIVERSITY_BEING_VIEWED
,
univId
};
return
{
type
:
SAVE_UNIVERSITY_BEING_VIEWED
,
univId
};
}
frontend/src/api/CrudActions.js
View file @
3a3bbbd2
...
...
@@ -9,7 +9,7 @@ function _isReading(status, type) {
return
{
type
,
status
}
}
;
}
function
_readFailed
(
failed
,
error
,
type
)
{
...
...
@@ -17,7 +17,7 @@ function _readFailed(failed, error, type) {
type
,
failed
,
error
}
}
;
}
function
_readSucceeded
(
data
,
type
)
{
...
...
@@ -82,7 +82,7 @@ export default class CrudActions {
readAllSucceeded
,
this
.
setInvalidatedAll
.
bind
(
this
),
readAllFailed
)
)
;
}
...
...
@@ -116,7 +116,7 @@ export default class CrudActions {
readSpecificSucceeded
,
this
.
setInvalidatedSpecific
.
bind
(
this
),
readSpecificFailed
)
)
;
}
...
...
@@ -182,7 +182,7 @@ export default class CrudActions {
isCreating
,
createSucceeded
,
createFailed
)
)
;
}
/**
...
...
@@ -218,7 +218,7 @@ export default class CrudActions {
}
self
.
_checkNotReadonly
();
if
(
!
'
id
'
in
data
)
{
if
(
!
(
"
id
"
in
data
)
)
{
throw
Error
(
"
When updating an object, an id is expected in the data
"
);
}
...
...
@@ -228,7 +228,7 @@ export default class CrudActions {
isUpdating
,
updateSucceeded
,
updateFailed
)
)
;
}
///////////
...
...
@@ -246,10 +246,10 @@ export default class CrudActions {
return
{
type
:
this
.
types
.
isInvalidatedAll
,
isInvalidated
:
bool
}
}
;
}
/**
/**
* Function to tell the store that this element has been invalidated relative to "specific"
*
* @param {boolean} bool
...
...
@@ -260,6 +260,6 @@ export default class CrudActions {
return
{
type
:
this
.
types
.
isInvalidatedSpecific
,
isInvalidated
:
bool
}
}
;
}
}
\ No newline at end of file
frontend/src/api/CrudReducers.js
View file @
3a3bbbd2
import
{
combineReducers
}
from
'
redux
'
;
import
{
combineReducers
}
from
"
redux
"
;
import
getCrudActionTypes
from
"
./getCrudActionTypes
"
;
import
SmartActions
from
"
./SmartActions
"
;
...
...
@@ -6,47 +6,47 @@ import SmartActions from "./SmartActions";
// generic function helpers
function
failed
(
state
,
action
,
type
)
{
switch
(
action
.
type
)
{
case
type
:
return
{
failed
:
action
.
failed
,
error
:
action
.
error
}
default
:
return
state
;
case
type
:
return
{
failed
:
action
.
failed
,
error
:
action
.
error
}
;
default
:
return
state
;
}
}
function
succeeded
(
state
,
action
,
type
)
{
switch
(
action
.
type
)
{
case
type
:
return
{
data
:
action
.
data
,
readAt
:
(
new
Date
()).
getTime
()
}
default
:
return
state
;
case
type
:
return
{
data
:
action
.
data
,
readAt
:
(
new
Date
()).
getTime
()
}
;
default
:
return
state
;
}
}
function
is
(
state
,
action
,
type
)
{
switch
(
action
.
type
)
{
case
type
:
return
action
.
status
;
case
type
:
return
action
.
status
;
default
:
return
state
;
default
:
return
state
;
}
}
function
invalidate
(
state
,
action
,
type
)
{
switch
(
action
.
type
)
{
case
type
:
return
action
.
isInvalidated
;
case
type
:
return
action
.
isInvalidated
;
default
:
return
state
;
default
:
return
state
;
}
}
...
...
@@ -150,7 +150,7 @@ export default class CrudReducers {
readSucceeded
:
readSpecificSucceeded
,
readFailed
:
readSpecificFailed
,
isInvalidated
:
isInvalidatedSpecific
,
}
}
;
// Add only appropriate reducers
if
(
this
.
readOnly
!==
true
)
{
...
...
frontend/src/api/SmartActions.js
View file @
3a3bbbd2
import
Cookies
from
'
js-cookie
'
;
import
Cookies
from
"
js-cookie
"
;
// TODO uodate parameters name to match new CRUD actions
...
...
@@ -19,7 +19,7 @@ export default class SmartActions {
}
/**
* Generic function for handling a GET request to the API
* Generic function for handling a GET request to the API
*
* @param {string} pk
* @param {string} api_end_point
...
...
@@ -32,11 +32,11 @@ export default class SmartActions {
* @memberof SmartActions
*/
_FetchData
(
pk
,
api_end_point
,
_IsLoading
,
_FetchDataSuccess
,
_Invalidated
,
_HasError
,
pk_required
=
false
)
{
if
(
pk_required
&&
(
typeof
pk
==
'
undefined
'
))
{
if
(
pk_required
&&
(
typeof
pk
==
"
undefined
"
))
{
throw
"
pk shouldn't be empty when requesting a specific element
"
;
}
if
(
pk
!=
""
)
{
api_end_point
+=
pk
+
'
/
'
;
api_end_point
+=
pk
+
"
/
"
;
}
if
(
!
this
.
shouldFetchEndPoint
(
api_end_point
))
{
...
...
@@ -47,8 +47,8 @@ export default class SmartActions {
return
(
dispatch
)
=>
{
dispatch
(
_IsLoading
(
true
));
let
token
=
Cookies
.
get
(
'
csrftoken
'
);
fetch
(
api_end_point
,
{
credentials
:
'
same-origin
'
,
headers
:
{
'
X-CSRFToken
'
:
token
}
})
let
token
=
Cookies
.
get
(
"
csrftoken
"
);
fetch
(
api_end_point
,
{
credentials
:
"
same-origin
"
,
headers
:
{
"
X-CSRFToken
"
:
token
}
})
.
then
((
response
)
=>
{
if
(
!
response
.
ok
)
{
this
.
fetching
.
delete
(
api_end_point
);
...
...
@@ -74,7 +74,7 @@ export default class SmartActions {
/**
* Generic function for handling a PUT and POST requests to the API
* Generic function for handling a PUT and POST requests to the API
*
* @param {object} data, to update the data, `data` should contains the `id` field.
* @param {string} api_end_point
...
...
@@ -88,26 +88,26 @@ export default class SmartActions {
return
(
dispatch
)
=>
{
let
method
=
"
POST
"
;
let
pk
=
""
;
if
(
'
id
'
in
data
)
{
if
(
"
id
"
in
data
)
{
method
=
"
PUT
"
;
pk
=
data
.
id
+
'
/
'
;
pk
=
data
.
id
+
"
/
"
;
}
let
__apiAttr
=
''
;
if
(
'
__apiAttr
'
in
data
&&
data
.
__apiAttr
!=
''
)
{
__apiAttr
=
data
.
__apiAttr
+
'
/
'
;
let
__apiAttr
=
""
;
if
(
"
__apiAttr
"
in
data
&&
data
.
__apiAttr
!=
""
)
{
__apiAttr
=
data
.
__apiAttr
+
"
/
"
;
}
let
errorStatusText
=
''
;
let
errorStatusText
=
""
;
dispatch
(
_ElIsSaving
(
true
));
let
token
=
Cookies
.
get
(
'
csrftoken
'
);
let
token
=
Cookies
.
get
(
"
csrftoken
"
);
fetch
(
api_end_point
+
__apiAttr
+
pk
,
{
method
:
method
,
credentials
:
'
same-origin
'
,
credentials
:
"
same-origin
"
,
headers
:
{
'
Accept
'
:
'
application/json
'
,
'
Content-Type
'
:
'
application/json
'
,
'
X-CSRFToken
'
:
token
"
Accept
"
:
"
application/json
"
,
"
Content-Type
"
:
"
application/json
"
,
"
X-CSRFToken
"
:
token
},
body
:
JSON
.
stringify
(
data
)
})
...
...
@@ -123,18 +123,19 @@ export default class SmartActions {
dispatch
(
_ElIsSaving
(
false
));
})
.
catch
((
e
)
=>
{
if
(
typeof
e
.
json
==
'
function
'
)
{
return
e
.
json
()
if
(
typeof
e
.
json
==
"
function
"
)
{
return
e
.
json
()
;
}
else
{
return
new
Promise
(
function
(
resolve
,
reject
)
{
resolve
(
e
)
});
// eslint-disable-next-line no-unused-vars
return
new
Promise
(
function
(
resolve
,
reject
)
{
resolve
(
e
);
});
}
})
.
then
((
errorContent
)
=>
{
if
(
typeof
errorContent
!=
'
undefined
'
)
{
if
(
typeof
errorContent
!=
"
undefined
"
)
{
dispatch
(
_ElHasError
(
true
,
{
message
:
errorStatusText
,
content
:
errorContent
}));
dispatch
(
_ElIsSaving
(
false
));
}
})
})
;
};
}
}
\ No newline at end of file
}
frontend/src/api/buildApiActionsAndReducers.js
View file @
3a3bbbd2
...
...
@@ -14,7 +14,7 @@ const otherAPI = [
name
:
"
serverModerationStatus
"
,
api_end_point
:
"
serverModerationStatus
"
}
]
]
;
/**
* Create api actions and reducers for given the info in each arr obj
...
...
@@ -43,7 +43,7 @@ function addAPIs(arr) {
const
reducers
=
new
CrudReducers
(
apiInfo
);
apiReducersTmp
[
`
${
apiInfo
.
name
}
All`
]
=
reducers
.
getCombinedAll
();
apiReducersTmp
[
`
${
apiInfo
.
name
}
Specific`
]
=
reducers
.
getCombinedSpecific
();
})
})
;
}
addAPIs
(
otherAPI
);
...
...
frontend/src/api/getActions.js
View file @
3a3bbbd2
import
{
apiActions
}
from
"
./buildApiActionsAndReducers
"
;
import
CrudActions
from
"
./CrudActions
"
;
/**
* Function to get the the actions corresponding to an API end point.
* Function to get the the actions corresponding to an API end point.
*
* @export
* @param {string} name
...
...
@@ -10,8 +9,8 @@ import CrudActions from "./CrudActions";
*/
export
default
function
getActions
(
name
)
{
if
(
!
(
name
in
apiActions
))
{
console
.
error
(
"
available actions
"
,
apiActions
);
console
.
error
(
"
available actions
"
,
apiActions
);
// eslint-disable-line no-console
throw
Error
(
`Requested api action is not defined, check the name:
${
name
}
`
);
}
return
apiActions
[
name
];
}
\ No newline at end of file
}
frontend/src/api/getCrudActionTypes.js
View file @
3a3bbbd2
...
...
@@ -30,5 +30,5 @@ export default function getCrudActionTypes(name) {
// Not directly a CRUD action but needed for in app behavior
isInvalidatedAll
:
`API_
${
name
}
_ALL_INVALIDATED`
,
isInvalidatedSpecific
:
`API_
${
name
}
_SPECIFIC_INVALIDATED`
,
}
}
;
}
\ No newline at end of file
frontend/src/components/App.js
View file @
3a3bbbd2
// Inspired by https://github.com/mui-org/material-ui/tree/master/docs/src/pages/page-layout-examples/dashboard
import
React
from
'
react
'
;
import
PropTypes
from
'
prop-types
'
;
import
classNames
from
'
classnames
'
;
import
withStyles
from
'
@material-ui/core/styles/withStyles
'
;
import
CssBaseline
from
'
@material-ui/core/CssBaseline
'
;
import
Drawer
from
'
@material-ui/core/Drawer
'
;
import
List
from
'
@material-ui/core/List
'
;
import
Divider
from
'
@material-ui/core/Divider
'
;
import
IconButton
from
'
@material-ui/core/IconButton
'
;
import
MenuIcon
from
'
@material-ui/icons/Menu
'
;