Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add event listener trackers to Map and Label #3469

Merged
merged 6 commits into from
Aug 5, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 89 additions & 19 deletions editor.planx.uk/src/@planx/components/MapAndLabel/Public.tsx
Original file line number Diff line number Diff line change
@@ -1,42 +1,112 @@
import { alpha } from "@mui/material/styles";
import Typography from "@mui/material/Typography";
import { Feature } from "geojson";
import { useStore } from "pages/FlowEditor/lib/store";
import React from "react";
import React, { useEffect, useState } from "react";
import { FONT_WEIGHT_SEMI_BOLD } from "theme";
import ErrorWrapper from "ui/shared/ErrorWrapper";

import Card from "../shared/Preview/Card";
import CardHeader from "../shared/Preview/CardHeader";
import { MapContainer } from "../shared/Preview/MapContainer";
import { MapContainer, MapFooter } from "../shared/Preview/MapContainer";
import { PublicProps } from "../ui";
import { MapAndLabel } from "./model";

type Props = PublicProps<MapAndLabel>;

type Boundary = Feature | undefined;

function MapAndLabelComponent(props: Props) {
const teamSettings = useStore.getState().teamSettings;
const [boundary, setBoundary] = useState<Boundary>();
RODO94 marked this conversation as resolved.
Show resolved Hide resolved
const [area, setArea] = useState<number | undefined>(0);
const [objectArray, setObjectArray] = useState<any>([]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I understand the purpose of objectArray here (variable name is quite vague & it's never rendered)? Is boundary sufficient alone?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a way for me to track the event listener dispatching events and collecting info into an array. Most likely negated in a PR or two when multiple items get added to the map and we can use the geoJSON features, but helpful for now if I wanted to test adding a list of items to the Public comp... is it too rough to add in the PR? @jessicamcinchak

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for explanation - happy for it to merge here now better understanding it's work-in-progress 🙂

const [mapValidationError, setMapValidationError] = useState<string>();

let count = 0;

useEffect(() => {
const areaChangeHandler = ({ detail }: { detail: string }) => {
const numberString = detail.split(" ")[0];
const area = Number(numberString);
setArea(area);
};

const geojsonChangeHandler = ({ detail: geojson }: any) => {
if (geojson["EPSG:3857"]?.features) {
count++;

// only a single polygon can be drawn, so get first feature in geojson "FeatureCollection"
setBoundary(geojson["EPSG:3857"].features[0]);
setObjectArray([
...objectArray,
{ number: count, feature: geojson["EPSG:3857"].features[0] },
]);
} else {
// if the user clicks 'reset' to erase the drawing, geojson will be empty object, so set boundary to undefined
setBoundary(undefined);
}
};

const map: any = document.getElementById("draw-boundary-map");

map?.addEventListener("areaChange", areaChangeHandler);
map?.addEventListener("geojsonChange", geojsonChangeHandler);

return function cleanup() {
map?.removeEventListener("areaChange", areaChangeHandler);
map?.removeEventListener("geojsonChange", geojsonChangeHandler);
};
}, [objectArray, boundary]);

useEffect(() => {
if (!boundary && objectArray.length < 1) {
setMapValidationError("Add a boundary to the map");
}
}, [boundary]);

return (
<Card handleSubmit={props.handleSubmit} isValid>
<Card handleSubmit={props.handleSubmit} isValid={!mapValidationError}>
<CardHeader
title={props.title}
description={props.description}
info={props.info}
policyRef={props.policyRef}
howMeasured={props.howMeasured}
/>
<MapContainer environment="standalone">
{/* @ts-ignore */}
<my-map
drawMode
drawPointer="crosshair"
zoom={16}
drawFillColor={alpha(props.drawColor, 0.1)}
drawColor={props.drawColor}
drawPointColor={props.drawColor}
drawType={props.drawType}
clipGeojsonData={
teamSettings?.boundaryBBox &&
JSON.stringify(teamSettings?.boundaryBBox)
}
/>
</MapContainer>
<ErrorWrapper error={mapValidationError} id="draw-boundary-map">
<MapContainer environment="standalone">
{/* @ts-ignore */}
<my-map
id="draw-boundary-map"
drawMode
drawPointer="crosshair"
drawGeojsonData={JSON.stringify(boundary)}
zoom={16}
drawFillColor={alpha(props.drawColor, 0.1)}
drawColor={props.drawColor}
drawPointColor={props.drawColor}
drawType={props.drawType}
clipGeojsonData={
teamSettings?.boundaryBBox &&
JSON.stringify(teamSettings?.boundaryBBox)
}
/>

<MapFooter>
<Typography variant="body1">
The property boundary you have drawn is{" "}
<Typography
component="span"
noWrap
sx={{ fontWeight: FONT_WEIGHT_SEMI_BOLD }}
>
{area?.toLocaleString("en-GB") ?? 0} m²
</Typography>
</Typography>
</MapFooter>
</MapContainer>
</ErrorWrapper>
</Card>
);
}
Expand Down
Loading