Lint code

This commit is contained in:
dbroqua 2019-04-13 13:59:58 +02:00
parent cbf28c16f2
commit 1a68a67bf8
13 changed files with 795 additions and 243 deletions

View file

@ -1,6 +1,24 @@
module.exports = {
"extends": "airbnb",
"env": {
"browser": true
env: {
browser: true,
es6: true,
},
extends: 'airbnb',
globals: {
Atomics: 'readonly',
SharedArrayBuffer: 'readonly',
},
parserOptions: {
ecmaFeatures: {
jsx: true,
},
ecmaVersion: 2018,
sourceType: 'module',
},
plugins: [
'react',
],
rules: {
'react/jsx-filename-extension': [1, { extensions: ['.js', '.jsx'] }],
},
};

View file

@ -5,7 +5,8 @@
"dependencies": {
"axios": "^0.18.0",
"bootstrap": "^4.1.3",
"history": "^4.7.2",
"history": "^4.9.0",
"prop-types": "^15.7.2",
"react": "^16.6.1",
"react-dom": "^16.6.1",
"react-icons": "^3.2.2",
@ -28,5 +29,12 @@
"not dead",
"not ie <= 11",
"not op_mini all"
]
],
"devDependencies": {
"eslint": "^5.16.0",
"eslint-config-airbnb": "^17.1.0",
"eslint-plugin-import": "^2.16.0",
"eslint-plugin-jsx-a11y": "^6.2.1",
"eslint-plugin-react": "^7.12.4"
}
}

View file

@ -1,9 +1,9 @@
import React, { Component, Fragment } from 'react';
import Header from './Header';
import {
BrowserRouter as Router, Route,
Switch,
} from 'react-router-dom';
import Header from './Header';
import Map from '../Routes/Map';
import Search from '../Routes/Search';
import Home from '../Routes/Home';
@ -11,17 +11,7 @@ import Vegetables from '../Routes/Vegetables';
import Vegetable from '../Routes/Vegetable';
class App extends Component {
constructor(props) {
super(props)
this.state = {
background: 1
}
this.changeBackground = this.changeBackground.bind(this);
}
changeBackground(background) {
static changeBackground(background) {
document.body.style.background = `url('/background/${background}.jpg') no-repeat fixed`;
document.body.style.backgroundSize = 'cover';
document.body.style.backgroundPosition = 'center center';
@ -30,33 +20,33 @@ class App extends Component {
render() {
return (
<Fragment>
<Header></Header>
<Header />
<Router>
<Switch>
<Route
exact
path="/"
render={(props) => <Home {...props} changeBackground={this.changeBackground} />}
render={props => <Home {...props} changeBackground={App.changeBackground} />}
/>
<Route
exact
path="/carte"
render={(props) => <Map {...props} changeBackground={this.changeBackground} />}
render={props => <Map {...props} changeBackground={App.changeBackground} />}
/>
<Route
exact
path="/recherche/:query"
render={(props) => <Search {...props} changeBackground={this.changeBackground} />}
render={props => <Search {...props} changeBackground={App.changeBackground} />}
/>
<Route
exact
path="/vegetaux/:typeId-:typeSlug"
render={(props) => <Vegetables {...props} changeBackground={this.changeBackground} />}
render={props => <Vegetables {...props} changeBackground={App.changeBackground} />}
/>
<Route
exact
path="/vegetaux/:typeId-:typeSlug/:vegetableId-:vegetableSlug"
render={(props) => <Vegetable {...props} changeBackground={this.changeBackground} />}
render={props => <Vegetable {...props} changeBackground={App.changeBackground} />}
/>
</Switch>
</Router>

View file

@ -24,9 +24,9 @@ import {
NotificationContainer,
NotificationManager,
} from 'react-notifications';
import { createBrowserHistory } from 'history';
import Api from './Api';
import strToSlug from '../StrToSlug';
import { createBrowserHistory } from 'history';
import '../css/Header.css';
@ -50,12 +50,6 @@ export default class Header extends React.Component {
this.getVegetablesTypes();
}
toggle() {
this.setState({
isOpen: !this.state.isOpen,
});
}
getVegetablesTypes() {
Api.get('types')
.then((res) => {
@ -68,20 +62,33 @@ export default class Header extends React.Component {
});
}
toggle() {
const {
isOpen,
} = this.state;
this.setState({
isOpen: !isOpen,
});
}
handleChange(event) {
this.setState({ search: event.target.value });
}
handleSubmit(event) {
handleSubmit() {
const {
search
search,
} = this.state;
history.push(`/recherche/${search}`);
}
render() {
const {
search,
isOpen,
types,
} = this.state;
return (
@ -90,7 +97,7 @@ export default class Header extends React.Component {
<Navbar color="light" light fixed="top" expand="md">
<NavbarBrand href="/"><img src="/logo.png" alt="RodiVert" /></NavbarBrand>
<NavbarToggler onClick={this.toggle} />
<Collapse isOpen={this.state.isOpen} navbar>
<Collapse isOpen={isOpen} navbar>
<Nav className="ml-auto" navbar>
<NavItem>
<NavLink href="/carte">Carte</NavLink>
@ -101,9 +108,8 @@ export default class Header extends React.Component {
</DropdownToggle>
<DropdownMenu right>
{
this.state.types.map((type, key) => (
<DropdownItem as="div" key={key}>
types.map(type => (
<DropdownItem as="div" key={type.id}>
<NavLink href={`/vegetaux/${type.id}-${strToSlug(type.name)}`}>
<span className="text">{type.name}</span>
{' '}

View file

@ -1,4 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';
import {
Row,
Col,
@ -19,14 +20,19 @@ const MapDimensions = {
height: 530,
};
export default class Map extends React.Component {
class Map extends React.Component {
constructor(props) {
super(props);
const {
selectedType,
selectedVegetable,
} = this.props;
this.state = {
selectedType: this.props.selectedType,
selectedVegetable: this.props.selectedVegetable,
Map: {
selectedType,
selectedVegetable,
map: {
width: '20px',
height: '20px',
},
@ -38,32 +44,37 @@ export default class Map extends React.Component {
this.toggle = this.toggle.bind(this);
}
componentDidMount() {
window.addEventListener('resize', this.setMap);
this.setMap();
}
componentWillReceiveProps(newProps) {
const {
selectedType,
selectedVegetable,
} = this.state;
if (newProps.selectedType !== selectedType || newProps.selectedVegetable !== selectedVegetable) {
if (newProps.selectedType !== selectedType
|| newProps.selectedVegetable !== selectedVegetable
) {
this.setState(prevState => ({
...prevState,
selectedType: newProps.selectedType,
selectedVegetable: newProps.selectedVegetable,
}), this.setMap);
}
}
componentDidMount() {
window.addEventListener('resize', this.setMap);
this.setMap();
}
componentWillUnmount() {
window.removeEventListener('resize', this.setMap);
}
setMap() {
const {
setHeight,
} = this.props;
const width = document.getElementById('MapContainer').clientWidth;
let MapWidth = MapDimensions.width;
let MapHeight = MapDimensions.height;
@ -71,12 +82,12 @@ export default class Map extends React.Component {
MapWidth = width;
MapHeight = Math.round(MapDimensions.height * MapWidth / MapDimensions.width);
if (this.props.setHeight) {
this.props.setHeight(MapHeight)
if (setHeight) {
setHeight(MapHeight);
}
this.setState({
Map: {
map: {
width: MapWidth,
height: MapHeight,
},
@ -87,7 +98,11 @@ export default class Map extends React.Component {
this.setState({
selectedVegetable: vegetable,
});
this.props.selectVegetable(vegetable);
const {
selectVegetable,
} = this.props;
selectVegetable(vegetable);
}
toggle(id) {
@ -97,11 +112,15 @@ export default class Map extends React.Component {
}
createLink(vegetable) {
const {
selectedType,
} = this.state;
let url = '/vegetaux/';
if (vegetable.Type) {
url += `${vegetable.Type.id}-${strToSlug(vegetable.Type.name)}`;
} else {
url += `${this.state.selectedType.id}-${strToSlug(this.state.selectedType.name)}`;
url += `${selectedType.id}-${strToSlug(selectedType.name)}`;
}
url += `/${vegetable.id}-${strToSlug(vegetable.name)}`;
@ -109,23 +128,31 @@ export default class Map extends React.Component {
}
render() {
const {
map,
selectedType,
selectedVegetable,
tooltipOpen,
} = this.state;
return (
<Row className="with-margin">
<Col className="with-border with-background">
<div id="MapContainer">
<div className="map" style={{ width: this.state.Map.width, height: this.state.Map.height }}>
<div className="map" style={{ width: map.width, height: map.height }}>
{
this.state.selectedType
&& this.state.selectedType.Vegetables
&& this.state.selectedType.Vegetables.map((vegetable, key) => (
selectedType
&& selectedType.Vegetables
&& selectedType.Vegetables.map(vegetable => (
<Link
to={this.createLink(vegetable)}
key={key}
className={`mapMarker ${this.state.selectedVegetable && this.state.selectedVegetable.id === vegetable.id ? 'selected' : ''}`}
key={vegetable.id}
className={`mapMarker ${selectedVegetable && selectedVegetable.id === vegetable.id ? 'selected' : ''}`}
style={{ left: `calc(${vegetable.lat}% - 16px)`, top: `calc(${vegetable.lng}% - 16px)` }}
onMouseOver={e => this.selectVegetable(vegetable)}
onMouseOver={() => this.selectVegetable(vegetable)}
onFocus={() => { }}
>
<Tooltip placement="top" isOpen={this.state.tooltipOpen === vegetable.id} target={`Tooltip-${vegetable.id}`} toggle={() => this.toggle(vegetable.id)}>
<Tooltip placement="top" isOpen={tooltipOpen === vegetable.id} target={`Tooltip-${vegetable.id}`} toggle={() => this.toggle(vegetable.id)}>
{vegetable.name}
</Tooltip>
<FaMapMarkerAlt id={`Tooltip-${vegetable.id}`} />
@ -139,3 +166,12 @@ export default class Map extends React.Component {
);
}
}
Map.propTypes = {
selectedType: PropTypes.shape().isRequired,
selectedVegetable: PropTypes.shape().isRequired,
setHeight: PropTypes.func.isRequired,
selectVegetable: PropTypes.func.isRequired,
};
export default Map;

View file

@ -3,6 +3,7 @@ import {
ListGroup,
ListGroupItem,
} from 'reactstrap';
import PropTypes from 'prop-types';
import {
Link,
} from 'react-router-dom';
@ -10,14 +11,21 @@ import strToSlug from '../StrToSlug';
import '../css/Vegetables.css';
export default class Map extends React.Component {
class Vegetables extends React.Component {
constructor(props) {
super(props);
const {
selectedType,
selectVegetable,
} = this.props;
this.state = {
selectedType: this.props.selectedType,
selectedVegetable: this.props.selectVegetable,
selectedType,
selectedVegetable: selectVegetable,
};
this.goTo = this.goTo.bind(this);
}
componentWillReceiveProps(newProps) {
@ -25,35 +33,64 @@ export default class Map extends React.Component {
}
createLink(vegetable) {
const {
selectedType,
} = this.state;
let url = '/vegetaux/';
if (vegetable.Type) {
url += `${vegetable.Type.id}-${strToSlug(vegetable.Type.name)}`;
} else {
url += `${this.state.selectedType.id}-${strToSlug(this.state.selectedType.name)}`;
url += `${selectedType.id}-${strToSlug(selectedType.name)}`;
}
url += `/${vegetable.id}-${strToSlug(vegetable.name)}`;
return url;
}
goTo(vegetable) {
const {
history,
} = this.props;
const url = this.createLink(vegetable);
history.push(url);
}
render() {
const {
double,
simple,
selectVegetable,
} = this.props;
const {
selectedType,
selectedVegetable,
} = this.state;
let addClass = 'triple';
if (simple) {
addClass = '';
} else if (double) {
addClass = 'double';
}
return (
<div className="with-margin">
<div className=" with-border with-background">
<ListGroup className={`vegetables--types--group ${simple ? '' : double ? 'double' : 'triple'}`}>
<ListGroup className={`vegetables--types--group ${addClass}`}>
{
this.state.selectedType
&& this.state.selectedType.Vegetables
&& this.state.selectedType.Vegetables.map((vegetable, key) => (
selectedType
&& selectedType.Vegetables
&& selectedType.Vegetables.map(vegetable => (
<ListGroupItem
key={key}
className={this.state.selectedVegetable.id === vegetable.id ? 'selected' : 'null'}
onMouseOver={e => this.props.selectVegetable(vegetable)}
key={vegetable.id}
className={selectedVegetable.id === vegetable.id ? 'selected' : 'null'}
onMouseOver={() => selectVegetable(vegetable)}
onClick={() => this.goTo(vegetable)}
onFocus={() => { }}
>
<Link to={this.createLink(vegetable)}>
{vegetable.name}
@ -68,3 +105,18 @@ export default class Map extends React.Component {
);
}
}
Vegetables.defaultProps = {
double: false,
simple: false,
};
Vegetables.propTypes = {
double: PropTypes.bool,
simple: PropTypes.bool,
selectedType: PropTypes.shape().isRequired,
selectVegetable: PropTypes.shape().isRequired,
history: PropTypes.shape().isRequired,
};
export default Vegetables;

View file

@ -1,4 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';
import {
Container,
Row,
@ -7,37 +8,56 @@ import {
import '../css/Home.css';
export default class RouterHome extends React.Component {
render() {
this.props.changeBackground('home')
function RouterHome(props) {
const {
changeBackground,
} = props;
return (
<Container>
<Row className="with-margin">
{/* <Row className="mainContainer"> */}
<Col xs="12" className=" with-border with-background">
<img src="/logo.png" className="logo float-left" alt="RodiVert" />
<p>
En tant quétudiant, nous savons ce que cest que de chercher chaque caractéristique dun végétal et de créer une fiche de technique. Cela demande un temps énorme, en plus du travail que lon doit fournir pour réussir notre BTS. Cest pour cela que nous avons pensé à créer un site rassemblant toutes les informations sur le végétal que nous avons besoin au cours de notre scolarité.
</p>
<p>
RodiVert regroupe toutes les caractéristiques dune plante, sa nomenclature et une photo de celle-ci pour pouvoir le reconnaitre. Cest maintenant facile et un plaisir dapprendre !
</p>
<p>
Etant donné que nous finissons nos études cette année, le site sera utile pour la génération future. Notre but est de faire découvrir aux futurs étudiants une nouvelle méthode dapprentissage, qui évolue avec laire du temps, une méthode plus moderne. Mais aussi de créer un lieu entre les formateurs et les élèves.
</p>
<p>
Il permet aussi dapporter une plus-value au CFA du Gard. Le lien sera inscrit sur le site officiel de létablissement.
</p>
<p>
Nous laissons lévolution du site entre les mains de formateur compétent en reconnaissance de végétaux et technique.
</p>
<Col lg={{ size: 8, offset: 2 }} xs="12" className="margin-botton">
<img src="/img/Home_01.jpg" className="img-fluid" alt="Sharlotte, Julie, Clément, Alois" />
</Col>
changeBackground('home');
return (
<Container>
<Row className="with-margin">
{/* <Row className="mainContainer"> */}
<Col xs="12" className=" with-border with-background">
<img src="/logo.png" className="logo float-left" alt="RodiVert" />
<p>
En tant quétudiant, nous savons ce que cest que de chercher chaque caractéristique
dun végétal et de créer une fiche de technique. Cela demande un temps énorme, en plus
du travail que lon doit fournir pour réussir notre BTS. Cest pour cela que nous avons
pensé à créer un site rassemblant toutes les informations sur le végétal que nous avons
besoin au cours de notre scolarité.
</p>
<p>
RodiVert regroupe toutes les caractéristiques dune plante, sa nomenclature et une
photo de celle-ci pour pouvoir le reconnaitre. Cest maintenant facile et un plaisir
dapprendre !
</p>
<p>
Etant donné que nous finissons nos études cette année, le site sera utile pour la
génération future. Notre but est de faire découvrir aux futurs étudiants une nouvelle
méthode dapprentissage, qui évolue avec laire du temps, une méthode plus moderne.
Mais aussi de créer un lieu entre les formateurs et les élèves.
</p>
<p>
Il permet aussi dapporter une plus-value au CFA du Gard. Le lien sera inscrit sur le
site officiel de létablissement.
</p>
<p>
Nous laissons lévolution du site entre les mains de formateur compétent en
reconnaissance de végétaux et technique.
</p>
<Col lg={{ size: 8, offset: 2 }} xs="12" className="margin-botton">
<img src="/img/Home_01.jpg" className="img-fluid" alt="Sharlotte, Julie, Clément, Alois" />
</Col>
</Row>
</Container>
);
}
</Col>
</Row>
</Container>
);
}
RouterHome.propTypes = {
changeBackground: PropTypes.func.isRequired,
};
export default RouterHome;

View file

@ -1,4 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';
import {
Container,
Row,
@ -15,13 +16,16 @@ import Api from '../Components/Api';
import MapItem from '../Components/Map';
import Vegetables from '../Components/Vegetables';
export default class RouterMap extends React.Component {
class RouterMap extends React.Component {
constructor(props) {
super(props);
const {
changeBackground,
} = this.props;
this.state = {
types: [],
vegetables: [],
selectedType: {},
selectedVegetable: {},
};
@ -31,7 +35,7 @@ export default class RouterMap extends React.Component {
this.selectVegetable = this.selectVegetable.bind(this);
this.getVegetablesTypes();
this.props.changeBackground('map')
changeBackground('map');
}
getVegetablesTypes() {
@ -59,6 +63,15 @@ export default class RouterMap extends React.Component {
}
render() {
const {
selectedType,
selectedVegetable,
types,
} = this.state;
const {
history,
} = this.props;
return (
<Container>
<NotificationContainer />
@ -66,8 +79,8 @@ export default class RouterMap extends React.Component {
<Col xs="12" sm="8">
<MapItem
selectedType={this.state.selectedType}
selectedVegetable={this.state.selectedVegetable}
selectedType={selectedType}
selectedVegetable={selectedVegetable}
selectVegetable={this.selectVegetable}
/>
</Col>
@ -78,11 +91,11 @@ export default class RouterMap extends React.Component {
<div className=" with-border with-background">
<ListGroup className="vegetables--types--group">
{
this.state.types.map((type, key) => (
types.map(type => (
<ListGroupItem
key={key}
className={this.state.selectedType.id === type.id ? 'selected' : 'null'}
onClick={e => this.selectType(type)}
key={type.id}
className={selectedType.id === type.id ? 'selected' : 'null'}
onClick={() => this.selectType(type)}
>
{type.name}
<Badge pill>{type.Vegetables.length}</Badge>
@ -98,9 +111,10 @@ export default class RouterMap extends React.Component {
<Col xs="12" sm="12">
<Vegetables
selectedType={this.state.selectedType}
selectedVegetable={this.state.selectedVegetable}
selectedType={selectedType}
selectedVegetable={selectedVegetable}
selectVegetable={this.selectVegetable}
history={history}
/>
</Col>
</Row>
@ -108,3 +122,10 @@ export default class RouterMap extends React.Component {
);
}
}
RouterMap.propTypes = {
changeBackground: PropTypes.func.isRequired,
history: PropTypes.shape().isRequired,
};
export default RouterMap;

View file

@ -1,4 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';
import {
Container,
Row,
@ -12,13 +13,16 @@ import Api from '../Components/Api';
import MapItem from '../Components/Map';
import Vegetables from '../Components/Vegetables';
export default class Search extends React.Component {
class Search extends React.Component {
constructor(props) {
super(props);
const {
match,
changeBackground,
} = props;
this.state = {
query: props.match.params.query || null,
vegetables: [],
query: match.params.query || null,
selectedType: {},
selectedVegetable: {},
};
@ -27,7 +31,7 @@ export default class Search extends React.Component {
this.selectVegetable = this.selectVegetable.bind(this);
this.getVegetables();
this.props.changeBackground('map');
changeBackground('map');
}
getVegetables() {
@ -43,7 +47,6 @@ export default class Search extends React.Component {
id: res.data.rows.length > 0 ? res.data.rows[0].Type.id : null,
name: res.data.rows.length > 0 ? res.data.rows[0].Type.name : null,
},
vegetables: res.data.rows,
});
})
.catch(() => {
@ -58,14 +61,22 @@ export default class Search extends React.Component {
}
render() {
const {
history,
} = this.props;
const {
selectedType,
selectedVegetable,
} = this.state;
return (
<Container>
<NotificationContainer />
<Row>
<Col xs="12" sm="8">
<MapItem
selectedType={this.state.selectedType}
selectedVegetable={this.state.selectedVegetable}
selectedType={selectedType}
selectedVegetable={selectedVegetable}
selectVegetable={this.selectVegetable}
/>
</Col>
@ -73,10 +84,11 @@ export default class Search extends React.Component {
<Row>
<Col xs="12">
<Vegetables
selectedType={this.state.selectedType}
selectedVegetable={this.state.selectedVegetable}
selectedType={selectedType}
selectedVegetable={selectedVegetable}
selectVegetable={this.selectVegetable}
simple={true}
simple
history={history}
/>
</Col>
</Row>
@ -86,3 +98,23 @@ export default class Search extends React.Component {
);
}
}
Search.defaultProps = {
match: {
params: {
query: null,
},
},
};
Search.propTypes = {
changeBackground: PropTypes.func.isRequired,
match: PropTypes.shape({
params: PropTypes.shape({
query: PropTypes.string,
}),
}),
history: PropTypes.shape().isRequired,
};
export default Search;

View file

@ -1,4 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';
import {
Container,
Row,
@ -10,7 +11,7 @@ import {
CarouselControl,
CarouselIndicators,
Breadcrumb,
BreadcrumbItem
BreadcrumbItem,
} from 'reactstrap';
import {
NotificationContainer,
@ -20,26 +21,41 @@ import Api from '../Components/Api';
import MapItem from '../Components/Map';
import strToSlug from '../StrToSlug';
export default class RouterVegetable extends React.Component {
class RouterVegetable extends React.Component {
static formatValue(value) {
if (!value) {
return (null);
}
if (value[0] === '*') {
return (<div className="tabbed" dangerouslySetInnerHTML={{ __html: value.replace('*', '- ').replace(/\*/g, '<br />- ') }} />);
}
return value;
}
constructor(props) {
super(props);
const {
match,
changeBackground,
} = props;
this.state = {
typeId: props.match.params.typeId,
vegetableId: props.match.params.vegetableId,
typeId: match.params.typeId,
vegetableId: match.params.vegetableId,
selectedType: {
name: '',
Vegetables: []
Vegetables: [],
},
item: {
name: null,
Type: {
id: null,
name: null
}
name: null,
},
},
activeIndex: 0,
carouselHeight: 0
carouselHeight: 0,
};
this.getItem = this.getItem.bind(this);
@ -49,10 +65,9 @@ export default class RouterVegetable extends React.Component {
this.onExiting = this.onExiting.bind(this);
this.onExited = this.onExited.bind(this);
this.setHeight = this.setHeight.bind(this);
this.renderProperty = this.renderProperty.bind(this);
this.getItem();
this.props.changeBackground('vegetables')
changeBackground('vegetables');
}
onExiting() {
@ -63,33 +78,21 @@ export default class RouterVegetable extends React.Component {
this.animating = false;
}
next() {
if (this.animating) return;
const nextIndex = this.state.activeIndex === this.state.item.Pictures.length - 1 ? 0 : this.state.activeIndex + 1;
this.setState({ activeIndex: nextIndex });
}
previous() {
if (this.animating) return;
const nextIndex = this.state.activeIndex === 0 ? this.state.item.Pictures.length - 1 : this.state.activeIndex - 1;
this.setState({ activeIndex: nextIndex });
}
goToIndex(newIndex) {
if (this.animating) return;
this.setState({ activeIndex: newIndex });
}
getItem() {
Api.get(`/types/${this.state.typeId}/vegetables/${this.state.vegetableId}`)
const {
typeId,
vegetableId,
} = this.state;
Api.get(`/types/${typeId}/vegetables/${vegetableId}`)
.then((res) => {
this.setState({
selectedType: {
id: res.data.Type.id,
name: res.data.Type.name,
Vegetables: [
res.data
]
res.data,
],
},
item: res.data,
});
@ -99,6 +102,39 @@ export default class RouterVegetable extends React.Component {
});
}
setHeight(height) {
this.setState({
carouselHeight: height,
});
}
goToIndex(newIndex) {
if (this.animating) return;
this.setState({ activeIndex: newIndex });
}
next() {
const {
activeIndex,
item,
} = this.state;
if (this.animating) return;
const nextIndex = activeIndex === item.Pictures.length - 1 ? 0 : activeIndex + 1;
this.setState({ activeIndex: nextIndex });
}
previous() {
const {
activeIndex,
item,
} = this.state;
if (this.animating) return;
const nextIndex = activeIndex === 0 ? item.Pictures.length - 1 : activeIndex - 1;
this.setState({ activeIndex: nextIndex });
}
renderCarousel() {
const {
activeIndex,
@ -110,79 +146,74 @@ export default class RouterVegetable extends React.Component {
return (null);
}
return (<Col xs="12" lg="6">
<Row className="with-margin">
<Col className="with-border with-background">
<Carousel
activeIndex={activeIndex}
next={this.next}
previous={this.previous}
>
<CarouselIndicators items={this.state.item.Pictures} activeIndex={activeIndex} onClickHandler={this.goToIndex} />
{this.state.item &&
this.state.item.Pictures &&
this.state.item.Pictures.map((picture) => (
<CarouselItem
onExiting={this.onExiting}
onExited={this.onExited}
key={picture.url}
>
<img src={picture.url} alt={picture.url} style={{ maxHeight: `${carouselHeight}px` }} />
</CarouselItem>
))}
<CarouselControl direction="prev" directionText="Previous" onClickHandler={this.previous} />
<CarouselControl direction="next" directionText="Next" onClickHandler={this.next} />
</Carousel>
</Col>
</Row>
</Col>);
}
setHeight(height) {
this.setState({
carouselHeight: height
})
return (
<Col xs="12" lg="6">
<Row className="with-margin">
<Col className="with-border with-background">
<Carousel
activeIndex={activeIndex}
next={this.next}
previous={this.previous}
>
<CarouselIndicators
items={item.Pictures}
activeIndex={activeIndex}
onClickHandler={this.goToIndex}
/>
{item
&& item.Pictures
&& item.Pictures.map(picture => (
<CarouselItem
onExiting={this.onExiting}
onExited={this.onExited}
key={picture.url}
>
<img src={picture.url} alt={picture.url} style={{ maxHeight: `${carouselHeight}px` }} />
</CarouselItem>
))}
<CarouselControl direction="prev" directionText="Previous" onClickHandler={this.previous} />
<CarouselControl direction="next" directionText="Next" onClickHandler={this.next} />
</Carousel>
</Col>
</Row>
</Col>
);
}
renderMap() {
const {
item,
selectedType,
} = this.state;
const sm = (!item || !item.Pictures || item.Pictures.length === 0) ? 12 : 6;
return (<Col xs="12" lg={sm}>
<MapItem
selectedType={this.state.selectedType}
selectedVegetable={this.state.item}
selectVegetable={() => { }}
setHeight={this.setHeight}
/>
</Col>);
return (
<Col xs="12" lg={sm}>
<MapItem
selectedType={selectedType}
selectedVegetable={item}
selectVegetable={() => { }}
setHeight={this.setHeight}
/>
</Col>
);
}
formatValue(value) {
if (!value) {
return (null)
}
if (value[0] === '*') {
return (<div className='tabbed' dangerouslySetInnerHTML={{ __html: value.replace('*', '- ').replace(/\*/g, '<br />- ') }} />);
}
return value
}
renderProperty(item, key) {
static renderProperty(item, key) {
if (item.Property === null || item.Property === undefined || !item.value) {
return (null)
return (null);
}
return (
<ListGroupItem key={key}>
<strong>{item.Property.name}</strong> : {this.formatValue(item.value)}
<strong>{item.Property.name}</strong>
{' '}
:
{' '}
{RouterVegetable.formatValue(item.value)}
</ListGroupItem>
)
);
}
renderProperties() {
@ -190,18 +221,24 @@ export default class RouterVegetable extends React.Component {
item,
} = this.state;
if (!item.Properties ||
!item.Properties.length === 0
if (!item.Properties
|| !item.Properties.length === 0
) {
return (null);
}
return (<ListGroup className="double">
{item.Properties.map(this.renderProperty)}
</ListGroup>)
return (
<ListGroup className="double">
{item.Properties.map(RouterVegetable.renderProperty)}
</ListGroup>
);
}
render() {
const {
item,
} = this.state;
return (
<Container>
<NotificationContainer />
@ -210,16 +247,13 @@ export default class RouterVegetable extends React.Component {
<Row className="with-margin">
<Col className="no-padding">
<Breadcrumb>
<BreadcrumbItem><a href={`/vegetaux/${this.state.item.Type.id}-${strToSlug(this.state.item.Type.name)}`}>{this.state.item.Type.name}</a></BreadcrumbItem>
<BreadcrumbItem active>{this.state.item.name}</BreadcrumbItem>
<BreadcrumbItem><a href={`/vegetaux/${item.Type.id}-${strToSlug(item.Type.name)}`}>{item.Type.name}</a></BreadcrumbItem>
<BreadcrumbItem active>{item.name}</BreadcrumbItem>
</Breadcrumb>
</Col>
</Row>
</Col>
<div>
</div>
{this.renderMap()}
{this.renderCarousel()}
<Col xs="12">
@ -232,7 +266,28 @@ export default class RouterVegetable extends React.Component {
</Col>
</Row>
</Container >
</Container>
);
}
}
RouterVegetable.defaultProps = {
match: {
params: {
typeId: null,
vegetableId: null,
},
},
};
RouterVegetable.propTypes = {
changeBackground: PropTypes.func.isRequired,
match: PropTypes.shape({
params: PropTypes.shape({
typeId: PropTypes.string,
vegetableId: PropTypes.string,
}),
}),
};
export default RouterVegetable;

View file

@ -1,4 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';
import {
Container,
Row,
@ -12,12 +13,17 @@ import Api from '../Components/Api';
import MapItem from '../Components/Map';
import VegetablesList from '../Components/Vegetables';
export default class RouterVegetables extends React.Component {
class RouterVegetables extends React.Component {
constructor(props) {
super(props);
const {
match,
changeBackground,
} = props;
this.state = {
typeId: props.match.params.typeId,
typeId: match.params.typeId,
selectedType: {},
selectedVegetable: {},
};
@ -26,11 +32,15 @@ export default class RouterVegetables extends React.Component {
this.selectVegetable = this.selectVegetable.bind(this);
this.getItem();
this.props.changeBackground('vegetables')
changeBackground('vegetables');
}
getItem() {
Api.get(`/types/${this.state.typeId}`)
const {
typeId,
} = this.state;
Api.get(`/types/${typeId}`)
.then((res) => {
this.setState({
selectedType: res.data,
@ -48,6 +58,14 @@ export default class RouterVegetables extends React.Component {
}
render() {
const {
history,
} = this.props;
const {
selectedType,
selectedVegetable,
} = this.state;
return (
<Container>
<NotificationContainer />
@ -55,8 +73,8 @@ export default class RouterVegetables extends React.Component {
<Col xs="12" md="6">
<MapItem
selectedType={this.state.selectedType}
selectedVegetable={this.state.selectedVegetable}
selectedType={selectedType}
selectedVegetable={selectedVegetable}
selectVegetable={this.selectVegetable}
/>
</Col>
@ -64,10 +82,11 @@ export default class RouterVegetables extends React.Component {
<Row>
<Col xs="12">
<VegetablesList
selectedType={this.state.selectedType}
selectedVegetable={this.state.selectedVegetable}
selectedType={selectedType}
selectedVegetable={selectedVegetable}
selectVegetable={this.selectVegetable}
double={true}
double
history={history}
/>
</Col>
</Row>
@ -77,3 +96,23 @@ export default class RouterVegetables extends React.Component {
);
}
}
RouterVegetables.defaultProps = {
match: {
params: {
typeId: null,
},
},
};
RouterVegetables.propTypes = {
changeBackground: PropTypes.func.isRequired,
match: PropTypes.shape({
params: PropTypes.shape({
typeId: PropTypes.string,
}),
}),
history: PropTypes.shape().isRequired,
};
export default RouterVegetables;

View file

@ -1,6 +1,6 @@
export default (string) => {
if (!string) {
return ''
return '';
}
let str = string;
str = str.replace(/^\s+|\s+$/g, ''); // trim

299
yarn.lock
View file

@ -1132,7 +1132,7 @@ acorn@^5.0.0, acorn@^5.5.3, acorn@^5.6.2:
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279"
integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==
acorn@^6.0.1, acorn@^6.0.2, acorn@^6.0.4:
acorn@^6.0.1, acorn@^6.0.2, acorn@^6.0.4, acorn@^6.0.7:
version "6.1.1"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.1.1.tgz#7d25ae05bb8ad1f9b699108e1094ecd7884adc1f"
integrity sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==
@ -1152,7 +1152,7 @@ ajv-keywords@^3.0.0, ajv-keywords@^3.1.0:
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.0.tgz#4b831e7b531415a7cc518cd404e73f6193c6349d"
integrity sha512-aUjdRFISbuFOl0EIZc+9e4FfZp0bDZgAdOOf30bJmw8VM9v84SHyVyxDfbWxpGYbdZD/9XoKxfHVNmxPkhwyGw==
ajv@^6.0.1, ajv@^6.1.0, ajv@^6.5.3, ajv@^6.5.5:
ajv@^6.0.1, ajv@^6.1.0, ajv@^6.5.3, ajv@^6.5.5, ajv@^6.9.1:
version "6.10.0"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.0.tgz#90d0d54439da587cd7e843bfb7045f50bd22bdf1"
integrity sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==
@ -1449,7 +1449,7 @@ axios@^0.18.0:
follow-redirects "^1.3.0"
is-buffer "^1.1.5"
axobject-query@^2.0.1:
axobject-query@^2.0.1, axobject-query@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.0.2.tgz#ea187abe5b9002b377f925d8bf7d1c561adf38f9"
integrity sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww==
@ -2075,6 +2075,11 @@ callsites@^2.0.0:
resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50"
integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=
callsites@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
camel-case@3.0.x:
version "3.0.0"
resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73"
@ -2837,7 +2842,7 @@ debug@^3.1.0, debug@^3.2.6:
dependencies:
ms "^2.1.1"
debug@^4.1.0:
debug@^4.0.1, debug@^4.1.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
@ -3046,6 +3051,13 @@ doctrine@^2.1.0:
dependencies:
esutils "^2.0.2"
doctrine@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961"
integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==
dependencies:
esutils "^2.0.2"
dom-converter@^0.2:
version "0.2.0"
resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768"
@ -3176,6 +3188,11 @@ emoji-regex@^6.5.1:
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-6.5.1.tgz#9baea929b155565c11ea41c6626eaa65cef992c2"
integrity sha512-PAHp6TxrCy7MGMFidro8uikr+zlJJKJ/Q6mm2ExZ7HwkyR9lSVFfE3kt36qcwa24BQL7y0G9axycGjK1A/0uNQ==
emoji-regex@^7.0.1, emoji-regex@^7.0.2:
version "7.0.3"
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156"
integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==
emojis-list@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389"
@ -3221,7 +3238,7 @@ error-ex@^1.2.0, error-ex@^1.3.1:
dependencies:
is-arrayish "^0.2.1"
es-abstract@^1.12.0, es-abstract@^1.5.1, es-abstract@^1.7.0:
es-abstract@^1.11.0, es-abstract@^1.12.0, es-abstract@^1.5.1, es-abstract@^1.7.0:
version "1.13.0"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.13.0.tgz#ac86145fdd5099d8dd49558ccba2eaf9b88e24e9"
integrity sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==
@ -3264,6 +3281,24 @@ escodegen@^1.11.0, escodegen@^1.9.1:
optionalDependencies:
source-map "~0.6.1"
eslint-config-airbnb-base@^13.1.0:
version "13.1.0"
resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-13.1.0.tgz#b5a1b480b80dfad16433d6c4ad84e6605052c05c"
integrity sha512-XWwQtf3U3zIoKO1BbHh6aUhJZQweOwSt4c2JrPDg9FP3Ltv3+YfEv7jIDB8275tVnO/qOHbfuYg3kzw6Je7uWw==
dependencies:
eslint-restricted-globals "^0.1.1"
object.assign "^4.1.0"
object.entries "^1.0.4"
eslint-config-airbnb@^17.1.0:
version "17.1.0"
resolved "https://registry.yarnpkg.com/eslint-config-airbnb/-/eslint-config-airbnb-17.1.0.tgz#3964ed4bc198240315ff52030bf8636f42bc4732"
integrity sha512-R9jw28hFfEQnpPau01NO5K/JWMGLi6aymiF6RsnMURjTk+MqZKllCqGK/0tOvHkPi/NWSSOU2Ced/GX++YxLnw==
dependencies:
eslint-config-airbnb-base "^13.1.0"
object.assign "^4.1.0"
object.entries "^1.0.4"
eslint-config-react-app@^3.0.5:
version "3.0.8"
resolved "https://registry.yarnpkg.com/eslint-config-react-app/-/eslint-config-react-app-3.0.8.tgz#6f606828ba30bafee7d744c41cd07a3fea8f3035"
@ -3271,7 +3306,7 @@ eslint-config-react-app@^3.0.5:
dependencies:
confusing-browser-globals "^1.0.6"
eslint-import-resolver-node@^0.3.1:
eslint-import-resolver-node@^0.3.1, eslint-import-resolver-node@^0.3.2:
version "0.3.2"
resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a"
integrity sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==
@ -3290,7 +3325,7 @@ eslint-loader@2.1.1:
object-hash "^1.1.4"
rimraf "^2.6.1"
eslint-module-utils@^2.2.0:
eslint-module-utils@^2.2.0, eslint-module-utils@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.3.0.tgz#546178dab5e046c8b562bbb50705e2456d7bda49"
integrity sha512-lmDJgeOOjk8hObTysjqH7wyMi+nsHwwvfBykwfhjR1LNdd7C2uFJBvx4OpWYpXOw4df1yE1cDEVd1yLHitk34w==
@ -3321,6 +3356,22 @@ eslint-plugin-import@2.14.0:
read-pkg-up "^2.0.0"
resolve "^1.6.0"
eslint-plugin-import@^2.16.0:
version "2.16.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.16.0.tgz#97ac3e75d0791c4fac0e15ef388510217be7f66f"
integrity sha512-z6oqWlf1x5GkHIFgrSvtmudnqM6Q60KM4KvpWi5ubonMjycLjndvd5+8VAZIsTlHC03djdgJuyKG6XO577px6A==
dependencies:
contains-path "^0.1.0"
debug "^2.6.9"
doctrine "1.5.0"
eslint-import-resolver-node "^0.3.2"
eslint-module-utils "^2.3.0"
has "^1.0.3"
lodash "^4.17.11"
minimatch "^3.0.4"
read-pkg-up "^2.0.0"
resolve "^1.9.0"
eslint-plugin-jsx-a11y@6.1.2:
version "6.1.2"
resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.1.2.tgz#69bca4890b36dcf0fe16dd2129d2d88b98f33f88"
@ -3335,6 +3386,20 @@ eslint-plugin-jsx-a11y@6.1.2:
has "^1.0.3"
jsx-ast-utils "^2.0.1"
eslint-plugin-jsx-a11y@^6.2.1:
version "6.2.1"
resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.1.tgz#4ebba9f339b600ff415ae4166e3e2e008831cf0c"
integrity sha512-cjN2ObWrRz0TTw7vEcGQrx+YltMvZoOEx4hWU8eEERDnBIU00OTq7Vr+jA7DFKxiwLNv4tTh5Pq2GUNEa8b6+w==
dependencies:
aria-query "^3.0.0"
array-includes "^3.0.3"
ast-types-flow "^0.0.7"
axobject-query "^2.0.2"
damerau-levenshtein "^1.0.4"
emoji-regex "^7.0.2"
has "^1.0.3"
jsx-ast-utils "^2.0.1"
eslint-plugin-react@7.11.1:
version "7.11.1"
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.11.1.tgz#c01a7af6f17519457d6116aa94fc6d2ccad5443c"
@ -3346,6 +3411,24 @@ eslint-plugin-react@7.11.1:
jsx-ast-utils "^2.0.1"
prop-types "^15.6.2"
eslint-plugin-react@^7.12.4:
version "7.12.4"
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.12.4.tgz#b1ecf26479d61aee650da612e425c53a99f48c8c"
integrity sha512-1puHJkXJY+oS1t467MjbqjvX53uQ05HXwjqDgdbGBqf5j9eeydI54G3KwiJmWciQ0HTBacIKw2jgwSBSH3yfgQ==
dependencies:
array-includes "^3.0.3"
doctrine "^2.1.0"
has "^1.0.3"
jsx-ast-utils "^2.0.1"
object.fromentries "^2.0.0"
prop-types "^15.6.2"
resolve "^1.9.0"
eslint-restricted-globals@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz#35f0d5cbc64c2e3ed62e93b4b1a7af05ba7ed4d7"
integrity sha1-NfDVy8ZMLj7WLpO0saevBbp+1Nc=
eslint-scope@3.7.1:
version "3.7.1"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8"
@ -3362,6 +3445,14 @@ eslint-scope@^4.0.0:
esrecurse "^4.1.0"
estraverse "^4.1.1"
eslint-scope@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848"
integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==
dependencies:
esrecurse "^4.1.0"
estraverse "^4.1.1"
eslint-utils@^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.3.1.tgz#9a851ba89ee7c460346f97cf8939c7298827e512"
@ -3416,6 +3507,48 @@ eslint@5.6.0:
table "^4.0.3"
text-table "^0.2.0"
eslint@^5.16.0:
version "5.16.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.16.0.tgz#a1e3ac1aae4a3fbd8296fcf8f7ab7314cbb6abea"
integrity sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==
dependencies:
"@babel/code-frame" "^7.0.0"
ajv "^6.9.1"
chalk "^2.1.0"
cross-spawn "^6.0.5"
debug "^4.0.1"
doctrine "^3.0.0"
eslint-scope "^4.0.3"
eslint-utils "^1.3.1"
eslint-visitor-keys "^1.0.0"
espree "^5.0.1"
esquery "^1.0.1"
esutils "^2.0.2"
file-entry-cache "^5.0.1"
functional-red-black-tree "^1.0.1"
glob "^7.1.2"
globals "^11.7.0"
ignore "^4.0.6"
import-fresh "^3.0.0"
imurmurhash "^0.1.4"
inquirer "^6.2.2"
js-yaml "^3.13.0"
json-stable-stringify-without-jsonify "^1.0.1"
levn "^0.3.0"
lodash "^4.17.11"
minimatch "^3.0.4"
mkdirp "^0.5.1"
natural-compare "^1.4.0"
optionator "^0.8.2"
path-is-inside "^1.0.2"
progress "^2.0.0"
regexpp "^2.0.1"
semver "^5.5.1"
strip-ansi "^4.0.0"
strip-json-comments "^2.0.1"
table "^5.2.3"
text-table "^0.2.0"
espree@^4.0.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/espree/-/espree-4.1.0.tgz#728d5451e0fd156c04384a7ad89ed51ff54eb25f"
@ -3425,6 +3558,15 @@ espree@^4.0.0:
acorn-jsx "^5.0.0"
eslint-visitor-keys "^1.0.0"
espree@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.1.tgz#5d6526fa4fc7f0788a5cf75b15f30323e2f81f7a"
integrity sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==
dependencies:
acorn "^6.0.7"
acorn-jsx "^5.0.0"
eslint-visitor-keys "^1.0.0"
esprima@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"
@ -3755,6 +3897,13 @@ file-entry-cache@^2.0.0:
flat-cache "^1.2.1"
object-assign "^4.0.1"
file-entry-cache@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c"
integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==
dependencies:
flat-cache "^2.0.1"
file-loader@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-2.0.0.tgz#39749c82f020b9e85901dcff98e8004e6401cfde"
@ -3874,6 +4023,20 @@ flat-cache@^1.2.1:
rimraf "~2.6.2"
write "^0.2.1"
flat-cache@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0"
integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==
dependencies:
flatted "^2.0.0"
rimraf "2.6.3"
write "1.0.3"
flatted@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.0.tgz#55122b6536ea496b4b44893ee2608141d10d9916"
integrity sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg==
flatten@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782"
@ -4385,6 +4548,18 @@ history@^4.7.2:
value-equal "^0.4.0"
warning "^3.0.0"
history@^4.9.0:
version "4.9.0"
resolved "https://registry.yarnpkg.com/history/-/history-4.9.0.tgz#84587c2068039ead8af769e9d6a6860a14fa1bca"
integrity sha512-H2DkjCjXf0Op9OAr6nJ56fcRkTSNrUiv41vNJ6IswJjif6wlpZK0BTfFbi7qK9dXLSYZxkq5lBsj3vUjlYBYZA==
dependencies:
"@babel/runtime" "^7.1.2"
loose-envify "^1.2.0"
resolve-pathname "^2.2.0"
tiny-invariant "^1.0.2"
tiny-warning "^1.0.0"
value-equal "^0.4.0"
hmac-drbg@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
@ -4637,6 +4812,14 @@ import-fresh@^2.0.0:
caller-path "^2.0.0"
resolve-from "^3.0.0"
import-fresh@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.0.0.tgz#a3d897f420cab0e671236897f75bc14b4885c390"
integrity sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ==
dependencies:
parent-module "^1.0.0"
resolve-from "^4.0.0"
import-from@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/import-from/-/import-from-2.1.0.tgz#335db7f2a7affd53aaa471d4b8021dee36b7f3b1"
@ -4717,7 +4900,7 @@ inquirer@6.2.0:
strip-ansi "^4.0.0"
through "^2.3.6"
inquirer@^6.1.0:
inquirer@^6.1.0, inquirer@^6.2.2:
version "6.2.2"
resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.2.tgz#46941176f65c9eb20804627149b743a218f25406"
integrity sha512-Z2rREiXA6cHRR9KBOarR3WuLlFzlIfAEIiB45ll5SSadMg7WqOh1MKEjjndfuH5ewXdixWCxqnVfGOQzPeiztA==
@ -5556,6 +5739,14 @@ js-yaml@^3.12.0, js-yaml@^3.7.0, js-yaml@^3.9.0:
argparse "^1.0.7"
esprima "^4.0.0"
js-yaml@^3.13.0:
version "3.13.1"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==
dependencies:
argparse "^1.0.7"
esprima "^4.0.0"
jsbn@~0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
@ -6614,6 +6805,26 @@ object.assign@^4.1.0:
has-symbols "^1.0.0"
object-keys "^1.0.11"
object.entries@^1.0.4:
version "1.1.0"
resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.0.tgz#2024fc6d6ba246aee38bdb0ffd5cfbcf371b7519"
integrity sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA==
dependencies:
define-properties "^1.1.3"
es-abstract "^1.12.0"
function-bind "^1.1.1"
has "^1.0.3"
object.fromentries@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.0.tgz#49a543d92151f8277b3ac9600f1e930b189d30ab"
integrity sha512-9iLiI6H083uiqUuvzyY6qrlmc/Gz8hLQFOcb/Ri/0xXFkSNS3ctV+CbE6yM2+AnkYfOB3dGjdzC0wrMLIhQICA==
dependencies:
define-properties "^1.1.2"
es-abstract "^1.11.0"
function-bind "^1.1.1"
has "^1.0.1"
object.getownpropertydescriptors@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16"
@ -6840,6 +7051,13 @@ param-case@2.1.x:
dependencies:
no-case "^2.2.0"
parent-module@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2"
integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==
dependencies:
callsites "^3.0.0"
parse-asn1@^5.0.0:
version "5.1.4"
resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.4.tgz#37f6628f823fbdeb2273b4d540434a22f3ef1fcc"
@ -7766,7 +7984,7 @@ prompts@^0.1.9:
kleur "^2.0.1"
sisteransi "^0.1.1"
prop-types@^15.5.10, prop-types@^15.5.6, prop-types@^15.5.8, prop-types@^15.6.1, prop-types@^15.6.2:
prop-types@^15.5.10, prop-types@^15.5.6, prop-types@^15.5.8, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2:
version "15.7.2"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
@ -8272,7 +8490,7 @@ regexp-tree@^0.1.0:
resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.5.tgz#7cd71fca17198d04b4176efd79713f2998009397"
integrity sha512-nUmxvfJyAODw+0B13hj8CFVAxhe7fDEAgJgaotBu3nnR+IgGgZq59YedJP5VYTlkEfqjuK6TuRpnymKdatLZfQ==
regexpp@^2.0.0:
regexpp@^2.0.0, regexpp@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f"
integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==
@ -8455,6 +8673,11 @@ resolve-from@^3.0.0:
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748"
integrity sha1-six699nWiBvItuZTM17rywoYh0g=
resolve-from@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
resolve-pathname@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-2.2.0.tgz#7e9ae21ed815fd63ab189adeee64dc831eefa879"
@ -8477,7 +8700,7 @@ resolve@1.8.1:
dependencies:
path-parse "^1.0.5"
resolve@^1.10.0, resolve@^1.3.2, resolve@^1.5.0, resolve@^1.6.0, resolve@^1.8.1:
resolve@^1.10.0, resolve@^1.3.2, resolve@^1.5.0, resolve@^1.6.0, resolve@^1.8.1, resolve@^1.9.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.10.0.tgz#3bdaaeaf45cc07f375656dfd2e54ed0810b101ba"
integrity sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==
@ -8507,7 +8730,7 @@ rgba-regex@^1.0.0:
resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3"
integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=
rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@~2.6.2:
rimraf@2.6.3, rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@~2.6.2:
version "2.6.3"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab"
integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==
@ -8812,6 +9035,15 @@ slice-ansi@1.0.0:
dependencies:
is-fullwidth-code-point "^2.0.0"
slice-ansi@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636"
integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==
dependencies:
ansi-styles "^3.2.0"
astral-regex "^1.0.0"
is-fullwidth-code-point "^2.0.0"
snapdragon-node@^2.0.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b"
@ -9090,6 +9322,15 @@ string-width@^1.0.1:
is-fullwidth-code-point "^2.0.0"
strip-ansi "^4.0.0"
string-width@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961"
integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==
dependencies:
emoji-regex "^7.0.1"
is-fullwidth-code-point "^2.0.0"
strip-ansi "^5.1.0"
string_decoder@^1.0.0, string_decoder@^1.1.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d"
@ -9134,6 +9375,13 @@ strip-ansi@^5.0.0:
dependencies:
ansi-regex "^4.1.0"
strip-ansi@^5.1.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae"
integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==
dependencies:
ansi-regex "^4.1.0"
strip-bom@3.0.0, strip-bom@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
@ -9244,6 +9492,16 @@ table@^4.0.3:
slice-ansi "1.0.0"
string-width "^2.1.1"
table@^5.2.3:
version "5.2.3"
resolved "https://registry.yarnpkg.com/table/-/table-5.2.3.tgz#cde0cc6eb06751c009efab27e8c820ca5b67b7f2"
integrity sha512-N2RsDAMvDLvYwFcwbPyF3VmVSSkuF+G1e+8inhBLtHpvwXGw4QRPEZhihQNeEN0i1up6/f6ObCJXNdlRG3YVyQ==
dependencies:
ajv "^6.9.1"
lodash "^4.17.11"
slice-ansi "^2.1.0"
string-width "^3.0.0"
tapable@^1.0.0, tapable@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.1.tgz#4d297923c5a72a42360de2ab52dadfaaec00018e"
@ -9336,6 +9594,16 @@ timsort@^0.3.0:
resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4"
integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=
tiny-invariant@^1.0.2:
version "1.0.4"
resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.0.4.tgz#346b5415fd93cb696b0c4e8a96697ff590f92463"
integrity sha512-lMhRd/djQJ3MoaHEBrw8e2/uM4rs9YMNk0iOr8rHQ0QdbM7D4l0gFl3szKdeixrlyfm9Zqi4dxHCM2qVG8ND5g==
tiny-warning@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.2.tgz#1dfae771ee1a04396bdfde27a3adcebc6b648b28"
integrity sha512-rru86D9CpQRLvsFG5XFdy0KdLAvjdQDyZCsRcuu60WtzFylDM3eAWSxEVz5kzL2Gp544XiUvPbVKtOA/txLi9Q==
tmp@^0.0.33:
version "0.0.33"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
@ -10111,6 +10379,13 @@ write-file-atomic@^2.1.0:
imurmurhash "^0.1.4"
signal-exit "^3.0.2"
write@1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3"
integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==
dependencies:
mkdirp "^0.5.1"
write@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757"