@geops/rvf-mobility-web-component 0.1.33 → 0.1.34

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.33",
5
+ "version": "0.1.34",
6
6
  "homepage": "https://rvf-mobility-web-component-geops.vercel.app/",
7
7
  "type": "module",
8
8
  "main": "index.js",
@@ -34,7 +34,7 @@ function RouteIcon({
34
34
  departure?.line ||
35
35
  stopSequence?.line ||
36
36
  trajectory?.properties?.line;
37
- const type = stopSequence?.type || trajectory?.type;
37
+ const type = lineToUse?.type || stopSequence?.type || trajectory?.type;
38
38
  const backgroundColor = getMainColorForVehicle(
39
39
  line || departure || stopSequence || trajectory,
40
40
  );
@@ -46,7 +46,10 @@ function RouteIcon({
46
46
 
47
47
  const fontSize = fontSizesByNbLetters[text.length] || 12;
48
48
  const font = getTextFontForVehicle(fontSize, text);
49
- const hasRealtime = stopSequence?.has_realtime_journey;
49
+
50
+ // RealtimeIcon only for stopsequence for now
51
+ const hasRealtime = stopSequence?.has_realtime_journey === true;
52
+ const showNoRealtimeIcon = !!stopSequence;
50
53
  const isCancelled = stopSequence?.stations[0]?.state === "JOURNEY_CANCELLED";
51
54
 
52
55
  if (borderColor === backgroundColor) {
@@ -67,7 +70,7 @@ function RouteIcon({
67
70
  >
68
71
  {children || text}
69
72
 
70
- {!isCancelled && !hasRealtime && (
73
+ {showNoRealtimeIcon && !isCancelled && !hasRealtime && (
71
74
  <NoRealtime className={"absolute -left-2 -top-2"} />
72
75
  )}
73
76
  </span>
@@ -6,11 +6,16 @@ import useMapContext from "../utils/hooks/useMapContext";
6
6
  import useRouteStop from "../utils/hooks/useRouteStop";
7
7
 
8
8
  export type RouteStopProgressProps = {
9
+ lineColor?: string;
9
10
  svgProps?: JSX.HTMLAttributes<SVGElement> & PreactDOMAttributes;
10
11
  } & JSX.HTMLAttributes<HTMLDivElement> &
11
12
  PreactDOMAttributes;
12
13
 
13
- function RouteStopProgress({ svgProps, ...props }: RouteStopProgressProps) {
14
+ function RouteStopProgress({
15
+ lineColor,
16
+ svgProps,
17
+ ...props
18
+ }: RouteStopProgressProps) {
14
19
  const { stopSequence } = useMapContext();
15
20
  const { invertColor, status } = useRouteStop();
16
21
  const { isBoarding, isFirst, isLast, isLeft, isPassed, progress } = status;
@@ -19,16 +24,16 @@ function RouteStopProgress({ svgProps, ...props }: RouteStopProgressProps) {
19
24
  const yDone = `${progress}%`;
20
25
 
21
26
  const greyColor = "rgb(156, 163, 175)";
22
- const lineColor = getMainColorForVehicle(stopSequence);
27
+ const lineColorr = lineColor || getMainColorForVehicle(stopSequence);
23
28
 
24
- let colorScheme = isPassed ? greyColor : lineColor;
25
- let invertColorScheme = isPassed ? lineColor : greyColor;
29
+ let colorScheme = isPassed ? greyColor : lineColorr;
30
+ let invertColorScheme = isPassed ? lineColorr : greyColor;
26
31
  let progressDoneColor = greyColor;
27
32
 
28
33
  if (invertColor) {
29
- colorScheme = isPassed ? lineColor : greyColor;
30
- invertColorScheme = isPassed ? greyColor : lineColor;
31
- progressDoneColor = lineColor;
34
+ colorScheme = isPassed ? lineColorr : greyColor;
35
+ invertColorScheme = isPassed ? greyColor : lineColorr;
36
+ progressDoneColor = lineColorr;
32
37
  }
33
38
 
34
39
  const circleColor =
@@ -1,9 +1,35 @@
1
+ import { RealtimeLine } from "mobility-toolbox-js/types";
1
2
  import { Feature } from "ol";
2
3
  import { useEffect, useMemo, useState } from "preact/hooks";
3
4
 
5
+ import ArrowDown from "../../icons/ArrowDown";
6
+ import ArrowUp from "../../icons/ArrowUp";
7
+ import RouteIcon from "../../RouteIcon";
8
+ import RouteStopProgress from "../../RouteStopProgress";
4
9
  import useMapContext from "../../utils/hooks/useMapContext";
10
+ import { RouteStopContext } from "../../utils/hooks/useRouteStop";
5
11
 
6
12
  let cacheLineInfosById = null;
13
+ let cacheStopInfosById = null;
14
+
15
+ interface LineInfo {
16
+ color: string;
17
+ external_id: string;
18
+ id: string;
19
+ long_name: string;
20
+ mot: string;
21
+ operator_name: string;
22
+ short_name: string;
23
+ text_color: string;
24
+ }
25
+
26
+ interface StopInfo {
27
+ external_id: string;
28
+ importance: number;
29
+ long_name: string;
30
+ short_name: string;
31
+ visibility_level: number;
32
+ }
7
33
 
8
34
  function RvfLineNetworkDetails({
9
35
  feature,
@@ -13,7 +39,11 @@ function RvfLineNetworkDetails({
13
39
  features: Feature[];
14
40
  }) {
15
41
  const { apikey, mapsurl } = useMapContext();
16
- const [lineInfos, setLineInfos] = useState(null);
42
+ const [lineInfos, setLineInfos] = useState<LineInfo[]>(null);
43
+ const [stopInfos, setStopInfos] = useState<StopInfo[]>(null);
44
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
45
+ const [stopInfosOpenId, setStopInfosOpenId] = useState<string>(null);
46
+
17
47
  useEffect(() => {
18
48
  const fetchInfos = async () => {
19
49
  if (!cacheLineInfosById) {
@@ -22,15 +52,16 @@ function RvfLineNetworkDetails({
22
52
  );
23
53
  const data = await response.json();
24
54
  cacheLineInfosById = data["geops.lnp.lines"];
55
+ cacheStopInfosById = data["geops.lnp.stops"];
25
56
  }
26
57
  setLineInfos(cacheLineInfosById);
58
+ setStopInfos(cacheStopInfosById);
27
59
  };
28
60
  fetchInfos();
29
61
  }, [apikey, mapsurl]);
30
62
 
31
- const lineNetworkIdsByOperator = useMemo(() => {
63
+ const lineInfosByOperator: Record<string, LineInfo[]> = useMemo(() => {
32
64
  const byOperators = {};
33
-
34
65
  [
35
66
  ...new Set(
36
67
  features.map((f) => {
@@ -46,51 +77,155 @@ function RvfLineNetworkDetails({
46
77
  if (!byOperators[operatorName]) {
47
78
  byOperators[operatorName] = [];
48
79
  }
80
+ lineInfos[id].id = id;
49
81
  byOperators[operatorName].push(lineInfos[id]);
50
82
  });
51
83
 
52
84
  return byOperators;
53
85
  }, [features, lineInfos]);
54
86
 
87
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
88
+ const stopInfoIdsByLineId: Record<string, string[]> = useMemo(() => {
89
+ const byLineId = {};
90
+ features.forEach((f) => {
91
+ const lineId = f.get("original_line_id");
92
+ if (lineId && !byLineId[lineId]) {
93
+ try {
94
+ byLineId[lineId] = JSON.parse(f.get("stop_ids"));
95
+ } catch (e) {
96
+ console.log(e);
97
+ }
98
+ }
99
+ });
100
+
101
+ return byLineId;
102
+ }, [features]);
103
+
55
104
  if (!feature || !lineInfos) {
56
105
  return null;
57
106
  }
58
107
 
59
108
  return (
60
109
  <div className="flex flex-col gap-4">
61
- {Object.entries(lineNetworkIdsByOperator).map(
62
- ([operatorName, linesInfos]) => {
63
- return (
64
- <div className={"flex flex-col gap-2"} key={operatorName}>
65
- <div>{operatorName}</div>
66
- {linesInfos.map((lineInfo) => {
110
+ {Object.entries(lineInfosByOperator).map(([operatorName, linesInfos]) => {
111
+ return (
112
+ <div className={"flex flex-col gap-2"} key={operatorName}>
113
+ <div>{operatorName}</div>
114
+ {linesInfos
115
+ .sort((a, b) => {
116
+ return a.short_name?.localeCompare(b.short_name);
117
+ })
118
+ .map((lineInfo) => {
67
119
  const {
120
+ color: backgroundColor,
121
+ id,
68
122
  // color,
69
123
  // external_id,
70
- long_name: longName,
124
+ long_name,
125
+ mot,
71
126
  short_name: shortName,
72
- // text_color,
127
+ text_color: textColor,
73
128
  } = lineInfo;
129
+ let longName = long_name;
130
+
131
+ let stops = null;
132
+ //stopInfoIdsByLineId?.[id] || null;
133
+ if (!stops?.length) {
134
+ stops = null;
135
+ }
136
+ console.log("stops", stops, longName);
137
+ if (!longName && stops) {
138
+ const names = stops.map((stopId) => {
139
+ return stopInfos[stopId].short_name;
140
+ });
141
+ console.log("stops", names);
142
+
143
+ longName = [
144
+ ...new Set([names[0], names[names.length - 1]]),
145
+ ].join(" - ");
146
+ }
147
+
148
+ // Build a line object
149
+ const line: { type: string } & RealtimeLine = {
150
+ color: null,
151
+ id: null,
152
+ name: shortName,
153
+ stroke: null,
154
+ text_color: null,
155
+ type: mot,
156
+ };
157
+
158
+ if (textColor) {
159
+ line.text_color = "#" + textColor;
160
+ }
161
+
162
+ if (backgroundColor) {
163
+ line.color = "#" + backgroundColor;
164
+ }
74
165
 
75
166
  return (
76
- <div className={"flex items-center gap-2"} key={shortName}>
77
- <div>
167
+ <div key={shortName}>
168
+ <div
169
+ className={
170
+ "flex w-full items-center justify-between gap-2"
171
+ }
172
+ // onClick={() => {
173
+ // setStopInfosOpenId(stopInfosOpenId === id ? null : id);
174
+ // }}
175
+ >
176
+ <div>
177
+ <RouteIcon line={line}></RouteIcon>
178
+ </div>
179
+ {!!longName && (
180
+ <div className={"flex-1 text-left"}>{longName}</div>
181
+ )}
182
+ {!!stops && (
183
+ <button className={"shrink-0"}>
184
+ {stopInfosOpenId === id ? <ArrowUp /> : <ArrowDown />}
185
+ </button>
186
+ )}
187
+ </div>
188
+ {!!stops && (
78
189
  <div
79
- className={
80
- "rounded-md bg-red px-[12px] py-[9px] font-bold leading-none text-white"
81
- }
190
+ className={`${stopInfosOpenId === id ? "" : "hidden"}`}
82
191
  >
83
- {shortName}
192
+ {stops?.map((stopId, index, arr) => {
193
+ const stop = stopInfos[stopId];
194
+ return (
195
+ <div
196
+ className={"flex items-center gap-2"}
197
+ key={stopId}
198
+ >
199
+ <RouteStopContext.Provider
200
+ value={{
201
+ index,
202
+ status: {
203
+ isFirst: !index,
204
+ isLast: index === arr.length - 1,
205
+ isLeft: false,
206
+ isPassed: false,
207
+ progress: !index ? 50 : 0,
208
+ },
209
+ stop,
210
+ }}
211
+ >
212
+ <RouteStopProgress
213
+ className="relative flex size-8 shrink-0 items-center justify-center"
214
+ lineColor={line.color}
215
+ />
216
+ <div>{stop.short_name}</div>
217
+ </RouteStopContext.Provider>
218
+ </div>
219
+ );
220
+ })}
84
221
  </div>
85
- </div>
86
- <div>{longName}</div>
222
+ )}
87
223
  </div>
88
224
  );
89
225
  })}
90
- </div>
91
- );
92
- },
93
- )}
226
+ </div>
227
+ );
228
+ })}
94
229
  </div>
95
230
  );
96
231
  }
@@ -15,9 +15,10 @@ const getFeatureInformationTitle = (feature: Feature) => {
15
15
  category,
16
16
  disruption_type: disruptionType,
17
17
  feed_id: feedId,
18
- long_name: longName,
18
+ line_id: lineId,
19
19
  tickets,
20
20
  } = selectedFeature.getProperties();
21
+ console.log(selectedFeature.getProperties());
21
22
 
22
23
  if (disruptionType) {
23
24
  return "MOCO Meldung";
@@ -29,7 +30,7 @@ const getFeatureInformationTitle = (feature: Feature) => {
29
30
  return TITLE_BY_FEED_ID[feedId] || defaultTitle;
30
31
  }
31
32
 
32
- if (longName) {
33
+ if (lineId) {
33
34
  return RVF_LAYERS_TITLES.liniennetz;
34
35
  }
35
36
  if (tickets) {