@geops/rvf-mobility-web-component 0.1.22 → 0.1.24-beta.0

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.
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@geops/rvf-mobility-web-component",
3
3
  "license": "UNLICENSED",
4
4
  "description": "Web components for rvf in the domains of mobility and logistics.",
5
- "version": "0.1.22",
5
+ "version": "0.1.24-beta.0",
6
6
  "homepage": "https://rvf-mobility-web-component-geops.vercel.app/",
7
7
  "type": "module",
8
8
  "main": "index.js",
@@ -9,12 +9,12 @@ export type RvfFeatureDetailsProps = JSX.HTMLAttributes<HTMLDivElement> &
9
9
  PreactDOMAttributes;
10
10
 
11
11
  const getIsSharedMobility = (selectedFeature): boolean => {
12
- const id =
13
- selectedFeature.getId() || selectedFeature.get("features")[0].getId();
14
- if (typeof id === "number") {
15
- return !!selectedFeature.get("category");
16
- } else if (typeof id === "string") {
17
- return id.includes("sharing_stations") || id.includes("Vehicle");
12
+ if (
13
+ selectedFeature.get("station_id") ||
14
+ selectedFeature.get("vehicle_id") ||
15
+ selectedFeature.get("cluster_id")
16
+ ) {
17
+ return true;
18
18
  }
19
19
  };
20
20
 
@@ -2,15 +2,7 @@ import { Feature } from "ol";
2
2
  import { useEffect, useMemo, useState } from "preact/hooks";
3
3
  import { Fragment } from "preact/jsx-runtime";
4
4
 
5
- import callBike from "../../logos/callabike_logo.png";
6
- import flinkster from "../../logos/flinkster_logo.png";
7
- import grueneFlotteLogo from "../../logos/gruene_flotte_logo.png";
8
- import lastenVeloLogo from "../../logos/lasten_velo_freiburg.png";
9
- import freloLogo from "../../logos/logo_frelo_web_rgb.png";
10
- import naturEnergieLogo from "../../logos/natur_energie_logo.png";
11
- import yoioLogo from "../../logos/yoio_logo.png";
12
- import zeusLogo from "../../logos/zeus_logo.png";
13
- import { API_REQUEST_FEATURE_TYPE } from "../../utils/constants";
5
+ import { PROVIDER_LOGOS_BY_FEED_ID } from "../../utils/constants";
14
6
  import FloatingVehiclesDetails from "./FloatingVehiclesDetails";
15
7
  import StationDetails from "./StationDetails";
16
8
 
@@ -18,89 +10,21 @@ export interface RvfSharedMobilityDetailsProps {
18
10
  selectedFeature: Feature;
19
11
  }
20
12
 
21
- const logos = {
22
- callabike_ice: callBike,
23
- flinkster_carsharing: flinkster,
24
- "gruene-flotte_freiburg": grueneFlotteLogo,
25
- lastenvelo_fr: lastenVeloLogo,
26
- naturenergie_sharing: naturEnergieLogo,
27
- nextbike_df: freloLogo,
28
- yoio_freiburg: yoioLogo,
29
- zeus_freiburg: zeusLogo,
30
- };
31
-
32
13
  function RvfSharedMobilityDetails({
33
14
  selectedFeature,
34
15
  }: RvfSharedMobilityDetailsProps) {
35
16
  const [features, setFeatures] = useState([]);
36
- const isStationDetails =
37
- !!selectedFeature.get("categories") ||
38
- !selectedFeature.get("features")?.length;
39
- const isFloatingVehicle = !!selectedFeature.get("features")?.length;
17
+ const isStationDetails = !!selectedFeature.get("station_id");
18
+ const isFloatingVehicle = !!selectedFeature.get("vehicle_id");
19
+ const isCluster = !!selectedFeature.get("cluster_id");
40
20
 
41
21
  useEffect(() => {
42
- const extent = selectedFeature.getGeometry().getExtent();
43
- extent[0] = extent[0] - 2;
44
- extent[1] = extent[1] - 2;
45
- extent[2] = extent[2] + 2;
46
- extent[3] = extent[3] + 2;
47
- const categoryName = selectedFeature.get("category")?.toLowerCase();
48
- let featureType;
49
- let abortController;
50
-
51
- if (categoryName) {
52
- if (categoryName === "bike sharing") {
53
- featureType = API_REQUEST_FEATURE_TYPE.stations.bike;
54
- } else if (categoryName === "car sharing") {
55
- featureType = API_REQUEST_FEATURE_TYPE.stations.car;
56
- } else if (categoryName === "cargo bike sharing") {
57
- featureType = API_REQUEST_FEATURE_TYPE.stations.cargoBike;
58
- }
59
- abortController = new AbortController();
60
-
61
- fetch(createRequestLink(featureType, extent), {
62
- signal: new AbortController().signal,
63
- })
64
- .then((res) => {
65
- return res.json();
66
- })
67
- .then((data) => {
68
- if (data.features?.[0].properties) {
69
- selectedFeature.setProperties(data.features[0].properties);
70
- }
71
- setFeatures([selectedFeature]);
72
- })
73
- .catch((err) => {
74
- console.error(err);
75
- });
22
+ if (isCluster) {
23
+ setFeatures(selectedFeature.get("features"));
76
24
  } else {
77
- if (isFloatingVehicle) {
78
- setFeatures(selectedFeature.get("features"));
79
- } else {
80
- setFeatures([selectedFeature]);
81
- }
25
+ setFeatures([selectedFeature]);
82
26
  }
83
- return () => {
84
- abortController?.abort();
85
- };
86
- }, [selectedFeature, isFloatingVehicle]);
87
-
88
- const createRequestLink = (name, extent) => {
89
- return (
90
- "https://api.mobidata-bw.de/geoserver/MobiData-BW/" +
91
- name +
92
- "/ows" +
93
- "?service=WFS&" +
94
- "version=1.1.0&request=GetFeature&typename=" +
95
- "MobiData-BW:" +
96
- name +
97
- "&" +
98
- "outputFormat=application/json&srsname=EPSG:3857&" +
99
- "bbox=" +
100
- extent.join(",") +
101
- ",EPSG:3857"
102
- );
103
- };
27
+ }, [selectedFeature, isFloatingVehicle, isCluster]);
104
28
 
105
29
  const featuresByFeedId: Record<string, Feature[]> = useMemo(() => {
106
30
  const featuresByFeedId = {};
@@ -125,14 +49,14 @@ function RvfSharedMobilityDetails({
125
49
  <img
126
50
  alt="logo"
127
51
  className="max-w-24"
128
- src={logos[features[0]?.get("feed_id")]}
52
+ src={PROVIDER_LOGOS_BY_FEED_ID[features[0]?.get("feed_id")]}
129
53
  />
130
54
  {features.length && isStationDetails && (
131
55
  <StationDetails feature={features[0]} />
132
56
  )}
133
57
  </>
134
58
  )}
135
- {isFloatingVehicle &&
59
+ {(isFloatingVehicle || isCluster) &&
136
60
  featuresByFeedId &&
137
61
  Object.entries(featuresByFeedId).map(([key, feats]) => {
138
62
  return (
@@ -140,7 +64,7 @@ function RvfSharedMobilityDetails({
140
64
  <img
141
65
  alt="logo"
142
66
  className="max-w-24"
143
- src={logos[feats[0]?.get("feed_id")]}
67
+ src={PROVIDER_LOGOS_BY_FEED_ID[feats[0]?.get("feed_id")]}
144
68
  />
145
69
  <FloatingVehiclesDetails features={feats} />
146
70
  </Fragment>
@@ -1,162 +1,13 @@
1
- import { gql, GraphQLClient } from "graphql-request";
2
1
  import { Feature } from "ol";
3
2
  import { useEffect, useMemo, useState } from "preact/hooks";
4
3
 
5
4
  import RvfLink from "../../../RvfLink";
6
5
  import getLinkByDevice from "../../../utils/getLinkByDevice";
6
+ import { fetchSharingStation } from "../../../utils/sharingGraphqlUtils";
7
7
  export interface StationDetailsProps {
8
8
  feature: Feature;
9
9
  }
10
10
 
11
- const document = gql`
12
- query station($id: String!) {
13
- station(id: $id) {
14
- name {
15
- translation {
16
- language
17
- value
18
- }
19
- }
20
- shortName {
21
- translation {
22
- language
23
- value
24
- }
25
- }
26
- lat
27
- lon
28
- region {
29
- id
30
- }
31
- rentalUris {
32
- android
33
- ios
34
- web
35
- }
36
- isVirtualStation
37
- rentalMethods
38
- parkingHoop
39
- parkingType
40
- contactPhone
41
- address
42
- rentalMethods
43
- capacity
44
- vehicleTypesAvailable {
45
- count
46
- vehicleType {
47
- id
48
- formFactor
49
- riderCapacity
50
- cargoVolumeCapacity
51
- cargoLoadCapacity
52
- propulsionType
53
- ecoLabels {
54
- countryCode
55
- ecoSticker
56
- }
57
- maxRangeMeters
58
- name {
59
- translation {
60
- language
61
- value
62
- }
63
- }
64
- description {
65
- translation {
66
- language
67
- value
68
- }
69
- }
70
- vehicleAccessories
71
- gCO2km
72
- vehicleImage
73
- make
74
- model
75
- color
76
- wheelCount
77
- maxPermittedSpeed
78
- ratedPower
79
- defaultReserveTime
80
- returnConstraint
81
- vehicleAssets {
82
- iconUrl
83
- iconUrlDark
84
- iconLastModified
85
- }
86
- defaultReserveTime
87
- defaultPricingPlan {
88
- id
89
- url
90
- currency
91
- isTaxable
92
- description {
93
- translation {
94
- language
95
- value
96
- }
97
- }
98
- perKmPricing {
99
- start
100
- rate
101
- interval
102
- end
103
- }
104
- perMinPricing {
105
- start
106
- rate
107
- interval
108
- end
109
- }
110
- surgePricing
111
- }
112
- }
113
- count
114
- }
115
- vehicleDocksCapacity {
116
- vehicleTypes {
117
- id
118
- }
119
- count
120
- }
121
- numVehiclesAvailable
122
- numDocksDisabled
123
- numVehiclesDisabled
124
- numDocksAvailable
125
- isInstalled
126
- isRenting
127
- isReturning
128
- pricingPlans {
129
- id
130
- url
131
- currency
132
- isTaxable
133
- description {
134
- translation {
135
- language
136
- value
137
- }
138
- }
139
- perKmPricing {
140
- start
141
- rate
142
- interval
143
- end
144
- }
145
- perMinPricing {
146
- start
147
- rate
148
- interval
149
- end
150
- }
151
- surgePricing
152
- }
153
- }
154
- }
155
- `;
156
- const client = new GraphQLClient("https://api.mobidata-bw.de/sharing/graphql", {
157
- method: "GET",
158
- });
159
-
160
11
  function StationDetails({ feature }: StationDetailsProps) {
161
12
  const [data, setData] = useState(null);
162
13
  const link = useMemo(() => {
@@ -167,15 +18,8 @@ function StationDetails({ feature }: StationDetailsProps) {
167
18
  const stationId = feature.get("station_id");
168
19
  if (stationId) {
169
20
  const fetchData = async () => {
170
- const { station }: { station: unknown } = await client.request(
171
- document,
172
- {
173
- __operation: "station",
174
- id: feature.get("station_id"),
175
- },
176
- );
21
+ const station = await fetchSharingStation(feature.get("station_id"));
177
22
  setData(station);
178
- // console.log(station);
179
23
  };
180
24
  fetchData();
181
25
  }
@@ -229,7 +73,7 @@ function StationDetails({ feature }: StationDetailsProps) {
229
73
  </div>
230
74
  {data?.vehicleTypesAvailable?.length > 0 && link && (
231
75
  <div>
232
- <RvfLink href={link}>Jetzt Buchen</RvfLink>
76
+ <RvfLink href={link}>Jetzt buchen</RvfLink>
233
77
  </div>
234
78
  )}
235
79
  </div>
@@ -42,7 +42,7 @@ import RvfPoisLayer from "../RvfPoisLayer";
42
42
  import RvfSelectedFeatureHighlightLayer from "../RvfSelectedFeatureHighlightLayer";
43
43
  import RvfSellingPointsLayer from "../RvfSellingPointsLayer";
44
44
  import RvfShare from "../RvfShare";
45
- import RvfSharedMobilityLayerGroup from "../RvfSharedMobilityLayerGroup";
45
+ import RvfSharedMobilityLayerGroup2 from "../RvfSharedMobilityLayerGroup2";
46
46
  import RvfShareMenuButton from "../RvfShareMenuButton";
47
47
  import RvfTarifZonenLayer from "../RvfTarifZonenLayer";
48
48
  import Topics from "../RvfTopics";
@@ -67,6 +67,7 @@ import MobilityEvent from "../utils/MobilityEvent";
67
67
  import style from "./index.css";
68
68
 
69
69
  export type RvfMobilityMapProps = {
70
+ details: string;
70
71
  layers: string; // list of visible layers on load
71
72
  layertree: string;
72
73
  print: string;
@@ -89,11 +90,17 @@ const styleProps = {
89
90
  const scrollableHandlerProps = {
90
91
  style: { width: "calc(100% - 60px)" },
91
92
  };
93
+ const realtimeLayerProps = {
94
+ bboxParameters: {
95
+ line_tags: "RVF",
96
+ },
97
+ };
92
98
 
93
99
  function RvfMobilityMap({
94
100
  apikey = "5cc87b12d7c5370001c1d655820abcc37dfd4d968d7bab5b2a74a935",
95
101
  baselayer = "de.rvf",
96
102
  center = null,
103
+ details = "true",
97
104
  extent = bbox,
98
105
  geolocation = "true",
99
106
  layers = null,
@@ -114,7 +121,7 @@ function RvfMobilityMap({
114
121
  search = "false",
115
122
  share = "true",
116
123
  stopsurl = "https://api.geops.io/stops/v1/",
117
- tenant = null,
124
+ tenant = "de-gtfs-de",
118
125
  toolbar = "true",
119
126
  zoom = null,
120
127
  }: RvfMobilityMapProps) {
@@ -176,6 +183,10 @@ function RvfMobilityMap({
176
183
  return print === "true";
177
184
  }, [print]);
178
185
 
186
+ const hasDetails = useMemo(() => {
187
+ return details === "true";
188
+ }, [details]);
189
+
179
190
  // Apply initial visibility of layers
180
191
  useInitialLayersVisiblity(map, layers);
181
192
 
@@ -265,6 +276,7 @@ function RvfMobilityMap({
265
276
  new MobilityEvent<RvfMobilityMapProps>("mwc:attribute", {
266
277
  baselayer,
267
278
  center,
279
+ details,
268
280
  extent,
269
281
  geolocation,
270
282
  layers,
@@ -312,6 +324,7 @@ function RvfMobilityMap({
312
324
  maxextent,
313
325
  print,
314
326
  share,
327
+ details,
315
328
  ]);
316
329
 
317
330
  const rvfContextValue = useMemo(() => {
@@ -462,7 +475,10 @@ function RvfMobilityMap({
462
475
  <RvfSelectedFeatureHighlightLayer />
463
476
 
464
477
  {hasRealtime && (
465
- <RealtimeLayer title={RVF_LAYERS_TITLES.echtzeit} />
478
+ <RealtimeLayer
479
+ title={RVF_LAYERS_TITLES.echtzeit}
480
+ {...realtimeLayerProps}
481
+ />
466
482
  )}
467
483
  {
468
484
  <StationsLayer
@@ -483,7 +499,7 @@ function RvfMobilityMap({
483
499
  title={RVF_LAYERS_TITLES.liniennetz}
484
500
  />
485
501
  <RvfPoisLayer title={RVF_LAYERS_TITLES.pois} />
486
- <RvfSharedMobilityLayerGroup
502
+ <RvfSharedMobilityLayerGroup2
487
503
  title={RVF_LAYERS_TITLES.sharedMobility}
488
504
  />
489
505
 
@@ -546,7 +562,7 @@ function RvfMobilityMap({
546
562
  <Station className="relative flex flex-col overflow-y-auto overflow-x-hidden p-2" />
547
563
  </>
548
564
  )}
549
- {selectedFeature && (
565
+ {hasDetails && selectedFeature && (
550
566
  <>
551
567
  <RvfOverlayHeader
552
568
  onClose={() => {