11// @flow
22
3- import Icon from '@conveyal/woonerf/components/icon'
43import React , { Component } from 'react'
5- import { Col , Row , ListGroup , ListGroupItem , Button , Panel , FormControl , InputGroup , ControlLabel , FormGroup , Checkbox } from 'react-bootstrap'
4+ import {
5+ Col ,
6+ ListGroup ,
7+ ListGroupItem ,
8+ Panel ,
9+ Row
10+ } from 'react-bootstrap'
611import { LinkContainer } from 'react-router-bootstrap'
712
813import * as feedsActions from '../actions/feeds'
914import toSentenceCase from '../../common/util/to-sentence-case'
1015import ExternalPropertiesTable from './ExternalPropertiesTable'
16+ import FeedTransformationSettings from './FeedTransformationSettings'
17+ import GeneralSettings from './GeneralSettings'
1118
1219import type { Feed , Project } from '../../types'
1320import type { ManagerUserState } from '../../types/reducers'
@@ -23,85 +30,24 @@ type Props = {
2330 user : ManagerUserState
2431}
2532
26- type State = {
27- name ?: ?string ,
28- url ?: ?string
29- }
30-
31- export default class FeedSourceSettings extends Component < Props , State > {
32- state = { }
33-
34- _onChange = ( { target} : SyntheticInputEvent < HTMLInputElement > ) => {
35- // Change empty string to null to avoid setting URL to empty string value.
36- const value = target . value === '' ? null : target . value . trim ( )
37- this . setState ( { [ target . name ] : value } )
38- }
39-
40- _onToggleDeployable = ( ) => {
41- const { feedSource, updateFeedSource} = this . props
42- updateFeedSource ( feedSource , { deployable : ! feedSource . deployable } )
43- }
44-
45- _getFormValue = ( key : 'name' | 'url' ) => {
46- // If state value does not exist (i.e., form is unedited), revert to value
47- // from props.
48- const value = typeof this . state [ key ] === 'undefined'
49- ? this . props . feedSource [ key ]
50- : this . state [ key ]
51- // Revert to empty string to avoid console error with null value for form.
52- return value || ''
53- }
54-
55- _onToggleAutoFetch = ( ) => {
56- const { feedSource, updateFeedSource} = this . props
57- const value = feedSource . retrievalMethod === 'FETCHED_AUTOMATICALLY'
58- ? 'MANUALLY_UPLOADED'
59- : 'FETCHED_AUTOMATICALLY'
60- updateFeedSource ( feedSource , { retrievalMethod : value } )
61- }
62-
63- _onTogglePublic = ( ) => {
64- const { feedSource, updateFeedSource} = this . props
65- updateFeedSource ( feedSource , { isPublic : ! feedSource . isPublic } )
66- }
67-
68- _onNameChanged = ( evt : SyntheticInputEvent < HTMLInputElement > ) => {
69- this . setState ( { name : evt . target . value } )
70- }
71-
72- _onNameSaved = ( ) => {
73- const { feedSource, updateFeedSource} = this . props
74- updateFeedSource ( feedSource , { name : this . state . name } )
75- }
76-
77- _onSaveUrl = ( ) => {
78- const { feedSource, updateFeedSource} = this . props
79- updateFeedSource ( feedSource , { url : this . state . url } )
80- }
81-
33+ export default class FeedSourceSettings extends Component < Props > {
8234 render ( ) {
8335 const {
8436 activeComponent,
8537 activeSubComponent,
86- confirmDeleteFeedSource,
8738 updateExternalFeedResource,
8839 feedSource,
8940 project,
9041 user
9142 } = this . props
92- const {
93- name ,
94- url
95- } = this . state
9643 const disabled = user . permissions && ! user . permissions . hasFeedPermission (
9744 project . organizationId , project . id , feedSource . id , 'manage-feed'
9845 )
9946 const isProjectAdmin = user . permissions && user . permissions . isProjectAdmin (
10047 project . id , project . organizationId
10148 )
102- // const editGtfsDisabled = !user.permissions.hasFeedPermission(project.organizationId, project.id, feedSource.id, 'edit-gtfs')
103- const autoFetchFeed = feedSource . retrievalMethod === 'FETCHED_AUTOMATICALLY'
10449 const resourceType = activeComponent === 'settings' && activeSubComponent && activeSubComponent . toUpperCase ( )
50+ const showTransformationsTab = resourceType === 'TRANSFORMATIONS'
10551 if ( disabled ) {
10652 return (
10753 < Row >
@@ -122,6 +68,11 @@ export default class FeedSourceSettings extends Component<Props, State> {
12268 active = { ! activeSubComponent } >
12369 < ListGroupItem > General</ ListGroupItem >
12470 </ LinkContainer >
71+ < LinkContainer
72+ to = { `/feed/${ feedSource . id } /settings/transformations` }
73+ active = { showTransformationsTab } >
74+ < ListGroupItem > Feed Transformations</ ListGroupItem >
75+ </ LinkContainer >
12576 { Object . keys ( feedSource . externalProperties || { } ) . map ( resourceType => {
12677 const resourceLowerCase = resourceType . toLowerCase ( )
12778 return (
@@ -138,118 +89,26 @@ export default class FeedSourceSettings extends Component<Props, State> {
13889 </ Col >
13990 < Col xs = { 6 } />
14091 { ! resourceType
141- ? < Col xs = { 7 } >
142- { /* Settings */ }
143- < Panel header = { < h3 > Settings</ h3 > } >
144- < ListGroup fill >
145- < ListGroupItem >
146- < FormGroup >
147- < ControlLabel > Feed source name</ ControlLabel >
148- < InputGroup >
149- < FormControl
150- value = { this . _getFormValue ( 'name' ) }
151- name = { 'name' }
152- disabled = { disabled }
153- onChange = { this . _onChange } />
154- < InputGroup . Button >
155- < Button
156- // disable if no change or no value (name is required).
157- disabled = { disabled || ! name || name === feedSource . name }
158- onClick = { this . _onNameSaved } >
159- Rename
160- </ Button >
161- </ InputGroup . Button >
162- </ InputGroup >
163- </ FormGroup >
164- </ ListGroupItem >
165- < ListGroupItem >
166- < FormGroup >
167- < Checkbox
168- checked = { feedSource . deployable }
169- data-test-id = 'make-feed-source-deployable-button'
170- onChange = { this . _onToggleDeployable } >
171- < strong > Make feed source deployable</ strong >
172- </ Checkbox >
173- < small > Enable this feed source to be deployed to an OpenTripPlanner (OTP) instance (defined in organization settings) as part of a collection of feed sources or individually.</ small >
174- </ FormGroup >
175- </ ListGroupItem >
176- </ ListGroup >
177- </ Panel >
178- < Panel header = { < h3 > Automatic fetch</ h3 > } >
179- < ListGroup fill >
180- < ListGroupItem >
181- < FormGroup >
182- < ControlLabel > Feed source fetch URL</ ControlLabel >
183- < InputGroup data-test-id = 'feed-source-url-input-group' >
184- < FormControl
185- disabled = { disabled }
186- name = { 'url' }
187- onChange = { this . _onChange }
188- value = { this . _getFormValue ( 'url' ) }
189- />
190- < InputGroup . Button >
191- < Button
192- // Disable if no change or field has not been edited.
193- disabled = { disabled || typeof url === 'undefined' || url === feedSource . url }
194- onClick = { this . _onSaveUrl } >
195- Change URL
196- </ Button >
197- </ InputGroup . Button >
198- </ InputGroup >
199- </ FormGroup >
200- </ ListGroupItem >
201- < ListGroupItem >
202- < FormGroup >
203- < Checkbox
204- checked = { autoFetchFeed }
205- disabled = { disabled }
206- onChange = { this . _onToggleAutoFetch }
207- bsStyle = 'danger' >
208- < strong > Auto fetch feed source</ strong >
209- </ Checkbox >
210- < small > Set this feed source to fetch automatically. (Feed source URL must be specified and project auto fetch must be enabled.)</ small >
211- </ FormGroup >
212- </ ListGroupItem >
213- </ ListGroup >
214- </ Panel >
215- < Panel bsStyle = 'danger' header = { < h3 > Danger zone</ h3 > } >
216- < ListGroup fill >
217- < ListGroupItem >
218- < Button
219- onClick = { this . _onTogglePublic }
220- disabled = { disabled }
221- className = 'pull-right' >
222- Make { feedSource . isPublic ? 'private' : 'public' }
223- </ Button >
224- < h4 > Make this feed source { feedSource . isPublic ? 'private' : 'public' } .</ h4 >
225- < p > This feed source is currently { feedSource . isPublic ? 'public' : 'private' } .</ p >
226- </ ListGroupItem >
227- < ListGroupItem >
228- < Button
229- onClick = { confirmDeleteFeedSource }
230- className = 'pull-right'
231- disabled = { disabled }
232- bsStyle = 'danger' >
233- < Icon type = 'trash' /> Delete feed source
234- </ Button >
235- < h4 > Delete this feed source.</ h4 >
236- < p > Once you delete a feed source, it cannot be recovered.</ p >
237- </ ListGroupItem >
238- </ ListGroup >
239- </ Panel >
240- </ Col >
241- : < Col xs = { 7 } >
242- < ExternalPropertiesTable
243- resourceType = { resourceType }
244- feedSource = { feedSource }
245- editingIsDisabled = { disabled }
246- isProjectAdmin = { isProjectAdmin }
247- resourceProps = { feedSource . externalProperties
248- ? feedSource . externalProperties [ resourceType ]
249- : { }
250- }
251- updateExternalFeedResource = { updateExternalFeedResource } />
252- </ Col >
92+ ? < GeneralSettings
93+ // FIXME: Remove props spread.
94+ { ...this . props }
95+ disabled = { disabled }
96+ />
97+ : showTransformationsTab
98+ // FIXME: Remove props spread.
99+ ? < FeedTransformationSettings { ...this . props } />
100+ : < Col xs = { 7 } >
101+ < ExternalPropertiesTable
102+ resourceType = { resourceType }
103+ feedSource = { feedSource }
104+ editingIsDisabled = { disabled }
105+ isProjectAdmin = { isProjectAdmin }
106+ resourceProps = { feedSource . externalProperties
107+ ? feedSource . externalProperties [ resourceType ]
108+ : { }
109+ }
110+ updateExternalFeedResource = { updateExternalFeedResource } />
111+ </ Col >
253112 }
254113 </ Row >
255114 )
0 commit comments