@geops/rvf-mobility-web-component 0.1.45 → 0.1.47-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/.prettierrc.js +3 -1
- package/CHANGELOG.md +7 -0
- package/README.md +1 -1
- package/doc/package.json +4 -3
- package/doc/postcss.config.mjs +1 -1
- package/doc/src/app/components/GeopsMobilityDoc.tsx +13 -224
- package/doc/src/app/components/GeopsMobilitySearchDoc.tsx +11 -107
- package/doc/src/app/components/WebComponentDoc.tsx +45 -56
- package/doc/src/app/geops-mobility/page.tsx +7 -2
- package/doc/src/app/geops-mobility-search/page.tsx +6 -2
- package/doc/src/app/globals.css +47 -27
- package/doc/src/app/layout.tsx +4 -2
- package/docutils.js +33 -17
- package/eslint.config.mjs +28 -34
- package/iframe.html +5624 -201
- package/index.html +108 -88
- package/index.js +2229 -1976
- package/input.css +21 -3
- package/package.json +37 -40
- package/scripts/build.mjs +2 -2
- package/scripts/dev.mjs +3 -3
- package/search.html +70 -23
- package/src/BaseLayer/BaseLayer.tsx +2 -1
- package/src/Copyright/Copyright.tsx +4 -2
- package/src/DebugDeparture/DebugDeparture.tsx +16 -12
- package/src/DebugStop/DebugStop.tsx +2 -2
- package/src/Departure/Departure.tsx +2 -3
- package/src/EmbedNavigation/DragPanWarning.ts +125 -0
- package/src/EmbedNavigation/EmbedNavigation.tsx +52 -0
- package/src/EmbedNavigation/index.js +1 -0
- package/src/EmbedNavigation/index.tsx +1 -0
- package/src/GeolocationButton/GeolocationButton.tsx +11 -35
- package/src/GeolocationButton/index.tsx +1 -1
- package/src/Map/Map.tsx +5 -3
- package/src/MapDispatchEvents/MapDispatchEvents.tsx +78 -0
- package/src/MapDispatchEvents/index.tsx +1 -0
- package/src/MobilityMap/MobilityMap.tsx +117 -162
- package/src/MobilityMap/MobilityMapAttributes.test.ts +21 -0
- package/src/MobilityMap/MobilityMapAttributes.ts +243 -0
- package/src/MobilityMap/index.tsx +1 -0
- package/src/MobilitySearch/MobilitySearch.tsx +35 -0
- package/src/MobilitySearch/MobilitySearchAttributes.test.ts +21 -0
- package/src/MobilitySearch/MobilitySearchAttributes.ts +68 -0
- package/src/MobilitySearch/index.ts +2 -0
- package/src/NotificationLayer/NotificationLayer.tsx +27 -4
- package/src/Overlay/Overlay.tsx +24 -11
- package/src/Permalink/Permalink.tsx +77 -0
- package/src/Permalink/index.tsx +1 -0
- package/src/RealtimeLayer/RealtimeLayer.tsx +72 -33
- package/src/RouteDestination/RouteDestination.tsx +3 -3
- package/src/RouteIcon/RouteIcon.tsx +33 -25
- package/src/RouteIcon/index.tsx +1 -1
- package/src/RouteIdentifier/RouteIdentifer.tsx +6 -5
- package/src/RouteInfos/RouteInfos.tsx +7 -3
- package/src/RouteSchedule/RouteSchedule.tsx +3 -3
- package/src/RouteScheduleFooter/RouteScheduleFooter.tsx +1 -1
- package/src/RouteScheduleHeader/RouteScheduleHeader.tsx +7 -29
- package/src/RouteStop/RouteStop.tsx +8 -11
- package/src/RouteStopDelay/RouteStopDelay.tsx +2 -1
- package/src/RouteStopName/RouteStopName.tsx +2 -2
- package/src/RouteStopPlatform/RouteStopPlatform.tsx +2 -2
- package/src/RouteStopProgress/RouteStopProgress.tsx +2 -1
- package/src/RouteStopServices/RouteStopServices.tsx +2 -2
- package/src/RouteStopStation/RouteStopStation.tsx +8 -2
- package/src/RouteStopTime/RouteStopTime.tsx +2 -1
- package/src/RvfButton/RvfButton.tsx +14 -5
- package/src/RvfCheckbox/RvfCheckbox.tsx +8 -8
- package/src/RvfEmbedNavigation/DragPanWarning.ts +5 -5
- package/src/RvfEmbedNavigation/RvfEmbedNavigation.tsx +1 -0
- package/src/RvfExportMenu/RvfExportMenu.tsx +14 -12
- package/src/RvfExportMenuButton/RvfExportMenuButton.tsx +6 -7
- package/src/RvfFeatureDetails/RvfFeatureDetails.tsx +5 -5
- package/src/RvfFeatureDetails/RvfLineNetworkDetails/RvfLineNetworkDetails.tsx +164 -138
- package/src/RvfFeatureDetails/RvfNotificationDetails/RvfNotificationDetails.tsx +151 -109
- package/src/RvfFeatureDetails/RvfSellingPointDetails/RvfSellingPointDetails.tsx +2 -2
- package/src/RvfFeatureDetails/RvfSharedMobilityDetail/FloatingVehiclesDetails/FloatingVehiclesDetails.tsx +3 -3
- package/src/RvfFeatureDetails/RvfSharedMobilityDetail/RvfSharedMobilityDetails.tsx +8 -6
- package/src/RvfFeatureDetails/RvfSharedMobilityDetail/StationDetails/StationDetails.tsx +5 -4
- package/src/RvfFeatureDetailsTitle/RvfFeatureDetailsTitle.tsx +81 -0
- package/src/RvfFeatureDetailsTitle/index.tsx +1 -0
- package/src/RvfFloatingMenu/RvfFloatingMenu.tsx +4 -4
- package/src/RvfGeolocationButton/GeolocationButton.tsx +98 -0
- package/src/RvfGeolocationButton/index.tsx +1 -0
- package/src/RvfIconButton/RvfIconButton.tsx +20 -9
- package/src/RvfInputCopy/RvfInputCopy.tsx +8 -8
- package/src/RvfLayerTree/RvfLayerTree.tsx +5 -2
- package/src/RvfLayerTree/TreeItem/TreeItem.tsx +13 -16
- package/src/RvfLayerTree/layersTreeReducer.ts +23 -18
- package/src/RvfLayerTreeButton/RvfLayerTreeButton.tsx +6 -6
- package/src/RvfLineNetworkPlanLayer/RvfLineNetworkPlanLayer.tsx +2 -1
- package/src/RvfLink/RvfLink.tsx +4 -3
- package/src/RvfMobilityMap/RvfMobilityMap.tsx +314 -322
- package/src/RvfModal/RvfModal.tsx +4 -3
- package/src/RvfOverlayContent/RvfOverlayContent.tsx +126 -0
- package/src/RvfOverlayContent/index.ts +0 -0
- package/src/RvfOverlayHeader/RvfOverlayHeader.tsx +13 -10
- package/src/RvfPermalink/RvfPermalink.tsx +2 -2
- package/src/RvfPoisLayer/RvfPoisLayer.tsx +2 -1
- package/src/RvfRadioButton/RvfRadioButton.tsx +1 -1
- package/src/RvfRouteIcon/RvfRouteIcon.tsx +10 -0
- package/src/RvfRouteIcon/index.tsx +1 -0
- package/src/RvfSearch/RvfSearch.tsx +4 -1
- package/src/RvfSearchButton/RvfSearchButton.tsx +27 -0
- package/src/RvfSearchButton/index.tsx +1 -0
- package/src/RvfSelect/RvfSelect.tsx +7 -5
- package/src/RvfSelectedFeatureHighlightLayer/RvfSelectedFeatureHighlightLayer.tsx +1 -2
- package/src/RvfSellingPointsLayer/RvfSellingPointsLayer.tsx +2 -1
- package/src/RvfShare/RvfPermalinkButton/RvfPermalinkButton.tsx +13 -12
- package/src/RvfShare/RvfShare.tsx +11 -10
- package/src/RvfShareMenuButton/RvfShareMenuButton.tsx +5 -5
- package/src/RvfSharedMobilityLayerGroup/RvfSharedMobilityLayerGroup.tsx +25 -22
- package/src/RvfSingleClickListener/RvfSingleClickListener.tsx +46 -31
- package/src/RvfTarifZonenLayer/RvfTarifZonenLayer.tsx +2 -1
- package/src/RvfTopics/RvfTopics.tsx +6 -5
- package/src/RvfZoomButtons/RvfZoomButtons.tsx +3 -3
- package/src/ScaleLine/ScaleLine.tsx +5 -4
- package/src/ScrollableHandler/ScrollableHandler.tsx +2 -1
- package/src/ScrollableHandler/index.tsx +1 -1
- package/src/SingleClickListener/SingleClickListener.tsx +47 -4
- package/src/Station/Station.tsx +5 -5
- package/src/StationName/StationName.tsx +3 -3
- package/src/StationServices/StationServices.tsx +3 -3
- package/src/StationsLayer/StationsLayer.tsx +5 -4
- package/src/StopsSearch/StopsSearch.tsx +115 -84
- package/src/WindowMessageListener/WindowMessageListener.tsx +67 -0
- package/src/WindowMessageListener/index.tsx +1 -0
- package/src/icons/Airport/Airport.tsx +4 -4
- package/src/icons/ArrowDown/ArrowDown.tsx +1 -1
- package/src/icons/ArrowUp/ArrowUp.tsx +1 -1
- package/src/icons/ArrowUpRight/ArrowUpRight.tsx +1 -1
- package/src/icons/BarAndRestaurants/BarAndRestaurants.tsx +2 -2
- package/src/icons/Bathroom/Bathroom.tsx +1 -1
- package/src/icons/Copy/Copy.tsx +1 -1
- package/src/icons/Doc/Doc.tsx +1 -1
- package/src/icons/Email/Email.tsx +1 -1
- package/src/icons/FilePdf/FilePdf.tsx +1 -1
- package/src/icons/Geolocation/Geolocation.tsx +3 -5
- package/src/icons/Image/Image.tsx +1 -1
- package/src/icons/Menu/Menu.tsx +1 -1
- package/src/icons/Minus/Minus.tsx +1 -1
- package/src/icons/NoRealtime/NoRealtime.tsx +1 -1
- package/src/icons/Plus/Plus.tsx +1 -1
- package/src/icons/Police/Police.tsx +3 -3
- package/src/icons/Share/Share.tsx +1 -1
- package/src/icons/Stack/Stack.tsx +1 -1
- package/src/icons/Tracking/Tracking.tsx +29 -0
- package/src/icons/Tracking/airport-14-svgrepo-com.svg +41 -0
- package/src/icons/Tracking/index.tsx +1 -0
- package/src/icons/WaitingAreas/WaitingAreas.tsx +1 -1
- package/src/icons/WheelChair/WheelChair.tsx +1 -1
- package/src/index.tsx +8 -46
- package/src/indexDoc.ts +13 -0
- package/src/ui/Button/Button.tsx +57 -0
- package/src/ui/Button/index.tsx +1 -0
- package/src/ui/IconButton/IconButton.tsx +44 -0
- package/src/ui/IconButton/index.tsx +1 -0
- package/src/utils/MobilityEvent.ts +4 -3
- package/src/utils/applyInitialLayerVisibility.ts +3 -3
- package/src/utils/centerOnStation.ts +3 -2
- package/src/utils/centerOnVehicle.ts +5 -4
- package/src/utils/constants.ts +17 -3
- package/src/utils/exportPdf.ts +26 -20
- package/src/utils/fullTrajectoryStyle.ts +2 -2
- package/src/utils/getAllLayers.ts +4 -3
- package/src/utils/getDelayColor.test.ts +1 -0
- package/src/utils/getDelayColorForVehicle.test.ts +2 -0
- package/src/utils/getDelayString.test.ts +3 -0
- package/src/utils/getDelayTextForVehicle.test.ts +4 -0
- package/src/utils/getFullTrajectoryAndFit.ts +4 -3
- package/src/utils/getHoursAndMinutes.test.ts +1 -0
- package/src/utils/getLayersAsFlatArray.ts +2 -2
- package/src/utils/getLinkByDevice.ts +1 -1
- package/src/utils/getMainColorForVehicle.ts +3 -3
- package/src/utils/getPermalinkParameters.ts +2 -2
- package/src/utils/getStopStatus.test.ts +2 -1
- package/src/utils/getStopStatus.ts +1 -1
- package/src/utils/getTextForVehicle.ts +1 -1
- package/src/utils/hooks/useDeparture.tsx +6 -5
- package/src/utils/hooks/useI18n.tsx +6 -4
- package/src/utils/hooks/useInitialLayersVisiblity.tsx +2 -1
- package/src/utils/hooks/useLayerConfig.tsx +39 -0
- package/src/utils/hooks/useMapContext.tsx +30 -18
- package/src/utils/hooks/useRouteStop.tsx +3 -2
- package/src/utils/hooks/useRvfContext.tsx +11 -3
- package/src/utils/hooks/useStation.tsx +2 -1
- package/src/utils/hooks/useUpdatePermalink.tsx +25 -24
- package/src/utils/hooks/useZoom.tsx +4 -4
- package/src/utils/realtimeRVFStyle.ts +5 -4
- package/src/utils/sharingGraphqlUtils.ts +3 -2
- package/src/utils/sharingStylesUtils.ts +7 -7
- package/src/utils/sharingWFSUtils.ts +9 -15
- package/tailwind.config.mjs +1 -0
- package/tsconfig.json +1 -1
- package/doc/tailwind.config.ts +0 -20
- package/src/utils/getFeatureInformationTitle.tsx +0 -54
package/src/index.tsx
CHANGED
|
@@ -1,58 +1,20 @@
|
|
|
1
1
|
import register from "preact-custom-element";
|
|
2
2
|
|
|
3
3
|
import MobilityMap from "./MobilityMap";
|
|
4
|
-
import
|
|
4
|
+
import MobilityMapAttributes from "./MobilityMap/MobilityMapAttributes";
|
|
5
|
+
import MobilitySearch, { MobilitySearchAttributes } from "./MobilitySearch";
|
|
5
6
|
|
|
6
|
-
register(
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
"apikey",
|
|
11
|
-
"baselayer",
|
|
12
|
-
"center",
|
|
13
|
-
"extent",
|
|
14
|
-
"maxextent",
|
|
15
|
-
"geolocation",
|
|
16
|
-
"details",
|
|
17
|
-
"layers",
|
|
18
|
-
"layertree",
|
|
19
|
-
"mapsurl",
|
|
20
|
-
"mots",
|
|
21
|
-
"notification",
|
|
22
|
-
"notificationat",
|
|
23
|
-
"notificationurl",
|
|
24
|
-
"notificationbeforelayerid",
|
|
25
|
-
"print",
|
|
26
|
-
"realtime",
|
|
27
|
-
"realtimeurl",
|
|
28
|
-
"search",
|
|
29
|
-
"share",
|
|
30
|
-
"tenant",
|
|
31
|
-
"zoom",
|
|
32
|
-
"permalink",
|
|
33
|
-
"embed",
|
|
34
|
-
],
|
|
35
|
-
{ shadow: true },
|
|
36
|
-
);
|
|
7
|
+
register(MobilityMap, "geops-mobility", Object.keys(MobilityMapAttributes), {
|
|
8
|
+
mode: "open",
|
|
9
|
+
shadow: true,
|
|
10
|
+
});
|
|
37
11
|
|
|
38
12
|
register(
|
|
39
13
|
MobilitySearch,
|
|
40
14
|
"geops-mobility-search",
|
|
41
|
-
|
|
42
|
-
"apikey",
|
|
43
|
-
"bbox",
|
|
44
|
-
"countrycode",
|
|
45
|
-
"event",
|
|
46
|
-
"field",
|
|
47
|
-
"limit",
|
|
48
|
-
"mots",
|
|
49
|
-
"onselect",
|
|
50
|
-
"params",
|
|
51
|
-
"prefagencies",
|
|
52
|
-
"reflocation",
|
|
53
|
-
"url",
|
|
54
|
-
],
|
|
15
|
+
Object.keys(MobilitySearchAttributes),
|
|
55
16
|
{
|
|
17
|
+
mode: "open",
|
|
56
18
|
shadow: true,
|
|
57
19
|
},
|
|
58
20
|
);
|
package/src/indexDoc.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// This file contains what we need to build the documentation in the index.html file
|
|
2
|
+
|
|
3
|
+
import MobilityMapAttributes from "./MobilityMap/MobilityMapAttributes";
|
|
4
|
+
import MobilitySearchAttributes from "./MobilitySearch/MobilitySearchAttributes";
|
|
5
|
+
|
|
6
|
+
if (typeof window !== "undefined") {
|
|
7
|
+
// @ts-expect-error it's wanted
|
|
8
|
+
window.MobilityMapAttributes = MobilityMapAttributes;
|
|
9
|
+
// @ts-expect-error it's wanted
|
|
10
|
+
window.MobilitySearchAttributes = MobilitySearchAttributes;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default { MobilityMapAttributes, MobilitySearchAttributes };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { memo, useMemo } from "preact/compat";
|
|
2
|
+
|
|
3
|
+
import type {
|
|
4
|
+
AnchorHTMLAttributes,
|
|
5
|
+
ButtonHTMLAttributes,
|
|
6
|
+
PreactDOMAttributes,
|
|
7
|
+
} from "preact";
|
|
8
|
+
|
|
9
|
+
export type ButtonProps = {
|
|
10
|
+
className?: string;
|
|
11
|
+
selected?: boolean;
|
|
12
|
+
theme?: "primary" | "secondary";
|
|
13
|
+
} & AnchorHTMLAttributes &
|
|
14
|
+
ButtonHTMLAttributes &
|
|
15
|
+
PreactDOMAttributes;
|
|
16
|
+
|
|
17
|
+
const baseClasses = "flex";
|
|
18
|
+
|
|
19
|
+
export const themes = {
|
|
20
|
+
primary: {
|
|
21
|
+
classes: "",
|
|
22
|
+
selectedClasses: "",
|
|
23
|
+
},
|
|
24
|
+
secondary: {
|
|
25
|
+
classes: "",
|
|
26
|
+
selectedClasses: "",
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
function Button({
|
|
31
|
+
children,
|
|
32
|
+
className,
|
|
33
|
+
href,
|
|
34
|
+
selected = false,
|
|
35
|
+
theme = "secondary",
|
|
36
|
+
...props
|
|
37
|
+
}: ButtonProps) {
|
|
38
|
+
const classes = useMemo(() => {
|
|
39
|
+
return `${baseClasses} ${themes[theme].classes} ${selected ? themes[theme].selectedClasses : ""} ${className || ""}`;
|
|
40
|
+
}, [className, selected, theme]);
|
|
41
|
+
|
|
42
|
+
if (href) {
|
|
43
|
+
return (
|
|
44
|
+
<a className={classes} href={href} {...props}>
|
|
45
|
+
{children}
|
|
46
|
+
</a>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<button className={classes} {...props}>
|
|
52
|
+
{children}
|
|
53
|
+
</button>
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export default memo(Button);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "../../RvfButton";
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { memo, useMemo } from "preact/compat";
|
|
2
|
+
|
|
3
|
+
import type { ButtonHTMLAttributes, PreactDOMAttributes } from "preact";
|
|
4
|
+
|
|
5
|
+
export type IconButtonProps = {
|
|
6
|
+
className?: string;
|
|
7
|
+
selected?: boolean;
|
|
8
|
+
theme?: "primary" | "secondary";
|
|
9
|
+
} & ButtonHTMLAttributes<HTMLButtonElement> &
|
|
10
|
+
PreactDOMAttributes;
|
|
11
|
+
|
|
12
|
+
const baseClasses =
|
|
13
|
+
"flex size-9 items-center justify-center rounded-full bg-white p-1.5 shadow-lg";
|
|
14
|
+
|
|
15
|
+
export const themes = {
|
|
16
|
+
primary: {
|
|
17
|
+
classes: "",
|
|
18
|
+
selectedClasses: "",
|
|
19
|
+
},
|
|
20
|
+
secondary: {
|
|
21
|
+
classes: "",
|
|
22
|
+
selectedClasses: "",
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
function IconButton({
|
|
27
|
+
children,
|
|
28
|
+
className,
|
|
29
|
+
selected = false,
|
|
30
|
+
theme = "secondary",
|
|
31
|
+
...props
|
|
32
|
+
}: IconButtonProps) {
|
|
33
|
+
const classes = useMemo(() => {
|
|
34
|
+
return `${baseClasses} ${themes[theme].classes} ${selected ? themes[theme].selectedClasses : ""} ${className || ""}`;
|
|
35
|
+
}, [className, selected, theme]);
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<button className={classes} {...props}>
|
|
39
|
+
{children}
|
|
40
|
+
</button>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export default memo(IconButton);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "../../RvfIconButton";
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import type { MobilityMapProps } from "../MobilityMap/MobilityMap";
|
|
2
|
-
|
|
3
1
|
export type MobilityEventType =
|
|
4
2
|
| "mwc:attribute"
|
|
3
|
+
| "mwc:permalink"
|
|
4
|
+
| "mwc:selectedfeature"
|
|
5
5
|
| "mwc:stopssearchselect"
|
|
6
6
|
| string;
|
|
7
7
|
|
|
8
8
|
class MobilityEvent<T> extends Event {
|
|
9
|
-
data:
|
|
9
|
+
data: T;
|
|
10
10
|
|
|
11
11
|
constructor(name: MobilityEventType, data: T, options: EventInit = {}) {
|
|
12
12
|
super(name, { ...options, composed: true });
|
|
@@ -14,6 +14,7 @@ class MobilityEvent<T> extends Event {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
logImportantData() {
|
|
17
|
+
// eslint-disable-next-line no-console
|
|
17
18
|
console.log(this.data);
|
|
18
19
|
}
|
|
19
20
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Group } from "ol/layer";
|
|
2
|
-
import BaseLayer from "ol/layer/Base";
|
|
1
|
+
import type { Group } from "ol/layer";
|
|
2
|
+
import type BaseLayer from "ol/layer/Base";
|
|
3
3
|
|
|
4
4
|
const applyInitialLayerVisibility = (
|
|
5
5
|
layersAttrValue: string,
|
|
@@ -11,7 +11,7 @@ const applyInitialLayerVisibility = (
|
|
|
11
11
|
!!(layersAttrValue !== null && layersAttrValue !== undefined);
|
|
12
12
|
|
|
13
13
|
if (hasLayersAttribute) {
|
|
14
|
-
const names =
|
|
14
|
+
const names = layersAttrValue?.split(",") || [];
|
|
15
15
|
const name = layer.get("name");
|
|
16
16
|
const shouldBeVisible = names.includes(name);
|
|
17
17
|
if (layer.getVisible() !== shouldBeVisible) {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { Map } from "ol";
|
|
2
1
|
import { fromLonLat } from "ol/proj";
|
|
3
2
|
|
|
4
|
-
import {
|
|
3
|
+
import type { Map } from "ol";
|
|
4
|
+
|
|
5
|
+
import type { StationFeature } from "../StopsSearch";
|
|
5
6
|
|
|
6
7
|
const centerOnStation = (selectedStation: StationFeature, map: Map) => {
|
|
7
8
|
const center = selectedStation?.geometry?.coordinates;
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { getVehiclePosition } from "mobility-toolbox-js/ol";
|
|
2
|
-
import { RealtimeTrajectory } from "mobility-toolbox-js/types";
|
|
3
|
-
import { Map } from "ol";
|
|
4
2
|
import { linear } from "ol/easing";
|
|
5
3
|
|
|
4
|
+
import type { RealtimeTrajectory } from "mobility-toolbox-js/types";
|
|
5
|
+
import type { Map } from "ol";
|
|
6
|
+
|
|
6
7
|
const centerOnVehicle = async (
|
|
7
8
|
vehicle: RealtimeTrajectory,
|
|
8
9
|
map: Map,
|
|
9
10
|
targetZoom = 0,
|
|
10
11
|
) => {
|
|
11
12
|
if (!vehicle) {
|
|
12
|
-
return Promise.reject();
|
|
13
|
+
return Promise.reject(new Error("No vehicle provided"));
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
const {
|
|
@@ -26,7 +27,7 @@ const centerOnVehicle = async (
|
|
|
26
27
|
center = coord as [number, number];
|
|
27
28
|
}
|
|
28
29
|
if (!center) {
|
|
29
|
-
return Promise.reject();
|
|
30
|
+
return Promise.reject(new Error("No center found"));
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
view.cancelAnimations();
|
package/src/utils/constants.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { FeatureCollection } from "geojson";
|
|
2
1
|
import { fromLonLat, toLonLat, transformExtent } from "ol/proj";
|
|
3
2
|
|
|
4
3
|
import callBike from "../logos/callabike_logo.png";
|
|
@@ -10,6 +9,12 @@ import naturEnergieLogo from "../logos/natur_energie_logo.png";
|
|
|
10
9
|
import yoioLogo from "../logos/yoio_logo.png";
|
|
11
10
|
import zeusLogo from "../logos/zeus_logo.png";
|
|
12
11
|
|
|
12
|
+
import type { FeatureCollection } from "geojson";
|
|
13
|
+
|
|
14
|
+
export const LAYER_NAME_REALTIME = "echtzeit";
|
|
15
|
+
export const LAYER_NAME_STATIONS = "haltestellen";
|
|
16
|
+
export const LAYER_NAME_NOTIFICATION = "meldungen";
|
|
17
|
+
|
|
13
18
|
export const RVF_EXTENT_4326 = [7.5, 47.7, 8.45, 48.4];
|
|
14
19
|
|
|
15
20
|
export const RVF_EXTENT_3857 = transformExtent(
|
|
@@ -48,16 +53,25 @@ export const RVF_LAYERS_NAMES = {
|
|
|
48
53
|
carGrf: "grueneflotte",
|
|
49
54
|
carNatur: "naturenergie",
|
|
50
55
|
carOthers: "autoandere",
|
|
51
|
-
echtzeit:
|
|
56
|
+
echtzeit: LAYER_NAME_REALTIME,
|
|
52
57
|
eroller: "e-roller",
|
|
53
|
-
haltestellen:
|
|
58
|
+
haltestellen: LAYER_NAME_STATIONS,
|
|
54
59
|
liniennetz: "liniennetz",
|
|
60
|
+
meldungen: LAYER_NAME_NOTIFICATION,
|
|
55
61
|
mitfahrpunkte: "mitfahrpunkte",
|
|
56
62
|
pois: "pois",
|
|
57
63
|
tarifzonen: "tarifzonen",
|
|
58
64
|
verkaufsstellen: "verkaufsstellen",
|
|
59
65
|
};
|
|
60
66
|
|
|
67
|
+
export const DEFAULT_QUERYABLE_LAYERS = Object.keys(RVF_LAYERS_NAMES)
|
|
68
|
+
.filter((name) => {
|
|
69
|
+
return (
|
|
70
|
+
name !== RVF_LAYERS_NAMES.tarifzonen && name !== RVF_LAYERS_NAMES.pois
|
|
71
|
+
);
|
|
72
|
+
})
|
|
73
|
+
.toString();
|
|
74
|
+
|
|
61
75
|
export const WFS_CARGO_BIKE_TYPE = "sharing_stations_cargo_bicycle";
|
|
62
76
|
export const WFS_CAR_TYPE = "sharing_stations_car";
|
|
63
77
|
export const WFS_BIKE_TYPE = "sharing_stations_bicycle";
|
package/src/utils/exportPdf.ts
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
|
-
import jsPDF
|
|
1
|
+
import jsPDF from "jspdf";
|
|
2
2
|
import { CopyrightControl } from "mobility-toolbox-js/ol";
|
|
3
3
|
import { Map } from "ol";
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
6
|
-
import BaseLayer from "ol/layer/Base";
|
|
7
|
-
import { MapOptions } from "ol/Map";
|
|
8
|
-
import { Size } from "ol/size";
|
|
9
|
-
import View, { ViewOptions } from "ol/View";
|
|
4
|
+
import { getBottomRight, getTopLeft } from "ol/extent";
|
|
5
|
+
import View from "ol/View";
|
|
10
6
|
|
|
11
7
|
import { RVF_EXTENT_3857 } from "./constants";
|
|
12
8
|
|
|
9
|
+
import type { jsPDFOptions } from "jspdf";
|
|
10
|
+
import type { Coordinate } from "ol/coordinate";
|
|
11
|
+
import type { Extent } from "ol/extent";
|
|
12
|
+
import type BaseLayer from "ol/layer/Base";
|
|
13
|
+
import type { MapOptions } from "ol/Map";
|
|
14
|
+
import type { Size } from "ol/size";
|
|
15
|
+
import type { ViewOptions } from "ol/View";
|
|
16
|
+
|
|
13
17
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
14
18
|
const getMargin = (destCanvas) => {
|
|
15
19
|
const newMargin = destCanvas.width / 100; // 1% of the canvas width
|
|
@@ -186,7 +190,9 @@ const drawText = (
|
|
|
186
190
|
const wordNumber = text.split(" ").length;
|
|
187
191
|
for (let i = 0; i < wordNumber; i += 1) {
|
|
188
192
|
// Stop removing word when fits within one line.
|
|
189
|
-
|
|
193
|
+
// Wher comes the scale from?
|
|
194
|
+
// if (firstLineMetrics.width * (scale ?? 1) < canvas.width) {
|
|
195
|
+
if (firstLineMetrics.width * 1 < canvas.width) {
|
|
190
196
|
break;
|
|
191
197
|
}
|
|
192
198
|
firstLine = firstLine.substring(0, firstLine.lastIndexOf(" "));
|
|
@@ -213,12 +219,12 @@ const drawText = (
|
|
|
213
219
|
lines.forEach((line) => {
|
|
214
220
|
const { fontBoundingBoxAscent, fontBoundingBoxDescent } =
|
|
215
221
|
ctx.measureText(line);
|
|
216
|
-
const
|
|
222
|
+
const heightt = fontBoundingBoxAscent + fontBoundingBoxDescent;
|
|
217
223
|
ctx.fillText(line, lineX, lineY);
|
|
218
224
|
|
|
219
|
-
let delta =
|
|
225
|
+
let delta = heightt;
|
|
220
226
|
if (textBaseline === "bottom") {
|
|
221
|
-
delta = -
|
|
227
|
+
delta = -heightt;
|
|
222
228
|
}
|
|
223
229
|
|
|
224
230
|
lineY = lineY + delta;
|
|
@@ -358,7 +364,7 @@ const calculatePixelsToExport = (map: Map, extent: Extent, coordinates) => {
|
|
|
358
364
|
};
|
|
359
365
|
|
|
360
366
|
// Create an canvas from a map.
|
|
361
|
-
const createCanvasImage =
|
|
367
|
+
const createCanvasImage = (
|
|
362
368
|
map: Map,
|
|
363
369
|
extent?: Extent,
|
|
364
370
|
coordinates?: Coordinate[],
|
|
@@ -405,14 +411,14 @@ const createCanvasImage = async (
|
|
|
405
411
|
);
|
|
406
412
|
}
|
|
407
413
|
|
|
408
|
-
return destCanvas;
|
|
414
|
+
return Promise.resolve(destCanvas);
|
|
409
415
|
};
|
|
410
416
|
|
|
411
|
-
const downloadCanvasImage =
|
|
417
|
+
const downloadCanvasImage = (
|
|
412
418
|
canvas: HTMLCanvasElement,
|
|
413
419
|
format = "image/png",
|
|
414
|
-
getDownloadImageName = (
|
|
415
|
-
return
|
|
420
|
+
getDownloadImageName = (formatImage: string) => {
|
|
421
|
+
return formatImage.replace("/", ".");
|
|
416
422
|
},
|
|
417
423
|
): Promise<boolean> => {
|
|
418
424
|
try {
|
|
@@ -442,10 +448,10 @@ const downloadCanvasImage = async (
|
|
|
442
448
|
}, format);
|
|
443
449
|
}
|
|
444
450
|
|
|
445
|
-
return true;
|
|
451
|
+
return Promise.resolve(true);
|
|
446
452
|
} catch (error) {
|
|
447
453
|
console.error(error);
|
|
448
|
-
return false;
|
|
454
|
+
return Promise.resolve(false);
|
|
449
455
|
}
|
|
450
456
|
};
|
|
451
457
|
|
|
@@ -499,7 +505,7 @@ const createMapToExport = async (
|
|
|
499
505
|
}, 10000);
|
|
500
506
|
|
|
501
507
|
// rendercomplete is triggered when all the layers renderer have the property "ready" to true.
|
|
502
|
-
mapHd.once("rendercomplete",
|
|
508
|
+
mapHd.once("rendercomplete", () => {
|
|
503
509
|
clearTimeout(timeout);
|
|
504
510
|
resolve(mapHd);
|
|
505
511
|
});
|
|
@@ -633,7 +639,7 @@ async function exportPdf(
|
|
|
633
639
|
if (useCopyright) {
|
|
634
640
|
drawCopyright(copyrightText, canvas, {
|
|
635
641
|
...(mapExportOptions?.copyrightOptions || {}),
|
|
636
|
-
font: (pixelRatio * 12).toString()
|
|
642
|
+
font: `${(pixelRatio * 12).toString()}px Arial`,
|
|
637
643
|
});
|
|
638
644
|
}
|
|
639
645
|
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { Collection } from "ol";
|
|
2
|
-
import BaseLayer from "ol/layer/Base";
|
|
3
1
|
import Group from "ol/layer/Group";
|
|
4
2
|
|
|
3
|
+
import type { Collection } from "ol";
|
|
4
|
+
import type BaseLayer from "ol/layer/Base";
|
|
5
|
+
|
|
5
6
|
const getAllLayers = (
|
|
6
7
|
layersOrLayerGroup: BaseLayer[] | Collection<BaseLayer> | Group,
|
|
7
8
|
) => {
|
|
@@ -9,7 +10,7 @@ const getAllLayers = (
|
|
|
9
10
|
function addLayersFrom(layers: BaseLayer[] | Collection<BaseLayer>) {
|
|
10
11
|
layers.forEach(function (layer) {
|
|
11
12
|
if (layer instanceof Group) {
|
|
12
|
-
addLayersFrom(
|
|
13
|
+
addLayersFrom(layer.getLayers());
|
|
13
14
|
} else {
|
|
14
15
|
allLayers.push(layer);
|
|
15
16
|
}
|
|
@@ -14,6 +14,7 @@ describe("getDelayColor", () => {
|
|
|
14
14
|
expect(getDelayColor(3 * 60 * 1000)).toBe("#ea580c");
|
|
15
15
|
expect(getDelayColor(5 * 60 * 1000)).toBe("#ea580c");
|
|
16
16
|
});
|
|
17
|
+
|
|
17
18
|
it("returns red", () => {
|
|
18
19
|
expect(getDelayColor(9.49 * 60 * 1000 - 1)).toBe("#dc2626");
|
|
19
20
|
expect(getDelayColor(10 * 60 * 1000)).toBe("#dc2626");
|
|
@@ -5,6 +5,7 @@ describe("getDelayColorForVehicle", () => {
|
|
|
5
5
|
expect(getDelayColorForVehicle(0, true, true)).toBe("#dc2626");
|
|
6
6
|
expect(getDelayColorForVehicle(0, true, false)).toBe("#a0a0a0");
|
|
7
7
|
});
|
|
8
|
+
|
|
8
9
|
it("returns null delay (no realtime train) color", () => {
|
|
9
10
|
expect(getDelayColorForVehicle(null)).toBe("transparent");
|
|
10
11
|
});
|
|
@@ -27,6 +28,7 @@ describe("getDelayColorForVehicle", () => {
|
|
|
27
28
|
expect(getDelayColorForVehicle(4.49 * 60 * 1000 - 1)).toBe("#ea580c");
|
|
28
29
|
expect(getDelayColorForVehicle(5 * 60 * 1000)).toBe("#ea580c");
|
|
29
30
|
});
|
|
31
|
+
|
|
30
32
|
it("returns red", () => {
|
|
31
33
|
expect(getDelayColorForVehicle(9.49 * 60 * 1000 - 1)).toBe("#dc2626");
|
|
32
34
|
expect(getDelayColorForVehicle(10 * 60 * 1000)).toBe("#dc2626");
|
|
@@ -5,15 +5,18 @@ describe("getDelayString", () => {
|
|
|
5
5
|
expect(getDelayString(7200000)).toBe("2h");
|
|
6
6
|
expect(getDelayString(7255555)).toBe("2h1m");
|
|
7
7
|
});
|
|
8
|
+
|
|
8
9
|
it("returns minutes (round)", () => {
|
|
9
10
|
expect(getDelayString(120000)).toBe("2m");
|
|
10
11
|
expect(getDelayString(151000)).toBe("3m");
|
|
11
12
|
});
|
|
13
|
+
|
|
12
14
|
it("doesn't display seconds", () => {
|
|
13
15
|
expect(getDelayString(1000)).toBe("0");
|
|
14
16
|
expect(getDelayString(30000)).toBe("1m");
|
|
15
17
|
expect(getDelayString(7255555)).toBe("2h1m");
|
|
16
18
|
});
|
|
19
|
+
|
|
17
20
|
it("returns defsult 0 value", () => {
|
|
18
21
|
expect(getDelayString(0)).toBe("0");
|
|
19
22
|
expect(getDelayString(null)).toBe("0");
|
|
@@ -6,19 +6,23 @@ describe("getDelayTextForVehicle", () => {
|
|
|
6
6
|
String.fromCodePoint(0x00d7),
|
|
7
7
|
);
|
|
8
8
|
});
|
|
9
|
+
|
|
9
10
|
it("returns hours (floor)", () => {
|
|
10
11
|
expect(getDelayTextForVehicle(7200000)).toBe("+2h");
|
|
11
12
|
expect(getDelayTextForVehicle(7255555)).toBe("+2h1m");
|
|
12
13
|
});
|
|
14
|
+
|
|
13
15
|
it("returns minutes (round)", () => {
|
|
14
16
|
expect(getDelayTextForVehicle(120000)).toBe("+2m");
|
|
15
17
|
expect(getDelayTextForVehicle(151000)).toBe("+3m");
|
|
16
18
|
});
|
|
19
|
+
|
|
17
20
|
it("doesn't display seconds", () => {
|
|
18
21
|
expect(getDelayTextForVehicle(1000)).toBe("");
|
|
19
22
|
expect(getDelayTextForVehicle(30000)).toBe("+1m");
|
|
20
23
|
expect(getDelayTextForVehicle(7255555)).toBe("+2h1m");
|
|
21
24
|
});
|
|
25
|
+
|
|
22
26
|
it("returns empty value", () => {
|
|
23
27
|
expect(getDelayTextForVehicle(1000)).toBe("");
|
|
24
28
|
expect(getDelayTextForVehicle(null)).toBe("");
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { RealtimeLayer } from "mobility-toolbox-js/ol";
|
|
2
|
-
import { RealtimeTrainId } from "mobility-toolbox-js/types";
|
|
3
|
-
import { Map } from "ol";
|
|
4
1
|
import { GeoJSON } from "ol/format";
|
|
5
2
|
import { Vector } from "ol/source";
|
|
6
3
|
|
|
4
|
+
import type { RealtimeLayer } from "mobility-toolbox-js/ol";
|
|
5
|
+
import type { RealtimeTrainId } from "mobility-toolbox-js/types";
|
|
6
|
+
import type { Map } from "ol";
|
|
7
|
+
|
|
7
8
|
const getFullTrajectoryAndFit = async (
|
|
8
9
|
map: Map,
|
|
9
10
|
realtimeLayer: RealtimeLayer,
|
|
@@ -5,6 +5,7 @@ describe("getHoursAndMinutes", () => {
|
|
|
5
5
|
expect(getHoursAndMinutes(7200000)).toBe("02:00");
|
|
6
6
|
expect(getHoursAndMinutes(72999999)).toBe("20:16");
|
|
7
7
|
});
|
|
8
|
+
|
|
8
9
|
it("returns empty string", () => {
|
|
9
10
|
expect(getHoursAndMinutes(null)).toBe("");
|
|
10
11
|
expect(getHoursAndMinutes(undefined)).toBe("");
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import getBgColor from "./getBgColor";
|
|
2
|
+
|
|
3
|
+
import type {
|
|
2
4
|
RealtimeDeparture,
|
|
3
5
|
RealtimeLine,
|
|
4
6
|
RealtimeMot,
|
|
@@ -6,8 +8,6 @@ import {
|
|
|
6
8
|
RealtimeTrajectory,
|
|
7
9
|
} from "mobility-toolbox-js/types";
|
|
8
10
|
|
|
9
|
-
import getBgColor from "./getBgColor";
|
|
10
|
-
|
|
11
11
|
// This function returns the main color of a line using a line, trajectory, stopsequence or departure object.
|
|
12
12
|
const getMainColorForVehicle = (object: unknown = null): string => {
|
|
13
13
|
const line =
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getLayersAsFlatArray } from "mobility-toolbox-js/ol";
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import type { Map } from "ol";
|
|
4
4
|
|
|
5
5
|
// This function return URL parameters representing a map.
|
|
6
6
|
const getPermalinkParameters = (
|
|
@@ -75,7 +75,8 @@ describe("getStopStatus", () => {
|
|
|
75
75
|
expect(isNextStop).toBe(true);
|
|
76
76
|
});
|
|
77
77
|
});
|
|
78
|
-
|
|
78
|
+
|
|
79
|
+
describe("when it's the first station and not a stop", () => {
|
|
79
80
|
it("returns a correct status", () => {
|
|
80
81
|
const stopSequence = {
|
|
81
82
|
stations: [{}],
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import { RealtimeDeparture } from "mobility-toolbox-js/types";
|
|
2
1
|
import { createContext } from "preact";
|
|
3
2
|
import { useContext } from "preact/hooks";
|
|
4
3
|
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
import type { RealtimeDeparture } from "mobility-toolbox-js/types";
|
|
5
|
+
|
|
6
|
+
export interface DepartureContextType {
|
|
7
7
|
departure?: RealtimeDeparture;
|
|
8
|
-
|
|
8
|
+
index?: number;
|
|
9
|
+
}
|
|
9
10
|
|
|
10
11
|
export const DepartureContext = createContext({
|
|
11
|
-
index: null,
|
|
12
12
|
departure: null,
|
|
13
|
+
index: null,
|
|
13
14
|
} as DepartureContextType);
|
|
14
15
|
|
|
15
16
|
const useDeparture = (): DepartureContextType => {
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { createContext } from "preact";
|
|
2
2
|
import { useContext } from "preact/hooks";
|
|
3
3
|
|
|
4
|
-
export
|
|
5
|
-
t: (id: string, templateValues?:
|
|
6
|
-
}
|
|
4
|
+
export interface I18NContextType {
|
|
5
|
+
t: (id: string, templateValues?: Record<string, string>) => string;
|
|
6
|
+
}
|
|
7
7
|
|
|
8
8
|
export const I18nContext = createContext({
|
|
9
|
-
t: (id, templateValues) =>
|
|
9
|
+
t: (id, templateValues) => {
|
|
10
|
+
return `${id} ${JSON.stringify(templateValues)}`;
|
|
11
|
+
},
|
|
10
12
|
} as I18NContextType);
|
|
11
13
|
|
|
12
14
|
const useI18n = (): I18NContextType => {
|