diff --git a/rollup.config.js b/rollup.config.js index ea9d4a8b..bb7889e1 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -18,5 +18,5 @@ export default { }), typescript() ], - external: ['react', 'react-dom', 'leaflet', 'react-leaflet', 'react-toastify' , 'react-toastify/dist/ReactToastify.css', 'tw-elements' ,'react-router-dom', 'react-leaflet-cluster', 'leaflet/dist/leaflet.css', '@heroicons/react/20/solid'] + external: ['react', 'react-dom', 'leaflet', 'react-leaflet', 'react-toastify' , 'react-toastify/dist/ReactToastify.css', 'tw-elements' ,'react-router-dom', 'react-leaflet-cluster', '@tanstack/react-query', 'leaflet/dist/leaflet.css', '@heroicons/react/20/solid'] } \ No newline at end of file diff --git a/src/Components/Map/Layer.tsx b/src/Components/Map/Layer.tsx index 6bcf1d05..c8020454 100644 --- a/src/Components/Map/Layer.tsx +++ b/src/Components/Map/Layer.tsx @@ -5,11 +5,15 @@ import MarkerIconFactory from '../../Utils/MarkerIconFactory' import { ItemViewPopup } from './Subcomponents/ItemViewPopup' import { useTags } from './hooks/useTags' import { useAddItem, useItems, useResetItems } from './hooks/useItems' -import { useEffect } from 'react' +import { useEffect, useState } from 'react' import { useAddLayer } from './hooks/useLayers' +import ItemFormPopup, { ItemFormPopupProps } from './Subcomponents/ItemFormPopup' export const Layer = (props: LayerProps) => { + const [itemFormPopup, setItemFormPopup] = useState(null); + + const tags = useTags(); // create a JS-Map with all Tags @@ -19,11 +23,14 @@ export const Layer = (props: LayerProps) => { const getTags = (item: Item) => { const tags: Tag[] = []; item.tags && item.tags.forEach(element => { - if (tagMap.has(element)) { tags.push(tagMap.get(element)!)} + if (tagMap.has(element)) { tags.push(tagMap.get(element)!) } }); return tags; }; + + + const items = useItems(); const addItem = useAddItem() const addLayer = useAddLayer(); @@ -31,36 +38,54 @@ export const Layer = (props: LayerProps) => { useEffect(() => { resetItems(props); + props.data?.map(item => { - if(item.position) { + if (item.position) { item.layer = props; addItem(item); - } + } }) - addLayer(props); - }, [props.data]) + + props.api?.getItems().then(result => { + if (result.data) { + result.data.map(item => { + if (item.position) { + addItem(({layer: props, api: props.api, ...item})); + } + }); + } + }) + if(props.api || props.api) { + addLayer(props); + } + + }, [props.data, props.api]) return ( <> - {items.filter(item => item.layer?.name === props.name)?.map((place: Item) => { - const tags = getTags(place); - let color1 = "#666"; - let color2 = "RGBA(35, 31, 32, 0.2)"; - if (tags[0]) { - color1 = tags[0].color; - } - if (tags[1]) { - color2 = tags[1].color; - } - return ( - - - - ); - }) + {items && + items.filter(item => item.layer?.name === props.name)?.map((place: Item) => { + const tags = getTags(place); + let color1 = "#666"; + let color2 = "RGBA(35, 31, 32, 0.2)"; + if (tags[0]) { + color1 = tags[0].color; + } + if (tags[1]) { + color2 = tags[1].color; + } + return ( + + + + ); + }) } {props.children} + {props.itemFormPopup && props.itemFormPopup.layer.name == props.name && + + } ) } diff --git a/src/Components/Map/Subcomponents/AddButton.tsx b/src/Components/Map/Subcomponents/AddButton.tsx index bd2fc699..15095840 100644 --- a/src/Components/Map/Subcomponents/AddButton.tsx +++ b/src/Components/Map/Subcomponents/AddButton.tsx @@ -6,6 +6,9 @@ import { useLayers } from '../hooks/useLayers' export default function AddButton({setSelectMode} : {setSelectMode: React.Dispatch>}) { const layers = useLayers(); + console.log(layers); + + return (
@@ -18,7 +21,8 @@ export default function AddButton({setSelectMode} : {setSelectMode: React.Dispat
    {layers.map((layer) => ( -
  • + layer.api?.createItem && ( +
  • + ) + ))}
diff --git a/src/Components/Map/Subcomponents/ItemFormPopup.tsx b/src/Components/Map/Subcomponents/ItemFormPopup.tsx index 0a0cfbd4..fd22d3f1 100644 --- a/src/Components/Map/Subcomponents/ItemFormPopup.tsx +++ b/src/Components/Map/Subcomponents/ItemFormPopup.tsx @@ -3,18 +3,20 @@ import { LatLng } from 'leaflet' import { Popup as LeafletPopup, useMap } from 'react-leaflet' import { useEffect, useState } from 'react' import { useAddItem, useUpdateItem } from '../hooks/useItems' -import { Geometry, LayerProps, Item} from '../../../types' +import { Geometry, LayerProps, Item, ItemsApi} from '../../../types' export interface ItemFormPopupProps { position: LatLng, layer: LayerProps, item?: Item, + api?: ItemsApi, setItemFormPopup: React.Dispatch> } export default function ItemFormPopup(props: ItemFormPopupProps) { const [name, setName] = useState('') const [text, setText] = useState('') + const [spinner, setSpinner] = useState(false); const map = useMap(); const addItem = useAddItem(); @@ -24,11 +26,21 @@ export default function ItemFormPopup(props: ItemFormPopupProps) { evt.preventDefault() console.log("New Item Popup is adding Item ..."); if(props.item) { - updateItem(new Item(props.item.id, name, text, new Geometry(props.position.lng, props.position.lat), props.layer)) + setSpinner(true); + props.api?.updateItem!(new Item(props.item.id, name, text, new Geometry(props.position.lng, props.position.lat))) + .then( () => updateItem(new Item(props.item!.id, name, text, new Geometry(props.position.lng, props.position.lat), props.layer, props.item!.api))) + .then(()=> setSpinner(false)) + .then(()=> map.closePopup()) + .catch(err => console.log(err)); } else { - addItem(new Item(crypto.randomUUID(), name, text, new Geometry(props.position.lng, props.position.lat), props.layer))} - map.closePopup(); + setSpinner(true); + props.api?.createItem!(new Item(crypto.randomUUID(), name, text, new Geometry(props.position.lng, props.position.lat))) + .then( () => addItem(new Item(crypto.randomUUID(), name, text, new Geometry(props.position.lng, props.position.lat), props.layer, props.api))) + .then(()=> setSpinner(false)) + .then(()=> map.closePopup()) + .catch(err => console.log(err)); + } props.setItemFormPopup(null); } @@ -41,7 +53,6 @@ export default function ItemFormPopup(props: ItemFormPopupProps) { if(props.item) { setName(props.item?.name); setText(props.item?.text); - console.log('set name + txt'); } } @@ -59,7 +70,7 @@ export default function ItemFormPopup(props: ItemFormPopupProps) {
New {props.layer.name}
setName(e.target.value)} /> -
+
) diff --git a/src/Components/Map/Subcomponents/ItemViewPopup.tsx b/src/Components/Map/Subcomponents/ItemViewPopup.tsx index d900f042..a183fd65 100644 --- a/src/Components/Map/Subcomponents/ItemViewPopup.tsx +++ b/src/Components/Map/Subcomponents/ItemViewPopup.tsx @@ -20,9 +20,12 @@ const ItemViewPopup = (props: ItemViewPopupProps) => { const map = useMap(); const removeItemFromMap = (event: React.MouseEvent) => { - removeItem(item); + props.item.api?.deleteItem!(props.item.id) + .then( () => removeItem(item)) + .then(()=> map.closePopup()) + .catch(err => console.log(err)); + event.stopPropagation(); - map.closePopup(); } const openEditPopup = (event: React.MouseEvent) => { @@ -40,6 +43,7 @@ const ItemViewPopup = (props: ItemViewPopupProps) => { {item.name}
+ {item.api &&
    -
  • + {item.api.updateItem &&
  • -
  • -
  • +
  • } + + {item.api.deleteItem &&
  • -
  • + }
-
+
}
diff --git a/src/Components/Map/UtopiaMap.tsx b/src/Components/Map/UtopiaMap.tsx index e5873556..bf5f2ae7 100644 --- a/src/Components/Map/UtopiaMap.tsx +++ b/src/Components/Map/UtopiaMap.tsx @@ -7,7 +7,7 @@ import { LatLng } from "leaflet"; import MarkerClusterGroup from 'react-leaflet-cluster' import AddButton from "./Subcomponents/AddButton"; import { useState } from "react"; -import ItemFormPopup, { ItemFormPopupProps } from "./Subcomponents/ItemFormPopup"; +import { ItemFormPopupProps } from "./Subcomponents/ItemFormPopup"; import { ItemsProvider } from "./hooks/useItems"; import { TagsProvider } from "./hooks/useTags"; import { LayersProvider } from "./hooks/useLayers"; @@ -43,7 +43,7 @@ function UtopiaMap({ : UtopiaMapProps) { const [selectMode, setSelectMode] = useState(null); - const [newItemPopup, setItemFormPopup] = useState(null); + const [itemFormPopup, setItemFormPopup] = useState(null); @@ -59,14 +59,11 @@ function UtopiaMap({ { React.Children.toArray(children).map((child) => - React.isValidElement<{ setItemFormPopup: React.Dispatch> }>(child) ? React.cloneElement(child, { setItemFormPopup: setItemFormPopup }) : child + React.isValidElement<{ setItemFormPopup: React.Dispatch>, itemFormPopup: ItemFormPopupProps | null }>(child) ? React.cloneElement(child, { setItemFormPopup: setItemFormPopup, itemFormPopup: itemFormPopup }) : child ) } - {newItemPopup && - - } {selectMode != null && diff --git a/src/types.ts b/src/types.ts index ddf17614..1899c01e 100644 --- a/src/types.ts +++ b/src/types.ts @@ -21,8 +21,9 @@ export interface LayerProps { markerShape: string, markerDefaultColor: string, tags?: Tag[], - api?: ItemsApi, - setItemFormPopup?: React.Dispatch> + api?: ItemsApi, + setItemFormPopup?: React.Dispatch>, + itemFormPopup?: ItemFormPopupProps | null } export class Item { @@ -36,12 +37,14 @@ export class Item { start?: string; end?: string; tags?: number[]; - constructor(id:string|number,name:string,text:string,position:Geometry, layer: LayerProps){ + api?: ItemsApi + constructor(id:string|number,name:string,text:string,position:Geometry, layer?: LayerProps, api?: ItemsApi){ this.id = id; this.name = name; this.text = text; this.position = position; this.layer = layer; + this.api = api; } } @@ -60,9 +63,9 @@ export interface Tag { name: string; } -export interface ItemsApi { - getItems(): Promise, - addItem(item : Item): Promise, - updateItem(item : Item): Promise, - deleteItem(id : number): Promise, +export interface ItemsApi { + getItems(): Promise, + createItem?(item : T): Promise, + updateItem?(item : T): Promise, + deleteItem?(id : number | string): Promise, } \ No newline at end of file