Commit 8647ed5c authored by Florent Chehab's avatar Florent Chehab

Added js linting settings and fixed linting issues

Added editor config
parent 7c509208
# 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
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"
}
};
This diff is collapsed.
......@@ -4,6 +4,8 @@
"description": "[![build](/../badges/master/build.svg)](https://gitlab.utc.fr/chehabfl/outgoing_rex/pipelines) [![coverage](/../badges/master/coverage.svg)](https://chehabfl.gitlab.utc.fr/outgoing_rex/) [![License](https://img.shields.io/badge/License-BSD%202--Clause-green.svg)](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",
......
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";
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
};
}
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
};
}
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
};
}
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
};
}
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
};
}
......@@ -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
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) {
......
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
}
......@@ -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);
......
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
}
......@@ -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
// 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';
import Chip from '@material-ui/core/Chip';
import Avatar from '@material-ui/core/Avatar';
import ChevronLeftIcon from '@material-ui/icons/ChevronLeft';
import SchoolIcon from '@material-ui/icons/School';
import { mainListItems, secondaryListItems, thirdListItems } from './template/listItems';
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";
import Chip from "@material-ui/core/Chip";
import Avatar from "@material-ui/core/Avatar";
import ChevronLeftIcon from "@material-ui/icons/ChevronLeft";
import SchoolIcon from "@material-ui/icons/School";
import { mainListItems, secondaryListItems, thirdListItems } from "./template/listItems";
import { connect } from "react-redux";
import CustomComponentForAPI from './CustomComponentForAPI'
import CustomComponentForAPI from "./CustomComponentForAPI";
// import route Components here
import {
Route,
Redirect
} from 'react-router-dom';
} from "react-router-dom";
import getActions from "../api/getActions";
import PageMap from './pages/PageMap';
import PageHome from './pages/PageHome';
import PageUniversity from './pages/PageUniversity';
import PageSearch from './pages/PageSearch';
import PageSettings from './pages/PageSettings';
import PageMap from "./pages/PageMap";
import PageHome from "./pages/PageHome";
import PageUniversity from "./pages/PageUniversity";
import PageSearch from "./pages/PageSearch";
import PageSettings from "./pages/PageSettings";
const drawerWidth = 240;
const styles = theme => ({
root: {
display: 'flex',
display: "flex",
},
toolbar: {
paddingRight: 24, // keep right padding when drawer closed
},
toolbarIcon: {
display: 'flex',
alignItems: 'center',
justifyContent: 'flex-end',
padding: '0 8px',
display: "flex",
alignItems: "center",
justifyContent: "flex-end",
padding: "0 8px",
...theme.mixins.toolbar,
},
chip: {
......@@ -56,36 +56,36 @@ const styles = theme => ({
marginRight: 4,
},
hideIt: {
display: 'none',
display: "none",
},
title: {
flexGrow: 1,
},
drawerPaper: {
position: 'relative',
whiteSpace: 'nowrap',
position: "relative",
whiteSpace: "nowrap",
width: drawerWidth,
transition: theme.transitions.create('width', {
transition: theme.transitions.create("width", {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen,
}),
},
drawerPaperClose: {
overflowX: 'hidden',
transition: theme.transitions.create('width', {
overflowX: "hidden",
transition: theme.transitions.create("width", {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
width: theme.spacing.unit * 7,
[theme.breakpoints.up('sm')]: {
[theme.breakpoints.up("sm")]: {
width: theme.spacing.unit * 9,