Skip to content
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

Staging deployment #1209

Draft
wants to merge 42 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
c549ec1
fix(kilometrage): add support for multiple lines in popup
danji90 Jan 14, 2025
a98a6c5
chore: improve error message
danji90 Jan 14, 2025
e56a2e3
chore: improve unique filter
danji90 Jan 14, 2025
e4a15e6
chore: overriding searchUrl in layer file
danji90 Jan 15, 2025
9369505
chore: show all lines in same popup to avoid pagination
danji90 Jan 15, 2025
14193c4
chore: fix cursor in infrastruktur topic
danji90 Jan 15, 2025
35d5e91
chore: fix cursor handling
danji90 Jan 15, 2025
b32c8c2
Merge branch 'master' into daniel/kilometrage
danji90 Jan 15, 2025
edb69b8
fix: change main route names
oterral Jan 20, 2025
d4ab595
chore(release): 1.30.17-beta.0
oterral Jan 21, 2025
bcaba48
fix: fix the size of the legend
oterral Jan 21, 2025
14a3043
chore(release): 1.30.17-beta.1
oterral Jan 21, 2025
c4dde8c
chore(release): 1.30.17-beta.2
danji90 Jan 22, 2025
009b153
chore: clean
danji90 Jan 22, 2025
a37d401
chore: export kilometrageLayers
danji90 Jan 22, 2025
9f8b7b6
chore(release): 1.30.17-beta.3
danji90 Jan 22, 2025
07bf9cc
chore: remove bad queryRenderedFeaturesFilter
danji90 Jan 22, 2025
60470e4
chore(release): 1.30.17-beta.4
danji90 Jan 22, 2025
1e872ac
Merge remote-tracking branch 'origin/daniel/kilometrage' into stag
oterral Jan 23, 2025
2a06d23
chore(release): 1.30.17-beta.2
oterral Jan 23, 2025
a0b7ed5
chore(release): 1.30.17-beta.3
oterral Jan 23, 2025
18fcc06
chore(release): 1.30.17-beta.4
oterral Jan 23, 2025
2f61f85
chore(release): 1.30.17-beta.5
oterral Jan 23, 2025
9a85ccd
Merge remote-tracking branch 'origin/daniel/kilometrage' into stag
oterral Jan 23, 2025
8ea17d2
chore(release): 1.30.17-beta.6
oterral Jan 23, 2025
1ed451b
fix(STS): add SearchBar to STS menu
danji90 Jan 27, 2025
c23245a
chore: fix css
danji90 Jan 27, 2025
62cf550
chore: improve CSS, add test
danji90 Jan 28, 2025
bce285f
chore: update italian translations
danji90 Jan 28, 2025
296edf8
chore: remove context provider code
danji90 Jan 28, 2025
a70b6c6
chore: extract SearchInput into component
danji90 Jan 28, 2025
436f0de
chore: fix submit btn css
danji90 Jan 28, 2025
acbbf87
chore: readd scrollbar to seach suggestion container
danji90 Jan 29, 2025
9ac635a
fix: add 2 empty spaces
oterral Jan 30, 2025
0d6fa10
fix: add test for bad key lines
oterral Jan 30, 2025
fbdbcce
Merge branch 'olivier/updateausbild' into stag
oterral Jan 30, 2025
433e885
chore(release): 1.30.17-beta.7
oterral Jan 30, 2025
47cf7e6
fix(netzkarte): update translations for departure and station popup
danji90 Feb 3, 2025
479bcf5
chore: merge master
danji90 Feb 3, 2025
2e7ad1d
Merge branch 'daniel/stsSearchBar' into stag
danji90 Feb 3, 2025
0c5ee2a
Merge branch 'daniel/departureWording' into stag
danji90 Feb 3, 2025
737f754
chore(release): 1.30.18-beta.0
danji90 Feb 3, 2025
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 .env
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ REACT_APP_BASE_URL=//maps.trafimage.ch
REACT_APP_MATOMO_URL_BASE=https://analytics.geops.de/
REACT_APP_MATOMO_SITE_ID=9
REACT_APP_VECTOR_TILES_URL=https://maps.geops.io
REACT_APP_VECTOR_TILES_URL=https://maps.test.geops.io
#REACT_APP_STYLE_REVIEW_PREFIX=
REACT_APP_SEARCH_URL=https://maps.trafimage.ch
# REACT_APP_SEARCH_URL=https://wkp.dev.trafimage.geops.ch
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "trafimage-maps",
"description": "trafimage-maps web component",
"version": "1.30.17",
"version": "1.30.18-beta.0",
"private": true,
"main": "build/bundle.js",
"proxy": "http://127.0.0.1:8000",
Expand Down
1 change: 1 addition & 0 deletions src/WebComponent.scss
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
@import "./components/Menu/MenuItemHeader.scss";
@import "./components/Search/Search.scss";
@import "./components/Search/SearchToggle.scss";
@import "./components/Search/SearchInput.scss";
@import "./components/Share/Share.scss";
@import "./components/TopicMenu/TopicMenu.scss";
@import "./components/TopicsMenu/TopicsMenu.scss";
Expand Down
3 changes: 2 additions & 1 deletion src/components/MapControls/MapControls.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ function MapControls({
const dispatch = useDispatch();
const overlayWidth = useOverlayWidth();
const screenHeight = useSelector((state) => state.app.screenHeight);
const activeTopic = useSelector((state) => state.app.activeTopic);
const isSmallHeight = useMemo(() => {
return ["xs", "s"].includes(screenHeight);
}, [screenHeight]);
Expand Down Expand Up @@ -153,7 +154,7 @@ function MapControls({
className={`wkp-map-controls ${classes.mapControls}`}
data-testid="map-controls-wrapper"
>
{menuToggler && <MenuToggler />}
{menuToggler && (activeTopic?.menuToggler ?? <MenuToggler />)}
<Zoom
map={map}
zoomInChildren={<ZoomIn />}
Expand Down
13 changes: 10 additions & 3 deletions src/components/MapControls/MenuToggler/MenuToggler.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from "react";
import { useDispatch, useSelector } from "react-redux";
import { makeStyles } from "@mui/styles";
import { useTranslation } from "react-i18next";
import PropTypes from "prop-types";
import MapButton from "../../MapButton";
import { ReactComponent as MenuOpen } from "../../../img/sbb/040_hamburgermenu_102_36.svg";
import { ReactComponent as MenuClosed } from "../../../img/sbb/040_schliessen_104_36.svg";
Expand All @@ -11,21 +12,27 @@ const useStyles = makeStyles({
displayMenuToggler: { padding: "8px" },
});

function MenuToggler() {
function MenuToggler({ children, ...props }) {
const classes = useStyles();
const { t } = useTranslation();
const displayMenu = useSelector((state) => state.app.displayMenu);
const dispatch = useDispatch();

return (
<MapButton
className={`wkp-display-menu-toggler ${classes.displayMenuToggler}`}
onClick={() => dispatch(setDisplayMenu(!displayMenu))}
title={t("Menü")}
title={displayMenu ? t("Schliessen") : t("Menü")}
data-testid="map-controls-menu-toggler"
{...props}
>
{displayMenu ? <MenuClosed /> : <MenuOpen />}
{children ?? (displayMenu ? <MenuClosed /> : <MenuOpen />)}
</MapButton>
);
}

MenuToggler.propTypes = {
children: PropTypes.node,
};

export default MenuToggler;
241 changes: 4 additions & 237 deletions src/components/Search/Search.js
Original file line number Diff line number Diff line change
@@ -1,249 +1,16 @@
/* eslint-disable react/jsx-props-no-spreading */
import React, { useEffect, useState, useRef } from "react";
import { useSelector, useDispatch } from "react-redux";
import Autosuggest from "react-autosuggest";
import { FaSearch, FaAngleDown, FaAngleUp } from "react-icons/fa";
import { useTranslation } from "react-i18next";
import { IconButton, Typography } from "@mui/material";
import { setFeatureInfo, setSearchOpen } from "../../model/app/actions";
import useHasScreenSize from "../../utils/useHasScreenSize";
import React, { useRef } from "react";
import SearchInput from "./SearchInput";
import SearchToggle from "./SearchToggle";

import "./Search.scss";
import CloseButton from "../CloseButton";
import { trackEvent } from "../../utils/trackingUtils";

const mobileMapPadding = [50, 50, 50, 50];

function Search() {
const [suggestions, setSuggestions] = useState([]);
const [value, setValue] = useState("");
const map = useSelector((state) => state.app.map);
const featureInfo = useSelector((state) => state.app.featureInfo);
const searchService = useSelector((state) => state.app.searchService);
const activeTopic = useSelector((state) => state.app.activeTopic);
const isMobile = useHasScreenSize();
const searchContainerRef = useRef();
const { t } = useTranslation();
const dispatch = useDispatch();

useEffect(() => {
if (!searchService) {
return;
}
searchService.setUpsert((section, items, position) => {
setSuggestions((oldSuggestions) => {
const index = oldSuggestions.findIndex((s) => s.section === section);
const start = index === -1 ? position : index;
const deleteCount = index === -1 ? 0 : 1;
const newSuggestions = [...oldSuggestions];
newSuggestions.splice(start, deleteCount, { section, items });
return newSuggestions;
});
});
}, [searchService, setSuggestions]);

useEffect(
() => searchService && map && searchService.setMap(map),
[searchService, map],
);

if (!searchService || !Object.keys(searchService.searches || []).length) {
return null;
}

return (
<div className="wkp-search">
<div className="wkp-search" ref={searchContainerRef}>
<SearchToggle popupAnchor={searchContainerRef?.current}>
<Autosuggest
multiSection
shouldRenderSuggestions={(val) => val.trim().length > 2}
suggestions={suggestions}
onSuggestionsFetchRequested={(evt) => {
searchService.search(evt.value);
}}
onSuggestionsClearRequested={() => {
setSuggestions([]);
}}
onSuggestionHighlighted={({ suggestion }) =>
searchService.highlight(suggestion)
}
onSuggestionSelected={(e, thing) => {
const { suggestion } = thing;
trackEvent(
{
eventType: "action",
componentName: "search result",
label: searchService.value(suggestion),
variant: suggestion.section,
location: t(activeTopic?.name, { lng: "de" }),
eventName: e.type,
},
activeTopic,
);
dispatch(setFeatureInfo());
searchService.select(
suggestion,
isMobile ? mobileMapPadding : undefined,
);
dispatch(setSearchOpen(false));
}}
getSuggestionValue={(suggestion) => searchService.value(suggestion)}
renderSuggestion={(suggestion) => searchService.render(suggestion)}
renderSectionTitle={({ section }) => {
const count = searchService.countItems(section);
return (
count > 0 && (
<div
className="wkp-search-section-opener"
onClick={() => searchService.toggleSection(section)}
onKeyPress={() => searchService.toggleSection(section)}
role="button"
tabIndex={0}
>
<div className="wkp-search-section-header">
<Typography variant="h4" component="span">
{t(section)}:{" "}
</Typography>
<Typography variant="subtitle1" component="span">
{t("overallResult", { count })}
</Typography>
</div>
{searchService.sectionCollapsed(section) ? (
<FaAngleDown focusable={false} />
) : (
<FaAngleUp focusable={false} />
)}
</div>
)
);
}}
getSectionSuggestions={(result) => {
return (
result?.items?.map((i) => ({ ...i, section: result.section })) ||
[]
);
}}
inputProps={{
autoFocus: true,
tabIndex: 0,
"aria-label": t("Suchmaske"),
onChange: (e, { newValue }) => setValue(newValue),
onKeyUp: (e) => {
const { key } = e;
if (key === "Enter") {
trackEvent(
{
eventType: "action",
componentName: "search input",
label: t("Suche starten"),
location: t(activeTopic?.name, { lng: "de" }),
variant: "Suche starten",
},
activeTopic,
);
const filtered = suggestions.filter((s) => s.items.length > 0);
if (filtered.length > 0) {
const { items, section } = filtered[0];
dispatch(setSearchOpen(false));
searchService.select(
{ ...items[0], section },
isMobile ? mobileMapPadding : undefined,
);
}
} else if (key === "ArrowDown" || key === "ArrowUp") {
searchService.highlightSection(); // for improved accessibility
}
},
placeholder: searchService.getPlaceholder(t),
value,
}}
renderInputComponent={(inputProps) => {
return (
<div className="wkp-search-input" ref={searchContainerRef}>
<input {...inputProps} />
{value && (
<CloseButton
tabIndex={0}
title={t("Suchtext löschen")}
className="wkp-search-button wkp-search-button-clear"
onClick={() => {
setValue("");
searchService.clearHighlight();
searchService.clearSelect();
const searchFeatureInfos = searchService.clearPopup();

// We remove the stations feature infos from the current list of feature infos.
if (featureInfo?.length && searchFeatureInfos?.length) {
(searchFeatureInfos || []).forEach(
(searchFeatureInfo) => {
const index = featureInfo?.findIndex((info) => {
return info === searchFeatureInfo;
});
if (index > -1) {
featureInfo.splice(index, 1);
}
},
);
dispatch(setFeatureInfo([...featureInfo]));
}
}}
/>
)}
<IconButton
tabIndex={0}
aria-label={t("Suche starten")}
title={t("Suche starten")}
className="wkp-search-button wkp-search-button-submit"
onClick={() => {
trackEvent(
{
eventType: "action",
componentName: "search button",
label: t("Suche starten"),
location: t(activeTopic?.name, { lng: "de" }),
variant: "Suche starten",
},
activeTopic,
);

if (!value) {
// Hide the search input on small screen
dispatch(setSearchOpen(false));
}

if (searchService.selectItem) {
// Will zoom on the current selected feature
searchService.select(
searchService.selectItem,
isMobile ? mobileMapPadding : undefined,
);
}

// Launch a search
if (value) {
searchService.search(value).then((searchResults) => {
const result = searchResults.find(
(results) => results.items.length > 0,
);
if (result) {
const { items, section } = result;
dispatch(setSearchOpen(false));
searchService.select(
{ ...items[0], section },
isMobile ? mobileMapPadding : undefined,
);
}
});
}
}}
>
<FaSearch focusable={false} />
</IconButton>
</div>
);
}}
/>
<SearchInput />
</SearchToggle>
</div>
);
Expand Down
Loading
Loading