diff --git a/lib/editor/actions/trip.js b/lib/editor/actions/trip.js
index 7cedd4120..9d12e16bc 100644
--- a/lib/editor/actions/trip.js
+++ b/lib/editor/actions/trip.js
@@ -35,6 +35,12 @@ export function fetchTripsForCalendar (feedId, pattern, calendarId) {
id: pattern_id
trips (service_id: $service_id, limit: -1) {
id
+ frequencies {
+ startTime: start_time
+ endTime: end_time
+ headwaySecs: headway_secs
+ exactTimes: exact_times
+ }
tripId: trip_id
tripHeadsign: trip_headsign
tripShortName: trip_short_name
@@ -160,6 +166,10 @@ export function saveMultipleTripsForCalendar (feedId, pattern, calendarId, trips
}
}
+/**
+ * Delete multiple trips. This method takes the provided trips and maps the trips'
+ * IDs to a comma-separated query parameter, indicating which trips to delete.
+ */
export function deleteTripsForCalendar (feedId, pattern, calendarId, trips) {
return function (dispatch, getState) {
let errorCount = 0
diff --git a/lib/editor/actions/tripPattern.js b/lib/editor/actions/tripPattern.js
index 74f4e1f38..ce7cdc884 100644
--- a/lib/editor/actions/tripPattern.js
+++ b/lib/editor/actions/tripPattern.js
@@ -74,3 +74,16 @@ export function saveTripPattern (feedId, tripPattern) {
})
}
}
+
+/**
+ * Deletes all trips for a given pattern ID. This is used to clear the trips for
+ * a pattern if/when a pattern is changed from frequency-based to timetable-baed.
+ */
+export function deleteAllTripsForPattern (feedId, patternId) {
+ return function (dispatch, getState) {
+ const url = `/api/editor/secure/pattern/${patternId}/trips?feedId=${feedId}`
+ return dispatch(secureFetch(url, 'delete'))
+ .then(res => res.json())
+ .then(json => json && json.result === 'OK')
+ }
+}
diff --git a/lib/editor/components/pattern/EditSchedulePanel.js b/lib/editor/components/pattern/EditSchedulePanel.js
index 604868899..dca040079 100644
--- a/lib/editor/components/pattern/EditSchedulePanel.js
+++ b/lib/editor/components/pattern/EditSchedulePanel.js
@@ -29,20 +29,24 @@ export default class EditSchedulePanel extends Component {
}
_onChangeUseFrequency = key => {
+ const {activePattern, deleteAllTripsForPattern, feedSource, saveActiveEntity, showConfirmModal, updateActiveEntity} = this.props
const useFrequency = key !== 'timetables' ? 1 : 0
const unselectedOption = key === 'timetables' ? 'frequencies' : 'timetables'
- this.props.showConfirmModal({
- title: `Use ${key} for ${this.props.activePattern.name}?`,
+ showConfirmModal({
+ title: `Use ${key} for ${activePattern.name}?`,
body: `Are you sure you want to use ${key} for this trip pattern? Any trips created using ${unselectedOption} will be lost.`,
onConfirm: () => {
- this.props.updateActiveEntity(this.props.activePattern, 'trippattern', {useFrequency})
- this.props.saveActiveEntity('trippattern')
+ // Update and save useFrequency field
+ updateActiveEntity(activePattern, 'trippattern', {useFrequency})
+ saveActiveEntity('trippattern')
+ // Then, delete all trips for the pattern.
+ .then(() => deleteAllTripsForPattern(feedSource.id, activePattern.patternId))
}
})
}
render () {
- const { activePattern, activePatternId } = this.props
+ const {activePattern, activePatternId} = this.props
const timetableOptions = [
diff --git a/lib/editor/components/timetable/TimetableGrid.js b/lib/editor/components/timetable/TimetableGrid.js index 962961181..9fdcbae79 100644 --- a/lib/editor/components/timetable/TimetableGrid.js +++ b/lib/editor/components/timetable/TimetableGrid.js @@ -30,6 +30,7 @@ export default class TimetableGrid extends Component { static propTypes = { updateCellValue: PropTypes.func, toggleAllRows: PropTypes.func, + saveEditedTrips: PropTypes.func, selected: PropTypes.array, toggleRowSelection: PropTypes.func } @@ -50,7 +51,10 @@ export default class TimetableGrid extends Component { handleKeyPress = (evt) => { const { activeCell, + activePattern, + activeScheduleId, data, + saveEditedTrips, setActiveCell, scrollToColumn, scrollToRow, @@ -67,7 +71,14 @@ export default class TimetableGrid extends Component { break case 13: // Enter if (!activeCell) { - return setActiveCell(`${scrollToRow}-${scrollToColumn}`) + if (evt.metaKey || evt.ctrlKey) { + // If Enter is pressed with CTRL or CMD and no cell is active, save + // any unsaved trips. + return saveEditedTrips(activePattern, activeScheduleId) + } else { + // Otherwise, set active cell + return setActiveCell(`${scrollToRow}-${scrollToColumn}`) + } } else { return setActiveCell(null) } @@ -242,6 +253,7 @@ export default class TimetableGrid extends Component { (selected[0] !== '*' && selected.indexOf(rowIndex) !== -1) let val = objectPath.get(data[rowIndex], col.key) + // console.log(val, data[rowIndex], col.key) if (col.key === 'tripId' && val === null) { val = objectPath.get(data[rowIndex], 'id') !== ENTITY.NEW_ID ? objectPath.get(data[rowIndex], 'id') : null } diff --git a/lib/editor/containers/ActiveTripPatternList.js b/lib/editor/containers/ActiveTripPatternList.js index d40555db3..0cedeba87 100644 --- a/lib/editor/containers/ActiveTripPatternList.js +++ b/lib/editor/containers/ActiveTripPatternList.js @@ -16,6 +16,7 @@ import {addStopToPattern, removeStopFromPattern} from '../actions/map/stopStrate import {updatePatternGeometry} from '../actions/map' import {setErrorMessage} from '../../manager/actions/status' import { + deleteAllTripsForPattern, resnapStops, setActiveStop, setActivePatternSegment, @@ -79,6 +80,7 @@ const mapDispatchToProps = { newGtfsEntity, // Trip pattern specific actions addStopToPattern, + deleteAllTripsForPattern, removeStopFromPattern, resnapStops, setActivePatternSegment, diff --git a/lib/editor/selectors/timetable.js b/lib/editor/selectors/timetable.js index 00c526a9b..08e133fa3 100644 --- a/lib/editor/selectors/timetable.js +++ b/lib/editor/selectors/timetable.js @@ -70,24 +70,31 @@ export const getTimetableColumns = createSelector( columns.push({ name: 'Start time', width: 100, - key: 'startTime', + key: 'frequencies.0.startTime', type: 'TIME', placeholder: 'HH:MM:SS' }) columns.push({ name: 'End time', width: 100, - key: 'endTime', + key: 'frequencies.0.endTime', type: 'TIME', placeholder: 'HH:MM:SS' }) columns.push({ name: 'Headway', width: 60, - key: 'headway', + key: 'frequencies.0.headwaySecs', type: 'MINUTES', placeholder: '15 (min)' }) + // columns.push({ + // name: 'Exact times', + // width: 60, + // key: 'frequencies.0.exactTimes', + // type: 'MINUTES', + // placeholder: '15 (min)' + // }) } } return columns