mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2025-12-13 07:46:10 +00:00
Refactor Layer and its subcomponents, replacing cloneElement by context
This commit is contained in:
parent
9e6bcf1846
commit
d739977ca1
@ -1,38 +0,0 @@
|
|||||||
import { Children, cloneElement, isValidElement, useEffect } from 'react'
|
|
||||||
|
|
||||||
import type { Item } from '#types/Item'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @category Map
|
|
||||||
*/
|
|
||||||
export const ItemForm = ({
|
|
||||||
children,
|
|
||||||
item,
|
|
||||||
title,
|
|
||||||
setPopupTitle,
|
|
||||||
}: {
|
|
||||||
children?: React.ReactNode
|
|
||||||
item?: Item
|
|
||||||
title?: string
|
|
||||||
setPopupTitle?: React.Dispatch<React.SetStateAction<string>>
|
|
||||||
}) => {
|
|
||||||
useEffect(() => {
|
|
||||||
setPopupTitle && title && setPopupTitle(title)
|
|
||||||
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
}, [title])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
{children
|
|
||||||
? Children.toArray(children).map((child) =>
|
|
||||||
isValidElement<{ item: Item; test: string }>(child)
|
|
||||||
? cloneElement(child, { item, test: 'test' })
|
|
||||||
: '',
|
|
||||||
)
|
|
||||||
: ''}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
ItemForm.__TYPE = 'ItemForm'
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
import { Children, cloneElement, isValidElement } from 'react'
|
|
||||||
|
|
||||||
import type { Item } from '#types/Item'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @category Map
|
|
||||||
*/
|
|
||||||
export const ItemView = ({ children, item }: { children?: React.ReactNode; item?: Item }) => {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
{children
|
|
||||||
? Children.toArray(children).map((child) =>
|
|
||||||
isValidElement<{ item: Item }>(child) ? cloneElement(child, { item }) : null,
|
|
||||||
)
|
|
||||||
: null}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
ItemView.__TYPE = 'ItemView'
|
|
||||||
@ -1,31 +1,12 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
import { useEffect, useState } from 'react'
|
||||||
/* eslint-disable @typescript-eslint/prefer-optional-chain */
|
|
||||||
import { Children, isValidElement, useEffect, useState } from 'react'
|
|
||||||
import { Marker, Tooltip } from 'react-leaflet'
|
|
||||||
|
|
||||||
import { encodeTag } from '#utils/FormatTags'
|
import LayerContext from '#components/Profile/templateComponents/LayerContext'
|
||||||
import { hashTagRegex } from '#utils/HashTagRegex'
|
|
||||||
import MarkerIconFactory from '#utils/MarkerIconFactory'
|
|
||||||
import { randomColor } from '#utils/RandomColor'
|
|
||||||
|
|
||||||
import {
|
import { useSetItemsApi, useSetItemsData } from './hooks/useItems'
|
||||||
useFilterTags,
|
import { useAddTag } from './hooks/useTags'
|
||||||
useIsGroupTypeVisible,
|
|
||||||
useIsLayerVisible,
|
|
||||||
useVisibleGroupType,
|
|
||||||
} from './hooks/useFilter'
|
|
||||||
import { useAllItemsLoaded, useItems, useSetItemsApi, useSetItemsData } from './hooks/useItems'
|
|
||||||
import { useAddMarker, useAddPopup, useLeafletRefs } from './hooks/useLeafletRefs'
|
|
||||||
import { useSelectPosition, useSetMarkerClicked } from './hooks/useSelectPosition'
|
|
||||||
import { useAddTag, useAllTagsLoaded, useGetItemTags, useTags } from './hooks/useTags'
|
|
||||||
import { ItemFormPopup } from './Subcomponents/ItemFormPopup'
|
|
||||||
import { ItemViewPopup } from './Subcomponents/ItemViewPopup'
|
|
||||||
|
|
||||||
import type { Item } from '#types/Item'
|
|
||||||
import type { LayerProps } from '#types/LayerProps'
|
import type { LayerProps } from '#types/LayerProps'
|
||||||
import type { Tag } from '#types/Tag'
|
import type { Tag } from '#types/Tag'
|
||||||
import type { Popup } from 'leaflet'
|
|
||||||
import type { ReactElement, ReactNode } from 'react'
|
|
||||||
|
|
||||||
export type { Point } from 'geojson'
|
export type { Point } from 'geojson'
|
||||||
export type { Item } from '#types/Item'
|
export type { Item } from '#types/Item'
|
||||||
@ -59,32 +40,12 @@ export const Layer = ({
|
|||||||
itemFormPopup,
|
itemFormPopup,
|
||||||
clusterRef,
|
clusterRef,
|
||||||
}: LayerProps) => {
|
}: LayerProps) => {
|
||||||
const filterTags = useFilterTags()
|
|
||||||
|
|
||||||
const items = useItems()
|
|
||||||
const setItemsApi = useSetItemsApi()
|
const setItemsApi = useSetItemsApi()
|
||||||
const setItemsData = useSetItemsData()
|
const setItemsData = useSetItemsData()
|
||||||
const getItemTags = useGetItemTags()
|
|
||||||
const addMarker = useAddMarker()
|
|
||||||
const addPopup = useAddPopup()
|
|
||||||
const leafletRefs = useLeafletRefs()
|
|
||||||
|
|
||||||
const allTagsLoaded = useAllTagsLoaded()
|
|
||||||
const allItemsLoaded = useAllItemsLoaded()
|
|
||||||
|
|
||||||
const setMarkerClicked = useSetMarkerClicked()
|
|
||||||
const selectPosition = useSelectPosition()
|
|
||||||
|
|
||||||
const tags = useTags()
|
|
||||||
const addTag = useAddTag()
|
const addTag = useAddTag()
|
||||||
const [newTagsToAdd, setNewTagsToAdd] = useState<Tag[]>([])
|
const [newTagsToAdd] = useState<Tag[]>([])
|
||||||
const [tagsReady, setTagsReady] = useState<boolean>(false)
|
const [tagsReady] = useState<boolean>(false)
|
||||||
|
|
||||||
const isLayerVisible = useIsLayerVisible()
|
|
||||||
|
|
||||||
const isGroupTypeVisible = useIsGroupTypeVisible()
|
|
||||||
|
|
||||||
const visibleGroupTypes = useVisibleGroupType()
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
data &&
|
data &&
|
||||||
@ -156,178 +117,18 @@ export const Layer = ({
|
|||||||
}, [tagsReady])
|
}, [tagsReady])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<LayerContext.Provider
|
||||||
{items &&
|
value={{
|
||||||
items
|
name,
|
||||||
.filter((item) => item.layer?.name === name)
|
markerDefaultColor,
|
||||||
.filter((item) =>
|
markerDefaultColor2,
|
||||||
filterTags.length === 0
|
|
||||||
? item
|
|
||||||
: filterTags.some((tag) =>
|
|
||||||
getItemTags(item).some(
|
|
||||||
(filterTag) =>
|
|
||||||
filterTag.name.toLocaleLowerCase() === tag.name.toLocaleLowerCase(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.filter((item) => item.layer && isLayerVisible(item.layer))
|
|
||||||
.filter(
|
|
||||||
(item) =>
|
|
||||||
(item.group_type && isGroupTypeVisible(item.group_type)) ||
|
|
||||||
visibleGroupTypes.length === 0,
|
|
||||||
)
|
|
||||||
.map((item: Item) => {
|
|
||||||
if (item.position?.coordinates[0] && item.position?.coordinates[1]) {
|
|
||||||
if (item.tags) {
|
|
||||||
item.text += '\n\n'
|
|
||||||
item.tags.map((tag) => {
|
|
||||||
if (!item.text?.includes(`#${encodeTag(tag)}`)) {
|
|
||||||
item.text += `#${encodeTag(tag)}`
|
|
||||||
}
|
|
||||||
return item.text
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if (allTagsLoaded && allItemsLoaded) {
|
|
||||||
item.text?.match(hashTagRegex)?.map((tag) => {
|
|
||||||
if (
|
|
||||||
!tags.find(
|
|
||||||
(t) => t.name.toLocaleLowerCase() === tag.slice(1).toLocaleLowerCase(),
|
|
||||||
) &&
|
|
||||||
!newTagsToAdd.find(
|
|
||||||
(t) => t.name.toLocaleLowerCase() === tag.slice(1).toLocaleLowerCase(),
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
const newTag = {
|
|
||||||
id: crypto.randomUUID(),
|
|
||||||
name: tag.slice(1),
|
|
||||||
color: randomColor(),
|
|
||||||
}
|
|
||||||
setNewTagsToAdd((current) => [...current, newTag])
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
})
|
|
||||||
!tagsReady && setTagsReady(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
const itemTags = getItemTags(item)
|
|
||||||
|
|
||||||
const latitude = item.position.coordinates[1]
|
|
||||||
const longitude = item.position.coordinates[0]
|
|
||||||
|
|
||||||
let color1 = markerDefaultColor
|
|
||||||
let color2 = markerDefaultColor2
|
|
||||||
if (item.color) {
|
|
||||||
color1 = item.color
|
|
||||||
} else if (itemTags[0]) {
|
|
||||||
color1 = itemTags[0].color
|
|
||||||
}
|
|
||||||
if (itemTags[0] && item.color) {
|
|
||||||
color2 = itemTags[0].color
|
|
||||||
} else if (itemTags[1]) {
|
|
||||||
color2 = itemTags[1].color
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<Marker
|
|
||||||
ref={(r) => {
|
|
||||||
if (!(item.id in leafletRefs && leafletRefs[item.id].marker === r)) {
|
|
||||||
r && addMarker(item, r)
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
eventHandlers={{
|
|
||||||
click: () => {
|
|
||||||
selectPosition && setMarkerClicked(item)
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
icon={MarkerIconFactory(
|
|
||||||
markerShape,
|
markerShape,
|
||||||
color1,
|
markerIcon,
|
||||||
color2,
|
itemFormPopup,
|
||||||
item.markerIcon ? item.markerIcon : markerIcon,
|
setItemFormPopup,
|
||||||
)}
|
|
||||||
key={item.id}
|
|
||||||
position={[latitude, longitude]}
|
|
||||||
>
|
|
||||||
{children &&
|
|
||||||
Children.toArray(children).some(
|
|
||||||
(child) => isComponentWithType(child) && child.type.__TYPE === 'ItemView',
|
|
||||||
) ? (
|
|
||||||
Children.toArray(children).map((child) =>
|
|
||||||
isComponentWithType(child) && child.type.__TYPE === 'ItemView' ? (
|
|
||||||
<ItemViewPopup
|
|
||||||
ref={(r) => {
|
|
||||||
if (!(item.id in leafletRefs && leafletRefs[item.id].popup === r)) {
|
|
||||||
r && addPopup(item, r as Popup)
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
key={item.id + item.name}
|
|
||||||
item={item}
|
|
||||||
setItemFormPopup={setItemFormPopup}
|
|
||||||
>
|
>
|
||||||
{child}
|
{children}
|
||||||
</ItemViewPopup>
|
</LayerContext.Provider>
|
||||||
) : null,
|
|
||||||
)
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<ItemViewPopup
|
|
||||||
key={item.id + item.name}
|
|
||||||
ref={(r) => {
|
|
||||||
if (!(item.id in leafletRefs && leafletRefs[item.id].popup === r)) {
|
|
||||||
r && addPopup(item, r as Popup)
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
item={item}
|
|
||||||
setItemFormPopup={setItemFormPopup}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<Tooltip offset={[0, -38]} direction='top'>
|
|
||||||
{item.name}
|
|
||||||
</Tooltip>
|
|
||||||
</Marker>
|
|
||||||
)
|
|
||||||
} else return null
|
|
||||||
})}
|
|
||||||
{
|
|
||||||
// {children}}
|
|
||||||
}
|
|
||||||
{itemFormPopup &&
|
|
||||||
itemFormPopup.layer.name === name &&
|
|
||||||
(children &&
|
|
||||||
Children.toArray(children).some(
|
|
||||||
(child) => isComponentWithType(child) && child.type.__TYPE === 'ItemForm',
|
|
||||||
) ? (
|
|
||||||
Children.toArray(children).map((child) =>
|
|
||||||
isComponentWithType(child) && child.type.__TYPE === 'ItemForm' ? (
|
|
||||||
<ItemFormPopup
|
|
||||||
key={setItemFormPopup?.name}
|
|
||||||
position={itemFormPopup.position}
|
|
||||||
layer={itemFormPopup.layer}
|
|
||||||
setItemFormPopup={setItemFormPopup}
|
|
||||||
item={itemFormPopup.item}
|
|
||||||
>
|
|
||||||
{child}
|
|
||||||
</ItemFormPopup>
|
|
||||||
) : (
|
|
||||||
''
|
|
||||||
),
|
|
||||||
)
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<ItemFormPopup
|
|
||||||
position={itemFormPopup.position}
|
|
||||||
layer={itemFormPopup.layer}
|
|
||||||
setItemFormPopup={setItemFormPopup}
|
|
||||||
item={itemFormPopup.item}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
))}
|
|
||||||
</>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function isComponentWithType(node: ReactNode): node is ReactElement & { type: { __TYPE: string } } {
|
|
||||||
return isValidElement(node) && typeof node.type !== 'string' && '__TYPE' in node.type
|
|
||||||
}
|
|
||||||
|
|||||||
0
src/Components/Map/ProfileView.tsx
Normal file
0
src/Components/Map/ProfileView.tsx
Normal file
@ -2,8 +2,6 @@ export { UtopiaMap } from './UtopiaMap'
|
|||||||
export * from './Layer'
|
export * from './Layer'
|
||||||
export { Tags } from './Tags'
|
export { Tags } from './Tags'
|
||||||
export * from './Permissions'
|
export * from './Permissions'
|
||||||
export { ItemForm } from './ItemForm'
|
|
||||||
export { ItemView } from './ItemView'
|
|
||||||
export { PopupTextAreaInput } from './Subcomponents/ItemPopupComponents/PopupTextAreaInput'
|
export { PopupTextAreaInput } from './Subcomponents/ItemPopupComponents/PopupTextAreaInput'
|
||||||
export { PopupStartEndInput } from './Subcomponents/ItemPopupComponents/PopupStartEndInput'
|
export { PopupStartEndInput } from './Subcomponents/ItemPopupComponents/PopupStartEndInput'
|
||||||
export { PopupTextInput } from './Subcomponents/ItemPopupComponents/PopupTextInput'
|
export { PopupTextInput } from './Subcomponents/ItemPopupComponents/PopupTextInput'
|
||||||
|
|||||||
@ -2,3 +2,5 @@ export { UserSettings } from './UserSettings'
|
|||||||
// export { PlusButton } from './Subcomponents/PlusButton'
|
// export { PlusButton } from './Subcomponents/PlusButton'
|
||||||
export { ProfileView } from './ProfileView'
|
export { ProfileView } from './ProfileView'
|
||||||
export { ProfileForm } from './ProfileForm'
|
export { ProfileForm } from './ProfileForm'
|
||||||
|
export { CardForm } from './templateComponents/CardForm'
|
||||||
|
export { CardView } from './templateComponents/CardView'
|
||||||
|
|||||||
29
src/Components/Profile/templateComponents/CardForm.tsx
Normal file
29
src/Components/Profile/templateComponents/CardForm.tsx
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import { useContext } from 'react'
|
||||||
|
|
||||||
|
import { ItemFormPopup } from '#components/Map/Subcomponents/ItemFormPopup'
|
||||||
|
|
||||||
|
import LayerContext from './LayerContext'
|
||||||
|
import TemplateItemContext from './TemplateItemContext'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @category Map
|
||||||
|
*/
|
||||||
|
export const CardForm = ({ children }: { children?: React.ReactNode }) => {
|
||||||
|
const { itemFormPopup, setItemFormPopup } = useContext(LayerContext)
|
||||||
|
|
||||||
|
return (
|
||||||
|
itemFormPopup && (
|
||||||
|
<ItemFormPopup
|
||||||
|
key={setItemFormPopup?.name}
|
||||||
|
position={itemFormPopup.position}
|
||||||
|
layer={itemFormPopup.layer}
|
||||||
|
setItemFormPopup={setItemFormPopup}
|
||||||
|
item={itemFormPopup.item}
|
||||||
|
>
|
||||||
|
<TemplateItemContext.Provider value={itemFormPopup.item}>
|
||||||
|
{children}
|
||||||
|
</TemplateItemContext.Provider>
|
||||||
|
</ItemFormPopup>
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
186
src/Components/Profile/templateComponents/CardView.tsx
Normal file
186
src/Components/Profile/templateComponents/CardView.tsx
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
import { useContext, useMemo, useState } from 'react'
|
||||||
|
import { Marker, Tooltip } from 'react-leaflet'
|
||||||
|
|
||||||
|
import {
|
||||||
|
useFilterTags,
|
||||||
|
useIsLayerVisible,
|
||||||
|
useIsGroupTypeVisible,
|
||||||
|
useVisibleGroupType,
|
||||||
|
} from '#components/Map/hooks/useFilter'
|
||||||
|
import { useItems, useAllItemsLoaded } from '#components/Map/hooks/useItems'
|
||||||
|
import { useAddMarker, useAddPopup, useLeafletRefs } from '#components/Map/hooks/useLeafletRefs'
|
||||||
|
import { useSetMarkerClicked, useSelectPosition } from '#components/Map/hooks/useSelectPosition'
|
||||||
|
import { useGetItemTags, useAllTagsLoaded, useTags } from '#components/Map/hooks/useTags'
|
||||||
|
import { ItemViewPopup } from '#components/Map/Subcomponents/ItemViewPopup'
|
||||||
|
import { encodeTag } from '#utils/FormatTags'
|
||||||
|
import { hashTagRegex } from '#utils/HashTagRegex'
|
||||||
|
import MarkerIconFactory from '#utils/MarkerIconFactory'
|
||||||
|
import { randomColor } from '#utils/RandomColor'
|
||||||
|
|
||||||
|
import LayerContext from './LayerContext'
|
||||||
|
import TemplateItemContext from './TemplateItemContext'
|
||||||
|
|
||||||
|
import type { Item } from '#types/Item'
|
||||||
|
import type { Tag } from '#types/Tag'
|
||||||
|
import type { Popup } from 'leaflet'
|
||||||
|
|
||||||
|
// TODO Think about folder structure. This is not for profile, but for card / popup. Both can use the same template components.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @category Profile
|
||||||
|
*/
|
||||||
|
export const CardView = ({ children }: { children?: React.ReactNode }) => {
|
||||||
|
const cardViewContext = useContext(LayerContext)
|
||||||
|
const {
|
||||||
|
name,
|
||||||
|
markerDefaultColor,
|
||||||
|
markerDefaultColor2,
|
||||||
|
markerShape,
|
||||||
|
markerIcon,
|
||||||
|
setItemFormPopup,
|
||||||
|
} = cardViewContext
|
||||||
|
|
||||||
|
const filterTags = useFilterTags()
|
||||||
|
|
||||||
|
const items = useItems()
|
||||||
|
const getItemTags = useGetItemTags()
|
||||||
|
const addMarker = useAddMarker()
|
||||||
|
const addPopup = useAddPopup()
|
||||||
|
const leafletRefs = useLeafletRefs()
|
||||||
|
|
||||||
|
const allTagsLoaded = useAllTagsLoaded()
|
||||||
|
const allItemsLoaded = useAllItemsLoaded()
|
||||||
|
|
||||||
|
const setMarkerClicked = useSetMarkerClicked()
|
||||||
|
const selectPosition = useSelectPosition()
|
||||||
|
|
||||||
|
const tags = useTags()
|
||||||
|
const [newTagsToAdd, setNewTagsToAdd] = useState<Tag[]>([])
|
||||||
|
const [tagsReady, setTagsReady] = useState<boolean>(false)
|
||||||
|
|
||||||
|
const isLayerVisible = useIsLayerVisible()
|
||||||
|
|
||||||
|
const isGroupTypeVisible = useIsGroupTypeVisible()
|
||||||
|
|
||||||
|
const visibleGroupTypes = useVisibleGroupType()
|
||||||
|
|
||||||
|
const visibleItems = useMemo(
|
||||||
|
() =>
|
||||||
|
items
|
||||||
|
.filter((item) => item.layer?.name === name)
|
||||||
|
.filter((item) =>
|
||||||
|
filterTags.length === 0
|
||||||
|
? item
|
||||||
|
: filterTags.some((tag) =>
|
||||||
|
getItemTags(item).some(
|
||||||
|
(filterTag) =>
|
||||||
|
filterTag.name.toLocaleLowerCase() === tag.name.toLocaleLowerCase(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.filter((item) => item.layer && isLayerVisible(item.layer))
|
||||||
|
.filter(
|
||||||
|
(item) =>
|
||||||
|
(item.group_type && isGroupTypeVisible(item.group_type)) ||
|
||||||
|
visibleGroupTypes.length === 0,
|
||||||
|
),
|
||||||
|
[
|
||||||
|
filterTags,
|
||||||
|
getItemTags,
|
||||||
|
isGroupTypeVisible,
|
||||||
|
isLayerVisible,
|
||||||
|
items,
|
||||||
|
name,
|
||||||
|
visibleGroupTypes.length,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!setItemFormPopup) {
|
||||||
|
throw new Error('setItemFormPopup is not defined')
|
||||||
|
}
|
||||||
|
|
||||||
|
return visibleItems.map((item: Item) => {
|
||||||
|
if (!(item.position?.coordinates[0] && item.position.coordinates[1])) return null
|
||||||
|
|
||||||
|
if (item.tags) {
|
||||||
|
item.text += '\n\n'
|
||||||
|
item.tags.map((tag) => {
|
||||||
|
if (!item.text?.includes(`#${encodeTag(tag)}`)) {
|
||||||
|
item.text += `#${encodeTag(tag)}`
|
||||||
|
}
|
||||||
|
return item.text
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allTagsLoaded && allItemsLoaded) {
|
||||||
|
item.text?.match(hashTagRegex)?.map((tag) => {
|
||||||
|
if (
|
||||||
|
!tags.find((t) => t.name.toLocaleLowerCase() === tag.slice(1).toLocaleLowerCase()) &&
|
||||||
|
!newTagsToAdd.find((t) => t.name.toLocaleLowerCase() === tag.slice(1).toLocaleLowerCase())
|
||||||
|
) {
|
||||||
|
const newTag = {
|
||||||
|
id: crypto.randomUUID(),
|
||||||
|
name: tag.slice(1),
|
||||||
|
color: randomColor(),
|
||||||
|
}
|
||||||
|
setNewTagsToAdd((current) => [...current, newTag])
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
})
|
||||||
|
!tagsReady && setTagsReady(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
const itemTags = getItemTags(item)
|
||||||
|
|
||||||
|
const latitude = item.position.coordinates[1]
|
||||||
|
const longitude = item.position.coordinates[0]
|
||||||
|
|
||||||
|
let color1 = markerDefaultColor
|
||||||
|
let color2 = markerDefaultColor2
|
||||||
|
if (item.color) {
|
||||||
|
color1 = item.color
|
||||||
|
} else if (itemTags[0]) {
|
||||||
|
color1 = itemTags[0].color
|
||||||
|
}
|
||||||
|
if (itemTags[0] && item.color) {
|
||||||
|
color2 = itemTags[0].color
|
||||||
|
} else if (itemTags[1]) {
|
||||||
|
color2 = itemTags[1].color
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TemplateItemContext.Provider value={item} key={item.id}>
|
||||||
|
<Marker
|
||||||
|
ref={(r) => {
|
||||||
|
if (!(item.id in leafletRefs && leafletRefs[item.id].marker === r)) {
|
||||||
|
r && addMarker(item, r)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
eventHandlers={{
|
||||||
|
click: () => {
|
||||||
|
selectPosition && setMarkerClicked(item)
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
icon={MarkerIconFactory(markerShape, color1, color2, item.markerIcon ?? markerIcon)}
|
||||||
|
position={[latitude, longitude]}
|
||||||
|
>
|
||||||
|
<ItemViewPopup
|
||||||
|
ref={(r: Popup | null) => {
|
||||||
|
if (!(item.id in leafletRefs && leafletRefs[item.id].popup === r)) {
|
||||||
|
r && addPopup(item, r)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
item={item}
|
||||||
|
setItemFormPopup={setItemFormPopup}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</ItemViewPopup>
|
||||||
|
|
||||||
|
<Tooltip offset={[0, -38]} direction='top'>
|
||||||
|
{item.name}
|
||||||
|
</Tooltip>
|
||||||
|
</Marker>
|
||||||
|
</TemplateItemContext.Provider>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
27
src/Components/Profile/templateComponents/LayerContext.ts
Normal file
27
src/Components/Profile/templateComponents/LayerContext.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { createContext } from 'react'
|
||||||
|
|
||||||
|
import type { ItemFormPopupProps } from '#types/ItemFormPopupProps'
|
||||||
|
|
||||||
|
// Where should we define defaults, here or in Layer.tsx?
|
||||||
|
|
||||||
|
interface LayerContextType {
|
||||||
|
name: string
|
||||||
|
markerDefaultColor: string
|
||||||
|
markerDefaultColor2: string
|
||||||
|
markerShape: string
|
||||||
|
markerIcon: string
|
||||||
|
itemFormPopup: ItemFormPopupProps | null | undefined
|
||||||
|
setItemFormPopup: React.Dispatch<React.SetStateAction<ItemFormPopupProps | null>> | undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
const LayerContext = createContext<LayerContextType>({
|
||||||
|
name: '',
|
||||||
|
markerDefaultColor: '#777',
|
||||||
|
markerDefaultColor2: 'RGBA(35, 31, 32, 0.2)',
|
||||||
|
markerShape: 'circle',
|
||||||
|
markerIcon: '',
|
||||||
|
itemFormPopup: undefined,
|
||||||
|
setItemFormPopup: undefined,
|
||||||
|
})
|
||||||
|
|
||||||
|
export default LayerContext
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
import { createContext } from 'react'
|
||||||
|
|
||||||
|
import type { Item } from '#types/Item'
|
||||||
|
|
||||||
|
const ItemContext = createContext<Item | undefined>(undefined)
|
||||||
|
|
||||||
|
export default ItemContext
|
||||||
Loading…
x
Reference in New Issue
Block a user