From 4968d66a026a19d9efc87f02a784bf8d8f306dfb Mon Sep 17 00:00:00 2001 From: miles-grant-ibigroup Date: Wed, 11 Oct 2023 11:29:16 -0400 Subject: [PATCH 01/15] refactor: route viewer always use route color overrides --- lib/actions/apiV2.js | 53 +++++++++++++++++++++++++------------------- lib/util/viewer.js | 2 +- 2 files changed, 31 insertions(+), 24 deletions(-) diff --git a/lib/actions/apiV2.js b/lib/actions/apiV2.js index ae64d539c..544f5aec5 100644 --- a/lib/actions/apiV2.js +++ b/lib/actions/apiV2.js @@ -12,8 +12,13 @@ import { generateModeSettingValues } from '../util/api' import { getActiveItineraries, getActiveItinerary, + getRouteOperator, queryIsValid } from '../util/state' +import { + getColorAndNameFromRoute, + getRouteColorBasedOnSettings +} from '../util/viewer' import { ItineraryView } from '../util/ui' import { @@ -669,6 +674,10 @@ export const findRoute = (params) => newRoute.patterns = routePatterns // TODO: avoid explicit behavior shift like this newRoute.v2 = true + newRoute.color = getColorAndNameFromRoute( + getRouteOperator(route, getState().otp.config.transitOperators), + route + ).backgroundColor.split('#')[1] newRoute.mode = checkForRouteModeOverride( newRoute, getState().otp.config?.routeModeOverrides @@ -716,29 +725,27 @@ export function findRoutes() { const { config } = getState().otp // To initialize the route viewer, // convert the routes array to a dictionary indexed by route ids. - return routes.reduce( - ( - result, - { agency, color, id, longName, mode, shortName, type } - ) => { - result[id] = { - agencyId: agency.id, - agencyName: agency.name, - color, - id, - longName, - mode: checkForRouteModeOverride( - { id, mode }, - config?.routeModeOverrides - ), - shortName, - type, - v2: true - } - return result - }, - {} - ) + return routes.reduce((result, route) => { + const { agency, id, longName, mode, shortName, type } = route + result[id] = { + agencyId: agency.id, + agencyName: agency.name, + color: getColorAndNameFromRoute( + getRouteOperator(route, config.transitOperators), + route + ).backgroundColor.split('#')[1], + id, + longName, + mode: checkForRouteModeOverride( + { id, mode }, + config?.routeModeOverrides + ), + shortName, + type, + v2: true + } + return result + }, {}) } } ) diff --git a/lib/util/viewer.js b/lib/util/viewer.js index 9f1f9ef9d..b2e9df92e 100644 --- a/lib/util/viewer.js +++ b/lib/util/viewer.js @@ -383,7 +383,7 @@ export function getColorAndNameFromRoute(operator, route) { const modeColors = operator?.modeColors?.[getModeFromRoute(route)] const backgroundColor = `#${ - modeColors?.color || defaultRouteColor || route.color || '333333' + modeColors?.color || defaultRouteColor || route?.color || '333333' }` // NOTE: text color is not a part of short response route object, so there // is no way to determine from OTP what the text color should be if the From bbf852217a715dee506ed0a73a3adaade1911224 Mon Sep 17 00:00:00 2001 From: miles-grant-ibigroup Date: Wed, 11 Oct 2023 11:35:43 -0400 Subject: [PATCH 02/15] use cleaner method --- lib/actions/apiV2.js | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/lib/actions/apiV2.js b/lib/actions/apiV2.js index 544f5aec5..15644d947 100644 --- a/lib/actions/apiV2.js +++ b/lib/actions/apiV2.js @@ -15,10 +15,7 @@ import { getRouteOperator, queryIsValid } from '../util/state' -import { - getColorAndNameFromRoute, - getRouteColorBasedOnSettings -} from '../util/viewer' +import { getRouteColorBasedOnSettings } from '../util/viewer' import { ItineraryView } from '../util/ui' import { @@ -674,10 +671,10 @@ export const findRoute = (params) => newRoute.patterns = routePatterns // TODO: avoid explicit behavior shift like this newRoute.v2 = true - newRoute.color = getColorAndNameFromRoute( + newRoute.color = getRouteColorBasedOnSettings( getRouteOperator(route, getState().otp.config.transitOperators), route - ).backgroundColor.split('#')[1] + ).split('#')[1] newRoute.mode = checkForRouteModeOverride( newRoute, getState().otp.config?.routeModeOverrides @@ -730,10 +727,10 @@ export function findRoutes() { result[id] = { agencyId: agency.id, agencyName: agency.name, - color: getColorAndNameFromRoute( + color: getRouteColorBasedOnSettings( getRouteOperator(route, config.transitOperators), route - ).backgroundColor.split('#')[1], + ).split('#')[1], id, longName, mode: checkForRouteModeOverride( From 6f97b7701ab9bcfaf33eec4b3081bb747ce05d2a Mon Sep 17 00:00:00 2001 From: miles-grant-ibigroup Date: Wed, 11 Oct 2023 15:16:42 -0400 Subject: [PATCH 03/15] refactor: use getRouteColorBasedOnSettings in itinerary result --- lib/actions/apiV2.js | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/lib/actions/apiV2.js b/lib/actions/apiV2.js index 15644d947..318c77eb6 100644 --- a/lib/actions/apiV2.js +++ b/lib/actions/apiV2.js @@ -927,7 +927,26 @@ export function routingQuery(searchId = null, updateSearchInReducer) { const withCollapsedShortNames = response.data?.plan?.itineraries?.map((itin) => ({ ...itin, - legs: itin.legs?.map(convertGraphQLResponseToLegacy) + legs: itin.legs + ?.map((leg) => { + return { + ...leg, + route: { + ...leg.route, + color: getRouteColorBasedOnSettings( + getRouteOperator( + { + agencyId: leg?.agency?.id, + id: leg?.route?.id + }, + config.transitOperators + ), + { color: leg?.route?.color, mode: leg.mode } + ).split('#')?.[1] + } + } + }) + ?.map(convertGraphQLResponseToLegacy) })) /* It is possible for a NO_TRANSIT_CONNECTION error to be From acafa1c3ba9b0625fa7a659199c70afeee588e2b Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Thu, 19 Oct 2023 11:30:40 -0400 Subject: [PATCH 04/15] fix(nav-login-button-auth0): Request the correct Chinese language variant to Auth0. --- lib/components/user/nav-login-button-auth0.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/components/user/nav-login-button-auth0.tsx b/lib/components/user/nav-login-button-auth0.tsx index cdc60bf44..e4a44bf14 100644 --- a/lib/components/user/nav-login-button-auth0.tsx +++ b/lib/components/user/nav-login-button-auth0.tsx @@ -28,14 +28,18 @@ const NavLoginButtonAuth0 = ({ }: NavLoginButtonAuth0Props): JSX.Element => { const { isAuthenticated, loginWithRedirect, logout, user } = useAuth0() + // For Chinese (Chinese (Simplified)), we must pass 'zh-CN' to auth0. + // Unlike 'fr', 'zh' alone is not recognized and falls back to English. + const auth0Locale = locale === 'zh' ? 'zh-CN' : locale + // On login, preserve the current trip query if any. const handleLogin = useCallback( () => loginWithRedirect({ appState: { returnTo: getCurrentRoute() }, - ui_locales: locale + ui_locales: auth0Locale }), - [locale, loginWithRedirect] + [auth0Locale, loginWithRedirect] ) const handleLogout = useCallback( () => From 7e965328d1511b7cc76c83c5ac81d22e6d3f57b0 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Tue, 17 Oct 2023 16:58:11 -0400 Subject: [PATCH 05/15] fix(trip-tools): Localize header. --- i18n/en-US.yml | 1 + i18n/es.yml | 7 ++++--- i18n/fr.yml | 1 + i18n/ko.yml | 1 + i18n/vi.yml | 1 + i18n/zh.yml | 1 + lib/components/narrative/trip-tools.js | 9 ++++----- 7 files changed, 13 insertions(+), 8 deletions(-) diff --git a/i18n/en-US.yml b/i18n/en-US.yml index 32c9b46f1..eafbba0db 100644 --- a/i18n/en-US.yml +++ b/i18n/en-US.yml @@ -677,6 +677,7 @@ components: notificationsDisabled: "Notifications: Disabled" TripTools: copyLink: Copy Link + header: Trip Tools linkCopied: Copied reportEmailSubject: Reporting an Issue with OpenTripPlanner reportEmailTemplate: > diff --git a/i18n/es.yml b/i18n/es.yml index 4df1c29df..0cce495b2 100644 --- a/i18n/es.yml +++ b/i18n/es.yml @@ -55,6 +55,8 @@ actions: 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. + mustBeLoggedInToSavePlace: Por favor, inicia la sesión para guardar las ubicaciones. + placeRemembered: La configuración de este lugar se ha guardado. preferencesSaved: Sus preferencias se han guardado. smsInvalidCode: El código introducido no es válido. Por favor, inténtelo de nuevo. smsResendThrottled: >- @@ -63,8 +65,6 @@ actions: smsVerificationFailed: >- Su teléfono no ha podido ser verificado. Quizás el código que has introducido ha caducado. Solicita un nuevo código e inténtalo de nuevo. - mustBeLoggedInToSavePlace: Por favor, inicia la sesión para guardar las ubicaciones. - placeRemembered: La configuración de este lugar se ha guardado. common: coordinates: "{lat}; {lon}" dateExpressions: @@ -487,11 +487,11 @@ components: tripsFound: Encontramos {count, plural, one {# opción} other {# opciones}} waiting: Espera... RouteDetails: + headsignTo: "{headsign} ({lastStop})" moreDetails: Más detalles operatedBy: Servicio operado por {agencyName} selectADirection: Seleccione una dirección… stopsTo: Hacia - headsignTo: '{headsign} ({lastStop})' RouteViewer: agencyFilter: Filtro de agencia allAgencies: Todas las agencias @@ -703,6 +703,7 @@ components: notificationsDisabled: "Notificaciones: Disabled" TripTools: copyLink: Copiar enlace + header: Herramientas linkCopied: Copiado reportEmailSubject: Informar un problema con OpenTripPlanner reportEmailTemplate: > diff --git a/i18n/fr.yml b/i18n/fr.yml index 6e7c7d6ba..1ef6fd89a 100644 --- a/i18n/fr.yml +++ b/i18n/fr.yml @@ -703,6 +703,7 @@ components: notificationsDisabled: "Notifications : Désactivées" TripTools: copyLink: Copier le lien + header: Outils linkCopied: Copié reportEmailSubject: Signaler un problème avec OpenTripPlanner reportEmailTemplate: > diff --git a/i18n/ko.yml b/i18n/ko.yml index c36644127..e04f7e8f2 100644 --- a/i18n/ko.yml +++ b/i18n/ko.yml @@ -561,6 +561,7 @@ components: notificationsDisabled: "알림: 비활성화됨" TripTools: copyLink: 링크 복사 + header: 도구 linkCopied: 복사됨 reportEmailSubject: OpenTripPlanner로 문제 보고 reportEmailTemplate: | diff --git a/i18n/vi.yml b/i18n/vi.yml index e31f08271..471a3e7cb 100644 --- a/i18n/vi.yml +++ b/i18n/vi.yml @@ -602,6 +602,7 @@ components: notificationsDisabled: "Thông báo: Đã tắt" TripTools: copyLink: Sao chép URL + header: Công cụ linkCopied: Đã sao chép reportEmailSubject: Báo cáo sự cố với OpenTripPlanner reportEmailTemplate: | diff --git a/i18n/zh.yml b/i18n/zh.yml index 021e91a97..99ec4cacb 100644 --- a/i18n/zh.yml +++ b/i18n/zh.yml @@ -559,6 +559,7 @@ components: notificationsDisabled: "通知: 已禁用" TripTools: copyLink: 复制链接 + header: 工具 linkCopied: 已复制 reportEmailSubject: 报告OpenTripPlanner的问题 reportEmailTemplate: | diff --git a/lib/components/narrative/trip-tools.js b/lib/components/narrative/trip-tools.js index 449e63f3c..ecd3518bc 100644 --- a/lib/components/narrative/trip-tools.js +++ b/lib/components/narrative/trip-tools.js @@ -185,7 +185,6 @@ LinkButton.propTypes = { const TripTools = ({ buttonTypes, - intl, location, popupTarget, reactRouterConfig, @@ -224,7 +223,6 @@ const TripTools = ({ location?.search ) buttonComponents.push( - // FIXME: The Spanish string does not fit in button width. } @@ -250,7 +248,9 @@ const TripTools = ({ return (
-

Trip Tools

+

+ +

{buttonComponents.map((btn, i) => (
@@ -264,7 +264,6 @@ const TripTools = ({ TripTools.propTypes = { buttonTypes: PropTypes.arrayOf(PropTypes.string), - intl: PropTypes.object, location: PropTypes.object, popupTarget: PropTypes.string, reactRouterConfig: PropTypes.object, @@ -290,5 +289,5 @@ const mapDispatchToProps = { } export default withRouter( - connect(mapStateToProps, mapDispatchToProps)(injectIntl(TripTools)) + connect(mapStateToProps, mapDispatchToProps)(TripTools) ) From dde52e43e118aac7c9ae46bf99b7a78e1819d388 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Fri, 22 Sep 2023 15:28:35 -0400 Subject: [PATCH 06/15] perf(state): Don't include calltaker state or reducer if not config-enabled. --- lib/reducers/call-taker.js | 14 ++++++++++---- lib/util/state.js | 4 ++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/reducers/call-taker.js b/lib/reducers/call-taker.js index 202bc22c0..9953484ef 100644 --- a/lib/reducers/call-taker.js +++ b/lib/reducers/call-taker.js @@ -6,11 +6,17 @@ import { FETCH_STATUS } from '../util/constants' import { getISOLikeTimestamp } from '../util/state' import { getModuleConfig, Modules } from '../util/config' +function getCalltakerConfig(config) { + return getModuleConfig({ otp: { config } }, Modules.CALL_TAKER) +} + function createCallTakerReducer(config) { - const calltakerConfig = getModuleConfig( - { otp: { config } }, - Modules.CALL_TAKER - ) + const calltakerConfig = getCalltakerConfig(config) + if (!calltakerConfig) { + // Don't include the calltaker reducer at all if calltaker is not enabled in config. + return undefined + } + const initialState = { activeCall: null, callHistory: { diff --git a/lib/util/state.js b/lib/util/state.js index c25b0b615..dee8fd604 100644 --- a/lib/util/state.js +++ b/lib/util/state.js @@ -245,8 +245,8 @@ function getActiveSearchRealtimeResponse(state) { * https://decembersoft.com/posts/error-selector-creators-expect-all-input-selectors-to-be-functions/ */ export const getActiveFieldTripRequest = createSelector( - (state) => state.callTaker?.fieldTrip.activeId, - (state) => state.callTaker?.fieldTrip.requests, + (state) => state.callTaker?.fieldTrip?.activeId, + (state) => state.callTaker?.fieldTrip?.requests, (activeId, requests) => { if (!activeId || !requests) return return requests.data.find((req) => req.id === activeId) From 6301c915dee4cae040281ade39c29fe937e0138c Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Fri, 22 Sep 2023 16:03:30 -0400 Subject: [PATCH 07/15] refactor(app): Remove unneeded calltaker config. --- lib/app.js | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/lib/app.js b/lib/app.js index 4ea733227..b56facafa 100644 --- a/lib/app.js +++ b/lib/app.js @@ -21,12 +21,7 @@ import { BatchResultsScreen, BatchRoutingPanel, BatchSearchScreen, - CallHistoryWindow, - CallTakerControls, - CallTakerPanel, DefaultItinerary, - FieldTripWindows, - MailablesWindow, ResponsiveWebapp } from './index' @@ -178,17 +173,7 @@ const components = { ItineraryBody: DefaultItinerary, - MainControls: isCallTakerModuleEnabled ? CallTakerControls : null, - - MainPanel: isCallTakerModuleEnabled ? CallTakerPanel : BatchRoutingPanel, - - MapWindows: isCallTakerModuleEnabled ? ( - <> - - - - - ) : null, + MainPanel: BatchRoutingPanel, MobileResultsScreen: BatchResultsScreen, From face9d645fe96b4cf7fb6d9d99cdb76a03066a32 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Fri, 22 Sep 2023 16:32:03 -0400 Subject: [PATCH 08/15] perf(index): Remove calltaker components from index --- lib/index.js | 12 ------------ percy/har-mock-config-call-taker.js | 10 ++++++---- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/lib/index.js b/lib/index.js index 9b8180f8a..f7d142a80 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,9 +1,5 @@ /* eslint-disable prettier/prettier */ /* eslint-disable sort-imports-es6-autofix/sort-imports-es6 */ -import CallTakerControls from './components/admin/call-taker-controls' -import CallHistoryWindow from './components/admin/call-history-window' -import FieldTripWindows from './components/admin/field-trip-windows' -import MailablesWindow from './components/admin/mailables-window' import DateTimeModal from './components/form/date-time-modal' import DateTimePreview from './components/form/date-time-preview' import ErrorMessage from './components/form/error-message' @@ -29,7 +25,6 @@ import ViewStopButton from './components/viewers/view-stop-button' import ViewerContainer from './components/viewers/viewer-container' import ResponsiveWebapp from './components/app/responsive-webapp' import AppMenu from './components/app/app-menu' -import CallTakerPanel from './components/app/call-taker-panel' import DesktopNav from './components/app/desktop-nav' import BatchRoutingPanel from './components/app/batch-routing-panel' import BatchResultsScreen from './components/mobile/batch-results-screen' @@ -50,12 +45,6 @@ const MobileResultsScreen = BatchResultsScreen const MobileSearchScreen = BatchSearchScreen export { - // module components - CallHistoryWindow, - CallTakerControls, - FieldTripWindows, - MailablesWindow, - // form components DateTimeModal, DateTimePreview, @@ -96,7 +85,6 @@ export { // app components, ResponsiveWebapp, AppMenu, - CallTakerPanel, DesktopNav, // batch routing components diff --git a/percy/har-mock-config-call-taker.js b/percy/har-mock-config-call-taker.js index f1e892114..31cd154f1 100644 --- a/percy/har-mock-config-call-taker.js +++ b/percy/har-mock-config-call-taker.js @@ -14,14 +14,16 @@ import React from 'react' import { BatchResultsScreen, BatchSearchScreen, - CallHistoryWindow, - CallTakerPanel, - FieldTripWindows, - MailablesWindow, MetroItinerary // Webpack sets this file to run from a subdirectory within otp-react-redux // ../lib points to the index file of otp-react-redux's source code } from '../lib' +import { + CallHistoryWindow, + FieldTripWindows, + MailablesWindow +} from '../lib/components/admin' +import { CallTakerPanel } from '../lib/components/app' /** * Custom itinerary footer for this deployment. From f9901891606c2bc55452e23c30cd1db918737093 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Fri, 22 Sep 2023 16:46:16 -0400 Subject: [PATCH 09/15] ci(percy): Update paths for percy calltaker config. --- percy/har-mock-config-call-taker.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/percy/har-mock-config-call-taker.js b/percy/har-mock-config-call-taker.js index 31cd154f1..418f5f6c9 100644 --- a/percy/har-mock-config-call-taker.js +++ b/percy/har-mock-config-call-taker.js @@ -18,12 +18,10 @@ import { // Webpack sets this file to run from a subdirectory within otp-react-redux // ../lib points to the index file of otp-react-redux's source code } from '../lib' -import { - CallHistoryWindow, - FieldTripWindows, - MailablesWindow -} from '../lib/components/admin' -import { CallTakerPanel } from '../lib/components/app' +import CallHistoryWindow from '../lib/components/admin/call-history-window' +import CallTakerPanel from '../lib/components/app/call-taker-panel' +import FieldTripWindows from '../lib/components/admin/field-trip-windows' +import MailablesWindow from '../lib/components/admin/mailables-window' /** * Custom itinerary footer for this deployment. From c7b5a9f37ebd33550a7883876e8b154f211a0da5 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Mon, 25 Sep 2023 16:52:39 -0400 Subject: [PATCH 10/15] ci(percy): Use separate YML config for calltaker. --- .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 c5e878b72..9684cb875 100644 --- a/.github/workflows/percy.yml +++ b/.github/workflows/percy.yml @@ -52,7 +52,7 @@ jobs: - 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 }} + PERCY_OTP2_CONFIG_URL: ${{ secrets.PERCY_MOCK_OTP2_GEOCODER_CALLTAKER_CONFIG }} - name: Build OTP-RR Calltaker # Calltaker has a separate config file, so another build should be produced. run: yarn build From b38e37e0900aa6d644ce76ed67354ab3926edaaf Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Thu, 19 Oct 2023 13:59:15 -0400 Subject: [PATCH 11/15] refactor(app): Prevent call history from appearing if datastore is not configured. --- lib/app.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/app.js b/lib/app.js index b56facafa..fda84a81f 100644 --- a/lib/app.js +++ b/lib/app.js @@ -175,6 +175,8 @@ const components = { MainPanel: BatchRoutingPanel, + MapWindows: isCallTakerModuleEnabled ? jsConfig.MapWindows : null, + MobileResultsScreen: BatchResultsScreen, MobileSearchScreen: BatchSearchScreen, From b8271bf2c08eed0571d0c3e4081f24ad0057f72a Mon Sep 17 00:00:00 2001 From: Binh Dam Date: Fri, 20 Oct 2023 14:15:32 +0000 Subject: [PATCH 12/15] Translated using Weblate (Spanish) Currently translated at 100.0% (517 of 517 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 | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/i18n/es.yml b/i18n/es.yml index 0cce495b2..be9f8314a 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:" @@ -52,9 +53,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. mustBeLoggedInToSavePlace: Por favor, inicia la sesión para guardar las ubicaciones. placeRemembered: La configuración de este lugar se ha guardado. preferencesSaved: Sus preferencias se han guardado. @@ -245,7 +248,8 @@ components: a incluir el transporte publico en la selección de modos. 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: > @@ -547,7 +551,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: @@ -610,16 +615,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 @@ -700,7 +708,7 @@ components: notifications: >- Notificaciones: {leadTimeInMinutes} minutos antes de la salida programada - notificationsDisabled: "Notificaciones: Disabled" + notificationsDisabled: "Notificaciones: Desactivadas" TripTools: copyLink: Copiar enlace header: Herramientas From 769823d315e65430cd0fcef6e9edc6e59d9b78ea Mon Sep 17 00:00:00 2001 From: Binh Dam Date: Fri, 20 Oct 2023 14:16:54 +0000 Subject: [PATCH 13/15] Translated using Weblate (Korean) Currently translated at 83.7% (433 of 517 strings) Translation: OTP-react-redux/OTP-RR Main UI Translate-URL: https://hosted.weblate.org/projects/otp-react-redux/otp-rr-main-ui/ko/ --- i18n/ko.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/i18n/ko.yml b/i18n/ko.yml index e04f7e8f2..53bfc40c3 100644 --- a/i18n/ko.yml +++ b/i18n/ko.yml @@ -22,7 +22,8 @@ actions: fetchFieldTripsError: "트립을 가져오는 중에 오류가 발생했습니다: {err}" fetchTripsForDateError: "필트 트립 날짜에 대한 트립을 가져오는 중에 오류가 발생했습니다: {err}" incompatibleTripDateError: 계획한 트립 날짜({tripDate})가 요청한 트립 날짜({requestDate})가 아닙니다 - itineraryCapacityError: "플랜을 저장할 수 없습니다: 하나 이상의 차량의 용량이 부족하여 이 플랜을 저장할 수 없습니다. 트립을 다시 계획하세요." + itineraryCapacityError: "플랜을 저장할 수 없습니다: 하나 이상의 차량의 용량이 부족하여 이 플랜을 저장할 수 없습니다. + 트립을 다시 계획하세요." maxTripRequestsExceeded: 유효한 결과없이 초과된 트립 요청의 개수 saveItinerariesError: "트립을 저장하는 데 실패했습니다: {err}" setDateError: "날짜를 설정하는 중에 오류가 발생했습니다:" @@ -504,6 +505,7 @@ components: notifyViaChannelWhen: "다음의 경우, {channel}을 통해 알려주세요:" oneHour: 1 시간 realtimeAlertFlagged: 내 트립 일정에 실시간 경고가 있습니다 + timeBefore: '{time} 전' TripStatus: alerts: "{alerts, plural, one {# 경고!} other {# 경고!}}" deleteTrip: 트립 삭제 @@ -641,5 +643,6 @@ util: networkUnavailable: 현재 {network} 네트워크를 사용할 수 없습니다. noTripFound: 트립을 찾을 수 없습니다. noTripFoundForMode: "{modes}의 트립을 찾을 수 없습니다." - noTripFoundReason: 지정된 최대 거리 내 또는 지정된 시간에 대중 교통 서비스가 없거나, 출발지 또는 도착지가 안전하게 접근가능하지 못할 수 있습니다. + noTripFoundReason: 지정된 최대 거리 내 또는 지정된 시간에 대중 교통 서비스가 없거나, 출발지 또는 도착지가 안전하게 접근가능하지 + 못할 수 있습니다. noTripFoundWithReason: "{noTripFound} {reason}" From 7a5f118b2fd8df404bd6c405a63e120c69a0dfc4 Mon Sep 17 00:00:00 2001 From: Binh Dam Date: Fri, 20 Oct 2023 14:16:16 +0000 Subject: [PATCH 14/15] Translated using Weblate (Chinese (Simplified)) Currently translated at 84.5% (437 of 517 strings) Translation: OTP-react-redux/OTP-RR Main UI Translate-URL: https://hosted.weblate.org/projects/otp-react-redux/otp-rr-main-ui/zh_Hans/ --- i18n/zh.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/i18n/zh.yml b/i18n/zh.yml index 99ec4cacb..d487fa672 100644 --- a/i18n/zh.yml +++ b/i18n/zh.yml @@ -502,6 +502,7 @@ components: notifyViaChannelWhen: "通过 {channel} 通知我当:" oneHour: 1小时 realtimeAlertFlagged: 在我的行程中有一个实时警报标志着 + timeBefore: '{time} 前' TripStatus: alerts: "{alerts, plural, one {# 警报!} other {# 警报!}}" deleteTrip: 删除行程 From 00b28fb5dc53e773a0043777580183430f25822e Mon Sep 17 00:00:00 2001 From: miles-grant-ibigroup Date: Fri, 20 Oct 2023 14:33:45 -0400 Subject: [PATCH 15/15] update otp-ui --- package.json | 6 +++--- yarn.lock | 48 ++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index e25487124..75253a754 100644 --- a/package.json +++ b/package.json @@ -39,13 +39,13 @@ "@bugsnag/plugin-react": "^7.17.0", "@floating-ui/react": "^0.19.2", "@opentripplanner/base-map": "^3.0.15", - "@opentripplanner/core-utils": "^11.0.6", + "@opentripplanner/core-utils": "^11.1.2", "@opentripplanner/endpoints-overlay": "^2.0.9", "@opentripplanner/from-to-location-picker": "^2.1.9", "@opentripplanner/geocoder": "^1.4.2", "@opentripplanner/humanize-distance": "^1.2.0", "@opentripplanner/icons": "^2.0.6", - "@opentripplanner/itinerary-body": "^5.1.0", + "@opentripplanner/itinerary-body": "^5.1.1", "@opentripplanner/location-field": "^2.0.11", "@opentripplanner/location-icon": "^1.4.1", "@opentripplanner/map-popup": "^2.0.6", @@ -58,7 +58,7 @@ "@opentripplanner/transit-vehicle-overlay": "^4.0.6", "@opentripplanner/transitive-overlay": "^3.0.16", "@opentripplanner/trip-details": "^5.0.4", - "@opentripplanner/trip-form": "^3.3.4", + "@opentripplanner/trip-form": "^3.3.5", "@opentripplanner/trip-viewer-overlay": "^2.0.7", "@opentripplanner/vehicle-rental-overlay": "^2.1.3", "@styled-icons/fa-regular": "^10.34.0", diff --git a/yarn.lock b/yarn.lock index 61aeaa722..c7eee4146 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2353,7 +2353,7 @@ maplibre-gl "^2.1.9" react-map-gl "^7.0.15" -"@opentripplanner/core-utils@^11.0.2", "@opentripplanner/core-utils@^11.0.6": +"@opentripplanner/core-utils@^11.0.2": version "11.0.6" resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-11.0.6.tgz#f8bd9796b4a9bc7490fb7fdca9ce661ed785bab1" integrity sha512-ullRWOhvx4TzCmNk97Fk3FefX5jVlk0oYaLUsSfZNJJSiO0WKQadHBaxXBHQ6JHv7pk9SPuEP7xXfjz8YV6vRA== @@ -2371,6 +2371,24 @@ lodash.isequal "^4.5.0" qs "^6.9.1" +"@opentripplanner/core-utils@^11.1.2": + version "11.1.2" + resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-11.1.2.tgz#a99d1fa4fb1f587d58fae8fcfd70a3bfe4eed424" + integrity sha512-Rn1tBm5F+nt/A4/0cpq6cyNTprSsxfFslujMoZ4P4r6fZ7YTx0d25di+MZ/CZgSlCzHJIiGAfi8DsfJ7yStcTA== + dependencies: + "@conveyal/lonlat" "^1.4.1" + "@mapbox/polyline" "^1.1.0" + "@opentripplanner/geocoder" "^1.4.2" + "@styled-icons/foundation" "^10.34.0" + "@turf/along" "^6.0.1" + chroma-js "^2.4.2" + date-fns "^2.28.0" + date-fns-tz "^1.2.2" + graphql "^16.6.0" + lodash.clonedeep "^4.5.0" + lodash.isequal "^4.5.0" + qs "^6.9.1" + "@opentripplanner/endpoints-overlay@^2.0.9": version "2.0.9" resolved "https://registry.yarnpkg.com/@opentripplanner/endpoints-overlay/-/endpoints-overlay-2.0.9.tgz#74a5bab257686130dea768dc921ac197dc0a7c0d" @@ -2413,7 +2431,7 @@ "@opentripplanner/core-utils" "^11.0.2" prop-types "^15.7.2" -"@opentripplanner/itinerary-body@^5.0.2", "@opentripplanner/itinerary-body@^5.0.7", "@opentripplanner/itinerary-body@^5.1.0": +"@opentripplanner/itinerary-body@^5.0.2", "@opentripplanner/itinerary-body@^5.0.7": version "5.1.0" resolved "https://registry.yarnpkg.com/@opentripplanner/itinerary-body/-/itinerary-body-5.1.0.tgz#29bba91db379bb4f63d13ec95c1cb058248d0683" integrity sha512-DTS4KlbqokS/ZA+gL0QCuPFORoPq/GVcHlRv0s9YqKmr0aS5eBBLg4f4mOuv1CcNeHKyZc6lNb/Ro3epjshd5A== @@ -2431,6 +2449,24 @@ react-resize-detector "^4.2.1" string-similarity "^4.0.4" +"@opentripplanner/itinerary-body@^5.1.1": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@opentripplanner/itinerary-body/-/itinerary-body-5.1.1.tgz#bcd76d6bc079c6407088223d021a5777358ab060" + integrity sha512-obsPBhgvpvVkJuTsgNhQFN+3QKpxlzrNU3FGUZT+PAkgUHQxFo/6FQ0LNGSC+dTBBS1t7EKDfC0czQz4KZPQiw== + dependencies: + "@opentripplanner/core-utils" "^11.0.2" + "@opentripplanner/humanize-distance" "^1.2.0" + "@opentripplanner/icons" "^2.0.5" + "@opentripplanner/location-icon" "^1.4.1" + "@styled-icons/fa-solid" "^10.34.0" + "@styled-icons/foundation" "^10.34.0" + date-fns "^2.28.0" + date-fns-tz "^1.2.2" + flat "^5.0.2" + react-animate-height "^3.0.4" + react-resize-detector "^4.2.1" + string-similarity "^4.0.4" + "@opentripplanner/location-field@^2.0.11": version "2.0.11" resolved "https://registry.yarnpkg.com/@opentripplanner/location-field/-/location-field-2.0.11.tgz#06a31ec2e62cf5b542d3392281bc28b9dd1ea416" @@ -2561,10 +2597,10 @@ flat "^5.0.2" react-animate-height "^3.0.4" -"@opentripplanner/trip-form@^3.3.4": - version "3.3.4" - resolved "https://registry.yarnpkg.com/@opentripplanner/trip-form/-/trip-form-3.3.4.tgz#12847736515aa11e1c69c8db627a54c1ad5e7e89" - integrity sha512-adEjAJ+2ygkc6vptiD7tHI3O+1tEIvoDsM3+/DFIgvtKxkSKuRzzTNXn67CI2pmEev75aiiTyT97PiWbDKRTJw== +"@opentripplanner/trip-form@^3.3.5": + version "3.3.5" + resolved "https://registry.yarnpkg.com/@opentripplanner/trip-form/-/trip-form-3.3.5.tgz#0c27191f6c3bfb491130d0f849a4086f199d9f20" + integrity sha512-rDfHWqaL9RTskgJPoV2acu7nRbxwtji5yposOVTzx4LK4GVOxczbpAD6KxXXLbx8nYwp+L6y2vqX97GmlogHKQ== dependencies: "@floating-ui/react" "^0.19.2" "@opentripplanner/core-utils" "^11.0.2"