@geops/rvf-mobility-web-component 0.1.93 → 0.1.95

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,20 +2,20 @@
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.93",
5
+ "version": "0.1.95",
6
6
  "homepage": "https://rvf-mobility-web-component-geops.vercel.app/",
7
7
  "type": "module",
8
8
  "main": "index.js",
9
9
  "dependencies": {
10
10
  "graphql": "^16.10.0",
11
11
  "graphql-request": "^7.1.2",
12
- "jspdf": "^3.0.3",
12
+ "jspdf": "^3.0.4",
13
13
  "lodash.debounce": "^4.0.8",
14
- "maplibre-gl": "^5.10.0",
15
- "mobility-toolbox-js": "3.5.1-beta.5",
16
- "ol": "^10.6.1",
17
- "preact": "^10.27.2",
18
- "preact-custom-element": "^4.5.1",
14
+ "maplibre-gl": "5.12.0",
15
+ "mobility-toolbox-js": "3.6.0",
16
+ "ol": "^10.7.0",
17
+ "preact": "^10.28.0",
18
+ "preact-custom-element": "^4.6.0",
19
19
  "react": "npm:@preact/compat@^18.3.1",
20
20
  "react-dom": "npm:@preact/compat@^18.3.1",
21
21
  "react-icons": "^5.5.0",
@@ -23,21 +23,21 @@
23
23
  "rosetta": "^1.1.0"
24
24
  },
25
25
  "devDependencies": {
26
- "@commitlint/cli": "^20.1.0",
27
- "@commitlint/config-conventional": "^20.0.0",
28
- "@eslint/js": "^9.38.0",
26
+ "@commitlint/cli": "^20.2.0",
27
+ "@commitlint/config-conventional": "^20.2.0",
28
+ "@eslint/js": "^9.39.1",
29
29
  "@geops/eslint-config-react": "^1.6.0-beta.1",
30
- "@tailwindcss/cli": "^4.1.16",
30
+ "@tailwindcss/cli": "^4.1.17",
31
31
  "@tailwindcss/container-queries": "^0.1.1",
32
32
  "@testing-library/preact": "^3.2.4",
33
33
  "@types/geojson": "^7946.0.16",
34
34
  "@types/jest": "^30.0.0",
35
- "@types/lodash": "^4.17.20",
35
+ "@types/lodash": "^4.17.21",
36
36
  "@types/preact-custom-element": "^4.0.4",
37
37
  "concurrently": "^9.2.1",
38
- "esbuild": "^0.25.11",
38
+ "esbuild": "^0.27.1",
39
39
  "esbuild-sass-plugin": "^3.3.1",
40
- "eslint": "^9.38.0",
40
+ "eslint": "^9.39.1",
41
41
  "eslint-plugin-tailwindcss": "^4.0.0-beta.0",
42
42
  "fixpack": "^4.0.0",
43
43
  "generact": "^0.4.0",
@@ -46,16 +46,16 @@
46
46
  "jest-canvas-mock": "^2.5.2",
47
47
  "jest-environment-jsdom": "^30.2.0",
48
48
  "jest-preset-preact": "^4.1.1",
49
- "next": "15.5.5",
49
+ "next": "15.5.7",
50
50
  "preact-render-to-string": "^6.6.3",
51
- "prettier": "^3.6.2",
52
- "prettier-plugin-tailwindcss": "^0.7.1",
51
+ "prettier": "^3.7.4",
52
+ "prettier-plugin-tailwindcss": "^0.7.2",
53
53
  "standard-version": "^9.5.0",
54
- "tailwind-merge": "^3.3.1",
55
- "tailwindcss": "^4.1.16",
56
- "ts-jest": "^29.4.5",
54
+ "tailwind-merge": "^3.4.0",
55
+ "tailwindcss": "^4.1.17",
56
+ "ts-jest": "^29.4.6",
57
57
  "typescript": "^5.9.3",
58
- "typescript-eslint": "^8.46.2"
58
+ "typescript-eslint": "^8.49.0"
59
59
  },
60
60
  "scripts": {
61
61
  "build": "yarn build:css && yarn build:js && cp index*.js* doc/public/",
@@ -16,8 +16,7 @@ export type GeolocationButtonProps = IconButtonProps;
16
16
  const TRACKING_ZOOM = 16;
17
17
 
18
18
  function GeolocationButton({ ...props }: GeolocationButtonProps) {
19
- const mapContext = useMapContext();
20
- const { isTracking, map, setIsTracking } = mapContext;
19
+ const { isTracking, map, setIsTracking } = useMapContext();
21
20
  const { t } = useI18n();
22
21
 
23
22
  const geolocation = useMemo(() => {
@@ -1 +1 @@
1
- export { default } from "../RvfGeolocationButton";
1
+ export { default } from "./GeolocationButton";
@@ -1,6 +1,7 @@
1
1
  import { useCallback, useEffect } from "preact/hooks";
2
2
 
3
3
  import useFit from "../utils/hooks/useFit";
4
+ import useI18n from "../utils/hooks/useI18n";
4
5
  import useLnpLineInfo, { useLnpStopInfo } from "../utils/hooks/useLnp";
5
6
  import useMapContext from "../utils/hooks/useMapContext";
6
7
  import useRealtimeTrainByRouteIdentifier from "../utils/hooks/useRealtimeTrainsByRouteIdentifier";
@@ -32,6 +33,7 @@ function LayoutState() {
32
33
  notification,
33
34
  notificationid,
34
35
  notificationId,
36
+ notificationlang,
35
37
  permalink,
36
38
  previewNotifications,
37
39
  print,
@@ -60,6 +62,7 @@ function LayoutState() {
60
62
  setIsShareMenuOpen,
61
63
  setLinesIds,
62
64
  setNotificationId,
65
+ setNotificationLangFallbacks,
63
66
  setStationId,
64
67
  setTrainId,
65
68
  share,
@@ -75,6 +78,21 @@ function LayoutState() {
75
78
  const stopInfo = useLnpStopInfo(stationid);
76
79
  const trainInfo = useRealtimeTrainByRouteIdentifier(trainid);
77
80
  const fit = useFit();
81
+ const { locale } = useI18n();
82
+
83
+ // Define fallback languages from the notifications details
84
+ useEffect(() => {
85
+ const fallbackLangs =
86
+ notificationlang
87
+ ?.split(",")
88
+ .map((lang) => {
89
+ return lang.trim();
90
+ })
91
+ .filter((lang) => {
92
+ return lang !== locale();
93
+ }) || [];
94
+ setNotificationLangFallbacks(fallbackLangs);
95
+ }, [notificationlang, setNotificationLangFallbacks, locale]);
78
96
 
79
97
  useEffect(() => {
80
98
  setHasStations(!!tenant);
@@ -331,10 +349,10 @@ function LayoutState() {
331
349
  (hasPrint && isExportMenuOpen) ||
332
350
  (hasLayerTree && isLayerTreeOpen) ||
333
351
  (hasShare && isShareMenuOpen) ||
334
- (hasRealtime && !!trainId) ||
335
- (tenant && !!stationId) ||
336
- (hasLnp && !!linesIds) ||
337
- (hasNotification && !!notificationId),
352
+ (hasDetails && hasRealtime && !!trainId) ||
353
+ (hasDetails && tenant && !!stationId) ||
354
+ (hasDetails && hasLnp && !!linesIds) ||
355
+ (hasDetails && hasNotification && !!notificationId),
338
356
  );
339
357
  }, [
340
358
  hasDetails,
@@ -85,6 +85,8 @@ function MobilityMap(props: MobilityMapProps) {
85
85
  const [trainId, setTrainId] = useState<RealtimeTrainId>();
86
86
  const [linesIds, setLinesIds] = useState<string[]>();
87
87
  const [notificationId, setNotificationId] = useState<string>();
88
+ const [notificationLangFallbacks, setNotificationLangFallbacks] =
89
+ useState<string[]>();
88
90
 
89
91
  const [featuresInfos, setFeaturesInfos] = useState<
90
92
  LayerGetFeatureInfoResponse[]
@@ -110,7 +112,6 @@ function MobilityMap(props: MobilityMapProps) {
110
112
  return {
111
113
  // MobilityMapProps
112
114
  ...props,
113
- // MapContextProps
114
115
  baseLayer,
115
116
  featuresInfos,
116
117
  featuresInfosHovered,
@@ -140,6 +141,8 @@ function MobilityMap(props: MobilityMapProps) {
140
141
  map,
141
142
  mapsetLayer,
142
143
  notificationId,
144
+ // MapContextProps
145
+ notificationLangFallbacks,
143
146
  notificationsLayer,
144
147
  permalinkUrlSearchParams,
145
148
  previewNotifications,
@@ -175,6 +178,7 @@ function MobilityMap(props: MobilityMapProps) {
175
178
  setMap,
176
179
  setMapsetLayer,
177
180
  setNotificationId,
181
+ setNotificationLangFallbacks,
178
182
  setNotificationsLayer,
179
183
  setPermalinkUrlSearchParams,
180
184
  setPreviewNotifications,
@@ -221,6 +225,7 @@ function MobilityMap(props: MobilityMapProps) {
221
225
  map,
222
226
  mapsetLayer,
223
227
  notificationId,
228
+ notificationLangFallbacks,
224
229
  notificationsLayer,
225
230
  permalinkUrlSearchParams,
226
231
  previewNotifications,
@@ -1,5 +1,4 @@
1
1
  //type: "checkbox" | "date" | "select" | "textfield";
2
-
3
2
  import {
4
3
  DEFAULT_QUERYABLE_LAYERS,
5
4
  LAYERS_NAMES,
@@ -53,6 +52,7 @@ export type MobilityMapAttributeName =
53
52
  | "notification"
54
53
  | "notificationat"
55
54
  | "notificationid"
55
+ | "notificationlang"
56
56
  | "notificationtenant"
57
57
  | "notificationurl"
58
58
  | "permalink"
@@ -125,7 +125,7 @@ const attrs: MobilityMapAttributes = {
125
125
  defaultValue: "de",
126
126
  description:
127
127
  "The language to use for the map. Supported languages are : de, en, fr, it.",
128
- public: false,
128
+ public: true,
129
129
  },
130
130
  layers: {
131
131
  defaultValue: null,
@@ -258,6 +258,12 @@ where:
258
258
  description: `An id of a notification to show details of.`,
259
259
  public: false,
260
260
  },
261
+ notificationlang: {
262
+ defaultValue: "en,de,fr",
263
+ description:
264
+ "A comma separated list of languages supported by the notification, if a textual content is not available in the current lang it will try to display the content in one of these languages. Order is important. <br/>Supported languages are: en,de,fr,it",
265
+ public: true,
266
+ },
261
267
  notificationtenant: {
262
268
  defaultValue: "rvf",
263
269
  description: `The ${geopsMocoApiLink} tenant to get the notification from.`,
@@ -1,9 +1,10 @@
1
1
  import { MocoAPI } from "mobility-toolbox-js/ol";
2
2
  import { SeverityEnumeration } from "mobility-toolbox-js/types";
3
- import { memo, useEffect, useState } from "preact/compat";
3
+ import { memo, useEffect, useMemo, useState } from "preact/compat";
4
4
 
5
5
  import I18n from "../I18n";
6
6
  import SituationDetails from "../SituationDetails";
7
+ import useI18n from "../utils/hooks/useI18n";
7
8
 
8
9
  import MobilityNotificationsAttributes from "./MobilityNotificationsAttributes";
9
10
 
@@ -33,10 +34,26 @@ const severityOrder = {
33
34
  function MobilityNotifications({
34
35
  apikey,
35
36
  lang,
37
+ notificationlang,
36
38
  notificationtenant,
37
39
  notificationurl,
38
40
  }: MobilityNotificationsProps) {
39
41
  const [situations, setSituations] = useState<SituationType[]>([]);
42
+ const { locale } = useI18n();
43
+
44
+ // Define fallback languages from the notificationlang attribute
45
+ const fallbackLangs = useMemo(() => {
46
+ return (
47
+ notificationlang
48
+ ?.split(",")
49
+ .map((l) => {
50
+ return l.trim();
51
+ })
52
+ .filter((l) => {
53
+ return l !== locale();
54
+ }) || []
55
+ );
56
+ }, [locale, notificationlang]);
40
57
 
41
58
  useEffect(() => {
42
59
  new MocoAPI({
@@ -104,6 +121,7 @@ function MobilityNotifications({
104
121
  return (
105
122
  <SituationDetails
106
123
  canToggle={true}
124
+ fallbackLangs={fallbackLangs}
107
125
  headerClassName="text-rvf-h3 font-semibold"
108
126
  iconClassName="w-8 h-8 text-red"
109
127
  key={situation.id}
@@ -7,6 +7,7 @@ export type MobilityNotificationsAttributeName =
7
7
  | "apikey"
8
8
  | "lang"
9
9
  | "notificationat"
10
+ | "notificationlang"
10
11
  | "notificationtenant"
11
12
  | "notificationurl";
12
13
 
@@ -24,13 +25,19 @@ const attrs: MobilityNotificationsAttributes = {
24
25
  lang: {
25
26
  defaultValue: "de",
26
27
  description: "The language to use for the notifications.",
27
- public: false,
28
+ public: true,
28
29
  },
29
30
  notificationat: {
30
31
  description:
31
32
  "An ISO date string used to display active notification at this date in the notification layer. If not defined the current date will be used.<br/>Ex: 2025-08-01T00:00:00Z .",
32
33
  public: false,
33
34
  },
35
+ notificationlang: {
36
+ defaultValue: "en,de,fr",
37
+ description:
38
+ "A comma separated list of languages supported by the notification, if a textual content is not available in the current lang it will try to display the content in one of these languages. Order is important. <br/>Supported languages are: en,de,fr,it",
39
+ public: true,
40
+ },
34
41
  notificationtenant: {
35
42
  defaultValue: "rvf",
36
43
  description: `The ${geopsMocoApiLink} tenant to get the notification from.`,
@@ -52,7 +52,7 @@ function NotificationDetails({
52
52
  feature: Feature;
53
53
  }) {
54
54
  const { locale, t } = useI18n();
55
- const { notificationId } = useMapContext();
55
+ const { notificationId, notificationLangFallbacks } = useMapContext();
56
56
  const situationParsed = useMocoSituation(notificationId);
57
57
 
58
58
  // moco export v2
@@ -116,20 +116,31 @@ function NotificationDetails({
116
116
  textualContentMedium,
117
117
  textualContentSmall,
118
118
  }) => {
119
+ let localeToUse = locale();
120
+
119
121
  // Get the textual content in German
120
122
  textualContentMultilingual =
121
123
  textualContentLarge ||
122
124
  textualContentMedium ||
123
125
  textualContentSmall;
124
126
 
125
- textualContent = textualContentMultilingual?.[locale()];
127
+ textualContent = textualContentMultilingual?.[localeToUse];
126
128
 
127
- // Fallback to default language if there is not title in the current language
128
129
  if (!textualContent?.summary) {
129
- textualContent = textualContentMultilingual?.de;
130
+ // Try to find textualContent with a title using fallback languages
131
+ // If we do notfind a fallback we stick to the current language.
132
+ for (const fallbackLang of notificationLangFallbacks) {
133
+ const goodTextualContent =
134
+ textualContentMultilingual?.[fallbackLang];
135
+ if (goodTextualContent?.summary) {
136
+ localeToUse = fallbackLang;
137
+ textualContent = goodTextualContent;
138
+ break;
139
+ }
140
+ }
130
141
  }
131
142
 
132
- const pubLines =
143
+ let pubLines =
133
144
  publicationLines?.flatMap((publication) => {
134
145
  return (
135
146
  publication.lines?.map(({ name }) => {
@@ -137,11 +148,14 @@ function NotificationDetails({
137
148
  }) || []
138
149
  );
139
150
  }) || [];
151
+ pubLines = [...new Set(pubLines)]; // Remove duplicates
140
152
 
141
- const stations = publicationStops.map((publication) => {
153
+ let stations = publicationStops.map((publication) => {
142
154
  return publication?.name || "";
143
155
  });
144
156
 
157
+ stations = [...new Set(stations)]; // Remove duplicates
158
+
145
159
  return (
146
160
  <div className={"text-base"} key={id}>
147
161
  <div className="text-xs uppercase">{reasonsToDisplay}</div>
@@ -233,8 +247,7 @@ function NotificationDetails({
233
247
  <div>
234
248
  {textualContentMultilingual.infoLinks.map(
235
249
  ({ label, uri }) => {
236
- const title =
237
- label?.[locale()] || label?.de || uri || "";
250
+ const title = label?.[localeToUse] || uri || "";
238
251
  return (
239
252
  <Link href={uri} key={uri} title={title}>
240
253
  {title}
@@ -3,7 +3,10 @@ import { unByKey } from "ol/Observable";
3
3
  import { memo } from "preact/compat";
4
4
  import { useEffect, useMemo, useState } from "preact/hooks";
5
5
 
6
- import { LAYER_NAME_NOTIFICATIONS } from "../utils/constants";
6
+ import {
7
+ LAYER_NAME_NOTIFICATIONS,
8
+ // MAX_EXTENT
9
+ } from "../utils/constants";
7
10
  import useMapContext from "../utils/hooks/useMapContext";
8
11
 
9
12
  function NotificationsLayer(props?: Partial<MocoLayerOptions>) {
@@ -29,6 +32,7 @@ function NotificationsLayer(props?: Partial<MocoLayerOptions>) {
29
32
  const mocoLayer = new MocoLayer({
30
33
  apiKey: apikey,
31
34
  apiParameters: {
35
+ // bbox: MAX_EXTENT,
32
36
  contentMedium: true,
33
37
  isEdited: true,
34
38
  publicNow: true,
@@ -2,13 +2,13 @@ import { twMerge } from "tailwind-merge";
2
2
 
3
3
  import ShadowOverflow from "../../ShadowOverflow";
4
4
  import SituationDetails from "../../SituationDetails";
5
+ import useMapContext from "../../utils/hooks/useMapContext";
5
6
  import useMocoSituation from "../../utils/hooks/useMocoSituation";
6
7
 
7
8
  import type { Feature } from "ol";
8
9
 
9
10
  function NotificationDetails({
10
11
  className,
11
- feature,
12
12
  ...props
13
13
  }: {
14
14
  className?: string;
@@ -20,12 +20,15 @@ function NotificationDetails({
20
20
  timeIntervalClassName?: string;
21
21
  toggleable?: boolean;
22
22
  }) {
23
- const { situationId } = feature.getProperties();
24
- const situationParsed = useMocoSituation(situationId);
25
- console.log("situationParsed", feature.getProperties());
23
+ const { notificationId, notificationLangFallbacks } = useMapContext();
24
+ const situationParsed = useMocoSituation(notificationId);
25
+
26
26
  return (
27
27
  <ShadowOverflow {...props} className={twMerge("px-4 text-base", className)}>
28
- <SituationDetails situation={situationParsed} />
28
+ <SituationDetails
29
+ fallbackLangs={notificationLangFallbacks}
30
+ situation={situationParsed}
31
+ />
29
32
  </ShadowOverflow>
30
33
  );
31
34
  }
@@ -82,7 +82,7 @@ function RvfMapLayout({
82
82
  <Copyright className="pointer-events-auto bg-slate-50/70" />
83
83
  </div>
84
84
  <div className="absolute top-2 right-2 z-10 flex">
85
- {hasGeolocation && <GeolocationButton title={"Geolokalisierung"} />}
85
+ {hasGeolocation && <GeolocationButton />}
86
86
  </div>
87
87
  <div className="absolute right-2 bottom-10 z-10 flex flex-col justify-between gap-2">
88
88
  <ZoomButtons />
@@ -39,8 +39,11 @@ const toShortDate = (
39
39
  );
40
40
  };
41
41
 
42
+ const emptyArray: string[] = [];
43
+
42
44
  function SituationDetails({
43
45
  canToggle = false,
46
+ fallbackLangs = emptyArray,
44
47
  headerClassName,
45
48
  iconClassName,
46
49
  publicationClassName,
@@ -50,6 +53,7 @@ function SituationDetails({
50
53
  useShortMonth = true,
51
54
  }: {
52
55
  canToggle?: boolean;
56
+ fallbackLangs?: string[];
53
57
  headerClassName?: string;
54
58
  iconClassName?: string;
55
59
  publicationClassName?: string;
@@ -122,15 +126,27 @@ function SituationDetails({
122
126
  textualContentMedium,
123
127
  textualContentSmall,
124
128
  }) => {
129
+ let localeToUse = locale();
130
+
125
131
  // Get the textual content in German
126
132
  textualContentMultilingual =
127
133
  textualContentLarge || textualContentMedium || textualContentSmall;
128
134
 
129
- textualContent = textualContentMultilingual?.[locale()];
135
+ textualContent = textualContentMultilingual?.[localeToUse];
130
136
 
131
137
  // Fallback to default language if there is not title in the current language
132
138
  if (!textualContent?.summary) {
133
- textualContent = textualContentMultilingual?.de;
139
+ // Try to find textualContent with a title using fallback languages
140
+ // If we do notfind a fallback we stick to the current language.
141
+ for (const fallbackLang of fallbackLangs) {
142
+ const goodTextualContent =
143
+ textualContentMultilingual?.[fallbackLang];
144
+ if (goodTextualContent?.summary) {
145
+ localeToUse = fallbackLang;
146
+ textualContent = goodTextualContent;
147
+ break;
148
+ }
149
+ }
134
150
  }
135
151
 
136
152
  const pubLines =
@@ -273,8 +289,7 @@ function SituationDetails({
273
289
  <div>
274
290
  {textualContentMultilingual.infoLinks.map(
275
291
  ({ label, uri }) => {
276
- const title =
277
- label?.[locale()] || label?.de || uri || "";
292
+ const title = label?.[localeToUse] || uri || "";
278
293
  return (
279
294
  <Link href={uri} key={uri} title={title}>
280
295
  {title}
@@ -14,28 +14,10 @@ const applyInitialLayerVisibility = (
14
14
  const names = layersAttrValue?.split(",") || [];
15
15
  const name = layer.get("name");
16
16
  const shouldBeVisible = names.includes(name);
17
- if (layer.getVisible() !== shouldBeVisible) {
17
+ // Visiblity of group are defined by their children, they should not appear in the permalink.
18
+ if (layer.getVisible() !== shouldBeVisible && !(layer as Group).getLayers) {
18
19
  layer.setVisible(shouldBeVisible);
19
-
20
- if ((layer as Group).getLayers) {
21
- (layer as Group)
22
- .getLayers()
23
- .getArray()
24
- .forEach((subLayer) => {
25
- subLayer.setVisible(shouldBeVisible);
26
- // applyInitialLayerVisibility(layersAttrValue, subLayer);
27
- });
28
- }
29
20
  }
30
21
  }
31
- if ((layer as Group).getLayers) {
32
- (layer as Group)
33
- .getLayers()
34
- .getArray()
35
- .forEach((subLayer) => {
36
- // subLayer.setVisible(false);
37
- applyInitialLayerVisibility(layersAttrValue, subLayer);
38
- });
39
- }
40
22
  };
41
23
  export default applyInitialLayerVisibility;
@@ -7,6 +7,7 @@ import applyInitialLayerVisibility from "../applyInitialLayerVisibility";
7
7
  import useInitialPermalink from "./useInitialPermalink";
8
8
 
9
9
  import type { Map } from "ol";
10
+ import type { Group } from "ol/layer";
10
11
  const useInitialLayersVisiblity = (
11
12
  map: Map,
12
13
  layers: string,
@@ -34,10 +35,31 @@ const useInitialLayersVisiblity = (
34
35
  isPermalinkAlreadyUsed.current = true;
35
36
  }
36
37
 
37
- getLayersAsFlatArray(map.getLayers().getArray()).forEach((layer) => {
38
+ // We reverse the array to begin by the end of the tree (so the group layers are applied last)
39
+ const layersAsArray = getLayersAsFlatArray(map.getLayers().getArray());
40
+ layersAsArray.forEach((layer) => {
38
41
  applyInitialLayerVisibility(layersToUse, layer);
39
42
  });
40
43
 
44
+ // Hide group if there is no children visible
45
+ layersAsArray
46
+ .filter((l) => {
47
+ return (l as Group).getLayers;
48
+ })
49
+ .forEach((layer) => {
50
+ if (
51
+ layer.getVisible() &&
52
+ !(layer as Group)
53
+ .getLayers()
54
+ ?.getArray()
55
+ .some((l) => {
56
+ return l.getVisible();
57
+ })
58
+ ) {
59
+ layer.setVisible(false);
60
+ }
61
+ });
62
+
41
63
  const key = map.getLayers().on("add", (event) => {
42
64
  applyInitialLayerVisibility(layersToUse, event.element);
43
65
  });
@@ -51,6 +51,7 @@ export type MapContextType = {
51
51
  map: Map;
52
52
  mapsetLayer?: MapsetLayer;
53
53
  notificationId?: string;
54
+ notificationLangFallbacks: string[];
54
55
  notificationsLayer?: MocoLayer;
55
56
  permalinkUrlSearchParams: URLSearchParams;
56
57
  previewNotifications?: SituationType[];
@@ -88,6 +89,7 @@ export type MapContextType = {
88
89
  setMap: (map?: Map) => void;
89
90
  setMapsetLayer: (mapsetLayer?: MapsetLayer) => void;
90
91
  setNotificationId: (notificationId?: string) => void;
92
+ setNotificationLangFallbacks: (langs: string[]) => void;
91
93
  setNotificationsLayer: (notificationsLayer?: MocoLayer) => void;
92
94
  setPermalinkUrlSearchParams: (
93
95
  setPermalinkUrlSearchParams: URLSearchParams,
@@ -128,6 +130,7 @@ export const MapContext = createContext<MapContextType>({
128
130
  isSearchOpen: false,
129
131
  isShareMenuOpen: false,
130
132
  isTracking: false,
133
+ notificationLangFallbacks: [],
131
134
  selectedFeatures: [],
132
135
  setBaseLayer: (baseLayer?: MaplibreLayer) => {},
133
136
  setIsFollowing: (isFollowing: boolean) => {},
@@ -137,6 +140,7 @@ export const MapContext = createContext<MapContextType>({
137
140
  setMap: (map?: Map) => {},
138
141
  setMapsetLayer: (mapsetLayer?: MapsetLayer) => {},
139
142
  setNotificationId: (notificationId?: string) => {},
143
+ setNotificationLangFallbacks: (langs: string[]) => {},
140
144
  setNotificationsLayer: (notificationsLayer?: MocoLayer) => {},
141
145
  setPermalinkUrlSearchParams: (
142
146
  permalinkUrlSearchParams: URLSearchParams,
@@ -35,7 +35,7 @@ const translations: Translations = {
35
35
  [LAYERS_NAMES.notifications]: "Meldungen",
36
36
  [LAYERS_NAMES.pois]: "POIs",
37
37
  [LAYERS_NAMES.realtime]: "Echtzeit",
38
- [LAYERS_NAMES.sharedMobility]: "Shared-Angebote",
38
+ [LAYERS_NAMES.sharedMobility]: "Sharing-Angebote",
39
39
  [LAYERS_NAMES.stations]: "Stationen",
40
40
  [LAYERS_NAMES.tarifzonen]: "Tarifzonen",
41
41
  [LAYERS_NAMES.verkaufsstellen]: "Verkaufsstellen",
package/.yarnrc.yml DELETED
@@ -1 +0,0 @@
1
- nodeLinker: node-modules