-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathFilters.js
126 lines (111 loc) · 4.22 KB
/
Filters.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import React, { PropTypes, Component } from 'react'
import classNames from 'classnames'
import { isRangeFilter, isSelectFilter } from '../utils'
import {
OSM_CITY, OSM_NAME, OSM_LENGTH,
PROP_INSTANCE_OF, DETAILS, PROP_NAMES, PROP_PLACEHOLDERS, PROP_SELECTORS,
} from '../constants'
export default class Filters extends Component {
static propTypes = {
filters: PropTypes.array.isRequired,
data: PropTypes.object,
}
calculateStats (data, streetIds) {
let streetsLength = 0
let cities = {}
for (let streetId of streetIds) {
let street = data.results[streetId]
streetsLength += street.l
cities[street.c] = true
}
return {streetsLength, streetsCount: streetIds.length, citiesCount: Object.keys(cities).length}
}
fullFilters (filters) {
let fullFilters = {}
fullFilters[OSM_CITY] = filters[OSM_CITY]
fullFilters[OSM_NAME] = filters[OSM_NAME]
fullFilters[OSM_LENGTH] = filters[OSM_LENGTH]
fullFilters[PROP_INSTANCE_OF] = filters[PROP_INSTANCE_OF]
for (let filter of DETAILS[filters[PROP_INSTANCE_OF]]) {
fullFilters[filter] = filters[filter]
}
return fullFilters
}
handleChange (filters, filter, index, event) {
const value = event.target.value
if (index === null) {
if (value === '') {
delete filters[filter]
} else {
filters[filter] = value
}
} else {
filters[filter] = filters[filter] || [null, null]
filters[filter][index] = value === '' ? null : value
if (filters[filter][0] === null && filters[filter][1] === null) {
delete filters[filter]
}
}
this.props.updateFilters(filters)
}
renderField (filters, filter, i18n) {
const value = filters[filter]
if (isRangeFilter(filter)) {
return <div className='filter-item'>
<input className='filter-input'
type='text'
placeholder={ i18n.pgettext.apply(i18n, PROP_PLACEHOLDERS[filter][0]) }
value={ value && value[0] }
onChange={ this.handleChange.bind(this, filters, filter, 0) }/>
–
<input className='filter-input'
type='text'
placeholder={ i18n.pgettext.apply(i18n, PROP_PLACEHOLDERS[filter][1]) }
value={ value && value[1] }
onChange={ this.handleChange.bind(this, filters, filter, 1) }/>
</div>
} else if (isSelectFilter(filter)) {
return <select className='filter-item' onChange={ this.handleChange.bind(this, filters, filter, null) }>
{ Object.keys(PROP_SELECTORS[filter]).map(item =>
<option value={ item } selected={ item === value ? 'selected' : '' }>
{ i18n.pgettext.apply(i18n, PROP_SELECTORS[filter][item]) }
</option>)
}
</select>
} else {
return <div className='filter-item'>
<input className='filter-input'
type='text'
placeholder={ i18n.pgettext.apply(i18n, PROP_PLACEHOLDERS[filter]) }
value={ value }
onChange={ this.handleChange.bind(this, filters, filter, null) }/>
</div>
}
}
render () {
const {data, filters, backMap, i18n} = this.props
if (!data) {
return null
}
let stats = this.calculateStats(data, Object.keys(data.results))
let fullFilters = this.fullFilters(filters)
let newFilters = {...filters}
return <div className={ classNames('filters', {'back-map': backMap})}>
<div className='filter-stats'>
{ stats.streetsCount } { i18n.ngettext('street', 'streets', stats.streetsCount) }
{ i18n.gettext('with summary length') }
{ stats.streetsLength } { i18n.ngettext('meter in', 'meters in', stats.streetsLength) }
{ stats.citiesCount } { i18n.npgettext('in', 'city', 'cities', stats.citiesCount) }
</div>
{ Object.keys(fullFilters).map((filter) =>
<div className='filter'>
<h3 className='filter-caption'>{ i18n.pgettext.apply(i18n, PROP_NAMES[filter]) }:</h3>
{ this.renderField(newFilters, filter, i18n) }
</div>
) }
</div>
}
shouldComponentUpdate (nextProps) {
return nextProps.data !== this.props.data || nextProps.filters !== this.props.filters
}
}