Skip to content

Commit

Permalink
Changes:
Browse files Browse the repository at this point in the history
- Changed Webpage title
- Changed manifest.json -> React app to GeoAnnotator
- Added 'Clear selection' button, sothat when textitems are selected, we can remove them either by clicking the 'ESC' key or clicking on the button
- Fixed an issue in DialogMapping: When a marker-element is empty (or has no valid name or position, it will skip to the next marker)
- Fixed an issue in MappingFunctions: When the attribute 'position' of lastMarker is undefined or empty, do not render a new layer on the mapper (Do not set the view)
- Added LocationDialog to TextContent, so that optionalCoordinates can be selected (Save button needs to be implemented)
  • Loading branch information
siri_yu committed May 8, 2024
1 parent d67e332 commit 8cf3aca
Show file tree
Hide file tree
Showing 9 changed files with 115 additions and 50 deletions.
4 changes: 2 additions & 2 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
content="Created by Yunus Emre Sirin"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
Expand All @@ -24,7 +24,7 @@
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
<title>GeoAnnotator</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
Expand Down
4 changes: 2 additions & 2 deletions public/manifest.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"short_name": "GeoAnnotator",
"name": "Annotate data with GeoAnnotator",
"icons": [
{
"src": "favicon.ico",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { TextField, MenuItem, Select, FormControl, InputLabel, Box, Typography,
* @param {{ open: Boolean, onClose: Function }} param.dialogProps
* @returns {React.JSX.Element}
*/
export default function EditDialog({ geolocations, geolocation, dialogProps }) {
export default function LocationDialog({ geolocations, geolocation, dialogProps }) {
const
{ sessionData, setSessionData } = useSession(),
[location, setLocation] = useState(0),
Expand Down Expand Up @@ -41,7 +41,7 @@ export default function EditDialog({ geolocations, geolocation, dialogProps }) {

return (
<DialogContentArea
title={'Edit location'}
title={dialogProps.title}
open={dialogProps.open}
onClose={resetProps}
>
Expand All @@ -67,10 +67,10 @@ export default function EditDialog({ geolocations, geolocation, dialogProps }) {
{/* Position */}
<Grid item xs={8}>
<FormControl variant='filled' sx={{ width: "100%" }}>
<InputLabel id="editdialog-position-select-label">Position</InputLabel>
<InputLabel id="locationdialog-position-select-label">Position</InputLabel>
<Select
labelId="editdialog-position-select-label"
id="editdialog-position-select"
labelId="locationdialog-position-select-label"
id="locationdialog-position-select"
value={location}
onChange={(event) => {
event.preventDefault(); // Prevent the default rerendering of the dialog
Expand All @@ -84,7 +84,7 @@ export default function EditDialog({ geolocations, geolocation, dialogProps }) {
}
}}
>
{/* Default value */} <MenuItem key={geolocation?.name} value={0} children={`(${geolocation?.position[0]}, ${geolocation?.position[1]})`} />
{/* Default value */} <MenuItem key={geolocation?.name} value={0} children={geolocation?.position.length ? `(${geolocation?.position[0]}, ${geolocation?.position[1]})` : 'None'} />
{
// Optional values
optionalCoordinates?.map((coordinates, index) => (
Expand Down Expand Up @@ -116,36 +116,44 @@ export default function EditDialog({ geolocations, geolocation, dialogProps }) {
<ListItem disablePadding sx={{ mt: 1 }}>
{/* Mapping */}
<Box sx={{ width: '100%', height: '15rem' }}>
<DialogMapping
geolocations={optionalCoordinates?.concat([geolocation])} // Add current geolocation, sothat all locations + the optional ones are displayed
<DialogMapping
// Add current geolocation, sothat all locations + the optional ones are displayed
geolocations={optionalCoordinates?.concat([geolocation])}
// FIXME: When dblclicking the default marker, an error occurs ('Reading property of undefined is not possible (reading value when Array.map)')
markerClickHandler={(event) => {
markerDblClickHandler={(event) => {
let latlng = event.latlng, position = [latlng['lat'], latlng['lng']];
setLocation(position.toString()); // Convert it into a string, sothat JS doesn't compare by reference, but by value (In this case, only with primitive values)
setDisableButton(position.toString() === geolocation?.position.toString());
setSessionData({...sessionData, selectedOptionPosition: position });
}}
/>
<Typography fontSize={10}>Double click the respective marker to change the corresponding position (BETA)</Typography>
<Typography fontSize={10}>Double click the respective marker to select the position (BETA)</Typography>
</Box>
</ListItem>

<ListItem disablePadding sx={{ mt: 2 }}>
<ListItem disablePadding sx={{ mt: 2, display: 'flex', flexWrap: 'nowrap', justifyContent: 'space-between' }}>
{/* Save Button */}
<SaveButton
variant='contained'
disabled={disableButton}
onClick={() => {
// If changes were made, pass the updated geolocation to the high order component "MainArea" and enable the save changes button
if(location) {
dialogProps.enableSaveChangesButton();
if(dialogProps.enableSaveChangesButton) dialogProps.enableSaveChangesButton();
setSessionData({...sessionData, updatedGeolocations: geolocations.forEach((geo) => { if(geo.name === geolocation?.name) geo.position = JSON.parse(`[${location}]`) })});
}
resetProps()
}}
>
Save
</SaveButton>
{
optionalCoordinates === undefined || optionalCoordinates?.length === 0 ?
<Typography paragraph={true} sx={{ fontWeight: 'bold', color: 'red' }}>
No Locations available
</Typography>
: null
}
</ListItem>
</DialogContentArea>
)
Expand Down
5 changes: 3 additions & 2 deletions src/components/Geolocation/GeolocationFunctions.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
Place,
MenuRounded
} from '@mui/icons-material';
import EditDialog from './Dialogs/EditDialog';
import LocationDialog from './Dialogs/LocationDialog'

/**
* Location list: Geolocation entries
Expand Down Expand Up @@ -99,10 +99,11 @@ export function GeolocationItems({ data, disableSaveChangesButton }) {
</ListItem>
))
}
<EditDialog
<LocationDialog
geolocation={geolocation}
geolocations={geolocations}
dialogProps={{
title: 'Edit location',
open: open,
onClose: setOpen,
enableSaveChangesButton: () => disableSaveChangesButton(false)
Expand Down
39 changes: 23 additions & 16 deletions src/components/Mapping/DialogMapping.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
* @param {{ name: string, position: float[] }[]} param.geolocations
* @param {Function} param.markerClickHandler
*/
export default function DialogMapping({ geolocations, markerClickHandler }) {
export default function DialogMapping({ geolocations, markerDblClickHandler }) {
return (
<MapContainer
zoom={12}
Expand All @@ -31,21 +31,28 @@ export default function DialogMapping({ geolocations, markerClickHandler }) {
attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
/>
{
geolocations ? geolocations?.map((marker, index) => (
<Marker
key={index}
position={marker.position}
eventHandlers={{
'dblclick': markerClickHandler ? markerClickHandler : () => undefined
}}
>
<Popup>
{marker.name}
<br/>
{`(${marker.position})`}
</Popup>
</Marker>
)) : null
geolocations ? geolocations?.map((marker, index) => {
if(
marker.name === undefined ||
marker.position === undefined ||
marker.position.length === 0
) return null;
return (
<Marker
key={index}
position={marker.position}
eventHandlers={{
'dblclick': markerDblClickHandler ? markerDblClickHandler : () => undefined
}}
>
<Popup>
{marker.name}
<br/>
{`(${marker.position})`}
</Popup>
</Marker>
)
}) : null
}
<FocusOnLatest markers={geolocations}/>
<FocusOnSelectedMarker/>
Expand Down
2 changes: 1 addition & 1 deletion src/components/Mapping/MappingFunctions.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const FocusOnLatest = ({ markers }) => {
useEffect(() => {
if (markers && markers.length > 0) {
const lastMarker = markers[markers.length - 1]; // Get the last marker
map.setView(lastMarker.position, 8); // Set view to the last marker
if(lastMarker.position.length) map.setView(lastMarker.position, 8); // Set view to the last marker
}
}, [markers, map]); // Effect depends on markers changing

Expand Down
15 changes: 15 additions & 0 deletions src/components/TextContent/TextContent.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,19 @@

.TextItem::selection {
background-color: transparent;
}

.TextItem[ishighlighted='true'].Selected {
background-color: defaultColor;
}

.TextItem[ishighlighted='true'].Selecting {
background-color: defaultColor;
}

.grid-container-textcontent-buttons {
display: flex;
flex-wrap: nowrap;
flex-direction: row;
justify-content: space-between;
}
63 changes: 48 additions & 15 deletions src/components/TextContent/TextContent.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
import './TextContent.css'
import { Box } from "@mui/material"
import { Box, Button, Grid } from "@mui/material"
import { pipe } from '../../utils/utilFunctions'
import { SaveButton } from '../customComponents'
import { useEffect, useRef, useState } from "react"
import { SelectableGroup } from "react-selectable-fast"
import { highlightDetectedLocations } from "./TextContentFunctions"
import { SaveButton } from '../customComponents'
import { pipe } from '../../utils/utilFunctions'
import LocationDialog from '../Geolocation/Dialogs/LocationDialog'

export function TextContent({ textContent, geolocations }) {
const
// eslint-disable-next-line no-unused-vars
refSelectableGroup = useRef(null),
[open, setOpen] = useState(false),
[selectedItems, setSelectedItems] = useState([]),
[disableButton, setDisableButton] = useState(true),
refSelectableGroup = useRef(null),
/* HandleFunctions */
[geolocation, setGeolocation] = useState({ name: undefined, position: [] }),
handleSelectionFinish = (selectedItems) => {
let processOutput = pipe(
items => items.filter(item => !item.props.props.isHighlighted),
items => items.map(item => item.props.props.text)
), output = processOutput(selectedItems);
setSelectedItems(output);
setDisableButton(false);
setDisableButton(output.length === 0);
};

// When another file is loaded, clear the selected items
Expand Down Expand Up @@ -50,23 +52,54 @@ export function TextContent({ textContent, geolocations }) {
>
<SelectableGroup
ref={refSelectableGroup}
resetOnStart
deselectOnEsc
enableDeselect
onSelectionFinish={handleSelectionFinish}
style={{ display: 'flex', flexWrap: 'wrap' }}
>
{highlightDetectedLocations(textContent, geolocations)}
</SelectableGroup>
</Box>
{/* Add location button */}
<SaveButton
variant='contained'
disabled={disableButton}
onClick={() => console.log(selectedItems)}
>
Add new Location
</SaveButton>

<Grid container spacing={1} className='grid-container-textcontent-buttons'>

{/* Clear selection button */}
<Grid item xs={'auto'}>
<Button
variant='contained'
disabled={disableButton}
sx={{ fontWeight: 'bold' }}
onClick={() => refSelectableGroup.current.clearSelection()}
>
Clear selection
</Button>
</Grid>

{/* Add location button */}
<Grid item xs={'auto'}>
<SaveButton
variant='contained'
disabled={disableButton}
onClick={() => {
setGeolocation({...geolocation, name: selectedItems.join(' ')});
setOpen(true);
}}
>
Add new location
</SaveButton>
</Grid>

</Grid>

<LocationDialog
geolocations={geolocations}
geolocation={geolocation}
dialogProps={{
title: 'Add new location',
open: open,
onClose: setOpen
}}
/>
</Box>
)
}
1 change: 1 addition & 0 deletions src/components/customComponents.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export const SelectableTextItem = createSelectable(({ selectableRef, isSelected,
marginX={0.25}
component={'p'}
children={props.text}
ishighlighted={`${props.isHighlighted}`}
sx={props.isHighlighted ? {backgroundColor: '#2587be', color: 'white', padding: 0.1, borderRadius: 1} : null}
className={`TextItem ${isSelected ? 'Selected' : isSelecting ? 'Selecting' : ''}`}
/>
Expand Down

0 comments on commit 8cf3aca

Please sign in to comment.