@opentripplanner/vehicle-rental-overlay 1.3.2 → 1.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,5 @@
1
1
  import { divIcon } from "leaflet";
2
2
  import memoize from "lodash.memoize";
3
- import coreUtils from "@opentripplanner/core-utils";
4
3
  import PropTypes from "prop-types";
5
4
  import React from "react";
6
5
  import ReactDOMServer from "react-dom/server";
@@ -21,7 +20,9 @@ var templatePropTypes = {
21
20
  children: PropTypes.node,
22
21
 
23
22
  /** The rental vehicle or station to render. */
24
- entity: coreUtils.types.stationType.isRequired,
23
+ // entity: coreUtils.types.stationType.isRequired,
24
+ // eslint-disable-next-line react/forbid-prop-types
25
+ entity: PropTypes.object.isRequired,
25
26
 
26
27
  /** leaflet attribute to control tabindex value for keyboaryd-only / SR users */
27
28
  keyboard: PropTypes.bool
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/DefaultMarkers/index.js"],"names":["divIcon","memoize","coreUtils","PropTypes","React","ReactDOMServer","CircleMarker","Marker","floatingBikeIcon","hubIcons","Styled","templatePropTypes","children","node","entity","types","stationType","isRequired","keyboard","bool","templateDefaultProps","SharedBikeCircle","dockStrokeColor","fillColor","pixels","strokeColor","GeneratedMarker","station","newStrokeColor","isFloatingBike","y","x","propTypes","defaultProps","HubAndFloatingBike","icon","capacity","bikesAvailable","spacesAvailable","pctFull","i","Math","round","getStationMarkerByColor","color","className","iconSize","popupAnchor","html","renderToStaticMarkup","GenericMarker","markerIcon"],"mappings":"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","sourcesContent":["import { divIcon } from \"leaflet\";\nimport memoize from \"lodash.memoize\";\nimport coreUtils from \"@opentripplanner/core-utils\";\nimport PropTypes from \"prop-types\";\nimport React from \"react\";\nimport ReactDOMServer from \"react-dom/server\";\nimport { CircleMarker, Marker } from \"react-leaflet\";\n\nimport { floatingBikeIcon, hubIcons } from \"../bike-icons\";\nimport * as Styled from \"../styled\";\n\n/**\n * This file contains default marker types for rental vehicles,\n * that can be used when defining the VehicleRentalOverlay's symbol prop:\n * - SharedBikeCircle\n * - GenericMarker\n * - HubAndFloatingBike\n */\n\n// Prop types reused across components.\nconst templatePropTypes = {\n /** The children of the component. */\n children: PropTypes.node,\n /** The rental vehicle or station to render. */\n entity: coreUtils.types.stationType.isRequired,\n /** leaflet attribute to control tabindex value for keyboaryd-only / SR users */\n keyboard: PropTypes.bool\n};\nconst templateDefaultProps = {\n children: null,\n keyboard: false\n};\n\n/**\n * Renders a shared bike or shared bike dock as a circle\n * with predefined colors and size.\n */\nexport const SharedBikeCircle = ({\n dockStrokeColor,\n fillColor = \"gray\",\n pixels,\n strokeColor\n}) => {\n const GeneratedMarker = ({ children, keyboard, entity: station }) => {\n let newStrokeColor = strokeColor || fillColor;\n\n if (!station.isFloatingBike) {\n newStrokeColor = dockStrokeColor || strokeColor;\n }\n\n return (\n <CircleMarker\n center={[station.y, station.x]}\n color={newStrokeColor}\n fillColor={fillColor}\n fillOpacity={1}\n keyboard={keyboard}\n radius={pixels - (station.isFloatingBike ? 1 : 0)}\n weight={1}\n >\n {children}\n </CircleMarker>\n );\n };\n\n GeneratedMarker.propTypes = templatePropTypes;\n GeneratedMarker.defaultProps = templateDefaultProps;\n return GeneratedMarker;\n};\n\n/**\n * A component that renders rental bike entities\n * either as a bike or a bike dock (or hub, showing spaces available).\n */\nexport const HubAndFloatingBike = ({ children, keyboard, entity: station }) => {\n let icon;\n if (station.isFloatingBike) {\n icon = floatingBikeIcon;\n } else {\n const capacity = station.bikesAvailable + station.spacesAvailable;\n if (capacity === 0) return null;\n const pctFull = station.bikesAvailable / capacity;\n const i = Math.round(pctFull * 9);\n icon = hubIcons[i];\n }\n return (\n <Marker icon={icon} keyboard={keyboard} position={[station.y, station.x]}>\n {children}\n </Marker>\n );\n};\nHubAndFloatingBike.propTypes = templatePropTypes;\nHubAndFloatingBike.defaultProps = templateDefaultProps;\n\n/**\n * Creates and caches a leaflet element icon based on color.\n */\nconst getStationMarkerByColor = memoize(color =>\n divIcon({\n className: \"\",\n iconSize: [11, 16],\n popupAnchor: [0, -6],\n html: ReactDOMServer.renderToStaticMarkup(\n <Styled.StationMarker color={color} />\n )\n })\n);\n\n/**\n * Helper function to create a leaflet Marker component to render entities\n * using fixed fill color.\n * Usage: GenericMarker({ fillColor: \"#F204B5\" })\n */\nexport const GenericMarker = ({ fillColor = \"gray\" }) => {\n const markerIcon = getStationMarkerByColor(fillColor);\n\n const GeneratedMarker = ({ children, keyboard, entity: station }) => (\n <Marker\n icon={markerIcon}\n keyboard={keyboard}\n position={[station.y, station.x]}\n >\n {children}\n </Marker>\n );\n GeneratedMarker.propTypes = templatePropTypes;\n GeneratedMarker.defaultProps = templateDefaultProps;\n return GeneratedMarker;\n};\n"],"file":"index.js"}
1
+ {"version":3,"sources":["../../src/DefaultMarkers/index.js"],"names":["divIcon","memoize","PropTypes","React","ReactDOMServer","CircleMarker","Marker","floatingBikeIcon","hubIcons","Styled","templatePropTypes","children","node","entity","object","isRequired","keyboard","bool","templateDefaultProps","SharedBikeCircle","dockStrokeColor","fillColor","pixels","strokeColor","GeneratedMarker","station","newStrokeColor","isFloatingBike","y","x","propTypes","defaultProps","HubAndFloatingBike","icon","capacity","bikesAvailable","spacesAvailable","pctFull","i","Math","round","getStationMarkerByColor","color","className","iconSize","popupAnchor","html","renderToStaticMarkup","GenericMarker","markerIcon"],"mappings":"AAAA,SAASA,OAAT,QAAwB,SAAxB;AACA,OAAOC,OAAP,MAAoB,gBAApB;AACA,OAAOC,SAAP,MAAsB,YAAtB;AACA,OAAOC,KAAP,MAAkB,OAAlB;AACA,OAAOC,cAAP,MAA2B,kBAA3B;AACA,SAASC,YAAT,EAAuBC,MAAvB,QAAqC,eAArC;AAEA,SAASC,gBAAT,EAA2BC,QAA3B,QAA2C,eAA3C;AACA,OAAO,KAAKC,MAAZ,MAAwB,WAAxB;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;AACA,IAAMC,iBAAiB,GAAG;AACxB;AACAC,EAAAA,QAAQ,EAAET,SAAS,CAACU,IAFI;;AAGxB;AACA;AACA;AACAC,EAAAA,MAAM,EAAEX,SAAS,CAACY,MAAV,CAAiBC,UAND;;AAOxB;AACAC,EAAAA,QAAQ,EAAEd,SAAS,CAACe;AARI,CAA1B;AAUA,IAAMC,oBAAoB,GAAG;AAC3BP,EAAAA,QAAQ,EAAE,IADiB;AAE3BK,EAAAA,QAAQ,EAAE;AAFiB,CAA7B;AAKA;AACA;AACA;AACA;;AACA,OAAO,IAAMG,gBAAgB,GAAG,SAAnBA,gBAAmB,OAK1B;AAAA,MAJJC,eAII,QAJJA,eAII;AAAA,4BAHJC,SAGI;AAAA,MAHJA,SAGI,+BAHQ,MAGR;AAAA,MAFJC,MAEI,QAFJA,MAEI;AAAA,MADJC,WACI,QADJA,WACI;;AACJ,MAAMC,eAAe,GAAG,SAAlBA,eAAkB,QAA6C;AAAA,QAA1Cb,QAA0C,SAA1CA,QAA0C;AAAA,QAAhCK,QAAgC,SAAhCA,QAAgC;AAAA,QAAdS,OAAc,SAAtBZ,MAAsB;AACnE,QAAIa,cAAc,GAAGH,WAAW,IAAIF,SAApC;;AAEA,QAAI,CAACI,OAAO,CAACE,cAAb,EAA6B;AAC3BD,MAAAA,cAAc,GAAGN,eAAe,IAAIG,WAApC;AACD;;AAED,wBACE,oBAAC,YAAD;AACE,MAAA,MAAM,EAAE,CAACE,OAAO,CAACG,CAAT,EAAYH,OAAO,CAACI,CAApB,CADV;AAEE,MAAA,KAAK,EAAEH,cAFT;AAGE,MAAA,SAAS,EAAEL,SAHb;AAIE,MAAA,WAAW,EAAE,CAJf;AAKE,MAAA,QAAQ,EAAEL,QALZ;AAME,MAAA,MAAM,EAAEM,MAAM,IAAIG,OAAO,CAACE,cAAR,GAAyB,CAAzB,GAA6B,CAAjC,CANhB;AAOE,MAAA,MAAM,EAAE;AAPV,OASGhB,QATH,CADF;AAaD,GApBD;;AAsBAa,EAAAA,eAAe,CAACM,SAAhB,GAA4BpB,iBAA5B;AACAc,EAAAA,eAAe,CAACO,YAAhB,GAA+Bb,oBAA/B;AACA,SAAOM,eAAP;AACD,CA/BM;AAiCP;AACA;AACA;AACA;;AACA,OAAO,IAAMQ,kBAAkB,GAAG,SAArBA,kBAAqB,QAA6C;AAAA,MAA1CrB,QAA0C,SAA1CA,QAA0C;AAAA,MAAhCK,QAAgC,SAAhCA,QAAgC;AAAA,MAAdS,OAAc,SAAtBZ,MAAsB;AAC7E,MAAIoB,IAAJ;;AACA,MAAIR,OAAO,CAACE,cAAZ,EAA4B;AAC1BM,IAAAA,IAAI,GAAG1B,gBAAP;AACD,GAFD,MAEO;AACL,QAAM2B,QAAQ,GAAGT,OAAO,CAACU,cAAR,GAAyBV,OAAO,CAACW,eAAlD;AACA,QAAIF,QAAQ,KAAK,CAAjB,EAAoB,OAAO,IAAP;AACpB,QAAMG,OAAO,GAAGZ,OAAO,CAACU,cAAR,GAAyBD,QAAzC;AACA,QAAMI,CAAC,GAAGC,IAAI,CAACC,KAAL,CAAWH,OAAO,GAAG,CAArB,CAAV;AACAJ,IAAAA,IAAI,GAAGzB,QAAQ,CAAC8B,CAAD,CAAf;AACD;;AACD,sBACE,oBAAC,MAAD;AAAQ,IAAA,IAAI,EAAEL,IAAd;AAAoB,IAAA,QAAQ,EAAEjB,QAA9B;AAAwC,IAAA,QAAQ,EAAE,CAACS,OAAO,CAACG,CAAT,EAAYH,OAAO,CAACI,CAApB;AAAlD,KACGlB,QADH,CADF;AAKD,CAhBM;AAiBPqB,kBAAkB,CAACF,SAAnB,GAA+BpB,iBAA/B;AACAsB,kBAAkB,CAACD,YAAnB,GAAkCb,oBAAlC;AAEA;AACA;AACA;;AACA,IAAMuB,uBAAuB,GAAGxC,OAAO,CAAC,UAAAyC,KAAK;AAAA,SAC3C1C,OAAO,CAAC;AACN2C,IAAAA,SAAS,EAAE,EADL;AAENC,IAAAA,QAAQ,EAAE,CAAC,EAAD,EAAK,EAAL,CAFJ;AAGNC,IAAAA,WAAW,EAAE,CAAC,CAAD,EAAI,CAAC,CAAL,CAHP;AAINC,IAAAA,IAAI,EAAE1C,cAAc,CAAC2C,oBAAf,eACJ,oBAAC,MAAD,CAAQ,aAAR;AAAsB,MAAA,KAAK,EAAEL;AAA7B,MADI;AAJA,GAAD,CADoC;AAAA,CAAN,CAAvC;AAWA;AACA;AACA;AACA;AACA;;AACA,OAAO,IAAMM,aAAa,GAAG,SAAhBA,aAAgB,QAA4B;AAAA,8BAAzB3B,SAAyB;AAAA,MAAzBA,SAAyB,gCAAb,MAAa;AACvD,MAAM4B,UAAU,GAAGR,uBAAuB,CAACpB,SAAD,CAA1C;;AAEA,MAAMG,eAAe,GAAG,SAAlBA,eAAkB;AAAA,QAAGb,QAAH,SAAGA,QAAH;AAAA,QAAaK,QAAb,SAAaA,QAAb;AAAA,QAA+BS,OAA/B,SAAuBZ,MAAvB;AAAA,wBACtB,oBAAC,MAAD;AACE,MAAA,IAAI,EAAEoC,UADR;AAEE,MAAA,QAAQ,EAAEjC,QAFZ;AAGE,MAAA,QAAQ,EAAE,CAACS,OAAO,CAACG,CAAT,EAAYH,OAAO,CAACI,CAApB;AAHZ,OAKGlB,QALH,CADsB;AAAA,GAAxB;;AASAa,EAAAA,eAAe,CAACM,SAAhB,GAA4BpB,iBAA5B;AACAc,EAAAA,eAAe,CAACO,YAAhB,GAA+Bb,oBAA/B;AACA,SAAOM,eAAP;AACD,CAfM","sourcesContent":["import { divIcon } from \"leaflet\";\nimport memoize from \"lodash.memoize\";\nimport PropTypes from \"prop-types\";\nimport React from \"react\";\nimport ReactDOMServer from \"react-dom/server\";\nimport { CircleMarker, Marker } from \"react-leaflet\";\n\nimport { floatingBikeIcon, hubIcons } from \"../bike-icons\";\nimport * as Styled from \"../styled\";\n\n/**\n * This file contains default marker types for rental vehicles,\n * that can be used when defining the VehicleRentalOverlay's symbol prop:\n * - SharedBikeCircle\n * - GenericMarker\n * - HubAndFloatingBike\n */\n\n// Prop types reused across components.\nconst templatePropTypes = {\n /** The children of the component. */\n children: PropTypes.node,\n /** The rental vehicle or station to render. */\n // entity: coreUtils.types.stationType.isRequired,\n // eslint-disable-next-line react/forbid-prop-types\n entity: PropTypes.object.isRequired,\n /** leaflet attribute to control tabindex value for keyboaryd-only / SR users */\n keyboard: PropTypes.bool\n};\nconst templateDefaultProps = {\n children: null,\n keyboard: false\n};\n\n/**\n * Renders a shared bike or shared bike dock as a circle\n * with predefined colors and size.\n */\nexport const SharedBikeCircle = ({\n dockStrokeColor,\n fillColor = \"gray\",\n pixels,\n strokeColor\n}) => {\n const GeneratedMarker = ({ children, keyboard, entity: station }) => {\n let newStrokeColor = strokeColor || fillColor;\n\n if (!station.isFloatingBike) {\n newStrokeColor = dockStrokeColor || strokeColor;\n }\n\n return (\n <CircleMarker\n center={[station.y, station.x]}\n color={newStrokeColor}\n fillColor={fillColor}\n fillOpacity={1}\n keyboard={keyboard}\n radius={pixels - (station.isFloatingBike ? 1 : 0)}\n weight={1}\n >\n {children}\n </CircleMarker>\n );\n };\n\n GeneratedMarker.propTypes = templatePropTypes;\n GeneratedMarker.defaultProps = templateDefaultProps;\n return GeneratedMarker;\n};\n\n/**\n * A component that renders rental bike entities\n * either as a bike or a bike dock (or hub, showing spaces available).\n */\nexport const HubAndFloatingBike = ({ children, keyboard, entity: station }) => {\n let icon;\n if (station.isFloatingBike) {\n icon = floatingBikeIcon;\n } else {\n const capacity = station.bikesAvailable + station.spacesAvailable;\n if (capacity === 0) return null;\n const pctFull = station.bikesAvailable / capacity;\n const i = Math.round(pctFull * 9);\n icon = hubIcons[i];\n }\n return (\n <Marker icon={icon} keyboard={keyboard} position={[station.y, station.x]}>\n {children}\n </Marker>\n );\n};\nHubAndFloatingBike.propTypes = templatePropTypes;\nHubAndFloatingBike.defaultProps = templateDefaultProps;\n\n/**\n * Creates and caches a leaflet element icon based on color.\n */\nconst getStationMarkerByColor = memoize(color =>\n divIcon({\n className: \"\",\n iconSize: [11, 16],\n popupAnchor: [0, -6],\n html: ReactDOMServer.renderToStaticMarkup(\n <Styled.StationMarker color={color} />\n )\n })\n);\n\n/**\n * Helper function to create a leaflet Marker component to render entities\n * using fixed fill color.\n * Usage: GenericMarker({ fillColor: \"#F204B5\" })\n */\nexport const GenericMarker = ({ fillColor = \"gray\" }) => {\n const markerIcon = getStationMarkerByColor(fillColor);\n\n const GeneratedMarker = ({ children, keyboard, entity: station }) => (\n <Marker\n icon={markerIcon}\n keyboard={keyboard}\n position={[station.y, station.x]}\n >\n {children}\n </Marker>\n );\n GeneratedMarker.propTypes = templatePropTypes;\n GeneratedMarker.defaultProps = templateDefaultProps;\n return GeneratedMarker;\n};\n"],"file":"index.js"}
package/esm/index.js CHANGED
@@ -8,20 +8,67 @@ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflec
8
8
 
9
9
  function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
10
10
 
11
+ import flatten from "flat";
11
12
  import { Styled as BaseMapStyled } from "@opentripplanner/base-map";
12
13
  import coreUtils from "@opentripplanner/core-utils";
13
14
  import FromToLocationPicker from "@opentripplanner/from-to-location-picker";
14
15
  import ZoomBasedMarkers from "@opentripplanner/zoom-based-markers";
15
16
  import PropTypes from "prop-types";
16
17
  import React from "react";
18
+ import { FormattedMessage, injectIntl } from "react-intl";
17
19
  import { FeatureGroup, MapLayer, Popup, withLeaflet } from "react-leaflet";
18
- import { GenericMarker, HubAndFloatingBike, SharedBikeCircle } from "./DefaultMarkers";
20
+ import { GenericMarker, HubAndFloatingBike, SharedBikeCircle } from "./DefaultMarkers"; // Load the default messages.
21
+
22
+ import defaultEnglishMessages from "../i18n/en-US.yml"; // HACK: We should flatten the messages loaded above because
23
+ // the YAML loaders behave differently between webpack and our version of jest:
24
+ // - the yaml loader for webpack returns a nested object,
25
+ // - the yaml loader for jest returns messages with flattened ids.
26
+
27
+ var defaultMessages = flatten(defaultEnglishMessages);
28
+
29
+ function makeDefaultGetStationName(intl) {
30
+ return function defaultGetStationName(configCompanies, station) {
31
+ var stationNetworks = coreUtils.itinerary.getCompaniesLabelFromNetworks(station.networks, configCompanies);
32
+ var stationName = station.name || station.id;
33
+
34
+ if (station.isFloatingBike) {
35
+ stationName = intl.formatMessage({
36
+ defaultMessage: defaultEnglishMessages["otpUi.VehicleRentalOverlay.floatingBike"],
37
+ description: "Popup title for a free-floating bike",
38
+ id: "otpUi.VehicleRentalOverlay.floatingBike"
39
+ }, {
40
+ name: stationName
41
+ });
42
+ } else if (station.isFloatingCar) {
43
+ stationName = intl.formatMessage({
44
+ defaultMessage: defaultEnglishMessages["otpUi.VehicleRentalOverlay.floatingCar"],
45
+ description: "Popup title for a free-floating car",
46
+ id: "otpUi.VehicleRentalOverlay.floatingCar"
47
+ }, {
48
+ company: stationNetworks,
49
+ name: stationName
50
+ });
51
+ } else if (station.isFloatingVehicle) {
52
+ // assumes that all floating vehicles are E-scooters
53
+ stationName = intl.formatMessage({
54
+ defaultMessage: defaultEnglishMessages["otpUi.VehicleRentalOverlay.floatingEScooter"],
55
+ description: "Popup title for a free-floating e-scooter",
56
+ id: "otpUi.VehicleRentalOverlay.floatingEScooter"
57
+ }, {
58
+ company: stationNetworks
59
+ });
60
+ }
61
+
62
+ return stationName;
63
+ };
64
+ }
19
65
  /**
20
66
  * This vehicle rental overlay can be used to render vehicle rentals of various
21
67
  * types. This layer can be configured to show different styles of markers at
22
68
  * different zoom levels.
23
69
  */
24
70
 
71
+
25
72
  var VehicleRentalOverlay = /*#__PURE__*/function (_MapLayer) {
26
73
  _inherits(VehicleRentalOverlay, _MapLayer);
27
74
 
@@ -45,7 +92,7 @@ var VehicleRentalOverlay = /*#__PURE__*/function (_MapLayer) {
45
92
  };
46
93
 
47
94
  SymbolWrapper.propTypes = {
48
- entity: coreUtils.types.stationType.isRequired,
95
+ // entity: coreUtils.types.stationType.isRequired,
49
96
  zoom: PropTypes.number.isRequired
50
97
  };
51
98
  return SymbolWrapper;
@@ -104,21 +151,38 @@ var VehicleRentalOverlay = /*#__PURE__*/function (_MapLayer) {
104
151
  var _this$props = _this.props,
105
152
  configCompanies = _this$props.configCompanies,
106
153
  getStationName = _this$props.getStationName,
154
+ intl = _this$props.intl,
107
155
  setLocation = _this$props.setLocation;
108
- var stationName = getStationName(configCompanies, station);
156
+ var getStationNameFunc = getStationName || makeDefaultGetStationName(intl);
157
+ var stationName = getStationNameFunc(configCompanies, station);
109
158
  var location = {
110
159
  lat: station.y,
111
160
  lon: station.x,
112
161
  name: stationName
113
162
  };
114
- return /*#__PURE__*/React.createElement(Popup, null, /*#__PURE__*/React.createElement(BaseMapStyled.MapOverlayPopup, null, /*#__PURE__*/React.createElement(BaseMapStyled.PopupTitle, null, stationName), stationIsHub && /*#__PURE__*/React.createElement(BaseMapStyled.PopupRow, null, /*#__PURE__*/React.createElement("div", null, "Available bikes: ", station.bikesAvailable), /*#__PURE__*/React.createElement("div", null, "Available docks: ", station.spacesAvailable)), /*#__PURE__*/React.createElement(BaseMapStyled.PopupRow, null, /*#__PURE__*/React.createElement("b", null, "Plan a trip:"), /*#__PURE__*/React.createElement(FromToLocationPicker, {
163
+ return /*#__PURE__*/React.createElement(Popup, null, /*#__PURE__*/React.createElement(BaseMapStyled.MapOverlayPopup, null, /*#__PURE__*/React.createElement(BaseMapStyled.PopupTitle, null, stationName), stationIsHub && /*#__PURE__*/React.createElement(BaseMapStyled.PopupRow, null, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(FormattedMessage, {
164
+ defaultMessage: defaultMessages["otpUi.VehicleRentalOverlay.availableBikes"],
165
+ description: "Label text for the number of bikes available",
166
+ id: "otpUi.VehicleRentalOverlay.availableBikes",
167
+ values: {
168
+ value: station.bikesAvailable
169
+ }
170
+ })), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(FormattedMessage, {
171
+ defaultMessage: defaultMessages["otpUi.VehicleRentalOverlay.availableDocks"],
172
+ description: "Label text for the number of docks available",
173
+ id: "otpUi.VehicleRentalOverlay.availableDocks",
174
+ values: {
175
+ value: station.spacesAvailable
176
+ }
177
+ }))), /*#__PURE__*/React.createElement(BaseMapStyled.PopupRow, null, /*#__PURE__*/React.createElement(FromToLocationPicker, {
178
+ label: true,
115
179
  location: location,
116
180
  setLocation: setLocation
117
181
  }))));
118
182
  };
119
183
 
120
184
  _this.state = {
121
- zoom: props.leaflet.map.getZoom()
185
+ zoom: null
122
186
  };
123
187
  return _this;
124
188
  }
@@ -169,8 +233,12 @@ var VehicleRentalOverlay = /*#__PURE__*/function (_MapLayer) {
169
233
  */
170
234
  function componentDidMount() {
171
235
  var _this$props2 = this.props,
236
+ leaflet = _this$props2.leaflet,
172
237
  registerOverlay = _this$props2.registerOverlay,
173
238
  visible = _this$props2.visible;
239
+ this.setState({
240
+ zoom: leaflet.map.getZoom()
241
+ });
174
242
  if (visible) this.startRefreshing();
175
243
 
176
244
  if (typeof registerOverlay === "function") {
@@ -193,9 +261,11 @@ var VehicleRentalOverlay = /*#__PURE__*/function (_MapLayer) {
193
261
  value: function render() {
194
262
  var _this$props3 = this.props,
195
263
  companies = _this$props3.companies,
264
+ leaflet = _this$props3.leaflet,
196
265
  mapSymbols = _this$props3.mapSymbols,
197
266
  stations = _this$props3.stations;
198
- var zoom = this.state.zoom; // Render an empty FeatureGroup if the rental vehicles should not be visible
267
+ var _this$state$zoom = this.state.zoom,
268
+ zoom = _this$state$zoom === void 0 ? leaflet.map.getZoom() : _this$state$zoom; // Render an empty FeatureGroup if the rental vehicles should not be visible
199
269
  // on the map. Otherwise previous stations may still be shown due to some
200
270
  // react-leaflet internals, maybe? Also, do not return null because that will
201
271
  // prevent the overlay from appearing in the layer controls.
@@ -232,7 +302,8 @@ VehicleRentalOverlay.props = {
232
302
  /**
233
303
  * The entire companies config array.
234
304
  */
235
- configCompanies: PropTypes.arrayOf(coreUtils.types.companyType.isRequired).isRequired,
305
+ // configCompanies: PropTypes.arrayOf(coreUtils.types.companyType.isRequired)
306
+ // .isRequired,
236
307
 
237
308
  /**
238
309
  * A list of companies that are applicable to just this instance of the
@@ -251,7 +322,7 @@ VehicleRentalOverlay.props = {
251
322
  * A configuration of what map markers or symbols to show at various
252
323
  * zoom levels.
253
324
  */
254
- mapSymbols: coreUtils.types.vehicleRentalMapOverlaySymbolsType,
325
+ // mapSymbols: coreUtils.types.vehicleRentalMapOverlaySymbolsType,
255
326
 
256
327
  /**
257
328
  * If specified, a function that will be triggered every 30 seconds whenever this layer is
@@ -281,7 +352,7 @@ VehicleRentalOverlay.props = {
281
352
  /**
282
353
  * A list of the vehicle rental stations specific to this overlay instance.
283
354
  */
284
- stations: PropTypes.arrayOf(coreUtils.types.stationType),
355
+ // stations: PropTypes.arrayOf(coreUtils.types.stationType),
285
356
 
286
357
  /**
287
358
  * Whether the overlay is currently visible.
@@ -289,21 +360,7 @@ VehicleRentalOverlay.props = {
289
360
  visible: PropTypes.bool
290
361
  };
291
362
  VehicleRentalOverlay.defaultProps = {
292
- getStationName: function getStationName(configCompanies, station) {
293
- var stationNetworks = coreUtils.itinerary.getCompaniesLabelFromNetworks(station.networks, configCompanies);
294
- var stationName = station.name || station.id;
295
-
296
- if (station.isFloatingBike) {
297
- stationName = "Free-floating bike: ".concat(stationName);
298
- } else if (station.isFloatingCar) {
299
- stationName = "".concat(stationNetworks, " ").concat(stationName);
300
- } else if (station.isFloatingVehicle) {
301
- // assumes that all floating vehicles are E-scooters
302
- stationName = "".concat(stationNetworks, " E-scooter");
303
- }
304
-
305
- return stationName;
306
- },
363
+ getStationName: null,
307
364
  mapSymbols: [{
308
365
  zoom: 0,
309
366
  symbol: GenericMarker
@@ -312,5 +369,5 @@ VehicleRentalOverlay.defaultProps = {
312
369
  stations: [],
313
370
  visible: false
314
371
  };
315
- export default withLeaflet(VehicleRentalOverlay);
372
+ export default withLeaflet(injectIntl(VehicleRentalOverlay));
316
373
  //# sourceMappingURL=index.js.map
package/esm/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.js"],"names":["Styled","BaseMapStyled","coreUtils","FromToLocationPicker","ZoomBasedMarkers","PropTypes","React","FeatureGroup","MapLayer","Popup","withLeaflet","GenericMarker","HubAndFloatingBike","SharedBikeCircle","VehicleRentalOverlay","props","renderSymbolWithPopup","Symbol","SymbolWrapper","station","entity","zoom","renderPopupForStation","bikesAvailable","undefined","isFloatingBike","propTypes","types","stationType","isRequired","number","convertToZoomMarkerSymbols","mapSymbols","map","mapSymbol","symbol","type","minZoom","onOverlayAdded","startRefreshing","onOverlayRemoved","stopRefreshing","onViewportChanged","viewport","newZoom","state","setState","stationIsHub","configCompanies","getStationName","setLocation","stationName","location","lat","y","lon","x","name","spacesAvailable","leaflet","getZoom","refreshVehicles","refreshTimer","setInterval","clearInterval","registerOverlay","visible","companies","stations","filteredStations","filter","networks","value","includes","length","symbols","arrayOf","companyType","string","func","vehicleRentalMapOverlaySymbolsType","bool","defaultProps","stationNetworks","itinerary","getCompaniesLabelFromNetworks","id","isFloatingCar","isFloatingVehicle"],"mappings":"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","sourcesContent":["import { Styled as BaseMapStyled } from \"@opentripplanner/base-map\";\nimport coreUtils from \"@opentripplanner/core-utils\";\nimport FromToLocationPicker from \"@opentripplanner/from-to-location-picker\";\nimport ZoomBasedMarkers from \"@opentripplanner/zoom-based-markers\";\nimport PropTypes from \"prop-types\";\nimport React from \"react\";\nimport { FeatureGroup, MapLayer, Popup, withLeaflet } from \"react-leaflet\";\n\nimport {\n GenericMarker,\n HubAndFloatingBike,\n SharedBikeCircle\n} from \"./DefaultMarkers\";\n\n/**\n * This vehicle rental overlay can be used to render vehicle rentals of various\n * types. This layer can be configured to show different styles of markers at\n * different zoom levels.\n */\nclass VehicleRentalOverlay extends MapLayer {\n constructor(props) {\n super(props);\n this.state = {\n zoom: props.leaflet.map.getZoom()\n };\n }\n\n /**\n * This helper method will be passed to the ZoomBasedMarkers symbolTransform prop.\n * It creates a component that inserts a popup\n * as a child of the specified symbol from the mapSymbols prop.\n */\n renderSymbolWithPopup = Symbol => {\n const SymbolWrapper = ({ entity: station, zoom }) => (\n <Symbol entity={station} zoom={zoom}>\n {this.renderPopupForStation(\n station,\n station.bikesAvailable !== undefined && !station.isFloatingBike\n )}\n </Symbol>\n );\n SymbolWrapper.propTypes = {\n entity: coreUtils.types.stationType.isRequired,\n zoom: PropTypes.number.isRequired\n };\n\n return SymbolWrapper;\n };\n\n /**\n * Convert map symbols to zoomBasedSymbolType.\n */\n convertToZoomMarkerSymbols = mapSymbols =>\n mapSymbols.map(mapSymbol => {\n // If mapSymbol uses zoomBasedSymbolType, use it as is.\n if (mapSymbol.symbol) {\n return mapSymbol;\n }\n\n // Otherwise, convert into zoomBasedType (no support for symbols by type).\n let symbol;\n switch (mapSymbol.type) {\n case \"circle\":\n symbol = SharedBikeCircle(mapSymbol);\n break;\n case \"hubAndFloatingBike\":\n symbol = HubAndFloatingBike;\n break;\n default:\n symbol = GenericMarker(mapSymbol);\n }\n\n return {\n minZoom: mapSymbol.minZoom,\n symbol\n };\n });\n\n createLeafletElement() {}\n\n updateLeafletElement() {}\n\n startRefreshing() {\n const { refreshVehicles } = this.props;\n\n // Create the timer only if refreshVehicles is a valid function.\n if (typeof refreshVehicles === \"function\") {\n // initial station retrieval\n refreshVehicles();\n\n // set up timer to refresh stations periodically\n this.refreshTimer = setInterval(() => {\n refreshVehicles();\n }, 30000); // defaults to every 30 sec. TODO: make this configurable?\n }\n }\n\n stopRefreshing() {\n if (this.refreshTimer) clearInterval(this.refreshTimer);\n }\n\n /**\n * When the layer is added (or toggled on, or its visibility becomes true),\n * start refreshing vehicle positions.\n */\n onOverlayAdded = () => {\n this.startRefreshing();\n };\n\n /**\n * When the layer is removed (or toggled off, or its visibility becomes false),\n * stop refreshing vehicle positions.\n */\n onOverlayRemoved = () => {\n this.stopRefreshing();\n };\n\n /**\n * Listen to changes on the BaseMap's center or zoom.\n * @param viewport The viewport data. See https://github.com/PaulLeCam/react-leaflet/blob/master/example/components/viewport.js for details.\n */\n onViewportChanged = viewport => {\n const { zoom: newZoom } = viewport;\n if (this.state.zoom !== newZoom) {\n this.setState({ zoom: newZoom });\n }\n };\n\n /**\n * Upon mounting, see whether the vehicles should be fetched,\n * and also call the register overlay prop that the\n * @opentripplanner/base-map package has injected to listen to zoom/position changes.\n */\n componentDidMount() {\n const { registerOverlay, visible } = this.props;\n if (visible) this.startRefreshing();\n if (typeof registerOverlay === \"function\") {\n registerOverlay(this);\n }\n }\n\n componentWillUnmount() {\n this.stopRefreshing();\n }\n\n /**\n * Render some popup html for a station. This contains custom logic for\n * displaying rental vehicles in the TriMet MOD website that might not be\n * applicable to other regions.\n */\n renderPopupForStation = (station, stationIsHub = false) => {\n const { configCompanies, getStationName, setLocation } = this.props;\n const stationName = getStationName(configCompanies, station);\n const location = {\n lat: station.y,\n lon: station.x,\n name: stationName\n };\n return (\n <Popup>\n <BaseMapStyled.MapOverlayPopup>\n <BaseMapStyled.PopupTitle>{stationName}</BaseMapStyled.PopupTitle>\n\n {/* render dock info if it is available */}\n {stationIsHub && (\n <BaseMapStyled.PopupRow>\n <div>Available bikes: {station.bikesAvailable}</div>\n <div>Available docks: {station.spacesAvailable}</div>\n </BaseMapStyled.PopupRow>\n )}\n\n {/* Set as from/to toolbar */}\n <BaseMapStyled.PopupRow>\n <b>Plan a trip:</b>\n <FromToLocationPicker\n location={location}\n setLocation={setLocation}\n />\n </BaseMapStyled.PopupRow>\n </BaseMapStyled.MapOverlayPopup>\n </Popup>\n );\n };\n\n render() {\n const { companies, mapSymbols, stations } = this.props;\n const { zoom } = this.state;\n // Render an empty FeatureGroup if the rental vehicles should not be visible\n // on the map. Otherwise previous stations may still be shown due to some\n // react-leaflet internals, maybe? Also, do not return null because that will\n // prevent the overlay from appearing in the layer controls.\n\n let filteredStations = stations;\n if (companies) {\n filteredStations = stations.filter(\n station =>\n station.networks.filter(value => companies.includes(value)).length > 0\n );\n }\n\n if (!filteredStations || filteredStations.length === 0) {\n return <FeatureGroup />;\n }\n\n // Convert map symbols for this overlay to zoomBasedSymbolType.\n const symbols = this.convertToZoomMarkerSymbols(mapSymbols);\n\n return (\n <FeatureGroup>\n <ZoomBasedMarkers\n entities={filteredStations}\n symbols={symbols}\n symbolTransform={this.renderSymbolWithPopup}\n zoom={zoom}\n />\n </FeatureGroup>\n );\n }\n}\n\nVehicleRentalOverlay.props = {\n /**\n * The entire companies config array.\n */\n configCompanies: PropTypes.arrayOf(coreUtils.types.companyType.isRequired)\n .isRequired,\n /**\n * A list of companies that are applicable to just this instance of the\n * overlay.\n */\n companies: PropTypes.arrayOf(PropTypes.string.isRequired),\n /**\n * An optional custom function to create a string name of a particular vehicle\n * rental station. This function takes two arguments of the configCompanies\n * prop and a vehicle rental station. The function must return a string.\n */\n getStationName: PropTypes.func,\n /**\n * A configuration of what map markers or symbols to show at various\n * zoom levels.\n */\n mapSymbols: coreUtils.types.vehicleRentalMapOverlaySymbolsType,\n /**\n * If specified, a function that will be triggered every 30 seconds whenever this layer is\n * visible.\n */\n refreshVehicles: PropTypes.func,\n /**\n * A callback for when a user clicks on setting this stop as either the from\n * or to location of a new search.\n *\n * This will be dispatched with the following argument:\n *\n * ```js\n * {\n * location: {\n * lat: number,\n * lon: number,\n * name: string\n * },\n * locationType: \"from\" or \"to\"\n * }\n * ```\n */\n setLocation: PropTypes.func.isRequired,\n /**\n * A list of the vehicle rental stations specific to this overlay instance.\n */\n stations: PropTypes.arrayOf(coreUtils.types.stationType),\n /**\n * Whether the overlay is currently visible.\n */\n visible: PropTypes.bool\n};\n\nVehicleRentalOverlay.defaultProps = {\n getStationName: (configCompanies, station) => {\n const stationNetworks = coreUtils.itinerary.getCompaniesLabelFromNetworks(\n station.networks,\n configCompanies\n );\n let stationName = station.name || station.id;\n if (station.isFloatingBike) {\n stationName = `Free-floating bike: ${stationName}`;\n } else if (station.isFloatingCar) {\n stationName = `${stationNetworks} ${stationName}`;\n } else if (station.isFloatingVehicle) {\n // assumes that all floating vehicles are E-scooters\n stationName = `${stationNetworks} E-scooter`;\n }\n return stationName;\n },\n mapSymbols: [\n {\n zoom: 0,\n symbol: GenericMarker\n }\n ],\n refreshVehicles: null,\n stations: [],\n visible: false\n};\n\nexport default withLeaflet(VehicleRentalOverlay);\n"],"file":"index.js"}
1
+ {"version":3,"sources":["../src/index.js"],"names":["flatten","Styled","BaseMapStyled","coreUtils","FromToLocationPicker","ZoomBasedMarkers","PropTypes","React","FormattedMessage","injectIntl","FeatureGroup","MapLayer","Popup","withLeaflet","GenericMarker","HubAndFloatingBike","SharedBikeCircle","defaultEnglishMessages","defaultMessages","makeDefaultGetStationName","intl","defaultGetStationName","configCompanies","station","stationNetworks","itinerary","getCompaniesLabelFromNetworks","networks","stationName","name","id","isFloatingBike","formatMessage","defaultMessage","description","isFloatingCar","company","isFloatingVehicle","VehicleRentalOverlay","props","renderSymbolWithPopup","Symbol","SymbolWrapper","entity","zoom","renderPopupForStation","bikesAvailable","undefined","propTypes","number","isRequired","convertToZoomMarkerSymbols","mapSymbols","map","mapSymbol","symbol","type","minZoom","onOverlayAdded","startRefreshing","onOverlayRemoved","stopRefreshing","onViewportChanged","viewport","newZoom","state","setState","stationIsHub","getStationName","setLocation","getStationNameFunc","location","lat","y","lon","x","value","spacesAvailable","refreshVehicles","refreshTimer","setInterval","clearInterval","leaflet","registerOverlay","visible","getZoom","companies","stations","filteredStations","filter","includes","length","symbols","arrayOf","string","func","bool","defaultProps"],"mappings":"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","sourcesContent":["import flatten from \"flat\";\nimport { Styled as BaseMapStyled } from \"@opentripplanner/base-map\";\nimport coreUtils from \"@opentripplanner/core-utils\";\nimport FromToLocationPicker from \"@opentripplanner/from-to-location-picker\";\nimport ZoomBasedMarkers from \"@opentripplanner/zoom-based-markers\";\nimport PropTypes from \"prop-types\";\nimport React from \"react\";\nimport { FormattedMessage, injectIntl } from \"react-intl\";\nimport { FeatureGroup, MapLayer, Popup, withLeaflet } from \"react-leaflet\";\n\nimport {\n GenericMarker,\n HubAndFloatingBike,\n SharedBikeCircle\n} from \"./DefaultMarkers\";\n\n// Load the default messages.\nimport defaultEnglishMessages from \"../i18n/en-US.yml\";\n\n// HACK: We should flatten the messages loaded above because\n// the YAML loaders behave differently between webpack and our version of jest:\n// - the yaml loader for webpack returns a nested object,\n// - the yaml loader for jest returns messages with flattened ids.\nconst defaultMessages = flatten(defaultEnglishMessages);\n\nfunction makeDefaultGetStationName(intl) {\n return function defaultGetStationName(configCompanies, station) {\n const stationNetworks = coreUtils.itinerary.getCompaniesLabelFromNetworks(\n station.networks,\n configCompanies\n );\n let stationName = station.name || station.id;\n if (station.isFloatingBike) {\n stationName = intl.formatMessage(\n {\n defaultMessage:\n defaultEnglishMessages[\"otpUi.VehicleRentalOverlay.floatingBike\"],\n description: \"Popup title for a free-floating bike\",\n id: \"otpUi.VehicleRentalOverlay.floatingBike\"\n },\n { name: stationName }\n );\n } else if (station.isFloatingCar) {\n stationName = intl.formatMessage(\n {\n defaultMessage:\n defaultEnglishMessages[\"otpUi.VehicleRentalOverlay.floatingCar\"],\n description: \"Popup title for a free-floating car\",\n id: \"otpUi.VehicleRentalOverlay.floatingCar\"\n },\n {\n company: stationNetworks,\n name: stationName\n }\n );\n } else if (station.isFloatingVehicle) {\n // assumes that all floating vehicles are E-scooters\n stationName = intl.formatMessage(\n {\n defaultMessage:\n defaultEnglishMessages[\n \"otpUi.VehicleRentalOverlay.floatingEScooter\"\n ],\n description: \"Popup title for a free-floating e-scooter\",\n id: \"otpUi.VehicleRentalOverlay.floatingEScooter\"\n },\n { company: stationNetworks }\n );\n }\n return stationName;\n };\n}\n\n/**\n * This vehicle rental overlay can be used to render vehicle rentals of various\n * types. This layer can be configured to show different styles of markers at\n * different zoom levels.\n */\nclass VehicleRentalOverlay extends MapLayer {\n constructor(props) {\n super(props);\n this.state = {\n zoom: null\n };\n }\n\n /**\n * This helper method will be passed to the ZoomBasedMarkers symbolTransform prop.\n * It creates a component that inserts a popup\n * as a child of the specified symbol from the mapSymbols prop.\n */\n renderSymbolWithPopup = Symbol => {\n const SymbolWrapper = ({ entity: station, zoom }) => (\n <Symbol entity={station} zoom={zoom}>\n {this.renderPopupForStation(\n station,\n station.bikesAvailable !== undefined && !station.isFloatingBike\n )}\n </Symbol>\n );\n SymbolWrapper.propTypes = {\n // entity: coreUtils.types.stationType.isRequired,\n zoom: PropTypes.number.isRequired\n };\n\n return SymbolWrapper;\n };\n\n /**\n * Convert map symbols to zoomBasedSymbolType.\n */\n convertToZoomMarkerSymbols = mapSymbols =>\n mapSymbols.map(mapSymbol => {\n // If mapSymbol uses zoomBasedSymbolType, use it as is.\n if (mapSymbol.symbol) {\n return mapSymbol;\n }\n\n // Otherwise, convert into zoomBasedType (no support for symbols by type).\n let symbol;\n switch (mapSymbol.type) {\n case \"circle\":\n symbol = SharedBikeCircle(mapSymbol);\n break;\n case \"hubAndFloatingBike\":\n symbol = HubAndFloatingBike;\n break;\n default:\n symbol = GenericMarker(mapSymbol);\n }\n\n return {\n minZoom: mapSymbol.minZoom,\n symbol\n };\n });\n\n createLeafletElement() {}\n\n updateLeafletElement() {}\n\n startRefreshing() {\n const { refreshVehicles } = this.props;\n\n // Create the timer only if refreshVehicles is a valid function.\n if (typeof refreshVehicles === \"function\") {\n // initial station retrieval\n refreshVehicles();\n\n // set up timer to refresh stations periodically\n this.refreshTimer = setInterval(() => {\n refreshVehicles();\n }, 30000); // defaults to every 30 sec. TODO: make this configurable?\n }\n }\n\n stopRefreshing() {\n if (this.refreshTimer) clearInterval(this.refreshTimer);\n }\n\n /**\n * When the layer is added (or toggled on, or its visibility becomes true),\n * start refreshing vehicle positions.\n */\n onOverlayAdded = () => {\n this.startRefreshing();\n };\n\n /**\n * When the layer is removed (or toggled off, or its visibility becomes false),\n * stop refreshing vehicle positions.\n */\n onOverlayRemoved = () => {\n this.stopRefreshing();\n };\n\n /**\n * Listen to changes on the BaseMap's center or zoom.\n * @param viewport The viewport data. See https://github.com/PaulLeCam/react-leaflet/blob/master/example/components/viewport.js for details.\n */\n onViewportChanged = viewport => {\n const { zoom: newZoom } = viewport;\n if (this.state.zoom !== newZoom) {\n this.setState({ zoom: newZoom });\n }\n };\n\n /**\n * Upon mounting, see whether the vehicles should be fetched,\n * and also call the register overlay prop that the\n * @opentripplanner/base-map package has injected to listen to zoom/position changes.\n */\n componentDidMount() {\n const { leaflet, registerOverlay, visible } = this.props;\n this.setState({\n zoom: leaflet.map.getZoom()\n });\n if (visible) this.startRefreshing();\n if (typeof registerOverlay === \"function\") {\n registerOverlay(this);\n }\n }\n\n componentWillUnmount() {\n this.stopRefreshing();\n }\n\n /**\n * Render some popup html for a station. This contains custom logic for\n * displaying rental vehicles in the TriMet MOD website that might not be\n * applicable to other regions.\n */\n renderPopupForStation = (station, stationIsHub = false) => {\n const { configCompanies, getStationName, intl, setLocation } = this.props;\n const getStationNameFunc =\n getStationName || makeDefaultGetStationName(intl);\n const stationName = getStationNameFunc(configCompanies, station);\n const location = {\n lat: station.y,\n lon: station.x,\n name: stationName\n };\n return (\n <Popup>\n <BaseMapStyled.MapOverlayPopup>\n <BaseMapStyled.PopupTitle>{stationName}</BaseMapStyled.PopupTitle>\n\n {/* render dock info if it is available */}\n {stationIsHub && (\n <BaseMapStyled.PopupRow>\n <div>\n <FormattedMessage\n defaultMessage={\n defaultMessages[\"otpUi.VehicleRentalOverlay.availableBikes\"]\n }\n description=\"Label text for the number of bikes available\"\n id=\"otpUi.VehicleRentalOverlay.availableBikes\"\n values={{ value: station.bikesAvailable }}\n />\n </div>\n <div>\n <FormattedMessage\n defaultMessage={\n defaultMessages[\"otpUi.VehicleRentalOverlay.availableDocks\"]\n }\n description=\"Label text for the number of docks available\"\n id=\"otpUi.VehicleRentalOverlay.availableDocks\"\n values={{ value: station.spacesAvailable }}\n />\n </div>\n </BaseMapStyled.PopupRow>\n )}\n\n {/* Set as from/to toolbar */}\n <BaseMapStyled.PopupRow>\n <FromToLocationPicker\n label\n location={location}\n setLocation={setLocation}\n />\n </BaseMapStyled.PopupRow>\n </BaseMapStyled.MapOverlayPopup>\n </Popup>\n );\n };\n\n render() {\n const { companies, leaflet, mapSymbols, stations } = this.props;\n const { zoom = leaflet.map.getZoom() } = this.state;\n // Render an empty FeatureGroup if the rental vehicles should not be visible\n // on the map. Otherwise previous stations may still be shown due to some\n // react-leaflet internals, maybe? Also, do not return null because that will\n // prevent the overlay from appearing in the layer controls.\n\n let filteredStations = stations;\n if (companies) {\n filteredStations = stations.filter(\n station =>\n station.networks.filter(value => companies.includes(value)).length > 0\n );\n }\n\n if (!filteredStations || filteredStations.length === 0) {\n return <FeatureGroup />;\n }\n\n // Convert map symbols for this overlay to zoomBasedSymbolType.\n const symbols = this.convertToZoomMarkerSymbols(mapSymbols);\n\n return (\n <FeatureGroup>\n <ZoomBasedMarkers\n entities={filteredStations}\n symbols={symbols}\n symbolTransform={this.renderSymbolWithPopup}\n zoom={zoom}\n />\n </FeatureGroup>\n );\n }\n}\n\nVehicleRentalOverlay.props = {\n /**\n * The entire companies config array.\n */\n // configCompanies: PropTypes.arrayOf(coreUtils.types.companyType.isRequired)\n // .isRequired,\n /**\n * A list of companies that are applicable to just this instance of the\n * overlay.\n */\n companies: PropTypes.arrayOf(PropTypes.string.isRequired),\n /**\n * An optional custom function to create a string name of a particular vehicle\n * rental station. This function takes two arguments of the configCompanies\n * prop and a vehicle rental station. The function must return a string.\n */\n getStationName: PropTypes.func,\n /**\n * A configuration of what map markers or symbols to show at various\n * zoom levels.\n */\n // mapSymbols: coreUtils.types.vehicleRentalMapOverlaySymbolsType,\n /**\n * If specified, a function that will be triggered every 30 seconds whenever this layer is\n * visible.\n */\n refreshVehicles: PropTypes.func,\n /**\n * A callback for when a user clicks on setting this stop as either the from\n * or to location of a new search.\n *\n * This will be dispatched with the following argument:\n *\n * ```js\n * {\n * location: {\n * lat: number,\n * lon: number,\n * name: string\n * },\n * locationType: \"from\" or \"to\"\n * }\n * ```\n */\n setLocation: PropTypes.func.isRequired,\n /**\n * A list of the vehicle rental stations specific to this overlay instance.\n */\n // stations: PropTypes.arrayOf(coreUtils.types.stationType),\n /**\n * Whether the overlay is currently visible.\n */\n visible: PropTypes.bool\n};\n\nVehicleRentalOverlay.defaultProps = {\n getStationName: null,\n mapSymbols: [\n {\n zoom: 0,\n symbol: GenericMarker\n }\n ],\n refreshVehicles: null,\n stations: [],\n visible: false\n};\n\nexport default withLeaflet(injectIntl(VehicleRentalOverlay));\n"],"file":"index.js"}
package/i18n/en-US.yml ADDED
@@ -0,0 +1,17 @@
1
+ # Default messages for the VehicleRentalOverlay component.
2
+ # To use from a react-intl application:
3
+ # - merge the content of this file into the messages object
4
+ # that has your other localized strings,
5
+ # - flatten the ids, i.e. convert a structure such as
6
+ # otpUi > VehicleRentalOverlay > availableBikes
7
+ # into "otpUi.VehicleRentalOverlay.availableBikes".
8
+ # - pass the resulting object to the messages prop of IntlProvider.
9
+ #
10
+
11
+ otpUi:
12
+ VehicleRentalOverlay:
13
+ availableBikes: "Available bikes: {value}"
14
+ availableDocks: "Available docks: {value}"
15
+ floatingBike: "Free-floating bike: {name}"
16
+ floatingCar: "{company} {name}" # as in "CarCompany Veh1234a"
17
+ floatingEScooter: "{company} E-scooter"
package/i18n/fr.yml ADDED
@@ -0,0 +1,17 @@
1
+ # Default messages for the VehicleRentalOverlay component.
2
+ # To use from a react-intl application:
3
+ # - merge the content of this file into the messages object
4
+ # that has your other localized strings,
5
+ # - flatten the ids, i.e. convert a structure such as
6
+ # otpUi > VehicleRentalOverlay > availableBikes
7
+ # into "otpUi.VehicleRentalOverlay.availableBikes".
8
+ # - pass the resulting object to the messages prop of IntlProvider.
9
+ #
10
+
11
+ otpUi:
12
+ VehicleRentalOverlay:
13
+ availableBikes: "Vélos disponibles : {value}"
14
+ availableDocks: "Bornes disponibles : {value}"
15
+ floatingBike: "Vélo flottant : {name}"
16
+ floatingCar: "{company} {name}" # as in "CarCompany Veh1234a"
17
+ floatingEScooter: "Trottinette {company}"
@@ -11,8 +11,6 @@ var _leaflet = require("leaflet");
11
11
 
12
12
  var _lodash = _interopRequireDefault(require("lodash.memoize"));
13
13
 
14
- var _coreUtils = _interopRequireDefault(require("@opentripplanner/core-utils"));
15
-
16
14
  var _propTypes = _interopRequireDefault(require("prop-types"));
17
15
 
18
16
  var _react = _interopRequireDefault(require("react"));
@@ -42,7 +40,9 @@ const templatePropTypes = {
42
40
  children: _propTypes.default.node,
43
41
 
44
42
  /** The rental vehicle or station to render. */
45
- entity: _coreUtils.default.types.stationType.isRequired,
43
+ // entity: coreUtils.types.stationType.isRequired,
44
+ // eslint-disable-next-line react/forbid-prop-types
45
+ entity: _propTypes.default.object.isRequired,
46
46
 
47
47
  /** leaflet attribute to control tabindex value for keyboaryd-only / SR users */
48
48
  keyboard: _propTypes.default.bool
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/DefaultMarkers/index.js"],"names":["templatePropTypes","children","PropTypes","node","entity","coreUtils","types","stationType","isRequired","keyboard","bool","templateDefaultProps","SharedBikeCircle","dockStrokeColor","fillColor","pixels","strokeColor","GeneratedMarker","station","newStrokeColor","isFloatingBike","y","x","propTypes","defaultProps","HubAndFloatingBike","icon","floatingBikeIcon","capacity","bikesAvailable","spacesAvailable","pctFull","i","Math","round","hubIcons","getStationMarkerByColor","color","className","iconSize","popupAnchor","html","ReactDOMServer","renderToStaticMarkup","GenericMarker","markerIcon"],"mappings":"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","sourcesContent":["import { divIcon } from \"leaflet\";\nimport memoize from \"lodash.memoize\";\nimport coreUtils from \"@opentripplanner/core-utils\";\nimport PropTypes from \"prop-types\";\nimport React from \"react\";\nimport ReactDOMServer from \"react-dom/server\";\nimport { CircleMarker, Marker } from \"react-leaflet\";\n\nimport { floatingBikeIcon, hubIcons } from \"../bike-icons\";\nimport * as Styled from \"../styled\";\n\n/**\n * This file contains default marker types for rental vehicles,\n * that can be used when defining the VehicleRentalOverlay's symbol prop:\n * - SharedBikeCircle\n * - GenericMarker\n * - HubAndFloatingBike\n */\n\n// Prop types reused across components.\nconst templatePropTypes = {\n /** The children of the component. */\n children: PropTypes.node,\n /** The rental vehicle or station to render. */\n entity: coreUtils.types.stationType.isRequired,\n /** leaflet attribute to control tabindex value for keyboaryd-only / SR users */\n keyboard: PropTypes.bool\n};\nconst templateDefaultProps = {\n children: null,\n keyboard: false\n};\n\n/**\n * Renders a shared bike or shared bike dock as a circle\n * with predefined colors and size.\n */\nexport const SharedBikeCircle = ({\n dockStrokeColor,\n fillColor = \"gray\",\n pixels,\n strokeColor\n}) => {\n const GeneratedMarker = ({ children, keyboard, entity: station }) => {\n let newStrokeColor = strokeColor || fillColor;\n\n if (!station.isFloatingBike) {\n newStrokeColor = dockStrokeColor || strokeColor;\n }\n\n return (\n <CircleMarker\n center={[station.y, station.x]}\n color={newStrokeColor}\n fillColor={fillColor}\n fillOpacity={1}\n keyboard={keyboard}\n radius={pixels - (station.isFloatingBike ? 1 : 0)}\n weight={1}\n >\n {children}\n </CircleMarker>\n );\n };\n\n GeneratedMarker.propTypes = templatePropTypes;\n GeneratedMarker.defaultProps = templateDefaultProps;\n return GeneratedMarker;\n};\n\n/**\n * A component that renders rental bike entities\n * either as a bike or a bike dock (or hub, showing spaces available).\n */\nexport const HubAndFloatingBike = ({ children, keyboard, entity: station }) => {\n let icon;\n if (station.isFloatingBike) {\n icon = floatingBikeIcon;\n } else {\n const capacity = station.bikesAvailable + station.spacesAvailable;\n if (capacity === 0) return null;\n const pctFull = station.bikesAvailable / capacity;\n const i = Math.round(pctFull * 9);\n icon = hubIcons[i];\n }\n return (\n <Marker icon={icon} keyboard={keyboard} position={[station.y, station.x]}>\n {children}\n </Marker>\n );\n};\nHubAndFloatingBike.propTypes = templatePropTypes;\nHubAndFloatingBike.defaultProps = templateDefaultProps;\n\n/**\n * Creates and caches a leaflet element icon based on color.\n */\nconst getStationMarkerByColor = memoize(color =>\n divIcon({\n className: \"\",\n iconSize: [11, 16],\n popupAnchor: [0, -6],\n html: ReactDOMServer.renderToStaticMarkup(\n <Styled.StationMarker color={color} />\n )\n })\n);\n\n/**\n * Helper function to create a leaflet Marker component to render entities\n * using fixed fill color.\n * Usage: GenericMarker({ fillColor: \"#F204B5\" })\n */\nexport const GenericMarker = ({ fillColor = \"gray\" }) => {\n const markerIcon = getStationMarkerByColor(fillColor);\n\n const GeneratedMarker = ({ children, keyboard, entity: station }) => (\n <Marker\n icon={markerIcon}\n keyboard={keyboard}\n position={[station.y, station.x]}\n >\n {children}\n </Marker>\n );\n GeneratedMarker.propTypes = templatePropTypes;\n GeneratedMarker.defaultProps = templateDefaultProps;\n return GeneratedMarker;\n};\n"],"file":"index.js"}
1
+ {"version":3,"sources":["../../src/DefaultMarkers/index.js"],"names":["templatePropTypes","children","PropTypes","node","entity","object","isRequired","keyboard","bool","templateDefaultProps","SharedBikeCircle","dockStrokeColor","fillColor","pixels","strokeColor","GeneratedMarker","station","newStrokeColor","isFloatingBike","y","x","propTypes","defaultProps","HubAndFloatingBike","icon","floatingBikeIcon","capacity","bikesAvailable","spacesAvailable","pctFull","i","Math","round","hubIcons","getStationMarkerByColor","color","className","iconSize","popupAnchor","html","ReactDOMServer","renderToStaticMarkup","GenericMarker","markerIcon"],"mappings":"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","sourcesContent":["import { divIcon } from \"leaflet\";\nimport memoize from \"lodash.memoize\";\nimport PropTypes from \"prop-types\";\nimport React from \"react\";\nimport ReactDOMServer from \"react-dom/server\";\nimport { CircleMarker, Marker } from \"react-leaflet\";\n\nimport { floatingBikeIcon, hubIcons } from \"../bike-icons\";\nimport * as Styled from \"../styled\";\n\n/**\n * This file contains default marker types for rental vehicles,\n * that can be used when defining the VehicleRentalOverlay's symbol prop:\n * - SharedBikeCircle\n * - GenericMarker\n * - HubAndFloatingBike\n */\n\n// Prop types reused across components.\nconst templatePropTypes = {\n /** The children of the component. */\n children: PropTypes.node,\n /** The rental vehicle or station to render. */\n // entity: coreUtils.types.stationType.isRequired,\n // eslint-disable-next-line react/forbid-prop-types\n entity: PropTypes.object.isRequired,\n /** leaflet attribute to control tabindex value for keyboaryd-only / SR users */\n keyboard: PropTypes.bool\n};\nconst templateDefaultProps = {\n children: null,\n keyboard: false\n};\n\n/**\n * Renders a shared bike or shared bike dock as a circle\n * with predefined colors and size.\n */\nexport const SharedBikeCircle = ({\n dockStrokeColor,\n fillColor = \"gray\",\n pixels,\n strokeColor\n}) => {\n const GeneratedMarker = ({ children, keyboard, entity: station }) => {\n let newStrokeColor = strokeColor || fillColor;\n\n if (!station.isFloatingBike) {\n newStrokeColor = dockStrokeColor || strokeColor;\n }\n\n return (\n <CircleMarker\n center={[station.y, station.x]}\n color={newStrokeColor}\n fillColor={fillColor}\n fillOpacity={1}\n keyboard={keyboard}\n radius={pixels - (station.isFloatingBike ? 1 : 0)}\n weight={1}\n >\n {children}\n </CircleMarker>\n );\n };\n\n GeneratedMarker.propTypes = templatePropTypes;\n GeneratedMarker.defaultProps = templateDefaultProps;\n return GeneratedMarker;\n};\n\n/**\n * A component that renders rental bike entities\n * either as a bike or a bike dock (or hub, showing spaces available).\n */\nexport const HubAndFloatingBike = ({ children, keyboard, entity: station }) => {\n let icon;\n if (station.isFloatingBike) {\n icon = floatingBikeIcon;\n } else {\n const capacity = station.bikesAvailable + station.spacesAvailable;\n if (capacity === 0) return null;\n const pctFull = station.bikesAvailable / capacity;\n const i = Math.round(pctFull * 9);\n icon = hubIcons[i];\n }\n return (\n <Marker icon={icon} keyboard={keyboard} position={[station.y, station.x]}>\n {children}\n </Marker>\n );\n};\nHubAndFloatingBike.propTypes = templatePropTypes;\nHubAndFloatingBike.defaultProps = templateDefaultProps;\n\n/**\n * Creates and caches a leaflet element icon based on color.\n */\nconst getStationMarkerByColor = memoize(color =>\n divIcon({\n className: \"\",\n iconSize: [11, 16],\n popupAnchor: [0, -6],\n html: ReactDOMServer.renderToStaticMarkup(\n <Styled.StationMarker color={color} />\n )\n })\n);\n\n/**\n * Helper function to create a leaflet Marker component to render entities\n * using fixed fill color.\n * Usage: GenericMarker({ fillColor: \"#F204B5\" })\n */\nexport const GenericMarker = ({ fillColor = \"gray\" }) => {\n const markerIcon = getStationMarkerByColor(fillColor);\n\n const GeneratedMarker = ({ children, keyboard, entity: station }) => (\n <Marker\n icon={markerIcon}\n keyboard={keyboard}\n position={[station.y, station.x]}\n >\n {children}\n </Marker>\n );\n GeneratedMarker.propTypes = templatePropTypes;\n GeneratedMarker.defaultProps = templateDefaultProps;\n return GeneratedMarker;\n};\n"],"file":"index.js"}
package/lib/index.js CHANGED
@@ -7,6 +7,8 @@ Object.defineProperty(exports, "__esModule", {
7
7
  });
8
8
  exports.default = void 0;
9
9
 
10
+ var _flat = _interopRequireDefault(require("flat"));
11
+
10
12
  var _baseMap = require("@opentripplanner/base-map");
11
13
 
12
14
  var _coreUtils = _interopRequireDefault(require("@opentripplanner/core-utils"));
@@ -19,15 +21,65 @@ var _propTypes = _interopRequireDefault(require("prop-types"));
19
21
 
20
22
  var _react = _interopRequireDefault(require("react"));
21
23
 
24
+ var _reactIntl = require("react-intl");
25
+
22
26
  var _reactLeaflet = require("react-leaflet");
23
27
 
24
28
  var _DefaultMarkers = require("./DefaultMarkers");
25
29
 
30
+ var _enUS = _interopRequireDefault(require("../i18n/en-US.yml"));
31
+
32
+ // Load the default messages.
33
+ // HACK: We should flatten the messages loaded above because
34
+ // the YAML loaders behave differently between webpack and our version of jest:
35
+ // - the yaml loader for webpack returns a nested object,
36
+ // - the yaml loader for jest returns messages with flattened ids.
37
+ const defaultMessages = (0, _flat.default)(_enUS.default);
38
+
39
+ function makeDefaultGetStationName(intl) {
40
+ return function defaultGetStationName(configCompanies, station) {
41
+ const stationNetworks = _coreUtils.default.itinerary.getCompaniesLabelFromNetworks(station.networks, configCompanies);
42
+
43
+ let stationName = station.name || station.id;
44
+
45
+ if (station.isFloatingBike) {
46
+ stationName = intl.formatMessage({
47
+ defaultMessage: _enUS.default["otpUi.VehicleRentalOverlay.floatingBike"],
48
+ description: "Popup title for a free-floating bike",
49
+ id: "otpUi.VehicleRentalOverlay.floatingBike"
50
+ }, {
51
+ name: stationName
52
+ });
53
+ } else if (station.isFloatingCar) {
54
+ stationName = intl.formatMessage({
55
+ defaultMessage: _enUS.default["otpUi.VehicleRentalOverlay.floatingCar"],
56
+ description: "Popup title for a free-floating car",
57
+ id: "otpUi.VehicleRentalOverlay.floatingCar"
58
+ }, {
59
+ company: stationNetworks,
60
+ name: stationName
61
+ });
62
+ } else if (station.isFloatingVehicle) {
63
+ // assumes that all floating vehicles are E-scooters
64
+ stationName = intl.formatMessage({
65
+ defaultMessage: _enUS.default["otpUi.VehicleRentalOverlay.floatingEScooter"],
66
+ description: "Popup title for a free-floating e-scooter",
67
+ id: "otpUi.VehicleRentalOverlay.floatingEScooter"
68
+ }, {
69
+ company: stationNetworks
70
+ });
71
+ }
72
+
73
+ return stationName;
74
+ };
75
+ }
26
76
  /**
27
77
  * This vehicle rental overlay can be used to render vehicle rentals of various
28
78
  * types. This layer can be configured to show different styles of markers at
29
79
  * different zoom levels.
30
80
  */
81
+
82
+
31
83
  class VehicleRentalOverlay extends _reactLeaflet.MapLayer {
32
84
  constructor(props) {
33
85
  super(props);
@@ -42,7 +94,7 @@ class VehicleRentalOverlay extends _reactLeaflet.MapLayer {
42
94
  }, this.renderPopupForStation(station, station.bikesAvailable !== undefined && !station.isFloatingBike));
43
95
 
44
96
  SymbolWrapper.propTypes = {
45
- entity: _coreUtils.default.types.stationType.isRequired,
97
+ // entity: coreUtils.types.stationType.isRequired,
46
98
  zoom: _propTypes.default.number.isRequired
47
99
  };
48
100
  return SymbolWrapper;
@@ -100,22 +152,39 @@ class VehicleRentalOverlay extends _reactLeaflet.MapLayer {
100
152
  const {
101
153
  configCompanies,
102
154
  getStationName,
155
+ intl,
103
156
  setLocation
104
157
  } = this.props;
105
- const stationName = getStationName(configCompanies, station);
158
+ const getStationNameFunc = getStationName || makeDefaultGetStationName(intl);
159
+ const stationName = getStationNameFunc(configCompanies, station);
106
160
  const location = {
107
161
  lat: station.y,
108
162
  lon: station.x,
109
163
  name: stationName
110
164
  };
111
- return /*#__PURE__*/_react.default.createElement(_reactLeaflet.Popup, null, /*#__PURE__*/_react.default.createElement(_baseMap.Styled.MapOverlayPopup, null, /*#__PURE__*/_react.default.createElement(_baseMap.Styled.PopupTitle, null, stationName), stationIsHub && /*#__PURE__*/_react.default.createElement(_baseMap.Styled.PopupRow, null, /*#__PURE__*/_react.default.createElement("div", null, "Available bikes: ", station.bikesAvailable), /*#__PURE__*/_react.default.createElement("div", null, "Available docks: ", station.spacesAvailable)), /*#__PURE__*/_react.default.createElement(_baseMap.Styled.PopupRow, null, /*#__PURE__*/_react.default.createElement("b", null, "Plan a trip:"), /*#__PURE__*/_react.default.createElement(_fromToLocationPicker.default, {
165
+ return /*#__PURE__*/_react.default.createElement(_reactLeaflet.Popup, null, /*#__PURE__*/_react.default.createElement(_baseMap.Styled.MapOverlayPopup, null, /*#__PURE__*/_react.default.createElement(_baseMap.Styled.PopupTitle, null, stationName), stationIsHub && /*#__PURE__*/_react.default.createElement(_baseMap.Styled.PopupRow, null, /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(_reactIntl.FormattedMessage, {
166
+ defaultMessage: defaultMessages["otpUi.VehicleRentalOverlay.availableBikes"],
167
+ description: "Label text for the number of bikes available",
168
+ id: "otpUi.VehicleRentalOverlay.availableBikes",
169
+ values: {
170
+ value: station.bikesAvailable
171
+ }
172
+ })), /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(_reactIntl.FormattedMessage, {
173
+ defaultMessage: defaultMessages["otpUi.VehicleRentalOverlay.availableDocks"],
174
+ description: "Label text for the number of docks available",
175
+ id: "otpUi.VehicleRentalOverlay.availableDocks",
176
+ values: {
177
+ value: station.spacesAvailable
178
+ }
179
+ }))), /*#__PURE__*/_react.default.createElement(_baseMap.Styled.PopupRow, null, /*#__PURE__*/_react.default.createElement(_fromToLocationPicker.default, {
180
+ label: true,
112
181
  location: location,
113
182
  setLocation: setLocation
114
183
  }))));
115
184
  };
116
185
 
117
186
  this.state = {
118
- zoom: props.leaflet.map.getZoom()
187
+ zoom: null
119
188
  };
120
189
  }
121
190
  /**
@@ -160,9 +229,13 @@ class VehicleRentalOverlay extends _reactLeaflet.MapLayer {
160
229
  */
161
230
  componentDidMount() {
162
231
  const {
232
+ leaflet,
163
233
  registerOverlay,
164
234
  visible
165
235
  } = this.props;
236
+ this.setState({
237
+ zoom: leaflet.map.getZoom()
238
+ });
166
239
  if (visible) this.startRefreshing();
167
240
 
168
241
  if (typeof registerOverlay === "function") {
@@ -183,11 +256,12 @@ class VehicleRentalOverlay extends _reactLeaflet.MapLayer {
183
256
  render() {
184
257
  const {
185
258
  companies,
259
+ leaflet,
186
260
  mapSymbols,
187
261
  stations
188
262
  } = this.props;
189
263
  const {
190
- zoom
264
+ zoom = leaflet.map.getZoom()
191
265
  } = this.state; // Render an empty FeatureGroup if the rental vehicles should not be visible
192
266
  // on the map. Otherwise previous stations may still be shown due to some
193
267
  // react-leaflet internals, maybe? Also, do not return null because that will
@@ -219,7 +293,8 @@ VehicleRentalOverlay.props = {
219
293
  /**
220
294
  * The entire companies config array.
221
295
  */
222
- configCompanies: _propTypes.default.arrayOf(_coreUtils.default.types.companyType.isRequired).isRequired,
296
+ // configCompanies: PropTypes.arrayOf(coreUtils.types.companyType.isRequired)
297
+ // .isRequired,
223
298
 
224
299
  /**
225
300
  * A list of companies that are applicable to just this instance of the
@@ -238,7 +313,7 @@ VehicleRentalOverlay.props = {
238
313
  * A configuration of what map markers or symbols to show at various
239
314
  * zoom levels.
240
315
  */
241
- mapSymbols: _coreUtils.default.types.vehicleRentalMapOverlaySymbolsType,
316
+ // mapSymbols: coreUtils.types.vehicleRentalMapOverlaySymbolsType,
242
317
 
243
318
  /**
244
319
  * If specified, a function that will be triggered every 30 seconds whenever this layer is
@@ -268,7 +343,7 @@ VehicleRentalOverlay.props = {
268
343
  /**
269
344
  * A list of the vehicle rental stations specific to this overlay instance.
270
345
  */
271
- stations: _propTypes.default.arrayOf(_coreUtils.default.types.stationType),
346
+ // stations: PropTypes.arrayOf(coreUtils.types.stationType),
272
347
 
273
348
  /**
274
349
  * Whether the overlay is currently visible.
@@ -276,22 +351,7 @@ VehicleRentalOverlay.props = {
276
351
  visible: _propTypes.default.bool
277
352
  };
278
353
  VehicleRentalOverlay.defaultProps = {
279
- getStationName: (configCompanies, station) => {
280
- const stationNetworks = _coreUtils.default.itinerary.getCompaniesLabelFromNetworks(station.networks, configCompanies);
281
-
282
- let stationName = station.name || station.id;
283
-
284
- if (station.isFloatingBike) {
285
- stationName = `Free-floating bike: ${stationName}`;
286
- } else if (station.isFloatingCar) {
287
- stationName = `${stationNetworks} ${stationName}`;
288
- } else if (station.isFloatingVehicle) {
289
- // assumes that all floating vehicles are E-scooters
290
- stationName = `${stationNetworks} E-scooter`;
291
- }
292
-
293
- return stationName;
294
- },
354
+ getStationName: null,
295
355
  mapSymbols: [{
296
356
  zoom: 0,
297
357
  symbol: _DefaultMarkers.GenericMarker
@@ -301,7 +361,7 @@ VehicleRentalOverlay.defaultProps = {
301
361
  visible: false
302
362
  };
303
363
 
304
- var _default = (0, _reactLeaflet.withLeaflet)(VehicleRentalOverlay);
364
+ var _default = (0, _reactLeaflet.withLeaflet)((0, _reactIntl.injectIntl)(VehicleRentalOverlay));
305
365
 
306
366
  exports.default = _default;
307
367
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.js"],"names":["VehicleRentalOverlay","MapLayer","constructor","props","renderSymbolWithPopup","Symbol","SymbolWrapper","entity","station","zoom","renderPopupForStation","bikesAvailable","undefined","isFloatingBike","propTypes","coreUtils","types","stationType","isRequired","PropTypes","number","convertToZoomMarkerSymbols","mapSymbols","map","mapSymbol","symbol","type","HubAndFloatingBike","minZoom","onOverlayAdded","startRefreshing","onOverlayRemoved","stopRefreshing","onViewportChanged","viewport","newZoom","state","setState","stationIsHub","configCompanies","getStationName","setLocation","stationName","location","lat","y","lon","x","name","spacesAvailable","leaflet","getZoom","createLeafletElement","updateLeafletElement","refreshVehicles","refreshTimer","setInterval","clearInterval","componentDidMount","registerOverlay","visible","componentWillUnmount","render","companies","stations","filteredStations","filter","networks","value","includes","length","symbols","arrayOf","companyType","string","func","vehicleRentalMapOverlaySymbolsType","bool","defaultProps","stationNetworks","itinerary","getCompaniesLabelFromNetworks","id","isFloatingCar","isFloatingVehicle","GenericMarker"],"mappings":"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","sourcesContent":["import { Styled as BaseMapStyled } from \"@opentripplanner/base-map\";\nimport coreUtils from \"@opentripplanner/core-utils\";\nimport FromToLocationPicker from \"@opentripplanner/from-to-location-picker\";\nimport ZoomBasedMarkers from \"@opentripplanner/zoom-based-markers\";\nimport PropTypes from \"prop-types\";\nimport React from \"react\";\nimport { FeatureGroup, MapLayer, Popup, withLeaflet } from \"react-leaflet\";\n\nimport {\n GenericMarker,\n HubAndFloatingBike,\n SharedBikeCircle\n} from \"./DefaultMarkers\";\n\n/**\n * This vehicle rental overlay can be used to render vehicle rentals of various\n * types. This layer can be configured to show different styles of markers at\n * different zoom levels.\n */\nclass VehicleRentalOverlay extends MapLayer {\n constructor(props) {\n super(props);\n this.state = {\n zoom: props.leaflet.map.getZoom()\n };\n }\n\n /**\n * This helper method will be passed to the ZoomBasedMarkers symbolTransform prop.\n * It creates a component that inserts a popup\n * as a child of the specified symbol from the mapSymbols prop.\n */\n renderSymbolWithPopup = Symbol => {\n const SymbolWrapper = ({ entity: station, zoom }) => (\n <Symbol entity={station} zoom={zoom}>\n {this.renderPopupForStation(\n station,\n station.bikesAvailable !== undefined && !station.isFloatingBike\n )}\n </Symbol>\n );\n SymbolWrapper.propTypes = {\n entity: coreUtils.types.stationType.isRequired,\n zoom: PropTypes.number.isRequired\n };\n\n return SymbolWrapper;\n };\n\n /**\n * Convert map symbols to zoomBasedSymbolType.\n */\n convertToZoomMarkerSymbols = mapSymbols =>\n mapSymbols.map(mapSymbol => {\n // If mapSymbol uses zoomBasedSymbolType, use it as is.\n if (mapSymbol.symbol) {\n return mapSymbol;\n }\n\n // Otherwise, convert into zoomBasedType (no support for symbols by type).\n let symbol;\n switch (mapSymbol.type) {\n case \"circle\":\n symbol = SharedBikeCircle(mapSymbol);\n break;\n case \"hubAndFloatingBike\":\n symbol = HubAndFloatingBike;\n break;\n default:\n symbol = GenericMarker(mapSymbol);\n }\n\n return {\n minZoom: mapSymbol.minZoom,\n symbol\n };\n });\n\n createLeafletElement() {}\n\n updateLeafletElement() {}\n\n startRefreshing() {\n const { refreshVehicles } = this.props;\n\n // Create the timer only if refreshVehicles is a valid function.\n if (typeof refreshVehicles === \"function\") {\n // initial station retrieval\n refreshVehicles();\n\n // set up timer to refresh stations periodically\n this.refreshTimer = setInterval(() => {\n refreshVehicles();\n }, 30000); // defaults to every 30 sec. TODO: make this configurable?\n }\n }\n\n stopRefreshing() {\n if (this.refreshTimer) clearInterval(this.refreshTimer);\n }\n\n /**\n * When the layer is added (or toggled on, or its visibility becomes true),\n * start refreshing vehicle positions.\n */\n onOverlayAdded = () => {\n this.startRefreshing();\n };\n\n /**\n * When the layer is removed (or toggled off, or its visibility becomes false),\n * stop refreshing vehicle positions.\n */\n onOverlayRemoved = () => {\n this.stopRefreshing();\n };\n\n /**\n * Listen to changes on the BaseMap's center or zoom.\n * @param viewport The viewport data. See https://github.com/PaulLeCam/react-leaflet/blob/master/example/components/viewport.js for details.\n */\n onViewportChanged = viewport => {\n const { zoom: newZoom } = viewport;\n if (this.state.zoom !== newZoom) {\n this.setState({ zoom: newZoom });\n }\n };\n\n /**\n * Upon mounting, see whether the vehicles should be fetched,\n * and also call the register overlay prop that the\n * @opentripplanner/base-map package has injected to listen to zoom/position changes.\n */\n componentDidMount() {\n const { registerOverlay, visible } = this.props;\n if (visible) this.startRefreshing();\n if (typeof registerOverlay === \"function\") {\n registerOverlay(this);\n }\n }\n\n componentWillUnmount() {\n this.stopRefreshing();\n }\n\n /**\n * Render some popup html for a station. This contains custom logic for\n * displaying rental vehicles in the TriMet MOD website that might not be\n * applicable to other regions.\n */\n renderPopupForStation = (station, stationIsHub = false) => {\n const { configCompanies, getStationName, setLocation } = this.props;\n const stationName = getStationName(configCompanies, station);\n const location = {\n lat: station.y,\n lon: station.x,\n name: stationName\n };\n return (\n <Popup>\n <BaseMapStyled.MapOverlayPopup>\n <BaseMapStyled.PopupTitle>{stationName}</BaseMapStyled.PopupTitle>\n\n {/* render dock info if it is available */}\n {stationIsHub && (\n <BaseMapStyled.PopupRow>\n <div>Available bikes: {station.bikesAvailable}</div>\n <div>Available docks: {station.spacesAvailable}</div>\n </BaseMapStyled.PopupRow>\n )}\n\n {/* Set as from/to toolbar */}\n <BaseMapStyled.PopupRow>\n <b>Plan a trip:</b>\n <FromToLocationPicker\n location={location}\n setLocation={setLocation}\n />\n </BaseMapStyled.PopupRow>\n </BaseMapStyled.MapOverlayPopup>\n </Popup>\n );\n };\n\n render() {\n const { companies, mapSymbols, stations } = this.props;\n const { zoom } = this.state;\n // Render an empty FeatureGroup if the rental vehicles should not be visible\n // on the map. Otherwise previous stations may still be shown due to some\n // react-leaflet internals, maybe? Also, do not return null because that will\n // prevent the overlay from appearing in the layer controls.\n\n let filteredStations = stations;\n if (companies) {\n filteredStations = stations.filter(\n station =>\n station.networks.filter(value => companies.includes(value)).length > 0\n );\n }\n\n if (!filteredStations || filteredStations.length === 0) {\n return <FeatureGroup />;\n }\n\n // Convert map symbols for this overlay to zoomBasedSymbolType.\n const symbols = this.convertToZoomMarkerSymbols(mapSymbols);\n\n return (\n <FeatureGroup>\n <ZoomBasedMarkers\n entities={filteredStations}\n symbols={symbols}\n symbolTransform={this.renderSymbolWithPopup}\n zoom={zoom}\n />\n </FeatureGroup>\n );\n }\n}\n\nVehicleRentalOverlay.props = {\n /**\n * The entire companies config array.\n */\n configCompanies: PropTypes.arrayOf(coreUtils.types.companyType.isRequired)\n .isRequired,\n /**\n * A list of companies that are applicable to just this instance of the\n * overlay.\n */\n companies: PropTypes.arrayOf(PropTypes.string.isRequired),\n /**\n * An optional custom function to create a string name of a particular vehicle\n * rental station. This function takes two arguments of the configCompanies\n * prop and a vehicle rental station. The function must return a string.\n */\n getStationName: PropTypes.func,\n /**\n * A configuration of what map markers or symbols to show at various\n * zoom levels.\n */\n mapSymbols: coreUtils.types.vehicleRentalMapOverlaySymbolsType,\n /**\n * If specified, a function that will be triggered every 30 seconds whenever this layer is\n * visible.\n */\n refreshVehicles: PropTypes.func,\n /**\n * A callback for when a user clicks on setting this stop as either the from\n * or to location of a new search.\n *\n * This will be dispatched with the following argument:\n *\n * ```js\n * {\n * location: {\n * lat: number,\n * lon: number,\n * name: string\n * },\n * locationType: \"from\" or \"to\"\n * }\n * ```\n */\n setLocation: PropTypes.func.isRequired,\n /**\n * A list of the vehicle rental stations specific to this overlay instance.\n */\n stations: PropTypes.arrayOf(coreUtils.types.stationType),\n /**\n * Whether the overlay is currently visible.\n */\n visible: PropTypes.bool\n};\n\nVehicleRentalOverlay.defaultProps = {\n getStationName: (configCompanies, station) => {\n const stationNetworks = coreUtils.itinerary.getCompaniesLabelFromNetworks(\n station.networks,\n configCompanies\n );\n let stationName = station.name || station.id;\n if (station.isFloatingBike) {\n stationName = `Free-floating bike: ${stationName}`;\n } else if (station.isFloatingCar) {\n stationName = `${stationNetworks} ${stationName}`;\n } else if (station.isFloatingVehicle) {\n // assumes that all floating vehicles are E-scooters\n stationName = `${stationNetworks} E-scooter`;\n }\n return stationName;\n },\n mapSymbols: [\n {\n zoom: 0,\n symbol: GenericMarker\n }\n ],\n refreshVehicles: null,\n stations: [],\n visible: false\n};\n\nexport default withLeaflet(VehicleRentalOverlay);\n"],"file":"index.js"}
1
+ {"version":3,"sources":["../src/index.js"],"names":["defaultMessages","defaultEnglishMessages","makeDefaultGetStationName","intl","defaultGetStationName","configCompanies","station","stationNetworks","coreUtils","itinerary","getCompaniesLabelFromNetworks","networks","stationName","name","id","isFloatingBike","formatMessage","defaultMessage","description","isFloatingCar","company","isFloatingVehicle","VehicleRentalOverlay","MapLayer","constructor","props","renderSymbolWithPopup","Symbol","SymbolWrapper","entity","zoom","renderPopupForStation","bikesAvailable","undefined","propTypes","PropTypes","number","isRequired","convertToZoomMarkerSymbols","mapSymbols","map","mapSymbol","symbol","type","HubAndFloatingBike","minZoom","onOverlayAdded","startRefreshing","onOverlayRemoved","stopRefreshing","onViewportChanged","viewport","newZoom","state","setState","stationIsHub","getStationName","setLocation","getStationNameFunc","location","lat","y","lon","x","value","spacesAvailable","createLeafletElement","updateLeafletElement","refreshVehicles","refreshTimer","setInterval","clearInterval","componentDidMount","leaflet","registerOverlay","visible","getZoom","componentWillUnmount","render","companies","stations","filteredStations","filter","includes","length","symbols","arrayOf","string","func","bool","defaultProps","GenericMarker"],"mappings":"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","sourcesContent":["import flatten from \"flat\";\nimport { Styled as BaseMapStyled } from \"@opentripplanner/base-map\";\nimport coreUtils from \"@opentripplanner/core-utils\";\nimport FromToLocationPicker from \"@opentripplanner/from-to-location-picker\";\nimport ZoomBasedMarkers from \"@opentripplanner/zoom-based-markers\";\nimport PropTypes from \"prop-types\";\nimport React from \"react\";\nimport { FormattedMessage, injectIntl } from \"react-intl\";\nimport { FeatureGroup, MapLayer, Popup, withLeaflet } from \"react-leaflet\";\n\nimport {\n GenericMarker,\n HubAndFloatingBike,\n SharedBikeCircle\n} from \"./DefaultMarkers\";\n\n// Load the default messages.\nimport defaultEnglishMessages from \"../i18n/en-US.yml\";\n\n// HACK: We should flatten the messages loaded above because\n// the YAML loaders behave differently between webpack and our version of jest:\n// - the yaml loader for webpack returns a nested object,\n// - the yaml loader for jest returns messages with flattened ids.\nconst defaultMessages = flatten(defaultEnglishMessages);\n\nfunction makeDefaultGetStationName(intl) {\n return function defaultGetStationName(configCompanies, station) {\n const stationNetworks = coreUtils.itinerary.getCompaniesLabelFromNetworks(\n station.networks,\n configCompanies\n );\n let stationName = station.name || station.id;\n if (station.isFloatingBike) {\n stationName = intl.formatMessage(\n {\n defaultMessage:\n defaultEnglishMessages[\"otpUi.VehicleRentalOverlay.floatingBike\"],\n description: \"Popup title for a free-floating bike\",\n id: \"otpUi.VehicleRentalOverlay.floatingBike\"\n },\n { name: stationName }\n );\n } else if (station.isFloatingCar) {\n stationName = intl.formatMessage(\n {\n defaultMessage:\n defaultEnglishMessages[\"otpUi.VehicleRentalOverlay.floatingCar\"],\n description: \"Popup title for a free-floating car\",\n id: \"otpUi.VehicleRentalOverlay.floatingCar\"\n },\n {\n company: stationNetworks,\n name: stationName\n }\n );\n } else if (station.isFloatingVehicle) {\n // assumes that all floating vehicles are E-scooters\n stationName = intl.formatMessage(\n {\n defaultMessage:\n defaultEnglishMessages[\n \"otpUi.VehicleRentalOverlay.floatingEScooter\"\n ],\n description: \"Popup title for a free-floating e-scooter\",\n id: \"otpUi.VehicleRentalOverlay.floatingEScooter\"\n },\n { company: stationNetworks }\n );\n }\n return stationName;\n };\n}\n\n/**\n * This vehicle rental overlay can be used to render vehicle rentals of various\n * types. This layer can be configured to show different styles of markers at\n * different zoom levels.\n */\nclass VehicleRentalOverlay extends MapLayer {\n constructor(props) {\n super(props);\n this.state = {\n zoom: null\n };\n }\n\n /**\n * This helper method will be passed to the ZoomBasedMarkers symbolTransform prop.\n * It creates a component that inserts a popup\n * as a child of the specified symbol from the mapSymbols prop.\n */\n renderSymbolWithPopup = Symbol => {\n const SymbolWrapper = ({ entity: station, zoom }) => (\n <Symbol entity={station} zoom={zoom}>\n {this.renderPopupForStation(\n station,\n station.bikesAvailable !== undefined && !station.isFloatingBike\n )}\n </Symbol>\n );\n SymbolWrapper.propTypes = {\n // entity: coreUtils.types.stationType.isRequired,\n zoom: PropTypes.number.isRequired\n };\n\n return SymbolWrapper;\n };\n\n /**\n * Convert map symbols to zoomBasedSymbolType.\n */\n convertToZoomMarkerSymbols = mapSymbols =>\n mapSymbols.map(mapSymbol => {\n // If mapSymbol uses zoomBasedSymbolType, use it as is.\n if (mapSymbol.symbol) {\n return mapSymbol;\n }\n\n // Otherwise, convert into zoomBasedType (no support for symbols by type).\n let symbol;\n switch (mapSymbol.type) {\n case \"circle\":\n symbol = SharedBikeCircle(mapSymbol);\n break;\n case \"hubAndFloatingBike\":\n symbol = HubAndFloatingBike;\n break;\n default:\n symbol = GenericMarker(mapSymbol);\n }\n\n return {\n minZoom: mapSymbol.minZoom,\n symbol\n };\n });\n\n createLeafletElement() {}\n\n updateLeafletElement() {}\n\n startRefreshing() {\n const { refreshVehicles } = this.props;\n\n // Create the timer only if refreshVehicles is a valid function.\n if (typeof refreshVehicles === \"function\") {\n // initial station retrieval\n refreshVehicles();\n\n // set up timer to refresh stations periodically\n this.refreshTimer = setInterval(() => {\n refreshVehicles();\n }, 30000); // defaults to every 30 sec. TODO: make this configurable?\n }\n }\n\n stopRefreshing() {\n if (this.refreshTimer) clearInterval(this.refreshTimer);\n }\n\n /**\n * When the layer is added (or toggled on, or its visibility becomes true),\n * start refreshing vehicle positions.\n */\n onOverlayAdded = () => {\n this.startRefreshing();\n };\n\n /**\n * When the layer is removed (or toggled off, or its visibility becomes false),\n * stop refreshing vehicle positions.\n */\n onOverlayRemoved = () => {\n this.stopRefreshing();\n };\n\n /**\n * Listen to changes on the BaseMap's center or zoom.\n * @param viewport The viewport data. See https://github.com/PaulLeCam/react-leaflet/blob/master/example/components/viewport.js for details.\n */\n onViewportChanged = viewport => {\n const { zoom: newZoom } = viewport;\n if (this.state.zoom !== newZoom) {\n this.setState({ zoom: newZoom });\n }\n };\n\n /**\n * Upon mounting, see whether the vehicles should be fetched,\n * and also call the register overlay prop that the\n * @opentripplanner/base-map package has injected to listen to zoom/position changes.\n */\n componentDidMount() {\n const { leaflet, registerOverlay, visible } = this.props;\n this.setState({\n zoom: leaflet.map.getZoom()\n });\n if (visible) this.startRefreshing();\n if (typeof registerOverlay === \"function\") {\n registerOverlay(this);\n }\n }\n\n componentWillUnmount() {\n this.stopRefreshing();\n }\n\n /**\n * Render some popup html for a station. This contains custom logic for\n * displaying rental vehicles in the TriMet MOD website that might not be\n * applicable to other regions.\n */\n renderPopupForStation = (station, stationIsHub = false) => {\n const { configCompanies, getStationName, intl, setLocation } = this.props;\n const getStationNameFunc =\n getStationName || makeDefaultGetStationName(intl);\n const stationName = getStationNameFunc(configCompanies, station);\n const location = {\n lat: station.y,\n lon: station.x,\n name: stationName\n };\n return (\n <Popup>\n <BaseMapStyled.MapOverlayPopup>\n <BaseMapStyled.PopupTitle>{stationName}</BaseMapStyled.PopupTitle>\n\n {/* render dock info if it is available */}\n {stationIsHub && (\n <BaseMapStyled.PopupRow>\n <div>\n <FormattedMessage\n defaultMessage={\n defaultMessages[\"otpUi.VehicleRentalOverlay.availableBikes\"]\n }\n description=\"Label text for the number of bikes available\"\n id=\"otpUi.VehicleRentalOverlay.availableBikes\"\n values={{ value: station.bikesAvailable }}\n />\n </div>\n <div>\n <FormattedMessage\n defaultMessage={\n defaultMessages[\"otpUi.VehicleRentalOverlay.availableDocks\"]\n }\n description=\"Label text for the number of docks available\"\n id=\"otpUi.VehicleRentalOverlay.availableDocks\"\n values={{ value: station.spacesAvailable }}\n />\n </div>\n </BaseMapStyled.PopupRow>\n )}\n\n {/* Set as from/to toolbar */}\n <BaseMapStyled.PopupRow>\n <FromToLocationPicker\n label\n location={location}\n setLocation={setLocation}\n />\n </BaseMapStyled.PopupRow>\n </BaseMapStyled.MapOverlayPopup>\n </Popup>\n );\n };\n\n render() {\n const { companies, leaflet, mapSymbols, stations } = this.props;\n const { zoom = leaflet.map.getZoom() } = this.state;\n // Render an empty FeatureGroup if the rental vehicles should not be visible\n // on the map. Otherwise previous stations may still be shown due to some\n // react-leaflet internals, maybe? Also, do not return null because that will\n // prevent the overlay from appearing in the layer controls.\n\n let filteredStations = stations;\n if (companies) {\n filteredStations = stations.filter(\n station =>\n station.networks.filter(value => companies.includes(value)).length > 0\n );\n }\n\n if (!filteredStations || filteredStations.length === 0) {\n return <FeatureGroup />;\n }\n\n // Convert map symbols for this overlay to zoomBasedSymbolType.\n const symbols = this.convertToZoomMarkerSymbols(mapSymbols);\n\n return (\n <FeatureGroup>\n <ZoomBasedMarkers\n entities={filteredStations}\n symbols={symbols}\n symbolTransform={this.renderSymbolWithPopup}\n zoom={zoom}\n />\n </FeatureGroup>\n );\n }\n}\n\nVehicleRentalOverlay.props = {\n /**\n * The entire companies config array.\n */\n // configCompanies: PropTypes.arrayOf(coreUtils.types.companyType.isRequired)\n // .isRequired,\n /**\n * A list of companies that are applicable to just this instance of the\n * overlay.\n */\n companies: PropTypes.arrayOf(PropTypes.string.isRequired),\n /**\n * An optional custom function to create a string name of a particular vehicle\n * rental station. This function takes two arguments of the configCompanies\n * prop and a vehicle rental station. The function must return a string.\n */\n getStationName: PropTypes.func,\n /**\n * A configuration of what map markers or symbols to show at various\n * zoom levels.\n */\n // mapSymbols: coreUtils.types.vehicleRentalMapOverlaySymbolsType,\n /**\n * If specified, a function that will be triggered every 30 seconds whenever this layer is\n * visible.\n */\n refreshVehicles: PropTypes.func,\n /**\n * A callback for when a user clicks on setting this stop as either the from\n * or to location of a new search.\n *\n * This will be dispatched with the following argument:\n *\n * ```js\n * {\n * location: {\n * lat: number,\n * lon: number,\n * name: string\n * },\n * locationType: \"from\" or \"to\"\n * }\n * ```\n */\n setLocation: PropTypes.func.isRequired,\n /**\n * A list of the vehicle rental stations specific to this overlay instance.\n */\n // stations: PropTypes.arrayOf(coreUtils.types.stationType),\n /**\n * Whether the overlay is currently visible.\n */\n visible: PropTypes.bool\n};\n\nVehicleRentalOverlay.defaultProps = {\n getStationName: null,\n mapSymbols: [\n {\n zoom: 0,\n symbol: GenericMarker\n }\n ],\n refreshVehicles: null,\n stations: [],\n visible: false\n};\n\nexport default withLeaflet(injectIntl(VehicleRentalOverlay));\n"],"file":"index.js"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opentripplanner/vehicle-rental-overlay",
3
- "version": "1.3.2",
3
+ "version": "1.4.2",
4
4
  "description": "A map overlay to show vehicle rentals from a specific company",
5
5
  "main": "lib/index.js",
6
6
  "module": "esm/index.js",
@@ -18,11 +18,11 @@
18
18
  "url": "git+https://github.com/opentripplanner/otp-ui.git"
19
19
  },
20
20
  "dependencies": {
21
- "@opentripplanner/base-map": "^2.0.0",
22
21
  "@opentripplanner/core-utils": "^4.5.0",
23
- "@opentripplanner/from-to-location-picker": "^1.3.0",
22
+ "@opentripplanner/from-to-location-picker": "^2.1.2",
24
23
  "@opentripplanner/zoom-based-markers": "^1.2.1",
25
24
  "@styled-icons/fa-solid": "^10.34.0",
25
+ "flat": "^5.0.2",
26
26
  "lodash.memoize": "^4.1.2",
27
27
  "prop-types": "^15.7.2"
28
28
  },
@@ -30,6 +30,7 @@
30
30
  "@opentripplanner/base-map": "^2.0.0",
31
31
  "react": "^16.14.0",
32
32
  "react-dom": "^16.8.6",
33
+ "react-intl": "^5.24.6",
33
34
  "react-leaflet": "^2.6.1",
34
35
  "styled-components": "^5.3.0"
35
36
  }
@@ -1,6 +1,5 @@
1
1
  import { divIcon } from "leaflet";
2
2
  import memoize from "lodash.memoize";
3
- import coreUtils from "@opentripplanner/core-utils";
4
3
  import PropTypes from "prop-types";
5
4
  import React from "react";
6
5
  import ReactDOMServer from "react-dom/server";
@@ -22,7 +21,9 @@ const templatePropTypes = {
22
21
  /** The children of the component. */
23
22
  children: PropTypes.node,
24
23
  /** The rental vehicle or station to render. */
25
- entity: coreUtils.types.stationType.isRequired,
24
+ // entity: coreUtils.types.stationType.isRequired,
25
+ // eslint-disable-next-line react/forbid-prop-types
26
+ entity: PropTypes.object.isRequired,
26
27
  /** leaflet attribute to control tabindex value for keyboaryd-only / SR users */
27
28
  keyboard: PropTypes.bool
28
29
  };
@@ -1,5 +1,6 @@
1
+ // Removed as core-utils is typescripted. TODO: Remove when typescripting!
2
+ /* eslint-disable react/forbid-prop-types */
1
3
  import BaseMap from "@opentripplanner/base-map";
2
- import coreUtils from "@opentripplanner/core-utils";
3
4
  import PropTypes from "prop-types";
4
5
  import React from "react";
5
6
  import { CircleMarker } from "react-leaflet";
@@ -37,7 +38,8 @@ const MyCircle = ({ fillColor = "gray", pixels, strokeColor }) => {
37
38
  );
38
39
  GeneratedCircle.propTypes = {
39
40
  children: PropTypes.node,
40
- entity: coreUtils.types.stationType.isRequired
41
+ // entity: coreUtils.types.stationType.isRequired
42
+ entity: PropTypes.object.isRequired
41
43
  };
42
44
  GeneratedCircle.defaultProps = {
43
45
  children: null
@@ -194,10 +196,12 @@ const ZoomControlledMapWithVehicleRentalOverlay = ({
194
196
  ZoomControlledMapWithVehicleRentalOverlay.propTypes = {
195
197
  companies: PropTypes.arrayOf(PropTypes.string.isRequired),
196
198
  getStationName: PropTypes.func,
197
- mapSymbols: coreUtils.types.vehicleRentalMapOverlaySymbolsType,
199
+ // mapSymbols: coreUtils.types.vehicleRentalMapOverlaySymbolsType,
200
+ mapSymbols: PropTypes.object,
198
201
  refreshVehicles: PropTypes.func.isRequired,
199
- stations: PropTypes.arrayOf(coreUtils.types.stationType.isRequired)
200
- .isRequired,
202
+ // stations: PropTypes.arrayOf(coreUtils.types.stationType.isRequired)
203
+ // .isRequired,
204
+ stations: PropTypes.arrayOf(PropTypes.object.isRequired).isRequired,
201
205
  visible: PropTypes.bool
202
206
  };
203
207
 
package/src/index.js CHANGED
@@ -1,9 +1,11 @@
1
+ import flatten from "flat";
1
2
  import { Styled as BaseMapStyled } from "@opentripplanner/base-map";
2
3
  import coreUtils from "@opentripplanner/core-utils";
3
4
  import FromToLocationPicker from "@opentripplanner/from-to-location-picker";
4
5
  import ZoomBasedMarkers from "@opentripplanner/zoom-based-markers";
5
6
  import PropTypes from "prop-types";
6
7
  import React from "react";
8
+ import { FormattedMessage, injectIntl } from "react-intl";
7
9
  import { FeatureGroup, MapLayer, Popup, withLeaflet } from "react-leaflet";
8
10
 
9
11
  import {
@@ -12,6 +14,63 @@ import {
12
14
  SharedBikeCircle
13
15
  } from "./DefaultMarkers";
14
16
 
17
+ // Load the default messages.
18
+ import defaultEnglishMessages from "../i18n/en-US.yml";
19
+
20
+ // HACK: We should flatten the messages loaded above because
21
+ // the YAML loaders behave differently between webpack and our version of jest:
22
+ // - the yaml loader for webpack returns a nested object,
23
+ // - the yaml loader for jest returns messages with flattened ids.
24
+ const defaultMessages = flatten(defaultEnglishMessages);
25
+
26
+ function makeDefaultGetStationName(intl) {
27
+ return function defaultGetStationName(configCompanies, station) {
28
+ const stationNetworks = coreUtils.itinerary.getCompaniesLabelFromNetworks(
29
+ station.networks,
30
+ configCompanies
31
+ );
32
+ let stationName = station.name || station.id;
33
+ if (station.isFloatingBike) {
34
+ stationName = intl.formatMessage(
35
+ {
36
+ defaultMessage:
37
+ defaultEnglishMessages["otpUi.VehicleRentalOverlay.floatingBike"],
38
+ description: "Popup title for a free-floating bike",
39
+ id: "otpUi.VehicleRentalOverlay.floatingBike"
40
+ },
41
+ { name: stationName }
42
+ );
43
+ } else if (station.isFloatingCar) {
44
+ stationName = intl.formatMessage(
45
+ {
46
+ defaultMessage:
47
+ defaultEnglishMessages["otpUi.VehicleRentalOverlay.floatingCar"],
48
+ description: "Popup title for a free-floating car",
49
+ id: "otpUi.VehicleRentalOverlay.floatingCar"
50
+ },
51
+ {
52
+ company: stationNetworks,
53
+ name: stationName
54
+ }
55
+ );
56
+ } else if (station.isFloatingVehicle) {
57
+ // assumes that all floating vehicles are E-scooters
58
+ stationName = intl.formatMessage(
59
+ {
60
+ defaultMessage:
61
+ defaultEnglishMessages[
62
+ "otpUi.VehicleRentalOverlay.floatingEScooter"
63
+ ],
64
+ description: "Popup title for a free-floating e-scooter",
65
+ id: "otpUi.VehicleRentalOverlay.floatingEScooter"
66
+ },
67
+ { company: stationNetworks }
68
+ );
69
+ }
70
+ return stationName;
71
+ };
72
+ }
73
+
15
74
  /**
16
75
  * This vehicle rental overlay can be used to render vehicle rentals of various
17
76
  * types. This layer can be configured to show different styles of markers at
@@ -21,7 +80,7 @@ class VehicleRentalOverlay extends MapLayer {
21
80
  constructor(props) {
22
81
  super(props);
23
82
  this.state = {
24
- zoom: props.leaflet.map.getZoom()
83
+ zoom: null
25
84
  };
26
85
  }
27
86
 
@@ -40,7 +99,7 @@ class VehicleRentalOverlay extends MapLayer {
40
99
  </Symbol>
41
100
  );
42
101
  SymbolWrapper.propTypes = {
43
- entity: coreUtils.types.stationType.isRequired,
102
+ // entity: coreUtils.types.stationType.isRequired,
44
103
  zoom: PropTypes.number.isRequired
45
104
  };
46
105
 
@@ -132,7 +191,10 @@ class VehicleRentalOverlay extends MapLayer {
132
191
  * @opentripplanner/base-map package has injected to listen to zoom/position changes.
133
192
  */
134
193
  componentDidMount() {
135
- const { registerOverlay, visible } = this.props;
194
+ const { leaflet, registerOverlay, visible } = this.props;
195
+ this.setState({
196
+ zoom: leaflet.map.getZoom()
197
+ });
136
198
  if (visible) this.startRefreshing();
137
199
  if (typeof registerOverlay === "function") {
138
200
  registerOverlay(this);
@@ -149,8 +211,10 @@ class VehicleRentalOverlay extends MapLayer {
149
211
  * applicable to other regions.
150
212
  */
151
213
  renderPopupForStation = (station, stationIsHub = false) => {
152
- const { configCompanies, getStationName, setLocation } = this.props;
153
- const stationName = getStationName(configCompanies, station);
214
+ const { configCompanies, getStationName, intl, setLocation } = this.props;
215
+ const getStationNameFunc =
216
+ getStationName || makeDefaultGetStationName(intl);
217
+ const stationName = getStationNameFunc(configCompanies, station);
154
218
  const location = {
155
219
  lat: station.y,
156
220
  lon: station.x,
@@ -164,15 +228,33 @@ class VehicleRentalOverlay extends MapLayer {
164
228
  {/* render dock info if it is available */}
165
229
  {stationIsHub && (
166
230
  <BaseMapStyled.PopupRow>
167
- <div>Available bikes: {station.bikesAvailable}</div>
168
- <div>Available docks: {station.spacesAvailable}</div>
231
+ <div>
232
+ <FormattedMessage
233
+ defaultMessage={
234
+ defaultMessages["otpUi.VehicleRentalOverlay.availableBikes"]
235
+ }
236
+ description="Label text for the number of bikes available"
237
+ id="otpUi.VehicleRentalOverlay.availableBikes"
238
+ values={{ value: station.bikesAvailable }}
239
+ />
240
+ </div>
241
+ <div>
242
+ <FormattedMessage
243
+ defaultMessage={
244
+ defaultMessages["otpUi.VehicleRentalOverlay.availableDocks"]
245
+ }
246
+ description="Label text for the number of docks available"
247
+ id="otpUi.VehicleRentalOverlay.availableDocks"
248
+ values={{ value: station.spacesAvailable }}
249
+ />
250
+ </div>
169
251
  </BaseMapStyled.PopupRow>
170
252
  )}
171
253
 
172
254
  {/* Set as from/to toolbar */}
173
255
  <BaseMapStyled.PopupRow>
174
- <b>Plan a trip:</b>
175
256
  <FromToLocationPicker
257
+ label
176
258
  location={location}
177
259
  setLocation={setLocation}
178
260
  />
@@ -183,8 +265,8 @@ class VehicleRentalOverlay extends MapLayer {
183
265
  };
184
266
 
185
267
  render() {
186
- const { companies, mapSymbols, stations } = this.props;
187
- const { zoom } = this.state;
268
+ const { companies, leaflet, mapSymbols, stations } = this.props;
269
+ const { zoom = leaflet.map.getZoom() } = this.state;
188
270
  // Render an empty FeatureGroup if the rental vehicles should not be visible
189
271
  // on the map. Otherwise previous stations may still be shown due to some
190
272
  // react-leaflet internals, maybe? Also, do not return null because that will
@@ -222,8 +304,8 @@ VehicleRentalOverlay.props = {
222
304
  /**
223
305
  * The entire companies config array.
224
306
  */
225
- configCompanies: PropTypes.arrayOf(coreUtils.types.companyType.isRequired)
226
- .isRequired,
307
+ // configCompanies: PropTypes.arrayOf(coreUtils.types.companyType.isRequired)
308
+ // .isRequired,
227
309
  /**
228
310
  * A list of companies that are applicable to just this instance of the
229
311
  * overlay.
@@ -239,7 +321,7 @@ VehicleRentalOverlay.props = {
239
321
  * A configuration of what map markers or symbols to show at various
240
322
  * zoom levels.
241
323
  */
242
- mapSymbols: coreUtils.types.vehicleRentalMapOverlaySymbolsType,
324
+ // mapSymbols: coreUtils.types.vehicleRentalMapOverlaySymbolsType,
243
325
  /**
244
326
  * If specified, a function that will be triggered every 30 seconds whenever this layer is
245
327
  * visible.
@@ -266,7 +348,7 @@ VehicleRentalOverlay.props = {
266
348
  /**
267
349
  * A list of the vehicle rental stations specific to this overlay instance.
268
350
  */
269
- stations: PropTypes.arrayOf(coreUtils.types.stationType),
351
+ // stations: PropTypes.arrayOf(coreUtils.types.stationType),
270
352
  /**
271
353
  * Whether the overlay is currently visible.
272
354
  */
@@ -274,22 +356,7 @@ VehicleRentalOverlay.props = {
274
356
  };
275
357
 
276
358
  VehicleRentalOverlay.defaultProps = {
277
- getStationName: (configCompanies, station) => {
278
- const stationNetworks = coreUtils.itinerary.getCompaniesLabelFromNetworks(
279
- station.networks,
280
- configCompanies
281
- );
282
- let stationName = station.name || station.id;
283
- if (station.isFloatingBike) {
284
- stationName = `Free-floating bike: ${stationName}`;
285
- } else if (station.isFloatingCar) {
286
- stationName = `${stationNetworks} ${stationName}`;
287
- } else if (station.isFloatingVehicle) {
288
- // assumes that all floating vehicles are E-scooters
289
- stationName = `${stationNetworks} E-scooter`;
290
- }
291
- return stationName;
292
- },
359
+ getStationName: null,
293
360
  mapSymbols: [
294
361
  {
295
362
  zoom: 0,
@@ -301,4 +368,4 @@ VehicleRentalOverlay.defaultProps = {
301
368
  visible: false
302
369
  };
303
370
 
304
- export default withLeaflet(VehicleRentalOverlay);
371
+ export default withLeaflet(injectIntl(VehicleRentalOverlay));