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

WIP: Show object detail on click #6

Draft
wants to merge 9 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
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
4 changes: 4 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"arrowParens": "always",
"printWidth": 100
}
3,069 changes: 1,525 additions & 1,544 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@
"osmtogeojson": "cloudniner/osmtogeojson#c48bcbd99d79aee9656521b225d764f4afce020c",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-mapbox-gl": "^4.8.6",
"react-scripts": "3.4.1",
"react-scripts": "^3.4.3",
"typescript": "~3.7.2"
},
"scripts": {
Expand Down
81 changes: 43 additions & 38 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,17 @@
import React, { useState } from "react";

import { Box, Button, ButtonGroup, Divider } from "@material-ui/core";
import { Box, Button, ButtonGroup, Divider, Modal } from "@material-ui/core";
import { makeStyles } from "@material-ui/core/styles";
import { DropzoneArea } from "material-ui-dropzone";

import {
getAugmentedDiff,
isSequenceValid,
parseDiff,
AugmentedDiff,
} from "./osm";
import { getAugmentedDiff, isSequenceValid, parseDiff, AugmentedDiff, OsmObjectDiff } from "./osm";
import ADifferLegend from "./Components/ADifferLegend";
import ActionSelector, {
ActionSelectorState,
} from "./Components/ActionSelector";
import ActionSelector, { ActionSelectorState } from "./Components/ActionSelector";
import Header from "./Components/Header";
import SequenceSelector from "./Components/SequenceSelector";
import AugmentedDiffMap from "./Sections/AugmentedDiffMap";
import OsmObjectSelector, {
OsmObjectSelectorState,
} from "./Components/OsmObjectSelector";
import OsmObjectSelector, { OsmObjectSelectorState } from "./Components/OsmObjectSelector";
import OsmDiffDetail from "./Components/OsmDiffDetail";

const useStyles = makeStyles((theme) => ({
divider: {
Expand All @@ -40,6 +32,17 @@ const useStyles = makeStyles((theme) => ({
mapBox: {
flex: 1,
},
modal: {
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
minWidth: 400,
backgroundColor: theme.palette.background.paper,
border: "2px solid #000",
boxShadow: theme.shadows[5],
padding: theme.spacing(2, 4, 3),
},
sidebarBox: {
flex: "0 0 24em",
display: "flex",
Expand Down Expand Up @@ -76,24 +79,21 @@ function App() {
modified: [],
deleted: [],
});
const [selectedActions, setSelectedActions] = useState<ActionSelectorState>(
defaultActions
);
const [selectedObjects, setSelectedObjects] = useState<
OsmObjectSelectorState
>(defaultObjects);
const [selectedActions, setSelectedActions] = useState<ActionSelectorState>(defaultActions);
const [selectedObjects, setSelectedObjects] = useState<OsmObjectSelectorState>(defaultObjects);
const [sequenceId, setSequenceId] = useState<string>("");
const [isLoading, setIsLoading] = useState<boolean>(false);
const [selectedDiff, setSelectedDiff] = useState<OsmObjectDiff | undefined>(undefined);

const isAugmentedDiffValid = !!(
augmentedDiff.created.length ||
augmentedDiff.deleted.length ||
augmentedDiff.modified.length
);

const [inputMethod, setInputMethod] = useState<"overpass" | "file">(
"overpass"
);
const [inputMethod, setInputMethod] = useState<"overpass" | "file">("overpass");

const handleModalClose = () => setSelectedDiff(undefined);

const goButtonClicked = () => {
setIsLoading(true);
Expand All @@ -103,8 +103,7 @@ function App() {
.finally(() => setIsLoading(false));
};

const onActionChanged = (state: ActionSelectorState) =>
setSelectedActions(state);
const onActionChanged = (state: ActionSelectorState) => setSelectedActions(state);

const onDropzoneFilesChange = (files: File[]) => {
if (files.length) {
Expand All @@ -122,18 +121,19 @@ function App() {
}
};

const onOsmObjectChanged = (state: OsmObjectSelectorState) =>
setSelectedObjects(state);
const onMapFeatureClick = (diff: OsmObjectDiff) => {
console.log(diff);
setSelectedDiff(diff);
};

const onOsmObjectChanged = (state: OsmObjectSelectorState) => setSelectedObjects(state);

return (
<Box className={classes.windowBox}>
<Box mx={2} className={classes.sidebarBox}>
<Header />
<Box mb={2} display="flex" justifyContent="center">
<ButtonGroup
color="primary"
aria-label="outlined primary button group"
>
<ButtonGroup color="primary" aria-label="outlined primary button group">
<Button
variant={inputMethod === "overpass" ? "contained" : "outlined"}
onClick={() => setInputMethod("overpass")}
Expand Down Expand Up @@ -175,20 +175,15 @@ function App() {
{isAugmentedDiffValid && (
<>
<Divider className={classes.divider} />
<ActionSelector
defaultState={defaultActions}
onChange={onActionChanged}
/>
<OsmObjectSelector
defaultState={defaultObjects}
onChange={onOsmObjectChanged}
/>
<ActionSelector defaultState={defaultActions} onChange={onActionChanged} />
<OsmObjectSelector defaultState={defaultObjects} onChange={onOsmObjectChanged} />
</>
)}
</Box>
<AugmentedDiffMap
augmentedDiff={augmentedDiff}
className={classes.mapBox}
onFeatureClick={onMapFeatureClick}
showActionCreate={selectedActions.create}
showActionDelete={selectedActions.delete}
showActionModify={selectedActions.modify}
Expand All @@ -199,6 +194,16 @@ function App() {
<Box className={classes.legendBox}>
<ADifferLegend />
</Box>
<Modal
open={selectedDiff !== undefined}
onClose={handleModalClose}
aria-labelledby="osm-feature-modal-title"
aria-describedby="osm-feature-modal-description"
>
<div className={classes.modal}>
{selectedDiff !== undefined ? <OsmDiffDetail diff={selectedDiff} /> : <></>}
</div>
</Modal>
</Box>
);
}
Expand Down
83 changes: 83 additions & 0 deletions src/Components/OsmDiffDetail.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import React from "react";

import Box from "@material-ui/core/Box";
import Table from "@material-ui/core/Table";
import TableBody from "@material-ui/core/TableBody";
import TableCell from "@material-ui/core/TableCell";
import TableRow from "@material-ui/core/TableRow";
import Typography from "@material-ui/core/Typography";

import { OsmObjectDiff } from "../osm";

interface OsmDetailTableProps {
diff: OsmObjectDiff;
}

const OsmDetailTable: React.FC<OsmDetailTableProps> = ({ diff }) => {
const tagKeys = new Set<string>();
Object.keys(diff.old?.properties.tags || {}).forEach((k, _) => tagKeys.add(k));
Object.keys(diff.new?.properties.tags || {}).forEach((k, _) => tagKeys.add(k));
return (
<Table size="small">
<TableBody>
<TableRow>
<TableCell>timestamp</TableCell>
<TableCell>{diff.old?.properties.meta.timestamp || ""}</TableCell>
<TableCell>{diff.new?.properties.meta.timestamp || ""}</TableCell>
</TableRow>
<TableRow>
<TableCell>uid</TableCell>
<TableCell>{diff.old?.properties.meta.uid || ""}</TableCell>
<TableCell>{diff.new?.properties.meta.uid || ""}</TableCell>
</TableRow>
<TableRow>
<TableCell>user</TableCell>
<TableCell>{diff.old?.properties.meta.user || ""}</TableCell>
<TableCell>{diff.new?.properties.meta.user || ""}</TableCell>
</TableRow>
<TableRow>
<TableCell>version</TableCell>
<TableCell>{diff.old?.properties.meta.version?.toString() || ""}</TableCell>
<TableCell>{diff.new?.properties.meta.version?.toString() || ""}</TableCell>
</TableRow>
<TableRow>
<TableCell>changeset</TableCell>
<TableCell>{diff.old?.properties.meta.changeset || ""}</TableCell>
<TableCell>{diff.new?.properties.meta.changeset || ""}</TableCell>
</TableRow>
{Array.from(tagKeys.values()).map((tagKey) => {
// TODO: Figure out how to type this properly (any is a band aid)
// https://stackoverflow.com/a/57088282 didn't solve
const oldTags: any = diff.old?.properties.tags || {};
const newTags: any = diff.new?.properties.tags || {};
return (
<TableRow>
<TableCell>{tagKey}</TableCell>
<TableCell>{oldTags[tagKey] || ""}</TableCell>
<TableCell>{newTags[tagKey] || ""}</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
);
};

interface OsmDiffDetailProps {
className?: string;
diff: OsmObjectDiff;
}

const OsmDiffDetail: React.FC<OsmDiffDetailProps> = ({ className, diff }) => {
const featureId = diff.new?.id || diff.old?.id || "";
return (
<Box className={className}>
<Typography variant="h6">
{diff.action}:{featureId}
</Typography>
<OsmDetailTable diff={diff} />
</Box>
);
};

export default OsmDiffDetail;
Loading