Skip to content

ERA-11237: Conditional display of event detail location markers on map #1258

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

Merged
merged 4 commits into from
Mar 24, 2025

Conversation

luixlive
Copy link
Contributor

@luixlive luixlive commented Mar 19, 2025

What does this PR do?

Add location markers on the map when the user opens an event with a form that includes location fields.

How does it look

image

Relevant link(s)

Where / how to start reviewing (optional)

  • Start with the new hook useLocationMarkersLayer, which receives the event location and a click callback and exposes methods to update the markers, focus and blur them.
  • Then you can go through its implementation in the SchemaForm and its children.

Any background context you want to provide(if applicable)

This feature won't work in mobile devices for two reasons:

  • The agreed logic was to show the markers when opening the details view of an event. So we can see the event details, like its form, while having the markers on the map (see screenshot above). In mobile devices, the event detail view opens a side bar that entirely hides the map.
  • There is a relation between a location field and its map marker that basically focuses the marker while the field is focused (clicking or navigating with the keyboard into the field will make the marker of that field blue). Also, clicking the marker will immediately focus the location field if it is visible. The user experience of focusing fields is very different in mobile devices than in a computer, since there we have touch events instead of a pointer or a keyboard.

@luixlive luixlive marked this pull request as draft March 19, 2025 22:10
@@ -71,6 +71,7 @@ const LocationPicker = ({
className={`${styles.input} ${readOnly ? styles.readOnly : ''}`}
disabled={disabled}
id={id}
onFocus={() => setLocationButtonRef.current.focus()}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

For form data management, the id must be appended to the <input> but we forward the focusing to the button so when we programmatically focus the element by the id (like when we click a location marker) we see the location picker button being focused.

return <li
className={itemClassName}
data-testid="schema-form-collection-item"
id={`${collectionDetails.value}.${id}`}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Add an id to the collection items so we can focus them programmatically when a user clicks a location marker which has its corresponding location field inside a collection item.

@@ -131,6 +132,11 @@ const Collection = ({
setItems([...items, { id: lastAddedItemIdRef.current, isFormModalOpen: true, isFormPreviewOpen: false }]);
};

// If a location field from an item requests to focus its location marker, prefix the marker id with the collection
// id and the item index.
const focusLocationMarkerFromItem = (itemIndex) => (markerId) =>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Location fields inside collection items need to have prefixed ids to make them unique, otherwise several items may have the location field set and have their ids clashing, so we propagate the callbacks prefixing the ids like: collection1.2.nested-collection.1.item. Notice that, since we decided to allow every single character in the values of a field in the EFB, there may be scenarios where this is not enough to make ids unique (a user could decide to set the value of a field like: collection.1.field, the chances are extremely low, but its possible). We should have prohibited some characters 😅

blurLocationMarker,
focusLocationMarker,
updateLocationMarkers
} = useLocationMarkersLayer(eventLocation, onLocationMarkerClick);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here we use the new hook, we pass the event location and the callback to focus the corresponding fields when clicking a marker, and receive the methods to focus, blur and update the markers.

};
addLocationMarkersFromFormDataRecursively(formData);

updateLocationMarkers(locationMarkers);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here we update the markers every time the form data changes.

const MARKER_CONNECTING_LINES_LAYER_ID = `${LAYER_IDS.EVENT_LOCATION_MARKERS}-lines`;
const MARKER_CONNECTING_OUTLINES_LAYER_ID = `${LAYER_IDS.EVENT_LOCATION_MARKERS}-outlines`;

const useLocationMarkersLayer = (eventLocation, onMarkerClickCallback) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

And here we have all the source / layer / map events logic to handle the new location markers. Hopefully the file is very self-explanatory.

Base automatically changed from ERA-11236 to develop March 20, 2025 18:17
@luixlive luixlive marked this pull request as ready for review March 20, 2025 19:53
@tiffanynwong
Copy link
Collaborator

Looking so good! Just a few notes/ ideas:

  1. Right now we focus on the field if the user clicks on the pin. If the user clicks the jump to location button from the field the field stays the same. Could we focus the field when clicking the jump to location button too? That way the user can always see which field is tied to which location on the map.
    Mar-20-2025 10-15-53

  2. When clicking on the jump to location button from a field, can we zoom in really close to that location. This is because it's likely that the these locations w/in the form will be really close to the event location. For example if the user is documenting a cluster of invasive plants, the plants could be very close to each other.

In this example I changed the locations to a few meters from each other.
Mar-20-2025 10-28-43
Screenshot 2025-03-20 at 10 30 10 AM

  1. Would it be possible to add a jump to location button in the collection summary? only if it's easy, if it adds too much scope it's ok.
    Screenshot 2025-03-20 at 10 19 02 AM

…ease zoom level when jumping to location markers
@luixlive
Copy link
Contributor Author

@tiffanynwong

  1. Right now we focus on the field if the user clicks on the pin. If the user clicks the jump to location button from the field the field stays the same. Could we focus the field when clicking the jump to location button too? That way the user can always see which field is tied to which location on the map.

It's not hard to do so, but honestly I have mixed feelings about this. The idea behind the current logic is very simple:
1- If we focus the time picker widget (any of its parts: its value, menu, copy to clipboard button, jump to location button) we paint the marker blue.
2- If we click a marker, we focus its corresponding location field (which takes us to the point 1, causing to paint the clicked marker blue).

When focusing our location widget, by default we focus the open popover button, which wraps the value. This adds a blue border, which is what you are referring to. Now, when clicking a button, browsers natively put the focus on them, but it's not common practice to add a border or outline to them. It's just the standard. It doesn't mean the button is not focused. That is why when we click the jump to location button the marker gets blue, because the button keeps the focus, even if the border doesn't appear.

Your suggestion is to do something that is not common, and that may be confusing or irritating for users: move the from button A to button B when clicking button A. That is not an accessible practice, the expected behavior is to just keep the focus in the clicked button, even if its not being surrounded by a blue border or outline (which again, is normal with buttons, we just add the outline when they are navigated to from the keyboard). I could do it, if you really think it's worth it, I just wanted to write my thoughts.

Regarding point 2 and 3, I already worked on them 😄
image

Copy link
Contributor

@gaboDev gaboDev left a comment

Choose a reason for hiding this comment

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

Looking great! 🫡

@luixlive luixlive merged commit 180ae3a into develop Mar 24, 2025
3 checks passed
@luixlive luixlive deleted the ERA-11237 branch March 24, 2025 15:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants