@geops/rvf-mobility-web-component 0.1.83 → 0.1.84

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.
Files changed (97) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/index.js +206 -187
  3. package/package.json +2 -2
  4. package/src/Departure/Departure.tsx +6 -3
  5. package/src/FeatureDetails/FeatureDetails.tsx +4 -4
  6. package/src/FeaturesInfosListener/FeaturesInfosListener.tsx +22 -0
  7. package/src/LayerTreeMenu/LayerTreeMenu.tsx +12 -4
  8. package/src/LayoutState/LayoutState.tsx +144 -63
  9. package/src/LinesNetworkPlanDetails/LinesNetworkPlanDetails.tsx +2 -2
  10. package/src/LinesNetworkPlanLayerHighlight/LinesNetworkPlanLayerHighlight.tsx +2 -40
  11. package/src/MapLayout/MapLayout.tsx +2 -7
  12. package/src/MobilityMap/MobilityMap.tsx +1 -6
  13. package/src/MobilityMap/MobilityMapAttributes.ts +28 -7
  14. package/src/NotificationDetails/NotificationDetails.tsx +21 -22
  15. package/src/NotificationsLayer/NotificationsLayer.tsx +47 -3
  16. package/src/OverlayDetails/OverlayDetails.tsx +5 -0
  17. package/src/RealtimeLayer/RealtimeLayer.tsx +44 -50
  18. package/src/RouteIcon/RouteIcon.tsx +25 -14
  19. package/src/RouteSchedule/RouteSchedule.tsx +14 -11
  20. package/src/RouteScheduleFooter/RouteScheduleFooter.tsx +6 -3
  21. package/src/RouteScheduleHeader/RouteScheduleHeader.tsx +8 -2
  22. package/src/RouteStop/RouteStop.tsx +14 -29
  23. package/src/RouteStopPlatform/RouteStopPlatform.tsx +1 -3
  24. package/src/RouteStopProgress/RouteStopProgress.tsx +11 -18
  25. package/src/RouteStopStation/RouteStopStation.tsx +3 -3
  26. package/src/RvfRealtimeLayer/RvfRealtimeLayer.tsx +16 -3
  27. package/src/RvfSearch/RvfSearch.tsx +5 -4
  28. package/src/Search/Search.tsx +41 -20
  29. package/src/Search/SearchBase.tsx +169 -0
  30. package/src/Search/SearchHeadless.tsx +79 -0
  31. package/src/Search/index.tsx +2 -0
  32. package/src/SearchLinesResult/SearchLinesResult.tsx +43 -0
  33. package/src/SearchLinesResult/index.tsx +1 -0
  34. package/src/SearchLinesResults/SearchLinesResults.tsx +106 -0
  35. package/src/SearchLinesResults/index.tsx +1 -0
  36. package/src/SearchLnpStopsResult/SearchLnpStopsResult.tsx +42 -0
  37. package/src/SearchLnpStopsResult/index.tsx +1 -0
  38. package/src/SearchLnpStopsResults/SearchLnpStopsResults.tsx +106 -0
  39. package/src/SearchLnpStopsResults/index.tsx +1 -0
  40. package/src/SearchResult/SearchResult.tsx +25 -0
  41. package/src/SearchResult/index.tsx +1 -0
  42. package/src/SearchResults/SearchResults.tsx +81 -0
  43. package/src/SearchResults/index.tsx +1 -0
  44. package/src/SearchResultsHeader/SearchResultsHeader.tsx +36 -0
  45. package/src/SearchResultsHeader/index.tsx +1 -0
  46. package/src/SearchStopsResult/SearchStopsResult.tsx +43 -0
  47. package/src/SearchStopsResult/index.tsx +1 -0
  48. package/src/SearchStopsResults/SearchStopsResults.tsx +101 -0
  49. package/src/SearchStopsResults/index.tsx +1 -0
  50. package/src/SearchTrainsResult/SearchTrainsResult.tsx +42 -0
  51. package/src/SearchTrainsResult/index.tsx +1 -0
  52. package/src/SearchTrainsResults/SearchTrainsResults.tsx +109 -0
  53. package/src/SearchTrainsResults/index.tsx +1 -0
  54. package/src/SingleClickListener/SingleClickListener.tsx +38 -2
  55. package/src/Station/Station.tsx +23 -48
  56. package/src/StationHeader/StationHeader.tsx +3 -3
  57. package/src/StationsLayer/StationsLayer.tsx +9 -1
  58. package/src/StopsSearch/StopsSearch.tsx +2 -2
  59. package/src/ui/InputSearch/InputSearch.tsx +105 -0
  60. package/src/ui/InputSearch/index.tsx +1 -0
  61. package/src/utils/centerOnVehicle.ts +9 -2
  62. package/src/utils/constants.ts +8 -1
  63. package/src/utils/fullTrajectoryStyle.ts +4 -7
  64. package/src/utils/getBgColor.ts +4 -2
  65. package/src/utils/getDelayColorForVehicle.test.ts +21 -11
  66. package/src/utils/getDelayColorForVehicle.ts +7 -5
  67. package/src/utils/getDelayTextForVehicle.test.ts +12 -12
  68. package/src/utils/getDelayTextForVehicle.ts +4 -0
  69. package/src/utils/getMainColorForVehicle.ts +11 -4
  70. package/src/utils/getRadius.ts +9 -3
  71. package/src/utils/getTextColor.ts +1 -1
  72. package/src/utils/getTextColorForVehicle.ts +29 -0
  73. package/src/utils/getTextFontForVehicle.test.ts +1 -1
  74. package/src/utils/getTextFontForVehicle.tsx +11 -3
  75. package/src/utils/getTextForVehicle.ts +7 -1
  76. package/src/utils/hooks/useFit.tsx +69 -0
  77. package/src/utils/hooks/useFitOnFeatures.tsx +77 -0
  78. package/src/utils/hooks/useLayersConfig.tsx +3 -0
  79. package/src/utils/hooks/useLnp.tsx +39 -5
  80. package/src/utils/hooks/useMapContext.tsx +2 -5
  81. package/src/utils/hooks/useRealtimeDepartures.tsx +45 -0
  82. package/src/utils/hooks/useRealtimeRenderedTrajectory.tsx +42 -0
  83. package/src/utils/hooks/useRealtimeStation.tsx +39 -0
  84. package/src/utils/hooks/useRealtimeStopSequences.tsx +43 -0
  85. package/src/utils/hooks/useRealtimeTrainsByRouteIdentifier.tsx +71 -0
  86. package/src/utils/hooks/useRouteStop.tsx +7 -1
  87. package/src/utils/hooks/useSearchLines.tsx +34 -0
  88. package/src/utils/hooks/useSearchLnpStops.tsx +38 -0
  89. package/src/utils/hooks/useSearchStops.tsx +85 -0
  90. package/src/utils/hooks/useSearchTrains.tsx +83 -0
  91. package/src/utils/realtimeRVFStyle.ts +38 -30
  92. package/src/utils/translations.ts +17 -0
  93. package/tash +58 -0
  94. package/src/utils/centerOnStation.ts +0 -18
  95. package/src/utils/getDelayFontForVehicle.test.ts +0 -7
  96. package/src/utils/getDelayFontForVehicle.tsx +0 -8
  97. package/src/utils/hooks/useStation.tsx +0 -22
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.83",
5
+ "version": "0.1.84",
6
6
  "homepage": "https://rvf-mobility-web-component-geops.vercel.app/",
7
7
  "type": "module",
8
8
  "main": "index.js",
@@ -12,7 +12,7 @@
12
12
  "jspdf": "^3.0.3",
13
13
  "lodash.debounce": "^4.0.8",
14
14
  "maplibre-gl": "^5.10.0",
15
- "mobility-toolbox-js": "3.4.7",
15
+ "mobility-toolbox-js": "3.5.1-beta.4",
16
16
  "ol": "^10.6.1",
17
17
  "preact": "^10.27.2",
18
18
  "preact-custom-element": "^4.5.1",
@@ -14,7 +14,8 @@ export interface DepartureProps {
14
14
  }
15
15
 
16
16
  function Departure({ departure, index, ...props }: DepartureProps) {
17
- const { setStationId, setTrainId } = useMapContext();
17
+ const { realtimeLayer, setFeaturesInfos, setStationId, setTrainId } =
18
+ useMapContext();
18
19
 
19
20
  const departureState = useMemo(() => {
20
21
  return { departure, index };
@@ -23,10 +24,12 @@ function Departure({ departure, index, ...props }: DepartureProps) {
23
24
  return (
24
25
  <DepartureContext.Provider value={departureState}>
25
26
  <button
26
- className="w-full border-b"
27
+ className="w-full cursor-pointer border-b"
27
28
  onClick={() => {
28
- setTrainId(departure.train_id);
29
+ setFeaturesInfos(undefined);
29
30
  setStationId();
31
+ realtimeLayer?.setVisible(true);
32
+ setTrainId(departure.train_id);
30
33
  }}
31
34
  {...props}
32
35
  >
@@ -25,6 +25,7 @@ function FeatureDetails({ feature, featuresInfo, layer }: FeatureDetailsProps) {
25
25
  const {
26
26
  linesIds,
27
27
  linesNetworkPlanLayer,
28
+ notificationId,
28
29
  notificationsLayer,
29
30
  realtimeLayer,
30
31
  stationId,
@@ -50,10 +51,9 @@ function FeatureDetails({ feature, featuresInfo, layer }: FeatureDetailsProps) {
50
51
  features={featuresInfo?.features || []}
51
52
  />
52
53
  )}
53
- {feature &&
54
- !!notificationsLayer &&
55
- !!layer &&
56
- layer.get("name") === notificationsLayer.get("name") && (
54
+ {!!notificationsLayer &&
55
+ layer === notificationsLayer &&
56
+ notificationId && (
57
57
  <NotificationDetails className={contentClassName} feature={feature} />
58
58
  )}
59
59
  </>
@@ -1,5 +1,6 @@
1
1
  import { useEffect } from "preact/hooks";
2
2
 
3
+ import { LNP_LINE_ID_PROP } from "../utils/constants";
3
4
  import useMapContext from "../utils/hooks/useMapContext";
4
5
 
5
6
  /**
@@ -10,7 +11,9 @@ function FeaturesInfosListener() {
10
11
  baseLayer,
11
12
  featuresInfos,
12
13
  featuresInfosHovered,
14
+ linesNetworkPlanLayer,
13
15
  realtimeLayer,
16
+ setLinesIds,
14
17
  setSelectedFeature,
15
18
  setSelectedFeatures,
16
19
  setStationId,
@@ -38,6 +41,20 @@ function FeaturesInfosListener() {
38
41
  return info.layer === stationsLayer;
39
42
  })?.features || [];
40
43
 
44
+ // Find the line to highlight in the LNP layer
45
+ const linesFeatures =
46
+ featuresInfos?.find((featuresInfo) => {
47
+ return featuresInfo.layer === linesNetworkPlanLayer;
48
+ })?.features || [];
49
+
50
+ const linesIds = [
51
+ ...new Set(
52
+ (linesFeatures || []).map((f) => {
53
+ return f.get(LNP_LINE_ID_PROP) as string;
54
+ }),
55
+ ),
56
+ ];
57
+
41
58
  const features =
42
59
  featuresInfos?.flatMap((info) => {
43
60
  return info.features;
@@ -53,11 +70,16 @@ function FeaturesInfosListener() {
53
70
  } else {
54
71
  setSelectedFeatures(features);
55
72
  setSelectedFeature(realtimeFeature || stationFeature || features[0]);
73
+ if (linesIds.length) {
74
+ setLinesIds(linesIds?.length ? linesIds : null);
75
+ }
56
76
  }
57
77
  }, [
58
78
  baseLayer?.mapLibreMap,
59
79
  featuresInfos,
80
+ linesNetworkPlanLayer,
60
81
  realtimeLayer,
82
+ setLinesIds,
61
83
  setSelectedFeature,
62
84
  setSelectedFeatures,
63
85
  setStationId,
@@ -5,7 +5,11 @@ import { memo, useEffect, useMemo, useState } from "preact/compat";
5
5
 
6
6
  import LayerTree from "../LayerTree";
7
7
  import { SelectionType } from "../LayerTree/TreeItem";
8
- import { LAYER_TREE_ORDER } from "../utils/constants";
8
+ import {
9
+ LAYER_TREE_HIDE_PROP,
10
+ LAYER_TREE_ORDER,
11
+ LAYER_TREE_TITLE_FUNC_PROP,
12
+ } from "../utils/constants";
9
13
  import useLayersConfig from "../utils/hooks/useLayersConfig";
10
14
  import useMapContext from "../utils/hooks/useMapContext";
11
15
 
@@ -39,7 +43,7 @@ const getConfigForLayer = (
39
43
  layersConfig: Record<string, LayerConfig> = {},
40
44
  ): LayerTreeConfig => {
41
45
  const defaultTitle = layersConfig[layer.get("name")]?.title || "";
42
- const customTitleFunction = layer.get("layerTreeTitle");
46
+ const customTitleFunction = layer.get(LAYER_TREE_TITLE_FUNC_PROP);
43
47
  let title = defaultTitle;
44
48
  if (typeof customTitleFunction === "function") {
45
49
  title = customTitleFunction(title);
@@ -78,8 +82,12 @@ function LayerTreeMenu({
78
82
  .getArray()
79
83
  .filter(
80
84
  filter ??
81
- (() => {
82
- return true;
85
+ ((layer) => {
86
+ return (
87
+ (layer.get(LAYER_TREE_HIDE_PROP) ||
88
+ layersConfig[layer.get("name")]?.[LAYER_TREE_HIDE_PROP]) !==
89
+ true
90
+ );
83
91
  }),
84
92
  )
85
93
  .sort((a, b) => {
@@ -1,7 +1,9 @@
1
- import { useEffect } from "preact/hooks";
1
+ import { useCallback, useEffect } from "preact/hooks";
2
2
 
3
- import useLnpLineInfo from "../utils/hooks/useLnp";
3
+ import useFit from "../utils/hooks/useFit";
4
+ import useLnpLineInfo, { useLnpStopInfo } from "../utils/hooks/useLnp";
4
5
  import useMapContext from "../utils/hooks/useMapContext";
6
+ import useRealtimeTrainByRouteIdentifier from "../utils/hooks/useRealtimeTrainsByRouteIdentifier";
5
7
 
6
8
  /**
7
9
  * This component is responsible for updating the layout state in the context.
@@ -14,6 +16,7 @@ function LayoutState() {
14
16
  hasDetails,
15
17
  hasLayerTree,
16
18
  hasLnp,
19
+ hasNotification,
17
20
  hasPrint,
18
21
  hasRealtime,
19
22
  hasShare,
@@ -22,11 +25,13 @@ function LayoutState() {
22
25
  isSearchOpen,
23
26
  isShareMenuOpen,
24
27
  layertree,
28
+ lineid,
25
29
  linesIds,
26
30
  lnp,
27
- lnpid,
28
31
  mapset,
29
32
  notification,
33
+ notificationid,
34
+ notificationId,
30
35
  permalink,
31
36
  previewNotifications,
32
37
  print,
@@ -54,16 +59,22 @@ function LayoutState() {
54
59
  setIsSearchOpen,
55
60
  setIsShareMenuOpen,
56
61
  setLinesIds,
62
+ setNotificationId,
57
63
  setStationId,
58
64
  setTrainId,
59
65
  share,
60
66
  stationId,
67
+ stationid,
61
68
  tenant,
62
69
  toolbar,
70
+ trainid,
63
71
  trainId,
64
72
  } = useMapContext();
65
73
 
66
- const lineInfo = useLnpLineInfo(lnpid);
74
+ const lineInfo = useLnpLineInfo(lineid);
75
+ const stopInfo = useLnpStopInfo(stationid);
76
+ const trainInfo = useRealtimeTrainByRouteIdentifier(trainid);
77
+ const fit = useFit();
67
78
 
68
79
  useEffect(() => {
69
80
  setHasStations(!!tenant);
@@ -122,28 +133,80 @@ function LayoutState() {
122
133
  }, [layertree, setHasLayerTree]);
123
134
 
124
135
  useEffect(() => {
125
- setLinesIds(lineInfo ? [lineInfo.external_id] : null);
136
+ setLinesIds(lineInfo?.external_id ? [lineInfo.external_id] : null);
126
137
  }, [lineInfo, setLinesIds]);
127
138
 
139
+ // Zoom when linesids attribute changes
140
+ useEffect(() => {
141
+ fit.current(lineInfo, true);
142
+ }, [lineInfo, fit]);
143
+
144
+ useEffect(() => {
145
+ setStationId(stopInfo?.external_id);
146
+ }, [stopInfo, setStationId]);
147
+
148
+ // Center and zoom when stationid attribute changes
149
+ useEffect(() => {
150
+ fit.current(stopInfo, true);
151
+ }, [stopInfo, fit]);
152
+
153
+ useEffect(() => {
154
+ setNotificationId(notificationid);
155
+ }, [notificationid, setNotificationId]);
156
+
157
+ useEffect(() => {
158
+ setTrainId(trainInfo?.train_id);
159
+ }, [setTrainId, trainInfo]);
160
+
161
+ // Center and zoom when trainid attribute changes
162
+ useEffect(() => {
163
+ fit.current(trainInfo, true);
164
+ }, [trainInfo, fit]);
165
+
166
+ // Close all menus
167
+ const closeMenus = useCallback(() => {
168
+ setIsLayerTreeOpen(false);
169
+ setIsExportMenuOpen(false);
170
+ setIsSearchOpen(false);
171
+ setIsShareMenuOpen(false);
172
+ }, [
173
+ setIsExportMenuOpen,
174
+ setIsLayerTreeOpen,
175
+ setIsSearchOpen,
176
+ setIsShareMenuOpen,
177
+ ]);
178
+
179
+ // Close all features details
180
+ const closeFeatureDetails = useCallback(() => {
181
+ setStationId(null);
182
+ setTrainId(null);
183
+ setNotificationId(null);
184
+ setLinesIds(null);
185
+ setFeaturesInfos(null);
186
+ }, [
187
+ setStationId,
188
+ setTrainId,
189
+ setNotificationId,
190
+ setLinesIds,
191
+ setFeaturesInfos,
192
+ ]);
193
+
128
194
  useEffect(() => {
129
195
  if (isSearchOpen) {
130
196
  setIsLayerTreeOpen(false);
131
197
  setIsExportMenuOpen(false);
132
198
  setIsShareMenuOpen(false);
133
199
  setStationId(null);
134
- setTrainId(null);
135
- setFeaturesInfos(null);
136
- setLinesIds(null);
200
+
201
+ closeFeatureDetails();
137
202
  }
138
203
  }, [
204
+ closeFeatureDetails,
139
205
  isSearchOpen,
140
- setFeaturesInfos,
141
206
  setIsExportMenuOpen,
142
207
  setIsLayerTreeOpen,
143
208
  setIsShareMenuOpen,
144
- setLinesIds,
145
209
  setStationId,
146
- setTrainId,
147
210
  ]);
148
211
 
149
212
  useEffect(() => {
@@ -151,20 +214,15 @@ function LayoutState() {
151
214
  setIsLayerTreeOpen(false);
152
215
  setIsExportMenuOpen(false);
153
216
  setIsSearchOpen(false);
154
- setStationId(null);
155
- setTrainId(null);
156
- setFeaturesInfos(null);
157
- setLinesIds(null);
217
+
218
+ closeFeatureDetails();
158
219
  }
159
220
  }, [
160
221
  isShareMenuOpen,
161
- setFeaturesInfos,
222
+ closeFeatureDetails,
162
223
  setIsExportMenuOpen,
163
224
  setIsLayerTreeOpen,
164
225
  setIsSearchOpen,
165
- setLinesIds,
166
- setStationId,
167
- setTrainId,
168
226
  ]);
169
227
 
170
228
  useEffect(() => {
@@ -172,22 +230,17 @@ function LayoutState() {
172
230
  setIsExportMenuOpen(false);
173
231
  setIsLayerTreeOpen(isLayerTreeOpen);
174
232
  setIsSearchOpen(false);
175
- setFeaturesInfos(null);
176
- setTrainId(null);
177
- setStationId(null);
178
- setLinesIds(null);
179
233
  setIsShareMenuOpen(false);
234
+
235
+ closeFeatureDetails();
180
236
  }
181
237
  }, [
182
238
  isLayerTreeOpen,
183
- setFeaturesInfos,
239
+ closeFeatureDetails,
184
240
  setIsExportMenuOpen,
185
241
  setIsLayerTreeOpen,
186
242
  setIsSearchOpen,
187
243
  setIsShareMenuOpen,
188
- setLinesIds,
189
- setStationId,
190
- setTrainId,
191
244
  ]);
192
245
 
193
246
  useEffect(() => {
@@ -195,84 +248,109 @@ function LayoutState() {
195
248
  setIsLayerTreeOpen(false);
196
249
  setIsExportMenuOpen(isExportMenuOpen);
197
250
  setIsSearchOpen(false);
198
- setFeaturesInfos(null);
199
- setTrainId(null);
200
- setLinesIds(null);
201
251
  setIsShareMenuOpen(false);
202
- setStationId(null);
252
+
253
+ closeFeatureDetails();
203
254
  }
204
255
  }, [
256
+ closeFeatureDetails,
205
257
  isExportMenuOpen,
206
- setFeaturesInfos,
207
258
  setIsExportMenuOpen,
208
259
  setIsLayerTreeOpen,
209
260
  setIsSearchOpen,
210
261
  setIsShareMenuOpen,
211
- setLinesIds,
212
- setStationId,
213
- setTrainId,
214
262
  ]);
215
263
 
216
264
  useEffect(() => {
217
265
  if (selectedFeature) {
218
- setIsLayerTreeOpen(false);
219
- setIsSearchOpen(false);
220
- setIsExportMenuOpen(false);
221
- setIsShareMenuOpen(false);
266
+ closeMenus();
222
267
  setTrainId(selectedFeature?.get("train_id") || null);
223
268
  setStationId(selectedFeature?.get("uid") || null);
224
- } else if (!selectedFeature) {
225
- setTrainId(null);
226
- setStationId(null);
269
+ setNotificationId(selectedFeature?.get("situationId") || null);
227
270
  }
228
271
  }, [
229
272
  selectedFeature,
230
- setIsExportMenuOpen,
231
- setIsLayerTreeOpen,
232
- setIsSearchOpen,
233
- setIsShareMenuOpen,
273
+ closeMenus,
234
274
  setStationId,
235
275
  setTrainId,
276
+ setNotificationId,
236
277
  ]);
237
278
 
238
279
  useEffect(() => {
239
280
  if (stationId) {
240
- setIsLayerTreeOpen(false);
241
- setIsExportMenuOpen(false);
242
- setIsSearchOpen(false);
281
+ closeMenus();
282
+
243
283
  setTrainId(null);
244
- setIsShareMenuOpen(false);
245
284
  setLinesIds(null);
285
+ setNotificationId(null);
246
286
  }
247
287
  }, [
248
288
  setFeaturesInfos,
249
- setIsExportMenuOpen,
250
- setIsLayerTreeOpen,
251
- setIsSearchOpen,
252
- setIsShareMenuOpen,
289
+ closeMenus,
253
290
  setLinesIds,
291
+ setNotificationId,
254
292
  setTrainId,
255
293
  stationId,
256
294
  ]);
257
295
 
258
296
  useEffect(() => {
259
297
  if (trainId) {
260
- setIsLayerTreeOpen(false);
261
- setIsExportMenuOpen(false);
262
- setIsSearchOpen(false);
298
+ closeMenus();
299
+
300
+ // Close overlay details
263
301
  setStationId(null);
264
- setIsShareMenuOpen(false);
302
+ setLinesIds(null);
303
+ setNotificationId(null);
265
304
  }
266
305
  }, [
306
+ closeMenus,
267
307
  setFeaturesInfos,
268
- setIsExportMenuOpen,
269
- setIsLayerTreeOpen,
270
- setIsSearchOpen,
271
- setIsShareMenuOpen,
308
+ setLinesIds,
309
+ setNotificationId,
272
310
  setStationId,
273
311
  trainId,
274
312
  ]);
275
313
 
314
+ useEffect(() => {
315
+ if (notificationId) {
316
+ closeMenus();
317
+
318
+ // Close overlay details
319
+ setStationId(null);
320
+ setLinesIds(null);
321
+ setTrainId(null);
322
+ }
323
+ }, [
324
+ closeMenus,
325
+ notificationId,
326
+ setFeaturesInfos,
327
+ setLinesIds,
328
+ setNotificationId,
329
+ setStationId,
330
+ setTrainId,
331
+ ]);
332
+
333
+ useEffect(() => {
334
+ if (linesIds?.length) {
335
+ closeMenus();
336
+
337
+ // Close overlay details
338
+ setStationId(null);
339
+ setNotificationId(null);
340
+ setTrainId(null);
341
+ }
342
+ }, [
343
+ linesIds?.length,
344
+ notificationId,
345
+ setFeaturesInfos,
346
+ closeMenus,
347
+
348
+ setLinesIds,
349
+ setNotificationId,
350
+ setStationId,
351
+ setTrainId,
352
+ ]);
353
+
276
354
  useEffect(() => {
277
355
  setIsOverlayOpen(
278
356
  (hasDetails && !!selectedFeature) ||
@@ -281,7 +359,8 @@ function LayoutState() {
281
359
  (hasShare && isShareMenuOpen) ||
282
360
  (hasRealtime && !!trainId) ||
283
361
  (tenant && !!stationId) ||
284
- (hasLnp && !!linesIds),
362
+ (hasLnp && !!linesIds) ||
363
+ (hasNotification && !!notificationId),
285
364
  );
286
365
  }, [
287
366
  hasDetails,
@@ -299,6 +378,8 @@ function LayoutState() {
299
378
  setIsOverlayOpen,
300
379
  hasLnp,
301
380
  linesIds,
381
+ hasNotification,
382
+ notificationId,
302
383
  ]);
303
384
 
304
385
  return null;
@@ -12,7 +12,7 @@ import type { RealtimeLine } from "mobility-toolbox-js/types";
12
12
  import type { Feature } from "ol";
13
13
  import type { PreactDOMAttributes } from "preact";
14
14
 
15
- import type { LineInfo } from "../utils/hooks/useLnp";
15
+ import type { LnpLineInfo } from "../utils/hooks/useLnp";
16
16
 
17
17
  const RUNS_PROP = "runs";
18
18
 
@@ -46,7 +46,7 @@ function LinesNetworkPlanDetails({
46
46
  [layerConfig],
47
47
  );
48
48
 
49
- const lineInfosByOperator: Record<string, LineInfo[]> = useMemo(() => {
49
+ const lineInfosByOperator: Record<string, LnpLineInfo[]> = useMemo(() => {
50
50
  const byOperators = {};
51
51
 
52
52
  [
@@ -2,24 +2,14 @@ import { MaplibreStyleLayer } from "mobility-toolbox-js/ol";
2
2
  import { memo } from "preact/compat";
3
3
  import { useEffect, useMemo } from "preact/hooks";
4
4
 
5
- import {
6
- LNP_GEOPS_FILTER_HIGHLIGHT,
7
- LNP_LINE_ID_PROP,
8
- } from "../utils/constants";
5
+ import { LNP_GEOPS_FILTER_HIGHLIGHT } from "../utils/constants";
9
6
  import highlightLinesNetworkPlan from "../utils/highlightLinesNetworkPlan";
10
7
  import useMapContext from "../utils/hooks/useMapContext";
11
8
 
12
9
  import type { MaplibreStyleLayerOptions } from "mobility-toolbox-js/ol/layers/MaplibreStyleLayer";
13
10
 
14
11
  function LinesNetworkPlanLayerHighlight(props: MaplibreStyleLayerOptions) {
15
- const {
16
- baseLayer,
17
- featuresInfos,
18
- linesIds,
19
- linesNetworkPlanLayer,
20
- map,
21
- setLinesIds,
22
- } = useMapContext();
12
+ const { baseLayer, linesIds, map } = useMapContext();
23
13
 
24
14
  const layer = useMemo(() => {
25
15
  if (!baseLayer) {
@@ -48,34 +38,6 @@ function LinesNetworkPlanLayerHighlight(props: MaplibreStyleLayerOptions) {
48
38
  };
49
39
  }, [map, layer]);
50
40
 
51
- useEffect(() => {
52
- if (!layer || !featuresInfos?.length || !linesNetworkPlanLayer) {
53
- return;
54
- }
55
- const features =
56
- featuresInfos.find((featuresInfo) => {
57
- return featuresInfo.layer === linesNetworkPlanLayer;
58
- })?.features || [];
59
-
60
- if (!features.length) {
61
- setLinesIds(null);
62
- return;
63
- }
64
-
65
- const ids = [
66
- ...new Set(
67
- (features || []).map((f) => {
68
- return f.get(LNP_LINE_ID_PROP) as string;
69
- }),
70
- ),
71
- ];
72
- if (!ids.length) {
73
- setLinesIds(null);
74
- return;
75
- }
76
- setLinesIds(ids?.length ? ids : null);
77
- }, [featuresInfos, layer, linesNetworkPlanLayer, setLinesIds]);
78
-
79
41
  useEffect(() => {
80
42
  if (!layer || !baseLayer?.loaded) {
81
43
  return;
@@ -102,7 +102,7 @@ function MapLayout({
102
102
  {hasSearch && <SearchButton />}
103
103
  </div>
104
104
 
105
- {hasSearch && (
105
+ {hasSearch && isSearchOpen && (
106
106
  <div
107
107
  className={twMerge(
108
108
  "absolute top-14 left-0 z-5 w-0 p-0 opacity-0 transition-all @sm:top-0 @sm:left-[calc(100%-47px)]",
@@ -111,13 +111,8 @@ function MapLayout({
111
111
  >
112
112
  <Search
113
113
  className={
114
- "border-grey @container m-0 h-[48px] gap-4 rounded-2xl border p-2 px-4 text-base @sm/main:rounded-l-none @sm/main:rounded-r-2xl"
114
+ "@container @sm/main:gap-4 @sm/main:rounded-l-none @sm/main:rounded-r-2xl"
115
115
  }
116
- // inputClassName="h-6 text-base"
117
- inputContainerClassName="border-none"
118
- resultClassName="text-base **:hover:cursor-pointer p-2"
119
- resultsContainerClassName="@container rounded-b-2xl max-h-[200px] overflow-y-auto border border-t-0 "
120
- withResultsClassName="text-base !rounded-b-none"
121
116
  />
122
117
  </div>
123
118
  )}
@@ -38,7 +38,6 @@ import type {
38
38
  LayerGetFeatureInfoResponse,
39
39
  RealtimeStation,
40
40
  RealtimeStationId,
41
- RealtimeStopSequence,
42
41
  RealtimeTrainId,
43
42
  SituationType,
44
43
  } from "mobility-toolbox-js/types";
@@ -75,7 +74,6 @@ function MobilityMap(props: MobilityMapProps) {
75
74
  const [isShareMenuOpen, setIsShareMenuOpen] = useState<boolean>(false);
76
75
  const [isLayerTreeOpen, setIsLayerTreeOpen] = useState<boolean>(false);
77
76
  const [isSearchOpen, setIsSearchOpen] = useState<boolean>(false);
78
- const [stopSequence, setStopSequence] = useState<RealtimeStopSequence>();
79
77
  const [stationsLayer, setStationsLayer] = useState<MaplibreStyleLayer>();
80
78
  const [station, setStation] = useState<RealtimeStation>();
81
79
  const [realtimeLayer, setRealtimeLayer] = useState<MtbRealtimeLayer>();
@@ -84,7 +82,7 @@ function MobilityMap(props: MobilityMapProps) {
84
82
  const [linesNetworkPlanLayer, setLinesNetworkPlanLayer] =
85
83
  useState<MaplibreStyleLayer>();
86
84
  const [map, setMap] = useState<OlMap>();
87
- const [stationId, setStationId] = useState<RealtimeStationId>();
85
+ const [stationId, setStationId] = useState<RealtimeStationId | string>();
88
86
  const [trainId, setTrainId] = useState<RealtimeTrainId>();
89
87
  const [linesIds, setLinesIds] = useState<string[]>();
90
88
  const [notificationId, setNotificationId] = useState<string>();
@@ -187,12 +185,10 @@ function MobilityMap(props: MobilityMapProps) {
187
185
  setStation,
188
186
  setStationId,
189
187
  setStationsLayer,
190
- setStopSequence,
191
188
  setTrainId,
192
189
  station,
193
190
  stationId,
194
191
  stationsLayer,
195
- stopSequence,
196
192
  trainId,
197
193
  };
198
194
  }, [
@@ -235,7 +231,6 @@ function MobilityMap(props: MobilityMapProps) {
235
231
  station,
236
232
  stationId,
237
233
  stationsLayer,
238
- stopSequence,
239
234
  trainId,
240
235
  ]);
241
236