From 57bb8b1f04cdb925321dcc6b921b8249264b84fb Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Thu, 11 May 2023 16:38:01 -0400
Subject: [PATCH 01/80] refactor(NotificationPrefsPane): Remove redundant
header
---
i18n/en-US.yml | 1 -
i18n/es.yml | 30 +++++++------------
i18n/fr.yml | 3 --
i18n/ko.yml | 1 -
i18n/vi.yml | 3 --
i18n/zh.yml | 1 -
.../user/notification-prefs-pane.tsx | 3 --
7 files changed, 10 insertions(+), 32 deletions(-)
diff --git a/i18n/en-US.yml b/i18n/en-US.yml
index b2e036689..e8b46ea69 100644
--- a/i18n/en-US.yml
+++ b/i18n/en-US.yml
@@ -356,7 +356,6 @@ components:
description: The content you requested is not available.
header: Content not found
NotificationPrefsPane:
- description: You can receive notifications about trips you frequently take.
noneSelect: Don't notify me
notificationChannelPrompt: How would you like to receive notifications?
notificationEmailDetail: "Notification emails will be sent to:"
diff --git a/i18n/es.yml b/i18n/es.yml
index 08c82b945..29a962b6d 100644
--- a/i18n/es.yml
+++ b/i18n/es.yml
@@ -30,8 +30,7 @@ actions:
No se puede guardar el plan: este plan no se pudo guardar debido a la
falta de capacidad en uno o más vehículos. Por favor, vuelva a planificar
su viaje.
- maxTripRequestsExceeded: Número de solicitudes de viaje superadas sin resultados
- válidos
+ maxTripRequestsExceeded: Número de solicitudes de viaje superadas sin resultados válidos
saveItinerariesError: "No se pudieron guardar los itinerarios: {err}"
setDateError: "Error al establecer la fecha:"
setGroupSizeError: "No se pudo establecer el tamaño del grupo:"
@@ -47,11 +46,9 @@ actions:
authTokenError: Error al obtener un token de autorización.
confirmDeleteMonitoredTrip: ¿Desea eliminar este viaje?
confirmDeletePlace: ¿Quiere eliminar este lugar?
- emailVerificationResent: El mensaje de verificación de correo electrónico ha sido
- reenviado.
+ emailVerificationResent: El mensaje de verificación de correo electrónico ha sido reenviado.
genericError: "Se ha encontrado un error: {err}"
- itineraryExistenceCheckFailed: Comprobación de errores para ver si el viaje seleccionado
- es posible.
+ itineraryExistenceCheckFailed: Comprobación de errores para ver si el viaje seleccionado es posible.
preferencesSaved: Sus preferencias se han guardado.
smsInvalidCode: El código introducido no es válido. Por favor, inténtelo de nuevo.
smsResendThrottled: >-
@@ -113,6 +110,7 @@ common:
{co2} de CO₂ en {isMore, select, true {más} other {menos} } que conducir
solo
transfers: "{transfers, plural, =0 {} one {# transferencia} other {# transferencias}}"
+ linkOpensNewWindow: (Abre una nueva ventana)
modes:
bicycle_rent: Compartir bicicleta
bike: Bicicleta
@@ -160,7 +158,6 @@ common:
tripDurationFormat: >-
{hours, plural, =0 {} other {# h }}{minutes} min { seconds, plural, =0 {}
other {# s}}
- linkOpensNewWindow: (Abre una nueva ventana)
components:
A11yPrefs:
accessibilityRoutingByDefault: Prefiera los viajes accesibles por defecto
@@ -237,8 +234,7 @@ components:
origin: origen
planTripTooltip: Planificar viaje
settings: Preferencias de viaje
- validationMessage: "Por favor, defina los siguientes campos para planificar un\
- \ viaje: {issues}"
+ validationMessage: "Por favor, defina los siguientes campos para planificar un viaje: {issues}"
BeforeSignInScreen:
mainTitle: Iniciando sesión
message: >
@@ -366,11 +362,9 @@ components:
description: El contenido que ha solicitado no está disponible.
header: No se encontró el contenido
NotificationPrefsPane:
- description: Puede recibir notificaciones sobre los viajes que realiza con frecuencia.
noneSelect: No enviar notificaciones
notificationChannelPrompt: ¿Cómo desea recibir las notificaciones?
- notificationEmailDetail: "Los correos electrónicos de notificación se enviarán\
- \ a:"
+ notificationEmailDetail: "Los correos electrónicos de notificación se enviarán a:"
PhoneNumberEditor:
changeNumber: Cambiar número de teléfono
invalidCode: Introduzca 6 dígitos para el código de validación.
@@ -503,8 +497,7 @@ components:
Opciones
y Preferencias del viaje
SimpleRealtimeAnnotation:
- usingRealtimeInfo: Este viaje utiliza información de tráfico y retrasos en tiempo
- real
+ usingRealtimeInfo: Este viaje utiliza información de tráfico y retrasos en tiempo real
StackedPaneDisplay:
savePreferences: Guardar preferencias
StopScheduleTable:
@@ -566,19 +559,16 @@ components:
travelingAt: Viajando a {milesPerHour}
vehicleName: Vehículo {vehicleNumber}
TripBasicsPane:
- checkingItineraryExistence: Comprobación de la existencia de itinerarios para
- cada día de la semana…
+ checkingItineraryExistence: Comprobación de la existencia de itinerarios para cada día de la semana…
selectAtLeastOneDay: Por favor, seleccione al menos un día para el seguimiento.
tripDaysPrompt: ¿Qué días hace este viaje?
- tripIsAvailableOnDaysIndicated: Su viaje está disponible en los días de la semana
- indicados anteriormente.
+ tripIsAvailableOnDaysIndicated: Su viaje está disponible en los días de la semana indicados anteriormente.
tripNamePrompt: "Por favor, indique un nombre para este viaje:"
tripNotAvailableOnDay: El viaje no está disponible el {repeatedDay}
unsavedChangesExistingTrip: >-
Todavía no ha guardado su viaje. Si abandona la página, los cambios se
perderán.
- unsavedChangesNewTrip: Todavía no ha guardado su nuevo viaje. Si abandona la página,
- se perderá.
+ unsavedChangesNewTrip: Todavía no ha guardado su nuevo viaje. Si abandona la página, se perderá.
TripNotificationsPane:
advancedSettings: Configuración avanzada
altRouteRecommended: Se recomienda una ruta alternativa o un punto de transferencia
diff --git a/i18n/fr.yml b/i18n/fr.yml
index 925933b69..29c3ee110 100644
--- a/i18n/fr.yml
+++ b/i18n/fr.yml
@@ -368,9 +368,6 @@ components:
description: Le contenu que vous avez demandé n'est pas disponible.
header: Contenu introuvable
NotificationPrefsPane:
- description: >-
- Vous pouvez recevoir des notifications sur les trajets que vous effectuez
- fréquemment.
noneSelect: Ne pas me notifier
notificationChannelPrompt: Comment voulez-vous recevoir vos notifications ?
notificationEmailDetail: "Les courriers de notification seront envoyés à :"
diff --git a/i18n/ko.yml b/i18n/ko.yml
index a4d9f9afa..605c75f7a 100644
--- a/i18n/ko.yml
+++ b/i18n/ko.yml
@@ -335,7 +335,6 @@ components:
description: 요청한 콘텐츠를 사용할 수 없습니다.
header: 콘텐츠를 찾을 수 없음
NotificationPrefsPane:
- description: 자주 가는 트립에 대한 알림을 받을 수 있습니다.
noneSelect: 알림 거부
notificationChannelPrompt: 알림을 어떻게 받고 싶습니까?
notificationEmailDetail: "알림 이메일이 다음으로 전송됩니다:"
diff --git a/i18n/vi.yml b/i18n/vi.yml
index 854e37905..64f48d2d3 100644
--- a/i18n/vi.yml
+++ b/i18n/vi.yml
@@ -343,9 +343,6 @@ components:
description: Nội dung bạn yêu cầu không có sẵn.
header: Không tìm thấy nội dung
NotificationPrefsPane:
- description: >-
- Bạn có thể nhận được thông báo về các chuyến đi bạn thường xuyên thực
- hiện.
noneSelect: Đừng thông báo cho tôi
notificationChannelPrompt: Bạn muốn nhận thông báo như thế nào?
notificationEmailDetail: "Email thông báo sẽ được gửi đến:"
diff --git a/i18n/zh.yml b/i18n/zh.yml
index e44e03592..bc32777c4 100644
--- a/i18n/zh.yml
+++ b/i18n/zh.yml
@@ -335,7 +335,6 @@ components:
description: 您要求的内容不存在.
header: 未找到内容
NotificationPrefsPane:
- description: 你可以收到关于你常用行程的通知.
noneSelect: 不要通知我
notificationChannelPrompt: 您希望如何接收通知?
notificationEmailDetail: "通知邮件将被发送至:"
diff --git a/lib/components/user/notification-prefs-pane.tsx b/lib/components/user/notification-prefs-pane.tsx
index 4bee1cca9..ac9ea0ca8 100644
--- a/lib/components/user/notification-prefs-pane.tsx
+++ b/lib/components/user/notification-prefs-pane.tsx
@@ -53,9 +53,6 @@ const NotificationPrefsPane = ({
return (
-
-
-
From 18aa10220ff8dbbf1a3fa1381f5a39cbcb7e7e7b Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Thu, 11 May 2023 16:56:11 -0400
Subject: [PATCH 02/80] refactor(NotificationPrefsPane): Rephrase the
notification selector prompt.
---
i18n/en-US.yml | 2 +-
i18n/es.yml | 2 +-
i18n/fr.yml | 2 +-
i18n/ko.yml | 2 +-
i18n/vi.yml | 2 +-
i18n/zh.yml | 2 +-
6 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/i18n/en-US.yml b/i18n/en-US.yml
index e8b46ea69..e13f71b32 100644
--- a/i18n/en-US.yml
+++ b/i18n/en-US.yml
@@ -357,7 +357,7 @@ components:
header: Content not found
NotificationPrefsPane:
noneSelect: Don't notify me
- notificationChannelPrompt: How would you like to receive notifications?
+ notificationChannelPrompt: "Receive notifications about your saved trips via:"
notificationEmailDetail: "Notification emails will be sent to:"
PhoneNumberEditor:
changeNumber: Change number
diff --git a/i18n/es.yml b/i18n/es.yml
index 29a962b6d..e6142f4fc 100644
--- a/i18n/es.yml
+++ b/i18n/es.yml
@@ -363,7 +363,7 @@ components:
header: No se encontró el contenido
NotificationPrefsPane:
noneSelect: No enviar notificaciones
- notificationChannelPrompt: ¿Cómo desea recibir las notificaciones?
+ notificationChannelPrompt: "Recibir notificaciones para sus viajes guardados por :"
notificationEmailDetail: "Los correos electrónicos de notificación se enviarán a:"
PhoneNumberEditor:
changeNumber: Cambiar número de teléfono
diff --git a/i18n/fr.yml b/i18n/fr.yml
index 29c3ee110..4133097ed 100644
--- a/i18n/fr.yml
+++ b/i18n/fr.yml
@@ -369,7 +369,7 @@ components:
header: Contenu introuvable
NotificationPrefsPane:
noneSelect: Ne pas me notifier
- notificationChannelPrompt: Comment voulez-vous recevoir vos notifications ?
+ notificationChannelPrompt: "Recevoir des notifications sur vos trajets enregistrés par :"
notificationEmailDetail: "Les courriers de notification seront envoyés à :"
PhoneNumberEditor:
changeNumber: Changer de numéro
diff --git a/i18n/ko.yml b/i18n/ko.yml
index 605c75f7a..71434375c 100644
--- a/i18n/ko.yml
+++ b/i18n/ko.yml
@@ -336,7 +336,7 @@ components:
header: 콘텐츠를 찾을 수 없음
NotificationPrefsPane:
noneSelect: 알림 거부
- notificationChannelPrompt: 알림을 어떻게 받고 싶습니까?
+ notificationChannelPrompt: "저장된 여행의 알림을 받는 방법:"
notificationEmailDetail: "알림 이메일이 다음으로 전송됩니다:"
PhoneNumberEditor:
changeNumber: 번호 변경
diff --git a/i18n/vi.yml b/i18n/vi.yml
index 64f48d2d3..694873eb5 100644
--- a/i18n/vi.yml
+++ b/i18n/vi.yml
@@ -344,7 +344,7 @@ components:
header: Không tìm thấy nội dung
NotificationPrefsPane:
noneSelect: Đừng thông báo cho tôi
- notificationChannelPrompt: Bạn muốn nhận thông báo như thế nào?
+ notificationChannelPrompt: "Nhận thông báo về các chuyến đi đã lưu bằng:"
notificationEmailDetail: "Email thông báo sẽ được gửi đến:"
PhoneNumberEditor:
changeNumber: Thay đổi số điện thoại
diff --git a/i18n/zh.yml b/i18n/zh.yml
index bc32777c4..c83ce0d63 100644
--- a/i18n/zh.yml
+++ b/i18n/zh.yml
@@ -336,7 +336,7 @@ components:
header: 未找到内容
NotificationPrefsPane:
noneSelect: 不要通知我
- notificationChannelPrompt: 您希望如何接收通知?
+ notificationChannelPrompt: "如何接收已保存行程的通知:"
notificationEmailDetail: "通知邮件将被发送至:"
PhoneNumberEditor:
changeNumber: 更改电话号码
From 148190bb733d66597b139701b568b9c3b1531b66 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Thu, 11 May 2023 18:18:15 -0400
Subject: [PATCH 03/80] refactor(NotificationPrefsPane): Update layout to use
checkboxes (rough)
---
.../user/notification-prefs-pane.tsx | 99 +++++++++++--------
1 file changed, 60 insertions(+), 39 deletions(-)
diff --git a/lib/components/user/notification-prefs-pane.tsx b/lib/components/user/notification-prefs-pane.tsx
index ac9ea0ca8..38dc4713c 100644
--- a/lib/components/user/notification-prefs-pane.tsx
+++ b/lib/components/user/notification-prefs-pane.tsx
@@ -29,7 +29,7 @@ interface Props extends FormikProps {
}
}
-const allowedNotificationChannels = ['email', 'sms', 'none']
+const allowedNotificationChannels = ['email', 'sms']
// Styles
// HACK: Preserve container height.
@@ -38,6 +38,22 @@ const Details = styled.div`
margin-bottom: 15px;
`
+const NotificationOption = styled.div`
+ align-items: flex-start;
+ display: flex;
+ gap: 1ch;
+ margin-bottom: 10px;
+
+ label {
+ display: block;
+ font-weight: normal;
+ margin-bottom: 0;
+ }
+ label::first-letter {
+ text-transform: uppercase;
+ }
+`
+
/**
* User notification preferences pane.
*/
@@ -53,44 +69,49 @@ const NotificationPrefsPane = ({
return (
-
-
-
-
-
- {allowedNotificationChannels.map((type) => {
- // TODO: If removing the Save/Cancel buttons on the account screen,
- // persist changes immediately when onChange is triggered.
- const inputId = `notification-channel-${type}`
- const isChecked = notificationChannel === type
- return (
-
- {/* Note: labels are placed after inputs so that the CSS focus selector can be easily applied. */}
-
-
- {type === 'email' ? (
-
- ) : type === 'sms' ? (
-
- ) : (
-
- )}
-
-
- )
- })}
-
-
+
+
+
+
+ {allowedNotificationChannels.map((type) => {
+ // TODO: If removing the Save/Cancel buttons on the account screen,
+ // persist changes immediately when onChange is triggered.
+ const inputId = `notification-channel-${type}`
+ return (
+
+ {' '}
+
+ {type === 'email' ? (
+ <>
+
+
+
+ {email}
+ >
+ ) : (
+ <>
+
+
+
+
+ >
+ )}
+
+
+ )
+ })}
+
{notificationChannel === 'email' && (
From 5d04a3953567421558c8e9d6a52a0c1e20d2f66f Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Fri, 12 May 2023 11:00:09 -0400
Subject: [PATCH 04/80] refactor(NotificationPrefsPane): Improve layout for
phone number description
---
i18n/en-US.yml | 1 -
i18n/es.yml | 1 -
i18n/fr.yml | 1 -
i18n/ko.yml | 1 -
i18n/vi.yml | 1 -
i18n/zh.yml | 1 -
.../user/notification-prefs-pane.tsx | 51 +++++---------
lib/components/user/phone-number-editor.tsx | 66 +++++++++----------
8 files changed, 49 insertions(+), 74 deletions(-)
diff --git a/i18n/en-US.yml b/i18n/en-US.yml
index e13f71b32..959eb6980 100644
--- a/i18n/en-US.yml
+++ b/i18n/en-US.yml
@@ -370,7 +370,6 @@ components:
prompt: "Enter your phone number for SMS notifications:"
requestNewCode: Request a new code
sendVerificationText: Send verification text
- smsDetail: "SMS notifications will be sent to:"
verificationCode: "Verification code:"
verificationInstructions: >
Please check the SMS messaging app on your mobile phone for a text message
diff --git a/i18n/es.yml b/i18n/es.yml
index e6142f4fc..9cfc2d409 100644
--- a/i18n/es.yml
+++ b/i18n/es.yml
@@ -378,7 +378,6 @@ components:
texto:
requestNewCode: Solicitar un nuevo código
sendVerificationText: Enviar texto de verificación
- smsDetail: "Las notificaciones por mensaje de texto se enviarán a:"
verificationCode: "Código de verificación:"
verificationInstructions: >
Por favor, compruebe en la aplicación de mensajería de texto de su
diff --git a/i18n/fr.yml b/i18n/fr.yml
index 4133097ed..e3bfde8e1 100644
--- a/i18n/fr.yml
+++ b/i18n/fr.yml
@@ -382,7 +382,6 @@ components:
prompt: "Entrez votre numéro de téléphone pour les SMS de notification :"
requestNewCode: Envoyer un nouveau code
sendVerificationText: Envoyer le SMS de vérification
- smsDetail: "Les SMS de notification seront envoyés au :"
verificationCode: "Code de vérification :"
verificationInstructions: >
Un SMS vous a été envoyé avec un code de vérification. Veuillez taper ce
diff --git a/i18n/ko.yml b/i18n/ko.yml
index 71434375c..627b4a9de 100644
--- a/i18n/ko.yml
+++ b/i18n/ko.yml
@@ -348,7 +348,6 @@ components:
prompt: "SMS 알림 수신을 위한 전화번호를 입력하세요:"
requestNewCode: 새 코드 요청
sendVerificationText: 확인 텍스트 전송
- smsDetail: "SMS 알림이 다음으로 전송됩니다:"
verificationCode: "확인 코드:"
verificationInstructions: |
휴대폰의 SMS 메시지 앱에서 인증 코드를 확인하고 아래에 코드를 입력하세요(코드는 10분 후에 만료됩니다).
diff --git a/i18n/vi.yml b/i18n/vi.yml
index 694873eb5..7b582ca5c 100644
--- a/i18n/vi.yml
+++ b/i18n/vi.yml
@@ -356,7 +356,6 @@ components:
prompt: "Nhập số điện thoại của bạn để nhận thông báo SMS:"
requestNewCode: Yêu cầu một mã mới
sendVerificationText: Gửi văn bản xác minh
- smsDetail: "Thông báo SMS sẽ được gửi đến:"
verificationCode: "Mã xác nhận:"
verificationInstructions: >
Vui lòng kiểm tra ứng dụng nhắn tin SMS trên điện thoại di động của bạn để
diff --git a/i18n/zh.yml b/i18n/zh.yml
index c83ce0d63..59f0f3fec 100644
--- a/i18n/zh.yml
+++ b/i18n/zh.yml
@@ -348,7 +348,6 @@ components:
prompt: "输入你的电话号码以便收到短信通知:"
requestNewCode: 申请一个新的代码
sendVerificationText: 发送验证短信
- smsDetail: "短信通知将被发送到:"
verificationCode: "验证码:"
verificationInstructions: |
请检查您手机上的短信应用查看是否有验证码的短信并输入以下代码 (代码在10分钟后失效).
diff --git a/lib/components/user/notification-prefs-pane.tsx b/lib/components/user/notification-prefs-pane.tsx
index 38dc4713c..d929c512a 100644
--- a/lib/components/user/notification-prefs-pane.tsx
+++ b/lib/components/user/notification-prefs-pane.tsx
@@ -1,12 +1,9 @@
import { Field, FormikProps } from 'formik'
import { FormattedMessage } from 'react-intl'
-import { FormGroup } from 'react-bootstrap'
import React, { Fragment } from 'react'
import styled from 'styled-components'
-import ButtonGroup from '../util/button-group'
-
-import { FakeLabel, InlineStatic } from './styled'
+import { labelStyle } from './styled'
import { PhoneVerificationSubmitHandler } from './phone-verification-form'
import PhoneNumberEditor, {
PhoneCodeRequestHandler
@@ -32,12 +29,6 @@ interface Props extends FormikProps {
const allowedNotificationChannels = ['email', 'sms']
// Styles
-// HACK: Preserve container height.
-const Details = styled.div`
- min-height: 60px;
- margin-bottom: 15px;
-`
-
const NotificationOption = styled.div`
align-items: flex-start;
display: flex;
@@ -54,6 +45,13 @@ const NotificationOption = styled.div`
}
`
+const NotificationOptions = styled.fieldset`
+ /* Format like labels. */
+ legend {
+ ${labelStyle}
+ }
+`
+
/**
* User notification preferences pane.
*/
@@ -62,14 +60,13 @@ const NotificationPrefsPane = ({
onRequestPhoneVerificationCode,
onSendPhoneVerificationCode,
phoneFormatOptions,
- values: userData // Formik prop
+ values: userData // Formik prop // TODO: remove
}: Props): JSX.Element => {
const { email, isPhoneNumberVerified, phoneNumber } = loggedInUser
- const { notificationChannel } = userData
return (
-
+
@@ -77,9 +74,11 @@ const NotificationPrefsPane = ({
// TODO: If removing the Save/Cancel buttons on the account screen,
// persist changes immediately when onChange is triggered.
const inputId = `notification-channel-${type}`
+ const inputDescriptionId = `${inputId}-description`
return (
- {email}
+
+ {email}
+
>
) : (
<>
@@ -99,6 +100,7 @@ const NotificationPrefsPane = ({
)
})}
-
-
- {notificationChannel === 'email' && (
-
-
-
-
- {email}
-
- )}
- {notificationChannel === 'sms' && (
-
- )}
-
+
)
}
diff --git a/lib/components/user/phone-number-editor.tsx b/lib/components/user/phone-number-editor.tsx
index 7e9113a32..4fef908f4 100644
--- a/lib/components/user/phone-number-editor.tsx
+++ b/lib/components/user/phone-number-editor.tsx
@@ -10,7 +10,7 @@ import { isBlank } from '../../util/ui'
import InvisibleA11yLabel from '../util/invisible-a11y-label'
import SpanWithSpace from '../util/span-with-space'
-import { ControlStrip, FakeLabel, InlineStatic } from './styled'
+import { ControlStrip } from './styled'
import PhoneChangeForm, { PhoneChangeSubmitHandler } from './phone-change-form'
import PhoneVerificationForm, {
PhoneVerificationSubmitHandler
@@ -19,7 +19,7 @@ import PhoneVerificationForm, {
export type PhoneCodeRequestHandler = (phoneNumber: string) => void
const PlainLink = styled(SpanWithSpace)`
- color: inherit;
+ color: #757575;
&:hover {
text-decoration: none;
}
@@ -34,6 +34,7 @@ const blankState = {
}
interface Props {
+ descriptorId: string
initialPhoneNumber?: string
initialPhoneNumberVerified?: boolean
intl: IntlShape
@@ -169,7 +170,7 @@ class PhoneNumberEditor extends Component {
}
render() {
- const { initialPhoneNumber, phoneFormatOptions } = this.props
+ const { descriptorId, initialPhoneNumber, phoneFormatOptions } = this.props
const {
isEditing,
phoneNumberReceived,
@@ -220,9 +221,6 @@ class PhoneNumberEditor extends Component {
return (
<>
-
- {ariaAlertContent}
-
{isEditing ? (
{
/>
) : (
-
-
-
-
-
- {shownPhoneNumber}
-
- {/* Invisible parentheses for no-CSS and screen readers */}
- (
- {isPending ? (
-
-
-
- ) : (
-
-
-
- )}
- )
-
+
+ {shownPhoneNumber}
+
+ {/* Invisible parentheses for no-CSS and screen readers */}
+ (
+ {isPending ? (
+
+
+
+ ) : (
+
+
+
+ )}
+ )
)}
+
+ {ariaAlertContent}
+
{isPending && !isEditing && (
Date: Fri, 12 May 2023 12:00:52 -0400
Subject: [PATCH 05/80] refactor(NotificationPrefsPane): Improve layout.
---
.../user/notification-prefs-pane.tsx | 23 ++++++++++++-------
lib/components/user/phone-number-editor.tsx | 10 +++-----
2 files changed, 18 insertions(+), 15 deletions(-)
diff --git a/lib/components/user/notification-prefs-pane.tsx b/lib/components/user/notification-prefs-pane.tsx
index d929c512a..0e72a4db5 100644
--- a/lib/components/user/notification-prefs-pane.tsx
+++ b/lib/components/user/notification-prefs-pane.tsx
@@ -32,9 +32,14 @@ const allowedNotificationChannels = ['email', 'sms']
const NotificationOption = styled.div`
align-items: flex-start;
display: flex;
- gap: 1ch;
margin-bottom: 10px;
+ /* Use bootstrap's spacing between checkbox and label */
+ & > span:first-child {
+ flex-shrink: 0;
+ width: 20px;
+ }
+
label {
display: block;
font-weight: normal;
@@ -77,13 +82,15 @@ const NotificationPrefsPane = ({
const inputDescriptionId = `${inputId}-description`
return (
- {' '}
+
+
+
{type === 'email' ? (
<>
diff --git a/lib/components/user/phone-number-editor.tsx b/lib/components/user/phone-number-editor.tsx
index 4fef908f4..62f9c33e4 100644
--- a/lib/components/user/phone-number-editor.tsx
+++ b/lib/components/user/phone-number-editor.tsx
@@ -8,7 +8,6 @@ import styled from 'styled-components'
import { getAriaPhoneNumber } from '../../util/a11y'
import { isBlank } from '../../util/ui'
import InvisibleA11yLabel from '../util/invisible-a11y-label'
-import SpanWithSpace from '../util/span-with-space'
import { ControlStrip } from './styled'
import PhoneChangeForm, { PhoneChangeSubmitHandler } from './phone-change-form'
@@ -18,7 +17,7 @@ import PhoneVerificationForm, {
export type PhoneCodeRequestHandler = (phoneNumber: string) => void
-const PlainLink = styled(SpanWithSpace)`
+const PlainLink = styled.a`
color: #757575;
&:hover {
text-decoration: none;
@@ -232,15 +231,12 @@ class PhoneNumberEditor extends Component {
) : (
+ {/* Use an anchor so that the aria-label applies and phone actions can be performed,
+ if necessary. Styling will make the text appear plain (mostly). */}
{shownPhoneNumber}
From 08fee5bcf3db667ffe92626df52f1f4f090b3791 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Fri, 12 May 2023 12:33:14 -0400
Subject: [PATCH 06/80] refactor: Refactor fieldset and color styles.
---
.../user/monitored-trip/trip-basics-pane.tsx | 9 ++------
.../trip-notifications-pane.tsx | 15 +++----------
.../user/notification-prefs-pane.tsx | 22 ++++++++-----------
lib/components/user/phone-number-editor.tsx | 3 ++-
lib/components/user/styled.ts | 15 ++++++-------
lib/components/util/button-group.tsx | 11 ++--------
6 files changed, 25 insertions(+), 50 deletions(-)
diff --git a/lib/components/user/monitored-trip/trip-basics-pane.tsx b/lib/components/user/monitored-trip/trip-basics-pane.tsx
index 3ab97bf9e..b2aa897cc 100644
--- a/lib/components/user/monitored-trip/trip-basics-pane.tsx
+++ b/lib/components/user/monitored-trip/trip-basics-pane.tsx
@@ -18,9 +18,9 @@ import styled from 'styled-components'
import type { IntlShape, WrappedComponentProps } from 'react-intl'
import * as userActions from '../../../actions/user'
+import { FieldSet } from '../styled'
import { getErrorStates } from '../../../util/ui'
import { getFormattedDayOfWeekPlural } from '../../../util/monitored-trip'
-import { labelStyle } from '../styled'
import FormattedDayOfWeek from '../../util/formatted-day-of-week'
import FormattedDayOfWeekCompact from '../../util/formatted-day-of-week-compact'
import FormattedValidationError from '../../util/formatted-validation-error'
@@ -65,12 +65,7 @@ const ALL_DAYS = [
] as const
// Styles.
-const AvailableDays = styled.fieldset`
- /* Format like labels. */
- legend {
- ${labelStyle}
- }
-
+const AvailableDays = styled(FieldSet)`
& > span {
border: 1px solid #ccc;
border-left: none;
diff --git a/lib/components/user/monitored-trip/trip-notifications-pane.tsx b/lib/components/user/monitored-trip/trip-notifications-pane.tsx
index a6702f08a..1428b8c22 100644
--- a/lib/components/user/monitored-trip/trip-notifications-pane.tsx
+++ b/lib/components/user/monitored-trip/trip-notifications-pane.tsx
@@ -5,6 +5,7 @@ import { FormattedMessage, IntlShape, useIntl } from 'react-intl'
import React, { Component, ComponentType, FormEvent, ReactNode } from 'react'
import styled from 'styled-components'
+import { FieldSet } from '../styled'
import { IconWithText } from '../../util/styledIcon'
// Element styles
@@ -36,16 +37,6 @@ const Summary = styled.summary`
margin-bottom: 5px;
`
-const NotificationSettings = styled.fieldset`
- /* Format like labels. */
- legend {
- border: none;
- font-size: inherit;
- font-weight: 700;
- margin-bottom: 5px;
- }
-`
-
/**
* A label followed by a dropdown control.
*/
@@ -214,7 +205,7 @@ class TripNotificationsPane extends Component {
)
} else {
notificationSettingsContent = (
-
+
{
-
+
)
}
diff --git a/lib/components/user/notification-prefs-pane.tsx b/lib/components/user/notification-prefs-pane.tsx
index 0e72a4db5..5d95db2d2 100644
--- a/lib/components/user/notification-prefs-pane.tsx
+++ b/lib/components/user/notification-prefs-pane.tsx
@@ -3,7 +3,9 @@ import { FormattedMessage } from 'react-intl'
import React, { Fragment } from 'react'
import styled from 'styled-components'
-import { labelStyle } from './styled'
+import { GRAY_ON_WHITE } from '../util/colors'
+
+import { FieldSet } from './styled'
import { PhoneVerificationSubmitHandler } from './phone-verification-form'
import PhoneNumberEditor, {
PhoneCodeRequestHandler
@@ -34,7 +36,7 @@ const NotificationOption = styled.div`
display: flex;
margin-bottom: 10px;
- /* Use bootstrap's spacing between checkbox and label */
+ /* Match bootstrap's spacing between checkbox and label */
& > span:first-child {
flex-shrink: 0;
width: 20px;
@@ -48,12 +50,8 @@ const NotificationOption = styled.div`
label::first-letter {
text-transform: uppercase;
}
-`
-
-const NotificationOptions = styled.fieldset`
- /* Format
like labels. */
- legend {
- ${labelStyle}
+ label + span {
+ color: ${GRAY_ON_WHITE};
}
`
@@ -71,7 +69,7 @@ const NotificationPrefsPane = ({
return (
-
+
@@ -97,9 +95,7 @@ const NotificationPrefsPane = ({
-
- {email}
-
+ {email}
>
) : (
<>
@@ -120,7 +116,7 @@ const NotificationPrefsPane = ({
)
})}
-
+
)
}
diff --git a/lib/components/user/phone-number-editor.tsx b/lib/components/user/phone-number-editor.tsx
index 62f9c33e4..b53d142de 100644
--- a/lib/components/user/phone-number-editor.tsx
+++ b/lib/components/user/phone-number-editor.tsx
@@ -6,6 +6,7 @@ import React, { Component, createRef, Fragment } from 'react'
import styled from 'styled-components'
import { getAriaPhoneNumber } from '../../util/a11y'
+import { GRAY_ON_WHITE } from '../util/colors'
import { isBlank } from '../../util/ui'
import InvisibleA11yLabel from '../util/invisible-a11y-label'
@@ -18,7 +19,7 @@ import PhoneVerificationForm, {
export type PhoneCodeRequestHandler = (phoneNumber: string) => void
const PlainLink = styled.a`
- color: #757575;
+ color: ${GRAY_ON_WHITE};
&:hover {
text-decoration: none;
}
diff --git a/lib/components/user/styled.ts b/lib/components/user/styled.ts
index 092dfdbd8..ae2c07e0d 100644
--- a/lib/components/user/styled.ts
+++ b/lib/components/user/styled.ts
@@ -77,7 +77,7 @@ export const TripPanelFooter = styled(Panel.Footer)`
`
/** Formats non- elements like s. */
-export const labelStyle = css`
+const labelStyle = css`
border: none;
cursor: default;
font-size: inherit;
@@ -85,9 +85,12 @@ export const labelStyle = css`
margin-bottom: 5px;
`
-export const FakeLabel = styled.span`
- display: block;
- ${labelStyle}
+/** Fieldset with a legend that looks like labels. */
+export const FieldSet = styled.fieldset`
+ /* Format like labels. */
+ legend {
+ ${labelStyle}
+ }
`
/** A container with spacing between controls. */
@@ -103,7 +106,3 @@ export const phoneFieldStyle = css`
vertical-align: middle;
width: 14em;
`
-
-export const InlineStatic = styled.span`
- ${phoneFieldStyle}
-`
diff --git a/lib/components/util/button-group.tsx b/lib/components/util/button-group.tsx
index b4a22e214..882c61bbc 100644
--- a/lib/components/util/button-group.tsx
+++ b/lib/components/util/button-group.tsx
@@ -1,17 +1,10 @@
import styled from 'styled-components'
-import { labelStyle } from '../user/styled'
+import { FieldSet } from '../user/styled'
-const ButtonGroup = styled.fieldset.attrs({
+const ButtonGroup = styled(FieldSet).attrs({
className: 'btn-group'
})`
- display: block;
-
- /* Format like labels. */
- legend {
- ${labelStyle}
- }
-
label::first-letter {
text-transform: uppercase;
}
From cd7ca93a54a5c4f7e55209ce40e901b566a00335 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Fri, 12 May 2023 15:24:36 -0400
Subject: [PATCH 07/80] refactor(NotificationPrefsPane): Improve layout
---
.../user/notification-prefs-pane.tsx | 111 +++++++++---------
1 file changed, 53 insertions(+), 58 deletions(-)
diff --git a/lib/components/user/notification-prefs-pane.tsx b/lib/components/user/notification-prefs-pane.tsx
index 5d95db2d2..2a034c3bd 100644
--- a/lib/components/user/notification-prefs-pane.tsx
+++ b/lib/components/user/notification-prefs-pane.tsx
@@ -12,15 +12,13 @@ import PhoneNumberEditor, {
} from './phone-number-editor'
interface Fields {
+ email: string
+ isPhoneNumberVerified?: boolean
notificationChannel: string
+ phoneNumber?: string
}
interface Props extends FormikProps {
- loggedInUser: {
- email: string
- isPhoneNumberVerified?: boolean
- phoneNumber?: string
- }
onRequestPhoneVerificationCode: PhoneCodeRequestHandler
onSendPhoneVerificationCode: PhoneVerificationSubmitHandler
phoneFormatOptions: {
@@ -59,65 +57,62 @@ const NotificationOption = styled.div`
* User notification preferences pane.
*/
const NotificationPrefsPane = ({
- loggedInUser,
onRequestPhoneVerificationCode,
onSendPhoneVerificationCode,
phoneFormatOptions,
- values: userData // Formik prop // TODO: remove
+ values: userData // Formik prop
}: Props): JSX.Element => {
- const { email, isPhoneNumberVerified, phoneNumber } = loggedInUser
+ const { email, isPhoneNumberVerified, phoneNumber } = userData
return (
-
-
-
-
-
- {allowedNotificationChannels.map((type) => {
- // TODO: If removing the Save/Cancel buttons on the account screen,
- // persist changes immediately when onChange is triggered.
- const inputId = `notification-channel-${type}`
- const inputDescriptionId = `${inputId}-description`
- return (
-
-
-
-
-
- {type === 'email' ? (
- <>
-
-
-
- {email}
- >
- ) : (
- <>
-
-
-
-
- >
- )}
-
-
- )
- })}
-
-
+
+
+
+
+ {allowedNotificationChannels.map((type) => {
+ // TODO: If removing the Save/Cancel buttons on the account screen,
+ // persist changes immediately when onChange is triggered.
+ const inputId = `notification-channel-${type}`
+ const inputDescriptionId = `${inputId}-description`
+ return (
+
+
+
+
+
+ {type === 'email' ? (
+ <>
+
+
+
+ {email}
+ >
+ ) : (
+ <>
+
+
+
+
+ >
+ )}
+
+
+ )
+ })}
+
)
}
From e5bd1f6236e055bff456291007686d36baaba2d2 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Fri, 12 May 2023 15:39:32 -0400
Subject: [PATCH 08/80] feat(UserAccountScreen): Support saving multiple
notification channels.
---
lib/components/user/user-account-screen.js | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/lib/components/user/user-account-screen.js b/lib/components/user/user-account-screen.js
index 83eefd4b9..b153f5667 100644
--- a/lib/components/user/user-account-screen.js
+++ b/lib/components/user/user-account-screen.js
@@ -5,6 +5,7 @@ import { connect } from 'react-redux'
import { Form, Formik } from 'formik'
import { injectIntl } from 'react-intl'
import { withAuthenticationRequired } from '@auth0/auth0-react'
+import clone from 'clone'
import React, { Component } from 'react'
import * as uiActions from '../../actions/ui'
@@ -26,7 +27,6 @@ const validationSchema = yup.object({
hasConsentedToTerms: yup
.boolean()
.oneOf([true], 'You must agree to the terms to continue.'),
- notificationChannel: yup.string().oneOf(['email', 'sms', 'none']),
savedLocations: yup.array().of(
yup.object({
address: yup.string(),
@@ -43,9 +43,14 @@ const validationSchema = yup.object({
class UserAccountScreen extends Component {
_updateUserPrefs = async (userData, silentOnSucceed = false) => {
const { createOrUpdateUser, intl } = this.props
- // TODO: Change state of Save button while the update action takes place.
- await createOrUpdateUser(userData, silentOnSucceed, intl)
+ // Convert the notification attributes from array to comma-separated string.
+ const passedUserData = clone(userData)
+ const { notificationChannel } = passedUserData
+ if (typeof notificationChannel === 'object' && notificationChannel.length) {
+ passedUserData.notificationChannel = notificationChannel.join(',')
+ }
+ await createOrUpdateUser(passedUserData, silentOnSucceed, intl)
// TODO: Handle UI feedback (currently an alert() dialog inside createOrUpdateUser).
}
@@ -101,20 +106,22 @@ class UserAccountScreen extends Component {
await verifyPhoneNumber(code, intl)
}
- // TODO: Update title bar during componentDidMount.
-
render() {
const { auth0, isCreating, itemId, loggedInUser, phoneFormatOptions } =
this.props
const DisplayComponent = isCreating
? NewAccountWizard
: ExistingAccountDisplay
+ const loggedInUserWithNotificationArray = {
+ ...loggedInUser,
+ notificationChannel: loggedInUser.notificationChannel.split(',')
+ }
return (
Date: Fri, 12 May 2023 16:20:17 -0400
Subject: [PATCH 09/80] feat(NotificationPrefsPane): Add push notification
option.
---
i18n/en-US.yml | 1 +
i18n/es.yml | 1 +
i18n/fr.yml | 1 +
i18n/ko.yml | 1 +
i18n/vi.yml | 1 +
i18n/zh.yml | 1 +
lib/components/user/notification-prefs-pane.tsx | 14 +++++++++++---
7 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/i18n/en-US.yml b/i18n/en-US.yml
index 959eb6980..5143f007f 100644
--- a/i18n/en-US.yml
+++ b/i18n/en-US.yml
@@ -129,6 +129,7 @@ common:
walk: Walk
notifications:
email: email
+ push: push notifications
sms: SMS
places:
custom: custom
diff --git a/i18n/es.yml b/i18n/es.yml
index 9cfc2d409..238604ce2 100644
--- a/i18n/es.yml
+++ b/i18n/es.yml
@@ -133,6 +133,7 @@ common:
walk: Caminar
notifications:
email: correo electrónico
+ push: notificaciones push
sms: Mensaje de texto
places:
custom: personalizado
diff --git a/i18n/fr.yml b/i18n/fr.yml
index e3bfde8e1..0a600bbb8 100644
--- a/i18n/fr.yml
+++ b/i18n/fr.yml
@@ -137,6 +137,7 @@ common:
walk: À pied
notifications:
email: e-mail
+ push: notifications push
sms: SMS
places:
custom: divers
diff --git a/i18n/ko.yml b/i18n/ko.yml
index 627b4a9de..597d963c1 100644
--- a/i18n/ko.yml
+++ b/i18n/ko.yml
@@ -119,6 +119,7 @@ common:
walk: 걷기
notifications:
email: 이메일
+ push: 푸시 알림
sms: SMS
places:
custom: 사용자 정의
diff --git a/i18n/vi.yml b/i18n/vi.yml
index 7b582ca5c..f9aa6fc98 100644
--- a/i18n/vi.yml
+++ b/i18n/vi.yml
@@ -128,6 +128,7 @@ common:
walk: Đi bộ
notifications:
email: e-mail
+ push: thông báo đẩy
sms: tin nhắn
places:
custom: phong tục
diff --git a/i18n/zh.yml b/i18n/zh.yml
index 59f0f3fec..d61801e44 100644
--- a/i18n/zh.yml
+++ b/i18n/zh.yml
@@ -119,6 +119,7 @@ common:
walk: 步行
notifications:
email: 电子邮件
+ push: 推送通知
sms: 短信
places:
custom: 习俗
diff --git a/lib/components/user/notification-prefs-pane.tsx b/lib/components/user/notification-prefs-pane.tsx
index 2a034c3bd..0804875e8 100644
--- a/lib/components/user/notification-prefs-pane.tsx
+++ b/lib/components/user/notification-prefs-pane.tsx
@@ -16,6 +16,7 @@ interface Fields {
isPhoneNumberVerified?: boolean
notificationChannel: string
phoneNumber?: string
+ pushDeviceName?: string
}
interface Props extends FormikProps {
@@ -26,7 +27,7 @@ interface Props extends FormikProps {
}
}
-const allowedNotificationChannels = ['email', 'sms']
+const allowedNotificationChannels = ['email', 'sms', 'push']
// Styles
const NotificationOption = styled.div`
@@ -62,7 +63,7 @@ const NotificationPrefsPane = ({
phoneFormatOptions,
values: userData // Formik prop
}: Props): JSX.Element => {
- const { email, isPhoneNumberVerified, phoneNumber } = userData
+ const { email, isPhoneNumberVerified, phoneNumber, pushDeviceName } = userData
return (
@@ -93,7 +94,7 @@ const NotificationPrefsPane = ({
{email}
>
- ) : (
+ ) : type === 'sms' ? (
<>
@@ -107,6 +108,13 @@ const NotificationPrefsPane = ({
phoneFormatOptions={phoneFormatOptions}
/>
>
+ ) : (
+ <>
+
+
+
+ {pushDeviceName}
+ >
)}
From 42f01a70538fd65af0a670ea659170fd616a01a5 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Fri, 12 May 2023 16:28:36 -0400
Subject: [PATCH 10/80] improvement(NotificationPrefsPane): Add explanation if
no device has been set for push notifications
---
i18n/en-US.yml | 1 +
i18n/es.yml | 1 +
i18n/fr.yml | 1 +
lib/components/user/notification-prefs-pane.tsx | 8 +++++++-
4 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/i18n/en-US.yml b/i18n/en-US.yml
index 5143f007f..26f9af5a6 100644
--- a/i18n/en-US.yml
+++ b/i18n/en-US.yml
@@ -357,6 +357,7 @@ components:
description: The content you requested is not available.
header: Content not found
NotificationPrefsPane:
+ noDeviceForPush: Register your device using the mobile app to access this setting.
noneSelect: Don't notify me
notificationChannelPrompt: "Receive notifications about your saved trips via:"
notificationEmailDetail: "Notification emails will be sent to:"
diff --git a/i18n/es.yml b/i18n/es.yml
index 238604ce2..883c408a4 100644
--- a/i18n/es.yml
+++ b/i18n/es.yml
@@ -363,6 +363,7 @@ components:
description: El contenido que ha solicitado no está disponible.
header: No se encontró el contenido
NotificationPrefsPane:
+ noDeviceForPush: Regístrese con la aplicación móvil para acceder a esta configuración.
noneSelect: No enviar notificaciones
notificationChannelPrompt: "Recibir notificaciones para sus viajes guardados por :"
notificationEmailDetail: "Los correos electrónicos de notificación se enviarán a:"
diff --git a/i18n/fr.yml b/i18n/fr.yml
index 0a600bbb8..cf133eefe 100644
--- a/i18n/fr.yml
+++ b/i18n/fr.yml
@@ -369,6 +369,7 @@ components:
description: Le contenu que vous avez demandé n'est pas disponible.
header: Contenu introuvable
NotificationPrefsPane:
+ noDeviceForPush: Inscrivez-vous avec l'application mobile pour accéder à ce paramètre.
noneSelect: Ne pas me notifier
notificationChannelPrompt: "Recevoir des notifications sur vos trajets enregistrés par :"
notificationEmailDetail: "Les courriers de notification seront envoyés à :"
diff --git a/lib/components/user/notification-prefs-pane.tsx b/lib/components/user/notification-prefs-pane.tsx
index 0804875e8..a89be00e7 100644
--- a/lib/components/user/notification-prefs-pane.tsx
+++ b/lib/components/user/notification-prefs-pane.tsx
@@ -80,6 +80,8 @@ const NotificationPrefsPane = ({
- {pushDeviceName}
+
+ {pushDeviceName || (
+
+ )}
+
>
)}
From a6005d3816be30a455e585c08f1a03bf7cca6b39 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Fri, 12 May 2023 16:35:24 -0400
Subject: [PATCH 11/80] chore(i18n): Remove unused messages.
---
i18n/en-US.yml | 2 --
i18n/es.yml | 2 --
i18n/fr.yml | 2 --
i18n/ko.yml | 2 --
i18n/vi.yml | 2 --
i18n/zh.yml | 2 --
6 files changed, 12 deletions(-)
diff --git a/i18n/en-US.yml b/i18n/en-US.yml
index 26f9af5a6..d1ee7d1a3 100644
--- a/i18n/en-US.yml
+++ b/i18n/en-US.yml
@@ -358,9 +358,7 @@ components:
header: Content not found
NotificationPrefsPane:
noDeviceForPush: Register your device using the mobile app to access this setting.
- noneSelect: Don't notify me
notificationChannelPrompt: "Receive notifications about your saved trips via:"
- notificationEmailDetail: "Notification emails will be sent to:"
PhoneNumberEditor:
changeNumber: Change number
invalidCode: Please enter 6 digits for the validation code.
diff --git a/i18n/es.yml b/i18n/es.yml
index 883c408a4..dd7f4f833 100644
--- a/i18n/es.yml
+++ b/i18n/es.yml
@@ -364,9 +364,7 @@ components:
header: No se encontró el contenido
NotificationPrefsPane:
noDeviceForPush: Regístrese con la aplicación móvil para acceder a esta configuración.
- noneSelect: No enviar notificaciones
notificationChannelPrompt: "Recibir notificaciones para sus viajes guardados por :"
- notificationEmailDetail: "Los correos electrónicos de notificación se enviarán a:"
PhoneNumberEditor:
changeNumber: Cambiar número de teléfono
invalidCode: Introduzca 6 dígitos para el código de validación.
diff --git a/i18n/fr.yml b/i18n/fr.yml
index cf133eefe..a19401137 100644
--- a/i18n/fr.yml
+++ b/i18n/fr.yml
@@ -370,9 +370,7 @@ components:
header: Contenu introuvable
NotificationPrefsPane:
noDeviceForPush: Inscrivez-vous avec l'application mobile pour accéder à ce paramètre.
- noneSelect: Ne pas me notifier
notificationChannelPrompt: "Recevoir des notifications sur vos trajets enregistrés par :"
- notificationEmailDetail: "Les courriers de notification seront envoyés à :"
PhoneNumberEditor:
changeNumber: Changer de numéro
invalidCode: Le code de vérification doit comporter 6 chiffres.
diff --git a/i18n/ko.yml b/i18n/ko.yml
index 597d963c1..53fa7c86e 100644
--- a/i18n/ko.yml
+++ b/i18n/ko.yml
@@ -336,9 +336,7 @@ components:
description: 요청한 콘텐츠를 사용할 수 없습니다.
header: 콘텐츠를 찾을 수 없음
NotificationPrefsPane:
- noneSelect: 알림 거부
notificationChannelPrompt: "저장된 여행의 알림을 받는 방법:"
- notificationEmailDetail: "알림 이메일이 다음으로 전송됩니다:"
PhoneNumberEditor:
changeNumber: 번호 변경
invalidCode: 확인 코드 6 자리를 입력하세요.
diff --git a/i18n/vi.yml b/i18n/vi.yml
index f9aa6fc98..704c1faff 100644
--- a/i18n/vi.yml
+++ b/i18n/vi.yml
@@ -344,9 +344,7 @@ components:
description: Nội dung bạn yêu cầu không có sẵn.
header: Không tìm thấy nội dung
NotificationPrefsPane:
- noneSelect: Đừng thông báo cho tôi
notificationChannelPrompt: "Nhận thông báo về các chuyến đi đã lưu bằng:"
- notificationEmailDetail: "Email thông báo sẽ được gửi đến:"
PhoneNumberEditor:
changeNumber: Thay đổi số điện thoại
invalidCode: Vui lòng nhập 6 chữ số cho mã xác thực.
diff --git a/i18n/zh.yml b/i18n/zh.yml
index d61801e44..5805c2cd6 100644
--- a/i18n/zh.yml
+++ b/i18n/zh.yml
@@ -336,9 +336,7 @@ components:
description: 您要求的内容不存在.
header: 未找到内容
NotificationPrefsPane:
- noneSelect: 不要通知我
notificationChannelPrompt: "如何接收已保存行程的通知:"
- notificationEmailDetail: "通知邮件将被发送至:"
PhoneNumberEditor:
changeNumber: 更改电话号码
invalidCode: 请输入6位数的验证码.
From 459fa01f531f27abf9ac7fc8ee2cae347ff4c736 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Thu, 18 May 2023 12:33:53 -0400
Subject: [PATCH 12/80] chore(i18n): Tweak wording when no device is
registered.
---
i18n/en-US.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/i18n/en-US.yml b/i18n/en-US.yml
index d1ee7d1a3..03677b927 100644
--- a/i18n/en-US.yml
+++ b/i18n/en-US.yml
@@ -357,7 +357,7 @@ components:
description: The content you requested is not available.
header: Content not found
NotificationPrefsPane:
- noDeviceForPush: Register your device using the mobile app to access this setting.
+ noDeviceForPush: Register your device using the mobile app to access push notifications.
notificationChannelPrompt: "Receive notifications about your saved trips via:"
PhoneNumberEditor:
changeNumber: Change number
From edc4cc8bb941f2b880b4d10dc04bea6c25f66dcd Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Thu, 18 May 2023 14:13:14 -0400
Subject: [PATCH 13/80] fix(UserAccountScreen): Send blank string to server if
no notif channels are selected.
---
lib/components/user/user-account-screen.js | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/lib/components/user/user-account-screen.js b/lib/components/user/user-account-screen.js
index b153f5667..6b05245be 100644
--- a/lib/components/user/user-account-screen.js
+++ b/lib/components/user/user-account-screen.js
@@ -47,7 +47,10 @@ class UserAccountScreen extends Component {
// Convert the notification attributes from array to comma-separated string.
const passedUserData = clone(userData)
const { notificationChannel } = passedUserData
- if (typeof notificationChannel === 'object' && notificationChannel.length) {
+ if (
+ typeof notificationChannel === 'object' &&
+ typeof notificationChannel.length === 'number'
+ ) {
passedUserData.notificationChannel = notificationChannel.join(',')
}
await createOrUpdateUser(passedUserData, silentOnSucceed, intl)
From 14f73d60665c1e8120a91c2455670832c42453c8 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Wed, 12 Jul 2023 16:36:25 -0400
Subject: [PATCH 14/80] refactor(NotificationPrefsPane): Adjust push devices
field name
---
lib/components/user/notification-prefs-pane.tsx | 9 ++++++---
lib/components/user/types.ts | 1 +
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/lib/components/user/notification-prefs-pane.tsx b/lib/components/user/notification-prefs-pane.tsx
index 47db97795..84a691eeb 100644
--- a/lib/components/user/notification-prefs-pane.tsx
+++ b/lib/components/user/notification-prefs-pane.tsx
@@ -57,7 +57,7 @@ const NotificationPrefsPane = ({
phoneFormatOptions,
values: userData // Formik prop
}: Props): JSX.Element => {
- const { email, isPhoneNumberVerified, phoneNumber, pushDeviceName } = userData
+ const { email, isPhoneNumberVerified, phoneNumber, pushDevices } = userData
return (
@@ -75,7 +75,7 @@ const NotificationPrefsPane = ({
- {pushDeviceName || (
+ {pushDevices ? (
+ // TODO: i18n
+ `${pushDevices} devices registered`
+ ) : (
)}
diff --git a/lib/components/user/types.ts b/lib/components/user/types.ts
index 47c583755..4360052d9 100644
--- a/lib/components/user/types.ts
+++ b/lib/components/user/types.ts
@@ -22,6 +22,7 @@ export interface User {
isPhoneNumberVerified?: boolean
notificationChannel?: string
phoneNumber?: string
+ pushDevices?: number
savedLocations?: UserSavedLocation[]
storeTripHistory?: boolean
}
From 72980b4cdbd493a9f64a9af99814b2f78bc291ef Mon Sep 17 00:00:00 2001
From: miles-grant-ibigroup
Date: Tue, 8 Aug 2023 14:17:24 -0400
Subject: [PATCH 15/80] refactor: remove old view trip button
---
lib/components/viewers/view-trip-button.tsx | 56 ---------------------
lib/index.js | 2 -
2 files changed, 58 deletions(-)
delete mode 100644 lib/components/viewers/view-trip-button.tsx
diff --git a/lib/components/viewers/view-trip-button.tsx b/lib/components/viewers/view-trip-button.tsx
deleted file mode 100644
index 1cf0fce9e..000000000
--- a/lib/components/viewers/view-trip-button.tsx
+++ /dev/null
@@ -1,56 +0,0 @@
-import { Button } from 'react-bootstrap'
-import { connect } from 'react-redux'
-import { FormattedMessage } from 'react-intl'
-import React, { Component } from 'react'
-
-import { MainPanelContent } from '../../actions/ui-constants'
-import { setMainPanelContent, setViewedTrip } from '../../actions/ui'
-
-type Props = {
- fromIndex: number
- setMainPanelContent: (panel: number | null) => void
- setViewedTrip({
- fromIndex,
- toIndex,
- tripId
- }: {
- fromIndex: number
- toIndex: number
- tripId: string
- }): void
- text: JSX.Element
- toIndex: number
- tripId: string
-}
-
-class ViewTripButton extends Component {
- _onClick = () => {
- this.props.setMainPanelContent(MainPanelContent.TRIP_VIEWER)
- this.props.setViewedTrip({
- fromIndex: this.props.fromIndex,
- toIndex: this.props.toIndex,
- tripId: this.props.tripId
- })
- }
-
- render() {
- return (
-
- {this.props.text || (
-
- )}
-
- )
- }
-}
-
-const mapDispatchToProps = {
- setMainPanelContent,
- setViewedTrip
-}
-
-export default connect(null, mapDispatchToProps)(ViewTripButton)
diff --git a/lib/index.js b/lib/index.js
index dea45ab4e..3fc9e61c5 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -27,7 +27,6 @@ import NavLoginButton from './components/user/nav-login-button'
import NavLoginButtonAuth0 from './components/user/nav-login-button-auth0'
import StopViewer from './components/viewers/stop-viewer'
import ViewStopButton from './components/viewers/view-stop-button'
-import ViewTripButton from './components/viewers/view-trip-button'
import ViewerContainer from './components/viewers/viewer-container'
import ResponsiveWebapp from './components/app/responsive-webapp'
import AppMenu from './components/app/app-menu'
@@ -91,7 +90,6 @@ export {
StopViewer,
ViewerContainer,
ViewStopButton,
- ViewTripButton,
// user-related components
NavLoginButton,
From ed93acdd705c16598cbdc7adf20e363bd5ded63c Mon Sep 17 00:00:00 2001
From: miles-grant-ibigroup
Date: Tue, 8 Aug 2023 14:41:19 -0400
Subject: [PATCH 16/80] refactor: make use of new OTP2 props
---
lib/components/viewers/trip-viewer.js | 28 +++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/lib/components/viewers/trip-viewer.js b/lib/components/viewers/trip-viewer.js
index 2336b558c..df40cf95b 100644
--- a/lib/components/viewers/trip-viewer.js
+++ b/lib/components/viewers/trip-viewer.js
@@ -88,6 +88,13 @@ class TripViewer extends Component {
timeZone: homeTimezone
})
+ const fromIndex = tripData?.stops?.findIndex(
+ (stop) => stop.stopId === viewedTrip?.fromStopId
+ )
+ const toIndex = tripData?.stops?.findIndex(
+ (stop) => stop.stopId === viewedTrip?.toStopId
+ )
+
return (
@@ -133,20 +140,16 @@ class TripViewer extends Component {
screenreader or keyboard nav, the departure, arrival, and stop viewer links
are all accessible without having to go through all the stops not on the trip. */}
- {viewedTrip?.fromIndex && (
+ {fromIndex && (
- {tripData.stops?.[viewedTrip?.fromIndex]?.name}
-
+ {tripData.stops?.[fromIndex]?.name}
),
disembarkAtStop: (
-
- {tripData.stops?.[viewedTrip?.toIndex]?.name}
-
+ {tripData.stops?.[toIndex]?.name}
)
}}
/>
@@ -197,12 +200,12 @@ class TripViewer extends Component {
}
let stopLabel = null
- if (viewedTrip?.fromIndex === i) {
+ if (fromIndex === i) {
stopLabel = (
)
}
- if (viewedTrip?.toIndex === i) {
+ if (toIndex === i) {
stopLabel = (
)
@@ -210,12 +213,9 @@ class TripViewer extends Component {
// determine whether to show highlight in strip map
let highlightClass
- if (i === viewedTrip?.fromIndex) {
+ if (i === fromIndex) {
highlightClass = 'strip-map-highlight-first'
- } else if (
- i > viewedTrip?.fromIndex &&
- i < viewedTrip.toIndex
- ) {
+ } else if (i > fromIndex && i < toIndex) {
highlightClass = 'strip-map-highlight'
} else if (i === viewedTrip?.toIndex) {
highlightClass = 'strip-map-highlight-last'
From 4a2e1c6a092a0264dccd2c2970a6512da7891ddf Mon Sep 17 00:00:00 2001
From: miles-grant-ibigroup
Date: Wed, 9 Aug 2023 10:20:31 -0400
Subject: [PATCH 17/80] refactor: use correct toIndex
---
lib/components/viewers/trip-viewer.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/components/viewers/trip-viewer.js b/lib/components/viewers/trip-viewer.js
index df40cf95b..0c4991977 100644
--- a/lib/components/viewers/trip-viewer.js
+++ b/lib/components/viewers/trip-viewer.js
@@ -217,7 +217,7 @@ class TripViewer extends Component {
highlightClass = 'strip-map-highlight-first'
} else if (i > fromIndex && i < toIndex) {
highlightClass = 'strip-map-highlight'
- } else if (i === viewedTrip?.toIndex) {
+ } else if (i === toIndex) {
highlightClass = 'strip-map-highlight-last'
}
From 1c4d7d8a66d15d3625028037f416e2beddee7af3 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Tue, 15 Aug 2023 17:02:59 -0400
Subject: [PATCH 18/80] refactor(i18n): Remove unused strings.
---
i18n/en-US.yml | 3 ---
i18n/fr.yml | 5 -----
2 files changed, 8 deletions(-)
diff --git a/i18n/en-US.yml b/i18n/en-US.yml
index d6f6650a3..5abed7019 100644
--- a/i18n/en-US.yml
+++ b/i18n/en-US.yml
@@ -354,11 +354,8 @@ components:
description: The content you requested is not available.
header: Content not found
NotificationPrefsPane:
- description: You can receive notifications about trips you frequently take.
noDeviceForPush: Register your device using the mobile app to access push notifications.
- noneSelect: Don't notify me
notificationChannelPrompt: "Receive notifications about your saved trips via:"
- notificationEmailDetail: "Notification emails will be sent to:"
OTP2ErrorRenderer:
LOCATION_NOT_FOUND:
body: >-
diff --git a/i18n/fr.yml b/i18n/fr.yml
index c6af5b03b..3d2e4afe0 100644
--- a/i18n/fr.yml
+++ b/i18n/fr.yml
@@ -367,13 +367,8 @@ components:
description: Le contenu que vous avez demandé n'est pas disponible.
header: Contenu introuvable
NotificationPrefsPane:
- description: >-
- Vous pouvez recevoir des notifications sur les trajets que vous effectuez
- fréquemment.
noDeviceForPush: Inscrivez-vous avec l'application mobile pour accéder à ce paramètre.
- noneSelect: Ne pas me notifier
notificationChannelPrompt: "Recevoir des notifications sur vos trajets par :"
- notificationEmailDetail: "Les courriers de notification seront envoyés à :"
OTP2ErrorRenderer:
LOCATION_NOT_FOUND:
body: >-
From 9ae5bfda7a0b9fff321465c130bb0810da4a105c Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Wed, 23 Aug 2023 12:20:18 -0400
Subject: [PATCH 19/80] refactor(NotificationPrefsPane): Apply review feedback.
---
i18n/i18n-exceptions.json | 5 ++
.../user/notification-prefs-pane.tsx | 52 +++++++------------
2 files changed, 25 insertions(+), 32 deletions(-)
diff --git a/i18n/i18n-exceptions.json b/i18n/i18n-exceptions.json
index db534b0e4..60f5855cd 100644
--- a/i18n/i18n-exceptions.json
+++ b/i18n/i18n-exceptions.json
@@ -1,5 +1,10 @@
{
"groups": {
+ "common.notifications.*": [
+ "email",
+ "sms",
+ "push"
+ ],
"components.OTP2ErrorRenderer.*.body": [
"LOCATION_NOT_FOUND",
"NO_STOPS_IN_RANGE",
diff --git a/lib/components/user/notification-prefs-pane.tsx b/lib/components/user/notification-prefs-pane.tsx
index 84a691eeb..3636dedec 100644
--- a/lib/components/user/notification-prefs-pane.tsx
+++ b/lib/components/user/notification-prefs-pane.tsx
@@ -83,41 +83,29 @@ const NotificationPrefsPane = ({
/>
+
+
+
{type === 'email' ? (
- <>
-
-
-
- {email}
- >
+ {email}
) : type === 'sms' ? (
- <>
-
-
-
-
- >
+
) : (
- <>
-
-
-
-
- {pushDevices ? (
- // TODO: i18n
- `${pushDevices} devices registered`
- ) : (
-
- )}
-
- >
+
+ {pushDevices ? (
+ // TODO: i18n
+ `${pushDevices} devices registered`
+ ) : (
+
+ )}
+
)}
From cddbd028b30f028063551765627b7e9aa011f922 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Wed, 23 Aug 2023 12:39:50 -0400
Subject: [PATCH 20/80] refactor(TripNotificationsPane): Enumerate selected
notif channels.
---
.../trip-notifications-pane.tsx | 32 ++++++++++---------
1 file changed, 17 insertions(+), 15 deletions(-)
diff --git a/lib/components/user/monitored-trip/trip-notifications-pane.tsx b/lib/components/user/monitored-trip/trip-notifications-pane.tsx
index 1428b8c22..50145d780 100644
--- a/lib/components/user/monitored-trip/trip-notifications-pane.tsx
+++ b/lib/components/user/monitored-trip/trip-notifications-pane.tsx
@@ -1,7 +1,7 @@
import { Alert, FormControl } from 'react-bootstrap'
import { ExclamationTriangle } from '@styled-icons/fa-solid/ExclamationTriangle'
import { Field, FormikProps } from 'formik'
-import { FormattedMessage, IntlShape, useIntl } from 'react-intl'
+import { FormattedList, FormattedMessage, IntlShape, useIntl } from 'react-intl'
import React, { Component, ComponentType, FormEvent, ReactNode } from 'react'
import styled from 'styled-components'
@@ -179,7 +179,8 @@ class TripNotificationsPane extends Component {
render(): JSX.Element {
const { notificationChannel, values } = this.props
- const areNotificationsDisabled = notificationChannel === 'none'
+ const areNotificationsDisabled =
+ notificationChannel === 'none' || !notificationChannel?.length
// Define a common trip delay field for simplicity, set to the smallest between the
// retrieved departure/arrival delay attributes.
const commonDelayThreshold = Math.min(
@@ -204,24 +205,25 @@ class TripNotificationsPane extends Component {
)
} else {
+ const selectedChannels = notificationChannel
+ .split(',')
+ .filter((channel) => channel?.length)
+ .map((channel) => (
+
+ ))
notificationSettingsContent = (
- )
- }
- : {
- channel: (
-
- )
- }
- }
+ values={{
+ channel: (
+
+ )
+ }}
/>
From 1edbbb9d1e26b3de845ca1accce534aa1a8a0a25 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Tue, 29 Aug 2023 13:46:29 -0400
Subject: [PATCH 21/80] improvement(BatchSettings): Alert if user clicks Plan
Trip when no OTP query will be issued.
---
i18n/en-US.yml | 1 +
i18n/fr.yml | 1 +
lib/actions/api-constants.ts | 5 +++++
lib/actions/apiV2.js | 7 ++++++-
lib/components/form/batch-settings.tsx | 12 +++++++++++-
5 files changed, 24 insertions(+), 2 deletions(-)
create mode 100644 lib/actions/api-constants.ts
diff --git a/i18n/en-US.yml b/i18n/en-US.yml
index 613156575..03d9611a4 100644
--- a/i18n/en-US.yml
+++ b/i18n/en-US.yml
@@ -227,6 +227,7 @@ components:
modeSelectorLabel: Select a transit mode
BatchSettings:
destination: destination
+ invalidModeSelection: Cannot plan a trip using the selected modes.
origin: origin
planTripTooltip: Plan trip
validationMessage: "Please define the following fields to plan a trip: {issues}"
diff --git a/i18n/fr.yml b/i18n/fr.yml
index 742db4275..326179282 100644
--- a/i18n/fr.yml
+++ b/i18n/fr.yml
@@ -238,6 +238,7 @@ components:
modeSelectorLabel: Sélectionnez un mode de transport
BatchSettings:
destination: destination
+ invalidModeSelection: Impossible de planifier un trajet avec les modes sélectionnés.
origin: point de départ
planTripTooltip: Planifier le trajet
validationMessage: >-
diff --git a/lib/actions/api-constants.ts b/lib/actions/api-constants.ts
new file mode 100644
index 000000000..b47743b9b
--- /dev/null
+++ b/lib/actions/api-constants.ts
@@ -0,0 +1,5 @@
+export const RoutingQueryResult = {
+ INVALID_MODE_SELECTION: 2,
+ INVALID_QUERY: 1,
+ SUCCESS: 0
+}
diff --git a/lib/actions/apiV2.js b/lib/actions/apiV2.js
index 3b9eba694..5c82ec36a 100644
--- a/lib/actions/apiV2.js
+++ b/lib/actions/apiV2.js
@@ -41,6 +41,7 @@ import {
updateOtpUrlParams
} from './api'
import { rememberPlace } from './user'
+import { RoutingQueryResult } from './api-constants'
import { setItineraryView } from './ui'
import { zoomToPlace } from './map'
@@ -840,7 +841,7 @@ export function routingQuery(searchId = null, updateSearchInReducer) {
// Don't permit a routing query if the query is invalid
if (!queryIsValid(state)) {
console.warn('Query is invalid. Aborting routing query', currentQuery)
- return
+ return RoutingQueryResult.INVALID_QUERY
}
const {
@@ -1007,6 +1008,10 @@ export function routingQuery(searchId = null, updateSearchInReducer) {
if (isNewSearch || params.ui_activeSearch !== searchId) {
dispatch(updateOtpUrlParams(state, searchId))
}
+
+ return combinations.length === 0
+ ? RoutingQueryResult.INVALID_MODE_SELECTION
+ : RoutingQueryResult.SUCCESS
}
}
diff --git a/lib/components/form/batch-settings.tsx b/lib/components/form/batch-settings.tsx
index 6cc65fce4..c005d05a1 100644
--- a/lib/components/form/batch-settings.tsx
+++ b/lib/components/form/batch-settings.tsx
@@ -26,6 +26,7 @@ import { ComponentContext } from '../../util/contexts'
import { generateModeSettingValues } from '../../util/api'
import { getActiveSearch, hasValidLocation } from '../../util/state'
import { getFormattedMode } from '../../util/i18n'
+import { RoutingQueryResult } from '../../actions/api-constants'
import { StyledIconWrapper } from '../util/styledIcon'
import {
@@ -165,7 +166,16 @@ function BatchSettings({
// Plan trip.
updateQueryTimeIfLeavingNow()
- routingQuery()
+ const routingQueryResult = routingQuery()
+
+ // If mode combination is not valid (i.e. produced no query), alert the user.
+ if (routingQueryResult === RoutingQueryResult.INVALID_MODE_SELECTION) {
+ window.alert(
+ intl.formatMessage({
+ id: 'components.BatchSettings.invalidModeSelection'
+ })
+ )
+ }
}, [
currentQuery,
intl,
From 2c6aacd1fd1c6563a48a8dc3507fa51acf68605d Mon Sep 17 00:00:00 2001
From: miles-grant-ibigroup
Date: Tue, 29 Aug 2023 16:19:20 -0400
Subject: [PATCH 22/80] fix(batch ui): OTP2 fare support
---
lib/components/narrative/default/default-itinerary.js | 8 ++++----
lib/util/state.js | 6 ++++--
2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/lib/components/narrative/default/default-itinerary.js b/lib/components/narrative/default/default-itinerary.js
index f7f98e49c..bfbf25518 100644
--- a/lib/components/narrative/default/default-itinerary.js
+++ b/lib/components/narrative/default/default-itinerary.js
@@ -20,8 +20,8 @@ import {
getAccessibilityScoreForItinerary,
itineraryHasAccessibilityScores
} from '../../../util/accessibility-routing'
+import { getFare, getTotalFare } from '../../../util/state'
import { getFirstLegStartTime } from '../../../util/itinerary'
-import { getTotalFare } from '../../../util/state'
import { Icon, StyledIconWrapperTextAlign } from '../../util/styledIcon'
import { localizeGradationMap } from '../utils'
import FieldTripGroupSize from '../../admin/field-trip-itinerary-group-size'
@@ -121,7 +121,7 @@ const ITINERARY_ATTRIBUTES = [
id: 'cost',
order: 2,
render: (itinerary, options, defaultFareType) => {
- const fare = getTotalFare(itinerary, options.configCosts, defaultFareType)
+ const fare = getFare(itinerary, defaultFareType)
const currency = getItineraryCost(
itinerary.legs,
defaultFareType.mediumId,
@@ -142,11 +142,11 @@ const ITINERARY_ATTRIBUTES = [
return (
)
}
diff --git a/lib/util/state.js b/lib/util/state.js
index 1d2f35f15..c25b0b615 100644
--- a/lib/util/state.js
+++ b/lib/util/state.js
@@ -99,8 +99,10 @@ export function getTotalFare(
let drivingCost = 0
let hasBikeshare = false
let transitFareNotProvided = false
+ let rideHailTrip = false
itinerary.legs.forEach((leg) => {
- if (leg.mode === 'CAR') {
+ rideHailTrip = rideHailTrip || leg?.rideHailingEstimate
+ if (leg.mode === 'CAR' && !rideHailTrip) {
// Convert meters to miles and multiple by cost per mile.
drivingCost += leg.distance * 0.000621371 * costs.drivingCentsPerMile
}
@@ -121,7 +123,7 @@ export function getTotalFare(
if (transitFareNotProvided) return null
const bikeshareCost = hasBikeshare ? costs.bikeshareTripCostCents : 0
// If some leg uses driving, add parking cost to the total.
- if (drivingCost > 0) drivingCost += costs.carParkingCostCents
+ if (drivingCost > 0 && !rideHailTrip) drivingCost += costs.carParkingCostCents
return bikeshareCost + drivingCost + transitFare + maxTNCFare * 100
}
From 1870e93eb30445fae0ba97d994b73701437763d8 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Tue, 22 Aug 2023 14:56:33 -0400
Subject: [PATCH 23/80] fix(create-otp-reducer): Ensure that responses for mode
combos are stored in same order as the combo
---
lib/actions/apiV2.js | 3 ++-
lib/components/narrative/narrative-itineraries.js | 2 +-
lib/reducers/create-otp-reducer.js | 9 ++++++++-
3 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/lib/actions/apiV2.js b/lib/actions/apiV2.js
index 3b9eba694..839eb7fea 100644
--- a/lib/actions/apiV2.js
+++ b/lib/actions/apiV2.js
@@ -919,7 +919,7 @@ export function routingQuery(searchId = null, updateSearchInReducer) {
dispatch(setItineraryView(ItineraryView.LIST))
- combinations.forEach((combo) => {
+ combinations.forEach((combo, index) => {
const query = generateOtp2Query(combo)
dispatch(
createGraphQLQueryAction(
@@ -982,6 +982,7 @@ export function routingQuery(searchId = null, updateSearchInReducer) {
}
return {
+ index,
response: {
plan: {
...response.data?.plan,
diff --git a/lib/components/narrative/narrative-itineraries.js b/lib/components/narrative/narrative-itineraries.js
index 23d1d96fe..4fa470537 100644
--- a/lib/components/narrative/narrative-itineraries.js
+++ b/lib/components/narrative/narrative-itineraries.js
@@ -560,7 +560,7 @@ class NarrativeItineraries extends Component {
}
const reduceErrorsFromResponse = (acc, cur) => {
- const { routingErrors } = cur?.plan
+ const { routingErrors } = cur?.plan || {}
if (routingErrors) {
routingErrors.forEach((routingError) => {
const { code, inputField } = routingError
diff --git a/lib/reducers/create-otp-reducer.js b/lib/reducers/create-otp-reducer.js
index 172ccb710..b5534a071 100644
--- a/lib/reducers/create-otp-reducer.js
+++ b/lib/reducers/create-otp-reducer.js
@@ -325,7 +325,14 @@ function createOtpReducer(config) {
searches: {
[searchId]: {
pending: { $set: activeSearch?.pending - 1 },
- response: { $push: [response] }
+ response:
+ action.payload.index !== undefined
+ ? {
+ [action.payload.index]: {
+ $set: response
+ }
+ }
+ : { $push: [response] }
}
},
ui: {
From 6954113e49e8541bdf35af84cd6c24b4a0d48f68 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Thu, 31 Aug 2023 12:03:14 -0400
Subject: [PATCH 24/80] refactor(notification-prefs-pane): Add config setting
for showing push notification settings.
---
example-config.yml | 1 +
.../user/notification-prefs-pane.tsx | 20 ++++++++++++++++---
2 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/example-config.yml b/example-config.yml
index b725f59a4..63fbf78cc 100644
--- a/example-config.yml
+++ b/example-config.yml
@@ -68,6 +68,7 @@ persistence:
# otp_middleware:
# apiBaseUrl: https://otp-middleware.example.com
# apiKey: your-middleware-api-key
+# supportsPushNotifications: true # If not set, push notification settings will not be shown.
### Adding additional menu items to the main menu items. Use the separator flag
### to include a separator line if you have groups of menu items
diff --git a/lib/components/user/notification-prefs-pane.tsx b/lib/components/user/notification-prefs-pane.tsx
index 3636dedec..85668867c 100644
--- a/lib/components/user/notification-prefs-pane.tsx
+++ b/lib/components/user/notification-prefs-pane.tsx
@@ -1,6 +1,7 @@
+import { connect } from 'react-redux'
import { Field, FormikProps } from 'formik'
import { FormattedMessage } from 'react-intl'
-import React, { Fragment } from 'react'
+import React from 'react'
import styled from 'styled-components'
import { GRAY_ON_WHITE } from '../util/colors'
@@ -13,6 +14,7 @@ import PhoneNumberEditor, {
} from './phone-number-editor'
interface Props extends FormikProps {
+ allowedNotificationChannels: string[]
loggedInUser: User
onRequestPhoneVerificationCode: PhoneCodeRequestHandler
onSendPhoneVerificationCode: PhoneVerificationSubmitHandler
@@ -21,7 +23,8 @@ interface Props extends FormikProps {
}
}
-const allowedNotificationChannels = ['email', 'sms', 'push']
+const allNotificationChannels = ['email', 'sms', 'push']
+const emailAndSms = ['email', 'sms']
// Styles
const NotificationOption = styled.div`
@@ -52,6 +55,7 @@ const NotificationOption = styled.div`
* User notification preferences pane.
*/
const NotificationPrefsPane = ({
+ allowedNotificationChannels,
onRequestPhoneVerificationCode,
onSendPhoneVerificationCode,
phoneFormatOptions,
@@ -115,4 +119,14 @@ const NotificationPrefsPane = ({
)
}
-export default NotificationPrefsPane
+const mapStateToProps = (state: any) => {
+ const { supportsPushNotifications } =
+ state.otp.config.persistence?.otp_middleware || {}
+ return {
+ allowedNotificationChannels: supportsPushNotifications
+ ? allNotificationChannels
+ : emailAndSms
+ }
+}
+
+export default connect(mapStateToProps)(NotificationPrefsPane)
From 97dca1d73ef0f31656d83ba1b2914aa0b424dafb Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Thu, 31 Aug 2023 12:17:01 -0400
Subject: [PATCH 25/80] refactor(notification-prefs-pane): Reduce phone options
prop drilling.
---
lib/components/user/notification-prefs-pane.tsx | 3 ++-
lib/components/user/user-account-screen.js | 7 ++-----
2 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/lib/components/user/notification-prefs-pane.tsx b/lib/components/user/notification-prefs-pane.tsx
index 85668867c..ffe092eb3 100644
--- a/lib/components/user/notification-prefs-pane.tsx
+++ b/lib/components/user/notification-prefs-pane.tsx
@@ -125,7 +125,8 @@ const mapStateToProps = (state: any) => {
return {
allowedNotificationChannels: supportsPushNotifications
? allNotificationChannels
- : emailAndSms
+ : emailAndSms,
+ phoneFormatOptions: state.otp.config.phoneFormatOptions
}
}
diff --git a/lib/components/user/user-account-screen.js b/lib/components/user/user-account-screen.js
index 6b05245be..78e756d01 100644
--- a/lib/components/user/user-account-screen.js
+++ b/lib/components/user/user-account-screen.js
@@ -110,8 +110,7 @@ class UserAccountScreen extends Component {
}
render() {
- const { auth0, isCreating, itemId, loggedInUser, phoneFormatOptions } =
- this.props
+ const { auth0, isCreating, itemId, loggedInUser } = this.props
const DisplayComponent = isCreating
? NewAccountWizard
: ExistingAccountDisplay
@@ -153,7 +152,6 @@ class UserAccountScreen extends Component {
onSendPhoneVerificationCode={
this._handleSendPhoneVerificationCode
}
- phoneFormatOptions={phoneFormatOptions}
/>
)
@@ -173,8 +171,7 @@ const mapStateToProps = (state, ownProps) => {
return {
isCreating,
itemId: step,
- loggedInUser: state.user.loggedInUser,
- phoneFormatOptions: state.otp.config.phoneFormatOptions
+ loggedInUser: state.user.loggedInUser
}
}
From 344442f42157939bef5dd4fc69bfcbdb6fe36ff2 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Thu, 31 Aug 2023 12:41:04 -0400
Subject: [PATCH 26/80] improvement(notification-prefs-pane): Improve checkbox
layout
---
.../user/notification-prefs-pane.tsx | 98 ++++++++++---------
lib/components/user/phone-number-editor.tsx | 2 +-
2 files changed, 51 insertions(+), 49 deletions(-)
diff --git a/lib/components/user/notification-prefs-pane.tsx b/lib/components/user/notification-prefs-pane.tsx
index ffe092eb3..127fcb10c 100644
--- a/lib/components/user/notification-prefs-pane.tsx
+++ b/lib/components/user/notification-prefs-pane.tsx
@@ -1,6 +1,7 @@
import { connect } from 'react-redux'
import { Field, FormikProps } from 'formik'
import { FormattedMessage } from 'react-intl'
+import { ListGroup, ListGroupItem } from 'react-bootstrap'
import React from 'react'
import styled from 'styled-components'
@@ -27,10 +28,9 @@ const allNotificationChannels = ['email', 'sms', 'push']
const emailAndSms = ['email', 'sms']
// Styles
-const NotificationOption = styled.div`
+const NotificationOption = styled(ListGroupItem)`
align-items: flex-start;
display: flex;
- margin-bottom: 10px;
/* Match bootstrap's spacing between checkbox and label */
& > span:first-child {
@@ -68,53 +68,55 @@ const NotificationPrefsPane = ({
- {allowedNotificationChannels.map((type) => {
- // TODO: If removing the Save/Cancel buttons on the account screen,
- // persist changes immediately when onChange is triggered.
- const inputId = `notification-channel-${type}`
- const inputDescriptionId = `${inputId}-description`
- return (
-
-
-
-
-
-
-
-
- {type === 'email' ? (
- {email}
- ) : type === 'sms' ? (
-
+ {allowedNotificationChannels.map((type) => {
+ // TODO: If removing the Save/Cancel buttons on the account screen,
+ // persist changes immediately when onChange is triggered.
+ const inputId = `notification-channel-${type}`
+ const inputDescriptionId = `${inputId}-description`
+ return (
+
+
+
- ) : (
-
- {pushDevices ? (
- // TODO: i18n
- `${pushDevices} devices registered`
- ) : (
-
- )}
-
- )}
-
-
- )
- })}
+
+
+
+
+
+ {type === 'email' ? (
+ {email}
+ ) : type === 'sms' ? (
+
+ ) : (
+
+ {pushDevices ? (
+ // TODO: i18n
+ `${pushDevices} devices registered`
+ ) : (
+
+ )}
+
+ )}
+
+
+ )
+ })}
+
)
}
diff --git a/lib/components/user/phone-number-editor.tsx b/lib/components/user/phone-number-editor.tsx
index b53d142de..b3dc52efc 100644
--- a/lib/components/user/phone-number-editor.tsx
+++ b/lib/components/user/phone-number-editor.tsx
@@ -265,7 +265,7 @@ class PhoneNumberEditor extends Component
{
)}
-
+
{ariaAlertContent}
From e7b2aeebd7a27edab7c6a4595ebc15a8d5f88bab Mon Sep 17 00:00:00 2001
From: Daniel Heppner
Date: Fri, 1 Sep 2023 01:01:16 +0200
Subject: [PATCH 27/80] improvement(apiv2): use the OTP-UI conversion utility
for legacy format
---
lib/actions/apiV2.js | 49 ++++++--------------------------------------
1 file changed, 6 insertions(+), 43 deletions(-)
diff --git a/lib/actions/apiV2.js b/lib/actions/apiV2.js
index 3b9eba694..ec8aec770 100644
--- a/lib/actions/apiV2.js
+++ b/lib/actions/apiV2.js
@@ -44,7 +44,11 @@ import { rememberPlace } from './user'
import { setItineraryView } from './ui'
import { zoomToPlace } from './map'
-const { generateCombinations, generateOtp2Query } = coreUtils.queryGen
+const {
+ convertGraphQLResponseToLegacy,
+ generateCombinations,
+ generateOtp2Query
+} = coreUtils.queryGen
const { getTripOptionsFromQuery, getUrlParams } = coreUtils.query
const { randId } = coreUtils.storage
@@ -782,47 +786,6 @@ const pickupDropoffTypeToOtp1 = (otp2Type) => {
}
}
-/**
- * Converts a leg from GraphQL format to legacy REST format.
- * @param leg OTP2 GraphQL style leg
- * @returns REST shaped leg
- */
-const processLeg = (leg) => ({
- ...leg,
- agencyBrandingUrl: leg.agency?.url,
- agencyName: leg.agency?.name,
- agencyUrl: leg.agency?.url,
- alerts: aggregateAlerts(
- leg.agency?.alerts,
- leg.route?.alerts,
- leg.to?.stop?.alerts,
- leg.from?.stop?.alerts
- ),
- alightRule: pickupDropoffTypeToOtp1(leg.dropoffType),
- boardRule: pickupDropoffTypeToOtp1(leg.pickupType),
- dropOffBookingInfo: {
- latestBookingTime: leg.dropOffBookingInfo
- },
- from: {
- ...leg.from,
- stopCode: leg.from.stop?.code,
- stopId: leg.from.stop?.gtfsId
- },
- route: leg.route?.shortName,
- routeColor: leg.route?.color,
- routeId: leg.route?.id,
- routeLongName: leg.route?.longName,
- routeShortName: leg.route?.shortName,
- routeTextColor: leg.route?.textColor,
- to: {
- ...leg.to,
- stopCode: leg.to.stop?.code,
- stopId: leg.to.stop?.gtfsId
- },
- tripHeadsign: leg.trip?.tripHeadsign,
- tripId: leg.trip?.gtfsId
-})
-
const queryParamConfig = { modeButtons: DelimitedArrayParam }
export function routingQuery(searchId = null, updateSearchInReducer) {
@@ -962,7 +925,7 @@ export function routingQuery(searchId = null, updateSearchInReducer) {
const withCollapsedShortNames =
response.data?.plan?.itineraries?.map((itin) => ({
...itin,
- legs: itin.legs?.map(processLeg)
+ legs: itin.legs?.map(convertGraphQLResponseToLegacy)
}))
/* It is possible for a NO_TRANSIT_CONNECTION error to be
From bc341dea9436c2d3353de4bf023242542ce7d205 Mon Sep 17 00:00:00 2001
From: Daniel Heppner
Date: Fri, 1 Sep 2023 12:46:26 +0200
Subject: [PATCH 28/80] fix incorrect import
---
lib/actions/apiV2.js | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/lib/actions/apiV2.js b/lib/actions/apiV2.js
index ec8aec770..70f116d2a 100644
--- a/lib/actions/apiV2.js
+++ b/lib/actions/apiV2.js
@@ -44,12 +44,9 @@ import { rememberPlace } from './user'
import { setItineraryView } from './ui'
import { zoomToPlace } from './map'
-const {
- convertGraphQLResponseToLegacy,
- generateCombinations,
- generateOtp2Query
-} = coreUtils.queryGen
+const { generateCombinations, generateOtp2Query } = coreUtils.queryGen
const { getTripOptionsFromQuery, getUrlParams } = coreUtils.query
+const { convertGraphQLResponseToLegacy } = coreUtils.itinerary
const { randId } = coreUtils.storage
const LIGHT_GRAY = '666666'
From 3e9e8a2f44635c478a7c8688148f73137fd170a6 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Fri, 1 Sep 2023 17:20:43 -0400
Subject: [PATCH 29/80] improvement(actions/user): Replace window.alert with
toast on saving user/trip prefs.
---
lib/actions/user.js | 13 ++++++++-----
lib/components/app/responsive-webapp.js | 2 ++
package.json | 3 ++-
yarn.lock | 12 ++++++++++++
4 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/lib/actions/user.js b/lib/actions/user.js
index d630bfb33..0c00f3064 100644
--- a/lib/actions/user.js
+++ b/lib/actions/user.js
@@ -3,6 +3,7 @@ import clone from 'clone'
import coreUtils from '@opentripplanner/core-utils'
import isEmpty from 'lodash.isempty'
import qs from 'qs'
+import toast from 'react-hot-toast'
import {
convertToPlace,
@@ -322,10 +323,11 @@ export function createOrUpdateUser(userData, silentOnSuccess = false, intl) {
body: JSON.stringify(userData)
})
- // TODO: improve the UI feedback messages for this.
if (status === 'success' && returnedUser) {
if (!silentOnSuccess && intl) {
- alert(intl.formatMessage({ id: 'actions.user.preferencesSaved' }))
+ toast.success(
+ intl.formatMessage({ id: 'actions.user.preferencesSaved' })
+ )
}
// Update application state with the user entry as saved
@@ -447,10 +449,11 @@ export function createOrUpdateUserMonitoredTrip(
}
)
- // TODO: improve the UI feedback messages for this.
if (status === 'success' && data) {
- if (!silentOnSuccess) {
- alert(intl.formatMessage({ id: 'actions.user.preferencesSaved' }))
+ if (!silentOnSuccess && intl) {
+ toast.success(
+ intl.formatMessage({ id: 'actions.user.preferencesSaved' })
+ )
}
// Reload user's monitored trips after add/update.
diff --git a/lib/components/app/responsive-webapp.js b/lib/components/app/responsive-webapp.js
index 0ae74b8a7..fec45036f 100644
--- a/lib/components/app/responsive-webapp.js
+++ b/lib/components/app/responsive-webapp.js
@@ -10,6 +10,7 @@ import { MapProvider } from 'react-map-gl'
import { QueryParamProvider } from 'use-query-params'
import { ReactRouter5Adapter } from 'use-query-params/adapters/react-router-5'
import { Route, Switch, withRouter } from 'react-router'
+import { Toaster } from 'react-hot-toast'
import coreUtils from '@opentripplanner/core-utils'
import isEqual from 'lodash.isequal'
import PropTypes from 'prop-types'
@@ -336,6 +337,7 @@ class RouterWrapperWithAuth0 extends Component {
// Don't render anything until the locale/localized messages have been initialized.
const router = localizedMessages && (
+
Date: Fri, 1 Sep 2023 17:28:01 -0400
Subject: [PATCH 30/80] improvement(actions/user): Replace window.alert with
toast notif after resending phone verif code.
---
lib/actions/user.js | 5 +++--
lib/components/user/user-account-screen.js | 3 +--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/lib/actions/user.js b/lib/actions/user.js
index 0c00f3064..e0cc68c28 100644
--- a/lib/actions/user.js
+++ b/lib/actions/user.js
@@ -404,9 +404,10 @@ export function resendVerificationEmail(intl) {
const requestUrl = `${apiBaseUrl}${API_OTPUSER_PATH}/verification-email`
const { status } = await secureFetch(requestUrl, accessToken, apiKey)
- // TODO: improve the UI feedback messages for this.
if (status === 'success') {
- alert(intl.formatMessage({ id: 'actions.user.emailVerificationResent' }))
+ toast.success(
+ intl.formatMessage({ id: 'actions.user.emailVerificationResent' })
+ )
}
}
}
diff --git a/lib/components/user/user-account-screen.js b/lib/components/user/user-account-screen.js
index 83eefd4b9..d119bd4f5 100644
--- a/lib/components/user/user-account-screen.js
+++ b/lib/components/user/user-account-screen.js
@@ -45,9 +45,8 @@ class UserAccountScreen extends Component {
const { createOrUpdateUser, intl } = this.props
// TODO: Change state of Save button while the update action takes place.
+ // The call below will also display a toast notification on success.
await createOrUpdateUser(userData, silentOnSucceed, intl)
-
- // TODO: Handle UI feedback (currently an alert() dialog inside createOrUpdateUser).
}
/**
From 6938b8fbcd5cfff8ff1015229180f1a9ca040216 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Fri, 1 Sep 2023 17:39:01 -0400
Subject: [PATCH 31/80] refactor(actions/user): Extract code for showing a
generic alert.
---
lib/actions/user.js | 48 +++++++++++++++------------------------------
1 file changed, 16 insertions(+), 32 deletions(-)
diff --git a/lib/actions/user.js b/lib/actions/user.js
index e0cc68c28..461fff389 100644
--- a/lib/actions/user.js
+++ b/lib/actions/user.js
@@ -53,6 +53,17 @@ export const rememberStop = createAction('REMEMBER_STOP')
const rememberLocalUserPlace = createAction('REMEMBER_LOCAL_USER_PLACE')
const deleteRecentPlace = createAction('DELETE_LOCAL_USER_RECENT_PLACE')
+function genericErrorAlert(intl, messageObject) {
+ if (intl) {
+ alert(
+ intl.formatMessage(
+ { id: 'actions.user.genericError' },
+ { err: JSON.stringify(messageObject) }
+ )
+ )
+ }
+}
+
function createNewUser(auth0User) {
return {
accessibilityRoutingByDefault: false,
@@ -335,14 +346,7 @@ export function createOrUpdateUser(userData, silentOnSuccess = false, intl) {
// (This sorts saved places, and, for existing users, fetches trips.)
dispatch(setUser(returnedUser, isCreatingUser))
} else {
- if (intl) {
- alert(
- intl.formatMessage(
- { id: 'actions.user.genericError' },
- { err: JSON.stringify(message) }
- )
- )
- }
+ genericErrorAlert(intl, message)
}
}
}
@@ -381,12 +385,7 @@ export function deleteUser(userData, auth0, intl) {
// Log out user and route them to the home page.
auth0.logout({ returnTo: window.location.origin })
} else {
- alert(
- intl.formatMessage(
- { id: 'actions.user.genericError' },
- { err: JSON.stringify(message) }
- )
- )
+ genericErrorAlert(intl, message)
}
}
}
@@ -465,12 +464,7 @@ export function createOrUpdateUserMonitoredTrip(
// Finally, navigate to the saved trips page.
dispatch(routeTo(TRIPS_PATH))
} else {
- alert(
- intl.formatMessage(
- { id: 'actions.user.genericError' },
- { err: JSON.stringify(message) }
- )
- )
+ genericErrorAlert(intl, message)
}
}
}
@@ -531,12 +525,7 @@ export function confirmAndDeleteUserMonitoredTrip(tripId, intl) {
// Reload user's monitored trips after deletion.
dispatch(fetchMonitoredTrips())
} else {
- alert(
- intl.formatMessage(
- { id: 'actions.user.genericError' },
- { err: JSON.stringify(message) }
- )
- )
+ genericErrorAlert(intl, message)
}
}
}
@@ -579,12 +568,7 @@ export function requestPhoneVerificationSms(newPhoneNumber, intl) {
// Refetch user and update application state with new phone number and verification status.
dispatch(fetchOrInitializeUser())
} else {
- alert(
- intl.formatMessage(
- { id: 'actions.user.genericError' },
- { err: JSON.stringify(message) }
- )
- )
+ genericErrorAlert(intl, message)
}
} else {
// Alert user if they have been throttled.
From 92ac6c941b335b824d90257f6222cffcfa2b09d2 Mon Sep 17 00:00:00 2001
From: Daniel Heppner
Date: Sat, 2 Sep 2023 00:52:22 +0200
Subject: [PATCH 32/80] deps: update core-utils
---
package.json | 2 +-
yarn.lock | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/package.json b/package.json
index 770861132..5982b1c6f 100644
--- a/package.json
+++ b/package.json
@@ -39,7 +39,7 @@
"@bugsnag/plugin-react": "^7.17.0",
"@floating-ui/react": "^0.19.2",
"@opentripplanner/base-map": "^3.0.14",
- "@opentripplanner/core-utils": "^11.0.0",
+ "@opentripplanner/core-utils": "^11.0.2",
"@opentripplanner/endpoints-overlay": "^2.0.8",
"@opentripplanner/from-to-location-picker": "^2.1.8",
"@opentripplanner/geocoder": "^1.4.2",
diff --git a/yarn.lock b/yarn.lock
index 2d9cec407..d24a5c104 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2439,10 +2439,10 @@
lodash.isequal "^4.5.0"
qs "^6.9.1"
-"@opentripplanner/core-utils@^11.0.0":
- version "11.0.0"
- resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-11.0.0.tgz#dd40b7cd68d7d7bf4f56d87bf708d6bd4b7660ed"
- integrity sha512-b+oPQWKpzXHeq9QdU0JmsplZX2QIRj4ARdIPJ++f5i/hpIxMnbKApwDHVkRdHz6kYCOQI7pcVNTunT7AGNvudg==
+"@opentripplanner/core-utils@^11.0.2":
+ version "11.0.2"
+ resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-11.0.2.tgz#ebfa939c3b7b266e3bf47dcaddda88e093430a9d"
+ integrity sha512-3oQYvnhFHY88K61j2tUkU2fm8tDci5qaMVGEgqTzxpE5NmBTUdAWU1V7W9snJoRATzz3zy+K9qrtIhGjwbwlnA==
dependencies:
"@conveyal/lonlat" "^1.4.1"
"@mapbox/polyline" "^1.1.0"
From 31c000b6b2ff458f9985ef882f41520e45752c99 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Tue, 5 Sep 2023 17:52:47 -0400
Subject: [PATCH 33/80] fix(otp reducer): Handle new FT search and updating FT
responses.
---
lib/reducers/create-otp-reducer.js | 37 +++++++++++++++++++++++++-----
1 file changed, 31 insertions(+), 6 deletions(-)
diff --git a/lib/reducers/create-otp-reducer.js b/lib/reducers/create-otp-reducer.js
index b5534a071..91ee98d72 100644
--- a/lib/reducers/create-otp-reducer.js
+++ b/lib/reducers/create-otp-reducer.js
@@ -353,30 +353,55 @@ function createOtpReducer(config) {
}
})
case 'SET_PENDING_REQUESTS':
+ if (state.searches[searchId]) {
+ return update(state, {
+ searches: {
+ [searchId]: {
+ pending: { $set: action.payload?.pending }
+ }
+ }
+ })
+ }
return update(state, {
searches: {
[searchId]: {
- pending: { $set: action.payload?.pending }
+ $set: {
+ pending: action.payload?.pending
+ }
}
}
})
case 'SET_ACTIVE_ITINERARIES':
const responseUpdate = {}
+ const responseSet = []
Object.entries(action.payload.assignedItinerariesByResponse).forEach(
([responseIdx, responsePlanItineraries]) => {
- responseUpdate[responseIdx] = {
+ const responsePart = {
plan: {
- itineraries: {
- $set: responsePlanItineraries
- }
+ itineraries: responsePlanItineraries
}
}
+ responseUpdate[responseIdx] = {
+ $set: responsePart
+ }
+ responseSet[responseIdx] = responsePart
}
)
+ if (state.searches[searchId]?.response) {
+ return update(state, {
+ searches: {
+ [searchId]: {
+ response: responseUpdate
+ }
+ }
+ })
+ }
return update(state, {
searches: {
[searchId]: {
- response: responseUpdate
+ $set: {
+ response: responseSet
+ }
}
}
})
From a7e82dc780c38bf302439457ee3f716b0edd6db9 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Wed, 6 Sep 2023 19:22:00 -0400
Subject: [PATCH 34/80] fix(otp reducer): Update successive responses, fix ft
wait for current search.
---
lib/actions/field-trip.js | 23 ++++++----
lib/reducers/create-otp-reducer.js | 68 +++++++++++++++---------------
2 files changed, 47 insertions(+), 44 deletions(-)
diff --git a/lib/actions/field-trip.js b/lib/actions/field-trip.js
index ee77d2ca1..da34ec27b 100644
--- a/lib/actions/field-trip.js
+++ b/lib/actions/field-trip.js
@@ -687,7 +687,7 @@ function checkValidityAndCapacity(state, request) {
// iterate through itineraries to check validity and assign field trip
// groups
- response.plan.itineraries.forEach((itinerary) => {
+ response.plan.itineraries.forEach((itinerary, itinIdx) => {
let itineraryCapacity = Number.POSITIVE_INFINITY
// check each individual trip to see if there aren't any trips in this
@@ -744,12 +744,13 @@ function checkValidityAndCapacity(state, request) {
// A field trip response is guaranteed to have only one itinerary, so it
// ok to set the itinerary by response as an array with a single
// itinerary.
- assignedItinerariesByResponse[responseIdx] = [
- {
- ...itinerary,
- fieldTripGroupSize: Math.min(itineraryCapacity, remainingGroupSize)
- }
- ]
+ if (!assignedItinerariesByResponse[responseIdx]) {
+ assignedItinerariesByResponse[responseIdx] = {}
+ }
+ assignedItinerariesByResponse[responseIdx][itinIdx] = {
+ ...itinerary,
+ fieldTripGroupSize: Math.min(itineraryCapacity, remainingGroupSize)
+ }
remainingGroupSize -= itineraryCapacity
}
})
@@ -844,8 +845,12 @@ function makeFieldTripPlanRequests(request, outbound, intl) {
// I do not believe that it is worth the effort. I am instead in favor of
// re-building field trip from the ground up as a separate application.
setInterval(() => {
- const activeItineraries = getActiveItineraries(getState())
- if (activeItineraries.length >= numRequests) {
+ const searchResponse = getState().otp.searches[searchId]?.response
+ const activeItineraries =
+ searchResponse?.reduce((prev, resp) => {
+ return (prev += resp?.plan?.itineraries?.length || 0)
+ }, 0) || 0
+ if (activeItineraries >= numRequests) {
resolve()
}
}, 20)
diff --git a/lib/reducers/create-otp-reducer.js b/lib/reducers/create-otp-reducer.js
index 91ee98d72..0888474e9 100644
--- a/lib/reducers/create-otp-reducer.js
+++ b/lib/reducers/create-otp-reducer.js
@@ -327,12 +327,31 @@ function createOtpReducer(config) {
pending: { $set: activeSearch?.pending - 1 },
response:
action.payload.index !== undefined
- ? {
- [action.payload.index]: {
- $set: response
+ ? state.searches[searchId].response?.[action.payload.index]
+ ? {
+ // Field Trip may make multiple requests, one itinerary at a time,
+ // to divide up large groups. In that case, append the itineraries to the plan array
+ // at the indicated response index, as if multiple itineraries were returned in one request.
+ [action.payload.index]: {
+ plan: {
+ itineraries: {
+ $push: [...response.plan.itineraries]
+ }
+ }
+ }
}
+ : {
+ // Accommodate regular mode combination responses in the order they were requested
+ // to ensure that the response order remains the same if doing the same search again.
+ [action.payload.index]: {
+ $set: response
+ }
+ }
+ : {
+ // If queries were made outside of mode combinations, just add the responses
+ // in the order they are received (order may change if doing the same search again).
+ $push: [response]
}
- : { $push: [response] }
}
},
ui: {
@@ -353,55 +372,34 @@ function createOtpReducer(config) {
}
})
case 'SET_PENDING_REQUESTS':
- if (state.searches[searchId]) {
- return update(state, {
- searches: {
- [searchId]: {
- pending: { $set: action.payload?.pending }
- }
- }
- })
- }
return update(state, {
searches: {
[searchId]: {
- $set: {
- pending: action.payload?.pending
- }
+ pending: { $set: action.payload?.pending }
}
}
})
case 'SET_ACTIVE_ITINERARIES':
const responseUpdate = {}
- const responseSet = []
Object.entries(action.payload.assignedItinerariesByResponse).forEach(
([responseIdx, responsePlanItineraries]) => {
- const responsePart = {
+ responseUpdate[responseIdx] = {
plan: {
- itineraries: responsePlanItineraries
+ itineraries: Object.entries(responsePlanItineraries).reduce(
+ (prev, [itinIdx, itin]) => {
+ prev[itinIdx] = { $set: itin }
+ return prev
+ },
+ {}
+ )
}
}
- responseUpdate[responseIdx] = {
- $set: responsePart
- }
- responseSet[responseIdx] = responsePart
}
)
- if (state.searches[searchId]?.response) {
- return update(state, {
- searches: {
- [searchId]: {
- response: responseUpdate
- }
- }
- })
- }
return update(state, {
searches: {
[searchId]: {
- $set: {
- response: responseSet
- }
+ response: responseUpdate
}
}
})
From 7830b5d242e7bbd845bd1659a3af952f0f5bba8f Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Thu, 7 Sep 2023 10:42:11 -0400
Subject: [PATCH 35/80] improvement(connected-endpoints-overlay): Add intl
support for rememberPlace.
---
i18n/en-US.yml | 1 +
lib/actions/user.js | 19 ++++++++++++--
.../map/connected-endpoints-overlay.js | 25 ++++++++++++++++---
3 files changed, 39 insertions(+), 6 deletions(-)
diff --git a/i18n/en-US.yml b/i18n/en-US.yml
index 8c438529b..d7d88e730 100644
--- a/i18n/en-US.yml
+++ b/i18n/en-US.yml
@@ -52,6 +52,7 @@ actions:
emailVerificationResent: The email verification message has been resent.
genericError: "An error was encountered: {err}"
itineraryExistenceCheckFailed: Error checking whether your selected trip is possible.
+ placeRemembered: Your {placeType} has been set to {address}.
preferencesSaved: Your preferences have been saved.
smsInvalidCode: The code you entered is invalid. Please try again.
smsResendThrottled: >-
diff --git a/lib/actions/user.js b/lib/actions/user.js
index 461fff389..f6be73415 100644
--- a/lib/actions/user.js
+++ b/lib/actions/user.js
@@ -683,6 +683,21 @@ export function saveUserPlace(placeToSave, placeIndex, intl) {
}
dispatch(createOrUpdateUser(loggedInUser, true, intl))
+ if (intl) {
+ toast.success(
+ intl.formatMessage(
+ {
+ id: 'actions.user.placeRemembered'
+ },
+ {
+ address: placeToSave.address,
+ placeType: intl.formatMessage({
+ id: `common.places.${placeToSave.type}`
+ })
+ }
+ )
+ )
+ }
}
}
@@ -738,7 +753,7 @@ export function deleteUserPlace(place, intl) {
* Remembers a place for the logged-in or local user
* according to the persistence strategy.
*/
-export function rememberPlace(placeTypeLocation) {
+export function rememberPlace(placeTypeLocation, intl) {
return function (dispatch, getState) {
const { otp, user } = getState()
const persistenceMode = getPersistenceMode(otp.config.persistence)
@@ -755,7 +770,7 @@ export function rememberPlace(placeTypeLocation) {
)
if (placeIndex > -1) {
// Convert to loggedInUser saved place
- dispatch(saveUserPlace(convertToPlace(location), placeIndex))
+ dispatch(saveUserPlace(convertToPlace(location), placeIndex, intl))
}
}
} else if (persistenceMode.isLocalStorage) {
diff --git a/lib/components/map/connected-endpoints-overlay.js b/lib/components/map/connected-endpoints-overlay.js
index 8ea8a94cc..ef07e6510 100644
--- a/lib/components/map/connected-endpoints-overlay.js
+++ b/lib/components/map/connected-endpoints-overlay.js
@@ -10,15 +10,32 @@ import { getActiveSearch, getShowUserSettings } from '../../util/state'
import { getUserLocations } from '../../util/user'
import { setLocation } from '../../actions/map'
-const ConnectedEndpointsOverlay = (props) => {
+const ConnectedEndpointsOverlay = ({
+ forgetPlace,
+ rememberPlace,
+ ...otherProps
+}) => {
const intl = useIntl()
const _forgetPlace = useCallback(
(place) => {
- props.forgetPlace(place, intl)
+ forgetPlace(place, intl)
+ },
+ [forgetPlace, intl]
+ )
+
+ const _rememberPlace = useCallback(
+ (placeTypeLocation) => {
+ rememberPlace(placeTypeLocation, intl)
},
- [props, intl]
+ [rememberPlace, intl]
+ )
+ return (
+
)
- return
}
// connect to the redux store
From 1cd733e41e58e3a57929ce9e3cd46b5452c54de9 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Thu, 7 Sep 2023 11:07:34 -0400
Subject: [PATCH 36/80] refactor(connected-endpoints-overlay): Convert to
TypeScript.
---
...lay.js => connected-endpoints-overlay.tsx} | 20 ++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
rename lib/components/map/{connected-endpoints-overlay.js => connected-endpoints-overlay.tsx} (80%)
diff --git a/lib/components/map/connected-endpoints-overlay.js b/lib/components/map/connected-endpoints-overlay.tsx
similarity index 80%
rename from lib/components/map/connected-endpoints-overlay.js
rename to lib/components/map/connected-endpoints-overlay.tsx
index ef07e6510..67566f0c4 100644
--- a/lib/components/map/connected-endpoints-overlay.js
+++ b/lib/components/map/connected-endpoints-overlay.tsx
@@ -1,8 +1,8 @@
-/* eslint-disable react/prop-types */
import { connect } from 'react-redux'
-import { useIntl } from 'react-intl'
+import { IntlShape, useIntl } from 'react-intl'
+import { UserLocationAndType } from '@opentripplanner/types'
import EndpointsOverlay from '@opentripplanner/endpoints-overlay'
-import React, { useCallback } from 'react'
+import React, { ComponentProps, useCallback } from 'react'
import { clearLocation } from '../../actions/form'
import { forgetPlace, rememberPlace } from '../../actions/user'
@@ -10,11 +10,16 @@ import { getActiveSearch, getShowUserSettings } from '../../util/state'
import { getUserLocations } from '../../util/user'
import { setLocation } from '../../actions/map'
+type Props = ComponentProps & {
+ forgetPlace: (place: string, intl: IntlShape) => void
+ rememberPlace: (arg: UserLocationAndType, intl: IntlShape) => void
+}
+
const ConnectedEndpointsOverlay = ({
forgetPlace,
rememberPlace,
...otherProps
-}) => {
+}: Props): JSX.Element => {
const intl = useIntl()
const _forgetPlace = useCallback(
(place) => {
@@ -39,8 +44,9 @@ const ConnectedEndpointsOverlay = ({
}
// connect to the redux store
+// TODO: Add TypeScript to this section.
-const mapStateToProps = (state) => {
+const mapStateToProps = (state: any) => {
const { viewedRoute } = state.otp.ui
// If the route viewer is active, do not show itinerary on map.
// mainPanelContent is null whenever the trip planner is active.
@@ -53,13 +59,13 @@ const mapStateToProps = (state) => {
// Use query from active search (if a search has been made) or default to
// current query is no search is available.
- const activeSearch = getActiveSearch(state)
+ const activeSearch: any = getActiveSearch(state)
const query = activeSearch ? activeSearch.query : state.otp.currentQuery
const showUserSettings = getShowUserSettings(state)
const { from, to } = query
// Intermediate places doesn't trigger a re-plan, so for now default to
// current query. FIXME: Determine with TriMet if this is desired behavior.
- const places = state.otp.currentQuery.intermediatePlaces.filter((p) => p)
+ const places = state.otp.currentQuery.intermediatePlaces.filter((p: any) => p)
return {
fromLocation: from,
From 9ed7040b07a59f49860f9316bfbe566f857bdfd7 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Thu, 7 Sep 2023 12:11:45 -0400
Subject: [PATCH 37/80] refactor(actions/user): Move "preferences saved"
feedback to the user account screen.
---
lib/actions/ui.js | 2 +-
lib/actions/user.js | 24 +++++++++++-----------
lib/components/user/user-account-screen.js | 9 ++++++--
3 files changed, 20 insertions(+), 15 deletions(-)
diff --git a/lib/actions/ui.js b/lib/actions/ui.js
index 43cf75b58..27c499a50 100644
--- a/lib/actions/ui.js
+++ b/lib/actions/ui.js
@@ -401,7 +401,7 @@ export function setLocale(locale) {
if (loggedInUser) {
loggedInUser.preferredLocale = matchedLocale
- dispatch(createOrUpdateUser(loggedInUser, false))
+ dispatch(createOrUpdateUser(loggedInUser))
}
}
}
diff --git a/lib/actions/user.js b/lib/actions/user.js
index f6be73415..36ee06ba1 100644
--- a/lib/actions/user.js
+++ b/lib/actions/user.js
@@ -53,6 +53,11 @@ export const rememberStop = createAction('REMEMBER_STOP')
const rememberLocalUserPlace = createAction('REMEMBER_LOCAL_USER_PLACE')
const deleteRecentPlace = createAction('DELETE_LOCAL_USER_RECENT_PLACE')
+export const UserActionResult = {
+ FAILURE: 1,
+ SUCCESS: 0
+}
+
function genericErrorAlert(intl, messageObject) {
if (intl) {
alert(
@@ -301,10 +306,9 @@ export function fetchOrInitializeUser(auth0User) {
* Updates (or creates) a user entry in the middleware,
* then, if that was successful, updates the redux state with that user.
* @param userData the user entry to persist.
- * @param silentOnSuccess true to suppress the confirmation if the operation is successful (e.g. immediately after user accepts the terms).
* @param intl the react-intl formatter
*/
-export function createOrUpdateUser(userData, silentOnSuccess = false, intl) {
+export function createOrUpdateUser(userData, intl) {
return async function (dispatch, getState) {
const { accessToken, apiBaseUrl, apiKey, loggedInUser } =
getMiddlewareVariables(getState())
@@ -335,18 +339,14 @@ export function createOrUpdateUser(userData, silentOnSuccess = false, intl) {
})
if (status === 'success' && returnedUser) {
- if (!silentOnSuccess && intl) {
- toast.success(
- intl.formatMessage({ id: 'actions.user.preferencesSaved' })
- )
- }
-
// Update application state with the user entry as saved
// (as returned) by the middleware.
// (This sorts saved places, and, for existing users, fetches trips.)
dispatch(setUser(returnedUser, isCreatingUser))
+ return UserActionResult.SUCCESS
} else {
genericErrorAlert(intl, message)
+ return UserActionResult.FAILURE
}
}
}
@@ -674,7 +674,7 @@ export function planNewTripFromMonitoredTrip(monitoredTrip) {
* Note: places with blank addresses will not appear in persistence.
*/
export function saveUserPlace(placeToSave, placeIndex, intl) {
- return function (dispatch, getState) {
+ return async function (dispatch, getState) {
const { loggedInUser } = getState().user
if (placeIndex === 'new') {
loggedInUser.savedLocations.push(placeToSave)
@@ -682,8 +682,8 @@ export function saveUserPlace(placeToSave, placeIndex, intl) {
loggedInUser.savedLocations[placeIndex] = placeToSave
}
- dispatch(createOrUpdateUser(loggedInUser, true, intl))
- if (intl) {
+ const result = await dispatch(createOrUpdateUser(loggedInUser, intl))
+ if (result === UserActionResult.SUCCESS && intl) {
toast.success(
intl.formatMessage(
{
@@ -717,7 +717,7 @@ export function deleteLoggedInUserPlace(placeIndex, intl) {
const { loggedInUser } = getState().user
loggedInUser.savedLocations.splice(placeIndex, 1)
- dispatch(createOrUpdateUser(loggedInUser, true, intl))
+ dispatch(createOrUpdateUser(loggedInUser, intl))
}
}
diff --git a/lib/components/user/user-account-screen.js b/lib/components/user/user-account-screen.js
index d119bd4f5..77e48e6b0 100644
--- a/lib/components/user/user-account-screen.js
+++ b/lib/components/user/user-account-screen.js
@@ -6,6 +6,7 @@ import { Form, Formik } from 'formik'
import { injectIntl } from 'react-intl'
import { withAuthenticationRequired } from '@auth0/auth0-react'
import React, { Component } from 'react'
+import toast from 'react-hot-toast'
import * as uiActions from '../../actions/ui'
import * as userActions from '../../actions/user'
@@ -45,8 +46,12 @@ class UserAccountScreen extends Component {
const { createOrUpdateUser, intl } = this.props
// TODO: Change state of Save button while the update action takes place.
- // The call below will also display a toast notification on success.
- await createOrUpdateUser(userData, silentOnSucceed, intl)
+ const result = await createOrUpdateUser(userData, intl)
+
+ // If needed, display a toast notification on success.
+ if (result === userActions.UserActionResult.SUCCESS && !silentOnSucceed) {
+ toast.success(intl.formatMessage({ id: 'actions.user.preferencesSaved' }))
+ }
}
/**
From d385ec2c9500fb1cb030e115dafd3a0a735f5491 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Thu, 7 Sep 2023 12:42:19 -0400
Subject: [PATCH 38/80] improvement(actions/user): Alert if trying to save
location while logged out.
---
i18n/en-US.yml | 3 ++-
i18n/fr.yml | 2 ++
lib/actions/user.js | 30 ++++++++++++++++++------------
3 files changed, 22 insertions(+), 13 deletions(-)
diff --git a/i18n/en-US.yml b/i18n/en-US.yml
index d7d88e730..968c369ba 100644
--- a/i18n/en-US.yml
+++ b/i18n/en-US.yml
@@ -52,7 +52,8 @@ actions:
emailVerificationResent: The email verification message has been resent.
genericError: "An error was encountered: {err}"
itineraryExistenceCheckFailed: Error checking whether your selected trip is possible.
- placeRemembered: Your {placeType} has been set to {address}.
+ mustBeLoggedInToSavePlace: Please log in to save locations.
+ placeRemembered: "Your {placeType} has been set to: {address}."
preferencesSaved: Your preferences have been saved.
smsInvalidCode: The code you entered is invalid. Please try again.
smsResendThrottled: >-
diff --git a/i18n/fr.yml b/i18n/fr.yml
index 5c41e72fc..0d88fc3ab 100644
--- a/i18n/fr.yml
+++ b/i18n/fr.yml
@@ -58,6 +58,8 @@ actions:
nouveau.
genericError: "Une erreur s'est produite : {err}"
itineraryExistenceCheckFailed: Erreur lors de la vérification de la validité du trajet choisi.
+ mustBeLoggedInToSavePlace: Veuillez vous connecter pour enregistrer des lieux.
+ placeRemembered: "Votre {placeType} est maintenant à : {address}."
preferencesSaved: Vos préférences ont été enregistrées.
smsInvalidCode: Le code saisi est incorrect. Veuillez réessayer.
smsResendThrottled: >-
diff --git a/lib/actions/user.js b/lib/actions/user.js
index 36ee06ba1..aed8f4de6 100644
--- a/lib/actions/user.js
+++ b/lib/actions/user.js
@@ -759,19 +759,25 @@ export function rememberPlace(placeTypeLocation, intl) {
const persistenceMode = getPersistenceMode(otp.config.persistence)
const { loggedInUser } = user
- if (persistenceMode.isOtpMiddleware && loggedInUser) {
- // For middleware loggedInUsers, this method should only be triggered by the
- // 'Save as home' or 'Save as work' links from OTP UI's EndPointOverlay/EndPoint.
- const { location } = placeTypeLocation
- if (isHomeOrWork(location)) {
- // Find the index of the place in the loggedInUser.savedLocations
- const placeIndex = loggedInUser.savedLocations.findIndex(
- (loc) => loc.type === location.type
- )
- if (placeIndex > -1) {
- // Convert to loggedInUser saved place
- dispatch(saveUserPlace(convertToPlace(location), placeIndex, intl))
+ if (persistenceMode.isOtpMiddleware) {
+ if (loggedInUser) {
+ // For middleware loggedInUsers, this method should only be triggered by the
+ // 'Save as home' or 'Save as work' links from OTP UI's EndPointOverlay/EndPoint.
+ const { location } = placeTypeLocation
+ if (isHomeOrWork(location)) {
+ // Find the index of the place in the loggedInUser.savedLocations
+ const placeIndex = loggedInUser.savedLocations.findIndex(
+ (loc) => loc.type === location.type
+ )
+ if (placeIndex > -1) {
+ // Convert to loggedInUser saved place
+ dispatch(saveUserPlace(convertToPlace(location), placeIndex, intl))
+ }
}
+ } else {
+ alert(
+ intl.formatMessage({ id: 'actions.user.mustBeLoggedInToSavePlace' })
+ )
}
} else if (persistenceMode.isLocalStorage) {
dispatch(rememberLocalUserPlace(placeTypeLocation))
From 22ca13ce47aa2f1e77ced3473909631382462bb2 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Thu, 7 Sep 2023 13:19:51 -0400
Subject: [PATCH 39/80] improvement(actions/user): Apply toast to localStorage
strategy.
---
lib/actions/user.js | 27 ++++++-------------
.../map/connected-endpoints-overlay.tsx | 19 ++++++++++---
.../user/places/favorite-place-screen.js | 7 +++--
lib/util/user.js | 22 ++++++++++++++-
4 files changed, 49 insertions(+), 26 deletions(-)
diff --git a/lib/actions/user.js b/lib/actions/user.js
index aed8f4de6..5964965fe 100644
--- a/lib/actions/user.js
+++ b/lib/actions/user.js
@@ -674,7 +674,7 @@ export function planNewTripFromMonitoredTrip(monitoredTrip) {
* Note: places with blank addresses will not appear in persistence.
*/
export function saveUserPlace(placeToSave, placeIndex, intl) {
- return async function (dispatch, getState) {
+ return function (dispatch, getState) {
const { loggedInUser } = getState().user
if (placeIndex === 'new') {
loggedInUser.savedLocations.push(placeToSave)
@@ -682,22 +682,7 @@ export function saveUserPlace(placeToSave, placeIndex, intl) {
loggedInUser.savedLocations[placeIndex] = placeToSave
}
- const result = await dispatch(createOrUpdateUser(loggedInUser, intl))
- if (result === UserActionResult.SUCCESS && intl) {
- toast.success(
- intl.formatMessage(
- {
- id: 'actions.user.placeRemembered'
- },
- {
- address: placeToSave.address,
- placeType: intl.formatMessage({
- id: `common.places.${placeToSave.type}`
- })
- }
- )
- )
- }
+ return dispatch(createOrUpdateUser(loggedInUser, intl))
}
}
@@ -754,7 +739,7 @@ export function deleteUserPlace(place, intl) {
* according to the persistence strategy.
*/
export function rememberPlace(placeTypeLocation, intl) {
- return function (dispatch, getState) {
+ return async function (dispatch, getState) {
const { otp, user } = getState()
const persistenceMode = getPersistenceMode(otp.config.persistence)
const { loggedInUser } = user
@@ -771,7 +756,9 @@ export function rememberPlace(placeTypeLocation, intl) {
)
if (placeIndex > -1) {
// Convert to loggedInUser saved place
- dispatch(saveUserPlace(convertToPlace(location), placeIndex, intl))
+ return dispatch(
+ saveUserPlace(convertToPlace(location), placeIndex, intl)
+ )
}
}
} else {
@@ -779,8 +766,10 @@ export function rememberPlace(placeTypeLocation, intl) {
intl.formatMessage({ id: 'actions.user.mustBeLoggedInToSavePlace' })
)
}
+ return UserActionResult.FAILURE
} else if (persistenceMode.isLocalStorage) {
dispatch(rememberLocalUserPlace(placeTypeLocation))
+ return UserActionResult.SUCCESS
}
}
}
diff --git a/lib/components/map/connected-endpoints-overlay.tsx b/lib/components/map/connected-endpoints-overlay.tsx
index 67566f0c4..f491999a8 100644
--- a/lib/components/map/connected-endpoints-overlay.tsx
+++ b/lib/components/map/connected-endpoints-overlay.tsx
@@ -5,9 +5,17 @@ import EndpointsOverlay from '@opentripplanner/endpoints-overlay'
import React, { ComponentProps, useCallback } from 'react'
import { clearLocation } from '../../actions/form'
-import { forgetPlace, rememberPlace } from '../../actions/user'
+import {
+ convertToPlace,
+ getUserLocations,
+ toastOnPlaceSaved
+} from '../../util/user'
+import {
+ forgetPlace,
+ rememberPlace,
+ UserActionResult
+} from '../../actions/user'
import { getActiveSearch, getShowUserSettings } from '../../util/state'
-import { getUserLocations } from '../../util/user'
import { setLocation } from '../../actions/map'
type Props = ComponentProps & {
@@ -29,8 +37,11 @@ const ConnectedEndpointsOverlay = ({
)
const _rememberPlace = useCallback(
- (placeTypeLocation) => {
- rememberPlace(placeTypeLocation, intl)
+ async (placeTypeLocation) => {
+ const result = await rememberPlace(placeTypeLocation, intl)
+ if (result === UserActionResult.SUCCESS) {
+ toastOnPlaceSaved(convertToPlace(placeTypeLocation.location), intl)
+ }
},
[rememberPlace, intl]
)
diff --git a/lib/components/user/places/favorite-place-screen.js b/lib/components/user/places/favorite-place-screen.js
index 900a123ff..771e7cca4 100644
--- a/lib/components/user/places/favorite-place-screen.js
+++ b/lib/components/user/places/favorite-place-screen.js
@@ -21,7 +21,7 @@ import { PageHeading } from '../styled'
import { CREATE_ACCOUNT_PLACES_PATH } from '../../../util/constants'
import { getFormattedPlaces } from '../../../util/i18n'
import { isBlank, navigateBack, RETURN_TO_CURRENT_ROUTE } from '../../../util/ui'
-import { isHomeOrWork, PLACE_TYPES } from '../../../util/user'
+import { isHomeOrWork, PLACE_TYPES, toastOnPlaceSaved } from '../../../util/user'
import withLoggedInUserSupport from '../with-logged-in-user-support'
import { InlineLoading } from '../../narrative/loading'
import PageTitle from '../../util/page-title'
@@ -70,7 +70,10 @@ class FavoritePlaceScreen extends Component {
// Save changes to loggedInUser.
const { intl, placeIndex, saveUserPlace } = this.props
- await saveUserPlace(placeToSave, placeIndex, intl)
+ const result = await saveUserPlace(placeToSave, placeIndex, intl)
+ if (result === userActions.UserActionResult.SUCCESS) {
+ toastOnPlaceSaved(placeToSave, intl)
+ }
// Return to previous location when done.
navigateBack()
diff --git a/lib/util/user.js b/lib/util/user.js
index 0c12afcd0..47545982c 100644
--- a/lib/util/user.js
+++ b/lib/util/user.js
@@ -1,5 +1,6 @@
import { addInParentheses } from '@opentripplanner/location-field/lib/utils'
import coreUtils from '@opentripplanner/core-utils'
+import toast from 'react-hot-toast'
import {
CREATE_ACCOUNT_PLACES_PATH,
@@ -138,7 +139,7 @@ export function convertToLegacyLocation(place) {
lon,
// HACK: If a place name and address are provided, put the address in parentheses
// to mimic the existing LocationField behavior for "work" and "home".
- // TODO: use addInParentheses from location-field (requires passing an intl contexty).
+ // TODO: use addInParentheses from location-field (requires passing an intl context).
name: isHomeOrWork(place)
? address
: address && name
@@ -221,3 +222,22 @@ export function getPlaceMainText(place, intl) {
? toSentenceCase(getFormattedPlaces(place.type, intl))
: place.name || place.address
}
+
+/**
+ * Helper that will display a toast notification when a place is saved.
+ */
+export function toastOnPlaceSaved(place, intl) {
+ toast.success(
+ intl.formatMessage(
+ {
+ id: 'actions.user.placeRemembered'
+ },
+ {
+ address: place.address,
+ placeType: intl.formatMessage({
+ id: `common.places.${place.type}`
+ })
+ }
+ )
+ )
+}
From bcba7664a48e9b9ae6bdeb40ea8d4f8506499bef Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Thu, 7 Sep 2023 13:29:55 -0400
Subject: [PATCH 40/80] chore(i18n): Tweak FR text.
---
i18n/fr.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/i18n/fr.yml b/i18n/fr.yml
index 0d88fc3ab..e2a22c1f2 100644
--- a/i18n/fr.yml
+++ b/i18n/fr.yml
@@ -59,7 +59,7 @@ actions:
genericError: "Une erreur s'est produite : {err}"
itineraryExistenceCheckFailed: Erreur lors de la vérification de la validité du trajet choisi.
mustBeLoggedInToSavePlace: Veuillez vous connecter pour enregistrer des lieux.
- placeRemembered: "Votre {placeType} est maintenant à : {address}."
+ placeRemembered: "Votre {placeType} est maintenant au : {address}."
preferencesSaved: Vos préférences ont été enregistrées.
smsInvalidCode: Le code saisi est incorrect. Veuillez réessayer.
smsResendThrottled: >-
From 79cb19815746d7c78ecd9fee15b4e1e49d86f566 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Thu, 7 Sep 2023 14:09:35 -0400
Subject: [PATCH 41/80] refactor: Address type errors, remove unneeded async.
---
lib/actions/user.js | 2 +-
lib/components/map/connected-endpoints-overlay.tsx | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/actions/user.js b/lib/actions/user.js
index 5964965fe..4c5336bff 100644
--- a/lib/actions/user.js
+++ b/lib/actions/user.js
@@ -739,7 +739,7 @@ export function deleteUserPlace(place, intl) {
* according to the persistence strategy.
*/
export function rememberPlace(placeTypeLocation, intl) {
- return async function (dispatch, getState) {
+ return function (dispatch, getState) {
const { otp, user } = getState()
const persistenceMode = getPersistenceMode(otp.config.persistence)
const { loggedInUser } = user
diff --git a/lib/components/map/connected-endpoints-overlay.tsx b/lib/components/map/connected-endpoints-overlay.tsx
index f491999a8..9c4c39e07 100644
--- a/lib/components/map/connected-endpoints-overlay.tsx
+++ b/lib/components/map/connected-endpoints-overlay.tsx
@@ -20,7 +20,7 @@ import { setLocation } from '../../actions/map'
type Props = ComponentProps & {
forgetPlace: (place: string, intl: IntlShape) => void
- rememberPlace: (arg: UserLocationAndType, intl: IntlShape) => void
+ rememberPlace: (arg: UserLocationAndType, intl: IntlShape) => number
}
const ConnectedEndpointsOverlay = ({
From dc40b6eee60f212327afdedca7af652cf8493d32 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Thu, 7 Sep 2023 17:36:52 -0400
Subject: [PATCH 42/80] ci(percy): Use sep key for calltaker, take mobile snaps
in non-calltaker test.
---
.github/workflows/percy.yml | 14 +++---
percy/percy.test.js | 85 +++++++++++++++++++------------------
2 files changed, 48 insertions(+), 51 deletions(-)
diff --git a/.github/workflows/percy.yml b/.github/workflows/percy.yml
index ae53907d2..957eafc81 100644
--- a/.github/workflows/percy.yml
+++ b/.github/workflows/percy.yml
@@ -32,18 +32,13 @@ jobs:
env:
YAML_CONFIG: /tmp/otp2config.yml
JS_CONFIG: ./percy/har-mock-config.js
- - name: Take Percy Snapshots (Desktop)
+ - name: Take Percy Snapshots (Desktop + Mobile)
run: npx percy exec -- npx jest percy/percy.test.js --force-exit
env:
PERCY_TOKEN: ${{ secrets.PERCY_TOKEN_OTP2 }}
- OTP_RR_UI_MODE: desktop
- - name: Take Percy Snapshots (Mobile)
- run: npx percy exec -- npx jest percy/percy.test.js --force-exit
- env:
- PERCY_TOKEN: ${{ secrets.PERCY_TOKEN_OTP2 }}
- OTP_RR_UI_MODE: mobile
- # Calltaker has a separate config file, so another build should be produced.
+ OTP_RR_UI_MODE: normal
- name: Build OTP-RR Calltaker
+ # Calltaker has a separate config file, so another build should be produced.
run: yarn build
env:
YAML_CONFIG: /tmp/otp2config.yml
@@ -51,5 +46,6 @@ jobs:
- name: Take Percy Snapshots (Calltaker)
run: npx percy exec -- npx jest percy/percy.test.js --force-exit
env:
- PERCY_TOKEN: ${{ secrets.PERCY_TOKEN_OTP2 }}
+ # Calltaker has a separate key because the calltaker-specific snapshots are different.
+ PERCY_TOKEN: ${{ secrets.PERCY_TOKEN_CALL_TAKER_OTP2 }}
OTP_RR_UI_MODE: calltaker
diff --git a/percy/percy.test.js b/percy/percy.test.js
index 462419dcb..9c62e92e7 100644
--- a/percy/percy.test.js
+++ b/percy/percy.test.js
@@ -357,7 +357,49 @@ async function executeTest(page, isMobile, isCallTaker) {
}
}
-if (OTP_RR_UI_MODE === 'mobile') {
+test('OTP-RR Desktop', async () => {
+ const page = await loadPath('/')
+ await page.setViewport({
+ height: 1080,
+ width: 1920
+ })
+ page.on('console', async (msg) => {
+ const args = await msg.args()
+ args.forEach(async (arg) => {
+ const val = await arg.jsonValue()
+ // value is serializable
+ if (JSON.stringify(val) !== JSON.stringify({})) console.log(val)
+ // value is unserializable (or an empty oject)
+ else {
+ const { description, subtype, type } = arg._remoteObject
+ console.log(
+ `type: ${type}, subtype: ${subtype}, description:\n ${description}`
+ )
+ }
+ })
+ })
+ // log all errors that were logged to the browser console
+ page.on('warn', (warn) => {
+ console.log(warn)
+ })
+ page.on('error', (error) => {
+ console.error(error)
+ console.error(error.stack)
+ })
+ // log all uncaught exceptions
+ page.on('pageerror', (error) => {
+ console.error(`Page Error: ${error}`)
+ })
+ // log all failed requests
+ page.on('requestfailed', (req) => {
+ console.error(`Request failed: ${req.method()} ${req.url()}`)
+ })
+
+ await executeTest(page, false, OTP_RR_UI_MODE === 'calltaker')
+})
+
+if (OTP_RR_UI_MODE !== 'calltaker') {
+ // Non-calltaker test runs both mobile and desktop test.
test('OTP-RR Mobile', async () => {
const page = await loadPath('/')
await page.setUserAgent('android')
@@ -371,45 +413,4 @@ if (OTP_RR_UI_MODE === 'mobile') {
// Execute the rest of the test
await executeTest(page, true, false)
})
-} else {
- test('OTP-RR Desktop', async () => {
- const page = await loadPath('/')
- await page.setViewport({
- height: 1080,
- width: 1920
- })
- page.on('console', async (msg) => {
- const args = await msg.args()
- args.forEach(async (arg) => {
- const val = await arg.jsonValue()
- // value is serializable
- if (JSON.stringify(val) !== JSON.stringify({})) console.log(val)
- // value is unserializable (or an empty oject)
- else {
- const { description, subtype, type } = arg._remoteObject
- console.log(
- `type: ${type}, subtype: ${subtype}, description:\n ${description}`
- )
- }
- })
- })
- // log all errors that were logged to the browser console
- page.on('warn', (warn) => {
- console.log(warn)
- })
- page.on('error', (error) => {
- console.error(error)
- console.error(error.stack)
- })
- // log all uncaught exceptions
- page.on('pageerror', (error) => {
- console.error(`Page Error: ${error}`)
- })
- // log all failed requests
- page.on('requestfailed', (req) => {
- console.error(`Request failed: ${req.method()} ${req.url()}`)
- })
-
- await executeTest(page, false, OTP_RR_UI_MODE === 'calltaker')
- })
}
From 4b7acc1668f63f8a06e7cc5491abb22319991c80 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Fri, 8 Sep 2023 12:22:05 -0400
Subject: [PATCH 43/80] test(percy): Create and use mock geocoder responses for
calltaker.
---
percy/geocoder-mock.har | 793 ++++++++++++++++++++++++++++++++++++++++
percy/percy.test.js | 16 +-
2 files changed, 808 insertions(+), 1 deletion(-)
create mode 100644 percy/geocoder-mock.har
diff --git a/percy/geocoder-mock.har b/percy/geocoder-mock.har
new file mode 100644
index 000000000..6d9e46391
--- /dev/null
+++ b/percy/geocoder-mock.har
@@ -0,0 +1,793 @@
+{
+ "log": {
+ "version": "1.2",
+ "creator": {
+ "name": "WebInspector",
+ "version": "537.36"
+ },
+ "pages": [],
+ "entries": [
+ {
+ "request": {
+ "method": "GET",
+ "url": "http://localhost:9977/autocomplete?text=a&layers=address%2Cvenue%2Cstreet%2Cintersection&focus.point.lat=33.749&focus.point.lon=-84.388&boundary.rect.min_lat=32.066&boundary.rect.min_lon=-86.0856&boundary.rect.max_lat=35.7251&boundary.rect.max_lon=-81.9499",
+ "httpVersion": "http/2.0",
+ "queryString": [
+ {
+ "name": "text",
+ "value": "a"
+ },
+ {
+ "name": "layers",
+ "value": "address%2Cvenue%2Cstreet%2Cintersection"
+ },
+ {
+ "name": "focus.point.lat",
+ "value": "33.749"
+ },
+ {
+ "name": "focus.point.lon",
+ "value": "-84.388"
+ },
+ {
+ "name": "boundary.rect.min_lat",
+ "value": "32.066"
+ },
+ {
+ "name": "boundary.rect.min_lon",
+ "value": "-86.0856"
+ },
+ {
+ "name": "boundary.rect.max_lat",
+ "value": "35.7251"
+ },
+ {
+ "name": "boundary.rect.max_lon",
+ "value": "-81.9499"
+ }
+ ],
+ "headersSize": -1,
+ "bodySize": 0
+ },
+ "response": {
+ "status": 200,
+ "statusText": "",
+ "httpVersion": "http/2.0",
+ "content": {
+ "size": 11710,
+ "mimeType": "application/json",
+ "text": ""
+ },
+ "redirectURL": "",
+ "headersSize": -1,
+ "bodySize": -1,
+ "_transferSize": 12109,
+ "_error": null
+ },
+ "serverIPAddress": "[64:ff9b::d21:40f]",
+ "startedDateTime": "2023-09-08T13:53:49.885Z",
+ "time": 449.04499999984364,
+ "timings": {
+ "blocked": 2.153000000224507,
+ "dns": 86.366,
+ "ssl": 73.93199999999999,
+ "connect": 192.28,
+ "send": 7.209000000000003,
+ "wait": 160.31799999995653,
+ "receive": 0.7189999996626284,
+ "_blocked_queueing": 1.352000000224507
+ }
+ },
+ {
+ "request": {
+ "method": "GET",
+ "url": "http://localhost:9977/autocomplete?text=ar&layers=address%2Cvenue%2Cstreet%2Cintersection&focus.point.lat=33.749&focus.point.lon=-84.388&boundary.rect.min_lat=32.066&boundary.rect.min_lon=-86.0856&boundary.rect.max_lat=35.7251&boundary.rect.max_lon=-81.9499",
+ "httpVersion": "http/2.0",
+ "queryString": [
+ {
+ "name": "text",
+ "value": "ar"
+ },
+ {
+ "name": "layers",
+ "value": "address%2Cvenue%2Cstreet%2Cintersection"
+ },
+ {
+ "name": "focus.point.lat",
+ "value": "33.749"
+ },
+ {
+ "name": "focus.point.lon",
+ "value": "-84.388"
+ },
+ {
+ "name": "boundary.rect.min_lat",
+ "value": "32.066"
+ },
+ {
+ "name": "boundary.rect.min_lon",
+ "value": "-86.0856"
+ },
+ {
+ "name": "boundary.rect.max_lat",
+ "value": "35.7251"
+ },
+ {
+ "name": "boundary.rect.max_lon",
+ "value": "-81.9499"
+ }
+ ],
+ "headersSize": -1,
+ "bodySize": 0
+ },
+ "response": {
+ "status": 200,
+ "statusText": "",
+ "httpVersion": "http/2.0",
+ "content": {
+ "size": 10681,
+ "mimeType": "application/json",
+ "text": ""
+ },
+ "redirectURL": "",
+ "headersSize": -1,
+ "bodySize": -1,
+ "_transferSize": 11081,
+ "_error": null
+ },
+ "serverIPAddress": "[64:ff9b::d21:40f]",
+ "startedDateTime": "2023-09-08T13:53:49.902Z",
+ "time": 804.0409999994154,
+ "timings": {
+ "blocked": 181.69800000018896,
+ "dns": -1,
+ "ssl": -1,
+ "connect": -1,
+ "send": 3.2079999999999984,
+ "wait": 618.41899999967,
+ "receive": 0.7159999995565158,
+ "_blocked_queueing": 1.231000000188942
+ }
+ },
+ {
+ "request": {
+ "method": "GET",
+ "url": "http://localhost:9977/autocomplete?text=art&layers=address%2Cvenue%2Cstreet%2Cintersection&focus.point.lat=33.749&focus.point.lon=-84.388&boundary.rect.min_lat=32.066&boundary.rect.min_lon=-86.0856&boundary.rect.max_lat=35.7251&boundary.rect.max_lon=-81.9499",
+ "httpVersion": "http/2.0",
+ "queryString": [
+ {
+ "name": "text",
+ "value": "art"
+ },
+ {
+ "name": "layers",
+ "value": "address%2Cvenue%2Cstreet%2Cintersection"
+ },
+ {
+ "name": "focus.point.lat",
+ "value": "33.749"
+ },
+ {
+ "name": "focus.point.lon",
+ "value": "-84.388"
+ },
+ {
+ "name": "boundary.rect.min_lat",
+ "value": "32.066"
+ },
+ {
+ "name": "boundary.rect.min_lon",
+ "value": "-86.0856"
+ },
+ {
+ "name": "boundary.rect.max_lat",
+ "value": "35.7251"
+ },
+ {
+ "name": "boundary.rect.max_lon",
+ "value": "-81.9499"
+ }
+ ],
+ "headersSize": -1,
+ "bodySize": 0
+ },
+ "response": {
+ "status": 200,
+ "statusText": "",
+ "httpVersion": "http/2.0",
+ "content": {
+ "size": 10853,
+ "mimeType": "application/json",
+ "text": ""
+ },
+ "redirectURL": "",
+ "headersSize": -1,
+ "bodySize": -1,
+ "_transferSize": 11253,
+ "_error": null
+ },
+ "serverIPAddress": "[64:ff9b::d21:40f]",
+ "startedDateTime": "2023-09-08T13:53:49.909Z",
+ "time": 1204.160999999658,
+ "timings": {
+ "blocked": 175.13099999983532,
+ "dns": -1,
+ "ssl": -1,
+ "connect": -1,
+ "send": 2.973000000000013,
+ "wait": 1025.2889999999427,
+ "receive": 0.7679999998799758,
+ "_blocked_queueing": 1.2809999998353305
+ }
+ },
+ {
+ "request": {
+ "method": "GET",
+ "url": "http://localhost:9977/autocomplete?text=arts&layers=address%2Cvenue%2Cstreet%2Cintersection&focus.point.lat=33.749&focus.point.lon=-84.388&boundary.rect.min_lat=32.066&boundary.rect.min_lon=-86.0856&boundary.rect.max_lat=35.7251&boundary.rect.max_lon=-81.9499",
+ "httpVersion": "http/2.0",
+ "queryString": [
+ {
+ "name": "text",
+ "value": "arts"
+ },
+ {
+ "name": "layers",
+ "value": "address%2Cvenue%2Cstreet%2Cintersection"
+ },
+ {
+ "name": "focus.point.lat",
+ "value": "33.749"
+ },
+ {
+ "name": "focus.point.lon",
+ "value": "-84.388"
+ },
+ {
+ "name": "boundary.rect.min_lat",
+ "value": "32.066"
+ },
+ {
+ "name": "boundary.rect.min_lon",
+ "value": "-86.0856"
+ },
+ {
+ "name": "boundary.rect.max_lat",
+ "value": "35.7251"
+ },
+ {
+ "name": "boundary.rect.max_lon",
+ "value": "-81.9499"
+ }
+ ],
+ "headersSize": -1,
+ "bodySize": 0
+ },
+ "response": {
+ "status": 200,
+ "statusText": "",
+ "httpVersion": "http/2.0",
+ "content": {
+ "size": 12368,
+ "mimeType": "application/json",
+ "text": ""
+ },
+ "redirectURL": "",
+ "headersSize": -1,
+ "bodySize": -1,
+ "_transferSize": 12769,
+ "_error": null
+ },
+ "serverIPAddress": "[64:ff9b::d21:40f]",
+ "startedDateTime": "2023-09-08T13:53:49.917Z",
+ "time": 313.9339999997901,
+ "timings": {
+ "blocked": 167.4080000005329,
+ "dns": -1,
+ "ssl": -1,
+ "connect": -1,
+ "send": 2.7959999999999923,
+ "wait": 143.22000000031747,
+ "receive": 0.5099999989397475,
+ "_blocked_queueing": 1.4550000005328911
+ }
+ },
+ {
+ "request": {
+ "method": "GET",
+ "url": "http://localhost:9977/autocomplete?text=arts%20&layers=address%2Cvenue%2Cstreet%2Cintersection&focus.point.lat=33.749&focus.point.lon=-84.388&boundary.rect.min_lat=32.066&boundary.rect.min_lon=-86.0856&boundary.rect.max_lat=35.7251&boundary.rect.max_lon=-81.9499",
+ "httpVersion": "http/2.0",
+ "queryString": [
+ {
+ "name": "text",
+ "value": "arts%20"
+ },
+ {
+ "name": "layers",
+ "value": "address%2Cvenue%2Cstreet%2Cintersection"
+ },
+ {
+ "name": "focus.point.lat",
+ "value": "33.749"
+ },
+ {
+ "name": "focus.point.lon",
+ "value": "-84.388"
+ },
+ {
+ "name": "boundary.rect.min_lat",
+ "value": "32.066"
+ },
+ {
+ "name": "boundary.rect.min_lon",
+ "value": "-86.0856"
+ },
+ {
+ "name": "boundary.rect.max_lat",
+ "value": "35.7251"
+ },
+ {
+ "name": "boundary.rect.max_lon",
+ "value": "-81.9499"
+ }
+ ],
+ "headersSize": -1,
+ "bodySize": 0
+ },
+ "response": {
+ "status": 200,
+ "statusText": "",
+ "httpVersion": "http/2.0",
+ "content": {
+ "size": 12369,
+ "mimeType": "application/json",
+ "text": ""
+ },
+ "redirectURL": "",
+ "headersSize": -1,
+ "bodySize": -1,
+ "_transferSize": 12768,
+ "_error": null
+ },
+ "serverIPAddress": "[64:ff9b::d21:40f]",
+ "startedDateTime": "2023-09-08T13:53:49.923Z",
+ "time": 1060.0050000002739,
+ "timings": {
+ "blocked": 161.1640000008461,
+ "dns": -1,
+ "ssl": -1,
+ "connect": -1,
+ "send": 2.658999999999992,
+ "wait": 895.6010000000988,
+ "receive": 0.5809999993289239,
+ "_blocked_queueing": 1.4210000008461066
+ }
+ },
+ {
+ "request": {
+ "method": "GET",
+ "url": "http://localhost:9977/autocomplete?text=arts%20c&layers=address%2Cvenue%2Cstreet%2Cintersection&focus.point.lat=33.749&focus.point.lon=-84.388&boundary.rect.min_lat=32.066&boundary.rect.min_lon=-86.0856&boundary.rect.max_lat=35.7251&boundary.rect.max_lon=-81.9499",
+ "httpVersion": "http/2.0",
+ "queryString": [
+ {
+ "name": "text",
+ "value": "arts%20c"
+ },
+ {
+ "name": "layers",
+ "value": "address%2Cvenue%2Cstreet%2Cintersection"
+ },
+ {
+ "name": "focus.point.lat",
+ "value": "33.749"
+ },
+ {
+ "name": "focus.point.lon",
+ "value": "-84.388"
+ },
+ {
+ "name": "boundary.rect.min_lat",
+ "value": "32.066"
+ },
+ {
+ "name": "boundary.rect.min_lon",
+ "value": "-86.0856"
+ },
+ {
+ "name": "boundary.rect.max_lat",
+ "value": "35.7251"
+ },
+ {
+ "name": "boundary.rect.max_lon",
+ "value": "-81.9499"
+ }
+ ],
+ "headersSize": -1,
+ "bodySize": 0
+ },
+ "response": {
+ "status": 200,
+ "statusText": "",
+ "httpVersion": "http/2.0",
+ "content": {
+ "size": 10616,
+ "mimeType": "application/json",
+ "text": ""
+ },
+ "redirectURL": "",
+ "headersSize": -1,
+ "bodySize": -1,
+ "_transferSize": 11016,
+ "_error": null
+ },
+ "serverIPAddress": "[64:ff9b::d21:40f]",
+ "startedDateTime": "2023-09-08T13:53:49.932Z",
+ "time": 812.2540000003937,
+ "timings": {
+ "blocked": 152.40299999998243,
+ "dns": -1,
+ "ssl": -1,
+ "connect": -1,
+ "send": 2.4749999999999943,
+ "wait": 656.5110000004352,
+ "receive": 0.8649999999761349,
+ "_blocked_queueing": 1.6279999999824213
+ }
+ },
+ {
+ "request": {
+ "method": "GET",
+ "url": "http://localhost:9977/autocomplete?text=arts%20ce&layers=address%2Cvenue%2Cstreet%2Cintersection&focus.point.lat=33.749&focus.point.lon=-84.388&boundary.rect.min_lat=32.066&boundary.rect.min_lon=-86.0856&boundary.rect.max_lat=35.7251&boundary.rect.max_lon=-81.9499",
+ "httpVersion": "http/2.0",
+ "queryString": [
+ {
+ "name": "text",
+ "value": "arts%20ce"
+ },
+ {
+ "name": "layers",
+ "value": "address%2Cvenue%2Cstreet%2Cintersection"
+ },
+ {
+ "name": "focus.point.lat",
+ "value": "33.749"
+ },
+ {
+ "name": "focus.point.lon",
+ "value": "-84.388"
+ },
+ {
+ "name": "boundary.rect.min_lat",
+ "value": "32.066"
+ },
+ {
+ "name": "boundary.rect.min_lon",
+ "value": "-86.0856"
+ },
+ {
+ "name": "boundary.rect.max_lat",
+ "value": "35.7251"
+ },
+ {
+ "name": "boundary.rect.max_lon",
+ "value": "-81.9499"
+ }
+ ],
+ "headersSize": -1,
+ "bodySize": 0
+ },
+ "response": {
+ "status": 200,
+ "statusText": "",
+ "httpVersion": "http/2.0",
+ "content": {
+ "size": 10608,
+ "mimeType": "application/json",
+ "text": ""
+ },
+ "redirectURL": "",
+ "headersSize": -1,
+ "bodySize": -1,
+ "_transferSize": 11006,
+ "_error": null
+ },
+ "serverIPAddress": "[64:ff9b::d21:40f]",
+ "startedDateTime": "2023-09-08T13:53:49.938Z",
+ "time": 1667.8229999997711,
+ "timings": {
+ "blocked": 147.01800000041595,
+ "dns": -1,
+ "ssl": -1,
+ "connect": -1,
+ "send": 1.9000000000000057,
+ "wait": 1517.6120000000049,
+ "receive": 1.292999999350286,
+ "_blocked_queueing": 1.006000000415952
+ }
+ },
+ {
+ "request": {
+ "method": "GET",
+ "url": "http://localhost:9977/autocomplete?text=arts%20cen&layers=address%2Cvenue%2Cstreet%2Cintersection&focus.point.lat=33.749&focus.point.lon=-84.388&boundary.rect.min_lat=32.066&boundary.rect.min_lon=-86.0856&boundary.rect.max_lat=35.7251&boundary.rect.max_lon=-81.9499",
+ "httpVersion": "http/2.0",
+ "queryString": [
+ {
+ "name": "text",
+ "value": "arts%20cen"
+ },
+ {
+ "name": "layers",
+ "value": "address%2Cvenue%2Cstreet%2Cintersection"
+ },
+ {
+ "name": "focus.point.lat",
+ "value": "33.749"
+ },
+ {
+ "name": "focus.point.lon",
+ "value": "-84.388"
+ },
+ {
+ "name": "boundary.rect.min_lat",
+ "value": "32.066"
+ },
+ {
+ "name": "boundary.rect.min_lon",
+ "value": "-86.0856"
+ },
+ {
+ "name": "boundary.rect.max_lat",
+ "value": "35.7251"
+ },
+ {
+ "name": "boundary.rect.max_lon",
+ "value": "-81.9499"
+ }
+ ],
+ "headersSize": -1,
+ "bodySize": 0
+ },
+ "response": {
+ "status": 200,
+ "statusText": "",
+ "httpVersion": "http/2.0",
+ "content": {
+ "size": 10612,
+ "mimeType": "application/json",
+ "text": ""
+ },
+ "redirectURL": "",
+ "headersSize": -1,
+ "bodySize": -1,
+ "_transferSize": 11011,
+ "_error": null
+ },
+ "serverIPAddress": "[64:ff9b::d21:40f]",
+ "startedDateTime": "2023-09-08T13:53:49.950Z",
+ "time": 1307.301999999254,
+ "timings": {
+ "blocked": 134.52299999937532,
+ "dns": -1,
+ "ssl": -1,
+ "connect": -1,
+ "send": 2.140999999999991,
+ "wait": 1169.752000000069,
+ "receive": 0.8859999998094281,
+ "_blocked_queueing": 1.1479999993753154
+ }
+ },
+ {
+ "request": {
+ "method": "GET",
+ "url": "http://localhost:9977/autocomplete?text=arts%20cent&layers=address%2Cvenue%2Cstreet%2Cintersection&focus.point.lat=33.749&focus.point.lon=-84.388&boundary.rect.min_lat=32.066&boundary.rect.min_lon=-86.0856&boundary.rect.max_lat=35.7251&boundary.rect.max_lon=-81.9499",
+ "httpVersion": "http/2.0",
+ "queryString": [
+ {
+ "name": "text",
+ "value": "arts%20cent"
+ },
+ {
+ "name": "layers",
+ "value": "address%2Cvenue%2Cstreet%2Cintersection"
+ },
+ {
+ "name": "focus.point.lat",
+ "value": "33.749"
+ },
+ {
+ "name": "focus.point.lon",
+ "value": "-84.388"
+ },
+ {
+ "name": "boundary.rect.min_lat",
+ "value": "32.066"
+ },
+ {
+ "name": "boundary.rect.min_lon",
+ "value": "-86.0856"
+ },
+ {
+ "name": "boundary.rect.max_lat",
+ "value": "35.7251"
+ },
+ {
+ "name": "boundary.rect.max_lon",
+ "value": "-81.9499"
+ }
+ ],
+ "headersSize": -1,
+ "bodySize": 0
+ },
+ "response": {
+ "status": 200,
+ "statusText": "",
+ "httpVersion": "http/2.0",
+ "content": {
+ "size": 10616,
+ "mimeType": "application/json",
+ "text": ""
+ },
+ "redirectURL": "",
+ "headersSize": -1,
+ "bodySize": -1,
+ "_transferSize": 11016,
+ "_error": null
+ },
+ "serverIPAddress": "[64:ff9b::d21:40f]",
+ "startedDateTime": "2023-09-08T13:53:49.958Z",
+ "time": 746.1700000003475,
+ "timings": {
+ "blocked": 126.27700000000658,
+ "dns": -1,
+ "ssl": -1,
+ "connect": -1,
+ "send": 2.3049999999999926,
+ "wait": 616.7630000002638,
+ "receive": 0.8250000000771252,
+ "_blocked_queueing": 0.9430000000065775
+ }
+ },
+ {
+ "request": {
+ "method": "GET",
+ "url": "http://localhost:9977/autocomplete?text=arts%20cente&layers=address%2Cvenue%2Cstreet%2Cintersection&focus.point.lat=33.749&focus.point.lon=-84.388&boundary.rect.min_lat=32.066&boundary.rect.min_lon=-86.0856&boundary.rect.max_lat=35.7251&boundary.rect.max_lon=-81.9499",
+ "httpVersion": "http/2.0",
+ "queryString": [
+ {
+ "name": "text",
+ "value": "arts%20cente"
+ },
+ {
+ "name": "layers",
+ "value": "address%2Cvenue%2Cstreet%2Cintersection"
+ },
+ {
+ "name": "focus.point.lat",
+ "value": "33.749"
+ },
+ {
+ "name": "focus.point.lon",
+ "value": "-84.388"
+ },
+ {
+ "name": "boundary.rect.min_lat",
+ "value": "32.066"
+ },
+ {
+ "name": "boundary.rect.min_lon",
+ "value": "-86.0856"
+ },
+ {
+ "name": "boundary.rect.max_lat",
+ "value": "35.7251"
+ },
+ {
+ "name": "boundary.rect.max_lon",
+ "value": "-81.9499"
+ }
+ ],
+ "headersSize": -1,
+ "bodySize": 0
+ },
+ "response": {
+ "status": 200,
+ "statusText": "",
+ "httpVersion": "http/2.0",
+ "content": {
+ "size": 10620,
+ "mimeType": "application/json",
+ "text": ""
+ },
+ "redirectURL": "",
+ "headersSize": -1,
+ "bodySize": -1,
+ "_transferSize": 11020,
+ "_error": null
+ },
+ "serverIPAddress": "[64:ff9b::d21:40f]",
+ "startedDateTime": "2023-09-08T13:53:49.967Z",
+ "time": 1989.0759999998409,
+ "timings": {
+ "blocked": 117.72999999992608,
+ "dns": -1,
+ "ssl": -1,
+ "connect": -1,
+ "send": 2.0219999999999914,
+ "wait": 1868.6450000001512,
+ "receive": 0.6789999997636187,
+ "_blocked_queueing": 1.1549999999260763
+ }
+ },
+ {
+ "request": {
+ "method": "GET",
+ "url": "http://localhost:9977/autocomplete?text=arts%20center&layers=address%2Cvenue%2Cstreet%2Cintersection&focus.point.lat=33.749&focus.point.lon=-84.388&boundary.rect.min_lat=32.066&boundary.rect.min_lon=-86.0856&boundary.rect.max_lat=35.7251&boundary.rect.max_lon=-81.9499",
+ "httpVersion": "http/2.0",
+ "queryString": [
+ {
+ "name": "text",
+ "value": "arts%20center"
+ },
+ {
+ "name": "layers",
+ "value": "address%2Cvenue%2Cstreet%2Cintersection"
+ },
+ {
+ "name": "focus.point.lat",
+ "value": "33.749"
+ },
+ {
+ "name": "focus.point.lon",
+ "value": "-84.388"
+ },
+ {
+ "name": "boundary.rect.min_lat",
+ "value": "32.066"
+ },
+ {
+ "name": "boundary.rect.min_lon",
+ "value": "-86.0856"
+ },
+ {
+ "name": "boundary.rect.max_lat",
+ "value": "35.7251"
+ },
+ {
+ "name": "boundary.rect.max_lon",
+ "value": "-81.9499"
+ }
+ ],
+ "headersSize": -1,
+ "bodySize": 0
+ },
+ "response": {
+ "status": 200,
+ "statusText": "",
+ "httpVersion": "http/2.0",
+ "content": {
+ "size": 12558,
+ "mimeType": "application/json",
+ "text": "{\"geocoding\":{\"version\":\"0.2\",\"attribution\":\"https://geocode.earth/guidelines\",\"query\":{\"text\":\"arts center\",\"parser\":\"pelias\",\"parsed_text\":{\"subject\":\"arts center\",\"street\":\"arts center\"},\"size\":10,\"layers\":[\"address\",\"venue\",\"street\",\"intersection\"],\"sources\":[\"openstreetmap\",\"openaddresses\",\"geonames\",\"whosonfirst\",\"uscensus\"],\"private\":false,\"focus.point.lat\":33.749,\"focus.point.lon\":-84.388,\"boundary.rect.min_lat\":32.066,\"boundary.rect.max_lat\":35.7251,\"boundary.rect.min_lon\":-86.0856,\"boundary.rect.max_lon\":-81.9499,\"lang\":{\"name\":\"English\",\"iso6391\":\"en\",\"iso6393\":\"eng\",\"via\":\"default\",\"defaulted\":true},\"querySize\":20},\"engine\":{\"name\":\"Pelias\",\"author\":\"Mapzen\",\"version\":\"1.0\"},\"timestamp\":1694180535585},\"type\":\"FeatureCollection\",\"features\":[{\"geometry\":{\"type\":\"Point\",\"coordinates\":[-84.387125,33.789283]},\"id\":\"MARTA:68900\",\"properties\":{\"layer\":\"stops\",\"source\":\"otp\",\"name\":\"Arts Center Station (901789)\",\"label\":\"Arts Center Station (901789)\"},\"type\":\"Feature\"},{\"geometry\":{\"type\":\"Point\",\"coordinates\":[-84.38712,33.789418]},\"id\":\"CobbLinc:717\",\"properties\":{\"layer\":\"stops\",\"source\":\"otp\",\"name\":\"Arts Center Station (920907)\",\"label\":\"Arts Center Station (920907)\"},\"type\":\"Feature\"},{\"geometry\":{\"type\":\"Point\",\"coordinates\":[-84.387272,33.788828]},\"id\":\"MARTA:112\",\"properties\":{\"layer\":\"stops\",\"source\":\"otp\",\"name\":\"Arts Center Station (906370)\",\"label\":\"Arts Center Station (906370)\"},\"type\":\"Feature\"},{\"geometry\":{\"type\":\"Point\",\"coordinates\":[-84.387414,33.789669]},\"id\":\"MARTA:111\",\"properties\":{\"layer\":\"stops\",\"source\":\"otp\",\"name\":\"Arts Center Station (906369)\",\"label\":\"Arts Center Station (906369)\"},\"type\":\"Feature\"},{\"geometry\":{\"type\":\"Point\",\"coordinates\":[-84.387692,33.789216]},\"id\":\"Xpress:239\",\"properties\":{\"layer\":\"stops\",\"source\":\"otp\",\"name\":\"Arts Center Station (400208)\",\"label\":\"Arts Center Station (400208)\"},\"type\":\"Feature\"},{\"geometry\":{\"type\":\"Point\",\"coordinates\":[-84.386904,33.789285]},\"id\":\"GwinnettCountyTransit:32\",\"properties\":{\"layer\":\"stops\",\"source\":\"otp\",\"name\":\"Arts Center MARTA Station (32)\",\"label\":\"Arts Center MARTA Station (32)\"},\"type\":\"Feature\"},{\"geometry\":{\"type\":\"Point\",\"coordinates\":[-84.386402,33.789213]},\"id\":\"MARTA:99973485\",\"properties\":{\"layer\":\"stops\",\"source\":\"otp\",\"name\":\"Arts Center Way at 15th St (Arts Center Stn - Upper Entrance) (213110)\",\"label\":\"Arts Center Way at 15th St (Arts Center Stn - Upper Entrance) (213110)\"},\"type\":\"Feature\"},{\"geometry\":{\"type\":\"Point\",\"coordinates\":[-84.38568,33.788298]},\"id\":\"MARTA:68056\",\"properties\":{\"layer\":\"stops\",\"source\":\"otp\",\"name\":\"15th St NE at Arts Center Way NE (902514)\",\"label\":\"15th St NE at Arts Center Way NE (902514)\"},\"type\":\"Feature\"},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[-84.387325,33.789121]},\"properties\":{\"id\":\"node/4172450835\",\"gid\":\"openstreetmap:venue:node/4172450835\",\"layer\":\"venue\",\"source\":\"openstreetmap\",\"source_id\":\"node/4172450835\",\"country_code\":\"US\",\"name\":\"Arts Center\",\"distance\":4.467,\"accuracy\":\"point\",\"country\":\"United States\",\"country_gid\":\"whosonfirst:country:85633793\",\"country_a\":\"USA\",\"region\":\"Georgia\",\"region_gid\":\"whosonfirst:region:85688535\",\"region_a\":\"GA\",\"county\":\"Fulton County\",\"county_gid\":\"whosonfirst:county:102083603\",\"county_a\":\"FU\",\"locality\":\"Atlanta\",\"locality_gid\":\"whosonfirst:locality:85936429\",\"continent\":\"North America\",\"continent_gid\":\"whosonfirst:continent:102191575\",\"label\":\"Arts Center, Atlanta, GA, USA\",\"addendum\":{\"osm\":{\"wheelchair\":\"yes\",\"wikidata\":\"Q4801432\"}}}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[-84.385282,33.789341]},\"properties\":{\"id\":\"way/28961767\",\"gid\":\"openstreetmap:venue:way/28961767\",\"layer\":\"venue\",\"source\":\"openstreetmap\",\"source_id\":\"way/28961767\",\"country_code\":\"US\",\"name\":\"Woodruff Arts Center\",\"housenumber\":\"1314\",\"street\":\"Peachtree Street NE\",\"postalcode\":\"30309\",\"distance\":4.498,\"accuracy\":\"point\",\"country\":\"United States\",\"country_gid\":\"whosonfirst:country:85633793\",\"country_a\":\"USA\",\"region\":\"Georgia\",\"region_gid\":\"whosonfirst:region:85688535\",\"region_a\":\"GA\",\"county\":\"Fulton County\",\"county_gid\":\"whosonfirst:county:102083603\",\"county_a\":\"FU\",\"locality\":\"Atlanta\",\"locality_gid\":\"whosonfirst:locality:85936429\",\"continent\":\"North America\",\"continent_gid\":\"whosonfirst:continent:102191575\",\"label\":\"Woodruff Arts Center, Atlanta, GA, USA\",\"addendum\":{\"osm\":{\"wheelchair\":\"yes\",\"wikidata\":\"Q8033228\",\"website\":\"https://woodruffcenter.org/\"}}},\"bbox\":[-84.3859925,33.7885967,-84.3844398,33.7896945]},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[-84.389529,33.756815]},\"properties\":{\"id\":\"way/252608898\",\"gid\":\"openstreetmap:venue:way/252608898\",\"layer\":\"venue\",\"source\":\"openstreetmap\",\"source_id\":\"way/252608898\",\"country_code\":\"US\",\"name\":\"Rialto Center for the Arts\",\"housenumber\":\"80\",\"street\":\"Forsyth Street NW\",\"postalcode\":\"30303\",\"distance\":0.881,\"accuracy\":\"point\",\"country\":\"United States\",\"country_gid\":\"whosonfirst:country:85633793\",\"country_a\":\"USA\",\"region\":\"Georgia\",\"region_gid\":\"whosonfirst:region:85688535\",\"region_a\":\"GA\",\"county\":\"Fulton County\",\"county_gid\":\"whosonfirst:county:102083603\",\"county_a\":\"FU\",\"locality\":\"Atlanta\",\"locality_gid\":\"whosonfirst:locality:85936429\",\"continent\":\"North America\",\"continent_gid\":\"whosonfirst:continent:102191575\",\"label\":\"Rialto Center for the Arts, Atlanta, GA, USA\",\"addendum\":{\"osm\":{\"wikidata\":\"Q7322136\",\"wikipedia\":\"en:Rialto Center for the Arts\",\"operator\":\"Georgia State University\",\"website\":\"https://rialto.gsu.edu/\",\"phone\":\"+1 404 413 9849\"}}},\"bbox\":[-84.3897872,33.7565707,-84.3892141,33.7570301]},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[-84.388317,33.789408]},\"properties\":{\"id\":\"way/536720728\",\"gid\":\"openstreetmap:venue:way/536720728\",\"layer\":\"venue\",\"source\":\"openstreetmap\",\"source_id\":\"way/536720728\",\"country_code\":\"US\",\"name\":\"Arts Center Tower\",\"housenumber\":\"1270\",\"street\":\"West Peachtree Street NW\",\"distance\":4.498,\"accuracy\":\"point\",\"country\":\"United States\",\"country_gid\":\"whosonfirst:country:85633793\",\"country_a\":\"USA\",\"region\":\"Georgia\",\"region_gid\":\"whosonfirst:region:85688535\",\"region_a\":\"GA\",\"county\":\"Fulton County\",\"county_gid\":\"whosonfirst:county:102083603\",\"county_a\":\"FU\",\"locality\":\"Atlanta\",\"locality_gid\":\"whosonfirst:locality:85936429\",\"continent\":\"North America\",\"continent_gid\":\"whosonfirst:continent:102191575\",\"label\":\"Arts Center Tower, Atlanta, GA, USA\"},\"bbox\":[-84.3885134,33.7891714,-84.3879231,33.7895687]},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[-84.389665,33.792892]},\"properties\":{\"id\":\"way/269541904\",\"gid\":\"openstreetmap:venue:way/269541904\",\"layer\":\"venue\",\"source\":\"openstreetmap\",\"source_id\":\"way/269541904\",\"country_code\":\"US\",\"name\":\"Center for Puppetry Arts\",\"housenumber\":\"1404\",\"street\":\"Spring Street NW\",\"postalcode\":\"30309\",\"distance\":4.888,\"accuracy\":\"point\",\"country\":\"United States\",\"country_gid\":\"whosonfirst:country:85633793\",\"country_a\":\"USA\",\"region\":\"Georgia\",\"region_gid\":\"whosonfirst:region:85688535\",\"region_a\":\"GA\",\"county\":\"Fulton County\",\"county_gid\":\"whosonfirst:county:102083603\",\"county_a\":\"FU\",\"locality\":\"Atlanta\",\"locality_gid\":\"whosonfirst:locality:85936429\",\"continent\":\"North America\",\"continent_gid\":\"whosonfirst:continent:102191575\",\"label\":\"Center for Puppetry Arts, Atlanta, GA, USA\",\"addendum\":{\"osm\":{\"wheelchair\":\"yes\",\"website\":\"https://puppet.org/\",\"phone\":\"+1 404 873 3391\",\"opening_hours\":\"Tu-Fr 09:00-17:00; Sa 10:00-17:00; Su 12:00-17:00\"}}},\"bbox\":[-84.3898377,33.7925985,-84.3893181,33.7932157]},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[-84.386897,33.789283]},\"properties\":{\"id\":\"way/269637886\",\"gid\":\"openstreetmap:venue:way/269637886\",\"layer\":\"venue\",\"source\":\"openstreetmap\",\"source_id\":\"way/269637886\",\"country_code\":\"US\",\"name\":\"MARTA Arts Center Station\",\"distance\":4.485,\"accuracy\":\"point\",\"country\":\"United States\",\"country_gid\":\"whosonfirst:country:85633793\",\"country_a\":\"USA\",\"region\":\"Georgia\",\"region_gid\":\"whosonfirst:region:85688535\",\"region_a\":\"GA\",\"county\":\"Fulton County\",\"county_gid\":\"whosonfirst:county:102083603\",\"county_a\":\"FU\",\"locality\":\"Atlanta\",\"locality_gid\":\"whosonfirst:locality:85936429\",\"continent\":\"North America\",\"continent_gid\":\"whosonfirst:continent:102191575\",\"label\":\"MARTA Arts Center Station, Atlanta, GA, USA\"},\"bbox\":[-84.3872294,33.788859,-84.3867044,33.7898455]},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[-84.416912,33.744017]},\"properties\":{\"id\":\"way/802755819\",\"gid\":\"openstreetmap:venue:way/802755819\",\"layer\":\"venue\",\"source\":\"openstreetmap\",\"source_id\":\"way/802755819\",\"country_code\":\"US\",\"name\":\"Ray Charles Proformance Arts Center\",\"distance\":2.733,\"accuracy\":\"point\",\"country\":\"United States\",\"country_gid\":\"whosonfirst:country:85633793\",\"country_a\":\"USA\",\"region\":\"Georgia\",\"region_gid\":\"whosonfirst:region:85688535\",\"region_a\":\"GA\",\"county\":\"Fulton County\",\"county_gid\":\"whosonfirst:county:102083603\",\"county_a\":\"FU\",\"locality\":\"Atlanta\",\"locality_gid\":\"whosonfirst:locality:85936429\",\"neighbourhood\":\"Harris Chiles\",\"neighbourhood_gid\":\"whosonfirst:neighbourhood:1108798423\",\"continent\":\"North America\",\"continent_gid\":\"whosonfirst:continent:102191575\",\"label\":\"Ray Charles Proformance Arts Center, Atlanta, GA, USA\"},\"bbox\":[-84.417336,33.7436268,-84.4164033,33.7442824]},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[-84.345203,33.781772]},\"properties\":{\"id\":\"node/367912794\",\"gid\":\"openstreetmap:venue:node/367912794\",\"layer\":\"venue\",\"source\":\"openstreetmap\",\"source_id\":\"node/367912794\",\"country_code\":\"US\",\"name\":\"Callanwolde Fine Arts Center\",\"housenumber\":\"980\",\"street\":\"Briarcliff Road NE\",\"distance\":5.385,\"accuracy\":\"point\",\"country\":\"United States\",\"country_gid\":\"whosonfirst:country:85633793\",\"country_a\":\"USA\",\"region\":\"Georgia\",\"region_gid\":\"whosonfirst:region:85688535\",\"region_a\":\"GA\",\"county\":\"DeKalb County\",\"county_gid\":\"whosonfirst:county:102084539\",\"county_a\":\"DA\",\"locality\":\"Druid Hills\",\"locality_gid\":\"whosonfirst:locality:85937251\",\"continent\":\"North America\",\"continent_gid\":\"whosonfirst:continent:102191575\",\"label\":\"Callanwolde Fine Arts Center, Druid Hills, GA, USA\",\"addendum\":{\"osm\":{\"website\":\"https://www.callanwolde.org/\",\"phone\":\"+1-404-872-5338\",\"opening_hours\":\"Mo-Th 09:00-17:00; Fr-Sa 09:00-12:00\"}}}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[-84.399209,33.774791]},\"properties\":{\"id\":\"way/43332730\",\"gid\":\"openstreetmap:venue:way/43332730\",\"layer\":\"venue\",\"source\":\"openstreetmap\",\"source_id\":\"way/43332730\",\"country_code\":\"US\",\"name\":\"Robert H. Ferst Center for the Arts\",\"distance\":3.053,\"accuracy\":\"point\",\"country\":\"United States\",\"country_gid\":\"whosonfirst:country:85633793\",\"country_a\":\"USA\",\"region\":\"Georgia\",\"region_gid\":\"whosonfirst:region:85688535\",\"region_a\":\"GA\",\"county\":\"Fulton County\",\"county_gid\":\"whosonfirst:county:102083603\",\"county_a\":\"FU\",\"locality\":\"Atlanta\",\"locality_gid\":\"whosonfirst:locality:85936429\",\"neighbourhood\":\"Georgia Tech\",\"neighbourhood_gid\":\"whosonfirst:neighbourhood:1108798439\",\"continent\":\"North America\",\"continent_gid\":\"whosonfirst:continent:102191575\",\"label\":\"Robert H. Ferst Center for the Arts, Atlanta, GA, USA\",\"addendum\":{\"osm\":{\"wikidata\":\"Q5445560\"}}},\"bbox\":[-84.3994357,33.7747789,-84.3989903,33.7754228]},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[-84.392316,33.750426]},\"properties\":{\"id\":\"node/3499486829\",\"gid\":\"openstreetmap:venue:node/3499486829\",\"layer\":\"venue\",\"source\":\"openstreetmap\",\"source_id\":\"node/3499486829\",\"country_code\":\"US\",\"name\":\"FUSE Arts Center (C4 Atlanta)\",\"housenumber\":\"132\",\"street\":\"Mitchell Street SW\",\"postalcode\":\"30303\",\"distance\":0.43,\"accuracy\":\"point\",\"country\":\"United States\",\"country_gid\":\"whosonfirst:country:85633793\",\"country_a\":\"USA\",\"region\":\"Georgia\",\"region_gid\":\"whosonfirst:region:85688535\",\"region_a\":\"GA\",\"county\":\"Fulton County\",\"county_gid\":\"whosonfirst:county:102083603\",\"county_a\":\"FU\",\"locality\":\"Atlanta\",\"locality_gid\":\"whosonfirst:locality:85936429\",\"continent\":\"North America\",\"continent_gid\":\"whosonfirst:continent:102191575\",\"label\":\"FUSE Arts Center (C4 Atlanta), Atlanta, GA, USA\",\"addendum\":{\"osm\":{\"website\":\"https://www.c4atlanta.org\",\"phone\":\"+1-404-969-2787\"}}}}],\"bbox\":[-84.417336,33.7436268,-84.345203,33.7932157],\"isomorphicMapzenSearchQuery\":{\"api_key\":\"ge-0624346c114543d5\",\"text\":\"arts center\",\"layers\":\"address,venue,street,intersection\",\"focus.point.lat\":33.749,\"focus.point.lon\":-84.388,\"boundary.rect.min_lat\":32.066,\"boundary.rect.min_lon\":-86.0856,\"boundary.rect.max_lat\":35.7251,\"boundary.rect.max_lon\":-81.9499}}"
+ },
+ "redirectURL": "",
+ "headersSize": -1,
+ "bodySize": -1,
+ "_transferSize": 12959,
+ "_error": null
+ },
+ "serverIPAddress": "[64:ff9b::d21:40f]",
+ "startedDateTime": "2023-09-08T13:53:49.974Z",
+ "time": 1773.866000000453,
+ "timings": {
+ "blocked": 111.16500000039605,
+ "dns": -1,
+ "ssl": -1,
+ "connect": -1,
+ "send": 1.6709999999999923,
+ "wait": 1659.9850000000804,
+ "receive": 1.044999999976426,
+ "_blocked_queueing": 1.194000000396045
+ }
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/percy/percy.test.js b/percy/percy.test.js
index 9c62e92e7..e6862a86e 100644
--- a/percy/percy.test.js
+++ b/percy/percy.test.js
@@ -22,6 +22,7 @@ const percySnapshotWithWait = async (page, name, enableJavaScript) => {
let browser
const serveAbortController = new AbortController()
const harAbortController = new AbortController()
+const geocoderAbortController = new AbortController()
/**
* Loads a path
@@ -49,6 +50,15 @@ beforeAll(async () => {
signal: harAbortController.signal
}).stdout.pipe(process.stdout)
+ // Launch mock geocoder server
+ execa(
+ 'yarn',
+ ['percy-har-express', '-p', '9977', 'percy/geocoder-mock.har'],
+ {
+ signal: geocoderAbortController.signal
+ }
+ ).stdout.pipe(process.stdout)
+
// Web security is disabled to allow requests to the mock OTP server
browser = await puppeteer.launch({
args: ['--disable-web-security']
@@ -66,6 +76,7 @@ afterAll(async () => {
try {
serveAbortController.abort()
harAbortController.abort()
+ geocoderAbortController.abort()
await browser.close()
} catch (error) {
console.log(error)
@@ -73,7 +84,7 @@ afterAll(async () => {
console.log('Closed mock server and headless browser')
})
-// Puppeteer can take a long time to load, espeically in some ci environments
+// Puppeteer can take a long time to load, especially in some ci environments
jest.setTimeout(600000)
async function executeTest(page, isMobile, isCallTaker) {
@@ -153,6 +164,7 @@ async function executeTest(page, isMobile, isCallTaker) {
// Fill in new origin
await page.hover('.from-form-control')
await page.focus('.from-form-control')
+ // FIXME: Characters are typed very fast, but each stroke still triggers a geocoder call.
await page.keyboard.type('Opus Music')
await page.waitForTimeout(2000)
await page.keyboard.press('ArrowDown')
@@ -161,6 +173,7 @@ async function executeTest(page, isMobile, isCallTaker) {
// Fill in new destination
await page.focus('.to-form-control')
+ // FIXME: Characters are typed very fast, but each stroke still triggers a geocoder call.
await page.keyboard.type('908981')
await page.waitForTimeout(2000)
await page.keyboard.press('ArrowDown')
@@ -196,6 +209,7 @@ async function executeTest(page, isMobile, isCallTaker) {
)
await page.waitForSelector('.intermediate-place-0-form-control')
await page.focus('.intermediate-place-0-form-control')
+ // FIXME: Characters are typed very fast, but each stroke still triggers a geocoder call.
await page.keyboard.type('arts center')
await page.waitForTimeout(2000)
await page.keyboard.press('ArrowDown')
From 4a262a6fa10fcc098d9fbf4eaf194a9289304018 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Fri, 8 Sep 2023 16:11:53 -0400
Subject: [PATCH 44/80] test(percy): Use different mock files for normal vs
calltaker
---
...r-mock.har => geocoder-mock-calltaker.har} | 18 +-
percy/geocoder-mock-normal.har | 1130 +++++++++++++++++
percy/percy.test.js | 7 +-
3 files changed, 1145 insertions(+), 10 deletions(-)
rename percy/{geocoder-mock.har => geocoder-mock-calltaker.har} (99%)
create mode 100644 percy/geocoder-mock-normal.har
diff --git a/percy/geocoder-mock.har b/percy/geocoder-mock-calltaker.har
similarity index 99%
rename from percy/geocoder-mock.har
rename to percy/geocoder-mock-calltaker.har
index 6d9e46391..447fc319f 100644
--- a/percy/geocoder-mock.har
+++ b/percy/geocoder-mock-calltaker.har
@@ -125,7 +125,7 @@
"statusText": "",
"httpVersion": "http/2.0",
"content": {
- "size": 10681,
+ "size": 0,
"mimeType": "application/json",
"text": ""
},
@@ -196,7 +196,7 @@
"statusText": "",
"httpVersion": "http/2.0",
"content": {
- "size": 10853,
+ "size": 0,
"mimeType": "application/json",
"text": ""
},
@@ -267,7 +267,7 @@
"statusText": "",
"httpVersion": "http/2.0",
"content": {
- "size": 12368,
+ "size": 0,
"mimeType": "application/json",
"text": ""
},
@@ -338,7 +338,7 @@
"statusText": "",
"httpVersion": "http/2.0",
"content": {
- "size": 12369,
+ "size": 0,
"mimeType": "application/json",
"text": ""
},
@@ -409,7 +409,7 @@
"statusText": "",
"httpVersion": "http/2.0",
"content": {
- "size": 10616,
+ "size": 0,
"mimeType": "application/json",
"text": ""
},
@@ -480,7 +480,7 @@
"statusText": "",
"httpVersion": "http/2.0",
"content": {
- "size": 10608,
+ "size": 0,
"mimeType": "application/json",
"text": ""
},
@@ -551,7 +551,7 @@
"statusText": "",
"httpVersion": "http/2.0",
"content": {
- "size": 10612,
+ "size": 0,
"mimeType": "application/json",
"text": ""
},
@@ -622,7 +622,7 @@
"statusText": "",
"httpVersion": "http/2.0",
"content": {
- "size": 10616,
+ "size": 0,
"mimeType": "application/json",
"text": ""
},
@@ -693,7 +693,7 @@
"statusText": "",
"httpVersion": "http/2.0",
"content": {
- "size": 10620,
+ "size": 0,
"mimeType": "application/json",
"text": ""
},
diff --git a/percy/geocoder-mock-normal.har b/percy/geocoder-mock-normal.har
new file mode 100644
index 000000000..5d6763cd2
--- /dev/null
+++ b/percy/geocoder-mock-normal.har
@@ -0,0 +1,1130 @@
+{
+ "log": {
+ "version": "1.2",
+ "creator": {
+ "name": "WebInspector",
+ "version": "537.36"
+ },
+ "pages": [],
+ "entries": [
+ {
+ "request": {
+ "method": "GET",
+ "url": "http://localhost:9977/autocomplete?text=O&layers=address%2Cvenue%2Cstreet%2Cintersection&focus.point.lat=33.749&focus.point.lon=-84.388&boundary.rect.min_lat=32.066&boundary.rect.min_lon=-86.0856&boundary.rect.max_lat=35.7251&boundary.rect.max_lon=-81.9499",
+ "httpVersion": "http/2.0",
+ "queryString": [
+ {
+ "name": "text",
+ "value": "O"
+ },
+ {
+ "name": "layers",
+ "value": "address%2Cvenue%2Cstreet%2Cintersection"
+ },
+ {
+ "name": "focus.point.lat",
+ "value": "33.749"
+ },
+ {
+ "name": "focus.point.lon",
+ "value": "-84.388"
+ },
+ {
+ "name": "boundary.rect.min_lat",
+ "value": "32.066"
+ },
+ {
+ "name": "boundary.rect.min_lon",
+ "value": "-86.0856"
+ },
+ {
+ "name": "boundary.rect.max_lat",
+ "value": "35.7251"
+ },
+ {
+ "name": "boundary.rect.max_lon",
+ "value": "-81.9499"
+ }
+ ],
+ "headersSize": -1,
+ "bodySize": 0
+ },
+ "response": {
+ "status": 200,
+ "statusText": "OK",
+ "httpVersion": "http/2.0",
+ "content": {
+ "size": 0,
+ "mimeType": "application/json",
+ "text": ""
+ },
+ "redirectURL": "",
+ "headersSize": -1,
+ "bodySize": -1,
+ "_transferSize": 12785,
+ "_error": null
+ },
+ "serverIPAddress": "[64:ff9b::de1:2f3f]",
+ "startedDateTime": "2023-09-08T14:07:22.644Z",
+ "time": 2125.9739999999583,
+ "timings": {
+ "blocked": 15.940999999456107,
+ "dns": 73.76899999999999,
+ "ssl": 1088.1299999999999,
+ "connect": 1244.485,
+ "send": 4.813000000000102,
+ "wait": 786.1689999998994,
+ "receive": 0.7970000006025657,
+ "_blocked_queueing": 1.1159999994561076
+ }
+ },
+ {
+ "request": {
+ "method": "GET",
+ "url": "http://localhost:9977/autocomplete?text=Op&layers=address%2Cvenue%2Cstreet%2Cintersection&focus.point.lat=33.749&focus.point.lon=-84.388&boundary.rect.min_lat=32.066&boundary.rect.min_lon=-86.0856&boundary.rect.max_lat=35.7251&boundary.rect.max_lon=-81.9499",
+ "httpVersion": "http/2.0",
+ "queryString": [
+ {
+ "name": "text",
+ "value": "Op"
+ },
+ {
+ "name": "layers",
+ "value": "address%2Cvenue%2Cstreet%2Cintersection"
+ },
+ {
+ "name": "focus.point.lat",
+ "value": "33.749"
+ },
+ {
+ "name": "focus.point.lon",
+ "value": "-84.388"
+ },
+ {
+ "name": "boundary.rect.min_lat",
+ "value": "32.066"
+ },
+ {
+ "name": "boundary.rect.min_lon",
+ "value": "-86.0856"
+ },
+ {
+ "name": "boundary.rect.max_lat",
+ "value": "35.7251"
+ },
+ {
+ "name": "boundary.rect.max_lon",
+ "value": "-81.9499"
+ }
+ ],
+ "headersSize": -1,
+ "bodySize": 0
+ },
+ "response": {
+ "status": 200,
+ "statusText": "",
+ "httpVersion": "http/2.0",
+ "content": {
+ "size": 0,
+ "mimeType": "application/json",
+ "text": ""
+ },
+ "redirectURL": "",
+ "headersSize": -1,
+ "bodySize": -1,
+ "_transferSize": 11262,
+ "_error": null
+ },
+ "serverIPAddress": "[64:ff9b::de1:2f3f]",
+ "startedDateTime": "2023-09-08T14:07:22.656Z",
+ "time": 2307.477999999719,
+ "timings": {
+ "blocked": 1250.2649999995253,
+ "dns": -1,
+ "ssl": -1,
+ "connect": -1,
+ "send": 2.7480000000000473,
+ "wait": 1053.786999999859,
+ "receive": 0.6780000003345776,
+ "_blocked_queueing": 3.2949999995253165
+ }
+ },
+ {
+ "request": {
+ "method": "GET",
+ "url": "http://localhost:9977/autocomplete?text=Opu&layers=address%2Cvenue%2Cstreet%2Cintersection&focus.point.lat=33.749&focus.point.lon=-84.388&boundary.rect.min_lat=32.066&boundary.rect.min_lon=-86.0856&boundary.rect.max_lat=35.7251&boundary.rect.max_lon=-81.9499",
+ "httpVersion": "http/2.0",
+ "queryString": [
+ {
+ "name": "text",
+ "value": "Opu"
+ },
+ {
+ "name": "layers",
+ "value": "address%2Cvenue%2Cstreet%2Cintersection"
+ },
+ {
+ "name": "focus.point.lat",
+ "value": "33.749"
+ },
+ {
+ "name": "focus.point.lon",
+ "value": "-84.388"
+ },
+ {
+ "name": "boundary.rect.min_lat",
+ "value": "32.066"
+ },
+ {
+ "name": "boundary.rect.min_lon",
+ "value": "-86.0856"
+ },
+ {
+ "name": "boundary.rect.max_lat",
+ "value": "35.7251"
+ },
+ {
+ "name": "boundary.rect.max_lon",
+ "value": "-81.9499"
+ }
+ ],
+ "headersSize": -1,
+ "bodySize": 0
+ },
+ "response": {
+ "status": 200,
+ "statusText": "",
+ "httpVersion": "http/2.0",
+ "content": {
+ "size": 0,
+ "mimeType": "application/json",
+ "text": ""
+ },
+ "redirectURL": "",
+ "headersSize": -1,
+ "bodySize": -1,
+ "_transferSize": 5615,
+ "_error": null
+ },
+ "serverIPAddress": "[64:ff9b::de1:2f3f]",
+ "startedDateTime": "2023-09-08T14:07:22.663Z",
+ "time": 2034.0139999998428,
+ "timings": {
+ "blocked": 1243.6879999990954,
+ "dns": -1,
+ "ssl": -1,
+ "connect": -1,
+ "send": 2.394999999999982,
+ "wait": 787.3710000003423,
+ "receive": 0.5600000004051253,
+ "_blocked_queueing": 3.059999999095453
+ }
+ },
+ {
+ "request": {
+ "method": "GET",
+ "url": "http://localhost:9977/autocomplete?text=Opus&layers=address%2Cvenue%2Cstreet%2Cintersection&focus.point.lat=33.749&focus.point.lon=-84.388&boundary.rect.min_lat=32.066&boundary.rect.min_lon=-86.0856&boundary.rect.max_lat=35.7251&boundary.rect.max_lon=-81.9499",
+ "httpVersion": "http/2.0",
+ "queryString": [
+ {
+ "name": "text",
+ "value": "Opus"
+ },
+ {
+ "name": "layers",
+ "value": "address%2Cvenue%2Cstreet%2Cintersection"
+ },
+ {
+ "name": "focus.point.lat",
+ "value": "33.749"
+ },
+ {
+ "name": "focus.point.lon",
+ "value": "-84.388"
+ },
+ {
+ "name": "boundary.rect.min_lat",
+ "value": "32.066"
+ },
+ {
+ "name": "boundary.rect.min_lon",
+ "value": "-86.0856"
+ },
+ {
+ "name": "boundary.rect.max_lat",
+ "value": "35.7251"
+ },
+ {
+ "name": "boundary.rect.max_lon",
+ "value": "-81.9499"
+ }
+ ],
+ "headersSize": -1,
+ "bodySize": 0
+ },
+ "response": {
+ "status": 200,
+ "statusText": "",
+ "httpVersion": "http/2.0",
+ "content": {
+ "size": 0,
+ "mimeType": "application/json",
+ "text": ""
+ },
+ "redirectURL": "",
+ "headersSize": -1,
+ "bodySize": -1,
+ "_transferSize": 5619,
+ "_error": null
+ },
+ "serverIPAddress": "[64:ff9b::de1:2f3f]",
+ "startedDateTime": "2023-09-08T14:07:22.666Z",
+ "time": 1865.16599999959,
+ "timings": {
+ "blocked": 1240.8119999999617,
+ "dns": -1,
+ "ssl": -1,
+ "connect": -1,
+ "send": 2.0030000000001564,
+ "wait": 621.6149999996674,
+ "receive": 0.735999999960768,
+ "_blocked_queueing": 4.472999999961758
+ }
+ },
+ {
+ "request": {
+ "method": "GET",
+ "url": "http://localhost:9977/autocomplete?text=Opus%20&layers=address%2Cvenue%2Cstreet%2Cintersection&focus.point.lat=33.749&focus.point.lon=-84.388&boundary.rect.min_lat=32.066&boundary.rect.min_lon=-86.0856&boundary.rect.max_lat=35.7251&boundary.rect.max_lon=-81.9499",
+ "httpVersion": "http/2.0",
+ "queryString": [
+ {
+ "name": "text",
+ "value": "Opus%20"
+ },
+ {
+ "name": "layers",
+ "value": "address%2Cvenue%2Cstreet%2Cintersection"
+ },
+ {
+ "name": "focus.point.lat",
+ "value": "33.749"
+ },
+ {
+ "name": "focus.point.lon",
+ "value": "-84.388"
+ },
+ {
+ "name": "boundary.rect.min_lat",
+ "value": "32.066"
+ },
+ {
+ "name": "boundary.rect.min_lon",
+ "value": "-86.0856"
+ },
+ {
+ "name": "boundary.rect.max_lat",
+ "value": "35.7251"
+ },
+ {
+ "name": "boundary.rect.max_lon",
+ "value": "-81.9499"
+ }
+ ],
+ "headersSize": -1,
+ "bodySize": 0
+ },
+ "response": {
+ "status": 200,
+ "statusText": "",
+ "httpVersion": "http/2.0",
+ "content": {
+ "size": 0,
+ "mimeType": "application/json",
+ "text": ""
+ },
+ "redirectURL": "",
+ "headersSize": -1,
+ "bodySize": -1,
+ "_transferSize": 5621,
+ "_error": null
+ },
+ "serverIPAddress": "[64:ff9b::de1:2f3f]",
+ "startedDateTime": "2023-09-08T14:07:22.676Z",
+ "time": 2317.60100000065,
+ "timings": {
+ "blocked": 1231.086000000746,
+ "dns": -1,
+ "ssl": -1,
+ "connect": -1,
+ "send": 1.884999999999991,
+ "wait": 1083.7900000002057,
+ "receive": 0.8399999996981933,
+ "_blocked_queueing": 8.215000000745931
+ }
+ },
+ {
+ "request": {
+ "method": "GET",
+ "url": "http://localhost:9977/autocomplete?text=Opus%20M&layers=address%2Cvenue%2Cstreet%2Cintersection&focus.point.lat=33.749&focus.point.lon=-84.388&boundary.rect.min_lat=32.066&boundary.rect.min_lon=-86.0856&boundary.rect.max_lat=35.7251&boundary.rect.max_lon=-81.9499",
+ "httpVersion": "http/2.0",
+ "queryString": [
+ {
+ "name": "text",
+ "value": "Opus%20M"
+ },
+ {
+ "name": "layers",
+ "value": "address%2Cvenue%2Cstreet%2Cintersection"
+ },
+ {
+ "name": "focus.point.lat",
+ "value": "33.749"
+ },
+ {
+ "name": "focus.point.lon",
+ "value": "-84.388"
+ },
+ {
+ "name": "boundary.rect.min_lat",
+ "value": "32.066"
+ },
+ {
+ "name": "boundary.rect.min_lon",
+ "value": "-86.0856"
+ },
+ {
+ "name": "boundary.rect.max_lat",
+ "value": "35.7251"
+ },
+ {
+ "name": "boundary.rect.max_lon",
+ "value": "-81.9499"
+ }
+ ],
+ "headersSize": -1,
+ "bodySize": 0
+ },
+ "response": {
+ "status": 200,
+ "statusText": "",
+ "httpVersion": "http/2.0",
+ "content": {
+ "size": 0,
+ "mimeType": "application/json",
+ "text": ""
+ },
+ "redirectURL": "",
+ "headersSize": -1,
+ "bodySize": -1,
+ "_transferSize": 3972,
+ "_error": null
+ },
+ "serverIPAddress": "[64:ff9b::de1:2f3f]",
+ "startedDateTime": "2023-09-08T14:07:22.679Z",
+ "time": 1605.46499999964,
+ "timings": {
+ "blocked": 1227.7660000004744,
+ "dns": -1,
+ "ssl": -1,
+ "connect": -1,
+ "send": 2.2730000000001382,
+ "wait": 339.82599999991635,
+ "receive": 35.59999999924912,
+ "_blocked_queueing": 5.936000000474451
+ }
+ },
+ {
+ "request": {
+ "method": "GET",
+ "url": "http://localhost:9977/autocomplete?text=Opus%20Mu&layers=address%2Cvenue%2Cstreet%2Cintersection&focus.point.lat=33.749&focus.point.lon=-84.388&boundary.rect.min_lat=32.066&boundary.rect.min_lon=-86.0856&boundary.rect.max_lat=35.7251&boundary.rect.max_lon=-81.9499",
+ "httpVersion": "http/2.0",
+ "queryString": [
+ {
+ "name": "text",
+ "value": "Opus%20Mu"
+ },
+ {
+ "name": "layers",
+ "value": "address%2Cvenue%2Cstreet%2Cintersection"
+ },
+ {
+ "name": "focus.point.lat",
+ "value": "33.749"
+ },
+ {
+ "name": "focus.point.lon",
+ "value": "-84.388"
+ },
+ {
+ "name": "boundary.rect.min_lat",
+ "value": "32.066"
+ },
+ {
+ "name": "boundary.rect.min_lon",
+ "value": "-86.0856"
+ },
+ {
+ "name": "boundary.rect.max_lat",
+ "value": "35.7251"
+ },
+ {
+ "name": "boundary.rect.max_lon",
+ "value": "-81.9499"
+ }
+ ],
+ "headersSize": -1,
+ "bodySize": 0
+ },
+ "response": {
+ "status": 200,
+ "statusText": "",
+ "httpVersion": "http/2.0",
+ "content": {
+ "size": 0,
+ "mimeType": "application/json",
+ "text": ""
+ },
+ "redirectURL": "",
+ "headersSize": -1,
+ "bodySize": -1,
+ "_transferSize": 2370,
+ "_error": null
+ },
+ "serverIPAddress": "[64:ff9b::de1:2f3f]",
+ "startedDateTime": "2023-09-08T14:07:22.682Z",
+ "time": 1566.6149999997288,
+ "timings": {
+ "blocked": 1225.0449999998693,
+ "dns": -1,
+ "ssl": -1,
+ "connect": -1,
+ "send": 2.119999999999891,
+ "wait": 338.85400000000004,
+ "receive": 0.5959999998594867,
+ "_blocked_queueing": 3.5189999998692656
+ }
+ },
+ {
+ "request": {
+ "method": "GET",
+ "url": "http://localhost:9977/autocomplete?text=Opus%20Mus&layers=address%2Cvenue%2Cstreet%2Cintersection&focus.point.lat=33.749&focus.point.lon=-84.388&boundary.rect.min_lat=32.066&boundary.rect.min_lon=-86.0856&boundary.rect.max_lat=35.7251&boundary.rect.max_lon=-81.9499",
+ "httpVersion": "http/2.0",
+ "queryString": [
+ {
+ "name": "text",
+ "value": "Opus%20Mus"
+ },
+ {
+ "name": "layers",
+ "value": "address%2Cvenue%2Cstreet%2Cintersection"
+ },
+ {
+ "name": "focus.point.lat",
+ "value": "33.749"
+ },
+ {
+ "name": "focus.point.lon",
+ "value": "-84.388"
+ },
+ {
+ "name": "boundary.rect.min_lat",
+ "value": "32.066"
+ },
+ {
+ "name": "boundary.rect.min_lon",
+ "value": "-86.0856"
+ },
+ {
+ "name": "boundary.rect.max_lat",
+ "value": "35.7251"
+ },
+ {
+ "name": "boundary.rect.max_lon",
+ "value": "-81.9499"
+ }
+ ],
+ "headersSize": -1,
+ "bodySize": 0
+ },
+ "response": {
+ "status": 200,
+ "statusText": "",
+ "httpVersion": "http/2.0",
+ "content": {
+ "size": 0,
+ "mimeType": "application/json",
+ "text": ""
+ },
+ "redirectURL": "",
+ "headersSize": -1,
+ "bodySize": -1,
+ "_transferSize": 2367,
+ "_error": null
+ },
+ "serverIPAddress": "[64:ff9b::de1:2f3f]",
+ "startedDateTime": "2023-09-08T14:07:22.690Z",
+ "time": 2356.9259999994756,
+ "timings": {
+ "blocked": 1217.2119999999413,
+ "dns": -1,
+ "ssl": -1,
+ "connect": -1,
+ "send": 1.7999999999999545,
+ "wait": 1136.8809999999824,
+ "receive": 1.0329999995519756,
+ "_blocked_queueing": 4.3009999999412685
+ }
+ },
+ {
+ "request": {
+ "method": "GET",
+ "url": "http://localhost:9977/autocomplete?text=Opus%20Musi&layers=address%2Cvenue%2Cstreet%2Cintersection&focus.point.lat=33.749&focus.point.lon=-84.388&boundary.rect.min_lat=32.066&boundary.rect.min_lon=-86.0856&boundary.rect.max_lat=35.7251&boundary.rect.max_lon=-81.9499",
+ "httpVersion": "http/2.0",
+ "queryString": [
+ {
+ "name": "text",
+ "value": "Opus%20Musi"
+ },
+ {
+ "name": "layers",
+ "value": "address%2Cvenue%2Cstreet%2Cintersection"
+ },
+ {
+ "name": "focus.point.lat",
+ "value": "33.749"
+ },
+ {
+ "name": "focus.point.lon",
+ "value": "-84.388"
+ },
+ {
+ "name": "boundary.rect.min_lat",
+ "value": "32.066"
+ },
+ {
+ "name": "boundary.rect.min_lon",
+ "value": "-86.0856"
+ },
+ {
+ "name": "boundary.rect.max_lat",
+ "value": "35.7251"
+ },
+ {
+ "name": "boundary.rect.max_lon",
+ "value": "-81.9499"
+ }
+ ],
+ "headersSize": -1,
+ "bodySize": 0
+ },
+ "response": {
+ "status": 200,
+ "statusText": "",
+ "httpVersion": "http/2.0",
+ "content": {
+ "size": 0,
+ "mimeType": "application/json",
+ "text": ""
+ },
+ "redirectURL": "",
+ "headersSize": -1,
+ "bodySize": -1,
+ "_transferSize": 2379,
+ "_error": null
+ },
+ "serverIPAddress": "[64:ff9b::de1:2f3f]",
+ "startedDateTime": "2023-09-08T14:07:22.699Z",
+ "time": 2625.739999999496,
+ "timings": {
+ "blocked": 1208.077999999743,
+ "dns": -1,
+ "ssl": -1,
+ "connect": -1,
+ "send": 1.5919999999998709,
+ "wait": 1415.6090000001211,
+ "receive": 0.46099999963189475,
+ "_blocked_queueing": 3.523999999742955
+ }
+ },
+ {
+ "request": {
+ "method": "GET",
+ "url": "http://localhost:9977/autocomplete?text=Opus%20Music&layers=address%2Cvenue%2Cstreet%2Cintersection&focus.point.lat=33.749&focus.point.lon=-84.388&boundary.rect.min_lat=32.066&boundary.rect.min_lon=-86.0856&boundary.rect.max_lat=35.7251&boundary.rect.max_lon=-81.9499",
+ "httpVersion": "http/2.0",
+ "queryString": [
+ {
+ "name": "text",
+ "value": "Opus%20Music"
+ },
+ {
+ "name": "layers",
+ "value": "address%2Cvenue%2Cstreet%2Cintersection"
+ },
+ {
+ "name": "focus.point.lat",
+ "value": "33.749"
+ },
+ {
+ "name": "focus.point.lon",
+ "value": "-84.388"
+ },
+ {
+ "name": "boundary.rect.min_lat",
+ "value": "32.066"
+ },
+ {
+ "name": "boundary.rect.min_lon",
+ "value": "-86.0856"
+ },
+ {
+ "name": "boundary.rect.max_lat",
+ "value": "35.7251"
+ },
+ {
+ "name": "boundary.rect.max_lon",
+ "value": "-81.9499"
+ }
+ ],
+ "headersSize": -1,
+ "bodySize": 0
+ },
+ "response": {
+ "status": 200,
+ "statusText": "",
+ "httpVersion": "http/2.0",
+ "content": {
+ "size": 5231,
+ "mimeType": "application/json",
+ "text": "{\"geocoding\":{\"version\":\"0.2\",\"attribution\":\"https://geocode.earth/guidelines\",\"query\":{\"text\":\"Opus\",\"parser\":\"pelias\",\"parsed_text\":{\"subject\":\"Opus\"},\"size\":10,\"layers\":[\"address\",\"venue\",\"street\",\"intersection\"],\"sources\":[\"openstreetmap\",\"openaddresses\",\"geonames\",\"whosonfirst\",\"uscensus\"],\"private\":false,\"focus.point.lat\":33.749,\"focus.point.lon\":-84.388,\"boundary.rect.min_lat\":32.066,\"boundary.rect.max_lat\":35.7251,\"boundary.rect.min_lon\":-86.0856,\"boundary.rect.max_lon\":-81.9499,\"lang\":{\"name\":\"English\",\"iso6391\":\"en\",\"iso6393\":\"eng\",\"via\":\"default\",\"defaulted\":true},\"querySize\":20},\"engine\":{\"name\":\"Pelias\",\"author\":\"Mapzen\",\"version\":\"1.0\"},\"timestamp\":1694202052257},\"type\":\"FeatureCollection\",\"features\":[{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[-84.300178,33.77505]},\"properties\":{\"id\":\"node/556611976\",\"gid\":\"openstreetmap:venue:node/556611976\",\"layer\":\"venue\",\"source\":\"openstreetmap\",\"source_id\":\"node/556611976\",\"country_code\":\"US\",\"name\":\"Opus Music Store\",\"housenumber\":\"308D\",\"distance\":8.629,\"accuracy\":\"point\",\"country\":\"United States\",\"country_gid\":\"whosonfirst:country:85633793\",\"country_a\":\"USA\",\"region\":\"Georgia\",\"region_gid\":\"whosonfirst:region:85688535\",\"region_a\":\"GA\",\"county\":\"DeKalb County\",\"county_gid\":\"whosonfirst:county:102084539\",\"county_a\":\"DA\",\"locality\":\"Decatur\",\"locality_gid\":\"whosonfirst:locality:85936441\",\"continent\":\"North America\",\"continent_gid\":\"whosonfirst:continent:102191575\",\"label\":\"Opus Music Store, Decatur, GA, USA\",\"addendum\":{\"osm\":{\"website\":\"http://www.opusmusicstore.com/\",\"phone\":\"+1 404 370 0507\"}}}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[-84.385934,33.787145]},\"properties\":{\"id\":\"way/885660365\",\"gid\":\"openstreetmap:venue:way/885660365\",\"layer\":\"venue\",\"source\":\"openstreetmap\",\"source_id\":\"way/885660365\",\"country_code\":\"US\",\"name\":\"2 Opus Place (construction)\",\"distance\":4.251,\"accuracy\":\"point\",\"country\":\"United States\",\"country_gid\":\"whosonfirst:country:85633793\",\"country_a\":\"USA\",\"region\":\"Georgia\",\"region_gid\":\"whosonfirst:region:85688535\",\"region_a\":\"GA\",\"county\":\"Fulton County\",\"county_gid\":\"whosonfirst:county:102083603\",\"county_a\":\"FU\",\"locality\":\"Atlanta\",\"locality_gid\":\"whosonfirst:locality:85936429\",\"continent\":\"North America\",\"continent_gid\":\"whosonfirst:continent:102191575\",\"label\":\"2 Opus Place (construction), Atlanta, GA, USA\"},\"bbox\":[-84.3866911,33.7867611,-84.385266,33.7874624]},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[-85.211688,35.00657]},\"properties\":{\"id\":\"way/51791114\",\"gid\":\"openstreetmap:venue:way/51791114\",\"layer\":\"venue\",\"source\":\"openstreetmap\",\"source_id\":\"way/51791114\",\"country_code\":\"US\",\"name\":\"Opus Inspection\",\"distance\":159.136,\"accuracy\":\"point\",\"country\":\"United States\",\"country_gid\":\"whosonfirst:country:85633793\",\"country_a\":\"USA\",\"region\":\"Tennessee\",\"region_gid\":\"whosonfirst:region:85688701\",\"region_a\":\"TN\",\"county\":\"Hamilton County\",\"county_gid\":\"whosonfirst:county:102087185\",\"county_a\":\"HL\",\"locality\":\"Chattanooga\",\"locality_gid\":\"whosonfirst:locality:101723043\",\"continent\":\"North America\",\"continent_gid\":\"whosonfirst:continent:102191575\",\"label\":\"Opus Inspection, Chattanooga, TN, USA\"},\"bbox\":[-85.2118453,35.0064715,-85.21153,35.0067042]},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[-82.230045,33.55809]},\"properties\":{\"id\":\"w577848242-n5538625175-w577848271\",\"gid\":\"openstreetmap:intersection:w577848242-n5538625175-w577848271\",\"layer\":\"intersection\",\"source\":\"openstreetmap\",\"source_id\":\"w577848242-n5538625175-w577848271\",\"country_code\":\"US\",\"name\":\"Bent Creek Drive & Magnum Opus Way\",\"street\":\"Bent Creek Drive\",\"distance\":201.084,\"accuracy\":\"centroid\",\"country\":\"United States\",\"country_gid\":\"whosonfirst:country:85633793\",\"country_a\":\"USA\",\"region\":\"Georgia\",\"region_gid\":\"whosonfirst:region:85688535\",\"region_a\":\"GA\",\"county\":\"Columbia County\",\"county_gid\":\"whosonfirst:county:102082315\",\"county_a\":\"CI\",\"continent\":\"North America\",\"continent_gid\":\"whosonfirst:continent:102191575\",\"label\":\"Bent Creek Drive & Magnum Opus Way, Columbia County, GA, USA\"}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[-82.22882,33.559832]},\"properties\":{\"id\":\"polyline:18601022\",\"gid\":\"openstreetmap:street:polyline:18601022\",\"layer\":\"street\",\"source\":\"openstreetmap\",\"source_id\":\"polyline:18601022\",\"country_code\":\"US\",\"name\":\"Magnum Opus Way\",\"street\":\"Magnum Opus Way\",\"distance\":201.175,\"accuracy\":\"centroid\",\"country\":\"United States\",\"country_gid\":\"whosonfirst:country:85633793\",\"country_a\":\"USA\",\"region\":\"Georgia\",\"region_gid\":\"whosonfirst:region:85688535\",\"region_a\":\"GA\",\"county\":\"Columbia County\",\"county_gid\":\"whosonfirst:county:102082315\",\"county_a\":\"CI\",\"continent\":\"North America\",\"continent_gid\":\"whosonfirst:continent:102191575\",\"label\":\"Magnum Opus Way, Columbia County, GA, USA\"},\"bbox\":[-82.230045,33.55809,-82.227691,33.561696]}],\"bbox\":[-85.2118453,33.55809,-82.227691,35.0067042],\"isomorphicMapzenSearchQuery\":{\"api_key\":\"ge-0624346c114543d5\",\"text\":\"Opus\",\"layers\":\"address,venue,street,intersection\",\"focus.point.lat\":33.749,\"focus.point.lon\":-84.388,\"boundary.rect.min_lat\":32.066,\"boundary.rect.min_lon\":-86.0856,\"boundary.rect.max_lat\":35.7251,\"boundary.rect.max_lon\":-81.9499}}"
+ },
+ "redirectURL": "",
+ "headersSize": -1,
+ "bodySize": -1,
+ "_transferSize": 2351,
+ "_error": null
+ },
+ "serverIPAddress": "[64:ff9b::de1:2f3f]",
+ "startedDateTime": "2023-09-08T14:07:22.703Z",
+ "time": 2622.787999999673,
+ "timings": {
+ "blocked": 1203.8749999999998,
+ "dns": -1,
+ "ssl": -1,
+ "connect": -1,
+ "send": 1.731999999999971,
+ "wait": 1416.4810000000764,
+ "receive": 0.699999999596912,
+ "_blocked_queueing": 3.0169999999998254
+ }
+ },
+
+ {
+ "request": {
+ "bodySize": 0,
+ "method": "GET",
+ "url": "http://localhost:9977/autocomplete?text=9&layers=address%2Cvenue%2Cstreet%2Cintersection&focus.point.lat=33.749&focus.point.lon=-84.388&boundary.rect.min_lat=32.066&boundary.rect.min_lon=-86.0856&boundary.rect.max_lat=35.7251&boundary.rect.max_lon=-81.9499",
+ "httpVersion": "",
+ "queryString": [
+ {
+ "name": "text",
+ "value": "9"
+ },
+ {
+ "name": "layers",
+ "value": "address,venue,street,intersection"
+ },
+ {
+ "name": "focus.point.lat",
+ "value": "33.749"
+ },
+ {
+ "name": "focus.point.lon",
+ "value": "-84.388"
+ },
+ {
+ "name": "boundary.rect.min_lat",
+ "value": "32.066"
+ },
+ {
+ "name": "boundary.rect.min_lon",
+ "value": "-86.0856"
+ },
+ {
+ "name": "boundary.rect.max_lat",
+ "value": "35.7251"
+ },
+ {
+ "name": "boundary.rect.max_lon",
+ "value": "-81.9499"
+ }
+ ],
+ "headersSize": 730
+ },
+ "response": {
+ "status": 0,
+ "statusText": "",
+ "httpVersion": "",
+ "content": {
+ "mimeType": "",
+ "size": 0,
+ "encoding": "base64",
+ "text": ""
+ },
+ "redirectURL": "",
+ "headersSize": 0,
+ "bodySize": 0
+ },
+ "cache": {},
+ "timings": {
+ "blocked": 0,
+ "dns": 0,
+ "connect": 0,
+ "ssl": 0,
+ "send": 0,
+ "wait": 0,
+ "receive": 0
+ },
+ "time": 0
+ },
+ {
+ "request": {
+ "bodySize": 0,
+ "method": "GET",
+ "url": "http://localhost:9977/autocomplete?text=90&layers=address%2Cvenue%2Cstreet%2Cintersection&focus.point.lat=33.749&focus.point.lon=-84.388&boundary.rect.min_lat=32.066&boundary.rect.min_lon=-86.0856&boundary.rect.max_lat=35.7251&boundary.rect.max_lon=-81.9499",
+ "httpVersion": "",
+ "queryString": [
+ {
+ "name": "text",
+ "value": "90"
+ },
+ {
+ "name": "layers",
+ "value": "address,venue,street,intersection"
+ },
+ {
+ "name": "focus.point.lat",
+ "value": "33.749"
+ },
+ {
+ "name": "focus.point.lon",
+ "value": "-84.388"
+ },
+ {
+ "name": "boundary.rect.min_lat",
+ "value": "32.066"
+ },
+ {
+ "name": "boundary.rect.min_lon",
+ "value": "-86.0856"
+ },
+ {
+ "name": "boundary.rect.max_lat",
+ "value": "35.7251"
+ },
+ {
+ "name": "boundary.rect.max_lon",
+ "value": "-81.9499"
+ }
+ ],
+ "headersSize": 731
+ },
+ "response": {
+ "status": 0,
+ "statusText": "",
+ "httpVersion": "",
+ "content": {
+ "mimeType": "",
+ "size": 0,
+ "encoding": "base64",
+ "text": ""
+ },
+ "redirectURL": "",
+ "headersSize": 0,
+ "bodySize": 0
+ },
+ "cache": {},
+ "timings": {
+ "blocked": 0,
+ "dns": 0,
+ "connect": 0,
+ "ssl": 0,
+ "send": 0,
+ "wait": 0,
+ "receive": 0
+ },
+ "time": 0
+ },
+ {
+ "request": {
+ "bodySize": 0,
+ "method": "GET",
+ "url": "http://localhost:9977/autocomplete?text=908&layers=address%2Cvenue%2Cstreet%2Cintersection&focus.point.lat=33.749&focus.point.lon=-84.388&boundary.rect.min_lat=32.066&boundary.rect.min_lon=-86.0856&boundary.rect.max_lat=35.7251&boundary.rect.max_lon=-81.9499",
+ "httpVersion": "",
+ "queryString": [
+ {
+ "name": "text",
+ "value": "908"
+ },
+ {
+ "name": "layers",
+ "value": "address,venue,street,intersection"
+ },
+ {
+ "name": "focus.point.lat",
+ "value": "33.749"
+ },
+ {
+ "name": "focus.point.lon",
+ "value": "-84.388"
+ },
+ {
+ "name": "boundary.rect.min_lat",
+ "value": "32.066"
+ },
+ {
+ "name": "boundary.rect.min_lon",
+ "value": "-86.0856"
+ },
+ {
+ "name": "boundary.rect.max_lat",
+ "value": "35.7251"
+ },
+ {
+ "name": "boundary.rect.max_lon",
+ "value": "-81.9499"
+ }
+ ],
+ "headersSize": 732
+ },
+ "response": {
+ "status": 0,
+ "statusText": "",
+ "httpVersion": "",
+ "content": {
+ "mimeType": "",
+ "size": 0,
+ "encoding": "base64",
+ "text": ""
+ },
+ "redirectURL": "",
+ "headersSize": 0,
+ "bodySize": 0
+ },
+ "cache": {},
+ "timings": {
+ "blocked": 0,
+ "dns": 0,
+ "connect": 0,
+ "ssl": 0,
+ "send": 0,
+ "wait": 0,
+ "receive": 0
+ },
+ "time": 0
+ },
+ {
+ "request": {
+ "bodySize": 0,
+ "method": "GET",
+ "url": "http://localhost:9977/autocomplete?text=9089&layers=address%2Cvenue%2Cstreet%2Cintersection&focus.point.lat=33.749&focus.point.lon=-84.388&boundary.rect.min_lat=32.066&boundary.rect.min_lon=-86.0856&boundary.rect.max_lat=35.7251&boundary.rect.max_lon=-81.9499",
+ "httpVersion": "",
+ "queryString": [
+ {
+ "name": "text",
+ "value": "9089"
+ },
+ {
+ "name": "layers",
+ "value": "address,venue,street,intersection"
+ },
+ {
+ "name": "focus.point.lat",
+ "value": "33.749"
+ },
+ {
+ "name": "focus.point.lon",
+ "value": "-84.388"
+ },
+ {
+ "name": "boundary.rect.min_lat",
+ "value": "32.066"
+ },
+ {
+ "name": "boundary.rect.min_lon",
+ "value": "-86.0856"
+ },
+ {
+ "name": "boundary.rect.max_lat",
+ "value": "35.7251"
+ },
+ {
+ "name": "boundary.rect.max_lon",
+ "value": "-81.9499"
+ }
+ ],
+ "headersSize": 733
+ },
+ "response": {
+ "status": 0,
+ "statusText": "",
+ "httpVersion": "",
+ "content": {
+ "mimeType": "",
+ "size": 0,
+ "encoding": "base64",
+ "text": ""
+ },
+ "redirectURL": "",
+ "headersSize": 0,
+ "bodySize": 0
+ },
+ "cache": {},
+ "timings": {
+ "blocked": 0,
+ "dns": 0,
+ "connect": 0,
+ "ssl": 0,
+ "send": 0,
+ "wait": 0,
+ "receive": 0
+ },
+ "time": 0
+ },
+ {
+ "request": {
+ "bodySize": 0,
+ "method": "GET",
+ "url": "http://localhost:9977/autocomplete?text=90898&layers=address%2Cvenue%2Cstreet%2Cintersection&focus.point.lat=33.749&focus.point.lon=-84.388&boundary.rect.min_lat=32.066&boundary.rect.min_lon=-86.0856&boundary.rect.max_lat=35.7251&boundary.rect.max_lon=-81.9499",
+ "httpVersion": "",
+ "queryString": [
+ {
+ "name": "text",
+ "value": "90898"
+ },
+ {
+ "name": "layers",
+ "value": "address,venue,street,intersection"
+ },
+ {
+ "name": "focus.point.lat",
+ "value": "33.749"
+ },
+ {
+ "name": "focus.point.lon",
+ "value": "-84.388"
+ },
+ {
+ "name": "boundary.rect.min_lat",
+ "value": "32.066"
+ },
+ {
+ "name": "boundary.rect.min_lon",
+ "value": "-86.0856"
+ },
+ {
+ "name": "boundary.rect.max_lat",
+ "value": "35.7251"
+ },
+ {
+ "name": "boundary.rect.max_lon",
+ "value": "-81.9499"
+ }
+ ],
+ "headersSize": 735
+ },
+ "response": {
+ "status": 0,
+ "statusText": "",
+ "httpVersion": "",
+ "content": {
+ "mimeType": "",
+ "size": 0,
+ "encoding": "base64",
+ "text": ""
+ },
+ "redirectURL": "",
+ "headersSize": 0,
+ "bodySize": 0
+ },
+ "cache": {},
+ "timings": {
+ "blocked": 0,
+ "dns": 0,
+ "connect": 0,
+ "ssl": 0,
+ "send": 0,
+ "wait": 0,
+ "receive": 0
+ },
+ "time": 0
+ },
+ {
+ "request": {
+ "bodySize": 0,
+ "method": "GET",
+ "url": "http://localhost:9977/autocomplete?text=908981&layers=address%2Cvenue%2Cstreet%2Cintersection&focus.point.lat=33.749&focus.point.lon=-84.388&boundary.rect.min_lat=32.066&boundary.rect.min_lon=-86.0856&boundary.rect.max_lat=35.7251&boundary.rect.max_lon=-81.9499",
+ "httpVersion": "HTTP/2",
+ "queryString": [
+ {
+ "name": "text",
+ "value": "908981"
+ },
+ {
+ "name": "layers",
+ "value": "address,venue,street,intersection"
+ },
+ {
+ "name": "focus.point.lat",
+ "value": "33.749"
+ },
+ {
+ "name": "focus.point.lon",
+ "value": "-84.388"
+ },
+ {
+ "name": "boundary.rect.min_lat",
+ "value": "32.066"
+ },
+ {
+ "name": "boundary.rect.min_lon",
+ "value": "-86.0856"
+ },
+ {
+ "name": "boundary.rect.max_lat",
+ "value": "35.7251"
+ },
+ {
+ "name": "boundary.rect.max_lon",
+ "value": "-81.9499"
+ }
+ ],
+ "headersSize": 736
+ },
+ "response": {
+ "status": 200,
+ "statusText": "OK",
+ "httpVersion": "HTTP/2",
+ "content": {
+ "mimeType": "application/json",
+ "size": 12687,
+ "text": "{\"features\":[{\"geometry\":{\"type\":\"Point\",\"coordinates\":[-84.391397,33.753837]},\"id\":\"MARTA:797\",\"properties\":{\"layer\":\"stops\",\"source\":\"otp\",\"name\":\"Five Points Station (908981)\",\"label\":\"Five Points Station (908981)\"},\"type\":\"Feature\"}],\"type\":\"FeatureCollection\"}"
+ },
+ "redirectURL": "",
+ "headersSize": 547,
+ "bodySize": 13234
+ },
+ "cache": {},
+ "timings": {
+ "blocked": 0,
+ "dns": 0,
+ "connect": 0,
+ "ssl": 0,
+ "send": 0,
+ "wait": 199,
+ "receive": 0
+ },
+ "time": 199
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/percy/percy.test.js b/percy/percy.test.js
index e6862a86e..87b5b1ec3 100644
--- a/percy/percy.test.js
+++ b/percy/percy.test.js
@@ -53,7 +53,12 @@ beforeAll(async () => {
// Launch mock geocoder server
execa(
'yarn',
- ['percy-har-express', '-p', '9977', 'percy/geocoder-mock.har'],
+ [
+ 'percy-har-express',
+ '-p',
+ '9977',
+ `percy/geocoder-mock-${OTP_RR_UI_MODE}.har`
+ ],
{
signal: geocoderAbortController.signal
}
From 6870b139e50fe9be954879271489e0bf111bee49 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Fri, 8 Sep 2023 16:16:46 -0400
Subject: [PATCH 45/80] test(percy): Remove sv info from mocks
---
percy/geocoder-mock-calltaker.har | 11 -----------
percy/geocoder-mock-normal.har | 10 ----------
percy/mock.har | 23 -----------------------
3 files changed, 44 deletions(-)
diff --git a/percy/geocoder-mock-calltaker.har b/percy/geocoder-mock-calltaker.har
index 447fc319f..0a93718b8 100644
--- a/percy/geocoder-mock-calltaker.har
+++ b/percy/geocoder-mock-calltaker.har
@@ -64,7 +64,6 @@
"_transferSize": 12109,
"_error": null
},
- "serverIPAddress": "[64:ff9b::d21:40f]",
"startedDateTime": "2023-09-08T13:53:49.885Z",
"time": 449.04499999984364,
"timings": {
@@ -135,7 +134,6 @@
"_transferSize": 11081,
"_error": null
},
- "serverIPAddress": "[64:ff9b::d21:40f]",
"startedDateTime": "2023-09-08T13:53:49.902Z",
"time": 804.0409999994154,
"timings": {
@@ -206,7 +204,6 @@
"_transferSize": 11253,
"_error": null
},
- "serverIPAddress": "[64:ff9b::d21:40f]",
"startedDateTime": "2023-09-08T13:53:49.909Z",
"time": 1204.160999999658,
"timings": {
@@ -277,7 +274,6 @@
"_transferSize": 12769,
"_error": null
},
- "serverIPAddress": "[64:ff9b::d21:40f]",
"startedDateTime": "2023-09-08T13:53:49.917Z",
"time": 313.9339999997901,
"timings": {
@@ -348,7 +344,6 @@
"_transferSize": 12768,
"_error": null
},
- "serverIPAddress": "[64:ff9b::d21:40f]",
"startedDateTime": "2023-09-08T13:53:49.923Z",
"time": 1060.0050000002739,
"timings": {
@@ -419,7 +414,6 @@
"_transferSize": 11016,
"_error": null
},
- "serverIPAddress": "[64:ff9b::d21:40f]",
"startedDateTime": "2023-09-08T13:53:49.932Z",
"time": 812.2540000003937,
"timings": {
@@ -490,7 +484,6 @@
"_transferSize": 11006,
"_error": null
},
- "serverIPAddress": "[64:ff9b::d21:40f]",
"startedDateTime": "2023-09-08T13:53:49.938Z",
"time": 1667.8229999997711,
"timings": {
@@ -561,7 +554,6 @@
"_transferSize": 11011,
"_error": null
},
- "serverIPAddress": "[64:ff9b::d21:40f]",
"startedDateTime": "2023-09-08T13:53:49.950Z",
"time": 1307.301999999254,
"timings": {
@@ -632,7 +624,6 @@
"_transferSize": 11016,
"_error": null
},
- "serverIPAddress": "[64:ff9b::d21:40f]",
"startedDateTime": "2023-09-08T13:53:49.958Z",
"time": 746.1700000003475,
"timings": {
@@ -703,7 +694,6 @@
"_transferSize": 11020,
"_error": null
},
- "serverIPAddress": "[64:ff9b::d21:40f]",
"startedDateTime": "2023-09-08T13:53:49.967Z",
"time": 1989.0759999998409,
"timings": {
@@ -774,7 +764,6 @@
"_transferSize": 12959,
"_error": null
},
- "serverIPAddress": "[64:ff9b::d21:40f]",
"startedDateTime": "2023-09-08T13:53:49.974Z",
"time": 1773.866000000453,
"timings": {
diff --git a/percy/geocoder-mock-normal.har b/percy/geocoder-mock-normal.har
index 5d6763cd2..39164fea8 100644
--- a/percy/geocoder-mock-normal.har
+++ b/percy/geocoder-mock-normal.har
@@ -64,7 +64,6 @@
"_transferSize": 12785,
"_error": null
},
- "serverIPAddress": "[64:ff9b::de1:2f3f]",
"startedDateTime": "2023-09-08T14:07:22.644Z",
"time": 2125.9739999999583,
"timings": {
@@ -135,7 +134,6 @@
"_transferSize": 11262,
"_error": null
},
- "serverIPAddress": "[64:ff9b::de1:2f3f]",
"startedDateTime": "2023-09-08T14:07:22.656Z",
"time": 2307.477999999719,
"timings": {
@@ -206,7 +204,6 @@
"_transferSize": 5615,
"_error": null
},
- "serverIPAddress": "[64:ff9b::de1:2f3f]",
"startedDateTime": "2023-09-08T14:07:22.663Z",
"time": 2034.0139999998428,
"timings": {
@@ -277,7 +274,6 @@
"_transferSize": 5619,
"_error": null
},
- "serverIPAddress": "[64:ff9b::de1:2f3f]",
"startedDateTime": "2023-09-08T14:07:22.666Z",
"time": 1865.16599999959,
"timings": {
@@ -348,7 +344,6 @@
"_transferSize": 5621,
"_error": null
},
- "serverIPAddress": "[64:ff9b::de1:2f3f]",
"startedDateTime": "2023-09-08T14:07:22.676Z",
"time": 2317.60100000065,
"timings": {
@@ -419,7 +414,6 @@
"_transferSize": 3972,
"_error": null
},
- "serverIPAddress": "[64:ff9b::de1:2f3f]",
"startedDateTime": "2023-09-08T14:07:22.679Z",
"time": 1605.46499999964,
"timings": {
@@ -490,7 +484,6 @@
"_transferSize": 2370,
"_error": null
},
- "serverIPAddress": "[64:ff9b::de1:2f3f]",
"startedDateTime": "2023-09-08T14:07:22.682Z",
"time": 1566.6149999997288,
"timings": {
@@ -561,7 +554,6 @@
"_transferSize": 2367,
"_error": null
},
- "serverIPAddress": "[64:ff9b::de1:2f3f]",
"startedDateTime": "2023-09-08T14:07:22.690Z",
"time": 2356.9259999994756,
"timings": {
@@ -632,7 +624,6 @@
"_transferSize": 2379,
"_error": null
},
- "serverIPAddress": "[64:ff9b::de1:2f3f]",
"startedDateTime": "2023-09-08T14:07:22.699Z",
"time": 2625.739999999496,
"timings": {
@@ -703,7 +694,6 @@
"_transferSize": 2351,
"_error": null
},
- "serverIPAddress": "[64:ff9b::de1:2f3f]",
"startedDateTime": "2023-09-08T14:07:22.703Z",
"time": 2622.787999999673,
"timings": {
diff --git a/percy/mock.har b/percy/mock.har
index 64f8ee2a4..168b2f6c5 100644
--- a/percy/mock.har
+++ b/percy/mock.har
@@ -35,7 +35,6 @@
"_transferSize": 9618,
"_error": null
},
- "serverIPAddress": "23.22.4.67",
"startedDateTime": "2023-08-09T14:44:09.561Z",
"time": 221.89399999479065,
"timings": {
@@ -77,7 +76,6 @@
"_transferSize": 9618,
"_error": null
},
- "serverIPAddress": "23.22.4.67",
"startedDateTime": "2023-08-09T14:44:09.561Z",
"time": 221.89399999479065,
"timings": {
@@ -119,7 +117,6 @@
"_transferSize": 76937,
"_error": null
},
- "serverIPAddress": "35.173.73.127",
"startedDateTime": "2023-08-03T20:49:50.033Z",
"time": 590.6560000003083,
"timings": {
@@ -161,7 +158,6 @@
"_transferSize": 7340,
"_error": null
},
- "serverIPAddress": "35.173.73.127",
"startedDateTime": "2023-08-03T20:49:50.036Z",
"time": 257.49999999970896,
"timings": {
@@ -203,7 +199,6 @@
"_transferSize": 40856,
"_error": null
},
- "serverIPAddress": "52.20.220.65",
"startedDateTime": "2023-08-04T20:40:31.694Z",
"time": 82.74900000105845,
"timings": {
@@ -241,7 +236,6 @@
"_transferSize": 5438,
"_error": null
},
- "serverIPAddress": "3.222.122.125",
"startedDateTime": "2023-08-04T20:59:03.536Z",
"time": 54.81599999620812,
"timings": {
@@ -279,7 +273,6 @@
"_transferSize": 38256,
"_error": null
},
- "serverIPAddress": "3.222.122.125",
"startedDateTime": "2023-08-04T20:59:03.536Z",
"time": 60.42699999670731,
"timings": {
@@ -321,7 +314,6 @@
"_transferSize": 2433,
"_error": null
},
- "serverIPAddress": "34.195.110.47",
"startedDateTime": "2023-08-04T21:29:23.087Z",
"time": 66.22100000095088,
"timings": {
@@ -368,7 +360,6 @@
"_transferSize": 1604,
"_error": null
},
- "serverIPAddress": "34.195.110.47",
"startedDateTime": "2023-08-04T21:29:23.171Z",
"time": 51.44000000291271,
"timings": {
@@ -410,7 +401,6 @@
"_transferSize": 2002,
"_error": null
},
- "serverIPAddress": "34.195.110.47",
"startedDateTime": "2023-08-04T21:29:23.176Z",
"time": 58.54399999952875,
"timings": {
@@ -452,7 +442,6 @@
"_transferSize": 7459,
"_error": null
},
- "serverIPAddress": "34.195.110.47",
"startedDateTime": "2023-08-04T21:29:23.177Z",
"time": 57.214999993448146,
"timings": {
@@ -495,7 +484,6 @@
"_transferSize": 27049,
"_error": null
},
- "serverIPAddress": "34.238.57.75",
"startedDateTime": "2023-08-07T19:09:16.223Z",
"time": 66.91099999807193,
"timings": {
@@ -537,7 +525,6 @@
"_transferSize": 33935,
"_error": null
},
- "serverIPAddress": "44.207.110.234",
"startedDateTime": "2023-08-07T19:49:43.900Z",
"time": 168.25500000049942,
"timings": {
@@ -596,7 +583,6 @@
"_transferSize": 1191061,
"_error": null
},
- "serverIPAddress": "3.232.128.121",
"startedDateTime": "2023-08-07T21:13:12.901Z",
"time": 327.1550000026764,
"timings": {
@@ -638,7 +624,6 @@
"_transferSize": 25417,
"_error": null
},
- "serverIPAddress": "54.86.250.244",
"startedDateTime": "2023-08-07T20:31:47.159Z",
"time": 305.05600000105915,
"timings": {
@@ -680,7 +665,6 @@
"_transferSize": 1077,
"_error": null
},
- "serverIPAddress": "3.220.60.180",
"startedDateTime": "2023-08-08T20:29:50.871Z",
"time": 62.50199999703909,
"timings": {
@@ -722,7 +706,6 @@
"_transferSize": 1077,
"_error": null
},
- "serverIPAddress": "3.220.60.180",
"startedDateTime": "2023-08-08T20:29:50.871Z",
"time": 62.50199999703909,
"timings": {
@@ -764,7 +747,6 @@
"_transferSize": 1077,
"_error": null
},
- "serverIPAddress": "3.220.60.180",
"startedDateTime": "2023-08-08T20:29:50.871Z",
"time": 62.50199999703909,
"timings": {
@@ -806,7 +788,6 @@
"_transferSize": 1077,
"_error": null
},
- "serverIPAddress": "3.220.60.180",
"startedDateTime": "2023-08-08T20:29:50.871Z",
"time": 62.50199999703909,
"timings": {
@@ -848,7 +829,6 @@
"_transferSize": 31570,
"_error": null
},
- "serverIPAddress": "3.220.60.180",
"startedDateTime": "2023-08-08T14:50:06.820Z",
"time": 189.288999999917,
"timings": {
@@ -885,7 +865,6 @@
"_transferSize": 21813,
"_error": null
},
- "serverIPAddress": "3.220.60.180",
"startedDateTime": "2023-08-08T14:50:06.819Z",
"time": 185.85299999995186,
"timings": {
@@ -927,7 +906,6 @@
"_transferSize": 4511,
"_error": null
},
- "serverIPAddress": "3.220.60.180",
"startedDateTime": "2023-08-08T14:50:07.079Z",
"time": 57.98200000026554,
"timings": {
@@ -969,7 +947,6 @@
"_transferSize": 43200,
"_error": null
},
- "serverIPAddress": "3.220.60.180",
"startedDateTime": "2023-08-08T14:50:07.080Z",
"time": 65.15599999966071,
"timings": {
From 10e612a0eb46c90cb7ef902925672ee04415216f Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Fri, 8 Sep 2023 18:04:06 -0400
Subject: [PATCH 46/80] test(percy): Tighten up mocks
---
percy/geocoder-mock-calltaker.har | 20 +++----
percy/geocoder-mock-normal.har | 99 ++++++++++++-------------------
2 files changed, 49 insertions(+), 70 deletions(-)
diff --git a/percy/geocoder-mock-calltaker.har b/percy/geocoder-mock-calltaker.har
index 0a93718b8..895bf6a9b 100644
--- a/percy/geocoder-mock-calltaker.har
+++ b/percy/geocoder-mock-calltaker.har
@@ -56,7 +56,7 @@
"content": {
"size": 11710,
"mimeType": "application/json",
- "text": ""
+ "text": "{\"features\":[]}"
},
"redirectURL": "",
"headersSize": -1,
@@ -126,7 +126,7 @@
"content": {
"size": 0,
"mimeType": "application/json",
- "text": ""
+ "text": "{\"features\":[]}"
},
"redirectURL": "",
"headersSize": -1,
@@ -196,7 +196,7 @@
"content": {
"size": 0,
"mimeType": "application/json",
- "text": ""
+ "text": "{\"features\":[]}"
},
"redirectURL": "",
"headersSize": -1,
@@ -266,7 +266,7 @@
"content": {
"size": 0,
"mimeType": "application/json",
- "text": ""
+ "text": "{\"features\":[]}"
},
"redirectURL": "",
"headersSize": -1,
@@ -336,7 +336,7 @@
"content": {
"size": 0,
"mimeType": "application/json",
- "text": ""
+ "text": "{\"features\":[]}"
},
"redirectURL": "",
"headersSize": -1,
@@ -406,7 +406,7 @@
"content": {
"size": 0,
"mimeType": "application/json",
- "text": ""
+ "text": "{\"features\":[]}"
},
"redirectURL": "",
"headersSize": -1,
@@ -476,7 +476,7 @@
"content": {
"size": 0,
"mimeType": "application/json",
- "text": ""
+ "text": "{\"features\":[]}"
},
"redirectURL": "",
"headersSize": -1,
@@ -546,7 +546,7 @@
"content": {
"size": 0,
"mimeType": "application/json",
- "text": ""
+ "text": "{\"features\":[]}"
},
"redirectURL": "",
"headersSize": -1,
@@ -616,7 +616,7 @@
"content": {
"size": 0,
"mimeType": "application/json",
- "text": ""
+ "text": "{\"features\":[]}"
},
"redirectURL": "",
"headersSize": -1,
@@ -686,7 +686,7 @@
"content": {
"size": 0,
"mimeType": "application/json",
- "text": ""
+ "text": "{\"features\":[]}"
},
"redirectURL": "",
"headersSize": -1,
diff --git a/percy/geocoder-mock-normal.har b/percy/geocoder-mock-normal.har
index 39164fea8..e33efa664 100644
--- a/percy/geocoder-mock-normal.har
+++ b/percy/geocoder-mock-normal.har
@@ -56,9 +56,8 @@
"content": {
"size": 0,
"mimeType": "application/json",
- "text": ""
+ "text": "{\"features\":[]}"
},
- "redirectURL": "",
"headersSize": -1,
"bodySize": -1,
"_transferSize": 12785,
@@ -126,9 +125,8 @@
"content": {
"size": 0,
"mimeType": "application/json",
- "text": ""
+ "text": "{\"features\":[]}"
},
- "redirectURL": "",
"headersSize": -1,
"bodySize": -1,
"_transferSize": 11262,
@@ -196,9 +194,8 @@
"content": {
"size": 0,
"mimeType": "application/json",
- "text": ""
+ "text": "{\"features\":[]}"
},
- "redirectURL": "",
"headersSize": -1,
"bodySize": -1,
"_transferSize": 5615,
@@ -266,9 +263,8 @@
"content": {
"size": 0,
"mimeType": "application/json",
- "text": ""
+ "text": "{\"features\":[]}"
},
- "redirectURL": "",
"headersSize": -1,
"bodySize": -1,
"_transferSize": 5619,
@@ -336,9 +332,8 @@
"content": {
"size": 0,
"mimeType": "application/json",
- "text": ""
+ "text": "{\"features\":[]}"
},
- "redirectURL": "",
"headersSize": -1,
"bodySize": -1,
"_transferSize": 5621,
@@ -406,9 +401,8 @@
"content": {
"size": 0,
"mimeType": "application/json",
- "text": ""
+ "text": "{\"features\":[]}"
},
- "redirectURL": "",
"headersSize": -1,
"bodySize": -1,
"_transferSize": 3972,
@@ -476,9 +470,8 @@
"content": {
"size": 0,
"mimeType": "application/json",
- "text": ""
+ "text": "{\"features\":[]}"
},
- "redirectURL": "",
"headersSize": -1,
"bodySize": -1,
"_transferSize": 2370,
@@ -546,9 +539,8 @@
"content": {
"size": 0,
"mimeType": "application/json",
- "text": ""
+ "text": "{\"features\":[]}"
},
- "redirectURL": "",
"headersSize": -1,
"bodySize": -1,
"_transferSize": 2367,
@@ -616,9 +608,8 @@
"content": {
"size": 0,
"mimeType": "application/json",
- "text": ""
+ "text": "{\"features\":[]}"
},
- "redirectURL": "",
"headersSize": -1,
"bodySize": -1,
"_transferSize": 2379,
@@ -688,7 +679,6 @@
"mimeType": "application/json",
"text": "{\"geocoding\":{\"version\":\"0.2\",\"attribution\":\"https://geocode.earth/guidelines\",\"query\":{\"text\":\"Opus\",\"parser\":\"pelias\",\"parsed_text\":{\"subject\":\"Opus\"},\"size\":10,\"layers\":[\"address\",\"venue\",\"street\",\"intersection\"],\"sources\":[\"openstreetmap\",\"openaddresses\",\"geonames\",\"whosonfirst\",\"uscensus\"],\"private\":false,\"focus.point.lat\":33.749,\"focus.point.lon\":-84.388,\"boundary.rect.min_lat\":32.066,\"boundary.rect.max_lat\":35.7251,\"boundary.rect.min_lon\":-86.0856,\"boundary.rect.max_lon\":-81.9499,\"lang\":{\"name\":\"English\",\"iso6391\":\"en\",\"iso6393\":\"eng\",\"via\":\"default\",\"defaulted\":true},\"querySize\":20},\"engine\":{\"name\":\"Pelias\",\"author\":\"Mapzen\",\"version\":\"1.0\"},\"timestamp\":1694202052257},\"type\":\"FeatureCollection\",\"features\":[{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[-84.300178,33.77505]},\"properties\":{\"id\":\"node/556611976\",\"gid\":\"openstreetmap:venue:node/556611976\",\"layer\":\"venue\",\"source\":\"openstreetmap\",\"source_id\":\"node/556611976\",\"country_code\":\"US\",\"name\":\"Opus Music Store\",\"housenumber\":\"308D\",\"distance\":8.629,\"accuracy\":\"point\",\"country\":\"United States\",\"country_gid\":\"whosonfirst:country:85633793\",\"country_a\":\"USA\",\"region\":\"Georgia\",\"region_gid\":\"whosonfirst:region:85688535\",\"region_a\":\"GA\",\"county\":\"DeKalb County\",\"county_gid\":\"whosonfirst:county:102084539\",\"county_a\":\"DA\",\"locality\":\"Decatur\",\"locality_gid\":\"whosonfirst:locality:85936441\",\"continent\":\"North America\",\"continent_gid\":\"whosonfirst:continent:102191575\",\"label\":\"Opus Music Store, Decatur, GA, USA\",\"addendum\":{\"osm\":{\"website\":\"http://www.opusmusicstore.com/\",\"phone\":\"+1 404 370 0507\"}}}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[-84.385934,33.787145]},\"properties\":{\"id\":\"way/885660365\",\"gid\":\"openstreetmap:venue:way/885660365\",\"layer\":\"venue\",\"source\":\"openstreetmap\",\"source_id\":\"way/885660365\",\"country_code\":\"US\",\"name\":\"2 Opus Place (construction)\",\"distance\":4.251,\"accuracy\":\"point\",\"country\":\"United States\",\"country_gid\":\"whosonfirst:country:85633793\",\"country_a\":\"USA\",\"region\":\"Georgia\",\"region_gid\":\"whosonfirst:region:85688535\",\"region_a\":\"GA\",\"county\":\"Fulton County\",\"county_gid\":\"whosonfirst:county:102083603\",\"county_a\":\"FU\",\"locality\":\"Atlanta\",\"locality_gid\":\"whosonfirst:locality:85936429\",\"continent\":\"North America\",\"continent_gid\":\"whosonfirst:continent:102191575\",\"label\":\"2 Opus Place (construction), Atlanta, GA, USA\"},\"bbox\":[-84.3866911,33.7867611,-84.385266,33.7874624]},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[-85.211688,35.00657]},\"properties\":{\"id\":\"way/51791114\",\"gid\":\"openstreetmap:venue:way/51791114\",\"layer\":\"venue\",\"source\":\"openstreetmap\",\"source_id\":\"way/51791114\",\"country_code\":\"US\",\"name\":\"Opus Inspection\",\"distance\":159.136,\"accuracy\":\"point\",\"country\":\"United States\",\"country_gid\":\"whosonfirst:country:85633793\",\"country_a\":\"USA\",\"region\":\"Tennessee\",\"region_gid\":\"whosonfirst:region:85688701\",\"region_a\":\"TN\",\"county\":\"Hamilton County\",\"county_gid\":\"whosonfirst:county:102087185\",\"county_a\":\"HL\",\"locality\":\"Chattanooga\",\"locality_gid\":\"whosonfirst:locality:101723043\",\"continent\":\"North America\",\"continent_gid\":\"whosonfirst:continent:102191575\",\"label\":\"Opus Inspection, Chattanooga, TN, USA\"},\"bbox\":[-85.2118453,35.0064715,-85.21153,35.0067042]},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[-82.230045,33.55809]},\"properties\":{\"id\":\"w577848242-n5538625175-w577848271\",\"gid\":\"openstreetmap:intersection:w577848242-n5538625175-w577848271\",\"layer\":\"intersection\",\"source\":\"openstreetmap\",\"source_id\":\"w577848242-n5538625175-w577848271\",\"country_code\":\"US\",\"name\":\"Bent Creek Drive & Magnum Opus Way\",\"street\":\"Bent Creek Drive\",\"distance\":201.084,\"accuracy\":\"centroid\",\"country\":\"United States\",\"country_gid\":\"whosonfirst:country:85633793\",\"country_a\":\"USA\",\"region\":\"Georgia\",\"region_gid\":\"whosonfirst:region:85688535\",\"region_a\":\"GA\",\"county\":\"Columbia County\",\"county_gid\":\"whosonfirst:county:102082315\",\"county_a\":\"CI\",\"continent\":\"North America\",\"continent_gid\":\"whosonfirst:continent:102191575\",\"label\":\"Bent Creek Drive & Magnum Opus Way, Columbia County, GA, USA\"}},{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[-82.22882,33.559832]},\"properties\":{\"id\":\"polyline:18601022\",\"gid\":\"openstreetmap:street:polyline:18601022\",\"layer\":\"street\",\"source\":\"openstreetmap\",\"source_id\":\"polyline:18601022\",\"country_code\":\"US\",\"name\":\"Magnum Opus Way\",\"street\":\"Magnum Opus Way\",\"distance\":201.175,\"accuracy\":\"centroid\",\"country\":\"United States\",\"country_gid\":\"whosonfirst:country:85633793\",\"country_a\":\"USA\",\"region\":\"Georgia\",\"region_gid\":\"whosonfirst:region:85688535\",\"region_a\":\"GA\",\"county\":\"Columbia County\",\"county_gid\":\"whosonfirst:county:102082315\",\"county_a\":\"CI\",\"continent\":\"North America\",\"continent_gid\":\"whosonfirst:continent:102191575\",\"label\":\"Magnum Opus Way, Columbia County, GA, USA\"},\"bbox\":[-82.230045,33.55809,-82.227691,33.561696]}],\"bbox\":[-85.2118453,33.55809,-82.227691,35.0067042],\"isomorphicMapzenSearchQuery\":{\"api_key\":\"ge-0624346c114543d5\",\"text\":\"Opus\",\"layers\":\"address,venue,street,intersection\",\"focus.point.lat\":33.749,\"focus.point.lon\":-84.388,\"boundary.rect.min_lat\":32.066,\"boundary.rect.min_lon\":-86.0856,\"boundary.rect.max_lat\":35.7251,\"boundary.rect.max_lon\":-81.9499}}"
},
- "redirectURL": "",
"headersSize": -1,
"bodySize": -1,
"_transferSize": 2351,
@@ -713,7 +703,7 @@
"bodySize": 0,
"method": "GET",
"url": "http://localhost:9977/autocomplete?text=9&layers=address%2Cvenue%2Cstreet%2Cintersection&focus.point.lat=33.749&focus.point.lon=-84.388&boundary.rect.min_lat=32.066&boundary.rect.min_lon=-86.0856&boundary.rect.max_lat=35.7251&boundary.rect.max_lon=-81.9499",
- "httpVersion": "",
+ "httpVersion": "HTTP/2",
"queryString": [
{
"name": "text",
@@ -751,16 +741,14 @@
"headersSize": 730
},
"response": {
- "status": 0,
- "statusText": "",
- "httpVersion": "",
+ "status": 200,
+ "statusText": "OK",
+ "httpVersion": "HTTP/2",
"content": {
- "mimeType": "",
+ "mimeType": "application/json",
"size": 0,
- "encoding": "base64",
- "text": ""
+ "text": "{\"features\":[]}"
},
- "redirectURL": "",
"headersSize": 0,
"bodySize": 0
},
@@ -781,7 +769,7 @@
"bodySize": 0,
"method": "GET",
"url": "http://localhost:9977/autocomplete?text=90&layers=address%2Cvenue%2Cstreet%2Cintersection&focus.point.lat=33.749&focus.point.lon=-84.388&boundary.rect.min_lat=32.066&boundary.rect.min_lon=-86.0856&boundary.rect.max_lat=35.7251&boundary.rect.max_lon=-81.9499",
- "httpVersion": "",
+ "httpVersion": "HTTP/2",
"queryString": [
{
"name": "text",
@@ -819,16 +807,14 @@
"headersSize": 731
},
"response": {
- "status": 0,
- "statusText": "",
- "httpVersion": "",
+ "status": 200,
+ "statusText": "OK",
+ "httpVersion": "HTTP/2",
"content": {
- "mimeType": "",
+ "mimeType": "application/json",
"size": 0,
- "encoding": "base64",
- "text": ""
+ "text": "{\"features\":[]}"
},
- "redirectURL": "",
"headersSize": 0,
"bodySize": 0
},
@@ -849,7 +835,7 @@
"bodySize": 0,
"method": "GET",
"url": "http://localhost:9977/autocomplete?text=908&layers=address%2Cvenue%2Cstreet%2Cintersection&focus.point.lat=33.749&focus.point.lon=-84.388&boundary.rect.min_lat=32.066&boundary.rect.min_lon=-86.0856&boundary.rect.max_lat=35.7251&boundary.rect.max_lon=-81.9499",
- "httpVersion": "",
+ "httpVersion": "HTTP/2",
"queryString": [
{
"name": "text",
@@ -887,16 +873,14 @@
"headersSize": 732
},
"response": {
- "status": 0,
- "statusText": "",
- "httpVersion": "",
+ "status": 200,
+ "statusText": "OK",
+ "httpVersion": "HTTP/2",
"content": {
- "mimeType": "",
+ "mimeType": "application/json",
"size": 0,
- "encoding": "base64",
- "text": ""
+ "text": "{\"features\":[]}"
},
- "redirectURL": "",
"headersSize": 0,
"bodySize": 0
},
@@ -917,7 +901,7 @@
"bodySize": 0,
"method": "GET",
"url": "http://localhost:9977/autocomplete?text=9089&layers=address%2Cvenue%2Cstreet%2Cintersection&focus.point.lat=33.749&focus.point.lon=-84.388&boundary.rect.min_lat=32.066&boundary.rect.min_lon=-86.0856&boundary.rect.max_lat=35.7251&boundary.rect.max_lon=-81.9499",
- "httpVersion": "",
+ "httpVersion": "HTTP/2",
"queryString": [
{
"name": "text",
@@ -955,16 +939,14 @@
"headersSize": 733
},
"response": {
- "status": 0,
- "statusText": "",
- "httpVersion": "",
+ "status": 200,
+ "statusText": "OK",
+ "httpVersion": "HTTP/2",
"content": {
- "mimeType": "",
+ "mimeType": "application/json",
"size": 0,
- "encoding": "base64",
- "text": ""
+ "text": "{\"features\":[]}"
},
- "redirectURL": "",
"headersSize": 0,
"bodySize": 0
},
@@ -985,7 +967,7 @@
"bodySize": 0,
"method": "GET",
"url": "http://localhost:9977/autocomplete?text=90898&layers=address%2Cvenue%2Cstreet%2Cintersection&focus.point.lat=33.749&focus.point.lon=-84.388&boundary.rect.min_lat=32.066&boundary.rect.min_lon=-86.0856&boundary.rect.max_lat=35.7251&boundary.rect.max_lon=-81.9499",
- "httpVersion": "",
+ "httpVersion": "HTTP/2",
"queryString": [
{
"name": "text",
@@ -1023,16 +1005,14 @@
"headersSize": 735
},
"response": {
- "status": 0,
- "statusText": "",
- "httpVersion": "",
+ "status": 200,
+ "statusText": "OK",
+ "httpVersion": "HTTP/2",
"content": {
- "mimeType": "",
+ "mimeType": "application/json",
"size": 0,
- "encoding": "base64",
- "text": ""
+ "text": "{\"features\":[]}"
},
- "redirectURL": "",
"headersSize": 0,
"bodySize": 0
},
@@ -1099,7 +1079,6 @@
"size": 12687,
"text": "{\"features\":[{\"geometry\":{\"type\":\"Point\",\"coordinates\":[-84.391397,33.753837]},\"id\":\"MARTA:797\",\"properties\":{\"layer\":\"stops\",\"source\":\"otp\",\"name\":\"Five Points Station (908981)\",\"label\":\"Five Points Station (908981)\"},\"type\":\"Feature\"}],\"type\":\"FeatureCollection\"}"
},
- "redirectURL": "",
"headersSize": 547,
"bodySize": 13234
},
From c331c12f4c1b0bc028c82455fb3fc912394a0724 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Fri, 8 Sep 2023 18:05:40 -0400
Subject: [PATCH 47/80] test(percy): Add delay between location keystrokes
---
percy/percy.test.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/percy/percy.test.js b/percy/percy.test.js
index 87b5b1ec3..5c2f07931 100644
--- a/percy/percy.test.js
+++ b/percy/percy.test.js
@@ -170,7 +170,7 @@ async function executeTest(page, isMobile, isCallTaker) {
await page.hover('.from-form-control')
await page.focus('.from-form-control')
// FIXME: Characters are typed very fast, but each stroke still triggers a geocoder call.
- await page.keyboard.type('Opus Music')
+ await page.keyboard.type('Opus Music', { delay: 100 })
await page.waitForTimeout(2000)
await page.keyboard.press('ArrowDown')
await page.waitForTimeout(200)
@@ -179,7 +179,7 @@ async function executeTest(page, isMobile, isCallTaker) {
// Fill in new destination
await page.focus('.to-form-control')
// FIXME: Characters are typed very fast, but each stroke still triggers a geocoder call.
- await page.keyboard.type('908981')
+ await page.keyboard.type('908981', { delay: 100 })
await page.waitForTimeout(2000)
await page.keyboard.press('ArrowDown')
await page.waitForTimeout(200)
@@ -215,7 +215,7 @@ async function executeTest(page, isMobile, isCallTaker) {
await page.waitForSelector('.intermediate-place-0-form-control')
await page.focus('.intermediate-place-0-form-control')
// FIXME: Characters are typed very fast, but each stroke still triggers a geocoder call.
- await page.keyboard.type('arts center')
+ await page.keyboard.type('arts center', { delay: 100 })
await page.waitForTimeout(2000)
await page.keyboard.press('ArrowDown')
await page.waitForTimeout(200)
From 35c0cf991888d72f375a1230f717e67d816452eb Mon Sep 17 00:00:00 2001
From: Daniel Heppner
Date: Tue, 12 Sep 2023 15:25:32 +0200
Subject: [PATCH 48/80] deps: update to alpha version of core utils
---
package.json | 4 ++--
yarn.lock | 16 ++++++++--------
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/package.json b/package.json
index 46e9ff69a..eb43f07ab 100644
--- a/package.json
+++ b/package.json
@@ -39,7 +39,7 @@
"@bugsnag/plugin-react": "^7.17.0",
"@floating-ui/react": "^0.19.2",
"@opentripplanner/base-map": "^3.0.14",
- "@opentripplanner/core-utils": "^11.0.2",
+ "@opentripplanner/core-utils": "^12.0.0-alpha.2",
"@opentripplanner/endpoints-overlay": "^2.0.8",
"@opentripplanner/from-to-location-picker": "^2.1.8",
"@opentripplanner/geocoder": "^1.4.2",
@@ -132,7 +132,7 @@
"@craco/craco": "^6.3.0",
"@jackwilsdon/craco-use-babelrc": "^1.0.0",
"@opentripplanner/scripts": "^1.2.0",
- "@opentripplanner/types": "^6.1.0",
+ "@opentripplanner/types": "^7.0.0-alpha.9",
"@percy/cli": "^1.20.3",
"@percy/puppeteer": "^2.0.2",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.1",
diff --git a/yarn.lock b/yarn.lock
index d24a5c104..d7225a50b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2439,10 +2439,10 @@
lodash.isequal "^4.5.0"
qs "^6.9.1"
-"@opentripplanner/core-utils@^11.0.2":
- version "11.0.2"
- resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-11.0.2.tgz#ebfa939c3b7b266e3bf47dcaddda88e093430a9d"
- integrity sha512-3oQYvnhFHY88K61j2tUkU2fm8tDci5qaMVGEgqTzxpE5NmBTUdAWU1V7W9snJoRATzz3zy+K9qrtIhGjwbwlnA==
+"@opentripplanner/core-utils@^12.0.0-alpha.2":
+ version "12.0.0-alpha.2"
+ resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-12.0.0-alpha.2.tgz#7069e03b1f2c002b19e13968ac779cd2ea8d862f"
+ integrity sha512-iyrPNZWkt0fBwfBfJU467aW9UvGz2sXLdwxtutvMqs2rmA+M38+UgiIIDNYXTzto7hsHTFDcHpDaRDFFMPeNhg==
dependencies:
"@conveyal/lonlat" "^1.4.1"
"@mapbox/polyline" "^1.1.0"
@@ -2771,10 +2771,10 @@
"@opentripplanner/base-map" "^3.0.13"
"@opentripplanner/core-utils" "^9.0.0"
-"@opentripplanner/types@^6.1.0":
- version "6.1.0"
- resolved "https://registry.yarnpkg.com/@opentripplanner/types/-/types-6.1.0.tgz#dd5b88cc0b73939cd1eb5bd44d4768e21bedaacc"
- integrity sha512-fFuNMJLrSCIoIWJ7VugM1Jb7HfIcRDzb8o2LNsASExWAEYDuONFxyGYT/98g82/70Grl8kCSMSAFi0lEiQ/cPQ==
+"@opentripplanner/types@^7.0.0-alpha.9":
+ version "7.0.0-alpha.10"
+ resolved "https://registry.yarnpkg.com/@opentripplanner/types/-/types-7.0.0-alpha.10.tgz#56a3f90e000e815a663c9ade7965d4d4914f8bf2"
+ integrity sha512-hHltdB1espxHypiu28bUcsFhYpj6511k1NJjLjV2+mC3T1hfb0/aqa1QYj6ydlEww7+mV5b/ENnZEMkDtHErJg==
"@opentripplanner/vehicle-rental-overlay@^2.1.2":
version "2.1.2"
From e1dda38aafd528aa3584e5e82c85bf53c9eeb4e7 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Tue, 12 Sep 2023 16:02:09 -0400
Subject: [PATCH 49/80] ci(percy): Use new config that uses mock geocoder
---
.github/workflows/percy.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/percy.yml b/.github/workflows/percy.yml
index 957eafc81..3f12e171a 100644
--- a/.github/workflows/percy.yml
+++ b/.github/workflows/percy.yml
@@ -25,7 +25,7 @@ jobs:
- name: Download OTP2 config file
run: curl $PERCY_OTP2_CONFIG_URL --output /tmp/otp2config.yml
env:
- PERCY_OTP2_CONFIG_URL: ${{ secrets.PERCY_MOCKOTP2_CONFIG_URL_METRO_MODE_SELECTOR }}
+ PERCY_OTP2_CONFIG_URL: ${{ secrets.PERCY_MOCK_OTP2_GEOCODER_CONFIG }}
- name: Build OTP-RR
# Artifacts are shared between desktop and mobile tests (but not call-taker).
run: yarn build
From 16b5ba599538cf840a888bb5c7a024ac45efb9e7 Mon Sep 17 00:00:00 2001
From: Daniel Heppner
Date: Tue, 12 Sep 2023 23:33:53 +0100
Subject: [PATCH 50/80] deps: use non alpha versions
---
package.json | 4 ++--
yarn.lock | 16 ++++++++--------
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/package.json b/package.json
index eb43f07ab..4f7774ef8 100644
--- a/package.json
+++ b/package.json
@@ -39,7 +39,7 @@
"@bugsnag/plugin-react": "^7.17.0",
"@floating-ui/react": "^0.19.2",
"@opentripplanner/base-map": "^3.0.14",
- "@opentripplanner/core-utils": "^12.0.0-alpha.2",
+ "@opentripplanner/core-utils": "^11.0.3",
"@opentripplanner/endpoints-overlay": "^2.0.8",
"@opentripplanner/from-to-location-picker": "^2.1.8",
"@opentripplanner/geocoder": "^1.4.2",
@@ -132,7 +132,7 @@
"@craco/craco": "^6.3.0",
"@jackwilsdon/craco-use-babelrc": "^1.0.0",
"@opentripplanner/scripts": "^1.2.0",
- "@opentripplanner/types": "^7.0.0-alpha.9",
+ "@opentripplanner/types": "^6.1.1",
"@percy/cli": "^1.20.3",
"@percy/puppeteer": "^2.0.2",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.1",
diff --git a/yarn.lock b/yarn.lock
index d7225a50b..1521f2a66 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2439,10 +2439,10 @@
lodash.isequal "^4.5.0"
qs "^6.9.1"
-"@opentripplanner/core-utils@^12.0.0-alpha.2":
- version "12.0.0-alpha.2"
- resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-12.0.0-alpha.2.tgz#7069e03b1f2c002b19e13968ac779cd2ea8d862f"
- integrity sha512-iyrPNZWkt0fBwfBfJU467aW9UvGz2sXLdwxtutvMqs2rmA+M38+UgiIIDNYXTzto7hsHTFDcHpDaRDFFMPeNhg==
+"@opentripplanner/core-utils@^11.0.3":
+ version "11.0.3"
+ resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-11.0.3.tgz#b8aa21f81be420c07128e78c20a74d32d0034476"
+ integrity sha512-hTLZwU8YyokTA86tIa+iy46g0lqcjBX/HDxyzwxvbm6lFnUvUhHgWRPKvr8fzUA5aE0vYzwlj16WygQ43n4ubQ==
dependencies:
"@conveyal/lonlat" "^1.4.1"
"@mapbox/polyline" "^1.1.0"
@@ -2771,10 +2771,10 @@
"@opentripplanner/base-map" "^3.0.13"
"@opentripplanner/core-utils" "^9.0.0"
-"@opentripplanner/types@^7.0.0-alpha.9":
- version "7.0.0-alpha.10"
- resolved "https://registry.yarnpkg.com/@opentripplanner/types/-/types-7.0.0-alpha.10.tgz#56a3f90e000e815a663c9ade7965d4d4914f8bf2"
- integrity sha512-hHltdB1espxHypiu28bUcsFhYpj6511k1NJjLjV2+mC3T1hfb0/aqa1QYj6ydlEww7+mV5b/ENnZEMkDtHErJg==
+"@opentripplanner/types@^6.1.1":
+ version "6.1.1"
+ resolved "https://registry.yarnpkg.com/@opentripplanner/types/-/types-6.1.1.tgz#ed28406d71b48d5299edc7ac884583d00917edc9"
+ integrity sha512-VNqWQI8hQfQQZQZFHrUbxGZzldNODMls3wXM9aawUJ7OJRjjmNOhkgTjohMcpvA3Ed3wUAkzOXByBQO3MTVH6Q==
"@opentripplanner/vehicle-rental-overlay@^2.1.2":
version "2.1.2"
From 56a230be2189b7f0867aa5ff1abdddebe85f36ed Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Wed, 13 Sep 2023 10:28:10 -0400
Subject: [PATCH 51/80] ci(percy): Remove --force-exit option for percy jest.
---
.github/workflows/percy.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/percy.yml b/.github/workflows/percy.yml
index 3f12e171a..2abae2be2 100644
--- a/.github/workflows/percy.yml
+++ b/.github/workflows/percy.yml
@@ -33,7 +33,7 @@ jobs:
YAML_CONFIG: /tmp/otp2config.yml
JS_CONFIG: ./percy/har-mock-config.js
- name: Take Percy Snapshots (Desktop + Mobile)
- run: npx percy exec -- npx jest percy/percy.test.js --force-exit
+ run: npx percy exec -- npx jest percy/percy.test.js
env:
PERCY_TOKEN: ${{ secrets.PERCY_TOKEN_OTP2 }}
OTP_RR_UI_MODE: normal
@@ -44,7 +44,7 @@ jobs:
YAML_CONFIG: /tmp/otp2config.yml
JS_CONFIG: ./percy/har-mock-config-call-taker.js
- name: Take Percy Snapshots (Calltaker)
- run: npx percy exec -- npx jest percy/percy.test.js --force-exit
+ run: npx percy exec -- npx jest percy/percy.test.js
env:
# Calltaker has a separate key because the calltaker-specific snapshots are different.
PERCY_TOKEN: ${{ secrets.PERCY_TOKEN_CALL_TAKER_OTP2 }}
From c192fed8b19ce60057514fa0cadb1090e110f611 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Wed, 13 Sep 2023 11:44:10 -0400
Subject: [PATCH 52/80] Revert "ci(percy): Remove --force-exit option for percy
jest."
This reverts commit 56a230be2189b7f0867aa5ff1abdddebe85f36ed.
---
.github/workflows/percy.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/percy.yml b/.github/workflows/percy.yml
index 2abae2be2..3f12e171a 100644
--- a/.github/workflows/percy.yml
+++ b/.github/workflows/percy.yml
@@ -33,7 +33,7 @@ jobs:
YAML_CONFIG: /tmp/otp2config.yml
JS_CONFIG: ./percy/har-mock-config.js
- name: Take Percy Snapshots (Desktop + Mobile)
- run: npx percy exec -- npx jest percy/percy.test.js
+ run: npx percy exec -- npx jest percy/percy.test.js --force-exit
env:
PERCY_TOKEN: ${{ secrets.PERCY_TOKEN_OTP2 }}
OTP_RR_UI_MODE: normal
@@ -44,7 +44,7 @@ jobs:
YAML_CONFIG: /tmp/otp2config.yml
JS_CONFIG: ./percy/har-mock-config-call-taker.js
- name: Take Percy Snapshots (Calltaker)
- run: npx percy exec -- npx jest percy/percy.test.js
+ run: npx percy exec -- npx jest percy/percy.test.js --force-exit
env:
# Calltaker has a separate key because the calltaker-specific snapshots are different.
PERCY_TOKEN: ${{ secrets.PERCY_TOKEN_CALL_TAKER_OTP2 }}
From 2a72f3483ef3bde220699ac920ea484fa0952c33 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Wed, 13 Sep 2023 11:46:04 -0400
Subject: [PATCH 53/80] test(percy): Use different UI port for calltaker vs
normal.
---
percy/percy.test.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/percy/percy.test.js b/percy/percy.test.js
index 5c2f07931..8dea1f8c1 100644
--- a/percy/percy.test.js
+++ b/percy/percy.test.js
@@ -7,7 +7,7 @@ const percySnapshot = require('@percy/puppeteer')
const { OTP_RR_UI_MODE } = process.env
-const MOCK_SERVER_PORT = 5486
+const MOCK_SERVER_PORT = OTP_RR_UI_MODE === 'calltaker' ? 5487 : 5486
// Puppeteer can take a long time to load, especially in some ci environments
jest.setTimeout(600000)
From 9ed9c561f23eeed24e6734771988ed103bac61fe Mon Sep 17 00:00:00 2001
From: miles-grant-ibigroup
Date: Wed, 13 Sep 2023 12:41:12 -0400
Subject: [PATCH 54/80] chore(deps): update otp-ui
---
package.json | 12 ++++-----
yarn.lock | 72 ++++++++++++++++++++++++++--------------------------
2 files changed, 42 insertions(+), 42 deletions(-)
diff --git a/package.json b/package.json
index 46e9ff69a..596d7a0e2 100644
--- a/package.json
+++ b/package.json
@@ -39,19 +39,19 @@
"@bugsnag/plugin-react": "^7.17.0",
"@floating-ui/react": "^0.19.2",
"@opentripplanner/base-map": "^3.0.14",
- "@opentripplanner/core-utils": "^11.0.2",
+ "@opentripplanner/core-utils": "^11.0.3",
"@opentripplanner/endpoints-overlay": "^2.0.8",
"@opentripplanner/from-to-location-picker": "^2.1.8",
"@opentripplanner/geocoder": "^1.4.2",
"@opentripplanner/humanize-distance": "^1.2.0",
"@opentripplanner/icons": "^2.0.5",
- "@opentripplanner/itinerary-body": "^5.0.5",
- "@opentripplanner/location-field": "^2.0.7",
+ "@opentripplanner/itinerary-body": "^5.0.6",
+ "@opentripplanner/location-field": "^2.0.8",
"@opentripplanner/location-icon": "^1.4.1",
"@opentripplanner/map-popup": "^2.0.5",
"@opentripplanner/otp2-tile-overlay": "^1.0.5",
- "@opentripplanner/printable-itinerary": "2.0.10-alpha.4",
"@opentripplanner/park-and-ride-overlay": "^2.0.6",
+ "@opentripplanner/printable-itinerary": "2.0.12",
"@opentripplanner/route-viewer-overlay": "^2.0.13",
"@opentripplanner/stop-viewer-overlay": "^2.0.6",
"@opentripplanner/stops-overlay": "^5.1.1",
@@ -132,7 +132,7 @@
"@craco/craco": "^6.3.0",
"@jackwilsdon/craco-use-babelrc": "^1.0.0",
"@opentripplanner/scripts": "^1.2.0",
- "@opentripplanner/types": "^6.1.0",
+ "@opentripplanner/types": "^6.1.1",
"@percy/cli": "^1.20.3",
"@percy/puppeteer": "^2.0.2",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.1",
@@ -240,4 +240,4 @@
"percy-css": ".percy-hide { opacity: 0!important; } "
}
}
-}
\ No newline at end of file
+}
diff --git a/yarn.lock b/yarn.lock
index d24a5c104..a5c8b7679 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2439,10 +2439,10 @@
lodash.isequal "^4.5.0"
qs "^6.9.1"
-"@opentripplanner/core-utils@^11.0.2":
- version "11.0.2"
- resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-11.0.2.tgz#ebfa939c3b7b266e3bf47dcaddda88e093430a9d"
- integrity sha512-3oQYvnhFHY88K61j2tUkU2fm8tDci5qaMVGEgqTzxpE5NmBTUdAWU1V7W9snJoRATzz3zy+K9qrtIhGjwbwlnA==
+"@opentripplanner/core-utils@^11.0.3":
+ version "11.0.3"
+ resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-11.0.3.tgz#b8aa21f81be420c07128e78c20a74d32d0034476"
+ integrity sha512-hTLZwU8YyokTA86tIa+iy46g0lqcjBX/HDxyzwxvbm6lFnUvUhHgWRPKvr8fzUA5aE0vYzwlj16WygQ43n4ubQ==
dependencies:
"@conveyal/lonlat" "^1.4.1"
"@mapbox/polyline" "^1.1.0"
@@ -2546,14 +2546,6 @@
resolved "https://registry.yarnpkg.com/@opentripplanner/humanize-distance/-/humanize-distance-1.2.0.tgz#71cf5d5d1b756adef15300edbba0995ccd4b35ee"
integrity sha512-x0QRXMDhypFeazZ6r6vzrdU8vhiV56nZ/WX6zUbxpgp6T9Oclw0gwR2Zdw6DZiiFpSYVNeVNxVzZwsu6NRGjcA==
-"@opentripplanner/icons@^2.0.1", "@opentripplanner/icons@^2.0.5":
- version "2.0.5"
- resolved "https://registry.yarnpkg.com/@opentripplanner/icons/-/icons-2.0.5.tgz#7274597e1d568b1d18861c36d9d4f77f4a6f82f3"
- integrity sha512-0QIXsoGHK8c5Y2rFwKKfsDFTIL6NXuvTUtKDNH6qybkMDPc+IovswCdFjKLDvgR+7pmE5iEmhTvNBHvw/MZjig==
- dependencies:
- "@opentripplanner/core-utils" "^9.0.2"
- prop-types "^15.7.2"
-
"@opentripplanner/icons@^2.0.3":
version "2.0.3"
resolved "https://registry.yarnpkg.com/@opentripplanner/icons/-/icons-2.0.3.tgz#c7c587f5b3b8ea050f50af3537e2e409d7258829"
@@ -2570,14 +2562,22 @@
"@opentripplanner/core-utils" "^9.0.0"
prop-types "^15.7.2"
-"@opentripplanner/itinerary-body@^4.2.0-alpha.3":
- version "4.2.0-alpha.4"
- resolved "https://registry.yarnpkg.com/@opentripplanner/itinerary-body/-/itinerary-body-4.2.0-alpha.4.tgz#407dcab1e74bab536c4818d11d39cdc2ca7f1e21"
- integrity sha512-zJX/Safz7ZKtW10T9aF5VIYDAhXR8pkD6EfdlHS42j+eiwlL2ISsjEHWZ8NxaqGPHpqFW2C3A8rOXcduFTLrTw==
+"@opentripplanner/icons@^2.0.5":
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/@opentripplanner/icons/-/icons-2.0.5.tgz#7274597e1d568b1d18861c36d9d4f77f4a6f82f3"
+ integrity sha512-0QIXsoGHK8c5Y2rFwKKfsDFTIL6NXuvTUtKDNH6qybkMDPc+IovswCdFjKLDvgR+7pmE5iEmhTvNBHvw/MZjig==
dependencies:
- "@opentripplanner/core-utils" "^8.2.1"
+ "@opentripplanner/core-utils" "^9.0.2"
+ prop-types "^15.7.2"
+
+"@opentripplanner/itinerary-body@^5.0.0":
+ version "5.0.5"
+ resolved "https://registry.yarnpkg.com/@opentripplanner/itinerary-body/-/itinerary-body-5.0.5.tgz#3038a910291e42d1a7ed3a03abcd8ecd32cd958e"
+ integrity sha512-58xn0cadRt7Vth8arjExZOt85KVESkqt9MKh2yqnMeXeSFMvP14/+jobgBRY+xsAh+EcLWPVBKq3ylas8npmEw==
+ dependencies:
+ "@opentripplanner/core-utils" "^9.0.2"
"@opentripplanner/humanize-distance" "^1.2.0"
- "@opentripplanner/icons" "^2.0.1"
+ "@opentripplanner/icons" "^2.0.4"
"@opentripplanner/location-icon" "^1.4.1"
"@styled-icons/fa-solid" "^10.34.0"
"@styled-icons/foundation" "^10.34.0"
@@ -2588,10 +2588,10 @@
react-resize-detector "^4.2.1"
string-similarity "^4.0.4"
-"@opentripplanner/itinerary-body@^5.0.0", "@opentripplanner/itinerary-body@^5.0.5":
- version "5.0.5"
- resolved "https://registry.yarnpkg.com/@opentripplanner/itinerary-body/-/itinerary-body-5.0.5.tgz#3038a910291e42d1a7ed3a03abcd8ecd32cd958e"
- integrity sha512-58xn0cadRt7Vth8arjExZOt85KVESkqt9MKh2yqnMeXeSFMvP14/+jobgBRY+xsAh+EcLWPVBKq3ylas8npmEw==
+"@opentripplanner/itinerary-body@^5.0.2", "@opentripplanner/itinerary-body@^5.0.6":
+ version "5.0.6"
+ resolved "https://registry.yarnpkg.com/@opentripplanner/itinerary-body/-/itinerary-body-5.0.6.tgz#33ad8c0dfa06702ed76ecbbd53974a1c0df8d21c"
+ integrity sha512-+9xDpo6HJrgOPyC2aOb6cw/Juimf0BBF9j3brSstJA9DIODp3cMsz39Iv35rETIory9R4wstEYFBwFzwE62I+g==
dependencies:
"@opentripplanner/core-utils" "^9.0.2"
"@opentripplanner/humanize-distance" "^1.2.0"
@@ -2606,10 +2606,10 @@
react-resize-detector "^4.2.1"
string-similarity "^4.0.4"
-"@opentripplanner/location-field@^2.0.7":
- version "2.0.7"
- resolved "https://registry.yarnpkg.com/@opentripplanner/location-field/-/location-field-2.0.7.tgz#a4479041c0c82d8f469076a47bc9874de2330efb"
- integrity sha512-yexAnUk4CEnxDhAzTmA4rR4xF7aw18THFhdstf6Z7TdceVUxUdIFJv3Pa6A4IjudURN947hi6euuY+qUU0TBqw==
+"@opentripplanner/location-field@^2.0.8":
+ version "2.0.8"
+ resolved "https://registry.yarnpkg.com/@opentripplanner/location-field/-/location-field-2.0.8.tgz#cf684a5dd902410378924b06434783f35c758c85"
+ integrity sha512-xmJJgdRsKBaiWSHdh8XDtyq+deuvn/QWgSh0Cab9/BlNlQGlodl1IF6j+faf+93zfmHbwXcl8ZZ/rdG1Z5fqLw==
dependencies:
"@conveyal/geocoder-arcgis-geojson" "^0.0.3"
"@opentripplanner/core-utils" "^9.0.2"
@@ -2662,13 +2662,13 @@
"@opentripplanner/base-map" "^3.0.13"
"@opentripplanner/from-to-location-picker" "^2.1.7"
-"@opentripplanner/printable-itinerary@2.0.10-alpha.4":
- version "2.0.10-alpha.4"
- resolved "https://registry.yarnpkg.com/@opentripplanner/printable-itinerary/-/printable-itinerary-2.0.10-alpha.4.tgz#c2debbb816346770e45968740b315d731858798c"
- integrity sha512-vL/KTy5IDiUzhIRTBoliIP+FDVUeaUqEkOiYJ0aCvir/mm+xX80wqERsb9Z9THIpKT5rjx9s5Y6mZNE3sbtB6Q==
+"@opentripplanner/printable-itinerary@2.0.12":
+ version "2.0.12"
+ resolved "https://registry.yarnpkg.com/@opentripplanner/printable-itinerary/-/printable-itinerary-2.0.12.tgz#1eb42d76e7a359660116bad77937ed3c4ccb2f26"
+ integrity sha512-gdlU5uDtcJioM1JqnA2USuvahYGpw6HolJEaCfyTMBT5PiChGf5dEX8tWV8F8c/YnlOyQJ/M3EMEtlN2iNxP5g==
dependencies:
- "@opentripplanner/core-utils" "^8.2.1"
- "@opentripplanner/itinerary-body" "^4.2.0-alpha.3"
+ "@opentripplanner/core-utils" "^9.0.2"
+ "@opentripplanner/itinerary-body" "^5.0.2"
"@opentripplanner/route-viewer-overlay@^2.0.13":
version "2.0.13"
@@ -2771,10 +2771,10 @@
"@opentripplanner/base-map" "^3.0.13"
"@opentripplanner/core-utils" "^9.0.0"
-"@opentripplanner/types@^6.1.0":
- version "6.1.0"
- resolved "https://registry.yarnpkg.com/@opentripplanner/types/-/types-6.1.0.tgz#dd5b88cc0b73939cd1eb5bd44d4768e21bedaacc"
- integrity sha512-fFuNMJLrSCIoIWJ7VugM1Jb7HfIcRDzb8o2LNsASExWAEYDuONFxyGYT/98g82/70Grl8kCSMSAFi0lEiQ/cPQ==
+"@opentripplanner/types@^6.1.1":
+ version "6.1.1"
+ resolved "https://registry.yarnpkg.com/@opentripplanner/types/-/types-6.1.1.tgz#ed28406d71b48d5299edc7ac884583d00917edc9"
+ integrity sha512-VNqWQI8hQfQQZQZFHrUbxGZzldNODMls3wXM9aawUJ7OJRjjmNOhkgTjohMcpvA3Ed3wUAkzOXByBQO3MTVH6Q==
"@opentripplanner/vehicle-rental-overlay@^2.1.2":
version "2.1.2"
From babf7e22be51f0e75421c63ae0909f4a7e42c542 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Wed, 13 Sep 2023 12:52:04 -0400
Subject: [PATCH 55/80] test(percy): Differentiate mobile snapshot names.
---
percy/percy.test.js | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/percy/percy.test.js b/percy/percy.test.js
index 8dea1f8c1..fcf9bd8cb 100644
--- a/percy/percy.test.js
+++ b/percy/percy.test.js
@@ -16,7 +16,11 @@ jest.setTimeout(600000)
const PERCY_EXTRA_WAIT = 5000
const percySnapshotWithWait = async (page, name, enableJavaScript) => {
await page.waitForTimeout(PERCY_EXTRA_WAIT)
- await percySnapshot(page, `${name} [${OTP_RR_UI_MODE}]`, { enableJavaScript })
+ await percySnapshot(
+ page,
+ `${name} [${OTP_RR_UI_MODE}${page.isMobile ? '/mobile' : ''}]`,
+ { enableJavaScript }
+ )
}
let browser
@@ -421,6 +425,7 @@ if (OTP_RR_UI_MODE !== 'calltaker') {
// Non-calltaker test runs both mobile and desktop test.
test('OTP-RR Mobile', async () => {
const page = await loadPath('/')
+ page.isMobile = true
await page.setUserAgent('android')
await page.setViewport({
height: 1134,
From d7f8c8c786fd200b2139fe3ddfac6522ad76390d Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Thu, 14 Sep 2023 09:35:23 -0400
Subject: [PATCH 56/80] ci(percy): Separate calltaker snapshots to a separate
job.
---
.github/workflows/percy.yml | 18 +++++++++++++++++-
percy/percy.test.js | 2 +-
2 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/percy.yml b/.github/workflows/percy.yml
index 3f12e171a..c5e878b72 100644
--- a/.github/workflows/percy.yml
+++ b/.github/workflows/percy.yml
@@ -10,7 +10,6 @@ on:
jobs:
run-pixel-tests:
runs-on: ubuntu-latest
-
steps:
- uses: actions/checkout@v2
with:
@@ -37,6 +36,23 @@ jobs:
env:
PERCY_TOKEN: ${{ secrets.PERCY_TOKEN_OTP2 }}
OTP_RR_UI_MODE: normal
+ run-pixel-tests-calltaker:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ # This allows us to work with the repository during the lint step
+ fetch-depth: 2
+ - name: Use Node.js 16.x
+ uses: actions/setup-node@v1
+ with:
+ node-version: 16.x
+ - name: Install npm packages using cache
+ uses: bahmutov/npm-install@v1
+ - name: Download OTP2 config file
+ run: curl $PERCY_OTP2_CONFIG_URL --output /tmp/otp2config.yml
+ env:
+ PERCY_OTP2_CONFIG_URL: ${{ secrets.PERCY_MOCK_OTP2_GEOCODER_CONFIG }}
- name: Build OTP-RR Calltaker
# Calltaker has a separate config file, so another build should be produced.
run: yarn build
diff --git a/percy/percy.test.js b/percy/percy.test.js
index fcf9bd8cb..24bedcc0a 100644
--- a/percy/percy.test.js
+++ b/percy/percy.test.js
@@ -7,7 +7,7 @@ const percySnapshot = require('@percy/puppeteer')
const { OTP_RR_UI_MODE } = process.env
-const MOCK_SERVER_PORT = OTP_RR_UI_MODE === 'calltaker' ? 5487 : 5486
+const MOCK_SERVER_PORT = 5486
// Puppeteer can take a long time to load, especially in some ci environments
jest.setTimeout(600000)
From c72cbc70eeb78434188d524794b78dd25c406370 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Thu, 14 Sep 2023 11:33:11 -0400
Subject: [PATCH 57/80] chore(i18n): Add transit suggestion after invalid mode
combination.
---
i18n/en-US.yml | 4 +++-
i18n/fr.yml | 4 +++-
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/i18n/en-US.yml b/i18n/en-US.yml
index 03d9611a4..1e94f00ad 100644
--- a/i18n/en-US.yml
+++ b/i18n/en-US.yml
@@ -227,7 +227,9 @@ components:
modeSelectorLabel: Select a transit mode
BatchSettings:
destination: destination
- invalidModeSelection: Cannot plan a trip using the selected modes.
+ invalidModeSelection: >-
+ Cannot plan a trip using the selected modes. Try including transit in your
+ mode selection.
origin: origin
planTripTooltip: Plan trip
validationMessage: "Please define the following fields to plan a trip: {issues}"
diff --git a/i18n/fr.yml b/i18n/fr.yml
index 326179282..515b81b79 100644
--- a/i18n/fr.yml
+++ b/i18n/fr.yml
@@ -238,7 +238,9 @@ components:
modeSelectorLabel: Sélectionnez un mode de transport
BatchSettings:
destination: destination
- invalidModeSelection: Impossible de planifier un trajet avec les modes sélectionnés.
+ invalidModeSelection: >-
+ Impossible de planifier un trajet avec les modes sélectionnés. Réessayez
+ en ajoutant les transports publics.
origin: point de départ
planTripTooltip: Planifier le trajet
validationMessage: >-
From 8a0e6c906d37de4c0a8359da6fde1f7d77544b44 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Thu, 14 Sep 2023 11:34:53 -0400
Subject: [PATCH 58/80] refactor(api-constants): Rename RoutingQueryResult =>
RoutingQueryCallResult per PR feedback
---
lib/actions/api-constants.ts | 2 +-
lib/actions/apiV2.js | 8 ++++----
lib/components/form/batch-settings.tsx | 4 ++--
3 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/lib/actions/api-constants.ts b/lib/actions/api-constants.ts
index b47743b9b..bfa917885 100644
--- a/lib/actions/api-constants.ts
+++ b/lib/actions/api-constants.ts
@@ -1,4 +1,4 @@
-export const RoutingQueryResult = {
+export const RoutingQueryCallResult = {
INVALID_MODE_SELECTION: 2,
INVALID_QUERY: 1,
SUCCESS: 0
diff --git a/lib/actions/apiV2.js b/lib/actions/apiV2.js
index 5c82ec36a..74d0e53d1 100644
--- a/lib/actions/apiV2.js
+++ b/lib/actions/apiV2.js
@@ -41,7 +41,7 @@ import {
updateOtpUrlParams
} from './api'
import { rememberPlace } from './user'
-import { RoutingQueryResult } from './api-constants'
+import { RoutingQueryCallResult } from './api-constants'
import { setItineraryView } from './ui'
import { zoomToPlace } from './map'
@@ -841,7 +841,7 @@ export function routingQuery(searchId = null, updateSearchInReducer) {
// Don't permit a routing query if the query is invalid
if (!queryIsValid(state)) {
console.warn('Query is invalid. Aborting routing query', currentQuery)
- return RoutingQueryResult.INVALID_QUERY
+ return RoutingQueryCallResult.INVALID_QUERY
}
const {
@@ -1010,8 +1010,8 @@ export function routingQuery(searchId = null, updateSearchInReducer) {
}
return combinations.length === 0
- ? RoutingQueryResult.INVALID_MODE_SELECTION
- : RoutingQueryResult.SUCCESS
+ ? RoutingQueryCallResult.INVALID_MODE_SELECTION
+ : RoutingQueryCallResult.SUCCESS
}
}
diff --git a/lib/components/form/batch-settings.tsx b/lib/components/form/batch-settings.tsx
index c005d05a1..15e3f95e8 100644
--- a/lib/components/form/batch-settings.tsx
+++ b/lib/components/form/batch-settings.tsx
@@ -26,7 +26,7 @@ import { ComponentContext } from '../../util/contexts'
import { generateModeSettingValues } from '../../util/api'
import { getActiveSearch, hasValidLocation } from '../../util/state'
import { getFormattedMode } from '../../util/i18n'
-import { RoutingQueryResult } from '../../actions/api-constants'
+import { RoutingQueryCallResult } from '../../actions/api-constants'
import { StyledIconWrapper } from '../util/styledIcon'
import {
@@ -169,7 +169,7 @@ function BatchSettings({
const routingQueryResult = routingQuery()
// If mode combination is not valid (i.e. produced no query), alert the user.
- if (routingQueryResult === RoutingQueryResult.INVALID_MODE_SELECTION) {
+ if (routingQueryResult === RoutingQueryCallResult.INVALID_MODE_SELECTION) {
window.alert(
intl.formatMessage({
id: 'components.BatchSettings.invalidModeSelection'
From e2c8d13f940a3ed64e46a8eb355f43df654ce986 Mon Sep 17 00:00:00 2001
From: Hosted Weblate
Date: Fri, 15 Sep 2023 15:25:15 +0200
Subject: [PATCH 59/80] Update translation files
Updated by "Cleanup translation files" hook in Weblate.
Translation: OTP-react-redux/OTP-RR Main UI
Translate-URL: https://hosted.weblate.org/projects/otp-react-redux/otp-rr-main-ui/
---
i18n/es.yml | 27 ++++++++++++++++-----------
1 file changed, 16 insertions(+), 11 deletions(-)
diff --git a/i18n/es.yml b/i18n/es.yml
index ab2d2ec11..2813583fa 100644
--- a/i18n/es.yml
+++ b/i18n/es.yml
@@ -30,7 +30,8 @@ actions:
No se puede guardar el plan: este plan no se pudo guardar debido a la
falta de capacidad en uno o más vehículos. Por favor, vuelva a planificar
su viaje.
- maxTripRequestsExceeded: Número de solicitudes de viaje superadas sin resultados válidos
+ maxTripRequestsExceeded: Número de solicitudes de viaje superadas sin resultados
+ válidos
saveItinerariesError: "No se pudieron guardar los itinerarios: {err}"
setDateError: "Error al establecer la fecha:"
setGroupSizeError: "No se pudo establecer el tamaño del grupo:"
@@ -46,9 +47,11 @@ actions:
authTokenError: Error al obtener un token de autorización.
confirmDeleteMonitoredTrip: ¿Desea eliminar este viaje?
confirmDeletePlace: ¿Quiere eliminar este lugar?
- emailVerificationResent: El mensaje de verificación de correo electrónico ha sido reenviado.
+ emailVerificationResent: El mensaje de verificación de correo electrónico ha sido
+ reenviado.
genericError: "Se ha encontrado un error: {err}"
- itineraryExistenceCheckFailed: Comprobación de errores para ver si el viaje seleccionado es posible.
+ itineraryExistenceCheckFailed: Comprobación de errores para ver si el viaje seleccionado
+ es posible.
preferencesSaved: Sus preferencias se han guardado.
smsInvalidCode: El código introducido no es válido. Por favor, inténtelo de nuevo.
smsResendThrottled: >-
@@ -230,7 +233,8 @@ components:
destination: destino
origin: origen
planTripTooltip: Planificar viaje
- validationMessage: "Por favor, defina los siguientes campos para planificar un viaje: {issues}"
+ validationMessage: "Por favor, defina los siguientes campos para planificar un
+ viaje: {issues}"
BeforeSignInScreen:
mainTitle: Iniciando sesión
message: >
@@ -359,11 +363,8 @@ components:
description: El contenido que ha solicitado no está disponible.
header: No se encontró el contenido
NotificationPrefsPane:
- description: Puede recibir notificaciones sobre los viajes que realiza con frecuencia.
noDeviceForPush: Regístrese con la aplicación móvil para acceder a esta configuración.
- noneSelect: No enviar notificaciones
notificationChannelPrompt: "Recibir notificaciones para sus viajes guardados por:"
- notificationEmailDetail: "Los correos electrónicos de notificación se enviarán a:"
PhoneNumberEditor:
changeNumber: Cambiar número de teléfono
invalidCode: Introduzca 6 dígitos para el código de validación.
@@ -493,7 +494,8 @@ components:
header: ¡La sesión está a punto de terminar!
keepSession: Continuar sesión
SimpleRealtimeAnnotation:
- usingRealtimeInfo: Este viaje utiliza información de tráfico y retrasos en tiempo real
+ usingRealtimeInfo: Este viaje utiliza información de tráfico y retrasos en tiempo
+ real
StackedPaneDisplay:
savePreferences: Guardar preferencias
StopScheduleTable:
@@ -556,16 +558,19 @@ components:
travelingAt: Viajando a {milesPerHour}
vehicleName: Vehículo {vehicleNumber}
TripBasicsPane:
- checkingItineraryExistence: Comprobación de la existencia de itinerarios para cada día de la semana…
+ checkingItineraryExistence: Comprobación de la existencia de itinerarios para
+ cada día de la semana…
selectAtLeastOneDay: Por favor, seleccione al menos un día para el seguimiento.
tripDaysPrompt: ¿Qué días hace este viaje?
- tripIsAvailableOnDaysIndicated: Su viaje está disponible en los días de la semana indicados anteriormente.
+ tripIsAvailableOnDaysIndicated: Su viaje está disponible en los días de la semana
+ indicados anteriormente.
tripNamePrompt: "Por favor, indique un nombre para este viaje:"
tripNotAvailableOnDay: El viaje no está disponible el {repeatedDay}
unsavedChangesExistingTrip: >-
Todavía no ha guardado su viaje. Si abandona la página, los cambios se
perderán.
- unsavedChangesNewTrip: Todavía no ha guardado su nuevo viaje. Si abandona la página, se perderá.
+ unsavedChangesNewTrip: Todavía no ha guardado su nuevo viaje. Si abandona la página,
+ se perderá.
TripNotificationsPane:
advancedSettings: Configuración avanzada
altRouteRecommended: Se recomienda una ruta alternativa o un punto de transferencia
From 2f475ebed1fdfdc13fee8e4be957ccca079ed8da Mon Sep 17 00:00:00 2001
From: Binh Dam
Date: Fri, 15 Sep 2023 13:32:18 +0000
Subject: [PATCH 60/80] Translated using Weblate (Spanish)
Currently translated at 99.6% (513 of 515 strings)
Translation: OTP-react-redux/OTP-RR Main UI
Translate-URL: https://hosted.weblate.org/projects/otp-react-redux/otp-rr-main-ui/es/
---
i18n/es.yml | 43 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/i18n/es.yml b/i18n/es.yml
index 2813583fa..a8624868d 100644
--- a/i18n/es.yml
+++ b/i18n/es.yml
@@ -40,6 +40,10 @@ actions:
location:
geolocationNotSupportedError: Su navegador no admite la geolocalización
unknownPositionError: Error desconocido al obtener la posición
+ userDeniedPermission: Usuario sin permiso
+ deniedAccessAlert: "El acceso a tu ubicación está bloqueado.\nPara utilizar tu
+ ubicación actual, activa los permisos de ubicación desde tu navegador y vuelve
+ a cargar la página. \n"
map:
currentLocation: (Ubicación actual)
user:
@@ -113,6 +117,7 @@ common:
{co2} de CO₂ en {isMore, select, true {más} other {menos} } que conducir
solo
transfers: "{transfers, plural, =0 {} one {# transferencia} other {# transferencias}}"
+ fareUnknown: No hay información de las tarifas
linkOpensNewWindow: (Abre una nueva ventana)
modes:
bicycle_rent: Compartir bicicleta
@@ -174,6 +179,8 @@ components:
AdvancedOptions:
bannedRoutes: Seleccionar rutas prohibidas…
preferredRoutes: Seleccionar rutas preferidas…
+ bikeTolerance: Tolerancia de las bicicletas
+ walkTolerance: Tolerancia al andar
AfterSignInScreen:
mainTitle: Redirigiendo…
message: >-
@@ -229,6 +236,7 @@ components:
shortTitle: Planificar viaje
BatchSearchScreen:
header: Planifique su viaje
+ modeSelectorLabel: Seleccione un modo de transporte
BatchSettings:
destination: destino
origin: origen
@@ -730,6 +738,41 @@ components:
switcher: Botón de cambio
WelcomeScreen:
prompt: ¿A donde quiere ir?
+ OTP2ErrorRenderer:
+ SYSTEM_ERROR:
+ header: Error en el planificador de los viajes
+ body: Se ha producido un error desconocido en la búsqueda.
+ LOCATION_NOT_FOUND:
+ body: '{inputFieldsCount, plural, =0 {} one {localización es} other {localizaciones
+ son}} no están cerca de ninguna calle.'
+ header: No se puede acceder a la ubicación
+ NO_STOPS_IN_RANGE:
+ header: Sin paradas cerca
+ body: '{inputFieldsCount, plural, =0 {} one {ubicación es} other {ubicaciones
+ son}} no están cerca de ninguna parada del transporte.'
+ NO_TRANSIT_CONNECTION:
+ body: No se encontró ninguna conexión entre tu origen y destino en el día seleccionado,
+ utilizando los tipos de vehículos que seleccionaste.
+ header: Sin conexiones
+ inputFields:
+ FROM: Procedencia
+ TO: Destino
+ WALKING_BETTER_THAN_TRANSIT:
+ body: Puede completar esta ruta más rápido caminando.
+ header: El transporte público no es la forma más rápida de hacer este viaje
+ OUTSIDE_SERVICE_PERIOD:
+ header: Fuera de plazo
+ body: La fecha específicada está fuera del rango de los datos disponibles para
+ la búsqueda de los viajes.
+ OUTSIDE_BOUNDS:
+ header: Ubicación fuera de los límites
+ body: '{inputFieldsCount, plural, =0 {} one {localización es} other {localizaciones
+ son}} no están en los límites del planificador de viajes.'
+ NO_TRANSIT_CONNECTION_IN_SEARCH_WINDOW:
+ body: Se encontró una conexión, pero estaba fuera de las opciones de la búsqueda,
+ intenta ajustar las opciones de la búsqueda, usando los tipos de vehículos
+ que seleccionaste.
+ header: Sin conexiones por el criterio de la búsqueda
config:
accessModes:
bicycle: Tránsito + Bicicleta Personal
From 25be009b7551134c1e191ab4d4fdbfe6e2a84b99 Mon Sep 17 00:00:00 2001
From: Binh Dam
Date: Fri, 15 Sep 2023 13:49:22 +0000
Subject: [PATCH 61/80] Translated using Weblate (French)
Currently translated at 98.2% (506 of 515 strings)
Translation: OTP-react-redux/OTP-RR Main UI
Translate-URL: https://hosted.weblate.org/projects/otp-react-redux/otp-rr-main-ui/fr/
---
i18n/fr.yml | 32 ++++++++++++++++++++------------
1 file changed, 20 insertions(+), 12 deletions(-)
diff --git a/i18n/fr.yml b/i18n/fr.yml
index 3ad6429bc..dfce0604c 100644
--- a/i18n/fr.yml
+++ b/i18n/fr.yml
@@ -2,7 +2,8 @@ _id: fr
_name: Exemple de traduction pour OTP-react-redux en français
actions:
callTaker:
- callQuerySaveError: "Erreur lors de l'enregistrement des requêtes pour l'appel : {err}"
+ callQuerySaveError: "Erreur lors de l'enregistrement des requêtes pour l'appel
+ : {err}"
callSaveError: "Impossible d'enregistrer l'appel : {err}"
checkSessionError: "Erreur durant la session d'authentification : {err}"
couldNotFindCallError: >-
@@ -17,9 +18,11 @@ actions:
true {aller}
other {retour}
} planifié préalablement pour cette demande. Voulez-vous continuer ?
- deleteItinerariesError: "Erreur lors de la suppression du trajet pour le groupe :"
+ deleteItinerariesError: "Erreur lors de la suppression du trajet pour le groupe
+ :"
deleteNoteError: "Erreur lors de la suppression d'une note sur le groupe :"
- editSubmitterNotesError: "Erreur lors de la modification des notes du demandeur :"
+ editSubmitterNotesError: "Erreur lors de la modification des notes du demandeur
+ :"
fetchFieldTripError: "Erreur de chargement du groupe scolaire : {err}"
fetchFieldTripsError: "Erreur lors du chargement des groupes scolaires : {err}"
fetchTripsForDateError: >-
@@ -43,7 +46,8 @@ actions:
Pour utiliser votre emplacement actuel, permettez-en l'accès depuis votre
navigateur, et ouvrez de nouveau cette page.
- geolocationNotSupportedError: La géolocalisation n'est pas prise en charge par votre navigateur.
+ geolocationNotSupportedError: La géolocalisation n'est pas prise en charge par
+ votre navigateur.
unknownPositionError: Erreur inconnue lors de la détection de votre emplacement.
userDeniedPermission: Refusé par l'utilisateur
map:
@@ -57,7 +61,8 @@ actions:
Le message de vérification de votre adresse e-mail a été envoyé de
nouveau.
genericError: "Une erreur s'est produite : {err}"
- itineraryExistenceCheckFailed: Erreur lors de la vérification de la validité du trajet choisi.
+ itineraryExistenceCheckFailed: Erreur lors de la vérification de la validité du
+ trajet choisi.
preferencesSaved: Vos préférences ont été enregistrées.
smsInvalidCode: Le code saisi est incorrect. Veuillez réessayer.
smsResendThrottled: >-
@@ -346,8 +351,10 @@ components:
header: Options de recherche
NarrativeItinerariesHeader:
changeSortDir: Changer l'ordre de tri
- howToFindResults: Pour afficher les résultats, utilisez l'en-tête Trajets trouvés plus bas.
- itinerariesFound: "{itineraryNum, plural, one {# trajet trouvé} other {# trajets trouvés} }"
+ howToFindResults: Pour afficher les résultats, utilisez l'en-tête Trajets trouvés
+ plus bas.
+ itinerariesFound: "{itineraryNum, plural, one {# trajet trouvé} other {# trajets
+ trouvés} }"
numIssues: "{issueNum, plural, one {# problème} other {# problèmes} }"
resultsSortedBy: >-
Résultats triés par {sortSelected}. Pour modifier l'ordre, utilisez le
@@ -414,9 +421,8 @@ components:
header: Echec de la recherche
WALKING_BETTER_THAN_TRANSIT:
body: >-
- Vous pouvez effectuer ce trajet plus rapidement en évitant les
- transports.
- header: Transports moins rapides
+ Vous pouvez effectuer ce trajet plus rapidement sans prendre les transports.
+ header: Moins rapide en transports
inputFields:
FROM: point de départ
TO: destination
@@ -660,7 +666,8 @@ components:
unknownState: État du trajet inconnu
untogglePause: Reprendre
inactive:
- description: Reprenez le suivi pour obtenir des dernières conditions de votre trajet.
+ description: Reprenez le suivi pour obtenir des dernières conditions de votre
+ trajet.
heading: Suivi suspendu
nextTripNotPossible:
description: >
@@ -679,7 +686,8 @@ components:
déterminées.
heading: Conditions du trajet indéterminées
snoozed:
- description: Reprenez le suivi pour obtenir des dernières conditions de votre trajet.
+ description: Reprenez le suivi pour obtenir des dernières conditions de votre
+ trajet.
heading: Suivi suspendu jusqu'à demain
upcoming:
nextTripBegins: >-
From 3afe67afa809b852148b41756df448164b425f65 Mon Sep 17 00:00:00 2001
From: miles-grant-ibigroup
Date: Fri, 15 Sep 2023 14:26:24 -0400
Subject: [PATCH 62/80] update caniuse db
---
yarn.lock | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/yarn.lock b/yarn.lock
index a5c8b7679..071239597 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5711,9 +5711,9 @@ caniuse-api@^3.0.0:
lodash.uniq "^4.5.0"
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001125, caniuse-lite@^1.0.30001251:
- version "1.0.30001465"
- resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001465.tgz"
- integrity sha512-HvjgL3MYAJjceTDCcjRnQGjwUz/5qec9n7JPOzUursUoOTIsYCSDOb1l7RsnZE8mjbxG78zVRCKfrBXyvChBag==
+ version "1.0.30001534"
+ resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001534.tgz"
+ integrity sha512-vlPVrhsCS7XaSh2VvWluIQEzVhefrUQcEsQWSS5A5V+dM07uv1qHeQzAOTGIMy9i3e9bH15+muvI/UHojVgS/Q==
capture-exit@^2.0.0:
version "2.0.0"
From 00426d037afcb19b727a8c7c2088905a43708178 Mon Sep 17 00:00:00 2001
From: miles-grant-ibigroup
Date: Fri, 15 Sep 2023 14:27:35 -0400
Subject: [PATCH 63/80] address pr feedback
---
lib/components/viewers/trip-viewer.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/components/viewers/trip-viewer.js b/lib/components/viewers/trip-viewer.js
index 0c4991977..b76db43e1 100644
--- a/lib/components/viewers/trip-viewer.js
+++ b/lib/components/viewers/trip-viewer.js
@@ -140,7 +140,7 @@ class TripViewer extends Component {
screenreader or keyboard nav, the departure, arrival, and stop viewer links
are all accessible without having to go through all the stops not on the trip. */}
- {fromIndex && (
+ {fromIndex > -1 && (
Date: Fri, 15 Sep 2023 17:34:35 -0400
Subject: [PATCH 64/80] fix(actions/ui): Hide nearby stops outside Stop Viewer.
---
lib/actions/ui.js | 2 ++
1 file changed, 2 insertions(+)
diff --git a/lib/actions/ui.js b/lib/actions/ui.js
index 43cf75b58..9ea85829e 100644
--- a/lib/actions/ui.js
+++ b/lib/actions/ui.js
@@ -189,6 +189,7 @@ export function matchContentToUrl(map, location) {
const id = match?.params?.id
switch (root) {
case 'route':
+ dispatch(setViewedStop(null))
if (id) {
await dispatch(findRoutesIfNeeded())
dispatch(findRouteIfNeeded({ routeId: id }))
@@ -223,6 +224,7 @@ export function matchContentToUrl(map, location) {
}
break
case 'trip':
+ dispatch(setViewedStop(null))
if (id) {
dispatch(setViewedTrip({ tripId: id }))
dispatch(setMainPanelContent(MainPanelContent.TRIP_VIEWER))
From 0fb4a91396f545c21c8a2c5129ab62e3279f5bc5 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Mon, 18 Sep 2023 17:47:37 -0400
Subject: [PATCH 65/80] fix(enhanced-stop-marker): Remove duplicate stop
popups.
---
lib/components/map/enhanced-stop-marker.js | 35 ++++++++++++++--------
1 file changed, 22 insertions(+), 13 deletions(-)
diff --git a/lib/components/map/enhanced-stop-marker.js b/lib/components/map/enhanced-stop-marker.js
index ad5d7fa4f..3e0dd8668 100644
--- a/lib/components/map/enhanced-stop-marker.js
+++ b/lib/components/map/enhanced-stop-marker.js
@@ -81,6 +81,18 @@ class EnhancedStopMarker extends Component {
this.setLocation('to')
}
+ onMarkerClick = (e) => {
+ // Make a copy because getElementsByClassName returns a live collection.
+ const elements = Array.from(
+ document.getElementsByClassName('maplibregl-popup-close-button')
+ )
+ elements.forEach((el) => {
+ if (el.parentElement.firstChild.firstChild.id !== 'enh-stop-popup') {
+ el.click()
+ }
+ })
+ }
+
setLocation(locationType) {
const { setLocation, stop } = this.props
const { lat, lon, name } = stop
@@ -108,22 +120,11 @@ class EnhancedStopMarker extends Component {
const { ModeIcon } = this.context
const stopIcon = mode ? :
- const icon = (
-
- {stopIcon}
-
- )
-
return (
+
)
}
From e33413aeb46b97113522fb9380e78c83d9355747 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Mon, 18 Sep 2023 18:02:09 -0400
Subject: [PATCH 66/80] refactor(enhanced-stop-marker): Extract constants and
add comment about the duplicate popup fix.
---
lib/components/map/enhanced-stop-marker.js | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/lib/components/map/enhanced-stop-marker.js b/lib/components/map/enhanced-stop-marker.js
index 3e0dd8668..7e3a99a72 100644
--- a/lib/components/map/enhanced-stop-marker.js
+++ b/lib/components/map/enhanced-stop-marker.js
@@ -65,6 +65,8 @@ const BaseStopIcon = styled.div`
}
`
+const activeContentId = 'enh-stop-popup'
+
class EnhancedStopMarker extends Component {
static contextType = ComponentContext
@@ -86,8 +88,14 @@ class EnhancedStopMarker extends Component {
const elements = Array.from(
document.getElementsByClassName('maplibregl-popup-close-button')
)
+ // HACK: If an OTP2 tile stop is right underneath the marker, the tile event handler in OTP-UI
+ // will fire before this one, and the popup from the regular stop layer will appear
+ // (even if we render the StopViewerOverlay after the OTP2 overlays in DefaultMap),
+ // so there will be two (duplicate) stop popups.
+ // We want to show the popup for the enhanced marker instead of the one from the tile handler
+ // because the stop marker has a much larger UI surface than the circle from the tile layer.
elements.forEach((el) => {
- if (el.parentElement.firstChild.firstChild.id !== 'enh-stop-popup') {
+ if (el.parentElement.firstChild.firstChild.id !== activeContentId) {
el.click()
}
})
@@ -124,7 +132,7 @@ class EnhancedStopMarker extends Component {