@geops/rvf-mobility-web-component 0.1.81 → 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.
- package/CHANGELOG.md +47 -0
- package/index.js +206 -187
- package/package.json +2 -2
- package/src/Departure/Departure.tsx +6 -3
- package/src/FeatureDetails/FeatureDetails.tsx +4 -4
- package/src/FeaturesInfosListener/FeaturesInfosListener.tsx +22 -0
- package/src/LayerTreeMenu/LayerTreeMenu.tsx +12 -4
- package/src/LayoutState/LayoutState.tsx +144 -63
- package/src/LinesNetworkPlanDetails/LinesNetworkPlanDetails.tsx +2 -2
- package/src/LinesNetworkPlanLayerHighlight/LinesNetworkPlanLayerHighlight.tsx +2 -40
- package/src/MapLayout/MapLayout.tsx +2 -7
- package/src/MobilityMap/MobilityMap.tsx +1 -6
- package/src/MobilityMap/MobilityMapAttributes.ts +28 -7
- package/src/MobilityNotifications/MobilityNotifications.tsx +1 -0
- package/src/NotificationDetails/NotificationDetails.tsx +21 -22
- package/src/NotificationsLayer/NotificationsLayer.tsx +49 -3
- package/src/OverlayDetails/OverlayDetails.tsx +5 -0
- package/src/RealtimeLayer/RealtimeLayer.tsx +44 -50
- package/src/RouteIcon/RouteIcon.tsx +25 -14
- package/src/RouteSchedule/RouteSchedule.tsx +14 -11
- package/src/RouteScheduleFooter/RouteScheduleFooter.tsx +6 -3
- package/src/RouteScheduleHeader/RouteScheduleHeader.tsx +8 -2
- package/src/RouteStop/RouteStop.tsx +14 -29
- package/src/RouteStopPlatform/RouteStopPlatform.tsx +1 -3
- package/src/RouteStopProgress/RouteStopProgress.tsx +11 -18
- package/src/RouteStopStation/RouteStopStation.tsx +3 -3
- package/src/RvfRealtimeLayer/RvfRealtimeLayer.tsx +16 -3
- package/src/RvfSearch/RvfSearch.tsx +5 -4
- package/src/Search/Search.tsx +41 -20
- package/src/Search/SearchBase.tsx +169 -0
- package/src/Search/SearchHeadless.tsx +79 -0
- package/src/Search/index.tsx +2 -0
- package/src/SearchLinesResult/SearchLinesResult.tsx +43 -0
- package/src/SearchLinesResult/index.tsx +1 -0
- package/src/SearchLinesResults/SearchLinesResults.tsx +106 -0
- package/src/SearchLinesResults/index.tsx +1 -0
- package/src/SearchLnpStopsResult/SearchLnpStopsResult.tsx +42 -0
- package/src/SearchLnpStopsResult/index.tsx +1 -0
- package/src/SearchLnpStopsResults/SearchLnpStopsResults.tsx +106 -0
- package/src/SearchLnpStopsResults/index.tsx +1 -0
- package/src/SearchResult/SearchResult.tsx +25 -0
- package/src/SearchResult/index.tsx +1 -0
- package/src/SearchResults/SearchResults.tsx +81 -0
- package/src/SearchResults/index.tsx +1 -0
- package/src/SearchResultsHeader/SearchResultsHeader.tsx +36 -0
- package/src/SearchResultsHeader/index.tsx +1 -0
- package/src/SearchStopsResult/SearchStopsResult.tsx +43 -0
- package/src/SearchStopsResult/index.tsx +1 -0
- package/src/SearchStopsResults/SearchStopsResults.tsx +101 -0
- package/src/SearchStopsResults/index.tsx +1 -0
- package/src/SearchTrainsResult/SearchTrainsResult.tsx +42 -0
- package/src/SearchTrainsResult/index.tsx +1 -0
- package/src/SearchTrainsResults/SearchTrainsResults.tsx +109 -0
- package/src/SearchTrainsResults/index.tsx +1 -0
- package/src/SingleClickListener/SingleClickListener.tsx +38 -2
- package/src/SituationDetails/SituationDetails.tsx +7 -6
- package/src/Station/Station.tsx +23 -48
- package/src/StationHeader/StationHeader.tsx +3 -3
- package/src/StationsLayer/StationsLayer.tsx +9 -1
- package/src/StopsSearch/StopsSearch.tsx +2 -2
- package/src/ui/InputSearch/InputSearch.tsx +105 -0
- package/src/ui/InputSearch/index.tsx +1 -0
- package/src/utils/centerOnVehicle.ts +9 -2
- package/src/utils/constants.ts +8 -1
- package/src/utils/fullTrajectoryStyle.ts +4 -7
- package/src/utils/getBgColor.ts +4 -2
- package/src/utils/getDelayColorForVehicle.test.ts +21 -11
- package/src/utils/getDelayColorForVehicle.ts +7 -5
- package/src/utils/getDelayTextForVehicle.test.ts +12 -12
- package/src/utils/getDelayTextForVehicle.ts +4 -0
- package/src/utils/getMainColorForVehicle.ts +11 -4
- package/src/utils/getRadius.ts +9 -3
- package/src/utils/getTextColor.ts +1 -1
- package/src/utils/getTextColorForVehicle.ts +29 -0
- package/src/utils/getTextFontForVehicle.test.ts +1 -1
- package/src/utils/getTextFontForVehicle.tsx +11 -3
- package/src/utils/getTextForVehicle.ts +7 -1
- package/src/utils/hooks/useFit.tsx +69 -0
- package/src/utils/hooks/useFitOnFeatures.tsx +77 -0
- package/src/utils/hooks/useLayersConfig.tsx +3 -0
- package/src/utils/hooks/useLnp.tsx +39 -5
- package/src/utils/hooks/useMapContext.tsx +2 -5
- package/src/utils/hooks/useRealtimeDepartures.tsx +45 -0
- package/src/utils/hooks/useRealtimeRenderedTrajectory.tsx +42 -0
- package/src/utils/hooks/useRealtimeStation.tsx +39 -0
- package/src/utils/hooks/useRealtimeStopSequences.tsx +43 -0
- package/src/utils/hooks/useRealtimeTrainsByRouteIdentifier.tsx +71 -0
- package/src/utils/hooks/useRouteStop.tsx +7 -1
- package/src/utils/hooks/useSearchLines.tsx +34 -0
- package/src/utils/hooks/useSearchLnpStops.tsx +38 -0
- package/src/utils/hooks/useSearchStops.tsx +85 -0
- package/src/utils/hooks/useSearchTrains.tsx +83 -0
- package/src/utils/realtimeRVFStyle.ts +38 -30
- package/src/utils/translations.ts +17 -0
- package/tash +58 -0
- package/src/utils/centerOnStation.ts +0 -18
- package/src/utils/getDelayFontForVehicle.test.ts +0 -7
- package/src/utils/getDelayFontForVehicle.tsx +0 -8
- 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.
|
|
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
|
|
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 } =
|
|
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
|
-
|
|
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
|
-
{
|
|
54
|
-
|
|
55
|
-
|
|
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 {
|
|
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(
|
|
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
|
|
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
|
|
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(
|
|
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
|
-
|
|
135
|
-
|
|
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
|
-
|
|
155
|
-
|
|
156
|
-
setFeaturesInfos(null);
|
|
157
|
-
setLinesIds(null);
|
|
217
|
+
|
|
218
|
+
closeFeatureDetails();
|
|
158
219
|
}
|
|
159
220
|
}, [
|
|
160
221
|
isShareMenuOpen,
|
|
161
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
225
|
-
setTrainId(null);
|
|
226
|
-
setStationId(null);
|
|
269
|
+
setNotificationId(selectedFeature?.get("situationId") || null);
|
|
227
270
|
}
|
|
228
271
|
}, [
|
|
229
272
|
selectedFeature,
|
|
230
|
-
|
|
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
|
-
|
|
241
|
-
|
|
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
|
-
|
|
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
|
-
|
|
261
|
-
|
|
262
|
-
|
|
298
|
+
closeMenus();
|
|
299
|
+
|
|
300
|
+
// Close overlay details
|
|
263
301
|
setStationId(null);
|
|
264
|
-
|
|
302
|
+
setLinesIds(null);
|
|
303
|
+
setNotificationId(null);
|
|
265
304
|
}
|
|
266
305
|
}, [
|
|
306
|
+
closeMenus,
|
|
267
307
|
setFeaturesInfos,
|
|
268
|
-
|
|
269
|
-
|
|
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 {
|
|
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,
|
|
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
|
-
"
|
|
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
|
|