Ensure map marker clicks preserve search context
Fixes the back button just closing the sidebar and clearing the whole search after having seleted a result via map marker
This commit is contained in:
@@ -1099,6 +1099,20 @@ export default class MapComponent extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper to transition with proper state
|
||||||
|
const transitionToPlace = (place) => {
|
||||||
|
// If we are currently in search mode OR have active search results,
|
||||||
|
// we want the "Back" button on the place details to return to the search results.
|
||||||
|
if (
|
||||||
|
this.router.currentRouteName === 'search' ||
|
||||||
|
(this.mapUi.currentSearch && this.mapUi.searchResults.length > 0)
|
||||||
|
) {
|
||||||
|
this.mapUi.returnToSearch = true;
|
||||||
|
}
|
||||||
|
this.mapUi.preventNextZoom = true;
|
||||||
|
this.router.transitionTo('place', place);
|
||||||
|
};
|
||||||
|
|
||||||
// Special handling when sidebar is OPEN
|
// Special handling when sidebar is OPEN
|
||||||
if (this.args.isSidebarOpen) {
|
if (this.args.isSidebarOpen) {
|
||||||
// If it's a bookmark or search result, we allow "switching" to it even if sidebar is open
|
// If it's a bookmark or search result, we allow "switching" to it even if sidebar is open
|
||||||
@@ -1108,8 +1122,7 @@ export default class MapComponent extends Component {
|
|||||||
'Clicked feature while sidebar open (switching):',
|
'Clicked feature while sidebar open (switching):',
|
||||||
targetPlace
|
targetPlace
|
||||||
);
|
);
|
||||||
this.mapUi.preventNextZoom = true;
|
transitionToPlace(targetPlace);
|
||||||
this.router.transitionTo('place', targetPlace);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1123,15 +1136,13 @@ export default class MapComponent extends Component {
|
|||||||
// Normal behavior (sidebar is closed)
|
// Normal behavior (sidebar is closed)
|
||||||
if (clickedBookmark) {
|
if (clickedBookmark) {
|
||||||
console.debug('Clicked bookmark:', clickedBookmark);
|
console.debug('Clicked bookmark:', clickedBookmark);
|
||||||
this.mapUi.preventNextZoom = true;
|
transitionToPlace(clickedBookmark);
|
||||||
this.router.transitionTo('place', clickedBookmark);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clickedSearchResult) {
|
if (clickedSearchResult) {
|
||||||
console.debug('Clicked search result:', clickedSearchResult);
|
console.debug('Clicked search result:', clickedSearchResult);
|
||||||
this.mapUi.preventNextZoom = true;
|
transitionToPlace(clickedSearchResult);
|
||||||
this.router.transitionTo('place', clickedSearchResult);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -170,6 +170,10 @@ export default class SearchRoute extends Route {
|
|||||||
// Ensure pulse is stopped if we reach here
|
// Ensure pulse is stopped if we reach here
|
||||||
this.mapUi.stopSearch();
|
this.mapUi.stopSearch();
|
||||||
this.mapUi.setSearchResults(model);
|
this.mapUi.setSearchResults(model);
|
||||||
|
|
||||||
|
// Store current search params to allow "Up" navigation from place details
|
||||||
|
const { q, category, lat, lon } = this.paramsFor('search');
|
||||||
|
this.mapUi.currentSearch = { q, category, lat, lon };
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ export default class MapUiService extends Service {
|
|||||||
@tracked selectionOptions = {};
|
@tracked selectionOptions = {};
|
||||||
@tracked preventNextZoom = false;
|
@tracked preventNextZoom = false;
|
||||||
@tracked searchResults = [];
|
@tracked searchResults = [];
|
||||||
|
@tracked currentSearch = null;
|
||||||
|
|
||||||
selectPlace(place, options = {}) {
|
selectPlace(place, options = {}) {
|
||||||
this.selectedPlace = place;
|
this.selectedPlace = place;
|
||||||
@@ -31,6 +32,7 @@ export default class MapUiService extends Service {
|
|||||||
|
|
||||||
clearSearchResults() {
|
clearSearchResults() {
|
||||||
this.searchResults = [];
|
this.searchResults = [];
|
||||||
|
this.currentSearch = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
startSearch() {
|
startSearch() {
|
||||||
|
|||||||
@@ -77,9 +77,11 @@ export default class PlaceTemplate extends Component {
|
|||||||
navigateBack(place) {
|
navigateBack(place) {
|
||||||
// The sidebar calls this with null when "Back" is clicked.
|
// The sidebar calls this with null when "Back" is clicked.
|
||||||
if (place === null) {
|
if (place === null) {
|
||||||
// If we came from search results, go back in history
|
// If we have an active search context, return to it (UP navigation)
|
||||||
if (this.mapUi.returnToSearch) {
|
if (this.mapUi.returnToSearch && this.mapUi.currentSearch) {
|
||||||
window.history.back();
|
this.router.transitionTo('search', {
|
||||||
|
queryParams: this.mapUi.currentSearch
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
// Otherwise just close the sidebar (return to map index)
|
// Otherwise just close the sidebar (return to map index)
|
||||||
this.router.transitionTo('index');
|
this.router.transitionTo('index');
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ export default class SearchTemplate extends Component {
|
|||||||
selectPlace(place) {
|
selectPlace(place) {
|
||||||
if (place) {
|
if (place) {
|
||||||
this.mapUi.returnToSearch = true;
|
this.mapUi.returnToSearch = true;
|
||||||
|
// We don't need to manually set currentSearch here because
|
||||||
|
// it was already set in the route's setupController
|
||||||
this.router.transitionTo('place', place);
|
this.router.transitionTo('place', place);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,25 +64,24 @@ module('Acceptance | navigation', function (hooks) {
|
|||||||
this.owner.register('service:storage', MockStorageService);
|
this.owner.register('service:storage', MockStorageService);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('navigating from search results to place and back uses history', async function (assert) {
|
test('navigating from search results to place and back returns to search', async function (assert) {
|
||||||
const mapUi = this.owner.lookup('service:map-ui');
|
const mapUi = this.owner.lookup('service:map-ui');
|
||||||
const backStub = sinon.stub(window.history, 'back');
|
|
||||||
|
|
||||||
try {
|
await visit('/search?lat=1&lon=1');
|
||||||
await visit('/search?lat=1&lon=1');
|
assert.strictEqual(currentURL(), '/search?lat=1&lon=1');
|
||||||
assert.strictEqual(currentURL(), '/search?lat=1&lon=1');
|
|
||||||
|
|
||||||
await click('.place-item');
|
await click('.place-item');
|
||||||
assert.ok(currentURL().includes('/place/'), 'Navigated to place');
|
assert.ok(currentURL().includes('/place/'), 'Navigated to place');
|
||||||
assert.true(mapUi.returnToSearch, 'Flag returnToSearch is set');
|
assert.true(mapUi.returnToSearch, 'Flag returnToSearch is set');
|
||||||
|
|
||||||
// Click the back button in the sidebar
|
// Click the back button in the sidebar
|
||||||
await click('.back-btn');
|
await click('.back-btn');
|
||||||
|
|
||||||
assert.true(backStub.calledOnce, 'window.history.back() was called');
|
assert.strictEqual(
|
||||||
} finally {
|
currentURL(),
|
||||||
backStub.restore();
|
'/search?lat=1&lon=1',
|
||||||
}
|
'Returned to search results'
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('closing the sidebar resets the returnToSearch flag', async function (assert) {
|
test('closing the sidebar resets the returnToSearch flag', async function (assert) {
|
||||||
|
|||||||
@@ -27,9 +27,9 @@ module('Unit | Utility | osm-icons', function () {
|
|||||||
assert.strictEqual(result, 'shopping-basket');
|
assert.strictEqual(result, 'shopping-basket');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('it returns shopping-basket for unknown shop types (catch-all)', function (assert) {
|
test('it returns shopping-bag for unknown shop types (catch-all)', function (assert) {
|
||||||
let result = getIconNameForTags({ shop: 'unknown_shop_type' });
|
let result = getIconNameForTags({ shop: 'unknown_shop_type' });
|
||||||
assert.strictEqual(result, 'shopping-basket');
|
assert.strictEqual(result, 'shopping-bag');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('it returns null for unknown tags', function (assert) {
|
test('it returns null for unknown tags', function (assert) {
|
||||||
|
|||||||
Reference in New Issue
Block a user