Skip to content

Commit f476a82

Browse files
authored
Merge pull request #352 from mapbox/develop
develop-master rebase
2 parents e40ef15 + 161992c commit f476a82

19 files changed

+5170
-2323
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
Log of changes since the 2.0 version
44

5+
### Next release
6+
7+
- Add Mapping Team filters
8+
- Show some details we have on the database about deleted users
9+
10+
511
### 0.54.1
612

713
- Fix error in trusted-users page link

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "osmcha-frontend",
3-
"version": "0.56.2",
3+
"version": "0.56.3",
44
"license": "ISC",
55
"engines": {
66
"node": ">=7.0"

src/app.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import { User } from './views/user';
1818
import { SavedFilters } from './views/saved_filters';
1919
import { TrustedUsers } from './views/trusted_users';
2020
import { Watchlist } from './views/watchlist';
21+
import { MappingTeams } from './views/teams';
22+
import { EditMappingTeam } from './views/edit_team';
2123

2224
import { gaPageView } from './utils/analytics';
2325
import { getSearchObj } from './utils/query_params';
@@ -79,6 +81,8 @@ export class App extends Component {
7981
<Route path="/about" component={About} />
8082
<Route path="/stats" component={Stats} />
8183
<Route path="/user" component={User} />
84+
<Route path="/teams" component={MappingTeams} />
85+
<Route path="/team/:id" component={EditMappingTeam} />
8286
<Route path="/saved-filters" component={SavedFilters} />
8387
<Route path="/trusted-users" component={TrustedUsers} />
8488
<Route path="/watchlist" component={Watchlist} />
@@ -108,6 +112,12 @@ export class App extends Component {
108112
<Route path="/about" component={About} />
109113
<Route path="/stats" component={Stats} />
110114
<Route path="/filters" component={Filters} />
115+
<Route path="/user" component={User} />
116+
<Route path="/saved-filters" component={SavedFilters} />
117+
<Route path="/trusted-users" component={TrustedUsers} />
118+
<Route path="/watchlist" component={Watchlist} />
119+
<Route path="/teams" component={MappingTeams} />
120+
<Route path={'/team/:id'} component={EditMappingTeam} />
111121
</div>
112122
<Modal />
113123
</div>

src/components/changeset/index.js

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -130,18 +130,43 @@ export class _Changeset extends React.PureComponent<*, propsType, *> {
130130
</Box>
131131
)}
132132
{bindingsState.get(CHANGESET_DETAILS_USER.label) && (
133-
<Box key={0} className=" responsive-box round-tr round-br">
133+
<Box key={0} className="responsive-box round-tr round-br">
134134
<User
135135
userDetails={
136136
data.getIn(['userDetails', 'name'])
137137
? data.getIn(['userDetails'], Map())
138-
: Map(this.state.userDetails)
138+
: Map([
139+
[
140+
'uid',
141+
this.props.currentChangeset.getIn(['properties', 'uid'])
142+
],
143+
[
144+
'name',
145+
this.props.currentChangeset.getIn([
146+
'properties',
147+
'user'
148+
])
149+
],
150+
[
151+
'harmful_changesets',
152+
data.getIn(['userDetails', 'harmful_changesets'])
153+
],
154+
[
155+
'checked_changesets',
156+
data.getIn(['userDetails', 'checked_changesets'])
157+
],
158+
[
159+
'changesets_in_osmcha',
160+
data.getIn(['userDetails', 'changesets_in_osmcha'])
161+
]
162+
])
139163
}
140164
whosThat={
141165
data.getIn(['userDetails', 'name'])
142166
? data.getIn(['whosThat', 0, 'names'], List())
143167
: this.state.whosThat || List()
144168
}
169+
changesetUsername
145170
/>
146171
</Box>
147172
)}
@@ -195,12 +220,7 @@ export class _Changeset extends React.PureComponent<*, propsType, *> {
195220
bindingsState={bindingsState}
196221
discussions={data && data.getIn(['osmComments'], List())}
197222
/>
198-
<Floater
199-
style={{
200-
marginTop: 5,
201-
marginLeft: 41
202-
}}
203-
>
223+
<Floater style={{ marginTop: 5, marginLeft: 41 }}>
204224
{this.showFloaters()}
205225
</Floater>
206226
</div>

src/components/changeset/user.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,15 @@ export class User extends React.PureComponent {
3636
</div>
3737
<div>
3838
<p className="txt-s color-gray align-center">
39-
Joined{' '}
40-
{moment(this.props.userDetails.get('accountCreated')).fromNow(
41-
true
42-
)}{' '}
43-
ago | {this.props.userDetails.get('count')} edits
39+
{this.props.userDetails.get('accountCreated') &&
40+
`Joined ${moment(
41+
this.props.userDetails.get('accountCreated')
42+
).fromNow(true)} ago |`}
43+
{this.props.userDetails.get('count')
44+
? `${this.props.userDetails.get('count')} edits`
45+
: `${this.props.userDetails.get(
46+
'changesets_in_osmcha'
47+
)} edits registered on OSMCha`}
4448
</p>
4549
</div>
4650
<div>

src/components/filters/filters_list.js

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import moment from 'moment';
55
import {
66
Text,
77
Radio,
8+
MappingTeamMultiSelect,
89
MultiSelect,
910
Wrapper,
1011
Meta,
@@ -182,14 +183,25 @@ class FiltersList extends React.PureComponent<void, propsType, *> {
182183
hasValue={this.props.filters.has(name)}
183184
description={this.props.active === f.name && f.description}
184185
>
185-
<MultiSelect
186-
{...propsToSend}
187-
name={name}
188-
value={value}
189-
onChange={onChange}
190-
showAllToggle={f.all}
191-
token={this.props.token}
192-
/>
186+
{name.endsWith('_teams') ? (
187+
<MappingTeamMultiSelect
188+
{...propsToSend}
189+
name={name}
190+
value={value}
191+
onChange={onChange}
192+
showAllToggle={f.all}
193+
token={this.props.token}
194+
/>
195+
) : (
196+
<MultiSelect
197+
{...propsToSend}
198+
name={name}
199+
value={value}
200+
onChange={onChange}
201+
showAllToggle={f.all}
202+
token={this.props.token}
203+
/>
204+
)}
193205
</Wrapper>
194206
);
195207
}
@@ -238,17 +250,17 @@ class FiltersList extends React.PureComponent<void, propsType, *> {
238250
<span className="flex-child flex-child--grow wmin420 wmax435" />
239251

240252
<h2 className="txt-xl mr6 txt-bold mt30 border-b border--gray-light border--1">
241-
Users
253+
Users & Teams
242254
</h2>
243255
{filtersData
244-
.slice(11, 14)
256+
.slice(11, 17)
245257
.map((f: Object, k) => this.renderFilters(f, k))}
246258
<span className="flex-child flex-child--grow wmin420 wmax435" />
247259

248260
<h2 className="txt-xl mr6 txt-bold mt30 border-b border--gray-light border--1">
249261
Changeset Details
250262
</h2>
251-
{filtersData.slice(14).map((f: Object, k) => this.renderFilters(f, k))}
263+
{filtersData.slice(17).map((f: Object, k) => this.renderFilters(f, k))}
252264
<span className="flex-child flex-child--grow wmin420 wmax435" />
253265
</div>
254266
);

src/components/filters/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Map, List } from 'immutable';
33
export { Radio } from './radio';
44
export { Text } from './text';
55
export { MultiSelect } from './multi_select';
6+
export { MappingTeamMultiSelect } from './multi_select';
67
export { LocationSelect } from './location';
78
export { Wrapper } from './wrapper';
89
export { Meta } from './meta';

src/components/filters/multi_select.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,34 @@ export class MultiSelect extends React.PureComponent {
126126
);
127127
}
128128
}
129+
130+
export class MappingTeamMultiSelect extends MultiSelect {
131+
getAsyncOptions = () => {
132+
if (!this.props.dataURL) return;
133+
return fetch(`${API_URL}/${this.props.dataURL}/?trusted=true`, {
134+
method: 'GET',
135+
headers: {
136+
'Content-Type': 'application/json',
137+
Authorization: this.props.token ? `Token ${this.props.token}` : ''
138+
}
139+
})
140+
.then(response => {
141+
return response.json();
142+
})
143+
.then(json => {
144+
const data = json.map(d => ({ ...d, label: d.name, value: d.name }));
145+
return { options: data };
146+
});
147+
};
148+
sendData = (allToggle: boolean, data: Array<Object>) => {
149+
let name =
150+
this.props.name.slice(0, 4) === 'all_'
151+
? this.props.name.slice(4)
152+
: this.props.name;
153+
154+
name = `${allToggle ? 'all_' : ''}${name}`;
155+
if (data.length === 0) return this.props.onChange(name);
156+
var processed = data.map(o => ({ label: o.label, value: o.value })); // remove any bogus keys
157+
this.props.onChange(name, fromJS(processed));
158+
};
159+
}

src/components/user/mapping_team.js

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import React from 'react';
2+
import { connect } from 'react-redux';
3+
import { Map } from 'immutable';
4+
5+
import { Button } from '../button';
6+
import { applyUpdateUserDetails } from '../../store/auth_actions';
7+
import type { RootStateType } from '../../store';
8+
import thumbsUp from '../../assets/thumbs-up.svg';
9+
import thumbsDown from '../../assets/thumbs-down.svg';
10+
11+
class EditUserDetails extends React.PureComponent {
12+
constructor(props) {
13+
super(props);
14+
this.state = {
15+
message_good: props.userDetails.get('message_good'),
16+
message_bad: props.userDetails.get('message_bad'),
17+
comment_feature: props.userDetails.get('comment_feature')
18+
};
19+
}
20+
componentWillReceiveProps(nextProps) {
21+
this.setState({ message_good: nextProps.userDetails.get('message_good') });
22+
this.setState({ message_bad: nextProps.userDetails.get('message_bad') });
23+
this.setState({
24+
comment_feature: nextProps.userDetails.get('comment_feature')
25+
});
26+
}
27+
onChangeMessageGood = (event: any) => {
28+
this.setState({ message_good: event.target.value });
29+
};
30+
onChangeMessageBad = (event: any) => {
31+
this.setState({ message_bad: event.target.value });
32+
};
33+
handleSubmit = event => {
34+
this.props.applyUpdateUserDetails(
35+
this.state.message_good,
36+
this.state.message_bad,
37+
this.state.comment_feature
38+
);
39+
};
40+
renderGoodBadImg(isGood) {
41+
return (
42+
<img
43+
src={isGood ? thumbsUp : thumbsDown}
44+
alt={`${isGood ? 'good' : 'bad'}`}
45+
className="icon inline-block mt3"
46+
/>
47+
);
48+
}
49+
50+
render() {
51+
return (
52+
<div>
53+
<span className="ml12 flex-parent flex-parent--row my3">
54+
<p className="flex-child txt-s">
55+
Default comment for changesets reviewed as GOOD{' '}
56+
{this.renderGoodBadImg(true)}:
57+
</p>
58+
</span>
59+
<textarea
60+
placeholder="Define a default message to the changesets you review as good. You can edit it before post a comment."
61+
className="textarea ml12"
62+
value={this.state.message_good}
63+
onChange={this.onChangeMessageGood}
64+
/>
65+
<span className="ml12 flex-parent flex-parent--row my3 pt6">
66+
<p className="flex-child txt-s">
67+
Default comment for changesets reviewed as BAD{' '}
68+
{this.renderGoodBadImg()}:
69+
</p>
70+
</span>
71+
<textarea
72+
placeholder="Define a default message to the changesets you review as bad. You can edit it before post a comment."
73+
className="textarea ml12"
74+
value={this.state.message_bad}
75+
onChange={this.onChangeMessageBad}
76+
/>
77+
<Button className="input wmax180 ml12 mt6" onClick={this.handleSubmit}>
78+
Save Preferences
79+
</Button>
80+
</div>
81+
);
82+
}
83+
}
84+
EditUserDetails = connect(
85+
(state: RootStateType, props) => ({
86+
userDetails: state.auth.getIn(['userDetails'], Map())
87+
}),
88+
{
89+
applyUpdateUserDetails
90+
}
91+
)(EditUserDetails);
92+
93+
export { EditUserDetails };

src/config/constants.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import { API_URL } from './';
33

44
export const PAGE_SIZE = 75;
5-
export const overpassBase = '//overpass.maptime.in/api/interpreter';
5+
export const overpassBase = '//overpass-api.de/api/interpreter';
66
export const osmBase = '//www.openstreetmap.org/api/0.6/';
77
export const mapboxAccessToken =
88
'pk.eyJ1Ijoib3BlbnN0cmVldG1hcCIsImEiOiJjam10OXpmc2YwMXI5M3BqeTRiMDBqMHVyIn0.LIcIDe3TZLSDdTWDoojzNg';

src/config/filters.json

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@
180180
"display": "Users",
181181
"cache": true,
182182
"type": "text_comma",
183-
"description": "Show changesets created by the users. Start typing to select one or more users. This filter requires authentication to work.",
183+
"description": "Show changesets created by the users. Start typing to select one or more users.",
184184
"placeholder": "Enter OSM usernames"
185185
},
186186
{
@@ -223,6 +223,48 @@
223223
"description": "If Yes, it will Filter changesets created by users that you added to your Watchlist.",
224224
"placeholder": "Filter changesets created by users from your Watchlist"
225225
},
226+
{
227+
"name": "mapping_teams",
228+
"icontains": false,
229+
"all": false,
230+
"range": false,
231+
"display": "Mapping teams",
232+
"data_url": "mapping-team",
233+
"type": "text_comma",
234+
"description": "Show changesets created by users that are part of a Mapping Team. Start typing to select one or more teams.",
235+
"placeholder": "Enter mapping teams"
236+
},
237+
{
238+
"name": "exclude_teams",
239+
"icontains": false,
240+
"all": false,
241+
"range": false,
242+
"display": "Hide mapping teams",
243+
"data_url": "mapping-team",
244+
"type": "text_comma",
245+
"description": "Exclude changesets created by users that are part of a Mapping Team. Start typing to select one or more teams.",
246+
"placeholder": "Enter mapping teams"
247+
},
248+
{
249+
"name": "exclude_trusted_teams",
250+
"icontains": false,
251+
"range": false,
252+
"all": false,
253+
"display": "Hide trusted mapping teams",
254+
"type": "radio",
255+
"options": [
256+
{
257+
"label": "Yes",
258+
"value": "True"
259+
},
260+
{
261+
"label": "No",
262+
"value": "False"
263+
}
264+
],
265+
"description": "If Yes, it will exclude the changesets created by users that are part of trusted mapping teams",
266+
"placeholder": "Exclude changesets created by users from trusted teams"
267+
},
226268
{
227269
"name": "create",
228270
"icontains": false,

0 commit comments

Comments
 (0)