Skip to content

Commit

Permalink
Merge 68cc3a8 into ffa0351
Browse files Browse the repository at this point in the history
  • Loading branch information
mahmoudadel54 committed May 2, 2024
2 parents ffa0351 + 68cc3a8 commit 4ed5eae
Show file tree
Hide file tree
Showing 13 changed files with 532 additions and 24 deletions.
4 changes: 2 additions & 2 deletions web/client/components/I18N/IntlNumberFormControl.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class IntlNumberFormControl extends React.Component {
parse = value => {
let formatValue = value;
// eslint-disable-next-line use-isnan
if (formatValue !== NaN && formatValue !== "NaN") { // Allow locale string to parse
if (formatValue !== NaN && formatValue !== "NaN" && formatValue !== '') { // Allow locale string to parse
const locale = this.context && this.context.intl && this.context.intl.locale || "en-US";
const format = new Intl.NumberFormat(locale);
const parts = format.formatToParts(12345.6);
Expand All @@ -103,7 +103,7 @@ class IntlNumberFormControl extends React.Component {
};

format = val => {
if (!isNaN(val) && val !== "NaN") {
if (!isNaN(val) && val !== "NaN" && val !== '') {
const locale = this.context && this.context.intl && this.context.intl.locale || "en-US";
const formatter = new Intl.NumberFormat(locale, {minimumFractionDigits: 0, maximumFractionDigits: 20});
return formatter.format(val);
Expand Down
21 changes: 17 additions & 4 deletions web/client/components/mapcontrols/search/SearchBar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import SearchBarToolbar from '../../search/SearchBarToolbar';
import { defaultSearchWrapper } from '../../search/SearchBarUtils';
import BookmarkSelect, {BookmarkOptions} from "../searchbookmarkconfig/BookmarkSelect";
import CoordinatesSearch, {CoordinateOptions} from "../searchcoordinates/CoordinatesSearch";
import CurrentMapCRSCoordSearch from '../searchcoordinates/CurrentMapCRSCoordSearch';
import tooltip from '../../misc/enhancers/tooltip';

const TMenuItem = tooltip(MenuItem);
Expand Down Expand Up @@ -101,6 +102,7 @@ export default ({
onZoomToPoint = () => {},
onClearBookmarkSearch = () => {},
onPurgeResults,
currentMapCRS = 'EPSG:4326',
items = [],
...props
}) => {
Expand All @@ -112,6 +114,13 @@ export default ({
}
}, [searchOptions?.services]);
useEffect(() => {
// Switch back to coordinate search when map CRS is EPSG:4326 and active tool is Map CRS coordinate search
if (currentMapCRS === 'EPSG:4326' && activeTool === 'mapCRSCoordinatesSearch') {
onChangeActiveSearchTool('coordinatesSearch');
}
}, [currentMapCRS]);

const selectedServices = searchOptions?.services?.filter((_, index) => selectedSearchService >= 0 ? selectedSearchService === index : true) ?? [];
const search = defaultSearchWrapper({
searchText,
Expand Down Expand Up @@ -160,6 +169,7 @@ export default ({
clearSearch={clearSearch}
onChangeActiveSearchTool={onChangeActiveSearchTool}
onClearBookmarkSearch={onClearBookmarkSearch}
currentMapCRS={currentMapCRS}
/>);
}

Expand Down Expand Up @@ -224,7 +234,10 @@ export default ({
onCancelSelectedItem={onCancelSelectedItem}
onPurgeResults={onPurgeResults}/>
{activeTool === "coordinatesSearch" && showCoordinatesSearchOption &&
<CoordinatesSearch format={format} defaultZoomLevel={defaultZoomLevel} onClearCoordinatesSearch={onClearCoordinatesSearch} />
<CoordinatesSearch currentMapCRS={currentMapCRS} format={format} defaultZoomLevel={defaultZoomLevel} onClearCoordinatesSearch={onClearCoordinatesSearch} />
}
{activeTool === "mapCRSCoordinatesSearch" && showCoordinatesSearchOption &&
<CurrentMapCRSCoordSearch currentMapCRS={currentMapCRS} format={format} defaultZoomLevel={defaultZoomLevel} onClearCoordinatesSearch={onClearCoordinatesSearch} />
}
{
activeTool === "bookmarkSearch" && showBookMarkSearchOption &&
Expand Down Expand Up @@ -253,7 +266,7 @@ export default ({
clearSearch();
}
},
...(activeTool === "coordinatesSearch" &&
...(["coordinatesSearch", "mapCRSCoordinatesSearch"].includes(activeTool) &&
CoordinateOptions.removeIcon(activeTool, coordinate, onClearCoordinatesSearch, onChangeCoord))
}, {
glyph: searchIcon,
Expand All @@ -265,8 +278,8 @@ export default ({
visible: activeTool === "addressSearch" &&
(!(searchText !== "" || selectedItems && selectedItems.length > 0) || !splitTools),
onClick: () => isSearchClickable && search(),
...(activeTool === "coordinatesSearch" &&
CoordinateOptions.searchIcon(activeTool, coordinate, onZoomToPoint, defaultZoomLevel)),
...(["coordinatesSearch", "mapCRSCoordinatesSearch"].includes(activeTool) &&
CoordinateOptions.searchIcon(activeTool, coordinate, onZoomToPoint, defaultZoomLevel, currentMapCRS)),
...(activeTool === "bookmarkSearch" &&
BookmarkOptions.searchIcon(activeTool, props))
}, {
Expand Down
112 changes: 112 additions & 0 deletions web/client/components/mapcontrols/search/__tests__/SearchBar-test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,17 @@ describe("test the SearchBar", () => {
expect(cog.length).toBe(1);
});

it('test zoomToPoint, with search, with decimal, with reset if mapCRS different than default 4326', () => {
const store = {dispatch: () => {}, subscribe: () => {}, getState: () => ({search: {coordinate: {lat: 0.05, lon: 0.05, yCoord: 2, xCoord: 2}}})};
ReactDOM.render(<Provider store={store}><SearchBar format="decimal" coordinate={{"lat": 0.05, "lon": 0.05, "yCoord": 2, "xCoord": 2}} activeSearchTool="mapCRSCoordinatesSearch" showOptions searchText={"va"} currentMapCRS={"EPSG:900913"} delay={0} typeAhead={false} /></Provider>, document.getElementById("container"));
let reset = document.getElementsByClassName("glyphicon-1-close");
let search = document.getElementsByClassName("glyphicon-search");
let cog = document.getElementsByClassName("glyphicon-cog");
expect(reset.length).toBe(1);
expect(search.length).toBe(1);
expect(cog.length).toBe(0);
});

it('test zoomToPoint, with search, with aeronautical, with reset', () => {
const store = {dispatch: () => {}, subscribe: () => {}, getState: () => ({search: {coordinate: {lat: 2, lon: 2}}})};
ReactDOM.render(<Provider store={store}><SearchBar format="aeronautical" activeSearchTool="coordinatesSearch" showOptions searchText={"va"} delay={0} typeAhead={false} /></Provider>, document.getElementById("container"));
Expand Down Expand Up @@ -342,6 +353,41 @@ describe("test the SearchBar", () => {
}
});
});
it('test calling zoomToPoint with onKeyDown event if mapCRS different than default 4326', (done) => {
const store = {
dispatch: () => {},
subscribe: () => {},
getState: () => ({search: {coordinate: {yCoord: 15, xCoord: 15}}})
};
ReactDOM.render(
<Provider store={store}>
<SearchBar
format="decimal"
activeSearchTool="mapCRSCoordinatesSearch"
showOptions
onZoomToPoint={(point, zoom, crs) => {
expect(point).toEqual({x: 15, y: 15});
expect(zoom).toEqual(12);
expect(crs).toEqual("EPSG:4326");
done();
}}
coordinate={{yCoord: 15, xCoord: 15}}
currentMapCRS={"EPSG:900913"}
typeAhead={false} />
</Provider>
, document.getElementById("container")
);
const container = document.getElementById('container');
const elements = container.querySelectorAll('input');
TestUtils.Simulate.keyDown(elements[0], {
keyCode: 13,
preventDefault: () => {
expect(true).toBe(true);
done();
}
});
});

it('Test SearchBar with not allowed e char for keyDown event', (done) => {
const store = {
dispatch: () => {},
Expand Down Expand Up @@ -374,6 +420,40 @@ describe("test the SearchBar", () => {
}
});
});
it('Test SearchBar with not allowed e char for keyDown event if mapCRS different than default 4326', (done) => {
const store = {
dispatch: () => {},
subscribe: () => {},
getState: () => ({search: {coordinate: {yCoord: 150, xCoord: 150}}})
};
ReactDOM.render(
<Provider store={store}>
<SearchBar
format="decimal"
activeSearchTool="mapCRSCoordinatesSearch"
showOptions
onZoomToPoint={() => {
expect(true).toBe(false);
}}
coordinate={{yCoord: 150, xCoord: 150}}
currentMapCRS={"EPSG:900913"}
typeAhead={false} />
</Provider>, document.getElementById("container")
);
const container = document.getElementById('container');
const elements = container.querySelectorAll('input');
expect(elements.length).toBe(2);
expect(elements[0].value).toBe('150');

TestUtils.Simulate.keyDown(elements[0], {
keyCode: 69, // char e
preventDefault: () => {
expect(true).toBe(true);
done();
}
});
});

it('Test SearchBar with valid onKeyDown event by pressing number 8', () => {
const store = {
dispatch: () => {},
Expand Down Expand Up @@ -405,6 +485,38 @@ describe("test the SearchBar", () => {
}
});
});
it('Test SearchBar with valid onKeyDown event by pressing number 8 if mapCRS different than default 4326', () => {
const store = {
dispatch: () => {},
subscribe: () => {},
getState: () => ({search: {coordinate: {yCoord: 1, xCoord: 1}}})
};
ReactDOM.render(
<Provider store={store}>
<SearchBar
format="decimal"
activeSearchTool="mapCRSCoordinatesSearch"
showOptions
onZoomToPoint={() => {
expect(true).toBe(false);
}}
coordinate={{yCoord: 1, xCoord: 1}}
currentMapCRS={"EPSG:900913"}
typeAhead={false} />
</Provider>, document.getElementById("container")
);
const container = document.getElementById('container');
const elements = container.querySelectorAll('input');
expect(elements.length).toBe(2);
expect(elements[0].value).toBe('1');

TestUtils.Simulate.keyDown(elements[0], {
keyCode: 56,
preventDefault: () => {
expect(true).toBe(false);
}
});
});

it('test showOptions false, only address tool visible', () => {
ReactDOM.render(<SearchBar splitTools showOptions={false} searchText={""} delay={0} typeAhead={false} />, document.getElementById("container"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,14 @@ import { zoomAndAddPoint, changeCoord } from '../../../actions/search';
export const CoordinateOptions = ({
clearCoordinates: (onClearCoordinatesSearch, onChangeCoord) =>{
onClearCoordinatesSearch({owner: "search"});
onChangeCoord("lat", "");
onChangeCoord("lon", "");
const clearedFields = ["lat", "lon", "xCoord", "yCoord"];
const resetVal = '';
clearedFields.forEach(field => onChangeCoord(field, resetVal));
},
areValidCoordinates: (coordinate) => {
if (!coordinate) return false;
return isNumber(coordinate?.lon) && isNumber(coordinate?.lat);
},
areValidCoordinates: (coordinate) => isNumber(coordinate?.lon) && isNumber(coordinate?.lat),
zoomToPoint: (onZoomToPoint, coordinate, defaultZoomLevel = 12) => {
onZoomToPoint({
x: parseFloat(coordinate.lon),
Expand Down Expand Up @@ -63,19 +67,31 @@ export const CoordinateOptions = ({
coordinate,
onClearCoordinatesSearch,
onChangeCoord) =>({
visible: activeTool === "coordinatesSearch" && (isNumber(coordinate.lon) || isNumber(coordinate.lat)),
visible: (['coordinatesSearch', 'mapCRSCoordinatesSearch'].includes(activeTool)) && (isNumber(coordinate.lon) || isNumber(coordinate.lat) || isNumber(coordinate.xCoord) || isNumber(coordinate.yCoord)),
onClick: () => CoordinateOptions.clearCoordinates(onClearCoordinatesSearch, onChangeCoord)
}),
searchIcon: (activeTool, coordinate, onZoomToPoint, defaultZoomLevel) => ({
visible: activeTool === "coordinatesSearch",
visible: ["coordinatesSearch", "mapCRSCoordinatesSearch"].includes(activeTool),
onClick: () => {
if (activeTool === "coordinatesSearch" && CoordinateOptions.areValidCoordinates(coordinate)) {
if ((['coordinatesSearch', 'mapCRSCoordinatesSearch'].includes(activeTool)) && CoordinateOptions.areValidCoordinates(coordinate)) {
CoordinateOptions.zoomToPoint(onZoomToPoint, coordinate, defaultZoomLevel);
}
}
}),
coordinatesMenuItem: ({activeTool, searchText, clearSearch, onChangeActiveSearchTool, onClearBookmarkSearch}) =>(
<MenuItem active={activeTool === "coordinatesSearch"} onClick={() => {
coordinatesMenuItem: ({activeTool, searchText, clearSearch, onChangeActiveSearchTool, onClearBookmarkSearch, currentMapCRS}) =>{
if (currentMapCRS === 'EPSG:4326') {
return (<MenuItem active={activeTool === "coordinatesSearch"} onClick={() => {
if (searchText !== undefined && searchText !== "") {
clearSearch();
}
onClearBookmarkSearch("selected");
onChangeActiveSearchTool("coordinatesSearch");
document.dispatchEvent(new MouseEvent('click'));
}}>
<Glyphicon glyph={"search-coords"}/> <Message msgId="search.coordinatesSearch"/>
</MenuItem>);
}
return (<><MenuItem active={activeTool === "coordinatesSearch"} onClick={() => {
if (searchText !== undefined && searchText !== "") {
clearSearch();
}
Expand All @@ -85,7 +101,20 @@ export const CoordinateOptions = ({
}}>
<Glyphicon glyph={"search-coords"}/> <Message msgId="search.coordinatesSearch"/>
</MenuItem>
)
<MenuItem active={activeTool === "mapCRSCoordinatesSearch"} onClick={() => {
if (searchText !== undefined && searchText !== "") {
clearSearch();
}
onClearBookmarkSearch("selected");
onChangeActiveSearchTool("mapCRSCoordinatesSearch");
document.dispatchEvent(new MouseEvent('click'));
}}>
<span style={{marginLeft: 20}}>
<Glyphicon glyph={"search-coords"}/> <Message msgId="search.currentMapCRS"/>
</span>
</MenuItem>
</>);
}
});


Expand Down Expand Up @@ -130,7 +159,9 @@ const CoordinatesSearch = ({
const {zoomToPoint, areValidCoordinates} = CoordinateOptions;

const changeCoordinates = (coord, value) => {
onChangeCoord(coord, parseFloat(value));
const numValue = parseFloat(value);
const isValValidNumber = isNumber(numValue) && !isNaN(numValue);
onChangeCoord(coord, isValValidNumber ? numValue : '');
if (!areValidCoordinates()) {
onClearCoordinatesSearch({owner: "search"});
}
Expand All @@ -147,6 +178,7 @@ const CoordinatesSearch = ({
<InputGroup >
<InputGroup.Addon style={{minWidth: 45}}><Message msgId="search.latitude"/></InputGroup.Addon>
<CoordinateEntry
owner="search"
format={format}
aeronauticalOptions={aeronauticalOptions}
coordinate="lat"
Expand All @@ -168,6 +200,7 @@ const CoordinatesSearch = ({
<InputGroup>
<InputGroup.Addon style={{minWidth: 45}}><Message msgId="search.longitude"/></InputGroup.Addon>
<CoordinateEntry
owner="search"
format={format}
aeronauticalOptions={aeronauticalOptions}
coordinate="lon"
Expand Down

0 comments on commit 4ed5eae

Please sign in to comment.