Skip to content
This repository has been archived by the owner on Jun 3, 2024. It is now read-only.

QMAPS-1883 refactor close buttons #1051

Merged
merged 35 commits into from
Apr 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
037b318
QMAPS-1883 remove close buttons on all panels (on mobile) and on POI …
xem Mar 31, 2021
f0de7b2
QMAPS-1883 fix close button on itinerary routes list
xem Mar 31, 2021
8d7775b
QMAPS-1883 fix tests, fill field in search field if not from PoI list
xem Apr 7, 2021
376566b
Use ismobile from context
bbecquet Apr 2, 2021
5ffcc0f
No button on desktop route result
bbecquet Apr 2, 2021
e1f6d1a
QMAPS-1883 fix tests
xem Apr 7, 2021
105c6f2
QMAPS-1883 fix tests
xem Apr 7, 2021
ff2871a
QMAPS-1883 fix tests
xem Apr 7, 2021
08be2ee
QMAPS-1883 fix tests
xem Apr 7, 2021
43fd5b6
QMAPS-1883 fix tests, always put poi name in search field
xem Apr 7, 2021
7863e9d
QMAPS-1883 fix lint
xem Apr 7, 2021
d6a143b
QMAPS-1883 add return arrow on PoI panel on mobile when the source il…
xem Apr 7, 2021
17c024b
QMAPS-1883 fix test
xem Apr 7, 2021
34767f5
QMAPS-1883 fix test
xem Apr 7, 2021
a8e915a
QMAPS-1883 lint
xem Apr 12, 2021
5bd6411
QMAPS-1883 move return button logic in panelManager
xem Apr 13, 2021
1cb8cc6
QMAPS-1883 fix everything from panelManager
xem Apr 14, 2021
eb32f90
QMAPS-1883 lint
xem Apr 14, 2021
63ce524
QMAPS-1883 lint
xem Apr 14, 2021
c50c094
QMAPS-1883 lint
xem Apr 14, 2021
b8d0822
QMAPS-1883 lint
xem Apr 14, 2021
fa5a614
QMAPS-1883 broken test
xem Apr 14, 2021
cc17016
QMAPS-1883 broken test
xem Apr 19, 2021
c846ad2
QMAPS-1883 fix test
xem Apr 19, 2021
c003d4f
QMAPS-1883 fix test
xem Apr 19, 2021
fda3f35
QMAPS-1883 fix test
xem Apr 19, 2021
25f60db
QMAPS-1883 fix test
xem Apr 19, 2021
6e394ce
QMAPS-1883 fix test
xem Apr 19, 2021
9c5a9d1
QMAPS-1883 fix test
xem Apr 19, 2021
c2d68b3
QMAPS-1883 comment test
xem Apr 19, 2021
3192910
QMAPS-1883 PR fixes
xem Apr 21, 2021
e89cc51
QMAPS-1883 PR fixes
xem Apr 21, 2021
d914550
QMAPS-1883 PR fixes
xem Apr 21, 2021
7d842ef
QMAPS-1883 PR fixes
xem Apr 21, 2021
3151aba
QMAPS-1883 comment
xem Apr 21, 2021
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
1 change: 1 addition & 0 deletions src/components/ui/Panel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class Panel extends React.Component {
isMapBottomUIDisplayed: PropTypes.bool,
floatingItems: PropTypes.arrayOf(PropTypes.object),
onTransitionEnd: PropTypes.func,
onClose: PropTypes.func,
};

static defaultProps = {
Expand Down
78 changes: 73 additions & 5 deletions src/panel/PanelManager.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import CategoryPanel from 'src/panel/category/CategoryPanel';
import DirectionPanel from 'src/panel/direction/DirectionPanel';
import Telemetry from 'src/libs/telemetry';
import CategoryService from 'src/adapters/category_service';
import { parseQueryString, getCurrentUrl } from 'src/libs/url_utils';
import { parseQueryString, getCurrentUrl, buildQueryString } from 'src/libs/url_utils';
import { fire, listen } from 'src/libs/customEvents';
import { isNullOrEmpty } from 'src/libs/object';
import { isMobileDevice } from 'src/libs/device';
Expand Down Expand Up @@ -77,18 +77,26 @@ export default class PanelManager extends React.Component {
const { ActivePanel, options } = this.state;

if (prevState.ActivePanel !== ActivePanel || prevState.options !== options) {
// poiFilters indicate we are in a "list of POI" context, where markers should be persistent
// Not in a "list of PoI" context (options.poiFilters is null)
if (isNullOrEmpty(options?.poiFilters)) {
// Markers are not persistent
fire('remove_category_markers');
}

// Handle search bar's style and text content
this.updateSearchBarContent(options);

// Handle top bar's return button
this.updateTopBarReturnButton(options);
}
}

updateSearchBarContent({ poiFilters = {}, query } = {}) {
updateSearchBarContent({ poiFilters = {}, poi = {}, query } = {}) {
const topBarHandle = document.querySelector('.top_bar');
if (poiFilters.category) {
if (poi.name) {
SearchInput.setInputValue(poi.name);
topBarHandle.classList.add('top_bar--search_filled');
} else if (poiFilters.category) {
const categoryLabel = CategoryService.getCategoryByName(poiFilters.category)?.getInputValue();
SearchInput.setInputValue(categoryLabel);
topBarHandle.classList.add('top_bar--search_filled');
Expand All @@ -104,6 +112,61 @@ export default class PanelManager extends React.Component {
}
}

updateTopBarReturnButton({ poiFilters = {}, isFromFavorite, poi = {} } = {}) {
const topBarReturnButton = document.querySelector('.search_form__return-to-list');
const backAction =
poiFilters.category || poiFilters.query
? this.backToList
: isFromFavorite
? this.backToFavorite
: () => {};
topBarReturnButton.onclick = e => {
backAction(e, poiFilters);
};

const topBarHandle = document.querySelector('.top_bar');

// Show return arrow (on mobile) if user comes from PoI / favorites list
if (poi.name && (poiFilters.category || poiFilters.query || isFromFavorite)) {
topBarHandle.classList.add('top_bar--poi-from-list');
}
// Hide return button when not on a POI anymore
else {
const topBarHandle = document.querySelector('.top_bar');
topBarHandle.classList.remove('top_bar--poi-from-list');
}
}

backToList(e, poiFilters) {
e.stopPropagation();
const queryObject = {};
const mappingParams = {
query: 'q',
category: 'type',
};

for (const name in poiFilters) {
if (!poiFilters[name]) {
continue;
}
const key = mappingParams[name];
queryObject[key || name] = poiFilters[name];
}

const params = buildQueryString(queryObject);
const uri = `/places/${params}`;

Telemetry.add(Telemetry.POI_BACKTOLIST);
fire('restore_location');
window.app.navigateTo(uri);
}

backToFavorite(e) {
e.stopPropagation();
Telemetry.add(Telemetry.POI_BACKTOFAVORITE);
window.app.navigateTo('/favs');
}

initRouter() {
const router = this.props.router;

Expand Down Expand Up @@ -134,7 +197,12 @@ export default class PanelManager extends React.Component {
const poiId = poiUrl.split('@')[0];
this.setState({
ActivePanel: PoiPanel,
options: { ...options, poiId },
options: {
...options,
poiId,
backToList: this.backToList,
backToFavorite: this.backToFavorite,
},
panelSize: 'default',
});
});
Expand Down
1 change: 0 additions & 1 deletion src/panel/direction/RouteResult.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import React, { useCallback, useEffect } from 'react';
import PropTypes from 'prop-types';
import { listen, unListen } from 'src/libs/customEvents';
import Telemetry from 'src/libs/telemetry';

import RoutesList from './RoutesList';
import { SourceFooter } from 'src/components/ui';

Expand Down
54 changes: 14 additions & 40 deletions src/panel/poi/PoiPanel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ import PoiBlockContainer from './PoiBlockContainer';
import OsmContribution from 'src/components/OsmContribution';
import CategoryList from 'src/components/CategoryList';
import { isFromPagesJaunes, isFromOSM } from 'src/libs/pois';
import { buildQueryString, shouldShowBackToQwant } from 'src/libs/url_utils';
import { shouldShowBackToQwant } from 'src/libs/url_utils';
import IdunnPoi from 'src/adapters/poi/idunn_poi';
import Poi from 'src/adapters/poi/poi.js';
import { fire, listen, unListen } from 'src/libs/customEvents';
import { addToFavorites, removeFromFavorites, isInFavorites } from 'src/adapters/store';
import PoiItem from 'src/components/PoiItem';
import { isNullOrEmpty } from 'src/libs/object';
import { DeviceContext } from 'src/libs/device';
import { Flex, Panel, PanelNav, CloseButton, Divider, Button } from 'src/components/ui';
import { Flex, Panel, PanelNav, Divider, Button } from 'src/components/ui';
import { BackToQwantButton } from 'src/components/BackToQwantButton';

const covid19Enabled = (nconf.get().covid19 || {}).enabled;
Expand All @@ -28,6 +28,8 @@ export default class PoiPanel extends React.Component {
poi: PropTypes.object,
poiFilters: PropTypes.object,
centerMap: PropTypes.bool,
backToList: PropTypes.func,
backToFavorite: PropTypes.func,
};

static defaultProps = {
Expand Down Expand Up @@ -130,12 +132,6 @@ export default class PoiPanel extends React.Component {
});
}

backToFavorite = e => {
e.stopPropagation();
Telemetry.add(Telemetry.POI_BACKTOFAVORITE);
window.app.navigateTo('/favs');
};

getBestPoi() {
return this.state.fullPoi || this.props.poi;
}
Expand All @@ -156,31 +152,6 @@ export default class PoiPanel extends React.Component {
window.app.navigateTo('/');
};

backToList = e => {
e.stopPropagation();
const { poiFilters } = this.props;
const queryObject = {};
const mappingParams = {
query: 'q',
category: 'type',
};

for (const name in poiFilters) {
if (!poiFilters[name]) {
continue;
}
const key = mappingParams[name];
queryObject[key || name] = poiFilters[name];
}

const params = buildQueryString(queryObject);
const uri = `/places/${params}`;

Telemetry.add(Telemetry.POI_BACKTOLIST);
fire('restore_location');
window.app.navigateTo(uri);
};

onClickPhoneNumber = () => {
const poi = this.getBestPoi();
const source = poi.meta && poi.meta.source;
Expand Down Expand Up @@ -220,9 +191,9 @@ export default class PoiPanel extends React.Component {

const backAction =
poiFilters.category || poiFilters.query
? this.backToList
? this.props.backToList
: isFromFavorite
? this.backToFavorite
? this.props.backToFavorite
: this.closeAction;

const NavHeader = ({ isMobile }) => {
Expand All @@ -238,10 +209,17 @@ export default class PoiPanel extends React.Component {
);
}

// If source is a PoI list: show a button to return to the list
if (backAction !== this.closeAction) {
return (
<PanelNav>
<Button icon="arrow-left" variant="tertiary" onClick={backAction}>
<Button
icon="arrow-left"
variant="tertiary"
onClick={e => {
backAction(e, poiFilters);
}}
>
{_('Display all results')}
</Button>
</PanelNav>
Expand Down Expand Up @@ -276,10 +254,6 @@ export default class PoiPanel extends React.Component {
withOpeningHours
onClick={this.center}
/>
<CloseButton
onClick={isMobile ? backAction : this.closeAction}
position="topRight"
/>
</Flex>
<div className="u-mb-l">
<ActionButtons
Expand Down
24 changes: 13 additions & 11 deletions src/panel/poi/blocks/Covid19.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,17 +85,19 @@ const getContent = ({ status, opening_hours, note, contribute_url }) => {
const LocalizedWarning = ({ countryCode }) => {
const { frInformationUrl } = useConfig('covid19');

return <div>
<p>{_('Please comply with government travel restrictions.', 'covid19')}</p>
{countryCode === 'FR' && (
<p>
{_('More information at', 'covid19')}{' '}
<a rel="noopener noreferrer" href={frInformationUrl}>
gouvernement.fr/info-coronavirus
</a>
</p>
)}
</div>
return (
<div>
<p>{_('Please comply with government travel restrictions.', 'covid19')}</p>
{countryCode === 'FR' && (
<p>
{_('More information at', 'covid19')}{' '}
<a rel="noopener noreferrer" href={frInformationUrl}>
gouvernement.fr/info-coronavirus
</a>
</p>
)}
</div>
);
};

const LegalWarning = ({ countryCode }) => (
Expand Down
29 changes: 26 additions & 3 deletions src/scss/includes/search_form.scss
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,9 @@ input[type="search"] {
}
}

// Return arrow
.search_form__return {
// Return arrows
.search_form__return,
.search_form__return-to-list {
display: none;
}

Expand Down Expand Up @@ -191,7 +192,8 @@ input[type="search"] {
font-size: 14px;
}

.search_form__return {
.search_form__return,
.search_form__return-to-list {
display: none;
font-size: 20px;
text-align: center;
Expand Down Expand Up @@ -303,4 +305,25 @@ input[type="search"] {
display: none;
}
}

// When a PoI Panel is displayed
.top_bar--poi-from-list {

// Show the return arrow
.search_form__return-to-list {
display: block;
}

// If the search field is focused, hide it
&.top_bar--search_focus {
.search_form__return-to-list {
display: none;
}
}

// Make room for it on the left of the field
.search_form__wrapper {
padding-left: $spacing-xxl-3;
}
}
}
4 changes: 2 additions & 2 deletions tests/integration/tests/autocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -249,8 +249,8 @@ test('Search Query', async () => {
await page.goto(`${APP_URL}/?q=${searchQuery}`);
const searchValue = await getInputValue(page, '#search');

// search input is filled with query
expect(searchValue).toEqual(searchQuery);
// search input is filled with PoI name (not the query)
expect(searchValue).toEqual('test result 1');

// app navigates to first result from autocomplete
expect(page.url()).toEqual(`${APP_URL}/place/osm:node:4872758213@test_result_1`);
Expand Down
2 changes: 0 additions & 2 deletions tests/integration/tests/poi.desktop.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ test('add a poi as favorite and find it back in the favorite menu', async () =>
expect(await exists(page, '.poiTitle')).toBeTruthy();
expect(await exists(page, '.poi_panel')).toBeTruthy();
await page.click('.poi_panel__actions .poi_panel__action__favorite');
await page.click('.poi_panel .closeButton');
// we check that the first favorite item is our poi
await toggleFavoritePanel(page);
let fav = await getFavorites(page);
Expand All @@ -99,7 +98,6 @@ test('add a poi as favorite and find it back in the favorite menu', async () =>
expect(await exists(page, '.poi_panel')).toBeTruthy();

await page.click('.poi_panel__actions .poi_panel__action__favorite');
await page.click('.poi_panel .closeButton');
// it should disappear from the favorites
await toggleFavoritePanel(page);
fav = await getFavorites(page);
Expand Down
1 change: 1 addition & 0 deletions views/index.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
></button>
<div class="search_form__wrapper empty">
<div class="search_form__return icon-arrow-left"></div>
<div class="search_form__return-to-list icon-arrow-left"></div>
<input id="search" type="search" class="search_form__input" spellcheck="false" required placeholder="<%= _('Search on Qwant Maps') %>" autocomplete="off">
<button id="clear_button_mobile" class="search_form__clear icon-x" type="button" onmousedown="clearSearch(event)" title="<%= _('Clear', 'search bar') %>"></button>
<input type="submit" value="" class="search_form__action" onclick="submitSearch()" title="<%= _('Search') %>">
Expand Down