diff --git a/src/components/Map.stories.tsx b/src/components/Map.stories.tsx index 16d94c3..a03cc4f 100644 --- a/src/components/Map.stories.tsx +++ b/src/components/Map.stories.tsx @@ -1,4 +1,5 @@ import { + DiscriminatedItem, MemberFactory, PackedFolderItemFactory, PermissionLevel, @@ -470,6 +471,10 @@ export const MapRead = { args: { item: PackedFolderItemFactory({}, { permission: PermissionLevel.Read }), viewItem: () => ({}) as any, + viewItemInBuilder: (it: DiscriminatedItem) => { + // eslint-disable-next-line no-console + console.log(it.id); + }, currentMember: MemberFactory({ extra: { lang: 'fr' } }), useDeleteItemGeolocation: () => ({}) as any, useItemsInMap: () => diff --git a/src/components/Map.tsx b/src/components/Map.tsx index 004581a..e03da39 100644 --- a/src/components/Map.tsx +++ b/src/components/Map.tsx @@ -31,6 +31,7 @@ const Map = ({ useDeleteItemGeolocation, handleAddOnClick, currentPosition, + viewItemInBuilder, }: Props): JSX.Element => { const [showMap, setShowMap] = useState(false); @@ -44,17 +45,18 @@ const Map = ({ return (
void; + viewItemInBuilder: (item: DiscriminatedItem) => void; handleAddOnClick?: ({ location, }: { @@ -44,6 +45,7 @@ export const QueryClientContext = createContext({ usePostItem: () => ({}) as any, useDeleteItemGeolocation: () => ({}) as any, viewItem: () => ({}) as any, + viewItemInBuilder: () => ({}) as any, }); export const QueryClientContextProvider = ({ @@ -59,6 +61,7 @@ export const QueryClientContextProvider = ({ item, currentPosition, handleAddOnClick, + viewItemInBuilder, }: QueryClientContextInterface & { children: JSX.Element }): JSX.Element => { const value = useMemo( () => ({ @@ -73,6 +76,7 @@ export const QueryClientContextProvider = ({ useSuggestionsForAddress, currentPosition, handleAddOnClick, + viewItemInBuilder, }), [ currentMember, @@ -86,6 +90,7 @@ export const QueryClientContextProvider = ({ item, currentPosition, handleAddOnClick, + viewItemInBuilder, ], ); diff --git a/src/components/map/ItemsMarkers.tsx b/src/components/map/ItemsMarkers.tsx index 206a25a..1e50d1e 100644 --- a/src/components/map/ItemsMarkers.tsx +++ b/src/components/map/ItemsMarkers.tsx @@ -1,5 +1,5 @@ -import { useRef } from 'react'; -import { FeatureGroup, Marker } from 'react-leaflet'; +import { useEffect, useRef, useState } from 'react'; +import { FeatureGroup, Marker, useMap } from 'react-leaflet'; import MarkerClusterGroup from 'react-leaflet-cluster'; import { useQueryClientContext } from '../context/QueryClientContext'; @@ -19,12 +19,26 @@ const ItemsMarkers = ({ }; }): JSX.Element | JSX.Element[] | undefined => { const groupRef = useRef(null); + const map = useMap(); const { useItemsInMap, item } = useQueryClientContext(); const { data: itemGeolocations } = useItemsInMap({ ...bounds, parentItemId: item?.id, keywords: tags, }); + const [prevState, setPrevState] = useState(itemGeolocations); + + useEffect(() => { + if (JSON.stringify(itemGeolocations) !== JSON.stringify(prevState)) { + // on positive search, focus on items + if (itemGeolocations?.length !== prevState?.length && tags.length) { + map.fitBounds(groupRef.current.getBounds()); + } + + setPrevState(itemGeolocations); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [tags, itemGeolocations]); // color of clusters is defined by number of markers grouped together return ( diff --git a/src/components/map/MarkerPopup.tsx b/src/components/map/MarkerPopup.tsx index d3739f3..13f4d97 100644 --- a/src/components/map/MarkerPopup.tsx +++ b/src/components/map/MarkerPopup.tsx @@ -1,6 +1,6 @@ import { Popup } from 'react-leaflet'; -import { Box, Chip, Stack, Typography } from '@mui/material'; +import { Box, Chip, Link, Stack, Tooltip, Typography } from '@mui/material'; import { ItemGeolocation, @@ -8,6 +8,9 @@ import { PermissionLevelCompare, } from '@graasp/sdk'; +import { useMapTranslation } from '@/config/i18n'; + +import { useQueryClientContext } from '../context/QueryClientContext'; import DeleteItemButton from './DeleteItemButton'; import DeleteLocationButton from './DeleteLocationButton'; import ViewButton from './ViewButton'; @@ -18,10 +21,26 @@ const MarkerPopup = ({ geolocation: ItemGeolocation; }): JSX.Element => { const { item } = geolocation; + const { viewItemInBuilder } = useQueryClientContext(); + const { t } = useMapTranslation(); return ( - {item.name} + + {/* eslint-disable-next-line jsx-a11y/anchor-is-valid */} + viewItemInBuilder(item)} + variant="h5" + sx={{ + '&:hover': { + cursor: 'pointer', + }, + }} + > + {item.name} + + {/* TODO: slice and show html */} {item.description && ( - {item.settings.tags?.map((t: string, idx) => ( + {item.settings.tags?.map((tag: string, idx) => ( // eslint-disable-next-line react/no-array-index-key - + ))} diff --git a/src/components/map/ViewButton.tsx b/src/components/map/ViewButton.tsx index 7cf47a7..481f441 100644 --- a/src/components/map/ViewButton.tsx +++ b/src/components/map/ViewButton.tsx @@ -3,6 +3,8 @@ import { IconButton, Tooltip } from '@mui/material'; import { DiscriminatedItem } from '@graasp/sdk'; +import { useMapTranslation } from '@/config/i18n'; + import { useQueryClientContext } from '../context/QueryClientContext'; type Props = { @@ -11,9 +13,10 @@ type Props = { const ViewButton = ({ item }: Props): JSX.Element => { const { viewItem } = useQueryClientContext(); + const { t } = useMapTranslation(); return ( - + { viewItem(item); diff --git a/src/components/topbar/Search.tsx b/src/components/topbar/Search.tsx index 54a9520..5a0ece1 100644 --- a/src/components/topbar/Search.tsx +++ b/src/components/topbar/Search.tsx @@ -23,7 +23,7 @@ const Search = ({ ( diff --git a/src/langs/en.json b/src/langs/en.json index 414b5fd..1119c88 100644 --- a/src/langs/en.json +++ b/src/langs/en.json @@ -17,5 +17,7 @@ "Name": "Name", "Add a new folder at this location": "Add a new folder at this location", "This location does not match a specific address.": "This location does not match a specific address.", - "Select a country": "Select a country" + "Select a country": "Select a country", + "VIEW_ITEM_BUILDER_TOOLTIP": "View item in Graasp Builder", + "VIEW_ITEM_PLAYER_TOOLTIP": "View item in Graasp Player" }