From f99327e5569dd49fa5cf764991730bc2b4391d76 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mirko=20M=C3=A4licke?=
Date: Sun, 9 Apr 2023 20:14:33 +0200
Subject: [PATCH 01/13] offline can now return selections
---
src/context/offline.tsx | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/src/context/offline.tsx b/src/context/offline.tsx
index 67d57ef..11cd9da 100644
--- a/src/context/offline.tsx
+++ b/src/context/offline.tsx
@@ -41,8 +41,8 @@ interface OfflineState {
remoteChecksums: Checksums | null;
getImageData: (name: string) => Promise
getBaselayer: (name: string) => Promise
- createSelection: (treeIds: number[], title?: string) => Promise
- updateSelection: (selection: InventorySelection) => Promise
+ createSelection: (treeIds: number[], title?: string) => Promise
+ updateSelection: (selection: InventorySelection) => Promise
dropSelection: (selectionId: string) => Promise
}
@@ -289,7 +289,7 @@ export const OfflineProvider: React.FC = ({ children })
}
- const createSelection = async (treeIds: number[], title?: string): Promise => {
+ const createSelection = async (treeIds: number[], title?: string): Promise => {
// create a random 16 character string as id
const id = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)
@@ -304,7 +304,7 @@ export const OfflineProvider: React.FC = ({ children })
return updateSelection(selection)
}
- const updateSelection = async (selection: InventorySelection): Promise => {
+ const updateSelection = async (selection: InventorySelection): Promise => {
// create the selections folder if it does not exist
if (!fileInfos?.map(i => i.name).includes('selections')) {
await Filesystem.mkdir({path: '/selections', directory: Directory.Data})
@@ -323,16 +323,16 @@ export const OfflineProvider: React.FC = ({ children })
// create the new array of selections
let newSelections: InventorySelection[] = []
if (selections) {
- newSelections = cloneDeep([...selections, selection])
+ newSelections = cloneDeep([...selections, {...selection}])
} else {
- newSelections = [selection]
+ newSelections = [{...selection}]
}
// update the selections state variable
setSelections(newSelections)
// return the local path
- return path
+ return selection
})
}
From 7c0de16d19f3a85486fec9c1032caa8e3dfdefa6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mirko=20M=C3=A4licke?=
Date: Sun, 9 Apr 2023 20:18:29 +0200
Subject: [PATCH 02/13] create the add function
---
src/context/selection.tsx | 86 +++++++++++++++++++++++++++------------
1 file changed, 60 insertions(+), 26 deletions(-)
diff --git a/src/context/selection.tsx b/src/context/selection.tsx
index 1d72ffa..de221fd 100644
--- a/src/context/selection.tsx
+++ b/src/context/selection.tsx
@@ -1,7 +1,6 @@
import bbox from "@turf/bbox";
import cloneDeep from "lodash.clonedeep";
import { createContext, useContext, useEffect, useState } from "react";
-import { useData } from "./data";
import { InventoryData } from "./data.model";
import { InventorySelection } from "./inventory-selection.model";
import { useOffline } from "./offline";
@@ -15,12 +14,14 @@ interface SelectionState {
selections: InventorySelection[];
activeSelection: ActiveSelection | null;
setActiveSelection: (selectionId: string | null) => void
+ addToActiveSelection: (treeId: number) => void
}
const initialState: SelectionState = {
selections: [],
activeSelection: null,
- setActiveSelection: (selectionId: string | null) => {}
+ setActiveSelection: (selectionId: string | null) => {},
+ addToActiveSelection: (treeId: number) => {}
}
// add the context
@@ -30,11 +31,13 @@ const SelectionContext = createContext(initialState);
export const SelectionProvider: React.FC = ({ children }) => {
// create the state
const [selections, setSelections] = useState(initialState.selections)
+ const [activeSelectionId, setActiveSelectionId] = useState(null)
const [activeSelection, setActiveSelectionState] = useState(initialState.activeSelection)
// get a reference to all inventory data
- const { filteredInventory } = useData()
- const {selections: offlineSelections} = useOffline()
+ const { inventory } = useOffline()
+
+ const {selections: offlineSelections, createSelection} = useOffline()
// subscribe to changes in offline selections
useEffect(() => {
@@ -45,40 +48,71 @@ export const SelectionProvider: React.FC = ({ children
}
}, [offlineSelections])
- // define the context functions
+ // setActiveSelection handler
const setActiveSelection = (selectionId: string | null) => {
- if (selectionId === null || !filteredInventory) {
- setActiveSelectionState(null)
+ if (!selectionId) {
+ setActiveSelectionId(null)
+ } else {
+ setActiveSelectionId(selectionId)
+ }
+ }
+
+ const addToActiveSelection = async (treeId: number) => {
+ // get the selection representation from the current data or create a new one
+ let selection: InventorySelection;
+ if (!activeSelection) {
+ selection = await createSelection([], `New Selection ${selections.length}`)
} else {
- const selection = selections.find(s => s.id === selectionId)
+ selection = activeSelection.selection
+ }
+
+ // add the tree to selection
+ selection.treeIds.push(treeId)
+
+ // build the geojson
+ const newActiveSelection = getSelectionWithGeoJSON(selection)
+ setActiveSelectionState(newActiveSelection)
+ }
+
+ const getSelectionWithGeoJSON = (selection: InventorySelection): ActiveSelection => {
+ // filter the full inventory for any selected tree
+ const features = inventory?.features.filter(f => selection.treeIds.includes(Number(f.properties.treeid))) || []
+
+ // create the geojson
+ const data = {
+ type: 'FeatureCollection',
+ features: cloneDeep(features),
+ } as InventoryData
+
+ // add the bounding box
+ data.bbox = bbox(data)
+
+ return {selection: cloneDeep(selection), geoJSON: cloneDeep(data)}
+ }
+
+ // use effect to update the current active selection, when the activeSelectionId or the filteredInventory changes
+ useEffect(() => {
+ if (!inventory) return
+ if (activeSelectionId) {
+ const selection = selections.find(s => s.id === activeSelectionId)
if (selection) {
- // extract the features from the inventory data that match the selection
- const features = filteredInventory.features.filter(f => selection.treeIds.includes(Number(f.properties.treeid)))
-
- // create the geojson
- const data = {
- type: 'FeatureCollection',
- features: cloneDeep(features),
- } as InventoryData
-
- // add the bounding box
- data.bbox = bbox(data)
-
- setActiveSelectionState({
- selection: cloneDeep(selection),
- geoJSON: cloneDeep(data)
- })
+ const newActiveSelection = getSelectionWithGeoJSON(selection)
+ setActiveSelectionState(newActiveSelection)
} else {
setActiveSelectionState(null)
}
+ } else {
+ setActiveSelectionState(null)
}
- }
+ }, [activeSelectionId, inventory])
+
// create the context value
const value = {
selections,
activeSelection,
- setActiveSelection
+ setActiveSelection,
+ addToActiveSelection
}
// return the provider
From 053483d732272775c93c0e4f3bbb4a619b61a69b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mirko=20M=C3=A4licke?=
Date: Mon, 10 Apr 2023 07:30:02 +0200
Subject: [PATCH 03/13] fix adding behavior
---
src/context/offline.tsx | 2 +-
src/context/selection.tsx | 33 +++++++++++++++++++++------------
2 files changed, 22 insertions(+), 13 deletions(-)
diff --git a/src/context/offline.tsx b/src/context/offline.tsx
index 11cd9da..96fa273 100644
--- a/src/context/offline.tsx
+++ b/src/context/offline.tsx
@@ -323,7 +323,7 @@ export const OfflineProvider: React.FC = ({ children })
// create the new array of selections
let newSelections: InventorySelection[] = []
if (selections) {
- newSelections = cloneDeep([...selections, {...selection}])
+ newSelections = cloneDeep([...selections.filter(s => s.id !== selection.id), {...selection}])
} else {
newSelections = [{...selection}]
}
diff --git a/src/context/selection.tsx b/src/context/selection.tsx
index de221fd..5624d33 100644
--- a/src/context/selection.tsx
+++ b/src/context/selection.tsx
@@ -1,6 +1,6 @@
import bbox from "@turf/bbox";
import cloneDeep from "lodash.clonedeep";
-import { createContext, useContext, useEffect, useState } from "react";
+import { createContext, useCallback, useContext, useEffect, useState } from "react";
import { InventoryData } from "./data.model";
import { InventorySelection } from "./inventory-selection.model";
import { useOffline } from "./offline";
@@ -37,7 +37,7 @@ export const SelectionProvider: React.FC = ({ children
// get a reference to all inventory data
const { inventory } = useOffline()
- const {selections: offlineSelections, createSelection} = useOffline()
+ const {selections: offlineSelections, createSelection, updateSelection} = useOffline()
// subscribe to changes in offline selections
useEffect(() => {
@@ -58,23 +58,32 @@ export const SelectionProvider: React.FC = ({ children
}
const addToActiveSelection = async (treeId: number) => {
+ // skip if the treeId is already selection
+ if (activeSelection && activeSelection.selection.treeIds.includes(treeId)) {
+ return
+ }
// get the selection representation from the current data or create a new one
let selection: InventorySelection;
if (!activeSelection) {
- selection = await createSelection([], `New Selection ${selections.length}`)
+ // create a new selection
+ selection = await createSelection([treeId], `New Selection ${selections.length}`)
} else {
- selection = activeSelection.selection
+ // update
+ activeSelection.selection.treeIds.push(treeId)
+ selection = await updateSelection(activeSelection.selection)
}
- // add the tree to selection
- selection.treeIds.push(treeId)
-
// build the geojson
- const newActiveSelection = getSelectionWithGeoJSON(selection)
- setActiveSelectionState(newActiveSelection)
+ // const newActiveSelection = getSelectionWithGeoJSON(selection)
+ // setActiveSelectionState(newActiveSelection)
+
+ // set the selection active if it was not
+ // if (activeSelectionId !== selection.id) {
+ setActiveSelectionId(selection.id)
+ // }
}
- const getSelectionWithGeoJSON = (selection: InventorySelection): ActiveSelection => {
+ const getSelectionWithGeoJSON = useCallback((selection: InventorySelection): ActiveSelection => {
// filter the full inventory for any selected tree
const features = inventory?.features.filter(f => selection.treeIds.includes(Number(f.properties.treeid))) || []
@@ -88,7 +97,7 @@ export const SelectionProvider: React.FC = ({ children
data.bbox = bbox(data)
return {selection: cloneDeep(selection), geoJSON: cloneDeep(data)}
- }
+ }, [selections])
// use effect to update the current active selection, when the activeSelectionId or the filteredInventory changes
useEffect(() => {
@@ -104,7 +113,7 @@ export const SelectionProvider: React.FC = ({ children
} else {
setActiveSelectionState(null)
}
- }, [activeSelectionId, inventory])
+ }, [activeSelectionId, inventory, selections])
// create the context value
From 976d7eb4b046277ef2b2c5718ad9d7bde0f4c879 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mirko=20M=C3=A4licke?=
Date: Mon, 10 Apr 2023 07:30:34 +0200
Subject: [PATCH 04/13] add a bookmark just somewhere
---
src/components/TreeDetails.tsx | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/src/components/TreeDetails.tsx b/src/components/TreeDetails.tsx
index b247470..dc9eba2 100644
--- a/src/components/TreeDetails.tsx
+++ b/src/components/TreeDetails.tsx
@@ -1,4 +1,6 @@
import {
+ IonButton,
+ IonButtons,
IonCard,
IonCardContent,
IonCardHeader,
@@ -6,6 +8,7 @@ import {
IonCardTitle,
IonCol,
IonGrid,
+ IonIcon,
IonItem,
IonLabel,
IonNote,
@@ -13,12 +16,14 @@ import {
IonSegment,
IonSegmentButton,
} from "@ionic/react";
+import { bookmarkOutline } from "ionicons/icons";
import { Data, Layout } from "plotly.js";
import { useEffect, useState } from "react";
import Plot from "react-plotly.js";
import { useData } from "../context/data";
import { InventoryFeature } from "../context/data.model";
import { useOffline } from "../context/offline";
+import { useSelection } from "../context/selection";
import * as plot from "../util/plot";
import "./TreeDetails.css";
@@ -61,6 +66,9 @@ const TreeDetails: React.FC = ({ treeID }) => {
// load all inventory data
const { filteredInventory, allInventory } = useData();
+ // get selection functions
+ const { addToActiveSelection } = useSelection()
+
// compnent state to store this feature
const [feature, setFeature] = useState();
const [currentImg, setCurrentImg] = useState();
@@ -137,6 +145,14 @@ const TreeDetails: React.FC = ({ treeID }) => {
return (
<>
{/* Overview */}
+
+
+ addToActiveSelection(treeID)}>
+
+
+
+
+
From 78223f96f120f2bec36a36431134889c67f8231a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mirko=20M=C3=A4licke?=
Date: Sun, 23 Apr 2023 10:42:39 +0200
Subject: [PATCH 05/13] wire up bookmark button
---
src/components/InventoryList.tsx | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/src/components/InventoryList.tsx b/src/components/InventoryList.tsx
index 0e590e5..26d9462 100644
--- a/src/components/InventoryList.tsx
+++ b/src/components/InventoryList.tsx
@@ -10,6 +10,7 @@ import {
} from "@ionic/react";
import {
bookmarkOutline,
+ bookmark,
navigate,
swapVerticalOutline,
arrowDownOutline,
@@ -24,6 +25,7 @@ import { useSettings } from "../context/settings";
import { InventoryFeature } from "../context/data.model";
import "./InventoryList.css";
+import { useSelection } from "../context/selection";
const InventoryList: React.FC = () => {
// load the filtered inventory list
@@ -35,6 +37,9 @@ const InventoryList: React.FC = () => {
setSortDirection
} = useData();
+ // get selection functions
+ const { addToActiveSelection, activeSelection } = useSelection()
+
// get a history context
const history = useHistory();
@@ -76,10 +81,16 @@ const InventoryList: React.FC = () => {
};
const addToBookmarksHandler = (
- event: React.MouseEvent
+ event: React.MouseEvent,
+ treeId: number
) => {
+ // stop event propagation
event.stopPropagation();
- console.log("add to bookmarks");
+
+ // add to active selection
+ addToActiveSelection(treeId)
+
+ //console.log("add to bookmarks");
};
return (
@@ -145,8 +156,8 @@ const InventoryList: React.FC = () => {
{distString(f)}
- addToBookmarksHandler(e)}>
-
+ addToBookmarksHandler(e, f.properties.treeid)} disabled={activeSelection?.selection.treeIds.includes(f.properties.treeid)} >
+
);
From 3c3a36f457cff86dc58426919632a891a5000815 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mirko=20M=C3=A4licke?=
Date: Sun, 23 Apr 2023 11:04:21 +0200
Subject: [PATCH 06/13] remove function for current selection
---
src/context/selection.tsx | 27 +++++++++++++++++++++++----
1 file changed, 23 insertions(+), 4 deletions(-)
diff --git a/src/context/selection.tsx b/src/context/selection.tsx
index 5624d33..ac8bf11 100644
--- a/src/context/selection.tsx
+++ b/src/context/selection.tsx
@@ -14,14 +14,16 @@ interface SelectionState {
selections: InventorySelection[];
activeSelection: ActiveSelection | null;
setActiveSelection: (selectionId: string | null) => void
- addToActiveSelection: (treeId: number) => void
+ addToActiveSelection: (treeId: number) => Promise
+ removeFromActiveSelection: (treeID: number) => Promise
}
const initialState: SelectionState = {
selections: [],
activeSelection: null,
setActiveSelection: (selectionId: string | null) => {},
- addToActiveSelection: (treeId: number) => {}
+ addToActiveSelection: (treeId: number) => Promise.reject('Not implemented.'),
+ removeFromActiveSelection: (treeID: number) => Promise.reject('Not implemented.'),
}
// add the context
@@ -57,7 +59,7 @@ export const SelectionProvider: React.FC = ({ children
}
}
- const addToActiveSelection = async (treeId: number) => {
+ const addToActiveSelection = async (treeId: number): Promise => {
// skip if the treeId is already selection
if (activeSelection && activeSelection.selection.treeIds.includes(treeId)) {
return
@@ -83,6 +85,22 @@ export const SelectionProvider: React.FC = ({ children
// }
}
+ const removeFromActiveSelection = async (treeId: number): Promise => {
+ // skip if the treeId is not in selection
+ if (activeSelection && !activeSelection.selection.treeIds.includes(treeId)) {
+ return Promise.reject(`Tree ID=${treeId} is not in the active selection.`)
+ }
+
+ // remove the treeId
+ const newTreeIds = activeSelection?.selection.treeIds.filter(id => id !== treeId) || []
+
+ // update the selection
+ const selection = await updateSelection({...activeSelection!.selection, treeIds: newTreeIds})
+
+ // set the selection as the new active selection
+ setActiveSelectionId(selection.id)
+ }
+
const getSelectionWithGeoJSON = useCallback((selection: InventorySelection): ActiveSelection => {
// filter the full inventory for any selected tree
const features = inventory?.features.filter(f => selection.treeIds.includes(Number(f.properties.treeid))) || []
@@ -121,7 +139,8 @@ export const SelectionProvider: React.FC = ({ children
selections,
activeSelection,
setActiveSelection,
- addToActiveSelection
+ addToActiveSelection,
+ removeFromActiveSelection
}
// return the provider
From b27bfa6f56a405b3f618db274209c3e131543aee Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mirko=20M=C3=A4licke?=
Date: Sun, 23 Apr 2023 11:04:39 +0200
Subject: [PATCH 07/13] wire-up remove functions
---
src/components/InventoryList.tsx | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/src/components/InventoryList.tsx b/src/components/InventoryList.tsx
index 26d9462..fc6599c 100644
--- a/src/components/InventoryList.tsx
+++ b/src/components/InventoryList.tsx
@@ -10,7 +10,7 @@ import {
} from "@ionic/react";
import {
bookmarkOutline,
- bookmark,
+ banOutline,
navigate,
swapVerticalOutline,
arrowDownOutline,
@@ -38,7 +38,7 @@ const InventoryList: React.FC = () => {
} = useData();
// get selection functions
- const { addToActiveSelection, activeSelection } = useSelection()
+ const { addToActiveSelection, removeFromActiveSelection, activeSelection } = useSelection()
// get a history context
const history = useHistory();
@@ -87,8 +87,12 @@ const InventoryList: React.FC = () => {
// stop event propagation
event.stopPropagation();
- // add to active selection
- addToActiveSelection(treeId)
+ // check if this treeId is already in the selection
+ if (activeSelection?.selection.treeIds.includes(treeId)) {
+ removeFromActiveSelection(treeId)
+ } else {
+ addToActiveSelection(treeId)
+ }
//console.log("add to bookmarks");
};
@@ -156,8 +160,11 @@ const InventoryList: React.FC = () => {
{distString(f)}
- addToBookmarksHandler(e, f.properties.treeid)} disabled={activeSelection?.selection.treeIds.includes(f.properties.treeid)} >
-
+ addToBookmarksHandler(e, f.properties.treeid)}
+ >
+
);
From 29fb8e04995feaecc5356a7efdf4c9f3b55221fe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mirko=20M=C3=A4licke?=
Date: Sun, 23 Apr 2023 13:17:49 +0200
Subject: [PATCH 08/13] fix string type treeIds
---
src/context/selection.tsx | 42 ++++++++++++++++++++++-----------------
1 file changed, 24 insertions(+), 18 deletions(-)
diff --git a/src/context/selection.tsx b/src/context/selection.tsx
index ac8bf11..02fe23d 100644
--- a/src/context/selection.tsx
+++ b/src/context/selection.tsx
@@ -14,16 +14,16 @@ interface SelectionState {
selections: InventorySelection[];
activeSelection: ActiveSelection | null;
setActiveSelection: (selectionId: string | null) => void
- addToActiveSelection: (treeId: number) => Promise
- removeFromActiveSelection: (treeID: number) => Promise
+ addToActiveSelection: (treeId: number | string) => Promise
+ removeFromActiveSelection: (treeID: number | string) => Promise
}
const initialState: SelectionState = {
selections: [],
activeSelection: null,
setActiveSelection: (selectionId: string | null) => {},
- addToActiveSelection: (treeId: number) => Promise.reject('Not implemented.'),
- removeFromActiveSelection: (treeID: number) => Promise.reject('Not implemented.'),
+ addToActiveSelection: (treeId: number | string) => Promise.reject('Not implemented.'),
+ removeFromActiveSelection: (treeID: number | string) => Promise.reject('Not implemented.'),
}
// add the context
@@ -59,35 +59,35 @@ export const SelectionProvider: React.FC = ({ children
}
}
- const addToActiveSelection = async (treeId: number): Promise => {
+ const addToActiveSelection = async (treeId: number | string): Promise => {
// skip if the treeId is already selection
- if (activeSelection && activeSelection.selection.treeIds.includes(treeId)) {
- return
+ if (activeSelection && activeSelection.selection.treeIds.includes(Number(treeId))) {
+ return Promise.reject(`The tree ID=${treeId} is already part of the current selection`)
}
// get the selection representation from the current data or create a new one
let selection: InventorySelection;
if (!activeSelection) {
// create a new selection
- selection = await createSelection([treeId], `New Selection ${selections.length}`)
+ selection = await createSelection([Number(treeId)], `New Selection ${selections.length}`)
} else {
// update
- activeSelection.selection.treeIds.push(treeId)
+ activeSelection.selection.treeIds.push(Number(treeId))
selection = await updateSelection(activeSelection.selection)
}
// build the geojson
- // const newActiveSelection = getSelectionWithGeoJSON(selection)
- // setActiveSelectionState(newActiveSelection)
+ const newActiveSelection = getSelectionWithGeoJSON(selection)
+ setActiveSelectionState(newActiveSelection)
// set the selection active if it was not
- // if (activeSelectionId !== selection.id) {
+ if (activeSelectionId !== selection.id) {
setActiveSelectionId(selection.id)
- // }
+ }
}
- const removeFromActiveSelection = async (treeId: number): Promise => {
+ const removeFromActiveSelection = async (treeId: number | string): Promise => {
// skip if the treeId is not in selection
- if (activeSelection && !activeSelection.selection.treeIds.includes(treeId)) {
+ if (activeSelection && !activeSelection.selection.treeIds.includes(Number(treeId))) {
return Promise.reject(`Tree ID=${treeId} is not in the active selection.`)
}
@@ -97,8 +97,14 @@ export const SelectionProvider: React.FC = ({ children
// update the selection
const selection = await updateSelection({...activeSelection!.selection, treeIds: newTreeIds})
+ // build the geoJSON
+ const newActiveSelection = getSelectionWithGeoJSON(selection)
+ setActiveSelectionState(newActiveSelection)
+
// set the selection as the new active selection
- setActiveSelectionId(selection.id)
+ if (activeSelectionId !== selection.id) {
+ setActiveSelectionId(selection.id)
+ }
}
const getSelectionWithGeoJSON = useCallback((selection: InventorySelection): ActiveSelection => {
@@ -115,7 +121,7 @@ export const SelectionProvider: React.FC = ({ children
data.bbox = bbox(data)
return {selection: cloneDeep(selection), geoJSON: cloneDeep(data)}
- }, [selections])
+ }, [inventory])
// use effect to update the current active selection, when the activeSelectionId or the filteredInventory changes
useEffect(() => {
@@ -131,7 +137,7 @@ export const SelectionProvider: React.FC = ({ children
} else {
setActiveSelectionState(null)
}
- }, [activeSelectionId, inventory, selections])
+ }, [activeSelectionId, inventory, selections, getSelectionWithGeoJSON])
// create the context value
From 6e01a33bc91684172db245138bd7786e734a69b9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mirko=20M=C3=A4licke?=
Date: Sun, 23 Apr 2023 13:17:58 +0200
Subject: [PATCH 09/13] cleanup
---
src/components/map-components/InventorySource.tsx | 10 ----------
1 file changed, 10 deletions(-)
diff --git a/src/components/map-components/InventorySource.tsx b/src/components/map-components/InventorySource.tsx
index 235a2eb..bb22419 100644
--- a/src/components/map-components/InventorySource.tsx
+++ b/src/components/map-components/InventorySource.tsx
@@ -6,18 +6,8 @@ import { Source, Layer, useMap } from "react-map-gl";
import { useData } from "../../context/data";
import { InventoryData, InventoryFeature } from "../../context/data.model";
import { useLayers } from "../../context/layers";
-import {
- IonCard,
- IonCardContent,
- IonCardHeader,
- IonCardTitle,
- IonItem,
- IonLabel,
- IonPopover,
-} from "@ionic/react";
import { useHistory } from "react-router";
import { useOffline } from "../../context/offline";
-import bbox from "@turf/bbox";
const InventoryLayer: React.FC = () => {
const {
From 809f7cce047b46fe5e61c45102c2d206d055a2fa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mirko=20M=C3=A4licke?=
Date: Sun, 23 Apr 2023 13:18:09 +0200
Subject: [PATCH 10/13] add processing state
---
src/components/InventoryList.tsx | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/src/components/InventoryList.tsx b/src/components/InventoryList.tsx
index fc6599c..26e31d3 100644
--- a/src/components/InventoryList.tsx
+++ b/src/components/InventoryList.tsx
@@ -6,6 +6,7 @@ import {
IonLabel,
IonList,
IonListHeader,
+ IonSpinner,
IonThumbnail,
} from "@ionic/react";
import {
@@ -26,8 +27,12 @@ import { InventoryFeature } from "../context/data.model";
import "./InventoryList.css";
import { useSelection } from "../context/selection";
+import { useState } from "react";
const InventoryList: React.FC = () => {
+ // add a state for processing selections
+ const [selectionProcessing, setSelectionProcessing] = useState(false)
+
// load the filtered inventory list
const {
filteredInventory,
@@ -84,14 +89,17 @@ const InventoryList: React.FC = () => {
event: React.MouseEvent,
treeId: number
) => {
+ // set selection processing
+ setSelectionProcessing(true)
+
// stop event propagation
event.stopPropagation();
// check if this treeId is already in the selection
if (activeSelection?.selection.treeIds.includes(treeId)) {
- removeFromActiveSelection(treeId)
+ removeFromActiveSelection(treeId).finally(() => setSelectionProcessing(false))
} else {
- addToActiveSelection(treeId)
+ addToActiveSelection(treeId).finally(() => setSelectionProcessing(false))
}
//console.log("add to bookmarks");
@@ -162,9 +170,11 @@ const InventoryList: React.FC = () => {
addToBookmarksHandler(e, f.properties.treeid)}
+ onClick={e => addToBookmarksHandler(e, Number(f.properties.treeid))}
>
-
+ { selectionProcessing ? : (
+
+ )}
);
From 09afce8c12ea2c6d3935defcff238cc3f5833558 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mirko=20M=C3=A4licke?=
Date: Sun, 23 Apr 2023 13:18:18 +0200
Subject: [PATCH 11/13] add a selection source
---
.../map-components/SelectionSource.tsx | 47 +++++++++++++++++++
1 file changed, 47 insertions(+)
create mode 100644 src/components/map-components/SelectionSource.tsx
diff --git a/src/components/map-components/SelectionSource.tsx b/src/components/map-components/SelectionSource.tsx
new file mode 100644
index 0000000..5f8c347
--- /dev/null
+++ b/src/components/map-components/SelectionSource.tsx
@@ -0,0 +1,47 @@
+import cloneDeep from "lodash.clonedeep"
+import { useEffect, useState } from "react"
+import { Layer, Source } from "react-map-gl"
+import { InventoryData } from "../../context/data.model"
+import { useSelection } from "../../context/selection"
+
+const SelectionSource: React.FC = () => {
+ // define a component state for the selection GeoJSON
+ const [src, setSrc] = useState()
+
+ // subscribe to the current active selection
+ const { activeSelection } = useSelection()
+
+ // update component state when activeSelection changes
+ useEffect(() => {
+ if (activeSelection) {
+ console.log(activeSelection)
+ setSrc(cloneDeep(activeSelection.geoJSON))
+ } else {
+ setSrc(undefined)
+ }
+ }, [activeSelection])
+
+ // if there is no source, return null
+ console.log(src)
+ if (!src) {
+ return (
+ null
+ )
+ } else {
+ return (
+
+
+
+ )
+ }
+}
+
+export default SelectionSource
\ No newline at end of file
From cc520cbca8de15771a6a6733f8cb7a6deba53c15 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mirko=20M=C3=A4licke?=
Date: Sun, 23 Apr 2023 13:18:25 +0200
Subject: [PATCH 12/13] enabled selection source
---
src/components/map-components/MainMapMaplibre.tsx | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/components/map-components/MainMapMaplibre.tsx b/src/components/map-components/MainMapMaplibre.tsx
index 3b82c2a..7154127 100644
--- a/src/components/map-components/MainMapMaplibre.tsx
+++ b/src/components/map-components/MainMapMaplibre.tsx
@@ -8,6 +8,7 @@ import InventorySource from "./InventorySource";
import BaseLayerSource from "./BaseLayerSource";
import UserLocationSource from "./UserLocationSource";
import LayerInteraction from "./LayerInteraction";
+import SelectionSource from "./SelectionSource";
const MainMap: React.FC = () => {
// onload callback handler
@@ -75,6 +76,7 @@ const MainMap: React.FC = () => {
>
+
From dae0730fcefbc85ce304d3deca536a40d0a8c2b3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mirko=20M=C3=A4licke?=
Date: Sun, 23 Apr 2023 13:19:01 +0200
Subject: [PATCH 13/13] remove old console.log
---
src/components/map-components/SelectionSource.tsx | 2 --
1 file changed, 2 deletions(-)
diff --git a/src/components/map-components/SelectionSource.tsx b/src/components/map-components/SelectionSource.tsx
index 5f8c347..2e28cf1 100644
--- a/src/components/map-components/SelectionSource.tsx
+++ b/src/components/map-components/SelectionSource.tsx
@@ -14,7 +14,6 @@ const SelectionSource: React.FC = () => {
// update component state when activeSelection changes
useEffect(() => {
if (activeSelection) {
- console.log(activeSelection)
setSrc(cloneDeep(activeSelection.geoJSON))
} else {
setSrc(undefined)
@@ -22,7 +21,6 @@ const SelectionSource: React.FC = () => {
}, [activeSelection])
// if there is no source, return null
- console.log(src)
if (!src) {
return (
null