Skip to content

Commit

Permalink
feat: add map popups to data extract geometries (#1266)
Browse files Browse the repository at this point in the history
* refactor: always return all properties on map click

* refactor: rename submissionModel --> taskModel

* refactor: configurable primary property key for map AsyncPopup

* feat: add map popup on data extract geom click
  • Loading branch information
spwoodcock authored Feb 23, 2024
1 parent 55bfdf5 commit 1c9a541
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type asyncPopupPropType = {
closePopup?: any;
loading?: boolean;
showOnHover?: string;
primaryKey: string;
};

function hasKey(obj, key) {
Expand All @@ -33,6 +34,7 @@ const AsyncPopup = ({
closePopup = false,
loading = false,
showOnHover = 'click',
primaryKey = 'uid',
}: asyncPopupPropType) => {
const popupRef = useRef<any>(null);
const popupCloserRef = useRef<any>(null);
Expand Down Expand Up @@ -111,8 +113,11 @@ const AsyncPopup = ({
return;
}
const featureProperties = features[0].getProperties();
const { uid } = featureProperties;
if (layerIds.includes(uid) || (hasKey(featureProperties, 'uid') && featureProperties?.uid)) {
const { [primaryKey]: primaryKeyValue } = featureProperties;
if (
layerIds.includes(primaryKeyValue) ||
(hasKey(featureProperties, primaryKey) && featureProperties?.[primaryKey])
) {
setProperties(featureProperties);
setCoordinates(coordinate);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,13 +221,6 @@ const VectorLayer = ({
if (feature) {
// Extract properties
const properties = feature.getProperties();
// Remove geometry key if properties are present
// If no properties are set, the feature uid is included
if (!('uid' in properties)) {
const { geometry, ...restProperties } = properties;
mapOnClick(restProperties, feature);
return;
}
mapOnClick(properties, feature);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Button from '@/components/common/Button';
import AssetModules from '@/shared/AssetModules.js';
import CoreModules from '@/shared/CoreModules.js';
import { TaskCardSkeletonLoader } from '@/components/ProjectSubmissions/ProjectSubmissionsSkeletonLoader';
import { taskInfoType } from '@/models/submission/submissionModel';
import { taskInfoType } from '@/models/task/taskModel';
import { useSearchParams } from 'react-router-dom';

const TaskSubmissions = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { basicGeojsonTemplate } from '@/utilities/mapUtils';
import TaskSubmissionsMapLegend from '@/components/ProjectSubmissions/TaskSubmissionsMapLegend';
import Accordion from '@/components/common/Accordion';
import AsyncPopup from '@/components/MapComponent/OpenLayersComponent/AsyncPopup/AsyncPopup';
import { taskFeaturePropertyType, taskInfoType } from '@/models/submission/submissionModel';
import { taskFeaturePropertyType, taskInfoType } from '@/models/task/taskModel';
import { isValidUrl } from '@/utilfunctions/urlChecker';

export const defaultStyles = {
Expand Down
11 changes: 11 additions & 0 deletions src/frontend/src/models/project/projectModel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export type osmTag = {
string: string;
};

export type dataExtractPropertyType = {
osm_id: number;
tags: Array<{ [key: string]: string }>;
timestamp: Date;
changeset: number;
version: number;
};
File renamed without changes.
42 changes: 35 additions & 7 deletions src/frontend/src/views/ProjectDetailsV2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import getTaskStatusStyle from '@/utilfunctions/getTaskStatusStyle';
import { defaultStyles } from '@/components/MapComponent/OpenLayersComponent/helpers/styleUtils';
import MapLegends from '@/components/MapLegends';
import Accordion from '@/components/common/Accordion';
import AsyncPopup from '@/components/MapComponent/OpenLayersComponent/AsyncPopup/AsyncPopup';
import { Geolocation } from '@capacitor/geolocation';
import { Icon, Style } from 'ol/style';
import { Motion } from '@capacitor/motion';
Expand All @@ -40,6 +41,7 @@ import { CommonActions } from '@/store/slices/CommonSlice';
import Button from '@/components/common/Button';
import ProjectInfo from '@/components/ProjectDetailsV2/ProjectInfo';
import useOutsideClick from '@/hooks/useOutsideClick';
import { dataExtractPropertyType } from '@/models/project/projectModel';
import { isValidUrl } from '@/utilfunctions/urlChecker';

const Home = () => {
Expand All @@ -49,7 +51,6 @@ const Home = () => {
const { windowSize, type } = WindowDimension();
const [divRef, toggle, handleToggle] = useOutsideClick();

const [taskId, setTaskId] = useState();
const [mainView, setView] = useState();
const [featuresLayer, setFeaturesLayer] = useState();
const [toggleGenerateModal, setToggleGenerateModal] = useState(false);
Expand All @@ -65,6 +66,7 @@ const Home = () => {
const defaultTheme = CoreModules.useAppSelector((state) => state.theme.hotTheme);
const state = CoreModules.useAppSelector((state) => state.project);
const projectInfo = CoreModules.useAppSelector((state) => state.home.selectedProject);
const selectedTask = CoreModules.useAppSelector((state) => state.task.selectedTask);
const stateSnackBar = CoreModules.useAppSelector((state) => state.home.snackbar);
const mobileFooterSelection = CoreModules.useAppSelector((state) => state.project.mobileFooterSelection);
const mapTheme = CoreModules.useAppSelector((state) => state.theme.hotTheme);
Expand Down Expand Up @@ -135,8 +137,31 @@ const Home = () => {
dispatch(GetProjectDashboard(`${import.meta.env.VITE_API_URL}/projects/project_dashboard/${decodedId}`));
}, []);

// TasksLayer(map, mainView, featuresLayer);
const projectClickOnMap = (properties, feature) => {
const dataExtractDataPopup = (properties: dataExtractPropertyType) => {
return (
<div className="fmtm-h-fit">
<h2 className="fmtm-border-b-[2px] fmtm-border-primaryRed fmtm-w-fit fmtm-pr-1">
OSM ID: #{properties?.osm_id}
</h2>
<div className="fmtm-flex fmtm-flex-col fmtm-gap-1 fmtm-mt-1">
<p>
Tags: <span className="fmtm-text-primaryRed">{properties?.tags}</span>
</p>
<p>
Timestamp: <span className="fmtm-text-primaryRed">{properties?.timestamp}</span>
</p>
<p>
Changeset: <span className="fmtm-text-primaryRed">{properties?.changeset}</span>
</p>
<p>
Version: <span className="fmtm-text-primaryRed">{properties?.version}</span>
</p>
</div>
</div>
);
};

const projectClickOnMapTask = (properties, feature) => {
setFeaturesLayer(feature, 'feature');
let extent = properties.geometry.getExtent();

Expand All @@ -147,7 +172,9 @@ const Home = () => {
block: 'center',
behavior: 'smooth',
});
setTaskId(properties.uid);

dispatch(CoreModules.TaskActions.SetSelectedTask(properties.uid));

dispatch(ProjectActions.ToggleTaskModalStatus(true));
if (windowSize.width < 768) {
map.getView().fit(extent, {
Expand Down Expand Up @@ -382,7 +409,7 @@ const Home = () => {
duration: 2000,
}}
layerProperties={{ name: 'project-area' }}
mapOnClick={projectClickOnMap}
mapOnClick={projectClickOnMapTask}
zoomToLayer
zIndex={5}
getTaskStatusStyle={(feature) => getTaskStatusStyle(feature, mapTheme)}
Expand All @@ -403,6 +430,7 @@ const Home = () => {
zIndex={5}
/>
)}
<AsyncPopup map={map} popupUI={dataExtractDataPopup} primaryKey={'osm_id'} />
{geolocationStatus && currentCoordinate?.latitude && currentCoordinate?.longitude && (
<VectorLayer
map={map}
Expand Down Expand Up @@ -485,11 +513,11 @@ const Home = () => {
</div>
{featuresLayer != undefined && (
<TaskSectionPopup
taskId={taskId}
taskId={selectedTask}
feature={featuresLayer}
body={
<div>
<DialogTaskActions map={map} view={mainView} feature={featuresLayer} taskId={taskId} />
<DialogTaskActions map={map} view={mainView} feature={featuresLayer} taskId={selectedTask} />
</div>
}
/>
Expand Down

0 comments on commit 1c9a541

Please sign in to comment.