From b0dd5d0399cfcdcd97330ce7cedbf4a433ca6a94 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Tue, 26 Sep 2023 07:42:15 -0400 Subject: [PATCH 01/18] refactor(config-types): Add config type file, use in app menu and popup components. --- lib/components/app/app-menu.tsx | 30 +++++++----------- lib/components/app/popup.tsx | 8 ++--- lib/util/config-types.ts | 56 +++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 24 deletions(-) create mode 100644 lib/util/config-types.ts diff --git a/lib/components/app/app-menu.tsx b/lib/components/app/app-menu.tsx index 4afc484f2..7de12d9fa 100644 --- a/lib/components/app/app-menu.tsx +++ b/lib/components/app/app-menu.tsx @@ -16,6 +16,11 @@ import type { WrappedComponentProps } from 'react-intl' import * as callTakerActions from '../../actions/call-taker' import * as fieldTripActions from '../../actions/field-trip' import * as uiActions from '../../actions/ui' +import { + AppConfig, + LanguageConfig, + AppMenuItemConfig as MenuItem +} from '../../util/config-types' import { ComponentContext } from '../../util/contexts' import { getLanguageOptions } from '../../util/i18n' import { isModuleEnabled, Modules } from '../../util/config' @@ -26,31 +31,17 @@ import startOver from '../util/start-over' import AppMenuItem from './app-menu-item' import PopupTriggerText from './popup-trigger-text' -type MenuItem = { - children?: MenuItem[] - href?: string - iconType: string | JSX.Element - iconUrl?: string - id: string - isSelected?: boolean - label: string | JSX.Element - lang?: string - onClick?: () => void - skipLocales?: boolean - subMenuDivider: boolean -} - type AppMenuProps = { activeLocale: string callTakerEnabled?: boolean extraMenuItems?: MenuItem[] fieldTripEnabled?: boolean // Typescript TODO language and language options based on configLanguage. - language: Record | null + language?: LanguageConfig languageOptions: Record | null location: { search: string } mailablesEnabled?: boolean - popupTarget: string + popupTarget?: string reactRouterConfig?: { basename: string } resetAndToggleCallHistory?: () => void resetAndToggleFieldTrips?: () => void @@ -89,7 +80,7 @@ class AppMenu extends Component< _triggerPopup = () => { const { popupTarget, setPopupContent } = this.props - setPopupContent(popupTarget) + if (popupTarget) setPopupContent(popupTarget) } _togglePane = () => { @@ -291,7 +282,8 @@ class AppMenu extends Component< // FIXME: type otp config // eslint-disable-next-line @typescript-eslint/no-explicit-any const mapStateToProps = (state: Record) => { - const { extraMenuItems, language } = state.otp.config + const config: AppConfig = state.otp.config + const { extraMenuItems, language, popups } = config return { activeLocale: state.otp.ui.locale, callTakerEnabled: isModuleEnabled(state, Modules.CALL_TAKER), @@ -300,7 +292,7 @@ const mapStateToProps = (state: Record) => { language, languageOptions: getLanguageOptions(language), mailablesEnabled: isModuleEnabled(state, Modules.MAILABLES), - popupTarget: state.otp.config?.popups?.launchers?.sidebarLink + popupTarget: popups?.launchers?.sidebarLink } } diff --git a/lib/components/app/popup.tsx b/lib/components/app/popup.tsx index d506ea5c1..8a67961cd 100644 --- a/lib/components/app/popup.tsx +++ b/lib/components/app/popup.tsx @@ -5,15 +5,13 @@ import coreUtils from '@opentripplanner/core-utils' import React, { useCallback, useEffect } from 'react' import styled from 'styled-components' +import { PopupLauncher, PopupTargetConfig } from '../../util/config-types' import { StyledIconWrapper } from '../util/styledIcon' import PageTitle from '../util/page-title' type Props = { - content?: { - appendLocale?: boolean - id?: string - modal?: boolean - url?: string + content?: PopupTargetConfig & { + id?: PopupLauncher } hideModal: () => void } diff --git a/lib/util/config-types.ts b/lib/util/config-types.ts new file mode 100644 index 000000000..dc2113e75 --- /dev/null +++ b/lib/util/config-types.ts @@ -0,0 +1,56 @@ +// This file is intended to contain configuration types, +// each suffixed with "Config", as in "MapConfig", "MenuItemConfig", etc. + +/** Configuration object for the application menu */ +export interface AppMenuItemConfig { + children?: AppMenuItemConfig[] + href?: string + iconType: string | JSX.Element + iconUrl?: string + id: string + isSelected?: boolean + label: string | JSX.Element + lang?: string + onClick?: () => void + skipLocales?: boolean + subMenuDivider?: boolean +} + +export interface BugsnagConfig { + key: string +} + +/** TODO: Configuration object for language settings */ +export type LanguageConfig = Record + +export interface PopupTargetConfig { + appendLocale?: boolean + modal?: boolean + url?: string +} + +export type PopupLauncher = + /** This button is rendered at the bottom of a selected itinerary */ + | 'itineraryFooter' + /** This button is rendered to the left of the itinerary filter in the batch and metro UIs */ + | 'optionFilter' + /** This button is rendered in the sidebar */ + | 'sidebarLink' + /** This button is rendered in the top right of the toolbar (desktop view only!) */ + | 'toolbar' + +/** Configuration object for popups */ +export interface PopupConfig { + launchers: Record + targets: Record +} + +/** The main application configuration object */ +export interface AppConfig { + bugsnag: BugsnagConfig + extraMenuItems?: AppMenuItemConfig[] + language?: LanguageConfig + popups?: PopupConfig + + // TODO: add other config items. +} From ce3e6f56e640566fcdc511549fcb53f624f79aa0 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Tue, 26 Sep 2023 08:12:09 -0400 Subject: [PATCH 02/18] refactor(config-types): Add more types and reuse in desktop-nav. --- lib/components/app/app-menu.tsx | 2 +- lib/components/app/desktop-nav.tsx | 8 +++++--- lib/util/config-types.ts | 24 ++++++++++++++++++++++++ 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/lib/components/app/app-menu.tsx b/lib/components/app/app-menu.tsx index 7de12d9fa..ea74aeee7 100644 --- a/lib/components/app/app-menu.tsx +++ b/lib/components/app/app-menu.tsx @@ -281,7 +281,7 @@ class AppMenu extends Component< // FIXME: type otp config // eslint-disable-next-line @typescript-eslint/no-explicit-any -const mapStateToProps = (state: Record) => { +const mapStateToProps = (state: any) => { const config: AppConfig = state.otp.config const { extraMenuItems, language, popups } = config return { diff --git a/lib/components/app/desktop-nav.tsx b/lib/components/app/desktop-nav.tsx index bfe583c1f..d93231178 100644 --- a/lib/components/app/desktop-nav.tsx +++ b/lib/components/app/desktop-nav.tsx @@ -6,6 +6,7 @@ import styled from 'styled-components' import * as uiActions from '../../actions/ui' import { accountLinks, getAuth0Config } from '../../util/auth' +import { AppConfig } from '../../util/config-types' import { DEFAULT_APP_TITLE } from '../../util/constants' import InvisibleA11yLabel from '../util/invisible-a11y-label' import NavLoginButtonAuth0 from '../user/nav-login-button-auth0' @@ -40,7 +41,7 @@ const NavItemOnLargeScreens = styled(NavbarItem)` // Typscript TODO: otpConfig type export type Props = { locale: string - otpConfig: any + otpConfig: AppConfig popupTarget?: string setPopupContent: (url: string) => void } @@ -145,10 +146,11 @@ const DesktopNav = ({ // connect to the redux store // Typescript TODO: state type const mapStateToProps = (state: any) => { + const otpConfig: AppConfig = state.otp.config return { locale: state.otp.ui.locale, - otpConfig: state.otp.config, - popupTarget: state.otp.config?.popups?.launchers?.toolbar + otpConfig, + popupTarget: otpConfig.popups?.launchers?.toolbar } } diff --git a/lib/util/config-types.ts b/lib/util/config-types.ts index dc2113e75..95386cf56 100644 --- a/lib/util/config-types.ts +++ b/lib/util/config-types.ts @@ -23,6 +23,26 @@ export interface BugsnagConfig { /** TODO: Configuration object for language settings */ export type LanguageConfig = Record +export interface Auth0Config { + audience: string + clientId: string + domain: string +} + +export interface OtpMiddlewareConfig { + apiBaseUrl: string + apiKey?: string + supportsPushNotifications?: boolean +} + +export interface PersistenceConfig { + auth0?: Auth0Config + enabled?: boolean + // eslint-disable-next-line camelcase + otp_middleware?: OtpMiddlewareConfig + strategy: 'localStorage' | 'otp_middleware' +} + export interface PopupTargetConfig { appendLocale?: boolean modal?: boolean @@ -47,10 +67,14 @@ export interface PopupConfig { /** The main application configuration object */ export interface AppConfig { + brandClickable?: boolean + branding?: string bugsnag: BugsnagConfig extraMenuItems?: AppMenuItemConfig[] language?: LanguageConfig + persistence?: PersistenceConfig popups?: PopupConfig + title?: string // TODO: add other config items. } From 406f49d19992c1c9ed1c60521fb1d6e092a3e5b3 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Tue, 26 Sep 2023 08:21:18 -0400 Subject: [PATCH 03/18] refactor(config-types): Tweak types and comments. --- lib/util/config-types.ts | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/lib/util/config-types.ts b/lib/util/config-types.ts index 95386cf56..32f1141b7 100644 --- a/lib/util/config-types.ts +++ b/lib/util/config-types.ts @@ -1,7 +1,7 @@ // This file is intended to contain configuration types, // each suffixed with "Config", as in "MapConfig", "MenuItemConfig", etc. -/** Configuration object for the application menu */ +/** Application side menu */ export interface AppMenuItemConfig { children?: AppMenuItemConfig[] href?: string @@ -16,39 +16,55 @@ export interface AppMenuItemConfig { subMenuDivider?: boolean } +/** Bugsnag */ export interface BugsnagConfig { key: string } -/** TODO: Configuration object for language settings */ +/** TODO: Language settings */ export type LanguageConfig = Record +/** Auth0 settings */ export interface Auth0Config { audience: string clientId: string domain: string } +/** OTP Middleware (Personas) settings */ export interface OtpMiddlewareConfig { apiBaseUrl: string apiKey?: string supportsPushNotifications?: boolean } -export interface PersistenceConfig { - auth0?: Auth0Config - enabled?: boolean +export interface LocalPersistenceConfig { + strategy: 'localStorage' +} + +export interface MiddlewarePersistenceConfig { + auth0: Auth0Config // eslint-disable-next-line camelcase - otp_middleware?: OtpMiddlewareConfig - strategy: 'localStorage' | 'otp_middleware' + otp_middleware: OtpMiddlewareConfig + strategy: 'otp_middleware' +} + +/** General persistence settings */ +export type PersistenceConfig = ( + | LocalPersistenceConfig + | MiddlewarePersistenceConfig +) & { + enabled?: boolean } +/** Popup target settings */ export interface PopupTargetConfig { appendLocale?: boolean modal?: boolean url?: string } +/** Supported popup launchers */ export type PopupLauncher = /** This button is rendered at the bottom of a selected itinerary */ | 'itineraryFooter' @@ -59,7 +75,7 @@ export type PopupLauncher = /** This button is rendered in the top right of the toolbar (desktop view only!) */ | 'toolbar' -/** Configuration object for popups */ +/** Popup settings */ export interface PopupConfig { launchers: Record targets: Record From 8f1bc560c50d41def8fbe9cd89e1ec4dc0b36c8b Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Tue, 26 Sep 2023 08:47:40 -0400 Subject: [PATCH 04/18] refactor(config-types): Add phone format, reuse in phone notification UI. --- lib/components/user/notification-prefs-pane.tsx | 15 +++++++++------ lib/components/user/phone-change-form.tsx | 5 ++--- lib/components/user/phone-number-editor.tsx | 5 ++--- lib/util/config-types.ts | 7 +++++++ 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/lib/components/user/notification-prefs-pane.tsx b/lib/components/user/notification-prefs-pane.tsx index 127fcb10c..05daba5a8 100644 --- a/lib/components/user/notification-prefs-pane.tsx +++ b/lib/components/user/notification-prefs-pane.tsx @@ -5,6 +5,7 @@ import { ListGroup, ListGroupItem } from 'react-bootstrap' import React from 'react' import styled from 'styled-components' +import { AppConfig, PhoneFormatConfig } from '../../util/config-types' import { GRAY_ON_WHITE } from '../util/colors' import { FieldSet } from './styled' @@ -19,9 +20,7 @@ interface Props extends FormikProps { loggedInUser: User onRequestPhoneVerificationCode: PhoneCodeRequestHandler onSendPhoneVerificationCode: PhoneVerificationSubmitHandler - phoneFormatOptions: { - countryCode: string - } + phoneFormatOptions: PhoneFormatConfig } const allNotificationChannels = ['email', 'sms', 'push'] @@ -122,13 +121,17 @@ const NotificationPrefsPane = ({ } const mapStateToProps = (state: any) => { - const { supportsPushNotifications } = - state.otp.config.persistence?.otp_middleware || {} + const config: AppConfig = state.otp.config + const { persistence, phoneFormatOptions } = config + const supportsPushNotifications = + persistence && 'otp_middleware' in persistence + ? persistence.otp_middleware?.supportsPushNotifications + : false return { allowedNotificationChannels: supportsPushNotifications ? allNotificationChannels : emailAndSms, - phoneFormatOptions: state.otp.config.phoneFormatOptions + phoneFormatOptions } } diff --git a/lib/components/user/phone-change-form.tsx b/lib/components/user/phone-change-form.tsx index 8e83ff2bd..7b34188ab 100644 --- a/lib/components/user/phone-change-form.tsx +++ b/lib/components/user/phone-change-form.tsx @@ -19,6 +19,7 @@ import React, { import styled from 'styled-components' import { InlineLoading } from '../narrative/loading' +import { PhoneFormatConfig } from '../../util/config-types' import InvisibleA11yLabel from '../util/invisible-a11y-label' import { ControlStrip, phoneFieldStyle } from './styled' @@ -59,9 +60,7 @@ interface Props { isSubmitting: boolean onCancel: () => void onSubmit: PhoneChangeSubmitHandler - phoneFormatOptions: { - countryCode: string - } + phoneFormatOptions: PhoneFormatConfig showCancel?: boolean } diff --git a/lib/components/user/phone-number-editor.tsx b/lib/components/user/phone-number-editor.tsx index b3dc52efc..fd5e8b972 100644 --- a/lib/components/user/phone-number-editor.tsx +++ b/lib/components/user/phone-number-editor.tsx @@ -8,6 +8,7 @@ import styled from 'styled-components' import { getAriaPhoneNumber } from '../../util/a11y' import { GRAY_ON_WHITE } from '../util/colors' import { isBlank } from '../../util/ui' +import { PhoneFormatConfig } from '../../util/config-types' import InvisibleA11yLabel from '../util/invisible-a11y-label' import { ControlStrip } from './styled' @@ -40,9 +41,7 @@ interface Props { intl: IntlShape onRequestCode: PhoneCodeRequestHandler onSubmitCode: PhoneVerificationSubmitHandler - phoneFormatOptions: { - countryCode: string - } + phoneFormatOptions: PhoneFormatConfig } interface State { diff --git a/lib/util/config-types.ts b/lib/util/config-types.ts index 32f1141b7..d30cadeae 100644 --- a/lib/util/config-types.ts +++ b/lib/util/config-types.ts @@ -81,6 +81,11 @@ export interface PopupConfig { targets: Record } +/** Phone format options */ +export interface PhoneFormatConfig { + countryCode: string +} + /** The main application configuration object */ export interface AppConfig { brandClickable?: boolean @@ -89,6 +94,8 @@ export interface AppConfig { extraMenuItems?: AppMenuItemConfig[] language?: LanguageConfig persistence?: PersistenceConfig + // Optional on declaration, populated with defaults in reducer if not configured. + phoneFormatOptions: PhoneFormatConfig popups?: PopupConfig title?: string From 00c1b2d7582327acc45e2e3de0ca1a183fa67ed2 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Tue, 26 Sep 2023 09:54:55 -0400 Subject: [PATCH 05/18] refactor(config-types): Add more types --- lib/util/config-types.ts | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/lib/util/config-types.ts b/lib/util/config-types.ts index d30cadeae..99cd3f92c 100644 --- a/lib/util/config-types.ts +++ b/lib/util/config-types.ts @@ -16,14 +16,21 @@ export interface AppMenuItemConfig { subMenuDivider?: boolean } -/** Bugsnag */ -export interface BugsnagConfig { +/** Generic API key config */ +interface ApiKeyConfig { key: string } +/** Bugsnag */ +export type BugsnagConfig = ApiKeyConfig + /** TODO: Language settings */ export type LanguageConfig = Record +export interface LocalizationConfig { + defaultLocale: string +} + /** Auth0 settings */ export interface Auth0Config { audience: string @@ -86,17 +93,30 @@ export interface PhoneFormatConfig { countryCode: string } +/** Mapillary settings */ +export type MapillaryConfig = ApiKeyConfig + /** The main application configuration object */ export interface AppConfig { + /** Whether the header brand should be clickable, and if so, reset the UI. */ brandClickable?: boolean branding?: string bugsnag: BugsnagConfig extraMenuItems?: AppMenuItemConfig[] + homeTimezone: string + /** Enable touch-friendly behavior on e.g. touch-screen kiosks that run a desktop OS. */ + isTouchScreenOnDesktop?: boolean language?: LanguageConfig + localization?: LocalizationConfig + mapillary?: MapillaryConfig + /** Interval in seconds past which a trip is no longer considered "on-time". */ + onTimeThresholdSeconds?: number persistence?: PersistenceConfig // Optional on declaration, populated with defaults in reducer if not configured. phoneFormatOptions: PhoneFormatConfig popups?: PopupConfig + /** Approx delay in seconds to reset the UI to an initial URL if there is no user activity */ + sessionTimeoutSeconds?: number title?: string // TODO: add other config items. From db839d6ca8925921d75a1ba91a2209c303e3b7f3 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Wed, 27 Sep 2023 10:25:44 -0400 Subject: [PATCH 06/18] refactor(config-types): Add more types. --- lib/util/config-types.ts | 92 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 89 insertions(+), 3 deletions(-) diff --git a/lib/util/config-types.ts b/lib/util/config-types.ts index 99cd3f92c..fd29af579 100644 --- a/lib/util/config-types.ts +++ b/lib/util/config-types.ts @@ -1,6 +1,16 @@ // This file is intended to contain configuration types, // each suffixed with "Config", as in "MapConfig", "MenuItemConfig", etc. +import { VehicleRentalMapOverlaySymbol } from '@opentripplanner/types' + +/** OTP URL settings */ +export interface ApiConfig { + host: string + path: string + port: number + v2?: boolean +} + /** Application side menu */ export interface AppMenuItemConfig { children?: AppMenuItemConfig[] @@ -21,8 +31,8 @@ interface ApiKeyConfig { key: string } -/** Bugsnag */ export type BugsnagConfig = ApiKeyConfig +export type MapillaryConfig = ApiKeyConfig /** TODO: Language settings */ export type LanguageConfig = Record @@ -93,11 +103,84 @@ export interface PhoneFormatConfig { countryCode: string } -/** Mapillary settings */ -export type MapillaryConfig = ApiKeyConfig +/** Map base layers (e.g. streets, satellite) */ +export interface BaseLayerConfig { + type: string + url: string +} + +/** Map views (e.g. default, stylized) */ +export interface MapViewConfig { + text: string + type: string // TODO use a list of values. +} + +export interface OverlayConfigBase { + modes?: string[] // TODO use allowed OTP mode list. + name?: string + visible?: boolean +} + +export interface ParkAndRideOverlayConfig extends OverlayConfigBase { + maxTransitDistance?: number + type: 'park-and-ride' +} + +export interface Otp1StopsOverlayConfig extends OverlayConfigBase { + type: 'stops' +} + +export interface Otp2TileLayer { + color?: string + initiallyVisible?: boolean + network?: string + type: 'stops' | 'stations' | 'rentalVehicles' | 'rentalStations' +} + +export interface Otp2TileLayerConfig { + layers: Otp2TileLayer[] + type: 'otp2' +} + +export interface MapTileLayerConfig extends OverlayConfigBase { + tileUrl: string + type: 'tile' +} + +export interface RentalOverlayConfig extends OverlayConfigBase { + companies?: string[] + mapSymbols: VehicleRentalMapOverlaySymbol[] + type: + | 'bike-rental' + | 'micromobility-rental' + | 'otp2-micromobility-rental' + | 'otp2-bike-rental' +} + +export type SupportedOverlays = + | ParkAndRideOverlayConfig + | RentalOverlayConfig + | Otp2TileLayerConfig + | Otp1StopsOverlayConfig + | MapTileLayerConfig + +export interface MapConfig { + baseLayers: BaseLayerConfig[] + initLat: number + initLon: number + initZoom?: number + overlays: SupportedOverlays[] + views: MapViewConfig[] +} + +/** Settings for reporting issues */ +export interface ReportIssueConfig { + mailto: string +} /** The main application configuration object */ export interface AppConfig { + api: ApiConfig /** Whether the header brand should be clickable, and if so, reset the UI. */ brandClickable?: boolean branding?: string @@ -108,6 +191,7 @@ export interface AppConfig { isTouchScreenOnDesktop?: boolean language?: LanguageConfig localization?: LocalizationConfig + map: MapConfig mapillary?: MapillaryConfig /** Interval in seconds past which a trip is no longer considered "on-time". */ onTimeThresholdSeconds?: number @@ -115,8 +199,10 @@ export interface AppConfig { // Optional on declaration, populated with defaults in reducer if not configured. phoneFormatOptions: PhoneFormatConfig popups?: PopupConfig + reportIssue?: ReportIssueConfig /** Approx delay in seconds to reset the UI to an initial URL if there is no user activity */ sessionTimeoutSeconds?: number + /** App title shown in the browser title bar. */ title?: string // TODO: add other config items. From 0970b80377e03a79bac8a196167449ce86d89d5c Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Wed, 27 Sep 2023 15:45:20 -0400 Subject: [PATCH 07/18] refactor(config-types): Tweak map types, add companies config. --- lib/util/config-types.ts | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/util/config-types.ts b/lib/util/config-types.ts index fd29af579..7897b0f4d 100644 --- a/lib/util/config-types.ts +++ b/lib/util/config-types.ts @@ -1,7 +1,7 @@ // This file is intended to contain configuration types, // each suffixed with "Config", as in "MapConfig", "MenuItemConfig", etc. -import { VehicleRentalMapOverlaySymbol } from '@opentripplanner/types' +import { Company, VehicleRentalMapOverlaySymbol } from '@opentripplanner/types' /** OTP URL settings */ export interface ApiConfig { @@ -105,7 +105,8 @@ export interface PhoneFormatConfig { /** Map base layers (e.g. streets, satellite) */ export interface BaseLayerConfig { - type: string + name?: string + type?: string url: string } @@ -165,12 +166,13 @@ export type SupportedOverlays = | MapTileLayerConfig export interface MapConfig { - baseLayers: BaseLayerConfig[] - initLat: number - initLon: number + baseLayers?: BaseLayerConfig[] + initLat?: number + initLon?: number initZoom?: number - overlays: SupportedOverlays[] - views: MapViewConfig[] + maxZoom?: number + overlays?: SupportedOverlays[] + views?: MapViewConfig[] } /** Settings for reporting issues */ @@ -185,6 +187,7 @@ export interface AppConfig { brandClickable?: boolean branding?: string bugsnag: BugsnagConfig + companies?: Company[] extraMenuItems?: AppMenuItemConfig[] homeTimezone: string /** Enable touch-friendly behavior on e.g. touch-screen kiosks that run a desktop OS. */ From 9961dd5eccd6027adf0c51af3fba715f424d0649 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Wed, 27 Sep 2023 16:22:39 -0400 Subject: [PATCH 08/18] refactor(config-types): Add itinerary config --- lib/util/config-types.ts | 45 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/lib/util/config-types.ts b/lib/util/config-types.ts index 7897b0f4d..5c76f94d0 100644 --- a/lib/util/config-types.ts +++ b/lib/util/config-types.ts @@ -1,7 +1,12 @@ // This file is intended to contain configuration types, // each suffixed with "Config", as in "MapConfig", "MenuItemConfig", etc. -import { Company, VehicleRentalMapOverlaySymbol } from '@opentripplanner/types' +import { + Company, + FareProductSelector, + VehicleRentalMapOverlaySymbol +} from '@opentripplanner/types' +import { FareTableLayout } from '@opentripplanner/trip-details/lib/types' /** OTP URL settings */ export interface ApiConfig { @@ -180,6 +185,43 @@ export interface ReportIssueConfig { mailto: string } +export interface ItineraryCostConfig { + bikeshareTripCostCents?: number + carParkingCostCents?: number + drivingCentsPerMile?: number +} + +export type ItinerarySortOption = + | 'DURATION' + | 'ARRIVALTIME' + | 'WALKTIME' + | 'COST' + | 'DEPARTURETIME' + +export interface ItineraryConfig { + costs?: ItineraryCostConfig + customBatchUiBackground?: boolean + defaultFareKey?: string + defaultFareType?: FareProductSelector + defaultSort?: ItinerarySortOption + disableMetroSeperatorDot?: true + displayCalories?: boolean + fareDetailsLayout?: FareTableLayout[] + fareKeyNameMap?: Record + fillModeIcons?: boolean + groupByMode?: boolean + groupTransitModes?: boolean + hideSkeletons?: boolean + mergeItineraries?: boolean + renderRouteNamesInBlocks?: boolean + showFirstResultByDefault?: boolean + showHeaderText?: boolean + showLegDurations?: boolean + showPlanFirstLastButtons?: boolean + showRouteFares?: boolean + sortModes?: ItinerarySortOption[] +} + /** The main application configuration object */ export interface AppConfig { api: ApiConfig @@ -192,6 +234,7 @@ export interface AppConfig { homeTimezone: string /** Enable touch-friendly behavior on e.g. touch-screen kiosks that run a desktop OS. */ isTouchScreenOnDesktop?: boolean + itinerary?: ItineraryConfig language?: LanguageConfig localization?: LocalizationConfig map: MapConfig From 638006977b263f4f51d040d57cd0f00b59b7c0b9 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Wed, 27 Sep 2023 16:26:14 -0400 Subject: [PATCH 09/18] refactor(sortOptions): Reuse types from config-types --- .../narrative/narrative-itineraries-header.tsx | 5 +++-- lib/components/util/sortOptions.ts | 17 ++++------------- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/lib/components/narrative/narrative-itineraries-header.tsx b/lib/components/narrative/narrative-itineraries-header.tsx index 5afc60308..6d9615510 100644 --- a/lib/components/narrative/narrative-itineraries-header.tsx +++ b/lib/components/narrative/narrative-itineraries-header.tsx @@ -9,7 +9,8 @@ import React, { useCallback } from 'react' import styled from 'styled-components' import { IconWithText, StyledIconWrapper } from '../util/styledIcon' -import { sortOptions, SortOptionsType } from '../util/sortOptions' +import { ItinerarySortOption } from '../../util/config-types' +import { sortOptions } from '../util/sortOptions' import { SortResultsDropdown } from '../util/dropdown' import { UnstyledButton } from '../util/unstyled-button' import InvisibleA11yLabel from '../util/invisible-a11y-label' @@ -53,7 +54,7 @@ export default function NarrativeItinerariesHeader({ sort }: { customBatchUiBackground?: boolean - enabledSortModes: SortOptionsType[] + enabledSortModes: ItinerarySortOption[] errors: unknown[] itineraries: unknown[] itinerary: Itinerary diff --git a/lib/components/util/sortOptions.ts b/lib/components/util/sortOptions.ts index 1a721c8f0..54ac217d3 100644 --- a/lib/components/util/sortOptions.ts +++ b/lib/components/util/sortOptions.ts @@ -1,18 +1,12 @@ import { IntlShape } from 'react-intl' -export type SortOptionsType = - | 'BEST' - | 'DURATION' - | 'ARRIVALTIME' - | 'DEPARTURETIME' - | 'WALKTIME' - | 'COST' +import { ItinerarySortOption } from '../../util/config-types' -type SortOptionEntry = { text: string; value: SortOptionsType } +type SortOptionEntry = { text: string; value: ItinerarySortOption } export const sortOptions = ( intl: IntlShape, - enabledOptions: SortOptionsType[] = [ + enabledOptions: ItinerarySortOption[] = [ 'BEST', 'DURATION', 'ARRIVALTIME', @@ -20,10 +14,7 @@ export const sortOptions = ( 'COST', 'DEPARTURETIME' ] -): { - text: string - value: string -}[] => { +): SortOptionEntry[] => { const sortOptionsArray: SortOptionEntry[] = [ { text: intl.formatMessage({ From 842a70afb1a99348b67b4a068634baa359e035ad Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Wed, 27 Sep 2023 17:00:18 -0400 Subject: [PATCH 10/18] refactor(config-types): Add carbon config --- lib/util/config-types.ts | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/lib/util/config-types.ts b/lib/util/config-types.ts index 5c76f94d0..fd0edd174 100644 --- a/lib/util/config-types.ts +++ b/lib/util/config-types.ts @@ -1,12 +1,16 @@ // This file is intended to contain configuration types, // each suffixed with "Config", as in "MapConfig", "MenuItemConfig", etc. +import { + CO2ConfigType, + FareTableLayout +} from '@opentripplanner/trip-details/lib/types' import { Company, FareProductSelector, + MassUnitOption, VehicleRentalMapOverlaySymbol } from '@opentripplanner/types' -import { FareTableLayout } from '@opentripplanner/trip-details/lib/types' /** OTP URL settings */ export interface ApiConfig { @@ -192,6 +196,7 @@ export interface ItineraryCostConfig { } export type ItinerarySortOption = + | 'BEST' | 'DURATION' | 'ARRIVALTIME' | 'WALKTIME' @@ -201,11 +206,9 @@ export type ItinerarySortOption = export interface ItineraryConfig { costs?: ItineraryCostConfig customBatchUiBackground?: boolean - defaultFareKey?: string defaultFareType?: FareProductSelector defaultSort?: ItinerarySortOption disableMetroSeperatorDot?: true - displayCalories?: boolean fareDetailsLayout?: FareTableLayout[] fareKeyNameMap?: Record fillModeIcons?: boolean @@ -222,13 +225,21 @@ export interface ItineraryConfig { sortModes?: ItinerarySortOption[] } +export interface CO2Config extends CO2ConfigType { + cutoffPercentage?: number + // FIXME: merge with the CO2ConfigType's unit field. + massUnit?: MassUnitOption + showIfHigher?: boolean +} + /** The main application configuration object */ export interface AppConfig { api: ApiConfig /** Whether the header brand should be clickable, and if so, reset the UI. */ brandClickable?: boolean branding?: string - bugsnag: BugsnagConfig + bugsnag?: BugsnagConfig + co2?: CO2Config companies?: Company[] extraMenuItems?: AppMenuItemConfig[] homeTimezone: string From f652d066f9f81308483905a000f4269bea10b70f Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Wed, 27 Sep 2023 17:03:19 -0400 Subject: [PATCH 11/18] refactor(connected-trip-details): Remove displayCalories config field. --- example-config.yml | 2 -- lib/components/narrative/connected-trip-details.js | 4 ---- 2 files changed, 6 deletions(-) diff --git a/example-config.yml b/example-config.yml index 63fbf78cc..3f1a3152d 100644 --- a/example-config.yml +++ b/example-config.yml @@ -349,8 +349,6 @@ itinerary: disableMetroSeperatorDot: false # Shows the duration of a leg below the leg in the metro itinerary summary showLegDurations: false - # Allows calorie counts to be hidden - displayCalories: true # The sort option to use by default # Available sort options: 'BEST', 'DURATION', 'ARRIVALTIME', 'WALKTIME', 'COST', 'DEPARTURETIME' # defaultSort: "BEST" # Default diff --git a/lib/components/narrative/connected-trip-details.js b/lib/components/narrative/connected-trip-details.js index 8affe6ef8..b25d5009c 100644 --- a/lib/components/narrative/connected-trip-details.js +++ b/lib/components/narrative/connected-trip-details.js @@ -20,10 +20,6 @@ const mapStateToProps = (state) => { mediumId: null, riderCategoryId: null }, - displayCalories: - typeof itinerary?.displayCalories === 'boolean' - ? itinerary?.displayCalories - : undefined, fareDetailsLayout: itinerary?.fareDetailsLayout || undefined, fareKeyNameMap: itinerary?.fareKeyNameMap || {} } From e085a80a6c082ec12520552c49e37830d97e404d Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Wed, 27 Sep 2023 17:14:16 -0400 Subject: [PATCH 12/18] refactor(config-types): Add autoplan config --- lib/util/config-types.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/lib/util/config-types.ts b/lib/util/config-types.ts index fd0edd174..2a33b0eeb 100644 --- a/lib/util/config-types.ts +++ b/lib/util/config-types.ts @@ -35,6 +35,15 @@ export interface AppMenuItemConfig { subMenuDivider?: boolean } +export type AutoPlanCondition = + | 'ONE_LOCATION_CHANGED' + | 'BOTH_LOCATIONS_CHANGED' + +export interface AutoPlanConfig { + default: AutoPlanCondition + mobile: AutoPlanCondition +} + /** Generic API key config */ interface ApiKeyConfig { key: string @@ -66,6 +75,8 @@ export interface OtpMiddlewareConfig { export interface LocalPersistenceConfig { strategy: 'localStorage' + // eslint-disable-next-line camelcase + terms_of_storage?: boolean } export interface MiddlewarePersistenceConfig { @@ -235,6 +246,8 @@ export interface CO2Config extends CO2ConfigType { /** The main application configuration object */ export interface AppConfig { api: ApiConfig + // Optional on declaration, populated with defaults in reducer if not configured. + autoPlan: AutoPlanConfig /** Whether the header brand should be clickable, and if so, reset the UI. */ brandClickable?: boolean branding?: string From ebee4c584b26bee1d814580fe386f486468cdf3f Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Wed, 27 Sep 2023 17:32:02 -0400 Subject: [PATCH 13/18] refactor(config-types): Add geocoder config --- lib/util/config-types.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lib/util/config-types.ts b/lib/util/config-types.ts index 2a33b0eeb..a23774c67 100644 --- a/lib/util/config-types.ts +++ b/lib/util/config-types.ts @@ -11,6 +11,7 @@ import { MassUnitOption, VehicleRentalMapOverlaySymbol } from '@opentripplanner/types' +import { GeocoderConfig as GeocoderConfigOtpUI } from '@opentripplanner/geocoder' /** OTP URL settings */ export interface ApiConfig { @@ -243,6 +244,18 @@ export interface CO2Config extends CO2ConfigType { showIfHigher?: boolean } +export interface GeocoderConfig extends GeocoderConfigOtpUI { + // layerColorMap is for LocationField. + layerColorMap?: { + [key: string]: string + // Explicitly include those used as headers + stations?: string + stops?: string + } + maxNearbyStops?: number + type: string +} + /** The main application configuration object */ export interface AppConfig { api: ApiConfig @@ -254,7 +267,9 @@ export interface AppConfig { bugsnag?: BugsnagConfig co2?: CO2Config companies?: Company[] + elevationProfile?: boolean extraMenuItems?: AppMenuItemConfig[] + geocoder: GeocoderConfig homeTimezone: string /** Enable touch-friendly behavior on e.g. touch-screen kiosks that run a desktop OS. */ isTouchScreenOnDesktop?: boolean From 21f730c13879ab89d322d6efce859f422f29500b Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Wed, 27 Sep 2023 18:04:03 -0400 Subject: [PATCH 14/18] refactor(config-modes): Add modes config, reuse types. --- lib/components/map/enhanced-stop-marker.tsx | 11 +++----- lib/components/util/types.ts | 7 ----- lib/util/config-types.ts | 30 ++++++++++++++++----- 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/lib/components/map/enhanced-stop-marker.tsx b/lib/components/map/enhanced-stop-marker.tsx index 82beaafa6..1dc8a21f8 100644 --- a/lib/components/map/enhanced-stop-marker.tsx +++ b/lib/components/map/enhanced-stop-marker.tsx @@ -13,13 +13,10 @@ import tinycolor from 'tinycolor2' import * as mapActions from '../../actions/map' import * as uiActions from '../../actions/ui' +import { AppConfig } from '../../util/config-types' import { ComponentContext } from '../../util/contexts' -import { - ConfiguredTransitMode, - SetLocationHandler, - SetViewedStopHandler -} from '../util/types' import { getModeFromStop, getStopName } from '../../util/viewer' +import { SetLocationHandler, SetViewedStopHandler } from '../util/types' interface OwnProps { stop: Stop @@ -169,9 +166,9 @@ class EnhancedStopMarker extends Component { const mapStateToProps = (state: any, ownProps: OwnProps) => { const { highlightedStop } = state.otp.ui - const transitModes = state.otp.config.modes.transitModes + const config: AppConfig = state.otp.config const modeColors: ModeColors = {} - transitModes.forEach((mode: ConfiguredTransitMode) => { + config.modes.transitModes.forEach((mode) => { modeColors[mode.mode] = mode.color }) diff --git a/lib/components/util/types.ts b/lib/components/util/types.ts index 8988c7126..03981f164 100644 --- a/lib/components/util/types.ts +++ b/lib/components/util/types.ts @@ -95,10 +95,3 @@ export type SetViewedRouteHandler = (route?: ViewedRouteState) => void export type SetViewedStopHandler = (payload: { stopId: string } | null) => void export type SetLocationHandler = (payload: MapLocationActionArg) => void - -export interface ConfiguredTransitMode { - color?: string - label?: string - mode: string - showWheelchairSetting?: boolean -} diff --git a/lib/util/config-types.ts b/lib/util/config-types.ts index a23774c67..ccf9eae14 100644 --- a/lib/util/config-types.ts +++ b/lib/util/config-types.ts @@ -9,6 +9,9 @@ import { Company, FareProductSelector, MassUnitOption, + ModeButtonDefinition, + ModeSetting, + ModeSettingValues, VehicleRentalMapOverlaySymbol } from '@opentripplanner/types' import { GeocoderConfig as GeocoderConfigOtpUI } from '@opentripplanner/geocoder' @@ -245,17 +248,29 @@ export interface CO2Config extends CO2ConfigType { } export interface GeocoderConfig extends GeocoderConfigOtpUI { - // layerColorMap is for LocationField. - layerColorMap?: { - [key: string]: string - // Explicitly include those used as headers - stations?: string - stops?: string - } + layerColorMap?: Record maxNearbyStops?: number type: string } +export interface TransitModeConfig { + color?: string + label?: string + mode: string + showWheelchairSetting?: boolean +} + +export interface ModesConfig { + accessModes: TransitModeConfig[] + initialState?: { + enabledModeButtons?: string[] + modeSettingValues?: ModeSettingValues + } + modeButtons?: ModeButtonDefinition[] + modeSettingDefinitions?: ModeSetting[] + transitModes: TransitModeConfig[] +} + /** The main application configuration object */ export interface AppConfig { api: ApiConfig @@ -278,6 +293,7 @@ export interface AppConfig { localization?: LocalizationConfig map: MapConfig mapillary?: MapillaryConfig + modes: ModesConfig /** Interval in seconds past which a trip is no longer considered "on-time". */ onTimeThresholdSeconds?: number persistence?: PersistenceConfig From f6d2fbb9a6d8e922262d58fb26c50f1287bb650f Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Thu, 28 Sep 2023 14:14:35 -0400 Subject: [PATCH 15/18] refactor(state-types): Introduce a basic redux state type, reuse in modified files. --- lib/components/app/app-menu.tsx | 16 ++++++---------- lib/components/app/desktop-nav.tsx | 6 +++--- lib/components/map/enhanced-stop-marker.tsx | 7 +++---- lib/components/user/notification-prefs-pane.tsx | 8 ++++---- lib/util/state-types.ts | 13 +++++++++++++ 5 files changed, 29 insertions(+), 21 deletions(-) create mode 100644 lib/util/state-types.ts diff --git a/lib/components/app/app-menu.tsx b/lib/components/app/app-menu.tsx index ea74aeee7..f4a5f6989 100644 --- a/lib/components/app/app-menu.tsx +++ b/lib/components/app/app-menu.tsx @@ -16,14 +16,14 @@ import type { WrappedComponentProps } from 'react-intl' import * as callTakerActions from '../../actions/call-taker' import * as fieldTripActions from '../../actions/field-trip' import * as uiActions from '../../actions/ui' +import { AppReduxState } from '../../util/state-types' +import { ComponentContext } from '../../util/contexts' +import { getLanguageOptions } from '../../util/i18n' +import { isModuleEnabled, Modules } from '../../util/config' import { - AppConfig, LanguageConfig, AppMenuItemConfig as MenuItem } from '../../util/config-types' -import { ComponentContext } from '../../util/contexts' -import { getLanguageOptions } from '../../util/i18n' -import { isModuleEnabled, Modules } from '../../util/config' import { MainPanelContent } from '../../actions/ui-constants' import { setMainPanelContent } from '../../actions/ui' import startOver from '../util/start-over' @@ -36,7 +36,6 @@ type AppMenuProps = { callTakerEnabled?: boolean extraMenuItems?: MenuItem[] fieldTripEnabled?: boolean - // Typescript TODO language and language options based on configLanguage. language?: LanguageConfig languageOptions: Record | null location: { search: string } @@ -279,11 +278,8 @@ class AppMenu extends Component< // connect to the redux store -// FIXME: type otp config -// eslint-disable-next-line @typescript-eslint/no-explicit-any -const mapStateToProps = (state: any) => { - const config: AppConfig = state.otp.config - const { extraMenuItems, language, popups } = config +const mapStateToProps = (state: AppReduxState) => { + const { extraMenuItems, language, popups } = state.otp.config return { activeLocale: state.otp.ui.locale, callTakerEnabled: isModuleEnabled(state, Modules.CALL_TAKER), diff --git a/lib/components/app/desktop-nav.tsx b/lib/components/app/desktop-nav.tsx index d93231178..e45a5027e 100644 --- a/lib/components/app/desktop-nav.tsx +++ b/lib/components/app/desktop-nav.tsx @@ -7,6 +7,7 @@ import styled from 'styled-components' import * as uiActions from '../../actions/ui' import { accountLinks, getAuth0Config } from '../../util/auth' import { AppConfig } from '../../util/config-types' +import { AppReduxState } from '../../util/state-types' import { DEFAULT_APP_TITLE } from '../../util/constants' import InvisibleA11yLabel from '../util/invisible-a11y-label' import NavLoginButtonAuth0 from '../user/nav-login-button-auth0' @@ -144,9 +145,8 @@ const DesktopNav = ({ } // connect to the redux store -// Typescript TODO: state type -const mapStateToProps = (state: any) => { - const otpConfig: AppConfig = state.otp.config +const mapStateToProps = (state: AppReduxState) => { + const { config: otpConfig } = state.otp return { locale: state.otp.ui.locale, otpConfig, diff --git a/lib/components/map/enhanced-stop-marker.tsx b/lib/components/map/enhanced-stop-marker.tsx index 1dc8a21f8..47c752ec5 100644 --- a/lib/components/map/enhanced-stop-marker.tsx +++ b/lib/components/map/enhanced-stop-marker.tsx @@ -13,7 +13,7 @@ import tinycolor from 'tinycolor2' import * as mapActions from '../../actions/map' import * as uiActions from '../../actions/ui' -import { AppConfig } from '../../util/config-types' +import { AppReduxState } from '../../util/state-types' import { ComponentContext } from '../../util/contexts' import { getModeFromStop, getStopName } from '../../util/viewer' import { SetLocationHandler, SetViewedStopHandler } from '../util/types' @@ -163,12 +163,11 @@ class EnhancedStopMarker extends Component { } } -const mapStateToProps = (state: any, ownProps: OwnProps) => { +const mapStateToProps = (state: AppReduxState, ownProps: OwnProps) => { const { highlightedStop } = state.otp.ui - const config: AppConfig = state.otp.config const modeColors: ModeColors = {} - config.modes.transitModes.forEach((mode) => { + state.otp.config.modes.transitModes.forEach((mode) => { modeColors[mode.mode] = mode.color }) diff --git a/lib/components/user/notification-prefs-pane.tsx b/lib/components/user/notification-prefs-pane.tsx index 05daba5a8..67f3fb091 100644 --- a/lib/components/user/notification-prefs-pane.tsx +++ b/lib/components/user/notification-prefs-pane.tsx @@ -5,8 +5,9 @@ import { ListGroup, ListGroupItem } from 'react-bootstrap' import React from 'react' import styled from 'styled-components' -import { AppConfig, PhoneFormatConfig } from '../../util/config-types' +import { AppReduxState } from '../../util/state-types' import { GRAY_ON_WHITE } from '../util/colors' +import { PhoneFormatConfig } from '../../util/config-types' import { FieldSet } from './styled' import { PhoneVerificationSubmitHandler } from './phone-verification-form' @@ -120,9 +121,8 @@ const NotificationPrefsPane = ({ ) } -const mapStateToProps = (state: any) => { - const config: AppConfig = state.otp.config - const { persistence, phoneFormatOptions } = config +const mapStateToProps = (state: AppReduxState) => { + const { persistence, phoneFormatOptions } = state.otp.config const supportsPushNotifications = persistence && 'otp_middleware' in persistence ? persistence.otp_middleware?.supportsPushNotifications diff --git a/lib/util/state-types.ts b/lib/util/state-types.ts new file mode 100644 index 000000000..18f7ef36b --- /dev/null +++ b/lib/util/state-types.ts @@ -0,0 +1,13 @@ +import { AppConfig } from './config-types' + +export interface OtpState { + config: AppConfig + // TODO: Add other OTP states + ui: any // TODO +} + +export interface AppReduxState { + calltaker?: any // TODO + otp: OtpState + user: any // TODO +} From 1c9f6e3f6cbf4f4a497bae1898ba0dd2f858b910 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Thu, 28 Sep 2023 14:48:11 -0400 Subject: [PATCH 16/18] refactor(config-types): Add transit operators --- lib/util/config-types.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/util/config-types.ts b/lib/util/config-types.ts index ccf9eae14..3707c50bf 100644 --- a/lib/util/config-types.ts +++ b/lib/util/config-types.ts @@ -12,6 +12,7 @@ import { ModeButtonDefinition, ModeSetting, ModeSettingValues, + TransitOperator, VehicleRentalMapOverlaySymbol } from '@opentripplanner/types' import { GeocoderConfig as GeocoderConfigOtpUI } from '@opentripplanner/geocoder' @@ -271,6 +272,16 @@ export interface ModesConfig { transitModes: TransitModeConfig[] } +export interface ModeColorConfig { + color: string + textColor: string +} + +export interface TransitOperatorConfig extends TransitOperator { + colorMode: 'gtfs' | 'gtfs-softened' | 'disabled' + modeColors: Record +} + /** The main application configuration object */ export interface AppConfig { api: ApiConfig @@ -305,6 +316,7 @@ export interface AppConfig { sessionTimeoutSeconds?: number /** App title shown in the browser title bar. */ title?: string + transitOperators?: TransitOperatorConfig[] // TODO: add other config items. } From 4f9cc21066a731a436bc407e8dcdbcfc1c69d8f1 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Thu, 28 Sep 2023 15:22:23 -0400 Subject: [PATCH 17/18] refactor(config-types): Add accessibility score --- lib/util/config-types.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/util/config-types.ts b/lib/util/config-types.ts index 3707c50bf..f6dfcfda4 100644 --- a/lib/util/config-types.ts +++ b/lib/util/config-types.ts @@ -278,12 +278,23 @@ export interface ModeColorConfig { } export interface TransitOperatorConfig extends TransitOperator { - colorMode: 'gtfs' | 'gtfs-softened' | 'disabled' - modeColors: Record + colorMode?: 'gtfs' | 'gtfs-softened' | 'disabled' + modeColors?: Record +} + +export interface AccessibilityScoreThresholdConfig { + color: string + icon: string + text?: string +} + +export interface AccessibilityScoreConfig { + gradationMap: Record } /** The main application configuration object */ export interface AppConfig { + accessibilityScore?: AccessibilityScoreConfig api: ApiConfig // Optional on declaration, populated with defaults in reducer if not configured. autoPlan: AutoPlanConfig From 380094daff801da57a344cd6f760a3fec9fdced7 Mon Sep 17 00:00:00 2001 From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com> Date: Thu, 28 Sep 2023 17:11:38 -0400 Subject: [PATCH 18/18] refactor(config-types): Add and tweak types. --- lib/components/app/app-menu.tsx | 23 +++++++--- lib/util/config-types.ts | 78 +++++++++++++++++++++++---------- 2 files changed, 71 insertions(+), 30 deletions(-) diff --git a/lib/components/app/app-menu.tsx b/lib/components/app/app-menu.tsx index f4a5f6989..580ff803f 100644 --- a/lib/components/app/app-menu.tsx +++ b/lib/components/app/app-menu.tsx @@ -16,14 +16,11 @@ import type { WrappedComponentProps } from 'react-intl' import * as callTakerActions from '../../actions/call-taker' import * as fieldTripActions from '../../actions/field-trip' import * as uiActions from '../../actions/ui' +import { AppMenuItemConfig, LanguageConfig } from '../../util/config-types' import { AppReduxState } from '../../util/state-types' import { ComponentContext } from '../../util/contexts' import { getLanguageOptions } from '../../util/i18n' import { isModuleEnabled, Modules } from '../../util/config' -import { - LanguageConfig, - AppMenuItemConfig as MenuItem -} from '../../util/config-types' import { MainPanelContent } from '../../actions/ui-constants' import { setMainPanelContent } from '../../actions/ui' import startOver from '../util/start-over' @@ -31,10 +28,24 @@ import startOver from '../util/start-over' import AppMenuItem from './app-menu-item' import PopupTriggerText from './popup-trigger-text' +type MenuItem = { + children?: MenuItem[] + href?: string + iconType?: string | JSX.Element + iconUrl?: string + id: string + isSelected?: boolean + label?: string | JSX.Element + lang?: string + onClick?: () => void + skipLocales?: boolean + subMenuDivider?: boolean +} + type AppMenuProps = { activeLocale: string callTakerEnabled?: boolean - extraMenuItems?: MenuItem[] + extraMenuItems?: AppMenuItemConfig[] fieldTripEnabled?: boolean language?: LanguageConfig languageOptions: Record | null @@ -312,7 +323,7 @@ export const Icon = ({ iconType, iconUrl }: { - iconType: string + iconType?: string iconUrl?: string }): JSX.Element => { // FIXME: add types to context diff --git a/lib/util/config-types.ts b/lib/util/config-types.ts index f6dfcfda4..734c39ed6 100644 --- a/lib/util/config-types.ts +++ b/lib/util/config-types.ts @@ -17,6 +17,18 @@ import { } from '@opentripplanner/types' import { GeocoderConfig as GeocoderConfigOtpUI } from '@opentripplanner/geocoder' +/** Accessibility threshold settings */ +export interface AccessibilityScoreThresholdConfig { + color: string + icon: string + text?: string +} + +/** All accessibility score settings */ +export interface AccessibilityScoreConfig { + gradationMap: Record +} + /** OTP URL settings */ export interface ApiConfig { host: string @@ -29,14 +41,10 @@ export interface ApiConfig { export interface AppMenuItemConfig { children?: AppMenuItemConfig[] href?: string - iconType: string | JSX.Element + iconType?: string iconUrl?: string id: string - isSelected?: boolean - label: string | JSX.Element - lang?: string - onClick?: () => void - skipLocales?: boolean + label?: string subMenuDivider?: boolean } @@ -71,23 +79,22 @@ export interface Auth0Config { domain: string } -/** OTP Middleware (Personas) settings */ -export interface OtpMiddlewareConfig { - apiBaseUrl: string - apiKey?: string - supportsPushNotifications?: boolean -} - +/** Local persistence setting */ export interface LocalPersistenceConfig { strategy: 'localStorage' // eslint-disable-next-line camelcase terms_of_storage?: boolean } +/** OTP Middleware (Personas) settings */ export interface MiddlewarePersistenceConfig { auth0: Auth0Config // eslint-disable-next-line camelcase - otp_middleware: OtpMiddlewareConfig + otp_middleware: { + apiBaseUrl: string + apiKey?: string + supportsPushNotifications?: boolean + } strategy: 'otp_middleware' } @@ -249,8 +256,9 @@ export interface CO2Config extends CO2ConfigType { } export interface GeocoderConfig extends GeocoderConfigOtpUI { - layerColorMap?: Record maxNearbyStops?: number + resultColors?: Record + resultsCount?: number type: string } @@ -282,14 +290,33 @@ export interface TransitOperatorConfig extends TransitOperator { modeColors?: Record } -export interface AccessibilityScoreThresholdConfig { - color: string - icon: string - text?: string -} - -export interface AccessibilityScoreConfig { - gradationMap: Record +/** Route Viewer config */ +export interface RouteViewerConfig { + /** Whether to hide the route linear shape inside a flex zone of that route. */ + hideRouteShapesWithinFlexZones?: boolean + /** Disable vehicle highlight if necessary (e.g. custom or inverted icons) */ + vehicleIconHighlight?: boolean + /** Customize vehicle icon padding (the default iconPadding is 2px in otp-ui) */ + vehicleIconPadding?: number + /** Interval for refreshing vehicle positions */ + vehiclePositionRefreshSeconds?: number +} + +/** Stop Viewer Config */ +export interface StopViewerConfig { + /** Radius (in meters) for searching nearby stops, rental vehicles, park and rides etc. */ + nearbyRadius?: number + /** The max. departures to show for each trip pattern in the Next Arrivals view */ + numberOfDepartures?: number + /** Whether to display block IDs with each departure in the schedule view. */ + showBlockIds?: boolean + /** + * Time window, in seconds, in which to search for next arrivals, + * so that, for example, if it is Friday and a route does + * not begin service again until Monday, we are showing its next + * departure and it is not entirely excluded from display. + */ + timeRange?: number } /** The main application configuration object */ @@ -297,7 +324,7 @@ export interface AppConfig { accessibilityScore?: AccessibilityScoreConfig api: ApiConfig // Optional on declaration, populated with defaults in reducer if not configured. - autoPlan: AutoPlanConfig + autoPlan?: boolean | AutoPlanConfig /** Whether the header brand should be clickable, and if so, reset the UI. */ brandClickable?: boolean branding?: string @@ -323,8 +350,11 @@ export interface AppConfig { phoneFormatOptions: PhoneFormatConfig popups?: PopupConfig reportIssue?: ReportIssueConfig + routeModeOverrides?: Record + routeViewer?: RouteViewerConfig /** Approx delay in seconds to reset the UI to an initial URL if there is no user activity */ sessionTimeoutSeconds?: number + stopViewer?: StopViewerConfig /** App title shown in the browser title bar. */ title?: string transitOperators?: TransitOperatorConfig[]