Skip to content

Commit 388647c

Browse files
committed
feat(gtfs-transform): add feed transformation settings
re #544
1 parent 82e1adb commit 388647c

File tree

8 files changed

+692
-187
lines changed

8 files changed

+692
-187
lines changed

gtfs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,7 @@
776776

777777
- id: scheduleexception
778778
name: (none)
779+
datatools: true
779780
helpContent: Conveyal-specific table for classifying schedule exceptions.
780781
fields:
781782
- name: name

lib/common/constants/index.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
// @flow
2+
3+
import type {RetrievalMethod} from '../../types'
4+
25
const SECURE: string = 'secure/'
36
export const API_PREFIX: string = `/api/manager/`
47
export const SECURE_API_PREFIX: string = `${API_PREFIX}${SECURE}`
@@ -9,3 +12,12 @@ export const DEFAULT_DESCRIPTION = 'A command center for managing, editing, vali
912
export const DEFAULT_LOGO = 'https://d2tyb7byn1fef9.cloudfront.net/ibi_group_black-512x512.png'
1013
export const DEFAULT_LOGO_SMALL = 'https://d2tyb7byn1fef9.cloudfront.net/ibi_group-128x128.png'
1114
export const DEFAULT_TITLE = 'Data Tools'
15+
16+
export const RETRIEVAL_METHODS: Array<RetrievalMethod> = [
17+
'MANUALLY_UPLOADED',
18+
'FETCHED_AUTOMATICALLY',
19+
'PRODUCED_IN_HOUSE',
20+
'SERVICE_PERIOD_MERGE',
21+
'REGIONAL_MERGE',
22+
'VERSION_CLONE'
23+
]

lib/manager/components/FeedSourceSettings.js

Lines changed: 36 additions & 177 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
// @flow
22

3-
import Icon from '@conveyal/woonerf/components/icon'
43
import 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'
611
import {LinkContainer} from 'react-router-bootstrap'
712

813
import * as feedsActions from '../actions/feeds'
914
import toSentenceCase from '../../common/util/to-sentence-case'
1015
import ExternalPropertiesTable from './ExternalPropertiesTable'
16+
import FeedTransformationSettings from './FeedTransformationSettings'
17+
import GeneralSettings from './GeneralSettings'
1118

1219
import type {Feed, Project} from '../../types'
1320
import 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

Comments
 (0)