Skip to content

Commit e019f31

Browse files
committed
fix(editor): refactor generic actions and fix feed info
1 parent 38d3417 commit e019f31

File tree

5 files changed

+95
-286
lines changed

5 files changed

+95
-286
lines changed

lib/editor/actions/active.js

Lines changed: 47 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
import clone from 'lodash.clonedeep'
2-
import { browserHistory } from 'react-router'
2+
import {browserHistory} from 'react-router'
33
import {createAction} from 'redux-actions'
44

55
import {ENTITY} from '../constants'
66
import {fetchGTFSEntities} from '../../manager/actions/versions'
7-
import { secureFetch } from '../../common/actions'
8-
import { saveFeedInfo } from './feedInfo'
7+
import {secureFetch} from '../../common/actions'
98
import {saveTripPattern} from './tripPattern'
10-
import { getGtfsTable, createGtfsEntity, fetchBaseGtfs } from './editor'
11-
import { isValidComponent, getEditorNamespace, getTableById, subComponentList, subSubComponentList } from '../util/gtfs'
12-
import { getMapFromGtfsStrategy, entityIsNew } from '../util/objects'
9+
import {newGtfsEntity, fetchBaseGtfs} from './editor'
10+
import {isValidComponent, getEditorNamespace, getTableById, subComponentList, subSubComponentList} from '../util/gtfs'
11+
import {getMapFromGtfsStrategy, entityIsNew} from '../util/objects'
1312

1413
export function updateEditSetting (setting, value, activePattern) {
1514
return {
@@ -20,6 +19,7 @@ export function updateEditSetting (setting, value, activePattern) {
2019
}
2120
}
2221

22+
export const clearGtfsContent = createAction('CLEAR_GTFSEDITOR_CONTENT')
2323
const settingActiveGtfsEntity = createAction('SETTING_ACTIVE_GTFS_ENTITY')
2424

2525
export function enterTimetableEditor () {
@@ -72,19 +72,23 @@ export function setActiveGtfsEntity (feedSourceId, component, entityId, subCompo
7272
// stop editing geometry if currently editing
7373
dispatch(updateEditSetting('editGeometry', false, null))
7474
}
75-
if (entityId === ENTITY.NEW_ID && (!activeTable || activeTable.findIndex(e => e.id === ENTITY.NEW_ID) === -1)) {
76-
// Create new GTFS entity if id is ENTITY.NEW_ID and no ENTITY.NEW_ID entity exists in table
77-
dispatch(createGtfsEntity(feedSourceId, component))
75+
if (
76+
entityId === ENTITY.NEW_ID &&
77+
(!activeTable || activeTable.findIndex(e => e.id === ENTITY.NEW_ID) === -1)
78+
) {
79+
// Create new GTFS entity if id is ENTITY.NEW_ID and no ENTITY.NEW_ID
80+
// entity exists in table
81+
dispatch(newGtfsEntity(feedSourceId, component))
7882
}
7983
const url = constructEditorURL(feedSourceId, component, entityId, subComponent, subEntityId, subSubComponent, subSubEntityId)
8084
const {locationBeforeTransitions} = getState().routing
8185
const pathname = locationBeforeTransitions && locationBeforeTransitions.pathname
8286
if (!locationBeforeTransitions || !pathname || pathname !== url) {
83-
// console.log('updating url', url, pathname, pathItems)
87+
console.log('updating url', url, pathname)
8488
browserHistory.push(url)
8589
}
8690
const activeEntity = component === 'feedinfo'
87-
? clone(activeTable)
91+
? clone(activeTable)[0]
8892
: activeTable && entityId
8993
? clone(activeTable.find(e => e.id === entityId))
9094
: null
@@ -122,35 +126,24 @@ export function setActiveGtfsEntity (feedSourceId, component, entityId, subCompo
122126
subSubComponent,
123127
subSubEntityId
124128
}))
125-
if (activeSubEntity && component === 'route') {
126-
dispatch(setActiveTripPattern(activeSubEntity))
127-
}
128-
}
129-
}
130-
131-
function setActiveTripPattern (pattern) {
132-
return function (dispatch, getState) {
133-
// const {data} = getState().editor
134-
// const stops = getTableById(data.tables, 'stop')
135-
// const patternStops = getStopsForPattern(pattern, stops)
136-
// const activeColumns = getTimetableColumns(pattern, patternStops)
137-
// dispatch(settingActiveTripPattern({pattern, columns, patternStops}))
138129
}
139130
}
140131

141132
function constructEditorURL (feedSourceId, component, entityId, subComponent, subEntityId, subSubComponent, subSubEntityId) {
142-
const pathItems = ['feed', feedSourceId, 'edit', component, entityId, subComponent, subEntityId, subSubComponent, subSubEntityId].filter(item => item)
133+
const pathItems = ['feed', feedSourceId, 'edit', component, entityId, subComponent, subEntityId, subSubComponent, subSubEntityId]
134+
// Filter out any null or undefined items
135+
.filter(item => item)
143136
let url = '/' + pathItems.join('/')
144-
// ensure component is valid
145137
if (component && !isValidComponent(component)) {
138+
// If component is not valid, go to editor root.
146139
console.warn(`"${component}" is not a valid URL component path`)
147140
url = `/feed/${feedSourceId}/edit/`
148141
} else if (subComponent && subComponentList.indexOf(subComponent) === -1) {
149-
// ensure subComponent is valid
142+
// If subComponent is not valid, go to active entity
150143
console.warn(`"${subComponent}" is not a valid URL subComponent path`)
151144
url = `/feed/${feedSourceId}/edit/${component}/${entityId}/`
152145
} else if (subSubComponent && subSubComponentList.indexOf(subSubComponent) === -1) {
153-
// ensure subSubComponent is valid
146+
// If subSubComponent is not valid, go to sub entity
154147
console.warn(`"${subSubComponent}" is not a valid URL subSubComponent path`)
155148
url = `/feed/${feedSourceId}/edit/${component}/${entityId}/${subComponent}/${subEntityId}/`
156149
}
@@ -173,11 +166,6 @@ export function saveActiveGtfsEntity (component, optionalEntity) {
173166
entity = optionalEntity || active.subEntity // route.tripPatterns.find(p => p.id === patternId)
174167
saveStrategy = saveTripPattern
175168
break
176-
// FIXME
177-
case 'feedinfo':
178-
feedId = entity.id || active.feedSourceId
179-
saveStrategy = saveFeedInfo
180-
break
181169
default:
182170
// Default method for agencies, stops, routes, fares, calendars.
183171
// Trip patterns and feed info are handled above. Trips are handled in
@@ -190,6 +178,15 @@ export function saveActiveGtfsEntity (component, optionalEntity) {
190178
}
191179
}
192180

181+
/**
182+
* Generic method for saving an entity using REST endpoint. The only entity
183+
* types with unique save methods are trip patterns and trips (handled in timetable
184+
* actions).
185+
*
186+
* This method determines the URL from entity type (component), maps the entity
187+
* data into the required format (primarily updates fields to snake_case), and
188+
* after performing PUT request re-fetches the entity.
189+
*/
193190
export function saveEntity (feedId, entity, component) {
194191
return function (dispatch, getState) {
195192
const notNew = !entityIsNew(entity)
@@ -201,24 +198,16 @@ export function saveEntity (feedId, entity, component) {
201198
const data = mappingStrategy(entity)
202199
return dispatch(secureFetch(url, method, data))
203200
.then(res => res.json())
204-
.then(e => {
205-
// FIXME: Instead of getting new table, should we receive entity and send
206-
// to reducer? For example:
207-
// dispatch(receiveStop({feedId, stop: newStop}))
208-
// if (stopId === ENTITY.NEW_ID) {
209-
// // Only set active if stop.id === ENTITY.NEW_ID.
210-
// // If id is undefined, do not set active entity
211-
// dispatch(deletingStop(feedId, stop))
212-
// dispatch(setActiveGtfsEntity(feedId, 'stop', `${newStop.id}`))
213-
// }
214-
return dispatch(getGtfsTable(component, feedId))
215-
.then(entities => {
216-
if (entity.id === ENTITY.NEW_ID) {
217-
// If we just created a new entity, update active entity with
218-
// it's server-created id.
219-
return dispatch(setActiveGtfsEntity(feedId, component, e.id))
220-
}
221-
})
201+
.then(savedEntity => {
202+
const namespace = getEditorNamespace(feedId, getState())
203+
// Refetch entity and replace in store
204+
dispatch(fetchGTFSEntities({
205+
namespace,
206+
id: savedEntity.id,
207+
type: component,
208+
editor: true,
209+
replaceNew: !notNew
210+
}))
222211
})
223212
}
224213
}
@@ -231,22 +220,26 @@ export const deletingEntity = createAction('DELETING_ENTITY')
231220
export function deleteGtfsEntity (feedId, component, entityId, routeId) {
232221
return function (dispatch, getState) {
233222
const namespace = getEditorNamespace(feedId, getState())
234-
dispatch(deletingEntity({namespace, feedId, component, entityId}))
223+
dispatch(deletingEntity({namespace, feedId, component, entityId, routeId}))
235224
if (entityId === ENTITY.NEW_ID) {
236225
// Entity is new/unsaved. Overwrite current table with existing entities.
237226
// FIXME: we should just remove the ENTITY.NEW_ID entity from the store. This is a
238227
// waste of network traffic (especially for large feeds)
239228
return dispatch(fetchBaseGtfs({namespace, component}))
240229
}
241-
const entityPath = component === 'trippattern' ? 'pattern' : component
230+
const entityPath = component === 'trippattern'
231+
? 'pattern'
232+
: component === 'fare' ? 'fareattribute' : component
242233
const url = `/api/editor/secure/${entityPath}/${entityId}?feedId=${feedId}`
243234
return dispatch(secureFetch(url, 'delete'))
244235
.then(response => response.json())
245236
.then(json => {
246237
if (component === 'trippattern' && routeId) {
238+
console.log('fetching trip patterns')
247239
// Replace trip patterns for route
248-
dispatch(fetchGTFSEntities({namespace, id: routeId, type: component, editor: true}))
240+
return dispatch(fetchGTFSEntities({namespace, id: routeId, type: 'route', editor: true}))
249241
} else {
242+
console.log('fetching base gtfs')
250243
// Replace entire table
251244
return dispatch(fetchBaseGtfs({namespace, component}))
252245
}
@@ -270,9 +263,3 @@ export function resetActiveGtfsEntity (entity, component) {
270263
component
271264
}
272265
}
273-
274-
export function clearGtfsContent () {
275-
return {
276-
type: 'CLEAR_GTFSEDITOR_CONTENT'
277-
}
278-
}

0 commit comments

Comments
 (0)