Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
9f48d7b264
|
|||
| bbd3bf47c6 | |||
|
59e3d91071
|
@@ -56,6 +56,8 @@ export default class PlaceRoute extends Route {
|
|||||||
deactivate() {
|
deactivate() {
|
||||||
// Clear the pin when leaving the route
|
// Clear the pin when leaving the route
|
||||||
this.mapUi.clearSelection();
|
this.mapUi.clearSelection();
|
||||||
|
// Reset the "return to search" flag so it doesn't persist to subsequent navigations
|
||||||
|
this.mapUi.returnToSearch = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
async loadOsmPlace(id, type = null) {
|
async loadOsmPlace(id, type = null) {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ export default class MapUiService extends Service {
|
|||||||
@tracked isSearching = false;
|
@tracked isSearching = false;
|
||||||
@tracked isCreating = false;
|
@tracked isCreating = false;
|
||||||
@tracked creationCoordinates = null;
|
@tracked creationCoordinates = null;
|
||||||
|
@tracked returnToSearch = false;
|
||||||
|
|
||||||
selectPlace(place) {
|
selectPlace(place) {
|
||||||
this.selectedPlace = place;
|
this.selectedPlace = place;
|
||||||
|
|||||||
@@ -77,11 +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 have history, go back (preserves search state)
|
// If we came from search results, go back in history
|
||||||
if (window.history.length > 1) {
|
if (this.mapUi.returnToSearch) {
|
||||||
window.history.back();
|
window.history.back();
|
||||||
} else {
|
} else {
|
||||||
// Fallback if opened directly
|
// Otherwise just close the sidebar (return to map index)
|
||||||
this.router.transitionTo('index');
|
this.router.transitionTo('index');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -5,10 +5,12 @@ import { action } from '@ember/object';
|
|||||||
|
|
||||||
export default class SearchTemplate extends Component {
|
export default class SearchTemplate extends Component {
|
||||||
@service router;
|
@service router;
|
||||||
|
@service mapUi;
|
||||||
|
|
||||||
@action
|
@action
|
||||||
selectPlace(place) {
|
selectPlace(place) {
|
||||||
if (place) {
|
if (place) {
|
||||||
|
this.mapUi.returnToSearch = true;
|
||||||
this.router.transitionTo('place', place);
|
this.router.transitionTo('place', place);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "marco",
|
"name": "marco",
|
||||||
"version": "1.11.1",
|
"version": "1.11.2",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "Unhosted maps app",
|
"description": "Unhosted maps app",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -26,7 +26,7 @@
|
|||||||
<meta name="msapplication-TileColor" content="#F6E9A6">
|
<meta name="msapplication-TileColor" content="#F6E9A6">
|
||||||
<meta name="msapplication-TileImage" content="/icons/icon-144.png">
|
<meta name="msapplication-TileImage" content="/icons/icon-144.png">
|
||||||
|
|
||||||
<script type="module" crossorigin src="/assets/main-DlYgnqpR.js"></script>
|
<script type="module" crossorigin src="/assets/main-CYFdUlXN.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/main-D53xPL_H.css">
|
<link rel="stylesheet" crossorigin href="/assets/main-D53xPL_H.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
106
tests/acceptance/navigation-test.js
Normal file
106
tests/acceptance/navigation-test.js
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
import { module, test } from 'qunit';
|
||||||
|
import { visit, currentURL, click, settled } from '@ember/test-helpers';
|
||||||
|
import { setupApplicationTest } from 'marco/tests/helpers';
|
||||||
|
import Service from '@ember/service';
|
||||||
|
import sinon from 'sinon';
|
||||||
|
|
||||||
|
class MockOsmService extends Service {
|
||||||
|
async getNearbyPois() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
osmId: '123',
|
||||||
|
lat: 1,
|
||||||
|
lon: 1,
|
||||||
|
osmTags: { name: 'Test Place', amenity: 'cafe' },
|
||||||
|
osmType: 'node',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
async getPoiById() {
|
||||||
|
return {
|
||||||
|
osmId: '123',
|
||||||
|
lat: 1,
|
||||||
|
lon: 1,
|
||||||
|
osmTags: { name: 'Test Place', amenity: 'cafe' },
|
||||||
|
osmType: 'node',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MockStorageService extends Service {
|
||||||
|
savedPlaces = [];
|
||||||
|
findPlaceById() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
loadPlacesInBounds() {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
get placesInView() {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
rs = {
|
||||||
|
on: () => {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
module('Acceptance | navigation', function (hooks) {
|
||||||
|
setupApplicationTest(hooks);
|
||||||
|
|
||||||
|
hooks.beforeEach(function () {
|
||||||
|
this.owner.register('service:osm', MockOsmService);
|
||||||
|
this.owner.register('service:storage', MockStorageService);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('navigating from search results to place and back uses history', async function (assert) {
|
||||||
|
const mapUi = this.owner.lookup('service:map-ui');
|
||||||
|
const backStub = sinon.stub(window.history, 'back');
|
||||||
|
|
||||||
|
try {
|
||||||
|
await visit('/search?lat=1&lon=1');
|
||||||
|
assert.strictEqual(currentURL(), '/search?lat=1&lon=1');
|
||||||
|
|
||||||
|
await click('.place-item');
|
||||||
|
assert.ok(currentURL().includes('/place/'), 'Navigated to place');
|
||||||
|
assert.true(mapUi.returnToSearch, 'Flag returnToSearch is set');
|
||||||
|
|
||||||
|
// Click the back button in the sidebar
|
||||||
|
await click('.back-btn');
|
||||||
|
|
||||||
|
assert.true(backStub.calledOnce, 'window.history.back() was called');
|
||||||
|
} finally {
|
||||||
|
backStub.restore();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('closing the sidebar resets the returnToSearch flag', async function (assert) {
|
||||||
|
const mapUi = this.owner.lookup('service:map-ui');
|
||||||
|
|
||||||
|
await visit('/search?lat=1&lon=1');
|
||||||
|
await click('.place-item'); // Sets returnToSearch = true
|
||||||
|
|
||||||
|
assert.true(mapUi.returnToSearch, 'Flag is set upon entering place');
|
||||||
|
|
||||||
|
// Click the Close (X) button
|
||||||
|
await click('.close-btn');
|
||||||
|
await settled();
|
||||||
|
|
||||||
|
assert.strictEqual(currentURL(), '/', 'Returned to index');
|
||||||
|
assert.false(mapUi.returnToSearch, 'Flag is reset after closing sidebar');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('navigating directly to place and back closes sidebar', async function (assert) {
|
||||||
|
const backStub = sinon.stub(window.history, 'back');
|
||||||
|
try {
|
||||||
|
await visit('/place/osm:node:123');
|
||||||
|
assert.ok(currentURL().includes('/place/'), 'Visited place directly');
|
||||||
|
|
||||||
|
await click('.back-btn');
|
||||||
|
await settled();
|
||||||
|
|
||||||
|
assert.strictEqual(currentURL(), '/', 'Returned to index/map');
|
||||||
|
assert.true(backStub.notCalled, 'window.history.back() was NOT called');
|
||||||
|
} finally {
|
||||||
|
backStub.restore();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user