@@ -5,20 +5,26 @@ import PropTypes from 'prop-types';
5
5
import { propsDiff } from './propsDiff' ;
6
6
import { Dropdown } from './dropdown' ;
7
7
import { cmap } from './render' ;
8
+ import { config } from './config' ;
8
9
9
10
//Calculates the difference in the selected features
10
11
11
12
export const displayDiff = function (
12
13
id ,
13
14
featureMap ,
15
+ changesetId ,
14
16
metadataContainer ,
15
17
tagsContainer ,
16
18
membersContainer
17
19
) {
18
20
var featuresWithId = featureMap [ id ] ;
19
21
20
22
reactDOM (
21
- < MetadataTable featuresWithId = { featuresWithId } id = { id } /> ,
23
+ < MetadataTable
24
+ featuresWithId = { featuresWithId }
25
+ id = { id }
26
+ changesetId = { changesetId }
27
+ /> ,
22
28
metadataContainer
23
29
) ;
24
30
reactDOM ( < TagsTable featuresWithId = { featuresWithId } /> , tagsContainer ) ;
@@ -31,7 +37,76 @@ export const displayDiff = function(
31
37
}
32
38
} ;
33
39
34
- const MetadataTable = function ( { featuresWithId, id } ) {
40
+ class FlagButton extends React . PureComponent {
41
+ constructor ( props ) {
42
+ super ( props ) ;
43
+ this . state = {
44
+ flagState : null
45
+ } ;
46
+ }
47
+ flagAsBad ( ) {
48
+ fetch (
49
+ `${ config . osmchaBase } api/v1/changesets/${ this . props . changesetId } /review-feature/${ this . props . type } -${ this . props . id } /` ,
50
+ {
51
+ method : 'PUT' ,
52
+ headers : {
53
+ 'Content-Type' : 'application/json' ,
54
+ Authorization : `Token ${ this . props . token } `
55
+ }
56
+ }
57
+ )
58
+ . then ( ( ) => this . setState ( { flagState : 'success' } ) )
59
+ . catch ( ( ) => this . setState ( { flagState : 'error' } ) ) ;
60
+ }
61
+
62
+ removeFlag ( ) {
63
+ fetch (
64
+ `${ config . osmchaBase } api/v1/changesets/${ this . props . changesetId } /review-feature/${ this . props . type } -${ this . props . id } /` ,
65
+ {
66
+ method : 'DELETE' ,
67
+ headers : {
68
+ 'Content-Type' : 'application/json' ,
69
+ Authorization : `Token ${ this . props . token } `
70
+ }
71
+ }
72
+ ) . then ( ( ) => this . setState ( { flagState : null } ) ) ;
73
+ }
74
+
75
+ render ( ) {
76
+ return (
77
+ < span >
78
+ { this . state . flagState === null && (
79
+ < button
80
+ className = "cmap-btn cmap-noselect cmap-pointer cmap-c-link-osm"
81
+ onClick = { ( ) => this . flagAsBad ( ) }
82
+ >
83
+ Add to flagged
84
+ </ button >
85
+ ) }
86
+ { this . state . flagState === 'success' && (
87
+ < button
88
+ className = "cmap-btn cmap-noselect cmap-pointer cmap-c-link-osm b--red bg-white"
89
+ onClick = { ( ) => this . removeFlag ( ) }
90
+ >
91
+ < ThumbsDownIcon style = { { verticalAlign : 'middle' } } />
92
+ < span className = "pl6" > Flagged</ span >
93
+ < i className = "gg-close" > </ i >
94
+ </ button >
95
+ ) }
96
+ { this . state . flagState === 'error' && < span > Failed</ span > }
97
+ </ span >
98
+ ) ;
99
+ }
100
+ }
101
+
102
+ FlagButton . propTypes = {
103
+ id : PropTypes . string . isRequired ,
104
+ type : PropTypes . string . isRequired ,
105
+ token : PropTypes . string . isRequired ,
106
+ changesetId : PropTypes . number . isRequired
107
+ } ;
108
+
109
+ const MetadataTable = function ( { featuresWithId, id, changesetId } ) {
35
110
const type = featuresWithId [ 0 ] . properties . type ;
36
111
const metadataProps = featuresWithId . map ( function ( f ) {
37
112
var filteredProps = Object . assign ( { } , f . properties ) ;
@@ -41,13 +116,16 @@ const MetadataTable = function({ featuresWithId, id }) {
41
116
delete filteredProps . action ;
42
117
return filteredProps ;
43
118
} ) ;
119
+ const token = localStorage . getItem ( 'token' ) ;
44
120
45
121
const metadataHeader = (
46
122
< div className = "cmap-space-between" >
47
- < span >
48
- { type . toUpperCase ( ) } : { id }
49
- </ span >
50
- < span >
123
+ < div className = "cmap-block" >
124
+ < span >
125
+ { type . toUpperCase ( ) } : { id }
126
+ </ span >
127
+ </ div >
128
+ < div id = "cmap-feature-btns" >
51
129
< Dropdown
52
130
display = "History"
53
131
options = { [
@@ -90,7 +168,15 @@ const MetadataTable = function({ featuresWithId, id }) {
90
168
}
91
169
] }
92
170
/>
93
- </ span >
171
+ { token && (
172
+ < FlagButton
173
+ token = { token }
174
+ type = { type }
175
+ id = { id }
176
+ changesetId = { changesetId }
177
+ />
178
+ ) }
179
+ </ div >
94
180
</ div >
95
181
) ;
96
182
return (
@@ -103,7 +189,8 @@ const MetadataTable = function({ featuresWithId, id }) {
103
189
} ;
104
190
MetadataTable . propTypes = {
105
191
featuresWithId : PropTypes . array . isRequired ,
106
- id : PropTypes . string . isRequired
192
+ id : PropTypes . string . isRequired ,
193
+ changesetId : PropTypes . number . isRequired
107
194
} ;
108
195
109
196
const TagsTable = function ( { featuresWithId } ) {
@@ -293,7 +380,7 @@ const DiffColumn = function({ diff, prop, type, propClass }) {
293
380
target = "_blank"
294
381
rel = "noopener noreferrer"
295
382
className = "cmap-changeset-link"
296
- href = { `//osmcha.org/ changesets/${ diff [ prop ] [ type ] } ` }
383
+ href = { `${ config . osmchaBase } changesets/${ diff [ prop ] [ type ] } ` }
297
384
>
298
385
{ diff [ prop ] [ type ] }
299
386
</ a >
@@ -309,3 +396,37 @@ DiffColumn.propTypes = {
309
396
type : PropTypes . string . isRequired ,
310
397
propClass : PropTypes . string
311
398
} ;
399
+
400
+ const ThumbsDownIcon = props => (
401
+ < svg width = "14px" height = "14px" viewBox = "0 0 100 99" { ...props } >
402
+ < g
403
+ id = "Symbols"
404
+ stroke = "none"
405
+ strokeWidth = "1"
406
+ fill = "none"
407
+ fillRule = "evenodd"
408
+ >
409
+ < g id = "icons/Thumbs-down-trans" fill = "#CC2C47" >
410
+ < g
411
+ id = "Thumbs-up"
412
+ transform = "translate(50.000000, 49.500000) rotate(-180.000000) translate(-50.000000, -49.500000) "
413
+ >
414
+ < path
415
+ d = "M41.8167977,42 L8.65058811,42 L8.65058811,42 C8.15292909,42 7.65635568,42.0464369 7.16732524,42.1387068 C2.82565287,42.9578902 -0.0298885833,47.1415905 0.789294882,51.4832629 L7.77042696,88.4832629 C8.483559,92.2628627 11.7854321,95 15.6317202,95 L15.6317202,95 L92,95 C96.418278,95 100,91.418278 100,87 L100,87 L100,50 C100,45.581722 96.418278,42 92,42 L64.8136835,42 C64.848108,41.339148 64.8257549,40.6662103 64.7423209,39.9866948 L61.0862406,10.2103103 C60.3122149,3.90637709 54.5743956,-0.576498687 48.2704624,0.197526982 L48.2704624,0.197526982 L48.2704624,0.197526982 C41.9665292,0.97155265 37.4836534,6.70937199 38.2576791,13.0133052 L38.2576791,13.0133052 L41.8167977,42 Z"
416
+ id = "Combined-Shape"
417
+ fillOpacity = "0.3"
418
+ > </ path >
419
+ < rect
420
+ id = "Rectangle-7"
421
+ fillOpacity = "0.9"
422
+ x = "76"
423
+ y = "37"
424
+ width = "24"
425
+ height = "62"
426
+ rx = "8"
427
+ > </ rect >
428
+ </ g >
429
+ </ g >
430
+ </ g >
431
+ </ svg >
432
+ ) ;
0 commit comments