Commit 4de8da0f authored by Andrew Hrdy's avatar Andrew Hrdy

Added tslint rules and fixed linting errors.

parent 76dd5bb9
Pipeline #3956 passed with stage
in 1 minute and 47 seconds
{
"parser": "babel-eslint",
"env": {
"browser": true,
"commonjs": true,
"es6": true,
"node": true
},
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"sourceType": "module"
},
"plugins": [
"react"
],
"extends": [
"eslint:recommended",
"plugin:react/recommended"
],
"rules": {
"no-unused-vars": "warn",
"no-console": "off",
"no-case-declarations": "off",
"no-template-curly-in-string": "warn",
"block-scoped-var": "error",
"no-empty-function": "error",
"no-implicit-globals": "error",
"no-multi-spaces": "error",
"no-self-compare": "warn",
"no-shadow": "warn",
"no-shadow-restricted-names": "error",
"no-undef-init": "error",
"array-bracket-spacing": "error",
"block-spacing": "error",
"brace-style": "error",
"camelcase": "error",
"comma-dangle": "warn",
"comma-spacing": "warn",
"computed-property-spacing": "error",
"func-call-spacing": "error",
"indent": [
"error",
4,
{
"SwitchCase": 1,
"ignoredNodes": [
"JSXAttribute",
"JSXSpreadAttribute"
]
}
],
"jsx-quotes": "error",
"key-spacing": "warn",
"keyword-spacing": "warn",
"no-multiple-empty-lines": "warn",
"no-tabs": "error",
"no-trailing-spaces": "error",
"no-whitespace-before-property": "error",
"object-curly-newline": [
"warn",
{
"ObjectExpression": {
"minProperties": 1
},
"ObjectPattern": "never"
}
],
"object-curly-spacing": "warn",
"object-property-newline": "warn",
"operator-assignment": "warn",
"operator-linebreak": ["warn", "after"],
"quote-props": [
"warn",
"as-needed"
],
"quotes": [
"warn",
"single"
],
"semi": "error",
"semi-spacing": [
"error",
{
"before": false,
"after": true
}
],
"space-before-blocks": "error",
"space-before-function-paren": [
"error",
"never"
],
"space-in-parens": "error",
"space-infix-ops": "error",
"space-unary-ops": [
"error",
{
"words": true,
"nonwords": false
}
],
"arrow-parens": "warn",
"arrow-spacing": [
"warn",
{
"before": true,
"after": true
}
],
"no-duplicate-imports": "warn",
"no-useless-computed-key": "warn",
"no-useless-rename": "warn",
"no-var": "error",
"prefer-arrow-callback": "warn",
"prefer-const": "error",
"prefer-rest-params": "error",
"prefer-spread": "error",
"prefer-template": "warn",
"rest-spread-spacing": "error",
"template-curly-spacing": "error",
"react/no-unescaped-entities": "off",
"react/prop-types": "off",
"react/no-find-dom-node": "off",
"react/boolean-prop-naming": "warn",
"react/no-danger": "error",
"react/no-typos": "warn",
"react/jsx-indent": "error",
"react/jsx-pascal-case": "error",
"react/jsx-wrap-multilines": "warn",
"react/no-deprecated": "off"
}
}
\ No newline at end of file
This diff is collapsed.
......@@ -6,7 +6,7 @@ import Chip from '@material-ui/core/Chip';
import Button from '@material-ui/core/Button';
import ArrowForwardIcon from '@material-ui/icons/ArrowForward';
var classNames = require('classnames');
const classNames = require('classnames');
class Alert extends React.Component<AlertProps> {
......@@ -26,19 +26,9 @@ class Alert extends React.Component<AlertProps> {
default:
return 'alert-info';
}
};
}
getBody = () => {
/*
API V2.2 removed the message field and replaced it with
subject and body. In order to ensure backwards compatability,
use the message field if it exists, otherwise use body.
TODO: Eventually, this check will be useless when older alerts
are phased out and should be removed to minimize complexity.
Alternatively, move this into the mapper once TypeScript is added.
*/
const alert: IAlert = this.props.alert;
const links = findLink(alert.body);
......@@ -58,7 +48,7 @@ class Alert extends React.Component<AlertProps> {
{alert.body.substring(links.index + links[0].length)}
</span>
);
};
}
getChipLabel = () => this.props.alert.urgency_tag.charAt(0).toUpperCase() + this.props.alert.urgency_tag.slice(1);
......@@ -86,7 +76,7 @@ class Alert extends React.Component<AlertProps> {
</span>
}
</div>
)
);
}
}
......
......@@ -8,7 +8,7 @@ import MenuIcon from '@material-ui/icons/Menu';
import SearchBar from '../containers/SearchBar';
import AlertContainer from '../containers/AlertContainer';
var classNames = require('classnames');
const classNames = require('classnames');
class CustomAppBar extends React.Component<{}, CustomAppBarState> {
......@@ -74,8 +74,8 @@ class CustomAppBar extends React.Component<{}, CustomAppBarState> {
}
export interface CustomAppBarState {
isAppBarExpanded: boolean,
isSearchExpanded: boolean
isAppBarExpanded: boolean;
isSearchExpanded: boolean;
}
export default CustomAppBar;
......@@ -38,7 +38,7 @@ class CardContainer extends React.Component<CardContainerProps, CardContainerSta
return facilityName.includes(lSearchTerm) || facilityLocation.includes(lSearchTerm) ||
facilityCategory.includes(lSearchTerm) || hasTag || friendlyName.includes(lSearchTerm);
};
}
handleFacilityClick = (slug: string) => {
const newValue = (slug !== this.state.selectedSlug) ? slug : null;
......@@ -52,12 +52,12 @@ class CardContainer extends React.Component<CardContainerProps, CardContainerSta
const {facilities} = this.props;
return (
<Grid container className={'card-container-root'} spacing={24} justify={'center'} alignItems={'flex-end'}>
<Grid container={true} className={'card-container-root'} spacing={24} justify={'center'} alignItems={'flex-end'}>
{facilities.filter(this.filterCards).map((item) => {
const isSelected = (item.slug === this.state.selectedSlug);
return (
<Grid key={item.slug} item>
<Grid key={item.slug} item={true}>
<FacilityCard facility={item} facilities={facilities} isSelected={isSelected} setSelected={this.handleFacilityClick}/>
</Grid>
);
......
import * as React from 'react';
import ReactMapboxGl, {Marker, Popup} from 'react-mapbox-gl';
import {getMaxBounds, getCenterOfCampusRegion} from '../utils/mapboxUtils';
import ReactMapboxGl, { Marker, Popup } from 'react-mapbox-gl';
import { getMaxBounds, getCenterOfCampusRegion } from '../utils/mapboxUtils';
import * as mapboxgl from 'mapbox-gl';
import {removeBrackets} from '../utils/nameUtils';
import { removeBrackets } from '../utils/nameUtils';
import { IFacility, CampusRegion, IFacilityLocation } from '../models/facility.model';
import MenuItem from '@material-ui/core/MenuItem';
......@@ -69,7 +69,7 @@ class FacilitiesMap extends React.Component<FacilitiesMapProps, FacilitiesMapSta
setTimeout(() => {
this.setState(newState);
}, 100);
};
}
generateLocationArray = (facilities: IFacility[]) => {
const locations: FacilityMapLocation[] = [];
......@@ -142,7 +142,7 @@ class FacilitiesMap extends React.Component<FacilitiesMapProps, FacilitiesMapSta
(
<FormControl className={'facilities-map-campus-select'}>
<Select
disableUnderline
disableUnderline={true}
value={this.state.campusRegion}
onChange={(e) => this.changeRegion((CampusRegion as any)[e.target.value])}>
<MenuItem value={CampusRegion.Fairfax}>Fairfax</MenuItem>
......
......@@ -12,11 +12,11 @@ class FacilityCategory extends React.Component<FacilityCategoryProps> {
render() {
return (
<div className={'facility-category-wrapper'}>
<Typography variant={'body1'} noWrap>
<Typography variant={'body1'} noWrap={true}>
{this.props.category.name}
</Typography>
</div>
)
);
}
}
......
import * as React from 'react';
import {removeBrackets} from '../utils/nameUtils';
import { removeBrackets } from '../utils/nameUtils';
import { IFacility } from '../models/facility.model';
import WeekHours from './WeekHours';
......@@ -28,7 +28,7 @@ class FacilityDialog extends React.Component<FacilityDialogProps, FacilityDialog
this.setState({
isMapOpen: !this.state.isMapOpen
});
};
}
render() {
const {facility, facilities, isOpen, onClose} = this.props;
......@@ -43,13 +43,13 @@ class FacilityDialog extends React.Component<FacilityDialogProps, FacilityDialog
<IconButton className={'fd-close-btn'} onClick={onClose}>
<CloseIcon />
</IconButton>
<Grid container className={'fd-container'} justify={'center'}>
<Grid item className={'fd-header-container'}>
<Grid container className={'fd-header'}>
<Grid item>
<Grid container={true} className={'fd-container'} justify={'center'}>
<Grid item={true} className={'fd-header-container'}>
<Grid container={true} className={'fd-header'}>
<Grid item={true}>
<Avatar className={'fd-avatar'} src={facility.logo} />
</Grid>
<Grid item className={'fd-header-text-container'}>
<Grid item={true} className={'fd-header-text-container'}>
<Typography className={'fd-header-text'} variant={'h5'}>
{removeBrackets(facility.facility_name)}
</Typography>
......@@ -57,7 +57,7 @@ class FacilityDialog extends React.Component<FacilityDialogProps, FacilityDialog
</Grid>
</Grid>
<Grid item className={'fd-location-wrapper'}>
<Grid item={true} className={'fd-location-wrapper'}>
<Typography variant={'caption'}>
<LocationOnIcon />
</Typography>
......@@ -66,11 +66,11 @@ class FacilityDialog extends React.Component<FacilityDialogProps, FacilityDialog
</Typography>
</Grid>
<Grid item className={'fd-week-hours'}>
<Grid item={true} className={'fd-week-hours'}>
<WeekHours facility={facility} />
</Grid>
<Grid item className={'fd-toggle-map-btn-container'}>
<Grid item={true} className={'fd-toggle-map-btn-container'}>
<Button className={'fd-toggle-map-btn'} onClick={this.toggleMap}>Open Map</Button>
</Grid>
</Grid>
......
......@@ -4,7 +4,7 @@ import { IFacility } from '../models/facility.model';
import Typography from '@material-ui/core/Typography';
var classNames = require('classnames');
const classNames = require('classnames');
class FacilityStatus extends React.Component<FacilityStatusProps> {
......@@ -13,10 +13,10 @@ class FacilityStatus extends React.Component<FacilityStatusProps> {
}
/**
* Generates information about the facility's status.
*
* @returns {{label: string, isOpen: boolean}} Information about the facility.
*/
* Generates information about the facility's status.
*
* @returns {{label: string, isOpen: boolean}} Information about the facility.
*/
generateStatusInfo = () => {
let label;
let isOpen;
......@@ -33,7 +33,7 @@ class FacilityStatus extends React.Component<FacilityStatusProps> {
label: label,
isOpen: isOpen
};
};
}
render() {
const statusInfo = this.generateStatusInfo();
......@@ -43,7 +43,7 @@ class FacilityStatus extends React.Component<FacilityStatusProps> {
className={classNames('facility-status-text', statusInfo.isOpen ? 'facility-status-open' : 'facility-status-closed')}>
{statusInfo.label}
</Typography>
)
);
}
}
......
......@@ -4,7 +4,7 @@ import FavoriteBorderIcon from '@material-ui/icons/FavoriteBorder';
import FavoriteIcon from '@material-ui/icons/Favorite';
import { trackPiwikEvent } from '../piwik/piwik';
var classNames = require('classnames');
const classNames = require('classnames');
class FavoriteButton extends React.Component<FavoriteButtonProps, FavoriteButtonState> {
......@@ -17,7 +17,7 @@ class FavoriteButton extends React.Component<FavoriteButtonProps, FavoriteButton
}
handleClick = (event: React.MouseEvent) => {
event.stopPropagation(); //Stops the card from being selected in the sidebar.
event.stopPropagation(); // Stops the card from being selected in the sidebar.
const newState = !this.state.isFavorite;
......@@ -38,7 +38,7 @@ class FavoriteButton extends React.Component<FavoriteButtonProps, FavoriteButton
this.props.addFavoriteFacility(this.props.slug);
}, 0);
}
};
}
render() {
......
import * as React from 'react';
import * as React from 'react';
import { IFacility } from '../models/facility.model';
import FacilitiesMap from './FacilitiesMap';
......@@ -10,7 +10,7 @@ import CloseIcon from '@material-ui/icons/Close';
class MapDialog extends React.Component<MapDialogProps> {
handleRequestClose = () => {
this.props.onClose();
};
}
render() {
const {facility, facilities, open, width, height, fullScreen = false} = this.props;
......
......@@ -16,7 +16,7 @@ import CloseIcon from '@material-ui/icons/Close';
import IconButton from '@material-ui/core/IconButton';
import { trackPiwikEvent } from '../piwik/piwik';
var classNames = require('classnames');
const classNames = require('classnames');
class Sidebar extends React.Component<SidebarProps, SidebarState> {
......@@ -31,7 +31,7 @@ class Sidebar extends React.Component<SidebarProps, SidebarState> {
handleSidebarClose = () => {
this.props.setSelectedFacility(null);
this.props.setSidebar(false);
};
}
handleMapDialogClose = () => {
trackPiwikEvent('map-action', 'close');
......@@ -39,7 +39,7 @@ class Sidebar extends React.Component<SidebarProps, SidebarState> {
this.setState({
mapDialogOpen: false
});
};
}
handleMapDialogOpen = () => {
trackPiwikEvent('map-action', 'open');
......@@ -56,7 +56,6 @@ class Sidebar extends React.Component<SidebarProps, SidebarState> {
return (
<div
className={classNames(['card-container-offset', (isSidebarOpen && 'card-container-offset-open'), (!isSidebarOpen && 'card-container-offset-closed')])}>
<meta></meta>
<Paper
className={classNames(['sidebar-root', (isSidebarOpen && 'sidebar-open'), (!isSidebarOpen && 'sidebar-closed')])}>
<IconButton className={'sidebar-close-btn'} onClick={this.handleSidebarClose}>
......
......@@ -16,7 +16,7 @@ class TextwTitle extends React.Component<TextwTitleProps> {
{this.props.content}
</div>
</div>
)
);
}
}
......
......@@ -28,11 +28,11 @@ export class WeekHours extends React.Component<WeekHoursProps> {
const todaysHours = facilityUtils.getHoursByDay(this.props.facility, dayOfWeek);
for (let i = 0; i < todaysHours.length; i++) {
output[index] = (
<Grid container spacing={0} key={this.props.facility.slug + index} className="week-hours-row">
<Grid item xs={2}>
<Grid container={true} spacing={0} key={this.props.facility.slug + index} className="week-hours-row">
<Grid item={true} xs={2}>
<Typography variant={'body1'}>{weekDays[dayOfWeek]}</Typography>
</Grid>
<Grid item>
<Grid item={true}>
<Typography variant={'body1'}>{todaysHours[i].text}</Typography>
</Grid>
</Grid>
......@@ -40,9 +40,7 @@ export class WeekHours extends React.Component<WeekHoursProps> {
index++;
}
}
} catch (e) {
//Empty
}
} catch (e) {}
return (
<div>
......
import * as React from 'react';
import {connect} from 'react-redux';
import { connect } from 'react-redux';
import { IAlert } from '../models/alert.model';
import Alert from '../components/Alert';
......@@ -31,14 +31,14 @@ class AlertContainer extends React.Component<AlertContainerProps, AlertContainer
});
this.props.addViewedAlerts(this.props.alerts.map(alert => alert.id));
};
}
handleClose = () => {
this.setState({
isOpen: false,
anchorEl: null
});
};
}
isAlertActive = (alert: IAlert) => {
const curDate = new Date();
......@@ -46,7 +46,7 @@ class AlertContainer extends React.Component<AlertContainerProps, AlertContainer
const endDate = new Date(alert.end_datetime);
return curDate > startDate && curDate < endDate;
};
}
hasAlertBeenViewed = (alert: IAlert) => {
return this.props.viewedAlerts.includes(alert.id);
......@@ -61,15 +61,14 @@ class AlertContainer extends React.Component<AlertContainerProps, AlertContainer
<IconButton classes={{
root: 'alert-container-btn'
}} onClick={this.handleOpen}>
{activeAlerts.filter((alert) => this.hasAlertBeenViewed(alert)).length !== 0 &&
{activeAlerts.filter((alert) => !this.hasAlertBeenViewed(alert)).length !== 0 &&
<span className={'alert-container-number'}>
<Typography variant={'caption'} className={'alert-container-number-text'}>
{activeAlerts.length}
</Typography>
</span>}
<NotificationsIcon>
</NotificationsIcon>
<NotificationsIcon />
</IconButton>
<Popover
open={this.state.isOpen}
......@@ -117,13 +116,13 @@ class AlertContainer extends React.Component<AlertContainerProps, AlertContainer
interface AlertContainerProps {
alerts: IAlert[];
viewedAlerts: number[]
viewedAlerts: number[];
addViewedAlerts: (alertIds: number[]) => any;
}
interface AlertContainerState {
isOpen: boolean;
anchorEl: HTMLElement
anchorEl: HTMLElement;
}
const mapStateToProps = (state: ApplicationState) => ({
......
import * as React from 'react';
import {connect} from 'react-redux';
import {removeBrackets} from '../utils/nameUtils';
import { connect } from 'react-redux';
import { removeBrackets } from '../utils/nameUtils';
import FacilityUtils from '../utils/facilityUtils';
import { IFacility } from '../models/facility.model';
......@@ -19,7 +19,7 @@ import { Dispatch } from 'redux';
import { addFavoriteFacility, removeFavoriteFacility, setSelectedFacility, setSidebarExpansion } from '../store/ui/ui.actions';
import { trackPiwikEvent } from '../piwik/piwik';
var classNames = require('classnames');
const classNames = require('classnames');
class FacilityCard extends React.Component<FacilityCardProps, FacilityCardState> {
......@@ -58,7 +58,7 @@ class FacilityCard extends React.Component<FacilityCardProps, FacilityCardState>
this.props.setSelectedFacility(newState ? this.props.facility : null);
this.props.setSidebarExpansion(newState);
}, 0);
};
}
render() {
......@@ -102,30 +102,30 @@ class FacilityCard extends React.Component<FacilityCardProps, FacilityCardState>
removeFavoriteFacility={removeFavoriteFacility} />
<CardContent className={'fc-card-content'}>
<Grid container alignItems={'center'} direction={'column'}>
<Grid item
<Grid container={true} alignItems={'center'} direction={'column'}>
<Grid item={true}
className={classNames('fc-small-grid-item-spacing', 'fc-ellipsis-container', 'fc-title-container')}>
<Typography variant={'subtitle1'} align={'center'}
className={classNames('fc-title', 'fc-one-line-ellipsis')}>
{removeBrackets(facility.facility_name)}
</Typography>
</Grid>
<Grid item className={'fc-small-grid-item-spacing'}>
<Grid item={true} className={'fc-small-grid-item-spacing'}>
<FacilityCategory category={facility.facility_category} />
</Grid>
<Grid item className={'fc-small-grid-item-spacing fc-display-hours'}>
<Grid item={true} className={'fc-small-grid-item-spacing fc-display-hours'}>
<Typography variant={'body1'}>
{`Today: ${getDisplayHours()}`}
</Typography>
</Grid>
</Grid>
<Grid container justify={'space-around'}>
<Grid item className={'fc-extra-info'}>
<Grid container={true} justify={'space-around'}>
<Grid item={true} className={'fc-extra-info'}>
<FacilityStatus facility={facility} />
</Grid>
<Grid item className={'fc-extra-info'}>
<Grid item={true} className={'fc-extra-info'}>
<Typography variant={'caption'}>
<LocationOnIcon className={'fc-card-map-marker-icon'} />
</Typography>
......@@ -171,6 +171,6 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({
addFavoriteFacility: (slug: string) => dispatch(addFavoriteFacility(slug)),
removeFavoriteFacility: (slug: string) => dispatch(removeFavoriteFacility(slug)),
setSidebarExpansion: (isOpen: boolean) => dispatch(setSidebarExpansion(isOpen))
})
});
export default connect(mapStateToProps, mapDispatchToProps)(FacilityCard);
\ No newline at end of file
import * as React from 'react';
import {connect} from 'react-redux';
import { connect } from 'react-redux';
import { IFacility, CampusRegion } from '../models/facility.model';
import { IAlert } from '../models/alert.model';
......@@ -20,7 +20,7 @@ class Layout extends React.Component<LayoutProps> {
componentWillMount = () => {
this.props.fetchFacilities();
this.props.fetchAlerts();
};
}
render() {
const {isSidebarOpen, selectedFacility, facilities, searchTerm, campusRegion, setSidebarExpansion, setSelectedFacility} = this.props;
......@@ -73,6 +73,6 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({
fetchAlerts: () => dispatch(fetchAlerts()),
setSidebarExpansion: (isOpen: boolean) => dispatch(setSidebarExpansion(isOpen)),
setSelectedFacility: (facility: IFacility) => dispatch(setSelectedFacility(facility))
})
});
export default connect(mapStateToProps, mapDispatchToProps)(Layout);
import * as React from 'react';
import {connect} from 'react-redux';
import { connect } from 'react-redux';
import { CampusRegion } from '../models/facility.model';
import SearchIcon from '@material-ui/icons/Search';
......@@ -15,7 +15,7 @@ import { Dispatch } from 'redux';
import { setSearchTerm, setSelectedCampusRegion } from '../store/ui/ui.actions';
import { trackPiwikEvent } from '../piwik/piwik';
var classNames = require('classnames');
const classNames = require('classnames');
class SearchBar extends React.Component<SearchBarProps, SearchBarState> {
private inputElement: any;
......@@ -37,7 +37,7 @@ class SearchBar extends React.Component<SearchBarProps, SearchBarState> {
});
this.props.setSearchTerm(e.target.value);
};
}
handleRegionChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
trackPiwikEvent('change-campus', e.target.value);
......@@ -49,7 +49,7 @@ class SearchBar extends React.Component<SearchBarProps, SearchBarState> {
});
this.props.setSelectedCampusRegion(campusRegion);
};
}
handleFocus = () => {
trackPiwikEvent('search-action', 'focused');
......@@ -57,13 +57,13 @@ class SearchBar extends React.Component<SearchBarProps, SearchBarState> {
this.setState({
isFocused: true
});
};
}
handleBlur = () => {