Skip to content

Commit

Permalink
restore basic enterCoordsWIndow functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
JustinElms committed Jan 15, 2025
1 parent b51cd02 commit a001b99
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 148 deletions.
203 changes: 69 additions & 134 deletions oceannavigator/frontend/src/components/EnterCoordsWindow.jsx
Original file line number Diff line number Diff line change
@@ -1,52 +1,39 @@
import React, { useState, useRef } from "react";
import Papa from "papaparse";

import { Button, ToggleButton } from "react-bootstrap";
import { Button } from "react-bootstrap";
import Table from "react-bootstrap/Table";
import { X } from "react-bootstrap-icons";

import { withTranslation } from "react-i18next";

function EnterCoordsWindow(props) {
const [enteredLat, setEnteredLat] = useState("");
const [enteredLon, setEnteredLon] = useState("");
function FeatureCard(props) {
const [timer, setTimer] = useState(null);
const fileForm = useRef(null);
const fileInput = useRef(null);

const radios = [
{ name: __("Point"), value: "point" },
{ name: __("Line"), value: "line" },
{ name: __("Area"), value: "area" },
];

const handleRadio = (e) => {
let type = e.currentTarget.value;
props.action("vectorType", type);
};

const submitHandler = (e) => {
e.preventDefault();
if (enteredLat & enteredLon) {
props.action("addPoints", [[enteredLat, enteredLon]]);
setEnteredLat("");
setEnteredLon("");
const updateCoordinate = (id, row, col, value) => {
if (!isNaN(value)) {
props.action("updateFeatureCoordinate", id, [row, col], value);
}
};

const latChangeHandler = (e) => {
setEnteredLat(parseFloat(e.target.value));
const updateType = (e) => {
props.action("updateFeatureType", props.feature.id, e.target.value);
};

const lonChangeHandler = (e) => {
setEnteredLon(parseFloat(e.target.value));
const removeFeature = () => {
props.action("removeFeature", props.feature.id);
};

const updateLat = (e) => {
clearTimeout(timer);
setTimer(
setTimeout(
updateCoordinate(parseInt(e.target.id), 0, parseFloat(e.target.value)),
updateCoordinate(
props.feature.id,
parseInt(e.target.id),
0,
parseFloat(e.target.value)
),
1000
)
);
Expand All @@ -56,32 +43,22 @@ function EnterCoordsWindow(props) {
clearTimeout(timer);
setTimer(
setTimeout(
updateCoordinate(parseInt(e.target.id), 1, parseFloat(e.target.value)),
updateCoordinate(
props.feature.id,
parseInt(e.target.id),
1,
parseFloat(e.target.value)
),
1000
)
);
};

const updateCoordinate = (row, col, value) => {
if (!isNaN(value)) {
props.action("updatePoint", row, col, value)
}
}

const handleClear = () => {
props.action("clearPoints");
};

const handleUpload = () => {
fileInput.current.click();
const addRow = () => {
updateCoordinate(props.feature.id, props.feature.coords.length, 0, 0);
};

const handlePlot = () => {
props.action("selectPoints");
props.updateUI({ modalType: props.vectorType, showModal: true });
};

const tableEntries = props.vectorCoordinates.map((coord, index) => {
const tableEntries = props.feature.coords.map((coord, index) => {
return (
<tr key={`row_${index}`}>
<td>
Expand All @@ -107,7 +84,9 @@ function EnterCoordsWindow(props) {
<td>
<button
className="remove-button"
onClick={() => props.action("removePoint", index)}
onClick={() =>
props.action("removeFeatureCoord", props.feature.id, index)
}
>
<X />
</button>
Expand All @@ -116,6 +95,47 @@ function EnterCoordsWindow(props) {
);
});

return (
<div>
<div>
<select value={props.feature.type} onChange={updateType}>
<option value="point">Point</option>
<option value="line">Line</option>
<option value="area">Area</option>
</select>
<Button disabled={props.feature.type === "point"} onClick={addRow}>
+
</Button>
<Button onClick={removeFeature}>
<X />
</Button>
</div>
<div>
<Table bordered size="sm">
<thead>
<tr>
<th>{"Latitude"}</th>
<th>{"Longitude"}</th>
<th style={{ width: "5%" }}></th>
</tr>
</thead>
<tbody>{tableEntries}</tbody>
</Table>
</div>
</div>
);
}

function EnterCoordsWindow(props) {
const fileForm = useRef(null);
const fileInput = useRef(null);

const tableEntries = props.mapFeatures.map((feature) => {
return (
<FeatureCard key={feature.id} feature={feature} action={props.action} />
);
});

const parseCSV = (e) => {
if (e.target.files.length == 1) {
const file = e.target.files[0];
Expand Down Expand Up @@ -167,92 +187,7 @@ function EnterCoordsWindow(props) {
}
};

const plotDisabled =
(props.vectorType === "point" && props.vectorCoordinates.length < 1) ||
(props.vectorType === "line" && props.vectorCoordinates.length < 2) ||
(props.vectorType === "area" && props.vectorCoordinates.length < 3);

return (
<div className="EnterCoordsWindow">
<div className="table-container">
<Table bordered size="sm">
<thead>
<tr>
<th>{__("Latitude")}</th>
<th>{__("Longitude")}</th>
<th style={{ width: "5%" }}></th>
</tr>
</thead>
<tbody>{tableEntries}</tbody>
</Table>

<form onSubmit={submitHandler}>
<div className="table-button-container">
<label>{__("Latitude")}:</label>
<input
type="number"
min="-90"
max="90"
step="0.0001"
value={enteredLat}
onChange={latChangeHandler}
/>
<label>{__("Longitude")}:</label>
<input
type="number"
min="-180"
max="180"
step="0.0001"
value={enteredLon}
onChange={lonChangeHandler}
/>
<button type="submit">{__("Add")}</button>
<button type="button" onClick={handleClear}>
{__("Clear")}
</button>
</div>
</form>
</div>

<div className="plot-button-container">
<div className="toggle-button-container">
{radios.map((radio, idx) => (
<ToggleButton
className="plot-toggle"
key={idx}
id={`radio-${idx}`}
type="radio"
name="radio"
value={radio.value}
checked={props.vectorType === radio.value}
onChange={handleRadio}
>
{radio.name}
</ToggleButton>
))}
</div>
<Button className="plot-button" onClick={handleUpload}>
{__("Upload CSV")}
</Button>
<Button
className="plot-button"
onClick={handlePlot}
disabled={plotDisabled}
>
{__("Plot")}
</Button>
</div>
<form ref={fileForm}>
<input
type="file"
style={{ display: "none" }}
onChange={parseCSV}
ref={fileInput}
accept=".csv,.CSV"
/>
</form>
</div>
);
return <div className="EnterCoordsWindow">{tableEntries}</div>;
}

export default withTranslation()(EnterCoordsWindow);
74 changes: 60 additions & 14 deletions oceannavigator/frontend/src/components/OceanNavigator.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ function OceanNavigator(props) {
};

const action = (name, arg, arg2, arg3) => {
let featIdx = null;
let updatedFeatures = null;
switch (name) {
case "startDrawing":
setVectorId(null);
Expand All @@ -135,7 +137,9 @@ function OceanNavigator(props) {
case "vectorType":
typeRef.current = arg;
setVectorType(arg);
setNewFeatures((prevFeatures) => updateFeatType(prevFeatures));
setNewFeatures((prevFeatures) =>
updateFeatType(prevFeatures, typeRef.current)
);
break;
case "undoMapFeature":
if (newFeatures.length > 0) {
Expand All @@ -159,10 +163,6 @@ function OceanNavigator(props) {
case "addPoints":
setVectorCoordinates((prevCoordinates) => [...prevCoordinates, ...arg]);
break;
case "removePoint":
let coords = vectorCoordinates.filter((coord, index) => index !== arg);
setVectorCoordinates(coords);
break;
case "addNewFeature":
setNewFeatures((prevFeatures) => {
if (typeRef.current === "point" || prevFeatures.length === 0) {
Expand All @@ -187,15 +187,61 @@ function OceanNavigator(props) {
setMapFeatures((prevFeatures) => [...prevFeatures, ...newFeatures]);
setNewFeatures([]);
break;
case "updatePoint":
let newCoords = null;
if (!isNaN(arg2) && !isNaN(arg3)) {
newCoords = [...vectorCoordinates];
newCoords[arg][arg2] = arg3;
case "updateFeatureCoordinate":
featIdx = mapFeatures.findIndex((feat) => {
return feat.id === arg;
});

updatedFeatures = [...mapFeatures];
if (arg2[0] >= updatedFeatures[featIdx].coords.length) {
updatedFeatures[featIdx].coords.push([0, 0]);
} else {
updatedFeatures[featIdx].coords[arg2[0]][arg2[1]] = arg3;
}
setMapFeatures(updatedFeatures);
break;
case "updateFeatureType":
featIdx = mapFeatures.findIndex((feat) => {
return feat.id === arg;
});

updatedFeatures = [...mapFeatures];
let prevType = updatedFeatures[featIdx].type;
let nextType = arg2;

if (nextType === "point" && prevType !== "point") {
let newFeats = updateFeatType([updatedFeatures[featIdx]], nextType);
updatedFeatures = [
...updatedFeatures.slice(0, featIdx),
...newFeats,
...updatedFeatures.slice(-featIdx, updatedFeatures.length),
];
} else {
updatedFeatures[featIdx].type = arg2;
}
setMapFeatures(updatedFeatures);
break;
case "removeFeature":
featIdx = mapFeatures.findIndex((feat) => {
return feat.id === arg;
});

updatedFeatures = [...mapFeatures];
updatedFeatures.splice(featIdx, 1);
setMapFeatures(updatedFeatures);
break;
case "removeFeatureCoord":
featIdx = mapFeatures.findIndex((feat) => {
return feat.id === arg;
});
updatedFeatures = [...mapFeatures];

if (updatedFeatures[featIdx].coords.length === 1) {
updatedFeatures.splice(featIdx, 1);
} else {
newCoords = arg;
updatedFeatures[featIdx].coords.splice(arg2, 1);
}
setVectorCoordinates(newCoords);
setMapFeatures(updatedFeatures);
break;
case "selectPoints":
if (!arg) {
Expand Down Expand Up @@ -340,12 +386,11 @@ function OceanNavigator(props) {
});
};

const updateFeatType = (features) => {
const updateFeatType = (features, nextType) => {
let updatedFeat = [];

if (features.length > 0) {
let prevType = features[0].type;
let nextType = typeRef.current;

if (
prevType === "point" &&
Expand Down Expand Up @@ -512,6 +557,7 @@ function OceanNavigator(props) {
updateUI={updateUI}
vectorType={vectorType}
vectorCoordinates={vectorCoordinates}
mapFeatures={mapFeatures}
/>
);
modalTitle = __("Enter Coordinates");
Expand Down

0 comments on commit a001b99

Please sign in to comment.