Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 29 additions & 3 deletions src/backend/data/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,14 @@ const GraphQLListContainer = new GraphQLObjectType({
interfaces: [nodeInterface]
})

const GeoPoint = new GraphQLInputObjectType({
name: 'GeoPoint',
fields: {
lat: {type: GraphQLFloat},
lon: {type: GraphQLFloat},
}
})

const GraphQLUser = new GraphQLObjectType({
name: 'User',
description: 'User of ground control',
Expand Down Expand Up @@ -554,10 +562,13 @@ const GraphQLUser = new GraphQLObjectType({
intervieweeForCallAssignment: {
type: GraphQLPerson,
args: {
callAssignmentId: {type: GraphQLString}
callAssignmentId: {type: GraphQLString},
center: {type: GeoPoint},
radiusMeters: {type: GraphQLFloat}
},
resolve: async(user, {callAssignmentId}, {rootValue}) => {

resolve: async(
user, {callAssignmentId, center, radiusMeters}, {rootValue}
) => {
let localCallAssignmentId = fromGlobalId(callAssignmentId)
if (localCallAssignmentId.type !== 'CallAssignment')
localCallAssignmentId = callAssignmentId
Expand Down Expand Up @@ -647,6 +658,21 @@ const GraphQLUser = new GraphQLObjectType({
if (userAddress)
query = query.whereNot('bsd_people.cons_id', userAddress.cons_id)

// Filter by distance from a geographical point.
// Spatial ref 4326 is WGS 84, in degrees
// Spatial ref 900913 is Google Web Mercator, in meters
if (center && radiusMeters > 0) {
query = query.whereRaw(`
ST_DWithin(bsd_addresses.geom,
ST_Transform(
ST_SetSRID(ST_MakePoint(${center.lon}, ${center.lat}), 4326),
900913
),
${radiusMeters}
)
`)
}

log.info(`Running query: ${query}`)

let person = await query
Expand Down
1 change: 1 addition & 0 deletions src/frontend/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ ReactDOM.render(
...CallAssignmentQueries,
...CurrentUserQueries
}}
queryParams={['ll', 'miles']}
renderLoading={() => <Loading />}
/>
</Route>
Expand Down
34 changes: 30 additions & 4 deletions src/frontend/components/CallAssignment.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import SubmitCallSurvey from '../mutations/SubmitCallSurvey'
import CallStatsBar from './CallStatsBar'
import MutationHandler from './MutationHandler'
import {PhoneNumberFormat, PhoneNumberUtil} from 'google-libphonenumber'
import getDefaultQuery from '../helpers/getDefaultQuery'
const phoneUtil = PhoneNumberUtil.getInstance()

const SurveyRenderers = {
Expand Down Expand Up @@ -408,8 +409,29 @@ ${userFirstName}`
}
}

// Convert the query parameters 'll' and 'miles' into the API arguments
// for the center and radius of the filter region.
var center = null;
var radiusMeters = null;

var queryParams = getDefaultQuery({
ll: null, // URL query parameter: point in lat,lon format
miles: null // URL query parameter: radius in miles
})
var llParts = (queryParams.ll || '').split(',')
if (llParts.length === 2) {
center = {lat: Number(llParts[0]), lon: Number(llParts[1])}
}
if (queryParams.miles) {
radiusMeters = Number(queryParams.miles) * 1609.34
}

export default Relay.createContainer(CallAssignment, {
initialVariables: { id: '' },
initialVariables: {
id: '',
center: center,
radiusMeters: radiusMeters
},
fragments: {
callAssignment: () => Relay.QL`
fragment on CallAssignment {
Expand All @@ -428,9 +450,13 @@ export default Relay.createContainer(CallAssignment, {
fragment on User {
id
firstName
allCallsMade:callsMade(forAssignmentId:$id)
completedCallsMade:callsMade(forAssignmentId:$id,completed:true)
intervieweeForCallAssignment(callAssignmentId:$id) {
allCallsMade: callsMade(forAssignmentId: $id)
completedCallsMade: callsMade(forAssignmentId: $id, completed: true)
intervieweeForCallAssignment(
callAssignmentId: $id,
center: $center,
radiusMeters: $radiusMeters
) {
id
prefix
firstName
Expand Down
26 changes: 26 additions & 0 deletions src/frontend/helpers/convertType.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const convertType = (value) => {
if (typeof value === 'object'){
let updatedValue = {}
Object.keys(value).forEach((key) => {
const currentValue = convertType(value[key])
if (currentValue != undefined)
value[key] = currentValue
})
return value
}
else if (value === 'none')
return null
else if (value === 'true')
return true
else if (value === 'false')
return false
else if (value != '' && !isNaN(value) && String(Number(value)) === value)
return Number(value)
else if (value)
return String(value)
else {
return undefined
}
}

export default convertType
18 changes: 18 additions & 0 deletions src/frontend/helpers/getDefaultQuery.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import qs from 'qs'
import convertType from './convertType'

export default function(defaultParams) {
const hashParams = convertType(qs.parse(location.hash.substr(1), { strictNullHandling: true }))
if (hashParams.query){
try {
let newQueryParams = {...defaultParams, ...hashParams.query}
newQueryParams.filters = {...defaultParams.filters, ...hashParams.query.filters}
return newQueryParams
}
catch(ex) {
console.error('Invalid query parameters', ex)
}
}

return {...defaultParams, ...hashParams}
}