Progress on filters

This commit is contained in:
Edin Dazdarevic
2017-04-05 00:14:30 +02:00
parent 49e9e2fdfb
commit d2ee02b6df
14 changed files with 395 additions and 164 deletions

View File

@@ -1,43 +1,72 @@
import React from 'react';
import React from "react";
import { formatFilterNumber } from "../lib/helpers";
export default class Filters extends React.Component {
onCloseClick(e) {
if (this.props.onClose) {
this.props.onClose();
}
}
onMaxPriceChange (e) {
this.props.dispatch({type: 'SET_MAX_PRICE', action: {maxPrice: e.target.value}})
onMaxPriceChange(e) {
this.props.dispatch({
type: "SET_MAX_PRICE",
action: { maxPrice: e.target.value }
});
}
onMinPriceChange (e) {
this.props.dispatch({type: 'SET_MIN_PRICE', action: {minPrice: e.target.value}})
onMinPriceChange(e) {
this.props.dispatch({
type: "SET_MIN_PRICE",
action: { minPrice: e.target.value }
});
}
onMaxSizeChange(e) {
this.props.dispatch({
type: "SET_MAX_SIZE",
action: { maxSize: e.target.value }
});
}
onMinSizeChange(e) {
this.props.dispatch({
type: "SET_MIN_SIZE",
action: { minSize: e.target.value }
});
}
onRoomsClick(rooms) {
console.log('rooms:', rooms);
this.props.dispatch({type: 'SET_ROOMS', action: {rooms}});
}
onRefreshClick () {
this.props.dispatch({type: 'UPDATE_SEARCH'});
onRefreshClick() {
this.updateSearch();
}
onKeyPress (e) {
if (e.key === 'Enter') {
this.updateSearch();
}
}
updateSearch () {
this.props.dispatch({ type: "UPDATE_SEARCH" });
}
render() {
const {filters} = this.props;
const selectedRooms = (val) => filters.rooms[val] ? 'selected' : '';
const { filters } = this.props;
const selectedRooms = val => filters.rooms[val] ? "selected" : "";
return (
<div className="filters">
<div className="filters-close">
Uslovi Pretrage
<i onClick={this.onCloseClick.bind(this)}
<i
onClick={this.onCloseClick.bind(this)}
className="close-icon fa fa-times"
aria-hidden="true"></i>
aria-hidden="true"
/>
</div>
<div className="filter-row">
@@ -46,71 +75,122 @@ export default class Filters extends React.Component {
</div>
<div className="filter-content value-between-box">
izmedju <input value={`${this.props.filters.minPrice}`} onChange={this.onMinPriceChange.bind(this)}></input> KM i <input onChange={this.onMaxPriceChange.bind(this)}></input>
{this.props.filters.dirty? <button onClick={this.onRefreshClick.bind(this)}>Refresh</button>: null}
</div>
OD
<input
onKeyPress={this.onKeyPress.bind(this)}
onChange={this.onMinPriceChange.bind(this)}
value={formatFilterNumber(filters.minPrice)}
/>
{" "}
DO
<input
onKeyPress={this.onKeyPress.bind(this)}
onChange={this.onMaxPriceChange.bind(this)}
value={formatFilterNumber(filters.maxPrice)}
/>
{this.props.filters.priceDirty
?
<i
onClick={this.onRefreshClick.bind(this)}
className="fa fa-refresh fa-refresh-custom"
aria-hidden="true">
</i>
: null}
</div>
</div>
<div className="filter-row filter-property-types">
<div className="filter-title">
TIP
</div>
<div className="filter-content">
<div className="filter-btn property-type-btn">
Stan
</div>
<div className="filter-btn property-type-btn">
Kuća
</div>
<div className="filter-content">
<div className="filter-btn property-type-btn">
Stan
</div>
<div className="filter-content">
<div className="filter-btn property-type-btn">
Zemljište
</div>
<div className="filter-btn property-type-btn">
Poslovni prostor
</div>
<div className="filter-btn property-type-btn">
Kuća
</div>
</div>
<div className="filter-content">
<div className="filter-btn property-type-btn">
Zemljište
</div>
<div className="filter-btn property-type-btn">
Poslovni prostor
</div>
</div>
</div>
<div className="filter-row">
<div className="filter-title">
KVADRATA
</div>
<div className="filter-content value-between-box">
izmedju <input></input>
i <input></input>
OD
<input
onKeyPress={this.onKeyPress.bind(this)}
value={formatFilterNumber(filters.minSize)}
onChange={this.onMinSizeChange.bind(this)}
/>
DO
{" "}
<input
onKeyPress={this.onKeyPress.bind(this)}
value={formatFilterNumber(filters.maxSize)}
onChange={this.onMaxSizeChange.bind(this)}
/>
{this.props.filters.sizeDirty
? <i
onClick={this.onRefreshClick.bind(this)}
className="fa fa-refresh fa-refresh-custom"
aria-hidden="true">
</i>
: null}
</div>
</div>
<div className="filter-row filter-property-rooms">
<div className="filter-row filter-property-rooms no-border">
<div className="filter-title">
BROJ SOBA
</div>
<div className="filter-content">
<div onClick={this.onRoomsClick.bind(this, 'Garsonjera')} className={`filter-btn property-rooms-studio-btn ${selectedRooms('Garsonjera')}`}>
<div
onClick={this.onRoomsClick.bind(this, "Garsonjera")}
className={
`filter-btn property-rooms-studio-btn ${selectedRooms("Garsonjera")}`
}
>
Garsonjera
</div>
<div onClick={this.onRoomsClick.bind(this, 2)} className={`filter-btn property-rooms-btn ${selectedRooms(2)}`}>
<div
onClick={this.onRoomsClick.bind(this, 2)}
className={`filter-btn property-rooms-btn ${selectedRooms(2)}`}
>
2
</div>
<div onClick={this.onRoomsClick.bind(this, 3)} className={`filter-btn property-rooms-btn ${selectedRooms(3)}`}>
<div
onClick={this.onRoomsClick.bind(this, 3)}
className={`filter-btn property-rooms-btn ${selectedRooms(3)}`}
>
3
</div>
<div onClick={this.onRoomsClick.bind(this, '4+')} className={`filter-btn property-rooms-btn ${selectedRooms('4+')}`}>
<div
onClick={this.onRoomsClick.bind(this, "4+")}
className={`filter-btn property-rooms-btn ${selectedRooms("4+")}`}
>
4+
</div>
</div>
</div>
<div className="filter-row no-border">
<div className="filter-title">
</div>
<div className="filter-title" />
<div className="filter-content">
<div className="filter-btn more-filters">Više Filtera</div>
<div className="hide filter-btn more-filters">Više Filtera</div>
</div>
</div>
<div className="clear-both">
</div>
<div className="filter-bottom">
</div>
</div>)
<div className="clear-both" />
<div className="filter-bottom" />
</div>
);
}
}

View File

@@ -1,5 +1,6 @@
import React from 'react';
import Gallery from './gallery';
import {formatPrice} from '../lib/helpers';
export default class ListingDetails extends React.Component {
onReadMore (e) {
@@ -48,7 +49,7 @@ export default class ListingDetails extends React.Component {
imageIndex={this.props.imageIndex} />
<div className="ld-price-address-box">
<div className="ld-price">
{listing.price.toLocaleString('bs')} KM
{formatPrice(listing.price)}
</div>
<div className="ld-address">

View File

@@ -1,4 +1,5 @@
import React from 'react';
import {formatPrice} from '../lib/helpers';
export default class Listings extends React.Component {
onListingClick(id) {
@@ -24,7 +25,7 @@ export default class Listings extends React.Component {
<img src={images[0]} alt=""></img>
</div>
<div className="pli-details">
<div className="price">{l.price.toLocaleString('bs')} KM</div>
<div className="price">{formatPrice(l.price)}</div>
<div className="description">{l.rooms ? `${l.rooms} sobe, `: null}{l.size ? `${l.size}m2`: null}</div>
<div className="address">
<div className="street">

View File

@@ -14,7 +14,6 @@ class Main extends React.Component {
listings: (new Map()),
imageIndex: 0,
filters: {
minPrice: 0,
rooms: {}
}
};
@@ -100,40 +99,44 @@ class Main extends React.Component {
refreshListings() {
const map = this.map;
const {rooms, minSize, maxSize, minPrice, maxPrice} = this.state.filters;
const properties = loadProperties({
bounds: map.getBounds().toUrlValue(),
minPrice: this.state.filters.minPrice,
maxPrice: this.state.filters.maxPrice,
rooms: this.state.filters.rooms
rooms,
minSize,
maxSize,
minPrice,
maxPrice
});
properties.then(p=> p.text()).then(p => {
const data = JSON.parse(p);
console.log('props', data)
for(const [index, prop] of data.entries()) {
const myLatLng = {lat: prop.loc[0], lng: prop.loc[1]};
properties.then(p=> p.text()).then(p => {
const data = JSON.parse(p);
console.log('props', data)
for(const [index, prop] of data.entries()) {
const myLatLng = {lat: prop.loc[0], lng: prop.loc[1]};
const marker = new google.maps.Marker({
position: myLatLng,
map: map,
title: prop.title
});
marker.addListener('click', () => {
console.log('clicking...')
this.dispatch({type: 'VIEW_LISTING_DETAILS', action: {
id: prop.url
}})
});
}
this.dispatch({
type: 'LISTINGS_LOADED',
action: {
listings: data
}
const marker = new google.maps.Marker({
position: myLatLng,
map: map,
title: prop.title
});
})
marker.addListener('click', () => {
console.log('clicking...')
this.dispatch({type: 'VIEW_LISTING_DETAILS', action: {
id: prop.url
}})
});
}
this.dispatch({
type: 'LISTINGS_LOADED',
action: {
listings: data
}
});
})
}
onListingClick() {

1
web/dist/index.html vendored
View File

@@ -1,6 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<title>KIVI - Najbolji način da pronađeš svoj dom</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">

13
web/dist/main.css vendored
View File

@@ -581,7 +581,7 @@ html {
letter-spacing: .26px;
border-radius: 3px;
background: #fff;
color: #5ab8f8;
color: #51bc6a;
cursor: pointer;
}
@@ -783,3 +783,14 @@ html {
}
}
.fa-refresh-custom {
font-size: 1.5em;
cursor: pointer;
color: #b6d53b;
padding: 5px;
}
.hide {
display: none;
}

View File

@@ -4,6 +4,8 @@ export const loadProperties = ({
bounds,
minPrice = '',
maxPrice = '',
minSize = '',
maxSize = '',
rooms
}) => {
const allRooms = Object
@@ -13,7 +15,7 @@ export const loadProperties = ({
// TODO: handle errors
//return fetch(process.env.API_URL + '/api/search', {
return fetch(`http://localhost:3001/api/search?bounds=${bounds}&minPrice=${minPrice}&maxPrice=${maxPrice}&rooms=${allRooms}`, {
return fetch(`http://localhost:3001/api/search?bounds=${bounds}&minPrice=${minPrice}&maxPrice=${maxPrice}&rooms=${allRooms}&minSize=${minSize}&maxSize=${maxSize}`, {
//credentials: 'include'
});

View File

@@ -1,125 +1,159 @@
const setMaxPrice = ({type, action}, component) => {
const setMaxPrice = ({ type, action }, component) => {
const maxPrice = parseFloat(action.maxPrice);
component.setState({
filters: {
...component.state.filters,
maxPrice: parseFloat(action.maxPrice),
dirty: true
maxPrice: isNaN(maxPrice) ? undefined : maxPrice,
priceDirty: true
}
})
}
});
};
const setMinPrice = ({type, action}, component) => {
const setMinPrice = ({ type, action }, component) => {
const minPrice = parseFloat(action.minPrice);
component.setState({
filters: {
...component.state.filters,
minPrice: parseFloat(action.minPrice),
dirty: true
minPrice: isNaN(minPrice) ? undefined : minPrice,
priceDirty: true
}
})
}
});
};
const viewListingDetails= ({type, action}, component) => {
const setMinSize = ({ type, action }, component) => {
const minSize = parseFloat(action.minSize);
component.setState({
filters: {
...component.state.filters,
minSize: isNaN(minSize) ? undefined : minSize,
sizeDirty: true
}
});
};
const setMaxSize = ({ type, action }, component) => {
const maxSize = parseFloat(action.maxSize);
component.setState({
filters: {
...component.state.filters,
maxSize: isNaN(maxSize) ? undefined : maxSize,
sizeDirty: true
}
});
};
const viewListingDetails = ({ type, action }, component) => {
component.setState({
listingDetails: true,
listingId: action.id,
descriptionExpanded: false,
imageIndex: 0
})
}
});
};
const listingsLoaded = ({type, action}, component) => {
const listingsLoaded = ({ type, action }, component) => {
const currentListings = new Map(); //component.state.listings;
for(const listing of action.listings) {
currentListings.set(listing.url, listing)
for (const listing of action.listings) {
currentListings.set(listing.url, listing);
}
component.setState({
listings: currentListings
});
}
};
const expandDescription = ({type, action}, component) => {
const expandDescription = ({ type, action }, component) => {
component.setState({
descriptionExpanded: true
});
}
};
const prevImage = ({type, action}, component) => {
const prevImage = ({ type, action }, component) => {
const index = component.state.imageIndex;
if (index > 0) {
component.setState({
imageIndex: index - 1
});
}
}
};
const nextImage = ({type, action}, component) => {
const nextImage = ({ type, action }, component) => {
const index = component.state.imageIndex;
component.setState({
imageIndex: index + 1
});
}
};
const viewImage = ({type, action}, component) => {
const viewImage = ({ type, action }, component) => {
component.setState({
imageIndex: action.index
});
}
};
const searchPlaceChanged = ({type, action}, component) => {
const searchPlaceChanged = ({ type, action }, component) => {
component.setState({
listingDetails: false
});
}
};
const setRooms = ({type, action}, component) => {
const prevRooms = (component.state.filters.rooms || {});
const setRooms = ({ type, action }, component) => {
const prevRooms = component.state.filters.rooms || {};
console.log('BERORE ROOMS');
component.setState({
filters: {
...component.state.filters,
rooms: {
...prevRooms,
[action.rooms]: !prevRooms[action.rooms]
component.setState(
{
filters: {
...component.state.filters,
rooms: {
...prevRooms,
[action.rooms]: !prevRooms[action.rooms]
}
}
},
() => {
console.log('after rooms');
component.refreshListings();
}
}, () => {
component.refreshListings();
});
}
);
};
const updateSearch = ({type, action}, component) => {
console.log('updating search');
component.setState({
filters: {
...component.state.filters,
dirty: false
const updateSearch = ({ type, action }, component) => {
console.log("updating search");
component.setState(
{
filters: {
...component.state.filters,
sizeDirty: false,
priceDirty: false
}
},
() => {
component.refreshListings();
}
}, () => {
component.refreshListings();
});
}
);
};
const handlers = {
'SET_MIN_PRICE': setMinPrice,
'SET_MAX_PRICE': setMaxPrice,
'LISTINGS_LOADED': listingsLoaded,
'EXPAND_DESCRIPTION': expandDescription,
'PREV_IMAGE': prevImage,
'NEXT_IMAGE': nextImage,
'VIEW_IMAGE': viewImage,
'SEARCH_PLACE_CHANGED': searchPlaceChanged,
'SET_ROOMS': setRooms,
'VIEW_LISTING_DETAILS': viewListingDetails,
'UPDATE_SEARCH': updateSearch
}
export const handleMessage = ({type, action}, component) => {
SET_MIN_PRICE: setMinPrice,
SET_MAX_PRICE: setMaxPrice,
SET_MIN_SIZE: setMinSize,
SET_MAX_SIZE: setMaxSize,
LISTINGS_LOADED: listingsLoaded,
EXPAND_DESCRIPTION: expandDescription,
PREV_IMAGE: prevImage,
NEXT_IMAGE: nextImage,
VIEW_IMAGE: viewImage,
SEARCH_PLACE_CHANGED: searchPlaceChanged,
SET_ROOMS: setRooms,
VIEW_LISTING_DETAILS: viewListingDetails,
UPDATE_SEARCH: updateSearch
};
export const handleMessage = ({ type, action }, component) => {
if (!handlers[type]) {
throw new `Unhandled message: ${type}`;
throw new `Unhandled message: ${type}`();
}
return handlers[type]({type, action}, component);
}
return handlers[type]({ type, action }, component);
};

14
web/lib/helpers.js Normal file
View File

@@ -0,0 +1,14 @@
export const formatPrice = (p) => {
if (p === -1) {
return 'Po dogovoru'
}
return p.toLocaleString('bs') + ' KM';
}
export const formatFilterNumber = (num) => {
if (isNaN(num) || num == null) {
return ''
}
return num;
}

View File

@@ -19,6 +19,7 @@
"babel-loader": "^6.2.7",
"babel-preset-es2015": "^6.18.0",
"babel-preset-react": "^6.16.0",
"prettier": "^0.22.0",
"webpack": "^1.13.3",
"webpack-dev-server": "^1.16.2"
}

View File

@@ -42,6 +42,12 @@ ansi-styles@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
ansi-styles@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.0.0.tgz#5404e93a544c4fec7f048262977bebfe3155e0c1"
dependencies:
color-convert "^1.0.0"
anymatch@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.0.tgz#a3e52fa39168c825ff57b0248126ce5a8ff95507"
@@ -104,6 +110,14 @@ assert@^1.1.1:
dependencies:
util "0.10.3"
ast-types@0.8.18:
version "0.8.18"
resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.8.18.tgz#c8b98574898e8914e9d8de74b947564a9fe929af"
ast-types@0.9.4:
version "0.9.4"
resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.4.tgz#410d1f81890aeb8e0a38621558ba5869ae53c91b"
async-each@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d"
@@ -132,7 +146,7 @@ aws4@^1.2.1:
version "1.6.0"
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e"
babel-code-frame@^6.22.0:
babel-code-frame@^6.22.0, babel-code-frame@6.22.0:
version "6.22.0"
resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4"
dependencies:
@@ -695,6 +709,10 @@ babylon@^6.11.0, babylon@^6.15.0:
version "6.16.1"
resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.16.1.tgz#30c5a22f481978a9e7f8cdfdf496b11d94b404d3"
babylon@6.15.0:
version "6.15.0"
resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.15.0.tgz#ba65cfa1a80e1759b0e89fb562e27dccae70348e"
balanced-match@^0.4.1:
version "0.4.2"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838"
@@ -795,7 +813,7 @@ center-align@^0.1.1:
align-text "^0.1.3"
lazy-cache "^1.0.3"
chalk@^1.1.0:
chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3, chalk@1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
dependencies:
@@ -840,6 +858,20 @@ code-point-at@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
color-convert@^1.0.0:
version "1.9.0"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.0.tgz#1accf97dd739b983bf994d56fec8f95853641b7a"
dependencies:
color-name "^1.1.1"
color-name@^1.1.1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.2.tgz#5c8ab72b64bd2215d617ae9559ebb148475cf98d"
colors@>=0.6.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63"
combined-stream@^1.0.5, combined-stream@~1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009"
@@ -1044,7 +1076,7 @@ escape-string-regexp@^1.0.2:
version "1.0.5"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
esutils@^2.0.0, esutils@^2.0.2:
esutils@^2.0.0, esutils@^2.0.2, esutils@2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
@@ -1190,6 +1222,14 @@ find-up@^1.0.0:
path-exists "^2.0.0"
pinkie-promise "^2.0.0"
flow-parser@0.40.0:
version "0.40.0"
resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.40.0.tgz#b3444742189093323c4319c4fe9d35391f46bcbc"
dependencies:
ast-types "0.8.18"
colors ">=0.6.2"
minimist ">=0.2.0"
for-in@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
@@ -1261,6 +1301,10 @@ gauge@~2.7.1:
strip-ansi "^3.0.1"
wide-align "^1.1.0"
get-stdin@5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398"
getpass@^0.1.1:
version "0.1.6"
resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.6.tgz#283ffd9fc1256840875311c1b60e8c40187110e6"
@@ -1280,7 +1324,7 @@ glob-parent@^2.0.0:
dependencies:
is-glob "^2.0.0"
glob@^7.0.5:
glob@^7.0.5, glob@7.1.1:
version "7.1.1"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8"
dependencies:
@@ -1533,6 +1577,22 @@ isstream@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
jest-matcher-utils@^19.0.0:
version "19.0.0"
resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-19.0.0.tgz#5ecd9b63565d2b001f61fbf7ec4c7f537964564d"
dependencies:
chalk "^1.1.3"
pretty-format "^19.0.0"
jest-validate@19.0.0:
version "19.0.0"
resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-19.0.0.tgz#8c6318a20ecfeaba0ba5378bfbb8277abded4173"
dependencies:
chalk "^1.1.1"
jest-matcher-utils "^19.0.0"
leven "^2.0.0"
pretty-format "^19.0.0"
jodid25519@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/jodid25519/-/jodid25519-1.0.2.tgz#06d4912255093419477d425633606e0e90782967"
@@ -1600,6 +1660,10 @@ lazy-cache@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e"
leven@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580"
loader-utils@^0.2.11, loader-utils@^0.2.16:
version "0.2.17"
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348"
@@ -1691,7 +1755,7 @@ minimatch@^3.0.0, minimatch@^3.0.2:
dependencies:
brace-expansion "^1.0.0"
minimist@^1.2.0:
minimist@^1.2.0, minimist@>=0.2.0, minimist@1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
@@ -1930,6 +1994,27 @@ preserve@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"
prettier:
version "0.22.0"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-0.22.0.tgz#7b37c4480d0858180407e5a8e13f0f47da7385d2"
dependencies:
ast-types "0.9.4"
babel-code-frame "6.22.0"
babylon "6.15.0"
chalk "1.1.3"
esutils "2.0.2"
flow-parser "0.40.0"
get-stdin "5.0.1"
glob "7.1.1"
jest-validate "19.0.0"
minimist "1.2.0"
pretty-format@^19.0.0:
version "19.0.0"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-19.0.0.tgz#56530d32acb98a3fa4851c4e2b9d37b420684c84"
dependencies:
ansi-styles "^3.0.0"
private@^0.1.6:
version "0.1.7"
resolved "https://registry.yarnpkg.com/private/-/private-0.1.7.tgz#68ce5e8a1ef0a23bb570cc28537b5332aba63ef1"