Skip to content

Commit

Permalink
Merge pull request #395 from opentripplanner/fix-calltaker-recording
Browse files Browse the repository at this point in the history
Fix calltaker recording
  • Loading branch information
evansiroky authored Jul 2, 2021
2 parents 1ed767a + 2dd8523 commit f18fa7e
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 35 deletions.
42 changes: 23 additions & 19 deletions lib/actions/call-taker.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export function beginCallIfNeeded () {
* End the active call and store the queries made during the call.
*/
export function endCall () {
return function (dispatch, getState) {
return async function (dispatch, getState) {
const {callTaker, otp} = getState()
const {activeCall, session} = callTaker
const { sessionId } = session
Expand All @@ -73,19 +73,20 @@ export function endCall () {
endTime: getTimestamp()
}
})
fetch(`${otp.config.datastoreUrl}/calltaker/call`,
{method: 'POST', body: callData}
)
.then(res => res.json())
.then(id => {
// Inject call ID into active call and save queries.
dispatch(saveQueriesForCall({...activeCall, id}))
dispatch(fetchCalls())
})
.catch(err => {
console.error(err)
alert(`Could not save call: ${JSON.stringify(err)}`)
})
try {
const fetchResult = await fetch(`${otp.config.datastoreUrl}/calltaker/call`,
{method: 'POST', body: callData}
)
const id = await fetchResult.json()

// Inject call ID into active call and save queries.
await dispatch(saveQueriesForCall({...activeCall, id}))
// Wait until query was saved before re-fetching queries for this call.
await dispatch(fetchCalls())
} catch (err) {
console.error(err)
alert(`Could not save call: ${JSON.stringify(err)}`)
}
// Clear itineraries shown when ending call.
dispatch(resetForm(true))
dispatch(endingCall())
Expand Down Expand Up @@ -153,17 +154,20 @@ function checkSession (datastoreUrl, sessionId) {
* Fetch latest calls for a particular session.
*/
export function fetchCalls () {
return function (dispatch, getState) {
return async function (dispatch, getState) {
dispatch(requestingCalls())
const {callTaker, otp} = getState()
if (sessionIsInvalid(callTaker.session)) return
const {datastoreUrl} = otp.config
const {sessionId} = callTaker.session
const limit = 1000
fetch(`${datastoreUrl}/calltaker/call?${qs.stringify({limit, sessionId})}`)
.then(res => res.json())
.then(calls => dispatch(receivedCalls({calls})))
.catch(err => alert(`Error fetching calls: ${JSON.stringify(err)}`))
try {
const fetchResult = await fetch(`${datastoreUrl}/calltaker/call?${qs.stringify({limit, sessionId})}`)
const calls = await fetchResult.json()
dispatch(receivedCalls({calls}))
} catch (err) {
alert(`Error fetching calls: ${JSON.stringify(err)}`)
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions lib/actions/field-trip.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { serialize } from 'object-to-formdata'
import qs from 'qs'
import { createAction } from 'redux-actions'

import {getGroupSize, getTripFromRequest, sessionIsInvalid} from '../util/call-taker'
import {getGroupSize, getTripFromRequest, parseQueryParams, sessionIsInvalid} from '../util/call-taker'

import {routingQuery} from './api'
import {toggleCallHistory} from './call-taker'
Expand Down Expand Up @@ -214,7 +214,7 @@ export function planTrip (request, outbound) {
else dispatch(planInbound(request))
} else {
// Populate params from saved query params
const params = await planParamsToQueryAsync(JSON.parse(trip.queryParams))
const params = await planParamsToQueryAsync(parseQueryParams(trip.queryParams))
dispatch(setQueryParam(params, trip.id))
}
}
Expand Down
9 changes: 7 additions & 2 deletions lib/actions/form.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,15 +88,20 @@ export function setQueryParam (payload, searchId) {
* performed according to the behavior of setQueryParam (i.e., if the passed
* searchId is not null).
* @param {Object} params an object containing URL query params
* @param {string} source optionally contains the source of the query params
* (e.g., _CALL indicates that the source is from a past
* query made during a call taker session, to prevent
* a search from being added to the current call)
*/
export function parseUrlQueryString (params = getUrlParams()) {
export function parseUrlQueryString (params = getUrlParams(), source) {
return function (dispatch, getState) {
// Filter out the OTP (i.e. non-UI) params and set the initial query
const planParams = {}
Object.keys(params).forEach(key => {
if (!key.startsWith('ui_')) planParams[key] = params[key]
})
const searchId = params.ui_activeSearch || coreUtils.storage.randId()
let searchId = params.ui_activeSearch || coreUtils.storage.randId()
if (source) searchId += source
// Convert strings to numbers/objects and dispatch
planParamsToQueryAsync(planParams, getState().otp.config)
.then(query => dispatch(setQueryParam(query, searchId)))
Expand Down
4 changes: 3 additions & 1 deletion lib/components/admin/call-history-window.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ function CallHistoryWindow (props) {
{callHistory.calls.data.length > 0
? callHistory.calls.data.map((call, i) => (
<CallRecord
key={i}
// Create a key so that when call records get added, elements in this list are
// recreated/remounted so that they don't show the state from the previous list.
key={`${call.id}-${i}`}
index={i}
call={call}
fetchQueries={fetchQueries} />
Expand Down
12 changes: 5 additions & 7 deletions lib/components/admin/query-record.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,20 @@ import React, { Component } from 'react'
import { connect } from 'react-redux'

import * as formActions from '../../actions/form'
import {CallRecordButton, CallRecordIcon} from './styled'
import { parseQueryParams } from '../../util/call-taker'

import { CallRecordButton, CallRecordIcon } from './styled'

/**
* Displays information for a query stored for the Call Taker module.
*/
class QueryRecordLayout extends Component {
_getParams = () => {
const {query} = this.props
return planParamsToQuery(JSON.parse(query.queryParams))
}
_getParams = () => planParamsToQuery(parseQueryParams(this.props.query.queryParams))

_viewQuery = () => {
const {parseUrlQueryString} = this.props
const params = this._getParams()
params.departArrive = params.arriveBy ? 'ARRIVE' : 'DEPART'
parseUrlQueryString(params)
parseUrlQueryString(params, '_CALL')
}

render () {
Expand Down
12 changes: 8 additions & 4 deletions lib/reducers/call-taker.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,15 @@ function createCallTakerReducer (config) {
const {searchId} = action.payload
if (state.activeCall) {
// If call is in progress, record search ID when a routing response is
// fulfilled.
// fulfilled, except in the case where the
// searchId contains _CALL and call history window is visible, which indicates that a user is viewing a
// past call record
// TODO: How should we handle routing errors.
return update(state, {
activeCall: { searches: { $push: [searchId] } }
})
if (!(state.callHistory.visible && searchId.indexOf('_CALL') !== -1)) {
return update(state, {
activeCall: { searches: { $push: [searchId] } }
})
}
}
// Otherwise, ignore.
return state
Expand Down
16 changes: 16 additions & 0 deletions lib/util/call-taker.js
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,22 @@ function createItinerary (itinData, tripPlan) {
return itin
}

/**
* @param queryParams The query parameters string to convert (stringified JSON).
* @returns An object with the parsed query params,
* where the arriveBy boolean is converted to a string
* per https://github.com/opentripplanner/otp-ui/blob/master/packages/core-utils/src/query.js#L285
*/
export function parseQueryParams (queryParams) {
return JSON.parse(
queryParams,
// convert boolean for the 'arriveBy' field to strings
(key, value) => key === 'arriveBy'
? value.toString()
: value // return everything else unchanged
)
}

/**
* LZW-compress a string
*
Expand Down

0 comments on commit f18fa7e

Please sign in to comment.