Skip to content

Commit

Permalink
fix(editor): refactor generic actions and fix feed info
Browse files Browse the repository at this point in the history
  • Loading branch information
landonreed committed Jan 26, 2018
1 parent 38d3417 commit e019f31
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 286 deletions.
107 changes: 47 additions & 60 deletions lib/editor/actions/active.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import clone from 'lodash.clonedeep'
import { browserHistory } from 'react-router'
import {browserHistory} from 'react-router'
import {createAction} from 'redux-actions'

import {ENTITY} from '../constants'
import {fetchGTFSEntities} from '../../manager/actions/versions'
import { secureFetch } from '../../common/actions'
import { saveFeedInfo } from './feedInfo'
import {secureFetch} from '../../common/actions'
import {saveTripPattern} from './tripPattern'
import { getGtfsTable, createGtfsEntity, fetchBaseGtfs } from './editor'
import { isValidComponent, getEditorNamespace, getTableById, subComponentList, subSubComponentList } from '../util/gtfs'
import { getMapFromGtfsStrategy, entityIsNew } from '../util/objects'
import {newGtfsEntity, fetchBaseGtfs} from './editor'
import {isValidComponent, getEditorNamespace, getTableById, subComponentList, subSubComponentList} from '../util/gtfs'
import {getMapFromGtfsStrategy, entityIsNew} from '../util/objects'

export function updateEditSetting (setting, value, activePattern) {
return {
Expand All @@ -20,6 +19,7 @@ export function updateEditSetting (setting, value, activePattern) {
}
}

export const clearGtfsContent = createAction('CLEAR_GTFSEDITOR_CONTENT')
const settingActiveGtfsEntity = createAction('SETTING_ACTIVE_GTFS_ENTITY')

export function enterTimetableEditor () {
Expand Down Expand Up @@ -72,19 +72,23 @@ export function setActiveGtfsEntity (feedSourceId, component, entityId, subCompo
// stop editing geometry if currently editing
dispatch(updateEditSetting('editGeometry', false, null))
}
if (entityId === ENTITY.NEW_ID && (!activeTable || activeTable.findIndex(e => e.id === ENTITY.NEW_ID) === -1)) {
// Create new GTFS entity if id is ENTITY.NEW_ID and no ENTITY.NEW_ID entity exists in table
dispatch(createGtfsEntity(feedSourceId, component))
if (
entityId === ENTITY.NEW_ID &&
(!activeTable || activeTable.findIndex(e => e.id === ENTITY.NEW_ID) === -1)
) {
// Create new GTFS entity if id is ENTITY.NEW_ID and no ENTITY.NEW_ID
// entity exists in table
dispatch(newGtfsEntity(feedSourceId, component))
}
const url = constructEditorURL(feedSourceId, component, entityId, subComponent, subEntityId, subSubComponent, subSubEntityId)
const {locationBeforeTransitions} = getState().routing
const pathname = locationBeforeTransitions && locationBeforeTransitions.pathname
if (!locationBeforeTransitions || !pathname || pathname !== url) {
// console.log('updating url', url, pathname, pathItems)
console.log('updating url', url, pathname)
browserHistory.push(url)
}
const activeEntity = component === 'feedinfo'
? clone(activeTable)
? clone(activeTable)[0]
: activeTable && entityId
? clone(activeTable.find(e => e.id === entityId))
: null
Expand Down Expand Up @@ -122,35 +126,24 @@ export function setActiveGtfsEntity (feedSourceId, component, entityId, subCompo
subSubComponent,
subSubEntityId
}))
if (activeSubEntity && component === 'route') {
dispatch(setActiveTripPattern(activeSubEntity))
}
}
}

function setActiveTripPattern (pattern) {
return function (dispatch, getState) {
// const {data} = getState().editor
// const stops = getTableById(data.tables, 'stop')
// const patternStops = getStopsForPattern(pattern, stops)
// const activeColumns = getTimetableColumns(pattern, patternStops)
// dispatch(settingActiveTripPattern({pattern, columns, patternStops}))
}
}

function constructEditorURL (feedSourceId, component, entityId, subComponent, subEntityId, subSubComponent, subSubEntityId) {
const pathItems = ['feed', feedSourceId, 'edit', component, entityId, subComponent, subEntityId, subSubComponent, subSubEntityId].filter(item => item)
const pathItems = ['feed', feedSourceId, 'edit', component, entityId, subComponent, subEntityId, subSubComponent, subSubEntityId]
// Filter out any null or undefined items
.filter(item => item)
let url = '/' + pathItems.join('/')
// ensure component is valid
if (component && !isValidComponent(component)) {
// If component is not valid, go to editor root.
console.warn(`"${component}" is not a valid URL component path`)
url = `/feed/${feedSourceId}/edit/`
} else if (subComponent && subComponentList.indexOf(subComponent) === -1) {
// ensure subComponent is valid
// If subComponent is not valid, go to active entity
console.warn(`"${subComponent}" is not a valid URL subComponent path`)
url = `/feed/${feedSourceId}/edit/${component}/${entityId}/`
} else if (subSubComponent && subSubComponentList.indexOf(subSubComponent) === -1) {
// ensure subSubComponent is valid
// If subSubComponent is not valid, go to sub entity
console.warn(`"${subSubComponent}" is not a valid URL subSubComponent path`)
url = `/feed/${feedSourceId}/edit/${component}/${entityId}/${subComponent}/${subEntityId}/`
}
Expand All @@ -173,11 +166,6 @@ export function saveActiveGtfsEntity (component, optionalEntity) {
entity = optionalEntity || active.subEntity // route.tripPatterns.find(p => p.id === patternId)
saveStrategy = saveTripPattern
break
// FIXME
case 'feedinfo':
feedId = entity.id || active.feedSourceId
saveStrategy = saveFeedInfo
break
default:
// Default method for agencies, stops, routes, fares, calendars.
// Trip patterns and feed info are handled above. Trips are handled in
Expand All @@ -190,6 +178,15 @@ export function saveActiveGtfsEntity (component, optionalEntity) {
}
}

/**
* Generic method for saving an entity using REST endpoint. The only entity
* types with unique save methods are trip patterns and trips (handled in timetable
* actions).
*
* This method determines the URL from entity type (component), maps the entity
* data into the required format (primarily updates fields to snake_case), and
* after performing PUT request re-fetches the entity.
*/
export function saveEntity (feedId, entity, component) {
return function (dispatch, getState) {
const notNew = !entityIsNew(entity)
Expand All @@ -201,24 +198,16 @@ export function saveEntity (feedId, entity, component) {
const data = mappingStrategy(entity)
return dispatch(secureFetch(url, method, data))
.then(res => res.json())
.then(e => {
// FIXME: Instead of getting new table, should we receive entity and send
// to reducer? For example:
// dispatch(receiveStop({feedId, stop: newStop}))
// if (stopId === ENTITY.NEW_ID) {
// // Only set active if stop.id === ENTITY.NEW_ID.
// // If id is undefined, do not set active entity
// dispatch(deletingStop(feedId, stop))
// dispatch(setActiveGtfsEntity(feedId, 'stop', `${newStop.id}`))
// }
return dispatch(getGtfsTable(component, feedId))
.then(entities => {
if (entity.id === ENTITY.NEW_ID) {
// If we just created a new entity, update active entity with
// it's server-created id.
return dispatch(setActiveGtfsEntity(feedId, component, e.id))
}
})
.then(savedEntity => {
const namespace = getEditorNamespace(feedId, getState())
// Refetch entity and replace in store
dispatch(fetchGTFSEntities({
namespace,
id: savedEntity.id,
type: component,
editor: true,
replaceNew: !notNew
}))
})
}
}
Expand All @@ -231,22 +220,26 @@ export const deletingEntity = createAction('DELETING_ENTITY')
export function deleteGtfsEntity (feedId, component, entityId, routeId) {
return function (dispatch, getState) {
const namespace = getEditorNamespace(feedId, getState())
dispatch(deletingEntity({namespace, feedId, component, entityId}))
dispatch(deletingEntity({namespace, feedId, component, entityId, routeId}))
if (entityId === ENTITY.NEW_ID) {
// Entity is new/unsaved. Overwrite current table with existing entities.
// FIXME: we should just remove the ENTITY.NEW_ID entity from the store. This is a
// waste of network traffic (especially for large feeds)
return dispatch(fetchBaseGtfs({namespace, component}))
}
const entityPath = component === 'trippattern' ? 'pattern' : component
const entityPath = component === 'trippattern'
? 'pattern'
: component === 'fare' ? 'fareattribute' : component
const url = `/api/editor/secure/${entityPath}/${entityId}?feedId=${feedId}`
return dispatch(secureFetch(url, 'delete'))
.then(response => response.json())
.then(json => {
if (component === 'trippattern' && routeId) {
console.log('fetching trip patterns')
// Replace trip patterns for route
dispatch(fetchGTFSEntities({namespace, id: routeId, type: component, editor: true}))
return dispatch(fetchGTFSEntities({namespace, id: routeId, type: 'route', editor: true}))
} else {
console.log('fetching base gtfs')
// Replace entire table
return dispatch(fetchBaseGtfs({namespace, component}))
}
Expand All @@ -270,9 +263,3 @@ export function resetActiveGtfsEntity (entity, component) {
component
}
}

export function clearGtfsContent () {
return {
type: 'CLEAR_GTFSEDITOR_CONTENT'
}
}
Loading

0 comments on commit e019f31

Please sign in to comment.