From ebb685e764da135c224556bf584c2785bb198ce4 Mon Sep 17 00:00:00 2001 From: marthevienne <123016211+marthevienne@users.noreply.github.com> Date: Fri, 13 Dec 2024 17:52:51 +0100 Subject: [PATCH 1/6] remove margin sidebar-expander --- frontend/components/ui/custom/sidebar-expander.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/components/ui/custom/sidebar-expander.tsx b/frontend/components/ui/custom/sidebar-expander.tsx index 8684cb54..fb32097e 100644 --- a/frontend/components/ui/custom/sidebar-expander.tsx +++ b/frontend/components/ui/custom/sidebar-expander.tsx @@ -95,7 +95,7 @@ function SidebarExpander({ disabled = false, children, className, opened = false {!disabled && (
@@ -73,10 +74,10 @@ const MapVesselTooltip = ({

- Vessel type Fishing Vessel + Type: {type}

- Vessel size: {length} meters + Length: {length} m

diff --git a/frontend/package.json b/frontend/package.json index 39cf40fe..62e8231f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -37,6 +37,7 @@ "class-variance-authority": "^0.4.0", "clsx": "^1.2.1", "cmdk": "^1.0.0", + "country-iso-3-to-2": "^1.1.1", "date-fns": "^3.6.0", "deck.gl": "^9.0.36", "framer-motion": "^11.1.3", From a9c7181dd5ac91507b74e13f1c0a89c0ff388018 Mon Sep 17 00:00:00 2001 From: Alexandre Phiev Date: Tue, 17 Dec 2024 11:39:26 +0100 Subject: [PATCH 6/6] feat: changed mui context menu for shadcn/ui --- frontend/components/core/map/context-menu.tsx | 38 ---- frontend/components/core/map/main-map.tsx | 101 +++++---- frontend/components/ui/context-menu.tsx | 198 ++++++++++++++++++ frontend/package.json | 6 +- 4 files changed, 250 insertions(+), 93 deletions(-) delete mode 100644 frontend/components/core/map/context-menu.tsx create mode 100644 frontend/components/ui/context-menu.tsx diff --git a/frontend/components/core/map/context-menu.tsx b/frontend/components/core/map/context-menu.tsx deleted file mode 100644 index bf3ad654..00000000 --- a/frontend/components/core/map/context-menu.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import Menu from "@mui/material/Menu" -import MenuItem from "@mui/material/MenuItem" - -type ContextMenuProps = { - setOpen: (state: boolean) => void - open: boolean - tooltipPosition: Record | null - coordinates: string -} - -export default function ContextMenu({ - open, - tooltipPosition, - setOpen, - coordinates -}: ContextMenuProps) { - - const copyText = (text: string) => { - navigator.clipboard.writeText(text) - setOpen(false) - } - - return ( - tooltipPosition && ( - setOpen(false)} - anchorReference="anchorPosition" - anchorPosition={{ - top: tooltipPosition.top, - left: tooltipPosition.left, - }} - > - copyText(coordinates)}>Copy coordinates - - ) - ) -} diff --git a/frontend/components/core/map/main-map.tsx b/frontend/components/core/map/main-map.tsx index 0c58ab07..346ce3fe 100644 --- a/frontend/components/core/map/main-map.tsx +++ b/frontend/components/core/map/main-map.tsx @@ -1,20 +1,24 @@ "use client" -import { useCallback, useEffect, useMemo, useState } from "react" +import React, { useCallback, useEffect, useMemo, useState } from "react" import type { PickingInfo } from "@deck.gl/core" -import { useMapStore } from "@/libs/stores/map-store" -import { useTrackModeOptionsStore } from "@/libs/stores" +import { useShallow } from "zustand/react/shallow" -import { VesselPosition, VesselPositions } from "@/types/vessel" +import { VesselPosition } from "@/types/vessel" import { ZoneWithGeometry } from "@/types/zone" - -import DeckGLMap from "./deck-gl-map" -import React from "react" -import { useShallow } from "zustand/react/shallow" +import { useTrackModeOptionsStore } from "@/libs/stores" +import { useMapStore } from "@/libs/stores/map-store" +import { + ContextMenu, + ContextMenuContent, + ContextMenuItem, + ContextMenuTrigger, +} from "@/components/ui/context-menu" import MapVesselTooltip from "@/components/ui/map-vessel-tooltip" import MapZoneTooltip from "@/components/ui/map-zone-tooltip" + +import DeckGLMap from "./deck-gl-map" import { getPickObjectType } from "./utils" -import ContextMenu from "./context-menu" type MainMapProps = { zones: ZoneWithGeometry[] @@ -28,7 +32,7 @@ function CoordonatesIndicator({ coordinates }: { coordinates: string }) { ) } -const MemoizedDeckGLMap = React.memo(DeckGLMap); +const MemoizedDeckGLMap = React.memo(DeckGLMap) export default function MainMap({ zones }: MainMapProps) { const { activePosition, setActivePosition } = useMapStore( @@ -39,30 +43,27 @@ export default function MainMap({ zones }: MainMapProps) { })) ) - const { - addTrackedVessel, - trackedVesselIDs, - removeTrackedVessel, - } = useTrackModeOptionsStore(useShallow((state) => ({ - addTrackedVessel: state.addTrackedVessel, - trackedVesselIDs: state.trackedVesselIDs, - removeTrackedVessel: state.removeTrackedVessel, - }))) + const { addTrackedVessel, trackedVesselIDs, removeTrackedVessel } = + useTrackModeOptionsStore( + useShallow((state) => ({ + addTrackedVessel: state.addTrackedVessel, + trackedVesselIDs: state.trackedVesselIDs, + removeTrackedVessel: state.removeTrackedVessel, + })) + ) const [tooltipPosition, setTooltipPosition] = useState<{ top: number left: number } | null>(null) - - const [contextMenuPosition, setContextMenuPosition] = useState<{ - top: number - left: number - } | null>(null) - const [hoverInfo, setHoverInfo] = useState(null) - const [contextMenu, setContextMenu] = useState(false) - const [previousCoordinates, setPreviousCoordinates] = useState("-°N; -°E") + const [previousCoordinates, setPreviousCoordinates] = + useState("-°N; -°E") + + const copyText = useCallback((text: string) => { + navigator.clipboard.writeText(text) + }, []) const isVesselTracked = (vesselId: number) => { return trackedVesselIDs.includes(vesselId) @@ -90,7 +91,6 @@ export default function MainMap({ zones }: MainMapProps) { } }, [activePosition]) - const onMapHover = useCallback((hoverInfo: PickingInfo) => { setHoverInfo(hoverInfo) }, []) @@ -104,43 +104,42 @@ export default function MainMap({ zones }: MainMapProps) { } const hoverTooltip = useMemo(() => { - if (!hoverInfo) return; + if (!hoverInfo) return - const { object, x, y } = hoverInfo; + const { object, x, y } = hoverInfo const objectType = getPickObjectType(hoverInfo) - let element: React.ReactNode = null; + let element: React.ReactNode = null if (objectType === "vessel") { const vesselInfo = object as VesselPosition const vesselId = vesselInfo.vessel.id if (activePosition?.vessel.id !== vesselId) { - element = + element = } } else if (objectType === "zone") { const zoneInfo = object as ZoneWithGeometry - element = + element = } - return element; - }, [hoverInfo, activePosition]); - - const onMapRightClick = (evt: any) => { - const top = hoverInfo.y > -1 ? hoverInfo.y : screen.height / 2 - 110 - const left = hoverInfo.x > -1 ? hoverInfo.x : screen.width / 2 + 10 - evt.preventDefault() - setContextMenuPosition({ top: top, left: left}) - setContextMenu(true) - } + return element + }, [hoverInfo, activePosition]) return ( -
onMapRightClick(evt)}> - - +
+ + + + + + copyText(coordinates)} + > + Copy coordinates + + + {tooltipPosition && activePosition && ( ) -} \ No newline at end of file +} diff --git a/frontend/components/ui/context-menu.tsx b/frontend/components/ui/context-menu.tsx new file mode 100644 index 00000000..9b89ed25 --- /dev/null +++ b/frontend/components/ui/context-menu.tsx @@ -0,0 +1,198 @@ +import * as React from "react" +import * as ContextMenuPrimitive from "@radix-ui/react-context-menu" +import { Check, ChevronRight, Circle } from "lucide-react" + +import { cn } from "@/libs/utils" + +const ContextMenu = ContextMenuPrimitive.Root + +const ContextMenuTrigger = ContextMenuPrimitive.Trigger + +const ContextMenuGroup = ContextMenuPrimitive.Group + +const ContextMenuPortal = ContextMenuPrimitive.Portal + +const ContextMenuSub = ContextMenuPrimitive.Sub + +const ContextMenuRadioGroup = ContextMenuPrimitive.RadioGroup + +const ContextMenuSubTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, children, ...props }, ref) => ( + + {children} + + +)) +ContextMenuSubTrigger.displayName = ContextMenuPrimitive.SubTrigger.displayName + +const ContextMenuSubContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +ContextMenuSubContent.displayName = ContextMenuPrimitive.SubContent.displayName + +const ContextMenuContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + +)) +ContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName + +const ContextMenuItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, ...props }, ref) => ( + +)) +ContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName + +const ContextMenuCheckboxItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, checked, ...props }, ref) => ( + + + + + + + {children} + +)) +ContextMenuCheckboxItem.displayName = + ContextMenuPrimitive.CheckboxItem.displayName + +const ContextMenuRadioItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + + + + + {children} + +)) +ContextMenuRadioItem.displayName = ContextMenuPrimitive.RadioItem.displayName + +const ContextMenuLabel = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, ...props }, ref) => ( + +)) +ContextMenuLabel.displayName = ContextMenuPrimitive.Label.displayName + +const ContextMenuSeparator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +ContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName + +const ContextMenuShortcut = ({ + className, + ...props +}: React.HTMLAttributes) => { + return ( + + ) +} +ContextMenuShortcut.displayName = "ContextMenuShortcut" + +export { + ContextMenu, + ContextMenuTrigger, + ContextMenuContent, + ContextMenuItem, + ContextMenuCheckboxItem, + ContextMenuRadioItem, + ContextMenuLabel, + ContextMenuSeparator, + ContextMenuShortcut, + ContextMenuGroup, + ContextMenuPortal, + ContextMenuSub, + ContextMenuSubContent, + ContextMenuSubTrigger, + ContextMenuRadioGroup, +} diff --git a/frontend/package.json b/frontend/package.json index 62e8231f..c50fa458 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -16,13 +16,11 @@ }, "dependencies": { "@deck.gl/extensions": "^9.0.36", - "@emotion/react": "^11.14.0", - "@emotion/styled": "^11.14.0", "@heroicons/react": "^2.1.3", "@js-temporal/polyfill": "^0.4.4", "@loaders.gl/core": "^4.2.0", "@loaders.gl/obj": "^4.2.0", - "@mui/material": "^6.2.0", + "@radix-ui/react-context-menu": "^2.2.4", "@radix-ui/react-dialog": "^1.1.2", "@radix-ui/react-dropdown-menu": "^2.1.2", "@radix-ui/react-label": "^2.1.0", @@ -75,4 +73,4 @@ "tailwindcss": "^3.3.2", "typescript": "^4.9.5" } -} +} \ No newline at end of file