@geops/rvf-mobility-web-component 0.1.8
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/.fixpackrc +21 -0
- package/.husky/commit-msg +1 -0
- package/.husky/post-checkout +1 -0
- package/.husky/post-merge +1 -0
- package/.husky/post-rebase +1 -0
- package/.husky/pre-commit +1 -0
- package/.lintstagedrc.js +12 -0
- package/.nvmrc +1 -0
- package/.prettierrc.js +1 -0
- package/CHANGELOG.md +183 -0
- package/Logo.svg +10 -0
- package/README.md +179 -0
- package/__mocks__/dataurl.js +11 -0
- package/__mocks__/mapbox-gl.js +19 -0
- package/commitlint.config.cjs +1 -0
- package/doc/.eslintrc.json +3 -0
- package/doc/.fixpackrc +21 -0
- package/doc/.prettierrc +1 -0
- package/doc/README.md +14 -0
- package/doc/declarations.d.ts +6 -0
- package/doc/next.config.mjs +4 -0
- package/doc/package.json +43 -0
- package/doc/postcss.config.mjs +8 -0
- package/doc/public/README.md +1 -0
- package/doc/src/app/components/GeopsAPIKeyLink.tsx +6 -0
- package/doc/src/app/components/GeopsAPIsLink.tsx +6 -0
- package/doc/src/app/components/GeopsMapsAPILink.tsx +8 -0
- package/doc/src/app/components/GeopsMobility.tsx +9 -0
- package/doc/src/app/components/GeopsMobilityDoc.tsx +231 -0
- package/doc/src/app/components/GeopsMobilitySearch.tsx +10 -0
- package/doc/src/app/components/GeopsMobilitySearchDoc.tsx +129 -0
- package/doc/src/app/components/GeopsRealtimeAPILink.tsx +10 -0
- package/doc/src/app/components/GeopsStopsAPILink.tsx +8 -0
- package/doc/src/app/components/Link.tsx +9 -0
- package/doc/src/app/components/WebComponentDoc.tsx +296 -0
- package/doc/src/app/favicon.ico +0 -0
- package/doc/src/app/geops-mobility/page.tsx +6 -0
- package/doc/src/app/geops-mobility-search/page.tsx +7 -0
- package/doc/src/app/globals.css +38 -0
- package/doc/src/app/hooks/useAttrFromUrlParams.ts +21 -0
- package/doc/src/app/hooks/useIsFullScreen.ts +14 -0
- package/doc/src/app/hooks/usePublicKey.ts +21 -0
- package/doc/src/app/layout.tsx +51 -0
- package/doc/src/app/page.tsx +86 -0
- package/doc/src/geops-ui.ts +3 -0
- package/doc/tailwind.config.ts +20 -0
- package/doc/tsconfig.json +40 -0
- package/eslint.config.mjs +40 -0
- package/favicon.ico +0 -0
- package/global.d.ts +4 -0
- package/iframe.html +34 -0
- package/index.html +276 -0
- package/index.js +2162 -0
- package/input.css +34 -0
- package/jest-setup.js +4 -0
- package/jest.config.js +17 -0
- package/package.json +80 -0
- package/scripts/build.mjs +16 -0
- package/scripts/dev.mjs +26 -0
- package/search.html +144 -0
- package/src/BaseLayer/BaseLayer.tsx +36 -0
- package/src/BaseLayer/index.tsx +1 -0
- package/src/Copyright/Copyright.tsx +54 -0
- package/src/Copyright/index.css +3 -0
- package/src/Copyright/index.tsx +1 -0
- package/src/DebugDeparture/DebugDeparture.tsx +116 -0
- package/src/DebugDeparture/index.tsx +1 -0
- package/src/DebugStop/DebugStop.tsx +47 -0
- package/src/DebugStop/index.tsx +1 -0
- package/src/Departure/Departure.tsx +55 -0
- package/src/Departure/index.tsx +1 -0
- package/src/GeolocationButton/GeolocationButton.tsx +81 -0
- package/src/GeolocationButton/index.tsx +1 -0
- package/src/Map/Map.tsx +89 -0
- package/src/Map/index.tsx +1 -0
- package/src/MobilityMap/MobilityMap.tsx +259 -0
- package/src/MobilityMap/index.css +13 -0
- package/src/MobilityMap/index.tsx +1 -0
- package/src/NotificationLayer/NotificationLayer.tsx +156 -0
- package/src/NotificationLayer/index.tsx +1 -0
- package/src/NotificationLayer/notificationUtils.ts +191 -0
- package/src/Overlay/Overlay.tsx +57 -0
- package/src/Overlay/index.tsx +1 -0
- package/src/RealtimeLayer/RealtimeLayer.tsx +230 -0
- package/src/RealtimeLayer/index.tsx +1 -0
- package/src/RouteDestination/RouteDestination.test.tsx +13 -0
- package/src/RouteDestination/RouteDestination.tsx +15 -0
- package/src/RouteDestination/index.tsx +1 -0
- package/src/RouteIcon/RouteIcon.tsx +66 -0
- package/src/RouteIcon/index.tsx +1 -0
- package/src/RouteIdentifier/RouteIdentifer.tsx +35 -0
- package/src/RouteIdentifier/index.tsx +1 -0
- package/src/RouteInfos/RouteInfos.tsx +22 -0
- package/src/RouteInfos/index.tsx +1 -0
- package/src/RouteSchedule/RouteSchedule.tsx +69 -0
- package/src/RouteSchedule/firstStation.png +0 -0
- package/src/RouteSchedule/index.tsx +1 -0
- package/src/RouteSchedule/lastStation.png +0 -0
- package/src/RouteSchedule/line.png +0 -0
- package/src/RouteSchedule/station.png +0 -0
- package/src/RouteScheduleFooter/RouteScheduleFooter.tsx +44 -0
- package/src/RouteScheduleFooter/index.tsx +1 -0
- package/src/RouteScheduleHeader/RouteScheduleHeader.tsx +58 -0
- package/src/RouteScheduleHeader/index.tsx +1 -0
- package/src/RouteStop/RouteStop.tsx +121 -0
- package/src/RouteStop/index.tsx +1 -0
- package/src/RouteStopDelay/RouteStopDelay.tsx +36 -0
- package/src/RouteStopDelay/index.tsx +1 -0
- package/src/RouteStopName/RouteStopName.tsx +24 -0
- package/src/RouteStopName/index.tsx +1 -0
- package/src/RouteStopPlatform/RouteStopPlatform.tsx +29 -0
- package/src/RouteStopPlatform/index.tsx +1 -0
- package/src/RouteStopProgress/RouteStopProgress.tsx +101 -0
- package/src/RouteStopProgress/index.tsx +1 -0
- package/src/RouteStopServices/RouteStopServices.tsx +26 -0
- package/src/RouteStopServices/index.tsx +1 -0
- package/src/RouteStopStation/RouteStopStation.tsx +32 -0
- package/src/RouteStopStation/index.tsx +1 -0
- package/src/RouteStopTime/RouteStopTime.tsx +34 -0
- package/src/RouteStopTime/index.tsx +1 -0
- package/src/RvfMobilityMap/RvfMobilityMap.tsx +245 -0
- package/src/RvfMobilityMap/index.css +13 -0
- package/src/RvfMobilityMap/index.tsx +1 -0
- package/src/ScaleLine/ScaleLine.tsx +51 -0
- package/src/ScaleLine/index.css +6 -0
- package/src/ScaleLine/index.tsx +1 -0
- package/src/ScrollableHandler/ScrollableHandler.tsx +65 -0
- package/src/ScrollableHandler/index.tsx +1 -0
- package/src/Search/Search.tsx +18 -0
- package/src/Search/index.tsx +1 -0
- package/src/SingleClickListener/SingleClickListener.tsx +103 -0
- package/src/SingleClickListener/index.tsx +1 -0
- package/src/Station/Station.tsx +68 -0
- package/src/Station/index.tsx +1 -0
- package/src/StationHeader/StationHeader.tsx +32 -0
- package/src/StationHeader/index.tsx +1 -0
- package/src/StationName/StationName.tsx +21 -0
- package/src/StationName/index.tsx +1 -0
- package/src/StationServices/StationServices.tsx +80 -0
- package/src/StationServices/index.tsx +1 -0
- package/src/StationsLayer/StationsLayer.tsx +41 -0
- package/src/StationsLayer/index.tsx +1 -0
- package/src/StopsSearch/StopsSearch.tsx +254 -0
- package/src/StopsSearch/index.tsx +1 -0
- package/src/icons/Airport/Airport.tsx +17 -0
- package/src/icons/Airport/airport-14-svgrepo-com.svg +41 -0
- package/src/icons/Airport/index.tsx +1 -0
- package/src/icons/BarAndRestaurants/BarAndRestaurants.tsx +17 -0
- package/src/icons/BarAndRestaurants/food-restaurant-svgrepo-com.svg +12 -0
- package/src/icons/BarAndRestaurants/index.tsx +1 -0
- package/src/icons/Bathroom/Bathroom.tsx +59 -0
- package/src/icons/Bathroom/bathroom-restroom-svgrepo-com.svg +38 -0
- package/src/icons/Bathroom/index.tsx +1 -0
- package/src/icons/BikeStorage/BikeStorage.tsx +17 -0
- package/src/icons/BikeStorage/index.tsx +1 -0
- package/src/icons/BikeStorage/parking-bicycle-14-svgrepo-com.svg +41 -0
- package/src/icons/Elevator/Elevator.tsx +16 -0
- package/src/icons/Elevator/elevator-svgrepo-com.svg +2 -0
- package/src/icons/Elevator/index.tsx +1 -0
- package/src/icons/Police/Police.tsx +20 -0
- package/src/icons/Police/index.tsx +1 -0
- package/src/icons/Police/polizia.png +0 -0
- package/src/icons/README.md +52 -0
- package/src/icons/WaitingAreas/WaitingAreas.tsx +16 -0
- package/src/icons/WaitingAreas/highway-rest-area-svgrepo-com.svg +5 -0
- package/src/icons/WaitingAreas/index.tsx +1 -0
- package/src/icons/WaitingAreas/wheelchair-svgrepo-com.svg +2 -0
- package/src/icons/WheelChair/WheelChair.tsx +16 -0
- package/src/icons/WheelChair/disabili.png +0 -0
- package/src/icons/WheelChair/index.tsx +1 -0
- package/src/icons/WheelChair/wheelchair-svgrepo-com.svg +2 -0
- package/src/index.tsx +50 -0
- package/src/utils/MobilityEvent.ts +21 -0
- package/src/utils/addSourceAndLayers.ts +62 -0
- package/src/utils/centerOnStation.ts +17 -0
- package/src/utils/centerOnVehicle.ts +50 -0
- package/src/utils/getBgColor.ts +3 -0
- package/src/utils/getDelayColor.test.ts +20 -0
- package/src/utils/getDelayColor.ts +23 -0
- package/src/utils/getDelayColorForVehicle.test.ts +28 -0
- package/src/utils/getDelayColorForVehicle.ts +25 -0
- package/src/utils/getDelayFontForVehicle.test.ts +7 -0
- package/src/utils/getDelayFontForVehicle.tsx +8 -0
- package/src/utils/getDelayString.test.ts +22 -0
- package/src/utils/getDelayString.ts +28 -0
- package/src/utils/getDelayTextForVehicle.test.ts +28 -0
- package/src/utils/getDelayTextForVehicle.ts +21 -0
- package/src/utils/getFullTrajectoryAndFit.ts +40 -0
- package/src/utils/getHoursAndMinutes.test.ts +14 -0
- package/src/utils/getHoursAndMinutes.ts +22 -0
- package/src/utils/getMainColorForVehicle.test.ts +27 -0
- package/src/utils/getMainColorForVehicle.ts +46 -0
- package/src/utils/getStopStatus.test.ts +104 -0
- package/src/utils/getStopStatus.ts +171 -0
- package/src/utils/getTextFontForVehicle.test.ts +7 -0
- package/src/utils/getTextFontForVehicle.tsx +9 -0
- package/src/utils/getTextForVehicle.test.ts +17 -0
- package/src/utils/getTextForVehicle.ts +19 -0
- package/src/utils/hooks/useDebug.tsx +11 -0
- package/src/utils/hooks/useDeparture.tsx +23 -0
- package/src/utils/hooks/useI18n.tsx +20 -0
- package/src/utils/hooks/useMapContext.tsx +74 -0
- package/src/utils/hooks/useParams.ts +5 -0
- package/src/utils/hooks/useRouteStop.tsx +33 -0
- package/src/utils/hooks/useStation.tsx +21 -0
- package/src/utils/hooks/useUpdatePermalink.tsx +33 -0
- package/src/utils/hooks/useZoom.tsx +32 -0
- package/src/utils/i18n.ts +16 -0
- package/src/utils/translations.ts +31 -0
- package/tailwind.config.mjs +56 -0
- package/testNotification.json +50653 -0
- package/tsconfig.json +12 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
@tailwind base;
|
|
2
|
+
@tailwind components;
|
|
3
|
+
@tailwind utilities;
|
|
4
|
+
|
|
5
|
+
:root {
|
|
6
|
+
--background: #ffffff;
|
|
7
|
+
--foreground: #171717;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
body {
|
|
11
|
+
color: var(--foreground);
|
|
12
|
+
background: var(--background);
|
|
13
|
+
font-family: Arial, Helvetica, sans-serif;
|
|
14
|
+
margin: 0;
|
|
15
|
+
font-family: Lato, Arial, sans-serif;
|
|
16
|
+
color: #353535;
|
|
17
|
+
position: relative;
|
|
18
|
+
min-height: 100%;
|
|
19
|
+
overflow-y: scroll;
|
|
20
|
+
font-size: 18px;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
a {
|
|
24
|
+
text-decoration: none;
|
|
25
|
+
color: #76b833;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
a:focus-visible {
|
|
29
|
+
outline: 2px solid black;
|
|
30
|
+
outline-offset: 2px;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@layer utilities {
|
|
35
|
+
.text-balance {
|
|
36
|
+
text-wrap: balance;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { useSearchParams } from "next/navigation";
|
|
2
|
+
import { useMemo } from "react";
|
|
3
|
+
|
|
4
|
+
const useAttrFromUrlParams = (attributes: string[]) => {
|
|
5
|
+
const searchParams = useSearchParams();
|
|
6
|
+
|
|
7
|
+
const attrs = useMemo(() => {
|
|
8
|
+
const values: Record<string, string> = {};
|
|
9
|
+
attributes.forEach((key) => {
|
|
10
|
+
const value = searchParams.get(key);
|
|
11
|
+
if (key && value !== undefined && value !== null) {
|
|
12
|
+
values[key] = value;
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
return values;
|
|
16
|
+
}, [attributes, searchParams]);
|
|
17
|
+
|
|
18
|
+
return attrs;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export default useAttrFromUrlParams;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { useSearchParams } from "next/navigation";
|
|
2
|
+
import { useMemo } from "react";
|
|
3
|
+
|
|
4
|
+
const useIsFullScreen = () => {
|
|
5
|
+
const searchParams = useSearchParams();
|
|
6
|
+
|
|
7
|
+
const isFullScreen = useMemo(() => {
|
|
8
|
+
return searchParams.get("fullscreen") === "true";
|
|
9
|
+
}, [searchParams]);
|
|
10
|
+
|
|
11
|
+
return isFullScreen;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export default useIsFullScreen;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
|
|
3
|
+
const usePublicKey = () => {
|
|
4
|
+
const [publicKey, setPublicKey] = useState<null | string>(null);
|
|
5
|
+
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
const fetchPublicKey = async () => {
|
|
8
|
+
const response = await fetch(
|
|
9
|
+
"https://backend.developer.geops.io/publickey",
|
|
10
|
+
);
|
|
11
|
+
const data = await response.json();
|
|
12
|
+
setPublicKey(data?.key);
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
fetchPublicKey();
|
|
16
|
+
}, []);
|
|
17
|
+
|
|
18
|
+
return publicKey;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export default usePublicKey;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { Metadata } from "next";
|
|
2
|
+
|
|
3
|
+
import { Container } from "@mui/material";
|
|
4
|
+
import { AppRouterCacheProvider } from "@mui/material-nextjs/v14-appRouter";
|
|
5
|
+
import { ThemeProvider } from "@mui/material/styles";
|
|
6
|
+
import Script from "next/script";
|
|
7
|
+
import { Suspense } from "react";
|
|
8
|
+
|
|
9
|
+
import { Footer, geopsTheme, Header } from "../geops-ui";
|
|
10
|
+
import "./globals.css";
|
|
11
|
+
|
|
12
|
+
const tabs = [
|
|
13
|
+
{
|
|
14
|
+
component: "a",
|
|
15
|
+
href: "/",
|
|
16
|
+
label: "Home",
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
component: "a",
|
|
20
|
+
href: "https://github.com/geops/mobility-web-component",
|
|
21
|
+
label: "Code",
|
|
22
|
+
},
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
export const metadata: Metadata = {
|
|
26
|
+
description: "A set of we component for geOps Mobility APIs",
|
|
27
|
+
title: "geOps Mobility Web Component",
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export default function RootLayout({
|
|
31
|
+
children,
|
|
32
|
+
}: Readonly<{
|
|
33
|
+
children: React.ReactNode;
|
|
34
|
+
}>) {
|
|
35
|
+
return (
|
|
36
|
+
<html lang="en">
|
|
37
|
+
<body className={`antialiased`}>
|
|
38
|
+
<AppRouterCacheProvider>
|
|
39
|
+
<ThemeProvider theme={geopsTheme}>
|
|
40
|
+
<Header tabs={tabs} title="mobility-web-component" />
|
|
41
|
+
<Container className="my-12" maxWidth="md">
|
|
42
|
+
<Suspense fallback={null}>{children}</Suspense>
|
|
43
|
+
</Container>
|
|
44
|
+
<Footer />
|
|
45
|
+
</ThemeProvider>
|
|
46
|
+
</AppRouterCacheProvider>
|
|
47
|
+
<Script src="index.js" />
|
|
48
|
+
</body>
|
|
49
|
+
</html>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
Button,
|
|
4
|
+
Card,
|
|
5
|
+
CardActions,
|
|
6
|
+
CardContent,
|
|
7
|
+
CardMedia,
|
|
8
|
+
Typography,
|
|
9
|
+
} from "@mui/material";
|
|
10
|
+
import Link from "next/link";
|
|
11
|
+
|
|
12
|
+
import GeopsAPIsLink from "./components/GeopsAPIsLink";
|
|
13
|
+
import GeopsMobility from "./components/GeopsMobility";
|
|
14
|
+
import GeopsMobilitySearch from "./components/GeopsMobilitySearch";
|
|
15
|
+
import GeopsStopsAPILink from "./components/GeopsStopsAPILink";
|
|
16
|
+
import usePublicKey from "./hooks/usePublicKey";
|
|
17
|
+
|
|
18
|
+
export default function Home() {
|
|
19
|
+
const apiKey = usePublicKey();
|
|
20
|
+
return (
|
|
21
|
+
<>
|
|
22
|
+
<Typography variant="h1">Mobility Web Component</Typography>
|
|
23
|
+
<br />
|
|
24
|
+
<p className="my-4">
|
|
25
|
+
This project contains a set of web components allowing to use easily the{" "}
|
|
26
|
+
<GeopsAPIsLink />:
|
|
27
|
+
</p>
|
|
28
|
+
<div className="my-8 flex flex-wrap gap-4">
|
|
29
|
+
<Card className="w-[345px] min-w-[320px] shrink-0">
|
|
30
|
+
<CardMedia sx={{ height: 160, padding: 0, pointerEvents: "none" }}>
|
|
31
|
+
<GeopsMobility
|
|
32
|
+
apikey={apiKey}
|
|
33
|
+
class="size-full"
|
|
34
|
+
geolocation="false"
|
|
35
|
+
search="false"
|
|
36
|
+
/>
|
|
37
|
+
</CardMedia>
|
|
38
|
+
<CardContent>
|
|
39
|
+
<Link href={`/geops-mobility`}>
|
|
40
|
+
<Typography variant="h3">{"<geops-mobility />"}</Typography>
|
|
41
|
+
</Link>
|
|
42
|
+
<Typography>
|
|
43
|
+
A web component used to display a map using different{" "}
|
|
44
|
+
<GeopsAPIsLink />.
|
|
45
|
+
</Typography>
|
|
46
|
+
</CardContent>
|
|
47
|
+
<CardActions sx={{ display: "flex", justifyContent: "end" }}>
|
|
48
|
+
<Button
|
|
49
|
+
href={`/geops-mobility`}
|
|
50
|
+
sx={{ borderRadius: 0, borderTopLeftRadius: 4 }}
|
|
51
|
+
>
|
|
52
|
+
More
|
|
53
|
+
</Button>
|
|
54
|
+
</CardActions>
|
|
55
|
+
</Card>
|
|
56
|
+
|
|
57
|
+
<Card className="w-[345px] min-w-[320px] shrink-0">
|
|
58
|
+
<CardMedia sx={{ height: 160, padding: 2, pointerEvents: "none" }}>
|
|
59
|
+
<GeopsMobilitySearch
|
|
60
|
+
apikey={apiKey}
|
|
61
|
+
class="m-4 size-full border-0 border-b"
|
|
62
|
+
/>
|
|
63
|
+
</CardMedia>
|
|
64
|
+
<CardContent>
|
|
65
|
+
<Link href={`/geops-mobility-search`}>
|
|
66
|
+
<Typography variant="h3">
|
|
67
|
+
{"<geops-mobility-search />"}
|
|
68
|
+
</Typography>
|
|
69
|
+
</Link>
|
|
70
|
+
<Typography>
|
|
71
|
+
A search input to search stops using the <GeopsStopsAPILink />.
|
|
72
|
+
</Typography>
|
|
73
|
+
</CardContent>
|
|
74
|
+
<CardActions sx={{ display: "flex", justifyContent: "end" }}>
|
|
75
|
+
<Button
|
|
76
|
+
href={`/geops-mobility-search`}
|
|
77
|
+
sx={{ borderRadius: 0, borderTopLeftRadius: 4 }}
|
|
78
|
+
>
|
|
79
|
+
More
|
|
80
|
+
</Button>
|
|
81
|
+
</CardActions>
|
|
82
|
+
</Card>
|
|
83
|
+
</div>
|
|
84
|
+
</>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Config } from "tailwindcss";
|
|
2
|
+
|
|
3
|
+
const config: Config = {
|
|
4
|
+
content: [
|
|
5
|
+
"./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
|
|
6
|
+
"./src/components/**/*.{js,ts,jsx,tsx,mdx}",
|
|
7
|
+
"./src/app/**/*.{js,ts,jsx,tsx,mdx}",
|
|
8
|
+
],
|
|
9
|
+
plugins: [],
|
|
10
|
+
theme: {
|
|
11
|
+
extend: {
|
|
12
|
+
colors: {},
|
|
13
|
+
fontFamily: {
|
|
14
|
+
sans: ["Lato", "sans-serif"],
|
|
15
|
+
serif: ["Merriweather", "serif"],
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
export default config;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"lib": [
|
|
4
|
+
"dom",
|
|
5
|
+
"dom.iterable",
|
|
6
|
+
"esnext"
|
|
7
|
+
],
|
|
8
|
+
"allowJs": true,
|
|
9
|
+
"skipLibCheck": true,
|
|
10
|
+
"strict": true,
|
|
11
|
+
"noEmit": true,
|
|
12
|
+
"esModuleInterop": true,
|
|
13
|
+
"module": "esnext",
|
|
14
|
+
"moduleResolution": "bundler",
|
|
15
|
+
"resolveJsonModule": true,
|
|
16
|
+
"isolatedModules": true,
|
|
17
|
+
"jsx": "preserve",
|
|
18
|
+
"incremental": true,
|
|
19
|
+
"plugins": [
|
|
20
|
+
{
|
|
21
|
+
"name": "next"
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
"paths": {
|
|
25
|
+
"@/*": [
|
|
26
|
+
"./src/*"
|
|
27
|
+
]
|
|
28
|
+
},
|
|
29
|
+
"target": "ES2017"
|
|
30
|
+
},
|
|
31
|
+
"include": [
|
|
32
|
+
"next-env.d.ts",
|
|
33
|
+
"**/*.ts",
|
|
34
|
+
"**/*.tsx",
|
|
35
|
+
".next/types/**/*.ts"
|
|
36
|
+
],
|
|
37
|
+
"exclude": [
|
|
38
|
+
"node_modules"
|
|
39
|
+
]
|
|
40
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { FlatCompat } from "@eslint/eslintrc";
|
|
2
|
+
import eslint from "@eslint/js";
|
|
3
|
+
import jsxA11y from "eslint-plugin-jsx-a11y";
|
|
4
|
+
import perfectionist from "eslint-plugin-perfectionist";
|
|
5
|
+
import prettier from "eslint-plugin-prettier/recommended";
|
|
6
|
+
import react from "eslint-plugin-react";
|
|
7
|
+
import tailwind from "eslint-plugin-tailwindcss";
|
|
8
|
+
import ts from "typescript-eslint";
|
|
9
|
+
|
|
10
|
+
// FlatCompat convert old definition to the new ones
|
|
11
|
+
const compat = new FlatCompat();
|
|
12
|
+
|
|
13
|
+
export default [
|
|
14
|
+
{
|
|
15
|
+
ignores: ["build/*", "node_modules/*"],
|
|
16
|
+
},
|
|
17
|
+
...ts.config(
|
|
18
|
+
eslint.configs.recommended,
|
|
19
|
+
...ts.configs.strict,
|
|
20
|
+
...ts.configs.stylistic,
|
|
21
|
+
react.configs.flat.recommended,
|
|
22
|
+
react.configs.flat["jsx-runtime"], // Avoid having the React-in-jsx-scope rule activated
|
|
23
|
+
...compat.config({
|
|
24
|
+
extends: ["plugin:react-hooks/recommended"],
|
|
25
|
+
rules: {
|
|
26
|
+
"react-hooks/exhaustive-deps": "error",
|
|
27
|
+
},
|
|
28
|
+
}),
|
|
29
|
+
jsxA11y.flatConfigs.recommended,
|
|
30
|
+
perfectionist.configs["recommended-alphabetical"],
|
|
31
|
+
prettier,
|
|
32
|
+
...tailwind.configs["flat/recommended"],
|
|
33
|
+
{
|
|
34
|
+
rules: {
|
|
35
|
+
"arrow-body-style": ["error", "always"],
|
|
36
|
+
curly: "error",
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
),
|
|
40
|
+
];
|
package/favicon.ico
ADDED
|
Binary file
|
package/global.d.ts
ADDED
package/iframe.html
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
6
|
+
<title></title>
|
|
7
|
+
<meta name="description" content="" />
|
|
8
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
9
|
+
<link rel="stylesheet" type="text/css" href="./output.css" />
|
|
10
|
+
<script type="module" src="./bundle.js"></script>
|
|
11
|
+
<style>
|
|
12
|
+
iframe {
|
|
13
|
+
width: 100vw;
|
|
14
|
+
height: 100vh;
|
|
15
|
+
}
|
|
16
|
+
</style>
|
|
17
|
+
</head>
|
|
18
|
+
<body>
|
|
19
|
+
<iframe
|
|
20
|
+
id="iframe"
|
|
21
|
+
src="/?realtime=false&baselayer=travic_v2_network_plans&type=notification¬ificationurl=https%3A%2F%2Fmoco.dev.geops.io%2Fapi%2Fv1%2Fexport%2Fnotification%2F%3Fsso_config%3Dsob¬ificationbeforelayerid=netzplan_line_lable&maxzoom=12¢er=955768,5922646"
|
|
22
|
+
frameborder="0"
|
|
23
|
+
></iframe>
|
|
24
|
+
</body>
|
|
25
|
+
<script type="module">
|
|
26
|
+
import testNotification from "./testNotification.json" assert { type: "json" };
|
|
27
|
+
const iframe = document.getElementById("iframe");
|
|
28
|
+
iframe.addEventListener("load", function () {
|
|
29
|
+
setTimeout(() => {
|
|
30
|
+
this.contentWindow.postMessage({ notification: testNotification }, "*");
|
|
31
|
+
}, 500);
|
|
32
|
+
});
|
|
33
|
+
</script>
|
|
34
|
+
</html>
|
package/index.html
ADDED
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<title>Mobility Web Component</title>
|
|
6
|
+
<link rel="icon" type="image/x-icon" href="favicon.ico" />
|
|
7
|
+
<meta
|
|
8
|
+
name="viewport"
|
|
9
|
+
content="initial-scale=1,maximum-scale=1,user-scalable=no"
|
|
10
|
+
/>
|
|
11
|
+
<link rel="stylesheet" href="https://use.typekit.net/orf1mlq.css">
|
|
12
|
+
|
|
13
|
+
<script type="text/javascript">
|
|
14
|
+
if (/localhost/.test(window.location.hostname)) {
|
|
15
|
+
new EventSource("/esbuild").addEventListener("change", () => {
|
|
16
|
+
location.reload();
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
</script>
|
|
20
|
+
<script type="module" src="./index.js"></script>
|
|
21
|
+
<link rel="stylesheet" type="text/css" href="./output.css" />
|
|
22
|
+
<style>
|
|
23
|
+
::-webkit-scrollbar {
|
|
24
|
+
width: 3px;
|
|
25
|
+
}
|
|
26
|
+
a {
|
|
27
|
+
text-decoration: underline;
|
|
28
|
+
}
|
|
29
|
+
</style>
|
|
30
|
+
</head>
|
|
31
|
+
<body class="p-8">
|
|
32
|
+
<div id="doc" style="display: none" class="mx-auto max-w-5xl space-y-4">
|
|
33
|
+
<h1 class="flex gap-4"><img src="./Logo.svg">Mobility Web Component</h1>
|
|
34
|
+
<p>This is a demo of the Mobility Web Component.</p>
|
|
35
|
+
<h2>Usage example</h2>
|
|
36
|
+
<pre id="code" class="bg-slate-800 text-slate-200 p-4 rounded"></pre>
|
|
37
|
+
|
|
38
|
+
<!-- Default -->
|
|
39
|
+
<geops-mobility
|
|
40
|
+
class="h-96 block resize overflow-auto w-full"
|
|
41
|
+
></geops-mobility>
|
|
42
|
+
|
|
43
|
+
<br />
|
|
44
|
+
<!-- <h2 class="text-xl font-bold">Attributes</h2> -->
|
|
45
|
+
<!-- <button
|
|
46
|
+
class="border rounded p-2 hover:bg-slate-200"
|
|
47
|
+
onclick="toggleBooleanAttribute('search')"
|
|
48
|
+
>
|
|
49
|
+
Toggle search
|
|
50
|
+
</button> -->
|
|
51
|
+
|
|
52
|
+
<!-- <table class="table-auto w-full" >
|
|
53
|
+
<thead>
|
|
54
|
+
<tr>
|
|
55
|
+
<th class="border px-4 py-2">Name</th>
|
|
56
|
+
<th class="border px-4 py-2">Default</th>
|
|
57
|
+
<th class="border px-4 py-2">Description</th>
|
|
58
|
+
<th class="border px-4 py-2">Selected</th>
|
|
59
|
+
</tr>
|
|
60
|
+
</thead>
|
|
61
|
+
<tbody>
|
|
62
|
+
<tr>
|
|
63
|
+
<td class="border px-4 py-2">apikey</td>
|
|
64
|
+
<td class="border px-4 py-2"></td>
|
|
65
|
+
<td class="border px-4 py-2"></td>
|
|
66
|
+
<td class="border px-4 py-2">
|
|
67
|
+
<input
|
|
68
|
+
type="text"
|
|
69
|
+
class="border"
|
|
70
|
+
value=""
|
|
71
|
+
onchange="map.setAttribute('apikey', this.value)"/>
|
|
72
|
+
</td>
|
|
73
|
+
</tr>
|
|
74
|
+
|
|
75
|
+
<tr>
|
|
76
|
+
<td class="border px-4 py-2">search</td>
|
|
77
|
+
<td class="border px-4 py-2">true</td>
|
|
78
|
+
<td class="border px-4 py-2"></td>
|
|
79
|
+
<td class="border px-4 py-2">
|
|
80
|
+
<select
|
|
81
|
+
class="border px-4 py-2"
|
|
82
|
+
name="baselayer"
|
|
83
|
+
onchange="map.setAttribute(this.name, this.value)">
|
|
84
|
+
<option value="travic_v2">travic_v2</option>
|
|
85
|
+
<option value="base_dark_v2">base_dark_v2</option>
|
|
86
|
+
</select>
|
|
87
|
+
</td>
|
|
88
|
+
</tr>
|
|
89
|
+
|
|
90
|
+
<tr>
|
|
91
|
+
<td class="border px-4 py-2">realtime</td>
|
|
92
|
+
<td class="border px-4 py-2">true</td>
|
|
93
|
+
<td class="border px-4 py-2"></td>
|
|
94
|
+
<td class="border px-4 py-2">
|
|
95
|
+
<input
|
|
96
|
+
name="realtime"
|
|
97
|
+
type="checkbox"
|
|
98
|
+
checked
|
|
99
|
+
onchange="toggleBooleanAttribute(this.name)"/>
|
|
100
|
+
</td>
|
|
101
|
+
</tr>
|
|
102
|
+
<tr>
|
|
103
|
+
<td class="border px-4 py-2">search</td>
|
|
104
|
+
<td class="border px-4 py-2">true</td>
|
|
105
|
+
<td class="border px-4 py-2"></td>
|
|
106
|
+
<td class="border px-4 py-2">
|
|
107
|
+
<input
|
|
108
|
+
name="search"
|
|
109
|
+
type="checkbox"
|
|
110
|
+
checked
|
|
111
|
+
onchange="toggleBooleanAttribute(this.name)"/>
|
|
112
|
+
</td>
|
|
113
|
+
</tr>
|
|
114
|
+
</tbody>
|
|
115
|
+
</table> -->
|
|
116
|
+
|
|
117
|
+
<!-- <br />
|
|
118
|
+
<br />
|
|
119
|
+
<h1 class="text-xl font-bold">More mobility web components</h1>
|
|
120
|
+
<p>
|
|
121
|
+
<a href="search.html" target="_blank"
|
|
122
|
+
>>> Usage example Search Component</a
|
|
123
|
+
>
|
|
124
|
+
</p> -->
|
|
125
|
+
</div>
|
|
126
|
+
|
|
127
|
+
<br />
|
|
128
|
+
<br />
|
|
129
|
+
<script type="text/javascript">
|
|
130
|
+
params = new URLSearchParams(window.location.search);
|
|
131
|
+
|
|
132
|
+
// There should be only on map on the html page at this point
|
|
133
|
+
const doc = document.querySelectorAll("#doc");
|
|
134
|
+
const map = document.querySelector("geops-mobility");
|
|
135
|
+
|
|
136
|
+
if (params.get("fullscreen") === "true") {
|
|
137
|
+
map.parentElement.removeChild(map);
|
|
138
|
+
map.className = "absolute w-full h-full inset-0";
|
|
139
|
+
document.body.appendChild(map);
|
|
140
|
+
document.body.style = "padding:0;";
|
|
141
|
+
} else {
|
|
142
|
+
doc.forEach((d) => (d.style.display = "block"));
|
|
143
|
+
}
|
|
144
|
+
params.delete("fullscreen");
|
|
145
|
+
|
|
146
|
+
if (
|
|
147
|
+
params.get("permalink") !== "false" &&
|
|
148
|
+
params.get("x") &&
|
|
149
|
+
params.get("y")
|
|
150
|
+
) {
|
|
151
|
+
map.setAttribute("center", `${params.get("x")},${params.get("y")}`);
|
|
152
|
+
params.delete("x");
|
|
153
|
+
params.delete("y");
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (params.get("permalink") !== "false" && params.get("z")) {
|
|
157
|
+
map.setAttribute("zoom", params.get("z"));
|
|
158
|
+
params.delete("z");
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Apply all url parameters as attribute of the web component
|
|
162
|
+
params.forEach((value, key) => {
|
|
163
|
+
map.setAttribute(key, value);
|
|
164
|
+
const input = document.querySelector(`input[name=${key}]`);
|
|
165
|
+
if (input) {
|
|
166
|
+
if (input.type === "checkbox") {
|
|
167
|
+
input.checked = value !== "false";
|
|
168
|
+
} else {
|
|
169
|
+
input.value = value;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
// if (!map.getAttribute("apikey")) {
|
|
175
|
+
// fetch("https://backend.developer.geops.io/publickey")
|
|
176
|
+
// .then((response) => response.json())
|
|
177
|
+
// .then((data) => {
|
|
178
|
+
// if (data && data.success) {
|
|
179
|
+
// map.setAttribute("apikey", data.key);
|
|
180
|
+
// }
|
|
181
|
+
// });
|
|
182
|
+
// }
|
|
183
|
+
|
|
184
|
+
// Listen StopsSearch event
|
|
185
|
+
window.addEventListener("mwc:stopssearchselect", (event) => {
|
|
186
|
+
console.log("mwc:stopssearchselect event: ", event.data);
|
|
187
|
+
// window.top.postMessage(event.data, "*");
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
// Send url search params to parent window
|
|
191
|
+
window.addEventListener("mwc:attribute", (event) => {
|
|
192
|
+
console.log("mwc:attribute event: ", event.data);
|
|
193
|
+
window.top.postMessage(new URLSearchParams(event.data).toString(), "*");
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
// Listen window event
|
|
197
|
+
window.addEventListener("message", (event) => {
|
|
198
|
+
console.log("message event: ", event);
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
function toggleBooleanAttribute(name) {
|
|
202
|
+
const value = map.getAttribute(name);
|
|
203
|
+
map.setAttribute(name, value === "false" ? "true" : "false");
|
|
204
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
205
|
+
urlParams.set(name, map.getAttribute(name));
|
|
206
|
+
window.history.replaceState(
|
|
207
|
+
{},
|
|
208
|
+
"",
|
|
209
|
+
`${window.location.pathname}?${urlParams}`,
|
|
210
|
+
);
|
|
211
|
+
generateCodeText();
|
|
212
|
+
}
|
|
213
|
+
const attrs = [
|
|
214
|
+
"apikey",
|
|
215
|
+
"baselayer",
|
|
216
|
+
"center",
|
|
217
|
+
"geolocation",
|
|
218
|
+
"mapsurl",
|
|
219
|
+
"mots",
|
|
220
|
+
"notification",
|
|
221
|
+
"notificationat",
|
|
222
|
+
"notificationurl",
|
|
223
|
+
"notificationbeforelayerid",
|
|
224
|
+
"realtime",
|
|
225
|
+
"realtimeUrl",
|
|
226
|
+
"search",
|
|
227
|
+
"tenant",
|
|
228
|
+
"zoom",
|
|
229
|
+
"permalink",
|
|
230
|
+
];
|
|
231
|
+
|
|
232
|
+
function generateCodeText() {
|
|
233
|
+
const codeElt = document.querySelector("#code");
|
|
234
|
+
let codeText = "";
|
|
235
|
+
codeText = `<script\n\ttype="module"\n\tsrc="https://www.unpkg.com/@geops/mobility-web-component">
|
|
236
|
+
</script>
|
|
237
|
+
<geops-mobility style="height:600px;width:100%;" `;
|
|
238
|
+
|
|
239
|
+
attrs.forEach((key) => {
|
|
240
|
+
if (key == "apikey") {
|
|
241
|
+
// codeText += `\n\tapikey="YOUR_GEOPS_API_KEY"`;
|
|
242
|
+
} else if (map.getAttribute(key) !== null) {
|
|
243
|
+
codeText += `\n\t${[key, '"' + map.getAttribute(key) + '"'].join("=")}`;
|
|
244
|
+
} else if (key == "center") {
|
|
245
|
+
// codeText += `\n\tcenter="831634,5933959"`;
|
|
246
|
+
} else if (key == "zoom") {
|
|
247
|
+
// codeText += `\n\tzoom="13"`;
|
|
248
|
+
} else if (key == "baselayer") {
|
|
249
|
+
// codeText += `\n\tbaselayer="travic_v2"`;
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
code.innerHTML = codeText + `>\n</geops-mobility>`;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// Initialize value of inputs fields
|
|
257
|
+
function initInputs() {
|
|
258
|
+
attrs.forEach((key) => {
|
|
259
|
+
const input = document.querySelector(`input[name=${key}]`);
|
|
260
|
+
if (input) {
|
|
261
|
+
input.value = map.getAttribute(key) || "";
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
const inputs = document.querySelectorAll("input");
|
|
265
|
+
inputs.forEach((input) => {
|
|
266
|
+
input.addEventListener("change", () => {
|
|
267
|
+
generateCodeText();
|
|
268
|
+
});
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
initInputs();
|
|
273
|
+
generateCodeText();
|
|
274
|
+
</script>
|
|
275
|
+
</body>
|
|
276
|
+
</html>
|