enhanced state management

This commit is contained in:
AT 2023-04-16 21:11:25 +02:00
parent 069cc18cbf
commit 96193ab8c2
6 changed files with 51 additions and 65 deletions

20
package-lock.json generated
View File

@ -1919,6 +1919,20 @@
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
"dev": true "dev": true
}, },
"node_modules/fsevents": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
"dev": true,
"hasInstallScript": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
"node_modules/function-bind": { "node_modules/function-bind": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
@ -3912,9 +3926,9 @@
} }
}, },
"node_modules/rollup": { "node_modules/rollup": {
"version": "2.75.7", "version": "2.79.1",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.75.7.tgz", "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz",
"integrity": "sha512-VSE1iy0eaAYNCxEXaleThdFXqZJ42qDBatAwrfnPlENEZ8erQ+0LYX4JXOLPceWfZpV1VtZwZ3dFCuOZiSyFtQ==", "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==",
"dev": true, "dev": true,
"bin": { "bin": {
"rollup": "dist/bin/rollup" "rollup": "dist/bin/rollup"

View File

@ -4,7 +4,7 @@
"description": "Reuseable React Components to build mapping apps for all kinds of communities ", "description": "Reuseable React Components to build mapping apps for all kinds of communities ",
"repository": "https://github.com/utopia-os/utopia-ui", "repository": "https://github.com/utopia-os/utopia-ui",
"homepage:": "https://utopia.os/", "homepage:": "https://utopia.os/",
"main": "dist/index.js", "module": "dist/index.js",
"scripts": { "scripts": {
"build": "rollup -c", "build": "rollup -c",
"start": "rollup -c -w" "start": "rollup -c -w"

View File

@ -4,7 +4,7 @@ import { Item, Tag, Layer as LayerProps } from '../../types'
import MarkerIconFactory from '../../Utils/MarkerIconFactory' import MarkerIconFactory from '../../Utils/MarkerIconFactory'
import { Popup } from './Subcomponents/Popup' import { Popup } from './Subcomponents/Popup'
import { useTags } from './hooks/useTags' import { useTags } from './hooks/useTags'
import { useAddItem, useItems } from './hooks/useItems' import { useAddItem, useItems, useResetItems } from './hooks/useItems'
import { useEffect } from 'react' import { useEffect } from 'react'
import { useAddLayer } from './hooks/useLayers' import { useAddLayer } from './hooks/useLayers'
@ -27,20 +27,27 @@ export const Layer = (props: LayerProps) => {
const items = useItems(); const items = useItems();
const addItem = useAddItem() const addItem = useAddItem()
const addLayer = useAddLayer(); const addLayer = useAddLayer();
const resetItems = useResetItems();
useEffect(() => { useEffect(() => {
console.log("props.data changed");
resetItems(props);
props.data.map(item => { props.data.map(item => {
item.layer = props; item.layer = props;
addItem(item); addItem(item);
}) })
addLayer(props); addLayer(props);
console.table(items)
}, [props.data])
}, [addItem, addLayer, props])
return ( return (
<> <>
{items.filter(item => item.layer?.name === props.name)?.map((place: Item) => { {items.filter(item => item.layer?.name === props.name)?.map((place: Item) => {
console.log(`layer ${props.name} rendering ....`);
const tags = getTags(place); const tags = getTags(place);
let color1 = "#666"; let color1 = "#666";
let color2 = "RGBA(35, 31, 32, 0.2)"; let color2 = "RGBA(35, 31, 32, 0.2)";

View File

@ -1,53 +0,0 @@
import * as React from "react";
import { ComponentStory, ComponentMeta } from "@storybook/react";
import { UtopiaMap } from "./UtopiaMap";
import { Layer } from "./Layer";
import { tags, places, events } from './data'
export default {
title: "Utopia Map",
component: UtopiaMap,
} as ComponentMeta<typeof UtopiaMap>;
const Template: ComponentStory<typeof UtopiaMap> = (args) => (
<UtopiaMap height={args.height} width={args.width} center={args.center} zoom={args.zoom}>
<Layer
name='places'
menuIcon='LocationMarkerIcon'
menuText='add new place'
menuColor='#2E7D32'
markerIcon='circle-solid'
markerShape='circle'
markerDefaultColor='#777'
data={places}
tags={tags}
/>
<Layer
name='events'
menuIcon='CalendarIcon'
menuText='add new event'
menuColor='#f9a825'
markerIcon='calendar-days-solid'
markerShape='square'
markerDefaultColor='#777'
data = {events}
tags={tags}
/>
</UtopiaMap>
);
export const Custom = Template.bind({});
Custom.args = {
};
export const BadSalzschlirf = Template.bind({});
BadSalzschlirf.args = {
center : [50.6238,9.5061],
zoom: 15,
height: "500px"
};

View File

@ -1,11 +1,12 @@
import { useCallback, useReducer, createContext, useContext } from "react"; import { useCallback, useReducer, createContext, useContext } from "react";
import * as React from "react"; import * as React from "react";
import { Item } from "../../../types"; import { Item, Layer } from "../../../types";
type ActionType = type ActionType =
| { type: "ADD"; item: Item } | { type: "ADD"; item: Item }
| { type: "UPDATE"; item: Item } | { type: "UPDATE"; item: Item }
| { type: "REMOVE"; item: Item }; | { type: "REMOVE"; item: Item }
| { type: "RESET"; layer: Layer };
type UseItemManagerResult = ReturnType<typeof useItemsManager>; type UseItemManagerResult = ReturnType<typeof useItemsManager>;
@ -13,7 +14,8 @@ const ItemContext = createContext<UseItemManagerResult>({
items: [], items: [],
addItem: () => {}, addItem: () => {},
updateItem: () => {}, updateItem: () => {},
removeItem: () => {} removeItem: () => {},
resetItems: () => {}
}); });
function useItemsManager (initialItems: Item[]): { function useItemsManager (initialItems: Item[]): {
@ -21,6 +23,7 @@ function useItemsManager (initialItems: Item[]): {
addItem: (item: Item) => void; addItem: (item: Item) => void;
updateItem: (item: Item) => void; updateItem: (item: Item) => void;
removeItem: (item: Item) => void; removeItem: (item: Item) => void;
resetItems: (layer: Layer) => void;
} { } {
const [items, dispatch] = useReducer((state: Item[], action: ActionType) => { const [items, dispatch] = useReducer((state: Item[], action: ActionType) => {
switch (action.type) { switch (action.type) {
@ -42,6 +45,8 @@ function useItemsManager (initialItems: Item[]): {
}); });
case "REMOVE": case "REMOVE":
return state.filter(item => item !== action.item); return state.filter(item => item !== action.item);
case "RESET":
return state.filter(item => item.layer.name !== action.layer.name);
default: default:
throw new Error(); throw new Error();
} }
@ -67,7 +72,15 @@ function useItemsManager (initialItems: Item[]): {
item, item,
}); });
}, []); }, []);
return { items, updateItem, addItem, removeItem };
const resetItems = useCallback((layer: Layer) => {
dispatch({
type: "RESET",
layer
});
}, []);
return { items, updateItem, addItem, removeItem, resetItems };
} }
export const ItemsProvider: React.FunctionComponent<{ export const ItemsProvider: React.FunctionComponent<{
@ -97,3 +110,8 @@ export const useRemoveItem = (): UseItemManagerResult["removeItem"] => {
const { removeItem } = useContext(ItemContext); const { removeItem } = useContext(ItemContext);
return removeItem; return removeItem;
}; };
export const useResetItems = (): UseItemManagerResult["resetItems"] => {
const { resetItems } = useContext(ItemContext);
return resetItems;
};

View File

@ -14,12 +14,12 @@
"noImplicitReturns": true, "noImplicitReturns": true,
"noImplicitThis": true, "noImplicitThis": true,
"strictNullChecks": true, "strictNullChecks": true,
"noUnusedLocals": true, "noUnusedLocals": false,
"noUnusedParameters": true, "noUnusedParameters": true,
}, },
"include": ["src"], "include": ["src"],
"exclude": ["node_modules", "dist", "example", "rollup.config.js"], "exclude": ["node_modules", "dist", "example", "rollup.config.mjss"],
"typeRoots": [ "typeRoots": [
"./types", "./types",
"./node_modules/@types/" "./node_modules/@types/"